diff --git a/CMakeLists.txt b/CMakeLists.txt index e9cac091..2ecd62cb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,459 +1,459 @@ -# ---------------------------------------------------------------------------- -# Root CMake file for Rockchip Media Process Platform (MPP) -# -# - 10:34 2015/7/27: Initial version -# -# ---------------------------------------------------------------------------- - -# vim: syntax=cmake -if(NOT CMAKE_BUILD_TYPE) - # default to Release build for GCC builds - set(CMAKE_BUILD_TYPE Debug CACHE STRING - "Choose the type of build, options are: None(CMAKE_CXX_FLAGS or CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel." - FORCE) -endif() -message(STATUS "cmake version ${CMAKE_VERSION}") -if(NOT CMAKE_VERSION VERSION_LESS "2.8.12.20131121") - cmake_policy(SET CMP0025 OLD) # report Apple's Clang as just Clang - cmake_policy(SET CMP0042 OLD) # do not require MACOSX_RPATH -endif() - -# Search packages for host system instead of packages for target system -# in case of cross compilation these macro should be defined by toolchain file -if(NOT COMMAND find_host_package) - macro(find_host_package) - find_package(${ARGN}) - endmacro() -endif() -if(NOT COMMAND find_host_program) - macro(find_host_program) - find_program(${ARGN}) - endmacro() -endif() - -option(RKPLATFORM "Enable RK HW CONFIG" OFF) -if(${CMAKE_RKPLATFORM_ENABLE} MATCHES "ON") - option(RKPLATFORM "Enable RK HW CONFIG" ON) - set(RKPLATFORM True) - add_definitions(-DRKPLATFORM) -endif() - -project (rk_mpp) - -cmake_minimum_required (VERSION 2.8.8) # OBJECT libraries require 2.8.8 -include(CheckIncludeFiles) -include(CheckFunctionExists) -include(CheckSymbolExists) -include(CheckCXXCompilerFlag) - -# ---------------------------------------------------------------------------- -# set property to classify library kinds -# ---------------------------------------------------------------------------- -set_property(GLOBAL PROPERTY USE_FOLDERS ON) -set_property(GLOBAL PROPERTY PREDEFINED_TARGETS_FOLDER "CMakeTargets") -# ---------------------------------------------------------------------------- -# enable test in this project -# ---------------------------------------------------------------------------- -enable_testing() - -# ---------------------------------------------------------------------------- -# add debug define in project -# ---------------------------------------------------------------------------- -if(NOT $(CMAKE_BUILD_TYPE) MATCHES "Release") - option(RK_DEBUG "Enable run-time debug mode(debugging)" ON) - if(RK_DEBUG) - add_definitions(-DRK_DEBUG) - message(STATUS "rk_mpp debug mode is enabled") - endif() -endif() - -# ---------------------------------------------------------------------------- -# System architecture detection -# ---------------------------------------------------------------------------- -string(TOLOWER "${CMAKE_SYSTEM_PROCESSOR}" SYSPROC) -set(X86_ALIASES x86 i386 i686 x86_64 amd64) -list(FIND X86_ALIASES "${SYSPROC}" X86MATCH) -if("${SYSPROC}" STREQUAL "" OR X86MATCH GREATER "-1") - message(STATUS "Detected x86 system processor") - set(X86 true) - add_definitions(-DARCH_X86=1) - if("${CMAKE_SIZEOF_VOID_P}" MATCHES 8) - set(X64 true) - add_definitions(-DARCH_X64=1) - message(STATUS "Define X86_64 to 1") - endif() -elseif(${SYSPROC} STREQUAL "armv6l") - message(STATUS "Detected ARMv6 system processor") - set(ARM true) - set(ARMEABI_V6 true) - add_definitions(-DARCH_ARM=1 -DDHAVE_ARMV6=1) -elseif(${SYSPROC} STREQUAL "armv7-a") - message(STATUS "Detected ARMv7 system processor") - set(ARM true) - set(ARMEABI_V7A true) - add_definitions(-DARCH_ARM=1 -DDHAVE_ARMV7=1) -elseif(${SYSPROC} STREQUAL "armv7-a_hardfp") - message(STATUS "Detected ARMv7 system processor") - set(ARM true) - set(ARMEABI_V7A_HARDFP true) - add_definitions(-DARCH_ARM=1 -DDHAVE_ARMV7=1) -else() - message(STATUS "CMAKE_SYSTEM_PROCESSOR value `${CMAKE_SYSTEM_PROCESSOR}` is unknown") - message(STATUS "Please add this value near ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE}") -endif() - -if(UNIX) - SET(PLATFORM_LIBS pthread) - if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin") - SET(PLATFORM_LIBS ${PLATFORM_LIBS} rt) - endif() -endif(UNIX) - -# ---------------------------------------------------------------------------- -# Compiler detection -# ---------------------------------------------------------------------------- -if(CMAKE_GENERATOR STREQUAL "Xcode") - set(XCODE true) -endif() - -if (APPLE) - add_definitions(-DMACOS) -endif() - -if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") - set(CLANG true) -endif() -if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel") - set(INTEL_CXX true) -endif() -if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") - set(GCC true) -endif() - -if(INTEL_CXX AND WIN32) - # treat icl roughly like MSVC - set(MSVC true) -endif() -if(MSVC) - option(STATIC_LINK_CRT "Statically link C runtime for release builds" OFF) - if (STATIC_LINK_CRT) - set(CompilerFlags CMAKE_CXX_FLAGS_RELEASE CMAKE_C_FLAGS_RELEASE) - foreach(CompilerFlag ${CompilerFlags}) - string(REPLACE "/MD" "/MT" ${CompilerFlag} "${${CompilerFlag}}") - endforeach() - endif (STATIC_LINK_CRT) - add_definitions(/W3) # Full warnings - add_definitions(/Ob2) # always inline - add_definitions(/MP) # multithreaded build - # disable Microsofts suggestions for proprietary secure APIs - add_definitions(/D_CRT_SECURE_NO_WARNINGS) -endif(MSVC) - -if(INTEL_CXX AND UNIX) - # treat icpc roughly like gcc - set(GCC true) - add_definitions(-Wall -Wextra -Wshadow) -elseif(CLANG) - # treat clang roughly like gcc - set(GCC true) - add_definitions(-Wall -Wextra -Wshadow -ffast-math) -elseif(CMAKE_COMPILER_IS_GNUCXX) - add_definitions(-Wall -Wextra -Wshadow -ffast-math) - check_cxx_compiler_flag(-Wno-narrowing GCC_HAS_NO_NARROWING) - check_cxx_compiler_flag(-mstackrealign GCC_HAS_STACK_REALIGN) - if (GCC_HAS_STACK_REALIGN) - add_definitions(-mstackrealign) - endif() - execute_process(COMMAND ${CMAKE_CXX_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION) -endif() - -if(GCC) - if(ARM) - if(ARMEABI_V6) - add_definitions(-march=armv6 -mfloat-abi=hard -mfpu=vfp) - elseif(ARMEABI_V7A) - add_definitions(-march=armv7-a -mfloat-abi=softfp -mfpu=neon) - elseif(ARMEABI_V7A_HARDFP) - add_definitions(-march=armv7-a -mfloat-abi=hard -mfpu=neon) - endif() - else() - if(X64 AND NOT WIN32) - add_definitions(-fPIC) - endif(X64 AND NOT WIN32) - if(X86 AND NOT X64) - add_definitions(-march=i686) - endif() - endif() - - if(NOT $(CMAKE_BUILD_TYPE) MATCHES "Release") - set(CMAKE_C_VISIBILITY_PRESET hidden) - set(CMAKE_CXX_VISIBILITY_PRESET hidden) - endif() - - # disable multichar warning - add_definitions(-Wno-multichar) -endif(GCC) - -# ---------------------------------------------------------------------------- -# Create svn version information -# ---------------------------------------------------------------------------- -set(HAVE_SVN 0) -if(EXISTS "${PROJECT_SOURCE_DIR}/.svn/") - find_host_package(Subversion) - if(Subversion_FOUND) - set(HAVE_SVN true) - else() - if(WIN32) - # The official subversion client is not available, so fall back to - # tortoise if it is installed. - find_program(TORTOISE_WCREV_EXECUTABLE - NAMES SubWCRev.exe - PATHS "[HKEY_LOCAL_MACHINE\\SOFTWARE\\TortoiseSVN;Directory]/bin" - ) - - if (NOT TORTOISE_WCREV_EXECUTABLE) - message(STATUS "TortoiseSVN was not found.") - else(NOT TORTOISE_WCREV_EXECUTABLE) - message(STATUS "TortoiseSVN was Found.") - set(HAVE_SVN true) - - macro(Subversion_WC_INFO dir prefix) - # the subversion commands should be executed with the C locale, otherwise - # the message (which are parsed) may be translated, Alex - set(_Subversion_SAVED_LC_ALL "$ENV{LC_ALL}") - set(ENV{LC_ALL} C) - - execute_process(COMMAND ${TORTOISE_WCREV_EXECUTABLE} ${dir} - OUTPUT_VARIABLE ${prefix}_WC_INFO - ERROR_VARIABLE Subversion_svn_info_error - RESULT_VARIABLE Subversion_svn_info_result - OUTPUT_STRIP_TRAILING_WHITESPACE - ERROR_STRIP_TRAILING_WHITESPACE) - - if(NOT ${Subversion_svn_info_result} EQUAL 0) - message(SEND_ERROR "Command \"${TORTOISE_WCREV_EXECUTABLE} ${dir}\" failed with output:\n${Subversion_svn_info_error}") - else() - string(REGEX REPLACE "^(.*\n)?Last committed at revision ([0-9]*)\n.*" - "\\2" ${prefix}_WC_REVISION "${${prefix}_WC_INFO}") - endif() - set(Project_WC_LAST_CHANGED_AUTHOR "unknown") - set(Project_WC_LAST_CHANGED_DATE "unknown") - - # restore the previous LC_ALL - set(ENV{LC_ALL} ${_Subversion_SAVED_LC_ALL}) - endmacro() - endif (NOT TORTOISE_WCREV_EXECUTABLE) - endif(WIN32) - endif(Subversion_FOUND) -endif(EXISTS "${PROJECT_SOURCE_DIR}/.svn/") - -if(${HAVE_SVN}) - Subversion_WC_INFO(${PROJECT_SOURCE_DIR} Project) - - message(STATUS "Current svn revision is ${Project_WC_REVISION}") - set(VERSION_REVISION ${Project_WC_REVISION}) - set(VERSION_LAST_AUTHOR ${Project_WC_LAST_CHANGED_AUTHOR}) - set(VERSION_LAST_DATA ${Project_WC_LAST_CHANGED_DATE}) - set(VERSION_ONE_LINE "${VERSION_REVISION} author: ${VERSION_LAST_AUTHOR} date: ${VERSION_LAST_DATA}") - set(VERSION_VER_NUM ${VERSION_REVISION}) -else() - set(VERSION_REVISION -1) -endif() - -# ---------------------------------------------------------------------------- -# Create git version information -# ---------------------------------------------------------------------------- -if(EXISTS "${PROJECT_SOURCE_DIR}/.git/") - find_package(Git) - if(GIT_FOUND) - # get author - execute_process(COMMAND ${GIT_EXECUTABLE} log -1 --format=%an - OUTPUT_VARIABLE EXEC_OUT - ERROR_VARIABLE EXEC_ERROR - RESULT_VARIABLE EXEC_RET - OUTPUT_STRIP_TRAILING_WHITESPACE - ERROR_STRIP_TRAILING_WHITESPACE) - - if (NOT EXEC_RET) - message(STATUS "author: ${EXEC_OUT}") - set(VERSION_LAST_AUTHOR ${EXEC_OUT}) - endif() - - # get date - execute_process(COMMAND ${GIT_EXECUTABLE} log -1 --format=%ad - OUTPUT_VARIABLE EXEC_OUT - ERROR_VARIABLE EXEC_ERROR - RESULT_VARIABLE EXEC_RET - OUTPUT_STRIP_TRAILING_WHITESPACE - ERROR_STRIP_TRAILING_WHITESPACE) - - if (NOT EXEC_RET) - message(STATUS "author: ${EXEC_OUT}") - set(VERSION_LAST_DATA ${EXEC_OUT}) - endif() - - # get version hash - execute_process(COMMAND ${GIT_EXECUTABLE} log -1 --format=%H - OUTPUT_VARIABLE EXEC_OUT - ERROR_VARIABLE EXEC_ERROR - RESULT_VARIABLE EXEC_RET - OUTPUT_STRIP_TRAILING_WHITESPACE - ERROR_STRIP_TRAILING_WHITESPACE) - - if (NOT EXEC_RET) - set(VERSION_REVISION ${EXEC_OUT}) - endif() - - # get one line version information - execute_process(COMMAND ${GIT_EXECUTABLE} log -1 --pretty=format:"%h author: %an %s" - OUTPUT_VARIABLE EXEC_OUT - ERROR_VARIABLE EXEC_ERROR - RESULT_VARIABLE EXEC_RET - OUTPUT_STRIP_TRAILING_WHITESPACE - ERROR_STRIP_TRAILING_WHITESPACE) - - if (NOT EXEC_RET) - message(STATUS "git version: ${EXEC_OUT}") - set(VERSION_ONE_LINE ${EXEC_OUT}) - string(REPLACE "\"" "" VERSION_ONE_LINE ${VERSION_ONE_LINE}) - endif() - - set(VERSION_VER_NUM -1) - endif() -endif(EXISTS "${PROJECT_SOURCE_DIR}/.git/") - -configure_file( - "${PROJECT_SOURCE_DIR}/build/cmake/version.in" - "${PROJECT_SOURCE_DIR}/mpp/version.h" -) - -# ---------------------------------------------------------------------------- -# Build options -# ---------------------------------------------------------------------------- -set(CMAKE_INSTALL_PREFIX "") -set(LIB_INSTALL_DIR "${CMAKE_SOURCE_DIR}/out/lib" CACHE STRING "Install location of libraries") -set(BIN_INSTALL_DIR "${CMAKE_SOURCE_DIR}/out/bin" CACHE STRING "Install location of executables") -set(TEST_INSTALL_DIR "${CMAKE_BINARY_DIR}/test" CACHE STRING "Install location of unit test") - - -# ---------------------------------------------------------------------------- -# Set Warning as Error -# ---------------------------------------------------------------------------- -option(WARNINGS_AS_ERRORS "Stop compiles on first warning" OFF) -if(WARNINGS_AS_ERRORS) - if(GCC) - add_definitions(-Werror) - elseif(MSVC) - add_definitions(/WX) - endif() -endif(WARNINGS_AS_ERRORS) - -# ---------------------------------------------------------------------------- -# Visual leak detector -# ---------------------------------------------------------------------------- -if (WIN32) - find_host_package(VLD QUIET) - if(VLD_FOUND) - add_definitions(-DHAVE_VLD) - include_directories(${VLD_INCLUDE_DIRS}) - set(PLATFORM_LIBS ${PLATFORM_LIBS} ${VLD_LIBRARIES}) - link_directories(${VLD_LIBRARY_DIRS}) - endif() - option(WINXP_SUPPORT "Make binaries compatible with Windows XP" OFF) - if(WINXP_SUPPORT) - # force use of workarounds for CONDITION_VARIABLE and atomic - # intrinsics introduced after XP - add_definitions(-D_WIN32_WINNT=_WIN32_WINNT_WINXP) - endif() -endif() - -# ---------------------------------------------------------------------------- -# look for stdint.h -# ---------------------------------------------------------------------------- -if(MSVC) - check_include_files(stdint.h HAVE_STDINT_H) - if(NOT HAVE_STDINT_H) - include_directories(osal/window) - endif(NOT HAVE_STDINT_H) -endif(MSVC) - -# ---------------------------------------------------------------------------- -# On window import win32 pthread library -# ---------------------------------------------------------------------------- -if(MSVC) - set(WIN32_PTHREAD_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/osal/window/pthread/inc") - include_directories(${WIN32_PTHREAD_INCLUDE_DIRS}) - add_library(pthread SHARED IMPORTED) - message(STATUS "platform X86 ${X86} X64 ${X64}") - set(WIN32_PTHREAD_LIB_DIRS "${CMAKE_SOURCE_DIR}/osal/window/pthread/lib") - set(WIN32_PTHREAD_DLL_DIRS "${CMAKE_SOURCE_DIR}/osal/window/pthread/dll") - if(X64) - set(WIN32_ARCH "x64") - else() - set(WIN32_ARCH "x86") - endif() - include_directories("${WIN32_PTHREAD_LIB_DIRS}/${WIN32_ARCH}") - include_directories("${WIN32_PTHREAD_DLL_DIRS}/${WIN32_ARCH}") - set_target_properties(pthread PROPERTIES - IMPORTED_LOCATION - "${WIN32_PTHREAD_LIB_DIRS}/${WIN32_ARCH}/pthreadVC2.dll") - set_target_properties(pthread PROPERTIES - IMPORTED_IMPLIB - "${WIN32_PTHREAD_LIB_DIRS}/${WIN32_ARCH}/pthreadVC2.lib") -endif() - -# ---------------------------------------------------------------------------- -# Share library option -# ---------------------------------------------------------------------------- -option(ENABLE_STATIC "Build shared library" ON) -option(ENABLE_SHARED "Build shared library" OFF) - -# ---------------------------------------------------------------------------- -# scan all LOG_TAG for log information and generate module header file -# ---------------------------------------------------------------------------- -set( module_list "" ) -file ( GLOB_RECURSE ALL_SRC . *.c;*.cpp ) -foreach( files ${ALL_SRC} ) - file( STRINGS ${files} module_tag_line REGEX "MODULE_TAG( )+\".+\"" ) - if(module_tag_line) - string( REGEX REPLACE "^(.)* MODULE_TAG( )+\"(.*)\"" \\3 module_tag ${module_tag_line} ) - list( APPEND module_list ${module_tag} ) - endif() -endforeach() -list( SORT module_list ) -list( LENGTH module_list module_size ) -#message(STATUS "module_list: ${module_list}") -#message(STATUS "module_size: ${module_size}") - -# ---------------------------------------------------------------------------- -# Start module definition -# ---------------------------------------------------------------------------- -# project overall include file -include_directories(inc) -# small utile functions for test case -include_directories(utils) - -# ---------------------------------------------------------------------------- -# osal library -# ---------------------------------------------------------------------------- -# Operation System Abstract Layer (OSAL) include -include_directories(osal/inc) -# OSAL is needed on all platform, do not need option -add_subdirectory(osal) - -# ---------------------------------------------------------------------------- -# utils for test case -# ---------------------------------------------------------------------------- -add_subdirectory(utils) - -# ---------------------------------------------------------------------------- -# Media Process Platform library -# ---------------------------------------------------------------------------- -# Media Process Platform include -include_directories(mpp/inc) -add_subdirectory(mpp) - -# ---------------------------------------------------------------------------- -# test / demo -# ---------------------------------------------------------------------------- -add_subdirectory(test) +# ---------------------------------------------------------------------------- +# Root CMake file for Rockchip Media Process Platform (MPP) +# +# - 10:34 2015/7/27: Initial version +# +# ---------------------------------------------------------------------------- + +# vim: syntax=cmake +if(NOT CMAKE_BUILD_TYPE) + # default to Release build for GCC builds + set(CMAKE_BUILD_TYPE Debug CACHE STRING + "Choose the type of build, options are: None(CMAKE_CXX_FLAGS or CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel." + FORCE) +endif() +message(STATUS "cmake version ${CMAKE_VERSION}") +if(NOT CMAKE_VERSION VERSION_LESS "2.8.12.20131121") + cmake_policy(SET CMP0025 OLD) # report Apple's Clang as just Clang + cmake_policy(SET CMP0042 OLD) # do not require MACOSX_RPATH +endif() + +# Search packages for host system instead of packages for target system +# in case of cross compilation these macro should be defined by toolchain file +if(NOT COMMAND find_host_package) + macro(find_host_package) + find_package(${ARGN}) + endmacro() +endif() +if(NOT COMMAND find_host_program) + macro(find_host_program) + find_program(${ARGN}) + endmacro() +endif() + +option(RKPLATFORM "Enable RK HW CONFIG" OFF) +if(${CMAKE_RKPLATFORM_ENABLE} MATCHES "ON") + option(RKPLATFORM "Enable RK HW CONFIG" ON) + set(RKPLATFORM True) + add_definitions(-DRKPLATFORM) +endif() + +project (rk_mpp) + +cmake_minimum_required (VERSION 2.8.8) # OBJECT libraries require 2.8.8 +include(CheckIncludeFiles) +include(CheckFunctionExists) +include(CheckSymbolExists) +include(CheckCXXCompilerFlag) + +# ---------------------------------------------------------------------------- +# set property to classify library kinds +# ---------------------------------------------------------------------------- +set_property(GLOBAL PROPERTY USE_FOLDERS ON) +set_property(GLOBAL PROPERTY PREDEFINED_TARGETS_FOLDER "CMakeTargets") +# ---------------------------------------------------------------------------- +# enable test in this project +# ---------------------------------------------------------------------------- +enable_testing() + +# ---------------------------------------------------------------------------- +# add debug define in project +# ---------------------------------------------------------------------------- +if(NOT $(CMAKE_BUILD_TYPE) MATCHES "Release") + option(RK_DEBUG "Enable run-time debug mode(debugging)" ON) + if(RK_DEBUG) + add_definitions(-DRK_DEBUG) + message(STATUS "rk_mpp debug mode is enabled") + endif() +endif() + +# ---------------------------------------------------------------------------- +# System architecture detection +# ---------------------------------------------------------------------------- +string(TOLOWER "${CMAKE_SYSTEM_PROCESSOR}" SYSPROC) +set(X86_ALIASES x86 i386 i686 x86_64 amd64) +list(FIND X86_ALIASES "${SYSPROC}" X86MATCH) +if("${SYSPROC}" STREQUAL "" OR X86MATCH GREATER "-1") + message(STATUS "Detected x86 system processor") + set(X86 true) + add_definitions(-DARCH_X86=1) + if("${CMAKE_SIZEOF_VOID_P}" MATCHES 8) + set(X64 true) + add_definitions(-DARCH_X64=1) + message(STATUS "Define X86_64 to 1") + endif() +elseif(${SYSPROC} STREQUAL "armv6l") + message(STATUS "Detected ARMv6 system processor") + set(ARM true) + set(ARMEABI_V6 true) + add_definitions(-DARCH_ARM=1 -DDHAVE_ARMV6=1) +elseif(${SYSPROC} STREQUAL "armv7-a") + message(STATUS "Detected ARMv7 system processor") + set(ARM true) + set(ARMEABI_V7A true) + add_definitions(-DARCH_ARM=1 -DDHAVE_ARMV7=1) +elseif(${SYSPROC} STREQUAL "armv7-a_hardfp") + message(STATUS "Detected ARMv7 system processor") + set(ARM true) + set(ARMEABI_V7A_HARDFP true) + add_definitions(-DARCH_ARM=1 -DDHAVE_ARMV7=1) +else() + message(STATUS "CMAKE_SYSTEM_PROCESSOR value `${CMAKE_SYSTEM_PROCESSOR}` is unknown") + message(STATUS "Please add this value near ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE}") +endif() + +if(UNIX) + SET(PLATFORM_LIBS pthread) + if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin") + SET(PLATFORM_LIBS ${PLATFORM_LIBS} rt) + endif() +endif(UNIX) + +# ---------------------------------------------------------------------------- +# Compiler detection +# ---------------------------------------------------------------------------- +if(CMAKE_GENERATOR STREQUAL "Xcode") + set(XCODE true) +endif() + +if (APPLE) + add_definitions(-DMACOS) +endif() + +if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") + set(CLANG true) +endif() +if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel") + set(INTEL_CXX true) +endif() +if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") + set(GCC true) +endif() + +if(INTEL_CXX AND WIN32) + # treat icl roughly like MSVC + set(MSVC true) +endif() +if(MSVC) + option(STATIC_LINK_CRT "Statically link C runtime for release builds" OFF) + if (STATIC_LINK_CRT) + set(CompilerFlags CMAKE_CXX_FLAGS_RELEASE CMAKE_C_FLAGS_RELEASE) + foreach(CompilerFlag ${CompilerFlags}) + string(REPLACE "/MD" "/MT" ${CompilerFlag} "${${CompilerFlag}}") + endforeach() + endif (STATIC_LINK_CRT) + add_definitions(/W3) # Full warnings + add_definitions(/Ob2) # always inline + add_definitions(/MP) # multithreaded build + # disable Microsofts suggestions for proprietary secure APIs + add_definitions(/D_CRT_SECURE_NO_WARNINGS) +endif(MSVC) + +if(INTEL_CXX AND UNIX) + # treat icpc roughly like gcc + set(GCC true) + add_definitions(-Wall -Wextra -Wshadow) +elseif(CLANG) + # treat clang roughly like gcc + set(GCC true) + add_definitions(-Wall -Wextra -Wshadow -ffast-math) +elseif(CMAKE_COMPILER_IS_GNUCXX) + add_definitions(-Wall -Wextra -Wshadow -ffast-math) + check_cxx_compiler_flag(-Wno-narrowing GCC_HAS_NO_NARROWING) + check_cxx_compiler_flag(-mstackrealign GCC_HAS_STACK_REALIGN) + if (GCC_HAS_STACK_REALIGN) + add_definitions(-mstackrealign) + endif() + execute_process(COMMAND ${CMAKE_CXX_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION) +endif() + +if(GCC) + if(ARM) + if(ARMEABI_V6) + add_definitions(-march=armv6 -mfloat-abi=hard -mfpu=vfp) + elseif(ARMEABI_V7A) + add_definitions(-march=armv7-a -mfloat-abi=softfp -mfpu=neon) + elseif(ARMEABI_V7A_HARDFP) + add_definitions(-march=armv7-a -mfloat-abi=hard -mfpu=neon) + endif() + else() + if(X64 AND NOT WIN32) + add_definitions(-fPIC) + endif(X64 AND NOT WIN32) + if(X86 AND NOT X64) + add_definitions(-march=i686) + endif() + endif() + + if(NOT $(CMAKE_BUILD_TYPE) MATCHES "Release") + set(CMAKE_C_VISIBILITY_PRESET hidden) + set(CMAKE_CXX_VISIBILITY_PRESET hidden) + endif() + + # disable multichar warning + add_definitions(-Wno-multichar) +endif(GCC) + +# ---------------------------------------------------------------------------- +# Create svn version information +# ---------------------------------------------------------------------------- +set(HAVE_SVN 0) +if(EXISTS "${PROJECT_SOURCE_DIR}/.svn/") + find_host_package(Subversion) + if(Subversion_FOUND) + set(HAVE_SVN true) + else() + if(WIN32) + # The official subversion client is not available, so fall back to + # tortoise if it is installed. + find_program(TORTOISE_WCREV_EXECUTABLE + NAMES SubWCRev.exe + PATHS "[HKEY_LOCAL_MACHINE\\SOFTWARE\\TortoiseSVN;Directory]/bin" + ) + + if (NOT TORTOISE_WCREV_EXECUTABLE) + message(STATUS "TortoiseSVN was not found.") + else(NOT TORTOISE_WCREV_EXECUTABLE) + message(STATUS "TortoiseSVN was Found.") + set(HAVE_SVN true) + + macro(Subversion_WC_INFO dir prefix) + # the subversion commands should be executed with the C locale, otherwise + # the message (which are parsed) may be translated, Alex + set(_Subversion_SAVED_LC_ALL "$ENV{LC_ALL}") + set(ENV{LC_ALL} C) + + execute_process(COMMAND ${TORTOISE_WCREV_EXECUTABLE} ${dir} + OUTPUT_VARIABLE ${prefix}_WC_INFO + ERROR_VARIABLE Subversion_svn_info_error + RESULT_VARIABLE Subversion_svn_info_result + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_STRIP_TRAILING_WHITESPACE) + + if(NOT ${Subversion_svn_info_result} EQUAL 0) + message(SEND_ERROR "Command \"${TORTOISE_WCREV_EXECUTABLE} ${dir}\" failed with output:\n${Subversion_svn_info_error}") + else() + string(REGEX REPLACE "^(.*\n)?Last committed at revision ([0-9]*)\n.*" + "\\2" ${prefix}_WC_REVISION "${${prefix}_WC_INFO}") + endif() + set(Project_WC_LAST_CHANGED_AUTHOR "unknown") + set(Project_WC_LAST_CHANGED_DATE "unknown") + + # restore the previous LC_ALL + set(ENV{LC_ALL} ${_Subversion_SAVED_LC_ALL}) + endmacro() + endif (NOT TORTOISE_WCREV_EXECUTABLE) + endif(WIN32) + endif(Subversion_FOUND) +endif(EXISTS "${PROJECT_SOURCE_DIR}/.svn/") + +if(${HAVE_SVN}) + Subversion_WC_INFO(${PROJECT_SOURCE_DIR} Project) + + message(STATUS "Current svn revision is ${Project_WC_REVISION}") + set(VERSION_REVISION ${Project_WC_REVISION}) + set(VERSION_LAST_AUTHOR ${Project_WC_LAST_CHANGED_AUTHOR}) + set(VERSION_LAST_DATA ${Project_WC_LAST_CHANGED_DATE}) + set(VERSION_ONE_LINE "${VERSION_REVISION} author: ${VERSION_LAST_AUTHOR} date: ${VERSION_LAST_DATA}") + set(VERSION_VER_NUM ${VERSION_REVISION}) +else() + set(VERSION_REVISION -1) +endif() + +# ---------------------------------------------------------------------------- +# Create git version information +# ---------------------------------------------------------------------------- +if(EXISTS "${PROJECT_SOURCE_DIR}/.git/") + find_package(Git) + if(GIT_FOUND) + # get author + execute_process(COMMAND ${GIT_EXECUTABLE} log -1 --format=%an + OUTPUT_VARIABLE EXEC_OUT + ERROR_VARIABLE EXEC_ERROR + RESULT_VARIABLE EXEC_RET + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_STRIP_TRAILING_WHITESPACE) + + if (NOT EXEC_RET) + message(STATUS "author: ${EXEC_OUT}") + set(VERSION_LAST_AUTHOR ${EXEC_OUT}) + endif() + + # get date + execute_process(COMMAND ${GIT_EXECUTABLE} log -1 --format=%ad + OUTPUT_VARIABLE EXEC_OUT + ERROR_VARIABLE EXEC_ERROR + RESULT_VARIABLE EXEC_RET + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_STRIP_TRAILING_WHITESPACE) + + if (NOT EXEC_RET) + message(STATUS "author: ${EXEC_OUT}") + set(VERSION_LAST_DATA ${EXEC_OUT}) + endif() + + # get version hash + execute_process(COMMAND ${GIT_EXECUTABLE} log -1 --format=%H + OUTPUT_VARIABLE EXEC_OUT + ERROR_VARIABLE EXEC_ERROR + RESULT_VARIABLE EXEC_RET + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_STRIP_TRAILING_WHITESPACE) + + if (NOT EXEC_RET) + set(VERSION_REVISION ${EXEC_OUT}) + endif() + + # get one line version information + execute_process(COMMAND ${GIT_EXECUTABLE} log -1 --pretty=format:"%h author: %an %s" + OUTPUT_VARIABLE EXEC_OUT + ERROR_VARIABLE EXEC_ERROR + RESULT_VARIABLE EXEC_RET + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_STRIP_TRAILING_WHITESPACE) + + if (NOT EXEC_RET) + message(STATUS "git version: ${EXEC_OUT}") + set(VERSION_ONE_LINE ${EXEC_OUT}) + string(REPLACE "\"" "" VERSION_ONE_LINE ${VERSION_ONE_LINE}) + endif() + + set(VERSION_VER_NUM -1) + endif() +endif(EXISTS "${PROJECT_SOURCE_DIR}/.git/") + +configure_file( + "${PROJECT_SOURCE_DIR}/build/cmake/version.in" + "${PROJECT_SOURCE_DIR}/mpp/version.h" +) + +# ---------------------------------------------------------------------------- +# Build options +# ---------------------------------------------------------------------------- +set(CMAKE_INSTALL_PREFIX "") +set(LIB_INSTALL_DIR "${CMAKE_SOURCE_DIR}/out/lib" CACHE STRING "Install location of libraries") +set(BIN_INSTALL_DIR "${CMAKE_SOURCE_DIR}/out/bin" CACHE STRING "Install location of executables") +set(TEST_INSTALL_DIR "${CMAKE_BINARY_DIR}/test" CACHE STRING "Install location of unit test") + + +# ---------------------------------------------------------------------------- +# Set Warning as Error +# ---------------------------------------------------------------------------- +option(WARNINGS_AS_ERRORS "Stop compiles on first warning" OFF) +if(WARNINGS_AS_ERRORS) + if(GCC) + add_definitions(-Werror) + elseif(MSVC) + add_definitions(/WX) + endif() +endif(WARNINGS_AS_ERRORS) + +# ---------------------------------------------------------------------------- +# Visual leak detector +# ---------------------------------------------------------------------------- +if (WIN32) + find_host_package(VLD QUIET) + if(VLD_FOUND) + add_definitions(-DHAVE_VLD) + include_directories(${VLD_INCLUDE_DIRS}) + set(PLATFORM_LIBS ${PLATFORM_LIBS} ${VLD_LIBRARIES}) + link_directories(${VLD_LIBRARY_DIRS}) + endif() + option(WINXP_SUPPORT "Make binaries compatible with Windows XP" OFF) + if(WINXP_SUPPORT) + # force use of workarounds for CONDITION_VARIABLE and atomic + # intrinsics introduced after XP + add_definitions(-D_WIN32_WINNT=_WIN32_WINNT_WINXP) + endif() +endif() + +# ---------------------------------------------------------------------------- +# look for stdint.h +# ---------------------------------------------------------------------------- +if(MSVC) + check_include_files(stdint.h HAVE_STDINT_H) + if(NOT HAVE_STDINT_H) + include_directories(osal/window) + endif(NOT HAVE_STDINT_H) +endif(MSVC) + +# ---------------------------------------------------------------------------- +# On window import win32 pthread library +# ---------------------------------------------------------------------------- +if(MSVC) + set(WIN32_PTHREAD_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/osal/window/pthread/inc") + include_directories(${WIN32_PTHREAD_INCLUDE_DIRS}) + add_library(pthread SHARED IMPORTED) + message(STATUS "platform X86 ${X86} X64 ${X64}") + set(WIN32_PTHREAD_LIB_DIRS "${CMAKE_SOURCE_DIR}/osal/window/pthread/lib") + set(WIN32_PTHREAD_DLL_DIRS "${CMAKE_SOURCE_DIR}/osal/window/pthread/dll") + if(X64) + set(WIN32_ARCH "x64") + else() + set(WIN32_ARCH "x86") + endif() + include_directories("${WIN32_PTHREAD_LIB_DIRS}/${WIN32_ARCH}") + include_directories("${WIN32_PTHREAD_DLL_DIRS}/${WIN32_ARCH}") + set_target_properties(pthread PROPERTIES + IMPORTED_LOCATION + "${WIN32_PTHREAD_LIB_DIRS}/${WIN32_ARCH}/pthreadVC2.dll") + set_target_properties(pthread PROPERTIES + IMPORTED_IMPLIB + "${WIN32_PTHREAD_LIB_DIRS}/${WIN32_ARCH}/pthreadVC2.lib") +endif() + +# ---------------------------------------------------------------------------- +# Share library option +# ---------------------------------------------------------------------------- +option(ENABLE_STATIC "Build shared library" ON) +option(ENABLE_SHARED "Build shared library" OFF) + +# ---------------------------------------------------------------------------- +# scan all LOG_TAG for log information and generate module header file +# ---------------------------------------------------------------------------- +set( module_list "" ) +file ( GLOB_RECURSE ALL_SRC . *.c;*.cpp ) +foreach( files ${ALL_SRC} ) + file( STRINGS ${files} module_tag_line REGEX "MODULE_TAG( )+\".+\"" ) + if(module_tag_line) + string( REGEX REPLACE "^(.)* MODULE_TAG( )+\"(.*)\"" \\3 module_tag ${module_tag_line} ) + list( APPEND module_list ${module_tag} ) + endif() +endforeach() +list( SORT module_list ) +list( LENGTH module_list module_size ) +#message(STATUS "module_list: ${module_list}") +#message(STATUS "module_size: ${module_size}") + +# ---------------------------------------------------------------------------- +# Start module definition +# ---------------------------------------------------------------------------- +# project overall include file +include_directories(inc) +# small utile functions for test case +include_directories(utils) + +# ---------------------------------------------------------------------------- +# osal library +# ---------------------------------------------------------------------------- +# Operation System Abstract Layer (OSAL) include +include_directories(osal/inc) +# OSAL is needed on all platform, do not need option +add_subdirectory(osal) + +# ---------------------------------------------------------------------------- +# utils for test case +# ---------------------------------------------------------------------------- +add_subdirectory(utils) + +# ---------------------------------------------------------------------------- +# Media Process Platform library +# ---------------------------------------------------------------------------- +# Media Process Platform include +include_directories(mpp/inc) +add_subdirectory(mpp) + +# ---------------------------------------------------------------------------- +# test / demo +# ---------------------------------------------------------------------------- +add_subdirectory(test) diff --git a/inc/mpp_buffer.h b/inc/mpp_buffer.h index a48982f9..ae77ed8f 100644 --- a/inc/mpp_buffer.h +++ b/inc/mpp_buffer.h @@ -1,282 +1,282 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __MPP_BUFFER_H__ -#define __MPP_BUFFER_H__ - -#include "rk_type.h" -#include "mpp_err.h" - -/* - * because buffer usage maybe unknown when decoder is not started - * buffer group may need to set a default group size limit - */ -#define SZ_1K (1024) -#define SZ_2K (SZ_1K*2) -#define SZ_4K (SZ_1K*4) -#define SZ_8K (SZ_1K*8) -#define SZ_16K (SZ_1K*16) -#define SZ_32K (SZ_1K*32) -#define SZ_64K (SZ_1K*64) -#define SZ_128K (SZ_1K*128) -#define SZ_256K (SZ_1K*256) -#define SZ_512K (SZ_1K*512) -#define SZ_1M (SZ_1K*SZ_1K) -#define SZ_2M (SZ_1M*2) -#define SZ_4M (SZ_1M*4) -#define SZ_8M (SZ_1M*8) -#define SZ_16M (SZ_1M*16) -#define SZ_32M (SZ_1M*32) -#define SZ_64M (SZ_1M*64) -#define SZ_80M (SZ_1M*80) -#define SZ_128M (SZ_1M*128) - -/* - * MppBuffer module has several functions: - * - * 1. buffer get / put / reference management / external commit / get info. - * this part is the basic user interface for MppBuffer. - * - * function: - * - * mpp_buffer_get - * mpp_buffer_put - * mpp_buffer_inc_ref - * mpp_buffer_commit - * mpp_buffer_info_get - * - * 2. user buffer working flow control abstraction. - * buffer should attach to certain group, and buffer mode control the buffer usage flow. - * this part is also a part of user interface. - * - * function: - * - * mpp_buffer_group_get - * mpp_buffer_group_normal_get - * mpp_buffer_group_limit_get - * mpp_buffer_group_put - * mpp_buffer_group_limit_config - * - * 3. buffer allocator management - * this part is for allocator on different os, it does not have user interface - * it will support normal buffer, Android ion buffer, Linux v4l2 vb2 buffer - * user can only use MppBufferType to choose. - * - */ -typedef void* MppBuffer; -typedef void* MppBufferGroup; - -/* - * mpp buffer group support two work flow mode: - * - * normal flow: all buffer are generated by MPP - * under this mode, buffer pool is maintained internally - * - * typical call flow: - * - * mpp_buffer_group_get() return A - * mpp_buffer_get(A) return a ref +1 -> used - * mpp_buffer_inc_ref(a) ref +1 - * mpp_buffer_put(a) ref -1 - * mpp_buffer_put(a) ref -1 -> unused - * mpp_buffer_group_put(A) - * - * commit flow: all buffer are commited out of MPP - * under this mode, buffers is commit by external api. - * normally MPP only use it but not generate it. - * - * typical call flow: - * - * ==== external allocator ==== - * mpp_buffer_group_get() return A - * mpp_buffer_commit(A, x) - * mpp_buffer_commit(A, y) - * - * ======= internal user ====== - * mpp_buffer_get(A) return a - * mpp_buffer_get(A) return b - * mpp_buffer_put(a) - * mpp_buffer_put(b) - * - * ==== external allocator ==== - * mpp_buffer_group_put(A) - * - * NOTE: commit interface required group handle to record group information - */ - -/* - * mpp buffer group has two buffer limit mode: normal and limit - * - * normal mode: allows any buffer size and always general new buffer is no unused buffer - * is available. - * This mode normally use with normal flow and is used for table / stream buffer - * - * limit mode : restrict the buffer's size and count in the buffer group. if try to calloc - * buffer with different size or extra count it will fail. - * This mode normally use with commit flow and is used for frame buffer - */ - -/* - * NOTE: normal mode is recommanded to work with normal flow, working with limit mode is not. - * limit mode is recommanded to work with commit flow, working with normal mode is not. - */ -typedef enum { - MPP_BUFFER_INTERNAL, - MPP_BUFFER_EXTERNAL, - MPP_BUFFER_MODE_BUTT, -} MppBufferMode; - -/* - * mpp buffer has two types: - * - * normal : normal malloc buffer for unit test or hardware simulation - * ion : use ion device under Android/Linux, MppBuffer will encapsulte ion file handle - */ -typedef enum { - MPP_BUFFER_TYPE_NORMAL, - MPP_BUFFER_TYPE_ION, - MPP_BUFFER_TYPE_V4L2, - MPP_BUFFER_TYPE_DRM, - MPP_BUFFER_TYPE_BUTT, -} MppBufferType; - -/* - * MppBufferInfo variable's meaning is different in different MppBufferType - * - * MPP_BUFFER_TYPE_NORMAL - * - * ptr - virtual address of normal malloced buffer - * fd - unused and set to -1 - * - * MPP_BUFFER_TYPE_ION - * - * ptr - virtual address of ion buffer in user space - * hnd - ion handle in user space - * fd - ion buffer file handle for map / unmap - * - * MPP_BUFFER_TYPE_V4L2 - * - * TODO: to be implemented. - */ -typedef struct MppBufferInfo_t { - MppBufferType type; - size_t size; - void *ptr; - void *hnd; - int fd; - int index; -} MppBufferInfo; - -#define BUFFER_GROUP_SIZE_DEFAULT (SZ_1M*80) - -/* - * mpp_buffer_import_with_tag(MppBufferGroup group, MppBufferInfo *info, MppBuffer *buffer) - * - * 1. group - specified the MppBuffer to be attached to. - * group can be NULL then this buffer will attached to default legecy group - * Default to NULL on mpp_buffer_import case - * - * 2. info - input information for the output MppBuffer - * info can NOT be NULL. It must contain at least one of ptr/fd. - * - * 3. buffer - generated MppBuffer from MppBufferInfo. - * buffer can be NULL then the buffer is commit to group with unused status. - * Otherwise generated buffer will be directly got and ref_count increased. - * Default to NULL on mpp_buffer_commit case - * - * mpp_buffer_commit usage: - * - * Add a external buffer info to group. This buffer will be on unused status. - * Typical usage is on Android. MediaPlayer gralloc Graphic buffer then commit these buffer - * to decoder's buffer group. Then decoder will recycle these buffer and return buffer reference - * to MediaPlayer for display. - * - * mpp_buffer_import usage: - * - * Transfer a external buffer info to MppBuffer but it is not expected to attached to certain - * buffer group. So the group is set to NULL. Then this buffer can be used for MppFrame/MppPacket. - * Typical usage is for image processing. Image processing normally will be a oneshot operation - * It does not need complicated group management. But in other hand mpp still need to know the - * imported buffer is leak or not and trace its usage inside mpp process. So we attach this kind - * of buffer to default misc buffer group for management. - */ -#define mpp_buffer_commit(group, info, ...) \ - mpp_buffer_import_with_tag(group, info, NULL, MODULE_TAG, __FUNCTION__) - -#define mpp_buffer_import(buffer, info, ...) \ - mpp_buffer_import_with_tag(NULL, info, buffer, MODULE_TAG, __FUNCTION__) - -#define mpp_buffer_get(group, buffer, size, ...) \ - mpp_buffer_get_with_tag(group, buffer, size, MODULE_TAG, __FUNCTION__) - -#define mpp_buffer_put(buffer) \ - mpp_buffer_put_with_caller(buffer, __FUNCTION__) - -#define mpp_buffer_inc_ref(buffer) \ - mpp_buffer_inc_ref_with_caller(buffer, __FUNCTION__); - -#define mpp_buffer_group_get_internal(group, type, ...) \ - mpp_buffer_group_get(group, type, MPP_BUFFER_INTERNAL, MODULE_TAG, __FUNCTION__) - -#define mpp_buffer_group_get_external(group, type, ...) \ - mpp_buffer_group_get(group, type, MPP_BUFFER_EXTERNAL, MODULE_TAG, __FUNCTION__) - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * MppBuffer interface - * these interface will change value of group and buffer so before calling functions - * parameter need to be checked. - * - * IMPORTANT: - * mpp_buffer_import_with_tag - compounded interface for commit and import - * - */ -MPP_RET mpp_buffer_import_with_tag(MppBufferGroup group, MppBufferInfo *info, MppBuffer *buffer, - const char *tag, const char *caller); -MPP_RET mpp_buffer_get_with_tag(MppBufferGroup group, MppBuffer *buffer, size_t size, - const char *tag, const char *caller); -MPP_RET mpp_buffer_put_with_caller(MppBuffer buffer, const char *caller); -MPP_RET mpp_buffer_inc_ref_with_caller(MppBuffer buffer, const char *caller); - -MPP_RET mpp_buffer_info_get(MppBuffer buffer, MppBufferInfo *info); -MPP_RET mpp_buffer_read(MppBuffer buffer, size_t offset, void *data, size_t size); -MPP_RET mpp_buffer_write(MppBuffer buffer, size_t offset, void *data, size_t size); -void *mpp_buffer_get_ptr(MppBuffer buffer); -int mpp_buffer_get_fd(MppBuffer buffer); -size_t mpp_buffer_get_size(MppBuffer buffer); - -MPP_RET mpp_buffer_group_get(MppBufferGroup *group, MppBufferType type, MppBufferMode mode, - const char *tag, const char *caller); -MPP_RET mpp_buffer_group_put(MppBufferGroup group); -MPP_RET mpp_buffer_group_clear(MppBufferGroup group); -RK_S32 mpp_buffer_group_unused(MppBufferGroup group); -MppBufferMode mpp_buffer_group_mode(MppBufferGroup group); -MppBufferType mpp_buffer_group_type(MppBufferGroup group); - -/* - * size : 0 - no limit, other - max buffer size - * count : 0 - no limit, other - max buffer count - */ -MPP_RET mpp_buffer_group_limit_config(MppBufferGroup group, size_t size, RK_S32 count); - -#ifdef __cplusplus -} -#endif - -#endif /*__MPP_BUFFER_H__*/ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPP_BUFFER_H__ +#define __MPP_BUFFER_H__ + +#include "rk_type.h" +#include "mpp_err.h" + +/* + * because buffer usage maybe unknown when decoder is not started + * buffer group may need to set a default group size limit + */ +#define SZ_1K (1024) +#define SZ_2K (SZ_1K*2) +#define SZ_4K (SZ_1K*4) +#define SZ_8K (SZ_1K*8) +#define SZ_16K (SZ_1K*16) +#define SZ_32K (SZ_1K*32) +#define SZ_64K (SZ_1K*64) +#define SZ_128K (SZ_1K*128) +#define SZ_256K (SZ_1K*256) +#define SZ_512K (SZ_1K*512) +#define SZ_1M (SZ_1K*SZ_1K) +#define SZ_2M (SZ_1M*2) +#define SZ_4M (SZ_1M*4) +#define SZ_8M (SZ_1M*8) +#define SZ_16M (SZ_1M*16) +#define SZ_32M (SZ_1M*32) +#define SZ_64M (SZ_1M*64) +#define SZ_80M (SZ_1M*80) +#define SZ_128M (SZ_1M*128) + +/* + * MppBuffer module has several functions: + * + * 1. buffer get / put / reference management / external commit / get info. + * this part is the basic user interface for MppBuffer. + * + * function: + * + * mpp_buffer_get + * mpp_buffer_put + * mpp_buffer_inc_ref + * mpp_buffer_commit + * mpp_buffer_info_get + * + * 2. user buffer working flow control abstraction. + * buffer should attach to certain group, and buffer mode control the buffer usage flow. + * this part is also a part of user interface. + * + * function: + * + * mpp_buffer_group_get + * mpp_buffer_group_normal_get + * mpp_buffer_group_limit_get + * mpp_buffer_group_put + * mpp_buffer_group_limit_config + * + * 3. buffer allocator management + * this part is for allocator on different os, it does not have user interface + * it will support normal buffer, Android ion buffer, Linux v4l2 vb2 buffer + * user can only use MppBufferType to choose. + * + */ +typedef void* MppBuffer; +typedef void* MppBufferGroup; + +/* + * mpp buffer group support two work flow mode: + * + * normal flow: all buffer are generated by MPP + * under this mode, buffer pool is maintained internally + * + * typical call flow: + * + * mpp_buffer_group_get() return A + * mpp_buffer_get(A) return a ref +1 -> used + * mpp_buffer_inc_ref(a) ref +1 + * mpp_buffer_put(a) ref -1 + * mpp_buffer_put(a) ref -1 -> unused + * mpp_buffer_group_put(A) + * + * commit flow: all buffer are commited out of MPP + * under this mode, buffers is commit by external api. + * normally MPP only use it but not generate it. + * + * typical call flow: + * + * ==== external allocator ==== + * mpp_buffer_group_get() return A + * mpp_buffer_commit(A, x) + * mpp_buffer_commit(A, y) + * + * ======= internal user ====== + * mpp_buffer_get(A) return a + * mpp_buffer_get(A) return b + * mpp_buffer_put(a) + * mpp_buffer_put(b) + * + * ==== external allocator ==== + * mpp_buffer_group_put(A) + * + * NOTE: commit interface required group handle to record group information + */ + +/* + * mpp buffer group has two buffer limit mode: normal and limit + * + * normal mode: allows any buffer size and always general new buffer is no unused buffer + * is available. + * This mode normally use with normal flow and is used for table / stream buffer + * + * limit mode : restrict the buffer's size and count in the buffer group. if try to calloc + * buffer with different size or extra count it will fail. + * This mode normally use with commit flow and is used for frame buffer + */ + +/* + * NOTE: normal mode is recommanded to work with normal flow, working with limit mode is not. + * limit mode is recommanded to work with commit flow, working with normal mode is not. + */ +typedef enum { + MPP_BUFFER_INTERNAL, + MPP_BUFFER_EXTERNAL, + MPP_BUFFER_MODE_BUTT, +} MppBufferMode; + +/* + * mpp buffer has two types: + * + * normal : normal malloc buffer for unit test or hardware simulation + * ion : use ion device under Android/Linux, MppBuffer will encapsulte ion file handle + */ +typedef enum { + MPP_BUFFER_TYPE_NORMAL, + MPP_BUFFER_TYPE_ION, + MPP_BUFFER_TYPE_V4L2, + MPP_BUFFER_TYPE_DRM, + MPP_BUFFER_TYPE_BUTT, +} MppBufferType; + +/* + * MppBufferInfo variable's meaning is different in different MppBufferType + * + * MPP_BUFFER_TYPE_NORMAL + * + * ptr - virtual address of normal malloced buffer + * fd - unused and set to -1 + * + * MPP_BUFFER_TYPE_ION + * + * ptr - virtual address of ion buffer in user space + * hnd - ion handle in user space + * fd - ion buffer file handle for map / unmap + * + * MPP_BUFFER_TYPE_V4L2 + * + * TODO: to be implemented. + */ +typedef struct MppBufferInfo_t { + MppBufferType type; + size_t size; + void *ptr; + void *hnd; + int fd; + int index; +} MppBufferInfo; + +#define BUFFER_GROUP_SIZE_DEFAULT (SZ_1M*80) + +/* + * mpp_buffer_import_with_tag(MppBufferGroup group, MppBufferInfo *info, MppBuffer *buffer) + * + * 1. group - specified the MppBuffer to be attached to. + * group can be NULL then this buffer will attached to default legecy group + * Default to NULL on mpp_buffer_import case + * + * 2. info - input information for the output MppBuffer + * info can NOT be NULL. It must contain at least one of ptr/fd. + * + * 3. buffer - generated MppBuffer from MppBufferInfo. + * buffer can be NULL then the buffer is commit to group with unused status. + * Otherwise generated buffer will be directly got and ref_count increased. + * Default to NULL on mpp_buffer_commit case + * + * mpp_buffer_commit usage: + * + * Add a external buffer info to group. This buffer will be on unused status. + * Typical usage is on Android. MediaPlayer gralloc Graphic buffer then commit these buffer + * to decoder's buffer group. Then decoder will recycle these buffer and return buffer reference + * to MediaPlayer for display. + * + * mpp_buffer_import usage: + * + * Transfer a external buffer info to MppBuffer but it is not expected to attached to certain + * buffer group. So the group is set to NULL. Then this buffer can be used for MppFrame/MppPacket. + * Typical usage is for image processing. Image processing normally will be a oneshot operation + * It does not need complicated group management. But in other hand mpp still need to know the + * imported buffer is leak or not and trace its usage inside mpp process. So we attach this kind + * of buffer to default misc buffer group for management. + */ +#define mpp_buffer_commit(group, info, ...) \ + mpp_buffer_import_with_tag(group, info, NULL, MODULE_TAG, __FUNCTION__) + +#define mpp_buffer_import(buffer, info, ...) \ + mpp_buffer_import_with_tag(NULL, info, buffer, MODULE_TAG, __FUNCTION__) + +#define mpp_buffer_get(group, buffer, size, ...) \ + mpp_buffer_get_with_tag(group, buffer, size, MODULE_TAG, __FUNCTION__) + +#define mpp_buffer_put(buffer) \ + mpp_buffer_put_with_caller(buffer, __FUNCTION__) + +#define mpp_buffer_inc_ref(buffer) \ + mpp_buffer_inc_ref_with_caller(buffer, __FUNCTION__); + +#define mpp_buffer_group_get_internal(group, type, ...) \ + mpp_buffer_group_get(group, type, MPP_BUFFER_INTERNAL, MODULE_TAG, __FUNCTION__) + +#define mpp_buffer_group_get_external(group, type, ...) \ + mpp_buffer_group_get(group, type, MPP_BUFFER_EXTERNAL, MODULE_TAG, __FUNCTION__) + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * MppBuffer interface + * these interface will change value of group and buffer so before calling functions + * parameter need to be checked. + * + * IMPORTANT: + * mpp_buffer_import_with_tag - compounded interface for commit and import + * + */ +MPP_RET mpp_buffer_import_with_tag(MppBufferGroup group, MppBufferInfo *info, MppBuffer *buffer, + const char *tag, const char *caller); +MPP_RET mpp_buffer_get_with_tag(MppBufferGroup group, MppBuffer *buffer, size_t size, + const char *tag, const char *caller); +MPP_RET mpp_buffer_put_with_caller(MppBuffer buffer, const char *caller); +MPP_RET mpp_buffer_inc_ref_with_caller(MppBuffer buffer, const char *caller); + +MPP_RET mpp_buffer_info_get(MppBuffer buffer, MppBufferInfo *info); +MPP_RET mpp_buffer_read(MppBuffer buffer, size_t offset, void *data, size_t size); +MPP_RET mpp_buffer_write(MppBuffer buffer, size_t offset, void *data, size_t size); +void *mpp_buffer_get_ptr(MppBuffer buffer); +int mpp_buffer_get_fd(MppBuffer buffer); +size_t mpp_buffer_get_size(MppBuffer buffer); + +MPP_RET mpp_buffer_group_get(MppBufferGroup *group, MppBufferType type, MppBufferMode mode, + const char *tag, const char *caller); +MPP_RET mpp_buffer_group_put(MppBufferGroup group); +MPP_RET mpp_buffer_group_clear(MppBufferGroup group); +RK_S32 mpp_buffer_group_unused(MppBufferGroup group); +MppBufferMode mpp_buffer_group_mode(MppBufferGroup group); +MppBufferType mpp_buffer_group_type(MppBufferGroup group); + +/* + * size : 0 - no limit, other - max buffer size + * count : 0 - no limit, other - max buffer count + */ +MPP_RET mpp_buffer_group_limit_config(MppBufferGroup group, size_t size, RK_S32 count); + +#ifdef __cplusplus +} +#endif + +#endif /*__MPP_BUFFER_H__*/ diff --git a/inc/mpp_err.h b/inc/mpp_err.h index f604174c..61841500 100644 --- a/inc/mpp_err.h +++ b/inc/mpp_err.h @@ -1,50 +1,50 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __MPP_ERR_H__ -#define __MPP_ERR_H__ - -#define RK_OK 0 -#define RK_SUCCESS 0 - -typedef enum { - MPP_SUCCESS = RK_SUCCESS, - MPP_OK = RK_OK, - - MPP_NOK = -1, - MPP_ERR_UNKNOW = -2, - MPP_ERR_NULL_PTR = -3, - MPP_ERR_MALLOC = -4, - MPP_ERR_OPEN_FILE = -5, - MPP_ERR_VALUE = -6, - MPP_ERR_READ_BIT = -7, - - MPP_ERR_BASE = -1000, - - MPP_ERR_LIST_STREAM = MPP_ERR_BASE - 1, - MPP_ERR_INIT = MPP_ERR_BASE - 2, - MPP_ERR_VPU_CODEC_INIT = MPP_ERR_BASE - 3, - MPP_ERR_STREAM = MPP_ERR_BASE - 4, - MPP_ERR_FATAL_THREAD = MPP_ERR_BASE - 5, - MPP_ERR_NOMEM = MPP_ERR_BASE - 6, - MPP_ERR_PROTOL = MPP_ERR_BASE - 7, - MPP_FAIL_SPLIT_FRAME = MPP_ERR_BASE - 8, - MPP_ERR_VPUHW = MPP_ERR_BASE - 9, - MPP_EOS_STREAM_REACHED = MPP_ERR_BASE - 11, - -} MPP_RET; - -#endif /*__MPP_ERR_H__*/ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPP_ERR_H__ +#define __MPP_ERR_H__ + +#define RK_OK 0 +#define RK_SUCCESS 0 + +typedef enum { + MPP_SUCCESS = RK_SUCCESS, + MPP_OK = RK_OK, + + MPP_NOK = -1, + MPP_ERR_UNKNOW = -2, + MPP_ERR_NULL_PTR = -3, + MPP_ERR_MALLOC = -4, + MPP_ERR_OPEN_FILE = -5, + MPP_ERR_VALUE = -6, + MPP_ERR_READ_BIT = -7, + + MPP_ERR_BASE = -1000, + + MPP_ERR_LIST_STREAM = MPP_ERR_BASE - 1, + MPP_ERR_INIT = MPP_ERR_BASE - 2, + MPP_ERR_VPU_CODEC_INIT = MPP_ERR_BASE - 3, + MPP_ERR_STREAM = MPP_ERR_BASE - 4, + MPP_ERR_FATAL_THREAD = MPP_ERR_BASE - 5, + MPP_ERR_NOMEM = MPP_ERR_BASE - 6, + MPP_ERR_PROTOL = MPP_ERR_BASE - 7, + MPP_FAIL_SPLIT_FRAME = MPP_ERR_BASE - 8, + MPP_ERR_VPUHW = MPP_ERR_BASE - 9, + MPP_EOS_STREAM_REACHED = MPP_ERR_BASE - 11, + +} MPP_RET; + +#endif /*__MPP_ERR_H__*/ diff --git a/inc/mpp_frame.h b/inc/mpp_frame.h index 17c08822..4d71b6b6 100644 --- a/inc/mpp_frame.h +++ b/inc/mpp_frame.h @@ -1,251 +1,251 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __MPP_FRAME_H__ -#define __MPP_FRAME_H__ - -#include "mpp_buffer.h" - -typedef void* MppFrame; - -/* - * bit definition for mode flag in MppFrame - */ -/* progressive frame */ -#define MPP_FRAME_FLAG_FRAME (0x00000000) -/* top field only */ -#define MPP_FRAME_FLAG_TOP_FIELD (0x00000001) -/* bottom field only */ -#define MPP_FRAME_FLAG_BOT_FIELD (0x00000002) -/* paired field */ -#define MPP_FRAME_FLAG_PAIRED_FIELD (MPP_FRAME_FLAG_TOP_FIELD|MPP_FRAME_FLAG_BOT_FIELD) -/* paired field with field order of top first */ -#define MPP_FRAME_FLAG_TOP_FIRST (0x00000004) -/* paired field with field order of bottom first */ -#define MPP_FRAME_FLAG_BOT_FIRST (0x00000008) -/* paired field with unknown field order (MBAFF) */ -#define MPP_FRAME_FLAG_DEINTERLACED (MPP_FRAME_FLAG_TOP_FIRST|MPP_FRAME_FLAG_BOT_FIRST) -#define MPP_FRAME_FLAG_FIELD_ORDER_MASK (0x0000000C) -// for multiview stream -#define MPP_FRAME_FLAG_VIEW_ID_MASK (0x000000f0) - - -/* - * MPEG vs JPEG YUV range. - */ -typedef enum { - MPP_FRAME_RANGE_UNSPECIFIED = 0, - MPP_FRAME_RANGE_MPEG = 1, ///< the normal 219*2^(n-8) "MPEG" YUV ranges - MPP_FRAME_RANGE_JPEG = 2, ///< the normal 2^n-1 "JPEG" YUV ranges - MPP_FRAME_RANGE_NB, ///< Not part of ABI -} MppFrameColorRange; - -/* - * Chromaticity coordinates of the source primaries. - */ -typedef enum { - MPP_FRAME_PRI_RESERVED0 = 0, - MPP_FRAME_PRI_BT709 = 1, ///< also ITU-R BT1361 / IEC 61966-2-4 / SMPTE RP177 Annex B - MPP_FRAME_PRI_UNSPECIFIED = 2, - MPP_FRAME_PRI_RESERVED = 3, - MPP_FRAME_PRI_BT470M = 4, ///< also FCC Title 47 Code of Federal Regulations 73.682 (a)(20) - - MPP_FRAME_PRI_BT470BG = 5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM - MPP_FRAME_PRI_SMPTE170M = 6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC - MPP_FRAME_PRI_SMPTE240M = 7, ///< functionally identical to above - MPP_FRAME_PRI_FILM = 8, ///< colour filters using Illuminant C - MPP_FRAME_PRI_BT2020 = 9, ///< ITU-R BT2020 - MPP_FRAME_PRI_NB, ///< Not part of ABI -} MppFrameColorPrimaries; - -/* - * Color Transfer Characteristic. - */ -typedef enum { - MPP_FRAME_TRC_RESERVED0 = 0, - MPP_FRAME_TRC_BT709 = 1, ///< also ITU-R BT1361 - MPP_FRAME_TRC_UNSPECIFIED = 2, - MPP_FRAME_TRC_RESERVED = 3, - MPP_FRAME_TRC_GAMMA22 = 4, ///< also ITU-R BT470M / ITU-R BT1700 625 PAL & SECAM - MPP_FRAME_TRC_GAMMA28 = 5, ///< also ITU-R BT470BG - MPP_FRAME_TRC_SMPTE170M = 6, ///< also ITU-R BT601-6 525 or 625 / ITU-R BT1358 525 or 625 / ITU-R BT1700 NTSC - MPP_FRAME_TRC_SMPTE240M = 7, - MPP_FRAME_TRC_LINEAR = 8, ///< "Linear transfer characteristics" - MPP_FRAME_TRC_LOG = 9, ///< "Logarithmic transfer characteristic (100:1 range)" - MPP_FRAME_TRC_LOG_SQRT = 10, ///< "Logarithmic transfer characteristic (100 * Sqrt(10) : 1 range)" - MPP_FRAME_TRC_IEC61966_2_4 = 11, ///< IEC 61966-2-4 - MPP_FRAME_TRC_BT1361_ECG = 12, ///< ITU-R BT1361 Extended Colour Gamut - MPP_FRAME_TRC_IEC61966_2_1 = 13, ///< IEC 61966-2-1 (sRGB or sYCC) - MPP_FRAME_TRC_BT2020_10 = 14, ///< ITU-R BT2020 for 10 bit system - MPP_FRAME_TRC_BT2020_12 = 15, ///< ITU-R BT2020 for 12 bit system - MPP_FRAME_TRC_NB, ///< Not part of ABI -} MppFrameColorTransferCharacteristic; - -/* - * YUV colorspace type. - */ -typedef enum { - MPP_FRAME_SPC_RGB = 0, ///< order of coefficients is actually GBR, also IEC 61966-2-1 (sRGB) - MPP_FRAME_SPC_BT709 = 1, ///< also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / SMPTE RP177 Annex B - MPP_FRAME_SPC_UNSPECIFIED = 2, - MPP_FRAME_SPC_RESERVED = 3, - MPP_FRAME_SPC_FCC = 4, ///< FCC Title 47 Code of Federal Regulations 73.682 (a)(20) - MPP_FRAME_SPC_BT470BG = 5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601 - MPP_FRAME_SPC_SMPTE170M = 6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC / functionally identical to above - MPP_FRAME_SPC_SMPTE240M = 7, - MPP_FRAME_SPC_YCOCG = 8, ///< Used by Dirac / VC-2 and H.264 FRext, see ITU-T SG16 - MPP_FRAME_SPC_BT2020_NCL = 9, ///< ITU-R BT2020 non-constant luminance system - MPP_FRAME_SPC_BT2020_CL = 10, ///< ITU-R BT2020 constant luminance system - MPP_FRAME_SPC_NB, ///< Not part of ABI -} MppFrameColorSpace; - -/* - * Location of chroma samples. - * - * Illustration showing the location of the first (top left) chroma sample of the - * image, the left shows only luma, the right - * shows the location of the chroma sample, the 2 could be imagined to overlay - * each other but are drawn separately due to limitations of ASCII - * - * 1st 2nd 1st 2nd horizontal luma sample positions - * v v v v - * ______ ______ - *1st luma line > |X X ... |3 4 X ... X are luma samples, - * | |1 2 1-6 are possible chroma positions - *2nd luma line > |X X ... |5 6 X ... 0 is undefined/unknown position - */ -typedef enum { - MPP_CHROMA_LOC_UNSPECIFIED = 0, - MPP_CHROMA_LOC_LEFT = 1, ///< mpeg2/4 4:2:0, h264 default for 4:2:0 - MPP_CHROMA_LOC_CENTER = 2, ///< mpeg1 4:2:0, jpeg 4:2:0, h263 4:2:0 - MPP_CHROMA_LOC_TOPLEFT = 3, ///< ITU-R 601, SMPTE 274M 296M S314M(DV 4:1:1), mpeg2 4:2:2 - MPP_CHROMA_LOC_TOP = 4, - MPP_CHROMA_LOC_BOTTOMLEFT = 5, - MPP_CHROMA_LOC_BOTTOM = 6, - MPP_CHROMA_LOC_NB, ///< Not part of ABI -} MppFrameChromaLocation; - -#define MPP_FRAME_FMT_MASK 0x000f0000 -#define MPP_FRAME_FMT_YUV 0x00000000 -#define MPP_FRAME_FMT_RGB 0x00010000 - -/* - *mpp color format define - */ -typedef enum { - MPP_FMT_YUV420SP = MPP_FRAME_FMT_YUV, /* YYYY... UVUVUV... */ - MPP_FMT_YUV420SP_10BIT, - MPP_FMT_YUV422SP, /* YYYY... UVUVUV... */ - MPP_FMT_YUV422SP_10BIT, ///< Not part of ABI - MPP_FMT_YUV420P, /* YYYY... UUUU... VVVV */ - MPP_FMT_YUV420SP_VU, /* YYYY... VUVUVU... */ - MPP_FMT_YUV422P, /* YYYY... UUUU... VVVV */ - MPP_FMT_YUV422SP_VU, /* YYYY... VUVUVU... */ - MPP_FMT_YUV422_YUYV, /* YUYVYUYV... */ - MPP_FMT_YUV422_UYVY, /* UYVYUYVY... */ - MPP_FMT_YUV_BUTT, - MPP_FMT_RGB565 = MPP_FRAME_FMT_RGB, /* 16-bit RGB */ - MPP_FMT_BGR565, /* 16-bit RGB */ - MPP_FMT_RGB555, /* 15-bit RGB */ - MPP_FMT_BGR555, /* 15-bit RGB */ - MPP_FMT_RGB444, /* 12-bit RGB */ - MPP_FMT_BGR444, /* 12-bit RGB */ - MPP_FMT_RGB888, /* 24-bit RGB */ - MPP_FMT_BGR888, /* 24-bit RGB */ - MPP_FMT_RGB101010, /* 30-bit RGB */ - MPP_FMT_BGR101010, /* 30-bit RGB */ - MPP_FMT_ARGB8888, /* 32-bit RGB */ - MPP_FMT_ABGR8888, /* 32-bit RGB */ - MPP_FMT_RGB_BUTT, - MPP_FMT_BUTT = MPP_FMT_RGB_BUTT, -} MppFrameFormat; - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * MppFrame interface - */ -MPP_RET mpp_frame_init(MppFrame *frame); -MPP_RET mpp_frame_deinit(MppFrame *frame); -MppFrame mpp_frame_get_next(MppFrame frame); - -/* - * normal parameter - */ -RK_U32 mpp_frame_get_width(const MppFrame frame); -void mpp_frame_set_width(MppFrame frame, RK_U32 width); -RK_U32 mpp_frame_get_height(const MppFrame frame); -void mpp_frame_set_height(MppFrame frame, RK_U32 height); -RK_U32 mpp_frame_get_hor_stride(const MppFrame frame); -void mpp_frame_set_hor_stride(MppFrame frame, RK_U32 hor_stride); -RK_U32 mpp_frame_get_ver_stride(const MppFrame frame); -void mpp_frame_set_ver_stride(MppFrame frame, RK_U32 ver_stride); -RK_U32 mpp_frame_get_mode(const MppFrame frame); -void mpp_frame_set_mode(MppFrame frame, RK_U32 mode); -RK_U32 mpp_frame_get_discard(const MppFrame frame); -void mpp_frame_set_discard(MppFrame frame, RK_U32 discard); -RK_U32 mpp_frame_get_viewid(const MppFrame frame); -void mpp_frame_set_viewid(MppFrame frame, RK_U32 viewid); -RK_U32 mpp_frame_get_poc(const MppFrame frame); -void mpp_frame_set_poc(MppFrame frame, RK_U32 poc); -RK_S64 mpp_frame_get_pts(const MppFrame frame); -void mpp_frame_set_pts(MppFrame frame, RK_S64 pts); -RK_S64 mpp_frame_get_dts(const MppFrame frame); -void mpp_frame_set_dts(MppFrame frame, RK_S64 dts); -RK_U32 mpp_frame_get_errinfo(const MppFrame frame); -void mpp_frame_set_errinfo(MppFrame frame, RK_U32 errinfo); -/* - * flow control parmeter - */ -RK_U32 mpp_frame_get_eos(const MppFrame frame); -void mpp_frame_set_eos(MppFrame frame, RK_U32 eos); -RK_U32 mpp_frame_get_info_change(const MppFrame frame); -void mpp_frame_set_info_change(MppFrame frame, RK_U32 info_change); - -/* - * buffer parameter - */ -MppBuffer mpp_frame_get_buffer(const MppFrame frame); -void mpp_frame_set_buffer(MppFrame frame, MppBuffer buffer); - -/* - * color related parameter - */ -MppFrameColorRange mpp_frame_get_color_range(const MppFrame frame); -void mpp_frame_set_color_range(MppFrame frame, MppFrameColorRange color_range); -MppFrameColorPrimaries mpp_frame_get_color_primaries(const MppFrame frame); -void mpp_frame_set_color_primaries(MppFrame frame, MppFrameColorPrimaries color_primaries); -MppFrameColorTransferCharacteristic mpp_frame_get_color_trc(const MppFrame frame); -void mpp_frame_set_color_trc(MppFrame frame, MppFrameColorTransferCharacteristic color_trc); -MppFrameColorSpace mpp_frame_get_colorspace(const MppFrame frame); -void mpp_frame_set_colorspace(MppFrame frame, MppFrameColorSpace colorspace); -MppFrameChromaLocation mpp_frame_get_chroma_location(const MppFrame frame); -void mpp_frame_set_chroma_location(MppFrame frame, MppFrameChromaLocation chroma_location); -MppFrameFormat mpp_frame_get_fmt(MppFrame frame); -void mpp_frame_set_fmt(MppFrame frame, MppFrameFormat fmt); - - -/* - * HDR parameter - */ - -#ifdef __cplusplus -} -#endif - -#endif /*__MPP_FRAME_H__*/ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPP_FRAME_H__ +#define __MPP_FRAME_H__ + +#include "mpp_buffer.h" + +typedef void* MppFrame; + +/* + * bit definition for mode flag in MppFrame + */ +/* progressive frame */ +#define MPP_FRAME_FLAG_FRAME (0x00000000) +/* top field only */ +#define MPP_FRAME_FLAG_TOP_FIELD (0x00000001) +/* bottom field only */ +#define MPP_FRAME_FLAG_BOT_FIELD (0x00000002) +/* paired field */ +#define MPP_FRAME_FLAG_PAIRED_FIELD (MPP_FRAME_FLAG_TOP_FIELD|MPP_FRAME_FLAG_BOT_FIELD) +/* paired field with field order of top first */ +#define MPP_FRAME_FLAG_TOP_FIRST (0x00000004) +/* paired field with field order of bottom first */ +#define MPP_FRAME_FLAG_BOT_FIRST (0x00000008) +/* paired field with unknown field order (MBAFF) */ +#define MPP_FRAME_FLAG_DEINTERLACED (MPP_FRAME_FLAG_TOP_FIRST|MPP_FRAME_FLAG_BOT_FIRST) +#define MPP_FRAME_FLAG_FIELD_ORDER_MASK (0x0000000C) +// for multiview stream +#define MPP_FRAME_FLAG_VIEW_ID_MASK (0x000000f0) + + +/* + * MPEG vs JPEG YUV range. + */ +typedef enum { + MPP_FRAME_RANGE_UNSPECIFIED = 0, + MPP_FRAME_RANGE_MPEG = 1, ///< the normal 219*2^(n-8) "MPEG" YUV ranges + MPP_FRAME_RANGE_JPEG = 2, ///< the normal 2^n-1 "JPEG" YUV ranges + MPP_FRAME_RANGE_NB, ///< Not part of ABI +} MppFrameColorRange; + +/* + * Chromaticity coordinates of the source primaries. + */ +typedef enum { + MPP_FRAME_PRI_RESERVED0 = 0, + MPP_FRAME_PRI_BT709 = 1, ///< also ITU-R BT1361 / IEC 61966-2-4 / SMPTE RP177 Annex B + MPP_FRAME_PRI_UNSPECIFIED = 2, + MPP_FRAME_PRI_RESERVED = 3, + MPP_FRAME_PRI_BT470M = 4, ///< also FCC Title 47 Code of Federal Regulations 73.682 (a)(20) + + MPP_FRAME_PRI_BT470BG = 5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM + MPP_FRAME_PRI_SMPTE170M = 6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC + MPP_FRAME_PRI_SMPTE240M = 7, ///< functionally identical to above + MPP_FRAME_PRI_FILM = 8, ///< colour filters using Illuminant C + MPP_FRAME_PRI_BT2020 = 9, ///< ITU-R BT2020 + MPP_FRAME_PRI_NB, ///< Not part of ABI +} MppFrameColorPrimaries; + +/* + * Color Transfer Characteristic. + */ +typedef enum { + MPP_FRAME_TRC_RESERVED0 = 0, + MPP_FRAME_TRC_BT709 = 1, ///< also ITU-R BT1361 + MPP_FRAME_TRC_UNSPECIFIED = 2, + MPP_FRAME_TRC_RESERVED = 3, + MPP_FRAME_TRC_GAMMA22 = 4, ///< also ITU-R BT470M / ITU-R BT1700 625 PAL & SECAM + MPP_FRAME_TRC_GAMMA28 = 5, ///< also ITU-R BT470BG + MPP_FRAME_TRC_SMPTE170M = 6, ///< also ITU-R BT601-6 525 or 625 / ITU-R BT1358 525 or 625 / ITU-R BT1700 NTSC + MPP_FRAME_TRC_SMPTE240M = 7, + MPP_FRAME_TRC_LINEAR = 8, ///< "Linear transfer characteristics" + MPP_FRAME_TRC_LOG = 9, ///< "Logarithmic transfer characteristic (100:1 range)" + MPP_FRAME_TRC_LOG_SQRT = 10, ///< "Logarithmic transfer characteristic (100 * Sqrt(10) : 1 range)" + MPP_FRAME_TRC_IEC61966_2_4 = 11, ///< IEC 61966-2-4 + MPP_FRAME_TRC_BT1361_ECG = 12, ///< ITU-R BT1361 Extended Colour Gamut + MPP_FRAME_TRC_IEC61966_2_1 = 13, ///< IEC 61966-2-1 (sRGB or sYCC) + MPP_FRAME_TRC_BT2020_10 = 14, ///< ITU-R BT2020 for 10 bit system + MPP_FRAME_TRC_BT2020_12 = 15, ///< ITU-R BT2020 for 12 bit system + MPP_FRAME_TRC_NB, ///< Not part of ABI +} MppFrameColorTransferCharacteristic; + +/* + * YUV colorspace type. + */ +typedef enum { + MPP_FRAME_SPC_RGB = 0, ///< order of coefficients is actually GBR, also IEC 61966-2-1 (sRGB) + MPP_FRAME_SPC_BT709 = 1, ///< also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / SMPTE RP177 Annex B + MPP_FRAME_SPC_UNSPECIFIED = 2, + MPP_FRAME_SPC_RESERVED = 3, + MPP_FRAME_SPC_FCC = 4, ///< FCC Title 47 Code of Federal Regulations 73.682 (a)(20) + MPP_FRAME_SPC_BT470BG = 5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601 + MPP_FRAME_SPC_SMPTE170M = 6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC / functionally identical to above + MPP_FRAME_SPC_SMPTE240M = 7, + MPP_FRAME_SPC_YCOCG = 8, ///< Used by Dirac / VC-2 and H.264 FRext, see ITU-T SG16 + MPP_FRAME_SPC_BT2020_NCL = 9, ///< ITU-R BT2020 non-constant luminance system + MPP_FRAME_SPC_BT2020_CL = 10, ///< ITU-R BT2020 constant luminance system + MPP_FRAME_SPC_NB, ///< Not part of ABI +} MppFrameColorSpace; + +/* + * Location of chroma samples. + * + * Illustration showing the location of the first (top left) chroma sample of the + * image, the left shows only luma, the right + * shows the location of the chroma sample, the 2 could be imagined to overlay + * each other but are drawn separately due to limitations of ASCII + * + * 1st 2nd 1st 2nd horizontal luma sample positions + * v v v v + * ______ ______ + *1st luma line > |X X ... |3 4 X ... X are luma samples, + * | |1 2 1-6 are possible chroma positions + *2nd luma line > |X X ... |5 6 X ... 0 is undefined/unknown position + */ +typedef enum { + MPP_CHROMA_LOC_UNSPECIFIED = 0, + MPP_CHROMA_LOC_LEFT = 1, ///< mpeg2/4 4:2:0, h264 default for 4:2:0 + MPP_CHROMA_LOC_CENTER = 2, ///< mpeg1 4:2:0, jpeg 4:2:0, h263 4:2:0 + MPP_CHROMA_LOC_TOPLEFT = 3, ///< ITU-R 601, SMPTE 274M 296M S314M(DV 4:1:1), mpeg2 4:2:2 + MPP_CHROMA_LOC_TOP = 4, + MPP_CHROMA_LOC_BOTTOMLEFT = 5, + MPP_CHROMA_LOC_BOTTOM = 6, + MPP_CHROMA_LOC_NB, ///< Not part of ABI +} MppFrameChromaLocation; + +#define MPP_FRAME_FMT_MASK 0x000f0000 +#define MPP_FRAME_FMT_YUV 0x00000000 +#define MPP_FRAME_FMT_RGB 0x00010000 + +/* + *mpp color format define + */ +typedef enum { + MPP_FMT_YUV420SP = MPP_FRAME_FMT_YUV, /* YYYY... UVUVUV... */ + MPP_FMT_YUV420SP_10BIT, + MPP_FMT_YUV422SP, /* YYYY... UVUVUV... */ + MPP_FMT_YUV422SP_10BIT, ///< Not part of ABI + MPP_FMT_YUV420P, /* YYYY... UUUU... VVVV */ + MPP_FMT_YUV420SP_VU, /* YYYY... VUVUVU... */ + MPP_FMT_YUV422P, /* YYYY... UUUU... VVVV */ + MPP_FMT_YUV422SP_VU, /* YYYY... VUVUVU... */ + MPP_FMT_YUV422_YUYV, /* YUYVYUYV... */ + MPP_FMT_YUV422_UYVY, /* UYVYUYVY... */ + MPP_FMT_YUV_BUTT, + MPP_FMT_RGB565 = MPP_FRAME_FMT_RGB, /* 16-bit RGB */ + MPP_FMT_BGR565, /* 16-bit RGB */ + MPP_FMT_RGB555, /* 15-bit RGB */ + MPP_FMT_BGR555, /* 15-bit RGB */ + MPP_FMT_RGB444, /* 12-bit RGB */ + MPP_FMT_BGR444, /* 12-bit RGB */ + MPP_FMT_RGB888, /* 24-bit RGB */ + MPP_FMT_BGR888, /* 24-bit RGB */ + MPP_FMT_RGB101010, /* 30-bit RGB */ + MPP_FMT_BGR101010, /* 30-bit RGB */ + MPP_FMT_ARGB8888, /* 32-bit RGB */ + MPP_FMT_ABGR8888, /* 32-bit RGB */ + MPP_FMT_RGB_BUTT, + MPP_FMT_BUTT = MPP_FMT_RGB_BUTT, +} MppFrameFormat; + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * MppFrame interface + */ +MPP_RET mpp_frame_init(MppFrame *frame); +MPP_RET mpp_frame_deinit(MppFrame *frame); +MppFrame mpp_frame_get_next(MppFrame frame); + +/* + * normal parameter + */ +RK_U32 mpp_frame_get_width(const MppFrame frame); +void mpp_frame_set_width(MppFrame frame, RK_U32 width); +RK_U32 mpp_frame_get_height(const MppFrame frame); +void mpp_frame_set_height(MppFrame frame, RK_U32 height); +RK_U32 mpp_frame_get_hor_stride(const MppFrame frame); +void mpp_frame_set_hor_stride(MppFrame frame, RK_U32 hor_stride); +RK_U32 mpp_frame_get_ver_stride(const MppFrame frame); +void mpp_frame_set_ver_stride(MppFrame frame, RK_U32 ver_stride); +RK_U32 mpp_frame_get_mode(const MppFrame frame); +void mpp_frame_set_mode(MppFrame frame, RK_U32 mode); +RK_U32 mpp_frame_get_discard(const MppFrame frame); +void mpp_frame_set_discard(MppFrame frame, RK_U32 discard); +RK_U32 mpp_frame_get_viewid(const MppFrame frame); +void mpp_frame_set_viewid(MppFrame frame, RK_U32 viewid); +RK_U32 mpp_frame_get_poc(const MppFrame frame); +void mpp_frame_set_poc(MppFrame frame, RK_U32 poc); +RK_S64 mpp_frame_get_pts(const MppFrame frame); +void mpp_frame_set_pts(MppFrame frame, RK_S64 pts); +RK_S64 mpp_frame_get_dts(const MppFrame frame); +void mpp_frame_set_dts(MppFrame frame, RK_S64 dts); +RK_U32 mpp_frame_get_errinfo(const MppFrame frame); +void mpp_frame_set_errinfo(MppFrame frame, RK_U32 errinfo); +/* + * flow control parmeter + */ +RK_U32 mpp_frame_get_eos(const MppFrame frame); +void mpp_frame_set_eos(MppFrame frame, RK_U32 eos); +RK_U32 mpp_frame_get_info_change(const MppFrame frame); +void mpp_frame_set_info_change(MppFrame frame, RK_U32 info_change); + +/* + * buffer parameter + */ +MppBuffer mpp_frame_get_buffer(const MppFrame frame); +void mpp_frame_set_buffer(MppFrame frame, MppBuffer buffer); + +/* + * color related parameter + */ +MppFrameColorRange mpp_frame_get_color_range(const MppFrame frame); +void mpp_frame_set_color_range(MppFrame frame, MppFrameColorRange color_range); +MppFrameColorPrimaries mpp_frame_get_color_primaries(const MppFrame frame); +void mpp_frame_set_color_primaries(MppFrame frame, MppFrameColorPrimaries color_primaries); +MppFrameColorTransferCharacteristic mpp_frame_get_color_trc(const MppFrame frame); +void mpp_frame_set_color_trc(MppFrame frame, MppFrameColorTransferCharacteristic color_trc); +MppFrameColorSpace mpp_frame_get_colorspace(const MppFrame frame); +void mpp_frame_set_colorspace(MppFrame frame, MppFrameColorSpace colorspace); +MppFrameChromaLocation mpp_frame_get_chroma_location(const MppFrame frame); +void mpp_frame_set_chroma_location(MppFrame frame, MppFrameChromaLocation chroma_location); +MppFrameFormat mpp_frame_get_fmt(MppFrame frame); +void mpp_frame_set_fmt(MppFrame frame, MppFrameFormat fmt); + + +/* + * HDR parameter + */ + +#ifdef __cplusplus +} +#endif + +#endif /*__MPP_FRAME_H__*/ diff --git a/inc/mpp_meta.h b/inc/mpp_meta.h index f703495c..a2b966b6 100644 --- a/inc/mpp_meta.h +++ b/inc/mpp_meta.h @@ -1,100 +1,100 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __MPP_META_H__ -#define __MPP_META_H__ - -#include -#include "rk_type.h" - -#include "mpp_frame.h" -#include "mpp_packet.h" - -/* - * Mpp Metadata definition - * - * Metadata is for information transmision in mpp. - * Mpp task will contain two meta data: - * - * 1. Data flow metadata - * This metadata contains information of input / output data flow. For example - * A. decoder input side task the input packet must be defined and output frame - * may not be defined. Then decoder will try malloc or use committed buffer to - * complete decoding. - * B. decoder output side task - * - * - * 2. Flow control metadata - * - */ -typedef enum MppMetaDataType_e { - /* - * mpp meta data of data flow - * reference counter will be used for these meta data type - */ - MPP_META_TYPE_FRAME = 'mfrm', - MPP_META_TYPE_PACKET = 'mpkt', - MPP_META_TYPE_BUFFER = 'mbuf', - - /* mpp meta data of normal data type */ - MPP_META_TYPE_S32 = 's32 ', - MPP_META_TYPE_S64 = 's64 ', - MPP_META_TYPE_PTR = 'ptr ', -} MppMetaType; - -typedef enum MppMetaKey_e { - MPP_META_KEY_INPUT_FRM = 'ifrm', - MPP_META_KEY_INPUT_PKT = 'ipkt', - MPP_META_KEY_OUTPUT_FRM = 'ofrm', - MPP_META_KEY_OUTPUT_PKT = 'opkt', - MPP_META_KEY_MOTION_INFO = 'mvif', /* output motion information for motion detection */ - - MPP_META_KEY_INPUT_BLOCK = 'iblk', - MPP_META_KEY_OUTPUT_BLOCK = 'oblk', - MPP_META_KEY_INPUT_IDR_REQ = 'iidr', /* input idr frame request flag */ - MPP_META_KEY_OUTPUT_INTRA = 'oidr', /* output intra frame indicator */ -} MppMetaKey; - -typedef void* MppMeta; - -#define mpp_meta_get(meta) mpp_meta_get_with_tag(meta, MODULE_TAG, __FUNCTION__) - -#ifdef __cplusplus -extern "C" { -#endif - -MPP_RET mpp_meta_get_with_tag(MppMeta *meta, const char *tag, const char *caller); -MPP_RET mpp_meta_put(MppMeta meta); - -MPP_RET mpp_meta_set_s32(MppMeta meta, MppMetaKey key, RK_S32 val); -MPP_RET mpp_meta_set_s64(MppMeta meta, MppMetaKey key, RK_S64 val); -MPP_RET mpp_meta_set_ptr(MppMeta meta, MppMetaKey key, void *val); -MPP_RET mpp_meta_get_s32(MppMeta meta, MppMetaKey key, RK_S32 *val); -MPP_RET mpp_meta_get_s64(MppMeta meta, MppMetaKey key, RK_S64 *val); -MPP_RET mpp_meta_get_ptr(MppMeta meta, MppMetaKey key, void **val); - -MPP_RET mpp_meta_set_frame (MppMeta meta, MppMetaKey key, MppFrame frame); -MPP_RET mpp_meta_set_packet(MppMeta meta, MppMetaKey key, MppPacket packet); -MPP_RET mpp_meta_set_buffer(MppMeta meta, MppMetaKey key, MppBuffer buffer); -MPP_RET mpp_meta_get_frame (MppMeta meta, MppMetaKey key, MppFrame *frame); -MPP_RET mpp_meta_get_packet(MppMeta meta, MppMetaKey key, MppPacket *packet); -MPP_RET mpp_meta_get_buffer(MppMeta meta, MppMetaKey key, MppBuffer *buffer); - -#ifdef __cplusplus -} -#endif - -#endif /*__MPP_META_H__*/ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPP_META_H__ +#define __MPP_META_H__ + +#include +#include "rk_type.h" + +#include "mpp_frame.h" +#include "mpp_packet.h" + +/* + * Mpp Metadata definition + * + * Metadata is for information transmision in mpp. + * Mpp task will contain two meta data: + * + * 1. Data flow metadata + * This metadata contains information of input / output data flow. For example + * A. decoder input side task the input packet must be defined and output frame + * may not be defined. Then decoder will try malloc or use committed buffer to + * complete decoding. + * B. decoder output side task + * + * + * 2. Flow control metadata + * + */ +typedef enum MppMetaDataType_e { + /* + * mpp meta data of data flow + * reference counter will be used for these meta data type + */ + MPP_META_TYPE_FRAME = 'mfrm', + MPP_META_TYPE_PACKET = 'mpkt', + MPP_META_TYPE_BUFFER = 'mbuf', + + /* mpp meta data of normal data type */ + MPP_META_TYPE_S32 = 's32 ', + MPP_META_TYPE_S64 = 's64 ', + MPP_META_TYPE_PTR = 'ptr ', +} MppMetaType; + +typedef enum MppMetaKey_e { + MPP_META_KEY_INPUT_FRM = 'ifrm', + MPP_META_KEY_INPUT_PKT = 'ipkt', + MPP_META_KEY_OUTPUT_FRM = 'ofrm', + MPP_META_KEY_OUTPUT_PKT = 'opkt', + MPP_META_KEY_MOTION_INFO = 'mvif', /* output motion information for motion detection */ + + MPP_META_KEY_INPUT_BLOCK = 'iblk', + MPP_META_KEY_OUTPUT_BLOCK = 'oblk', + MPP_META_KEY_INPUT_IDR_REQ = 'iidr', /* input idr frame request flag */ + MPP_META_KEY_OUTPUT_INTRA = 'oidr', /* output intra frame indicator */ +} MppMetaKey; + +typedef void* MppMeta; + +#define mpp_meta_get(meta) mpp_meta_get_with_tag(meta, MODULE_TAG, __FUNCTION__) + +#ifdef __cplusplus +extern "C" { +#endif + +MPP_RET mpp_meta_get_with_tag(MppMeta *meta, const char *tag, const char *caller); +MPP_RET mpp_meta_put(MppMeta meta); + +MPP_RET mpp_meta_set_s32(MppMeta meta, MppMetaKey key, RK_S32 val); +MPP_RET mpp_meta_set_s64(MppMeta meta, MppMetaKey key, RK_S64 val); +MPP_RET mpp_meta_set_ptr(MppMeta meta, MppMetaKey key, void *val); +MPP_RET mpp_meta_get_s32(MppMeta meta, MppMetaKey key, RK_S32 *val); +MPP_RET mpp_meta_get_s64(MppMeta meta, MppMetaKey key, RK_S64 *val); +MPP_RET mpp_meta_get_ptr(MppMeta meta, MppMetaKey key, void **val); + +MPP_RET mpp_meta_set_frame (MppMeta meta, MppMetaKey key, MppFrame frame); +MPP_RET mpp_meta_set_packet(MppMeta meta, MppMetaKey key, MppPacket packet); +MPP_RET mpp_meta_set_buffer(MppMeta meta, MppMetaKey key, MppBuffer buffer); +MPP_RET mpp_meta_get_frame (MppMeta meta, MppMetaKey key, MppFrame *frame); +MPP_RET mpp_meta_get_packet(MppMeta meta, MppMetaKey key, MppPacket *packet); +MPP_RET mpp_meta_get_buffer(MppMeta meta, MppMetaKey key, MppBuffer *buffer); + +#ifdef __cplusplus +} +#endif + +#endif /*__MPP_META_H__*/ diff --git a/inc/mpp_packet.h b/inc/mpp_packet.h index 30b17404..890aebc3 100644 --- a/inc/mpp_packet.h +++ b/inc/mpp_packet.h @@ -1,85 +1,85 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __MPP_PACKET_H__ -#define __MPP_PACKET_H__ - -#include "mpp_buffer.h" - -typedef void* MppPacket; - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * MppPacket interface - * - * mpp_packet_init = mpp_packet_new + mpp_packet_set_data + mpp_packet_set_size - * mpp_packet_copy_init = mpp_packet_init + memcpy - */ -MPP_RET mpp_packet_new(MppPacket *packet); -MPP_RET mpp_packet_init(MppPacket *packet, void *data, size_t size); -MPP_RET mpp_packet_init_with_buffer(MppPacket *packet, MppBuffer buffer); -MPP_RET mpp_packet_copy_init(MppPacket *packet, const MppPacket src); -MPP_RET mpp_packet_deinit(MppPacket *packet); - -/* - * data : ( R/W ) start address of the whole packet memory - * size : ( R/W ) total size of the whole packet memory - * pos : ( R/W ) current access position of the whole packet memory, used for buffer read/write - * length : ( R/W ) the rest length from current position to end of buffer - * NOTE: normally length is updated only by set_pos, - * so set length must be used carefully for special usage - */ -void mpp_packet_set_data(MppPacket packet, void *data); -void mpp_packet_set_size(MppPacket packet, size_t size); -void mpp_packet_set_pos(MppPacket packet, void *pos); -void mpp_packet_set_length(MppPacket packet, size_t size); - -void* mpp_packet_get_data(const MppPacket packet); -void* mpp_packet_get_pos(const MppPacket packet); -size_t mpp_packet_get_size(const MppPacket packet); -size_t mpp_packet_get_length(const MppPacket packet); - - -void mpp_packet_set_pts(MppPacket packet, RK_S64 pts); -RK_S64 mpp_packet_get_pts(const MppPacket packet); -void mpp_packet_set_dts(MppPacket packet, RK_S64 dts); -RK_S64 mpp_packet_get_dts(const MppPacket packet); - -void mpp_packet_set_flag(MppPacket packet, RK_U32 flag); -RK_U32 mpp_packet_get_flag(const MppPacket packet); - -MPP_RET mpp_packet_set_eos(MppPacket packet); -RK_U32 mpp_packet_get_eos(MppPacket packet); -MPP_RET mpp_packet_set_extra_data(MppPacket packet); - -void mpp_packet_set_buffer(MppPacket packet, MppBuffer buffer); -MppBuffer mpp_packet_get_buffer(const MppPacket packet); - -/* - * data access interface - */ -MPP_RET mpp_packet_read(MppPacket packet, size_t offset, void *data, size_t size); -MPP_RET mpp_packet_write(MppPacket packet, size_t offset, void *data, size_t size); - - -#ifdef __cplusplus -} -#endif - -#endif /*__MPP_PACKET_H__*/ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPP_PACKET_H__ +#define __MPP_PACKET_H__ + +#include "mpp_buffer.h" + +typedef void* MppPacket; + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * MppPacket interface + * + * mpp_packet_init = mpp_packet_new + mpp_packet_set_data + mpp_packet_set_size + * mpp_packet_copy_init = mpp_packet_init + memcpy + */ +MPP_RET mpp_packet_new(MppPacket *packet); +MPP_RET mpp_packet_init(MppPacket *packet, void *data, size_t size); +MPP_RET mpp_packet_init_with_buffer(MppPacket *packet, MppBuffer buffer); +MPP_RET mpp_packet_copy_init(MppPacket *packet, const MppPacket src); +MPP_RET mpp_packet_deinit(MppPacket *packet); + +/* + * data : ( R/W ) start address of the whole packet memory + * size : ( R/W ) total size of the whole packet memory + * pos : ( R/W ) current access position of the whole packet memory, used for buffer read/write + * length : ( R/W ) the rest length from current position to end of buffer + * NOTE: normally length is updated only by set_pos, + * so set length must be used carefully for special usage + */ +void mpp_packet_set_data(MppPacket packet, void *data); +void mpp_packet_set_size(MppPacket packet, size_t size); +void mpp_packet_set_pos(MppPacket packet, void *pos); +void mpp_packet_set_length(MppPacket packet, size_t size); + +void* mpp_packet_get_data(const MppPacket packet); +void* mpp_packet_get_pos(const MppPacket packet); +size_t mpp_packet_get_size(const MppPacket packet); +size_t mpp_packet_get_length(const MppPacket packet); + + +void mpp_packet_set_pts(MppPacket packet, RK_S64 pts); +RK_S64 mpp_packet_get_pts(const MppPacket packet); +void mpp_packet_set_dts(MppPacket packet, RK_S64 dts); +RK_S64 mpp_packet_get_dts(const MppPacket packet); + +void mpp_packet_set_flag(MppPacket packet, RK_U32 flag); +RK_U32 mpp_packet_get_flag(const MppPacket packet); + +MPP_RET mpp_packet_set_eos(MppPacket packet); +RK_U32 mpp_packet_get_eos(MppPacket packet); +MPP_RET mpp_packet_set_extra_data(MppPacket packet); + +void mpp_packet_set_buffer(MppPacket packet, MppBuffer buffer); +MppBuffer mpp_packet_get_buffer(const MppPacket packet); + +/* + * data access interface + */ +MPP_RET mpp_packet_read(MppPacket packet, size_t offset, void *data, size_t size); +MPP_RET mpp_packet_write(MppPacket packet, size_t offset, void *data, size_t size); + + +#ifdef __cplusplus +} +#endif + +#endif /*__MPP_PACKET_H__*/ diff --git a/inc/mpp_task.h b/inc/mpp_task.h index 2f02bca7..4fb83fb5 100644 --- a/inc/mpp_task.h +++ b/inc/mpp_task.h @@ -1,244 +1,244 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __MPP_TASK_H__ -#define __MPP_TASK_H__ - -#include "mpp_meta.h" - -/* - * Advanced task flow - * Advanced task flow introduces three concepts: port, task and item - * - * Port is from OpenMAX - * Port has two type: input port and output port which are all for data transaction. - * Port work like a queue. task will be dequeue from or enqueue to one port. - * On input side user will dequeue task from input port, setup task and enqueue task - * back to input port. - * On output side user will dequeue task from output port, get the information from - * and then enqueue task back to output port. - * - * Task indicates one transaction on the port. - * Task has two working mode: async mode and sync mode - * If mpp is work in sync mode on task enqueue function return the task has been done - * If mpp is work in async mode on task enqueue function return the task is just put - * on the task queue for process. - * Task can carry different items. Task just like a container of items - * - * Item indicates MppPacket or MppFrame which is contained in one task - */ - -/* - * One mpp task queue has two ports: input and output - * - * The whole picture is: - * Top layer mpp has two ports: mpp_input_port and mpp_output_port - * But internally these two ports belongs to two task queue. - * The mpp_input_port is the mpp_input_task_queue's input port. - * The mpp_output_port is the mpp_output_task_queue's output port. - * - * Each port uses its task queue to communication - */ -typedef enum { - MPP_PORT_INPUT, - MPP_PORT_OUTPUT, - MPP_PORT_BUTT, -} MppPortType; - -/* - * Advance task work flow mode: - ****************************************************************************** - * 1. async mode (default_val) - * - * mpp_init(type, coding, MPP_WORK_ASYNC) - * - * input thread - * a - dequeue(input, *task) - * b - task_set_item(packet/frame) - * c - enqueue(input, task) // when enqueue return the task is not done yet - * - * output thread - * a - dequeue(output, *task) - * b - task_get_item(frame/packet) - * c - enqueue(output, task) - ****************************************************************************** - * 2. sync mode - * - * mpp_init(type, coding, MPP_WORK_SYNC) - * - * a - dequeue(input, *task) - * b - task_set_item(packet/frame) - * c - enqueue(task) // when enqueue return the task is finished - ****************************************************************************** - */ -typedef enum { - MPP_TASK_ASYNC, - MPP_TASK_SYNC, - MPP_TASK_WORK_MODE_BUTT, -} MppTaskWorkMode; - -/* - * MppTask is descriptor of a task which send to mpp for process - * mpp can support different type of work mode, for example: - * - * decoder: - * - * 1. typical decoder mode: - * input - MppPacket (normal cpu buffer, need cpu copy) - * output - MppFrame (ion/drm buffer in external/internal mode) - * 2. secure decoder mode: - * input - MppPacket (externel ion/drm buffer, cpu can not access) - * output - MppFrame (ion/drm buffer in external/internal mode, cpu can not access) - * - * interface usage: - * - * typical flow - * input side: - * task_dequeue(ctx, PORT_INPUT, &task); - * task_put_item(task, MODE_INPUT, packet) - * task_enqueue(ctx, PORT_INPUT, task); - * output side: - * task_dequeue(ctx, PORT_OUTPUT, &task); - * task_get_item(task, MODE_OUTPUT, &frame) - * task_enqueue(ctx, PORT_OUTPUT, task); - * - * secure flow - * input side: - * task_dequeue(ctx, PORT_INPUT, &task); - * task_put_item(task, MODE_INPUT, packet) - * task_put_item(task, MODE_OUTPUT, frame) // buffer will be specified here - * task_enqueue(ctx, PORT_INPUT, task); - * output side: - * task_dequeue(ctx, PORT_OUTPUT, &task); - * task_get_item(task, MODE_OUTPUT, &frame) - * task_enqueue(ctx, PORT_OUTPUT, task); - * - * encoder: - * - * 1. typical encoder mode: - * input - MppFrame (ion/drm buffer in external mode) - * output - MppPacket (normal cpu buffer, need cpu copy) - * 2. user input encoder mode: - * input - MppFrame (normal cpu buffer, need to build hardware table for this buffer) - * output - MppPacket (normal cpu buffer, need cpu copy) - * 3. secure encoder mode: - * input - MppFrame (ion/drm buffer in external mode, cpu can not access) - * output - MppPacket (externel ion/drm buffer, cpu can not access) - * - * typical / user input flow - * input side: - * task_dequeue(ctx, PORT_INPUT, &task); - * task_put_item(task, MODE_INPUT, frame) - * task_enqueue(ctx, PORT_INPUT, task); - * output side: - * task_dequeue(ctx, PORT_OUTPUT, &task); - * task_get_item(task, MODE_OUTPUT, &packet) - * task_enqueue(ctx, PORT_OUTPUT, task); - * - * secure flow - * input side: - * task_dequeue(ctx, PORT_INPUT, &task); - * task_put_item(task, MODE_OUTPUT, packet) // buffer will be specified here - * task_put_item(task, MODE_INPUT, frame) - * task_enqueue(ctx, PORT_INPUT, task); - * output side: - * task_dequeue(ctx, PORT_OUTPUT, &task); - * task_get_item(task, MODE_OUTPUT, &packet) - * task_get_item(task, MODE_OUTPUT, &frame) - * task_enqueue(ctx, PORT_OUTPUT, task); - * - * NOTE: this flow can specify the output frame. User will setup both intput frame and output packet - * buffer at the input side. Then at output side when user gets a finished task user can get the output - * packet and corresponding released input frame. - * - * image processing - * - * 1. typical image process mode: - * input - MppFrame (ion/drm buffer in external mode) - * output - MppFrame (ion/drm buffer in external mode) - * - * typical / user input flow - * input side: - * task_dequeue(ctx, PORT_INPUT, &task); - * task_put_item(task, MODE_INPUT, frame) - * task_enqueue(ctx, PORT_INPUT, task); - * output side: - * task_dequeue(ctx, PORT_OUTPUT, &task); - * task_get_item(task, MODE_OUTPUT, &frame) - * task_enqueue(ctx, PORT_OUTPUT, task); - */ -/* NOTE: use index rather then handle to descripbe task */ -typedef void* MppTask; -typedef void* MppPort; -typedef void* MppTaskQueue; - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Mpp task queue function: - * - * mpp_task_queue_init - create task queue structure - * mpp_task_queue_deinit - destory task queue structure - * mpp_task_queue_get_port - return input or output port of task queue - * - * Typical work flow, task mpp_dec for example: - * - * 1. Mpp layer creates one task queue in order to connect mpp input and mpp_dec input. - * 2. Mpp layer setups the task count in task queue input port. - * 3. Get input port from the task queue and assign to mpp input as mpp_input_port. - * 4. Get output port from the task queue and assign to mpp_dec input as dec_input_port. - * 5. Let the loop start. - * a. mpi user will dequeue task from mpp_input_port. - * b. mpi user will setup task. - * c. mpi user will enqueue task back to mpp_input_port. - * d. task will automatically transfer to dec_input_port. - * e. mpp_dec will dequeue task from dec_input_port. - * f. mpp_dec will process task. - * g. mpp_dec will enqueue task back to dec_input_port. - * h. task will automatically transfer to mpp_input_port. - * 6. Stop the loop. All tasks must be return to input port with idle status. - * 6. Mpp layer destory the task queue. - */ -MPP_RET mpp_task_queue_init(MppTaskQueue *queue); -MPP_RET mpp_task_queue_setup(MppTaskQueue queue, RK_S32 task_count); -MPP_RET mpp_task_queue_deinit(MppTaskQueue queue); -MppPort mpp_task_queue_get_port(MppTaskQueue queue, MppPortType type); - -MPP_RET mpp_port_can_dequeue(MppPort port); -MPP_RET mpp_port_dequeue(MppPort port, MppTask *task); -MPP_RET mpp_port_enqueue(MppPort port, MppTask task); - -MPP_RET mpp_task_meta_set_s32(MppTask task, MppMetaKey key, RK_S32 val); -MPP_RET mpp_task_meta_set_s64(MppTask task, MppMetaKey key, RK_S64 val); -MPP_RET mpp_task_meta_set_ptr(MppTask task, MppMetaKey key, void *val); -MPP_RET mpp_task_meta_set_frame (MppTask task, MppMetaKey key, MppFrame frame); -MPP_RET mpp_task_meta_set_packet(MppTask task, MppMetaKey key, MppPacket packet); -MPP_RET mpp_task_meta_set_buffer(MppTask task, MppMetaKey key, MppBuffer buffer); - -MPP_RET mpp_task_meta_get_s32(MppTask task, MppMetaKey key, RK_S32 *val, RK_S32 default_val); -MPP_RET mpp_task_meta_get_s64(MppTask task, MppMetaKey key, RK_S64 *val, RK_S64 default_val); -MPP_RET mpp_task_meta_get_ptr(MppTask task, MppMetaKey key, void **val, void *default_val); -MPP_RET mpp_task_meta_get_frame (MppTask task, MppMetaKey key, MppFrame *frame); -MPP_RET mpp_task_meta_get_packet(MppTask task, MppMetaKey key, MppPacket *packet); -MPP_RET mpp_task_meta_get_buffer(MppTask task, MppMetaKey key, MppBuffer *buffer); - -#ifdef __cplusplus -} -#endif - -#endif /*__MPP_QUEUE_H__*/ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPP_TASK_H__ +#define __MPP_TASK_H__ + +#include "mpp_meta.h" + +/* + * Advanced task flow + * Advanced task flow introduces three concepts: port, task and item + * + * Port is from OpenMAX + * Port has two type: input port and output port which are all for data transaction. + * Port work like a queue. task will be dequeue from or enqueue to one port. + * On input side user will dequeue task from input port, setup task and enqueue task + * back to input port. + * On output side user will dequeue task from output port, get the information from + * and then enqueue task back to output port. + * + * Task indicates one transaction on the port. + * Task has two working mode: async mode and sync mode + * If mpp is work in sync mode on task enqueue function return the task has been done + * If mpp is work in async mode on task enqueue function return the task is just put + * on the task queue for process. + * Task can carry different items. Task just like a container of items + * + * Item indicates MppPacket or MppFrame which is contained in one task + */ + +/* + * One mpp task queue has two ports: input and output + * + * The whole picture is: + * Top layer mpp has two ports: mpp_input_port and mpp_output_port + * But internally these two ports belongs to two task queue. + * The mpp_input_port is the mpp_input_task_queue's input port. + * The mpp_output_port is the mpp_output_task_queue's output port. + * + * Each port uses its task queue to communication + */ +typedef enum { + MPP_PORT_INPUT, + MPP_PORT_OUTPUT, + MPP_PORT_BUTT, +} MppPortType; + +/* + * Advance task work flow mode: + ****************************************************************************** + * 1. async mode (default_val) + * + * mpp_init(type, coding, MPP_WORK_ASYNC) + * + * input thread + * a - dequeue(input, *task) + * b - task_set_item(packet/frame) + * c - enqueue(input, task) // when enqueue return the task is not done yet + * + * output thread + * a - dequeue(output, *task) + * b - task_get_item(frame/packet) + * c - enqueue(output, task) + ****************************************************************************** + * 2. sync mode + * + * mpp_init(type, coding, MPP_WORK_SYNC) + * + * a - dequeue(input, *task) + * b - task_set_item(packet/frame) + * c - enqueue(task) // when enqueue return the task is finished + ****************************************************************************** + */ +typedef enum { + MPP_TASK_ASYNC, + MPP_TASK_SYNC, + MPP_TASK_WORK_MODE_BUTT, +} MppTaskWorkMode; + +/* + * MppTask is descriptor of a task which send to mpp for process + * mpp can support different type of work mode, for example: + * + * decoder: + * + * 1. typical decoder mode: + * input - MppPacket (normal cpu buffer, need cpu copy) + * output - MppFrame (ion/drm buffer in external/internal mode) + * 2. secure decoder mode: + * input - MppPacket (externel ion/drm buffer, cpu can not access) + * output - MppFrame (ion/drm buffer in external/internal mode, cpu can not access) + * + * interface usage: + * + * typical flow + * input side: + * task_dequeue(ctx, PORT_INPUT, &task); + * task_put_item(task, MODE_INPUT, packet) + * task_enqueue(ctx, PORT_INPUT, task); + * output side: + * task_dequeue(ctx, PORT_OUTPUT, &task); + * task_get_item(task, MODE_OUTPUT, &frame) + * task_enqueue(ctx, PORT_OUTPUT, task); + * + * secure flow + * input side: + * task_dequeue(ctx, PORT_INPUT, &task); + * task_put_item(task, MODE_INPUT, packet) + * task_put_item(task, MODE_OUTPUT, frame) // buffer will be specified here + * task_enqueue(ctx, PORT_INPUT, task); + * output side: + * task_dequeue(ctx, PORT_OUTPUT, &task); + * task_get_item(task, MODE_OUTPUT, &frame) + * task_enqueue(ctx, PORT_OUTPUT, task); + * + * encoder: + * + * 1. typical encoder mode: + * input - MppFrame (ion/drm buffer in external mode) + * output - MppPacket (normal cpu buffer, need cpu copy) + * 2. user input encoder mode: + * input - MppFrame (normal cpu buffer, need to build hardware table for this buffer) + * output - MppPacket (normal cpu buffer, need cpu copy) + * 3. secure encoder mode: + * input - MppFrame (ion/drm buffer in external mode, cpu can not access) + * output - MppPacket (externel ion/drm buffer, cpu can not access) + * + * typical / user input flow + * input side: + * task_dequeue(ctx, PORT_INPUT, &task); + * task_put_item(task, MODE_INPUT, frame) + * task_enqueue(ctx, PORT_INPUT, task); + * output side: + * task_dequeue(ctx, PORT_OUTPUT, &task); + * task_get_item(task, MODE_OUTPUT, &packet) + * task_enqueue(ctx, PORT_OUTPUT, task); + * + * secure flow + * input side: + * task_dequeue(ctx, PORT_INPUT, &task); + * task_put_item(task, MODE_OUTPUT, packet) // buffer will be specified here + * task_put_item(task, MODE_INPUT, frame) + * task_enqueue(ctx, PORT_INPUT, task); + * output side: + * task_dequeue(ctx, PORT_OUTPUT, &task); + * task_get_item(task, MODE_OUTPUT, &packet) + * task_get_item(task, MODE_OUTPUT, &frame) + * task_enqueue(ctx, PORT_OUTPUT, task); + * + * NOTE: this flow can specify the output frame. User will setup both intput frame and output packet + * buffer at the input side. Then at output side when user gets a finished task user can get the output + * packet and corresponding released input frame. + * + * image processing + * + * 1. typical image process mode: + * input - MppFrame (ion/drm buffer in external mode) + * output - MppFrame (ion/drm buffer in external mode) + * + * typical / user input flow + * input side: + * task_dequeue(ctx, PORT_INPUT, &task); + * task_put_item(task, MODE_INPUT, frame) + * task_enqueue(ctx, PORT_INPUT, task); + * output side: + * task_dequeue(ctx, PORT_OUTPUT, &task); + * task_get_item(task, MODE_OUTPUT, &frame) + * task_enqueue(ctx, PORT_OUTPUT, task); + */ +/* NOTE: use index rather then handle to descripbe task */ +typedef void* MppTask; +typedef void* MppPort; +typedef void* MppTaskQueue; + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Mpp task queue function: + * + * mpp_task_queue_init - create task queue structure + * mpp_task_queue_deinit - destory task queue structure + * mpp_task_queue_get_port - return input or output port of task queue + * + * Typical work flow, task mpp_dec for example: + * + * 1. Mpp layer creates one task queue in order to connect mpp input and mpp_dec input. + * 2. Mpp layer setups the task count in task queue input port. + * 3. Get input port from the task queue and assign to mpp input as mpp_input_port. + * 4. Get output port from the task queue and assign to mpp_dec input as dec_input_port. + * 5. Let the loop start. + * a. mpi user will dequeue task from mpp_input_port. + * b. mpi user will setup task. + * c. mpi user will enqueue task back to mpp_input_port. + * d. task will automatically transfer to dec_input_port. + * e. mpp_dec will dequeue task from dec_input_port. + * f. mpp_dec will process task. + * g. mpp_dec will enqueue task back to dec_input_port. + * h. task will automatically transfer to mpp_input_port. + * 6. Stop the loop. All tasks must be return to input port with idle status. + * 6. Mpp layer destory the task queue. + */ +MPP_RET mpp_task_queue_init(MppTaskQueue *queue); +MPP_RET mpp_task_queue_setup(MppTaskQueue queue, RK_S32 task_count); +MPP_RET mpp_task_queue_deinit(MppTaskQueue queue); +MppPort mpp_task_queue_get_port(MppTaskQueue queue, MppPortType type); + +MPP_RET mpp_port_can_dequeue(MppPort port); +MPP_RET mpp_port_dequeue(MppPort port, MppTask *task); +MPP_RET mpp_port_enqueue(MppPort port, MppTask task); + +MPP_RET mpp_task_meta_set_s32(MppTask task, MppMetaKey key, RK_S32 val); +MPP_RET mpp_task_meta_set_s64(MppTask task, MppMetaKey key, RK_S64 val); +MPP_RET mpp_task_meta_set_ptr(MppTask task, MppMetaKey key, void *val); +MPP_RET mpp_task_meta_set_frame (MppTask task, MppMetaKey key, MppFrame frame); +MPP_RET mpp_task_meta_set_packet(MppTask task, MppMetaKey key, MppPacket packet); +MPP_RET mpp_task_meta_set_buffer(MppTask task, MppMetaKey key, MppBuffer buffer); + +MPP_RET mpp_task_meta_get_s32(MppTask task, MppMetaKey key, RK_S32 *val, RK_S32 default_val); +MPP_RET mpp_task_meta_get_s64(MppTask task, MppMetaKey key, RK_S64 *val, RK_S64 default_val); +MPP_RET mpp_task_meta_get_ptr(MppTask task, MppMetaKey key, void **val, void *default_val); +MPP_RET mpp_task_meta_get_frame (MppTask task, MppMetaKey key, MppFrame *frame); +MPP_RET mpp_task_meta_get_packet(MppTask task, MppMetaKey key, MppPacket *packet); +MPP_RET mpp_task_meta_get_buffer(MppTask task, MppMetaKey key, MppBuffer *buffer); + +#ifdef __cplusplus +} +#endif + +#endif /*__MPP_QUEUE_H__*/ diff --git a/inc/rk_mpi.h b/inc/rk_mpi.h index 66dcbcdc..769c4482 100644 --- a/inc/rk_mpi.h +++ b/inc/rk_mpi.h @@ -1,278 +1,278 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __RK_MPI_H__ -#define __RK_MPI_H__ - -#include "mpp_task.h" - -typedef enum { - MPP_CTX_DEC, - MPP_CTX_ENC, - MPP_CTX_ISP, - MPP_CTX_BUTT, -} MppCtxType; - -/** - * Enumeration used to define the possible video compression codings. - * NOTE: This essentially refers to file extensions. If the coding is - * being used to specify the ENCODE type, then additional work - * must be done to configure the exact flavor of the compression - * to be used. For decode cases where the user application can - * not differentiate between MPEG-4 and H.264 bit streams, it is - * up to the codec to handle this. - */ -//sync with the omx_video.h -typedef enum { - MPP_VIDEO_CodingUnused, /**< Value when coding is N/A */ - MPP_VIDEO_CodingAutoDetect, /**< Autodetection of coding type */ - MPP_VIDEO_CodingMPEG2, /**< AKA: H.262 */ - MPP_VIDEO_CodingH263, /**< H.263 */ - MPP_VIDEO_CodingMPEG4, /**< MPEG-4 */ - MPP_VIDEO_CodingWMV, /**< Windows Media Video (WMV1,WMV2,WMV3)*/ - MPP_VIDEO_CodingRV, /**< all versions of Real Video */ - MPP_VIDEO_CodingAVC, /**< H.264/AVC */ - MPP_VIDEO_CodingMJPEG, /**< Motion JPEG */ - MPP_VIDEO_CodingVP8, /**< VP8 */ - MPP_VIDEO_CodingVP9, /**< VP9 */ - MPP_VIDEO_CodingVC1 = 0x01000000, /**< Windows Media Video (WMV1,WMV2,WMV3)*/ - MPP_VIDEO_CodingFLV1, /**< Sorenson H.263 */ - MPP_VIDEO_CodingDIVX3, /**< DIVX3 */ - MPP_VIDEO_CodingVP6, - MPP_VIDEO_CodingHEVC, /**< H.265/HEVC */ - MPP_VIDEO_CodingAVS, /**< AVS+ */ - MPP_VIDEO_CodingKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - MPP_VIDEO_CodingVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - MPP_VIDEO_CodingMax = 0x7FFFFFFF -} MppCodingType; - -/* - * Command id bit usage is defined as follows: - * bit 20 - 23 - module id - * bit 16 - 19 - contex id - * bit 0 - 15 - command id - */ -#define CMD_MODULE_ID_MASK (0x00F00000) -#define CMD_MODULE_OSAL (0x00100000) -#define CMD_MODULE_MPP (0x00200000) -#define CMD_MODULE_CODEC (0x00300000) -#define CMD_MODULE_HAL (0x00400000) -#define CMD_CTX_ID_MASK (0x000F0000) -#define CMD_CTX_ID_DEC (0x00010000) -#define CMD_CTX_ID_ENC (0x00020000) -#define CMD_CTX_ID_ISP (0x00030000) -#define CMD_ID_MASK (0x0000FFFF) - -typedef enum { - MPP_OSAL_CMD_BASE = CMD_MODULE_OSAL, - MPP_OSAL_CMD_END, - - MPP_CMD_BASE = CMD_MODULE_MPP, - MPP_ENABLE_DEINTERLACE, - MPP_SET_INPUT_BLOCK, - MPP_SET_OUTPUT_BLOCK, - MPP_CMD_END, - - MPP_CODEC_CMD_BASE = CMD_MODULE_CODEC, - MPP_CODEC_GET_FRAME_INFO, - MPP_CODEC_CMD_END, - - MPP_DEC_CMD_BASE = CMD_MODULE_CODEC | CMD_CTX_ID_DEC, - MPP_DEC_SET_FRAME_INFO, /* vpu api legacy control for buffer slot dimension init */ - MPP_DEC_SET_EXT_BUF_GROUP, /* IMPORTANT: set external buffer group to mpp decoder */ - MPP_DEC_SET_INFO_CHANGE_READY, - MPP_DEC_SET_INTERNAL_PTS_ENABLE, - MPP_DEC_SET_PARSER_SPLIT_MODE, /* Need to setup before init */ - MPP_DEC_SET_PARSER_FAST_MODE, /* Need to setup before init */ - MPP_DEC_GET_STREAM_COUNT, - MPP_DEC_GET_VPUMEM_USED_COUNT, - MPP_DEC_SET_VC1_EXTRA_DATA, - MPP_DEC_SET_OUTPUT_FORMAT, - MPP_DEC_CMD_END, - - MPP_ENC_CMD_BASE = CMD_MODULE_CODEC | CMD_CTX_ID_ENC, - MPP_ENC_SET_CFG, - MPP_ENC_GET_CFG, - MPP_ENC_SET_EXTRA_INFO, - MPP_ENC_GET_EXTRA_INFO, - MPP_ENC_SET_FORMAT, - MPP_ENC_SET_IDR_FRAME, - MPP_ENC_CMD_END, - - MPP_ISP_CMD_BASE = CMD_MODULE_CODEC | CMD_CTX_ID_ISP, - MPP_ISP_CMD_END, - - MPP_HAL_CMD_BASE = CMD_MODULE_HAL, - MPP_HAL_CMD_END, - - MPI_CMD_BUTT, -} MpiCmd; - -typedef void* MppCtx; -typedef void* MppParam; - -/* - * in decoder mode application need to specify the coding type first - * send a stream header to mpi ctx using parameter data / size - * and decoder will try to decode the - */ -typedef struct MppEncConfig_t { - /* encoder config also need to know size of itself */ - RK_U32 size; - RK_U32 version; - - /* - * input source data format - */ - RK_S32 width; - RK_S32 height; - RK_S32 hor_stride; - RK_S32 ver_stride; - RK_S32 format; - - /* - * Encoder does not support scaling and output data only support yuv420 so far - */ - - /* - * rate control parameter - * - * rc_mode - rate control mode - * 0 - fix qp mode - * 1 - constant bit rate mode (CBR) - * 2 - variable bit rate mode (VBR) - * skip_cnt - max continuous frame skip count - * 0 - frame skip is not allow - * bps - target bit rate, unit: bit per second - * fps_in - input frame rate, unit: frame per second - * if 0 then default set to 30 - * fps_out - output frame rate, unit: frame per second - * if 0 then default set to fps_in - * qp - constant qp for fix qp mode - * initial qp for CBR / VBR - * gop - gap between Intra frame - * 0 for only 1 I frame the rest are all P frames - * 1 for all I frame - * 2 for I P I P I P - * 3 for I P P I P P - * etc... - */ - RK_S32 rc_mode; - RK_S32 skip_cnt; - RK_S32 bps; - RK_S32 fps_in; - RK_S32 fps_out; - RK_S32 qp; - RK_S32 gop; - - /* - * stream feature parameter - */ - RK_S32 profile; - RK_S32 level; - RK_S32 cabac_en; -} MppEncConfig; - -/* - * mpp main work function set - * size : MppApi structure size - * version : Mpp svn revision - * - * all api function are seperated into two sets: data io api set and control api set - * - * the data api set is for data input/output flow including: - * - * simple data api set: - * - * decode : both send video stream packet to decoder and get video frame from - * decoder at the same time. - * encode : both send video frame to encoder and get encoded video stream from - * encoder at the same time. - * - * decode_put_packet: send video stream packet to decoder only, async interface - * decode_get_frame : get video frame from decoder only, async interface - * - * encode_put_frame : send video frame to encoder only, async interface - * encode_get_packet: get encoded video packet from encoder only, async interface - * - * advance task api set: - * - * - * the control api set is for mpp context control including: - * control : similiar to ioctl in kernel driver, setup or get mpp internal parameter - * reset : clear all data in mpp context, reset to initialized status - * the simple api set is for simple codec usage including: - * - * - * reset : discard all packet and frame, reset all component, - * for both decoder and encoder - * control : control function for mpp property setting - */ -typedef struct MppApi_t { - RK_U32 size; - RK_U32 version; - - // simple data flow interface - MPP_RET (*decode)(MppCtx ctx, MppPacket packet, MppFrame *frame); - MPP_RET (*decode_put_packet)(MppCtx ctx, MppPacket packet); - MPP_RET (*decode_get_frame)(MppCtx ctx, MppFrame *frame); - - MPP_RET (*encode)(MppCtx ctx, MppFrame frame, MppPacket *packet); - MPP_RET (*encode_put_frame)(MppCtx ctx, MppFrame frame); - MPP_RET (*encode_get_packet)(MppCtx ctx, MppPacket *packet); - - MPP_RET (*isp)(MppCtx ctx, MppFrame dst, MppFrame src); - MPP_RET (*isp_put_frame)(MppCtx ctx, MppFrame frame); - MPP_RET (*isp_get_frame)(MppCtx ctx, MppFrame *frame); - - // advance data flow interface - MPP_RET (*dequeue)(MppCtx ctx, MppPortType type, MppTask *task); - MPP_RET (*enqueue)(MppCtx ctx, MppPortType type, MppTask task); - - // control interface - MPP_RET (*reset)(MppCtx ctx); - MPP_RET (*control)(MppCtx ctx, MpiCmd cmd, MppParam param); - - RK_U32 reserv[16]; -} MppApi; - - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * mpp interface work flow - * - * 1. mpp_create : Create empty context structure and mpi function pointers. - * 2. mpp_init : Call after mpp_create to setup mpp type and video format. - * This function will call internal context init function. - * 3. Use functions in MppApi to access mpp services. - * 4. mpp_destory: Destroy mpp context and free both context and mpi structure - */ -MPP_RET mpp_create(MppCtx *ctx, MppApi **mpi); -MPP_RET mpp_init(MppCtx ctx, MppCtxType type, MppCodingType coding); -MPP_RET mpp_destroy(MppCtx ctx); - -// coding type format function -MPP_RET mpp_check_support_format(MppCtxType type, MppCodingType coding); -void mpp_show_support_format(); - -#ifdef __cplusplus -} -#endif - -#endif /*__RK_MPI_H__*/ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __RK_MPI_H__ +#define __RK_MPI_H__ + +#include "mpp_task.h" + +typedef enum { + MPP_CTX_DEC, + MPP_CTX_ENC, + MPP_CTX_ISP, + MPP_CTX_BUTT, +} MppCtxType; + +/** + * Enumeration used to define the possible video compression codings. + * NOTE: This essentially refers to file extensions. If the coding is + * being used to specify the ENCODE type, then additional work + * must be done to configure the exact flavor of the compression + * to be used. For decode cases where the user application can + * not differentiate between MPEG-4 and H.264 bit streams, it is + * up to the codec to handle this. + */ +//sync with the omx_video.h +typedef enum { + MPP_VIDEO_CodingUnused, /**< Value when coding is N/A */ + MPP_VIDEO_CodingAutoDetect, /**< Autodetection of coding type */ + MPP_VIDEO_CodingMPEG2, /**< AKA: H.262 */ + MPP_VIDEO_CodingH263, /**< H.263 */ + MPP_VIDEO_CodingMPEG4, /**< MPEG-4 */ + MPP_VIDEO_CodingWMV, /**< Windows Media Video (WMV1,WMV2,WMV3)*/ + MPP_VIDEO_CodingRV, /**< all versions of Real Video */ + MPP_VIDEO_CodingAVC, /**< H.264/AVC */ + MPP_VIDEO_CodingMJPEG, /**< Motion JPEG */ + MPP_VIDEO_CodingVP8, /**< VP8 */ + MPP_VIDEO_CodingVP9, /**< VP9 */ + MPP_VIDEO_CodingVC1 = 0x01000000, /**< Windows Media Video (WMV1,WMV2,WMV3)*/ + MPP_VIDEO_CodingFLV1, /**< Sorenson H.263 */ + MPP_VIDEO_CodingDIVX3, /**< DIVX3 */ + MPP_VIDEO_CodingVP6, + MPP_VIDEO_CodingHEVC, /**< H.265/HEVC */ + MPP_VIDEO_CodingAVS, /**< AVS+ */ + MPP_VIDEO_CodingKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + MPP_VIDEO_CodingVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + MPP_VIDEO_CodingMax = 0x7FFFFFFF +} MppCodingType; + +/* + * Command id bit usage is defined as follows: + * bit 20 - 23 - module id + * bit 16 - 19 - contex id + * bit 0 - 15 - command id + */ +#define CMD_MODULE_ID_MASK (0x00F00000) +#define CMD_MODULE_OSAL (0x00100000) +#define CMD_MODULE_MPP (0x00200000) +#define CMD_MODULE_CODEC (0x00300000) +#define CMD_MODULE_HAL (0x00400000) +#define CMD_CTX_ID_MASK (0x000F0000) +#define CMD_CTX_ID_DEC (0x00010000) +#define CMD_CTX_ID_ENC (0x00020000) +#define CMD_CTX_ID_ISP (0x00030000) +#define CMD_ID_MASK (0x0000FFFF) + +typedef enum { + MPP_OSAL_CMD_BASE = CMD_MODULE_OSAL, + MPP_OSAL_CMD_END, + + MPP_CMD_BASE = CMD_MODULE_MPP, + MPP_ENABLE_DEINTERLACE, + MPP_SET_INPUT_BLOCK, + MPP_SET_OUTPUT_BLOCK, + MPP_CMD_END, + + MPP_CODEC_CMD_BASE = CMD_MODULE_CODEC, + MPP_CODEC_GET_FRAME_INFO, + MPP_CODEC_CMD_END, + + MPP_DEC_CMD_BASE = CMD_MODULE_CODEC | CMD_CTX_ID_DEC, + MPP_DEC_SET_FRAME_INFO, /* vpu api legacy control for buffer slot dimension init */ + MPP_DEC_SET_EXT_BUF_GROUP, /* IMPORTANT: set external buffer group to mpp decoder */ + MPP_DEC_SET_INFO_CHANGE_READY, + MPP_DEC_SET_INTERNAL_PTS_ENABLE, + MPP_DEC_SET_PARSER_SPLIT_MODE, /* Need to setup before init */ + MPP_DEC_SET_PARSER_FAST_MODE, /* Need to setup before init */ + MPP_DEC_GET_STREAM_COUNT, + MPP_DEC_GET_VPUMEM_USED_COUNT, + MPP_DEC_SET_VC1_EXTRA_DATA, + MPP_DEC_SET_OUTPUT_FORMAT, + MPP_DEC_CMD_END, + + MPP_ENC_CMD_BASE = CMD_MODULE_CODEC | CMD_CTX_ID_ENC, + MPP_ENC_SET_CFG, + MPP_ENC_GET_CFG, + MPP_ENC_SET_EXTRA_INFO, + MPP_ENC_GET_EXTRA_INFO, + MPP_ENC_SET_FORMAT, + MPP_ENC_SET_IDR_FRAME, + MPP_ENC_CMD_END, + + MPP_ISP_CMD_BASE = CMD_MODULE_CODEC | CMD_CTX_ID_ISP, + MPP_ISP_CMD_END, + + MPP_HAL_CMD_BASE = CMD_MODULE_HAL, + MPP_HAL_CMD_END, + + MPI_CMD_BUTT, +} MpiCmd; + +typedef void* MppCtx; +typedef void* MppParam; + +/* + * in decoder mode application need to specify the coding type first + * send a stream header to mpi ctx using parameter data / size + * and decoder will try to decode the + */ +typedef struct MppEncConfig_t { + /* encoder config also need to know size of itself */ + RK_U32 size; + RK_U32 version; + + /* + * input source data format + */ + RK_S32 width; + RK_S32 height; + RK_S32 hor_stride; + RK_S32 ver_stride; + RK_S32 format; + + /* + * Encoder does not support scaling and output data only support yuv420 so far + */ + + /* + * rate control parameter + * + * rc_mode - rate control mode + * 0 - fix qp mode + * 1 - constant bit rate mode (CBR) + * 2 - variable bit rate mode (VBR) + * skip_cnt - max continuous frame skip count + * 0 - frame skip is not allow + * bps - target bit rate, unit: bit per second + * fps_in - input frame rate, unit: frame per second + * if 0 then default set to 30 + * fps_out - output frame rate, unit: frame per second + * if 0 then default set to fps_in + * qp - constant qp for fix qp mode + * initial qp for CBR / VBR + * gop - gap between Intra frame + * 0 for only 1 I frame the rest are all P frames + * 1 for all I frame + * 2 for I P I P I P + * 3 for I P P I P P + * etc... + */ + RK_S32 rc_mode; + RK_S32 skip_cnt; + RK_S32 bps; + RK_S32 fps_in; + RK_S32 fps_out; + RK_S32 qp; + RK_S32 gop; + + /* + * stream feature parameter + */ + RK_S32 profile; + RK_S32 level; + RK_S32 cabac_en; +} MppEncConfig; + +/* + * mpp main work function set + * size : MppApi structure size + * version : Mpp svn revision + * + * all api function are seperated into two sets: data io api set and control api set + * + * the data api set is for data input/output flow including: + * + * simple data api set: + * + * decode : both send video stream packet to decoder and get video frame from + * decoder at the same time. + * encode : both send video frame to encoder and get encoded video stream from + * encoder at the same time. + * + * decode_put_packet: send video stream packet to decoder only, async interface + * decode_get_frame : get video frame from decoder only, async interface + * + * encode_put_frame : send video frame to encoder only, async interface + * encode_get_packet: get encoded video packet from encoder only, async interface + * + * advance task api set: + * + * + * the control api set is for mpp context control including: + * control : similiar to ioctl in kernel driver, setup or get mpp internal parameter + * reset : clear all data in mpp context, reset to initialized status + * the simple api set is for simple codec usage including: + * + * + * reset : discard all packet and frame, reset all component, + * for both decoder and encoder + * control : control function for mpp property setting + */ +typedef struct MppApi_t { + RK_U32 size; + RK_U32 version; + + // simple data flow interface + MPP_RET (*decode)(MppCtx ctx, MppPacket packet, MppFrame *frame); + MPP_RET (*decode_put_packet)(MppCtx ctx, MppPacket packet); + MPP_RET (*decode_get_frame)(MppCtx ctx, MppFrame *frame); + + MPP_RET (*encode)(MppCtx ctx, MppFrame frame, MppPacket *packet); + MPP_RET (*encode_put_frame)(MppCtx ctx, MppFrame frame); + MPP_RET (*encode_get_packet)(MppCtx ctx, MppPacket *packet); + + MPP_RET (*isp)(MppCtx ctx, MppFrame dst, MppFrame src); + MPP_RET (*isp_put_frame)(MppCtx ctx, MppFrame frame); + MPP_RET (*isp_get_frame)(MppCtx ctx, MppFrame *frame); + + // advance data flow interface + MPP_RET (*dequeue)(MppCtx ctx, MppPortType type, MppTask *task); + MPP_RET (*enqueue)(MppCtx ctx, MppPortType type, MppTask task); + + // control interface + MPP_RET (*reset)(MppCtx ctx); + MPP_RET (*control)(MppCtx ctx, MpiCmd cmd, MppParam param); + + RK_U32 reserv[16]; +} MppApi; + + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * mpp interface work flow + * + * 1. mpp_create : Create empty context structure and mpi function pointers. + * 2. mpp_init : Call after mpp_create to setup mpp type and video format. + * This function will call internal context init function. + * 3. Use functions in MppApi to access mpp services. + * 4. mpp_destory: Destroy mpp context and free both context and mpi structure + */ +MPP_RET mpp_create(MppCtx *ctx, MppApi **mpi); +MPP_RET mpp_init(MppCtx ctx, MppCtxType type, MppCodingType coding); +MPP_RET mpp_destroy(MppCtx ctx); + +// coding type format function +MPP_RET mpp_check_support_format(MppCtxType type, MppCodingType coding); +void mpp_show_support_format(); + +#ifdef __cplusplus +} +#endif + +#endif /*__RK_MPI_H__*/ diff --git a/inc/rk_type.h b/inc/rk_type.h index 146d5f89..4c5cb92d 100644 --- a/inc/rk_type.h +++ b/inc/rk_type.h @@ -1,55 +1,55 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __RK_TYPE_H__ -#define __RK_TYPE_H__ - -#include - -#if defined(_WIN32) && !defined(__MINGW32CE__) - -typedef unsigned char RK_U8; -typedef unsigned short RK_U16; -typedef unsigned int RK_U32; -typedef unsigned __int64 RK_U64; - -typedef signed char RK_S8; -typedef signed short RK_S16; -typedef signed int RK_S32; -typedef signed __int64 RK_S64; - -#else - -typedef unsigned char RK_U8; -typedef unsigned short RK_U16; -typedef unsigned int RK_U32; -typedef unsigned long long int RK_U64; - - -typedef signed char RK_S8; -typedef signed short RK_S16; -typedef signed int RK_S32; -typedef signed long long int RK_S64; - -#endif - -#ifndef MODULE_TAG -#define MODULE_TAG NULL -#endif - - - -#endif /*__RK_TYPE_H__*/ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __RK_TYPE_H__ +#define __RK_TYPE_H__ + +#include + +#if defined(_WIN32) && !defined(__MINGW32CE__) + +typedef unsigned char RK_U8; +typedef unsigned short RK_U16; +typedef unsigned int RK_U32; +typedef unsigned __int64 RK_U64; + +typedef signed char RK_S8; +typedef signed short RK_S16; +typedef signed int RK_S32; +typedef signed __int64 RK_S64; + +#else + +typedef unsigned char RK_U8; +typedef unsigned short RK_U16; +typedef unsigned int RK_U32; +typedef unsigned long long int RK_U64; + + +typedef signed char RK_S8; +typedef signed short RK_S16; +typedef signed int RK_S32; +typedef signed long long int RK_S64; + +#endif + +#ifndef MODULE_TAG +#define MODULE_TAG NULL +#endif + + + +#endif /*__RK_TYPE_H__*/ diff --git a/inc/vpu.h b/inc/vpu.h index 8c29fe2f..7e0273ec 100644 --- a/inc/vpu.h +++ b/inc/vpu.h @@ -1,127 +1,127 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __VPU_H__ -#define __VPU_H__ - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include "rk_type.h" - -#define VPU_SUCCESS (0) -#define VPU_FAILURE (-1) - -#define VPU_HW_WAIT_OK VPU_SUCCESS -#define VPU_HW_WAIT_ERROR VPU_FAILURE -#define VPU_HW_WAIT_TIMEOUT 1 - -// vpu decoder 60 registers, size 240B -#define VPU_REG_NUM_DEC (60) -// vpu post processor 41 registers, size 164B -#define VPU_REG_NUM_PP (41) -// vpu decoder + post processor 101 registers, size 404B -#define VPU_REG_NUM_DEC_PP (VPU_REG_NUM_DEC+VPU_REG_NUM_PP) -// vpu encoder 96 registers, size 384B -#define VPU_REG_NUM_ENC (96) - -typedef enum { - - VPU_ENC = 0x0, - VPU_DEC = 0x1, - VPU_PP = 0x2, - VPU_DEC_PP = 0x3, - VPU_DEC_HEVC = 0x4, - VPU_DEC_RKV = 0x5, - VPU_ENC_RKV = 0x6, - VPU_TYPE_BUTT , - -} VPU_CLIENT_TYPE; - -/* Hardware decoder configuration description */ - -typedef struct VPUHwDecConfig { - RK_U32 maxDecPicWidth; /* Maximum video decoding width supported */ - RK_U32 maxPpOutPicWidth; /* Maximum output width of Post-Processor */ - RK_U32 h264Support; /* HW supports h.264 */ - RK_U32 jpegSupport; /* HW supports JPEG */ - RK_U32 mpeg4Support; /* HW supports MPEG-4 */ - RK_U32 customMpeg4Support; /* HW supports custom MPEG-4 features */ - RK_U32 vc1Support; /* HW supports VC-1 Simple */ - RK_U32 mpeg2Support; /* HW supports MPEG-2 */ - RK_U32 ppSupport; /* HW supports post-processor */ - RK_U32 ppConfig; /* HW post-processor functions bitmask */ - RK_U32 sorensonSparkSupport; /* HW supports Sorenson Spark */ - RK_U32 refBufSupport; /* HW supports reference picture buffering */ - RK_U32 vp6Support; /* HW supports VP6 */ - RK_U32 vp7Support; /* HW supports VP7 */ - RK_U32 vp8Support; /* HW supports VP8 */ - RK_U32 avsSupport; /* HW supports AVS */ - RK_U32 jpegESupport; /* HW supports JPEG extensions */ - RK_U32 rvSupport; /* HW supports REAL */ - RK_U32 mvcSupport; /* HW supports H264 MVC extension */ -} VPUHwDecConfig_t; - -/* Hardware encoder configuration description */ - -typedef struct VPUHwEndConfig { - RK_U32 maxEncodedWidth; /* Maximum supported width for video encoding (not JPEG) */ - RK_U32 h264Enabled; /* HW supports H.264 */ - RK_U32 jpegEnabled; /* HW supports JPEG */ - RK_U32 mpeg4Enabled; /* HW supports MPEG-4 */ - RK_U32 vsEnabled; /* HW supports video stabilization */ - RK_U32 rgbEnabled; /* HW supports RGB input */ - RK_U32 reg_size; /* HW bus type in use */ - RK_U32 reserv[2]; -} VPUHwEncConfig_t; - -typedef enum { - - // common command - VPU_CMD_REGISTER , - VPU_CMD_REGISTER_ACK_OK , - VPU_CMD_REGISTER_ACK_FAIL , - VPU_CMD_UNREGISTER , - - VPU_SEND_CONFIG , - VPU_SEND_CONFIG_ACK_OK , - VPU_SEND_CONFIG_ACK_FAIL , - - VPU_GET_HW_INFO , - VPU_GET_HW_INFO_ACK_OK , - VPU_GET_HW_INFO_ACK_FAIL , - - VPU_CMD_BUTT , -} VPU_CMD_TYPE; - -int VPUClientInit(VPU_CLIENT_TYPE type); -RK_S32 VPUClientRelease(int socket); -RK_S32 VPUClientSendReg(int socket, RK_U32 *regs, RK_U32 nregs); -RK_S32 VPUClientWaitResult(int socket, RK_U32 *regs, RK_U32 nregs, VPU_CMD_TYPE *cmd, RK_S32 *len); -RK_S32 VPUClientGetHwCfg(int socket, RK_U32 *cfg, RK_U32 cfg_size); -RK_S32 VPUClientGetIOMMUStatus(); -RK_U32 VPUCheckSupportWidth(); - -#ifdef __cplusplus -} - -#endif - -#endif /* __VPU_H__ */ - - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __VPU_H__ +#define __VPU_H__ + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "rk_type.h" + +#define VPU_SUCCESS (0) +#define VPU_FAILURE (-1) + +#define VPU_HW_WAIT_OK VPU_SUCCESS +#define VPU_HW_WAIT_ERROR VPU_FAILURE +#define VPU_HW_WAIT_TIMEOUT 1 + +// vpu decoder 60 registers, size 240B +#define VPU_REG_NUM_DEC (60) +// vpu post processor 41 registers, size 164B +#define VPU_REG_NUM_PP (41) +// vpu decoder + post processor 101 registers, size 404B +#define VPU_REG_NUM_DEC_PP (VPU_REG_NUM_DEC+VPU_REG_NUM_PP) +// vpu encoder 96 registers, size 384B +#define VPU_REG_NUM_ENC (96) + +typedef enum { + + VPU_ENC = 0x0, + VPU_DEC = 0x1, + VPU_PP = 0x2, + VPU_DEC_PP = 0x3, + VPU_DEC_HEVC = 0x4, + VPU_DEC_RKV = 0x5, + VPU_ENC_RKV = 0x6, + VPU_TYPE_BUTT , + +} VPU_CLIENT_TYPE; + +/* Hardware decoder configuration description */ + +typedef struct VPUHwDecConfig { + RK_U32 maxDecPicWidth; /* Maximum video decoding width supported */ + RK_U32 maxPpOutPicWidth; /* Maximum output width of Post-Processor */ + RK_U32 h264Support; /* HW supports h.264 */ + RK_U32 jpegSupport; /* HW supports JPEG */ + RK_U32 mpeg4Support; /* HW supports MPEG-4 */ + RK_U32 customMpeg4Support; /* HW supports custom MPEG-4 features */ + RK_U32 vc1Support; /* HW supports VC-1 Simple */ + RK_U32 mpeg2Support; /* HW supports MPEG-2 */ + RK_U32 ppSupport; /* HW supports post-processor */ + RK_U32 ppConfig; /* HW post-processor functions bitmask */ + RK_U32 sorensonSparkSupport; /* HW supports Sorenson Spark */ + RK_U32 refBufSupport; /* HW supports reference picture buffering */ + RK_U32 vp6Support; /* HW supports VP6 */ + RK_U32 vp7Support; /* HW supports VP7 */ + RK_U32 vp8Support; /* HW supports VP8 */ + RK_U32 avsSupport; /* HW supports AVS */ + RK_U32 jpegESupport; /* HW supports JPEG extensions */ + RK_U32 rvSupport; /* HW supports REAL */ + RK_U32 mvcSupport; /* HW supports H264 MVC extension */ +} VPUHwDecConfig_t; + +/* Hardware encoder configuration description */ + +typedef struct VPUHwEndConfig { + RK_U32 maxEncodedWidth; /* Maximum supported width for video encoding (not JPEG) */ + RK_U32 h264Enabled; /* HW supports H.264 */ + RK_U32 jpegEnabled; /* HW supports JPEG */ + RK_U32 mpeg4Enabled; /* HW supports MPEG-4 */ + RK_U32 vsEnabled; /* HW supports video stabilization */ + RK_U32 rgbEnabled; /* HW supports RGB input */ + RK_U32 reg_size; /* HW bus type in use */ + RK_U32 reserv[2]; +} VPUHwEncConfig_t; + +typedef enum { + + // common command + VPU_CMD_REGISTER , + VPU_CMD_REGISTER_ACK_OK , + VPU_CMD_REGISTER_ACK_FAIL , + VPU_CMD_UNREGISTER , + + VPU_SEND_CONFIG , + VPU_SEND_CONFIG_ACK_OK , + VPU_SEND_CONFIG_ACK_FAIL , + + VPU_GET_HW_INFO , + VPU_GET_HW_INFO_ACK_OK , + VPU_GET_HW_INFO_ACK_FAIL , + + VPU_CMD_BUTT , +} VPU_CMD_TYPE; + +int VPUClientInit(VPU_CLIENT_TYPE type); +RK_S32 VPUClientRelease(int socket); +RK_S32 VPUClientSendReg(int socket, RK_U32 *regs, RK_U32 nregs); +RK_S32 VPUClientWaitResult(int socket, RK_U32 *regs, RK_U32 nregs, VPU_CMD_TYPE *cmd, RK_S32 *len); +RK_S32 VPUClientGetHwCfg(int socket, RK_U32 *cfg, RK_U32 cfg_size); +RK_S32 VPUClientGetIOMMUStatus(); +RK_U32 VPUCheckSupportWidth(); + +#ifdef __cplusplus +} + +#endif + +#endif /* __VPU_H__ */ + + diff --git a/inc/vpu_api.h b/inc/vpu_api.h index 8c898aca..949d8801 100644 --- a/inc/vpu_api.h +++ b/inc/vpu_api.h @@ -1,399 +1,399 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __VPU_API_LEGACY_H__ -#define __VPU_API_LEGACY_H__ - -#include "rk_type.h" -#include "mpp_err.h" - -#define VPU_API_NOPTS_VALUE (0x8000000000000000LL) - -/* - * bit definition of ColorType in structure VPU_FRAME - */ -#define VPU_OUTPUT_FORMAT_TYPE_MASK (0x0000ffff) -#define VPU_OUTPUT_FORMAT_ARGB8888 (0x00000000) -#define VPU_OUTPUT_FORMAT_ABGR8888 (0x00000001) -#define VPU_OUTPUT_FORMAT_RGB888 (0x00000002) -#define VPU_OUTPUT_FORMAT_RGB565 (0x00000003) -#define VPU_OUTPUT_FORMAT_RGB555 (0x00000004) -#define VPU_OUTPUT_FORMAT_YUV420_SEMIPLANAR (0x00000005) -#define VPU_OUTPUT_FORMAT_YUV420_PLANAR (0x00000006) -#define VPU_OUTPUT_FORMAT_YUV422 (0x00000007) -#define VPU_OUTPUT_FORMAT_YUV444 (0x00000008) -#define VPU_OUTPUT_FORMAT_YCH420 (0x00000009) -#define VPU_OUTPUT_FORMAT_BIT_MASK (0x000f0000) -#define VPU_OUTPUT_FORMAT_BIT_8 (0x00000000) -#define VPU_OUTPUT_FORMAT_BIT_10 (0x00010000) -#define VPU_OUTPUT_FORMAT_BIT_12 (0x00020000) -#define VPU_OUTPUT_FORMAT_BIT_14 (0x00030000) -#define VPU_OUTPUT_FORMAT_BIT_16 (0x00040000) - -typedef enum { - ENC_INPUT_YUV420_PLANAR = 0, /* YYYY... UUUU... VVVV */ - ENC_INPUT_YUV420_SEMIPLANAR = 1, /* YYYY... UVUVUV... */ - ENC_INPUT_YUV422_INTERLEAVED_YUYV = 2, /* YUYVYUYV... */ - ENC_INPUT_YUV422_INTERLEAVED_UYVY = 3, /* UYVYUYVY... */ - ENC_INPUT_RGB565 = 4, /* 16-bit RGB */ - ENC_INPUT_BGR565 = 5, /* 16-bit RGB */ - ENC_INPUT_RGB555 = 6, /* 15-bit RGB */ - ENC_INPUT_BGR555 = 7, /* 15-bit RGB */ - ENC_INPUT_RGB444 = 8, /* 12-bit RGB */ - ENC_INPUT_BGR444 = 9, /* 12-bit RGB */ - ENC_INPUT_RGB888 = 10, /* 24-bit RGB */ - ENC_INPUT_BGR888 = 11, /* 24-bit RGB */ - ENC_INPUT_RGB101010 = 12, /* 30-bit RGB */ - ENC_INPUT_BGR101010 = 13 /* 30-bit RGB */ -} EncInputPictureType; - -typedef enum VPU_API_CMD { - VPU_API_ENC_SETCFG, - VPU_API_ENC_GETCFG, - VPU_API_ENC_SETFORMAT, - VPU_API_ENC_SETIDRFRAME, - - VPU_API_ENABLE_DEINTERLACE, - VPU_API_SET_VPUMEM_CONTEXT, - VPU_API_USE_PRESENT_TIME_ORDER, - VPU_API_SET_DEFAULT_WIDTH_HEIGH, - VPU_API_SET_INFO_CHANGE, - VPU_API_USE_FAST_MODE, - VPU_API_DEC_GET_STREAM_COUNT, - VPU_API_GET_VPUMEM_USED_COUNT, - VPU_API_DEC_GETFORMAT, - VPU_API_SET_OUTPUT_BLOCK, - VPU_API_DEC_GET_EOS_STATUS, -} VPU_API_CMD; - -typedef struct { - RK_U32 TimeLow; - RK_U32 TimeHigh; -} TIME_STAMP; - -typedef struct { - RK_U32 CodecType; - RK_U32 ImgWidth; - RK_U32 ImgHeight; - RK_U32 ImgHorStride; - RK_U32 ImgVerStride; -} VPU_GENERIC; - -typedef struct VPUMem { - RK_U32 phy_addr; - RK_U32 *vir_addr; - RK_U32 size; - RK_U32 *offset; -} VPUMemLinear_t; - -typedef struct tVPU_FRAME { - RK_U32 FrameBusAddr[2]; // 0: Y address; 1: UV address; - RK_U32 FrameWidth; // buffer horizontal stride - RK_U32 FrameHeight; // buffer vertical stride - RK_U32 OutputWidth; // deprecated - RK_U32 OutputHeight; // deprecated - RK_U32 DisplayWidth; // valid width for display - RK_U32 DisplayHeight; // valid height for display - RK_U32 CodingType; - RK_U32 FrameType; // frame; top_field_first; bot_field_first - RK_U32 ColorType; - RK_U32 DecodeFrmNum; - TIME_STAMP ShowTime; - RK_U32 ErrorInfo; // error information - RK_U32 employ_cnt; - VPUMemLinear_t vpumem; - struct tVPU_FRAME *next_frame; - RK_U32 Res[4]; -} VPU_FRAME; - -typedef struct VideoPacket { - RK_S64 pts; /* with unit of us*/ - RK_S64 dts; /* with unit of us*/ - RK_U8 *data; - RK_S32 size; - RK_U32 capability; - RK_U32 nFlags; -} VideoPacket_t; - -typedef struct DecoderOut { - RK_U8 *data; - RK_U32 size; - RK_S64 timeUs; - RK_S32 nFlags; -} DecoderOut_t; - -typedef struct ParserOut { - RK_U8 *data; - RK_U32 size; - RK_S64 timeUs; - RK_U32 nFlags; - RK_U32 width; - RK_U32 height; -} ParserOut_t; - -typedef struct EncInputStream { - RK_U8 *buf; - RK_S32 size; - RK_U32 bufPhyAddr; - RK_S64 timeUs; - RK_U32 nFlags; -} EncInputStream_t; - -typedef struct EncoderOut { - RK_U8 *data; - RK_S32 size; - RK_S64 timeUs; - RK_S32 keyFrame; - -} EncoderOut_t; - -/* - * Enumeration used to define the possible video compression codings. - * NOTE: This essentially refers to file extensions. If the coding is - * being used to specify the ENCODE type, then additional work - * must be done to configure the exact flavor of the compression - * to be used. For decode cases where the user application can - * not differentiate between MPEG-4 and H.264 bit streams, it is - * up to the codec to handle this. - */ -//sync with the omx_video.h -typedef enum OMX_RK_VIDEO_CODINGTYPE { - OMX_RK_VIDEO_CodingUnused, /**< Value when coding is N/A */ - OMX_RK_VIDEO_CodingAutoDetect, /**< Autodetection of coding type */ - OMX_RK_VIDEO_CodingMPEG2, /**< AKA: H.262 */ - OMX_RK_VIDEO_CodingH263, /**< H.263 */ - OMX_RK_VIDEO_CodingMPEG4, /**< MPEG-4 */ - OMX_RK_VIDEO_CodingWMV, /**< Windows Media Video (WMV1,WMV2,WMV3)*/ - OMX_RK_VIDEO_CodingRV, /**< all versions of Real Video */ - OMX_RK_VIDEO_CodingAVC, /**< H.264/AVC */ - OMX_RK_VIDEO_CodingMJPEG, /**< Motion JPEG */ - OMX_RK_VIDEO_CodingVP8, /**< VP8 */ - OMX_RK_VIDEO_CodingVP9, /**< VP9 */ - OMX_RK_VIDEO_CodingVC1 = 0x01000000, /**< Windows Media Video (WMV1,WMV2,WMV3)*/ - OMX_RK_VIDEO_CodingFLV1, /**< Sorenson H.263 */ - OMX_RK_VIDEO_CodingDIVX3, /**< DIVX3 */ - OMX_RK_VIDEO_CodingVP6, - OMX_RK_VIDEO_CodingHEVC, /**< H.265/HEVC */ - OMX_RK_VIDEO_CodingAVS, /**< AVS+ */ - OMX_RK_VIDEO_CodingKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ - OMX_RK_VIDEO_CodingVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - OMX_RK_VIDEO_CodingMax = 0x7FFFFFFF -} OMX_RK_VIDEO_CODINGTYPE; - -typedef enum VPU_VIDEO_PIXEL_FMT { - VPU_VIDEO_PIXEL_FMT_NV12 -} VPU_VIDEO_PIXEL_FMT; - -typedef enum CODEC_TYPE { - CODEC_NONE, - CODEC_DECODER, - CODEC_ENCODER, - CODEC_BUTT, -} CODEC_TYPE; - -typedef enum VPU_API_ERR { - VPU_API_OK = 0, - VPU_API_ERR_UNKNOW = -1, - VPU_API_ERR_BASE = -1000, - VPU_API_ERR_LIST_STREAM = VPU_API_ERR_BASE - 1, - VPU_API_ERR_INIT = VPU_API_ERR_BASE - 2, - VPU_API_ERR_VPU_CODEC_INIT = VPU_API_ERR_BASE - 3, - VPU_API_ERR_STREAM = VPU_API_ERR_BASE - 4, - VPU_API_ERR_FATAL_THREAD = VPU_API_ERR_BASE - 5, - VPU_API_EOS_STREAM_REACHED = VPU_API_ERR_BASE - 11, - - VPU_API_ERR_BUTT, -} VPU_API_ERR; - -typedef struct DecoderFormat { - VPU_VIDEO_PIXEL_FMT format; - RK_U32 width; - RK_U32 height; - RK_U32 stride; - RK_U32 frame_size; - RK_U32 aligned_width; - RK_U32 aligned_height; - RK_U32 aligned_stride; - RK_U32 aligned_frame_size; -} DecoderFormat_t; - -typedef enum VPU_FRAME_ERR { - VPU_FRAME_ERR_UNKNOW = 0x0001, - VPU_FRAME_ERR_UNSUPPORT = 0x0002, - -} VPU_FRAME_ERR; - -typedef struct EncParameter { - RK_S32 width; - RK_S32 height; - RK_S32 rc_mode; /* 0 - CQP mode; 1 - CBR mode; */ - RK_S32 bitRate; /* target bitrate */ - RK_S32 framerate; - RK_S32 qp; - RK_S32 enableCabac; - RK_S32 cabacInitIdc; - RK_S32 format; - RK_S32 intraPicRate; - RK_S32 framerateout; - RK_S32 profileIdc; - RK_S32 levelIdc; - RK_S32 reserved[3]; -} EncParameter_t; - - -typedef struct EXtraCfg { - RK_S32 vc1extra_size; - RK_S32 vp6codeid; - RK_S32 tsformat; - RK_U32 reserved[20]; -} EXtraCfg_t; -/** - * @addtogroup rk_vpu_codec - * @{ - */ -typedef struct VpuCodecContext { - void* vpuApiObj; - - CODEC_TYPE codecType; - OMX_RK_VIDEO_CODINGTYPE videoCoding; - - RK_U32 width; - RK_U32 height; - void *extradata; - RK_S32 extradata_size; - - RK_U8 enableparsing; - - - - RK_S32 no_thread; - EXtraCfg_t extra_cfg; - - void* private_data; - - /* - ** 1: error state(not working) 0: working - */ - RK_S32 decoder_err; - - - /** - * Allocate and initialize an VpuCodecContext. - * - * @param ctx The context of vpu api, allocated in this function. - * @param extraData The extra data of codec, some codecs need / can - * use extradata like Huffman tables, also live VC1 codec can - * use extradata to initialize itself. - * @param extra_size The size of extra data. - * - * @return 0 for init success, others for failure. - * note: check whether ctx has been allocated success after you do init. - */ - RK_S32 (*init)(struct VpuCodecContext *ctx, RK_U8 *extraData, RK_U32 extra_size); - - /** - * @return 0 for decode success, others for failure. - */ - RK_S32 (*decode)(struct VpuCodecContext *ctx, VideoPacket_t *pkt, DecoderOut_t *aDecOut); - - /** - * @return 0 for encode success, others for failure. - */ - RK_S32 (*encode)(struct VpuCodecContext *ctx, EncInputStream_t *aEncInStrm, EncoderOut_t *aEncOut); - - /** - * flush codec while do fast forward playing. - * - * @return 0 for flush success, others for failure. - */ - RK_S32 (*flush)(struct VpuCodecContext *ctx); - RK_S32 (*control)(struct VpuCodecContext *ctx, VPU_API_CMD cmdType, void* param); - /** - *seperate the decode function to two function - * - */ - RK_S32 (*decode_sendstream)(struct VpuCodecContext *ctx, VideoPacket_t *pkt); - RK_S32 (*decode_getframe)(struct VpuCodecContext *ctx, DecoderOut_t *aDecOut); - - RK_S32 (*encoder_sendframe)(struct VpuCodecContext *ctx, EncInputStream_t *aEncInStrm); - RK_S32 (*encoder_getstream)(struct VpuCodecContext *ctx, EncoderOut_t *aEncOut); -} VpuCodecContext_t; - -/* allocated vpu codec context */ -#ifdef __cplusplus -extern "C" -{ -#endif - -RK_S32 vpu_open_context(struct VpuCodecContext **ctx); -RK_S32 vpu_close_context(struct VpuCodecContext **ctx); - -#ifdef __cplusplus -} -#endif - -/* - * vpu_mem api - */ -#define vpu_display_mem_pool_FIELDS \ - RK_S32 (*commit_hdl)(vpu_display_mem_pool *p, RK_S32 hdl, RK_S32 size); \ - void* (*get_free)(vpu_display_mem_pool *p); \ - RK_S32 (*inc_used)(vpu_display_mem_pool *p, void *hdl); \ - RK_S32 (*put_used)(vpu_display_mem_pool *p, void *hdl); \ - RK_S32 (*reset)(vpu_display_mem_pool *p); \ - RK_S32 (*get_unused_num)(vpu_display_mem_pool *p); \ - RK_S32 buff_size;\ - float version; \ - RK_S32 res[18]; - -typedef struct vpu_display_mem_pool vpu_display_mem_pool; - -struct vpu_display_mem_pool { - vpu_display_mem_pool_FIELDS -}; - -#ifdef __cplusplus -extern "C" -{ -#endif - -/* - * vpu memory handle interface - */ -RK_S32 VPUMemJudgeIommu(); -RK_S32 VPUMallocLinear(VPUMemLinear_t *p, RK_U32 size); -RK_S32 VPUFreeLinear(VPUMemLinear_t *p); -RK_S32 VPUMemDuplicate(VPUMemLinear_t *dst, VPUMemLinear_t *src); -RK_S32 VPUMemLink(VPUMemLinear_t *p); -RK_S32 VPUMemFlush(VPUMemLinear_t *p); -RK_S32 VPUMemClean(VPUMemLinear_t *p); -RK_S32 VPUMemInvalidate(VPUMemLinear_t *p); -RK_S32 VPUMemGetFD(VPUMemLinear_t *p); - - -/* - * vpu memory allocator and manager interface - */ -vpu_display_mem_pool* open_vpu_memory_pool(); -void close_vpu_memory_pool(vpu_display_mem_pool *p); -int create_vpu_memory_pool_allocator(vpu_display_mem_pool **ipool, int num, int size); -void release_vpu_memory_pool_allocator(vpu_display_mem_pool *ipool); - -#ifdef __cplusplus -} -#endif - -#endif /*__VPU_API_LEGACY_H__*/ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __VPU_API_LEGACY_H__ +#define __VPU_API_LEGACY_H__ + +#include "rk_type.h" +#include "mpp_err.h" + +#define VPU_API_NOPTS_VALUE (0x8000000000000000LL) + +/* + * bit definition of ColorType in structure VPU_FRAME + */ +#define VPU_OUTPUT_FORMAT_TYPE_MASK (0x0000ffff) +#define VPU_OUTPUT_FORMAT_ARGB8888 (0x00000000) +#define VPU_OUTPUT_FORMAT_ABGR8888 (0x00000001) +#define VPU_OUTPUT_FORMAT_RGB888 (0x00000002) +#define VPU_OUTPUT_FORMAT_RGB565 (0x00000003) +#define VPU_OUTPUT_FORMAT_RGB555 (0x00000004) +#define VPU_OUTPUT_FORMAT_YUV420_SEMIPLANAR (0x00000005) +#define VPU_OUTPUT_FORMAT_YUV420_PLANAR (0x00000006) +#define VPU_OUTPUT_FORMAT_YUV422 (0x00000007) +#define VPU_OUTPUT_FORMAT_YUV444 (0x00000008) +#define VPU_OUTPUT_FORMAT_YCH420 (0x00000009) +#define VPU_OUTPUT_FORMAT_BIT_MASK (0x000f0000) +#define VPU_OUTPUT_FORMAT_BIT_8 (0x00000000) +#define VPU_OUTPUT_FORMAT_BIT_10 (0x00010000) +#define VPU_OUTPUT_FORMAT_BIT_12 (0x00020000) +#define VPU_OUTPUT_FORMAT_BIT_14 (0x00030000) +#define VPU_OUTPUT_FORMAT_BIT_16 (0x00040000) + +typedef enum { + ENC_INPUT_YUV420_PLANAR = 0, /* YYYY... UUUU... VVVV */ + ENC_INPUT_YUV420_SEMIPLANAR = 1, /* YYYY... UVUVUV... */ + ENC_INPUT_YUV422_INTERLEAVED_YUYV = 2, /* YUYVYUYV... */ + ENC_INPUT_YUV422_INTERLEAVED_UYVY = 3, /* UYVYUYVY... */ + ENC_INPUT_RGB565 = 4, /* 16-bit RGB */ + ENC_INPUT_BGR565 = 5, /* 16-bit RGB */ + ENC_INPUT_RGB555 = 6, /* 15-bit RGB */ + ENC_INPUT_BGR555 = 7, /* 15-bit RGB */ + ENC_INPUT_RGB444 = 8, /* 12-bit RGB */ + ENC_INPUT_BGR444 = 9, /* 12-bit RGB */ + ENC_INPUT_RGB888 = 10, /* 24-bit RGB */ + ENC_INPUT_BGR888 = 11, /* 24-bit RGB */ + ENC_INPUT_RGB101010 = 12, /* 30-bit RGB */ + ENC_INPUT_BGR101010 = 13 /* 30-bit RGB */ +} EncInputPictureType; + +typedef enum VPU_API_CMD { + VPU_API_ENC_SETCFG, + VPU_API_ENC_GETCFG, + VPU_API_ENC_SETFORMAT, + VPU_API_ENC_SETIDRFRAME, + + VPU_API_ENABLE_DEINTERLACE, + VPU_API_SET_VPUMEM_CONTEXT, + VPU_API_USE_PRESENT_TIME_ORDER, + VPU_API_SET_DEFAULT_WIDTH_HEIGH, + VPU_API_SET_INFO_CHANGE, + VPU_API_USE_FAST_MODE, + VPU_API_DEC_GET_STREAM_COUNT, + VPU_API_GET_VPUMEM_USED_COUNT, + VPU_API_DEC_GETFORMAT, + VPU_API_SET_OUTPUT_BLOCK, + VPU_API_DEC_GET_EOS_STATUS, +} VPU_API_CMD; + +typedef struct { + RK_U32 TimeLow; + RK_U32 TimeHigh; +} TIME_STAMP; + +typedef struct { + RK_U32 CodecType; + RK_U32 ImgWidth; + RK_U32 ImgHeight; + RK_U32 ImgHorStride; + RK_U32 ImgVerStride; +} VPU_GENERIC; + +typedef struct VPUMem { + RK_U32 phy_addr; + RK_U32 *vir_addr; + RK_U32 size; + RK_U32 *offset; +} VPUMemLinear_t; + +typedef struct tVPU_FRAME { + RK_U32 FrameBusAddr[2]; // 0: Y address; 1: UV address; + RK_U32 FrameWidth; // buffer horizontal stride + RK_U32 FrameHeight; // buffer vertical stride + RK_U32 OutputWidth; // deprecated + RK_U32 OutputHeight; // deprecated + RK_U32 DisplayWidth; // valid width for display + RK_U32 DisplayHeight; // valid height for display + RK_U32 CodingType; + RK_U32 FrameType; // frame; top_field_first; bot_field_first + RK_U32 ColorType; + RK_U32 DecodeFrmNum; + TIME_STAMP ShowTime; + RK_U32 ErrorInfo; // error information + RK_U32 employ_cnt; + VPUMemLinear_t vpumem; + struct tVPU_FRAME *next_frame; + RK_U32 Res[4]; +} VPU_FRAME; + +typedef struct VideoPacket { + RK_S64 pts; /* with unit of us*/ + RK_S64 dts; /* with unit of us*/ + RK_U8 *data; + RK_S32 size; + RK_U32 capability; + RK_U32 nFlags; +} VideoPacket_t; + +typedef struct DecoderOut { + RK_U8 *data; + RK_U32 size; + RK_S64 timeUs; + RK_S32 nFlags; +} DecoderOut_t; + +typedef struct ParserOut { + RK_U8 *data; + RK_U32 size; + RK_S64 timeUs; + RK_U32 nFlags; + RK_U32 width; + RK_U32 height; +} ParserOut_t; + +typedef struct EncInputStream { + RK_U8 *buf; + RK_S32 size; + RK_U32 bufPhyAddr; + RK_S64 timeUs; + RK_U32 nFlags; +} EncInputStream_t; + +typedef struct EncoderOut { + RK_U8 *data; + RK_S32 size; + RK_S64 timeUs; + RK_S32 keyFrame; + +} EncoderOut_t; + +/* + * Enumeration used to define the possible video compression codings. + * NOTE: This essentially refers to file extensions. If the coding is + * being used to specify the ENCODE type, then additional work + * must be done to configure the exact flavor of the compression + * to be used. For decode cases where the user application can + * not differentiate between MPEG-4 and H.264 bit streams, it is + * up to the codec to handle this. + */ +//sync with the omx_video.h +typedef enum OMX_RK_VIDEO_CODINGTYPE { + OMX_RK_VIDEO_CodingUnused, /**< Value when coding is N/A */ + OMX_RK_VIDEO_CodingAutoDetect, /**< Autodetection of coding type */ + OMX_RK_VIDEO_CodingMPEG2, /**< AKA: H.262 */ + OMX_RK_VIDEO_CodingH263, /**< H.263 */ + OMX_RK_VIDEO_CodingMPEG4, /**< MPEG-4 */ + OMX_RK_VIDEO_CodingWMV, /**< Windows Media Video (WMV1,WMV2,WMV3)*/ + OMX_RK_VIDEO_CodingRV, /**< all versions of Real Video */ + OMX_RK_VIDEO_CodingAVC, /**< H.264/AVC */ + OMX_RK_VIDEO_CodingMJPEG, /**< Motion JPEG */ + OMX_RK_VIDEO_CodingVP8, /**< VP8 */ + OMX_RK_VIDEO_CodingVP9, /**< VP9 */ + OMX_RK_VIDEO_CodingVC1 = 0x01000000, /**< Windows Media Video (WMV1,WMV2,WMV3)*/ + OMX_RK_VIDEO_CodingFLV1, /**< Sorenson H.263 */ + OMX_RK_VIDEO_CodingDIVX3, /**< DIVX3 */ + OMX_RK_VIDEO_CodingVP6, + OMX_RK_VIDEO_CodingHEVC, /**< H.265/HEVC */ + OMX_RK_VIDEO_CodingAVS, /**< AVS+ */ + OMX_RK_VIDEO_CodingKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ + OMX_RK_VIDEO_CodingVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ + OMX_RK_VIDEO_CodingMax = 0x7FFFFFFF +} OMX_RK_VIDEO_CODINGTYPE; + +typedef enum VPU_VIDEO_PIXEL_FMT { + VPU_VIDEO_PIXEL_FMT_NV12 +} VPU_VIDEO_PIXEL_FMT; + +typedef enum CODEC_TYPE { + CODEC_NONE, + CODEC_DECODER, + CODEC_ENCODER, + CODEC_BUTT, +} CODEC_TYPE; + +typedef enum VPU_API_ERR { + VPU_API_OK = 0, + VPU_API_ERR_UNKNOW = -1, + VPU_API_ERR_BASE = -1000, + VPU_API_ERR_LIST_STREAM = VPU_API_ERR_BASE - 1, + VPU_API_ERR_INIT = VPU_API_ERR_BASE - 2, + VPU_API_ERR_VPU_CODEC_INIT = VPU_API_ERR_BASE - 3, + VPU_API_ERR_STREAM = VPU_API_ERR_BASE - 4, + VPU_API_ERR_FATAL_THREAD = VPU_API_ERR_BASE - 5, + VPU_API_EOS_STREAM_REACHED = VPU_API_ERR_BASE - 11, + + VPU_API_ERR_BUTT, +} VPU_API_ERR; + +typedef struct DecoderFormat { + VPU_VIDEO_PIXEL_FMT format; + RK_U32 width; + RK_U32 height; + RK_U32 stride; + RK_U32 frame_size; + RK_U32 aligned_width; + RK_U32 aligned_height; + RK_U32 aligned_stride; + RK_U32 aligned_frame_size; +} DecoderFormat_t; + +typedef enum VPU_FRAME_ERR { + VPU_FRAME_ERR_UNKNOW = 0x0001, + VPU_FRAME_ERR_UNSUPPORT = 0x0002, + +} VPU_FRAME_ERR; + +typedef struct EncParameter { + RK_S32 width; + RK_S32 height; + RK_S32 rc_mode; /* 0 - CQP mode; 1 - CBR mode; */ + RK_S32 bitRate; /* target bitrate */ + RK_S32 framerate; + RK_S32 qp; + RK_S32 enableCabac; + RK_S32 cabacInitIdc; + RK_S32 format; + RK_S32 intraPicRate; + RK_S32 framerateout; + RK_S32 profileIdc; + RK_S32 levelIdc; + RK_S32 reserved[3]; +} EncParameter_t; + + +typedef struct EXtraCfg { + RK_S32 vc1extra_size; + RK_S32 vp6codeid; + RK_S32 tsformat; + RK_U32 reserved[20]; +} EXtraCfg_t; +/** + * @addtogroup rk_vpu_codec + * @{ + */ +typedef struct VpuCodecContext { + void* vpuApiObj; + + CODEC_TYPE codecType; + OMX_RK_VIDEO_CODINGTYPE videoCoding; + + RK_U32 width; + RK_U32 height; + void *extradata; + RK_S32 extradata_size; + + RK_U8 enableparsing; + + + + RK_S32 no_thread; + EXtraCfg_t extra_cfg; + + void* private_data; + + /* + ** 1: error state(not working) 0: working + */ + RK_S32 decoder_err; + + + /** + * Allocate and initialize an VpuCodecContext. + * + * @param ctx The context of vpu api, allocated in this function. + * @param extraData The extra data of codec, some codecs need / can + * use extradata like Huffman tables, also live VC1 codec can + * use extradata to initialize itself. + * @param extra_size The size of extra data. + * + * @return 0 for init success, others for failure. + * note: check whether ctx has been allocated success after you do init. + */ + RK_S32 (*init)(struct VpuCodecContext *ctx, RK_U8 *extraData, RK_U32 extra_size); + + /** + * @return 0 for decode success, others for failure. + */ + RK_S32 (*decode)(struct VpuCodecContext *ctx, VideoPacket_t *pkt, DecoderOut_t *aDecOut); + + /** + * @return 0 for encode success, others for failure. + */ + RK_S32 (*encode)(struct VpuCodecContext *ctx, EncInputStream_t *aEncInStrm, EncoderOut_t *aEncOut); + + /** + * flush codec while do fast forward playing. + * + * @return 0 for flush success, others for failure. + */ + RK_S32 (*flush)(struct VpuCodecContext *ctx); + RK_S32 (*control)(struct VpuCodecContext *ctx, VPU_API_CMD cmdType, void* param); + /** + *seperate the decode function to two function + * + */ + RK_S32 (*decode_sendstream)(struct VpuCodecContext *ctx, VideoPacket_t *pkt); + RK_S32 (*decode_getframe)(struct VpuCodecContext *ctx, DecoderOut_t *aDecOut); + + RK_S32 (*encoder_sendframe)(struct VpuCodecContext *ctx, EncInputStream_t *aEncInStrm); + RK_S32 (*encoder_getstream)(struct VpuCodecContext *ctx, EncoderOut_t *aEncOut); +} VpuCodecContext_t; + +/* allocated vpu codec context */ +#ifdef __cplusplus +extern "C" +{ +#endif + +RK_S32 vpu_open_context(struct VpuCodecContext **ctx); +RK_S32 vpu_close_context(struct VpuCodecContext **ctx); + +#ifdef __cplusplus +} +#endif + +/* + * vpu_mem api + */ +#define vpu_display_mem_pool_FIELDS \ + RK_S32 (*commit_hdl)(vpu_display_mem_pool *p, RK_S32 hdl, RK_S32 size); \ + void* (*get_free)(vpu_display_mem_pool *p); \ + RK_S32 (*inc_used)(vpu_display_mem_pool *p, void *hdl); \ + RK_S32 (*put_used)(vpu_display_mem_pool *p, void *hdl); \ + RK_S32 (*reset)(vpu_display_mem_pool *p); \ + RK_S32 (*get_unused_num)(vpu_display_mem_pool *p); \ + RK_S32 buff_size;\ + float version; \ + RK_S32 res[18]; + +typedef struct vpu_display_mem_pool vpu_display_mem_pool; + +struct vpu_display_mem_pool { + vpu_display_mem_pool_FIELDS +}; + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* + * vpu memory handle interface + */ +RK_S32 VPUMemJudgeIommu(); +RK_S32 VPUMallocLinear(VPUMemLinear_t *p, RK_U32 size); +RK_S32 VPUFreeLinear(VPUMemLinear_t *p); +RK_S32 VPUMemDuplicate(VPUMemLinear_t *dst, VPUMemLinear_t *src); +RK_S32 VPUMemLink(VPUMemLinear_t *p); +RK_S32 VPUMemFlush(VPUMemLinear_t *p); +RK_S32 VPUMemClean(VPUMemLinear_t *p); +RK_S32 VPUMemInvalidate(VPUMemLinear_t *p); +RK_S32 VPUMemGetFD(VPUMemLinear_t *p); + + +/* + * vpu memory allocator and manager interface + */ +vpu_display_mem_pool* open_vpu_memory_pool(); +void close_vpu_memory_pool(vpu_display_mem_pool *p); +int create_vpu_memory_pool_allocator(vpu_display_mem_pool **ipool, int num, int size); +void release_vpu_memory_pool_allocator(vpu_display_mem_pool *ipool); + +#ifdef __cplusplus +} +#endif + +#endif /*__VPU_API_LEGACY_H__*/ diff --git a/mpp/base/inc/mpp_bitput.h b/mpp/base/inc/mpp_bitput.h index 18eb5c68..5dc05df0 100644 --- a/mpp/base/inc/mpp_bitput.h +++ b/mpp/base/inc/mpp_bitput.h @@ -1,50 +1,50 @@ -/* - * - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __MPP_BITPUT_H__ -#define __MPP_BITPUT_H__ - -#include -#include - -#include "rk_type.h" -#include "mpp_log.h" -#include "mpp_common.h" -#include "mpp_err.h" - -typedef struct bitput_ctx_t { - RK_U32 buflen; //!< max buf length, 64bit uint - RK_U32 index; //!< current uint position - RK_U64 *pbuf; //!< outpacket data - RK_U64 bvalue; //!< buffer value, 64 bit - RK_U8 bitpos; //!< bit pos in 64bit - RK_U32 size; //!< data size,except header -} BitputCtx_t; - -#ifdef __cplusplus -extern "C" { -#endif - -RK_S32 mpp_set_bitput_ctx(BitputCtx_t *bp, RK_U64 *data, RK_U32 len); -void mpp_put_bits(BitputCtx_t *bp, RK_U64 invalue, RK_S32 lbits); -void mpp_put_align(BitputCtx_t *bp, RK_S32 align_bits, int flag); - -#ifdef __cplusplus -} -#endif - -#endif +/* + * + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPP_BITPUT_H__ +#define __MPP_BITPUT_H__ + +#include +#include + +#include "rk_type.h" +#include "mpp_log.h" +#include "mpp_common.h" +#include "mpp_err.h" + +typedef struct bitput_ctx_t { + RK_U32 buflen; //!< max buf length, 64bit uint + RK_U32 index; //!< current uint position + RK_U64 *pbuf; //!< outpacket data + RK_U64 bvalue; //!< buffer value, 64 bit + RK_U8 bitpos; //!< bit pos in 64bit + RK_U32 size; //!< data size,except header +} BitputCtx_t; + +#ifdef __cplusplus +extern "C" { +#endif + +RK_S32 mpp_set_bitput_ctx(BitputCtx_t *bp, RK_U64 *data, RK_U32 len); +void mpp_put_bits(BitputCtx_t *bp, RK_U64 invalue, RK_S32 lbits); +void mpp_put_align(BitputCtx_t *bp, RK_S32 align_bits, int flag); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/mpp/base/inc/mpp_bitread.h b/mpp/base/inc/mpp_bitread.h index 3dd35bf2..353dbf9d 100644 --- a/mpp/base/inc/mpp_bitread.h +++ b/mpp/base/inc/mpp_bitread.h @@ -1,201 +1,201 @@ -/* -* -* Copyright 2015 Rockchip Electronics Co. LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -#ifndef __MPP_BITREAD_H__ -#define __MPP_BITREAD_H__ - -#include -#include -#include "rk_type.h" -#include "mpp_log.h" -#include "mpp_common.h" -#include "mpp_err.h" - -#define __BITREAD_ERR __bitread_error -typedef void (*LOG_FUN)(void *ctx, ...); - -#define BitReadLog(bitctx, ...)\ - do {\ - bitctx->wlog(bitctx->ctx, __FILE__, __LINE__, ##__VA_ARGS__);\ - } while (0) - - -#define READ_ONEBIT(bitctx, out, ...)\ - do {\ - RK_S32 _out; \ - bitctx->ret = mpp_read_bits(bitctx, 1, &_out); \ - BitReadLog(bitctx, "%48s = %10d", ##__VA_ARGS__, _out); \ - if (!bitctx->ret) { *out = _out; }\ - else { goto __BITREAD_ERR; }\ - } while (0) - -#define READ_BITS(bitctx, num_bits, out, ...)\ - do {\ - RK_S32 _out;\ - bitctx->ret = mpp_read_bits(bitctx, num_bits, &_out);\ - BitReadLog(bitctx, "%48s = %10d", ##__VA_ARGS__, _out); \ - if (!bitctx->ret) { *out = _out; }\ - else { goto __BITREAD_ERR;}\ - } while (0) - -#define READ_BITS_LONG(bitctx, num_bits, out, ...)\ - do {\ - RK_U32 _out; \ - bitctx->ret = mpp_read_longbits(bitctx, num_bits, &_out); \ - BitReadLog(bitctx, "%48s = %10d", ##__VA_ARGS__, _out); \ - if (!bitctx->ret) { *out = _out; }\ - else { goto __BITREAD_ERR; }\ - } while (0) - -#define SHOW_BITS(bitctx, num_bits, out)\ - do {\ - RK_S32 _out; \ - bitctx->ret = mpp_show_bits(bitctx, num_bits, &_out); \ - if (!bitctx->ret) { *out = _out; }\ - else { goto __BITREAD_ERR; }\ - } while (0) - -#define SHOW_BITS_LONG(bitctx, num_bits, out)\ - do {\ - RK_U32 _out; \ - bitctx->ret = mpp_show_longbits(bitctx, num_bits, &_out); \ - if (!bitctx->ret) { *out = _out; }\ - else { goto __BITREAD_ERR; }\ - } while (0) - -#define SKIP_BITS(bitctx, num_bits)\ - do {\ - bitctx->ret = mpp_skip_bits(bitctx, num_bits);\ - BitReadLog(bitctx, "%48s %d bits", "skip", num_bits);\ - if (bitctx->ret) { goto __BITREAD_ERR; }\ - } while (0) - -#define SKIP_BITS_LONG(bitctx, num_bits)\ - do {\ - bitctx->ret = mpp_skip_longbits(bitctx, num_bits); \ - BitReadLog(bitctx, "%48s %d bits", "skip", num_bits); \ - if (bitctx->ret) { goto __BITREAD_ERR; }\ - } while (0) - -#define READ_UE(bitctx, out, ...)\ - do {\ - RK_U32 _out;\ - bitctx->ret = mpp_read_ue(bitctx, &_out);\ - BitReadLog(bitctx, "%48s = %10d", ##__VA_ARGS__, _out);\ - if (!bitctx->ret) { *out = _out; }\ - else { goto __BITREAD_ERR;}\ - } while (0) - -#define READ_SE(bitctx, out, ...)\ - do {\ - RK_S32 _out;\ - bitctx->ret = mpp_read_se(bitctx, &_out);\ - BitReadLog(bitctx, "%48s = %10d", ##__VA_ARGS__, _out);\ - if (!bitctx->ret) { *out = _out; }\ - else { goto __BITREAD_ERR;}\ - } while (0) - -#define CHECK_RANGE(bitctx, val, _min, _max)\ - do {\ - if ((val) < (_min) || (val) > (_max)) {\ - mpp_log("%d[%d,%d]", val, _min, _max);\ - bitctx->ret = MPP_ERR_VALUE;\ - goto __BITREAD_ERR;\ - }\ - } while (0) - -#define CHECK_ERROR(bitctx, val)\ - do {\ - if (!(val)) {\ - mpp_log("value false");\ - bitctx->ret = MPP_ERR_VALUE;\ - goto __BITREAD_ERR;\ - }\ - } while (0) - -typedef struct bitread_ctx_t { - // Pointer to the next unread (not in curr_byte_) byte in the stream. - RK_U8 *data_; - // Bytes left in the stream (without the curr_byte_). - RK_U32 bytes_left_; - // Contents of the current byte; first unread bit starting at position - // 8 - num_remaining_bits_in_curr_byte_ from MSB. - RK_S64 curr_byte_; - // Number of bits remaining in curr_byte_ - RK_S32 num_remaining_bits_in_curr_byte_; - // Used in emulation prevention three byte detection (see spec). - // Initially set to 0xffff to accept all initial two-byte sequences. - RK_S64 prev_two_bytes_; - // Number of emulation presentation bytes (0x000003) we met. - RK_S64 emulation_prevention_bytes_; - // count PPS SPS SEI read bits - RK_S32 used_bits; - RK_U8 *buf; - RK_S32 buf_len; - // ctx - MPP_RET ret; - RK_S32 need_prevention_detection; - void *ctx; - LOG_FUN wlog; -} BitReadCtx_t; - - -#ifdef __cplusplus -extern "C" { -#endif - -//!< set bit read context -void mpp_set_bitread_ctx(BitReadCtx_t *bitctx, RK_U8 *data, RK_S32 size); - -//!< Read bits (1-31) -MPP_RET mpp_read_bits(BitReadCtx_t *bitctx, RK_S32 num_bits, RK_S32 *out); - -//!< Read bits (1-32) -MPP_RET mpp_read_longbits(BitReadCtx_t *bitctx, RK_S32 num_bits, RK_U32 *out); - -//!< Show bits (1-31) -MPP_RET mpp_show_bits(BitReadCtx_t *bitctx, RK_S32 num_bits, RK_S32 *out); - -//!< Show bits (1-32) -MPP_RET mpp_show_longbits(BitReadCtx_t *bitctx, RK_S32 num_bits, RK_U32 *out); - -//!< skip bits(1-31) -MPP_RET mpp_skip_bits(BitReadCtx_t *bitctx, RK_S32 num_bits); - -//!< skip bits(1-32) -MPP_RET mpp_skip_longbits(BitReadCtx_t *bitctx, RK_S32 num_bits); - -//!< read ue(1-32) -MPP_RET mpp_read_ue(BitReadCtx_t *bitctx, RK_U32* val); - -//!< read se(1-31) -MPP_RET mpp_read_se(BitReadCtx_t *bitctx, RK_S32* val); - -//!< set whether detect 0x03 (used in h264 and h265) -void mpp_set_pre_detection(BitReadCtx_t *bitctx); - -//!< check whether has more rbsp data(used in h264) -RK_U32 mpp_has_more_rbsp_data(BitReadCtx_t * bitctx); - -//!< align bits and get current pointer -RK_U8 *mpp_align_get_bits(BitReadCtx_t *bitctx); - -#ifdef __cplusplus -} -#endif - - -#endif /* __MPP_BITREAD_H__ */ +/* +* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#ifndef __MPP_BITREAD_H__ +#define __MPP_BITREAD_H__ + +#include +#include +#include "rk_type.h" +#include "mpp_log.h" +#include "mpp_common.h" +#include "mpp_err.h" + +#define __BITREAD_ERR __bitread_error +typedef void (*LOG_FUN)(void *ctx, ...); + +#define BitReadLog(bitctx, ...)\ + do {\ + bitctx->wlog(bitctx->ctx, __FILE__, __LINE__, ##__VA_ARGS__);\ + } while (0) + + +#define READ_ONEBIT(bitctx, out, ...)\ + do {\ + RK_S32 _out; \ + bitctx->ret = mpp_read_bits(bitctx, 1, &_out); \ + BitReadLog(bitctx, "%48s = %10d", ##__VA_ARGS__, _out); \ + if (!bitctx->ret) { *out = _out; }\ + else { goto __BITREAD_ERR; }\ + } while (0) + +#define READ_BITS(bitctx, num_bits, out, ...)\ + do {\ + RK_S32 _out;\ + bitctx->ret = mpp_read_bits(bitctx, num_bits, &_out);\ + BitReadLog(bitctx, "%48s = %10d", ##__VA_ARGS__, _out); \ + if (!bitctx->ret) { *out = _out; }\ + else { goto __BITREAD_ERR;}\ + } while (0) + +#define READ_BITS_LONG(bitctx, num_bits, out, ...)\ + do {\ + RK_U32 _out; \ + bitctx->ret = mpp_read_longbits(bitctx, num_bits, &_out); \ + BitReadLog(bitctx, "%48s = %10d", ##__VA_ARGS__, _out); \ + if (!bitctx->ret) { *out = _out; }\ + else { goto __BITREAD_ERR; }\ + } while (0) + +#define SHOW_BITS(bitctx, num_bits, out)\ + do {\ + RK_S32 _out; \ + bitctx->ret = mpp_show_bits(bitctx, num_bits, &_out); \ + if (!bitctx->ret) { *out = _out; }\ + else { goto __BITREAD_ERR; }\ + } while (0) + +#define SHOW_BITS_LONG(bitctx, num_bits, out)\ + do {\ + RK_U32 _out; \ + bitctx->ret = mpp_show_longbits(bitctx, num_bits, &_out); \ + if (!bitctx->ret) { *out = _out; }\ + else { goto __BITREAD_ERR; }\ + } while (0) + +#define SKIP_BITS(bitctx, num_bits)\ + do {\ + bitctx->ret = mpp_skip_bits(bitctx, num_bits);\ + BitReadLog(bitctx, "%48s %d bits", "skip", num_bits);\ + if (bitctx->ret) { goto __BITREAD_ERR; }\ + } while (0) + +#define SKIP_BITS_LONG(bitctx, num_bits)\ + do {\ + bitctx->ret = mpp_skip_longbits(bitctx, num_bits); \ + BitReadLog(bitctx, "%48s %d bits", "skip", num_bits); \ + if (bitctx->ret) { goto __BITREAD_ERR; }\ + } while (0) + +#define READ_UE(bitctx, out, ...)\ + do {\ + RK_U32 _out;\ + bitctx->ret = mpp_read_ue(bitctx, &_out);\ + BitReadLog(bitctx, "%48s = %10d", ##__VA_ARGS__, _out);\ + if (!bitctx->ret) { *out = _out; }\ + else { goto __BITREAD_ERR;}\ + } while (0) + +#define READ_SE(bitctx, out, ...)\ + do {\ + RK_S32 _out;\ + bitctx->ret = mpp_read_se(bitctx, &_out);\ + BitReadLog(bitctx, "%48s = %10d", ##__VA_ARGS__, _out);\ + if (!bitctx->ret) { *out = _out; }\ + else { goto __BITREAD_ERR;}\ + } while (0) + +#define CHECK_RANGE(bitctx, val, _min, _max)\ + do {\ + if ((val) < (_min) || (val) > (_max)) {\ + mpp_log("%d[%d,%d]", val, _min, _max);\ + bitctx->ret = MPP_ERR_VALUE;\ + goto __BITREAD_ERR;\ + }\ + } while (0) + +#define CHECK_ERROR(bitctx, val)\ + do {\ + if (!(val)) {\ + mpp_log("value false");\ + bitctx->ret = MPP_ERR_VALUE;\ + goto __BITREAD_ERR;\ + }\ + } while (0) + +typedef struct bitread_ctx_t { + // Pointer to the next unread (not in curr_byte_) byte in the stream. + RK_U8 *data_; + // Bytes left in the stream (without the curr_byte_). + RK_U32 bytes_left_; + // Contents of the current byte; first unread bit starting at position + // 8 - num_remaining_bits_in_curr_byte_ from MSB. + RK_S64 curr_byte_; + // Number of bits remaining in curr_byte_ + RK_S32 num_remaining_bits_in_curr_byte_; + // Used in emulation prevention three byte detection (see spec). + // Initially set to 0xffff to accept all initial two-byte sequences. + RK_S64 prev_two_bytes_; + // Number of emulation presentation bytes (0x000003) we met. + RK_S64 emulation_prevention_bytes_; + // count PPS SPS SEI read bits + RK_S32 used_bits; + RK_U8 *buf; + RK_S32 buf_len; + // ctx + MPP_RET ret; + RK_S32 need_prevention_detection; + void *ctx; + LOG_FUN wlog; +} BitReadCtx_t; + + +#ifdef __cplusplus +extern "C" { +#endif + +//!< set bit read context +void mpp_set_bitread_ctx(BitReadCtx_t *bitctx, RK_U8 *data, RK_S32 size); + +//!< Read bits (1-31) +MPP_RET mpp_read_bits(BitReadCtx_t *bitctx, RK_S32 num_bits, RK_S32 *out); + +//!< Read bits (1-32) +MPP_RET mpp_read_longbits(BitReadCtx_t *bitctx, RK_S32 num_bits, RK_U32 *out); + +//!< Show bits (1-31) +MPP_RET mpp_show_bits(BitReadCtx_t *bitctx, RK_S32 num_bits, RK_S32 *out); + +//!< Show bits (1-32) +MPP_RET mpp_show_longbits(BitReadCtx_t *bitctx, RK_S32 num_bits, RK_U32 *out); + +//!< skip bits(1-31) +MPP_RET mpp_skip_bits(BitReadCtx_t *bitctx, RK_S32 num_bits); + +//!< skip bits(1-32) +MPP_RET mpp_skip_longbits(BitReadCtx_t *bitctx, RK_S32 num_bits); + +//!< read ue(1-32) +MPP_RET mpp_read_ue(BitReadCtx_t *bitctx, RK_U32* val); + +//!< read se(1-31) +MPP_RET mpp_read_se(BitReadCtx_t *bitctx, RK_S32* val); + +//!< set whether detect 0x03 (used in h264 and h265) +void mpp_set_pre_detection(BitReadCtx_t *bitctx); + +//!< check whether has more rbsp data(used in h264) +RK_U32 mpp_has_more_rbsp_data(BitReadCtx_t * bitctx); + +//!< align bits and get current pointer +RK_U8 *mpp_align_get_bits(BitReadCtx_t *bitctx); + +#ifdef __cplusplus +} +#endif + + +#endif /* __MPP_BITREAD_H__ */ diff --git a/mpp/base/inc/mpp_buf_slot.h b/mpp/base/inc/mpp_buf_slot.h index df2bcc7f..7f81eec6 100644 --- a/mpp/base/inc/mpp_buf_slot.h +++ b/mpp/base/inc/mpp_buf_slot.h @@ -1,253 +1,253 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __MPP_BUF_SLOT_H__ -#define __MPP_BUF_SLOT_H__ - -#include "rk_type.h" -#include "mpp_frame.h" - -/* - * mpp_dec will alloc 18 decoded picture buffer slot - * buffer slot is for transferring information between parser / mpp/ hal - * it represent the dpb routine in logical - * - * basic working flow: - * - * buf_slot parser hal - * - * + + + - * | | | - * | +--------+--------+ | - * | | | | - * | | do parsing here | | - * | | | | - * | +--------+--------+ | - * | | | - * | get_slot | | - * | <--------------------------+ | - * | get unused dpb slot for | | - * | current decoder output | | - * | | | - * | update dpb refer status | | - * | <--------------------------+ | - * | parser will send marking | | - * | operation to dpb slot | | - * | including: | | - * | ref/unref/output/display | | - * | | | - * | | | - * | | set buffer status to hal | - * +-------------------------------------------------------> | - * | | | - * | | +--------+--------+ - * | | | | - * | | | reg generation | - * | | | | - * | | +--------+--------+ - * | | | - * | | get buffer address info | - * | <-------------------------------------------------------+ - * | | used buffer index to get | - * | | physical address or iommu | - * | | address for hardware | - * | | | - * | | +--------+--------+ - * | | | | - * | | | set/wait hw | - * | | | | - * | | +--------+--------+ - * | | | - * | | update the output status | - * | <-------------------------------------------------------+ - * | | mark picture is available | - * | | for output and generate | - * | | output frame information | - * + + + - * - * typical buffer status transfer - * - * -> unused initial - * -> set_hw_dst by parser - * -> set_buffer by mpp - do alloc buffer here / info change here - * -> clr_hw_dst by hal() - * - * next four step can be different order - * -> set_dpb_ref by parser - * -> set_display by parser - slot ready to display, can be output - * -> clr_display by mpp - output buffer struct - * -> clr_dpb_ref by parser - * - * -> set_unused automatic clear and dec buffer ref - * - */ - -typedef void* MppBufSlots; - -/* - * buffer slot index range is 0~254, 0xff (255) will indicated the invalid index - */ -#define SLOT_IDX_BUTT (0xff) - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * called by mpp context - * - * init / deinit - normal initialize and de-initialize function - * setup - called by parser when slot information changed - * is_changed - called by mpp to detect whether info change flow is needed - * ready - called by mpp when info changed is done - * - * typical info change flow: - * - * mpp_buf_slot_setup called in parser with changed equal to 1 - * mpp_buf_slot_is_changed called in mpp and found info change - * - * do info change outside - * - * mpp_buf_slot_ready called in mpp when info change is done - * - */ -MPP_RET mpp_buf_slot_init(MppBufSlots *slots); -MPP_RET mpp_buf_slot_deinit(MppBufSlots slots); -MPP_RET mpp_buf_slot_setup(MppBufSlots slots, RK_S32 count); -RK_U32 mpp_buf_slot_is_changed(MppBufSlots slots); -MPP_RET mpp_buf_slot_ready(MppBufSlots slots); -size_t mpp_buf_slot_get_size(MppBufSlots slots); -RK_S32 mpp_buf_slot_get_used_size(MppBufSlots slots); -/* - * called by parser - * - * mpp_buf_slot_get_unused - * - parser need a new slot for output, on field mode alloc one buffer for two field - * - * mpp_buf_slot_set_dpb_ref - * - mark a slot to be used as reference frame in dpb - * - * mpp_buf_slot_clr_dpb_ref - * - mark a slot to be unused as reference frame and remove from dpb - * - * mpp_buf_slot_set_hw_dst - * - mark a slot to be output destination buffer - * - NOTE: the frame information MUST be set here - * - * mpp_buf_slot_set_display - * - mark a slot to be can be display - * - NOTE: set display will generate a MppFrame for buffer slot internal usage - * for example store pts / buffer address, etc. - * - * mpp_buf_slot_inc_hw_ref - * - MUST be called once when one slot is used in hardware decoding as reference frame - * - * called by mpp - * - * mpp_buf_slot_get_hw_dst - * - mpp_dec need to get the output slot index to check buffer status - * - * mpp_buf_slot_clr_display - * - mark a slot has been send out to display - * - NOTE: will be called inside mpp_buf_slot_get_display - * - * called by hal - * - * mpp_buf_slot_clr_hw_dst - * - mark a slot's buffer is already decoded by hardware - * - NOTE: this call will clear used as output flag - * - * mpp_buf_slot_dec_hw_ref - * - when hal finished on hardware decoding it MUST be called once for each used slot - */ -MPP_RET mpp_buf_slot_get_unused(MppBufSlots slots, RK_S32 *index); - -/* - * mpp_buf_slot_set_buffer - * - called by dec thread when find a output index has not buffer - * - * mpp_buf_slot_get_buffer - * - called by hal module on register generation - * - * mpp_buf_slot_get_display - * - called by hal thread to output a display slot's frame info - * NOTE: get display will generate a new MppFrame for external mpp_frame_deinit call - * So that external mpp_frame_deinit will not release the MppFrame used in buf_slot - */ - -/* - * NOTE: - * buffer slot will be used both for frame and packet - * when buffer slot is used for packet management only inc_hw_ref and dec_hw_ref is used - */ - -typedef enum SlotUsageType_e { - SLOT_CODEC_READY, // bit flag for buffer is prepared by codec - SLOT_CODEC_USE, // bit flag for buffer is used as reference by codec - SLOT_HAL_INPUT, // counter for buffer is used as hardware input - SLOT_HAL_OUTPUT, // counter + bit flag for buffer is used as hardware output - SLOT_QUEUE_USE, // bit flag for buffer is hold in different queues - SLOT_USAGE_BUTT, -} SlotUsageType; - -MPP_RET mpp_buf_slot_set_flag(MppBufSlots slots, RK_S32 index, SlotUsageType type); -MPP_RET mpp_buf_slot_clr_flag(MppBufSlots slots, RK_S32 index, SlotUsageType type); - -// TODO: can be extended here -typedef enum SlotQueueType_e { - QUEUE_OUTPUT, - QUEUE_DISPLAY, - QUEUE_DEINTERLACE, - QUEUE_COLOR_CONVERT, - QUEUE_BUTT, -} SlotQueueType; - -MPP_RET mpp_buf_slot_enqueue(MppBufSlots slots, RK_S32 index, SlotQueueType type); -MPP_RET mpp_buf_slot_dequeue(MppBufSlots slots, RK_S32 *index, SlotQueueType type); - -typedef enum SlotPropType_e { - SLOT_EOS, - SLOT_FRAME, - SLOT_BUFFER, - SLOT_FRAME_PTR, - SLOT_PROP_BUTT, -} SlotPropType; - -MPP_RET mpp_buf_slot_set_prop(MppBufSlots slots, RK_S32 index, SlotPropType type, void *val); -MPP_RET mpp_buf_slot_get_prop(MppBufSlots slots, RK_S32 index, SlotPropType type, void *val); - -typedef enum SlotsPropType_e { - SLOTS_EOS, - SLOTS_HOR_ALIGN, // input must be buf_align function pointer - SLOTS_VER_ALIGN, // input must be buf_align function pointer - SLOTS_LEN_ALIGN, - SLOTS_COUNT, - SLOTS_SIZE, - SLOTS_FRAME_INFO, - SLOTS_PROP_BUTT, -} SlotsPropType; - -typedef RK_U32 (*AlignFunc)(RK_U32 val); - -MPP_RET mpp_slots_set_prop(MppBufSlots slots, SlotsPropType type, void *val); -MPP_RET mpp_slots_get_prop(MppBufSlots slots, SlotsPropType type, void *val); -MPP_RET mpp_buf_slot_reset(MppBufSlots slots, RK_S32 index); //rest slot status when info_change no ok - -#ifdef __cplusplus -} -#endif - -#endif /*__MPP_BUF_SLOT_H__*/ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPP_BUF_SLOT_H__ +#define __MPP_BUF_SLOT_H__ + +#include "rk_type.h" +#include "mpp_frame.h" + +/* + * mpp_dec will alloc 18 decoded picture buffer slot + * buffer slot is for transferring information between parser / mpp/ hal + * it represent the dpb routine in logical + * + * basic working flow: + * + * buf_slot parser hal + * + * + + + + * | | | + * | +--------+--------+ | + * | | | | + * | | do parsing here | | + * | | | | + * | +--------+--------+ | + * | | | + * | get_slot | | + * | <--------------------------+ | + * | get unused dpb slot for | | + * | current decoder output | | + * | | | + * | update dpb refer status | | + * | <--------------------------+ | + * | parser will send marking | | + * | operation to dpb slot | | + * | including: | | + * | ref/unref/output/display | | + * | | | + * | | | + * | | set buffer status to hal | + * +-------------------------------------------------------> | + * | | | + * | | +--------+--------+ + * | | | | + * | | | reg generation | + * | | | | + * | | +--------+--------+ + * | | | + * | | get buffer address info | + * | <-------------------------------------------------------+ + * | | used buffer index to get | + * | | physical address or iommu | + * | | address for hardware | + * | | | + * | | +--------+--------+ + * | | | | + * | | | set/wait hw | + * | | | | + * | | +--------+--------+ + * | | | + * | | update the output status | + * | <-------------------------------------------------------+ + * | | mark picture is available | + * | | for output and generate | + * | | output frame information | + * + + + + * + * typical buffer status transfer + * + * -> unused initial + * -> set_hw_dst by parser + * -> set_buffer by mpp - do alloc buffer here / info change here + * -> clr_hw_dst by hal() + * + * next four step can be different order + * -> set_dpb_ref by parser + * -> set_display by parser - slot ready to display, can be output + * -> clr_display by mpp - output buffer struct + * -> clr_dpb_ref by parser + * + * -> set_unused automatic clear and dec buffer ref + * + */ + +typedef void* MppBufSlots; + +/* + * buffer slot index range is 0~254, 0xff (255) will indicated the invalid index + */ +#define SLOT_IDX_BUTT (0xff) + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * called by mpp context + * + * init / deinit - normal initialize and de-initialize function + * setup - called by parser when slot information changed + * is_changed - called by mpp to detect whether info change flow is needed + * ready - called by mpp when info changed is done + * + * typical info change flow: + * + * mpp_buf_slot_setup called in parser with changed equal to 1 + * mpp_buf_slot_is_changed called in mpp and found info change + * + * do info change outside + * + * mpp_buf_slot_ready called in mpp when info change is done + * + */ +MPP_RET mpp_buf_slot_init(MppBufSlots *slots); +MPP_RET mpp_buf_slot_deinit(MppBufSlots slots); +MPP_RET mpp_buf_slot_setup(MppBufSlots slots, RK_S32 count); +RK_U32 mpp_buf_slot_is_changed(MppBufSlots slots); +MPP_RET mpp_buf_slot_ready(MppBufSlots slots); +size_t mpp_buf_slot_get_size(MppBufSlots slots); +RK_S32 mpp_buf_slot_get_used_size(MppBufSlots slots); +/* + * called by parser + * + * mpp_buf_slot_get_unused + * - parser need a new slot for output, on field mode alloc one buffer for two field + * + * mpp_buf_slot_set_dpb_ref + * - mark a slot to be used as reference frame in dpb + * + * mpp_buf_slot_clr_dpb_ref + * - mark a slot to be unused as reference frame and remove from dpb + * + * mpp_buf_slot_set_hw_dst + * - mark a slot to be output destination buffer + * - NOTE: the frame information MUST be set here + * + * mpp_buf_slot_set_display + * - mark a slot to be can be display + * - NOTE: set display will generate a MppFrame for buffer slot internal usage + * for example store pts / buffer address, etc. + * + * mpp_buf_slot_inc_hw_ref + * - MUST be called once when one slot is used in hardware decoding as reference frame + * + * called by mpp + * + * mpp_buf_slot_get_hw_dst + * - mpp_dec need to get the output slot index to check buffer status + * + * mpp_buf_slot_clr_display + * - mark a slot has been send out to display + * - NOTE: will be called inside mpp_buf_slot_get_display + * + * called by hal + * + * mpp_buf_slot_clr_hw_dst + * - mark a slot's buffer is already decoded by hardware + * - NOTE: this call will clear used as output flag + * + * mpp_buf_slot_dec_hw_ref + * - when hal finished on hardware decoding it MUST be called once for each used slot + */ +MPP_RET mpp_buf_slot_get_unused(MppBufSlots slots, RK_S32 *index); + +/* + * mpp_buf_slot_set_buffer + * - called by dec thread when find a output index has not buffer + * + * mpp_buf_slot_get_buffer + * - called by hal module on register generation + * + * mpp_buf_slot_get_display + * - called by hal thread to output a display slot's frame info + * NOTE: get display will generate a new MppFrame for external mpp_frame_deinit call + * So that external mpp_frame_deinit will not release the MppFrame used in buf_slot + */ + +/* + * NOTE: + * buffer slot will be used both for frame and packet + * when buffer slot is used for packet management only inc_hw_ref and dec_hw_ref is used + */ + +typedef enum SlotUsageType_e { + SLOT_CODEC_READY, // bit flag for buffer is prepared by codec + SLOT_CODEC_USE, // bit flag for buffer is used as reference by codec + SLOT_HAL_INPUT, // counter for buffer is used as hardware input + SLOT_HAL_OUTPUT, // counter + bit flag for buffer is used as hardware output + SLOT_QUEUE_USE, // bit flag for buffer is hold in different queues + SLOT_USAGE_BUTT, +} SlotUsageType; + +MPP_RET mpp_buf_slot_set_flag(MppBufSlots slots, RK_S32 index, SlotUsageType type); +MPP_RET mpp_buf_slot_clr_flag(MppBufSlots slots, RK_S32 index, SlotUsageType type); + +// TODO: can be extended here +typedef enum SlotQueueType_e { + QUEUE_OUTPUT, + QUEUE_DISPLAY, + QUEUE_DEINTERLACE, + QUEUE_COLOR_CONVERT, + QUEUE_BUTT, +} SlotQueueType; + +MPP_RET mpp_buf_slot_enqueue(MppBufSlots slots, RK_S32 index, SlotQueueType type); +MPP_RET mpp_buf_slot_dequeue(MppBufSlots slots, RK_S32 *index, SlotQueueType type); + +typedef enum SlotPropType_e { + SLOT_EOS, + SLOT_FRAME, + SLOT_BUFFER, + SLOT_FRAME_PTR, + SLOT_PROP_BUTT, +} SlotPropType; + +MPP_RET mpp_buf_slot_set_prop(MppBufSlots slots, RK_S32 index, SlotPropType type, void *val); +MPP_RET mpp_buf_slot_get_prop(MppBufSlots slots, RK_S32 index, SlotPropType type, void *val); + +typedef enum SlotsPropType_e { + SLOTS_EOS, + SLOTS_HOR_ALIGN, // input must be buf_align function pointer + SLOTS_VER_ALIGN, // input must be buf_align function pointer + SLOTS_LEN_ALIGN, + SLOTS_COUNT, + SLOTS_SIZE, + SLOTS_FRAME_INFO, + SLOTS_PROP_BUTT, +} SlotsPropType; + +typedef RK_U32 (*AlignFunc)(RK_U32 val); + +MPP_RET mpp_slots_set_prop(MppBufSlots slots, SlotsPropType type, void *val); +MPP_RET mpp_slots_get_prop(MppBufSlots slots, SlotsPropType type, void *val); +MPP_RET mpp_buf_slot_reset(MppBufSlots slots, RK_S32 index); //rest slot status when info_change no ok + +#ifdef __cplusplus +} +#endif + +#endif /*__MPP_BUF_SLOT_H__*/ diff --git a/mpp/base/inc/mpp_buffer_impl.h b/mpp/base/inc/mpp_buffer_impl.h index 96a4fd3b..4ac09cfa 100644 --- a/mpp/base/inc/mpp_buffer_impl.h +++ b/mpp/base/inc/mpp_buffer_impl.h @@ -1,154 +1,154 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __MPP_BUFFER_IMPL_H__ -#define __MPP_BUFFER_IMPL_H__ - -#include "mpp_list.h" -#include "mpp_common.h" -#include "mpp_allocator.h" - -#define MPP_BUF_DBG_FUNCTION (0x00000001) -#define MPP_BUF_DBG_OPS_RUNTIME (0x00000002) -#define MPP_BUF_DBG_OPS_HISTORY (0x00000004) -#define MPP_BUF_DBG_CLR_ON_EXIT (0x00000008) -#define MPP_BUF_DBG_CHECK_SIZE (0x00000010) - -#define mpp_buf_dbg(flag, fmt, ...) _mpp_dbg(mpp_buffer_debug, flag, fmt, ## __VA_ARGS__) -#define mpp_buf_dbg_f(flag, fmt, ...) _mpp_dbg_f(mpp_buffer_debug, flag, fmt, ## __VA_ARGS__) - -#define MPP_BUF_FUNCTION_ENTER() mpp_buf_dbg_f(MPP_BUF_DBG_FUNCTION, "enter\n") -#define MPP_BUF_FUNCTION_LEAVE() mpp_buf_dbg_f(MPP_BUF_DBG_FUNCTION, "leave\n") -#define MPP_BUF_FUNCTION_LEAVE_OK() mpp_buf_dbg_f(MPP_BUF_DBG_FUNCTION, "success\n") -#define MPP_BUF_FUNCTION_LEAVE_FAIL() mpp_buf_dbg_f(MPP_BUF_DBG_FUNCTION, "failed\n") - -typedef struct MppBufferImpl_t MppBufferImpl; -typedef struct MppBufferGroupImpl_t MppBufferGroupImpl; - -// use index instead of pointer to avoid invalid pointer -struct MppBufferImpl_t { - char tag[MPP_TAG_SIZE]; - const char *caller; - RK_U32 group_id; - RK_S32 buffer_id; - MppBufferMode mode; - - MppBufferInfo info; - - /* used for buf on group reset mode - set disard value to 1 when frame refcount no zero , - we will delay relesase buffer after refcount to zero, - not put this buf to unused list - */ - RK_S32 discard; - // used flag is for used/unused list detection - RK_U32 used; - RK_U32 internal; - RK_S32 ref_count; - struct list_head list_status; -}; - -struct MppBufferGroupImpl_t { - char tag[MPP_TAG_SIZE]; - const char *caller; - RK_U32 group_id; - MppBufferMode mode; - MppBufferType type; - // used in limit mode only - size_t limit_size; - RK_S32 limit_count; - // status record - size_t limit; - size_t usage; - RK_S32 buffer_id; - RK_S32 buffer_count; - RK_S32 count_used; - RK_S32 count_unused; - - MppAllocator allocator; - MppAllocatorApi *alloc_api; - - // thread that will be signal on buffer return - void *listener; - - // buffer force clear mode flag - RK_U32 clear_on_exit; - // is_orphan: 0 - normal group 1 - orphan group - RK_U32 is_orphan; - - // buffer log function - RK_U32 log_runtime_en; - RK_U32 log_history_en; - RK_U32 log_count; - struct list_head list_logs; - - // link to the other MppBufferGroupImpl - struct list_head list_group; - - // link to list_status in MppBufferImpl - struct list_head list_used; - struct list_head list_unused; -}; - -#ifdef __cplusplus -extern "C" { -#endif - -extern RK_U32 mpp_buffer_debug; - -/* - * mpp_buffer_create : create a unused buffer with parameter tag/size/data - * if input buffer is NULL then buffer will be register to unused list - * otherwise the buffer will be register to used list and set to paramter buffer - * - * mpp_buffer_destroy : destroy a buffer, it must be on unused status - * - * mpp_buffer_get_unused : get unused buffer with size. it will first search - * the unused list. if failed it will create on from - * group allocator. - * - * mpp_buffer_ref_inc : increase buffer's reference counter. if it is unused - * then it will be moved to used list. - * - * mpp_buffer_ref_dec : decrease buffer's reference counter. if the reference - * reduce to zero buffer will be moved to unused list. - * - * normal call flow will be like this: - * - * mpp_buffer_create - create a unused buffer - * mpp_buffer_get_unused - get the unused buffer - * mpp_buffer_ref_inc/dec - use the buffer - * mpp_buffer_destory - destroy the buffer - */ -MPP_RET mpp_buffer_create(const char *tag, const char *caller, MppBufferGroupImpl *group, MppBufferInfo *info, MppBufferImpl **buffer); -MPP_RET mpp_buffer_ref_inc(MppBufferImpl *buffer, const char* caller); -MPP_RET mpp_buffer_ref_dec(MppBufferImpl *buffer, const char* caller); -MppBufferImpl *mpp_buffer_get_unused(MppBufferGroupImpl *p, size_t size); - -MPP_RET mpp_buffer_group_init(MppBufferGroupImpl **group, const char *tag, const char *caller, MppBufferMode mode, MppBufferType type); -MPP_RET mpp_buffer_group_deinit(MppBufferGroupImpl *p); -MPP_RET mpp_buffer_group_reset(MppBufferGroupImpl *p); -MPP_RET mpp_buffer_group_set_listener(MppBufferGroupImpl *p, void *listener); -// mpp_buffer_group helper function -void mpp_buffer_group_dump(MppBufferGroupImpl *p); -void mpp_buffer_service_dump(); -MppBufferGroupImpl *mpp_buffer_get_misc_group(MppBufferMode mode, MppBufferType type); - -#ifdef __cplusplus -} -#endif - -#endif /*__MPP_BUFFER_IMPL_H__*/ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPP_BUFFER_IMPL_H__ +#define __MPP_BUFFER_IMPL_H__ + +#include "mpp_list.h" +#include "mpp_common.h" +#include "mpp_allocator.h" + +#define MPP_BUF_DBG_FUNCTION (0x00000001) +#define MPP_BUF_DBG_OPS_RUNTIME (0x00000002) +#define MPP_BUF_DBG_OPS_HISTORY (0x00000004) +#define MPP_BUF_DBG_CLR_ON_EXIT (0x00000008) +#define MPP_BUF_DBG_CHECK_SIZE (0x00000010) + +#define mpp_buf_dbg(flag, fmt, ...) _mpp_dbg(mpp_buffer_debug, flag, fmt, ## __VA_ARGS__) +#define mpp_buf_dbg_f(flag, fmt, ...) _mpp_dbg_f(mpp_buffer_debug, flag, fmt, ## __VA_ARGS__) + +#define MPP_BUF_FUNCTION_ENTER() mpp_buf_dbg_f(MPP_BUF_DBG_FUNCTION, "enter\n") +#define MPP_BUF_FUNCTION_LEAVE() mpp_buf_dbg_f(MPP_BUF_DBG_FUNCTION, "leave\n") +#define MPP_BUF_FUNCTION_LEAVE_OK() mpp_buf_dbg_f(MPP_BUF_DBG_FUNCTION, "success\n") +#define MPP_BUF_FUNCTION_LEAVE_FAIL() mpp_buf_dbg_f(MPP_BUF_DBG_FUNCTION, "failed\n") + +typedef struct MppBufferImpl_t MppBufferImpl; +typedef struct MppBufferGroupImpl_t MppBufferGroupImpl; + +// use index instead of pointer to avoid invalid pointer +struct MppBufferImpl_t { + char tag[MPP_TAG_SIZE]; + const char *caller; + RK_U32 group_id; + RK_S32 buffer_id; + MppBufferMode mode; + + MppBufferInfo info; + + /* used for buf on group reset mode + set disard value to 1 when frame refcount no zero , + we will delay relesase buffer after refcount to zero, + not put this buf to unused list + */ + RK_S32 discard; + // used flag is for used/unused list detection + RK_U32 used; + RK_U32 internal; + RK_S32 ref_count; + struct list_head list_status; +}; + +struct MppBufferGroupImpl_t { + char tag[MPP_TAG_SIZE]; + const char *caller; + RK_U32 group_id; + MppBufferMode mode; + MppBufferType type; + // used in limit mode only + size_t limit_size; + RK_S32 limit_count; + // status record + size_t limit; + size_t usage; + RK_S32 buffer_id; + RK_S32 buffer_count; + RK_S32 count_used; + RK_S32 count_unused; + + MppAllocator allocator; + MppAllocatorApi *alloc_api; + + // thread that will be signal on buffer return + void *listener; + + // buffer force clear mode flag + RK_U32 clear_on_exit; + // is_orphan: 0 - normal group 1 - orphan group + RK_U32 is_orphan; + + // buffer log function + RK_U32 log_runtime_en; + RK_U32 log_history_en; + RK_U32 log_count; + struct list_head list_logs; + + // link to the other MppBufferGroupImpl + struct list_head list_group; + + // link to list_status in MppBufferImpl + struct list_head list_used; + struct list_head list_unused; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +extern RK_U32 mpp_buffer_debug; + +/* + * mpp_buffer_create : create a unused buffer with parameter tag/size/data + * if input buffer is NULL then buffer will be register to unused list + * otherwise the buffer will be register to used list and set to paramter buffer + * + * mpp_buffer_destroy : destroy a buffer, it must be on unused status + * + * mpp_buffer_get_unused : get unused buffer with size. it will first search + * the unused list. if failed it will create on from + * group allocator. + * + * mpp_buffer_ref_inc : increase buffer's reference counter. if it is unused + * then it will be moved to used list. + * + * mpp_buffer_ref_dec : decrease buffer's reference counter. if the reference + * reduce to zero buffer will be moved to unused list. + * + * normal call flow will be like this: + * + * mpp_buffer_create - create a unused buffer + * mpp_buffer_get_unused - get the unused buffer + * mpp_buffer_ref_inc/dec - use the buffer + * mpp_buffer_destory - destroy the buffer + */ +MPP_RET mpp_buffer_create(const char *tag, const char *caller, MppBufferGroupImpl *group, MppBufferInfo *info, MppBufferImpl **buffer); +MPP_RET mpp_buffer_ref_inc(MppBufferImpl *buffer, const char* caller); +MPP_RET mpp_buffer_ref_dec(MppBufferImpl *buffer, const char* caller); +MppBufferImpl *mpp_buffer_get_unused(MppBufferGroupImpl *p, size_t size); + +MPP_RET mpp_buffer_group_init(MppBufferGroupImpl **group, const char *tag, const char *caller, MppBufferMode mode, MppBufferType type); +MPP_RET mpp_buffer_group_deinit(MppBufferGroupImpl *p); +MPP_RET mpp_buffer_group_reset(MppBufferGroupImpl *p); +MPP_RET mpp_buffer_group_set_listener(MppBufferGroupImpl *p, void *listener); +// mpp_buffer_group helper function +void mpp_buffer_group_dump(MppBufferGroupImpl *p); +void mpp_buffer_service_dump(); +MppBufferGroupImpl *mpp_buffer_get_misc_group(MppBufferMode mode, MppBufferType type); + +#ifdef __cplusplus +} +#endif + +#endif /*__MPP_BUFFER_IMPL_H__*/ diff --git a/mpp/base/inc/mpp_frame_impl.h b/mpp/base/inc/mpp_frame_impl.h index 70faa17c..5069be3b 100644 --- a/mpp/base/inc/mpp_frame_impl.h +++ b/mpp/base/inc/mpp_frame_impl.h @@ -1,113 +1,113 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __MPP_FRAME_IMPL_H__ -#define __MPP_FRAME_IMPL_H__ - -#include "mpp_frame.h" - -typedef struct MppFrameImpl_t MppFrameImpl; - -struct MppFrameImpl_t { - const char *name; - - /* - * dimension parameter for display - */ - RK_U32 width; - RK_U32 height; - RK_U32 hor_stride; - RK_U32 ver_stride; - - /* - * interlaced related mode status - * - * 0 - frame - * 1 - top field - * 2 - bottom field - * 3 - paired top and bottom field - * 4 - deinterlaced flag - * 7 - deinterlaced paired field - */ - RK_U32 mode; - /* - * current decoded frame whether to display - * - * 0 - reserve - * 1 - discard - */ - RK_U32 discard; - /* - * send decoded frame belong which view - */ - RK_U32 viewid; - /* - * poc - picture order count - */ - RK_U32 poc; - /* - * pts - display time stamp - * dts - decode time stamp - */ - RK_S64 pts; - RK_S64 dts; - - /* - * eos - end of stream - * info_change - set when buffer resized or frame infomation changed - */ - RK_U32 eos; - RK_U32 info_change; - RK_U32 errinfo; - MppFrameColorRange color_range; - MppFrameColorPrimaries color_primaries; - MppFrameColorTransferCharacteristic color_trc; - - /** - * YUV colorspace type. - * It must be accessed using av_frame_get_colorspace() and - * av_frame_set_colorspace(). - * - encoding: Set by user - * - decoding: Set by libavcodec - */ - MppFrameColorSpace colorspace; - MppFrameChromaLocation chroma_location; - - MppFrameFormat fmt; - /* - * buffer information - * NOTE: buf_size only access internally - */ - MppBuffer buffer; - size_t buf_size; - - /* - * pointer for multiple frame output at one time - */ - MppFrameImpl *next; -}; - - -size_t mpp_frame_get_buf_size(const MppFrame frame); -void mpp_frame_set_buf_size(MppFrame frame, size_t buf_size); - -MPP_RET mpp_frame_set_next(MppFrame frame, MppFrame next); -MPP_RET mpp_frame_copy(MppFrame frame, MppFrame next); -MPP_RET mpp_frame_info_cmp(MppFrame frame0, MppFrame frame1); - -MPP_RET check_is_mpp_frame(void *pointer); - -#endif /*__MPP_FRAME_IMPL_H__*/ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPP_FRAME_IMPL_H__ +#define __MPP_FRAME_IMPL_H__ + +#include "mpp_frame.h" + +typedef struct MppFrameImpl_t MppFrameImpl; + +struct MppFrameImpl_t { + const char *name; + + /* + * dimension parameter for display + */ + RK_U32 width; + RK_U32 height; + RK_U32 hor_stride; + RK_U32 ver_stride; + + /* + * interlaced related mode status + * + * 0 - frame + * 1 - top field + * 2 - bottom field + * 3 - paired top and bottom field + * 4 - deinterlaced flag + * 7 - deinterlaced paired field + */ + RK_U32 mode; + /* + * current decoded frame whether to display + * + * 0 - reserve + * 1 - discard + */ + RK_U32 discard; + /* + * send decoded frame belong which view + */ + RK_U32 viewid; + /* + * poc - picture order count + */ + RK_U32 poc; + /* + * pts - display time stamp + * dts - decode time stamp + */ + RK_S64 pts; + RK_S64 dts; + + /* + * eos - end of stream + * info_change - set when buffer resized or frame infomation changed + */ + RK_U32 eos; + RK_U32 info_change; + RK_U32 errinfo; + MppFrameColorRange color_range; + MppFrameColorPrimaries color_primaries; + MppFrameColorTransferCharacteristic color_trc; + + /** + * YUV colorspace type. + * It must be accessed using av_frame_get_colorspace() and + * av_frame_set_colorspace(). + * - encoding: Set by user + * - decoding: Set by libavcodec + */ + MppFrameColorSpace colorspace; + MppFrameChromaLocation chroma_location; + + MppFrameFormat fmt; + /* + * buffer information + * NOTE: buf_size only access internally + */ + MppBuffer buffer; + size_t buf_size; + + /* + * pointer for multiple frame output at one time + */ + MppFrameImpl *next; +}; + + +size_t mpp_frame_get_buf_size(const MppFrame frame); +void mpp_frame_set_buf_size(MppFrame frame, size_t buf_size); + +MPP_RET mpp_frame_set_next(MppFrame frame, MppFrame next); +MPP_RET mpp_frame_copy(MppFrame frame, MppFrame next); +MPP_RET mpp_frame_info_cmp(MppFrame frame0, MppFrame frame1); + +MPP_RET check_is_mpp_frame(void *pointer); + +#endif /*__MPP_FRAME_IMPL_H__*/ diff --git a/mpp/base/inc/mpp_packet_impl.h b/mpp/base/inc/mpp_packet_impl.h index 30dcfa7e..22f19c61 100644 --- a/mpp/base/inc/mpp_packet_impl.h +++ b/mpp/base/inc/mpp_packet_impl.h @@ -1,61 +1,61 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __MPP_IMPL_H__ -#define __MPP_IMPL_H__ - -#include "mpp_buffer.h" - -#define MPP_PACKET_FLAG_EOS (0x00000001) -#define MPP_PACKET_FLAG_EXTRA_DATA (0x00000002) -#define MPP_PACKET_FLAG_INTERNAL (0x00000004) -#define MPP_PACKET_FLAG_INTRA (0x00000008) - -/* - * mpp_packet_imp structure - * - * data : pointer - * size : total buffer size - * offset : valid data start offset - * length : valid data length - * pts : packet pts - * dts : packet dts - */ -typedef struct MppPacketImpl_t { - const char *name; - - void *data; - void *pos; - size_t size; - size_t length; - - RK_S64 pts; - RK_S64 dts; - - RK_U32 flag; - - MppBuffer buffer; -} MppPacketImpl; - -/* - * mpp_packet_reset is only used internelly and should NOT be used outside - */ -MPP_RET mpp_packet_reset(MppPacketImpl *packet); - -/* pointer check function */ -MPP_RET check_is_mpp_packet(void *ptr); - -#endif /*__MPP_IMPL_H__*/ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPP_IMPL_H__ +#define __MPP_IMPL_H__ + +#include "mpp_buffer.h" + +#define MPP_PACKET_FLAG_EOS (0x00000001) +#define MPP_PACKET_FLAG_EXTRA_DATA (0x00000002) +#define MPP_PACKET_FLAG_INTERNAL (0x00000004) +#define MPP_PACKET_FLAG_INTRA (0x00000008) + +/* + * mpp_packet_imp structure + * + * data : pointer + * size : total buffer size + * offset : valid data start offset + * length : valid data length + * pts : packet pts + * dts : packet dts + */ +typedef struct MppPacketImpl_t { + const char *name; + + void *data; + void *pos; + size_t size; + size_t length; + + RK_S64 pts; + RK_S64 dts; + + RK_U32 flag; + + MppBuffer buffer; +} MppPacketImpl; + +/* + * mpp_packet_reset is only used internelly and should NOT be used outside + */ +MPP_RET mpp_packet_reset(MppPacketImpl *packet); + +/* pointer check function */ +MPP_RET check_is_mpp_packet(void *ptr); + +#endif /*__MPP_IMPL_H__*/ diff --git a/mpp/base/inc/mpp_task_impl.h b/mpp/base/inc/mpp_task_impl.h index 24633b9f..a7648255 100644 --- a/mpp/base/inc/mpp_task_impl.h +++ b/mpp/base/inc/mpp_task_impl.h @@ -1,82 +1,82 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __MPP_TASK_IMPL_H__ -#define __MPP_TASK_IMPL_H__ - -#include "mpp_list.h" -#include "mpp_task.h" - -/* - * mpp task status transaction - * - * mpp task is generated from mpp port. When create a mpp port the corresponding task - * will be created, too. Then external user will dequeue task from port and enqueue to - * mpp port for process. - * - * input port task work flow: - * - * description | call | status transaction - * 1. input port init | enqueue(external) | -> external_queue - * 2. input port user dequeue | dequeue(external) | external_queue -> external_hold - * 3. user setup task for processing| | - * 4. input port user enqueue | enqueue(external) | external_hold -> internal_queue - * 5. input port mpp start process | dequeue(internal) | internal_queue -> internal_hold - * 6. mpp process task | | - * 7. input port mpp task finish | enqueue(internal) | internal_hold -> external_queue - * loop to 2 - * - * output port task work flow: - * description | call | status transaction - * 1. output port init | enqueue(internal) | -> internal_queue - * 2. output port mpp task dequeue | dequeue(internal) | internal_queue -> internal_hold - * 3. mpp setup task by processed frame/packet | - * 4. output port mpp task enqueue | enqueue(internal) | internal_hold -> external_queue - * 5. output port user task dequeue | dequeue(external) | external_queue -> external_hold - * 6. user get task as output | | - * 7. output port user release task | enqueue(external) | external_hold -> external_queue - * loop to 2 - * - */ -typedef enum MppTaskStatus_e { - MPP_INPUT_PORT, /* in external queue and ready for external dequeue */ - MPP_INPUT_HOLD, /* dequeued and hold by external user, user will config */ - MPP_OUTPUT_PORT, /* in mpp internal work queue and ready for mpp dequeue */ - MPP_OUTPUT_HOLD, /* dequeued and hold by mpp internal worker, mpp is processing */ - MPP_TASK_STATUS_BUTT, -} MppTaskStatus; - -typedef struct MppTaskImpl_t { - const char *name; - struct list_head list; - MppTaskQueue *queue; - RK_S32 index; - MppTaskStatus status; - - MppMeta meta; -} MppTaskImpl; - -#ifdef __cplusplus -extern "C" { -#endif - -MPP_RET check_mpp_task_name(MppTask task); - -#ifdef __cplusplus -} -#endif - -#endif /*__MPP_TASK_IMPL_H__*/ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPP_TASK_IMPL_H__ +#define __MPP_TASK_IMPL_H__ + +#include "mpp_list.h" +#include "mpp_task.h" + +/* + * mpp task status transaction + * + * mpp task is generated from mpp port. When create a mpp port the corresponding task + * will be created, too. Then external user will dequeue task from port and enqueue to + * mpp port for process. + * + * input port task work flow: + * + * description | call | status transaction + * 1. input port init | enqueue(external) | -> external_queue + * 2. input port user dequeue | dequeue(external) | external_queue -> external_hold + * 3. user setup task for processing| | + * 4. input port user enqueue | enqueue(external) | external_hold -> internal_queue + * 5. input port mpp start process | dequeue(internal) | internal_queue -> internal_hold + * 6. mpp process task | | + * 7. input port mpp task finish | enqueue(internal) | internal_hold -> external_queue + * loop to 2 + * + * output port task work flow: + * description | call | status transaction + * 1. output port init | enqueue(internal) | -> internal_queue + * 2. output port mpp task dequeue | dequeue(internal) | internal_queue -> internal_hold + * 3. mpp setup task by processed frame/packet | + * 4. output port mpp task enqueue | enqueue(internal) | internal_hold -> external_queue + * 5. output port user task dequeue | dequeue(external) | external_queue -> external_hold + * 6. user get task as output | | + * 7. output port user release task | enqueue(external) | external_hold -> external_queue + * loop to 2 + * + */ +typedef enum MppTaskStatus_e { + MPP_INPUT_PORT, /* in external queue and ready for external dequeue */ + MPP_INPUT_HOLD, /* dequeued and hold by external user, user will config */ + MPP_OUTPUT_PORT, /* in mpp internal work queue and ready for mpp dequeue */ + MPP_OUTPUT_HOLD, /* dequeued and hold by mpp internal worker, mpp is processing */ + MPP_TASK_STATUS_BUTT, +} MppTaskStatus; + +typedef struct MppTaskImpl_t { + const char *name; + struct list_head list; + MppTaskQueue *queue; + RK_S32 index; + MppTaskStatus status; + + MppMeta meta; +} MppTaskImpl; + +#ifdef __cplusplus +extern "C" { +#endif + +MPP_RET check_mpp_task_name(MppTask task); + +#ifdef __cplusplus +} +#endif + +#endif /*__MPP_TASK_IMPL_H__*/ diff --git a/mpp/base/mpp_bitput.c b/mpp/base/mpp_bitput.c index d2c31247..37896cea 100644 --- a/mpp/base/mpp_bitput.c +++ b/mpp/base/mpp_bitput.c @@ -1,76 +1,76 @@ -/* - * - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include "mpp_bitput.h" - -RK_S32 mpp_set_bitput_ctx(BitputCtx_t *bp, RK_U64 *data, RK_U32 len) -{ - memset(bp, 0, sizeof(BitputCtx_t)); - bp->index = 0; - bp->bitpos = 0; - bp->bvalue = 0; - bp->size = len; - bp->buflen = len; // align 64bit - bp->pbuf = data; - return 0; -} - -void mpp_put_bits(BitputCtx_t *bp, RK_U64 invalue, RK_S32 lbits) -{ - RK_U8 hbits = 0; - - if (!lbits) return; - - if (bp->index >= bp->buflen) return; - - hbits = 64 - lbits; - invalue = (invalue << hbits) >> hbits; - bp->bvalue |= invalue << bp->bitpos; // high bits value - if ((bp->bitpos + lbits) >= 64) { - bp->pbuf[bp->index] = bp->bvalue; - bp->bvalue = invalue >> (64 - bp->bitpos); // low bits value - bp->index++; - } - bp->pbuf[bp->index] = bp->bvalue; - bp->bitpos = (bp->bitpos + lbits) & 63; - // mpp_log("bp->index = %d bp->bitpos = %d lbits = %d invalue 0x%x bp->hvalue 0x%x bp->lvalue 0x%x",bp->index,bp->bitpos,lbits, (RK_U32)invalue,(RK_U32)(bp->bvalue >> 32),(RK_U32)bp->bvalue); -} - -void mpp_put_align(BitputCtx_t *bp, RK_S32 align_bits, int flag) -{ - RK_U32 word_offset = 0, len = 0; - - word_offset = (align_bits >= 64) ? ((bp->index & (((align_bits & 0xfe0) >> 6) - 1)) << 6) : 0; - len = (align_bits - (word_offset + (bp->bitpos % align_bits))) % align_bits; - while (len > 0) { - if (len >= 8) { - if (flag == 0) - mpp_put_bits(bp, ((RK_U64)0 << (64 - 8)) >> (64 - 8), 8); - else - mpp_put_bits(bp, (0xffffffffffffffff << (64 - 8)) >> (64 - 8), 8); - len -= 8; - } else { - if (flag == 0) - mpp_put_bits(bp, ((RK_U64)0 << (64 - len)) >> (64 - len), len); - else - mpp_put_bits(bp, (0xffffffffffffffff << (64 - len)) >> (64 - len), len); - len -= len; - } - } -} - +/* + * + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "mpp_bitput.h" + +RK_S32 mpp_set_bitput_ctx(BitputCtx_t *bp, RK_U64 *data, RK_U32 len) +{ + memset(bp, 0, sizeof(BitputCtx_t)); + bp->index = 0; + bp->bitpos = 0; + bp->bvalue = 0; + bp->size = len; + bp->buflen = len; // align 64bit + bp->pbuf = data; + return 0; +} + +void mpp_put_bits(BitputCtx_t *bp, RK_U64 invalue, RK_S32 lbits) +{ + RK_U8 hbits = 0; + + if (!lbits) return; + + if (bp->index >= bp->buflen) return; + + hbits = 64 - lbits; + invalue = (invalue << hbits) >> hbits; + bp->bvalue |= invalue << bp->bitpos; // high bits value + if ((bp->bitpos + lbits) >= 64) { + bp->pbuf[bp->index] = bp->bvalue; + bp->bvalue = invalue >> (64 - bp->bitpos); // low bits value + bp->index++; + } + bp->pbuf[bp->index] = bp->bvalue; + bp->bitpos = (bp->bitpos + lbits) & 63; + // mpp_log("bp->index = %d bp->bitpos = %d lbits = %d invalue 0x%x bp->hvalue 0x%x bp->lvalue 0x%x",bp->index,bp->bitpos,lbits, (RK_U32)invalue,(RK_U32)(bp->bvalue >> 32),(RK_U32)bp->bvalue); +} + +void mpp_put_align(BitputCtx_t *bp, RK_S32 align_bits, int flag) +{ + RK_U32 word_offset = 0, len = 0; + + word_offset = (align_bits >= 64) ? ((bp->index & (((align_bits & 0xfe0) >> 6) - 1)) << 6) : 0; + len = (align_bits - (word_offset + (bp->bitpos % align_bits))) % align_bits; + while (len > 0) { + if (len >= 8) { + if (flag == 0) + mpp_put_bits(bp, ((RK_U64)0 << (64 - 8)) >> (64 - 8), 8); + else + mpp_put_bits(bp, (0xffffffffffffffff << (64 - 8)) >> (64 - 8), 8); + len -= 8; + } else { + if (flag == 0) + mpp_put_bits(bp, ((RK_U64)0 << (64 - len)) >> (64 - len), len); + else + mpp_put_bits(bp, (0xffffffffffffffff << (64 - len)) >> (64 - len), len); + len -= len; + } + } +} + diff --git a/mpp/base/mpp_bitread.c b/mpp/base/mpp_bitread.c index ba0b7f80..e606597e 100644 --- a/mpp/base/mpp_bitread.c +++ b/mpp/base/mpp_bitread.c @@ -1,307 +1,307 @@ -/* -* -* Copyright 2015 Rockchip Electronics Co. LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#include -#include -#include "rk_type.h" -#include "mpp_mem.h" -#include "mpp_bitread.h" - -static void log_info(void *ctx, ...) -{ - (void)ctx; -} - -static MPP_RET update_curbyte(BitReadCtx_t *bitctx) -{ - if (bitctx->bytes_left_ < 1) - return MPP_ERR_READ_BIT; - - // Emulation prevention three-byte detection. - // If a sequence of 0x000003 is found, skip (ignore) the last byte (0x03). - if (bitctx->need_prevention_detection - && (*bitctx->data_ == 0x03) - && ((bitctx->prev_two_bytes_ & 0xffff) == 0)) { - // Detected 0x000003, skip last byte. - ++bitctx->data_; - --bitctx->bytes_left_; - ++bitctx->emulation_prevention_bytes_; - // Need another full three bytes before we can detect the sequence again. - bitctx->prev_two_bytes_ = 0xffff; - if (bitctx->bytes_left_ < 1) - return MPP_ERR_READ_BIT; - } - // Load a new byte and advance pointers. - bitctx->curr_byte_ = *bitctx->data_++ & 0xff; - --bitctx->bytes_left_; - bitctx->num_remaining_bits_in_curr_byte_ = 8; - bitctx->prev_two_bytes_ = (bitctx->prev_two_bytes_ << 8) | bitctx->curr_byte_; - - return MPP_OK; -} - -/*! -*********************************************************************** -* \brief -* Read |num_bits| (1 to 31 inclusive) from the stream and return them -* in |out|, with first bit in the stream as MSB in |out| at position -* (|num_bits| - 1) -*********************************************************************** -*/ -MPP_RET mpp_read_bits(BitReadCtx_t *bitctx, RK_S32 num_bits, RK_S32 *out) -{ - RK_S32 bits_left = num_bits; - *out = 0; - if (num_bits > 31) { - return MPP_ERR_READ_BIT; - } - while (bitctx->num_remaining_bits_in_curr_byte_ < bits_left) { - // Take all that's left in current byte, shift to make space for the rest. - *out |= (bitctx->curr_byte_ << (bits_left - bitctx->num_remaining_bits_in_curr_byte_)); - bits_left -= bitctx->num_remaining_bits_in_curr_byte_; - if (update_curbyte(bitctx)) { - return MPP_ERR_READ_BIT; - } - } - *out |= (bitctx->curr_byte_ >> (bitctx->num_remaining_bits_in_curr_byte_ - bits_left)); - *out &= ((1 << num_bits) - 1); - bitctx->num_remaining_bits_in_curr_byte_ -= bits_left; - bitctx->used_bits += num_bits; - - return MPP_OK; -} -/*! -*********************************************************************** -* \brief -* read more than 32 bits data -*********************************************************************** -*/ -MPP_RET mpp_read_longbits(BitReadCtx_t *bitctx, RK_S32 num_bits, RK_U32 *out) -{ - RK_S32 val = 0, val1 = 0; - if (mpp_read_bits(bitctx, 16, &val)) { - return MPP_ERR_READ_BIT; - } - if (mpp_read_bits(bitctx, (num_bits - 16), &val1)) { - return MPP_ERR_READ_BIT; - } - val = val << 16; - *out = (RK_U32)(val | val1); - - return MPP_OK; -} -/*! -*********************************************************************** -* \brief -* skip bits (0 - 31) -*********************************************************************** -*/ -MPP_RET mpp_skip_bits(BitReadCtx_t *bitctx, RK_S32 num_bits) -{ - RK_S32 bits_left = num_bits; - - while (bitctx->num_remaining_bits_in_curr_byte_ < bits_left) { - // Take all that's left in current byte, shift to make space for the rest. - bits_left -= bitctx->num_remaining_bits_in_curr_byte_; - if (update_curbyte(bitctx)) { - return MPP_ERR_READ_BIT; - } - } - bitctx->num_remaining_bits_in_curr_byte_ -= bits_left; - bitctx->used_bits += num_bits; - - return MPP_OK; -} -/*! -*********************************************************************** -* \brief -* skip bits long (0 - 32) -*********************************************************************** -*/ -MPP_RET mpp_skip_longbits(BitReadCtx_t *bitctx, RK_S32 num_bits) -{ - if (mpp_skip_bits(bitctx, 16)) { - return MPP_ERR_READ_BIT; - } - if (mpp_skip_bits(bitctx, (num_bits - 16))) { - return MPP_ERR_READ_BIT; - } - return MPP_OK; -} -/*! -*********************************************************************** -* \brief -* show bits (0 - 31) -*********************************************************************** -*/ -MPP_RET mpp_show_bits(BitReadCtx_t *bitctx, RK_S32 num_bits, RK_S32 *out) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - BitReadCtx_t tmp_ctx = *bitctx; - if (num_bits <= 31) - ret = mpp_read_bits(bitctx, num_bits, out); - else - ret = mpp_read_longbits(bitctx, num_bits, (RK_U32*)out); - memcpy(bitctx, &tmp_ctx, sizeof(BitReadCtx_t)); - - return ret; -} -/*! -*********************************************************************** -* \brief -* show long bits (0 - 32) -*********************************************************************** -*/ -MPP_RET mpp_show_longbits(BitReadCtx_t *bitctx, RK_S32 num_bits, RK_U32 *out) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - BitReadCtx_t tmp_ctx = *bitctx; - - ret = mpp_read_longbits(bitctx, num_bits, out); - memcpy(bitctx, &tmp_ctx, sizeof(BitReadCtx_t)); - - return ret; -} -/*! -*********************************************************************** -* \brief -* read unsigned data -*********************************************************************** -*/ -MPP_RET mpp_read_ue(BitReadCtx_t *bitctx, RK_U32 *val) -{ - RK_S32 num_bits = -1; - RK_S32 bit; - RK_S32 rest; - // Count the number of contiguous zero bits. - do { - if (mpp_read_bits(bitctx, 1, &bit)) { - return MPP_ERR_READ_BIT; - } - num_bits++; - } while (bit == 0); - if (num_bits > 31) { - return MPP_ERR_READ_BIT; - } - // Calculate exp-Golomb code value of size num_bits. - *val = (1 << num_bits) - 1; - if (num_bits > 0) { - if (mpp_read_bits(bitctx, num_bits, &rest)) { - return MPP_ERR_READ_BIT; - } - *val += rest; - } - - return MPP_OK; -} -/*! -*********************************************************************** -* \brief -* read signed data -*********************************************************************** -*/ -MPP_RET mpp_read_se(BitReadCtx_t *bitctx, RK_S32 *val) -{ - RK_U32 ue; - - if (mpp_read_ue(bitctx, &ue)) { - return MPP_ERR_READ_BIT; - } - if (ue % 2 == 0) { // odd - *val = -(RK_S32)(ue >> 1); - } else { - *val = (RK_S32)((ue >> 1) + 1); - } - return MPP_OK; -} - -/*! -*********************************************************************** -* \brief -* check whether has more rbsp data -*********************************************************************** -*/ -RK_U32 mpp_has_more_rbsp_data(BitReadCtx_t *bitctx) -{ - // Make sure we have more bits, if we are at 0 bits in current byte - // and updating current byte fails, we don't have more data anyway. - if (bitctx->num_remaining_bits_in_curr_byte_ == 0 && update_curbyte(bitctx)) - return 0; - // On last byte? - if (bitctx->bytes_left_) - return 1; - // Last byte, look for stop bit; - // We have more RBSP data if the last non-zero bit we find is not the - // first available bit. - return (bitctx->curr_byte_ & - ((1 << (bitctx->num_remaining_bits_in_curr_byte_ - 1)) - 1)) != 0; -} -/*! -*********************************************************************** -* \brief -* initialize bit read context -*********************************************************************** -*/ -void mpp_set_bitread_ctx(BitReadCtx_t *bitctx, RK_U8 *data, RK_S32 size) -{ - memset(bitctx, 0, sizeof(BitReadCtx_t)); - bitctx->data_ = data; - bitctx->bytes_left_ = size; - bitctx->num_remaining_bits_in_curr_byte_ = 0; - // Initially set to 0xffff to accept all initial two-byte sequences. - bitctx->prev_two_bytes_ = 0xffff; - bitctx->emulation_prevention_bytes_ = 0; - // add - bitctx->buf = data; - bitctx->buf_len = size; - bitctx->used_bits = 0; - bitctx->wlog = log_info; - bitctx->need_prevention_detection = 0; -} -/*! -*********************************************************************** -* \brief -* set whether detect 0x03 for h264 and h265 -*********************************************************************** -*/ -void mpp_set_pre_detection(BitReadCtx_t *bitctx) -{ - bitctx->need_prevention_detection = 1; -} -/*! -*********************************************************************** -* \brief -* align data and get current point -*********************************************************************** -*/ -RK_U8 *mpp_align_get_bits(BitReadCtx_t *bitctx) -{ - int n = bitctx->num_remaining_bits_in_curr_byte_; - if (n) - mpp_skip_bits(bitctx, n); - return bitctx->data_; -} -/*! -*********************************************************************** -* \brief -* get current data value -*********************************************************************** -*/ -RK_U8 mpp_get_curdata_value(BitReadCtx_t *bitctx) -{ - return (*bitctx->data_); -} +/* +* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include +#include +#include "rk_type.h" +#include "mpp_mem.h" +#include "mpp_bitread.h" + +static void log_info(void *ctx, ...) +{ + (void)ctx; +} + +static MPP_RET update_curbyte(BitReadCtx_t *bitctx) +{ + if (bitctx->bytes_left_ < 1) + return MPP_ERR_READ_BIT; + + // Emulation prevention three-byte detection. + // If a sequence of 0x000003 is found, skip (ignore) the last byte (0x03). + if (bitctx->need_prevention_detection + && (*bitctx->data_ == 0x03) + && ((bitctx->prev_two_bytes_ & 0xffff) == 0)) { + // Detected 0x000003, skip last byte. + ++bitctx->data_; + --bitctx->bytes_left_; + ++bitctx->emulation_prevention_bytes_; + // Need another full three bytes before we can detect the sequence again. + bitctx->prev_two_bytes_ = 0xffff; + if (bitctx->bytes_left_ < 1) + return MPP_ERR_READ_BIT; + } + // Load a new byte and advance pointers. + bitctx->curr_byte_ = *bitctx->data_++ & 0xff; + --bitctx->bytes_left_; + bitctx->num_remaining_bits_in_curr_byte_ = 8; + bitctx->prev_two_bytes_ = (bitctx->prev_two_bytes_ << 8) | bitctx->curr_byte_; + + return MPP_OK; +} + +/*! +*********************************************************************** +* \brief +* Read |num_bits| (1 to 31 inclusive) from the stream and return them +* in |out|, with first bit in the stream as MSB in |out| at position +* (|num_bits| - 1) +*********************************************************************** +*/ +MPP_RET mpp_read_bits(BitReadCtx_t *bitctx, RK_S32 num_bits, RK_S32 *out) +{ + RK_S32 bits_left = num_bits; + *out = 0; + if (num_bits > 31) { + return MPP_ERR_READ_BIT; + } + while (bitctx->num_remaining_bits_in_curr_byte_ < bits_left) { + // Take all that's left in current byte, shift to make space for the rest. + *out |= (bitctx->curr_byte_ << (bits_left - bitctx->num_remaining_bits_in_curr_byte_)); + bits_left -= bitctx->num_remaining_bits_in_curr_byte_; + if (update_curbyte(bitctx)) { + return MPP_ERR_READ_BIT; + } + } + *out |= (bitctx->curr_byte_ >> (bitctx->num_remaining_bits_in_curr_byte_ - bits_left)); + *out &= ((1 << num_bits) - 1); + bitctx->num_remaining_bits_in_curr_byte_ -= bits_left; + bitctx->used_bits += num_bits; + + return MPP_OK; +} +/*! +*********************************************************************** +* \brief +* read more than 32 bits data +*********************************************************************** +*/ +MPP_RET mpp_read_longbits(BitReadCtx_t *bitctx, RK_S32 num_bits, RK_U32 *out) +{ + RK_S32 val = 0, val1 = 0; + if (mpp_read_bits(bitctx, 16, &val)) { + return MPP_ERR_READ_BIT; + } + if (mpp_read_bits(bitctx, (num_bits - 16), &val1)) { + return MPP_ERR_READ_BIT; + } + val = val << 16; + *out = (RK_U32)(val | val1); + + return MPP_OK; +} +/*! +*********************************************************************** +* \brief +* skip bits (0 - 31) +*********************************************************************** +*/ +MPP_RET mpp_skip_bits(BitReadCtx_t *bitctx, RK_S32 num_bits) +{ + RK_S32 bits_left = num_bits; + + while (bitctx->num_remaining_bits_in_curr_byte_ < bits_left) { + // Take all that's left in current byte, shift to make space for the rest. + bits_left -= bitctx->num_remaining_bits_in_curr_byte_; + if (update_curbyte(bitctx)) { + return MPP_ERR_READ_BIT; + } + } + bitctx->num_remaining_bits_in_curr_byte_ -= bits_left; + bitctx->used_bits += num_bits; + + return MPP_OK; +} +/*! +*********************************************************************** +* \brief +* skip bits long (0 - 32) +*********************************************************************** +*/ +MPP_RET mpp_skip_longbits(BitReadCtx_t *bitctx, RK_S32 num_bits) +{ + if (mpp_skip_bits(bitctx, 16)) { + return MPP_ERR_READ_BIT; + } + if (mpp_skip_bits(bitctx, (num_bits - 16))) { + return MPP_ERR_READ_BIT; + } + return MPP_OK; +} +/*! +*********************************************************************** +* \brief +* show bits (0 - 31) +*********************************************************************** +*/ +MPP_RET mpp_show_bits(BitReadCtx_t *bitctx, RK_S32 num_bits, RK_S32 *out) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + BitReadCtx_t tmp_ctx = *bitctx; + if (num_bits <= 31) + ret = mpp_read_bits(bitctx, num_bits, out); + else + ret = mpp_read_longbits(bitctx, num_bits, (RK_U32*)out); + memcpy(bitctx, &tmp_ctx, sizeof(BitReadCtx_t)); + + return ret; +} +/*! +*********************************************************************** +* \brief +* show long bits (0 - 32) +*********************************************************************** +*/ +MPP_RET mpp_show_longbits(BitReadCtx_t *bitctx, RK_S32 num_bits, RK_U32 *out) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + BitReadCtx_t tmp_ctx = *bitctx; + + ret = mpp_read_longbits(bitctx, num_bits, out); + memcpy(bitctx, &tmp_ctx, sizeof(BitReadCtx_t)); + + return ret; +} +/*! +*********************************************************************** +* \brief +* read unsigned data +*********************************************************************** +*/ +MPP_RET mpp_read_ue(BitReadCtx_t *bitctx, RK_U32 *val) +{ + RK_S32 num_bits = -1; + RK_S32 bit; + RK_S32 rest; + // Count the number of contiguous zero bits. + do { + if (mpp_read_bits(bitctx, 1, &bit)) { + return MPP_ERR_READ_BIT; + } + num_bits++; + } while (bit == 0); + if (num_bits > 31) { + return MPP_ERR_READ_BIT; + } + // Calculate exp-Golomb code value of size num_bits. + *val = (1 << num_bits) - 1; + if (num_bits > 0) { + if (mpp_read_bits(bitctx, num_bits, &rest)) { + return MPP_ERR_READ_BIT; + } + *val += rest; + } + + return MPP_OK; +} +/*! +*********************************************************************** +* \brief +* read signed data +*********************************************************************** +*/ +MPP_RET mpp_read_se(BitReadCtx_t *bitctx, RK_S32 *val) +{ + RK_U32 ue; + + if (mpp_read_ue(bitctx, &ue)) { + return MPP_ERR_READ_BIT; + } + if (ue % 2 == 0) { // odd + *val = -(RK_S32)(ue >> 1); + } else { + *val = (RK_S32)((ue >> 1) + 1); + } + return MPP_OK; +} + +/*! +*********************************************************************** +* \brief +* check whether has more rbsp data +*********************************************************************** +*/ +RK_U32 mpp_has_more_rbsp_data(BitReadCtx_t *bitctx) +{ + // Make sure we have more bits, if we are at 0 bits in current byte + // and updating current byte fails, we don't have more data anyway. + if (bitctx->num_remaining_bits_in_curr_byte_ == 0 && update_curbyte(bitctx)) + return 0; + // On last byte? + if (bitctx->bytes_left_) + return 1; + // Last byte, look for stop bit; + // We have more RBSP data if the last non-zero bit we find is not the + // first available bit. + return (bitctx->curr_byte_ & + ((1 << (bitctx->num_remaining_bits_in_curr_byte_ - 1)) - 1)) != 0; +} +/*! +*********************************************************************** +* \brief +* initialize bit read context +*********************************************************************** +*/ +void mpp_set_bitread_ctx(BitReadCtx_t *bitctx, RK_U8 *data, RK_S32 size) +{ + memset(bitctx, 0, sizeof(BitReadCtx_t)); + bitctx->data_ = data; + bitctx->bytes_left_ = size; + bitctx->num_remaining_bits_in_curr_byte_ = 0; + // Initially set to 0xffff to accept all initial two-byte sequences. + bitctx->prev_two_bytes_ = 0xffff; + bitctx->emulation_prevention_bytes_ = 0; + // add + bitctx->buf = data; + bitctx->buf_len = size; + bitctx->used_bits = 0; + bitctx->wlog = log_info; + bitctx->need_prevention_detection = 0; +} +/*! +*********************************************************************** +* \brief +* set whether detect 0x03 for h264 and h265 +*********************************************************************** +*/ +void mpp_set_pre_detection(BitReadCtx_t *bitctx) +{ + bitctx->need_prevention_detection = 1; +} +/*! +*********************************************************************** +* \brief +* align data and get current point +*********************************************************************** +*/ +RK_U8 *mpp_align_get_bits(BitReadCtx_t *bitctx) +{ + int n = bitctx->num_remaining_bits_in_curr_byte_; + if (n) + mpp_skip_bits(bitctx, n); + return bitctx->data_; +} +/*! +*********************************************************************** +* \brief +* get current data value +*********************************************************************** +*/ +RK_U8 mpp_get_curdata_value(BitReadCtx_t *bitctx) +{ + return (*bitctx->data_); +} diff --git a/mpp/base/mpp_buf_slot.cpp b/mpp/base/mpp_buf_slot.cpp index b740a50e..477d0fb2 100644 --- a/mpp/base/mpp_buf_slot.cpp +++ b/mpp/base/mpp_buf_slot.cpp @@ -1,994 +1,994 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define MODULE_TAG "mpp_buf_slot" - -#include - -#include "mpp_log.h" -#include "mpp_mem.h" -#include "mpp_env.h" -#include "mpp_list.h" -#include "mpp_common.h" - -#include "mpp_frame_impl.h" -#include "mpp_buf_slot.h" - - -#define BUF_SLOT_DBG_FUNCTION (0x00000001) -#define BUF_SLOT_DBG_SETUP (0x00000002) -#define BUF_SLOT_DBG_INFO_CHANGE (0x00000004) -#define BUF_SLOT_DBG_OPS_RUNTIME (0x00000010) -#define BUF_SLOT_DBG_BUFFER (0x00000100) -#define BUF_SLOT_DBG_FRAME (0x00000200) -#define BUF_SLOT_DBG_BUF_UESD (0x00000400) -#define BUF_SLOT_DBG_OPS_HISTORY (0x10000000) -#define BUF_SLOT_DBG_ALL (0x10000011) - -#define buf_slot_dbg(flag, fmt, ...) _mpp_dbg(buf_slot_debug, flag, fmt, ## __VA_ARGS__) - -static RK_U32 buf_slot_debug = 0; -static RK_U32 buf_slot_idx = 0; - -#define slot_assert(impl, cond) do { \ - if (!(cond)) { \ - dump_slots(impl); \ - mpp_err("Assertion %s failed at %s:%d\n", \ - MPP_STRINGS(cond), __FUNCTION__, __LINE__); \ - abort(); \ - } \ -} while (0) - -typedef struct MppBufSlotEntry_t MppBufSlotEntry; -typedef struct MppBufSlotsImpl_t MppBufSlotsImpl; - -#define SLOT_OPS_MAX_COUNT 1024 - -typedef enum MppBufSlotOps_e { - // status opertaion - SLOT_INIT, - SLOT_SET_ON_USE, - SLOT_CLR_ON_USE, - SLOT_SET_NOT_READY, - SLOT_CLR_NOT_READY, - SLOT_SET_CODEC_READY, - SLOT_CLR_CODEC_READY, - SLOT_SET_CODEC_USE, - SLOT_CLR_CODEC_USE, - SLOT_SET_HAL_INPUT, - SLOT_CLR_HAL_INPUT, - SLOT_SET_HAL_OUTPUT, - SLOT_CLR_HAL_OUTPUT, - SLOT_SET_QUEUE_USE, - SLOT_CLR_QUEUE_USE, - - // queue operation - SLOT_ENQUEUE, - SLOT_DEQUEUE, - - // value operation - SLOT_SET_EOS, - SLOT_CLR_EOS, - SLOT_SET_FRAME, - SLOT_CLR_FRAME, - SLOT_SET_BUFFER, - SLOT_CLR_BUFFER, -} MppBufSlotOps; - -static const char op_string[][16] = { - "init ", - "set on use ", - "clr on use ", - "set not ready ", - "set ready ", - "set codec ready", - "clr codec ready", - "set codec use ", - "clr codec use ", - "set hal input ", - "clr hal input ", - "set hal output ", - "clr hal output ", - "set queue use ", - "clr queue use ", - - "enqueue display", - "dequeue display", - - "set eos ", - "clr eos ", - "set frame ", - "clr frame ", - "set buffer ", - "clr buffer ", -}; - -static const MppBufSlotOps set_flag_op[SLOT_USAGE_BUTT] = { - SLOT_SET_CODEC_READY, - SLOT_SET_CODEC_USE, - SLOT_SET_HAL_INPUT, - SLOT_SET_HAL_OUTPUT, - SLOT_SET_QUEUE_USE, -}; - -static const MppBufSlotOps clr_flag_op[SLOT_USAGE_BUTT] = { - SLOT_CLR_CODEC_READY, - SLOT_CLR_CODEC_USE, - SLOT_CLR_HAL_INPUT, - SLOT_CLR_HAL_OUTPUT, - SLOT_CLR_QUEUE_USE, -}; - -static const MppBufSlotOps set_val_op[SLOT_PROP_BUTT] = { - SLOT_SET_EOS, - SLOT_SET_FRAME, - SLOT_SET_BUFFER, -}; - -static const MppBufSlotOps clr_val_op[SLOT_PROP_BUTT] = { - SLOT_CLR_EOS, - SLOT_CLR_FRAME, - SLOT_CLR_BUFFER, -}; - -typedef union SlotStatus_u { - RK_U32 val; - struct { - // status flags - RK_U32 on_used : 1; - RK_U32 not_ready : 1; // buffer slot is filled or not - RK_U32 codec_use : 1; // buffer slot is used by codec ( dpb reference ) - RK_U32 hal_output : 1; // buffer slot is set to hw output will ready when hw done - RK_U32 hal_use : 8; // buffer slot is used by hardware - RK_U32 queue_use : 5; // buffer slot is used in different queue - - // value flags - RK_U32 eos : 1; // buffer slot is last buffer slot from codec - RK_U32 has_buffer : 1; - RK_U32 has_frame : 1; - }; -} SlotStatus; - -typedef struct MppBufSlotLog_t { - RK_S32 index; - MppBufSlotOps ops; - SlotStatus status_in; - SlotStatus status_out; -} MppBufSlotLog; - -struct MppBufSlotEntry_t { - MppBufSlotsImpl *slots; - struct list_head list; - SlotStatus status; - RK_S32 index; - - RK_U32 eos; - MppFrame frame; - MppBuffer buffer; -}; - -struct MppBufSlotsImpl_t { - Mutex *lock; - RK_U32 slots_idx; - - // status tracing - RK_U32 decode_count; - RK_U32 display_count; - - // if slot changed, all will be hold until all slot is unused - RK_U32 info_changed; - RK_S32 new_count; - - // slot infomation for info change and eos - RK_U32 eos; - - // buffer parameter, default alignement is 16 - AlignFunc hal_hor_align; // default NULL - AlignFunc hal_ver_align; // default NULL - AlignFunc hal_len_align; // default NULL - size_t buf_size; - RK_S32 buf_count; - // buffer size equal to (h_stride * v_stride) * numerator / denominator - // internal parameter - RK_U32 numerator; - RK_U32 denominator; - - // NOTE: use MppFrame to store the buffer/display infomation - // any buffer related infomation change comparing to previous frame will - // trigger a buffer info changed requirement - // any display related infomation change comparing to pevious frame will - // trigger a display info changed requirement - MppFrame info; - MppFrame info_set; - - // list for display - struct list_head queue[QUEUE_BUTT]; - - // list for log - mpp_list *logs; - - MppBufSlotEntry *slots; -}; - -static RK_U32 default_align_16(RK_U32 val) -{ - return MPP_ALIGN(val, 16); -} - -static void generate_info_set(MppBufSlotsImpl *impl, MppFrame frame, RK_U32 force_default_align) -{ - RK_U32 width = mpp_frame_get_width(frame); - RK_U32 height = mpp_frame_get_height(frame); - RK_U32 codec_hor_stride = mpp_frame_get_hor_stride(frame); - RK_U32 codec_ver_stride = mpp_frame_get_ver_stride(frame); - RK_U32 hal_hor_stride = (codec_hor_stride) ? - (impl->hal_hor_align(codec_hor_stride)) : - (impl->hal_hor_align(width)); - RK_U32 hal_ver_stride = (codec_ver_stride) ? - (impl->hal_ver_align(codec_ver_stride)) : - (impl->hal_ver_align(height)); - if (force_default_align) { - hal_hor_stride = codec_hor_stride; - hal_ver_stride = codec_ver_stride; - } - RK_U32 size = hal_hor_stride * hal_ver_stride; - size *= impl->numerator; - size /= impl->denominator; - size = impl->hal_len_align ? impl->hal_len_align(hal_hor_stride * hal_ver_stride) : size; - - mpp_frame_set_width(impl->info_set, width); - mpp_frame_set_height(impl->info_set, height); - mpp_frame_set_fmt(impl->info_set, mpp_frame_get_fmt(frame)); - mpp_frame_set_hor_stride(impl->info_set, hal_hor_stride); - mpp_frame_set_ver_stride(impl->info_set, hal_ver_stride); - mpp_frame_set_buf_size(impl->info_set, size); - impl->buf_size = size; - - MppFrameImpl *info_set_impl = (MppFrameImpl *)impl->info_set; - MppFrameImpl *frame_impl = (MppFrameImpl *)frame; - info_set_impl->color_range = frame_impl->color_range; - info_set_impl->color_primaries = frame_impl->color_primaries; - info_set_impl->color_trc = frame_impl->color_trc; - info_set_impl->colorspace = frame_impl->colorspace; - info_set_impl->chroma_location = frame_impl->chroma_location; -} - -#define dump_slots(...) _dump_slots(__FUNCTION__, ## __VA_ARGS__) - -static void _dump_slots(const char *caller, MppBufSlotsImpl *impl) -{ - RK_S32 i; - MppBufSlotEntry *slot = impl->slots; - - mpp_log("\ncaller %s is dumping slots\n", caller, impl->slots_idx); - mpp_log("slots %p buffer count %d buffer size %d\n", impl, impl->buf_count, impl->buf_size); - mpp_log("decode count %d\n", impl->decode_count); - mpp_log("display count %d\n", impl->display_count); - - for (i = 0; i < impl->buf_count; i++, slot++) { - SlotStatus status = slot->status; - mpp_log("slot %2d used %d refer %d decoding %d display %d status %08x\n", - i, status.on_used, status.codec_use, status.hal_use, status.queue_use, status.val); - } - - mpp_log("\nslot operation history:\n\n"); - - mpp_list *logs = impl->logs; - if (logs) { - while (logs->list_size()) { - MppBufSlotLog log; - logs->del_at_head(&log, sizeof(log)); - mpp_log("index %2d op: %s status in %08x out %08x", - log.index, op_string[log.ops], log.status_in.val, log.status_out.val); - } - } - - mpp_assert(0); - - return; -} - -static void add_slot_log(mpp_list *logs, RK_S32 index, MppBufSlotOps op, SlotStatus before, SlotStatus after) -{ - if (logs) { - MppBufSlotLog log = { - index, - op, - before, - after, - }; - if (logs->list_size() >= SLOT_OPS_MAX_COUNT) - logs->del_at_head(NULL, sizeof(log)); - logs->add_at_tail(&log, sizeof(log)); - } -} - -static void slot_ops_with_log(MppBufSlotsImpl *impl, MppBufSlotEntry *slot, MppBufSlotOps op, void *arg) -{ - RK_U32 error = 0; - RK_S32 index = slot->index; - SlotStatus status = slot->status; - SlotStatus before = status; - switch (op) { - case SLOT_INIT : { - status.val = 0; - } break; - case SLOT_SET_ON_USE : { - status.on_used = 1; - } break; - case SLOT_CLR_ON_USE : { - status.on_used = 0; - } break; - case SLOT_SET_NOT_READY : { - status.not_ready = 1; - } break; - case SLOT_CLR_NOT_READY : { - status.not_ready = 0; - } break; - case SLOT_SET_CODEC_READY : { - status.not_ready = 0; - } break; - case SLOT_CLR_CODEC_READY : { - status.not_ready = 1; - } break; - case SLOT_SET_CODEC_USE : { - status.codec_use = 1; - } break; - case SLOT_CLR_CODEC_USE : { - status.codec_use = 0; - } break; - case SLOT_SET_HAL_INPUT : { - status.hal_use++; - } break; - case SLOT_CLR_HAL_INPUT : { - if (status.hal_use) - status.hal_use--; - else { - mpp_err("can not clr hal_input on slot %d\n", slot->index); - error = 1; - } - } break; - case SLOT_SET_HAL_OUTPUT : { - status.hal_output = 1; - status.not_ready = 1; - } break; - case SLOT_CLR_HAL_OUTPUT : { - status.hal_output = 0; - // NOTE: set output index ready here - status.not_ready = 0; - } break; - case SLOT_SET_QUEUE_USE : - case SLOT_ENQUEUE : { - status.queue_use++; - } break; - case SLOT_CLR_QUEUE_USE : - case SLOT_DEQUEUE : { - if (status.queue_use) - status.queue_use--; - else { - mpp_err("can not clr queue_use on slot %d\n", slot->index); - error = 1; - } - } break; - case SLOT_SET_EOS : { - status.eos = 1; - } break; - case SLOT_CLR_EOS : { - status.eos = 0; - slot->eos = 0; - } break; - case SLOT_SET_FRAME : { - status.has_frame = (arg) ? (1) : (0); - } break; - case SLOT_CLR_FRAME : { - status.has_frame = 0; - } break; - case SLOT_SET_BUFFER : { - status.has_buffer = (arg) ? (1) : (0); - } break; - case SLOT_CLR_BUFFER : { - status.has_buffer = 0; - } break; - default : { - mpp_err("found invalid operation code %d\n", op); - error = 1; - } break; - } - slot->status = status; - buf_slot_dbg(BUF_SLOT_DBG_OPS_RUNTIME, "slot %3d index %2d op: %s arg %p status in %08x out %08x", - impl->slots_idx, index, op_string[op], arg, before.val, status.val); - add_slot_log(impl->logs, index, op, before, status); - if (error) - dump_slots(impl); -} - -static void init_slot_entry(MppBufSlotsImpl *impl, RK_S32 pos, RK_S32 count) -{ - MppBufSlotEntry *slot = impl->slots; - for (RK_S32 i = 0; i < count; i++, slot++) { - slot->slots = impl; - INIT_LIST_HEAD(&slot->list); - slot->index = pos + i; - slot->frame = NULL; - slot_ops_with_log(impl, slot, SLOT_INIT, NULL); - } -} - -/* - * only called on unref / displayed / decoded - * - * NOTE: MppFrame will be destroyed outside mpp - * but MppBuffer must dec_ref here - */ -static void check_entry_unused(MppBufSlotsImpl *impl, MppBufSlotEntry *entry) -{ - SlotStatus status = entry->status; - - if (status.on_used && - !status.not_ready && - !status.codec_use && - !status.hal_output && - !status.hal_use && - !status.queue_use) { - if (entry->frame) { - slot_ops_with_log(impl, entry, SLOT_CLR_FRAME, entry->frame); - mpp_frame_deinit(&entry->frame); - } - if (entry->buffer) { - mpp_buffer_put(entry->buffer); - slot_ops_with_log(impl, entry, SLOT_CLR_BUFFER, entry->buffer); - entry->buffer = NULL; - } - - slot_ops_with_log(impl, entry, SLOT_CLR_ON_USE, NULL); - } -} - -static void clear_slots_impl(MppBufSlotsImpl *impl) -{ - for (RK_U32 i = 0; i < MPP_ARRAY_ELEMS(impl->queue); i++) { - mpp_assert(list_empty(&impl->queue[i])); - } - MppBufSlotEntry *slot = (MppBufSlotEntry *)impl->slots; - RK_S32 i; - for (i = 0; i < impl->buf_count; i++, slot++) { - if (slot->status.on_used) - dump_slots(impl); - mpp_assert(!slot->status.on_used); - } - - if (impl->info) - mpp_frame_deinit(&impl->info); - - if (impl->info_set) - mpp_frame_deinit(&impl->info_set); - - if (impl->logs) - delete impl->logs; - - if (impl->lock) - delete impl->lock; - - mpp_free(impl->slots); - mpp_free(impl); -} - -MPP_RET mpp_buf_slot_init(MppBufSlots *slots) -{ - if (NULL == slots) { - mpp_err_f("found NULL input\n"); - return MPP_ERR_NULL_PTR; - } - MppBufSlotsImpl *impl = mpp_calloc(MppBufSlotsImpl, 1); - if (NULL == impl) { - *slots = NULL; - return MPP_NOK; - } - - mpp_env_get_u32("buf_slot_debug", &buf_slot_debug, BUF_SLOT_DBG_OPS_HISTORY); - - do { - impl->lock = new Mutex(); - if (NULL == impl->lock) - break; - - for (RK_U32 i = 0; i < MPP_ARRAY_ELEMS(impl->queue); i++) { - INIT_LIST_HEAD(&impl->queue[i]); - } - - if (buf_slot_debug & BUF_SLOT_DBG_OPS_HISTORY) { - impl->logs = new mpp_list(NULL); - if (NULL == impl->logs) - break; - } - - if (mpp_frame_init(&impl->info)) - break; - - if (mpp_frame_init(&impl->info_set)) - break; - - // slots information default setup - impl->hal_hor_align = default_align_16; - impl->hal_ver_align = default_align_16; - impl->hal_len_align = NULL; - impl->numerator = 9; - impl->denominator = 5; - impl->slots_idx = buf_slot_idx++; - - *slots = impl; - return MPP_OK; - } while (0); - - clear_slots_impl(impl); - - *slots = NULL; - return MPP_NOK; -} - -MPP_RET mpp_buf_slot_deinit(MppBufSlots slots) -{ - if (NULL == slots) { - mpp_err_f("found NULL input\n"); - return MPP_ERR_NULL_PTR; - } - - clear_slots_impl((MppBufSlotsImpl *)slots); - return MPP_OK; -} - -MPP_RET mpp_buf_slot_setup(MppBufSlots slots, RK_S32 count) -{ - if (NULL == slots) { - mpp_err_f("found NULL input\n"); - return MPP_ERR_NULL_PTR; - } - - buf_slot_dbg(BUF_SLOT_DBG_SETUP, "slot %p setup: count %d\n", slots, count); - - MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots; - AutoMutex auto_lock(impl->lock); - - if (NULL == impl->slots) { - // first slot setup - impl->buf_count = impl->new_count = count; - impl->slots = mpp_calloc(MppBufSlotEntry, count); - init_slot_entry(impl, 0, count); - } else { - // record the slot count for info changed ready config - if (count > impl->buf_count) { - mpp_realloc(impl->slots, MppBufSlotEntry, count); - init_slot_entry(impl, impl->buf_count, (count - impl->buf_count)); - } - impl->new_count = count; - } - - return MPP_OK; -} - -RK_U32 mpp_buf_slot_is_changed(MppBufSlots slots) -{ - if (NULL == slots) { - mpp_err_f("found NULL input\n"); - return 0; - } - - MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots; - AutoMutex auto_lock(impl->lock); - return impl->info_changed; -} - -MPP_RET mpp_buf_slot_ready(MppBufSlots slots) -{ - if (NULL == slots) { - mpp_err_f("found NULL input\n"); - return MPP_ERR_NULL_PTR; - } - - buf_slot_dbg(BUF_SLOT_DBG_SETUP, "slot %p is ready now\n", slots); - - MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots; - AutoMutex auto_lock(impl->lock); - slot_assert(impl, impl->info_changed); - slot_assert(impl, impl->slots); - - // ready mean the info_set will be copy to info as the new configuration - if (impl->buf_count != impl->new_count) { - mpp_realloc(impl->slots, MppBufSlotEntry, impl->new_count); - init_slot_entry(impl, 0, impl->new_count); - } - impl->buf_count = impl->new_count; - - mpp_frame_copy(impl->info, impl->info_set); - impl->buf_size = mpp_frame_get_buf_size(impl->info); - - if (impl->logs) { - mpp_list *logs = impl->logs; - while (logs->list_size()) - logs->del_at_head(NULL, sizeof(MppBufSlotLog)); - } - impl->info_changed = 0; - return MPP_OK; -} - -size_t mpp_buf_slot_get_size(MppBufSlots slots) -{ - if (NULL == slots) { - mpp_err_f("found NULL input\n"); - return 0; - } - - MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots; - return impl->buf_size; -} - -RK_S32 mpp_buf_slot_get_used_size(MppBufSlots slots) -{ - if (NULL == slots) { - mpp_err_f("found NULL input\n"); - return 0; - } - MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots; - AutoMutex auto_lock(impl->lock); - RK_S32 i; - RK_S32 used_size = 0; - MppBufSlotEntry *slot = impl->slots; - for (i = 0; i < impl->buf_count; i++, slot++) { - if (slot->status.on_used) { - buf_slot_dbg(BUF_SLOT_DBG_BUF_UESD, "[BUF_USED] buf_fd=%08x", mpp_buffer_get_fd(slot->buffer)); - used_size++; - } - } - return used_size; -} - -MPP_RET mpp_buf_slot_get_unused(MppBufSlots slots, RK_S32 *index) -{ - if (NULL == slots || NULL == index) { - mpp_err_f("found NULL input\n"); - return MPP_ERR_NULL_PTR; - } - - MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots; - AutoMutex auto_lock(impl->lock); - RK_S32 i; - MppBufSlotEntry *slot = impl->slots; - for (i = 0; i < impl->buf_count; i++, slot++) { - if (!slot->status.on_used) { - *index = i; - slot_ops_with_log(impl, slot, SLOT_SET_ON_USE, NULL); - slot_ops_with_log(impl, slot, SLOT_SET_NOT_READY, NULL); - return MPP_OK; - } - } - - *index = -1; - mpp_err_f("failed to get a unused slot\n"); - dump_slots(impl); - slot_assert(impl, 0); - return MPP_NOK; -} - -MPP_RET mpp_buf_slot_set_flag(MppBufSlots slots, RK_S32 index, SlotUsageType type) -{ - if (NULL == slots) { - mpp_err_f("found NULL input\n"); - return MPP_ERR_NULL_PTR; - } - - MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots; - AutoMutex auto_lock(impl->lock); - slot_assert(impl, (index >= 0) && (index < impl->buf_count)); - slot_ops_with_log(impl, &impl->slots[index], set_flag_op[type], NULL); - return MPP_OK; -} - -MPP_RET mpp_buf_slot_clr_flag(MppBufSlots slots, RK_S32 index, SlotUsageType type) -{ - if (NULL == slots) { - mpp_err_f("found NULL input\n"); - return MPP_ERR_NULL_PTR; - } - - MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots; - AutoMutex auto_lock(impl->lock); - slot_assert(impl, (index >= 0) && (index < impl->buf_count)); - MppBufSlotEntry *slot = &impl->slots[index]; - slot_ops_with_log(impl, slot, clr_flag_op[type], NULL); - - if (type == SLOT_HAL_OUTPUT) - impl->decode_count++; - - check_entry_unused(impl, slot); - return MPP_OK; -} - -MPP_RET mpp_buf_slot_enqueue(MppBufSlots slots, RK_S32 index, SlotQueueType type) -{ - if (NULL == slots) { - mpp_err_f("found NULL input\n"); - return MPP_ERR_NULL_PTR; - } - - MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots; - AutoMutex auto_lock(impl->lock); - slot_assert(impl, (index >= 0) && (index < impl->buf_count)); - MppBufSlotEntry *slot = &impl->slots[index]; - slot_ops_with_log(impl, slot, SLOT_ENQUEUE, NULL); - - // add slot to display list - list_del_init(&slot->list); - list_add_tail(&slot->list, &impl->queue[type]); - return MPP_OK; -} - -MPP_RET mpp_buf_slot_dequeue(MppBufSlots slots, RK_S32 *index, SlotQueueType type) -{ - if (NULL == slots || NULL == index) { - mpp_err_f("found NULL input\n"); - return MPP_ERR_NULL_PTR; - } - - MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots; - AutoMutex auto_lock(impl->lock); - if (list_empty(&impl->queue[type])) - return MPP_NOK; - - MppBufSlotEntry *slot = list_entry(impl->queue[type].next, MppBufSlotEntry, list); - if (slot->status.not_ready) - return MPP_NOK; - - // make sure that this slot is just the next display slot - list_del_init(&slot->list); - slot_assert(impl, slot->index < impl->buf_count); - slot_ops_with_log(impl, slot, SLOT_DEQUEUE, NULL); - impl->display_count++; - *index = slot->index; - - return MPP_OK; -} - -MPP_RET mpp_buf_slot_set_prop(MppBufSlots slots, RK_S32 index, SlotPropType type, void *val) -{ - if (NULL == slots || NULL == val || type >= SLOT_PROP_BUTT) { - mpp_err_f("found invalid input slots %p type %d val %p\n", slots, type, val); - return MPP_ERR_UNKNOW; - } - - MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots; - AutoMutex auto_lock(impl->lock); - slot_assert(impl, (index >= 0) && (index < impl->buf_count)); - MppBufSlotEntry *slot = &impl->slots[index]; - slot_ops_with_log(impl, slot, set_val_op[type], val); - - switch (type) { - case SLOT_EOS: { - RK_U32 eos = *(RK_U32*)val; - slot->eos = eos; - if (slot->frame) - mpp_frame_set_eos(slot->frame, eos); - } break; - case SLOT_FRAME: { - MppFrame frame = val; - - slot_assert(impl, slot->status.not_ready); - if (NULL == slot->frame) - mpp_frame_init(&slot->frame); - - MppFrameImpl *src = (MppFrameImpl *)frame; - MppFrameImpl *dst = (MppFrameImpl *)slot->frame; - mpp_frame_copy(dst, src); - // NOTE: stride from codec need to be change to hal stride - // hor_stride and ver_stride can not be zero - // they are the stride required by codec - // then hal will modify it according to hardware requirement - mpp_assert(src->hor_stride); - mpp_assert(src->ver_stride); - dst->hor_stride = impl->hal_hor_align(src->hor_stride); - dst->ver_stride = impl->hal_ver_align(src->ver_stride); - dst->eos = slot->eos; - - /* - * we need to detect infomation change here - * there are two types of info change: - * 1. buffer size change - * this case need to reset buffer group and commit buffer with new size - * 2. display info change - * if only width/height/fmt is change and buffer do not need to be reset - * only display info change is need - */ - generate_info_set(impl, frame, 0); - if (mpp_frame_info_cmp(impl->info, impl->info_set)) { - impl->info_changed = 1; -#ifdef RKPLATFORM - MppFrameImpl *old = (MppFrameImpl *)impl->info; - mpp_log("info change found\n"); - mpp_log("old width %4d height %4d stride hor %4d ver %4d fmt %4d\n", - old->width, old->height, old->hor_stride, old->ver_stride, old->fmt); - mpp_log("new width %4d height %4d stride hor %4d ver %4d fmt %4d\n", - dst->width, dst->height, dst->hor_stride, dst->ver_stride, dst->fmt); -#endif - // info change found here - } - } break; - case SLOT_BUFFER: { - MppBuffer buffer = val; - if (slot->buffer) { - // NOTE: reset buffer only on stream buffer slot - slot_assert(impl, NULL == slot->frame); - mpp_buffer_put(slot->buffer); - } - mpp_buffer_inc_ref(buffer); - slot->buffer = buffer; - - if (slot->frame) - mpp_frame_set_buffer(slot->frame, buffer); - } break; - default : { - } break; - } - - return MPP_OK; -} - -MPP_RET mpp_buf_slot_get_prop(MppBufSlots slots, RK_S32 index, SlotPropType type, void *val) -{ - if (NULL == slots || NULL == val || type >= SLOT_PROP_BUTT) { - mpp_err_f("found invalid input slots %p type %d val %p\n", slots, type, val); - return MPP_ERR_UNKNOW; - } - - MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots; - AutoMutex auto_lock(impl->lock); - slot_assert(impl, (index >= 0) && (index < impl->buf_count)); - MppBufSlotEntry *slot = &impl->slots[index]; - - switch (type) { - case SLOT_EOS: { - *(RK_U32*)val = slot->eos; - } break; - case SLOT_FRAME: { - MppFrame *frame = (MppFrame *)val; - //*frame = (slot->status.has_frame) ? (slot->frame) : (NULL); - - mpp_assert(slot->status.has_frame); - if (slot->status.has_frame) { - if (NULL == *frame ) - mpp_frame_init(frame); - if (*frame) - mpp_frame_copy(*frame, slot->frame); - } else - *frame = NULL; - } break; - case SLOT_FRAME_PTR: { - MppFrame *frame = (MppFrame *)val; - *frame = (slot->status.has_frame) ? (slot->frame) : (NULL); - } break; - case SLOT_BUFFER: { - MppBuffer *buffer = (MppBuffer *)val; - *buffer = (slot->status.has_buffer) ? (slot->buffer) : (NULL); - } break; - default : { - } break; - } - - return MPP_OK; -} -MPP_RET mpp_slots_set_prop(MppBufSlots slots, SlotsPropType type, void *val) -{ - if (NULL == slots || NULL == val || type >= SLOTS_PROP_BUTT) { - mpp_err_f("found invalid input slots %p type %d val %p\n", slots, type, val); - return MPP_ERR_UNKNOW; - } - - MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots; - AutoMutex auto_lock(impl->lock); - RK_U32 value = *((RK_U32*)val); - switch (type) { - case SLOTS_EOS: { - impl->eos = value; - } break; - case SLOTS_HOR_ALIGN: { - impl->hal_hor_align = (AlignFunc)val; - } break; - case SLOTS_VER_ALIGN: { - impl->hal_ver_align = (AlignFunc)val; - } break; - case SLOTS_LEN_ALIGN: { - impl->hal_len_align = (AlignFunc)val; - } break; - case SLOTS_COUNT: { - impl->buf_count = value; - } break; - case SLOTS_SIZE: { - impl->buf_size = value; - } break; - case SLOTS_FRAME_INFO: { - // do info change detection here - generate_info_set(impl, (MppFrame)val, 1); - mpp_frame_copy(impl->info, impl->info_set); - { - MppFrameImpl *p = (MppFrameImpl *)impl->info; - mpp_log("set frame info: w %4d h %4d hor %4d ver %4d\n", p->width, p->height, p->hor_stride, p->ver_stride); - } - impl->buf_size = mpp_frame_get_buf_size(impl->info); - } break; - default : { - } break; - } - - return MPP_OK; -} - -MPP_RET mpp_slots_get_prop(MppBufSlots slots, SlotsPropType type, void *val) -{ - if (NULL == slots || NULL == val || type >= SLOTS_PROP_BUTT) { - mpp_err_f("found invalid input slots %p type %d val %p\n", slots, type, val); - return MPP_NOK; - } - - MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots; - AutoMutex auto_lock(impl->lock); - MPP_RET ret = MPP_OK; - RK_U32 value = 0; - switch (type) { - case SLOTS_EOS: { - value = impl->eos; - } break; - case SLOTS_COUNT: { - value = impl->buf_count; - } break; - case SLOTS_SIZE: { - value = (RK_U32)impl->buf_size; - } break; - case SLOTS_FRAME_INFO: { - MppFrame frame = (MppFrame)val; - MppFrame info = impl->info; - mpp_frame_copy(frame, info); - } break; - default : { - mpp_err("can not get slots prop type %d\n", type); - ret = MPP_NOK; - } break; - } - if (MPP_OK == ret) { - if (SLOTS_FRAME_INFO != type) - *(RK_U32 *)val = value; - } - - return ret; -} - -MPP_RET mpp_buf_slot_reset(MppBufSlots slots, RK_S32 index) -{ - if (NULL == slots || index < 0) { - mpp_err_f("found NULL input\n"); - return MPP_ERR_NULL_PTR; - } - - MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots; - AutoMutex auto_lock(impl->lock); - slot_assert(impl, (index >= 0) && (index < impl->buf_count)); - MppBufSlotEntry *slot = &impl->slots[index]; - - // make sure that this slot is just the next display slot - list_del_init(&slot->list); - slot_ops_with_log(impl, slot, SLOT_CLR_QUEUE_USE, NULL); - slot_ops_with_log(impl, slot, SLOT_DEQUEUE, NULL); - slot_ops_with_log(impl, slot, SLOT_CLR_ON_USE, NULL); - return MPP_OK; -} - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define MODULE_TAG "mpp_buf_slot" + +#include + +#include "mpp_log.h" +#include "mpp_mem.h" +#include "mpp_env.h" +#include "mpp_list.h" +#include "mpp_common.h" + +#include "mpp_frame_impl.h" +#include "mpp_buf_slot.h" + + +#define BUF_SLOT_DBG_FUNCTION (0x00000001) +#define BUF_SLOT_DBG_SETUP (0x00000002) +#define BUF_SLOT_DBG_INFO_CHANGE (0x00000004) +#define BUF_SLOT_DBG_OPS_RUNTIME (0x00000010) +#define BUF_SLOT_DBG_BUFFER (0x00000100) +#define BUF_SLOT_DBG_FRAME (0x00000200) +#define BUF_SLOT_DBG_BUF_UESD (0x00000400) +#define BUF_SLOT_DBG_OPS_HISTORY (0x10000000) +#define BUF_SLOT_DBG_ALL (0x10000011) + +#define buf_slot_dbg(flag, fmt, ...) _mpp_dbg(buf_slot_debug, flag, fmt, ## __VA_ARGS__) + +static RK_U32 buf_slot_debug = 0; +static RK_U32 buf_slot_idx = 0; + +#define slot_assert(impl, cond) do { \ + if (!(cond)) { \ + dump_slots(impl); \ + mpp_err("Assertion %s failed at %s:%d\n", \ + MPP_STRINGS(cond), __FUNCTION__, __LINE__); \ + abort(); \ + } \ +} while (0) + +typedef struct MppBufSlotEntry_t MppBufSlotEntry; +typedef struct MppBufSlotsImpl_t MppBufSlotsImpl; + +#define SLOT_OPS_MAX_COUNT 1024 + +typedef enum MppBufSlotOps_e { + // status opertaion + SLOT_INIT, + SLOT_SET_ON_USE, + SLOT_CLR_ON_USE, + SLOT_SET_NOT_READY, + SLOT_CLR_NOT_READY, + SLOT_SET_CODEC_READY, + SLOT_CLR_CODEC_READY, + SLOT_SET_CODEC_USE, + SLOT_CLR_CODEC_USE, + SLOT_SET_HAL_INPUT, + SLOT_CLR_HAL_INPUT, + SLOT_SET_HAL_OUTPUT, + SLOT_CLR_HAL_OUTPUT, + SLOT_SET_QUEUE_USE, + SLOT_CLR_QUEUE_USE, + + // queue operation + SLOT_ENQUEUE, + SLOT_DEQUEUE, + + // value operation + SLOT_SET_EOS, + SLOT_CLR_EOS, + SLOT_SET_FRAME, + SLOT_CLR_FRAME, + SLOT_SET_BUFFER, + SLOT_CLR_BUFFER, +} MppBufSlotOps; + +static const char op_string[][16] = { + "init ", + "set on use ", + "clr on use ", + "set not ready ", + "set ready ", + "set codec ready", + "clr codec ready", + "set codec use ", + "clr codec use ", + "set hal input ", + "clr hal input ", + "set hal output ", + "clr hal output ", + "set queue use ", + "clr queue use ", + + "enqueue display", + "dequeue display", + + "set eos ", + "clr eos ", + "set frame ", + "clr frame ", + "set buffer ", + "clr buffer ", +}; + +static const MppBufSlotOps set_flag_op[SLOT_USAGE_BUTT] = { + SLOT_SET_CODEC_READY, + SLOT_SET_CODEC_USE, + SLOT_SET_HAL_INPUT, + SLOT_SET_HAL_OUTPUT, + SLOT_SET_QUEUE_USE, +}; + +static const MppBufSlotOps clr_flag_op[SLOT_USAGE_BUTT] = { + SLOT_CLR_CODEC_READY, + SLOT_CLR_CODEC_USE, + SLOT_CLR_HAL_INPUT, + SLOT_CLR_HAL_OUTPUT, + SLOT_CLR_QUEUE_USE, +}; + +static const MppBufSlotOps set_val_op[SLOT_PROP_BUTT] = { + SLOT_SET_EOS, + SLOT_SET_FRAME, + SLOT_SET_BUFFER, +}; + +static const MppBufSlotOps clr_val_op[SLOT_PROP_BUTT] = { + SLOT_CLR_EOS, + SLOT_CLR_FRAME, + SLOT_CLR_BUFFER, +}; + +typedef union SlotStatus_u { + RK_U32 val; + struct { + // status flags + RK_U32 on_used : 1; + RK_U32 not_ready : 1; // buffer slot is filled or not + RK_U32 codec_use : 1; // buffer slot is used by codec ( dpb reference ) + RK_U32 hal_output : 1; // buffer slot is set to hw output will ready when hw done + RK_U32 hal_use : 8; // buffer slot is used by hardware + RK_U32 queue_use : 5; // buffer slot is used in different queue + + // value flags + RK_U32 eos : 1; // buffer slot is last buffer slot from codec + RK_U32 has_buffer : 1; + RK_U32 has_frame : 1; + }; +} SlotStatus; + +typedef struct MppBufSlotLog_t { + RK_S32 index; + MppBufSlotOps ops; + SlotStatus status_in; + SlotStatus status_out; +} MppBufSlotLog; + +struct MppBufSlotEntry_t { + MppBufSlotsImpl *slots; + struct list_head list; + SlotStatus status; + RK_S32 index; + + RK_U32 eos; + MppFrame frame; + MppBuffer buffer; +}; + +struct MppBufSlotsImpl_t { + Mutex *lock; + RK_U32 slots_idx; + + // status tracing + RK_U32 decode_count; + RK_U32 display_count; + + // if slot changed, all will be hold until all slot is unused + RK_U32 info_changed; + RK_S32 new_count; + + // slot infomation for info change and eos + RK_U32 eos; + + // buffer parameter, default alignement is 16 + AlignFunc hal_hor_align; // default NULL + AlignFunc hal_ver_align; // default NULL + AlignFunc hal_len_align; // default NULL + size_t buf_size; + RK_S32 buf_count; + // buffer size equal to (h_stride * v_stride) * numerator / denominator + // internal parameter + RK_U32 numerator; + RK_U32 denominator; + + // NOTE: use MppFrame to store the buffer/display infomation + // any buffer related infomation change comparing to previous frame will + // trigger a buffer info changed requirement + // any display related infomation change comparing to pevious frame will + // trigger a display info changed requirement + MppFrame info; + MppFrame info_set; + + // list for display + struct list_head queue[QUEUE_BUTT]; + + // list for log + mpp_list *logs; + + MppBufSlotEntry *slots; +}; + +static RK_U32 default_align_16(RK_U32 val) +{ + return MPP_ALIGN(val, 16); +} + +static void generate_info_set(MppBufSlotsImpl *impl, MppFrame frame, RK_U32 force_default_align) +{ + RK_U32 width = mpp_frame_get_width(frame); + RK_U32 height = mpp_frame_get_height(frame); + RK_U32 codec_hor_stride = mpp_frame_get_hor_stride(frame); + RK_U32 codec_ver_stride = mpp_frame_get_ver_stride(frame); + RK_U32 hal_hor_stride = (codec_hor_stride) ? + (impl->hal_hor_align(codec_hor_stride)) : + (impl->hal_hor_align(width)); + RK_U32 hal_ver_stride = (codec_ver_stride) ? + (impl->hal_ver_align(codec_ver_stride)) : + (impl->hal_ver_align(height)); + if (force_default_align) { + hal_hor_stride = codec_hor_stride; + hal_ver_stride = codec_ver_stride; + } + RK_U32 size = hal_hor_stride * hal_ver_stride; + size *= impl->numerator; + size /= impl->denominator; + size = impl->hal_len_align ? impl->hal_len_align(hal_hor_stride * hal_ver_stride) : size; + + mpp_frame_set_width(impl->info_set, width); + mpp_frame_set_height(impl->info_set, height); + mpp_frame_set_fmt(impl->info_set, mpp_frame_get_fmt(frame)); + mpp_frame_set_hor_stride(impl->info_set, hal_hor_stride); + mpp_frame_set_ver_stride(impl->info_set, hal_ver_stride); + mpp_frame_set_buf_size(impl->info_set, size); + impl->buf_size = size; + + MppFrameImpl *info_set_impl = (MppFrameImpl *)impl->info_set; + MppFrameImpl *frame_impl = (MppFrameImpl *)frame; + info_set_impl->color_range = frame_impl->color_range; + info_set_impl->color_primaries = frame_impl->color_primaries; + info_set_impl->color_trc = frame_impl->color_trc; + info_set_impl->colorspace = frame_impl->colorspace; + info_set_impl->chroma_location = frame_impl->chroma_location; +} + +#define dump_slots(...) _dump_slots(__FUNCTION__, ## __VA_ARGS__) + +static void _dump_slots(const char *caller, MppBufSlotsImpl *impl) +{ + RK_S32 i; + MppBufSlotEntry *slot = impl->slots; + + mpp_log("\ncaller %s is dumping slots\n", caller, impl->slots_idx); + mpp_log("slots %p buffer count %d buffer size %d\n", impl, impl->buf_count, impl->buf_size); + mpp_log("decode count %d\n", impl->decode_count); + mpp_log("display count %d\n", impl->display_count); + + for (i = 0; i < impl->buf_count; i++, slot++) { + SlotStatus status = slot->status; + mpp_log("slot %2d used %d refer %d decoding %d display %d status %08x\n", + i, status.on_used, status.codec_use, status.hal_use, status.queue_use, status.val); + } + + mpp_log("\nslot operation history:\n\n"); + + mpp_list *logs = impl->logs; + if (logs) { + while (logs->list_size()) { + MppBufSlotLog log; + logs->del_at_head(&log, sizeof(log)); + mpp_log("index %2d op: %s status in %08x out %08x", + log.index, op_string[log.ops], log.status_in.val, log.status_out.val); + } + } + + mpp_assert(0); + + return; +} + +static void add_slot_log(mpp_list *logs, RK_S32 index, MppBufSlotOps op, SlotStatus before, SlotStatus after) +{ + if (logs) { + MppBufSlotLog log = { + index, + op, + before, + after, + }; + if (logs->list_size() >= SLOT_OPS_MAX_COUNT) + logs->del_at_head(NULL, sizeof(log)); + logs->add_at_tail(&log, sizeof(log)); + } +} + +static void slot_ops_with_log(MppBufSlotsImpl *impl, MppBufSlotEntry *slot, MppBufSlotOps op, void *arg) +{ + RK_U32 error = 0; + RK_S32 index = slot->index; + SlotStatus status = slot->status; + SlotStatus before = status; + switch (op) { + case SLOT_INIT : { + status.val = 0; + } break; + case SLOT_SET_ON_USE : { + status.on_used = 1; + } break; + case SLOT_CLR_ON_USE : { + status.on_used = 0; + } break; + case SLOT_SET_NOT_READY : { + status.not_ready = 1; + } break; + case SLOT_CLR_NOT_READY : { + status.not_ready = 0; + } break; + case SLOT_SET_CODEC_READY : { + status.not_ready = 0; + } break; + case SLOT_CLR_CODEC_READY : { + status.not_ready = 1; + } break; + case SLOT_SET_CODEC_USE : { + status.codec_use = 1; + } break; + case SLOT_CLR_CODEC_USE : { + status.codec_use = 0; + } break; + case SLOT_SET_HAL_INPUT : { + status.hal_use++; + } break; + case SLOT_CLR_HAL_INPUT : { + if (status.hal_use) + status.hal_use--; + else { + mpp_err("can not clr hal_input on slot %d\n", slot->index); + error = 1; + } + } break; + case SLOT_SET_HAL_OUTPUT : { + status.hal_output = 1; + status.not_ready = 1; + } break; + case SLOT_CLR_HAL_OUTPUT : { + status.hal_output = 0; + // NOTE: set output index ready here + status.not_ready = 0; + } break; + case SLOT_SET_QUEUE_USE : + case SLOT_ENQUEUE : { + status.queue_use++; + } break; + case SLOT_CLR_QUEUE_USE : + case SLOT_DEQUEUE : { + if (status.queue_use) + status.queue_use--; + else { + mpp_err("can not clr queue_use on slot %d\n", slot->index); + error = 1; + } + } break; + case SLOT_SET_EOS : { + status.eos = 1; + } break; + case SLOT_CLR_EOS : { + status.eos = 0; + slot->eos = 0; + } break; + case SLOT_SET_FRAME : { + status.has_frame = (arg) ? (1) : (0); + } break; + case SLOT_CLR_FRAME : { + status.has_frame = 0; + } break; + case SLOT_SET_BUFFER : { + status.has_buffer = (arg) ? (1) : (0); + } break; + case SLOT_CLR_BUFFER : { + status.has_buffer = 0; + } break; + default : { + mpp_err("found invalid operation code %d\n", op); + error = 1; + } break; + } + slot->status = status; + buf_slot_dbg(BUF_SLOT_DBG_OPS_RUNTIME, "slot %3d index %2d op: %s arg %p status in %08x out %08x", + impl->slots_idx, index, op_string[op], arg, before.val, status.val); + add_slot_log(impl->logs, index, op, before, status); + if (error) + dump_slots(impl); +} + +static void init_slot_entry(MppBufSlotsImpl *impl, RK_S32 pos, RK_S32 count) +{ + MppBufSlotEntry *slot = impl->slots; + for (RK_S32 i = 0; i < count; i++, slot++) { + slot->slots = impl; + INIT_LIST_HEAD(&slot->list); + slot->index = pos + i; + slot->frame = NULL; + slot_ops_with_log(impl, slot, SLOT_INIT, NULL); + } +} + +/* + * only called on unref / displayed / decoded + * + * NOTE: MppFrame will be destroyed outside mpp + * but MppBuffer must dec_ref here + */ +static void check_entry_unused(MppBufSlotsImpl *impl, MppBufSlotEntry *entry) +{ + SlotStatus status = entry->status; + + if (status.on_used && + !status.not_ready && + !status.codec_use && + !status.hal_output && + !status.hal_use && + !status.queue_use) { + if (entry->frame) { + slot_ops_with_log(impl, entry, SLOT_CLR_FRAME, entry->frame); + mpp_frame_deinit(&entry->frame); + } + if (entry->buffer) { + mpp_buffer_put(entry->buffer); + slot_ops_with_log(impl, entry, SLOT_CLR_BUFFER, entry->buffer); + entry->buffer = NULL; + } + + slot_ops_with_log(impl, entry, SLOT_CLR_ON_USE, NULL); + } +} + +static void clear_slots_impl(MppBufSlotsImpl *impl) +{ + for (RK_U32 i = 0; i < MPP_ARRAY_ELEMS(impl->queue); i++) { + mpp_assert(list_empty(&impl->queue[i])); + } + MppBufSlotEntry *slot = (MppBufSlotEntry *)impl->slots; + RK_S32 i; + for (i = 0; i < impl->buf_count; i++, slot++) { + if (slot->status.on_used) + dump_slots(impl); + mpp_assert(!slot->status.on_used); + } + + if (impl->info) + mpp_frame_deinit(&impl->info); + + if (impl->info_set) + mpp_frame_deinit(&impl->info_set); + + if (impl->logs) + delete impl->logs; + + if (impl->lock) + delete impl->lock; + + mpp_free(impl->slots); + mpp_free(impl); +} + +MPP_RET mpp_buf_slot_init(MppBufSlots *slots) +{ + if (NULL == slots) { + mpp_err_f("found NULL input\n"); + return MPP_ERR_NULL_PTR; + } + MppBufSlotsImpl *impl = mpp_calloc(MppBufSlotsImpl, 1); + if (NULL == impl) { + *slots = NULL; + return MPP_NOK; + } + + mpp_env_get_u32("buf_slot_debug", &buf_slot_debug, BUF_SLOT_DBG_OPS_HISTORY); + + do { + impl->lock = new Mutex(); + if (NULL == impl->lock) + break; + + for (RK_U32 i = 0; i < MPP_ARRAY_ELEMS(impl->queue); i++) { + INIT_LIST_HEAD(&impl->queue[i]); + } + + if (buf_slot_debug & BUF_SLOT_DBG_OPS_HISTORY) { + impl->logs = new mpp_list(NULL); + if (NULL == impl->logs) + break; + } + + if (mpp_frame_init(&impl->info)) + break; + + if (mpp_frame_init(&impl->info_set)) + break; + + // slots information default setup + impl->hal_hor_align = default_align_16; + impl->hal_ver_align = default_align_16; + impl->hal_len_align = NULL; + impl->numerator = 9; + impl->denominator = 5; + impl->slots_idx = buf_slot_idx++; + + *slots = impl; + return MPP_OK; + } while (0); + + clear_slots_impl(impl); + + *slots = NULL; + return MPP_NOK; +} + +MPP_RET mpp_buf_slot_deinit(MppBufSlots slots) +{ + if (NULL == slots) { + mpp_err_f("found NULL input\n"); + return MPP_ERR_NULL_PTR; + } + + clear_slots_impl((MppBufSlotsImpl *)slots); + return MPP_OK; +} + +MPP_RET mpp_buf_slot_setup(MppBufSlots slots, RK_S32 count) +{ + if (NULL == slots) { + mpp_err_f("found NULL input\n"); + return MPP_ERR_NULL_PTR; + } + + buf_slot_dbg(BUF_SLOT_DBG_SETUP, "slot %p setup: count %d\n", slots, count); + + MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots; + AutoMutex auto_lock(impl->lock); + + if (NULL == impl->slots) { + // first slot setup + impl->buf_count = impl->new_count = count; + impl->slots = mpp_calloc(MppBufSlotEntry, count); + init_slot_entry(impl, 0, count); + } else { + // record the slot count for info changed ready config + if (count > impl->buf_count) { + mpp_realloc(impl->slots, MppBufSlotEntry, count); + init_slot_entry(impl, impl->buf_count, (count - impl->buf_count)); + } + impl->new_count = count; + } + + return MPP_OK; +} + +RK_U32 mpp_buf_slot_is_changed(MppBufSlots slots) +{ + if (NULL == slots) { + mpp_err_f("found NULL input\n"); + return 0; + } + + MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots; + AutoMutex auto_lock(impl->lock); + return impl->info_changed; +} + +MPP_RET mpp_buf_slot_ready(MppBufSlots slots) +{ + if (NULL == slots) { + mpp_err_f("found NULL input\n"); + return MPP_ERR_NULL_PTR; + } + + buf_slot_dbg(BUF_SLOT_DBG_SETUP, "slot %p is ready now\n", slots); + + MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots; + AutoMutex auto_lock(impl->lock); + slot_assert(impl, impl->info_changed); + slot_assert(impl, impl->slots); + + // ready mean the info_set will be copy to info as the new configuration + if (impl->buf_count != impl->new_count) { + mpp_realloc(impl->slots, MppBufSlotEntry, impl->new_count); + init_slot_entry(impl, 0, impl->new_count); + } + impl->buf_count = impl->new_count; + + mpp_frame_copy(impl->info, impl->info_set); + impl->buf_size = mpp_frame_get_buf_size(impl->info); + + if (impl->logs) { + mpp_list *logs = impl->logs; + while (logs->list_size()) + logs->del_at_head(NULL, sizeof(MppBufSlotLog)); + } + impl->info_changed = 0; + return MPP_OK; +} + +size_t mpp_buf_slot_get_size(MppBufSlots slots) +{ + if (NULL == slots) { + mpp_err_f("found NULL input\n"); + return 0; + } + + MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots; + return impl->buf_size; +} + +RK_S32 mpp_buf_slot_get_used_size(MppBufSlots slots) +{ + if (NULL == slots) { + mpp_err_f("found NULL input\n"); + return 0; + } + MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots; + AutoMutex auto_lock(impl->lock); + RK_S32 i; + RK_S32 used_size = 0; + MppBufSlotEntry *slot = impl->slots; + for (i = 0; i < impl->buf_count; i++, slot++) { + if (slot->status.on_used) { + buf_slot_dbg(BUF_SLOT_DBG_BUF_UESD, "[BUF_USED] buf_fd=%08x", mpp_buffer_get_fd(slot->buffer)); + used_size++; + } + } + return used_size; +} + +MPP_RET mpp_buf_slot_get_unused(MppBufSlots slots, RK_S32 *index) +{ + if (NULL == slots || NULL == index) { + mpp_err_f("found NULL input\n"); + return MPP_ERR_NULL_PTR; + } + + MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots; + AutoMutex auto_lock(impl->lock); + RK_S32 i; + MppBufSlotEntry *slot = impl->slots; + for (i = 0; i < impl->buf_count; i++, slot++) { + if (!slot->status.on_used) { + *index = i; + slot_ops_with_log(impl, slot, SLOT_SET_ON_USE, NULL); + slot_ops_with_log(impl, slot, SLOT_SET_NOT_READY, NULL); + return MPP_OK; + } + } + + *index = -1; + mpp_err_f("failed to get a unused slot\n"); + dump_slots(impl); + slot_assert(impl, 0); + return MPP_NOK; +} + +MPP_RET mpp_buf_slot_set_flag(MppBufSlots slots, RK_S32 index, SlotUsageType type) +{ + if (NULL == slots) { + mpp_err_f("found NULL input\n"); + return MPP_ERR_NULL_PTR; + } + + MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots; + AutoMutex auto_lock(impl->lock); + slot_assert(impl, (index >= 0) && (index < impl->buf_count)); + slot_ops_with_log(impl, &impl->slots[index], set_flag_op[type], NULL); + return MPP_OK; +} + +MPP_RET mpp_buf_slot_clr_flag(MppBufSlots slots, RK_S32 index, SlotUsageType type) +{ + if (NULL == slots) { + mpp_err_f("found NULL input\n"); + return MPP_ERR_NULL_PTR; + } + + MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots; + AutoMutex auto_lock(impl->lock); + slot_assert(impl, (index >= 0) && (index < impl->buf_count)); + MppBufSlotEntry *slot = &impl->slots[index]; + slot_ops_with_log(impl, slot, clr_flag_op[type], NULL); + + if (type == SLOT_HAL_OUTPUT) + impl->decode_count++; + + check_entry_unused(impl, slot); + return MPP_OK; +} + +MPP_RET mpp_buf_slot_enqueue(MppBufSlots slots, RK_S32 index, SlotQueueType type) +{ + if (NULL == slots) { + mpp_err_f("found NULL input\n"); + return MPP_ERR_NULL_PTR; + } + + MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots; + AutoMutex auto_lock(impl->lock); + slot_assert(impl, (index >= 0) && (index < impl->buf_count)); + MppBufSlotEntry *slot = &impl->slots[index]; + slot_ops_with_log(impl, slot, SLOT_ENQUEUE, NULL); + + // add slot to display list + list_del_init(&slot->list); + list_add_tail(&slot->list, &impl->queue[type]); + return MPP_OK; +} + +MPP_RET mpp_buf_slot_dequeue(MppBufSlots slots, RK_S32 *index, SlotQueueType type) +{ + if (NULL == slots || NULL == index) { + mpp_err_f("found NULL input\n"); + return MPP_ERR_NULL_PTR; + } + + MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots; + AutoMutex auto_lock(impl->lock); + if (list_empty(&impl->queue[type])) + return MPP_NOK; + + MppBufSlotEntry *slot = list_entry(impl->queue[type].next, MppBufSlotEntry, list); + if (slot->status.not_ready) + return MPP_NOK; + + // make sure that this slot is just the next display slot + list_del_init(&slot->list); + slot_assert(impl, slot->index < impl->buf_count); + slot_ops_with_log(impl, slot, SLOT_DEQUEUE, NULL); + impl->display_count++; + *index = slot->index; + + return MPP_OK; +} + +MPP_RET mpp_buf_slot_set_prop(MppBufSlots slots, RK_S32 index, SlotPropType type, void *val) +{ + if (NULL == slots || NULL == val || type >= SLOT_PROP_BUTT) { + mpp_err_f("found invalid input slots %p type %d val %p\n", slots, type, val); + return MPP_ERR_UNKNOW; + } + + MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots; + AutoMutex auto_lock(impl->lock); + slot_assert(impl, (index >= 0) && (index < impl->buf_count)); + MppBufSlotEntry *slot = &impl->slots[index]; + slot_ops_with_log(impl, slot, set_val_op[type], val); + + switch (type) { + case SLOT_EOS: { + RK_U32 eos = *(RK_U32*)val; + slot->eos = eos; + if (slot->frame) + mpp_frame_set_eos(slot->frame, eos); + } break; + case SLOT_FRAME: { + MppFrame frame = val; + + slot_assert(impl, slot->status.not_ready); + if (NULL == slot->frame) + mpp_frame_init(&slot->frame); + + MppFrameImpl *src = (MppFrameImpl *)frame; + MppFrameImpl *dst = (MppFrameImpl *)slot->frame; + mpp_frame_copy(dst, src); + // NOTE: stride from codec need to be change to hal stride + // hor_stride and ver_stride can not be zero + // they are the stride required by codec + // then hal will modify it according to hardware requirement + mpp_assert(src->hor_stride); + mpp_assert(src->ver_stride); + dst->hor_stride = impl->hal_hor_align(src->hor_stride); + dst->ver_stride = impl->hal_ver_align(src->ver_stride); + dst->eos = slot->eos; + + /* + * we need to detect infomation change here + * there are two types of info change: + * 1. buffer size change + * this case need to reset buffer group and commit buffer with new size + * 2. display info change + * if only width/height/fmt is change and buffer do not need to be reset + * only display info change is need + */ + generate_info_set(impl, frame, 0); + if (mpp_frame_info_cmp(impl->info, impl->info_set)) { + impl->info_changed = 1; +#ifdef RKPLATFORM + MppFrameImpl *old = (MppFrameImpl *)impl->info; + mpp_log("info change found\n"); + mpp_log("old width %4d height %4d stride hor %4d ver %4d fmt %4d\n", + old->width, old->height, old->hor_stride, old->ver_stride, old->fmt); + mpp_log("new width %4d height %4d stride hor %4d ver %4d fmt %4d\n", + dst->width, dst->height, dst->hor_stride, dst->ver_stride, dst->fmt); +#endif + // info change found here + } + } break; + case SLOT_BUFFER: { + MppBuffer buffer = val; + if (slot->buffer) { + // NOTE: reset buffer only on stream buffer slot + slot_assert(impl, NULL == slot->frame); + mpp_buffer_put(slot->buffer); + } + mpp_buffer_inc_ref(buffer); + slot->buffer = buffer; + + if (slot->frame) + mpp_frame_set_buffer(slot->frame, buffer); + } break; + default : { + } break; + } + + return MPP_OK; +} + +MPP_RET mpp_buf_slot_get_prop(MppBufSlots slots, RK_S32 index, SlotPropType type, void *val) +{ + if (NULL == slots || NULL == val || type >= SLOT_PROP_BUTT) { + mpp_err_f("found invalid input slots %p type %d val %p\n", slots, type, val); + return MPP_ERR_UNKNOW; + } + + MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots; + AutoMutex auto_lock(impl->lock); + slot_assert(impl, (index >= 0) && (index < impl->buf_count)); + MppBufSlotEntry *slot = &impl->slots[index]; + + switch (type) { + case SLOT_EOS: { + *(RK_U32*)val = slot->eos; + } break; + case SLOT_FRAME: { + MppFrame *frame = (MppFrame *)val; + //*frame = (slot->status.has_frame) ? (slot->frame) : (NULL); + + mpp_assert(slot->status.has_frame); + if (slot->status.has_frame) { + if (NULL == *frame ) + mpp_frame_init(frame); + if (*frame) + mpp_frame_copy(*frame, slot->frame); + } else + *frame = NULL; + } break; + case SLOT_FRAME_PTR: { + MppFrame *frame = (MppFrame *)val; + *frame = (slot->status.has_frame) ? (slot->frame) : (NULL); + } break; + case SLOT_BUFFER: { + MppBuffer *buffer = (MppBuffer *)val; + *buffer = (slot->status.has_buffer) ? (slot->buffer) : (NULL); + } break; + default : { + } break; + } + + return MPP_OK; +} +MPP_RET mpp_slots_set_prop(MppBufSlots slots, SlotsPropType type, void *val) +{ + if (NULL == slots || NULL == val || type >= SLOTS_PROP_BUTT) { + mpp_err_f("found invalid input slots %p type %d val %p\n", slots, type, val); + return MPP_ERR_UNKNOW; + } + + MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots; + AutoMutex auto_lock(impl->lock); + RK_U32 value = *((RK_U32*)val); + switch (type) { + case SLOTS_EOS: { + impl->eos = value; + } break; + case SLOTS_HOR_ALIGN: { + impl->hal_hor_align = (AlignFunc)val; + } break; + case SLOTS_VER_ALIGN: { + impl->hal_ver_align = (AlignFunc)val; + } break; + case SLOTS_LEN_ALIGN: { + impl->hal_len_align = (AlignFunc)val; + } break; + case SLOTS_COUNT: { + impl->buf_count = value; + } break; + case SLOTS_SIZE: { + impl->buf_size = value; + } break; + case SLOTS_FRAME_INFO: { + // do info change detection here + generate_info_set(impl, (MppFrame)val, 1); + mpp_frame_copy(impl->info, impl->info_set); + { + MppFrameImpl *p = (MppFrameImpl *)impl->info; + mpp_log("set frame info: w %4d h %4d hor %4d ver %4d\n", p->width, p->height, p->hor_stride, p->ver_stride); + } + impl->buf_size = mpp_frame_get_buf_size(impl->info); + } break; + default : { + } break; + } + + return MPP_OK; +} + +MPP_RET mpp_slots_get_prop(MppBufSlots slots, SlotsPropType type, void *val) +{ + if (NULL == slots || NULL == val || type >= SLOTS_PROP_BUTT) { + mpp_err_f("found invalid input slots %p type %d val %p\n", slots, type, val); + return MPP_NOK; + } + + MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots; + AutoMutex auto_lock(impl->lock); + MPP_RET ret = MPP_OK; + RK_U32 value = 0; + switch (type) { + case SLOTS_EOS: { + value = impl->eos; + } break; + case SLOTS_COUNT: { + value = impl->buf_count; + } break; + case SLOTS_SIZE: { + value = (RK_U32)impl->buf_size; + } break; + case SLOTS_FRAME_INFO: { + MppFrame frame = (MppFrame)val; + MppFrame info = impl->info; + mpp_frame_copy(frame, info); + } break; + default : { + mpp_err("can not get slots prop type %d\n", type); + ret = MPP_NOK; + } break; + } + if (MPP_OK == ret) { + if (SLOTS_FRAME_INFO != type) + *(RK_U32 *)val = value; + } + + return ret; +} + +MPP_RET mpp_buf_slot_reset(MppBufSlots slots, RK_S32 index) +{ + if (NULL == slots || index < 0) { + mpp_err_f("found NULL input\n"); + return MPP_ERR_NULL_PTR; + } + + MppBufSlotsImpl *impl = (MppBufSlotsImpl *)slots; + AutoMutex auto_lock(impl->lock); + slot_assert(impl, (index >= 0) && (index < impl->buf_count)); + MppBufSlotEntry *slot = &impl->slots[index]; + + // make sure that this slot is just the next display slot + list_del_init(&slot->list); + slot_ops_with_log(impl, slot, SLOT_CLR_QUEUE_USE, NULL); + slot_ops_with_log(impl, slot, SLOT_DEQUEUE, NULL); + slot_ops_with_log(impl, slot, SLOT_CLR_ON_USE, NULL); + return MPP_OK; +} + diff --git a/mpp/base/mpp_buffer.cpp b/mpp/base/mpp_buffer.cpp index 419ffa6b..ad25c96d 100644 --- a/mpp/base/mpp_buffer.cpp +++ b/mpp/base/mpp_buffer.cpp @@ -1,283 +1,283 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define MODULE_TAG "mpp_buffer" - -#include - -#include "mpp_log.h" -#include "mpp_mem.h" -#include "mpp_buffer_impl.h" - -MPP_RET mpp_buffer_import_with_tag(MppBufferGroup group, MppBufferInfo *info, MppBuffer *buffer, - const char *tag, const char *caller) -{ - if (NULL == info) { - mpp_err("mpp_buffer_commit input null info\n", info); - return MPP_ERR_NULL_PTR; - } - - MppBufferGroupImpl *p = (MppBufferGroupImpl *)group; - - if (p) { - // if group is specified we need to check the parameter - if (p->type != info->type || p->type >= MPP_BUFFER_TYPE_BUTT || - p->mode != MPP_BUFFER_EXTERNAL) { - mpp_err("mpp_buffer_commit invalid type found group %d info %d group mode %d\n", - p->type, info->type, p->mode); - return MPP_ERR_UNKNOW; - } - } else { - // otherwise use default external group to manage them - p = mpp_buffer_get_misc_group(MPP_BUFFER_EXTERNAL, info->type); - } - - mpp_assert(p); - - MPP_RET ret = MPP_OK; - if (buffer) { - MppBufferImpl *buf = NULL; - ret = mpp_buffer_create(tag, caller, p, info, &buf); - *buffer = buf; - } else { - ret = mpp_buffer_create(tag, caller, p, info, NULL); - } - return ret; -} - -MPP_RET mpp_buffer_get_with_tag(MppBufferGroup group, MppBuffer *buffer, size_t size, - const char *tag, const char *caller) -{ - if (NULL == buffer || 0 == size) { - mpp_err("mpp_buffer_get invalid input: group %p buffer %p size %u\n", - group, buffer, size); - return MPP_ERR_UNKNOW; - } - - if (NULL == group) { - // deprecated, only for libvpu support - group = mpp_buffer_get_misc_group(MPP_BUFFER_INTERNAL, MPP_BUFFER_TYPE_ION); - } - - mpp_assert(group); - - MppBufferGroupImpl *p = (MppBufferGroupImpl *)group; - // try unused buffer first - MppBufferImpl *buf = mpp_buffer_get_unused(p, size); - if (NULL == buf && MPP_BUFFER_INTERNAL == p->mode) { - MppBufferInfo info = { - p->type, - size, - NULL, - NULL, - -1, - -1, - }; - // if failed try init a new buffer - mpp_buffer_create(tag, caller, p, &info, &buf); - } - *buffer = buf; - return (buf) ? (MPP_OK) : (MPP_NOK); -} - - -MPP_RET mpp_buffer_put_with_caller(MppBuffer buffer, const char *caller) -{ - if (NULL == buffer) { - mpp_err("mpp_buffer_put invalid input: buffer %p\n", buffer); - return MPP_ERR_UNKNOW; - } - - return mpp_buffer_ref_dec((MppBufferImpl*)buffer, caller); -} - -MPP_RET mpp_buffer_inc_ref_with_caller(MppBuffer buffer, const char *caller) -{ - if (NULL == buffer) { - mpp_err("mpp_buffer_inc_ref invalid input: buffer %p\n", buffer); - return MPP_ERR_UNKNOW; - } - - return mpp_buffer_ref_inc((MppBufferImpl*)buffer, caller); -} - -MPP_RET mpp_buffer_read(MppBuffer buffer, size_t offset, void *data, size_t size) -{ - if (NULL == buffer || NULL == data) { - mpp_err_f("invalid input: buffer %p data %p\n", buffer, data); - return MPP_ERR_UNKNOW; - } - - if (0 == size) - return MPP_OK; - - MppBufferImpl *p = (MppBufferImpl*)buffer; - void *src = p->info.ptr; - mpp_assert(src != NULL); - memcpy(data, (char*)src + offset, size); - return MPP_OK; -} - -MPP_RET mpp_buffer_write(MppBuffer buffer, size_t offset, void *data, size_t size) -{ - if (NULL == buffer || NULL == data) { - mpp_err_f("invalid input: buffer %p data %p\n", buffer, data); - return MPP_ERR_UNKNOW; - } - - if (0 == size) - return MPP_OK; - - MppBufferImpl *p = (MppBufferImpl*)buffer; - void *dst = p->info.ptr; - mpp_assert(dst != NULL); - memcpy((char*)dst + offset, data, size); - return MPP_OK; -} - -void *mpp_buffer_get_ptr(MppBuffer buffer) -{ - if (NULL == buffer) { - mpp_err_f("invalid NULL input\n"); - return NULL; - } - - MppBufferImpl *p = (MppBufferImpl*)buffer; - void *ptr = p->info.ptr; - mpp_assert(ptr != NULL); - return ptr; -} - -int mpp_buffer_get_fd(MppBuffer buffer) -{ - if (NULL == buffer) { - mpp_err_f("invalid NULL input\n"); - return -1; - } - - MppBufferImpl *p = (MppBufferImpl*)buffer; - int fd = p->info.fd; - -#ifdef RKPLATFORM - mpp_assert(fd >= 0); -#endif - - return fd; -} - -size_t mpp_buffer_get_size(MppBuffer buffer) -{ - if (NULL == buffer) { - mpp_err_f("invalid NULL input\n"); - return 0; - } - - MppBufferImpl *p = (MppBufferImpl*)buffer; - return p->info.size; -} - -MPP_RET mpp_buffer_info_get(MppBuffer buffer, MppBufferInfo *info) -{ - if (NULL == buffer || NULL == info) { - mpp_err_f("invalid input: buffer %p info %p\n", buffer, info); - return MPP_ERR_UNKNOW; - } - - *info = ((MppBufferImpl*)buffer)->info; - return MPP_OK; -} - -MPP_RET mpp_buffer_group_get(MppBufferGroup *group, MppBufferType type, MppBufferMode mode, - const char *tag, const char *caller) -{ - if (NULL == group || - mode >= MPP_BUFFER_MODE_BUTT || - type >= MPP_BUFFER_TYPE_BUTT) { - mpp_err_f("input invalid group %p mode %d type %d\n", - group, mode, type); - return MPP_ERR_UNKNOW; - } - - return mpp_buffer_group_init((MppBufferGroupImpl**)group, tag, caller, mode, type); -} - -MPP_RET mpp_buffer_group_put(MppBufferGroup group) -{ - if (NULL == group) { - mpp_err_f("input invalid group %p\n", group); - return MPP_NOK; - } - - return mpp_buffer_group_deinit((MppBufferGroupImpl *)group); -} - -MPP_RET mpp_buffer_group_clear(MppBufferGroup group) -{ - if (NULL == group) { - mpp_err_f("input invalid group %p\n", group); - return MPP_NOK; - } - - return mpp_buffer_group_reset((MppBufferGroupImpl *)group); -} - -RK_S32 mpp_buffer_group_unused(MppBufferGroup group) -{ - if (NULL == group) { - mpp_err_f("input invalid group %p\n", group); - return MPP_NOK; - } - - MppBufferGroupImpl *p = (MppBufferGroupImpl *)group; - return (p->mode == MPP_BUFFER_INTERNAL ? 1 : p->count_unused); -} - -MppBufferMode mpp_buffer_group_mode(MppBufferGroup group) -{ - if (NULL == group) { - mpp_err_f("input invalid group %p\n", group); - return MPP_BUFFER_MODE_BUTT; - } - - MppBufferGroupImpl *p = (MppBufferGroupImpl *)group; - return p->mode; -} - -MppBufferType mpp_buffer_group_type(MppBufferGroup group) -{ - if (NULL == group) { - mpp_err_f("input invalid group %p\n", group); - return MPP_BUFFER_TYPE_BUTT; - } - - MppBufferGroupImpl *p = (MppBufferGroupImpl *)group; - return p->type; -} - -MPP_RET mpp_buffer_group_limit_config(MppBufferGroup group, size_t size, RK_S32 count) -{ - if (NULL == group) { - mpp_err_f("input invalid group %p\n", group); - return MPP_NOK; - } - - MppBufferGroupImpl *p = (MppBufferGroupImpl *)group; - mpp_assert(p->mode == MPP_BUFFER_INTERNAL); - p->limit_size = size; - p->limit_count = count; - return MPP_OK; -} - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define MODULE_TAG "mpp_buffer" + +#include + +#include "mpp_log.h" +#include "mpp_mem.h" +#include "mpp_buffer_impl.h" + +MPP_RET mpp_buffer_import_with_tag(MppBufferGroup group, MppBufferInfo *info, MppBuffer *buffer, + const char *tag, const char *caller) +{ + if (NULL == info) { + mpp_err("mpp_buffer_commit input null info\n", info); + return MPP_ERR_NULL_PTR; + } + + MppBufferGroupImpl *p = (MppBufferGroupImpl *)group; + + if (p) { + // if group is specified we need to check the parameter + if (p->type != info->type || p->type >= MPP_BUFFER_TYPE_BUTT || + p->mode != MPP_BUFFER_EXTERNAL) { + mpp_err("mpp_buffer_commit invalid type found group %d info %d group mode %d\n", + p->type, info->type, p->mode); + return MPP_ERR_UNKNOW; + } + } else { + // otherwise use default external group to manage them + p = mpp_buffer_get_misc_group(MPP_BUFFER_EXTERNAL, info->type); + } + + mpp_assert(p); + + MPP_RET ret = MPP_OK; + if (buffer) { + MppBufferImpl *buf = NULL; + ret = mpp_buffer_create(tag, caller, p, info, &buf); + *buffer = buf; + } else { + ret = mpp_buffer_create(tag, caller, p, info, NULL); + } + return ret; +} + +MPP_RET mpp_buffer_get_with_tag(MppBufferGroup group, MppBuffer *buffer, size_t size, + const char *tag, const char *caller) +{ + if (NULL == buffer || 0 == size) { + mpp_err("mpp_buffer_get invalid input: group %p buffer %p size %u\n", + group, buffer, size); + return MPP_ERR_UNKNOW; + } + + if (NULL == group) { + // deprecated, only for libvpu support + group = mpp_buffer_get_misc_group(MPP_BUFFER_INTERNAL, MPP_BUFFER_TYPE_ION); + } + + mpp_assert(group); + + MppBufferGroupImpl *p = (MppBufferGroupImpl *)group; + // try unused buffer first + MppBufferImpl *buf = mpp_buffer_get_unused(p, size); + if (NULL == buf && MPP_BUFFER_INTERNAL == p->mode) { + MppBufferInfo info = { + p->type, + size, + NULL, + NULL, + -1, + -1, + }; + // if failed try init a new buffer + mpp_buffer_create(tag, caller, p, &info, &buf); + } + *buffer = buf; + return (buf) ? (MPP_OK) : (MPP_NOK); +} + + +MPP_RET mpp_buffer_put_with_caller(MppBuffer buffer, const char *caller) +{ + if (NULL == buffer) { + mpp_err("mpp_buffer_put invalid input: buffer %p\n", buffer); + return MPP_ERR_UNKNOW; + } + + return mpp_buffer_ref_dec((MppBufferImpl*)buffer, caller); +} + +MPP_RET mpp_buffer_inc_ref_with_caller(MppBuffer buffer, const char *caller) +{ + if (NULL == buffer) { + mpp_err("mpp_buffer_inc_ref invalid input: buffer %p\n", buffer); + return MPP_ERR_UNKNOW; + } + + return mpp_buffer_ref_inc((MppBufferImpl*)buffer, caller); +} + +MPP_RET mpp_buffer_read(MppBuffer buffer, size_t offset, void *data, size_t size) +{ + if (NULL == buffer || NULL == data) { + mpp_err_f("invalid input: buffer %p data %p\n", buffer, data); + return MPP_ERR_UNKNOW; + } + + if (0 == size) + return MPP_OK; + + MppBufferImpl *p = (MppBufferImpl*)buffer; + void *src = p->info.ptr; + mpp_assert(src != NULL); + memcpy(data, (char*)src + offset, size); + return MPP_OK; +} + +MPP_RET mpp_buffer_write(MppBuffer buffer, size_t offset, void *data, size_t size) +{ + if (NULL == buffer || NULL == data) { + mpp_err_f("invalid input: buffer %p data %p\n", buffer, data); + return MPP_ERR_UNKNOW; + } + + if (0 == size) + return MPP_OK; + + MppBufferImpl *p = (MppBufferImpl*)buffer; + void *dst = p->info.ptr; + mpp_assert(dst != NULL); + memcpy((char*)dst + offset, data, size); + return MPP_OK; +} + +void *mpp_buffer_get_ptr(MppBuffer buffer) +{ + if (NULL == buffer) { + mpp_err_f("invalid NULL input\n"); + return NULL; + } + + MppBufferImpl *p = (MppBufferImpl*)buffer; + void *ptr = p->info.ptr; + mpp_assert(ptr != NULL); + return ptr; +} + +int mpp_buffer_get_fd(MppBuffer buffer) +{ + if (NULL == buffer) { + mpp_err_f("invalid NULL input\n"); + return -1; + } + + MppBufferImpl *p = (MppBufferImpl*)buffer; + int fd = p->info.fd; + +#ifdef RKPLATFORM + mpp_assert(fd >= 0); +#endif + + return fd; +} + +size_t mpp_buffer_get_size(MppBuffer buffer) +{ + if (NULL == buffer) { + mpp_err_f("invalid NULL input\n"); + return 0; + } + + MppBufferImpl *p = (MppBufferImpl*)buffer; + return p->info.size; +} + +MPP_RET mpp_buffer_info_get(MppBuffer buffer, MppBufferInfo *info) +{ + if (NULL == buffer || NULL == info) { + mpp_err_f("invalid input: buffer %p info %p\n", buffer, info); + return MPP_ERR_UNKNOW; + } + + *info = ((MppBufferImpl*)buffer)->info; + return MPP_OK; +} + +MPP_RET mpp_buffer_group_get(MppBufferGroup *group, MppBufferType type, MppBufferMode mode, + const char *tag, const char *caller) +{ + if (NULL == group || + mode >= MPP_BUFFER_MODE_BUTT || + type >= MPP_BUFFER_TYPE_BUTT) { + mpp_err_f("input invalid group %p mode %d type %d\n", + group, mode, type); + return MPP_ERR_UNKNOW; + } + + return mpp_buffer_group_init((MppBufferGroupImpl**)group, tag, caller, mode, type); +} + +MPP_RET mpp_buffer_group_put(MppBufferGroup group) +{ + if (NULL == group) { + mpp_err_f("input invalid group %p\n", group); + return MPP_NOK; + } + + return mpp_buffer_group_deinit((MppBufferGroupImpl *)group); +} + +MPP_RET mpp_buffer_group_clear(MppBufferGroup group) +{ + if (NULL == group) { + mpp_err_f("input invalid group %p\n", group); + return MPP_NOK; + } + + return mpp_buffer_group_reset((MppBufferGroupImpl *)group); +} + +RK_S32 mpp_buffer_group_unused(MppBufferGroup group) +{ + if (NULL == group) { + mpp_err_f("input invalid group %p\n", group); + return MPP_NOK; + } + + MppBufferGroupImpl *p = (MppBufferGroupImpl *)group; + return (p->mode == MPP_BUFFER_INTERNAL ? 1 : p->count_unused); +} + +MppBufferMode mpp_buffer_group_mode(MppBufferGroup group) +{ + if (NULL == group) { + mpp_err_f("input invalid group %p\n", group); + return MPP_BUFFER_MODE_BUTT; + } + + MppBufferGroupImpl *p = (MppBufferGroupImpl *)group; + return p->mode; +} + +MppBufferType mpp_buffer_group_type(MppBufferGroup group) +{ + if (NULL == group) { + mpp_err_f("input invalid group %p\n", group); + return MPP_BUFFER_TYPE_BUTT; + } + + MppBufferGroupImpl *p = (MppBufferGroupImpl *)group; + return p->type; +} + +MPP_RET mpp_buffer_group_limit_config(MppBufferGroup group, size_t size, RK_S32 count) +{ + if (NULL == group) { + mpp_err_f("input invalid group %p\n", group); + return MPP_NOK; + } + + MppBufferGroupImpl *p = (MppBufferGroupImpl *)group; + mpp_assert(p->mode == MPP_BUFFER_INTERNAL); + p->limit_size = size; + p->limit_count = count; + return MPP_OK; +} + diff --git a/mpp/base/mpp_buffer_impl.cpp b/mpp/base/mpp_buffer_impl.cpp index bb9b42c5..16826b2a 100644 --- a/mpp/base/mpp_buffer_impl.cpp +++ b/mpp/base/mpp_buffer_impl.cpp @@ -1,731 +1,731 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define MODULE_TAG "mpp_buffer" - -#include - -#include "mpp_log.h" -#include "mpp_mem.h" -#include "mpp_env.h" - -#include "mpp_buffer_impl.h" - -#define BUFFER_OPS_MAX_COUNT 1024 - -#define SEARCH_GROUP_BY_ID(id) ((MppBufferService::get_instance())->get_group_by_id(id)) - -typedef MPP_RET (*BufferOp)(MppAllocator allocator, MppBufferInfo *data); - -typedef enum MppBufOps_e { - GRP_CREATE, - GRP_RELEASE, - GRP_DESTROY, - - GRP_OPS_BUTT = GRP_DESTROY, - BUF_COMMIT, - BUF_CREATE, - BUF_REF_INC, - BUF_REF_DEC, - BUF_DESTROY, - BUF_OPS_BUTT, -} MppBufOps; - -typedef struct MppBufLog_t { - struct list_head list; - RK_U32 group_id; - RK_S32 buffer_id; - MppBufOps ops; - RK_S32 ref_count; - const char *caller; -} MppBufLog; - -// use this class only need it to init legacy group before main -class MppBufferService -{ -private: - - // avoid any unwanted function - MppBufferService(); - ~MppBufferService(); - MppBufferService(const MppBufferService &); - MppBufferService &operator=(const MppBufferService &); - - // buffer group final release function - void destroy_group(MppBufferGroupImpl *group); - - RK_U32 get_group_id(); - RK_U32 group_id; - RK_U32 group_count; - - MppBufferGroupImpl *misc_ion_int; - MppBufferGroupImpl *misc_ion_ext; - - struct list_head mListGroup; - - // list for used buffer which do not have group - struct list_head mListOrphan; - -public: - static MppBufferService *get_instance() { - static MppBufferService instance; - return &instance; - } - static Mutex *get_lock() { - static Mutex lock; - return &lock; - } - - MppBufferGroupImpl *get_group(const char *tag, const char *caller, MppBufferMode mode, MppBufferType type); - MppBufferGroupImpl *get_misc_group(MppBufferMode mode, MppBufferType type); - void put_group(MppBufferGroupImpl *group); - MppBufferGroupImpl *get_group_by_id(RK_U32 id); - void dump_misc_group(); -}; - -static const char *mode2str[MPP_BUFFER_MODE_BUTT] = { - "internal", - "external", -}; - -static const char *type2str[MPP_BUFFER_TYPE_BUTT] = { - "normal", - "ion", - "v4l2", - "drm", -}; -static const char *ops2str[BUF_OPS_BUTT] = { - "grp create ", - "grp release", - "grp destroy", - "buf commit ", - "buf create ", - "buf ref inc", - "buf ref dec", - "buf destroy", -}; - -RK_U32 mpp_buffer_debug = 0; - -void buffer_group_add_log(MppBufferGroupImpl *group, MppBufferImpl *buffer, MppBufOps ops, const char* caller) -{ - if (group->log_runtime_en) { - if (buffer) { - mpp_log("group %2d buffer %2d fd %2d ops %s ref_count %d caller %s\n", group->group_id, - buffer->buffer_id, buffer->info.fd, ops2str[ops], buffer->ref_count, caller); - } else { - mpp_log("group %2d ops %s\n", group->group_id, ops2str[ops]); - } - } - if (group->log_history_en) { - struct list_head *logs = &group->list_logs; - MppBufLog *log = mpp_malloc(MppBufLog, 1); - if (log) { - INIT_LIST_HEAD(&log->list); - log->group_id = group->group_id; - log->buffer_id = (buffer) ? (buffer->buffer_id) : (-1); - log->ops = ops; - log->ref_count = (buffer) ? (buffer->ref_count) : (0); - log->caller = caller; - - if (group->log_count >= BUFFER_OPS_MAX_COUNT) { - struct list_head *tmp = logs->next; - list_del_init(tmp); - mpp_free(list_entry(tmp, MppBufLog, list)); - group->log_count--; - } - list_add_tail(&log->list, logs); - group->log_count++; - } - } -} - -void buffer_group_dump_log(MppBufferGroupImpl *group) -{ - if (group->log_history_en) { - struct list_head *logs = &group->list_logs; - - while (!list_empty(logs)) { - struct list_head *tmp = logs->next; - MppBufLog *log = list_entry(tmp, MppBufLog, list); - list_del_init(tmp); - if (log->buffer_id >= 0) { - mpp_log("group %2d buffer %2d ops %s ref_count %d caller %s\n", group->group_id, - log->buffer_id, ops2str[log->ops], log->ref_count, log->caller); - } else { - mpp_log("group %3d ops %s\n", group->group_id, ops2str[log->ops]); - } - mpp_free(log); - } - } -} - -MPP_RET deinit_buffer_no_lock(MppBufferImpl *buffer, const char *caller) -{ - mpp_assert(buffer->ref_count == 0); - mpp_assert(buffer->used == 0); - - list_del_init(&buffer->list_status); - MppBufferGroupImpl *group = SEARCH_GROUP_BY_ID(buffer->group_id); - BufferOp func = (group->mode == MPP_BUFFER_INTERNAL) ? - (group->alloc_api->free) : - (group->alloc_api->release); - func(group->allocator, &buffer->info); - group->usage -= buffer->info.size; - group->buffer_count--; - - buffer_group_add_log(group, buffer, BUF_DESTROY, caller); - - if (group->is_orphan && !group->usage) { - MppBufferService::get_instance()->put_group(group); - } - - mpp_free(buffer); - - return MPP_OK; -} - -static MPP_RET inc_buffer_ref_no_lock(MppBufferImpl *buffer, const char *caller) -{ - MPP_RET ret = MPP_OK; - MppBufferGroupImpl *group = SEARCH_GROUP_BY_ID(buffer->group_id); - if (!buffer->used) { - // NOTE: when increasing ref_count the unused buffer must be under certain group - mpp_assert(group); - buffer->used = 1; - if (group) { - list_del_init(&buffer->list_status); - list_add_tail(&buffer->list_status, &group->list_used); - group->count_used++; - group->count_unused--; - } else { - mpp_err_f("unused buffer without group\n"); - ret = MPP_NOK; - } - } - buffer_group_add_log(group, buffer, BUF_REF_INC, caller); - buffer->ref_count++; - return ret; -} - -static void dump_buffer_info(MppBufferImpl *buffer) -{ - mpp_log("buffer %p fd %4d size %10d ref_count %3d discard %d caller %s\n", - buffer, buffer->info.fd, buffer->info.size, - buffer->ref_count, buffer->discard, buffer->caller); -} - -MPP_RET mpp_buffer_create(const char *tag, const char *caller, - MppBufferGroupImpl *group, MppBufferInfo *info, - MppBufferImpl **buffer) -{ - AutoMutex auto_lock(MppBufferService::get_lock()); - MPP_BUF_FUNCTION_ENTER(); - - MPP_RET ret = MPP_OK; - BufferOp func = NULL; - MppBufferImpl *p = NULL; - - if (NULL == group) { - mpp_err_f("can not create buffer without group\n"); - ret = MPP_NOK; - goto RET; - } - - if (group->limit_count && group->buffer_count >= group->limit_count) { - if (group->log_runtime_en) - mpp_log_f("group %d reach count limit %d\n", group->group_id, group->limit_count); - ret = MPP_NOK; - goto RET; - } - - if (group->limit_size && info->size > group->limit_size) { - mpp_err_f("required size %d reach group size limit %d\n", info->size, group->limit_size); - ret = MPP_NOK; - goto RET; - } - - p = mpp_calloc(MppBufferImpl, 1); - if (NULL == p) { - mpp_err_f("failed to allocate context\n"); - ret = MPP_ERR_MALLOC; - goto RET; - } - - func = (group->mode == MPP_BUFFER_INTERNAL) ? - (group->alloc_api->alloc) : (group->alloc_api->import); - ret = func(group->allocator, info); - if (MPP_OK != ret) { - mpp_err_f("failed to create buffer with size %d\n", info->size); - mpp_free(p); - ret = MPP_ERR_MALLOC; - goto RET; - } - - p->info = *info; - p->mode = group->mode; - - if (NULL == tag) - tag = group->tag; - - strncpy(p->tag, tag, sizeof(p->tag)); - p->caller = caller; - p->group_id = group->group_id; - p->buffer_id = group->buffer_id; - INIT_LIST_HEAD(&p->list_status); - list_add_tail(&p->list_status, &group->list_unused); - - group->buffer_id++; - group->usage += info->size; - group->buffer_count++; - group->count_unused++; - - buffer_group_add_log(group, p, - (group->mode == MPP_BUFFER_INTERNAL) ? (BUF_CREATE) : (BUF_COMMIT), - caller); - - if (buffer) { - inc_buffer_ref_no_lock(p, caller); - *buffer = p; - } -RET: - MPP_BUF_FUNCTION_LEAVE(); - return ret; -} - -MPP_RET mpp_buffer_ref_inc(MppBufferImpl *buffer, const char* caller) -{ - AutoMutex auto_lock(MppBufferService::get_lock()); - MPP_BUF_FUNCTION_ENTER(); - - MPP_RET ret = inc_buffer_ref_no_lock(buffer, caller); - - MPP_BUF_FUNCTION_LEAVE(); - return ret; -} - - -MPP_RET mpp_buffer_ref_dec(MppBufferImpl *buffer, const char* caller) -{ - AutoMutex auto_lock(MppBufferService::get_lock()); - MPP_BUF_FUNCTION_ENTER(); - - MPP_RET ret = MPP_OK; - MppBufferGroupImpl *group = SEARCH_GROUP_BY_ID(buffer->group_id); - buffer_group_add_log(group, buffer, BUF_REF_DEC, caller); - - if (buffer->ref_count <= 0) { - mpp_err_f("found non-positive ref_count %d caller %s\n", - buffer->ref_count, buffer->caller); - mpp_abort(); - ret = MPP_NOK; - } else { - buffer->ref_count--; - if (0 == buffer->ref_count) { - buffer->used = 0; - list_del_init(&buffer->list_status); - if (group == MppBufferService::get_instance()->get_misc_group(group->mode, group->type)) { - deinit_buffer_no_lock(buffer, caller); - } else { - if (buffer->discard) { - deinit_buffer_no_lock(buffer, caller); - } else { - list_add_tail(&buffer->list_status, &group->list_unused); - group->count_unused++; - } - } - group->count_used--; - if (group->listener) { - MppThread *thread = (MppThread *)group->listener; - thread->signal(); - } - } - } - - MPP_BUF_FUNCTION_LEAVE(); - return ret; -} - -MppBufferImpl *mpp_buffer_get_unused(MppBufferGroupImpl *p, size_t size) -{ - AutoMutex auto_lock(MppBufferService::get_lock()); - MPP_BUF_FUNCTION_ENTER(); - - MppBufferImpl *buffer = NULL; - - if (!list_empty(&p->list_unused)) { - MppBufferImpl *pos, *n; - RK_S32 found = 0; - RK_S32 search_count = 0; - - list_for_each_entry_safe(pos, n, &p->list_unused, MppBufferImpl, list_status) { - mpp_buf_dbg(MPP_BUF_DBG_CHECK_SIZE, "request size %d on buf idx %d size %d\n", - size, pos->buffer_id, pos->info.size); - if (pos->info.size >= size) { - buffer = pos; - inc_buffer_ref_no_lock(buffer, __FUNCTION__); - found = 1; - break; - } else { - if (MPP_BUFFER_INTERNAL == p->mode) { - deinit_buffer_no_lock(pos, __FUNCTION__); - p->count_unused--; - } else - search_count++; - } - } - - if (!found && search_count) - mpp_err_f("can not found match buffer with size larger than %d\n", size); - } - - MPP_BUF_FUNCTION_LEAVE(); - return buffer; -} - -MPP_RET mpp_buffer_group_init(MppBufferGroupImpl **group, const char *tag, const char *caller, - MppBufferMode mode, MppBufferType type) -{ - AutoMutex auto_lock(MppBufferService::get_lock()); - - mpp_assert(caller); - MPP_BUF_FUNCTION_ENTER(); - - *group = MppBufferService::get_instance()->get_group(tag, caller, mode, type); - - MPP_BUF_FUNCTION_LEAVE(); - return ((*group) ? (MPP_OK) : (MPP_NOK)); -} - -MPP_RET mpp_buffer_group_deinit(MppBufferGroupImpl *p) -{ - AutoMutex auto_lock(MppBufferService::get_lock()); - if (NULL == p) { - mpp_err_f("found NULL pointer\n"); - return MPP_ERR_NULL_PTR; - } - - MPP_BUF_FUNCTION_ENTER(); - - MppBufferService::get_instance()->put_group(p); - - MPP_BUF_FUNCTION_LEAVE(); - return MPP_OK; -} - -MPP_RET mpp_buffer_group_reset(MppBufferGroupImpl *p) -{ - AutoMutex auto_lock(MppBufferService::get_lock()); - if (NULL == p) { - mpp_err_f("found NULL pointer\n"); - return MPP_ERR_NULL_PTR; - } - - MPP_BUF_FUNCTION_ENTER(); - - if (!list_empty(&p->list_used)) { - MppBufferImpl *pos, *n; - list_for_each_entry_safe(pos, n, &p->list_used, MppBufferImpl, list_status) { - // mpp_buffer_ref_dec(pos); - pos->discard = 1; - } - } - - // remove unused list - if (!list_empty(&p->list_unused)) { - MppBufferImpl *pos, *n; - list_for_each_entry_safe(pos, n, &p->list_unused, MppBufferImpl, list_status) { - deinit_buffer_no_lock(pos, __FUNCTION__); - p->count_unused--; - } - } - - MPP_BUF_FUNCTION_LEAVE(); - return MPP_OK; -} - -MPP_RET mpp_buffer_group_set_listener(MppBufferGroupImpl *p, void *listener) -{ - AutoMutex auto_lock(MppBufferService::get_lock()); - if (NULL == p) { - mpp_err_f("found NULL pointer\n"); - return MPP_ERR_NULL_PTR; - } - - MPP_BUF_FUNCTION_ENTER(); - - p->listener = listener; - - MPP_BUF_FUNCTION_LEAVE(); - return MPP_OK; -} - -void mpp_buffer_group_dump(MppBufferGroupImpl *group) -{ - mpp_log("\ndumping buffer group %p id %d\n", group, group->group_id); - mpp_log("mode %s\n", mode2str[group->mode]); - mpp_log("type %s\n", type2str[group->type]); - mpp_log("limit size %d count %d\n", group->limit_size, group->limit_count); - - mpp_log("used buffer count %d\n", group->count_used); - - MppBufferImpl *pos, *n; - list_for_each_entry_safe(pos, n, &group->list_used, MppBufferImpl, list_status) { - dump_buffer_info(pos); - } - - mpp_log("unused buffer count %d\n", group->count_unused); - list_for_each_entry_safe(pos, n, &group->list_unused, MppBufferImpl, list_status) { - dump_buffer_info(pos); - } - - buffer_group_dump_log(group); -} - -void mpp_buffer_service_dump() -{ - AutoMutex auto_lock(MppBufferService::get_lock()); - MppBufferService::get_instance()->dump_misc_group(); -} - -MppBufferGroupImpl *mpp_buffer_get_misc_group(MppBufferMode mode, MppBufferType type) -{ - AutoMutex auto_lock(MppBufferService::get_lock()); - return MppBufferService::get_instance()->get_misc_group(mode, type); -} - -MppBufferService::MppBufferService() - : group_id(0), - group_count(0), - misc_ion_int(NULL), - misc_ion_ext(NULL) -{ - INIT_LIST_HEAD(&mListGroup); - INIT_LIST_HEAD(&mListOrphan); - - // NOTE: here can not call mpp_buffer_group_init for the service is not started - // misc group can accept all kind of buffer which is available - misc_ion_int = get_group("misc_ion_int", "MppBufferService", MPP_BUFFER_INTERNAL, MPP_BUFFER_TYPE_ION); - misc_ion_ext = get_group("misc_ion_ext", "MppBufferService", MPP_BUFFER_EXTERNAL, MPP_BUFFER_TYPE_ION); -} - -MppBufferService::~MppBufferService() -{ - // first remove legacy group - if (misc_ion_ext) { - put_group(misc_ion_ext); - misc_ion_ext = NULL; - } - - if (misc_ion_int) { - put_group(misc_ion_int); - misc_ion_int = NULL; - } - - // then remove the remaining group - if (!list_empty(&mListGroup)) { - MppBufferGroupImpl *pos, *n; - list_for_each_entry_safe(pos, n, &mListGroup, MppBufferGroupImpl, list_group) { - put_group(pos); - } - } - - // remove all orphan buffer - if (!list_empty(&mListOrphan)) { - MppBufferImpl *pos, *n; - list_for_each_entry_safe(pos, n, &mListOrphan, MppBufferImpl, list_status) { - deinit_buffer_no_lock(pos, __FUNCTION__); - } - } -} - -RK_U32 MppBufferService::get_group_id() -{ - // avoid group_id reuse - RK_U32 id = group_id++; - while (get_group_by_id(group_id)) { - group_id++; - } - group_count++; - return id; -} - -MppBufferGroupImpl *MppBufferService::get_group(const char *tag, const char *caller, - MppBufferMode mode, MppBufferType type) -{ - MppBufferGroupImpl *p = mpp_calloc(MppBufferGroupImpl, 1); - if (NULL == p) { - mpp_err("MppBufferService failed to allocate group context\n"); - return NULL; - } - - RK_U32 id = get_group_id(); - - INIT_LIST_HEAD(&p->list_logs); - INIT_LIST_HEAD(&p->list_group); - INIT_LIST_HEAD(&p->list_used); - INIT_LIST_HEAD(&p->list_unused); - - mpp_env_get_u32("mpp_buffer_debug", &mpp_buffer_debug, 0); - p->log_runtime_en = (mpp_buffer_debug & MPP_BUF_DBG_OPS_RUNTIME) ? (1) : (0); - p->log_history_en = (mpp_buffer_debug & MPP_BUF_DBG_OPS_HISTORY) ? (1) : (0); - - list_add_tail(&p->list_group, &mListGroup); - - if (tag) { - snprintf(p->tag, sizeof(p->tag), "%s_%d", tag, id); - } else { - snprintf(p->tag, sizeof(p->tag), "unknown"); - } - p->caller = caller; - p->mode = mode; - p->type = type; - p->limit = BUFFER_GROUP_SIZE_DEFAULT; - p->group_id = id; - p->clear_on_exit = (mpp_buffer_debug & MPP_BUF_DBG_CLR_ON_EXIT) ? (1) : (0); - - mpp_allocator_get(&p->allocator, &p->alloc_api, type); - - buffer_group_add_log(p, NULL, GRP_CREATE, __FUNCTION__); - - return p; -} - -MppBufferGroupImpl *MppBufferService::get_misc_group(MppBufferMode mode, MppBufferType type) -{ - if (type == MPP_BUFFER_TYPE_NORMAL) - return NULL; - - mpp_assert(type == MPP_BUFFER_TYPE_ION); - mpp_assert(mode < MPP_BUFFER_MODE_BUTT); - return (mode == MPP_BUFFER_INTERNAL) ? (misc_ion_int) : (misc_ion_ext); -} - -void MppBufferService::put_group(MppBufferGroupImpl *p) -{ - buffer_group_add_log(p, NULL, GRP_RELEASE, __FUNCTION__); - - // remove unused list - if (!list_empty(&p->list_unused)) { - MppBufferImpl *pos, *n; - list_for_each_entry_safe(pos, n, &p->list_unused, MppBufferImpl, list_status) { - deinit_buffer_no_lock(pos, __FUNCTION__); - p->count_unused--; - } - } - - if (list_empty(&p->list_used)) { - destroy_group(p); - } else { - mpp_err("mpp_group %p tag %s caller %s mode %s type %s deinit with %d bytes not released\n", - p, p->tag, p->caller, mode2str[p->mode], type2str[p->type], p->usage); - - mpp_buffer_group_dump(p); - - /* if clear on exit we need to release remaining buffer */ - if (p->clear_on_exit) { - MppBufferImpl *pos, *n; - - mpp_err("force release all remaining buffer\n"); - - list_for_each_entry_safe(pos, n, &p->list_used, MppBufferImpl, list_status) { - mpp_err("clearing buffer %p pos\n"); - pos->ref_count = 0; - pos->used = 0; - pos->discard = 0; - deinit_buffer_no_lock(pos, __FUNCTION__); - p->count_used--; - } - - destroy_group(p); - } else { - // otherwise move the group to list_orphan and wait for buffer release - list_del_init(&p->list_group); - list_add_tail(&p->list_group, &mListOrphan); - p->is_orphan = 1; - } - } -} - -void MppBufferService::destroy_group(MppBufferGroupImpl *group) -{ - mpp_assert(group->count_used == 0); - mpp_assert(group->count_unused == 0); - if (group->count_unused || group->count_used) { - mpp_err("mpp_buffer_group_deinit mismatch counter used %4d unused %4d found\n", - group->count_used, group->count_unused); - group->count_unused = 0; - group->count_used = 0; - } - - buffer_group_add_log(group, NULL, GRP_DESTROY, __FUNCTION__); - - if (group->log_history_en) { - struct list_head *logs = &group->list_logs; - while (!list_empty(logs)) { - struct list_head *tmp = logs->next; - list_del_init(tmp); - mpp_free(list_entry(tmp, MppBufLog, list)); - group->log_count--; - } - mpp_assert(group->log_count == 0); - } - - mpp_assert(group->allocator); - mpp_allocator_put(&group->allocator); - list_del_init(&group->list_group); - mpp_free(group); - group_count--; - - if (group == misc_ion_int) { - misc_ion_int = NULL; - } else { - /* if only legacy group left dump the legacy group */ - if (group_count == 1 && misc_ion_int && misc_ion_int->buffer_count) { - mpp_log("found legacy group has buffer remain, start dumping\n"); - mpp_buffer_group_dump(misc_ion_int); - abort(); - } - } -} - -MppBufferGroupImpl *MppBufferService::get_group_by_id(RK_U32 id) -{ - MppBufferGroupImpl *pos, *n; - list_for_each_entry_safe(pos, n, &mListGroup, MppBufferGroupImpl, list_group) { - if (pos->group_id == id) { - return pos; - } - } - - list_for_each_entry_safe(pos, n, &mListOrphan, MppBufferGroupImpl, list_group) { - if (pos->group_id == id) { - return pos; - } - } - - return NULL; -} - -void MppBufferService::dump_misc_group() -{ - if (misc_ion_int->buffer_count) - mpp_buffer_group_dump(misc_ion_int); - - if (misc_ion_ext->buffer_count) - mpp_buffer_group_dump(misc_ion_ext); -} - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define MODULE_TAG "mpp_buffer" + +#include + +#include "mpp_log.h" +#include "mpp_mem.h" +#include "mpp_env.h" + +#include "mpp_buffer_impl.h" + +#define BUFFER_OPS_MAX_COUNT 1024 + +#define SEARCH_GROUP_BY_ID(id) ((MppBufferService::get_instance())->get_group_by_id(id)) + +typedef MPP_RET (*BufferOp)(MppAllocator allocator, MppBufferInfo *data); + +typedef enum MppBufOps_e { + GRP_CREATE, + GRP_RELEASE, + GRP_DESTROY, + + GRP_OPS_BUTT = GRP_DESTROY, + BUF_COMMIT, + BUF_CREATE, + BUF_REF_INC, + BUF_REF_DEC, + BUF_DESTROY, + BUF_OPS_BUTT, +} MppBufOps; + +typedef struct MppBufLog_t { + struct list_head list; + RK_U32 group_id; + RK_S32 buffer_id; + MppBufOps ops; + RK_S32 ref_count; + const char *caller; +} MppBufLog; + +// use this class only need it to init legacy group before main +class MppBufferService +{ +private: + + // avoid any unwanted function + MppBufferService(); + ~MppBufferService(); + MppBufferService(const MppBufferService &); + MppBufferService &operator=(const MppBufferService &); + + // buffer group final release function + void destroy_group(MppBufferGroupImpl *group); + + RK_U32 get_group_id(); + RK_U32 group_id; + RK_U32 group_count; + + MppBufferGroupImpl *misc_ion_int; + MppBufferGroupImpl *misc_ion_ext; + + struct list_head mListGroup; + + // list for used buffer which do not have group + struct list_head mListOrphan; + +public: + static MppBufferService *get_instance() { + static MppBufferService instance; + return &instance; + } + static Mutex *get_lock() { + static Mutex lock; + return &lock; + } + + MppBufferGroupImpl *get_group(const char *tag, const char *caller, MppBufferMode mode, MppBufferType type); + MppBufferGroupImpl *get_misc_group(MppBufferMode mode, MppBufferType type); + void put_group(MppBufferGroupImpl *group); + MppBufferGroupImpl *get_group_by_id(RK_U32 id); + void dump_misc_group(); +}; + +static const char *mode2str[MPP_BUFFER_MODE_BUTT] = { + "internal", + "external", +}; + +static const char *type2str[MPP_BUFFER_TYPE_BUTT] = { + "normal", + "ion", + "v4l2", + "drm", +}; +static const char *ops2str[BUF_OPS_BUTT] = { + "grp create ", + "grp release", + "grp destroy", + "buf commit ", + "buf create ", + "buf ref inc", + "buf ref dec", + "buf destroy", +}; + +RK_U32 mpp_buffer_debug = 0; + +void buffer_group_add_log(MppBufferGroupImpl *group, MppBufferImpl *buffer, MppBufOps ops, const char* caller) +{ + if (group->log_runtime_en) { + if (buffer) { + mpp_log("group %2d buffer %2d fd %2d ops %s ref_count %d caller %s\n", group->group_id, + buffer->buffer_id, buffer->info.fd, ops2str[ops], buffer->ref_count, caller); + } else { + mpp_log("group %2d ops %s\n", group->group_id, ops2str[ops]); + } + } + if (group->log_history_en) { + struct list_head *logs = &group->list_logs; + MppBufLog *log = mpp_malloc(MppBufLog, 1); + if (log) { + INIT_LIST_HEAD(&log->list); + log->group_id = group->group_id; + log->buffer_id = (buffer) ? (buffer->buffer_id) : (-1); + log->ops = ops; + log->ref_count = (buffer) ? (buffer->ref_count) : (0); + log->caller = caller; + + if (group->log_count >= BUFFER_OPS_MAX_COUNT) { + struct list_head *tmp = logs->next; + list_del_init(tmp); + mpp_free(list_entry(tmp, MppBufLog, list)); + group->log_count--; + } + list_add_tail(&log->list, logs); + group->log_count++; + } + } +} + +void buffer_group_dump_log(MppBufferGroupImpl *group) +{ + if (group->log_history_en) { + struct list_head *logs = &group->list_logs; + + while (!list_empty(logs)) { + struct list_head *tmp = logs->next; + MppBufLog *log = list_entry(tmp, MppBufLog, list); + list_del_init(tmp); + if (log->buffer_id >= 0) { + mpp_log("group %2d buffer %2d ops %s ref_count %d caller %s\n", group->group_id, + log->buffer_id, ops2str[log->ops], log->ref_count, log->caller); + } else { + mpp_log("group %3d ops %s\n", group->group_id, ops2str[log->ops]); + } + mpp_free(log); + } + } +} + +MPP_RET deinit_buffer_no_lock(MppBufferImpl *buffer, const char *caller) +{ + mpp_assert(buffer->ref_count == 0); + mpp_assert(buffer->used == 0); + + list_del_init(&buffer->list_status); + MppBufferGroupImpl *group = SEARCH_GROUP_BY_ID(buffer->group_id); + BufferOp func = (group->mode == MPP_BUFFER_INTERNAL) ? + (group->alloc_api->free) : + (group->alloc_api->release); + func(group->allocator, &buffer->info); + group->usage -= buffer->info.size; + group->buffer_count--; + + buffer_group_add_log(group, buffer, BUF_DESTROY, caller); + + if (group->is_orphan && !group->usage) { + MppBufferService::get_instance()->put_group(group); + } + + mpp_free(buffer); + + return MPP_OK; +} + +static MPP_RET inc_buffer_ref_no_lock(MppBufferImpl *buffer, const char *caller) +{ + MPP_RET ret = MPP_OK; + MppBufferGroupImpl *group = SEARCH_GROUP_BY_ID(buffer->group_id); + if (!buffer->used) { + // NOTE: when increasing ref_count the unused buffer must be under certain group + mpp_assert(group); + buffer->used = 1; + if (group) { + list_del_init(&buffer->list_status); + list_add_tail(&buffer->list_status, &group->list_used); + group->count_used++; + group->count_unused--; + } else { + mpp_err_f("unused buffer without group\n"); + ret = MPP_NOK; + } + } + buffer_group_add_log(group, buffer, BUF_REF_INC, caller); + buffer->ref_count++; + return ret; +} + +static void dump_buffer_info(MppBufferImpl *buffer) +{ + mpp_log("buffer %p fd %4d size %10d ref_count %3d discard %d caller %s\n", + buffer, buffer->info.fd, buffer->info.size, + buffer->ref_count, buffer->discard, buffer->caller); +} + +MPP_RET mpp_buffer_create(const char *tag, const char *caller, + MppBufferGroupImpl *group, MppBufferInfo *info, + MppBufferImpl **buffer) +{ + AutoMutex auto_lock(MppBufferService::get_lock()); + MPP_BUF_FUNCTION_ENTER(); + + MPP_RET ret = MPP_OK; + BufferOp func = NULL; + MppBufferImpl *p = NULL; + + if (NULL == group) { + mpp_err_f("can not create buffer without group\n"); + ret = MPP_NOK; + goto RET; + } + + if (group->limit_count && group->buffer_count >= group->limit_count) { + if (group->log_runtime_en) + mpp_log_f("group %d reach count limit %d\n", group->group_id, group->limit_count); + ret = MPP_NOK; + goto RET; + } + + if (group->limit_size && info->size > group->limit_size) { + mpp_err_f("required size %d reach group size limit %d\n", info->size, group->limit_size); + ret = MPP_NOK; + goto RET; + } + + p = mpp_calloc(MppBufferImpl, 1); + if (NULL == p) { + mpp_err_f("failed to allocate context\n"); + ret = MPP_ERR_MALLOC; + goto RET; + } + + func = (group->mode == MPP_BUFFER_INTERNAL) ? + (group->alloc_api->alloc) : (group->alloc_api->import); + ret = func(group->allocator, info); + if (MPP_OK != ret) { + mpp_err_f("failed to create buffer with size %d\n", info->size); + mpp_free(p); + ret = MPP_ERR_MALLOC; + goto RET; + } + + p->info = *info; + p->mode = group->mode; + + if (NULL == tag) + tag = group->tag; + + strncpy(p->tag, tag, sizeof(p->tag)); + p->caller = caller; + p->group_id = group->group_id; + p->buffer_id = group->buffer_id; + INIT_LIST_HEAD(&p->list_status); + list_add_tail(&p->list_status, &group->list_unused); + + group->buffer_id++; + group->usage += info->size; + group->buffer_count++; + group->count_unused++; + + buffer_group_add_log(group, p, + (group->mode == MPP_BUFFER_INTERNAL) ? (BUF_CREATE) : (BUF_COMMIT), + caller); + + if (buffer) { + inc_buffer_ref_no_lock(p, caller); + *buffer = p; + } +RET: + MPP_BUF_FUNCTION_LEAVE(); + return ret; +} + +MPP_RET mpp_buffer_ref_inc(MppBufferImpl *buffer, const char* caller) +{ + AutoMutex auto_lock(MppBufferService::get_lock()); + MPP_BUF_FUNCTION_ENTER(); + + MPP_RET ret = inc_buffer_ref_no_lock(buffer, caller); + + MPP_BUF_FUNCTION_LEAVE(); + return ret; +} + + +MPP_RET mpp_buffer_ref_dec(MppBufferImpl *buffer, const char* caller) +{ + AutoMutex auto_lock(MppBufferService::get_lock()); + MPP_BUF_FUNCTION_ENTER(); + + MPP_RET ret = MPP_OK; + MppBufferGroupImpl *group = SEARCH_GROUP_BY_ID(buffer->group_id); + buffer_group_add_log(group, buffer, BUF_REF_DEC, caller); + + if (buffer->ref_count <= 0) { + mpp_err_f("found non-positive ref_count %d caller %s\n", + buffer->ref_count, buffer->caller); + mpp_abort(); + ret = MPP_NOK; + } else { + buffer->ref_count--; + if (0 == buffer->ref_count) { + buffer->used = 0; + list_del_init(&buffer->list_status); + if (group == MppBufferService::get_instance()->get_misc_group(group->mode, group->type)) { + deinit_buffer_no_lock(buffer, caller); + } else { + if (buffer->discard) { + deinit_buffer_no_lock(buffer, caller); + } else { + list_add_tail(&buffer->list_status, &group->list_unused); + group->count_unused++; + } + } + group->count_used--; + if (group->listener) { + MppThread *thread = (MppThread *)group->listener; + thread->signal(); + } + } + } + + MPP_BUF_FUNCTION_LEAVE(); + return ret; +} + +MppBufferImpl *mpp_buffer_get_unused(MppBufferGroupImpl *p, size_t size) +{ + AutoMutex auto_lock(MppBufferService::get_lock()); + MPP_BUF_FUNCTION_ENTER(); + + MppBufferImpl *buffer = NULL; + + if (!list_empty(&p->list_unused)) { + MppBufferImpl *pos, *n; + RK_S32 found = 0; + RK_S32 search_count = 0; + + list_for_each_entry_safe(pos, n, &p->list_unused, MppBufferImpl, list_status) { + mpp_buf_dbg(MPP_BUF_DBG_CHECK_SIZE, "request size %d on buf idx %d size %d\n", + size, pos->buffer_id, pos->info.size); + if (pos->info.size >= size) { + buffer = pos; + inc_buffer_ref_no_lock(buffer, __FUNCTION__); + found = 1; + break; + } else { + if (MPP_BUFFER_INTERNAL == p->mode) { + deinit_buffer_no_lock(pos, __FUNCTION__); + p->count_unused--; + } else + search_count++; + } + } + + if (!found && search_count) + mpp_err_f("can not found match buffer with size larger than %d\n", size); + } + + MPP_BUF_FUNCTION_LEAVE(); + return buffer; +} + +MPP_RET mpp_buffer_group_init(MppBufferGroupImpl **group, const char *tag, const char *caller, + MppBufferMode mode, MppBufferType type) +{ + AutoMutex auto_lock(MppBufferService::get_lock()); + + mpp_assert(caller); + MPP_BUF_FUNCTION_ENTER(); + + *group = MppBufferService::get_instance()->get_group(tag, caller, mode, type); + + MPP_BUF_FUNCTION_LEAVE(); + return ((*group) ? (MPP_OK) : (MPP_NOK)); +} + +MPP_RET mpp_buffer_group_deinit(MppBufferGroupImpl *p) +{ + AutoMutex auto_lock(MppBufferService::get_lock()); + if (NULL == p) { + mpp_err_f("found NULL pointer\n"); + return MPP_ERR_NULL_PTR; + } + + MPP_BUF_FUNCTION_ENTER(); + + MppBufferService::get_instance()->put_group(p); + + MPP_BUF_FUNCTION_LEAVE(); + return MPP_OK; +} + +MPP_RET mpp_buffer_group_reset(MppBufferGroupImpl *p) +{ + AutoMutex auto_lock(MppBufferService::get_lock()); + if (NULL == p) { + mpp_err_f("found NULL pointer\n"); + return MPP_ERR_NULL_PTR; + } + + MPP_BUF_FUNCTION_ENTER(); + + if (!list_empty(&p->list_used)) { + MppBufferImpl *pos, *n; + list_for_each_entry_safe(pos, n, &p->list_used, MppBufferImpl, list_status) { + // mpp_buffer_ref_dec(pos); + pos->discard = 1; + } + } + + // remove unused list + if (!list_empty(&p->list_unused)) { + MppBufferImpl *pos, *n; + list_for_each_entry_safe(pos, n, &p->list_unused, MppBufferImpl, list_status) { + deinit_buffer_no_lock(pos, __FUNCTION__); + p->count_unused--; + } + } + + MPP_BUF_FUNCTION_LEAVE(); + return MPP_OK; +} + +MPP_RET mpp_buffer_group_set_listener(MppBufferGroupImpl *p, void *listener) +{ + AutoMutex auto_lock(MppBufferService::get_lock()); + if (NULL == p) { + mpp_err_f("found NULL pointer\n"); + return MPP_ERR_NULL_PTR; + } + + MPP_BUF_FUNCTION_ENTER(); + + p->listener = listener; + + MPP_BUF_FUNCTION_LEAVE(); + return MPP_OK; +} + +void mpp_buffer_group_dump(MppBufferGroupImpl *group) +{ + mpp_log("\ndumping buffer group %p id %d\n", group, group->group_id); + mpp_log("mode %s\n", mode2str[group->mode]); + mpp_log("type %s\n", type2str[group->type]); + mpp_log("limit size %d count %d\n", group->limit_size, group->limit_count); + + mpp_log("used buffer count %d\n", group->count_used); + + MppBufferImpl *pos, *n; + list_for_each_entry_safe(pos, n, &group->list_used, MppBufferImpl, list_status) { + dump_buffer_info(pos); + } + + mpp_log("unused buffer count %d\n", group->count_unused); + list_for_each_entry_safe(pos, n, &group->list_unused, MppBufferImpl, list_status) { + dump_buffer_info(pos); + } + + buffer_group_dump_log(group); +} + +void mpp_buffer_service_dump() +{ + AutoMutex auto_lock(MppBufferService::get_lock()); + MppBufferService::get_instance()->dump_misc_group(); +} + +MppBufferGroupImpl *mpp_buffer_get_misc_group(MppBufferMode mode, MppBufferType type) +{ + AutoMutex auto_lock(MppBufferService::get_lock()); + return MppBufferService::get_instance()->get_misc_group(mode, type); +} + +MppBufferService::MppBufferService() + : group_id(0), + group_count(0), + misc_ion_int(NULL), + misc_ion_ext(NULL) +{ + INIT_LIST_HEAD(&mListGroup); + INIT_LIST_HEAD(&mListOrphan); + + // NOTE: here can not call mpp_buffer_group_init for the service is not started + // misc group can accept all kind of buffer which is available + misc_ion_int = get_group("misc_ion_int", "MppBufferService", MPP_BUFFER_INTERNAL, MPP_BUFFER_TYPE_ION); + misc_ion_ext = get_group("misc_ion_ext", "MppBufferService", MPP_BUFFER_EXTERNAL, MPP_BUFFER_TYPE_ION); +} + +MppBufferService::~MppBufferService() +{ + // first remove legacy group + if (misc_ion_ext) { + put_group(misc_ion_ext); + misc_ion_ext = NULL; + } + + if (misc_ion_int) { + put_group(misc_ion_int); + misc_ion_int = NULL; + } + + // then remove the remaining group + if (!list_empty(&mListGroup)) { + MppBufferGroupImpl *pos, *n; + list_for_each_entry_safe(pos, n, &mListGroup, MppBufferGroupImpl, list_group) { + put_group(pos); + } + } + + // remove all orphan buffer + if (!list_empty(&mListOrphan)) { + MppBufferImpl *pos, *n; + list_for_each_entry_safe(pos, n, &mListOrphan, MppBufferImpl, list_status) { + deinit_buffer_no_lock(pos, __FUNCTION__); + } + } +} + +RK_U32 MppBufferService::get_group_id() +{ + // avoid group_id reuse + RK_U32 id = group_id++; + while (get_group_by_id(group_id)) { + group_id++; + } + group_count++; + return id; +} + +MppBufferGroupImpl *MppBufferService::get_group(const char *tag, const char *caller, + MppBufferMode mode, MppBufferType type) +{ + MppBufferGroupImpl *p = mpp_calloc(MppBufferGroupImpl, 1); + if (NULL == p) { + mpp_err("MppBufferService failed to allocate group context\n"); + return NULL; + } + + RK_U32 id = get_group_id(); + + INIT_LIST_HEAD(&p->list_logs); + INIT_LIST_HEAD(&p->list_group); + INIT_LIST_HEAD(&p->list_used); + INIT_LIST_HEAD(&p->list_unused); + + mpp_env_get_u32("mpp_buffer_debug", &mpp_buffer_debug, 0); + p->log_runtime_en = (mpp_buffer_debug & MPP_BUF_DBG_OPS_RUNTIME) ? (1) : (0); + p->log_history_en = (mpp_buffer_debug & MPP_BUF_DBG_OPS_HISTORY) ? (1) : (0); + + list_add_tail(&p->list_group, &mListGroup); + + if (tag) { + snprintf(p->tag, sizeof(p->tag), "%s_%d", tag, id); + } else { + snprintf(p->tag, sizeof(p->tag), "unknown"); + } + p->caller = caller; + p->mode = mode; + p->type = type; + p->limit = BUFFER_GROUP_SIZE_DEFAULT; + p->group_id = id; + p->clear_on_exit = (mpp_buffer_debug & MPP_BUF_DBG_CLR_ON_EXIT) ? (1) : (0); + + mpp_allocator_get(&p->allocator, &p->alloc_api, type); + + buffer_group_add_log(p, NULL, GRP_CREATE, __FUNCTION__); + + return p; +} + +MppBufferGroupImpl *MppBufferService::get_misc_group(MppBufferMode mode, MppBufferType type) +{ + if (type == MPP_BUFFER_TYPE_NORMAL) + return NULL; + + mpp_assert(type == MPP_BUFFER_TYPE_ION); + mpp_assert(mode < MPP_BUFFER_MODE_BUTT); + return (mode == MPP_BUFFER_INTERNAL) ? (misc_ion_int) : (misc_ion_ext); +} + +void MppBufferService::put_group(MppBufferGroupImpl *p) +{ + buffer_group_add_log(p, NULL, GRP_RELEASE, __FUNCTION__); + + // remove unused list + if (!list_empty(&p->list_unused)) { + MppBufferImpl *pos, *n; + list_for_each_entry_safe(pos, n, &p->list_unused, MppBufferImpl, list_status) { + deinit_buffer_no_lock(pos, __FUNCTION__); + p->count_unused--; + } + } + + if (list_empty(&p->list_used)) { + destroy_group(p); + } else { + mpp_err("mpp_group %p tag %s caller %s mode %s type %s deinit with %d bytes not released\n", + p, p->tag, p->caller, mode2str[p->mode], type2str[p->type], p->usage); + + mpp_buffer_group_dump(p); + + /* if clear on exit we need to release remaining buffer */ + if (p->clear_on_exit) { + MppBufferImpl *pos, *n; + + mpp_err("force release all remaining buffer\n"); + + list_for_each_entry_safe(pos, n, &p->list_used, MppBufferImpl, list_status) { + mpp_err("clearing buffer %p pos\n"); + pos->ref_count = 0; + pos->used = 0; + pos->discard = 0; + deinit_buffer_no_lock(pos, __FUNCTION__); + p->count_used--; + } + + destroy_group(p); + } else { + // otherwise move the group to list_orphan and wait for buffer release + list_del_init(&p->list_group); + list_add_tail(&p->list_group, &mListOrphan); + p->is_orphan = 1; + } + } +} + +void MppBufferService::destroy_group(MppBufferGroupImpl *group) +{ + mpp_assert(group->count_used == 0); + mpp_assert(group->count_unused == 0); + if (group->count_unused || group->count_used) { + mpp_err("mpp_buffer_group_deinit mismatch counter used %4d unused %4d found\n", + group->count_used, group->count_unused); + group->count_unused = 0; + group->count_used = 0; + } + + buffer_group_add_log(group, NULL, GRP_DESTROY, __FUNCTION__); + + if (group->log_history_en) { + struct list_head *logs = &group->list_logs; + while (!list_empty(logs)) { + struct list_head *tmp = logs->next; + list_del_init(tmp); + mpp_free(list_entry(tmp, MppBufLog, list)); + group->log_count--; + } + mpp_assert(group->log_count == 0); + } + + mpp_assert(group->allocator); + mpp_allocator_put(&group->allocator); + list_del_init(&group->list_group); + mpp_free(group); + group_count--; + + if (group == misc_ion_int) { + misc_ion_int = NULL; + } else { + /* if only legacy group left dump the legacy group */ + if (group_count == 1 && misc_ion_int && misc_ion_int->buffer_count) { + mpp_log("found legacy group has buffer remain, start dumping\n"); + mpp_buffer_group_dump(misc_ion_int); + abort(); + } + } +} + +MppBufferGroupImpl *MppBufferService::get_group_by_id(RK_U32 id) +{ + MppBufferGroupImpl *pos, *n; + list_for_each_entry_safe(pos, n, &mListGroup, MppBufferGroupImpl, list_group) { + if (pos->group_id == id) { + return pos; + } + } + + list_for_each_entry_safe(pos, n, &mListOrphan, MppBufferGroupImpl, list_group) { + if (pos->group_id == id) { + return pos; + } + } + + return NULL; +} + +void MppBufferService::dump_misc_group() +{ + if (misc_ion_int->buffer_count) + mpp_buffer_group_dump(misc_ion_int); + + if (misc_ion_ext->buffer_count) + mpp_buffer_group_dump(misc_ion_ext); +} + diff --git a/mpp/base/mpp_frame.cpp b/mpp/base/mpp_frame.cpp index baecc6cc..5a0d116f 100644 --- a/mpp/base/mpp_frame.cpp +++ b/mpp/base/mpp_frame.cpp @@ -1,193 +1,193 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define MODULE_TAG "mpp_frame" - -#include - -#include "mpp_log.h" -#include "mpp_mem.h" -#include "mpp_frame_impl.h" - -static const char *module_name = MODULE_TAG; - -static void setup_mpp_frame_name(MppFrameImpl *frame) -{ - frame->name = module_name; -} - -MPP_RET check_is_mpp_frame(void *frame) -{ - if (frame && ((MppFrameImpl*)frame)->name == module_name) - return MPP_OK; - - mpp_err_f("pointer %p failed on check\n", frame); - mpp_abort(); - return MPP_NOK; -} - -MPP_RET mpp_frame_init(MppFrame *frame) -{ - if (NULL == frame) { - mpp_err_f("invalid NULL pointer input\n"); - return MPP_ERR_NULL_PTR; - } - - MppFrameImpl *p = mpp_calloc(MppFrameImpl, 1); - if (NULL == p) { - mpp_err_f("malloc failed\n"); - return MPP_ERR_NULL_PTR; - } - - setup_mpp_frame_name(p); - *frame = p; - - return MPP_OK; -} - -MPP_RET mpp_frame_deinit(MppFrame *frame) -{ - if (NULL == frame || check_is_mpp_frame(*frame)) { - mpp_err_f("invalid NULL pointer input\n"); - return MPP_ERR_NULL_PTR; - } - - MppBuffer buffer = mpp_frame_get_buffer(*frame); - if (buffer) - mpp_buffer_put(buffer); - - mpp_free(*frame); - *frame = NULL; - return MPP_OK; -} - -MppFrame mpp_frame_get_next(MppFrame frame) -{ - if (check_is_mpp_frame(frame)) - return NULL; - - MppFrameImpl *p = (MppFrameImpl *)frame; - return (MppFrame)p->next; -} - -MPP_RET mpp_frame_set_next(MppFrame frame, MppFrame next) -{ - if (check_is_mpp_frame(frame)) - return MPP_ERR_UNKNOW; - - MppFrameImpl *p = (MppFrameImpl *)frame; - p->next = (MppFrameImpl *)next; - return MPP_OK; -} - -MppBuffer mpp_frame_get_buffer(MppFrame frame) -{ - if (check_is_mpp_frame(frame)) - return NULL; - - MppFrameImpl *p = (MppFrameImpl *)frame; - return (MppFrame)p->buffer; -} - -void mpp_frame_set_buffer(MppFrame frame, MppBuffer buffer) -{ - if (check_is_mpp_frame(frame)) - return ; - - MppFrameImpl *p = (MppFrameImpl *)frame; - if (p->buffer != buffer) { - if (buffer) - mpp_buffer_inc_ref(buffer); - - if (p->buffer) - mpp_buffer_put(p->buffer); - - p->buffer = buffer; - } -} - -MPP_RET mpp_frame_copy(MppFrame dst, MppFrame src) -{ - if (NULL == dst || check_is_mpp_frame(src)) { - mpp_err_f("invalid input dst %p src %p\n", dst, src); - return MPP_ERR_UNKNOW; - } - - memcpy(dst, src, sizeof(MppFrameImpl)); - return MPP_OK; -} - -MPP_RET mpp_frame_info_cmp(MppFrame frame0, MppFrame frame1) -{ - if (check_is_mpp_frame(frame0) || check_is_mpp_frame(frame0)) { - mpp_err_f("invalid NULL pointer input\n"); - return MPP_ERR_NULL_PTR; - } - - MppFrameImpl *f0 = (MppFrameImpl *)frame0; - MppFrameImpl *f1 = (MppFrameImpl *)frame1; - - if ((f0->width == f1->width) && - (f0->height == f1->height) && - (f0->hor_stride == f1->hor_stride) && - (f0->ver_stride == f1->ver_stride) && - (f0->fmt == f1->fmt) && - (f0->buf_size == f1->buf_size) && - (f0->color_range == f1->color_range) && - (f0->color_primaries == f1->color_primaries) && - (f0->color_trc == f1->color_trc) && - (f0->colorspace == f1->colorspace) && - (f0->chroma_location == f1->chroma_location)) { - return MPP_OK; - } - return MPP_NOK; -} - -/* - * object access function macro - */ -#define MPP_FRAME_ACCESSORS(type, field) \ - type mpp_frame_get_##field(const MppFrame s) \ - { \ - check_is_mpp_frame((MppFrameImpl*)s); \ - return ((MppFrameImpl*)s)->field; \ - } \ - void mpp_frame_set_##field(MppFrame s, type v) \ - { \ - check_is_mpp_frame((MppFrameImpl*)s); \ - ((MppFrameImpl*)s)->field = v; \ - } - -MPP_FRAME_ACCESSORS(RK_U32, width) -MPP_FRAME_ACCESSORS(RK_U32, height) -MPP_FRAME_ACCESSORS(RK_U32, hor_stride) -MPP_FRAME_ACCESSORS(RK_U32, ver_stride) -MPP_FRAME_ACCESSORS(RK_U32, mode) -MPP_FRAME_ACCESSORS(RK_U32, discard) -MPP_FRAME_ACCESSORS(RK_U32, viewid) -MPP_FRAME_ACCESSORS(RK_U32, poc) -MPP_FRAME_ACCESSORS(RK_S64, pts) -MPP_FRAME_ACCESSORS(RK_S64, dts) -MPP_FRAME_ACCESSORS(RK_U32, eos) -MPP_FRAME_ACCESSORS(RK_U32, info_change) -MPP_FRAME_ACCESSORS(MppFrameColorRange, color_range) -MPP_FRAME_ACCESSORS(MppFrameColorPrimaries, color_primaries) -MPP_FRAME_ACCESSORS(MppFrameColorTransferCharacteristic, color_trc) -MPP_FRAME_ACCESSORS(MppFrameColorSpace, colorspace) -MPP_FRAME_ACCESSORS(MppFrameChromaLocation, chroma_location) -MPP_FRAME_ACCESSORS(MppFrameFormat, fmt) -MPP_FRAME_ACCESSORS(size_t, buf_size) -MPP_FRAME_ACCESSORS(RK_U32, errinfo) +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define MODULE_TAG "mpp_frame" + +#include + +#include "mpp_log.h" +#include "mpp_mem.h" +#include "mpp_frame_impl.h" + +static const char *module_name = MODULE_TAG; + +static void setup_mpp_frame_name(MppFrameImpl *frame) +{ + frame->name = module_name; +} + +MPP_RET check_is_mpp_frame(void *frame) +{ + if (frame && ((MppFrameImpl*)frame)->name == module_name) + return MPP_OK; + + mpp_err_f("pointer %p failed on check\n", frame); + mpp_abort(); + return MPP_NOK; +} + +MPP_RET mpp_frame_init(MppFrame *frame) +{ + if (NULL == frame) { + mpp_err_f("invalid NULL pointer input\n"); + return MPP_ERR_NULL_PTR; + } + + MppFrameImpl *p = mpp_calloc(MppFrameImpl, 1); + if (NULL == p) { + mpp_err_f("malloc failed\n"); + return MPP_ERR_NULL_PTR; + } + + setup_mpp_frame_name(p); + *frame = p; + + return MPP_OK; +} + +MPP_RET mpp_frame_deinit(MppFrame *frame) +{ + if (NULL == frame || check_is_mpp_frame(*frame)) { + mpp_err_f("invalid NULL pointer input\n"); + return MPP_ERR_NULL_PTR; + } + + MppBuffer buffer = mpp_frame_get_buffer(*frame); + if (buffer) + mpp_buffer_put(buffer); + + mpp_free(*frame); + *frame = NULL; + return MPP_OK; +} + +MppFrame mpp_frame_get_next(MppFrame frame) +{ + if (check_is_mpp_frame(frame)) + return NULL; + + MppFrameImpl *p = (MppFrameImpl *)frame; + return (MppFrame)p->next; +} + +MPP_RET mpp_frame_set_next(MppFrame frame, MppFrame next) +{ + if (check_is_mpp_frame(frame)) + return MPP_ERR_UNKNOW; + + MppFrameImpl *p = (MppFrameImpl *)frame; + p->next = (MppFrameImpl *)next; + return MPP_OK; +} + +MppBuffer mpp_frame_get_buffer(MppFrame frame) +{ + if (check_is_mpp_frame(frame)) + return NULL; + + MppFrameImpl *p = (MppFrameImpl *)frame; + return (MppFrame)p->buffer; +} + +void mpp_frame_set_buffer(MppFrame frame, MppBuffer buffer) +{ + if (check_is_mpp_frame(frame)) + return ; + + MppFrameImpl *p = (MppFrameImpl *)frame; + if (p->buffer != buffer) { + if (buffer) + mpp_buffer_inc_ref(buffer); + + if (p->buffer) + mpp_buffer_put(p->buffer); + + p->buffer = buffer; + } +} + +MPP_RET mpp_frame_copy(MppFrame dst, MppFrame src) +{ + if (NULL == dst || check_is_mpp_frame(src)) { + mpp_err_f("invalid input dst %p src %p\n", dst, src); + return MPP_ERR_UNKNOW; + } + + memcpy(dst, src, sizeof(MppFrameImpl)); + return MPP_OK; +} + +MPP_RET mpp_frame_info_cmp(MppFrame frame0, MppFrame frame1) +{ + if (check_is_mpp_frame(frame0) || check_is_mpp_frame(frame0)) { + mpp_err_f("invalid NULL pointer input\n"); + return MPP_ERR_NULL_PTR; + } + + MppFrameImpl *f0 = (MppFrameImpl *)frame0; + MppFrameImpl *f1 = (MppFrameImpl *)frame1; + + if ((f0->width == f1->width) && + (f0->height == f1->height) && + (f0->hor_stride == f1->hor_stride) && + (f0->ver_stride == f1->ver_stride) && + (f0->fmt == f1->fmt) && + (f0->buf_size == f1->buf_size) && + (f0->color_range == f1->color_range) && + (f0->color_primaries == f1->color_primaries) && + (f0->color_trc == f1->color_trc) && + (f0->colorspace == f1->colorspace) && + (f0->chroma_location == f1->chroma_location)) { + return MPP_OK; + } + return MPP_NOK; +} + +/* + * object access function macro + */ +#define MPP_FRAME_ACCESSORS(type, field) \ + type mpp_frame_get_##field(const MppFrame s) \ + { \ + check_is_mpp_frame((MppFrameImpl*)s); \ + return ((MppFrameImpl*)s)->field; \ + } \ + void mpp_frame_set_##field(MppFrame s, type v) \ + { \ + check_is_mpp_frame((MppFrameImpl*)s); \ + ((MppFrameImpl*)s)->field = v; \ + } + +MPP_FRAME_ACCESSORS(RK_U32, width) +MPP_FRAME_ACCESSORS(RK_U32, height) +MPP_FRAME_ACCESSORS(RK_U32, hor_stride) +MPP_FRAME_ACCESSORS(RK_U32, ver_stride) +MPP_FRAME_ACCESSORS(RK_U32, mode) +MPP_FRAME_ACCESSORS(RK_U32, discard) +MPP_FRAME_ACCESSORS(RK_U32, viewid) +MPP_FRAME_ACCESSORS(RK_U32, poc) +MPP_FRAME_ACCESSORS(RK_S64, pts) +MPP_FRAME_ACCESSORS(RK_S64, dts) +MPP_FRAME_ACCESSORS(RK_U32, eos) +MPP_FRAME_ACCESSORS(RK_U32, info_change) +MPP_FRAME_ACCESSORS(MppFrameColorRange, color_range) +MPP_FRAME_ACCESSORS(MppFrameColorPrimaries, color_primaries) +MPP_FRAME_ACCESSORS(MppFrameColorTransferCharacteristic, color_trc) +MPP_FRAME_ACCESSORS(MppFrameColorSpace, colorspace) +MPP_FRAME_ACCESSORS(MppFrameChromaLocation, chroma_location) +MPP_FRAME_ACCESSORS(MppFrameFormat, fmt) +MPP_FRAME_ACCESSORS(size_t, buf_size) +MPP_FRAME_ACCESSORS(RK_U32, errinfo) diff --git a/mpp/base/mpp_meta.cpp b/mpp/base/mpp_meta.cpp index c7e6675c..1ab1ac36 100644 --- a/mpp/base/mpp_meta.cpp +++ b/mpp/base/mpp_meta.cpp @@ -1,496 +1,496 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define MODULE_TAG "mpp_meta" - -#include - -#include "mpp_mem.h" -#include "mpp_list.h" -#include "mpp_frame.h" -#include "mpp_packet.h" -#include "mpp_common.h" - -#include "mpp_meta.h" - -typedef struct MppMetaDef_t { - MppMetaKey key; - MppMetaType type; -} MppMetaDef; - -typedef struct MppMetaImpl_t { - char tag[MPP_TAG_SIZE]; - const char *caller; - RK_S32 meta_id; - - struct list_head list_meta; - struct list_head list_node; - RK_S32 node_count; -} MppMetaImpl; - -typedef union MppMetaVal_u { - RK_S32 val_s32; - RK_S64 val_s64; - void *val_ptr; - MppFrame frame; - MppPacket packet; - MppBuffer buffer; -} MppMetaVal; - -typedef struct MppMetaNode_t { - struct list_head list_meta; - struct list_head list_node; - MppMetaImpl *meta; - RK_S32 node_id; - - RK_S32 type_id; - MppMetaVal val; -} MppMetaNode; - -static MppMetaDef meta_defs[] = { - /* categorized by type */ - /* data flow type */ - { MPP_META_KEY_INPUT_FRM, MPP_META_TYPE_FRAME, }, - { MPP_META_KEY_OUTPUT_FRM, MPP_META_TYPE_FRAME, }, - { MPP_META_KEY_INPUT_PKT, MPP_META_TYPE_PACKET, }, - { MPP_META_KEY_OUTPUT_PKT, MPP_META_TYPE_PACKET, }, - { MPP_META_KEY_MOTION_INFO, MPP_META_TYPE_BUFFER, }, /* buffer for motion detection */ - - { MPP_META_KEY_INPUT_BLOCK, MPP_META_TYPE_S32, }, - { MPP_META_KEY_OUTPUT_BLOCK, MPP_META_TYPE_S32, }, -}; - -class MppMetaService -{ -private: - // avoid any unwanted function - MppMetaService(); - ~MppMetaService(); - MppMetaService(const MppMetaService &); - MppMetaService &operator=(const MppMetaService &); - - struct list_head mlist_meta; - struct list_head mlist_node; - - RK_U32 meta_id; - RK_U32 meta_count; - RK_U32 node_count; - -public: - static MppMetaService *get_instance() { - static MppMetaService instance; - return &instance; - } - static Mutex *get_lock() { - static Mutex lock; - return &lock; - } - - /* - * get_index_of_key does two things: - * 1. Check the key / type pair is correct or not. - * If failed on check return negative value - * 2. Compare all exsisting meta data defines to find the non-negative index - */ - RK_S32 get_index_of_key(MppMetaKey key, MppMetaType type); - - MppMetaImpl *get_meta(const char *tag, const char *caller); - void put_meta(MppMetaImpl *meta); - - MppMetaNode *get_node(MppMetaImpl *meta, RK_S32 index); - void put_node(MppMetaNode *node); - MppMetaNode *find_node(MppMetaImpl *meta, RK_S32 index); -}; - -MppMetaService::MppMetaService() - : meta_id(0), - meta_count(0), - node_count(0) -{ - INIT_LIST_HEAD(&mlist_meta); - INIT_LIST_HEAD(&mlist_node); -} - -MppMetaService::~MppMetaService() -{ - mpp_assert(list_empty(&mlist_meta)); - mpp_assert(list_empty(&mlist_node)); - - while (!list_empty(&mlist_meta)) { - MppMetaImpl *pos, *n; - list_for_each_entry_safe(pos, n, &mlist_meta, MppMetaImpl, list_meta) { - put_meta(pos); - } - } - - mpp_assert(list_empty(&mlist_node)); - - while (!list_empty(&mlist_node)) { - MppMetaNode *pos, *n; - list_for_each_entry_safe(pos, n, &mlist_node, MppMetaNode, list_node) { - put_node(pos); - } - } -} - -RK_S32 MppMetaService::get_index_of_key(MppMetaKey key, MppMetaType type) -{ - RK_S32 i = 0; - RK_S32 num = MPP_ARRAY_ELEMS(meta_defs); - - for (i = 0; i < num; i++) { - if ((meta_defs[i].key == key) && (meta_defs[i].type == type)) - break; - } - - return (i < num) ? (i) : (-1); -} - -MppMetaImpl *MppMetaService::get_meta(const char *tag, const char *caller) -{ - MppMetaImpl *impl = mpp_malloc(MppMetaImpl, 1); - if (impl) { - const char *tag_src = (tag) ? (tag) : (MODULE_TAG); - strncpy(impl->tag, tag_src, sizeof(impl->tag)); - impl->caller = caller; - impl->meta_id = meta_id++; - INIT_LIST_HEAD(&impl->list_meta); - INIT_LIST_HEAD(&impl->list_node); - impl->node_count = 0; - - list_add_tail(&impl->list_meta, &mlist_meta); - meta_count++; - } else { - mpp_err_f("failed to malloc meta data\n"); - } - return impl; -} - -void MppMetaService::put_meta(MppMetaImpl *meta) -{ - while (!list_empty(&meta->list_node)) { - MppMetaNode *node = list_entry(meta->list_node.next, MppMetaNode, list_meta); - put_node(node); - meta->node_count--; - } - list_del_init(&meta->list_meta); - meta_count--; - mpp_free(meta); -} - -MppMetaNode *MppMetaService::find_node(MppMetaImpl *meta, RK_S32 type_id) -{ - MppMetaNode *node = NULL; - if (meta->node_count) { - MppMetaNode *n, *pos; - - list_for_each_entry_safe(pos, n, &meta->list_node, MppMetaNode, list_meta) { - if (pos->type_id == type_id) { - node = pos; - break; - } - } - } - return node; -} - -MppMetaNode *MppMetaService::get_node(MppMetaImpl *meta, RK_S32 type_id) -{ - MppMetaNode *node = find_node(meta, type_id); - - if (NULL == node) { - node = mpp_malloc(MppMetaNode, 1); - if (node) { - INIT_LIST_HEAD(&node->list_meta); - INIT_LIST_HEAD(&node->list_node); - node->meta = meta; - node->node_id = meta->meta_id++; - node->type_id = type_id; - memset(&node->val, 0, sizeof(node->val)); - - meta->node_count++; - list_add_tail(&node->list_meta, &meta->list_node); - list_add_tail(&node->list_node, &mlist_node); - node_count++; - } else { - mpp_err_f("failed to malloc meta data node\n"); - } - } - - return node; -} - -void MppMetaService::put_node(MppMetaNode *node) -{ - MppMetaImpl *meta = node->meta; - list_del_init(&node->list_meta); - list_del_init(&node->list_node); - meta->node_count--; - node_count--; - // TODO: may be we need to release MppFrame / MppPacket / MppBuffer here - switch (meta_defs[node->type_id].type) { - case MPP_META_TYPE_FRAME : { - // mpp_frame_deinit(&node->val.frame); - } break; - case MPP_META_TYPE_PACKET : { - // mpp_packet_deinit(&node->val.packet); - } break; - case MPP_META_TYPE_BUFFER : { - //mpp_buffer_put(node->val.buffer); - } break; - default : { - } break; - } - mpp_free(node); -} - -MPP_RET mpp_meta_get_with_tag(MppMeta *meta, const char *tag, const char *caller) -{ - if (NULL == meta) { - mpp_err_f("found NULL input\n"); - return MPP_ERR_NULL_PTR; - } - - MppMetaService *service = MppMetaService::get_instance(); - AutoMutex auto_lock(service->get_lock()); - MppMetaImpl *impl = service->get_meta(tag, caller); - *meta = (MppMeta) impl; - return (impl) ? (MPP_OK) : (MPP_NOK); -} - -MPP_RET mpp_meta_put(MppMeta meta) -{ - if (NULL == meta) { - mpp_err_f("found NULL input\n"); - return MPP_ERR_NULL_PTR; - } - - MppMetaService *service = MppMetaService::get_instance(); - AutoMutex auto_lock(service->get_lock()); - MppMetaImpl *impl = (MppMetaImpl *)meta; - service->put_meta(impl); - return MPP_OK; -} - -static MPP_RET set_val_by_key(MppMetaImpl *meta, MppMetaKey key, MppMetaType type, MppMetaVal *val) -{ - MPP_RET ret = MPP_NOK; - MppMetaService *service = MppMetaService::get_instance(); - AutoMutex auto_lock(service->get_lock()); - RK_S32 index = service->get_index_of_key(key, type); - if (index < 0) - return ret; - - MppMetaNode *node = service->get_node(meta, index); - if (node) { - node->val = *val; - ret = MPP_OK; - } - return ret; -} - -static MPP_RET get_val_by_key(MppMetaImpl *meta, MppMetaKey key, MppMetaType type, MppMetaVal *val) -{ - MPP_RET ret = MPP_NOK; - MppMetaService *service = MppMetaService::get_instance(); - AutoMutex auto_lock(service->get_lock()); - RK_S32 index = service->get_index_of_key(key, type); - if (index < 0) - return ret; - - MppMetaNode *node = service->find_node(meta, index); - if (node) { - *val = node->val; - service->put_node(node); - ret = MPP_OK; - } - return ret; -} - -MPP_RET mpp_meta_set_s32(MppMeta meta, MppMetaKey key, RK_S32 val) -{ - if (NULL == meta) { - mpp_err_f("found NULL input\n"); - return MPP_ERR_NULL_PTR; - } - - MppMetaImpl *impl = (MppMetaImpl *)meta; - MppMetaVal meta_val; - meta_val.val_s32 = val; - return set_val_by_key(impl, key, MPP_META_TYPE_S32, &meta_val); -} - -MPP_RET mpp_meta_set_s64(MppMeta meta, MppMetaKey key, RK_S64 val) -{ - if (NULL == meta) { - mpp_err_f("found NULL input\n"); - return MPP_ERR_NULL_PTR; - } - - MppMetaImpl *impl = (MppMetaImpl *)meta; - MppMetaVal meta_val; - meta_val.val_s64 = val; - return set_val_by_key(impl, key, MPP_META_TYPE_S64, &meta_val); -} - -MPP_RET mpp_meta_set_ptr(MppMeta meta, MppMetaKey key, void *val) -{ - if (NULL == meta) { - mpp_err_f("found NULL input\n"); - return MPP_ERR_NULL_PTR; - } - - MppMetaImpl *impl = (MppMetaImpl *)meta; - MppMetaVal meta_val; - meta_val.val_ptr = val; - return set_val_by_key(impl, key, MPP_META_TYPE_PTR, &meta_val); -} - -MPP_RET mpp_meta_get_s32(MppMeta meta, MppMetaKey key, RK_S32 *val) -{ - if (NULL == meta) { - mpp_err_f("found NULL input\n"); - return MPP_ERR_NULL_PTR; - } - - MppMetaImpl *impl = (MppMetaImpl *)meta; - MppMetaVal meta_val; - MPP_RET ret = get_val_by_key(impl, key, MPP_META_TYPE_S32, &meta_val); - if (MPP_OK == ret) - *val = meta_val.val_s32; - - return ret; -} - -MPP_RET mpp_meta_get_s64(MppMeta meta, MppMetaKey key, RK_S64 *val) -{ - if (NULL == meta) { - mpp_err_f("found NULL input\n"); - return MPP_ERR_NULL_PTR; - } - - MppMetaImpl *impl = (MppMetaImpl *)meta; - MppMetaVal meta_val; - MPP_RET ret = get_val_by_key(impl, key, MPP_META_TYPE_S64, &meta_val); - if (MPP_OK == ret) - *val = meta_val.val_s64; - - return ret; -} - -MPP_RET mpp_meta_get_ptr(MppMeta meta, MppMetaKey key, void **val) -{ - if (NULL == meta) { - mpp_err_f("found NULL input\n"); - return MPP_ERR_NULL_PTR; - } - - MppMetaImpl *impl = (MppMetaImpl *)meta; - MppMetaVal meta_val; - MPP_RET ret = get_val_by_key(impl, key, MPP_META_TYPE_PTR, &meta_val); - if (MPP_OK == ret) - *val = meta_val.val_ptr; - - return ret; -} - -MPP_RET mpp_meta_set_frame(MppMeta meta, MppMetaKey key, MppFrame frame) -{ - if (NULL == meta) { - mpp_err_f("found NULL input\n"); - return MPP_ERR_NULL_PTR; - } - - MppMetaImpl *impl = (MppMetaImpl *)meta; - MppMetaVal meta_val; - meta_val.frame = frame; - return set_val_by_key(impl, key, MPP_META_TYPE_FRAME, &meta_val); -} - -MPP_RET mpp_meta_set_packet(MppMeta meta, MppMetaKey key, MppPacket packet) -{ - if (NULL == meta) { - mpp_err_f("found NULL input\n"); - return MPP_ERR_NULL_PTR; - } - - MppMetaImpl *impl = (MppMetaImpl *)meta; - MppMetaVal meta_val; - meta_val.packet = packet; - return set_val_by_key(impl, key, MPP_META_TYPE_PACKET, &meta_val); -} - -MPP_RET mpp_meta_set_buffer(MppMeta meta, MppMetaKey key, MppBuffer buffer) -{ - if (NULL == meta) { - mpp_err_f("found NULL input\n"); - return MPP_ERR_NULL_PTR; - } - - MppMetaImpl *impl = (MppMetaImpl *)meta; - MppMetaVal meta_val; - meta_val.buffer = buffer; - return set_val_by_key(impl, key, MPP_META_TYPE_BUFFER, &meta_val); -} - -MPP_RET mpp_meta_get_frame(MppMeta meta, MppMetaKey key, MppFrame *frame) -{ - if (NULL == meta) { - mpp_err_f("found NULL input\n"); - return MPP_ERR_NULL_PTR; - } - - MppMetaImpl *impl = (MppMetaImpl *)meta; - MppMetaVal meta_val; - MPP_RET ret = get_val_by_key(impl, key, MPP_META_TYPE_FRAME, &meta_val); - if (MPP_OK == ret) - *frame = meta_val.frame; - - return ret; -} - -MPP_RET mpp_meta_get_packet(MppMeta meta, MppMetaKey key, MppPacket *packet) -{ - if (NULL == meta) { - mpp_err_f("found NULL input\n"); - return MPP_ERR_NULL_PTR; - } - - MppMetaImpl *impl = (MppMetaImpl *)meta; - MppMetaVal meta_val; - MPP_RET ret = get_val_by_key(impl, key, MPP_META_TYPE_PACKET, &meta_val); - if (MPP_OK == ret) - *packet = meta_val.packet; - - return ret; -} - -MPP_RET mpp_meta_get_buffer(MppMeta meta, MppMetaKey key, MppBuffer *buffer) -{ - if (NULL == meta) { - mpp_err_f("found NULL input\n"); - return MPP_ERR_NULL_PTR; - } - - MppMetaImpl *impl = (MppMetaImpl *)meta; - MppMetaVal meta_val; - MPP_RET ret = get_val_by_key(impl, key, MPP_META_TYPE_BUFFER, &meta_val); - if (MPP_OK == ret) - *buffer = meta_val.buffer; - - return ret; -} - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define MODULE_TAG "mpp_meta" + +#include + +#include "mpp_mem.h" +#include "mpp_list.h" +#include "mpp_frame.h" +#include "mpp_packet.h" +#include "mpp_common.h" + +#include "mpp_meta.h" + +typedef struct MppMetaDef_t { + MppMetaKey key; + MppMetaType type; +} MppMetaDef; + +typedef struct MppMetaImpl_t { + char tag[MPP_TAG_SIZE]; + const char *caller; + RK_S32 meta_id; + + struct list_head list_meta; + struct list_head list_node; + RK_S32 node_count; +} MppMetaImpl; + +typedef union MppMetaVal_u { + RK_S32 val_s32; + RK_S64 val_s64; + void *val_ptr; + MppFrame frame; + MppPacket packet; + MppBuffer buffer; +} MppMetaVal; + +typedef struct MppMetaNode_t { + struct list_head list_meta; + struct list_head list_node; + MppMetaImpl *meta; + RK_S32 node_id; + + RK_S32 type_id; + MppMetaVal val; +} MppMetaNode; + +static MppMetaDef meta_defs[] = { + /* categorized by type */ + /* data flow type */ + { MPP_META_KEY_INPUT_FRM, MPP_META_TYPE_FRAME, }, + { MPP_META_KEY_OUTPUT_FRM, MPP_META_TYPE_FRAME, }, + { MPP_META_KEY_INPUT_PKT, MPP_META_TYPE_PACKET, }, + { MPP_META_KEY_OUTPUT_PKT, MPP_META_TYPE_PACKET, }, + { MPP_META_KEY_MOTION_INFO, MPP_META_TYPE_BUFFER, }, /* buffer for motion detection */ + + { MPP_META_KEY_INPUT_BLOCK, MPP_META_TYPE_S32, }, + { MPP_META_KEY_OUTPUT_BLOCK, MPP_META_TYPE_S32, }, +}; + +class MppMetaService +{ +private: + // avoid any unwanted function + MppMetaService(); + ~MppMetaService(); + MppMetaService(const MppMetaService &); + MppMetaService &operator=(const MppMetaService &); + + struct list_head mlist_meta; + struct list_head mlist_node; + + RK_U32 meta_id; + RK_U32 meta_count; + RK_U32 node_count; + +public: + static MppMetaService *get_instance() { + static MppMetaService instance; + return &instance; + } + static Mutex *get_lock() { + static Mutex lock; + return &lock; + } + + /* + * get_index_of_key does two things: + * 1. Check the key / type pair is correct or not. + * If failed on check return negative value + * 2. Compare all exsisting meta data defines to find the non-negative index + */ + RK_S32 get_index_of_key(MppMetaKey key, MppMetaType type); + + MppMetaImpl *get_meta(const char *tag, const char *caller); + void put_meta(MppMetaImpl *meta); + + MppMetaNode *get_node(MppMetaImpl *meta, RK_S32 index); + void put_node(MppMetaNode *node); + MppMetaNode *find_node(MppMetaImpl *meta, RK_S32 index); +}; + +MppMetaService::MppMetaService() + : meta_id(0), + meta_count(0), + node_count(0) +{ + INIT_LIST_HEAD(&mlist_meta); + INIT_LIST_HEAD(&mlist_node); +} + +MppMetaService::~MppMetaService() +{ + mpp_assert(list_empty(&mlist_meta)); + mpp_assert(list_empty(&mlist_node)); + + while (!list_empty(&mlist_meta)) { + MppMetaImpl *pos, *n; + list_for_each_entry_safe(pos, n, &mlist_meta, MppMetaImpl, list_meta) { + put_meta(pos); + } + } + + mpp_assert(list_empty(&mlist_node)); + + while (!list_empty(&mlist_node)) { + MppMetaNode *pos, *n; + list_for_each_entry_safe(pos, n, &mlist_node, MppMetaNode, list_node) { + put_node(pos); + } + } +} + +RK_S32 MppMetaService::get_index_of_key(MppMetaKey key, MppMetaType type) +{ + RK_S32 i = 0; + RK_S32 num = MPP_ARRAY_ELEMS(meta_defs); + + for (i = 0; i < num; i++) { + if ((meta_defs[i].key == key) && (meta_defs[i].type == type)) + break; + } + + return (i < num) ? (i) : (-1); +} + +MppMetaImpl *MppMetaService::get_meta(const char *tag, const char *caller) +{ + MppMetaImpl *impl = mpp_malloc(MppMetaImpl, 1); + if (impl) { + const char *tag_src = (tag) ? (tag) : (MODULE_TAG); + strncpy(impl->tag, tag_src, sizeof(impl->tag)); + impl->caller = caller; + impl->meta_id = meta_id++; + INIT_LIST_HEAD(&impl->list_meta); + INIT_LIST_HEAD(&impl->list_node); + impl->node_count = 0; + + list_add_tail(&impl->list_meta, &mlist_meta); + meta_count++; + } else { + mpp_err_f("failed to malloc meta data\n"); + } + return impl; +} + +void MppMetaService::put_meta(MppMetaImpl *meta) +{ + while (!list_empty(&meta->list_node)) { + MppMetaNode *node = list_entry(meta->list_node.next, MppMetaNode, list_meta); + put_node(node); + meta->node_count--; + } + list_del_init(&meta->list_meta); + meta_count--; + mpp_free(meta); +} + +MppMetaNode *MppMetaService::find_node(MppMetaImpl *meta, RK_S32 type_id) +{ + MppMetaNode *node = NULL; + if (meta->node_count) { + MppMetaNode *n, *pos; + + list_for_each_entry_safe(pos, n, &meta->list_node, MppMetaNode, list_meta) { + if (pos->type_id == type_id) { + node = pos; + break; + } + } + } + return node; +} + +MppMetaNode *MppMetaService::get_node(MppMetaImpl *meta, RK_S32 type_id) +{ + MppMetaNode *node = find_node(meta, type_id); + + if (NULL == node) { + node = mpp_malloc(MppMetaNode, 1); + if (node) { + INIT_LIST_HEAD(&node->list_meta); + INIT_LIST_HEAD(&node->list_node); + node->meta = meta; + node->node_id = meta->meta_id++; + node->type_id = type_id; + memset(&node->val, 0, sizeof(node->val)); + + meta->node_count++; + list_add_tail(&node->list_meta, &meta->list_node); + list_add_tail(&node->list_node, &mlist_node); + node_count++; + } else { + mpp_err_f("failed to malloc meta data node\n"); + } + } + + return node; +} + +void MppMetaService::put_node(MppMetaNode *node) +{ + MppMetaImpl *meta = node->meta; + list_del_init(&node->list_meta); + list_del_init(&node->list_node); + meta->node_count--; + node_count--; + // TODO: may be we need to release MppFrame / MppPacket / MppBuffer here + switch (meta_defs[node->type_id].type) { + case MPP_META_TYPE_FRAME : { + // mpp_frame_deinit(&node->val.frame); + } break; + case MPP_META_TYPE_PACKET : { + // mpp_packet_deinit(&node->val.packet); + } break; + case MPP_META_TYPE_BUFFER : { + //mpp_buffer_put(node->val.buffer); + } break; + default : { + } break; + } + mpp_free(node); +} + +MPP_RET mpp_meta_get_with_tag(MppMeta *meta, const char *tag, const char *caller) +{ + if (NULL == meta) { + mpp_err_f("found NULL input\n"); + return MPP_ERR_NULL_PTR; + } + + MppMetaService *service = MppMetaService::get_instance(); + AutoMutex auto_lock(service->get_lock()); + MppMetaImpl *impl = service->get_meta(tag, caller); + *meta = (MppMeta) impl; + return (impl) ? (MPP_OK) : (MPP_NOK); +} + +MPP_RET mpp_meta_put(MppMeta meta) +{ + if (NULL == meta) { + mpp_err_f("found NULL input\n"); + return MPP_ERR_NULL_PTR; + } + + MppMetaService *service = MppMetaService::get_instance(); + AutoMutex auto_lock(service->get_lock()); + MppMetaImpl *impl = (MppMetaImpl *)meta; + service->put_meta(impl); + return MPP_OK; +} + +static MPP_RET set_val_by_key(MppMetaImpl *meta, MppMetaKey key, MppMetaType type, MppMetaVal *val) +{ + MPP_RET ret = MPP_NOK; + MppMetaService *service = MppMetaService::get_instance(); + AutoMutex auto_lock(service->get_lock()); + RK_S32 index = service->get_index_of_key(key, type); + if (index < 0) + return ret; + + MppMetaNode *node = service->get_node(meta, index); + if (node) { + node->val = *val; + ret = MPP_OK; + } + return ret; +} + +static MPP_RET get_val_by_key(MppMetaImpl *meta, MppMetaKey key, MppMetaType type, MppMetaVal *val) +{ + MPP_RET ret = MPP_NOK; + MppMetaService *service = MppMetaService::get_instance(); + AutoMutex auto_lock(service->get_lock()); + RK_S32 index = service->get_index_of_key(key, type); + if (index < 0) + return ret; + + MppMetaNode *node = service->find_node(meta, index); + if (node) { + *val = node->val; + service->put_node(node); + ret = MPP_OK; + } + return ret; +} + +MPP_RET mpp_meta_set_s32(MppMeta meta, MppMetaKey key, RK_S32 val) +{ + if (NULL == meta) { + mpp_err_f("found NULL input\n"); + return MPP_ERR_NULL_PTR; + } + + MppMetaImpl *impl = (MppMetaImpl *)meta; + MppMetaVal meta_val; + meta_val.val_s32 = val; + return set_val_by_key(impl, key, MPP_META_TYPE_S32, &meta_val); +} + +MPP_RET mpp_meta_set_s64(MppMeta meta, MppMetaKey key, RK_S64 val) +{ + if (NULL == meta) { + mpp_err_f("found NULL input\n"); + return MPP_ERR_NULL_PTR; + } + + MppMetaImpl *impl = (MppMetaImpl *)meta; + MppMetaVal meta_val; + meta_val.val_s64 = val; + return set_val_by_key(impl, key, MPP_META_TYPE_S64, &meta_val); +} + +MPP_RET mpp_meta_set_ptr(MppMeta meta, MppMetaKey key, void *val) +{ + if (NULL == meta) { + mpp_err_f("found NULL input\n"); + return MPP_ERR_NULL_PTR; + } + + MppMetaImpl *impl = (MppMetaImpl *)meta; + MppMetaVal meta_val; + meta_val.val_ptr = val; + return set_val_by_key(impl, key, MPP_META_TYPE_PTR, &meta_val); +} + +MPP_RET mpp_meta_get_s32(MppMeta meta, MppMetaKey key, RK_S32 *val) +{ + if (NULL == meta) { + mpp_err_f("found NULL input\n"); + return MPP_ERR_NULL_PTR; + } + + MppMetaImpl *impl = (MppMetaImpl *)meta; + MppMetaVal meta_val; + MPP_RET ret = get_val_by_key(impl, key, MPP_META_TYPE_S32, &meta_val); + if (MPP_OK == ret) + *val = meta_val.val_s32; + + return ret; +} + +MPP_RET mpp_meta_get_s64(MppMeta meta, MppMetaKey key, RK_S64 *val) +{ + if (NULL == meta) { + mpp_err_f("found NULL input\n"); + return MPP_ERR_NULL_PTR; + } + + MppMetaImpl *impl = (MppMetaImpl *)meta; + MppMetaVal meta_val; + MPP_RET ret = get_val_by_key(impl, key, MPP_META_TYPE_S64, &meta_val); + if (MPP_OK == ret) + *val = meta_val.val_s64; + + return ret; +} + +MPP_RET mpp_meta_get_ptr(MppMeta meta, MppMetaKey key, void **val) +{ + if (NULL == meta) { + mpp_err_f("found NULL input\n"); + return MPP_ERR_NULL_PTR; + } + + MppMetaImpl *impl = (MppMetaImpl *)meta; + MppMetaVal meta_val; + MPP_RET ret = get_val_by_key(impl, key, MPP_META_TYPE_PTR, &meta_val); + if (MPP_OK == ret) + *val = meta_val.val_ptr; + + return ret; +} + +MPP_RET mpp_meta_set_frame(MppMeta meta, MppMetaKey key, MppFrame frame) +{ + if (NULL == meta) { + mpp_err_f("found NULL input\n"); + return MPP_ERR_NULL_PTR; + } + + MppMetaImpl *impl = (MppMetaImpl *)meta; + MppMetaVal meta_val; + meta_val.frame = frame; + return set_val_by_key(impl, key, MPP_META_TYPE_FRAME, &meta_val); +} + +MPP_RET mpp_meta_set_packet(MppMeta meta, MppMetaKey key, MppPacket packet) +{ + if (NULL == meta) { + mpp_err_f("found NULL input\n"); + return MPP_ERR_NULL_PTR; + } + + MppMetaImpl *impl = (MppMetaImpl *)meta; + MppMetaVal meta_val; + meta_val.packet = packet; + return set_val_by_key(impl, key, MPP_META_TYPE_PACKET, &meta_val); +} + +MPP_RET mpp_meta_set_buffer(MppMeta meta, MppMetaKey key, MppBuffer buffer) +{ + if (NULL == meta) { + mpp_err_f("found NULL input\n"); + return MPP_ERR_NULL_PTR; + } + + MppMetaImpl *impl = (MppMetaImpl *)meta; + MppMetaVal meta_val; + meta_val.buffer = buffer; + return set_val_by_key(impl, key, MPP_META_TYPE_BUFFER, &meta_val); +} + +MPP_RET mpp_meta_get_frame(MppMeta meta, MppMetaKey key, MppFrame *frame) +{ + if (NULL == meta) { + mpp_err_f("found NULL input\n"); + return MPP_ERR_NULL_PTR; + } + + MppMetaImpl *impl = (MppMetaImpl *)meta; + MppMetaVal meta_val; + MPP_RET ret = get_val_by_key(impl, key, MPP_META_TYPE_FRAME, &meta_val); + if (MPP_OK == ret) + *frame = meta_val.frame; + + return ret; +} + +MPP_RET mpp_meta_get_packet(MppMeta meta, MppMetaKey key, MppPacket *packet) +{ + if (NULL == meta) { + mpp_err_f("found NULL input\n"); + return MPP_ERR_NULL_PTR; + } + + MppMetaImpl *impl = (MppMetaImpl *)meta; + MppMetaVal meta_val; + MPP_RET ret = get_val_by_key(impl, key, MPP_META_TYPE_PACKET, &meta_val); + if (MPP_OK == ret) + *packet = meta_val.packet; + + return ret; +} + +MPP_RET mpp_meta_get_buffer(MppMeta meta, MppMetaKey key, MppBuffer *buffer) +{ + if (NULL == meta) { + mpp_err_f("found NULL input\n"); + return MPP_ERR_NULL_PTR; + } + + MppMetaImpl *impl = (MppMetaImpl *)meta; + MppMetaVal meta_val; + MPP_RET ret = get_val_by_key(impl, key, MPP_META_TYPE_BUFFER, &meta_val); + if (MPP_OK == ret) + *buffer = meta_val.buffer; + + return ret; +} + diff --git a/mpp/base/mpp_packet.cpp b/mpp/base/mpp_packet.cpp index 1e1750a7..8ba1d168 100644 --- a/mpp/base/mpp_packet.cpp +++ b/mpp/base/mpp_packet.cpp @@ -1,309 +1,309 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define MODULE_TAG "mpp_packet" - -#include - -#include "mpp_log.h" -#include "mpp_mem.h" -#include "mpp_packet.h" -#include "mpp_packet_impl.h" - -static const char *module_name = MODULE_TAG; - -#define setup_mpp_packet_name(packet) \ - ((MppPacketImpl*)packet)->name = module_name; - -MPP_RET check_is_mpp_packet(void *packet) -{ - if (packet && ((MppPacketImpl*)packet)->name == module_name) - return MPP_OK; - - mpp_err_f("pointer %p failed on check\n", packet); - mpp_abort(); - return MPP_NOK; -} - -MPP_RET mpp_packet_new(MppPacket *packet) -{ - if (NULL == packet) { - mpp_err_f("invalid NULL input\n"); - return MPP_ERR_NULL_PTR; - } - - MppPacketImpl *p = mpp_calloc(MppPacketImpl, 1); - *packet = p; - if (NULL == p) { - mpp_err_f("malloc failed\n"); - return MPP_ERR_NULL_PTR; - } - setup_mpp_packet_name(p); - return MPP_OK; -} - -MPP_RET mpp_packet_init(MppPacket *packet, void *data, size_t size) -{ - if (NULL == packet) { - mpp_err_f("invalid NULL input packet\n"); - return MPP_ERR_NULL_PTR; - } - - MPP_RET ret = mpp_packet_new(packet); - if (ret) { - mpp_err_f("new packet failed\n"); - return ret; - } - MppPacketImpl *p = (MppPacketImpl *)*packet; - p->data = p->pos = data; - p->size = p->length = size; - - return MPP_OK; -} - -MPP_RET mpp_packet_init_with_buffer(MppPacket *packet, MppBuffer buffer) -{ - if (NULL == packet || NULL == buffer) { - mpp_err_f("invalid input packet %p buffer %p\n", packet, buffer); - return MPP_ERR_NULL_PTR; - } - - MPP_RET ret = mpp_packet_new(packet); - if (ret) { - mpp_err_f("new packet failed\n"); - return ret; - } - MppPacketImpl *p = (MppPacketImpl *)*packet; - p->data = p->pos = mpp_buffer_get_ptr(buffer); - p->size = p->length = mpp_buffer_get_size(buffer); - p->buffer = buffer; - mpp_buffer_inc_ref(buffer); - - return MPP_OK; -} - -MPP_RET mpp_packet_copy_init(MppPacket *packet, const MppPacket src) -{ - if (NULL == packet || check_is_mpp_packet(src)) { - mpp_err_f("found invalid input %p %p\n", packet, src); - return MPP_ERR_UNKNOW; - } - - *packet = NULL; - - MppPacketImpl *src_impl = (MppPacketImpl *)src; - MppPacket pkt; - MPP_RET ret = mpp_packet_new(&pkt); - if (ret) - return ret; - - if (src_impl->buffer) { - /* if source packet has buffer just create a new reference to buffer */ - memcpy(pkt, src_impl, sizeof(*src_impl)); - mpp_buffer_inc_ref(src_impl->buffer); - return MPP_OK; - } - - size_t size = mpp_packet_get_size(src); - /* - * due to parser may be read 32 bit interface so we must alloc more size then real size - * to avoid read carsh - */ - void *data = mpp_malloc_size(void, size + 256); - if (NULL == data) { - mpp_err_f("malloc failed, size %d\n", size); - mpp_packet_deinit(&pkt); - return MPP_ERR_MALLOC; - } - - MppPacketImpl *p = (MppPacketImpl *)pkt; - memcpy(p, src_impl, sizeof(*src_impl)); - p->data = p->pos = data; - p->size = p->length = size; - p->flag |= MPP_PACKET_FLAG_INTERNAL; - if (size) { - memcpy(data, src_impl->data, size); - /* - * clean more alloc byte to zero - */ - memset((RK_U8*)data + size, 0, 256); - } - *packet = pkt; - return MPP_OK; -} - -MPP_RET mpp_packet_deinit(MppPacket *packet) -{ - if (NULL == packet || check_is_mpp_packet(*packet)) { - mpp_err_f("found NULL input\n"); - return MPP_ERR_NULL_PTR; - } - - MppPacketImpl *p = (MppPacketImpl *)(*packet); - - /* release buffer reference */ - if (p->buffer) - mpp_buffer_put(p->buffer); - - if (p->flag & MPP_PACKET_FLAG_INTERNAL) { - mpp_free(p->data); - } - - mpp_free(p); - *packet = NULL; - return MPP_OK; -} - -void mpp_packet_set_pos(MppPacket packet, void *pos) -{ - if (check_is_mpp_packet(packet)) - return ; - - MppPacketImpl *p = (MppPacketImpl *)packet; - p->pos = pos; - p->length = p->size - ((char *)pos - (char *)p->data); - mpp_assert(p->data <= p->pos); - mpp_assert(p->size >= p->length); -} - -void *mpp_packet_get_pos(const MppPacket packet) -{ - if (check_is_mpp_packet(packet)) - return NULL; - - MppPacketImpl *p = (MppPacketImpl *)packet; - return p->pos; -} - -MPP_RET mpp_packet_set_eos(MppPacket packet) -{ - if (check_is_mpp_packet(packet)) - return MPP_ERR_UNKNOW; - - MppPacketImpl *p = (MppPacketImpl *)packet; - p->flag |= MPP_PACKET_FLAG_EOS; - return MPP_OK; -} - -RK_U32 mpp_packet_get_eos(MppPacket packet) -{ - if (check_is_mpp_packet(packet)) - return 0; - - MppPacketImpl *p = (MppPacketImpl *)packet; - return (p->flag & MPP_PACKET_FLAG_EOS) ? (1) : (0); -} - -MPP_RET mpp_packet_set_extra_data(MppPacket packet) -{ - if (check_is_mpp_packet(packet)) - return MPP_ERR_UNKNOW; - - MppPacketImpl *p = (MppPacketImpl *)packet; - p->flag |= MPP_PACKET_FLAG_EXTRA_DATA; - return MPP_OK; -} - -MPP_RET mpp_packet_reset(MppPacketImpl *packet) -{ - if (check_is_mpp_packet(packet)) - return MPP_ERR_UNKNOW; - - memset(packet, 0, sizeof(*packet)); - setup_mpp_packet_name(packet); - return MPP_OK; -} - -void mpp_packet_set_buffer(MppPacket packet, MppBuffer buffer) -{ - if (check_is_mpp_packet(packet)) - return ; - - MppPacketImpl *p = (MppPacketImpl *)packet; - if (p->buffer != buffer) { - if (buffer) - mpp_buffer_inc_ref(buffer); - - if (p->buffer) - mpp_buffer_put(p->buffer); - - p->buffer = buffer; - } -} - -MppBuffer mpp_packet_get_buffer(const MppPacket packet) -{ - if (check_is_mpp_packet(packet)) - return NULL; - - MppPacketImpl *p = (MppPacketImpl *)packet; - return p->buffer; -} - -MPP_RET mpp_packet_read(MppPacket packet, size_t offset, void *data, size_t size) -{ - if (check_is_mpp_packet(packet) || NULL == data) { - mpp_err_f("invalid input: packet %p data %p\n", packet, data); - return MPP_ERR_UNKNOW; - } - - if (0 == size) - return MPP_OK; - - void *src = mpp_packet_get_data(packet); - mpp_assert(src != NULL); - memcpy(data, (char*)src + offset, size); - return MPP_OK; -} - -MPP_RET mpp_packet_write(MppPacket packet, size_t offset, void *data, size_t size) -{ - if (check_is_mpp_packet(packet) || NULL == data) { - mpp_err_f("invalid input: packet %p data %p\n", packet, data); - return MPP_ERR_UNKNOW; - } - - if (0 == size) - return MPP_OK; - - void *dst = mpp_packet_get_data(packet); - mpp_assert(dst != NULL); - memcpy((char*)dst + offset, data, size); - return MPP_OK; -} - -/* - * object access function macro - */ -#define MPP_PACKET_ACCESSORS(type, field) \ - type mpp_packet_get_##field(const MppPacket s) \ - { \ - check_is_mpp_packet(s); \ - return ((MppPacketImpl*)s)->field; \ - } \ - void mpp_packet_set_##field(MppPacket s, type v) \ - { \ - check_is_mpp_packet(s); \ - ((MppPacketImpl*)s)->field = v; \ - } - -MPP_PACKET_ACCESSORS(void *, data) -MPP_PACKET_ACCESSORS(size_t, size) -MPP_PACKET_ACCESSORS(size_t, length) -MPP_PACKET_ACCESSORS(RK_S64, pts) -MPP_PACKET_ACCESSORS(RK_S64, dts) -MPP_PACKET_ACCESSORS(RK_U32, flag) - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define MODULE_TAG "mpp_packet" + +#include + +#include "mpp_log.h" +#include "mpp_mem.h" +#include "mpp_packet.h" +#include "mpp_packet_impl.h" + +static const char *module_name = MODULE_TAG; + +#define setup_mpp_packet_name(packet) \ + ((MppPacketImpl*)packet)->name = module_name; + +MPP_RET check_is_mpp_packet(void *packet) +{ + if (packet && ((MppPacketImpl*)packet)->name == module_name) + return MPP_OK; + + mpp_err_f("pointer %p failed on check\n", packet); + mpp_abort(); + return MPP_NOK; +} + +MPP_RET mpp_packet_new(MppPacket *packet) +{ + if (NULL == packet) { + mpp_err_f("invalid NULL input\n"); + return MPP_ERR_NULL_PTR; + } + + MppPacketImpl *p = mpp_calloc(MppPacketImpl, 1); + *packet = p; + if (NULL == p) { + mpp_err_f("malloc failed\n"); + return MPP_ERR_NULL_PTR; + } + setup_mpp_packet_name(p); + return MPP_OK; +} + +MPP_RET mpp_packet_init(MppPacket *packet, void *data, size_t size) +{ + if (NULL == packet) { + mpp_err_f("invalid NULL input packet\n"); + return MPP_ERR_NULL_PTR; + } + + MPP_RET ret = mpp_packet_new(packet); + if (ret) { + mpp_err_f("new packet failed\n"); + return ret; + } + MppPacketImpl *p = (MppPacketImpl *)*packet; + p->data = p->pos = data; + p->size = p->length = size; + + return MPP_OK; +} + +MPP_RET mpp_packet_init_with_buffer(MppPacket *packet, MppBuffer buffer) +{ + if (NULL == packet || NULL == buffer) { + mpp_err_f("invalid input packet %p buffer %p\n", packet, buffer); + return MPP_ERR_NULL_PTR; + } + + MPP_RET ret = mpp_packet_new(packet); + if (ret) { + mpp_err_f("new packet failed\n"); + return ret; + } + MppPacketImpl *p = (MppPacketImpl *)*packet; + p->data = p->pos = mpp_buffer_get_ptr(buffer); + p->size = p->length = mpp_buffer_get_size(buffer); + p->buffer = buffer; + mpp_buffer_inc_ref(buffer); + + return MPP_OK; +} + +MPP_RET mpp_packet_copy_init(MppPacket *packet, const MppPacket src) +{ + if (NULL == packet || check_is_mpp_packet(src)) { + mpp_err_f("found invalid input %p %p\n", packet, src); + return MPP_ERR_UNKNOW; + } + + *packet = NULL; + + MppPacketImpl *src_impl = (MppPacketImpl *)src; + MppPacket pkt; + MPP_RET ret = mpp_packet_new(&pkt); + if (ret) + return ret; + + if (src_impl->buffer) { + /* if source packet has buffer just create a new reference to buffer */ + memcpy(pkt, src_impl, sizeof(*src_impl)); + mpp_buffer_inc_ref(src_impl->buffer); + return MPP_OK; + } + + size_t size = mpp_packet_get_size(src); + /* + * due to parser may be read 32 bit interface so we must alloc more size then real size + * to avoid read carsh + */ + void *data = mpp_malloc_size(void, size + 256); + if (NULL == data) { + mpp_err_f("malloc failed, size %d\n", size); + mpp_packet_deinit(&pkt); + return MPP_ERR_MALLOC; + } + + MppPacketImpl *p = (MppPacketImpl *)pkt; + memcpy(p, src_impl, sizeof(*src_impl)); + p->data = p->pos = data; + p->size = p->length = size; + p->flag |= MPP_PACKET_FLAG_INTERNAL; + if (size) { + memcpy(data, src_impl->data, size); + /* + * clean more alloc byte to zero + */ + memset((RK_U8*)data + size, 0, 256); + } + *packet = pkt; + return MPP_OK; +} + +MPP_RET mpp_packet_deinit(MppPacket *packet) +{ + if (NULL == packet || check_is_mpp_packet(*packet)) { + mpp_err_f("found NULL input\n"); + return MPP_ERR_NULL_PTR; + } + + MppPacketImpl *p = (MppPacketImpl *)(*packet); + + /* release buffer reference */ + if (p->buffer) + mpp_buffer_put(p->buffer); + + if (p->flag & MPP_PACKET_FLAG_INTERNAL) { + mpp_free(p->data); + } + + mpp_free(p); + *packet = NULL; + return MPP_OK; +} + +void mpp_packet_set_pos(MppPacket packet, void *pos) +{ + if (check_is_mpp_packet(packet)) + return ; + + MppPacketImpl *p = (MppPacketImpl *)packet; + p->pos = pos; + p->length = p->size - ((char *)pos - (char *)p->data); + mpp_assert(p->data <= p->pos); + mpp_assert(p->size >= p->length); +} + +void *mpp_packet_get_pos(const MppPacket packet) +{ + if (check_is_mpp_packet(packet)) + return NULL; + + MppPacketImpl *p = (MppPacketImpl *)packet; + return p->pos; +} + +MPP_RET mpp_packet_set_eos(MppPacket packet) +{ + if (check_is_mpp_packet(packet)) + return MPP_ERR_UNKNOW; + + MppPacketImpl *p = (MppPacketImpl *)packet; + p->flag |= MPP_PACKET_FLAG_EOS; + return MPP_OK; +} + +RK_U32 mpp_packet_get_eos(MppPacket packet) +{ + if (check_is_mpp_packet(packet)) + return 0; + + MppPacketImpl *p = (MppPacketImpl *)packet; + return (p->flag & MPP_PACKET_FLAG_EOS) ? (1) : (0); +} + +MPP_RET mpp_packet_set_extra_data(MppPacket packet) +{ + if (check_is_mpp_packet(packet)) + return MPP_ERR_UNKNOW; + + MppPacketImpl *p = (MppPacketImpl *)packet; + p->flag |= MPP_PACKET_FLAG_EXTRA_DATA; + return MPP_OK; +} + +MPP_RET mpp_packet_reset(MppPacketImpl *packet) +{ + if (check_is_mpp_packet(packet)) + return MPP_ERR_UNKNOW; + + memset(packet, 0, sizeof(*packet)); + setup_mpp_packet_name(packet); + return MPP_OK; +} + +void mpp_packet_set_buffer(MppPacket packet, MppBuffer buffer) +{ + if (check_is_mpp_packet(packet)) + return ; + + MppPacketImpl *p = (MppPacketImpl *)packet; + if (p->buffer != buffer) { + if (buffer) + mpp_buffer_inc_ref(buffer); + + if (p->buffer) + mpp_buffer_put(p->buffer); + + p->buffer = buffer; + } +} + +MppBuffer mpp_packet_get_buffer(const MppPacket packet) +{ + if (check_is_mpp_packet(packet)) + return NULL; + + MppPacketImpl *p = (MppPacketImpl *)packet; + return p->buffer; +} + +MPP_RET mpp_packet_read(MppPacket packet, size_t offset, void *data, size_t size) +{ + if (check_is_mpp_packet(packet) || NULL == data) { + mpp_err_f("invalid input: packet %p data %p\n", packet, data); + return MPP_ERR_UNKNOW; + } + + if (0 == size) + return MPP_OK; + + void *src = mpp_packet_get_data(packet); + mpp_assert(src != NULL); + memcpy(data, (char*)src + offset, size); + return MPP_OK; +} + +MPP_RET mpp_packet_write(MppPacket packet, size_t offset, void *data, size_t size) +{ + if (check_is_mpp_packet(packet) || NULL == data) { + mpp_err_f("invalid input: packet %p data %p\n", packet, data); + return MPP_ERR_UNKNOW; + } + + if (0 == size) + return MPP_OK; + + void *dst = mpp_packet_get_data(packet); + mpp_assert(dst != NULL); + memcpy((char*)dst + offset, data, size); + return MPP_OK; +} + +/* + * object access function macro + */ +#define MPP_PACKET_ACCESSORS(type, field) \ + type mpp_packet_get_##field(const MppPacket s) \ + { \ + check_is_mpp_packet(s); \ + return ((MppPacketImpl*)s)->field; \ + } \ + void mpp_packet_set_##field(MppPacket s, type v) \ + { \ + check_is_mpp_packet(s); \ + ((MppPacketImpl*)s)->field = v; \ + } + +MPP_PACKET_ACCESSORS(void *, data) +MPP_PACKET_ACCESSORS(size_t, size) +MPP_PACKET_ACCESSORS(size_t, length) +MPP_PACKET_ACCESSORS(RK_S64, pts) +MPP_PACKET_ACCESSORS(RK_S64, dts) +MPP_PACKET_ACCESSORS(RK_U32, flag) + diff --git a/mpp/base/mpp_task.cpp b/mpp/base/mpp_task.cpp index b38d91c2..4a2b5973 100644 --- a/mpp/base/mpp_task.cpp +++ b/mpp/base/mpp_task.cpp @@ -1,149 +1,149 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define MODULE_TAG "mpp_task" - -#include - -#include "mpp_task.h" -#include "mpp_task_impl.h" - -MPP_RET mpp_task_meta_set_s32(MppTask task, MppMetaKey key, RK_S32 val) -{ - if (check_mpp_task_name(task)) - return MPP_NOK; - - MppTaskImpl *impl = (MppTaskImpl *)task; - return mpp_meta_set_s32(impl->meta, key, val); -} - -MPP_RET mpp_task_meta_set_s64(MppTask task, MppMetaKey key, RK_S64 val) -{ - if (check_mpp_task_name(task)) - return MPP_NOK; - - MppTaskImpl *impl = (MppTaskImpl *)task; - return mpp_meta_set_s64(impl->meta, key, val); -} - -MPP_RET mpp_task_meta_set_ptr(MppTask task, MppMetaKey key, void *val) -{ - if (check_mpp_task_name(task)) - return MPP_NOK; - - MppTaskImpl *impl = (MppTaskImpl *)task; - return mpp_meta_set_ptr(impl->meta, key, val); -} - -MPP_RET mpp_task_meta_set_frame(MppTask task, MppMetaKey key, MppFrame frame) -{ - if (check_mpp_task_name(task)) - return MPP_NOK; - - MppTaskImpl *impl = (MppTaskImpl *)task; - return mpp_meta_set_frame(impl->meta, key, frame); -} - -MPP_RET mpp_task_meta_set_packet(MppTask task, MppMetaKey key, MppPacket packet) -{ - if (check_mpp_task_name(task)) - return MPP_NOK; - - MppTaskImpl *impl = (MppTaskImpl *)task; - return mpp_meta_set_packet(impl->meta, key, packet); -} - -MPP_RET mpp_task_meta_set_buffer(MppTask task, MppMetaKey key, MppBuffer buffer) -{ - if (check_mpp_task_name(task)) - return MPP_NOK; - - MppTaskImpl *impl = (MppTaskImpl *)task; - return mpp_meta_set_buffer(impl->meta, key, buffer); -} - -MPP_RET mpp_task_meta_get_s32(MppTask task, MppMetaKey key, RK_S32 *val, RK_S32 default_val) -{ - if (check_mpp_task_name(task)) - return MPP_NOK; - - MppTaskImpl *impl = (MppTaskImpl *)task; - MPP_RET ret = mpp_meta_get_s32(impl->meta, key, val); - if (ret) - *val = default_val; - return ret; -} - -MPP_RET mpp_task_meta_get_s64(MppTask task, MppMetaKey key, RK_S64 *val, RK_S64 default_val) -{ - if (check_mpp_task_name(task)) - return MPP_NOK; - - MppTaskImpl *impl = (MppTaskImpl *)task; - MPP_RET ret = mpp_meta_get_s64(impl->meta, key, val); - if (ret) - *val = default_val; - return ret; -} - -MPP_RET mpp_task_meta_get_ptr(MppTask task, MppMetaKey key, void **val, void *default_val) -{ - if (check_mpp_task_name(task)) - return MPP_NOK; - - MppTaskImpl *impl = (MppTaskImpl *)task; - MPP_RET ret = mpp_meta_get_ptr(impl->meta, key, val); - if (ret) - *val = default_val; - return ret; -} - -MPP_RET mpp_task_meta_get_frame(MppTask task, MppMetaKey key, MppFrame *frame) -{ - if (check_mpp_task_name(task)) - return MPP_NOK; - - MppTaskImpl *impl = (MppTaskImpl *)task; - MPP_RET ret = mpp_meta_get_frame(impl->meta, key, frame); - if (ret) - *frame = NULL; - return ret; -} - -MPP_RET mpp_task_meta_get_packet(MppTask task, MppMetaKey key, MppPacket *packet) -{ - if (check_mpp_task_name(task)) - return MPP_NOK; - - MppTaskImpl *impl = (MppTaskImpl *)task; - MPP_RET ret = mpp_meta_get_packet(impl->meta, key, packet); - if (ret) - *packet = NULL; - return ret; -} - -MPP_RET mpp_task_meta_get_buffer(MppTask task, MppMetaKey key, MppBuffer *buffer) -{ - if (check_mpp_task_name(task)) - return MPP_NOK; - - MppTaskImpl *impl = (MppTaskImpl *)task; - MPP_RET ret = mpp_meta_get_buffer(impl->meta, key, buffer); - if (ret) - *buffer = NULL; - return ret; -} - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define MODULE_TAG "mpp_task" + +#include + +#include "mpp_task.h" +#include "mpp_task_impl.h" + +MPP_RET mpp_task_meta_set_s32(MppTask task, MppMetaKey key, RK_S32 val) +{ + if (check_mpp_task_name(task)) + return MPP_NOK; + + MppTaskImpl *impl = (MppTaskImpl *)task; + return mpp_meta_set_s32(impl->meta, key, val); +} + +MPP_RET mpp_task_meta_set_s64(MppTask task, MppMetaKey key, RK_S64 val) +{ + if (check_mpp_task_name(task)) + return MPP_NOK; + + MppTaskImpl *impl = (MppTaskImpl *)task; + return mpp_meta_set_s64(impl->meta, key, val); +} + +MPP_RET mpp_task_meta_set_ptr(MppTask task, MppMetaKey key, void *val) +{ + if (check_mpp_task_name(task)) + return MPP_NOK; + + MppTaskImpl *impl = (MppTaskImpl *)task; + return mpp_meta_set_ptr(impl->meta, key, val); +} + +MPP_RET mpp_task_meta_set_frame(MppTask task, MppMetaKey key, MppFrame frame) +{ + if (check_mpp_task_name(task)) + return MPP_NOK; + + MppTaskImpl *impl = (MppTaskImpl *)task; + return mpp_meta_set_frame(impl->meta, key, frame); +} + +MPP_RET mpp_task_meta_set_packet(MppTask task, MppMetaKey key, MppPacket packet) +{ + if (check_mpp_task_name(task)) + return MPP_NOK; + + MppTaskImpl *impl = (MppTaskImpl *)task; + return mpp_meta_set_packet(impl->meta, key, packet); +} + +MPP_RET mpp_task_meta_set_buffer(MppTask task, MppMetaKey key, MppBuffer buffer) +{ + if (check_mpp_task_name(task)) + return MPP_NOK; + + MppTaskImpl *impl = (MppTaskImpl *)task; + return mpp_meta_set_buffer(impl->meta, key, buffer); +} + +MPP_RET mpp_task_meta_get_s32(MppTask task, MppMetaKey key, RK_S32 *val, RK_S32 default_val) +{ + if (check_mpp_task_name(task)) + return MPP_NOK; + + MppTaskImpl *impl = (MppTaskImpl *)task; + MPP_RET ret = mpp_meta_get_s32(impl->meta, key, val); + if (ret) + *val = default_val; + return ret; +} + +MPP_RET mpp_task_meta_get_s64(MppTask task, MppMetaKey key, RK_S64 *val, RK_S64 default_val) +{ + if (check_mpp_task_name(task)) + return MPP_NOK; + + MppTaskImpl *impl = (MppTaskImpl *)task; + MPP_RET ret = mpp_meta_get_s64(impl->meta, key, val); + if (ret) + *val = default_val; + return ret; +} + +MPP_RET mpp_task_meta_get_ptr(MppTask task, MppMetaKey key, void **val, void *default_val) +{ + if (check_mpp_task_name(task)) + return MPP_NOK; + + MppTaskImpl *impl = (MppTaskImpl *)task; + MPP_RET ret = mpp_meta_get_ptr(impl->meta, key, val); + if (ret) + *val = default_val; + return ret; +} + +MPP_RET mpp_task_meta_get_frame(MppTask task, MppMetaKey key, MppFrame *frame) +{ + if (check_mpp_task_name(task)) + return MPP_NOK; + + MppTaskImpl *impl = (MppTaskImpl *)task; + MPP_RET ret = mpp_meta_get_frame(impl->meta, key, frame); + if (ret) + *frame = NULL; + return ret; +} + +MPP_RET mpp_task_meta_get_packet(MppTask task, MppMetaKey key, MppPacket *packet) +{ + if (check_mpp_task_name(task)) + return MPP_NOK; + + MppTaskImpl *impl = (MppTaskImpl *)task; + MPP_RET ret = mpp_meta_get_packet(impl->meta, key, packet); + if (ret) + *packet = NULL; + return ret; +} + +MPP_RET mpp_task_meta_get_buffer(MppTask task, MppMetaKey key, MppBuffer *buffer) +{ + if (check_mpp_task_name(task)) + return MPP_NOK; + + MppTaskImpl *impl = (MppTaskImpl *)task; + MPP_RET ret = mpp_meta_get_buffer(impl->meta, key, buffer); + if (ret) + *buffer = NULL; + return ret; +} + diff --git a/mpp/base/mpp_task_impl.cpp b/mpp/base/mpp_task_impl.cpp index 70b61171..3cb6ad22 100644 --- a/mpp/base/mpp_task_impl.cpp +++ b/mpp/base/mpp_task_impl.cpp @@ -1,307 +1,307 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define MODULE_TAG "mpp_task_impl" - -#include - -#include "mpp_log.h" -#include "mpp_mem.h" - -#include "mpp_task_impl.h" - -#define MAX_TASK_COUNT 8 - -typedef struct MppTaskStatusInfo_t { - struct list_head list; - RK_S32 count; - MppTaskStatus status; -} MppTaskStatusInfo; - -typedef struct MppTaskQueueImpl_t { - Mutex *lock; - RK_S32 task_count; - - // two ports inside of task queue - MppPort input; - MppPort output; - - MppTaskImpl *tasks; - - MppTaskStatusInfo info[MPP_TASK_STATUS_BUTT]; -} MppTaskQueueImpl; - -typedef struct MppPortImpl_t { - MppPortType type; - MppTaskQueueImpl *queue; - - MppTaskStatus status_curr; - MppTaskStatus next_on_dequeue; - MppTaskStatus next_on_enqueue; -} MppPortImpl; - -static const char *module_name = MODULE_TAG; - -void setup_mpp_task_name(MppTaskImpl *task) -{ - task->name = module_name; -} - -MPP_RET check_mpp_task_name(MppTask task) -{ - if (task && ((MppTaskImpl *)task)->name == module_name) - return MPP_OK; - - mpp_err_f("pointer %p failed on check\n", task); - mpp_abort(); - return MPP_NOK; -} - -static MPP_RET mpp_port_init(MppTaskQueueImpl *queue, MppPortType type, MppPort *port) -{ - MppPortImpl *impl = mpp_malloc(MppPortImpl, 1); - if (NULL == impl) { - mpp_err_f("failed to malloc MppPort type %d\n", type); - return MPP_ERR_MALLOC; - } - - impl->type = type; - impl->queue = queue; - - if (MPP_PORT_INPUT == type) { - impl->status_curr = MPP_INPUT_PORT; - impl->next_on_dequeue = MPP_INPUT_HOLD; - impl->next_on_enqueue = MPP_OUTPUT_PORT; - } else { - impl->status_curr = MPP_OUTPUT_PORT; - impl->next_on_dequeue = MPP_OUTPUT_HOLD; - impl->next_on_enqueue = MPP_INPUT_PORT; - } - - *port = (MppPort *)impl; - - return MPP_OK; -} - -static MPP_RET mpp_port_deinit(MppPort port) -{ - mpp_free(port); - return MPP_OK; -} - -MPP_RET mpp_port_can_dequeue(MppPort port) -{ - MppPortImpl *port_impl = (MppPortImpl *)port; - MppTaskQueueImpl *queue = port_impl->queue; - - AutoMutex auto_lock(queue->lock); - MppTaskStatusInfo *curr = &queue->info[port_impl->status_curr]; - - if (curr->count) { - mpp_assert(!list_empty(&curr->list)); - return MPP_OK; - } - - mpp_assert(list_empty(&curr->list)); - return MPP_NOK; -} - -MPP_RET mpp_port_dequeue(MppPort port, MppTask *task) -{ - MppPortImpl *port_impl = (MppPortImpl *)port; - MppTaskQueueImpl *queue = port_impl->queue; - - AutoMutex auto_lock(queue->lock); - MppTaskStatusInfo *curr = &queue->info[port_impl->status_curr]; - MppTaskStatusInfo *next = &queue->info[port_impl->next_on_dequeue]; - - *task = NULL; - if (curr->count == 0) { - mpp_assert(list_empty(&curr->list)); - return MPP_OK; - } - - MppTaskImpl *task_impl = list_entry(curr->list.next, MppTaskImpl, list); - MppTask p = (MppTask)task_impl; - check_mpp_task_name(p); - list_del_init(&task_impl->list); - curr->count--; - mpp_assert(curr->count >= 0); - - list_add_tail(&task_impl->list, &next->list); - next->count++; - task_impl->status = next->status; - - *task = p; - - return MPP_OK; -} - -MPP_RET mpp_port_enqueue(MppPort port, MppTask task) -{ - MppTaskImpl *task_impl = (MppTaskImpl *)task; - MppPortImpl *port_impl = (MppPortImpl *)port; - MppTaskQueueImpl *queue = port_impl->queue; - check_mpp_task_name(task); - - mpp_assert(task_impl->queue == (MppTaskQueue *)queue); - mpp_assert(task_impl->status == port_impl->next_on_dequeue); - - AutoMutex auto_lock(queue->lock); - MppTaskStatusInfo *curr = &queue->info[task_impl->status]; - MppTaskStatusInfo *next = &queue->info[port_impl->next_on_enqueue]; - - list_del_init(&task_impl->list); - curr->count--; - list_add_tail(&task_impl->list, &next->list); - next->count++; - task_impl->status = next->status; - - return MPP_OK; -} - -MPP_RET mpp_task_queue_init(MppTaskQueue *queue) -{ - if (NULL == queue) { - mpp_err_f("invalid NULL input\n"); - return MPP_ERR_NULL_PTR; - } - - MppTaskQueueImpl *p = NULL; - MppTaskImpl *tasks = NULL; - Mutex *lock = NULL; - - do { - RK_S32 i; - - p = mpp_calloc(MppTaskQueueImpl, 1); - if (NULL == p) { - mpp_err_f("malloc queue failed\n"); - break; - } - lock = new Mutex(); - if (NULL == lock) { - mpp_err_f("new lock failed\n"); - break;; - } - - for (i = 0; i < MPP_TASK_STATUS_BUTT; i++) { - INIT_LIST_HEAD(&p->info[i].list); - p->info[i].count = 0; - p->info[i].status = (MppTaskStatus)i; - } - - p->lock = lock; - p->tasks = tasks; - - if (mpp_port_init(p, MPP_PORT_INPUT, &p->input)) - break; - - if (mpp_port_init(p, MPP_PORT_OUTPUT, &p->output)) { - mpp_port_deinit(p->input); - break; - } - - *queue = p; - return MPP_OK; - } while (0); - - if (p) - mpp_free(p); - if (lock) - delete lock; - if (tasks) - mpp_free(tasks); - - *queue = NULL; - return MPP_NOK; -} - -MPP_RET mpp_task_queue_setup(MppTaskQueue queue, RK_S32 task_count) -{ - MppTaskQueueImpl *impl = (MppTaskQueueImpl *)queue; - AutoMutex auto_lock(impl->lock); - - // NOTE: queue can only be setup once - mpp_assert(impl->tasks == NULL); - mpp_assert(impl->task_count == 0); - MppTaskImpl *tasks = mpp_calloc(MppTaskImpl, task_count); - if (NULL == tasks) { - mpp_err_f("malloc tasks list failed\n"); - return MPP_ERR_MALLOC; - } - - impl->tasks = tasks; - impl->task_count = task_count; - - MppTaskStatusInfo *info = &impl->info[MPP_INPUT_PORT]; - - for (RK_S32 i = 0; i < task_count; i++) { - setup_mpp_task_name(&tasks[i]); - INIT_LIST_HEAD(&tasks[i].list); - tasks[i].index = i; - tasks[i].queue = (MppTaskQueue *)queue; - tasks[i].status = MPP_INPUT_PORT; - mpp_meta_get(&tasks[i].meta); - - list_add_tail(&tasks[i].list, &info->list); - info->count++; - } - return MPP_OK; -} - -MPP_RET mpp_task_queue_deinit(MppTaskQueue queue) -{ - if (NULL == queue) { - mpp_err_f("found NULL input queue\n"); - return MPP_ERR_NULL_PTR; - } - - MppTaskQueueImpl *p = (MppTaskQueueImpl *)queue; - if (p->input) { - mpp_port_deinit(p->input); - p->input = NULL; - } - if (p->output) { - mpp_port_deinit(p->output); - p->output = NULL; - } - if (p->tasks) { - for (RK_S32 i = 0; i < p->task_count; i++) { - /* we must ensure that all task return to init status */ - mpp_assert(p->tasks[i].status == MPP_INPUT_PORT || - p->tasks[i].status == MPP_INPUT_HOLD); - mpp_meta_put(p->tasks[i].meta); - } - mpp_free(p->tasks); - } - if (p->lock) - delete p->lock; - mpp_free(p); - return MPP_OK; -} - -MppPort mpp_task_queue_get_port(MppTaskQueue queue, MppPortType type) -{ - if (NULL == queue || type >= MPP_PORT_BUTT) { - mpp_err_f("invalid input queue %p type %d\n", queue, type); - return NULL; - } - - MppTaskQueueImpl *impl = (MppTaskQueueImpl *)queue; - return (type == MPP_PORT_INPUT) ? (impl->input) : (impl->output); -} - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define MODULE_TAG "mpp_task_impl" + +#include + +#include "mpp_log.h" +#include "mpp_mem.h" + +#include "mpp_task_impl.h" + +#define MAX_TASK_COUNT 8 + +typedef struct MppTaskStatusInfo_t { + struct list_head list; + RK_S32 count; + MppTaskStatus status; +} MppTaskStatusInfo; + +typedef struct MppTaskQueueImpl_t { + Mutex *lock; + RK_S32 task_count; + + // two ports inside of task queue + MppPort input; + MppPort output; + + MppTaskImpl *tasks; + + MppTaskStatusInfo info[MPP_TASK_STATUS_BUTT]; +} MppTaskQueueImpl; + +typedef struct MppPortImpl_t { + MppPortType type; + MppTaskQueueImpl *queue; + + MppTaskStatus status_curr; + MppTaskStatus next_on_dequeue; + MppTaskStatus next_on_enqueue; +} MppPortImpl; + +static const char *module_name = MODULE_TAG; + +void setup_mpp_task_name(MppTaskImpl *task) +{ + task->name = module_name; +} + +MPP_RET check_mpp_task_name(MppTask task) +{ + if (task && ((MppTaskImpl *)task)->name == module_name) + return MPP_OK; + + mpp_err_f("pointer %p failed on check\n", task); + mpp_abort(); + return MPP_NOK; +} + +static MPP_RET mpp_port_init(MppTaskQueueImpl *queue, MppPortType type, MppPort *port) +{ + MppPortImpl *impl = mpp_malloc(MppPortImpl, 1); + if (NULL == impl) { + mpp_err_f("failed to malloc MppPort type %d\n", type); + return MPP_ERR_MALLOC; + } + + impl->type = type; + impl->queue = queue; + + if (MPP_PORT_INPUT == type) { + impl->status_curr = MPP_INPUT_PORT; + impl->next_on_dequeue = MPP_INPUT_HOLD; + impl->next_on_enqueue = MPP_OUTPUT_PORT; + } else { + impl->status_curr = MPP_OUTPUT_PORT; + impl->next_on_dequeue = MPP_OUTPUT_HOLD; + impl->next_on_enqueue = MPP_INPUT_PORT; + } + + *port = (MppPort *)impl; + + return MPP_OK; +} + +static MPP_RET mpp_port_deinit(MppPort port) +{ + mpp_free(port); + return MPP_OK; +} + +MPP_RET mpp_port_can_dequeue(MppPort port) +{ + MppPortImpl *port_impl = (MppPortImpl *)port; + MppTaskQueueImpl *queue = port_impl->queue; + + AutoMutex auto_lock(queue->lock); + MppTaskStatusInfo *curr = &queue->info[port_impl->status_curr]; + + if (curr->count) { + mpp_assert(!list_empty(&curr->list)); + return MPP_OK; + } + + mpp_assert(list_empty(&curr->list)); + return MPP_NOK; +} + +MPP_RET mpp_port_dequeue(MppPort port, MppTask *task) +{ + MppPortImpl *port_impl = (MppPortImpl *)port; + MppTaskQueueImpl *queue = port_impl->queue; + + AutoMutex auto_lock(queue->lock); + MppTaskStatusInfo *curr = &queue->info[port_impl->status_curr]; + MppTaskStatusInfo *next = &queue->info[port_impl->next_on_dequeue]; + + *task = NULL; + if (curr->count == 0) { + mpp_assert(list_empty(&curr->list)); + return MPP_OK; + } + + MppTaskImpl *task_impl = list_entry(curr->list.next, MppTaskImpl, list); + MppTask p = (MppTask)task_impl; + check_mpp_task_name(p); + list_del_init(&task_impl->list); + curr->count--; + mpp_assert(curr->count >= 0); + + list_add_tail(&task_impl->list, &next->list); + next->count++; + task_impl->status = next->status; + + *task = p; + + return MPP_OK; +} + +MPP_RET mpp_port_enqueue(MppPort port, MppTask task) +{ + MppTaskImpl *task_impl = (MppTaskImpl *)task; + MppPortImpl *port_impl = (MppPortImpl *)port; + MppTaskQueueImpl *queue = port_impl->queue; + check_mpp_task_name(task); + + mpp_assert(task_impl->queue == (MppTaskQueue *)queue); + mpp_assert(task_impl->status == port_impl->next_on_dequeue); + + AutoMutex auto_lock(queue->lock); + MppTaskStatusInfo *curr = &queue->info[task_impl->status]; + MppTaskStatusInfo *next = &queue->info[port_impl->next_on_enqueue]; + + list_del_init(&task_impl->list); + curr->count--; + list_add_tail(&task_impl->list, &next->list); + next->count++; + task_impl->status = next->status; + + return MPP_OK; +} + +MPP_RET mpp_task_queue_init(MppTaskQueue *queue) +{ + if (NULL == queue) { + mpp_err_f("invalid NULL input\n"); + return MPP_ERR_NULL_PTR; + } + + MppTaskQueueImpl *p = NULL; + MppTaskImpl *tasks = NULL; + Mutex *lock = NULL; + + do { + RK_S32 i; + + p = mpp_calloc(MppTaskQueueImpl, 1); + if (NULL == p) { + mpp_err_f("malloc queue failed\n"); + break; + } + lock = new Mutex(); + if (NULL == lock) { + mpp_err_f("new lock failed\n"); + break;; + } + + for (i = 0; i < MPP_TASK_STATUS_BUTT; i++) { + INIT_LIST_HEAD(&p->info[i].list); + p->info[i].count = 0; + p->info[i].status = (MppTaskStatus)i; + } + + p->lock = lock; + p->tasks = tasks; + + if (mpp_port_init(p, MPP_PORT_INPUT, &p->input)) + break; + + if (mpp_port_init(p, MPP_PORT_OUTPUT, &p->output)) { + mpp_port_deinit(p->input); + break; + } + + *queue = p; + return MPP_OK; + } while (0); + + if (p) + mpp_free(p); + if (lock) + delete lock; + if (tasks) + mpp_free(tasks); + + *queue = NULL; + return MPP_NOK; +} + +MPP_RET mpp_task_queue_setup(MppTaskQueue queue, RK_S32 task_count) +{ + MppTaskQueueImpl *impl = (MppTaskQueueImpl *)queue; + AutoMutex auto_lock(impl->lock); + + // NOTE: queue can only be setup once + mpp_assert(impl->tasks == NULL); + mpp_assert(impl->task_count == 0); + MppTaskImpl *tasks = mpp_calloc(MppTaskImpl, task_count); + if (NULL == tasks) { + mpp_err_f("malloc tasks list failed\n"); + return MPP_ERR_MALLOC; + } + + impl->tasks = tasks; + impl->task_count = task_count; + + MppTaskStatusInfo *info = &impl->info[MPP_INPUT_PORT]; + + for (RK_S32 i = 0; i < task_count; i++) { + setup_mpp_task_name(&tasks[i]); + INIT_LIST_HEAD(&tasks[i].list); + tasks[i].index = i; + tasks[i].queue = (MppTaskQueue *)queue; + tasks[i].status = MPP_INPUT_PORT; + mpp_meta_get(&tasks[i].meta); + + list_add_tail(&tasks[i].list, &info->list); + info->count++; + } + return MPP_OK; +} + +MPP_RET mpp_task_queue_deinit(MppTaskQueue queue) +{ + if (NULL == queue) { + mpp_err_f("found NULL input queue\n"); + return MPP_ERR_NULL_PTR; + } + + MppTaskQueueImpl *p = (MppTaskQueueImpl *)queue; + if (p->input) { + mpp_port_deinit(p->input); + p->input = NULL; + } + if (p->output) { + mpp_port_deinit(p->output); + p->output = NULL; + } + if (p->tasks) { + for (RK_S32 i = 0; i < p->task_count; i++) { + /* we must ensure that all task return to init status */ + mpp_assert(p->tasks[i].status == MPP_INPUT_PORT || + p->tasks[i].status == MPP_INPUT_HOLD); + mpp_meta_put(p->tasks[i].meta); + } + mpp_free(p->tasks); + } + if (p->lock) + delete p->lock; + mpp_free(p); + return MPP_OK; +} + +MppPort mpp_task_queue_get_port(MppTaskQueue queue, MppPortType type) +{ + if (NULL == queue || type >= MPP_PORT_BUTT) { + mpp_err_f("invalid input queue %p type %d\n", queue, type); + return NULL; + } + + MppTaskQueueImpl *impl = (MppTaskQueueImpl *)queue; + return (type == MPP_PORT_INPUT) ? (impl->input) : (impl->output); +} + diff --git a/mpp/codec/dec/avs/avsd_api.c b/mpp/codec/dec/avs/avsd_api.c index 3f716e5f..d0d1cb68 100644 --- a/mpp/codec/dec/avs/avsd_api.c +++ b/mpp/codec/dec/avs/avsd_api.c @@ -1,643 +1,643 @@ -/* -* -* Copyright 2015 Rockchip Electronics Co. LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#define MODULE_TAG "avsd_api" - -#include -#include -#include - -#include "mpp_time.h" -#include "mpp_mem.h" -#include "mpp_log.h" -#include "mpp_env.h" -#include "mpp_packet.h" -#include "mpp_packet_impl.h" -#include "mpp_buffer_impl.h" - -#include "avsd_api.h" -#include "avsd_parse.h" -#include "avsd_impl.h" - -RK_U32 avsd_parse_debug = 0; - -#ifdef RKV_AVSD_DEBUG -static MPP_RET free_input_ctx(AvsdInputCtx_t *p_inp) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - - INP_CHECK(ret, !p_inp); - AVSD_PARSE_TRACE("In."); - - MPP_FCLOSE(p_inp->fp_log); -__RETURN: - AVSD_PARSE_TRACE("Out."); - return ret = MPP_OK; -} -static MPP_RET init_input_ctx(AvsdInputCtx_t *p_inp, ParserCfg *init) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - - INP_CHECK(ret, !p_inp && !init); - AVSD_PARSE_TRACE("In."); - - p_inp->init = *init; -#if defined(_WIN32) - if ((p_inp->fp_log = fopen("F:/avs_log/avs_runlog.txt", "wb")) == 0) { - mpp_log("Wanning, open file, %s(%d)", __FUNCTION__, __LINE__); - } -#endif -__RETURN: - AVSD_PARSE_TRACE("Out."); - return ret = MPP_OK; -} - - -static MPP_RET free_cur_ctx(AvsdCurCtx_t *p_cur) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - - INP_CHECK(ret, !p_cur); - AVSD_PARSE_TRACE("In."); - - -__RETURN: - AVSD_PARSE_TRACE("Out."); - - return ret = MPP_OK; -} -static MPP_RET init_cur_ctx(AvsdCurCtx_t *p_cur) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - AvsdCurStream_t *p_strm = NULL; - - INP_CHECK(ret, !p_cur); - AVSD_PARSE_TRACE("In."); - - p_strm = &p_cur->m_strm; - p_strm->prefixdata = 0xffffffff; - -__RETURN: - AVSD_PARSE_TRACE("Out."); - return ret = MPP_OK; - -} - - -static MPP_RET free_vid_ctx(AvsdVideoCtx_t *p_vid) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - - INP_CHECK(ret, !p_vid); - AVSD_PARSE_TRACE("In."); - - -__RETURN: - AVSD_PARSE_TRACE("Out."); - - return ret = MPP_OK; -} -static MPP_RET init_vid_ctx(AvsdVideoCtx_t *p_vid) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - - INP_CHECK(ret, !p_vid); - AVSD_PARSE_TRACE("In."); - -__RETURN: - AVSD_PARSE_TRACE("Out."); - return ret = MPP_OK; -} - -static MPP_RET free_bitstream(AvsdBitstream_t *p) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - - INP_CHECK(ret, !p); - AVSD_PARSE_TRACE("In."); - - MPP_FREE(p->pbuf); - -__RETURN: - AVSD_PARSE_TRACE("Out."); - - return ret = MPP_OK; -} - -static MPP_RET init_bitstream(AvsdBitstream_t *p) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - - INP_CHECK(ret, !p); - AVSD_PARSE_TRACE("In."); - p->size = MAX_BITSTREAM_SIZE; - p->pbuf = mpp_malloc(RK_U8, MAX_BITSTREAM_SIZE); - MEM_CHECK(ret, p->pbuf); - -__RETURN: - AVSD_PARSE_TRACE("Out."); - return ret = MPP_OK; -__FAILED: - return ret; -} - - -static MPP_RET free_dec_ctx(Avs_DecCtx_t *p_dec) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - - INP_CHECK(ret, NULL == p_dec); - AVSD_PARSE_TRACE("In."); - lib_avsd_destory(p_dec->libdec); - mpp_packet_deinit(&p_dec->task_pkt); - free_bitstream(p_dec->bitstream); - MPP_FREE(p_dec->mem); - -__RETURN: - AVSD_PARSE_TRACE("Out."); - - return ret = MPP_OK; -} - - - -static MPP_RET init_dec_ctx(Avs_DecCtx_t *p_dec) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - - INP_CHECK(ret, !p_dec); - AVSD_PARSE_TRACE("In."); - - mpp_buf_slot_setup(p_dec->frame_slots, 4); - p_dec->mem = mpp_calloc(AvsdMemory_t, 1); - MEM_CHECK(ret, p_dec->mem); - p_dec->bitstream = &p_dec->mem->bitstream; - FUN_CHECK(ret = init_bitstream(p_dec->bitstream)); - //!< malloc mpp packet - mpp_packet_init(&p_dec->task_pkt, p_dec->bitstream->pbuf, p_dec->bitstream->size); - mpp_packet_set_length(p_dec->task_pkt, 0); - MEM_CHECK(ret, p_dec->task_pkt); - //!< malloc libavsd.so - p_dec->libdec = lib_avsd_create(); - MEM_CHECK(ret, p_dec->libdec); - FUN_CHECK(ret = lib_avsd_init(p_dec->libdec)); - p_dec->outframe = &p_dec->mem->outframe; - -__RETURN: - AVSD_PARSE_TRACE("Out."); - - return ret = MPP_OK; -__FAILED: - free_dec_ctx(p_dec); - - return ret; -} -/*! -*********************************************************************** -* \brief -* free all buffer -*********************************************************************** -*/ -MPP_RET avsd_deinit(void *decoder) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - Avs_DecCtx_t *p_dec = (Avs_DecCtx_t *)decoder; - - INP_CHECK(ret, !decoder); - AVSD_PARSE_TRACE("In."); - avsd_flush(decoder); - free_input_ctx(p_dec->p_inp); - MPP_FREE(p_dec->p_inp); - free_cur_ctx(p_dec->p_cur); - MPP_FREE(p_dec->p_cur); - free_vid_ctx(p_dec->p_vid); - MPP_FREE(p_dec->p_vid); - free_dec_ctx(p_dec); -__RETURN: - (void)decoder; - AVSD_PARSE_TRACE("Out."); - return ret = MPP_OK; -} - -/*! -*********************************************************************** -* \brief -* alloc all buffer -*********************************************************************** -*/ - -MPP_RET avsd_init(void *decoder, ParserCfg *init) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - Avs_DecCtx_t *p_dec = (Avs_DecCtx_t *)decoder; - - AVSD_PARSE_TRACE("In."); - INP_CHECK(ret, !p_dec); - memset(p_dec, 0, sizeof(Avs_DecCtx_t)); - // init logctx - mpp_env_get_u32("avsd_debug", &avsd_parse_debug, 0); - //!< get init frame_slots and packet_slots - p_dec->frame_slots = init->frame_slots; - p_dec->packet_slots = init->packet_slots; - //!< malloc decoder buffer - p_dec->p_inp = mpp_calloc(AvsdInputCtx_t, 1); - p_dec->p_cur = mpp_calloc(AvsdCurCtx_t, 1); - p_dec->p_vid = mpp_calloc(AvsdVideoCtx_t, 1); - MEM_CHECK(ret, p_dec->p_inp && p_dec->p_cur && p_dec->p_vid); - - p_dec->p_inp->p_dec = p_dec; - p_dec->p_inp->p_cur = p_dec->p_cur; - p_dec->p_inp->p_vid = p_dec->p_vid; - FUN_CHECK(ret = init_input_ctx(p_dec->p_inp, init)); - p_dec->p_cur->p_dec = p_dec; - p_dec->p_cur->p_inp = p_dec->p_inp; - p_dec->p_cur->p_vid = p_dec->p_vid; - FUN_CHECK(ret = init_cur_ctx(p_dec->p_cur)); - p_dec->p_vid->p_dec = p_dec; - p_dec->p_vid->p_inp = p_dec->p_inp; - p_dec->p_vid->p_cur = p_dec->p_cur; - FUN_CHECK(ret = init_vid_ctx(p_dec->p_vid)); - FUN_CHECK(ret = init_dec_ctx(p_dec)); -__RETURN: - (void)decoder; - (void)init; - AVSD_PARSE_TRACE("Out."); - return ret = MPP_OK; -__FAILED: - avsd_deinit(decoder); - - return ret; -} -/*! -*********************************************************************** -* \brief -* reset -*********************************************************************** -*/ -MPP_RET avsd_reset(void *decoder) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - Avs_DecCtx_t *p_dec = (Avs_DecCtx_t *)decoder; - - AVSD_PARSE_TRACE("In."); - - AVSD_PARSE_TRACE("Out."); - (void)p_dec; - (void)decoder; - return ret = MPP_OK; -} - -/*! -*********************************************************************** -* \brief -* flush -*********************************************************************** -*/ -MPP_RET avsd_flush(void *decoder) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - Avs_DecCtx_t *p_dec = (Avs_DecCtx_t *)decoder; - AVSD_PARSE_TRACE("In."); - - - AVSD_PARSE_TRACE("Out."); - (void)p_dec; - (void)decoder; - return ret = MPP_OK; -} - -/*! -*********************************************************************** -* \brief -* control/perform -*********************************************************************** -*/ -MPP_RET avsd_control(void *decoder, RK_S32 cmd_type, void *param) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - - AVSD_PARSE_TRACE("In."); - - - (void)decoder; - (void)cmd_type; - (void)param; - AVSD_PARSE_TRACE("Out."); - return ret = MPP_OK; -} - - -/*! -*********************************************************************** -* \brief -* prepare -*********************************************************************** -*/ -MPP_RET avsd_prepare(void *decoder, MppPacket pkt, HalDecTask *task) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - AvsdInputCtx_t *p_inp = NULL; - Avs_DecCtx_t *p_dec = (Avs_DecCtx_t *)decoder; - - AVSD_PARSE_TRACE("In."); - INP_CHECK(ret, !decoder && !pkt && !task); - p_inp = p_dec->p_inp; - if (p_inp->has_get_eos) { - mpp_packet_set_length(pkt, 0); - goto __RETURN; - } - p_inp->in_pkt = pkt; - p_inp->in_task = task; - - if (mpp_packet_get_eos(pkt)) { - if (mpp_packet_get_length(pkt) < 4) { - avsd_flush(decoder); - } - p_inp->has_get_eos = 1; - } - AVSD_DBG(AVSD_DBG_INPUT, "[pkt_in_timeUs] in_pts=%lld, pkt_eos=%d, len=%d, pkt_no=%d", - mpp_packet_get_pts(pkt), mpp_packet_get_eos(pkt), mpp_packet_get_length(pkt), p_inp->pkt_no++); - - if (mpp_packet_get_length(pkt) > MAX_STREM_IN_SIZE) { - AVSD_DBG(AVSD_DBG_ERROR, "[pkt_in_timeUs] input error, stream too large"); - mpp_packet_set_length(pkt, 0); - ret = MPP_NOK; - goto __FAILED; - } - p_inp->in_pts = mpp_packet_get_pts(pkt); - p_inp->in_dts = mpp_packet_get_dts(pkt); - - memset(task, 0, sizeof(HalDecTask)); - do { - (ret = avsd_parse_prepare(p_inp, p_dec->p_cur)); - - } while (mpp_packet_get_length(pkt) && !task->valid); - - if (task->valid) { - mpp_packet_set_pos(task->input_packet, p_dec->bitstream->pbuf); - mpp_packet_set_length(task->input_packet, 16); - mpp_packet_set_size(task->input_packet, 32); - } - -__RETURN: - (void)decoder; - (void)pkt; - (void)task; - AVSD_PARSE_TRACE("Out."); - return ret = MPP_OK; -__FAILED: - return ret; -} - - -/*! -*********************************************************************** -* \brief -* parser -*********************************************************************** -*/ -MPP_RET avsd_parse(void *decoder, HalDecTask *task) -{ - RK_S64 p_s = 0, p_e = 0, diff = 0; - MPP_RET ret = MPP_ERR_UNKNOW; - Avs_DecCtx_t *p_dec = (Avs_DecCtx_t *)decoder; - AVSD_PARSE_TRACE("In."); - - p_s = mpp_time(); - task->valid = 0; - memset(task->refer, -1, sizeof(task->refer)); - - lib_avsd_decode_one_frame(p_dec->libdec, (RK_S32 *)&task->valid); - mpp_log("[out_frame] task->valid=%d", task->valid); - if (task->flags.eos) { - avsd_flush(decoder); - goto __RETURN; - } - if (task->valid) { - RK_S32 out_slot_idx = -1; - mpp_buf_slot_get_unused(p_dec->frame_slots, &out_slot_idx); - if (out_slot_idx >= 0) { - MppFrame mframe = NULL; - AvsdOutframe_t *f = p_dec->outframe; - lib_avsd_get_outframe(p_dec->libdec, &f->nWidth, &f->nHeight, f->data, f->stride, f->corp); - mpp_log("[out_frame] width=%d, height=%d, stride[0]=%d, stride[1]=%d, stride[2]=%d", - f->nWidth, f->nHeight, f->stride[0], f->stride[1], f->stride[2]);; - mpp_frame_init(&mframe); - mpp_frame_set_fmt(mframe, MPP_FMT_YUV420SP); - mpp_frame_set_hor_stride(mframe, f->nWidth); // before crop - mpp_frame_set_ver_stride(mframe, f->nHeight); - mpp_frame_set_width(mframe, f->nWidth); // after crop - mpp_frame_set_height(mframe, f->nHeight); - //mpp_frame_set_pts(mframe, p_Vid->p_Cur->last_pts); - //mpp_frame_set_dts(mframe, p_Vid->p_Cur->last_dts); - mpp_buf_slot_set_prop(p_dec->frame_slots, out_slot_idx, SLOT_FRAME, mframe); - mpp_frame_deinit(&mframe); - mpp_buf_slot_get_prop(p_dec->frame_slots, out_slot_idx, SLOT_FRAME_PTR, &mframe); - f->hor_stride = mpp_frame_get_hor_stride(mframe); - f->ver_stride = mpp_frame_get_ver_stride(mframe); - out_slot_idx = task->output; - //mpp_buf_slot_set_flag(p_dec->frame_slots, task->output, SLOT_HAL_OUTPUT); - } - p_dec->parse_no++; - p_e = mpp_time(); - diff = (p_e - p_s) / 1000; - p_dec->parse_time += diff; - AVSD_DBG(AVSD_DBG_TIME, "[avsd_time] parser stream consume time %lld, av=%lld ", diff, p_dec->parse_time / p_dec->parse_no); - } -__RETURN: - (void)decoder; - (void)task; - AVSD_PARSE_TRACE("Out."); - - return ret = MPP_OK; -} -/*! -*********************************************************************** -* \brief -* callback -*********************************************************************** -*/ - -MPP_RET nv12_copy_buffer(RK_U8 *des, AvsdOutframe_t *f) -{ - RK_S32 i = 0, j = 0; - RK_U8 *ptr = NULL; - - //!< copy Y - mpp_log("[nv12_copy_buffer] width=%d, height=%d, hor_stride=%d, ver_stride=%d \n", f->nWidth, f->nHeight, f->hor_stride, f->ver_stride); - ptr = des; - for (i = 0; i < f->nHeight; i++) { - memcpy(ptr, f->data[0] + f->stride[0] * i, f->hor_stride); - ptr += f->hor_stride; - } -#if 0 - //!< copy U - ptr = des + f->nHeight * f->nWidth; - for (i = 0; i < f->nHeight / 2; i++) { - memcpy(ptr, f->data[1] + f->stride[1] * i, f->nWidth / 2); - ptr += f->nWidth / 2; - } - //!< copy V - ptr = des + f->nHeight * f->nWidth * 5 / 4; - for (i = 0; i < f->nHeight / 2; i++) { - memcpy(ptr, f->data[2] + f->stride[2] * i, f->nWidth / 2); - ptr += f->nWidth / 2; - } -#else - //!< copy U V - ptr = des + f->hor_stride * f->ver_stride; - for (i = 0; i < f->nHeight / 2; i++) { - for (j = 0; j < f->nWidth / 2; j++) { - ptr[2 * j + 0] = f->data[1][f->stride[1] * i + j]; - ptr[2 * j + 1] = f->data[2][f->stride[2] * i + j]; - } - ptr += f->hor_stride; - } -#endif - - return MPP_OK; -} - -MPP_RET avsd_callback(void *decoder, void *info) -{ - RK_S64 p_s = 0, p_e = 0, diff = 0; - MPP_RET ret = MPP_ERR_UNKNOW; - HalTaskInfo *task = (HalTaskInfo *)info; - Avs_DecCtx_t *p_dec = (Avs_DecCtx_t *)decoder; - AVSD_PARSE_TRACE("In."); - AVSD_PARSE_TRACE("[avsd_parse_decode] frame_dec_no=%d", p_dec->dec_no); - p_dec->dec_no++; - if (task->dec.valid) { - p_s = mpp_time(); - //lib_decode_one_frame(p_dec->libdec, &task->dec); - p_e = mpp_time(); - diff = (p_e - p_s) / 1000; - p_dec->decode_frame_time += diff; - AVSD_DBG(AVSD_DBG_TIME, "[avsd_time] decode one frame total time=%lld, av=%lld ", diff, p_dec->decode_frame_time / p_dec->dec_no); - - AVSD_DBG(AVSD_DBG_TIME, "[avsd_time] @ decode init av=%lld ", p_dec->decode_init_time / (1000 * p_dec->dec_no)); - AVSD_DBG(AVSD_DBG_TIME, "[avsd_time] @ decode data av=%lld ", p_dec->decode_data_time / (1000 * p_dec->dec_no)); - AVSD_DBG(AVSD_DBG_TIME, "[avsd_time] # read slice header consume av=%lld ", p_dec->read_slice_header_time / (1000 * p_dec->dec_no)); - AVSD_DBG(AVSD_DBG_TIME, "[avsd_time] # init arodeco slice consume av=%lld ", p_dec->init_arideco_slice_time / (1000 * p_dec->dec_no)); - AVSD_DBG(AVSD_DBG_TIME, "[avsd_time] # start marco blocks consume av=%lld ", p_dec->start_marcoblock_time / (1000 * p_dec->dec_no)); - AVSD_DBG(AVSD_DBG_TIME, "[avsd_time] # read marco blocks consume av=%lld ", p_dec->read_marcoblock_time / (1000 * p_dec->dec_no)); - AVSD_DBG(AVSD_DBG_TIME, "[avsd_time] # decode marco blocks consume av=%lld ", p_dec->decode_marcoblock_time / (1000 * p_dec->dec_no)); - AVSD_DBG(AVSD_DBG_TIME, "[avsd_time] $ get marco blocks consume av=%lld ", p_dec->get_block_time / (1000 * p_dec->dec_no)); - AVSD_DBG(AVSD_DBG_TIME, "[avsd_time] $ intra pred blocks consume av=%lld ", p_dec->intra_pred_block_time / (1000 * p_dec->dec_no)); - AVSD_DBG(AVSD_DBG_TIME, "[avsd_time] $ inter pred blocks consume av=%lld ", p_dec->inter_pred_block_time / (1000 * p_dec->dec_no)); - AVSD_DBG(AVSD_DBG_TIME, "[avsd_time] $ idc_dequant blocks consume av=%lld ", p_dec->idc_dequaut_time / (1000 * p_dec->dec_no)); - AVSD_DBG(AVSD_DBG_TIME, "[avsd_time] @ deblocking consume av=%lld ", p_dec->deblock_time / (1000 * p_dec->dec_no)); - AVSD_DBG(AVSD_DBG_TIME, "[avsd_time] @ decode updte consume av=%lld ", p_dec->decode_update_time / (1000 * p_dec->dec_no)); - AVSD_DBG(AVSD_DBG_TIME, "[avsd_time] @ frame post consume av=%lld ", p_dec->frame_post_time / (1000 * p_dec->dec_no)); - } - if (task->dec.valid) { - MppBuffer mbuffer = NULL; - mpp_buf_slot_get_prop(p_dec->frame_slots, task->dec.output, SLOT_BUFFER, &mbuffer); - if (mbuffer && (task->dec.output >= 0)) { - p_s = mpp_time(); - mpp_buf_slot_clr_flag(p_dec->frame_slots, task->dec.output, SLOT_HAL_OUTPUT); - - nv12_copy_buffer((RK_U8 *)mpp_buffer_get_ptr(mbuffer), p_dec->outframe); - - mpp_buf_slot_set_flag(p_dec->frame_slots, task->dec.output, SLOT_QUEUE_USE); - mpp_buf_slot_enqueue(p_dec->frame_slots, task->dec.output, QUEUE_DISPLAY); - - p_e = mpp_time(); - diff = (p_e - p_s) / 1000; - p_dec->nvcopy_time += diff; - AVSD_DBG(AVSD_DBG_TIME, "[avsd_time] copy one frame consume time=%lld, av=%lld ", diff, p_dec->nvcopy_time / p_dec->dec_no); - } - } - task->dec.valid = 0; - (void)task; - (void)decoder; - (void)info; - AVSD_PARSE_TRACE("Out."); - - return ret = MPP_OK; -} -#else -MPP_RET avsd_deinit(void *decoder) -{ - (void)decoder; - return MPP_OK; -} -MPP_RET avsd_init(void *decoder, ParserCfg *init) -{ - (void)decoder; - (void)init; - return MPP_OK; -} -MPP_RET avsd_prepare(void *decoder, MppPacket pkt, HalDecTask *task) -{ - (void)decoder; - (void)pkt; - (void)task; - return MPP_OK; - -} -MPP_RET avsd_parse(void *decoder, HalDecTask *task) -{ - (void)decoder; - (void)task; - return MPP_OK; -} -MPP_RET avsd_reset(void *decoder) -{ - (void)decoder; - return MPP_OK; -} -MPP_RET avsd_flush(void *decoder) -{ - (void)decoder; - return MPP_OK; -} -MPP_RET avsd_control(void *decoder, RK_S32 cmd_type, void *param) -{ - (void)decoder; - (void)cmd_type; - (void)param; - return MPP_OK; -} -MPP_RET avsd_callback(void *decoder, void *info) -{ - (void)decoder; - (void)info; - return MPP_OK; -} -#endif -/*! -*********************************************************************** -* \brief -* api struct interface -*********************************************************************** -*/ -const ParserApi api_avsd_parser = { - "avsd_parse", - MPP_VIDEO_CodingAVS, - sizeof(Avs_DecCtx_t), - 0, - avsd_init, - avsd_deinit, - avsd_prepare, - avsd_parse, - avsd_reset, - avsd_flush, - avsd_control, - avsd_callback, -}; - +/* +* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#define MODULE_TAG "avsd_api" + +#include +#include +#include + +#include "mpp_time.h" +#include "mpp_mem.h" +#include "mpp_log.h" +#include "mpp_env.h" +#include "mpp_packet.h" +#include "mpp_packet_impl.h" +#include "mpp_buffer_impl.h" + +#include "avsd_api.h" +#include "avsd_parse.h" +#include "avsd_impl.h" + +RK_U32 avsd_parse_debug = 0; + +#ifdef RKV_AVSD_DEBUG +static MPP_RET free_input_ctx(AvsdInputCtx_t *p_inp) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + + INP_CHECK(ret, !p_inp); + AVSD_PARSE_TRACE("In."); + + MPP_FCLOSE(p_inp->fp_log); +__RETURN: + AVSD_PARSE_TRACE("Out."); + return ret = MPP_OK; +} +static MPP_RET init_input_ctx(AvsdInputCtx_t *p_inp, ParserCfg *init) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + + INP_CHECK(ret, !p_inp && !init); + AVSD_PARSE_TRACE("In."); + + p_inp->init = *init; +#if defined(_WIN32) + if ((p_inp->fp_log = fopen("F:/avs_log/avs_runlog.txt", "wb")) == 0) { + mpp_log("Wanning, open file, %s(%d)", __FUNCTION__, __LINE__); + } +#endif +__RETURN: + AVSD_PARSE_TRACE("Out."); + return ret = MPP_OK; +} + + +static MPP_RET free_cur_ctx(AvsdCurCtx_t *p_cur) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + + INP_CHECK(ret, !p_cur); + AVSD_PARSE_TRACE("In."); + + +__RETURN: + AVSD_PARSE_TRACE("Out."); + + return ret = MPP_OK; +} +static MPP_RET init_cur_ctx(AvsdCurCtx_t *p_cur) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + AvsdCurStream_t *p_strm = NULL; + + INP_CHECK(ret, !p_cur); + AVSD_PARSE_TRACE("In."); + + p_strm = &p_cur->m_strm; + p_strm->prefixdata = 0xffffffff; + +__RETURN: + AVSD_PARSE_TRACE("Out."); + return ret = MPP_OK; + +} + + +static MPP_RET free_vid_ctx(AvsdVideoCtx_t *p_vid) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + + INP_CHECK(ret, !p_vid); + AVSD_PARSE_TRACE("In."); + + +__RETURN: + AVSD_PARSE_TRACE("Out."); + + return ret = MPP_OK; +} +static MPP_RET init_vid_ctx(AvsdVideoCtx_t *p_vid) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + + INP_CHECK(ret, !p_vid); + AVSD_PARSE_TRACE("In."); + +__RETURN: + AVSD_PARSE_TRACE("Out."); + return ret = MPP_OK; +} + +static MPP_RET free_bitstream(AvsdBitstream_t *p) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + + INP_CHECK(ret, !p); + AVSD_PARSE_TRACE("In."); + + MPP_FREE(p->pbuf); + +__RETURN: + AVSD_PARSE_TRACE("Out."); + + return ret = MPP_OK; +} + +static MPP_RET init_bitstream(AvsdBitstream_t *p) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + + INP_CHECK(ret, !p); + AVSD_PARSE_TRACE("In."); + p->size = MAX_BITSTREAM_SIZE; + p->pbuf = mpp_malloc(RK_U8, MAX_BITSTREAM_SIZE); + MEM_CHECK(ret, p->pbuf); + +__RETURN: + AVSD_PARSE_TRACE("Out."); + return ret = MPP_OK; +__FAILED: + return ret; +} + + +static MPP_RET free_dec_ctx(Avs_DecCtx_t *p_dec) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + + INP_CHECK(ret, NULL == p_dec); + AVSD_PARSE_TRACE("In."); + lib_avsd_destory(p_dec->libdec); + mpp_packet_deinit(&p_dec->task_pkt); + free_bitstream(p_dec->bitstream); + MPP_FREE(p_dec->mem); + +__RETURN: + AVSD_PARSE_TRACE("Out."); + + return ret = MPP_OK; +} + + + +static MPP_RET init_dec_ctx(Avs_DecCtx_t *p_dec) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + + INP_CHECK(ret, !p_dec); + AVSD_PARSE_TRACE("In."); + + mpp_buf_slot_setup(p_dec->frame_slots, 4); + p_dec->mem = mpp_calloc(AvsdMemory_t, 1); + MEM_CHECK(ret, p_dec->mem); + p_dec->bitstream = &p_dec->mem->bitstream; + FUN_CHECK(ret = init_bitstream(p_dec->bitstream)); + //!< malloc mpp packet + mpp_packet_init(&p_dec->task_pkt, p_dec->bitstream->pbuf, p_dec->bitstream->size); + mpp_packet_set_length(p_dec->task_pkt, 0); + MEM_CHECK(ret, p_dec->task_pkt); + //!< malloc libavsd.so + p_dec->libdec = lib_avsd_create(); + MEM_CHECK(ret, p_dec->libdec); + FUN_CHECK(ret = lib_avsd_init(p_dec->libdec)); + p_dec->outframe = &p_dec->mem->outframe; + +__RETURN: + AVSD_PARSE_TRACE("Out."); + + return ret = MPP_OK; +__FAILED: + free_dec_ctx(p_dec); + + return ret; +} +/*! +*********************************************************************** +* \brief +* free all buffer +*********************************************************************** +*/ +MPP_RET avsd_deinit(void *decoder) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + Avs_DecCtx_t *p_dec = (Avs_DecCtx_t *)decoder; + + INP_CHECK(ret, !decoder); + AVSD_PARSE_TRACE("In."); + avsd_flush(decoder); + free_input_ctx(p_dec->p_inp); + MPP_FREE(p_dec->p_inp); + free_cur_ctx(p_dec->p_cur); + MPP_FREE(p_dec->p_cur); + free_vid_ctx(p_dec->p_vid); + MPP_FREE(p_dec->p_vid); + free_dec_ctx(p_dec); +__RETURN: + (void)decoder; + AVSD_PARSE_TRACE("Out."); + return ret = MPP_OK; +} + +/*! +*********************************************************************** +* \brief +* alloc all buffer +*********************************************************************** +*/ + +MPP_RET avsd_init(void *decoder, ParserCfg *init) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + Avs_DecCtx_t *p_dec = (Avs_DecCtx_t *)decoder; + + AVSD_PARSE_TRACE("In."); + INP_CHECK(ret, !p_dec); + memset(p_dec, 0, sizeof(Avs_DecCtx_t)); + // init logctx + mpp_env_get_u32("avsd_debug", &avsd_parse_debug, 0); + //!< get init frame_slots and packet_slots + p_dec->frame_slots = init->frame_slots; + p_dec->packet_slots = init->packet_slots; + //!< malloc decoder buffer + p_dec->p_inp = mpp_calloc(AvsdInputCtx_t, 1); + p_dec->p_cur = mpp_calloc(AvsdCurCtx_t, 1); + p_dec->p_vid = mpp_calloc(AvsdVideoCtx_t, 1); + MEM_CHECK(ret, p_dec->p_inp && p_dec->p_cur && p_dec->p_vid); + + p_dec->p_inp->p_dec = p_dec; + p_dec->p_inp->p_cur = p_dec->p_cur; + p_dec->p_inp->p_vid = p_dec->p_vid; + FUN_CHECK(ret = init_input_ctx(p_dec->p_inp, init)); + p_dec->p_cur->p_dec = p_dec; + p_dec->p_cur->p_inp = p_dec->p_inp; + p_dec->p_cur->p_vid = p_dec->p_vid; + FUN_CHECK(ret = init_cur_ctx(p_dec->p_cur)); + p_dec->p_vid->p_dec = p_dec; + p_dec->p_vid->p_inp = p_dec->p_inp; + p_dec->p_vid->p_cur = p_dec->p_cur; + FUN_CHECK(ret = init_vid_ctx(p_dec->p_vid)); + FUN_CHECK(ret = init_dec_ctx(p_dec)); +__RETURN: + (void)decoder; + (void)init; + AVSD_PARSE_TRACE("Out."); + return ret = MPP_OK; +__FAILED: + avsd_deinit(decoder); + + return ret; +} +/*! +*********************************************************************** +* \brief +* reset +*********************************************************************** +*/ +MPP_RET avsd_reset(void *decoder) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + Avs_DecCtx_t *p_dec = (Avs_DecCtx_t *)decoder; + + AVSD_PARSE_TRACE("In."); + + AVSD_PARSE_TRACE("Out."); + (void)p_dec; + (void)decoder; + return ret = MPP_OK; +} + +/*! +*********************************************************************** +* \brief +* flush +*********************************************************************** +*/ +MPP_RET avsd_flush(void *decoder) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + Avs_DecCtx_t *p_dec = (Avs_DecCtx_t *)decoder; + AVSD_PARSE_TRACE("In."); + + + AVSD_PARSE_TRACE("Out."); + (void)p_dec; + (void)decoder; + return ret = MPP_OK; +} + +/*! +*********************************************************************** +* \brief +* control/perform +*********************************************************************** +*/ +MPP_RET avsd_control(void *decoder, RK_S32 cmd_type, void *param) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + + AVSD_PARSE_TRACE("In."); + + + (void)decoder; + (void)cmd_type; + (void)param; + AVSD_PARSE_TRACE("Out."); + return ret = MPP_OK; +} + + +/*! +*********************************************************************** +* \brief +* prepare +*********************************************************************** +*/ +MPP_RET avsd_prepare(void *decoder, MppPacket pkt, HalDecTask *task) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + AvsdInputCtx_t *p_inp = NULL; + Avs_DecCtx_t *p_dec = (Avs_DecCtx_t *)decoder; + + AVSD_PARSE_TRACE("In."); + INP_CHECK(ret, !decoder && !pkt && !task); + p_inp = p_dec->p_inp; + if (p_inp->has_get_eos) { + mpp_packet_set_length(pkt, 0); + goto __RETURN; + } + p_inp->in_pkt = pkt; + p_inp->in_task = task; + + if (mpp_packet_get_eos(pkt)) { + if (mpp_packet_get_length(pkt) < 4) { + avsd_flush(decoder); + } + p_inp->has_get_eos = 1; + } + AVSD_DBG(AVSD_DBG_INPUT, "[pkt_in_timeUs] in_pts=%lld, pkt_eos=%d, len=%d, pkt_no=%d", + mpp_packet_get_pts(pkt), mpp_packet_get_eos(pkt), mpp_packet_get_length(pkt), p_inp->pkt_no++); + + if (mpp_packet_get_length(pkt) > MAX_STREM_IN_SIZE) { + AVSD_DBG(AVSD_DBG_ERROR, "[pkt_in_timeUs] input error, stream too large"); + mpp_packet_set_length(pkt, 0); + ret = MPP_NOK; + goto __FAILED; + } + p_inp->in_pts = mpp_packet_get_pts(pkt); + p_inp->in_dts = mpp_packet_get_dts(pkt); + + memset(task, 0, sizeof(HalDecTask)); + do { + (ret = avsd_parse_prepare(p_inp, p_dec->p_cur)); + + } while (mpp_packet_get_length(pkt) && !task->valid); + + if (task->valid) { + mpp_packet_set_pos(task->input_packet, p_dec->bitstream->pbuf); + mpp_packet_set_length(task->input_packet, 16); + mpp_packet_set_size(task->input_packet, 32); + } + +__RETURN: + (void)decoder; + (void)pkt; + (void)task; + AVSD_PARSE_TRACE("Out."); + return ret = MPP_OK; +__FAILED: + return ret; +} + + +/*! +*********************************************************************** +* \brief +* parser +*********************************************************************** +*/ +MPP_RET avsd_parse(void *decoder, HalDecTask *task) +{ + RK_S64 p_s = 0, p_e = 0, diff = 0; + MPP_RET ret = MPP_ERR_UNKNOW; + Avs_DecCtx_t *p_dec = (Avs_DecCtx_t *)decoder; + AVSD_PARSE_TRACE("In."); + + p_s = mpp_time(); + task->valid = 0; + memset(task->refer, -1, sizeof(task->refer)); + + lib_avsd_decode_one_frame(p_dec->libdec, (RK_S32 *)&task->valid); + mpp_log("[out_frame] task->valid=%d", task->valid); + if (task->flags.eos) { + avsd_flush(decoder); + goto __RETURN; + } + if (task->valid) { + RK_S32 out_slot_idx = -1; + mpp_buf_slot_get_unused(p_dec->frame_slots, &out_slot_idx); + if (out_slot_idx >= 0) { + MppFrame mframe = NULL; + AvsdOutframe_t *f = p_dec->outframe; + lib_avsd_get_outframe(p_dec->libdec, &f->nWidth, &f->nHeight, f->data, f->stride, f->corp); + mpp_log("[out_frame] width=%d, height=%d, stride[0]=%d, stride[1]=%d, stride[2]=%d", + f->nWidth, f->nHeight, f->stride[0], f->stride[1], f->stride[2]);; + mpp_frame_init(&mframe); + mpp_frame_set_fmt(mframe, MPP_FMT_YUV420SP); + mpp_frame_set_hor_stride(mframe, f->nWidth); // before crop + mpp_frame_set_ver_stride(mframe, f->nHeight); + mpp_frame_set_width(mframe, f->nWidth); // after crop + mpp_frame_set_height(mframe, f->nHeight); + //mpp_frame_set_pts(mframe, p_Vid->p_Cur->last_pts); + //mpp_frame_set_dts(mframe, p_Vid->p_Cur->last_dts); + mpp_buf_slot_set_prop(p_dec->frame_slots, out_slot_idx, SLOT_FRAME, mframe); + mpp_frame_deinit(&mframe); + mpp_buf_slot_get_prop(p_dec->frame_slots, out_slot_idx, SLOT_FRAME_PTR, &mframe); + f->hor_stride = mpp_frame_get_hor_stride(mframe); + f->ver_stride = mpp_frame_get_ver_stride(mframe); + out_slot_idx = task->output; + //mpp_buf_slot_set_flag(p_dec->frame_slots, task->output, SLOT_HAL_OUTPUT); + } + p_dec->parse_no++; + p_e = mpp_time(); + diff = (p_e - p_s) / 1000; + p_dec->parse_time += diff; + AVSD_DBG(AVSD_DBG_TIME, "[avsd_time] parser stream consume time %lld, av=%lld ", diff, p_dec->parse_time / p_dec->parse_no); + } +__RETURN: + (void)decoder; + (void)task; + AVSD_PARSE_TRACE("Out."); + + return ret = MPP_OK; +} +/*! +*********************************************************************** +* \brief +* callback +*********************************************************************** +*/ + +MPP_RET nv12_copy_buffer(RK_U8 *des, AvsdOutframe_t *f) +{ + RK_S32 i = 0, j = 0; + RK_U8 *ptr = NULL; + + //!< copy Y + mpp_log("[nv12_copy_buffer] width=%d, height=%d, hor_stride=%d, ver_stride=%d \n", f->nWidth, f->nHeight, f->hor_stride, f->ver_stride); + ptr = des; + for (i = 0; i < f->nHeight; i++) { + memcpy(ptr, f->data[0] + f->stride[0] * i, f->hor_stride); + ptr += f->hor_stride; + } +#if 0 + //!< copy U + ptr = des + f->nHeight * f->nWidth; + for (i = 0; i < f->nHeight / 2; i++) { + memcpy(ptr, f->data[1] + f->stride[1] * i, f->nWidth / 2); + ptr += f->nWidth / 2; + } + //!< copy V + ptr = des + f->nHeight * f->nWidth * 5 / 4; + for (i = 0; i < f->nHeight / 2; i++) { + memcpy(ptr, f->data[2] + f->stride[2] * i, f->nWidth / 2); + ptr += f->nWidth / 2; + } +#else + //!< copy U V + ptr = des + f->hor_stride * f->ver_stride; + for (i = 0; i < f->nHeight / 2; i++) { + for (j = 0; j < f->nWidth / 2; j++) { + ptr[2 * j + 0] = f->data[1][f->stride[1] * i + j]; + ptr[2 * j + 1] = f->data[2][f->stride[2] * i + j]; + } + ptr += f->hor_stride; + } +#endif + + return MPP_OK; +} + +MPP_RET avsd_callback(void *decoder, void *info) +{ + RK_S64 p_s = 0, p_e = 0, diff = 0; + MPP_RET ret = MPP_ERR_UNKNOW; + HalTaskInfo *task = (HalTaskInfo *)info; + Avs_DecCtx_t *p_dec = (Avs_DecCtx_t *)decoder; + AVSD_PARSE_TRACE("In."); + AVSD_PARSE_TRACE("[avsd_parse_decode] frame_dec_no=%d", p_dec->dec_no); + p_dec->dec_no++; + if (task->dec.valid) { + p_s = mpp_time(); + //lib_decode_one_frame(p_dec->libdec, &task->dec); + p_e = mpp_time(); + diff = (p_e - p_s) / 1000; + p_dec->decode_frame_time += diff; + AVSD_DBG(AVSD_DBG_TIME, "[avsd_time] decode one frame total time=%lld, av=%lld ", diff, p_dec->decode_frame_time / p_dec->dec_no); + + AVSD_DBG(AVSD_DBG_TIME, "[avsd_time] @ decode init av=%lld ", p_dec->decode_init_time / (1000 * p_dec->dec_no)); + AVSD_DBG(AVSD_DBG_TIME, "[avsd_time] @ decode data av=%lld ", p_dec->decode_data_time / (1000 * p_dec->dec_no)); + AVSD_DBG(AVSD_DBG_TIME, "[avsd_time] # read slice header consume av=%lld ", p_dec->read_slice_header_time / (1000 * p_dec->dec_no)); + AVSD_DBG(AVSD_DBG_TIME, "[avsd_time] # init arodeco slice consume av=%lld ", p_dec->init_arideco_slice_time / (1000 * p_dec->dec_no)); + AVSD_DBG(AVSD_DBG_TIME, "[avsd_time] # start marco blocks consume av=%lld ", p_dec->start_marcoblock_time / (1000 * p_dec->dec_no)); + AVSD_DBG(AVSD_DBG_TIME, "[avsd_time] # read marco blocks consume av=%lld ", p_dec->read_marcoblock_time / (1000 * p_dec->dec_no)); + AVSD_DBG(AVSD_DBG_TIME, "[avsd_time] # decode marco blocks consume av=%lld ", p_dec->decode_marcoblock_time / (1000 * p_dec->dec_no)); + AVSD_DBG(AVSD_DBG_TIME, "[avsd_time] $ get marco blocks consume av=%lld ", p_dec->get_block_time / (1000 * p_dec->dec_no)); + AVSD_DBG(AVSD_DBG_TIME, "[avsd_time] $ intra pred blocks consume av=%lld ", p_dec->intra_pred_block_time / (1000 * p_dec->dec_no)); + AVSD_DBG(AVSD_DBG_TIME, "[avsd_time] $ inter pred blocks consume av=%lld ", p_dec->inter_pred_block_time / (1000 * p_dec->dec_no)); + AVSD_DBG(AVSD_DBG_TIME, "[avsd_time] $ idc_dequant blocks consume av=%lld ", p_dec->idc_dequaut_time / (1000 * p_dec->dec_no)); + AVSD_DBG(AVSD_DBG_TIME, "[avsd_time] @ deblocking consume av=%lld ", p_dec->deblock_time / (1000 * p_dec->dec_no)); + AVSD_DBG(AVSD_DBG_TIME, "[avsd_time] @ decode updte consume av=%lld ", p_dec->decode_update_time / (1000 * p_dec->dec_no)); + AVSD_DBG(AVSD_DBG_TIME, "[avsd_time] @ frame post consume av=%lld ", p_dec->frame_post_time / (1000 * p_dec->dec_no)); + } + if (task->dec.valid) { + MppBuffer mbuffer = NULL; + mpp_buf_slot_get_prop(p_dec->frame_slots, task->dec.output, SLOT_BUFFER, &mbuffer); + if (mbuffer && (task->dec.output >= 0)) { + p_s = mpp_time(); + mpp_buf_slot_clr_flag(p_dec->frame_slots, task->dec.output, SLOT_HAL_OUTPUT); + + nv12_copy_buffer((RK_U8 *)mpp_buffer_get_ptr(mbuffer), p_dec->outframe); + + mpp_buf_slot_set_flag(p_dec->frame_slots, task->dec.output, SLOT_QUEUE_USE); + mpp_buf_slot_enqueue(p_dec->frame_slots, task->dec.output, QUEUE_DISPLAY); + + p_e = mpp_time(); + diff = (p_e - p_s) / 1000; + p_dec->nvcopy_time += diff; + AVSD_DBG(AVSD_DBG_TIME, "[avsd_time] copy one frame consume time=%lld, av=%lld ", diff, p_dec->nvcopy_time / p_dec->dec_no); + } + } + task->dec.valid = 0; + (void)task; + (void)decoder; + (void)info; + AVSD_PARSE_TRACE("Out."); + + return ret = MPP_OK; +} +#else +MPP_RET avsd_deinit(void *decoder) +{ + (void)decoder; + return MPP_OK; +} +MPP_RET avsd_init(void *decoder, ParserCfg *init) +{ + (void)decoder; + (void)init; + return MPP_OK; +} +MPP_RET avsd_prepare(void *decoder, MppPacket pkt, HalDecTask *task) +{ + (void)decoder; + (void)pkt; + (void)task; + return MPP_OK; + +} +MPP_RET avsd_parse(void *decoder, HalDecTask *task) +{ + (void)decoder; + (void)task; + return MPP_OK; +} +MPP_RET avsd_reset(void *decoder) +{ + (void)decoder; + return MPP_OK; +} +MPP_RET avsd_flush(void *decoder) +{ + (void)decoder; + return MPP_OK; +} +MPP_RET avsd_control(void *decoder, RK_S32 cmd_type, void *param) +{ + (void)decoder; + (void)cmd_type; + (void)param; + return MPP_OK; +} +MPP_RET avsd_callback(void *decoder, void *info) +{ + (void)decoder; + (void)info; + return MPP_OK; +} +#endif +/*! +*********************************************************************** +* \brief +* api struct interface +*********************************************************************** +*/ +const ParserApi api_avsd_parser = { + "avsd_parse", + MPP_VIDEO_CodingAVS, + sizeof(Avs_DecCtx_t), + 0, + avsd_init, + avsd_deinit, + avsd_prepare, + avsd_parse, + avsd_reset, + avsd_flush, + avsd_control, + avsd_callback, +}; + diff --git a/mpp/codec/dec/avs/avsd_impl.h b/mpp/codec/dec/avs/avsd_impl.h index 91a568b1..a4b313fd 100644 --- a/mpp/codec/dec/avs/avsd_impl.h +++ b/mpp/codec/dec/avs/avsd_impl.h @@ -1,48 +1,48 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __AVSD_IMPL_H__ -#define __AVSD_IMPL_H__ - - -#include "rk_type.h" - -#include "mpp_err.h" -#include "mpp_packet.h" - -#include "hal_task.h" - - - -#ifdef __cplusplus -extern "C" { -#endif - -void avsd_test_main(int argc, char **argv); - -void *lib_avsd_create(); -int lib_avsd_init(void *decoder); -int lib_avsd_destory(void *decoder); -int lib_avsd_prepare(void *decoder, unsigned char *buf, int len); -int lib_avsd_decode_one_frame(void *decoder, int *got_frame); -int lib_avsd_get_outframe(void *decoder, int *w, int *h, unsigned char *data[], int *stride, int *crop); - - -#ifdef __cplusplus -} -#endif - -#endif /*__AVSD_IMPL_H__*/ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __AVSD_IMPL_H__ +#define __AVSD_IMPL_H__ + + +#include "rk_type.h" + +#include "mpp_err.h" +#include "mpp_packet.h" + +#include "hal_task.h" + + + +#ifdef __cplusplus +extern "C" { +#endif + +void avsd_test_main(int argc, char **argv); + +void *lib_avsd_create(); +int lib_avsd_init(void *decoder); +int lib_avsd_destory(void *decoder); +int lib_avsd_prepare(void *decoder, unsigned char *buf, int len); +int lib_avsd_decode_one_frame(void *decoder, int *got_frame); +int lib_avsd_get_outframe(void *decoder, int *w, int *h, unsigned char *data[], int *stride, int *crop); + + +#ifdef __cplusplus +} +#endif + +#endif /*__AVSD_IMPL_H__*/ diff --git a/mpp/codec/dec/avs/avsd_parse.c b/mpp/codec/dec/avs/avsd_parse.c index c399ea13..86f01fa6 100644 --- a/mpp/codec/dec/avs/avsd_parse.c +++ b/mpp/codec/dec/avs/avsd_parse.c @@ -1,211 +1,211 @@ -/* -* -* Copyright 2015 Rockchip Electronics Co. LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#define MODULE_TAG "avsd_parse" - -#include -#include - -#include "vpu_api.h" -#include "mpp_mem.h" -#include "mpp_log.h" -#include "mpp_packet.h" -#include "mpp_packet_impl.h" -#include "hal_task.h" - -#include "avsd_api.h" -#include "avsd_parse.h" -#include "avsd_impl.h" - -#if 0 -#define START_PREFIX_3BYTE (3) - -static void reset_curstream(AvsdCurStream_t *p_strm) -{ - p_strm->p_start = NULL; - p_strm->len = 0; - p_strm->got_frame_flag = 0; - p_strm->got_nalu_flag = 0; -} - -static MPP_RET add_nalu_header(AvsdCurCtx_t *p_cur) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - - RK_U32 add_size = sizeof(AvsdNalu_t); - AvsdBitstream_t *p_bitstream = p_cur->p_dec->bitstream; - - if ((p_bitstream->offset + add_size) > p_bitstream->size) { - AVSD_DBG(AVSD_DBG_ERROR, "error, head_offset is larger than %d", p_bitstream->size); - goto __FAILED; - } - p_cur->cur_nalu = (AvsdNalu_t *)&p_bitstream->pbuf[p_bitstream->offset]; - p_cur->cur_nalu->eof = 1; - p_cur->cur_nalu->header = 0; - p_cur->cur_nalu->pdata = NULL; - p_cur->cur_nalu->length = 0; - p_cur->cur_nalu->start_pos = 0; - p_bitstream->offset += add_size; - - (void)p_cur; - return ret = MPP_OK; -__FAILED: - return ret; -} - - - -static MPP_RET store_cur_nalu(AvsdCurCtx_t *p_cur, AvsdCurStream_t *p_strm) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - - AvsdNalu_t *p_nalu = p_cur->cur_nalu; - AvsdBitstream_t *p_bitstream = p_cur->p_dec->bitstream; - - //!< fill bitstream buffer - RK_U32 add_size = p_strm->len; - - if ((p_bitstream->offset + add_size) > p_bitstream->size) { - AVSD_DBG(AVSD_DBG_ERROR, "error, head_offset is larger than %d", p_bitstream->size); - goto __FAILED; - } - p_nalu->length += p_strm->len; - p_nalu->pdata = &p_bitstream->pbuf[p_bitstream->offset]; - memcpy(p_nalu->pdata, p_strm->p_start, p_strm->len); - p_bitstream->offset += add_size; - - return ret = MPP_OK; -__FAILED: - return ret; -} - -/*! -*********************************************************************** -* \brief -* prepare function for parser -*********************************************************************** -*/ - - -MPP_RET avsd_parse_prepare(AvsdInputCtx_t *p_inp, AvsdCurCtx_t *p_cur) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - RK_U8 *p_curdata = NULL; - - HalDecTask *in_task = p_inp->in_task; - MppPacket *in_pkt = p_inp->in_pkt; - MppPacketImpl *pkt_impl = (MppPacketImpl *)p_inp->in_pkt; - AvsdCurStream_t *p_strm = &p_cur->m_strm; - AvsdBitstream_t *p_bitstream = p_cur->p_dec->bitstream; - - AVSD_PARSE_TRACE("In."); - //!< check input - if (!mpp_packet_get_length(in_pkt)) { - AVSD_DBG(AVSD_DBG_WARNNING, "input have no stream."); - goto __RETURN; - } - - in_task->valid = 0; - in_task->flags.eos = 0; - - //!< check eos - if (mpp_packet_get_eos(in_pkt)) { - FUN_CHECK(ret = add_nalu_header(p_cur)); - in_task->valid = 1; - in_task->flags.eos = 1; - AVSD_DBG(AVSD_DBG_LOG, "end of stream."); - goto __RETURN; - } - - p_strm->p_start = p_curdata = (RK_U8 *)mpp_packet_get_pos(p_inp->in_pkt); - while (pkt_impl->length > 0) { - //!< found next picture start code - if (((*p_curdata) == I_PICTURE_START_CODE) - || ((*p_curdata) == PB_PICTURE_START_CODE)) { - if (p_strm->got_frame_flag) { - FUN_CHECK(ret = add_nalu_header(p_cur)); - in_task->valid = 1; - pkt_impl->length += START_PREFIX_3BYTE; - p_bitstream->len = p_bitstream->offset; - //!< reset value - p_bitstream->offset = 0; - reset_curstream(p_strm); - break; - } - p_strm->got_frame_flag = 1; - } - //!< found next nalu start code - p_strm->prefixdata = (p_strm->prefixdata << 8) | (*p_curdata); - if ((p_strm->prefixdata & 0xFFFFFF00) == 0x00000100) { - if (p_strm->got_nalu_flag) { - p_strm->len = (RK_U32)(p_curdata - p_strm->p_start) - START_PREFIX_3BYTE; - FUN_CHECK(ret = store_cur_nalu(p_cur, p_strm)); - FPRINT(p_cur->p_inp->fp_log, "g_nalu_no=%d, length=%d, header=0x%02x \n", g_nalu_no++, p_cur->cur_nalu->length, p_cur->cur_nalu->header); - - } - FUN_CHECK(ret = add_nalu_header(p_cur)); - p_cur->cur_nalu->header = (*p_curdata); - p_cur->cur_nalu->eof = 0; - p_cur->cur_nalu->start_pos = START_PREFIX_3BYTE; - - p_strm->p_start = p_curdata - START_PREFIX_3BYTE; - p_strm->got_nalu_flag = 1; - } - p_curdata++; - pkt_impl->length--; - } - if (!pkt_impl->length) { - p_strm->len = (RK_U32)(p_curdata - p_strm->p_start) - 1; - FUN_CHECK(ret = store_cur_nalu(p_cur, p_strm)); - } -__RETURN: - AVSD_PARSE_TRACE("Out."); - - return ret = MPP_OK; -__FAILED: - return ret; -} -#else - -MPP_RET avsd_parse_prepare(AvsdInputCtx_t *p_inp, AvsdCurCtx_t *p_cur) -{ - RK_S32 ret_val = 0; - MPP_RET ret = MPP_ERR_UNKNOW; - - Avs_DecCtx_t *p_dec = p_inp->p_dec; - HalDecTask *in_task = p_inp->in_task; - - AVSD_PARSE_TRACE("In."); - - in_task->input_packet = p_dec->task_pkt; - ret_val = lib_avsd_prepare(p_dec->libdec, - (RK_U8 *)mpp_packet_get_pos(p_inp->in_pkt), (RK_S32)mpp_packet_get_length(p_inp->in_pkt)); - if (ret_val < 0) { - goto __FAILED; - } - in_task->valid = 1; - mpp_packet_set_length(p_inp->in_pkt, 0); - - AVSD_PARSE_TRACE("Out."); - (void)p_cur; - return ret = MPP_OK; -__FAILED: - return ret; -} -#endif - - +/* +* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#define MODULE_TAG "avsd_parse" + +#include +#include + +#include "vpu_api.h" +#include "mpp_mem.h" +#include "mpp_log.h" +#include "mpp_packet.h" +#include "mpp_packet_impl.h" +#include "hal_task.h" + +#include "avsd_api.h" +#include "avsd_parse.h" +#include "avsd_impl.h" + +#if 0 +#define START_PREFIX_3BYTE (3) + +static void reset_curstream(AvsdCurStream_t *p_strm) +{ + p_strm->p_start = NULL; + p_strm->len = 0; + p_strm->got_frame_flag = 0; + p_strm->got_nalu_flag = 0; +} + +static MPP_RET add_nalu_header(AvsdCurCtx_t *p_cur) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + + RK_U32 add_size = sizeof(AvsdNalu_t); + AvsdBitstream_t *p_bitstream = p_cur->p_dec->bitstream; + + if ((p_bitstream->offset + add_size) > p_bitstream->size) { + AVSD_DBG(AVSD_DBG_ERROR, "error, head_offset is larger than %d", p_bitstream->size); + goto __FAILED; + } + p_cur->cur_nalu = (AvsdNalu_t *)&p_bitstream->pbuf[p_bitstream->offset]; + p_cur->cur_nalu->eof = 1; + p_cur->cur_nalu->header = 0; + p_cur->cur_nalu->pdata = NULL; + p_cur->cur_nalu->length = 0; + p_cur->cur_nalu->start_pos = 0; + p_bitstream->offset += add_size; + + (void)p_cur; + return ret = MPP_OK; +__FAILED: + return ret; +} + + + +static MPP_RET store_cur_nalu(AvsdCurCtx_t *p_cur, AvsdCurStream_t *p_strm) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + + AvsdNalu_t *p_nalu = p_cur->cur_nalu; + AvsdBitstream_t *p_bitstream = p_cur->p_dec->bitstream; + + //!< fill bitstream buffer + RK_U32 add_size = p_strm->len; + + if ((p_bitstream->offset + add_size) > p_bitstream->size) { + AVSD_DBG(AVSD_DBG_ERROR, "error, head_offset is larger than %d", p_bitstream->size); + goto __FAILED; + } + p_nalu->length += p_strm->len; + p_nalu->pdata = &p_bitstream->pbuf[p_bitstream->offset]; + memcpy(p_nalu->pdata, p_strm->p_start, p_strm->len); + p_bitstream->offset += add_size; + + return ret = MPP_OK; +__FAILED: + return ret; +} + +/*! +*********************************************************************** +* \brief +* prepare function for parser +*********************************************************************** +*/ + + +MPP_RET avsd_parse_prepare(AvsdInputCtx_t *p_inp, AvsdCurCtx_t *p_cur) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + RK_U8 *p_curdata = NULL; + + HalDecTask *in_task = p_inp->in_task; + MppPacket *in_pkt = p_inp->in_pkt; + MppPacketImpl *pkt_impl = (MppPacketImpl *)p_inp->in_pkt; + AvsdCurStream_t *p_strm = &p_cur->m_strm; + AvsdBitstream_t *p_bitstream = p_cur->p_dec->bitstream; + + AVSD_PARSE_TRACE("In."); + //!< check input + if (!mpp_packet_get_length(in_pkt)) { + AVSD_DBG(AVSD_DBG_WARNNING, "input have no stream."); + goto __RETURN; + } + + in_task->valid = 0; + in_task->flags.eos = 0; + + //!< check eos + if (mpp_packet_get_eos(in_pkt)) { + FUN_CHECK(ret = add_nalu_header(p_cur)); + in_task->valid = 1; + in_task->flags.eos = 1; + AVSD_DBG(AVSD_DBG_LOG, "end of stream."); + goto __RETURN; + } + + p_strm->p_start = p_curdata = (RK_U8 *)mpp_packet_get_pos(p_inp->in_pkt); + while (pkt_impl->length > 0) { + //!< found next picture start code + if (((*p_curdata) == I_PICTURE_START_CODE) + || ((*p_curdata) == PB_PICTURE_START_CODE)) { + if (p_strm->got_frame_flag) { + FUN_CHECK(ret = add_nalu_header(p_cur)); + in_task->valid = 1; + pkt_impl->length += START_PREFIX_3BYTE; + p_bitstream->len = p_bitstream->offset; + //!< reset value + p_bitstream->offset = 0; + reset_curstream(p_strm); + break; + } + p_strm->got_frame_flag = 1; + } + //!< found next nalu start code + p_strm->prefixdata = (p_strm->prefixdata << 8) | (*p_curdata); + if ((p_strm->prefixdata & 0xFFFFFF00) == 0x00000100) { + if (p_strm->got_nalu_flag) { + p_strm->len = (RK_U32)(p_curdata - p_strm->p_start) - START_PREFIX_3BYTE; + FUN_CHECK(ret = store_cur_nalu(p_cur, p_strm)); + FPRINT(p_cur->p_inp->fp_log, "g_nalu_no=%d, length=%d, header=0x%02x \n", g_nalu_no++, p_cur->cur_nalu->length, p_cur->cur_nalu->header); + + } + FUN_CHECK(ret = add_nalu_header(p_cur)); + p_cur->cur_nalu->header = (*p_curdata); + p_cur->cur_nalu->eof = 0; + p_cur->cur_nalu->start_pos = START_PREFIX_3BYTE; + + p_strm->p_start = p_curdata - START_PREFIX_3BYTE; + p_strm->got_nalu_flag = 1; + } + p_curdata++; + pkt_impl->length--; + } + if (!pkt_impl->length) { + p_strm->len = (RK_U32)(p_curdata - p_strm->p_start) - 1; + FUN_CHECK(ret = store_cur_nalu(p_cur, p_strm)); + } +__RETURN: + AVSD_PARSE_TRACE("Out."); + + return ret = MPP_OK; +__FAILED: + return ret; +} +#else + +MPP_RET avsd_parse_prepare(AvsdInputCtx_t *p_inp, AvsdCurCtx_t *p_cur) +{ + RK_S32 ret_val = 0; + MPP_RET ret = MPP_ERR_UNKNOW; + + Avs_DecCtx_t *p_dec = p_inp->p_dec; + HalDecTask *in_task = p_inp->in_task; + + AVSD_PARSE_TRACE("In."); + + in_task->input_packet = p_dec->task_pkt; + ret_val = lib_avsd_prepare(p_dec->libdec, + (RK_U8 *)mpp_packet_get_pos(p_inp->in_pkt), (RK_S32)mpp_packet_get_length(p_inp->in_pkt)); + if (ret_val < 0) { + goto __FAILED; + } + in_task->valid = 1; + mpp_packet_set_length(p_inp->in_pkt, 0); + + AVSD_PARSE_TRACE("Out."); + (void)p_cur; + return ret = MPP_OK; +__FAILED: + return ret; +} +#endif + + diff --git a/mpp/codec/dec/avs/avsd_parse.h b/mpp/codec/dec/avs/avsd_parse.h index e02a58c0..d27cd2b1 100644 --- a/mpp/codec/dec/avs/avsd_parse.h +++ b/mpp/codec/dec/avs/avsd_parse.h @@ -1,209 +1,209 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __AVSD_PARSE_H__ -#define __AVSD_PARSE_H__ - - -#include "rk_type.h" -#include "parser_api.h" - -#include "mpp_err.h" -#include "mpp_packet.h" -#include "mpp_buf_slot.h" - -#include "hal_task.h" - -#define MAX_STREM_IN_SIZE (2*1024*1024) -#define MAX_BITSTREAM_SIZE (2*1024*1024) - -//!< NALU type -#define SLICE_START_CODE_MIN 0x00 -#define SLICE_START_CODE_MAX 0xAF - -#define I_PICTURE_START_CODE 0xB3 -#define PB_PICTURE_START_CODE 0xB6 - -#define USER_DATA_START_CODE 0xB2 -#define SEQUENCE_HEADER_CODE 0xB0 -#define EXTENSION_START_CODE 0xB5 - -#define SEQUENCE_END_CODE 0xB1 //!< no in ffmpeg -#define VIDEO_EDIT_CODE 0xB7 //!< no in ffmpeg - - -#define FPRINT(fp, ...) do{ if (fp) { fprintf(fp, ## __VA_ARGS__); fflush(fp);} }while(0) - - -//!< input parameter -typedef struct avsd_input_ctx_t { - FILE *fp_log; - - ParserCfg init; - MppPacket in_pkt; - HalDecTask *in_task; - - RK_S64 in_pts; - RK_S64 in_dts; - - RK_U8 has_get_eos; - RK_U64 pkt_no; - struct avsd_cur_ctx_t *p_cur; - struct avsd_video_ctx_t *p_vid; - struct avs_dec_ctx_t *p_dec; -} AvsdInputCtx_t; - -//!< current stream -typedef struct avsd_cur_strm_t { - RK_U8 *p_start; //!< store read nalu data - RK_U32 len; - - RK_U32 prefixdata; - - RK_U8 got_frame_flag; - RK_U8 got_nalu_flag; -} AvsdCurStream_t; - -typedef struct avsd_nalu_t { - RK_U8 header; - RK_U8 *pdata; - RK_U32 size; - RK_U32 length; - RK_U8 start_pos; - RK_U8 eof; //!< end of frame stream -} AvsdNalu_t; - -//!< current parameters -typedef struct avsd_cur_ctx_t { - struct avsd_cur_strm_t m_strm; - struct avsd_nalu_t *cur_nalu; //!< current nalu - - struct avsd_input_ctx_t *p_inp; - struct avsd_video_ctx_t *p_vid; - struct avs_dec_ctx_t *p_dec; -} AvsdCurCtx_t; - - -//!< decoder parameters -typedef struct avsd_video_ctx_t { - - struct img_par *img; - - struct avsd_input_ctx_t *p_inp; - struct avsd_cur_ctx_t *p_cur; - struct avs_dec_ctx_t *p_dec; -} AvsdVideoCtx_t; - - -typedef struct avsd_bitstream_t { - RK_U8 *pbuf; - RK_U32 size; - RK_U32 len; - RK_U32 offset; //!< start from the offset byte -} AvsdBitstream_t; - - -typedef struct avsd_outframe_t { - RK_S32 nWidth; - RK_S32 nHeight; - RK_U8 *data[4]; // Y U V data - RK_S32 stride[4]; // Y U V stride - RK_S32 corp[2]; // crop_right crop_bottom - RK_S32 hor_stride; - RK_S32 ver_stride; - RK_S32 nFrameType; // 0I 1P 2B - RK_S32 nBitrate; - RK_S32 nFrameCoded; - RK_S32 nTopFieldFirst; - RK_S32 nFrameIndex; -} AvsdOutframe_t; - -typedef struct avsd_memory_t { - - struct avsd_bitstream_t bitstream; - struct avsd_outframe_t outframe; -} AvsdMemory_t; - - - - - -//!< decoder parameters -typedef struct avs_dec_ctx_t { - MppBufSlots frame_slots; - MppBufSlots packet_slots; - - MppPacket task_pkt; - struct avsd_memory_t *mem; //!< resotre slice data to decoder - struct avsd_bitstream_t *bitstream; - - struct avsd_input_ctx_t *p_inp; - struct avsd_cur_ctx_t *p_cur; - struct avsd_video_ctx_t *p_vid; - //!< use in libavs.so - void *libdec; - struct avsd_outframe_t *outframe; - - RK_U32 dec_no; - - RK_U32 prepare_no; - RK_U32 parse_no; - RK_U32 decode_no; - RK_U32 nvcopy_no; - - RK_S64 prepare_time; - RK_S64 parse_time; - - - RK_S64 read_slice_header_time; - RK_S64 init_arideco_slice_time; - - RK_S64 start_marcoblock_time; - RK_S64 read_marcoblock_time; - - RK_S64 get_block_time; - RK_S64 inter_pred_block_time; - RK_S64 intra_pred_block_time; - RK_S64 idc_dequaut_time; - RK_S64 decode_marcoblock_time; - RK_S64 deblock_time; - - RK_S64 decode_init_time; - RK_S64 decode_data_time; - RK_S64 decode_update_time; - RK_S64 frame_post_time; - - RK_S64 decode_frame_time; - - RK_S64 nvcopy_time; - -} Avs_DecCtx_t; - - - -#ifdef __cplusplus -extern "C" { -#endif - -MPP_RET avsd_parse_prepare(AvsdInputCtx_t *p_inp, AvsdCurCtx_t *p_cur); - - - -#ifdef __cplusplus -} -#endif - -#endif /*__AVSD_PARSE_H__*/ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __AVSD_PARSE_H__ +#define __AVSD_PARSE_H__ + + +#include "rk_type.h" +#include "parser_api.h" + +#include "mpp_err.h" +#include "mpp_packet.h" +#include "mpp_buf_slot.h" + +#include "hal_task.h" + +#define MAX_STREM_IN_SIZE (2*1024*1024) +#define MAX_BITSTREAM_SIZE (2*1024*1024) + +//!< NALU type +#define SLICE_START_CODE_MIN 0x00 +#define SLICE_START_CODE_MAX 0xAF + +#define I_PICTURE_START_CODE 0xB3 +#define PB_PICTURE_START_CODE 0xB6 + +#define USER_DATA_START_CODE 0xB2 +#define SEQUENCE_HEADER_CODE 0xB0 +#define EXTENSION_START_CODE 0xB5 + +#define SEQUENCE_END_CODE 0xB1 //!< no in ffmpeg +#define VIDEO_EDIT_CODE 0xB7 //!< no in ffmpeg + + +#define FPRINT(fp, ...) do{ if (fp) { fprintf(fp, ## __VA_ARGS__); fflush(fp);} }while(0) + + +//!< input parameter +typedef struct avsd_input_ctx_t { + FILE *fp_log; + + ParserCfg init; + MppPacket in_pkt; + HalDecTask *in_task; + + RK_S64 in_pts; + RK_S64 in_dts; + + RK_U8 has_get_eos; + RK_U64 pkt_no; + struct avsd_cur_ctx_t *p_cur; + struct avsd_video_ctx_t *p_vid; + struct avs_dec_ctx_t *p_dec; +} AvsdInputCtx_t; + +//!< current stream +typedef struct avsd_cur_strm_t { + RK_U8 *p_start; //!< store read nalu data + RK_U32 len; + + RK_U32 prefixdata; + + RK_U8 got_frame_flag; + RK_U8 got_nalu_flag; +} AvsdCurStream_t; + +typedef struct avsd_nalu_t { + RK_U8 header; + RK_U8 *pdata; + RK_U32 size; + RK_U32 length; + RK_U8 start_pos; + RK_U8 eof; //!< end of frame stream +} AvsdNalu_t; + +//!< current parameters +typedef struct avsd_cur_ctx_t { + struct avsd_cur_strm_t m_strm; + struct avsd_nalu_t *cur_nalu; //!< current nalu + + struct avsd_input_ctx_t *p_inp; + struct avsd_video_ctx_t *p_vid; + struct avs_dec_ctx_t *p_dec; +} AvsdCurCtx_t; + + +//!< decoder parameters +typedef struct avsd_video_ctx_t { + + struct img_par *img; + + struct avsd_input_ctx_t *p_inp; + struct avsd_cur_ctx_t *p_cur; + struct avs_dec_ctx_t *p_dec; +} AvsdVideoCtx_t; + + +typedef struct avsd_bitstream_t { + RK_U8 *pbuf; + RK_U32 size; + RK_U32 len; + RK_U32 offset; //!< start from the offset byte +} AvsdBitstream_t; + + +typedef struct avsd_outframe_t { + RK_S32 nWidth; + RK_S32 nHeight; + RK_U8 *data[4]; // Y U V data + RK_S32 stride[4]; // Y U V stride + RK_S32 corp[2]; // crop_right crop_bottom + RK_S32 hor_stride; + RK_S32 ver_stride; + RK_S32 nFrameType; // 0I 1P 2B + RK_S32 nBitrate; + RK_S32 nFrameCoded; + RK_S32 nTopFieldFirst; + RK_S32 nFrameIndex; +} AvsdOutframe_t; + +typedef struct avsd_memory_t { + + struct avsd_bitstream_t bitstream; + struct avsd_outframe_t outframe; +} AvsdMemory_t; + + + + + +//!< decoder parameters +typedef struct avs_dec_ctx_t { + MppBufSlots frame_slots; + MppBufSlots packet_slots; + + MppPacket task_pkt; + struct avsd_memory_t *mem; //!< resotre slice data to decoder + struct avsd_bitstream_t *bitstream; + + struct avsd_input_ctx_t *p_inp; + struct avsd_cur_ctx_t *p_cur; + struct avsd_video_ctx_t *p_vid; + //!< use in libavs.so + void *libdec; + struct avsd_outframe_t *outframe; + + RK_U32 dec_no; + + RK_U32 prepare_no; + RK_U32 parse_no; + RK_U32 decode_no; + RK_U32 nvcopy_no; + + RK_S64 prepare_time; + RK_S64 parse_time; + + + RK_S64 read_slice_header_time; + RK_S64 init_arideco_slice_time; + + RK_S64 start_marcoblock_time; + RK_S64 read_marcoblock_time; + + RK_S64 get_block_time; + RK_S64 inter_pred_block_time; + RK_S64 intra_pred_block_time; + RK_S64 idc_dequaut_time; + RK_S64 decode_marcoblock_time; + RK_S64 deblock_time; + + RK_S64 decode_init_time; + RK_S64 decode_data_time; + RK_S64 decode_update_time; + RK_S64 frame_post_time; + + RK_S64 decode_frame_time; + + RK_S64 nvcopy_time; + +} Avs_DecCtx_t; + + + +#ifdef __cplusplus +extern "C" { +#endif + +MPP_RET avsd_parse_prepare(AvsdInputCtx_t *p_inp, AvsdCurCtx_t *p_cur); + + + +#ifdef __cplusplus +} +#endif + +#endif /*__AVSD_PARSE_H__*/ diff --git a/mpp/codec/dec/dummy/dummy_dec_api.c b/mpp/codec/dec/dummy/dummy_dec_api.c index 93a1a04c..6b270b50 100644 --- a/mpp/codec/dec/dummy/dummy_dec_api.c +++ b/mpp/codec/dec/dummy/dummy_dec_api.c @@ -1,311 +1,311 @@ -/* -* -* Copyright 2015 Rockchip Electronics Co. LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -#define MODULE_TAG "dummy_dec_api" - -#include - -#include "mpp_log.h" -#include "mpp_mem.h" -#include "mpp_common.h" -#include "mpp_packet.h" - -#include "dummy_dec_api.h" - -#define DUMMY_DEC_FRAME_WIDTH 1280 -#define DUMMY_DEC_FRAME_HEIGHT 720 - -#define DUMMY_DEC_FRAME_NEW_WIDTH 1920 -#define DUMMY_DEC_FRAME_NEW_HEIGHT 1088 - -#define DUMMY_DEC_FRAME_SIZE SZ_1M -#define DUMMY_DEC_FRAME_COUNT 16 -#define DUMMY_DEC_REF_COUNT 2 - -typedef struct DummyDec_t { - MppBufSlots frame_slots; - MppBufSlots packet_slots; - RK_S32 task_count; - void *stream; - size_t stream_size; - MppPacket task_pkt; - - RK_S64 task_pts; - RK_U32 task_eos; - - RK_U32 slots_inited; - RK_U32 frame_count; - RK_S32 prev_index; - RK_S32 slot_index[DUMMY_DEC_REF_COUNT]; -} DummyDec; - -MPP_RET dummy_dec_init(void *dec, ParserCfg *cfg) -{ - DummyDec *p; - RK_S32 i; - void *stream; - size_t stream_size = SZ_512K; - MppPacket task_pkt; - - if (NULL == dec) { - mpp_err_f("found NULL intput dec %p cfg %p\n", dec, cfg); - return MPP_ERR_NULL_PTR; - } - - stream = mpp_malloc_size(void, stream_size); - if (NULL == stream) { - mpp_err_f("failed to malloc stream buffer size %d\n", stream_size); - return MPP_ERR_MALLOC; - } - - mpp_packet_init(&task_pkt, stream, stream_size); - if (NULL == task_pkt) { - mpp_err_f("failed to create mpp_packet for task\n"); - return MPP_ERR_UNKNOW; - } - - p = (DummyDec *)dec; - p->frame_slots = cfg->frame_slots; - p->packet_slots = cfg->packet_slots; - p->task_count = cfg->task_count = 2; - p->stream = stream; - p->stream_size = stream_size; - p->task_pkt = task_pkt; - for (i = 0; i < DUMMY_DEC_REF_COUNT; i++) { - p->slot_index[i] = -1; - } - return MPP_OK; -} - -MPP_RET dummy_dec_deinit(void *dec) -{ - DummyDec *p; - if (NULL == dec) { - mpp_err_f("found NULL intput\n"); - return MPP_ERR_NULL_PTR; - } - - p = (DummyDec *)dec; - if (p->task_pkt) - mpp_packet_deinit(&p->task_pkt); - if (p->stream) - mpp_free(p->stream); - return MPP_OK; -} - -MPP_RET dummy_dec_reset(void *dec) -{ - if (NULL == dec) { - mpp_err_f("found NULL intput\n"); - return MPP_ERR_NULL_PTR; - } - return MPP_OK; -} - - -MPP_RET dummy_dec_flush(void *dec) -{ - if (NULL == dec) { - mpp_err_f("found NULL intput\n"); - return MPP_ERR_NULL_PTR; - } - return MPP_OK; -} - - -MPP_RET dummy_dec_control(void *dec, RK_S32 cmd_type, void *param) -{ - if (NULL == dec) { - mpp_err_f("found NULL intput\n"); - return MPP_ERR_NULL_PTR; - } - (void)cmd_type; - (void)param; - return MPP_OK; -} - -MPP_RET dummy_dec_prepare(void *dec, MppPacket pkt, HalDecTask *task) -{ - DummyDec *p; - RK_U8 *data; - size_t length; - - if (NULL == dec) { - mpp_err_f("found NULL intput\n"); - return MPP_ERR_NULL_PTR; - } - - p = (DummyDec *)dec; - - /********************************************************************* - * do packet prepare here - * including connet nals into a big buffer, setup packet for task copy - * pts/eos record - *********************************************************************/ - p->task_pts = mpp_packet_get_pts(pkt); - p->task_eos = mpp_packet_get_eos(pkt); - - // set pos to indicate that buffer is done - data = mpp_packet_get_data(pkt); - length = mpp_packet_get_length(pkt); - if (length > p->stream_size) { - mpp_realloc(p->stream, RK_U8, length); - mpp_packet_set_data(p->task_pkt, p->stream); - p->stream_size = length; - } - if (p->stream) { - memcpy(p->stream, data, length); - mpp_packet_set_length(p->task_pkt, length); - } else { - mpp_err("failed to found task buffer for hardware\n"); - return MPP_ERR_UNKNOW; - } - mpp_packet_set_pos(pkt, data + length); - - /* - * this step will enable the task and goto parse stage - */ - task->input_packet = p->task_pkt; - task->flags.eos = p->task_eos; - task->valid = 1; - return MPP_OK; -} -MPP_RET dummy_dec_parse(void *dec, HalDecTask *task) -{ - DummyDec *p; - RK_S32 output; - MppFrame frame = NULL; - RK_U32 frame_count; - MppBufSlots slots; - RK_S32 i; - RK_U32 width, height; - - if (NULL == dec) { - mpp_err_f("found NULL intput\n"); - return MPP_ERR_NULL_PTR; - } - p = (DummyDec *)dec; - - slots = p->frame_slots; - frame_count = p->frame_count; - - width = DUMMY_DEC_FRAME_WIDTH; - height = DUMMY_DEC_FRAME_HEIGHT; - - mpp_frame_init(&frame); - - if (!p->slots_inited) { - mpp_buf_slot_setup(slots, DUMMY_DEC_FRAME_COUNT); - p->slots_inited = 1; - } else if (frame_count >= 2) { - // do info change test - width = DUMMY_DEC_FRAME_NEW_WIDTH; - height = DUMMY_DEC_FRAME_NEW_HEIGHT; - } - - mpp_frame_set_width(frame, width); - mpp_frame_set_height(frame, height); - mpp_frame_set_hor_stride(frame, MPP_ALIGN(width, 16)); - mpp_frame_set_ver_stride(frame, MPP_ALIGN(height, 16)); - - if (task->prev_status) { - /* - * if previous task has error happened mark the previous frame to be error - */ - mpp_err("previous task error found\n"); - } - - /* - * set slots information - * 1. output index MUST be set - * 2. get unused index for output if needed - * 3. set output index as hal_input - * 4. set frame information to output index - * 5. if one frame can be display, it SHOULD be enqueued to display queue - */ - mpp_buf_slot_get_unused(slots, &output); - mpp_buf_slot_set_flag(slots, output, SLOT_HAL_OUTPUT); - task->output = output; - - mpp_frame_set_pts(frame, p->task_pts); - mpp_buf_slot_set_prop(slots, output, SLOT_FRAME, frame); - mpp_frame_deinit(&frame); - mpp_assert(NULL == frame); - - /* - * setup output task - * 1. valid flag MUST be set if need hardware to run once - * 2. set output slot index - * 3. set reference slot index - */ - memset(&task->refer, -1, sizeof(task->refer)); - for (i = 0; i < DUMMY_DEC_REF_COUNT; i++) { - RK_S32 index = p->slot_index[i]; - if (index >= 0) { - task->refer[i] = index; - mpp_buf_slot_set_flag(slots, index, SLOT_HAL_INPUT); - mpp_buf_slot_set_flag(slots, index, SLOT_CODEC_USE); - } - } - - /* - * update dpb status assuming that hw has decoded the frame - */ - mpp_buf_slot_set_flag(slots, output, SLOT_QUEUE_USE); - mpp_buf_slot_enqueue(slots, output, QUEUE_DISPLAY); - - // add new reference buffer - if (p->task_eos) { - for (i = 0; i < DUMMY_DEC_REF_COUNT; i++) { - mpp_buf_slot_clr_flag(slots, p->slot_index[i], SLOT_CODEC_USE); - p->slot_index[i] = -1; - } - } else { - // clear unreference buffer - RK_U32 replace_index = frame_count & 1; - if (p->slot_index[replace_index] >= 0) - mpp_buf_slot_clr_flag(slots, p->slot_index[replace_index], SLOT_CODEC_USE); - - p->slot_index[replace_index] = output; - mpp_buf_slot_set_flag(slots, output, SLOT_CODEC_USE); - } - - p->frame_count = ++frame_count; - - return MPP_OK; -} - -MPP_RET dummy_dec_callback(void *dec, void *err_info) -{ - (void)dec; - (void)err_info; - return MPP_OK; -} -const ParserApi dummy_dec_parser = { - "dummy_dec_parser", - MPP_VIDEO_CodingUnused, - sizeof(DummyDec), - 0, - dummy_dec_init, - dummy_dec_deinit, - dummy_dec_prepare, - dummy_dec_parse, - dummy_dec_reset, - dummy_dec_flush, - dummy_dec_control, - dummy_dec_callback, -}; - +/* +* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#define MODULE_TAG "dummy_dec_api" + +#include + +#include "mpp_log.h" +#include "mpp_mem.h" +#include "mpp_common.h" +#include "mpp_packet.h" + +#include "dummy_dec_api.h" + +#define DUMMY_DEC_FRAME_WIDTH 1280 +#define DUMMY_DEC_FRAME_HEIGHT 720 + +#define DUMMY_DEC_FRAME_NEW_WIDTH 1920 +#define DUMMY_DEC_FRAME_NEW_HEIGHT 1088 + +#define DUMMY_DEC_FRAME_SIZE SZ_1M +#define DUMMY_DEC_FRAME_COUNT 16 +#define DUMMY_DEC_REF_COUNT 2 + +typedef struct DummyDec_t { + MppBufSlots frame_slots; + MppBufSlots packet_slots; + RK_S32 task_count; + void *stream; + size_t stream_size; + MppPacket task_pkt; + + RK_S64 task_pts; + RK_U32 task_eos; + + RK_U32 slots_inited; + RK_U32 frame_count; + RK_S32 prev_index; + RK_S32 slot_index[DUMMY_DEC_REF_COUNT]; +} DummyDec; + +MPP_RET dummy_dec_init(void *dec, ParserCfg *cfg) +{ + DummyDec *p; + RK_S32 i; + void *stream; + size_t stream_size = SZ_512K; + MppPacket task_pkt; + + if (NULL == dec) { + mpp_err_f("found NULL intput dec %p cfg %p\n", dec, cfg); + return MPP_ERR_NULL_PTR; + } + + stream = mpp_malloc_size(void, stream_size); + if (NULL == stream) { + mpp_err_f("failed to malloc stream buffer size %d\n", stream_size); + return MPP_ERR_MALLOC; + } + + mpp_packet_init(&task_pkt, stream, stream_size); + if (NULL == task_pkt) { + mpp_err_f("failed to create mpp_packet for task\n"); + return MPP_ERR_UNKNOW; + } + + p = (DummyDec *)dec; + p->frame_slots = cfg->frame_slots; + p->packet_slots = cfg->packet_slots; + p->task_count = cfg->task_count = 2; + p->stream = stream; + p->stream_size = stream_size; + p->task_pkt = task_pkt; + for (i = 0; i < DUMMY_DEC_REF_COUNT; i++) { + p->slot_index[i] = -1; + } + return MPP_OK; +} + +MPP_RET dummy_dec_deinit(void *dec) +{ + DummyDec *p; + if (NULL == dec) { + mpp_err_f("found NULL intput\n"); + return MPP_ERR_NULL_PTR; + } + + p = (DummyDec *)dec; + if (p->task_pkt) + mpp_packet_deinit(&p->task_pkt); + if (p->stream) + mpp_free(p->stream); + return MPP_OK; +} + +MPP_RET dummy_dec_reset(void *dec) +{ + if (NULL == dec) { + mpp_err_f("found NULL intput\n"); + return MPP_ERR_NULL_PTR; + } + return MPP_OK; +} + + +MPP_RET dummy_dec_flush(void *dec) +{ + if (NULL == dec) { + mpp_err_f("found NULL intput\n"); + return MPP_ERR_NULL_PTR; + } + return MPP_OK; +} + + +MPP_RET dummy_dec_control(void *dec, RK_S32 cmd_type, void *param) +{ + if (NULL == dec) { + mpp_err_f("found NULL intput\n"); + return MPP_ERR_NULL_PTR; + } + (void)cmd_type; + (void)param; + return MPP_OK; +} + +MPP_RET dummy_dec_prepare(void *dec, MppPacket pkt, HalDecTask *task) +{ + DummyDec *p; + RK_U8 *data; + size_t length; + + if (NULL == dec) { + mpp_err_f("found NULL intput\n"); + return MPP_ERR_NULL_PTR; + } + + p = (DummyDec *)dec; + + /********************************************************************* + * do packet prepare here + * including connet nals into a big buffer, setup packet for task copy + * pts/eos record + *********************************************************************/ + p->task_pts = mpp_packet_get_pts(pkt); + p->task_eos = mpp_packet_get_eos(pkt); + + // set pos to indicate that buffer is done + data = mpp_packet_get_data(pkt); + length = mpp_packet_get_length(pkt); + if (length > p->stream_size) { + mpp_realloc(p->stream, RK_U8, length); + mpp_packet_set_data(p->task_pkt, p->stream); + p->stream_size = length; + } + if (p->stream) { + memcpy(p->stream, data, length); + mpp_packet_set_length(p->task_pkt, length); + } else { + mpp_err("failed to found task buffer for hardware\n"); + return MPP_ERR_UNKNOW; + } + mpp_packet_set_pos(pkt, data + length); + + /* + * this step will enable the task and goto parse stage + */ + task->input_packet = p->task_pkt; + task->flags.eos = p->task_eos; + task->valid = 1; + return MPP_OK; +} +MPP_RET dummy_dec_parse(void *dec, HalDecTask *task) +{ + DummyDec *p; + RK_S32 output; + MppFrame frame = NULL; + RK_U32 frame_count; + MppBufSlots slots; + RK_S32 i; + RK_U32 width, height; + + if (NULL == dec) { + mpp_err_f("found NULL intput\n"); + return MPP_ERR_NULL_PTR; + } + p = (DummyDec *)dec; + + slots = p->frame_slots; + frame_count = p->frame_count; + + width = DUMMY_DEC_FRAME_WIDTH; + height = DUMMY_DEC_FRAME_HEIGHT; + + mpp_frame_init(&frame); + + if (!p->slots_inited) { + mpp_buf_slot_setup(slots, DUMMY_DEC_FRAME_COUNT); + p->slots_inited = 1; + } else if (frame_count >= 2) { + // do info change test + width = DUMMY_DEC_FRAME_NEW_WIDTH; + height = DUMMY_DEC_FRAME_NEW_HEIGHT; + } + + mpp_frame_set_width(frame, width); + mpp_frame_set_height(frame, height); + mpp_frame_set_hor_stride(frame, MPP_ALIGN(width, 16)); + mpp_frame_set_ver_stride(frame, MPP_ALIGN(height, 16)); + + if (task->prev_status) { + /* + * if previous task has error happened mark the previous frame to be error + */ + mpp_err("previous task error found\n"); + } + + /* + * set slots information + * 1. output index MUST be set + * 2. get unused index for output if needed + * 3. set output index as hal_input + * 4. set frame information to output index + * 5. if one frame can be display, it SHOULD be enqueued to display queue + */ + mpp_buf_slot_get_unused(slots, &output); + mpp_buf_slot_set_flag(slots, output, SLOT_HAL_OUTPUT); + task->output = output; + + mpp_frame_set_pts(frame, p->task_pts); + mpp_buf_slot_set_prop(slots, output, SLOT_FRAME, frame); + mpp_frame_deinit(&frame); + mpp_assert(NULL == frame); + + /* + * setup output task + * 1. valid flag MUST be set if need hardware to run once + * 2. set output slot index + * 3. set reference slot index + */ + memset(&task->refer, -1, sizeof(task->refer)); + for (i = 0; i < DUMMY_DEC_REF_COUNT; i++) { + RK_S32 index = p->slot_index[i]; + if (index >= 0) { + task->refer[i] = index; + mpp_buf_slot_set_flag(slots, index, SLOT_HAL_INPUT); + mpp_buf_slot_set_flag(slots, index, SLOT_CODEC_USE); + } + } + + /* + * update dpb status assuming that hw has decoded the frame + */ + mpp_buf_slot_set_flag(slots, output, SLOT_QUEUE_USE); + mpp_buf_slot_enqueue(slots, output, QUEUE_DISPLAY); + + // add new reference buffer + if (p->task_eos) { + for (i = 0; i < DUMMY_DEC_REF_COUNT; i++) { + mpp_buf_slot_clr_flag(slots, p->slot_index[i], SLOT_CODEC_USE); + p->slot_index[i] = -1; + } + } else { + // clear unreference buffer + RK_U32 replace_index = frame_count & 1; + if (p->slot_index[replace_index] >= 0) + mpp_buf_slot_clr_flag(slots, p->slot_index[replace_index], SLOT_CODEC_USE); + + p->slot_index[replace_index] = output; + mpp_buf_slot_set_flag(slots, output, SLOT_CODEC_USE); + } + + p->frame_count = ++frame_count; + + return MPP_OK; +} + +MPP_RET dummy_dec_callback(void *dec, void *err_info) +{ + (void)dec; + (void)err_info; + return MPP_OK; +} +const ParserApi dummy_dec_parser = { + "dummy_dec_parser", + MPP_VIDEO_CodingUnused, + sizeof(DummyDec), + 0, + dummy_dec_init, + dummy_dec_deinit, + dummy_dec_prepare, + dummy_dec_parse, + dummy_dec_reset, + dummy_dec_flush, + dummy_dec_control, + dummy_dec_callback, +}; + diff --git a/mpp/codec/dec/h263/h263d_api.c b/mpp/codec/dec/h263/h263d_api.c index c8ce8a48..b69f3c42 100644 --- a/mpp/codec/dec/h263/h263d_api.c +++ b/mpp/codec/dec/h263/h263d_api.c @@ -1,337 +1,337 @@ -/* -* -* Copyright 2015 Rockchip Electronics Co. LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#define MODULE_TAG "h263d_api" - -#include - -#include "rk_mpi.h" - -#include "mpp_log.h" -#include "mpp_mem.h" -#include "mpp_common.h" - -#include "h263d_api.h" -#include "h263d_parser.h" - -#define h263d_INIT_STREAM_SIZE SZ_64K - -typedef struct { - // parameter interact with mpp_dec - MppBufSlots frame_slots; - MppBufSlots packet_slots; - RK_S32 task_count; - RK_U8 *stream; - size_t stream_size; - MppPacket task_pkt; - RK_S64 task_pts; - RK_U32 task_eos; - - // runtime parameter - RK_U32 need_split; - RK_U32 frame_count; - RK_U32 internal_pts; - IOInterruptCB notify_cb; - - // parser context - H263dParser parser; -} H263dCtx; - -MPP_RET h263d_init(void *dec, ParserCfg *cfg) -{ - H263dParser parser = NULL; - MppPacket task_pkt = NULL; - H263dCtx *p; - MPP_RET ret; - RK_U8 *stream; - size_t stream_size = h263d_INIT_STREAM_SIZE; - - if (NULL == dec) { - mpp_err_f("found NULL intput dec %p cfg %p\n", dec, cfg); - return MPP_ERR_NULL_PTR; - } - - stream = mpp_malloc_size(RK_U8, stream_size); - if (NULL == stream) { - mpp_err_f("failed to malloc stream buffer size %d\n", stream_size); - return MPP_ERR_MALLOC; - } - - ret = mpp_packet_init(&task_pkt, stream, stream_size); - if (ret) { - mpp_err_f("failed to create mpp_packet for task\n"); - goto ERR_RET; - } - - // reset task packet length to zero - // NOTE: set length must after set pos - mpp_packet_set_pos(task_pkt, stream); - mpp_packet_set_length(task_pkt, 0); - - ret = mpp_h263_parser_init(&parser, cfg->frame_slots); - if (ret) { - mpp_err_f("failed to init parser\n"); - goto ERR_RET; - } - - p = (H263dCtx *)dec; - p->frame_slots = cfg->frame_slots; - p->packet_slots = cfg->packet_slots; - p->task_count = cfg->task_count = 2; - p->need_split = cfg->need_split; - p->internal_pts = cfg->internal_pts; - p->notify_cb = cfg->notify_cb; - p->stream = stream; - p->stream_size = stream_size; - p->task_pkt = task_pkt; - p->parser = parser; - - return MPP_OK; -ERR_RET: - if (task_pkt) { - mpp_packet_deinit(&task_pkt); - } - if (stream) { - mpp_free(stream); - stream = NULL; - } - return ret; -} - -MPP_RET h263d_deinit(void *dec) -{ - H263dCtx *p; - if (NULL == dec) { - mpp_err_f("found NULL intput\n"); - return MPP_ERR_NULL_PTR; - } - - p = (H263dCtx *)dec; - if (p->parser) { - mpp_h263_parser_deinit(p->parser); - p->parser = NULL; - } - - if (p->task_pkt) { - mpp_packet_deinit(&p->task_pkt); - } - - if (p->stream) { - mpp_free(p->stream); - p->stream = NULL; - } - return MPP_OK; -} - -MPP_RET h263d_reset(void *dec) -{ - if (NULL == dec) { - mpp_err_f("found NULL intput\n"); - return MPP_ERR_NULL_PTR; - } - - H263dCtx *p = (H263dCtx *)dec; - return mpp_h263_parser_reset(p->parser); -} - - -MPP_RET h263d_flush(void *dec) -{ - if (NULL == dec) { - mpp_err_f("found NULL intput\n"); - return MPP_ERR_NULL_PTR; - } - - H263dCtx *p = (H263dCtx *)dec; - return mpp_h263_parser_flush(p->parser); -} - - -MPP_RET h263d_control(void *dec, RK_S32 cmd_type, void *param) -{ - H263dCtx *p; - - if (NULL == dec) { - mpp_err_f("found NULL intput\n"); - return MPP_ERR_NULL_PTR; - } - - p = (H263dCtx *)dec; - switch (cmd_type) { - case MPP_DEC_SET_INTERNAL_PTS_ENABLE : { - mpp_h263_parser_set_pts_mode(p->parser, 0); - } break; - } - (void)param; - return MPP_OK; -} - -MPP_RET h263d_prepare(void *dec, MppPacket pkt, HalDecTask *task) -{ - H263dCtx *p; - RK_U8 *pos; - size_t length; - RK_U32 eos; - - if (NULL == dec || NULL == pkt || NULL == task) { - mpp_err_f("found NULL intput dec %p pkt %p task %p\n", dec, pkt, task); - return MPP_ERR_NULL_PTR; - } - - p = (H263dCtx *)dec; - pos = mpp_packet_get_pos(pkt); - length = mpp_packet_get_length(pkt); - eos = mpp_packet_get_eos(pkt); - - if (eos && !length) { - task->valid = 0; - task->flags.eos = 1; - mpp_log("h263d flush eos"); - h263d_flush(dec); - return MPP_OK; - } - - if (NULL == p->stream) { - mpp_err("failed to malloc task buffer for hardware with size %d\n", length); - return MPP_ERR_UNKNOW; - } - - if (!p->need_split) { - /* - * Copy packet mode: - * Decoder's user will insure each packet is one frame for process - * Parser will just copy packet to the beginning of stream buffer - */ - if (length > p->stream_size) { - // NOTE: here we double the buffer length to reduce frequency of realloc - do { - p->stream_size <<= 1; - } while (length > p->stream_size); - - mpp_free(p->stream); - p->stream = mpp_malloc_size(RK_U8, p->stream_size); - mpp_assert(p->stream); - mpp_packet_set_data(p->task_pkt, p->stream); - mpp_packet_set_size(p->task_pkt, p->stream_size); - } - - memcpy(p->stream, pos, length); - mpp_packet_set_pos(p->task_pkt, p->stream); - mpp_packet_set_length(p->task_pkt, length); - // set input packet length to 0 here - // indicate that the input packet has been all consumed - mpp_packet_set_pos(pkt, pos + length); - // always use latest pts for current packet - p->task_pts = mpp_packet_get_pts(pkt); - p->task_eos = mpp_packet_get_eos(pkt); - /* this step will enable the task and goto parse stage */ - task->valid = 1; - } else { - /* - * Split packet mode: - * Input packet can be any length and no need to be bound of on frame - * Parser will do split frame operation to find the beginning and end of one frame - */ - /* - * NOTE: on split mode total length is the left size plus the new incoming - * packet length. - */ - size_t remain_length = mpp_packet_get_length(p->task_pkt); - size_t total_length = remain_length + length; - if (total_length > p->stream_size) { - RK_U8 *dst; - do { - p->stream_size <<= 1; - } while (length > p->stream_size); - - // NOTE; split mode need to copy remaining stream to new buffer - dst = mpp_malloc_size(RK_U8, p->stream_size); - mpp_assert(dst); - - memcpy(dst, p->stream, remain_length); - mpp_free(p->stream); - p->stream = dst; - mpp_packet_set_data(p->task_pkt, p->stream); - mpp_packet_set_size(p->task_pkt, p->stream_size); - } - - // start parser split - if (MPP_OK == mpp_h263_parser_split(p->parser, p->task_pkt, pkt)) { - task->valid = 1; - } - p->task_pts = mpp_packet_get_pts(p->task_pkt); - p->task_eos = mpp_packet_get_eos(p->task_pkt); - } - - mpp_packet_set_pts(p->task_pkt, p->task_pts); - task->input_packet = p->task_pkt; - task->flags.eos = p->task_eos; - - return MPP_OK; -} - -MPP_RET h263d_parse(void *dec, HalDecTask *task) -{ - MPP_RET ret; - H263dCtx *p; - - if (NULL == dec || NULL == task) { - mpp_err_f("found NULL intput dec %p task %p\n", dec, task); - return MPP_ERR_NULL_PTR; - } - p = (H263dCtx *)dec; - ret = mpp_h263_parser_decode(p->parser, task->input_packet); - if (ret) { - // found error on decoding drop this task and clear remaining length - task->valid = 0; - task->output = -1; - mpp_packet_set_length(task->input_packet, 0); - return MPP_NOK; - } - - mpp_h263_parser_setup_syntax(p->parser, &task->syntax); - mpp_h263_parser_setup_hal_output(p->parser, &task->output); - mpp_h263_parser_setup_refer(p->parser, task->refer, MAX_DEC_REF_NUM); - mpp_h263_parser_update_dpb(p->parser); - - p->frame_count++; - - return MPP_OK; -} - -MPP_RET h263d_callback(void *dec, void *err_info) -{ - (void)dec; - (void)err_info; - return MPP_OK; -} - -const ParserApi api_h263d_parser = { - "api_h263d_parser", - MPP_VIDEO_CodingH263, - sizeof(H263dCtx), - 0, - h263d_init, - h263d_deinit, - h263d_prepare, - h263d_parse, - h263d_reset, - h263d_flush, - h263d_control, - h263d_callback, -}; - +/* +* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#define MODULE_TAG "h263d_api" + +#include + +#include "rk_mpi.h" + +#include "mpp_log.h" +#include "mpp_mem.h" +#include "mpp_common.h" + +#include "h263d_api.h" +#include "h263d_parser.h" + +#define h263d_INIT_STREAM_SIZE SZ_64K + +typedef struct { + // parameter interact with mpp_dec + MppBufSlots frame_slots; + MppBufSlots packet_slots; + RK_S32 task_count; + RK_U8 *stream; + size_t stream_size; + MppPacket task_pkt; + RK_S64 task_pts; + RK_U32 task_eos; + + // runtime parameter + RK_U32 need_split; + RK_U32 frame_count; + RK_U32 internal_pts; + IOInterruptCB notify_cb; + + // parser context + H263dParser parser; +} H263dCtx; + +MPP_RET h263d_init(void *dec, ParserCfg *cfg) +{ + H263dParser parser = NULL; + MppPacket task_pkt = NULL; + H263dCtx *p; + MPP_RET ret; + RK_U8 *stream; + size_t stream_size = h263d_INIT_STREAM_SIZE; + + if (NULL == dec) { + mpp_err_f("found NULL intput dec %p cfg %p\n", dec, cfg); + return MPP_ERR_NULL_PTR; + } + + stream = mpp_malloc_size(RK_U8, stream_size); + if (NULL == stream) { + mpp_err_f("failed to malloc stream buffer size %d\n", stream_size); + return MPP_ERR_MALLOC; + } + + ret = mpp_packet_init(&task_pkt, stream, stream_size); + if (ret) { + mpp_err_f("failed to create mpp_packet for task\n"); + goto ERR_RET; + } + + // reset task packet length to zero + // NOTE: set length must after set pos + mpp_packet_set_pos(task_pkt, stream); + mpp_packet_set_length(task_pkt, 0); + + ret = mpp_h263_parser_init(&parser, cfg->frame_slots); + if (ret) { + mpp_err_f("failed to init parser\n"); + goto ERR_RET; + } + + p = (H263dCtx *)dec; + p->frame_slots = cfg->frame_slots; + p->packet_slots = cfg->packet_slots; + p->task_count = cfg->task_count = 2; + p->need_split = cfg->need_split; + p->internal_pts = cfg->internal_pts; + p->notify_cb = cfg->notify_cb; + p->stream = stream; + p->stream_size = stream_size; + p->task_pkt = task_pkt; + p->parser = parser; + + return MPP_OK; +ERR_RET: + if (task_pkt) { + mpp_packet_deinit(&task_pkt); + } + if (stream) { + mpp_free(stream); + stream = NULL; + } + return ret; +} + +MPP_RET h263d_deinit(void *dec) +{ + H263dCtx *p; + if (NULL == dec) { + mpp_err_f("found NULL intput\n"); + return MPP_ERR_NULL_PTR; + } + + p = (H263dCtx *)dec; + if (p->parser) { + mpp_h263_parser_deinit(p->parser); + p->parser = NULL; + } + + if (p->task_pkt) { + mpp_packet_deinit(&p->task_pkt); + } + + if (p->stream) { + mpp_free(p->stream); + p->stream = NULL; + } + return MPP_OK; +} + +MPP_RET h263d_reset(void *dec) +{ + if (NULL == dec) { + mpp_err_f("found NULL intput\n"); + return MPP_ERR_NULL_PTR; + } + + H263dCtx *p = (H263dCtx *)dec; + return mpp_h263_parser_reset(p->parser); +} + + +MPP_RET h263d_flush(void *dec) +{ + if (NULL == dec) { + mpp_err_f("found NULL intput\n"); + return MPP_ERR_NULL_PTR; + } + + H263dCtx *p = (H263dCtx *)dec; + return mpp_h263_parser_flush(p->parser); +} + + +MPP_RET h263d_control(void *dec, RK_S32 cmd_type, void *param) +{ + H263dCtx *p; + + if (NULL == dec) { + mpp_err_f("found NULL intput\n"); + return MPP_ERR_NULL_PTR; + } + + p = (H263dCtx *)dec; + switch (cmd_type) { + case MPP_DEC_SET_INTERNAL_PTS_ENABLE : { + mpp_h263_parser_set_pts_mode(p->parser, 0); + } break; + } + (void)param; + return MPP_OK; +} + +MPP_RET h263d_prepare(void *dec, MppPacket pkt, HalDecTask *task) +{ + H263dCtx *p; + RK_U8 *pos; + size_t length; + RK_U32 eos; + + if (NULL == dec || NULL == pkt || NULL == task) { + mpp_err_f("found NULL intput dec %p pkt %p task %p\n", dec, pkt, task); + return MPP_ERR_NULL_PTR; + } + + p = (H263dCtx *)dec; + pos = mpp_packet_get_pos(pkt); + length = mpp_packet_get_length(pkt); + eos = mpp_packet_get_eos(pkt); + + if (eos && !length) { + task->valid = 0; + task->flags.eos = 1; + mpp_log("h263d flush eos"); + h263d_flush(dec); + return MPP_OK; + } + + if (NULL == p->stream) { + mpp_err("failed to malloc task buffer for hardware with size %d\n", length); + return MPP_ERR_UNKNOW; + } + + if (!p->need_split) { + /* + * Copy packet mode: + * Decoder's user will insure each packet is one frame for process + * Parser will just copy packet to the beginning of stream buffer + */ + if (length > p->stream_size) { + // NOTE: here we double the buffer length to reduce frequency of realloc + do { + p->stream_size <<= 1; + } while (length > p->stream_size); + + mpp_free(p->stream); + p->stream = mpp_malloc_size(RK_U8, p->stream_size); + mpp_assert(p->stream); + mpp_packet_set_data(p->task_pkt, p->stream); + mpp_packet_set_size(p->task_pkt, p->stream_size); + } + + memcpy(p->stream, pos, length); + mpp_packet_set_pos(p->task_pkt, p->stream); + mpp_packet_set_length(p->task_pkt, length); + // set input packet length to 0 here + // indicate that the input packet has been all consumed + mpp_packet_set_pos(pkt, pos + length); + // always use latest pts for current packet + p->task_pts = mpp_packet_get_pts(pkt); + p->task_eos = mpp_packet_get_eos(pkt); + /* this step will enable the task and goto parse stage */ + task->valid = 1; + } else { + /* + * Split packet mode: + * Input packet can be any length and no need to be bound of on frame + * Parser will do split frame operation to find the beginning and end of one frame + */ + /* + * NOTE: on split mode total length is the left size plus the new incoming + * packet length. + */ + size_t remain_length = mpp_packet_get_length(p->task_pkt); + size_t total_length = remain_length + length; + if (total_length > p->stream_size) { + RK_U8 *dst; + do { + p->stream_size <<= 1; + } while (length > p->stream_size); + + // NOTE; split mode need to copy remaining stream to new buffer + dst = mpp_malloc_size(RK_U8, p->stream_size); + mpp_assert(dst); + + memcpy(dst, p->stream, remain_length); + mpp_free(p->stream); + p->stream = dst; + mpp_packet_set_data(p->task_pkt, p->stream); + mpp_packet_set_size(p->task_pkt, p->stream_size); + } + + // start parser split + if (MPP_OK == mpp_h263_parser_split(p->parser, p->task_pkt, pkt)) { + task->valid = 1; + } + p->task_pts = mpp_packet_get_pts(p->task_pkt); + p->task_eos = mpp_packet_get_eos(p->task_pkt); + } + + mpp_packet_set_pts(p->task_pkt, p->task_pts); + task->input_packet = p->task_pkt; + task->flags.eos = p->task_eos; + + return MPP_OK; +} + +MPP_RET h263d_parse(void *dec, HalDecTask *task) +{ + MPP_RET ret; + H263dCtx *p; + + if (NULL == dec || NULL == task) { + mpp_err_f("found NULL intput dec %p task %p\n", dec, task); + return MPP_ERR_NULL_PTR; + } + p = (H263dCtx *)dec; + ret = mpp_h263_parser_decode(p->parser, task->input_packet); + if (ret) { + // found error on decoding drop this task and clear remaining length + task->valid = 0; + task->output = -1; + mpp_packet_set_length(task->input_packet, 0); + return MPP_NOK; + } + + mpp_h263_parser_setup_syntax(p->parser, &task->syntax); + mpp_h263_parser_setup_hal_output(p->parser, &task->output); + mpp_h263_parser_setup_refer(p->parser, task->refer, MAX_DEC_REF_NUM); + mpp_h263_parser_update_dpb(p->parser); + + p->frame_count++; + + return MPP_OK; +} + +MPP_RET h263d_callback(void *dec, void *err_info) +{ + (void)dec; + (void)err_info; + return MPP_OK; +} + +const ParserApi api_h263d_parser = { + "api_h263d_parser", + MPP_VIDEO_CodingH263, + sizeof(H263dCtx), + 0, + h263d_init, + h263d_deinit, + h263d_prepare, + h263d_parse, + h263d_reset, + h263d_flush, + h263d_control, + h263d_callback, +}; + diff --git a/mpp/codec/dec/h263/h263d_parser.c b/mpp/codec/dec/h263/h263d_parser.c index 1124d683..b4c52503 100644 --- a/mpp/codec/dec/h263/h263d_parser.c +++ b/mpp/codec/dec/h263/h263d_parser.c @@ -1,579 +1,579 @@ -/* - * - * Copyright 2010 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include - -#include "mpp_env.h" -#include "mpp_log.h" -#include "mpp_mem.h" -#include "mpp_packet.h" - -#include "mpp_bitread.h" -#include "h263d_parser.h" -#include "h263d_syntax.h" - -RK_U32 h263d_debug = 0; - -#define h263d_dbg(flag, fmt, ...) _mpp_dbg(h263d_debug, flag, fmt, ## __VA_ARGS__) -#define h263d_dbg_f(flag, fmt, ...) _mpp_dbg_f(h263d_debug, flag, fmt, ## __VA_ARGS__) - -#define h263d_dbg_func(fmt, ...) h263d_dbg_f(H263D_DBG_FUNCTION, fmt, ## __VA_ARGS__) -#define h263d_dbg_bit(fmt, ...) h263d_dbg(H263D_DBG_BITS, fmt, ## __VA_ARGS__) -#define h263d_dbg_status(fmt, ...) h263d_dbg(H263D_DBG_STATUS, fmt, ## __VA_ARGS__) - -#define H263_STARTCODE 0x00000080 /* 17 zero and 1 one */ -#define H263_STARTCODE_MASK 0x00FFFF80 -#define H263_GOB_ZERO 0x00000000 -#define H263_GOB_ZERO_MASK 0x0000007C - -#define H263_SF_SQCIF 1 /* 001 */ -#define H263_SF_QCIF 2 /* 010 */ -#define H263_SF_CIF 3 /* 011 */ -#define H263_SF_4CIF 4 /* 100 */ -#define H263_SF_16CIF 5 /* 101 */ -#define H263_SF_CUSTOM 6 /* 110 */ -#define H263_EXTENDED_PTYPE 7 /* 111 */ -#define H263_EXTENDED_PAR 15 /* 1111 */ - -typedef struct H263Hdr_t { - H263VOPType pict_type; - RK_S32 width; - RK_S32 height; - RK_U32 TR; - RK_U32 quant; - - // frame related parameter - RK_S64 pts; - RK_S32 slot_idx; - RK_U32 enqueued; - RK_U32 hdr_bits; -} H263Hdr; - -typedef struct { - // global paramter - MppBufSlots frame_slots; - RK_U32 use_internal_pts; - RK_U32 found_i_vop; - - // frame size parameter - RK_S32 width; - RK_S32 height; - RK_S32 hor_stride; - RK_S32 ver_stride; - RK_U32 info_change; - RK_U32 eos; - - // spliter parameter - RK_S32 pos_frm_start; // negtive - not found; non-negtive - position of frame start - RK_S32 pos_frm_end; // negtive - not found; non-negtive - position of frame end - - // bit read context - BitReadCtx_t *bit_ctx; - - // decoding parameter - H263Hdr hdr_curr; - H263Hdr hdr_ref0; - - // dpb/output information - RK_S32 output; - RK_S64 pts; - - // syntax for hal - h263d_dxva2_picture_context_t *syntax; -} H263dParserImpl; - -static RK_U32 h263d_fmt_to_dimension[8][2] = { - { 0, 0 }, /* invalid */ - { 128, 96 }, /* SQCIF */ - { 176, 144 }, /* QCIF */ - { 352, 288 }, /* CIF */ - { 704, 576 }, /* 4CIF */ - { 1408, 1152 }, /* 16CIF */ - { 0, 0 }, /* custorm */ - { 0, 0 }, /* extend */ -}; - -static void h263d_fill_picture_parameters(const H263dParserImpl *p, - DXVA_PicParams_H263 *pp) -{ - const H263Hdr *hdr_curr = &p->hdr_curr; - const H263Hdr *hdr_ref0 = &p->hdr_ref0; - - pp->short_video_header = 1; - pp->vop_coding_type = hdr_curr->pict_type; - pp->vop_quant = hdr_curr->quant; - pp->wDecodedPictureIndex = hdr_curr->slot_idx; - pp->wForwardRefPictureIndex = hdr_ref0->slot_idx; - pp->vop_time_increment_resolution = 30000; - pp->vop_width = hdr_curr->width; - pp->vop_height = hdr_curr->height; - - // Rockchip special data - pp->prev_coding_type = hdr_ref0->pict_type; - pp->header_bits = hdr_curr->hdr_bits; -} - -static void h263_syntax_init(h263d_dxva2_picture_context_t *syntax) -{ - DXVA2_DecodeBufferDesc *data = &syntax->desc[0]; - - //!< commit picture paramters - memset(data, 0, sizeof(*data)); - data->CompressedBufferType = DXVA2_PictureParametersBufferType; - data->pvPVPState = (void *)&syntax->pp; - data->DataSize = sizeof(syntax->pp); - syntax->data[0] = data; - - //!< commit bitstream - data = &syntax->desc[1]; - memset(data, 0, sizeof(*data)); - data->CompressedBufferType = DXVA2_BitStreamDateBufferType; - syntax->data[1] = data; -} - -static MPP_RET h263_parse_picture_header(H263dParserImpl *p, BitReadCtx_t *gb) -{ - RK_U32 val = 0; - H263Hdr *hdr_curr = &p->hdr_curr; - H263VOPType pict_type = H263_INVALID_VOP; - - /* start code */ - READ_BITS(gb, 17, &val, "start code"); - mpp_assert(val == 1); - - /* gob */ - READ_BITS(gb, 5, &val, "gob"); - mpp_assert(val == 0); - - /* time reference */ - READ_BITS(gb, 8, &hdr_curr->TR, "TR"); - - SKIP_BITS(gb, 5); - - /* source format */ - READ_BITS(gb, 3, &val, "source format"); - hdr_curr->width = h263d_fmt_to_dimension[val][0]; - hdr_curr->height = h263d_fmt_to_dimension[val][1]; - if (!hdr_curr->width && !hdr_curr->height) { - mpp_err_f("unsupport source format %d\n", val); - return MPP_NOK; - } - - READ_BITS(gb, 1, &val); - pict_type = val; - - SKIP_BITS(gb, 4); - - READ_BITS(gb, 5, &val); - hdr_curr->quant = val; - - SKIP_BITS(gb, 1); - - READ_BITS(gb, 1, &val); - while (val) { - SKIP_BITS(gb, 8); - READ_BITS(gb, 1, &val); - } - - if (!p->found_i_vop) - p->found_i_vop = (pict_type == H263_I_VOP); - - if (!p->found_i_vop) - return MPP_NOK; - - hdr_curr->hdr_bits = gb->used_bits; - hdr_curr->pict_type = pict_type; - - return MPP_OK; -__BITREAD_ERR: - mpp_err_f("found error stream\n"); - return MPP_ERR_STREAM; -} - -MPP_RET mpp_h263_parser_init(H263dParser *ctx, MppBufSlots frame_slots) -{ - BitReadCtx_t *bit_ctx = mpp_calloc(BitReadCtx_t, 1); - H263dParserImpl *p = mpp_calloc(H263dParserImpl, 1); - h263d_dxva2_picture_context_t *syntax = mpp_calloc(h263d_dxva2_picture_context_t, 1); - - if (NULL == p || NULL == bit_ctx || NULL == syntax) { - mpp_err_f("malloc context failed\n"); - if (p) - mpp_free(p); - if (bit_ctx) - mpp_free(bit_ctx); - if (syntax) - mpp_free(syntax); - return MPP_NOK; - } - - mpp_buf_slot_setup(frame_slots, 4); - p->frame_slots = frame_slots; - p->use_internal_pts = 0; - p->pos_frm_start = -1; - p->pos_frm_end = -1; - p->bit_ctx = bit_ctx; - p->hdr_curr.slot_idx = H263_INVALID_VOP; - p->hdr_ref0.slot_idx = H263_INVALID_VOP; - h263_syntax_init(syntax); - p->syntax = syntax; - - mpp_env_get_u32("h263d_debug", &h263d_debug, 0); - - *ctx = p; - return MPP_OK; -} - -MPP_RET mpp_h263_parser_deinit(H263dParser ctx) -{ - H263dParserImpl *p = (H263dParserImpl *)ctx; - if (p) { - if (p->bit_ctx) { - mpp_free(p->bit_ctx); - p->bit_ctx = NULL; - } - if (p->syntax) { - mpp_free(p->syntax); - p->syntax = NULL; - } - mpp_free(p); - } - return MPP_OK; -} - -MPP_RET mpp_h263_parser_flush(H263dParser ctx) -{ - H263dParserImpl *p = (H263dParserImpl *)ctx; - MppBufSlots slots = p->frame_slots; - H263Hdr *hdr_curr = &p->hdr_ref0; - RK_S32 index = hdr_curr->slot_idx; - - h263d_dbg_func("in\n"); - - if (!hdr_curr->enqueued && index >= 0) { - mpp_buf_slot_set_flag(slots, index, SLOT_QUEUE_USE); - mpp_buf_slot_enqueue(slots, index, QUEUE_DISPLAY); - hdr_curr->enqueued = 1; - } - - h263d_dbg_func("out\n"); - - return MPP_OK; -} - -MPP_RET mpp_h263_parser_reset(H263dParser ctx) -{ - H263dParserImpl *p = (H263dParserImpl *)ctx; - MppBufSlots slots = p->frame_slots; - H263Hdr *hdr_curr = &p->hdr_ref0; - H263Hdr *hdr_ref0 = &p->hdr_ref0; - RK_S32 index = hdr_curr->slot_idx; - - h263d_dbg_func("in\n"); - - if (index >= 0) { - mpp_buf_slot_clr_flag(slots, index, SLOT_CODEC_USE); - hdr_curr->slot_idx = -1; - } - - index = hdr_ref0->slot_idx; - if (index >= 0) { - mpp_buf_slot_clr_flag(slots, index, SLOT_CODEC_USE); - hdr_ref0->slot_idx = -1; - } - - p->found_i_vop = 0; - - h263d_dbg_func("out\n"); - - return MPP_OK; -} - -MPP_RET mpp_h263_parser_split(H263dParser ctx, MppPacket dst, MppPacket src) -{ - MPP_RET ret = MPP_NOK; - H263dParserImpl *p = (H263dParserImpl *)ctx; - RK_U8 *dst_buf = mpp_packet_get_data(dst); - size_t dst_len = mpp_packet_get_length(dst); - RK_U8 *src_buf = mpp_packet_get_pos(src); - RK_S32 src_len = (RK_S32)mpp_packet_get_length(src); - RK_S32 pos_frm_start = p->pos_frm_start; - RK_S32 pos_frm_end = p->pos_frm_end; - RK_U32 src_eos = mpp_packet_get_eos(src); - RK_S32 src_pos = 0; - RK_U32 state = (RK_U32) - 1; - - h263d_dbg_func("in\n"); - - mpp_assert(src_len); - - if (dst_len) { - mpp_assert(dst_len >= 4); - state = ((RK_U32)(dst_buf[dst_len - 1]) << 0) | - ((RK_U32)(dst_buf[dst_len - 2]) << 8) | - ((RK_U32)(dst_buf[dst_len - 3]) << 16) | - ((RK_U32)(dst_buf[dst_len - 4]) << 24); - } - - if (pos_frm_start < 0) { - // scan for frame start - for (src_pos = 0; src_pos < src_len; src_pos++) { - state = (state << 8) | src_buf[src_pos]; - if ((state & H263_STARTCODE_MASK) == H263_STARTCODE && - (state & H263_GOB_ZERO_MASK) == H263_GOB_ZERO) { - pos_frm_start = src_pos - 3; - src_pos++; - break; - } - } - } - - if (pos_frm_start >= 0) { - // scan for frame end - for (; src_pos < src_len; src_pos++) { - state = (state << 8) | src_buf[src_pos]; - - if ((state & H263_STARTCODE_MASK) == H263_STARTCODE && - (state & H263_GOB_ZERO_MASK) == H263_GOB_ZERO) { - pos_frm_end = src_pos - 3; - break; - } - } - if (src_eos && src_pos == src_len) { - pos_frm_end = src_len; - mpp_packet_set_eos(dst); - } - } - - //mpp_log("pkt pos: start %d end %d len: left %d in %d\n", - // pos_frm_start, pos_frm_end, dst_len, src_len); - - if (pos_frm_start < 0 || pos_frm_end < 0) { - // do not found frame start or do not found frame end, just copy the hold buffer to dst - memcpy(dst_buf + dst_len, src_buf, src_len); - // update dst buffer length - mpp_packet_set_length(dst, dst_len + src_len); - // set src buffer pos to end to src buffer - mpp_packet_set_pos(src, src_buf + src_len); - } else { - // found both frame start and frame end - only copy frame - memcpy(dst_buf + dst_len, src_buf, pos_frm_end); - mpp_packet_set_length(dst, dst_len + pos_frm_end); - - // set src buffer pos to end to src buffer - mpp_packet_set_pos(src, src_buf + pos_frm_end); - mpp_assert((RK_S32)mpp_packet_get_length(src) == (src_len - pos_frm_end)); - mpp_packet_set_length(src, src_len - pos_frm_end); - - // return ok indicate the frame is ready and reset frame start/end position - ret = MPP_OK; - pos_frm_start = -1; - pos_frm_end = -1; - } - - p->pos_frm_start = pos_frm_start; - p->pos_frm_end = pos_frm_end; - - h263d_dbg_func("out\n"); - - return ret; -} - -MPP_RET mpp_h263_parser_decode(H263dParser ctx, MppPacket pkt) -{ - MPP_RET ret = MPP_NOK; - H263dParserImpl *p = (H263dParserImpl *)ctx; - BitReadCtx_t *gb = p->bit_ctx; - RK_U8 *buf = mpp_packet_get_data(pkt); - RK_S32 len = (RK_S32)mpp_packet_get_length(pkt); - RK_U32 startcode = 0xff; - RK_S32 i = 0; - - h263d_dbg_func("in\n"); - - while (i < len) { - startcode = (startcode << 8) | buf[i++]; - - if (startcode >> (32 - 22) == 0x20) { - i -= 4; - h263d_dbg_bit("found startcode at byte %d\n", i); - break; - } - } - - if (i == len) { - mpp_err_f("can not found start code in len %d packet\n", len); - goto __BITREAD_ERR; - } - - // setup bit read context - mpp_set_bitread_ctx(gb, buf + i, len - i); - - ret = h263_parse_picture_header(p, gb); - if (ret) - goto __BITREAD_ERR; - - p->width = p->hdr_curr.width; - p->height = p->hdr_curr.height; - - if (!p->use_internal_pts) - p->pts = mpp_packet_get_pts(pkt); - -__BITREAD_ERR: - h263d_dbg_status("found i_frame %d frame_type %d ret %d\n", - p->found_i_vop, p->hdr_curr.pict_type, ret); - - mpp_packet_set_pos(pkt, buf); - mpp_packet_set_length(pkt, 0); - p->eos = mpp_packet_get_eos(pkt); - - h263d_dbg_func("out\n"); - - return ret; -} - -MPP_RET mpp_h263_parser_setup_syntax(H263dParser ctx, MppSyntax *syntax) -{ - H263dParserImpl *p = (H263dParserImpl *)ctx; - h263d_dxva2_picture_context_t *syn = p->syntax; - - h263d_dbg_func("in\n"); - - h263d_fill_picture_parameters(p, &syn->pp); - - // fill bit stream parameter - syn->data[1]->DataSize = p->bit_ctx->buf_len; - syn->data[1]->DataOffset = p->hdr_curr.hdr_bits; - syn->data[1]->pvPVPState = p->bit_ctx->buf; - - syntax->number = 2; - syntax->data = syn->data; - - h263d_dbg_func("out\n"); - - return MPP_OK; -} - -MPP_RET mpp_h263_parser_setup_hal_output(H263dParser ctx, RK_S32 *output) -{ - H263dParserImpl *p = (H263dParserImpl *)ctx; - RK_S32 index = -1; - - h263d_dbg_func("in\n"); - - if (p->found_i_vop) { - H263Hdr *hdr_curr = &p->hdr_curr; - MppBufSlots slots = p->frame_slots; - MppFrame frame = NULL; - - mpp_frame_init(&frame); - mpp_frame_set_width(frame, p->width); - mpp_frame_set_height(frame, p->height); - mpp_frame_set_hor_stride(frame, MPP_ALIGN(p->width, 16)); - mpp_frame_set_ver_stride(frame, MPP_ALIGN(p->height, 16)); - - /* - * set slots information - * 1. output index MUST be set - * 2. get unused index for output if needed - * 3. set output index as hal_input - * 4. set frame information to output index - * 5. if one frame can be display, it SHOULD be enqueued to display queue - */ - mpp_buf_slot_get_unused(slots, &index); - mpp_buf_slot_set_flag(slots, index, SLOT_HAL_OUTPUT); - mpp_frame_set_pts(frame, p->pts); - mpp_frame_set_mode(frame, MPP_FRAME_FLAG_FRAME); - - mpp_buf_slot_set_prop(slots, index, SLOT_FRAME, frame); - mpp_frame_deinit(&frame); - mpp_assert(NULL == frame); - - hdr_curr->slot_idx = index; - } - - p->output = index; - *output = index; - - h263d_dbg_func("out\n"); - - return MPP_OK; -} - -MPP_RET mpp_h263_parser_setup_refer(H263dParser ctx, RK_S32 *refer, RK_S32 max_ref) -{ - H263dParserImpl *p = (H263dParserImpl *)ctx; - H263Hdr *hdr_curr = &p->hdr_curr; - MppBufSlots slots = p->frame_slots; - RK_S32 index; - - h263d_dbg_func("in\n"); - - memset(refer, -1, sizeof(max_ref * sizeof(*refer))); - if (hdr_curr->pict_type == H263_P_VOP) { - index = p->hdr_ref0.slot_idx; - if (index >= 0) { - mpp_buf_slot_set_flag(slots, index, SLOT_HAL_INPUT); - refer[0] = index; - } - } - - h263d_dbg_func("out\n"); - - return MPP_OK; -} - -MPP_RET mpp_h263_parser_update_dpb(H263dParser ctx) -{ - H263dParserImpl *p = (H263dParserImpl *)ctx; - MppBufSlots slots = p->frame_slots; - H263Hdr *hdr_curr = &p->hdr_curr; - H263Hdr *hdr_ref0 = &p->hdr_ref0; - RK_S32 index = hdr_curr->slot_idx; - - h263d_dbg_func("in\n"); - - mpp_assert(index >= 0); - mpp_buf_slot_set_flag(slots, index, SLOT_CODEC_USE); - mpp_buf_slot_set_flag(slots, index, SLOT_QUEUE_USE); - mpp_buf_slot_enqueue(slots, index, QUEUE_DISPLAY); - hdr_curr->enqueued = 1; - - index = hdr_ref0->slot_idx; - if (index >= 0) { - mpp_buf_slot_clr_flag(slots, index, SLOT_CODEC_USE); - hdr_ref0->slot_idx = -1; - } - - // swap current to ref0 - *hdr_ref0 = *hdr_curr; - hdr_curr->slot_idx = H263_INVALID_VOP; - hdr_curr->pts = 0; - hdr_curr->enqueued = 0; - - h263d_dbg_func("out\n"); - - return MPP_OK; -} - -MPP_RET mpp_h263_parser_set_pts_mode(H263dParser ctx, RK_U32 use_internal_pts) -{ - H263dParserImpl *p = (H263dParserImpl *)ctx; - p->use_internal_pts = use_internal_pts; - return MPP_OK; -} - +/* + * + * Copyright 2010 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "mpp_env.h" +#include "mpp_log.h" +#include "mpp_mem.h" +#include "mpp_packet.h" + +#include "mpp_bitread.h" +#include "h263d_parser.h" +#include "h263d_syntax.h" + +RK_U32 h263d_debug = 0; + +#define h263d_dbg(flag, fmt, ...) _mpp_dbg(h263d_debug, flag, fmt, ## __VA_ARGS__) +#define h263d_dbg_f(flag, fmt, ...) _mpp_dbg_f(h263d_debug, flag, fmt, ## __VA_ARGS__) + +#define h263d_dbg_func(fmt, ...) h263d_dbg_f(H263D_DBG_FUNCTION, fmt, ## __VA_ARGS__) +#define h263d_dbg_bit(fmt, ...) h263d_dbg(H263D_DBG_BITS, fmt, ## __VA_ARGS__) +#define h263d_dbg_status(fmt, ...) h263d_dbg(H263D_DBG_STATUS, fmt, ## __VA_ARGS__) + +#define H263_STARTCODE 0x00000080 /* 17 zero and 1 one */ +#define H263_STARTCODE_MASK 0x00FFFF80 +#define H263_GOB_ZERO 0x00000000 +#define H263_GOB_ZERO_MASK 0x0000007C + +#define H263_SF_SQCIF 1 /* 001 */ +#define H263_SF_QCIF 2 /* 010 */ +#define H263_SF_CIF 3 /* 011 */ +#define H263_SF_4CIF 4 /* 100 */ +#define H263_SF_16CIF 5 /* 101 */ +#define H263_SF_CUSTOM 6 /* 110 */ +#define H263_EXTENDED_PTYPE 7 /* 111 */ +#define H263_EXTENDED_PAR 15 /* 1111 */ + +typedef struct H263Hdr_t { + H263VOPType pict_type; + RK_S32 width; + RK_S32 height; + RK_U32 TR; + RK_U32 quant; + + // frame related parameter + RK_S64 pts; + RK_S32 slot_idx; + RK_U32 enqueued; + RK_U32 hdr_bits; +} H263Hdr; + +typedef struct { + // global paramter + MppBufSlots frame_slots; + RK_U32 use_internal_pts; + RK_U32 found_i_vop; + + // frame size parameter + RK_S32 width; + RK_S32 height; + RK_S32 hor_stride; + RK_S32 ver_stride; + RK_U32 info_change; + RK_U32 eos; + + // spliter parameter + RK_S32 pos_frm_start; // negtive - not found; non-negtive - position of frame start + RK_S32 pos_frm_end; // negtive - not found; non-negtive - position of frame end + + // bit read context + BitReadCtx_t *bit_ctx; + + // decoding parameter + H263Hdr hdr_curr; + H263Hdr hdr_ref0; + + // dpb/output information + RK_S32 output; + RK_S64 pts; + + // syntax for hal + h263d_dxva2_picture_context_t *syntax; +} H263dParserImpl; + +static RK_U32 h263d_fmt_to_dimension[8][2] = { + { 0, 0 }, /* invalid */ + { 128, 96 }, /* SQCIF */ + { 176, 144 }, /* QCIF */ + { 352, 288 }, /* CIF */ + { 704, 576 }, /* 4CIF */ + { 1408, 1152 }, /* 16CIF */ + { 0, 0 }, /* custorm */ + { 0, 0 }, /* extend */ +}; + +static void h263d_fill_picture_parameters(const H263dParserImpl *p, + DXVA_PicParams_H263 *pp) +{ + const H263Hdr *hdr_curr = &p->hdr_curr; + const H263Hdr *hdr_ref0 = &p->hdr_ref0; + + pp->short_video_header = 1; + pp->vop_coding_type = hdr_curr->pict_type; + pp->vop_quant = hdr_curr->quant; + pp->wDecodedPictureIndex = hdr_curr->slot_idx; + pp->wForwardRefPictureIndex = hdr_ref0->slot_idx; + pp->vop_time_increment_resolution = 30000; + pp->vop_width = hdr_curr->width; + pp->vop_height = hdr_curr->height; + + // Rockchip special data + pp->prev_coding_type = hdr_ref0->pict_type; + pp->header_bits = hdr_curr->hdr_bits; +} + +static void h263_syntax_init(h263d_dxva2_picture_context_t *syntax) +{ + DXVA2_DecodeBufferDesc *data = &syntax->desc[0]; + + //!< commit picture paramters + memset(data, 0, sizeof(*data)); + data->CompressedBufferType = DXVA2_PictureParametersBufferType; + data->pvPVPState = (void *)&syntax->pp; + data->DataSize = sizeof(syntax->pp); + syntax->data[0] = data; + + //!< commit bitstream + data = &syntax->desc[1]; + memset(data, 0, sizeof(*data)); + data->CompressedBufferType = DXVA2_BitStreamDateBufferType; + syntax->data[1] = data; +} + +static MPP_RET h263_parse_picture_header(H263dParserImpl *p, BitReadCtx_t *gb) +{ + RK_U32 val = 0; + H263Hdr *hdr_curr = &p->hdr_curr; + H263VOPType pict_type = H263_INVALID_VOP; + + /* start code */ + READ_BITS(gb, 17, &val, "start code"); + mpp_assert(val == 1); + + /* gob */ + READ_BITS(gb, 5, &val, "gob"); + mpp_assert(val == 0); + + /* time reference */ + READ_BITS(gb, 8, &hdr_curr->TR, "TR"); + + SKIP_BITS(gb, 5); + + /* source format */ + READ_BITS(gb, 3, &val, "source format"); + hdr_curr->width = h263d_fmt_to_dimension[val][0]; + hdr_curr->height = h263d_fmt_to_dimension[val][1]; + if (!hdr_curr->width && !hdr_curr->height) { + mpp_err_f("unsupport source format %d\n", val); + return MPP_NOK; + } + + READ_BITS(gb, 1, &val); + pict_type = val; + + SKIP_BITS(gb, 4); + + READ_BITS(gb, 5, &val); + hdr_curr->quant = val; + + SKIP_BITS(gb, 1); + + READ_BITS(gb, 1, &val); + while (val) { + SKIP_BITS(gb, 8); + READ_BITS(gb, 1, &val); + } + + if (!p->found_i_vop) + p->found_i_vop = (pict_type == H263_I_VOP); + + if (!p->found_i_vop) + return MPP_NOK; + + hdr_curr->hdr_bits = gb->used_bits; + hdr_curr->pict_type = pict_type; + + return MPP_OK; +__BITREAD_ERR: + mpp_err_f("found error stream\n"); + return MPP_ERR_STREAM; +} + +MPP_RET mpp_h263_parser_init(H263dParser *ctx, MppBufSlots frame_slots) +{ + BitReadCtx_t *bit_ctx = mpp_calloc(BitReadCtx_t, 1); + H263dParserImpl *p = mpp_calloc(H263dParserImpl, 1); + h263d_dxva2_picture_context_t *syntax = mpp_calloc(h263d_dxva2_picture_context_t, 1); + + if (NULL == p || NULL == bit_ctx || NULL == syntax) { + mpp_err_f("malloc context failed\n"); + if (p) + mpp_free(p); + if (bit_ctx) + mpp_free(bit_ctx); + if (syntax) + mpp_free(syntax); + return MPP_NOK; + } + + mpp_buf_slot_setup(frame_slots, 4); + p->frame_slots = frame_slots; + p->use_internal_pts = 0; + p->pos_frm_start = -1; + p->pos_frm_end = -1; + p->bit_ctx = bit_ctx; + p->hdr_curr.slot_idx = H263_INVALID_VOP; + p->hdr_ref0.slot_idx = H263_INVALID_VOP; + h263_syntax_init(syntax); + p->syntax = syntax; + + mpp_env_get_u32("h263d_debug", &h263d_debug, 0); + + *ctx = p; + return MPP_OK; +} + +MPP_RET mpp_h263_parser_deinit(H263dParser ctx) +{ + H263dParserImpl *p = (H263dParserImpl *)ctx; + if (p) { + if (p->bit_ctx) { + mpp_free(p->bit_ctx); + p->bit_ctx = NULL; + } + if (p->syntax) { + mpp_free(p->syntax); + p->syntax = NULL; + } + mpp_free(p); + } + return MPP_OK; +} + +MPP_RET mpp_h263_parser_flush(H263dParser ctx) +{ + H263dParserImpl *p = (H263dParserImpl *)ctx; + MppBufSlots slots = p->frame_slots; + H263Hdr *hdr_curr = &p->hdr_ref0; + RK_S32 index = hdr_curr->slot_idx; + + h263d_dbg_func("in\n"); + + if (!hdr_curr->enqueued && index >= 0) { + mpp_buf_slot_set_flag(slots, index, SLOT_QUEUE_USE); + mpp_buf_slot_enqueue(slots, index, QUEUE_DISPLAY); + hdr_curr->enqueued = 1; + } + + h263d_dbg_func("out\n"); + + return MPP_OK; +} + +MPP_RET mpp_h263_parser_reset(H263dParser ctx) +{ + H263dParserImpl *p = (H263dParserImpl *)ctx; + MppBufSlots slots = p->frame_slots; + H263Hdr *hdr_curr = &p->hdr_ref0; + H263Hdr *hdr_ref0 = &p->hdr_ref0; + RK_S32 index = hdr_curr->slot_idx; + + h263d_dbg_func("in\n"); + + if (index >= 0) { + mpp_buf_slot_clr_flag(slots, index, SLOT_CODEC_USE); + hdr_curr->slot_idx = -1; + } + + index = hdr_ref0->slot_idx; + if (index >= 0) { + mpp_buf_slot_clr_flag(slots, index, SLOT_CODEC_USE); + hdr_ref0->slot_idx = -1; + } + + p->found_i_vop = 0; + + h263d_dbg_func("out\n"); + + return MPP_OK; +} + +MPP_RET mpp_h263_parser_split(H263dParser ctx, MppPacket dst, MppPacket src) +{ + MPP_RET ret = MPP_NOK; + H263dParserImpl *p = (H263dParserImpl *)ctx; + RK_U8 *dst_buf = mpp_packet_get_data(dst); + size_t dst_len = mpp_packet_get_length(dst); + RK_U8 *src_buf = mpp_packet_get_pos(src); + RK_S32 src_len = (RK_S32)mpp_packet_get_length(src); + RK_S32 pos_frm_start = p->pos_frm_start; + RK_S32 pos_frm_end = p->pos_frm_end; + RK_U32 src_eos = mpp_packet_get_eos(src); + RK_S32 src_pos = 0; + RK_U32 state = (RK_U32) - 1; + + h263d_dbg_func("in\n"); + + mpp_assert(src_len); + + if (dst_len) { + mpp_assert(dst_len >= 4); + state = ((RK_U32)(dst_buf[dst_len - 1]) << 0) | + ((RK_U32)(dst_buf[dst_len - 2]) << 8) | + ((RK_U32)(dst_buf[dst_len - 3]) << 16) | + ((RK_U32)(dst_buf[dst_len - 4]) << 24); + } + + if (pos_frm_start < 0) { + // scan for frame start + for (src_pos = 0; src_pos < src_len; src_pos++) { + state = (state << 8) | src_buf[src_pos]; + if ((state & H263_STARTCODE_MASK) == H263_STARTCODE && + (state & H263_GOB_ZERO_MASK) == H263_GOB_ZERO) { + pos_frm_start = src_pos - 3; + src_pos++; + break; + } + } + } + + if (pos_frm_start >= 0) { + // scan for frame end + for (; src_pos < src_len; src_pos++) { + state = (state << 8) | src_buf[src_pos]; + + if ((state & H263_STARTCODE_MASK) == H263_STARTCODE && + (state & H263_GOB_ZERO_MASK) == H263_GOB_ZERO) { + pos_frm_end = src_pos - 3; + break; + } + } + if (src_eos && src_pos == src_len) { + pos_frm_end = src_len; + mpp_packet_set_eos(dst); + } + } + + //mpp_log("pkt pos: start %d end %d len: left %d in %d\n", + // pos_frm_start, pos_frm_end, dst_len, src_len); + + if (pos_frm_start < 0 || pos_frm_end < 0) { + // do not found frame start or do not found frame end, just copy the hold buffer to dst + memcpy(dst_buf + dst_len, src_buf, src_len); + // update dst buffer length + mpp_packet_set_length(dst, dst_len + src_len); + // set src buffer pos to end to src buffer + mpp_packet_set_pos(src, src_buf + src_len); + } else { + // found both frame start and frame end - only copy frame + memcpy(dst_buf + dst_len, src_buf, pos_frm_end); + mpp_packet_set_length(dst, dst_len + pos_frm_end); + + // set src buffer pos to end to src buffer + mpp_packet_set_pos(src, src_buf + pos_frm_end); + mpp_assert((RK_S32)mpp_packet_get_length(src) == (src_len - pos_frm_end)); + mpp_packet_set_length(src, src_len - pos_frm_end); + + // return ok indicate the frame is ready and reset frame start/end position + ret = MPP_OK; + pos_frm_start = -1; + pos_frm_end = -1; + } + + p->pos_frm_start = pos_frm_start; + p->pos_frm_end = pos_frm_end; + + h263d_dbg_func("out\n"); + + return ret; +} + +MPP_RET mpp_h263_parser_decode(H263dParser ctx, MppPacket pkt) +{ + MPP_RET ret = MPP_NOK; + H263dParserImpl *p = (H263dParserImpl *)ctx; + BitReadCtx_t *gb = p->bit_ctx; + RK_U8 *buf = mpp_packet_get_data(pkt); + RK_S32 len = (RK_S32)mpp_packet_get_length(pkt); + RK_U32 startcode = 0xff; + RK_S32 i = 0; + + h263d_dbg_func("in\n"); + + while (i < len) { + startcode = (startcode << 8) | buf[i++]; + + if (startcode >> (32 - 22) == 0x20) { + i -= 4; + h263d_dbg_bit("found startcode at byte %d\n", i); + break; + } + } + + if (i == len) { + mpp_err_f("can not found start code in len %d packet\n", len); + goto __BITREAD_ERR; + } + + // setup bit read context + mpp_set_bitread_ctx(gb, buf + i, len - i); + + ret = h263_parse_picture_header(p, gb); + if (ret) + goto __BITREAD_ERR; + + p->width = p->hdr_curr.width; + p->height = p->hdr_curr.height; + + if (!p->use_internal_pts) + p->pts = mpp_packet_get_pts(pkt); + +__BITREAD_ERR: + h263d_dbg_status("found i_frame %d frame_type %d ret %d\n", + p->found_i_vop, p->hdr_curr.pict_type, ret); + + mpp_packet_set_pos(pkt, buf); + mpp_packet_set_length(pkt, 0); + p->eos = mpp_packet_get_eos(pkt); + + h263d_dbg_func("out\n"); + + return ret; +} + +MPP_RET mpp_h263_parser_setup_syntax(H263dParser ctx, MppSyntax *syntax) +{ + H263dParserImpl *p = (H263dParserImpl *)ctx; + h263d_dxva2_picture_context_t *syn = p->syntax; + + h263d_dbg_func("in\n"); + + h263d_fill_picture_parameters(p, &syn->pp); + + // fill bit stream parameter + syn->data[1]->DataSize = p->bit_ctx->buf_len; + syn->data[1]->DataOffset = p->hdr_curr.hdr_bits; + syn->data[1]->pvPVPState = p->bit_ctx->buf; + + syntax->number = 2; + syntax->data = syn->data; + + h263d_dbg_func("out\n"); + + return MPP_OK; +} + +MPP_RET mpp_h263_parser_setup_hal_output(H263dParser ctx, RK_S32 *output) +{ + H263dParserImpl *p = (H263dParserImpl *)ctx; + RK_S32 index = -1; + + h263d_dbg_func("in\n"); + + if (p->found_i_vop) { + H263Hdr *hdr_curr = &p->hdr_curr; + MppBufSlots slots = p->frame_slots; + MppFrame frame = NULL; + + mpp_frame_init(&frame); + mpp_frame_set_width(frame, p->width); + mpp_frame_set_height(frame, p->height); + mpp_frame_set_hor_stride(frame, MPP_ALIGN(p->width, 16)); + mpp_frame_set_ver_stride(frame, MPP_ALIGN(p->height, 16)); + + /* + * set slots information + * 1. output index MUST be set + * 2. get unused index for output if needed + * 3. set output index as hal_input + * 4. set frame information to output index + * 5. if one frame can be display, it SHOULD be enqueued to display queue + */ + mpp_buf_slot_get_unused(slots, &index); + mpp_buf_slot_set_flag(slots, index, SLOT_HAL_OUTPUT); + mpp_frame_set_pts(frame, p->pts); + mpp_frame_set_mode(frame, MPP_FRAME_FLAG_FRAME); + + mpp_buf_slot_set_prop(slots, index, SLOT_FRAME, frame); + mpp_frame_deinit(&frame); + mpp_assert(NULL == frame); + + hdr_curr->slot_idx = index; + } + + p->output = index; + *output = index; + + h263d_dbg_func("out\n"); + + return MPP_OK; +} + +MPP_RET mpp_h263_parser_setup_refer(H263dParser ctx, RK_S32 *refer, RK_S32 max_ref) +{ + H263dParserImpl *p = (H263dParserImpl *)ctx; + H263Hdr *hdr_curr = &p->hdr_curr; + MppBufSlots slots = p->frame_slots; + RK_S32 index; + + h263d_dbg_func("in\n"); + + memset(refer, -1, sizeof(max_ref * sizeof(*refer))); + if (hdr_curr->pict_type == H263_P_VOP) { + index = p->hdr_ref0.slot_idx; + if (index >= 0) { + mpp_buf_slot_set_flag(slots, index, SLOT_HAL_INPUT); + refer[0] = index; + } + } + + h263d_dbg_func("out\n"); + + return MPP_OK; +} + +MPP_RET mpp_h263_parser_update_dpb(H263dParser ctx) +{ + H263dParserImpl *p = (H263dParserImpl *)ctx; + MppBufSlots slots = p->frame_slots; + H263Hdr *hdr_curr = &p->hdr_curr; + H263Hdr *hdr_ref0 = &p->hdr_ref0; + RK_S32 index = hdr_curr->slot_idx; + + h263d_dbg_func("in\n"); + + mpp_assert(index >= 0); + mpp_buf_slot_set_flag(slots, index, SLOT_CODEC_USE); + mpp_buf_slot_set_flag(slots, index, SLOT_QUEUE_USE); + mpp_buf_slot_enqueue(slots, index, QUEUE_DISPLAY); + hdr_curr->enqueued = 1; + + index = hdr_ref0->slot_idx; + if (index >= 0) { + mpp_buf_slot_clr_flag(slots, index, SLOT_CODEC_USE); + hdr_ref0->slot_idx = -1; + } + + // swap current to ref0 + *hdr_ref0 = *hdr_curr; + hdr_curr->slot_idx = H263_INVALID_VOP; + hdr_curr->pts = 0; + hdr_curr->enqueued = 0; + + h263d_dbg_func("out\n"); + + return MPP_OK; +} + +MPP_RET mpp_h263_parser_set_pts_mode(H263dParser ctx, RK_U32 use_internal_pts) +{ + H263dParserImpl *p = (H263dParserImpl *)ctx; + p->use_internal_pts = use_internal_pts; + return MPP_OK; +} + diff --git a/mpp/codec/dec/h264/h264d_dpb.h b/mpp/codec/dec/h264/h264d_dpb.h index 96146b2b..f8284d89 100644 --- a/mpp/codec/dec/h264/h264d_dpb.h +++ b/mpp/codec/dec/h264/h264d_dpb.h @@ -1,56 +1,56 @@ -/* -* -* Copyright 2015 Rockchip Electronics Co. LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#ifndef _H264D_DPB_H_ -#define _H264D_DPB_H_ - - -#include "rk_type.h" -#include "mpp_err.h" -#include "h264d_global.h" - - -#ifdef __cplusplus -extern "C" { -#endif - -void update_ref_list(H264_DpbBuf_t *p_Dpb); -void update_ltref_list(H264_DpbBuf_t *p_Dpb); -void free_storable_picture(H264_DecCtx_t *p_Dec, H264_StorePic_t *p); -void free_frame_store(H264_DecCtx_t *p_Dec, H264_FrameStore_t *f); - -MPP_RET idr_memory_management(H264_DpbBuf_t *p_Dpb, H264_StorePic_t *p); -MPP_RET insert_picture_in_dpb(H264dVideoCtx_t *p_Vid, H264_FrameStore_t *fs, H264_StorePic_t *p, RK_U8 combine_flag); -MPP_RET store_picture_in_dpb (H264_DpbBuf_t *p_Dpb, H264_StorePic_t *p); - -MPP_RET init_dpb (H264dVideoCtx_t *p_Vid, H264_DpbBuf_t *p_Dpb, RK_S32 type); -MPP_RET flush_dpb (H264_DpbBuf_t *p_Dpb, RK_S32 type); -MPP_RET output_dpb (H264_DecCtx_t *p_Dec, H264_DpbBuf_t *p_Dpb); - -void free_dpb (H264_DpbBuf_t *p_Dpb); -MPP_RET exit_picture(H264dVideoCtx_t *p_Vid, H264_StorePic_t **dec_pic); - -RK_U32 get_filed_dpb_combine_flag(H264_FrameStore_t *p_last, H264_StorePic_t *p); -H264_StorePic_t *alloc_storable_picture(H264dVideoCtx_t *p_Vid, RK_S32 structure); - -#ifdef __cplusplus -} -#endif - -//======================================== -#endif /* end of _H264D_DPB_H_ */ - +/* +* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef _H264D_DPB_H_ +#define _H264D_DPB_H_ + + +#include "rk_type.h" +#include "mpp_err.h" +#include "h264d_global.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +void update_ref_list(H264_DpbBuf_t *p_Dpb); +void update_ltref_list(H264_DpbBuf_t *p_Dpb); +void free_storable_picture(H264_DecCtx_t *p_Dec, H264_StorePic_t *p); +void free_frame_store(H264_DecCtx_t *p_Dec, H264_FrameStore_t *f); + +MPP_RET idr_memory_management(H264_DpbBuf_t *p_Dpb, H264_StorePic_t *p); +MPP_RET insert_picture_in_dpb(H264dVideoCtx_t *p_Vid, H264_FrameStore_t *fs, H264_StorePic_t *p, RK_U8 combine_flag); +MPP_RET store_picture_in_dpb (H264_DpbBuf_t *p_Dpb, H264_StorePic_t *p); + +MPP_RET init_dpb (H264dVideoCtx_t *p_Vid, H264_DpbBuf_t *p_Dpb, RK_S32 type); +MPP_RET flush_dpb (H264_DpbBuf_t *p_Dpb, RK_S32 type); +MPP_RET output_dpb (H264_DecCtx_t *p_Dec, H264_DpbBuf_t *p_Dpb); + +void free_dpb (H264_DpbBuf_t *p_Dpb); +MPP_RET exit_picture(H264dVideoCtx_t *p_Vid, H264_StorePic_t **dec_pic); + +RK_U32 get_filed_dpb_combine_flag(H264_FrameStore_t *p_last, H264_StorePic_t *p); +H264_StorePic_t *alloc_storable_picture(H264dVideoCtx_t *p_Vid, RK_S32 structure); + +#ifdef __cplusplus +} +#endif + +//======================================== +#endif /* end of _H264D_DPB_H_ */ + diff --git a/mpp/codec/dec/h264/h264d_fill.c b/mpp/codec/dec/h264/h264d_fill.c index b57b64eb..683e7c86 100644 --- a/mpp/codec/dec/h264/h264d_fill.c +++ b/mpp/codec/dec/h264/h264d_fill.c @@ -1,368 +1,368 @@ -/* -* -* Copyright 2015 Rockchip Electronics Co. LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#define MODULE_TAG "h264d_fill" - -#include -#include - -#include "mpp_mem.h" -#include "mpp_common.h" - -#include "h264d_log.h" -#include "h264d_fill.h" - - -static const RK_U8 start_code[3] = { 0, 0, 1 }; - -static MPP_RET realloc_slice_list(H264dDxvaCtx_t *dxva_ctx) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - - dxva_ctx->max_slice_size += ADD_SLICE_SIZE; - dxva_ctx->slice_long = mpp_realloc(dxva_ctx->slice_long, DXVA_Slice_H264_Long, dxva_ctx->max_slice_size); - MEM_CHECK(ret, dxva_ctx->slice_long); - - return ret = MPP_OK; -__FAILED: - return ret; -} -static MPP_RET fill_slice_stream(H264dDxvaCtx_t *dxva_ctx, H264_Nalu_t *p_nal) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - DXVA_Slice_H264_Long *p_long = NULL; - - if (dxva_ctx->slice_count >= dxva_ctx->max_slice_size) { - FUN_CHECK(ret = realloc_slice_list(dxva_ctx)); - } - p_long = &dxva_ctx->slice_long[dxva_ctx->slice_count]; - memset(p_long, 0, sizeof(DXVA_Slice_H264_Long)); - p_long->BSNALunitDataLocation = dxva_ctx->strm_offset; - p_long->wBadSliceChopping = 0; //!< set to 0 in Rock-Chip RKVDEC IP - - (void)p_nal; - return ret = MPP_OK; -__FAILED: - return ret; -} - -static void fill_picture_entry(DXVA_PicEntry_H264 *pic, RK_U32 index, RK_U32 flag) -{ - ASSERT((index & 0x7f) == index && (flag & 0x01) == flag); - pic->bPicEntry = index | (flag << 7); -} - - -/*! -*********************************************************************** -* \brief -* fill picture parameters -*********************************************************************** -*/ -//extern "C" -void fill_scanlist(H264dVideoCtx_t *p_Vid, DXVA_Qmatrix_H264 *qm) -{ - RK_S32 i = 0, j = 0; - - memset(qm, 0, sizeof(DXVA_Qmatrix_H264)); - for (i = 0; i < 6; ++i) { //!< 4x4, 6 lists - for (j = 0; j < H264ScalingList4x4Length; j++) { - qm->bScalingLists4x4[i][j] = p_Vid->qmatrix[i][j]; - } - } - for (i = 6; i < ((p_Vid->active_sps->chroma_format_idc != YUV444) ? 8 : 12); ++i) { - for (j = 0; j < H264ScalingList8x8Length; j++) { - qm->bScalingLists8x8[i - 6][j] = p_Vid->qmatrix[i][j]; - } - } -} -/*! -*********************************************************************** -* \brief -* fill picture parameters -*********************************************************************** -*/ -//extern "C" -void fill_picparams(H264dVideoCtx_t *p_Vid, DXVA_PicParams_H264_MVC *pp) -{ - RK_U32 i = 0, j = 0, num_views = 0; - H264_StorePic_t *dec_pic = p_Vid->dec_pic; - H264_DpbInfo_t *dpb_info = p_Vid->p_Dec->dpb_info; - - memset(pp, 0, sizeof(DXVA_PicParams_H264_MVC)); - //!< Configure current picture - fill_picture_entry(&pp->CurrPic, dec_pic->mem_mark->slot_idx, dec_pic->structure == BOTTOM_FIELD); - //mpp_log_f("[DEC_OUT]line=%d, func = fill_picparams, In_cur_slot_idx=%d, Out_cur_slot_idx=%d", __LINE__, dec_pic->mem_mark->slot_idx, pp->CurrPic.Index7Bits); - //!< Configure the set of references - pp->UsedForReferenceFlags = 0; - pp->NonExistingFrameFlags = 0; - for (i = 0; i < MPP_ARRAY_ELEMS(pp->RefFrameList); i++) { - if (dpb_info[i].refpic) { - fill_picture_entry(&pp->RefFrameList[i], dpb_info[i].slot_index, dpb_info[i].is_long_term); - pp->FieldOrderCntList[i][0] = dpb_info[i].TOP_POC; - pp->FieldOrderCntList[i][1] = dpb_info[i].BOT_POC; - pp->FrameNumList[i] = dpb_info[i].is_long_term ? dpb_info[i].long_term_frame_idx : dpb_info[i].frame_num; - pp->LongTermPicNumList[i] = dpb_info[i].long_term_pic_num; - if (dpb_info[i].is_used & 0x01) { //!< top_field - pp->UsedForReferenceFlags |= 1 << (2 * i + 0); - } - if (dpb_info[i].is_used & 0x02) { //!< bot_field - pp->UsedForReferenceFlags |= 1 << (2 * i + 1); - } - } else { - pp->RefFrameList[i].bPicEntry = 0xff; - pp->FieldOrderCntList[i][0] = 0; - pp->FieldOrderCntList[i][1] = 0; - pp->FrameNumList[i] = 0; - } - } - pp->wFrameWidthInMbsMinus1 = p_Vid->active_sps->pic_width_in_mbs_minus1; - pp->wFrameHeightInMbsMinus1 = p_Vid->active_sps->pic_height_in_map_units_minus1; - pp->num_ref_frames = p_Vid->active_sps->max_num_ref_frames; - - pp->wBitFields = ((dec_pic->iCodingType == FIELD_CODING) << 0) //!< field_pic_flag - | (dec_pic->mb_aff_frame_flag << 1) //!< MbaffFrameFlag - | (0 << 2) //!< residual_colour_transform_flag - | (0 << 3) //!< sp_for_switch_flag - | (p_Vid->active_sps->chroma_format_idc << 4) //!< chroma_format_idc - | (dec_pic->used_for_reference << 6) //!< RefPicFlag - | (p_Vid->active_pps->constrained_intra_pred_flag << 7) //!< constrained_intra_pred_flag - | (p_Vid->active_pps->weighted_pred_flag << 8) //!< weighted_pred_flag - | (p_Vid->active_pps->weighted_bipred_idc << 9) //!< weighted_bipred_idc - | (1 << 11) //!< MbsConsecutiveFlag - | (p_Vid->active_sps->frame_mbs_only_flag << 12) //!< frame_mbs_only_flag - | (p_Vid->active_pps->transform_8x8_mode_flag << 13) //!< transform_8x8_mode_flag - | ((p_Vid->active_sps->level_idc >= 31) << 14) //!< MinLumaBipredSize8x8Flag - | (1 << 15); //!< IntraPicFlag (Modified if we detect a non-intra slice in dxva2_h264_decode_slice) - - pp->bit_depth_luma_minus8 = p_Vid->active_sps->bit_depth_luma_minus8; - pp->bit_depth_chroma_minus8 = p_Vid->active_sps->bit_depth_chroma_minus8; - pp->Reserved16Bits = 3; //!< FIXME is there a way to detect the right mode - - pp->StatusReportFeedbackNumber = 1 /*+ ctx->report_id++*/; - - pp->CurrFieldOrderCnt[0] = 0; - if (dec_pic->structure == TOP_FIELD || dec_pic->structure == FRAME) { - pp->CurrFieldOrderCnt[0] = dec_pic->top_poc; - } - pp->CurrFieldOrderCnt[1] = 0; - if (dec_pic->structure == BOTTOM_FIELD || dec_pic->structure == FRAME) { - pp->CurrFieldOrderCnt[1] = dec_pic->bottom_poc; - } - pp->pic_init_qs_minus26 = p_Vid->active_pps->pic_init_qs_minus26; - pp->chroma_qp_index_offset = p_Vid->active_pps->chroma_qp_index_offset; - pp->second_chroma_qp_index_offset = p_Vid->active_pps->second_chroma_qp_index_offset; - pp->ContinuationFlag = 1; - pp->pic_init_qp_minus26 = p_Vid->active_pps->pic_init_qp_minus26; - pp->num_ref_idx_l0_active_minus1 = p_Vid->active_pps->num_ref_idx_l0_default_active_minus1; - pp->num_ref_idx_l1_active_minus1 = p_Vid->active_pps->num_ref_idx_l1_default_active_minus1; - pp->Reserved8BitsA = 0; - - pp->frame_num = dec_pic->frame_num; - pp->log2_max_frame_num_minus4 = p_Vid->active_sps->log2_max_frame_num_minus4; - pp->pic_order_cnt_type = p_Vid->active_sps->pic_order_cnt_type; - if (pp->pic_order_cnt_type == 0) { - pp->log2_max_pic_order_cnt_lsb_minus4 = p_Vid->active_sps->log2_max_pic_order_cnt_lsb_minus4; - } else if (pp->pic_order_cnt_type == 1) { - pp->delta_pic_order_always_zero_flag = p_Vid->active_sps->delta_pic_order_always_zero_flag; - } - pp->direct_8x8_inference_flag = p_Vid->active_sps->direct_8x8_inference_flag; - pp->entropy_coding_mode_flag = p_Vid->active_pps->entropy_coding_mode_flag; - pp->pic_order_present_flag = p_Vid->active_pps->bottom_field_pic_order_in_frame_present_flag; - pp->num_slice_groups_minus1 = p_Vid->active_pps->num_slice_groups_minus1; - pp->slice_group_map_type = p_Vid->active_pps->slice_group_map_type; - pp->deblocking_filter_control_present_flag = p_Vid->active_pps->deblocking_filter_control_present_flag; - pp->redundant_pic_cnt_present_flag = p_Vid->active_pps->redundant_pic_cnt_present_flag; - pp->Reserved8BitsB = 0; - pp->slice_group_change_rate_minus1 = 0; //!< XXX not implemented by FFmpeg - //pp->SliceGroupMap[810]; //!< XXX not implemented by FFmpeg - - //!< Following are H.264 MVC Specific parameters - if (p_Vid->active_subsps) { - pp->num_views_minus1 = p_Vid->active_subsps->num_views_minus1; - num_views = 1 + pp->num_views_minus1; - ASSERT(num_views <= 16); - for (i = 0; i < num_views; i++) { - pp->view_id[i] = p_Vid->active_subsps->view_id[i]; - pp->num_anchor_refs_l0[i] = p_Vid->active_subsps->num_anchor_refs_l0[i]; - for (j = 0; j < pp->num_anchor_refs_l0[i]; j++) { - pp->anchor_ref_l0[i][j] = p_Vid->active_subsps->anchor_ref_l0[i][j]; - } - pp->num_anchor_refs_l1[i] = p_Vid->active_subsps->num_anchor_refs_l1[i]; - for (j = 0; j < pp->num_anchor_refs_l1[i]; j++) { - pp->anchor_ref_l1[i][j] = p_Vid->active_subsps->anchor_ref_l1[i][j]; - } - pp->num_non_anchor_refs_l0[i] = p_Vid->active_subsps->num_non_anchor_refs_l0[i]; - for (j = 0; j < pp->num_non_anchor_refs_l0[i]; j++) { - pp->non_anchor_ref_l0[i][j] = p_Vid->active_subsps->non_anchor_ref_l0[i][j]; - } - pp->num_non_anchor_refs_l1[i] = p_Vid->active_subsps->num_non_anchor_refs_l1[i]; - for (j = 0; j < pp->num_non_anchor_refs_l1[i]; j++) { - pp->non_anchor_ref_l1[i][j] = p_Vid->active_subsps->non_anchor_ref_l1[i][j]; - } - } - for (i = num_views; i < 16; i++) { - pp->view_id[i] = 0xffff; - } - } - pp->curr_view_id = dec_pic->view_id; - pp->anchor_pic_flag = dec_pic->anchor_pic_flag; - pp->inter_view_flag = dec_pic->inter_view_flag; - for (i = 0; i < 16; i++) { - pp->ViewIDList[i] = dpb_info[i].view_id; - } - //!< add in Rock-chip RKVDEC IP - pp->curr_layer_id = dec_pic->layer_id; - pp->UsedForInTerviewflags = 0; - for (i = 0; i < MPP_ARRAY_ELEMS(pp->RefFrameList); i++) { - if (dpb_info[i].colmv_is_used) { - pp->RefPicColmvUsedFlags |= 1 << i; - } - if (dpb_info[i].field_flag) { - pp->RefPicFiledFlags |= 1 << i; - } - if (dpb_info[i].is_ilt_flag) { - pp->UsedForInTerviewflags |= 1 << i; - } - pp->RefPicLayerIdList[i] = dpb_info[i].voidx; - } - if (p_Vid->active_pps->pic_scaling_matrix_present_flag - || p_Vid->active_sps->seq_scaling_matrix_present_flag) { - pp->scaleing_list_enable_flag = 1; - } else { - pp->scaleing_list_enable_flag = 0; - } -} - -/*! -*********************************************************************** -* \brief -* fill slice short struct -*********************************************************************** -*/ -//extern "C" -MPP_RET fill_slice_syntax(H264_SLICE_t *currSlice, H264dDxvaCtx_t *dxva_ctx) -{ - RK_U32 list = 0, i = 0; - MPP_RET ret = MPP_ERR_UNKNOW; - DXVA_Slice_H264_Long *p_long = NULL; - RK_S32 dpb_idx = 0, dpb_valid = 0, bottom_flag = 0; - - FUN_CHECK(ret = fill_slice_stream(dxva_ctx, &currSlice->p_Cur->nalu)); - p_long = &dxva_ctx->slice_long[dxva_ctx->slice_count]; - //!< fill slice long contents - p_long->first_mb_in_slice = currSlice->start_mb_nr; - p_long->NumMbsForSlice = 0; //!< XXX it is set once we have all slices - p_long->slice_type = currSlice->slice_type; - p_long->num_ref_idx_l0_active_minus1 = currSlice->active_pps->num_ref_idx_l0_default_active_minus1; - p_long->num_ref_idx_l1_active_minus1 = currSlice->active_pps->num_ref_idx_l1_default_active_minus1; - p_long->redundant_pic_cnt = currSlice->redundant_pic_cnt; - p_long->direct_spatial_mv_pred_flag = currSlice->direct_spatial_mv_pred_flag; - p_long->slice_id = dxva_ctx->slice_count; - //!< add parameters - p_long->active_sps_id = currSlice->active_sps->seq_parameter_set_id; - p_long->active_pps_id = currSlice->active_pps->pic_parameter_set_id; - p_long->idr_pic_id = currSlice->idr_pic_id; - p_long->idr_flag = currSlice->idr_flag; - p_long->drpm_used_bitlen = currSlice->drpm_used_bitlen; - p_long->poc_used_bitlen = currSlice->poc_used_bitlen; - p_long->nal_ref_idc = currSlice->nal_reference_idc; - p_long->profileIdc = currSlice->active_sps->profile_idc; - - - - - for (i = 0; i < MPP_ARRAY_ELEMS(p_long->RefPicList[0]); i++) { - dpb_idx = currSlice->p_Dec->refpic_info_p[i].dpb_idx; - dpb_valid = currSlice->p_Dec->refpic_info_p[i].valid; - //dpb_valid = (currSlice->p_Dec->dpb_info[dpb_idx].refpic ? 1 : 0); - if (dpb_valid) { - bottom_flag = currSlice->p_Dec->refpic_info_p[i].bottom_flag; - fill_picture_entry(&p_long->RefPicList[0][i], dpb_idx, bottom_flag); - } else { - p_long->RefPicList[0][i].bPicEntry = 0xff; - } - } - - for (list = 0; list < 2; list++) { - for (i = 0; i < MPP_ARRAY_ELEMS(p_long->RefPicList[list + 1]); i++) { - dpb_idx = currSlice->p_Dec->refpic_info_b[list][i].dpb_idx; - dpb_valid = currSlice->p_Dec->refpic_info_b[list][i].valid; - //dpb_valid = (currSlice->p_Dec->dpb_info[dpb_idx].refpic ? 1 : 0); - if (dpb_valid) { - bottom_flag = currSlice->p_Dec->refpic_info_b[list][i].bottom_flag; - fill_picture_entry(&p_long->RefPicList[list + 1][i], dpb_idx, bottom_flag); - } else { - p_long->RefPicList[list + 1][i].bPicEntry = 0xff; - } - } - } - dxva_ctx->slice_count++; - - return ret = MPP_OK; -__FAILED: - return ret; -} - - -/*! -*********************************************************************** -* \brief -* check parser is end and then configure register -*********************************************************************** -*/ -//extern "C" -void commit_buffer(H264dDxvaCtx_t *dxva_ctx) -{ - H264dSyntax_t *p_syn = &dxva_ctx->syn; - DXVA2_DecodeBufferDesc *p_dec = NULL; - - p_syn->num = 0; - //!< commit picture paramters - p_dec = &p_syn->buf[p_syn->num++]; - memset(p_dec, 0, sizeof(DXVA2_DecodeBufferDesc)); - p_dec->CompressedBufferType = DXVA2_PictureParametersBufferType; - p_dec->pvPVPState = (void *)&dxva_ctx->pp; - p_dec->DataSize = sizeof(DXVA_PicParams_H264_MVC); - p_dec->NumMBsInBuffer = 0; - //!< commit scanlist Qmatrix - p_dec = &p_syn->buf[p_syn->num++]; - memset(p_dec, 0, sizeof(DXVA2_DecodeBufferDesc)); - p_dec->CompressedBufferType = DXVA2_InverseQuantizationMatrixBufferType; - p_dec->pvPVPState = (void *)&dxva_ctx->qm; - p_dec->DataSize = sizeof(DXVA_Qmatrix_H264); - p_dec->NumMBsInBuffer = 0; - //!< commit bitstream - p_dec = &p_syn->buf[p_syn->num++]; - memset(p_dec, 0, sizeof(DXVA2_DecodeBufferDesc)); - p_dec->CompressedBufferType = DXVA2_BitStreamDateBufferType; - p_dec->DataSize = MPP_ALIGN(dxva_ctx->strm_offset, 16); - memset(dxva_ctx->bitstream + dxva_ctx->strm_offset, 0, p_dec->DataSize - dxva_ctx->strm_offset); - p_dec->pvPVPState = (void *)dxva_ctx->bitstream; - //!< commit slice control, DXVA_Slice_H264_Long - p_dec = &p_syn->buf[p_syn->num++]; - memset(p_dec, 0, sizeof(DXVA2_DecodeBufferDesc)); - p_dec->CompressedBufferType = DXVA2_SliceControlBufferType; - p_dec->NumMBsInBuffer = (dxva_ctx->pp.wFrameHeightInMbsMinus1 + 1) - * (dxva_ctx->pp.wFrameWidthInMbsMinus1 + 1); - p_dec->pvPVPState = dxva_ctx->slice_long; - p_dec->DataSize = dxva_ctx->slice_count * sizeof(DXVA_Slice_H264_Long); - - //!< reset dxva parameters - dxva_ctx->slice_count = 0; - dxva_ctx->strm_offset = 0; -} +/* +* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#define MODULE_TAG "h264d_fill" + +#include +#include + +#include "mpp_mem.h" +#include "mpp_common.h" + +#include "h264d_log.h" +#include "h264d_fill.h" + + +static const RK_U8 start_code[3] = { 0, 0, 1 }; + +static MPP_RET realloc_slice_list(H264dDxvaCtx_t *dxva_ctx) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + + dxva_ctx->max_slice_size += ADD_SLICE_SIZE; + dxva_ctx->slice_long = mpp_realloc(dxva_ctx->slice_long, DXVA_Slice_H264_Long, dxva_ctx->max_slice_size); + MEM_CHECK(ret, dxva_ctx->slice_long); + + return ret = MPP_OK; +__FAILED: + return ret; +} +static MPP_RET fill_slice_stream(H264dDxvaCtx_t *dxva_ctx, H264_Nalu_t *p_nal) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + DXVA_Slice_H264_Long *p_long = NULL; + + if (dxva_ctx->slice_count >= dxva_ctx->max_slice_size) { + FUN_CHECK(ret = realloc_slice_list(dxva_ctx)); + } + p_long = &dxva_ctx->slice_long[dxva_ctx->slice_count]; + memset(p_long, 0, sizeof(DXVA_Slice_H264_Long)); + p_long->BSNALunitDataLocation = dxva_ctx->strm_offset; + p_long->wBadSliceChopping = 0; //!< set to 0 in Rock-Chip RKVDEC IP + + (void)p_nal; + return ret = MPP_OK; +__FAILED: + return ret; +} + +static void fill_picture_entry(DXVA_PicEntry_H264 *pic, RK_U32 index, RK_U32 flag) +{ + ASSERT((index & 0x7f) == index && (flag & 0x01) == flag); + pic->bPicEntry = index | (flag << 7); +} + + +/*! +*********************************************************************** +* \brief +* fill picture parameters +*********************************************************************** +*/ +//extern "C" +void fill_scanlist(H264dVideoCtx_t *p_Vid, DXVA_Qmatrix_H264 *qm) +{ + RK_S32 i = 0, j = 0; + + memset(qm, 0, sizeof(DXVA_Qmatrix_H264)); + for (i = 0; i < 6; ++i) { //!< 4x4, 6 lists + for (j = 0; j < H264ScalingList4x4Length; j++) { + qm->bScalingLists4x4[i][j] = p_Vid->qmatrix[i][j]; + } + } + for (i = 6; i < ((p_Vid->active_sps->chroma_format_idc != YUV444) ? 8 : 12); ++i) { + for (j = 0; j < H264ScalingList8x8Length; j++) { + qm->bScalingLists8x8[i - 6][j] = p_Vid->qmatrix[i][j]; + } + } +} +/*! +*********************************************************************** +* \brief +* fill picture parameters +*********************************************************************** +*/ +//extern "C" +void fill_picparams(H264dVideoCtx_t *p_Vid, DXVA_PicParams_H264_MVC *pp) +{ + RK_U32 i = 0, j = 0, num_views = 0; + H264_StorePic_t *dec_pic = p_Vid->dec_pic; + H264_DpbInfo_t *dpb_info = p_Vid->p_Dec->dpb_info; + + memset(pp, 0, sizeof(DXVA_PicParams_H264_MVC)); + //!< Configure current picture + fill_picture_entry(&pp->CurrPic, dec_pic->mem_mark->slot_idx, dec_pic->structure == BOTTOM_FIELD); + //mpp_log_f("[DEC_OUT]line=%d, func = fill_picparams, In_cur_slot_idx=%d, Out_cur_slot_idx=%d", __LINE__, dec_pic->mem_mark->slot_idx, pp->CurrPic.Index7Bits); + //!< Configure the set of references + pp->UsedForReferenceFlags = 0; + pp->NonExistingFrameFlags = 0; + for (i = 0; i < MPP_ARRAY_ELEMS(pp->RefFrameList); i++) { + if (dpb_info[i].refpic) { + fill_picture_entry(&pp->RefFrameList[i], dpb_info[i].slot_index, dpb_info[i].is_long_term); + pp->FieldOrderCntList[i][0] = dpb_info[i].TOP_POC; + pp->FieldOrderCntList[i][1] = dpb_info[i].BOT_POC; + pp->FrameNumList[i] = dpb_info[i].is_long_term ? dpb_info[i].long_term_frame_idx : dpb_info[i].frame_num; + pp->LongTermPicNumList[i] = dpb_info[i].long_term_pic_num; + if (dpb_info[i].is_used & 0x01) { //!< top_field + pp->UsedForReferenceFlags |= 1 << (2 * i + 0); + } + if (dpb_info[i].is_used & 0x02) { //!< bot_field + pp->UsedForReferenceFlags |= 1 << (2 * i + 1); + } + } else { + pp->RefFrameList[i].bPicEntry = 0xff; + pp->FieldOrderCntList[i][0] = 0; + pp->FieldOrderCntList[i][1] = 0; + pp->FrameNumList[i] = 0; + } + } + pp->wFrameWidthInMbsMinus1 = p_Vid->active_sps->pic_width_in_mbs_minus1; + pp->wFrameHeightInMbsMinus1 = p_Vid->active_sps->pic_height_in_map_units_minus1; + pp->num_ref_frames = p_Vid->active_sps->max_num_ref_frames; + + pp->wBitFields = ((dec_pic->iCodingType == FIELD_CODING) << 0) //!< field_pic_flag + | (dec_pic->mb_aff_frame_flag << 1) //!< MbaffFrameFlag + | (0 << 2) //!< residual_colour_transform_flag + | (0 << 3) //!< sp_for_switch_flag + | (p_Vid->active_sps->chroma_format_idc << 4) //!< chroma_format_idc + | (dec_pic->used_for_reference << 6) //!< RefPicFlag + | (p_Vid->active_pps->constrained_intra_pred_flag << 7) //!< constrained_intra_pred_flag + | (p_Vid->active_pps->weighted_pred_flag << 8) //!< weighted_pred_flag + | (p_Vid->active_pps->weighted_bipred_idc << 9) //!< weighted_bipred_idc + | (1 << 11) //!< MbsConsecutiveFlag + | (p_Vid->active_sps->frame_mbs_only_flag << 12) //!< frame_mbs_only_flag + | (p_Vid->active_pps->transform_8x8_mode_flag << 13) //!< transform_8x8_mode_flag + | ((p_Vid->active_sps->level_idc >= 31) << 14) //!< MinLumaBipredSize8x8Flag + | (1 << 15); //!< IntraPicFlag (Modified if we detect a non-intra slice in dxva2_h264_decode_slice) + + pp->bit_depth_luma_minus8 = p_Vid->active_sps->bit_depth_luma_minus8; + pp->bit_depth_chroma_minus8 = p_Vid->active_sps->bit_depth_chroma_minus8; + pp->Reserved16Bits = 3; //!< FIXME is there a way to detect the right mode + + pp->StatusReportFeedbackNumber = 1 /*+ ctx->report_id++*/; + + pp->CurrFieldOrderCnt[0] = 0; + if (dec_pic->structure == TOP_FIELD || dec_pic->structure == FRAME) { + pp->CurrFieldOrderCnt[0] = dec_pic->top_poc; + } + pp->CurrFieldOrderCnt[1] = 0; + if (dec_pic->structure == BOTTOM_FIELD || dec_pic->structure == FRAME) { + pp->CurrFieldOrderCnt[1] = dec_pic->bottom_poc; + } + pp->pic_init_qs_minus26 = p_Vid->active_pps->pic_init_qs_minus26; + pp->chroma_qp_index_offset = p_Vid->active_pps->chroma_qp_index_offset; + pp->second_chroma_qp_index_offset = p_Vid->active_pps->second_chroma_qp_index_offset; + pp->ContinuationFlag = 1; + pp->pic_init_qp_minus26 = p_Vid->active_pps->pic_init_qp_minus26; + pp->num_ref_idx_l0_active_minus1 = p_Vid->active_pps->num_ref_idx_l0_default_active_minus1; + pp->num_ref_idx_l1_active_minus1 = p_Vid->active_pps->num_ref_idx_l1_default_active_minus1; + pp->Reserved8BitsA = 0; + + pp->frame_num = dec_pic->frame_num; + pp->log2_max_frame_num_minus4 = p_Vid->active_sps->log2_max_frame_num_minus4; + pp->pic_order_cnt_type = p_Vid->active_sps->pic_order_cnt_type; + if (pp->pic_order_cnt_type == 0) { + pp->log2_max_pic_order_cnt_lsb_minus4 = p_Vid->active_sps->log2_max_pic_order_cnt_lsb_minus4; + } else if (pp->pic_order_cnt_type == 1) { + pp->delta_pic_order_always_zero_flag = p_Vid->active_sps->delta_pic_order_always_zero_flag; + } + pp->direct_8x8_inference_flag = p_Vid->active_sps->direct_8x8_inference_flag; + pp->entropy_coding_mode_flag = p_Vid->active_pps->entropy_coding_mode_flag; + pp->pic_order_present_flag = p_Vid->active_pps->bottom_field_pic_order_in_frame_present_flag; + pp->num_slice_groups_minus1 = p_Vid->active_pps->num_slice_groups_minus1; + pp->slice_group_map_type = p_Vid->active_pps->slice_group_map_type; + pp->deblocking_filter_control_present_flag = p_Vid->active_pps->deblocking_filter_control_present_flag; + pp->redundant_pic_cnt_present_flag = p_Vid->active_pps->redundant_pic_cnt_present_flag; + pp->Reserved8BitsB = 0; + pp->slice_group_change_rate_minus1 = 0; //!< XXX not implemented by FFmpeg + //pp->SliceGroupMap[810]; //!< XXX not implemented by FFmpeg + + //!< Following are H.264 MVC Specific parameters + if (p_Vid->active_subsps) { + pp->num_views_minus1 = p_Vid->active_subsps->num_views_minus1; + num_views = 1 + pp->num_views_minus1; + ASSERT(num_views <= 16); + for (i = 0; i < num_views; i++) { + pp->view_id[i] = p_Vid->active_subsps->view_id[i]; + pp->num_anchor_refs_l0[i] = p_Vid->active_subsps->num_anchor_refs_l0[i]; + for (j = 0; j < pp->num_anchor_refs_l0[i]; j++) { + pp->anchor_ref_l0[i][j] = p_Vid->active_subsps->anchor_ref_l0[i][j]; + } + pp->num_anchor_refs_l1[i] = p_Vid->active_subsps->num_anchor_refs_l1[i]; + for (j = 0; j < pp->num_anchor_refs_l1[i]; j++) { + pp->anchor_ref_l1[i][j] = p_Vid->active_subsps->anchor_ref_l1[i][j]; + } + pp->num_non_anchor_refs_l0[i] = p_Vid->active_subsps->num_non_anchor_refs_l0[i]; + for (j = 0; j < pp->num_non_anchor_refs_l0[i]; j++) { + pp->non_anchor_ref_l0[i][j] = p_Vid->active_subsps->non_anchor_ref_l0[i][j]; + } + pp->num_non_anchor_refs_l1[i] = p_Vid->active_subsps->num_non_anchor_refs_l1[i]; + for (j = 0; j < pp->num_non_anchor_refs_l1[i]; j++) { + pp->non_anchor_ref_l1[i][j] = p_Vid->active_subsps->non_anchor_ref_l1[i][j]; + } + } + for (i = num_views; i < 16; i++) { + pp->view_id[i] = 0xffff; + } + } + pp->curr_view_id = dec_pic->view_id; + pp->anchor_pic_flag = dec_pic->anchor_pic_flag; + pp->inter_view_flag = dec_pic->inter_view_flag; + for (i = 0; i < 16; i++) { + pp->ViewIDList[i] = dpb_info[i].view_id; + } + //!< add in Rock-chip RKVDEC IP + pp->curr_layer_id = dec_pic->layer_id; + pp->UsedForInTerviewflags = 0; + for (i = 0; i < MPP_ARRAY_ELEMS(pp->RefFrameList); i++) { + if (dpb_info[i].colmv_is_used) { + pp->RefPicColmvUsedFlags |= 1 << i; + } + if (dpb_info[i].field_flag) { + pp->RefPicFiledFlags |= 1 << i; + } + if (dpb_info[i].is_ilt_flag) { + pp->UsedForInTerviewflags |= 1 << i; + } + pp->RefPicLayerIdList[i] = dpb_info[i].voidx; + } + if (p_Vid->active_pps->pic_scaling_matrix_present_flag + || p_Vid->active_sps->seq_scaling_matrix_present_flag) { + pp->scaleing_list_enable_flag = 1; + } else { + pp->scaleing_list_enable_flag = 0; + } +} + +/*! +*********************************************************************** +* \brief +* fill slice short struct +*********************************************************************** +*/ +//extern "C" +MPP_RET fill_slice_syntax(H264_SLICE_t *currSlice, H264dDxvaCtx_t *dxva_ctx) +{ + RK_U32 list = 0, i = 0; + MPP_RET ret = MPP_ERR_UNKNOW; + DXVA_Slice_H264_Long *p_long = NULL; + RK_S32 dpb_idx = 0, dpb_valid = 0, bottom_flag = 0; + + FUN_CHECK(ret = fill_slice_stream(dxva_ctx, &currSlice->p_Cur->nalu)); + p_long = &dxva_ctx->slice_long[dxva_ctx->slice_count]; + //!< fill slice long contents + p_long->first_mb_in_slice = currSlice->start_mb_nr; + p_long->NumMbsForSlice = 0; //!< XXX it is set once we have all slices + p_long->slice_type = currSlice->slice_type; + p_long->num_ref_idx_l0_active_minus1 = currSlice->active_pps->num_ref_idx_l0_default_active_minus1; + p_long->num_ref_idx_l1_active_minus1 = currSlice->active_pps->num_ref_idx_l1_default_active_minus1; + p_long->redundant_pic_cnt = currSlice->redundant_pic_cnt; + p_long->direct_spatial_mv_pred_flag = currSlice->direct_spatial_mv_pred_flag; + p_long->slice_id = dxva_ctx->slice_count; + //!< add parameters + p_long->active_sps_id = currSlice->active_sps->seq_parameter_set_id; + p_long->active_pps_id = currSlice->active_pps->pic_parameter_set_id; + p_long->idr_pic_id = currSlice->idr_pic_id; + p_long->idr_flag = currSlice->idr_flag; + p_long->drpm_used_bitlen = currSlice->drpm_used_bitlen; + p_long->poc_used_bitlen = currSlice->poc_used_bitlen; + p_long->nal_ref_idc = currSlice->nal_reference_idc; + p_long->profileIdc = currSlice->active_sps->profile_idc; + + + + + for (i = 0; i < MPP_ARRAY_ELEMS(p_long->RefPicList[0]); i++) { + dpb_idx = currSlice->p_Dec->refpic_info_p[i].dpb_idx; + dpb_valid = currSlice->p_Dec->refpic_info_p[i].valid; + //dpb_valid = (currSlice->p_Dec->dpb_info[dpb_idx].refpic ? 1 : 0); + if (dpb_valid) { + bottom_flag = currSlice->p_Dec->refpic_info_p[i].bottom_flag; + fill_picture_entry(&p_long->RefPicList[0][i], dpb_idx, bottom_flag); + } else { + p_long->RefPicList[0][i].bPicEntry = 0xff; + } + } + + for (list = 0; list < 2; list++) { + for (i = 0; i < MPP_ARRAY_ELEMS(p_long->RefPicList[list + 1]); i++) { + dpb_idx = currSlice->p_Dec->refpic_info_b[list][i].dpb_idx; + dpb_valid = currSlice->p_Dec->refpic_info_b[list][i].valid; + //dpb_valid = (currSlice->p_Dec->dpb_info[dpb_idx].refpic ? 1 : 0); + if (dpb_valid) { + bottom_flag = currSlice->p_Dec->refpic_info_b[list][i].bottom_flag; + fill_picture_entry(&p_long->RefPicList[list + 1][i], dpb_idx, bottom_flag); + } else { + p_long->RefPicList[list + 1][i].bPicEntry = 0xff; + } + } + } + dxva_ctx->slice_count++; + + return ret = MPP_OK; +__FAILED: + return ret; +} + + +/*! +*********************************************************************** +* \brief +* check parser is end and then configure register +*********************************************************************** +*/ +//extern "C" +void commit_buffer(H264dDxvaCtx_t *dxva_ctx) +{ + H264dSyntax_t *p_syn = &dxva_ctx->syn; + DXVA2_DecodeBufferDesc *p_dec = NULL; + + p_syn->num = 0; + //!< commit picture paramters + p_dec = &p_syn->buf[p_syn->num++]; + memset(p_dec, 0, sizeof(DXVA2_DecodeBufferDesc)); + p_dec->CompressedBufferType = DXVA2_PictureParametersBufferType; + p_dec->pvPVPState = (void *)&dxva_ctx->pp; + p_dec->DataSize = sizeof(DXVA_PicParams_H264_MVC); + p_dec->NumMBsInBuffer = 0; + //!< commit scanlist Qmatrix + p_dec = &p_syn->buf[p_syn->num++]; + memset(p_dec, 0, sizeof(DXVA2_DecodeBufferDesc)); + p_dec->CompressedBufferType = DXVA2_InverseQuantizationMatrixBufferType; + p_dec->pvPVPState = (void *)&dxva_ctx->qm; + p_dec->DataSize = sizeof(DXVA_Qmatrix_H264); + p_dec->NumMBsInBuffer = 0; + //!< commit bitstream + p_dec = &p_syn->buf[p_syn->num++]; + memset(p_dec, 0, sizeof(DXVA2_DecodeBufferDesc)); + p_dec->CompressedBufferType = DXVA2_BitStreamDateBufferType; + p_dec->DataSize = MPP_ALIGN(dxva_ctx->strm_offset, 16); + memset(dxva_ctx->bitstream + dxva_ctx->strm_offset, 0, p_dec->DataSize - dxva_ctx->strm_offset); + p_dec->pvPVPState = (void *)dxva_ctx->bitstream; + //!< commit slice control, DXVA_Slice_H264_Long + p_dec = &p_syn->buf[p_syn->num++]; + memset(p_dec, 0, sizeof(DXVA2_DecodeBufferDesc)); + p_dec->CompressedBufferType = DXVA2_SliceControlBufferType; + p_dec->NumMBsInBuffer = (dxva_ctx->pp.wFrameHeightInMbsMinus1 + 1) + * (dxva_ctx->pp.wFrameWidthInMbsMinus1 + 1); + p_dec->pvPVPState = dxva_ctx->slice_long; + p_dec->DataSize = dxva_ctx->slice_count * sizeof(DXVA_Slice_H264_Long); + + //!< reset dxva parameters + dxva_ctx->slice_count = 0; + dxva_ctx->strm_offset = 0; +} diff --git a/mpp/codec/dec/h264/h264d_fill.h b/mpp/codec/dec/h264/h264d_fill.h index c36626db..f88ff061 100644 --- a/mpp/codec/dec/h264/h264d_fill.h +++ b/mpp/codec/dec/h264/h264d_fill.h @@ -1,43 +1,43 @@ -/* -* -* Copyright 2015 Rockchip Electronics Co. LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#ifndef _H264D_FILL_H_ -#define _H264D_FILL_H_ - -#include "rk_type.h" -#include "mpp_err.h" -#include "dxva_syntax.h" -#include "h264d_syntax.h" -#include "h264d_global.h" - - - -#ifdef __cplusplus -extern "C" { -#endif - -void fill_picparams(H264dVideoCtx_t *p_Vid, DXVA_PicParams_H264_MVC *pp); -void fill_scanlist(H264dVideoCtx_t *p_Vid, DXVA_Qmatrix_H264 *qm); -void commit_buffer(H264dDxvaCtx_t *dxva); -MPP_RET fill_slice_syntax(H264_SLICE_t *currSlice, H264dDxvaCtx_t *dxva_ctx); -#ifdef __cplusplus -} -#endif - -//======================================== -#endif /* end of _RKV_H264_DECODER_FILL_H_ */ - +/* +* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef _H264D_FILL_H_ +#define _H264D_FILL_H_ + +#include "rk_type.h" +#include "mpp_err.h" +#include "dxva_syntax.h" +#include "h264d_syntax.h" +#include "h264d_global.h" + + + +#ifdef __cplusplus +extern "C" { +#endif + +void fill_picparams(H264dVideoCtx_t *p_Vid, DXVA_PicParams_H264_MVC *pp); +void fill_scanlist(H264dVideoCtx_t *p_Vid, DXVA_Qmatrix_H264 *qm); +void commit_buffer(H264dDxvaCtx_t *dxva); +MPP_RET fill_slice_syntax(H264_SLICE_t *currSlice, H264dDxvaCtx_t *dxva_ctx); +#ifdef __cplusplus +} +#endif + +//======================================== +#endif /* end of _RKV_H264_DECODER_FILL_H_ */ + diff --git a/mpp/codec/dec/h264/h264d_init.c b/mpp/codec/dec/h264/h264d_init.c index 30c16297..31050a33 100644 --- a/mpp/codec/dec/h264/h264d_init.c +++ b/mpp/codec/dec/h264/h264d_init.c @@ -1,1987 +1,1987 @@ -/* -* -* Copyright 2015 Rockchip Electronics Co. LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#define MODULE_TAG "h264d_init" - -#include -#include -#include - -#include "mpp_mem.h" -#include "vpu_api.h" - -#include "h264d_log.h" -#include "h264d_init.h" -#include "h264d_dpb.h" -#include "h264d_scalist.h" -#include "h264d_fill.h" -#include "h264d_slice.h" - -static MPP_RET decode_poc(H264dVideoCtx_t *p_Vid, H264_SLICE_t *pSlice) -{ - RK_S32 i = 0; - RK_U32 MaxPicOrderCntLsb = 0; - MPP_RET ret = MPP_ERR_UNKNOW; - H264_SPS_t *active_sps = p_Vid->active_sps; - // for POC mode 0: - MaxPicOrderCntLsb = (1 << (active_sps->log2_max_pic_order_cnt_lsb_minus4 + 4)); - - switch (active_sps->pic_order_cnt_type) { - case 0: // POC MODE 0 - // 1st - if (pSlice->idr_flag) { - p_Vid->PrevPicOrderCntMsb = 0; - p_Vid->PrevPicOrderCntLsb = 0; - } else { - if (p_Vid->last_has_mmco_5) { - if (p_Vid->last_pic_bottom_field) { - p_Vid->PrevPicOrderCntMsb = 0; - p_Vid->PrevPicOrderCntLsb = 0; - } else { - p_Vid->PrevPicOrderCntMsb = 0; - p_Vid->PrevPicOrderCntLsb = pSlice->toppoc; - } - } - } - // Calculate the MSBs of current picture - if (pSlice->pic_order_cnt_lsb < p_Vid->PrevPicOrderCntLsb && - (p_Vid->PrevPicOrderCntLsb - pSlice->pic_order_cnt_lsb) >= (RK_S32)(MaxPicOrderCntLsb / 2)) { - pSlice->PicOrderCntMsb = p_Vid->PrevPicOrderCntMsb + MaxPicOrderCntLsb; - } else if (pSlice->pic_order_cnt_lsb > p_Vid->PrevPicOrderCntLsb && - (pSlice->pic_order_cnt_lsb - p_Vid->PrevPicOrderCntLsb) > (RK_S32)(MaxPicOrderCntLsb / 2)) { - pSlice->PicOrderCntMsb = p_Vid->PrevPicOrderCntMsb - MaxPicOrderCntLsb; - } else { - pSlice->PicOrderCntMsb = p_Vid->PrevPicOrderCntMsb; - } - // 2nd - if (pSlice->field_pic_flag == 0) { - //frame pix - pSlice->toppoc = pSlice->PicOrderCntMsb + pSlice->pic_order_cnt_lsb; - pSlice->bottompoc = pSlice->toppoc + pSlice->delta_pic_order_cnt_bottom; - pSlice->ThisPOC = pSlice->framepoc = (pSlice->toppoc < pSlice->bottompoc) ? pSlice->toppoc : pSlice->bottompoc; // POC200301 - } else if (pSlice->bottom_field_flag == 0) { - //top field - pSlice->ThisPOC = pSlice->toppoc = pSlice->PicOrderCntMsb + pSlice->pic_order_cnt_lsb; - } else { - //bottom field - pSlice->ThisPOC = pSlice->bottompoc = pSlice->PicOrderCntMsb + pSlice->pic_order_cnt_lsb; - } - pSlice->framepoc = pSlice->ThisPOC; - p_Vid->ThisPOC = pSlice->ThisPOC; - //if ( pSlice->frame_num != p_Vid->PreviousFrameNum) //Seems redundant - p_Vid->PreviousFrameNum = pSlice->frame_num; - if (pSlice->nal_reference_idc) { - p_Vid->PrevPicOrderCntLsb = pSlice->pic_order_cnt_lsb; - p_Vid->PrevPicOrderCntMsb = pSlice->PicOrderCntMsb; - } - break; - - case 1: // POC MODE 1 - // 1st - if (pSlice->idr_flag) { - p_Vid->FrameNumOffset = 0; // first pix of IDRGOP, - VAL_CHECK(ret, 0 == pSlice->frame_num); - } else { - if (p_Vid->last_has_mmco_5) { - p_Vid->PreviousFrameNumOffset = 0; - p_Vid->PreviousFrameNum = 0; - } - if (pSlice->frame_num < (RK_S32)p_Vid->PreviousFrameNum) { - //not first pix of IDRGOP - p_Vid->FrameNumOffset = p_Vid->PreviousFrameNumOffset + p_Vid->max_frame_num; - } else { - p_Vid->FrameNumOffset = p_Vid->PreviousFrameNumOffset; - } - } - // 2nd - if (active_sps->num_ref_frames_in_pic_order_cnt_cycle) { - pSlice->AbsFrameNum = p_Vid->FrameNumOffset + pSlice->frame_num; - } else { - pSlice->AbsFrameNum = 0; - } - if ((!pSlice->nal_reference_idc) && pSlice->AbsFrameNum > 0) { - pSlice->AbsFrameNum--; - } - // 3rd - p_Vid->ExpectedDeltaPerPicOrderCntCycle = 0; - if (active_sps->num_ref_frames_in_pic_order_cnt_cycle) { - for (i = 0; i < (RK_S32)active_sps->num_ref_frames_in_pic_order_cnt_cycle; i++) { - p_Vid->ExpectedDeltaPerPicOrderCntCycle += active_sps->offset_for_ref_frame[i]; - } - } - if (pSlice->AbsFrameNum) { - p_Vid->PicOrderCntCycleCnt = (pSlice->AbsFrameNum - 1) / active_sps->num_ref_frames_in_pic_order_cnt_cycle; - p_Vid->FrameNumInPicOrderCntCycle = (pSlice->AbsFrameNum - 1) % active_sps->num_ref_frames_in_pic_order_cnt_cycle; - p_Vid->ExpectedPicOrderCnt = p_Vid->PicOrderCntCycleCnt * p_Vid->ExpectedDeltaPerPicOrderCntCycle; - for (i = 0; i <= (RK_S32)p_Vid->FrameNumInPicOrderCntCycle; i++) - p_Vid->ExpectedPicOrderCnt += active_sps->offset_for_ref_frame[i]; - } else { - p_Vid->ExpectedPicOrderCnt = 0; - } - if (!pSlice->nal_reference_idc) { - p_Vid->ExpectedPicOrderCnt += active_sps->offset_for_non_ref_pic; - } - if (pSlice->field_pic_flag == 0) { - //frame pix - pSlice->toppoc = p_Vid->ExpectedPicOrderCnt + pSlice->delta_pic_order_cnt[0]; - pSlice->bottompoc = pSlice->toppoc + active_sps->offset_for_top_to_bottom_field + pSlice->delta_pic_order_cnt[1]; - pSlice->ThisPOC = pSlice->framepoc = (pSlice->toppoc < pSlice->bottompoc) ? pSlice->toppoc : pSlice->bottompoc; // POC200301 - } else if (pSlice->bottom_field_flag == 0) { - //top field - pSlice->ThisPOC = pSlice->toppoc = p_Vid->ExpectedPicOrderCnt + pSlice->delta_pic_order_cnt[0]; - } else { - //bottom field - pSlice->ThisPOC = pSlice->bottompoc = p_Vid->ExpectedPicOrderCnt + active_sps->offset_for_top_to_bottom_field + pSlice->delta_pic_order_cnt[0]; - } - pSlice->framepoc = pSlice->ThisPOC; - p_Vid->PreviousFrameNum = pSlice->frame_num; - p_Vid->PreviousFrameNumOffset = p_Vid->FrameNumOffset; - break; - - - case 2: // POC MODE 2 - if (pSlice->idr_flag) { // IDR picture - p_Vid->FrameNumOffset = 0; // first pix of IDRGOP, - pSlice->ThisPOC = pSlice->framepoc = pSlice->toppoc = pSlice->bottompoc = 0; - VAL_CHECK(ret, 0 == pSlice->frame_num); - } else { - if (p_Vid->last_has_mmco_5) { - p_Vid->PreviousFrameNum = 0; - p_Vid->PreviousFrameNumOffset = 0; - } - if (pSlice->frame_num < (RK_S32)p_Vid->PreviousFrameNum) { - p_Vid->FrameNumOffset = p_Vid->PreviousFrameNumOffset + p_Vid->max_frame_num; - } else { - p_Vid->FrameNumOffset = p_Vid->PreviousFrameNumOffset; - } - pSlice->AbsFrameNum = p_Vid->FrameNumOffset + pSlice->frame_num; - if (!pSlice->nal_reference_idc) { - pSlice->ThisPOC = (2 * pSlice->AbsFrameNum - 1); - } else { - pSlice->ThisPOC = (2 * pSlice->AbsFrameNum); - } - if (pSlice->field_pic_flag == 0) { - pSlice->toppoc = pSlice->bottompoc = pSlice->framepoc = pSlice->ThisPOC; - } else if (pSlice->bottom_field_flag == 0) { - pSlice->toppoc = pSlice->framepoc = pSlice->ThisPOC; - } else { - pSlice->bottompoc = pSlice->framepoc = pSlice->ThisPOC; - } - } - p_Vid->PreviousFrameNum = pSlice->frame_num; - p_Vid->PreviousFrameNumOffset = p_Vid->FrameNumOffset; - break; - default: - ret = MPP_NOK; - goto __FAILED; - } - return ret = MPP_OK; - -__FAILED: - return ret; -} - -static MPP_RET store_proc_picture_in_dpb(H264_DpbBuf_t *p_Dpb, H264_StorePic_t *p) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - H264dVideoCtx_t *p_Vid = p_Dpb->p_Vid; - H264_FrameStore_t *fs = p_Dpb->fs_ilref[0]; - H264_DecCtx_t *p_Dec = p_Dpb->p_Vid->p_Dec; - - VAL_CHECK(ret, NULL != p); - if (p_Dpb->used_size_il > 0) { - if (fs->frame) { - free_storable_picture(p_Dec, fs->frame); - fs->frame = NULL; - } - if (fs->top_field) { - free_storable_picture(p_Dec, fs->top_field); - fs->top_field = NULL; - } - if (fs->bottom_field) { - free_storable_picture(p_Dec, fs->bottom_field); - fs->bottom_field = NULL; - } - fs->is_used = 0; - fs->is_reference = 0; - p_Dpb->used_size_il--; - } - if (fs->is_used > 0) { //checking; - if (p->structure == FRAME) { - VAL_CHECK(ret, fs->frame == NULL); - } else if (p->structure == TOP_FIELD) { - VAL_CHECK(ret, fs->top_field == NULL); - } else if (p->structure == BOTTOM_FIELD) { - VAL_CHECK(ret, fs->bottom_field == NULL); - } - } - FUN_CHECK(ret = insert_picture_in_dpb(p_Vid, fs, p, 0)); - if ((p->structure == FRAME && fs->is_used == 3) - || (p->structure != FRAME && fs->is_used && fs->is_used < 3)) { - p_Dpb->used_size_il++; - } - - return ret = MPP_OK; -__FAILED: - return ret; -} - -static void dpb_mark_add_used(H264_DpbMark_t *p_mark, RK_S32 structure) -{ - //!<---- index add ---- - if (structure == FRAME || structure == TOP_FIELD) { - p_mark->top_used += 1; - } - if (structure == FRAME || structure == BOTTOM_FIELD) { - p_mark->bot_used += 1; - } -} - -static H264_StorePic_t* clone_storable_picture(H264dVideoCtx_t *p_Vid, H264_StorePic_t *p_pic) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - H264_StorePic_t *p_stored_pic = alloc_storable_picture(p_Vid, p_Vid->structure); - - MEM_CHECK(ret, p_stored_pic); - p_stored_pic->mem_malloc_type = Mem_Clone; - p_stored_pic->mem_mark = p_pic->mem_mark; - dpb_mark_add_used(p_stored_pic->mem_mark, p_stored_pic->structure); - p_stored_pic->colmv_no_used_flag = 1; // clone, colmv is not be used - - p_stored_pic->pic_num = p_pic->pic_num; - p_stored_pic->frame_num = p_pic->frame_num; - p_stored_pic->long_term_frame_idx = p_pic->long_term_frame_idx; - p_stored_pic->long_term_pic_num = p_pic->long_term_pic_num; - p_stored_pic->is_long_term = 0; - p_stored_pic->non_existing = p_pic->non_existing; - p_stored_pic->max_slice_id = p_pic->max_slice_id; - p_stored_pic->structure = p_pic->structure; - - p_stored_pic->mb_aff_frame_flag = p_pic->mb_aff_frame_flag; - p_stored_pic->poc = p_pic->poc; - p_stored_pic->top_poc = p_pic->top_poc; - p_stored_pic->bottom_poc = p_pic->bottom_poc; - p_stored_pic->frame_poc = p_pic->frame_poc; - p_stored_pic->is_mmco_5 = p_pic->is_mmco_5; - p_stored_pic->poc_mmco5 = p_pic->poc_mmco5; - p_stored_pic->top_poc_mmco5 = p_pic->top_poc_mmco5; - p_stored_pic->bot_poc_mmco5 = p_pic->bot_poc_mmco5; - p_stored_pic->pic_num = p_pic->pic_num; - p_stored_pic->frame_num = p_pic->frame_num; - p_stored_pic->slice_type = p_pic->slice_type; - p_stored_pic->idr_flag = p_pic->idr_flag; - p_stored_pic->no_output_of_prior_pics_flag = p_pic->no_output_of_prior_pics_flag; - p_stored_pic->long_term_reference_flag = 0; - p_stored_pic->adaptive_ref_pic_buffering_flag = 0; - p_stored_pic->dec_ref_pic_marking_buffer = NULL; - p_stored_pic->PicWidthInMbs = p_pic->PicWidthInMbs; - - p_stored_pic->chroma_format_idc = p_pic->chroma_format_idc; - p_stored_pic->frame_mbs_only_flag = p_pic->frame_mbs_only_flag; - p_stored_pic->frame_cropping_flag = p_pic->frame_cropping_flag; - if (p_stored_pic->frame_cropping_flag) { - p_stored_pic->frame_crop_left_offset = p_pic->frame_crop_left_offset; - p_stored_pic->frame_crop_right_offset = p_pic->frame_crop_right_offset; - p_stored_pic->frame_crop_top_offset = p_pic->frame_crop_top_offset; - p_stored_pic->frame_crop_bottom_offset = p_pic->frame_crop_bottom_offset; - } - // MVC-related parameters - p_stored_pic->inter_view_flag = p_pic->inter_view_flag; - p_stored_pic->anchor_pic_flag = 0; - p_stored_pic->view_id = p_pic->view_id; - p_stored_pic->layer_id = p_pic->layer_id; - p_stored_pic->proc_flag = 1; - p_stored_pic->is_output = 1; - p_stored_pic->used_for_reference = 1; - - return p_stored_pic; -__FAILED: - (void)ret; - return NULL; -} - -static MPP_RET init_mvc_picture(H264_SLICE_t *currSlice) -{ - RK_U32 i = 0; - RK_S32 poc = 0; - MPP_RET ret = MPP_ERR_UNKNOW; - H264dVideoCtx_t *p_Vid = currSlice->p_Vid; - H264_DpbBuf_t *p_Dpb = p_Vid->p_Dpb_layer[0]; - H264_StorePic_t *p_pic = NULL; - H264_FrameStore_t *fs = NULL; - H264_StorePic_t *p_clone = NULL; - - // find BL reconstructed picture - if (currSlice->structure == FRAME) { - for (i = 0; i < p_Dpb->used_size; i++) { - fs = p_Dpb->fs[i]; - if (fs->frame) { - poc = fs->frame->is_mmco_5 ? fs->frame->poc_mmco5 : fs->frame->poc; - } - if (fs->frame && (fs->frame->layer_id == 0) && (poc == currSlice->framepoc)) { - p_pic = fs->frame; - if (!fs->frame->is_mmco_5) { - break; - } - } - } - } else if (currSlice->structure == TOP_FIELD) { - for (i = 0; i < p_Dpb->used_size; i++) { - fs = p_Dpb->fs[i]; - if (fs->top_field) { - poc = fs->top_field->is_mmco_5 ? fs->top_field->top_poc_mmco5 : fs->top_field->top_poc; - } - if (fs->top_field && (fs->top_field->layer_id == 0) && (poc == currSlice->toppoc)) { - p_pic = fs->top_field; - if (!fs->top_field->is_mmco_5) { - break; - } - } - } - } else { - for (i = 0; i < p_Dpb->used_size; i++) { - fs = p_Dpb->fs[i]; - if (fs->bottom_field) { - poc = fs->bottom_field->is_mmco_5 ? fs->bottom_field->bot_poc_mmco5 : fs->bottom_field->bottom_poc; - } - if (fs->bottom_field && (fs->bottom_field->layer_id == 0) && (poc == currSlice->bottompoc)) { - p_pic = fs->bottom_field; - if (!fs->bottom_field->is_mmco_5) { - break; - } - } - } - } - if (p_pic) { - p_clone = clone_storable_picture(p_Vid, p_pic); - MEM_CHECK(ret, p_clone); - FUN_CHECK(ret = store_proc_picture_in_dpb(currSlice->p_Dpb, p_clone)); - } - - return ret = MPP_OK; -__FAILED: - return ret; -} - -static RK_U32 rkv_len_align_422(RK_U32 val) -{ - return ((5 * MPP_ALIGN(val, 16)) / 2); -} - -static MPP_RET dpb_mark_malloc(H264dVideoCtx_t *p_Vid, H264_StorePic_t *dec_pic) -{ - RK_U8 idx = 0; - MPP_RET ret = MPP_ERR_UNKNOW; - H264_DpbMark_t *cur_mark = NULL; - RK_U32 hor_stride = 0, ver_stride = 0; - H264_DecCtx_t *p_Dec = p_Vid->p_Dec; - H264_DpbMark_t *p_mark = p_Vid->p_Dec->dpb_mark; - RK_S32 structure = dec_pic->structure; - RK_S32 layer_id = dec_pic->layer_id; - if (!dec_pic->combine_flag) { - while (p_mark[idx].out_flag || p_mark[idx].top_used || p_mark[idx].bot_used) { - idx++; - } - ASSERT(idx <= MAX_MARK_SIZE); - - mpp_buf_slot_get_unused(p_Vid->p_Dec->frame_slots, &p_mark[idx].slot_idx); - if (p_mark[idx].slot_idx < 0) { - H264D_WARNNING("[dpb_mark_malloc] error, buf_slot has not get."); - ret = MPP_NOK; - goto __FAILED; - } - cur_mark = &p_mark[idx]; - - cur_mark->out_flag = 1; - { - MppFrame mframe = NULL; - mpp_frame_init(&mframe); - if ((YUV420 == p_Vid->yuv_format) && (8 == p_Vid->bit_depth_luma)) { - mpp_frame_set_fmt(mframe, MPP_FMT_YUV420SP); - } else if ((YUV420 == p_Vid->yuv_format) && (10 == p_Vid->bit_depth_luma)) { - mpp_frame_set_fmt(mframe, MPP_FMT_YUV420SP_10BIT); - } else if ((YUV422 == p_Vid->yuv_format) && (8 == p_Vid->bit_depth_luma)) { - mpp_frame_set_fmt(mframe, MPP_FMT_YUV422SP); - mpp_slots_set_prop(p_Dec->frame_slots, SLOTS_LEN_ALIGN, rkv_len_align_422); - } else if ((YUV422 == p_Vid->yuv_format) && (10 == p_Vid->bit_depth_luma)) { - mpp_frame_set_fmt(mframe, MPP_FMT_YUV422SP_10BIT); - mpp_slots_set_prop(p_Dec->frame_slots, SLOTS_LEN_ALIGN, rkv_len_align_422); - } - hor_stride = ((p_Vid->width * p_Vid->bit_depth_luma + 127) & (~127)) / 8; - ver_stride = p_Vid->height; - mpp_frame_set_hor_stride(mframe, hor_stride); // before crop - mpp_frame_set_ver_stride(mframe, ver_stride); - mpp_frame_set_width(mframe, p_Vid->width_after_crop); // after crop - mpp_frame_set_height(mframe, p_Vid->height_after_crop); - mpp_frame_set_pts(mframe, p_Vid->p_Cur->last_pts); - mpp_frame_set_dts(mframe, p_Vid->p_Cur->last_dts); - mpp_buf_slot_set_prop(p_Dec->frame_slots, cur_mark->slot_idx, SLOT_FRAME, mframe); - mpp_frame_deinit(&mframe); - mpp_buf_slot_get_prop(p_Dec->frame_slots, cur_mark->slot_idx, SLOT_FRAME_PTR, &cur_mark->mframe); - } - - p_Vid->active_dpb_mark[layer_id] = cur_mark; - } - cur_mark = p_Vid->active_dpb_mark[layer_id]; - if (structure == FRAME || structure == TOP_FIELD) { - cur_mark->top_used += 1; - } - if (structure == FRAME || structure == BOTTOM_FIELD) { - cur_mark->bot_used += 1; - } - H264D_DBG(H264D_DBG_DPB_MALLIC, "[DPB_malloc] g_framecnt=%d, com_flag=%d, mark_idx=%d, slot_idx=%d, slice_type=%d, struct=%d, lay_id=%d\n", - p_Vid->g_framecnt, dec_pic->combine_flag, cur_mark->mark_idx, cur_mark->slot_idx, dec_pic->slice_type, dec_pic->structure, layer_id); - - p_Vid->p_Dec->in_task->output = cur_mark->slot_idx; - mpp_buf_slot_set_flag(p_Dec->frame_slots, cur_mark->slot_idx, SLOT_HAL_OUTPUT); - p_Dec->last_frame_slot_idx = cur_mark->slot_idx; - dec_pic->mem_mark = p_Vid->active_dpb_mark[layer_id]; - dec_pic->mem_mark->pic = dec_pic; - - return ret = MPP_OK; -__FAILED: - dec_pic->mem_mark = NULL; - return ret; -} -static MPP_RET check_dpb_field_paired(H264_FrameStore_t *p_last, H264_StorePic_t *dec_pic, RK_S32 last_pic_structure) -{ - MPP_RET ret = MPP_ERR_UNKNOW; -#if 0 - RK_S32 cur_structure = dec_pic->structure; - //!< check illegal field paired - if (p_last && (cur_structure == TOP_FIELD || cur_structure == BOTTOM_FIELD)) { - - if ((p_last->is_used == 1 && cur_structure == TOP_FIELD) //!< Top +Top - || (p_last->is_used == 2 && cur_structure == BOTTOM_FIELD) //!< Bot + Bot - //|| ((!dec_pic->combine_flag) && p_last->is_used == 2 && cur_structure == TOP_FIELD) //!< Bot + Top + not combine - || ((!dec_pic->combine_flag) && p_last->is_used == 1 && cur_structure == BOTTOM_FIELD) //!< Top + Bot + not combine - ) { - H264D_WARNNING("[check_field_paired] (discard) combine_flag=%d, last_used=%d, curr_struct=%d", - dec_pic->combine_flag, p_last->is_used, cur_structure); - return ret = MPP_NOK; - } - } - H264D_DBG(H264D_DBG_FIELD_PAIRED, "[check_field_paired] combine_flag=%d, last_used=%d, last_pic_struct=%d, curr_struct=%d", - dec_pic->combine_flag, (p_last ? p_last->is_used : -1), last_pic_structure, cur_structure); -#else - (void)p_last; - (void)dec_pic; - (void)last_pic_structure; -#endif - return ret = MPP_OK; -} - -static MPP_RET check_dpb_discontinuous(H264_StorePic_t *p_last, H264_StorePic_t *dec_pic, H264_SLICE_t *currSlice) -{ - MPP_RET ret = MPP_ERR_UNKNOW; -#if 1 - if (p_last && dec_pic && (dec_pic->slice_type != I_SLICE)) { - RK_U32 error_flag = 0; - RK_U32 wrap_frame_num = 0; - if (p_last->used_for_reference && !dec_pic->combine_flag) { - wrap_frame_num = (p_last->frame_num + 1) % currSlice->p_Vid->max_frame_num; - } else { - wrap_frame_num = p_last->frame_num; - } - error_flag = (wrap_frame_num != dec_pic->frame_num) ? 1 : 0; - currSlice->p_Dec->errctx.cur_err_flag |= error_flag ? 1 : 0; - - H264D_DBG(H264D_DBG_DISCONTINUOUS, "[discontinuous] last_slice=%d, cur_slice=%d, last_fnum=%d, cur_fnum=%d, last_poc=%d, cur_poc=%d", - p_last->slice_type, dec_pic->slice_type, p_last->frame_num, dec_pic->frame_num, p_last->poc, dec_pic->poc); - } -#endif - return ret = MPP_OK; -} - -static MPP_RET alloc_decpic(H264_SLICE_t *currSlice) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - H264_StorePic_t *dec_pic = NULL; - - H264dVideoCtx_t *p_Vid = currSlice->p_Vid; - H264_SPS_t *active_sps = p_Vid->active_sps; - H264_DpbBuf_t *p_Dpb = currSlice->p_Dpb; - - dec_pic = alloc_storable_picture(p_Vid, currSlice->structure); - MEM_CHECK(ret, dec_pic); - currSlice->toppoc = p_Vid->last_toppoc[currSlice->layer_id]; - currSlice->bottompoc = p_Vid->last_bottompoc[currSlice->layer_id]; - currSlice->framepoc = p_Vid->last_framepoc[currSlice->layer_id]; - currSlice->ThisPOC = p_Vid->last_thispoc[currSlice->layer_id]; - FUN_CHECK(ret = decode_poc(p_Vid, currSlice)); //!< calculate POC - - dec_pic->top_poc = currSlice->toppoc; - dec_pic->bottom_poc = currSlice->bottompoc; - dec_pic->frame_poc = currSlice->framepoc; - dec_pic->ThisPOC = currSlice->ThisPOC; - - p_Vid->last_toppoc[currSlice->layer_id] = currSlice->toppoc; - p_Vid->last_bottompoc[currSlice->layer_id] = currSlice->bottompoc; - p_Vid->last_framepoc[currSlice->layer_id] = currSlice->framepoc; - p_Vid->last_thispoc[currSlice->layer_id] = currSlice->ThisPOC; - - if (currSlice->structure == FRAME) { - if (currSlice->mb_aff_frame_flag) { - dec_pic->iCodingType = FRAME_MB_PAIR_CODING; - } else { - dec_pic->iCodingType = FRAME_CODING; - } - } else { - dec_pic->iCodingType = FIELD_CODING; - } - dec_pic->layer_id = currSlice->layer_id; - dec_pic->view_id = currSlice->view_id; - dec_pic->inter_view_flag = currSlice->inter_view_flag; - dec_pic->anchor_pic_flag = currSlice->anchor_pic_flag; - if (dec_pic->layer_id == 1) { - if ((p_Vid->profile_idc == H264_PROFILE_MVC_HIGH) || (p_Vid->profile_idc == H264_PROFILE_STEREO_HIGH)) { - FUN_CHECK(ret = init_mvc_picture(currSlice)); - } - } - if (currSlice->structure == TOP_FIELD) { - dec_pic->poc = currSlice->toppoc; - } else if (currSlice->structure == BOTTOM_FIELD) { - dec_pic->poc = currSlice->bottompoc; - } else if (currSlice->structure == FRAME) { - dec_pic->poc = currSlice->framepoc; - } else { - ret = MPP_NOK; - goto __FAILED; - } - dec_pic->slice_type = p_Vid->type; - dec_pic->used_for_reference = (currSlice->nal_reference_idc != 0); - dec_pic->idr_flag = currSlice->idr_flag; - dec_pic->no_output_of_prior_pics_flag = currSlice->no_output_of_prior_pics_flag; - dec_pic->long_term_reference_flag = currSlice->long_term_reference_flag; - dec_pic->adaptive_ref_pic_buffering_flag = currSlice->adaptive_ref_pic_buffering_flag; - dec_pic->dec_ref_pic_marking_buffer = currSlice->dec_ref_pic_marking_buffer; - - currSlice->dec_ref_pic_marking_buffer = NULL; - dec_pic->mb_aff_frame_flag = currSlice->mb_aff_frame_flag; - dec_pic->PicWidthInMbs = p_Vid->PicWidthInMbs; - dec_pic->pic_num = currSlice->frame_num; - dec_pic->frame_num = currSlice->frame_num; - dec_pic->chroma_format_idc = active_sps->chroma_format_idc; - - dec_pic->frame_mbs_only_flag = active_sps->frame_mbs_only_flag; - dec_pic->frame_cropping_flag = active_sps->frame_cropping_flag; - if (dec_pic->frame_cropping_flag) { - dec_pic->frame_crop_left_offset = active_sps->frame_crop_left_offset; - dec_pic->frame_crop_right_offset = active_sps->frame_crop_right_offset; - dec_pic->frame_crop_top_offset = active_sps->frame_crop_top_offset; - dec_pic->frame_crop_bottom_offset = active_sps->frame_crop_bottom_offset; - } else { - dec_pic->frame_crop_left_offset = 0; - dec_pic->frame_crop_right_offset = 0; - dec_pic->frame_crop_top_offset = 0; - dec_pic->frame_crop_bottom_offset = 0; - } - dec_pic->width = p_Vid->width; - dec_pic->height = p_Vid->height; - dec_pic->width_after_crop = p_Vid->width_after_crop; - dec_pic->height_after_crop = p_Vid->height_after_crop; - dec_pic->combine_flag = get_filed_dpb_combine_flag(p_Dpb->last_picture, dec_pic); - FUN_CHECK(ret = dpb_mark_malloc(p_Vid, dec_pic)); //!< malloc dpb_memory - FUN_CHECK(ret = check_dpb_field_paired(p_Dpb->last_picture, dec_pic, p_Vid->last_pic_structure)); - FUN_CHECK(ret = check_dpb_discontinuous(p_Vid->last_pic, dec_pic, currSlice)); - dec_pic->mem_malloc_type = Mem_Malloc; - dec_pic->colmv_no_used_flag = 0; - p_Vid->dec_pic = dec_pic; - - return ret = MPP_OK; -__FAILED: - MPP_FREE(dec_pic); - p_Vid->dec_pic = NULL; - - return ret; -} - -static void update_pic_num(H264_SLICE_t *currSlice) -{ - RK_U32 i = 0; - H264dVideoCtx_t *p_Vid = currSlice->p_Vid; - H264_DpbBuf_t *p_Dpb = currSlice->p_Dpb; - H264_SPS_t *active_sps = p_Vid->active_sps; - - RK_S32 add_top = 0, add_bottom = 0; - RK_S32 max_frame_num = 1 << (active_sps->log2_max_frame_num_minus4 + 4); - - if (currSlice->idr_flag) { - return; - } - if (currSlice->structure == FRAME) { - for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) { - if (p_Dpb->fs_ref[i]->is_used == 3) { - if ((p_Dpb->fs_ref[i]->frame->used_for_reference) && (!p_Dpb->fs_ref[i]->frame->is_long_term)) { - if ((RK_S32)p_Dpb->fs_ref[i]->frame_num > currSlice->frame_num) { - p_Dpb->fs_ref[i]->frame_num_wrap = p_Dpb->fs_ref[i]->frame_num - max_frame_num; - } else { - p_Dpb->fs_ref[i]->frame_num_wrap = p_Dpb->fs_ref[i]->frame_num; - } - p_Dpb->fs_ref[i]->frame->pic_num = p_Dpb->fs_ref[i]->frame_num_wrap; - } - } - } - //!< update long_term_pic_num - for (i = 0; i < p_Dpb->ltref_frames_in_buffer; i++) { - if (p_Dpb->fs_ltref[i]->is_used == 3) { - if (p_Dpb->fs_ltref[i]->frame->is_long_term) { - p_Dpb->fs_ltref[i]->frame->long_term_pic_num = p_Dpb->fs_ltref[i]->frame->long_term_frame_idx; - } - } - } - } else { - if (currSlice->structure == TOP_FIELD) { - add_top = 1; - add_bottom = 0; - } else { - add_top = 0; - add_bottom = 1; - } - - for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) { - if (p_Dpb->fs_ref[i]->is_reference) { - if ((RK_S32)p_Dpb->fs_ref[i]->frame_num > currSlice->frame_num) { - p_Dpb->fs_ref[i]->frame_num_wrap = p_Dpb->fs_ref[i]->frame_num - max_frame_num; - } else { - p_Dpb->fs_ref[i]->frame_num_wrap = p_Dpb->fs_ref[i]->frame_num; - } - if (p_Dpb->fs_ref[i]->is_reference & 1) { - p_Dpb->fs_ref[i]->top_field->pic_num = (2 * p_Dpb->fs_ref[i]->frame_num_wrap) + add_top; - } - if (p_Dpb->fs_ref[i]->is_reference & 2) { - p_Dpb->fs_ref[i]->bottom_field->pic_num = (2 * p_Dpb->fs_ref[i]->frame_num_wrap) + add_bottom; - } - } - } - //!< update long_term_pic_num - for (i = 0; i < p_Dpb->ltref_frames_in_buffer; i++) { - if (p_Dpb->fs_ltref[i]->is_long_term & 1) { - p_Dpb->fs_ltref[i]->top_field->long_term_pic_num = 2 * p_Dpb->fs_ltref[i]->top_field->long_term_frame_idx + add_top; - } - if (p_Dpb->fs_ltref[i]->is_long_term & 2) { - p_Dpb->fs_ltref[i]->bottom_field->long_term_pic_num = 2 * p_Dpb->fs_ltref[i]->bottom_field->long_term_frame_idx + add_bottom; - } - } - } -} - - - - -static RK_S32 compare_pic_by_pic_num_desc(const void *arg1, const void *arg2) -{ - RK_S32 pic_num1 = (*(H264_StorePic_t**)arg1)->pic_num; - RK_S32 pic_num2 = (*(H264_StorePic_t**)arg2)->pic_num; - - if (pic_num1 < pic_num2) - return 1; - if (pic_num1 > pic_num2) - return -1; - else - return 0; -} - -static RK_S32 compare_pic_by_lt_pic_num_asc(const void *arg1, const void *arg2) -{ - RK_S32 long_term_pic_num1 = (*(H264_StorePic_t**)arg1)->long_term_pic_num; - RK_S32 long_term_pic_num2 = (*(H264_StorePic_t**)arg2)->long_term_pic_num; - - if (long_term_pic_num1 < long_term_pic_num2) - return -1; - if (long_term_pic_num1 > long_term_pic_num2) - return 1; - else - return 0; -} - -static RK_S32 compare_fs_by_frame_num_desc(const void *arg1, const void *arg2) -{ - RK_S32 frame_num_wrap1 = (*(H264_FrameStore_t**)arg1)->frame_num_wrap; - RK_S32 frame_num_wrap2 = (*(H264_FrameStore_t**)arg2)->frame_num_wrap; - if (frame_num_wrap1 < frame_num_wrap2) - return 1; - if (frame_num_wrap1 > frame_num_wrap2) - return -1; - else - return 0; -} - -static RK_S32 compare_fs_by_lt_pic_idx_asc(const void *arg1, const void *arg2) -{ - RK_S32 long_term_frame_idx1 = (*(H264_FrameStore_t**)arg1)->long_term_frame_idx; - RK_S32 long_term_frame_idx2 = (*(H264_FrameStore_t**)arg2)->long_term_frame_idx; - - if (long_term_frame_idx1 < long_term_frame_idx2) - return -1; - else if (long_term_frame_idx1 > long_term_frame_idx2) - return 1; - else - return 0; -} - -static RK_U32 is_long_ref(H264_StorePic_t *s) -{ - return ((s->used_for_reference) && (s->is_long_term)); -} - -static RK_U32 is_short_ref(H264_StorePic_t *s) -{ - return ((s->used_for_reference) && (!(s->is_long_term))); -} - -static void gen_pic_list_from_frame_list(RK_S32 currStructure, H264_FrameStore_t **fs_list, - RK_S32 list_idx, H264_StorePic_t **list, RK_U8 *list_size, RK_U32 long_term) -{ - RK_S32 top_idx = 0; - RK_S32 bot_idx = 0; - - RK_U32(*is_ref)(H264_StorePic_t * s) = (long_term) ? is_long_ref : is_short_ref; - - if (currStructure == TOP_FIELD) { - while ((top_idx < list_idx) || (bot_idx < list_idx)) { - for (; top_idx < list_idx; top_idx++) { - if (fs_list[top_idx]->is_used & 1) { - if (is_ref(fs_list[top_idx]->top_field)) { - //top_field; - (*list_size)++; - top_idx++; - break; - } - } - } - for (; bot_idx < list_idx; bot_idx++) { - if (fs_list[bot_idx]->is_used & 2) { - if (is_ref(fs_list[bot_idx]->bottom_field)) { - //bottom_field; - (*list_size)++; - bot_idx++; - break; - } - } - } - } - } - if (currStructure == BOTTOM_FIELD) { - while ((top_idx < list_idx) || (bot_idx < list_idx)) { - for (; bot_idx < list_idx; bot_idx++) { - if (fs_list[bot_idx]->is_used & 2) { - if (is_ref(fs_list[bot_idx]->bottom_field)) { - // short term ref pic - list[(RK_S16)*list_size] = fs_list[bot_idx]->bottom_field; - (*list_size)++; - bot_idx++; - break; - } - } - } - for (; top_idx < list_idx; top_idx++) { - if (fs_list[top_idx]->is_used & 1) { - if (is_ref(fs_list[top_idx]->top_field)) { - //!< short term ref pic - list[(RK_S16)*list_size] = fs_list[top_idx]->top_field; - (*list_size)++; - top_idx++; - break; - } - } - } - } - } -} - -static RK_U32 is_view_id_in_ref_view_list(RK_S32 view_id, RK_S32 *ref_view_id, RK_S32 num_ref_views) -{ - RK_S32 i; - for (i = 0; i < num_ref_views; i++) { - if (view_id == ref_view_id[i]) - break; - } - - return (num_ref_views && (i < num_ref_views)); -} - -static MPP_RET append_interview_list(H264_DpbBuf_t *p_Dpb, - RK_S32 currPicStructure, RK_S32 list_idx, H264_FrameStore_t **list, - RK_S32 *listXsize, RK_S32 currPOC, RK_S32 curr_layer_id, RK_S32 anchor_pic_flag) -{ - RK_S32 poc = 0; - RK_S32 fld_idx = 0; - RK_U32 pic_avail = 0; - RK_S32 num_ref_views = 0; - RK_S32 *ref_view_id = NULL; - MPP_RET ret = MPP_ERR_UNKNOW; - RK_S32 iVOIdx = curr_layer_id; - H264_FrameStore_t *fs = p_Dpb->fs_ilref[0]; - H264dVideoCtx_t *p_Vid = p_Dpb->p_Vid; - - VAL_CHECK(ret, iVOIdx >= 0); //!< Error: iVOIdx: %d is not less than 0 - if (anchor_pic_flag) { - num_ref_views = list_idx ? p_Vid->active_subsps->num_anchor_refs_l1[iVOIdx] : p_Vid->active_subsps->num_anchor_refs_l0[iVOIdx]; - ref_view_id = list_idx ? p_Vid->active_subsps->anchor_ref_l1[iVOIdx] : p_Vid->active_subsps->anchor_ref_l0[iVOIdx]; - } else { - num_ref_views = list_idx ? p_Vid->active_subsps->num_non_anchor_refs_l1[iVOIdx] : p_Vid->active_subsps->num_non_anchor_refs_l0[iVOIdx]; - ref_view_id = list_idx ? p_Vid->active_subsps->non_anchor_ref_l1[iVOIdx] : p_Vid->active_subsps->non_anchor_ref_l0[iVOIdx]; - } - - if (currPicStructure == BOTTOM_FIELD) - fld_idx = 1; - else - fld_idx = 0; - - if (currPicStructure == FRAME) { - pic_avail = (fs->is_used == 3); - if (pic_avail) { - poc = fs->frame->is_mmco_5 ? fs->frame->poc_mmco5 : fs->frame->poc; - } - } else if (currPicStructure == TOP_FIELD) { - pic_avail = fs->is_used & 1; - if (pic_avail) { - poc = fs->top_field->is_mmco_5 ? fs->top_field->top_poc_mmco5 : fs->top_field->poc; - } - } else if (currPicStructure == BOTTOM_FIELD) { - pic_avail = fs->is_used & 2; - if (pic_avail) { - poc = fs->bottom_field->is_mmco_5 ? fs->bottom_field->bot_poc_mmco5 : fs->bottom_field->poc; - } - } else { - pic_avail = 0; - } - - if (pic_avail && fs->inter_view_flag[fld_idx]) { - if (poc == currPOC) { - if (is_view_id_in_ref_view_list(fs->view_id, ref_view_id, num_ref_views)) { - //!< add one inter-view reference; - list[*listXsize] = fs; - //!< next; - (*listXsize)++; - } - } - } - return ret = MPP_OK; -__FAILED: - return ret; -} - -static void gen_pic_list_from_frame_interview_list(RK_S32 currStructure, - H264_FrameStore_t **fs_list, RK_S32 list_idx, H264_StorePic_t **list, RK_U8 *list_size) -{ - RK_S32 i; - - if (currStructure == TOP_FIELD) { - for (i = 0; i < list_idx; i++) { - list[(RK_S32)(*list_size)] = fs_list[i]->top_field; - (*list_size)++; - } - } - if (currStructure == BOTTOM_FIELD) { - for (i = 0; i < list_idx; i++) { - list[(RK_S32)(*list_size)] = fs_list[i]->bottom_field; - (*list_size)++; - } - } -} - -static RK_S32 compare_pic_by_poc_desc(const void *arg1, const void *arg2) -{ - RK_S32 poc1 = (*(H264_StorePic_t**)arg1)->poc; - RK_S32 poc2 = (*(H264_StorePic_t**)arg2)->poc; - - if (poc1 < poc2) - return 1; - if (poc1 > poc2) - return -1; - else - return 0; -} - -static RK_S32 compare_pic_by_poc_asc(const void *arg1, const void *arg2) -{ - RK_S32 poc1 = (*(H264_StorePic_t**)arg1)->poc; - RK_S32 poc2 = (*(H264_StorePic_t**)arg2)->poc; - - if (poc1 < poc2) - return -1; - if (poc1 > poc2) - return 1; - else - return 0; -} - -static RK_S32 compare_fs_by_poc_desc(const void *arg1, const void *arg2) -{ - RK_S32 poc1 = (*(H264_FrameStore_t**)arg1)->poc; - RK_S32 poc2 = (*(H264_FrameStore_t**)arg2)->poc; - - if (poc1 < poc2) - return 1; - else if (poc1 > poc2) - return -1; - else - return 0; -} - -static RK_S32 compare_fs_by_poc_asc(const void *arg1, const void *arg2) -{ - RK_S32 poc1 = (*(H264_FrameStore_t**)arg1)->poc; - RK_S32 poc2 = (*(H264_FrameStore_t**)arg2)->poc; - - if (poc1 < poc2) - return -1; - else if (poc1 > poc2) - return 1; - else - return 0; -} - -static MPP_RET init_lists_p_slice_mvc(H264_SLICE_t *currSlice) -{ - RK_U32 i = 0; - RK_S32 list0idx = 0; - RK_S32 listltidx = 0; - H264_FrameStore_t **fs_list0 = 0; - H264_FrameStore_t **fs_listlt = 0; - MPP_RET ret = MPP_ERR_UNKNOW; - H264dVideoCtx_t *p_Vid = currSlice->p_Vid; - H264_DpbBuf_t *p_Dpb = currSlice->p_Dpb; - RK_S32 currPOC = currSlice->ThisPOC; - RK_S32 anchor_pic_flag = currSlice->anchor_pic_flag; - - currSlice->listXsizeP[0] = 0; - currSlice->listXsizeP[1] = 0; - currSlice->listinterviewidx0 = 0; - currSlice->listinterviewidx1 = 0; - - if (currSlice->structure == FRAME) { - for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) { - if (p_Dpb->fs_ref[i]->is_used == 3) { - if ((p_Dpb->fs_ref[i]->frame->used_for_reference) && (!p_Dpb->fs_ref[i]->frame->is_long_term)) { - currSlice->listP[0][list0idx++] = p_Dpb->fs_ref[i]->frame; - } - } - } - // order list 0 by PicNum - qsort((void *)currSlice->listP[0], list0idx, sizeof(H264_StorePic_t*), compare_pic_by_pic_num_desc); - currSlice->listXsizeP[0] = (RK_U8)list0idx; - // long term handling - for (i = 0; i < p_Dpb->ltref_frames_in_buffer; i++) { - if (p_Dpb->fs_ltref[i]->is_used == 3) { - if (p_Dpb->fs_ltref[i]->frame->is_long_term) { - currSlice->listP[0][list0idx++] = p_Dpb->fs_ltref[i]->frame; - } - } - } - qsort((void *)&currSlice->listP[0][(RK_S16)currSlice->listXsizeP[0]], - list0idx - currSlice->listXsizeP[0], sizeof(H264_StorePic_t*), compare_pic_by_lt_pic_num_asc); - currSlice->listXsizeP[0] = (RK_U8)list0idx; - } else { - fs_list0 = mpp_calloc(H264_FrameStore_t*, p_Dpb->size); - fs_listlt = mpp_calloc(H264_FrameStore_t*, p_Dpb->size); - MEM_CHECK(ret, fs_list0 && fs_listlt); - for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) { - if (p_Dpb->fs_ref[i]->is_reference) { - fs_list0[list0idx++] = p_Dpb->fs_ref[i]; - } - } - qsort((void *)fs_list0, list0idx, sizeof(H264_FrameStore_t*), compare_fs_by_frame_num_desc); - currSlice->listXsizeP[0] = 0; - gen_pic_list_from_frame_list(currSlice->structure, fs_list0, list0idx, currSlice->listP[0], &currSlice->listXsizeP[0], 0); - // long term handling - for (i = 0; i < p_Dpb->ltref_frames_in_buffer; i++) { - fs_listlt[listltidx++] = p_Dpb->fs_ltref[i]; - } - qsort((void *)fs_listlt, listltidx, sizeof(H264_FrameStore_t*), compare_fs_by_lt_pic_idx_asc); - gen_pic_list_from_frame_list(currSlice->structure, fs_listlt, listltidx, currSlice->listP[0], &currSlice->listXsizeP[0], 1); - MPP_FREE(fs_list0); - MPP_FREE(fs_listlt); - } - - currSlice->listXsizeP[1] = 0; - if (currSlice->svc_extension_flag == 0) { - RK_S32 curr_layer_id = currSlice->layer_id; - currSlice->fs_listinterview0 = mpp_calloc(H264_FrameStore_t*, p_Dpb->size); - MEM_CHECK(ret, currSlice->fs_listinterview0); - list0idx = currSlice->listXsizeP[0]; - if (currSlice->structure == FRAME) { - FUN_CHECK(ret = append_interview_list(p_Vid->p_Dpb_layer[1], 0, 0, - currSlice->fs_listinterview0, &currSlice->listinterviewidx0, currPOC, curr_layer_id, anchor_pic_flag)); - for (i = 0; i < (RK_U32)currSlice->listinterviewidx0; i++) { - currSlice->listP[0][list0idx++] = currSlice->fs_listinterview0[i]->frame; - } - currSlice->listXsizeP[0] = (RK_U8)list0idx; - } else { - FUN_CHECK(ret = append_interview_list(p_Vid->p_Dpb_layer[1], currSlice->structure, 0, - currSlice->fs_listinterview0, &currSlice->listinterviewidx0, currPOC, curr_layer_id, anchor_pic_flag)); - gen_pic_list_from_frame_interview_list(currSlice->structure, currSlice->fs_listinterview0, - currSlice->listinterviewidx0, currSlice->listP[0], &currSlice->listXsizeP[0]); - } - } - // set the unused list entries to NULL - for (i = currSlice->listXsizeP[0]; i < (MAX_LIST_SIZE); i++) { - currSlice->listP[0][i] = p_Vid->no_ref_pic; - } - for (i = currSlice->listXsizeP[1]; i < (MAX_LIST_SIZE); i++) { - currSlice->listP[1][i] = p_Vid->no_ref_pic; - } - MPP_FREE(currSlice->fs_listinterview0); - - return ret = MPP_OK; -__FAILED: - MPP_FREE(fs_list0); - MPP_FREE(fs_listlt); - MPP_FREE(currSlice->fs_listinterview0); - - return ret; -} - -static MPP_RET init_lists_b_slice_mvc(H264_SLICE_t *currSlice) -{ - RK_U32 i = 0; - RK_S32 j = 0; - RK_S32 list0idx = 0; - RK_S32 list0idx_1 = 0; - RK_S32 listltidx = 0; - H264_FrameStore_t **fs_list0 = NULL; - H264_FrameStore_t **fs_list1 = NULL; - H264_FrameStore_t **fs_listlt = NULL; - MPP_RET ret = MPP_ERR_UNKNOW; - - H264dVideoCtx_t *p_Vid = currSlice->p_Vid; - H264_DpbBuf_t *p_Dpb = currSlice->p_Dpb; - RK_S32 currPOC = currSlice->ThisPOC; - RK_S32 anchor_pic_flag = currSlice->anchor_pic_flag; - - currSlice->listXsizeB[0] = 0; - currSlice->listXsizeB[1] = 0; - currSlice->listinterviewidx0 = 0; - currSlice->listinterviewidx1 = 0; - // B-Slice - if (currSlice->structure == FRAME) { - for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) { - if (p_Dpb->fs_ref[i]->is_used == 3) { - if ((p_Dpb->fs_ref[i]->frame->used_for_reference) && (!p_Dpb->fs_ref[i]->frame->is_long_term)) { - if (currSlice->framepoc >= p_Dpb->fs_ref[i]->frame->poc) { - currSlice->listB[0][list0idx++] = p_Dpb->fs_ref[i]->frame; - } - } - } - } - qsort((void *)currSlice->listB[0], list0idx, sizeof(H264_StorePic_t*), compare_pic_by_poc_desc); - list0idx_1 = list0idx; - for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) { - if (p_Dpb->fs_ref[i]->is_used == 3) { - if ((p_Dpb->fs_ref[i]->frame->used_for_reference) && (!p_Dpb->fs_ref[i]->frame->is_long_term)) { - if (currSlice->framepoc < p_Dpb->fs_ref[i]->frame->poc) { - currSlice->listB[0][list0idx++] = p_Dpb->fs_ref[i]->frame; - } - } - } - } - qsort((void *)&currSlice->listB[0][list0idx_1], list0idx - list0idx_1, sizeof(H264_StorePic_t*), compare_pic_by_poc_asc); - - for (j = 0; j < list0idx_1; j++) { - currSlice->listB[1][list0idx - list0idx_1 + j] = currSlice->listB[0][j]; - } - for (j = list0idx_1; j < list0idx; j++) { - currSlice->listB[1][j - list0idx_1] = currSlice->listB[0][j]; - } - currSlice->listXsizeB[0] = currSlice->listXsizeB[1] = (RK_U8)list0idx; - // long term handling - for (i = 0; i < p_Dpb->ltref_frames_in_buffer; i++) { - if (p_Dpb->fs_ltref[i]->is_used == 3) { - if (p_Dpb->fs_ltref[i]->frame->is_long_term) { - currSlice->listB[0][list0idx] = p_Dpb->fs_ltref[i]->frame; - currSlice->listB[1][list0idx++] = p_Dpb->fs_ltref[i]->frame; - } - } - } - qsort((void *)&currSlice->listB[0][(RK_S16)currSlice->listXsizeB[0]], - list0idx - currSlice->listXsizeB[0], sizeof(H264_StorePic_t*), compare_pic_by_lt_pic_num_asc); - qsort((void *)&currSlice->listB[1][(RK_S16)currSlice->listXsizeB[0]], - list0idx - currSlice->listXsizeB[0], sizeof(H264_StorePic_t*), compare_pic_by_lt_pic_num_asc); - currSlice->listXsizeB[0] = currSlice->listXsizeB[1] = (RK_U8)list0idx; - } else { - fs_list0 = mpp_calloc(H264_FrameStore_t*, p_Dpb->size); - fs_list1 = mpp_calloc(H264_FrameStore_t*, p_Dpb->size); - fs_listlt = mpp_calloc(H264_FrameStore_t*, p_Dpb->size); - MEM_CHECK(ret, fs_list0 && fs_list1 && fs_listlt); - currSlice->listXsizeB[0] = 0; - currSlice->listXsizeB[1] = 1; - for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) { - if (p_Dpb->fs_ref[i]->is_used) { - if (currSlice->ThisPOC >= p_Dpb->fs_ref[i]->poc) { - fs_list0[list0idx++] = p_Dpb->fs_ref[i]; - } - } - } - qsort((void *)fs_list0, list0idx, sizeof(H264_FrameStore_t*), compare_fs_by_poc_desc); - list0idx_1 = list0idx; - for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) { - if (p_Dpb->fs_ref[i]->is_used) { - if (currSlice->ThisPOC < p_Dpb->fs_ref[i]->poc) { - fs_list0[list0idx++] = p_Dpb->fs_ref[i]; - } - } - } - qsort((void *)&fs_list0[list0idx_1], list0idx - list0idx_1, sizeof(H264_FrameStore_t*), compare_fs_by_poc_asc); - - for (j = 0; j < list0idx_1; j++) { - fs_list1[list0idx - list0idx_1 + j] = fs_list0[j]; - } - for (j = list0idx_1; j < list0idx; j++) { - fs_list1[j - list0idx_1] = fs_list0[j]; - } - currSlice->listXsizeB[0] = 0; - currSlice->listXsizeB[1] = 0; - gen_pic_list_from_frame_list(currSlice->structure, fs_list0, list0idx, currSlice->listB[0], &currSlice->listXsizeB[0], 0); - gen_pic_list_from_frame_list(currSlice->structure, fs_list1, list0idx, currSlice->listB[1], &currSlice->listXsizeB[1], 0); - - // long term handling - for (i = 0; i < p_Dpb->ltref_frames_in_buffer; i++) { - fs_listlt[listltidx++] = p_Dpb->fs_ltref[i]; - } - qsort((void *)fs_listlt, listltidx, sizeof(H264_FrameStore_t*), compare_fs_by_lt_pic_idx_asc); - - gen_pic_list_from_frame_list(currSlice->structure, fs_listlt, listltidx, currSlice->listB[0], &currSlice->listXsizeB[0], 1); - gen_pic_list_from_frame_list(currSlice->structure, fs_listlt, listltidx, currSlice->listB[1], &currSlice->listXsizeB[1], 1); - - MPP_FREE(fs_list0); - MPP_FREE(fs_list1); - MPP_FREE(fs_listlt); - } - if ((currSlice->listXsizeB[0] == currSlice->listXsizeB[1]) && (currSlice->listXsizeB[0] > 1)) { - // check if lists are identical, if yes swap first two elements of currSlice->listX[1] - RK_S32 diff = 0; - for (j = 0; j < currSlice->listXsizeB[0]; j++) { - if (currSlice->listB[0][j] != currSlice->listB[1][j]) { - diff = 1; - break; - } - } - if (!diff) { - H264_StorePic_t *tmp_s = currSlice->listB[1][0]; - currSlice->listB[1][0] = currSlice->listB[1][1]; - currSlice->listB[1][1] = tmp_s; - } - } - if (currSlice->svc_extension_flag == 0) { - RK_S32 curr_layer_id = currSlice->layer_id; - // B-Slice - currSlice->fs_listinterview0 = mpp_calloc(H264_FrameStore_t*, p_Dpb->size); - currSlice->fs_listinterview1 = mpp_calloc(H264_FrameStore_t*, p_Dpb->size); - MEM_CHECK(ret, currSlice->fs_listinterview0 && currSlice->fs_listinterview1); - list0idx = currSlice->listXsizeB[0]; - if (currSlice->structure == FRAME) { - FUN_CHECK(ret = append_interview_list(p_Vid->p_Dpb_layer[1], 0, 0, - currSlice->fs_listinterview0, &currSlice->listinterviewidx0, currPOC, curr_layer_id, anchor_pic_flag)); - FUN_CHECK(ret = append_interview_list(p_Vid->p_Dpb_layer[1], 0, 1, - currSlice->fs_listinterview1, &currSlice->listinterviewidx1, currPOC, curr_layer_id, anchor_pic_flag)); - - for (i = 0; i < (RK_U32)currSlice->listinterviewidx0; i++) { - currSlice->listB[0][list0idx++] = currSlice->fs_listinterview0[i]->frame; - } - currSlice->listXsizeB[0] = (RK_U8)list0idx; - list0idx = currSlice->listXsizeB[1]; - for (i = 0; i < (RK_U32)currSlice->listinterviewidx1; i++) { - currSlice->listB[1][list0idx++] = currSlice->fs_listinterview1[i]->frame; - } - currSlice->listXsizeB[1] = (RK_U8)list0idx; - } else { - FUN_CHECK(ret = append_interview_list(p_Vid->p_Dpb_layer[1], currSlice->structure, 0, - currSlice->fs_listinterview0, &currSlice->listinterviewidx0, currPOC, curr_layer_id, anchor_pic_flag)); - gen_pic_list_from_frame_interview_list(currSlice->structure, currSlice->fs_listinterview0, - currSlice->listinterviewidx0, currSlice->listB[0], &currSlice->listXsizeB[0]); - FUN_CHECK(ret = append_interview_list(p_Vid->p_Dpb_layer[1], currSlice->structure, 1, - currSlice->fs_listinterview1, &currSlice->listinterviewidx1, currPOC, curr_layer_id, anchor_pic_flag)); - gen_pic_list_from_frame_interview_list(currSlice->structure, currSlice->fs_listinterview1, - currSlice->listinterviewidx1, currSlice->listB[1], &currSlice->listXsizeB[1]); - } - } - // set the unused list entries to NULL - for (i = currSlice->listXsizeB[0]; i < (MAX_LIST_SIZE); i++) { - currSlice->listB[0][i] = p_Vid->no_ref_pic; - } - for (i = currSlice->listXsizeB[1]; i < (MAX_LIST_SIZE); i++) { - currSlice->listB[1][i] = p_Vid->no_ref_pic; - } - MPP_FREE(currSlice->fs_listinterview0); - MPP_FREE(currSlice->fs_listinterview1); - - return ret = MPP_OK; -__FAILED: - MPP_FREE(fs_list0); - MPP_FREE(fs_list1); - MPP_FREE(fs_listlt); - MPP_FREE(currSlice->fs_listinterview0); - MPP_FREE(currSlice->fs_listinterview1); - - return ret; -} - -static RK_U32 get_short_term_pic(H264_SLICE_t *currSlice, RK_S32 picNum, H264_StorePic_t **find_pic) -{ - RK_U32 i = 0; - H264_StorePic_t *ret_pic = NULL; - H264_StorePic_t *near_pic = NULL; - H264_DpbBuf_t *p_Dpb = currSlice->p_Dpb; - - for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) { - if (currSlice->structure == FRAME) { - if ((p_Dpb->fs_ref[i]->is_reference == 3) - && (!p_Dpb->fs_ref[i]->frame->is_long_term)) { - if (p_Dpb->fs_ref[i]->frame->pic_num == picNum) { - ret_pic = p_Dpb->fs_ref[i]->frame; - break; - } else { - near_pic = p_Dpb->fs_ref[i]->frame; - } - } - } else { - if ((p_Dpb->fs_ref[i]->is_reference & 1) - && (!p_Dpb->fs_ref[i]->top_field->is_long_term)) { - if (p_Dpb->fs_ref[i]->top_field->pic_num == picNum) { - ret_pic = p_Dpb->fs_ref[i]->top_field; - break; - } else { - near_pic = p_Dpb->fs_ref[i]->top_field; - } - } - if ((p_Dpb->fs_ref[i]->is_reference & 2) - && (!p_Dpb->fs_ref[i]->bottom_field->is_long_term)) { - if (p_Dpb->fs_ref[i]->bottom_field->pic_num == picNum) { - ret_pic = p_Dpb->fs_ref[i]->bottom_field; - break; - } else { - near_pic = p_Dpb->fs_ref[i]->bottom_field; - } - } - } - } - *find_pic = ret_pic ? ret_pic : near_pic; - return (ret_pic ? 1 : 0); -} - - -static H264_StorePic_t *get_long_term_pic(H264_SLICE_t *currSlice, RK_S32 LongtermPicNum) -{ - RK_U32 i = 0; - H264_DpbBuf_t *p_Dpb = currSlice->p_Dpb; - - for (i = 0; i < p_Dpb->ltref_frames_in_buffer; i++) { - if (currSlice->structure == FRAME) { - if (p_Dpb->fs_ltref[i]->is_reference == 3) - if ((p_Dpb->fs_ltref[i]->frame->is_long_term) - && (p_Dpb->fs_ltref[i]->frame->long_term_pic_num == LongtermPicNum)) - return p_Dpb->fs_ltref[i]->frame; - } else { - if (p_Dpb->fs_ltref[i]->is_reference & 1) - if ((p_Dpb->fs_ltref[i]->top_field->is_long_term) - && (p_Dpb->fs_ltref[i]->top_field->long_term_pic_num == LongtermPicNum)) - return p_Dpb->fs_ltref[i]->top_field; - if (p_Dpb->fs_ltref[i]->is_reference & 2) - if ((p_Dpb->fs_ltref[i]->bottom_field->is_long_term) - && (p_Dpb->fs_ltref[i]->bottom_field->long_term_pic_num == LongtermPicNum)) - return p_Dpb->fs_ltref[i]->bottom_field; - } - } - return NULL; -} -static RK_U32 check_ref_pic_list(H264_SLICE_t *currSlice, RK_S32 cur_list) -{ - RK_S32 i = 0; - RK_U32 dpb_error_flag = 0; - RK_S32 maxPicNum = 0, currPicNum = 0; - RK_S32 picNumLXNoWrap = 0, picNumLXPred = 0, picNumLX = 0; - - RK_S32 *modification_of_pic_nums_idc = currSlice->modification_of_pic_nums_idc[cur_list]; - RK_S32 *abs_diff_pic_num_minus1 = currSlice->abs_diff_pic_num_minus1[cur_list]; - RK_S32 *long_term_pic_idx = currSlice->long_term_pic_idx[cur_list]; - H264dVideoCtx_t *p_Vid = currSlice->p_Vid; - - if (currSlice->structure == FRAME) { - maxPicNum = p_Vid->max_frame_num; - currPicNum = currSlice->frame_num; - } else { - maxPicNum = 2 * p_Vid->max_frame_num; - currPicNum = 2 * currSlice->frame_num + 1; - } - picNumLXPred = currPicNum; - for (i = 0; modification_of_pic_nums_idc[i] != 3; i++) { - H264_StorePic_t *tmp = NULL; - RK_U32 error_flag = 0; - if (modification_of_pic_nums_idc[i] > 3) - continue; - if (modification_of_pic_nums_idc[i] < 2) { - if (modification_of_pic_nums_idc[i] == 0) { - if ( (picNumLXPred - (abs_diff_pic_num_minus1[i] + 1)) < 0) - picNumLXNoWrap = picNumLXPred - (abs_diff_pic_num_minus1[i] + 1) + maxPicNum; - else - picNumLXNoWrap = picNumLXPred - (abs_diff_pic_num_minus1[i] + 1); - } else { //!< (modification_of_pic_nums_idc[i] == 1) - if (picNumLXPred + (abs_diff_pic_num_minus1[i] + 1) >= maxPicNum) - picNumLXNoWrap = picNumLXPred + (abs_diff_pic_num_minus1[i] + 1) - maxPicNum; - else - picNumLXNoWrap = picNumLXPred + (abs_diff_pic_num_minus1[i] + 1); - } - picNumLXPred = picNumLXNoWrap; - picNumLX = (picNumLXNoWrap > currPicNum) ? (picNumLXNoWrap - maxPicNum) : picNumLXNoWrap; - error_flag = 1; - if (get_short_term_pic(currSlice, picNumLX, &tmp)) { //!< find short reference - MppFrame mframe = NULL; - H264D_DBG(H264D_DBG_DPB_REF_ERR, "find short reference, slot_idx=%d.\n", tmp->mem_mark->slot_idx); - if (tmp && tmp->mem_mark) { - mpp_buf_slot_get_prop(p_Vid->p_Dec->frame_slots, tmp->mem_mark->slot_idx, SLOT_FRAME_PTR, &mframe); - if (mframe && !mpp_frame_get_errinfo(mframe)) { - error_flag = 0; - } - } - } - - } else { //!< (modification_of_pic_nums_idc[i] == 2) - tmp = get_long_term_pic(currSlice, long_term_pic_idx[i]); - } - dpb_error_flag |= error_flag; - } - - return dpb_error_flag; -} - -static RK_U32 check_ref_dbp_err(H264_DecCtx_t *p_Dec, H264_RefPicInfo_t *pref, RK_U32 active_refs) -{ - RK_U32 i = 0; - RK_U32 dpb_error_flag = 0; - - for (i = 0; i < MAX_REF_SIZE; i++) { - if (pref[i].valid) { - MppFrame mframe = NULL; - RK_U32 slot_idx = p_Dec->dpb_info[pref[i].dpb_idx].slot_index; - mpp_buf_slot_get_prop(p_Dec->frame_slots, slot_idx, SLOT_FRAME_PTR, &mframe); - if (mframe) { - if (i < active_refs) { - dpb_error_flag |= mpp_frame_get_errinfo(mframe); - } - H264D_DBG(H264D_DBG_DPB_REF_ERR, "[DPB_REF_ERR] slot_idx=%d, dpb_err[%d]=%d", slot_idx, i, mpp_frame_get_errinfo(mframe)); - } - } - } - return dpb_error_flag; -} - -static void check_refer_picture_lists(H264_SLICE_t *currSlice) -{ - H264_DecCtx_t *p_Dec = currSlice->p_Dec; - H264dErrCtx_t *p_err = &p_Dec->errctx; - - if (I_SLICE == currSlice->slice_type) { - p_err->dpb_err_flag = 0; - return; - } -#if 1 - - if ((currSlice->slice_type % 5) != I_SLICE - && (currSlice->slice_type % 5) != SI_SLICE) { - if (currSlice->ref_pic_list_reordering_flag[LIST_0]) { - p_err->cur_err_flag |= check_ref_pic_list(currSlice, 0) ? 1 : 0; - } - else { - RK_S32 pps_refs = currSlice->active_pps->num_ref_idx_l0_default_active_minus1 + 1; - RK_S32 over_flag = currSlice->num_ref_idx_override_flag; - RK_S32 active_l0 = over_flag ? currSlice->num_ref_idx_active[LIST_0] : pps_refs; - p_err->cur_err_flag |= check_ref_dbp_err(p_Dec, p_Dec->refpic_info_p, active_l0) ? 1 : 0; - H264D_DBG(H264D_DBG_DPB_REF_ERR, "list0 dpb: cur_err_flag=%d, pps_refs=%d, over_flag=%d, num_ref_l0=%d\n", - p_err->cur_err_flag, pps_refs, over_flag, active_l0); - } - } - if (currSlice->slice_type % 5 == B_SLICE) { - if (currSlice->ref_pic_list_reordering_flag[LIST_1]) { - p_err->cur_err_flag |= check_ref_pic_list(currSlice, 1) ? 1 : 0; - } - else { - RK_S32 pps_refs = currSlice->active_pps->num_ref_idx_l1_default_active_minus1 + 1; - RK_S32 over_flag = currSlice->num_ref_idx_override_flag; - RK_S32 active_l1 = over_flag ? currSlice->num_ref_idx_active[LIST_1] : pps_refs; - p_err->cur_err_flag |= check_ref_dbp_err(p_Dec, p_Dec->refpic_info_b[1], active_l1) ? 1 : 0; - H264D_DBG(H264D_DBG_DPB_REF_ERR, "list1 dpb: cur_err_flag=%d, pps_refs=%d, over_flag=%d, num_ref_l1=%d\n", - p_err->cur_err_flag, pps_refs, over_flag, active_l1); - } - //!< B_SLICE only has one refer - if ((currSlice->active_sps->vui_seq_parameters.num_reorder_frames > 1) - && (currSlice->p_Dpb->ref_frames_in_buffer < 2)) { - p_err->cur_err_flag |= 1; - H264D_DBG(H264D_DBG_DPB_REF_ERR, "[DPB_REF_ERR] error, B frame only has one refer"); - } - } - -#endif - -} - -static void reset_dpb_info(H264_DpbInfo_t *p) -{ - p->refpic = NULL; - p->TOP_POC = 0; - p->BOT_POC = 0; - p->field_flag = 0; - p->slot_index = -1; - p->colmv_is_used = 0; - p->frame_num = 0; - p->is_long_term = 0; - p->long_term_pic_num = 0; - p->voidx = 0; - p->view_id = 0; - p->is_used = 0; -} - -static MPP_RET prepare_init_dpb_info(H264_SLICE_t *currSlice) -{ - RK_U32 i = 0, j = 0; - H264_DpbBuf_t *p_Dpb = currSlice->p_Dpb; - H264_DecCtx_t *p_Dec = currSlice->p_Dec; - - //!< reset parameters - for (i = 0; i < MAX_DPB_SIZE; i++) { - reset_dpb_info(&p_Dec->dpb_info[i]); - } - //!< reference -#if 1 - for (i = 0, j = 0; j < p_Dpb->ref_frames_in_buffer; i++, j++) { - if (p_Dpb->fs_ref[j]->is_used == 3) { - p_Dec->dpb_info[i].refpic = p_Dpb->fs_ref[j]->frame; - if (p_Dpb->fs_ref[j]->frame->iCodingType == FIELD_CODING) { - p_Dec->dpb_info[i].TOP_POC = p_Dpb->fs_ref[j]->top_field->poc; - p_Dec->dpb_info[i].BOT_POC = p_Dpb->fs_ref[j]->bottom_field->poc; - } else { - if (p_Dpb->fs_ref[j]->frame->frame_poc != p_Dpb->fs_ref[j]->frame->poc) { - p_Dec->dpb_info[i].TOP_POC = p_Dpb->fs_ref[j]->frame->top_poc - p_Dpb->fs_ref[j]->frame->frame_poc; - p_Dec->dpb_info[i].BOT_POC = p_Dpb->fs_ref[j]->frame->bottom_poc - p_Dpb->fs_ref[j]->frame->frame_poc; - } else { - p_Dec->dpb_info[i].TOP_POC = p_Dpb->fs_ref[j]->frame->top_poc; - p_Dec->dpb_info[i].BOT_POC = p_Dpb->fs_ref[j]->frame->bottom_poc; - } - } - p_Dec->dpb_info[i].field_flag = p_Dpb->fs_ref[j]->frame->iCodingType == FIELD_CODING; - p_Dec->dpb_info[i].slot_index = p_Dpb->fs_ref[j]->frame->mem_mark->slot_idx; - p_Dec->dpb_info[i].colmv_is_used = (p_Dpb->fs_ref[j]->frame->colmv_no_used_flag ? 0 : 1); - } else if (p_Dpb->fs_ref[j]->is_used) { - if (p_Dpb->fs_ref[j]->is_used & 0x1) { // top - p_Dec->dpb_info[i].refpic = p_Dpb->fs_ref[j]->top_field; - - p_Dec->dpb_info[i].TOP_POC = p_Dpb->fs_ref[j]->top_field->poc; - p_Dec->dpb_info[i].BOT_POC = 0; - p_Dec->dpb_info[i].field_flag = 1; - p_Dec->dpb_info[i].slot_index = p_Dpb->fs_ref[j]->top_field->mem_mark->slot_idx; - p_Dec->dpb_info[i].colmv_is_used = (p_Dpb->fs_ref[j]->top_field->colmv_no_used_flag ? 0 : 1); - } else { // if(p_Dpb->fs_ref[j]->is_used & 0x2) // bottom - p_Dec->dpb_info[i].refpic = p_Dpb->fs_ref[j]->bottom_field; - p_Dec->dpb_info[i].TOP_POC = 0; - p_Dec->dpb_info[i].BOT_POC = p_Dpb->fs_ref[j]->bottom_field->poc; - p_Dec->dpb_info[i].field_flag = 1; - p_Dec->dpb_info[i].slot_index = p_Dpb->fs_ref[j]->bottom_field->mem_mark->slot_idx; - p_Dec->dpb_info[i].colmv_is_used = (p_Dpb->fs_ref[j]->bottom_field->colmv_no_used_flag ? 0 : 1); - } - } - p_Dec->dpb_info[i].frame_num = p_Dpb->fs_ref[j]->frame_num; - p_Dec->dpb_info[i].is_long_term = 0; - p_Dec->dpb_info[i].long_term_pic_num = 0; - p_Dec->dpb_info[i].long_term_frame_idx = 0; - p_Dec->dpb_info[i].voidx = p_Dpb->fs_ref[j]->layer_id; - p_Dec->dpb_info[i].view_id = p_Dpb->fs_ref[j]->view_id; - p_Dec->dpb_info[i].is_used = p_Dpb->fs_ref[j]->is_used; - } -#endif - //!<---- long term reference -#if 1 - for (j = 0; j < p_Dpb->ltref_frames_in_buffer; i++, j++) { - if (p_Dpb->fs_ltref[j]->is_used == 3) { - p_Dec->dpb_info[i].refpic = p_Dpb->fs_ltref[j]->frame; - - if (p_Dpb->fs_ltref[j]->frame->iCodingType == FIELD_CODING) { - p_Dec->dpb_info[i].TOP_POC = p_Dpb->fs_ltref[j]->top_field->poc; - p_Dec->dpb_info[i].BOT_POC = p_Dpb->fs_ltref[j]->bottom_field->poc; - } else { - if (p_Dpb->fs_ltref[j]->frame->frame_poc != p_Dpb->fs_ltref[j]->frame->poc) { - p_Dec->dpb_info[i].TOP_POC = p_Dpb->fs_ltref[j]->frame->top_poc - p_Dpb->fs_ltref[j]->frame->frame_poc; - p_Dec->dpb_info[i].BOT_POC = p_Dpb->fs_ltref[j]->frame->bottom_poc - p_Dpb->fs_ltref[j]->frame->frame_poc; - } else { - p_Dec->dpb_info[i].TOP_POC = p_Dpb->fs_ltref[j]->frame->top_poc; - p_Dec->dpb_info[i].BOT_POC = p_Dpb->fs_ltref[j]->frame->bottom_poc; - } - - } - p_Dec->dpb_info[i].field_flag = p_Dpb->fs_ltref[j]->frame->iCodingType == FIELD_CODING; - p_Dec->dpb_info[i].slot_index = p_Dpb->fs_ltref[j]->frame->mem_mark->slot_idx; - p_Dec->dpb_info[i].colmv_is_used = (p_Dpb->fs_ltref[j]->frame->colmv_no_used_flag ? 0 : 1); - p_Dec->dpb_info[i].long_term_pic_num = p_Dpb->fs_ltref[j]->frame->long_term_pic_num; - } else if (p_Dpb->fs_ltref[j]->is_used) { - if (p_Dpb->fs_ltref[j]->is_used & 0x1) { - p_Dec->dpb_info[i].refpic = p_Dpb->fs_ltref[j]->top_field; - p_Dec->dpb_info[i].TOP_POC = p_Dpb->fs_ltref[j]->top_field->poc; - p_Dec->dpb_info[i].BOT_POC = 0; - p_Dec->dpb_info[i].field_flag = 1; - p_Dec->dpb_info[i].slot_index = p_Dpb->fs_ltref[j]->top_field->mem_mark->slot_idx; - p_Dec->dpb_info[i].colmv_is_used = (p_Dpb->fs_ltref[j]->top_field->colmv_no_used_flag ? 0 : 1); - p_Dec->dpb_info[i].long_term_pic_num = p_Dpb->fs_ltref[j]->top_field->long_term_pic_num; - } else { // if(p_Dpb->fs_ref[j]->is_used & 0x2) - p_Dec->dpb_info[i].refpic = p_Dpb->fs_ltref[j]->bottom_field; - p_Dec->dpb_info[i].TOP_POC = 0; - p_Dec->dpb_info[i].BOT_POC = p_Dpb->fs_ltref[j]->bottom_field->poc; - p_Dec->dpb_info[i].field_flag = 1; - p_Dec->dpb_info[i].slot_index = p_Dpb->fs_ltref[j]->bottom_field->mem_mark->slot_idx; - p_Dec->dpb_info[i].colmv_is_used = (p_Dpb->fs_ltref[j]->bottom_field->colmv_no_used_flag ? 0 : 1); - p_Dec->dpb_info[i].long_term_pic_num = p_Dpb->fs_ltref[j]->bottom_field->long_term_pic_num; - } - } - p_Dec->dpb_info[i].frame_num = p_Dpb->fs_ltref[j]->long_term_frame_idx; //long term use long_term_frame_idx - p_Dec->dpb_info[i].is_long_term = 1; - p_Dec->dpb_info[i].long_term_frame_idx = p_Dpb->fs_ltref[j]->long_term_frame_idx; - p_Dec->dpb_info[i].voidx = p_Dpb->fs_ltref[j]->layer_id; - p_Dec->dpb_info[i].view_id = p_Dpb->fs_ltref[j]->view_id; - p_Dec->dpb_info[i].is_used = p_Dpb->fs_ltref[j]->is_used; - } -#endif - //!< inter-layer reference (for multi-layered codecs) -#if 1 - for (j = 0; j < p_Dpb->used_size_il; i++, j++) { - if (currSlice->structure == FRAME && p_Dpb->fs_ilref[j]->is_used == 3) { - if (p_Dpb->fs_ilref[j]->inter_view_flag[0] == 0 && p_Dpb->fs_ilref[j]->inter_view_flag[1] == 0) - break; - p_Dec->dpb_info[i].refpic = p_Dpb->fs_ilref[j]->frame; - - if (p_Dpb->fs_ilref[j]->frame->is_mmco_5) { - p_Dec->dpb_info[i].TOP_POC = p_Dpb->fs_ilref[j]->frame->top_poc_mmco5; - p_Dec->dpb_info[i].BOT_POC = p_Dpb->fs_ilref[j]->frame->bot_poc_mmco5; - } else { - p_Dec->dpb_info[i].TOP_POC = p_Dpb->fs_ilref[j]->frame->top_poc; - p_Dec->dpb_info[i].BOT_POC = p_Dpb->fs_ilref[j]->frame->bottom_poc; - } - p_Dec->dpb_info[i].field_flag = p_Dpb->fs_ilref[j]->frame->iCodingType == FIELD_CODING; - p_Dec->dpb_info[i].slot_index = p_Dpb->fs_ilref[j]->frame->mem_mark->slot_idx; - p_Dec->dpb_info[i].colmv_is_used = (p_Dpb->fs_ilref[j]->frame->colmv_no_used_flag ? 0 : 1); - } else if (currSlice->structure != FRAME && p_Dpb->fs_ilref[j]->is_used) { - if (p_Dpb->fs_ilref[j]->is_used == 0x3) { - if (p_Dpb->fs_ilref[j]->inter_view_flag[currSlice->structure == BOTTOM_FIELD] == 0) - break; - p_Dec->dpb_info[i].refpic = p_Dpb->fs_ilref[j]->top_field; - - if (p_Dpb->fs_ilref[j]->top_field->is_mmco_5) { - p_Dec->dpb_info[i].TOP_POC = p_Dpb->fs_ilref[j]->top_field->top_poc_mmco5; - } else { - p_Dec->dpb_info[i].TOP_POC = p_Dpb->fs_ilref[j]->top_field->top_poc; - } - if (p_Dpb->fs_ilref[j]->bottom_field->is_mmco_5) { - p_Dec->dpb_info[i].BOT_POC = p_Dpb->fs_ilref[j]->bottom_field->bot_poc_mmco5; - } else { - p_Dec->dpb_info[i].BOT_POC = p_Dpb->fs_ilref[j]->bottom_field->bottom_poc; - } - p_Dec->dpb_info[i].field_flag = p_Dpb->fs_ilref[j]->frame->iCodingType == FIELD_CODING; - p_Dec->dpb_info[i].slot_index = p_Dpb->fs_ilref[j]->frame->mem_mark->slot_idx; - p_Dec->dpb_info[i].colmv_is_used = (p_Dpb->fs_ilref[j]->frame->colmv_no_used_flag ? 0 : 1); - } - if (p_Dpb->fs_ilref[j]->is_used & 0x1) { - if (p_Dpb->fs_ilref[j]->inter_view_flag[0] == 0) - break; - p_Dec->dpb_info[i].refpic = p_Dpb->fs_ilref[j]->top_field; - - if (p_Dpb->fs_ilref[j]->top_field->is_mmco_5) { - p_Dec->dpb_info[i].TOP_POC = p_Dpb->fs_ilref[j]->top_field->top_poc_mmco5; - } else { - p_Dec->dpb_info[i].TOP_POC = p_Dpb->fs_ilref[j]->top_field->top_poc; - } - p_Dec->dpb_info[i].BOT_POC = 0; - p_Dec->dpb_info[i].field_flag = 1; - p_Dec->dpb_info[i].slot_index = p_Dpb->fs_ilref[j]->top_field->mem_mark->slot_idx; - p_Dec->dpb_info[i].colmv_is_used = (p_Dpb->fs_ilref[j]->top_field->colmv_no_used_flag ? 0 : 1); - } else { // if(p_Dpb->fs_ref[j]->is_used & 0x2) - if (p_Dpb->fs_ilref[j]->inter_view_flag[1] == 0) - break; - p_Dec->dpb_info[i].refpic = p_Dpb->fs_ilref[j]->bottom_field; - - p_Dec->dpb_info[i].TOP_POC = 0; - if (p_Dpb->fs_ilref[j]->bottom_field->is_mmco_5) { - p_Dec->dpb_info[i].BOT_POC = p_Dpb->fs_ilref[j]->bottom_field->bot_poc_mmco5; - } else { - p_Dec->dpb_info[i].BOT_POC = p_Dpb->fs_ilref[j]->bottom_field->bottom_poc; - } - p_Dec->dpb_info[i].field_flag = 1; - p_Dec->dpb_info[i].slot_index = p_Dpb->fs_ilref[j]->bottom_field->mem_mark->slot_idx; - p_Dec->dpb_info[i].colmv_is_used = (p_Dpb->fs_ilref[j]->bottom_field->colmv_no_used_flag ? 0 : 1); - } - } - p_Dec->dpb_info[i].frame_num = p_Dpb->fs_ilref[j]->frame_num; - p_Dec->dpb_info[i].is_long_term = 0;//p_Dpb->fs_ilref[j]->is_long_term; - p_Dec->dpb_info[i].is_ilt_flag = 1; - p_Dec->dpb_info[i].long_term_pic_num = 0; - p_Dec->dpb_info[i].long_term_frame_idx = 0; - p_Dec->dpb_info[i].voidx = p_Dpb->fs_ilref[j]->layer_id; - p_Dec->dpb_info[i].view_id = p_Dpb->fs_ilref[j]->view_id; - p_Dec->dpb_info[i].is_used = p_Dpb->fs_ilref[j]->is_used; - } -#endif - - return MPP_OK; -} - -static MPP_RET prepare_init_ref_info(H264_SLICE_t *currSlice) -{ - void *refpic = NULL; - RK_U32 i = 0, j = 0, k = 0; - RK_S32 poc = 0, TOP_POC = 0, BOT_POC = 0; - RK_S32 min_poc = 0, max_poc = 0; - RK_S32 layer_id = 0, voidx = 0, is_used = 0, near_dpb_idx = 0; - H264_DecCtx_t *p_Dec = currSlice->p_Dec; - - memset(p_Dec->refpic_info_p, 0, MAX_REF_SIZE * sizeof(H264_RefPicInfo_t)); - memset(p_Dec->refpic_info_b[0], 0, MAX_REF_SIZE * sizeof(H264_RefPicInfo_t)); - memset(p_Dec->refpic_info_b[1], 0, MAX_REF_SIZE * sizeof(H264_RefPicInfo_t)); - - if (currSlice->idr_flag && (currSlice->layer_id == 0)) { // idr_flag==1 && layer_id==0 - goto __RETURN; - } - //!<------ set listP ------- - near_dpb_idx = 0; - for (j = 0; j < 32; j++) { - poc = 0; - layer_id = currSlice->listP[0][j]->layer_id; - if (j < currSlice->listXsizeP[0]) { - if (currSlice->listP[0][j]->structure == FRAME) { - poc = (currSlice->listP[0][j]->is_mmco_5 && currSlice->layer_id && currSlice->listP[0][j]->layer_id == 0) - ? currSlice->listP[0][j]->poc_mmco5 : currSlice->listP[0][j]->poc; - } else if (currSlice->listP[0][j]->structure == TOP_FIELD) { - poc = (currSlice->listP[0][j]->is_mmco_5 && currSlice->layer_id && currSlice->listP[0][j]->layer_id == 0) - ? currSlice->listP[0][j]->top_poc_mmco5 : currSlice->listP[0][j]->top_poc; - } else { - poc = (currSlice->listP[0][j]->is_mmco_5 && currSlice->layer_id && currSlice->listP[0][j]->layer_id == 0) - ? currSlice->listP[0][j]->bot_poc_mmco5 : currSlice->listP[0][j]->bottom_poc; - } - for (i = 0; i < 16; i++) { - refpic = p_Dec->dpb_info[i].refpic; - TOP_POC = p_Dec->dpb_info[i].TOP_POC; - BOT_POC = p_Dec->dpb_info[i].BOT_POC; - voidx = p_Dec->dpb_info[i].voidx; - is_used = p_Dec->dpb_info[i].is_used; - if (currSlice->structure == FRAME && refpic) { - if (poc == MPP_MIN(TOP_POC, BOT_POC) && (layer_id == voidx)) - break; - } else { - if (is_used == 3) { - if ((poc == BOT_POC || poc == TOP_POC) && layer_id == voidx) - break; - } else if (is_used & 1) { - if (poc == TOP_POC && layer_id == voidx) - break; - } else if (is_used & 2) { - if (poc == BOT_POC && layer_id == voidx) - break; - } - } - } - if (i < 16) { - near_dpb_idx = i; - p_Dec->refpic_info_p[j].dpb_idx = i; - } else { - ASSERT(near_dpb_idx >= 0); - p_Dec->refpic_info_p[j].dpb_idx = near_dpb_idx; - p_Dec->errctx.cur_err_flag |= 1; - } - if (currSlice->listP[0][j]->structure == BOTTOM_FIELD) { - p_Dec->refpic_info_p[j].bottom_flag = 1; - } else { - p_Dec->refpic_info_p[j].bottom_flag = 0; - } - p_Dec->refpic_info_p[j].valid = 1; - } else { - p_Dec->refpic_info_p[j].valid = 0; - p_Dec->refpic_info_p[j].dpb_idx = 0; - p_Dec->refpic_info_p[j].bottom_flag = 0; - } - } - //!<------ set listB ------- - for (k = 0; k < 2; k++) { - min_poc = 0xFFFF; - max_poc = -0xFFFF; - near_dpb_idx = 0; - for (j = 0; j < 32; j++) { - poc = 0; - layer_id = currSlice->listB[k][j]->layer_id; - if (j < currSlice->listXsizeB[k]) { - if (currSlice->listB[k][j]->structure == FRAME) { - poc = (currSlice->listB[k][j]->is_mmco_5 && currSlice->layer_id && currSlice->listB[k][j]->layer_id == 0) - ? currSlice->listB[k][j]->poc_mmco5 : currSlice->listB[k][j]->poc; - } else if (currSlice->listB[k][j]->structure == TOP_FIELD) { - poc = (currSlice->listB[k][j]->is_mmco_5 && currSlice->layer_id && currSlice->listB[k][j]->layer_id == 0) - ? currSlice->listB[k][j]->top_poc_mmco5 : currSlice->listB[k][j]->top_poc; - } else { - poc = (currSlice->listB[k][j]->is_mmco_5 && currSlice->layer_id && currSlice->listB[k][j]->layer_id == 0) - ? currSlice->listB[k][j]->bot_poc_mmco5 : currSlice->listB[k][j]->bottom_poc; - } - - min_poc = MPP_MIN(min_poc, poc); - max_poc = MPP_MAX(max_poc, poc); - for (i = 0; i < 16; i++) { - refpic = p_Dec->dpb_info[i].refpic; - TOP_POC = p_Dec->dpb_info[i].TOP_POC; - BOT_POC = p_Dec->dpb_info[i].BOT_POC; - voidx = p_Dec->dpb_info[i].voidx; - is_used = p_Dec->dpb_info[i].is_used; - if (currSlice->structure == FRAME && refpic) { - if (poc == MPP_MIN(TOP_POC, BOT_POC) && (layer_id == voidx)) - break; - } else { - if (is_used == 3) { - if ((poc == BOT_POC || poc == TOP_POC) && layer_id == voidx) - break; - } else if (is_used & 1) { - if (poc == TOP_POC && (layer_id == voidx || (layer_id != voidx && !currSlice->bottom_field_flag))) - break; - } else if (is_used & 2) { - if (poc == BOT_POC && (layer_id == voidx || (layer_id != voidx && currSlice->bottom_field_flag))) - break; - } - } - } - if (i < 16) { - near_dpb_idx = i; - p_Dec->refpic_info_b[k][j].dpb_idx = i; - } else { - ASSERT(near_dpb_idx >= 0); - p_Dec->refpic_info_b[k][j].dpb_idx = near_dpb_idx; - p_Dec->errctx.cur_err_flag |= 1; - } - if (currSlice->listB[k][j]->structure == BOTTOM_FIELD) { - p_Dec->refpic_info_b[k][j].bottom_flag = 1; - } else { - p_Dec->refpic_info_b[k][j].bottom_flag = 0; - } - p_Dec->refpic_info_b[k][j].valid = 1; - } else { - p_Dec->refpic_info_b[k][j].valid = 0; - p_Dec->refpic_info_b[k][j].dpb_idx = 0; - p_Dec->refpic_info_b[k][j].bottom_flag = 0; - } - } - - } - //!< check dpb list poc -#if 0 - { - RK_S32 cur_poc = p_Dec->p_Vid->dec_pic->poc; - if ((currSlice->slice_type % 5) != I_SLICE - && (currSlice->slice_type % 5) != SI_SLICE) { - if (cur_poc < min_poc) { - p_Dec->errctx.cur_err_flag |= 1; - H264D_DBG(H264D_DBG_DPB_REF_ERR, "[DPB_REF_ERR] min_poc=%d, dec_poc=%d", min_poc, cur_poc); - } - } - if (currSlice->slice_type % 5 == B_SLICE) { - if (cur_poc > max_poc) { - p_Dec->errctx.cur_err_flag |= 1; - H264D_DBG(H264D_DBG_DPB_REF_ERR, "[DPB_REF_ERR] max_poc=%d, dec_poc=%d", max_poc, cur_poc); - } - } - } -#endif -__RETURN: - return MPP_OK; -} - -static MPP_RET check_refer_dpb_buf_slots(H264_SLICE_t *currSlice) -{ - RK_U32 i = 0; - RK_S32 slot_idx = 0; - RK_U32 dpb_used = 0; - H264_DecCtx_t *p_Dec = NULL; - H264_DpbMark_t *p_mark = NULL; - - p_Dec = currSlice->p_Dec; - //!< set buf slot flag - for (i = 0; i < MAX_DPB_SIZE; i++) { - if ((NULL != p_Dec->dpb_info[i].refpic) && (p_Dec->dpb_info[i].slot_index >= 0)) { - p_Dec->in_task->refer[i] = p_Dec->dpb_info[i].slot_index; - mpp_buf_slot_set_flag(p_Dec->frame_slots, p_Dec->dpb_info[i].slot_index, SLOT_HAL_INPUT); - mpp_buf_slot_set_flag(p_Dec->frame_slots, p_Dec->dpb_info[i].slot_index, SLOT_CODEC_USE); - } else { - p_Dec->in_task->refer[i] = -1; - } - } - //!< dpb info - if (rkv_h264d_parse_debug & H264D_DBG_DPB_INFO) { - H264D_DBG(H264D_DBG_DPB_INFO, "[DPB_INFO] cur_slot_idx=%d", p_Dec->in_task->output); - for (i = 0; i < MAX_DPB_SIZE; i++) { - slot_idx = p_Dec->in_task->refer[i]; - if (slot_idx >= 0) { - H264D_DBG(H264D_DBG_DPB_INFO, "[DPB_INFO] ref_slot_idx[%d]=%d", i, slot_idx); - } - } - } - //!< mark info - for (i = 0; i < MAX_MARK_SIZE; i++) { - p_mark = &p_Dec->dpb_mark[i]; - if (p_mark->out_flag && (p_mark->slot_idx >= 0)) { - dpb_used++; - if (rkv_h264d_parse_debug & H264D_DBG_DPB_INFO) { - RK_S32 fd = 0; - MppFrame mframe = NULL; - MppBuffer mbuffer = NULL; - mpp_buf_slot_get_prop(p_Dec->frame_slots, p_mark->slot_idx, SLOT_FRAME_PTR, &mframe); - mbuffer = mframe ? mpp_frame_get_buffer(mframe) : NULL; - fd = mbuffer ? mpp_buffer_get_fd(mbuffer) : 0xFF; - H264D_DBG(H264D_DBG_DPB_INFO, "[DPB_MARK_INFO] slot_idx=%d, top_used=%d, bot_used=%d, out_flag=%d, fd=0x%02x", - p_mark->slot_idx, p_mark->top_used, p_mark->bot_used, p_mark->out_flag, fd); - } - } - } - H264D_DBG(H264D_DBG_DPB_INFO, "[DPB_MARK_INFO] ---------- cur_slot=%d --------------------", p_Dec->in_task->output); - - if (dpb_used > currSlice->p_Dpb->size + 2) { - H264D_ERR("[h264d_reset_error]"); - h264d_reset((void *)p_Dec); - return MPP_NOK; - } - - return MPP_OK; -} - - -/*! -*********************************************************************** -* \brief -* flush dpb buffer slot -*********************************************************************** -*/ -//extern "C" -void flush_dpb_buf_slot(H264_DecCtx_t *p_Dec) -{ - RK_U32 i = 0; - H264_DpbMark_t *p_mark = NULL; - - for (i = 0; i < MAX_MARK_SIZE; i++) { - p_mark = &p_Dec->dpb_mark[i]; - if (p_mark && p_mark->out_flag && (p_mark->slot_idx >= 0)) { - MppFrame mframe = NULL; - mpp_buf_slot_get_prop(p_Dec->frame_slots, p_mark->slot_idx, SLOT_FRAME_PTR, &mframe); - if (mframe) { - H264D_DBG(H264D_DBG_SLOT_FLUSH, "[DPB_BUF_FLUSH] slot_idx=%d, top_used=%d, bot_used=%d", - p_mark->slot_idx, p_mark->top_used, p_mark->bot_used); - mpp_frame_set_discard(mframe, 1); - mpp_buf_slot_set_flag(p_Dec->frame_slots, p_mark->slot_idx, SLOT_QUEUE_USE); - mpp_buf_slot_enqueue(p_Dec->frame_slots, p_mark->slot_idx, QUEUE_DISPLAY); - mpp_buf_slot_clr_flag(p_Dec->frame_slots, p_mark->slot_idx, SLOT_CODEC_USE); - p_Dec->last_frame_slot_idx = p_mark->slot_idx; - } - } - reset_dpb_mark(p_mark); - } -} - -/*! -*********************************************************************** -* \brief -* reset dpb mark -*********************************************************************** -*/ -//extern "C" -MPP_RET reset_dpb_mark(H264_DpbMark_t *p_mark) -{ - if (p_mark) { - p_mark->top_used = 0; - p_mark->bot_used = 0; - p_mark->out_flag = 0; - p_mark->slot_idx = -1; - p_mark->pic = NULL; - p_mark->mframe = NULL; - } - - return MPP_OK; -} -/*! -*********************************************************************** -* \brief -* init picture -*********************************************************************** -*/ -//extern "C" -MPP_RET init_picture(H264_SLICE_t *currSlice) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - H264_DecCtx_t *p_Dec = currSlice->p_Vid->p_Dec; - H264dVideoCtx_t *p_Vid = currSlice->p_Vid; - H264dErrCtx_t *p_err = &p_Dec->errctx; - - //!< discard stream before I_SLICE - p_err->i_slice_no += ((!currSlice->layer_id) && (I_SLICE == currSlice->slice_type)) ? 1 : 0; - if (!p_err->i_slice_no) { - H264D_WARNNING("[Discard] Discard slice before I Slice. \n"); - ret = MPP_NOK; - goto __FAILED; - } - FUN_CHECK(ret = alloc_decpic(currSlice)); - if ((p_err->i_slice_no < 2) - && (!currSlice->layer_id) && (I_SLICE == currSlice->slice_type)) { - p_err->first_iframe_poc = p_Vid->dec_pic->poc; //!< recoder first i frame poc - } - //!< idr_memory_management MVC_layer, idr_flag==1 - if (currSlice->layer_id && !currSlice->svc_extension_flag && !currSlice->mvcExt.non_idr_flag) { - ASSERT(currSlice->layer_id == 1); - FUN_CHECK(ret = idr_memory_management(p_Vid->p_Dpb_layer[currSlice->layer_id], p_Vid->dec_pic)); - } - update_ref_list(p_Vid->p_Dpb_layer[currSlice->layer_id]); - update_ltref_list(p_Vid->p_Dpb_layer[currSlice->layer_id]); - update_pic_num(currSlice); - //!< reorder - if (!currSlice->idr_flag || currSlice->layer_id) { - FUN_CHECK(ret = init_lists_p_slice_mvc(currSlice)); - FUN_CHECK(ret = init_lists_b_slice_mvc(currSlice)); - } - prepare_init_dpb_info(currSlice); - prepare_init_ref_info(currSlice); - - FUN_CHECK(ret = check_refer_dpb_buf_slots(currSlice)); - check_refer_picture_lists(currSlice); - - prepare_init_scanlist(currSlice); - fill_picparams(currSlice->p_Vid, &p_Dec->dxva_ctx->pp); - fill_scanlist(currSlice->p_Vid, &p_Dec->dxva_ctx->qm); - - - return ret = MPP_OK; -__FAILED: - return ret; -} - -/*! -*********************************************************************** -* \brief -* update dpb -*********************************************************************** -*/ -//extern "C" -MPP_RET update_dpb(H264_DecCtx_t *p_Dec) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - - p_Dec->p_Vid->exit_picture_flag = 1; - p_Dec->p_Vid->have_outpicture_flag = 1; - ret = exit_picture(p_Dec->p_Vid, &p_Dec->p_Vid->dec_pic); - - p_Dec->p_Vid->iNumOfSlicesDecoded = 0; - p_Dec->p_Vid->exit_picture_flag = 0; - - return ret; -} - +/* +* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#define MODULE_TAG "h264d_init" + +#include +#include +#include + +#include "mpp_mem.h" +#include "vpu_api.h" + +#include "h264d_log.h" +#include "h264d_init.h" +#include "h264d_dpb.h" +#include "h264d_scalist.h" +#include "h264d_fill.h" +#include "h264d_slice.h" + +static MPP_RET decode_poc(H264dVideoCtx_t *p_Vid, H264_SLICE_t *pSlice) +{ + RK_S32 i = 0; + RK_U32 MaxPicOrderCntLsb = 0; + MPP_RET ret = MPP_ERR_UNKNOW; + H264_SPS_t *active_sps = p_Vid->active_sps; + // for POC mode 0: + MaxPicOrderCntLsb = (1 << (active_sps->log2_max_pic_order_cnt_lsb_minus4 + 4)); + + switch (active_sps->pic_order_cnt_type) { + case 0: // POC MODE 0 + // 1st + if (pSlice->idr_flag) { + p_Vid->PrevPicOrderCntMsb = 0; + p_Vid->PrevPicOrderCntLsb = 0; + } else { + if (p_Vid->last_has_mmco_5) { + if (p_Vid->last_pic_bottom_field) { + p_Vid->PrevPicOrderCntMsb = 0; + p_Vid->PrevPicOrderCntLsb = 0; + } else { + p_Vid->PrevPicOrderCntMsb = 0; + p_Vid->PrevPicOrderCntLsb = pSlice->toppoc; + } + } + } + // Calculate the MSBs of current picture + if (pSlice->pic_order_cnt_lsb < p_Vid->PrevPicOrderCntLsb && + (p_Vid->PrevPicOrderCntLsb - pSlice->pic_order_cnt_lsb) >= (RK_S32)(MaxPicOrderCntLsb / 2)) { + pSlice->PicOrderCntMsb = p_Vid->PrevPicOrderCntMsb + MaxPicOrderCntLsb; + } else if (pSlice->pic_order_cnt_lsb > p_Vid->PrevPicOrderCntLsb && + (pSlice->pic_order_cnt_lsb - p_Vid->PrevPicOrderCntLsb) > (RK_S32)(MaxPicOrderCntLsb / 2)) { + pSlice->PicOrderCntMsb = p_Vid->PrevPicOrderCntMsb - MaxPicOrderCntLsb; + } else { + pSlice->PicOrderCntMsb = p_Vid->PrevPicOrderCntMsb; + } + // 2nd + if (pSlice->field_pic_flag == 0) { + //frame pix + pSlice->toppoc = pSlice->PicOrderCntMsb + pSlice->pic_order_cnt_lsb; + pSlice->bottompoc = pSlice->toppoc + pSlice->delta_pic_order_cnt_bottom; + pSlice->ThisPOC = pSlice->framepoc = (pSlice->toppoc < pSlice->bottompoc) ? pSlice->toppoc : pSlice->bottompoc; // POC200301 + } else if (pSlice->bottom_field_flag == 0) { + //top field + pSlice->ThisPOC = pSlice->toppoc = pSlice->PicOrderCntMsb + pSlice->pic_order_cnt_lsb; + } else { + //bottom field + pSlice->ThisPOC = pSlice->bottompoc = pSlice->PicOrderCntMsb + pSlice->pic_order_cnt_lsb; + } + pSlice->framepoc = pSlice->ThisPOC; + p_Vid->ThisPOC = pSlice->ThisPOC; + //if ( pSlice->frame_num != p_Vid->PreviousFrameNum) //Seems redundant + p_Vid->PreviousFrameNum = pSlice->frame_num; + if (pSlice->nal_reference_idc) { + p_Vid->PrevPicOrderCntLsb = pSlice->pic_order_cnt_lsb; + p_Vid->PrevPicOrderCntMsb = pSlice->PicOrderCntMsb; + } + break; + + case 1: // POC MODE 1 + // 1st + if (pSlice->idr_flag) { + p_Vid->FrameNumOffset = 0; // first pix of IDRGOP, + VAL_CHECK(ret, 0 == pSlice->frame_num); + } else { + if (p_Vid->last_has_mmco_5) { + p_Vid->PreviousFrameNumOffset = 0; + p_Vid->PreviousFrameNum = 0; + } + if (pSlice->frame_num < (RK_S32)p_Vid->PreviousFrameNum) { + //not first pix of IDRGOP + p_Vid->FrameNumOffset = p_Vid->PreviousFrameNumOffset + p_Vid->max_frame_num; + } else { + p_Vid->FrameNumOffset = p_Vid->PreviousFrameNumOffset; + } + } + // 2nd + if (active_sps->num_ref_frames_in_pic_order_cnt_cycle) { + pSlice->AbsFrameNum = p_Vid->FrameNumOffset + pSlice->frame_num; + } else { + pSlice->AbsFrameNum = 0; + } + if ((!pSlice->nal_reference_idc) && pSlice->AbsFrameNum > 0) { + pSlice->AbsFrameNum--; + } + // 3rd + p_Vid->ExpectedDeltaPerPicOrderCntCycle = 0; + if (active_sps->num_ref_frames_in_pic_order_cnt_cycle) { + for (i = 0; i < (RK_S32)active_sps->num_ref_frames_in_pic_order_cnt_cycle; i++) { + p_Vid->ExpectedDeltaPerPicOrderCntCycle += active_sps->offset_for_ref_frame[i]; + } + } + if (pSlice->AbsFrameNum) { + p_Vid->PicOrderCntCycleCnt = (pSlice->AbsFrameNum - 1) / active_sps->num_ref_frames_in_pic_order_cnt_cycle; + p_Vid->FrameNumInPicOrderCntCycle = (pSlice->AbsFrameNum - 1) % active_sps->num_ref_frames_in_pic_order_cnt_cycle; + p_Vid->ExpectedPicOrderCnt = p_Vid->PicOrderCntCycleCnt * p_Vid->ExpectedDeltaPerPicOrderCntCycle; + for (i = 0; i <= (RK_S32)p_Vid->FrameNumInPicOrderCntCycle; i++) + p_Vid->ExpectedPicOrderCnt += active_sps->offset_for_ref_frame[i]; + } else { + p_Vid->ExpectedPicOrderCnt = 0; + } + if (!pSlice->nal_reference_idc) { + p_Vid->ExpectedPicOrderCnt += active_sps->offset_for_non_ref_pic; + } + if (pSlice->field_pic_flag == 0) { + //frame pix + pSlice->toppoc = p_Vid->ExpectedPicOrderCnt + pSlice->delta_pic_order_cnt[0]; + pSlice->bottompoc = pSlice->toppoc + active_sps->offset_for_top_to_bottom_field + pSlice->delta_pic_order_cnt[1]; + pSlice->ThisPOC = pSlice->framepoc = (pSlice->toppoc < pSlice->bottompoc) ? pSlice->toppoc : pSlice->bottompoc; // POC200301 + } else if (pSlice->bottom_field_flag == 0) { + //top field + pSlice->ThisPOC = pSlice->toppoc = p_Vid->ExpectedPicOrderCnt + pSlice->delta_pic_order_cnt[0]; + } else { + //bottom field + pSlice->ThisPOC = pSlice->bottompoc = p_Vid->ExpectedPicOrderCnt + active_sps->offset_for_top_to_bottom_field + pSlice->delta_pic_order_cnt[0]; + } + pSlice->framepoc = pSlice->ThisPOC; + p_Vid->PreviousFrameNum = pSlice->frame_num; + p_Vid->PreviousFrameNumOffset = p_Vid->FrameNumOffset; + break; + + + case 2: // POC MODE 2 + if (pSlice->idr_flag) { // IDR picture + p_Vid->FrameNumOffset = 0; // first pix of IDRGOP, + pSlice->ThisPOC = pSlice->framepoc = pSlice->toppoc = pSlice->bottompoc = 0; + VAL_CHECK(ret, 0 == pSlice->frame_num); + } else { + if (p_Vid->last_has_mmco_5) { + p_Vid->PreviousFrameNum = 0; + p_Vid->PreviousFrameNumOffset = 0; + } + if (pSlice->frame_num < (RK_S32)p_Vid->PreviousFrameNum) { + p_Vid->FrameNumOffset = p_Vid->PreviousFrameNumOffset + p_Vid->max_frame_num; + } else { + p_Vid->FrameNumOffset = p_Vid->PreviousFrameNumOffset; + } + pSlice->AbsFrameNum = p_Vid->FrameNumOffset + pSlice->frame_num; + if (!pSlice->nal_reference_idc) { + pSlice->ThisPOC = (2 * pSlice->AbsFrameNum - 1); + } else { + pSlice->ThisPOC = (2 * pSlice->AbsFrameNum); + } + if (pSlice->field_pic_flag == 0) { + pSlice->toppoc = pSlice->bottompoc = pSlice->framepoc = pSlice->ThisPOC; + } else if (pSlice->bottom_field_flag == 0) { + pSlice->toppoc = pSlice->framepoc = pSlice->ThisPOC; + } else { + pSlice->bottompoc = pSlice->framepoc = pSlice->ThisPOC; + } + } + p_Vid->PreviousFrameNum = pSlice->frame_num; + p_Vid->PreviousFrameNumOffset = p_Vid->FrameNumOffset; + break; + default: + ret = MPP_NOK; + goto __FAILED; + } + return ret = MPP_OK; + +__FAILED: + return ret; +} + +static MPP_RET store_proc_picture_in_dpb(H264_DpbBuf_t *p_Dpb, H264_StorePic_t *p) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + H264dVideoCtx_t *p_Vid = p_Dpb->p_Vid; + H264_FrameStore_t *fs = p_Dpb->fs_ilref[0]; + H264_DecCtx_t *p_Dec = p_Dpb->p_Vid->p_Dec; + + VAL_CHECK(ret, NULL != p); + if (p_Dpb->used_size_il > 0) { + if (fs->frame) { + free_storable_picture(p_Dec, fs->frame); + fs->frame = NULL; + } + if (fs->top_field) { + free_storable_picture(p_Dec, fs->top_field); + fs->top_field = NULL; + } + if (fs->bottom_field) { + free_storable_picture(p_Dec, fs->bottom_field); + fs->bottom_field = NULL; + } + fs->is_used = 0; + fs->is_reference = 0; + p_Dpb->used_size_il--; + } + if (fs->is_used > 0) { //checking; + if (p->structure == FRAME) { + VAL_CHECK(ret, fs->frame == NULL); + } else if (p->structure == TOP_FIELD) { + VAL_CHECK(ret, fs->top_field == NULL); + } else if (p->structure == BOTTOM_FIELD) { + VAL_CHECK(ret, fs->bottom_field == NULL); + } + } + FUN_CHECK(ret = insert_picture_in_dpb(p_Vid, fs, p, 0)); + if ((p->structure == FRAME && fs->is_used == 3) + || (p->structure != FRAME && fs->is_used && fs->is_used < 3)) { + p_Dpb->used_size_il++; + } + + return ret = MPP_OK; +__FAILED: + return ret; +} + +static void dpb_mark_add_used(H264_DpbMark_t *p_mark, RK_S32 structure) +{ + //!<---- index add ---- + if (structure == FRAME || structure == TOP_FIELD) { + p_mark->top_used += 1; + } + if (structure == FRAME || structure == BOTTOM_FIELD) { + p_mark->bot_used += 1; + } +} + +static H264_StorePic_t* clone_storable_picture(H264dVideoCtx_t *p_Vid, H264_StorePic_t *p_pic) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + H264_StorePic_t *p_stored_pic = alloc_storable_picture(p_Vid, p_Vid->structure); + + MEM_CHECK(ret, p_stored_pic); + p_stored_pic->mem_malloc_type = Mem_Clone; + p_stored_pic->mem_mark = p_pic->mem_mark; + dpb_mark_add_used(p_stored_pic->mem_mark, p_stored_pic->structure); + p_stored_pic->colmv_no_used_flag = 1; // clone, colmv is not be used + + p_stored_pic->pic_num = p_pic->pic_num; + p_stored_pic->frame_num = p_pic->frame_num; + p_stored_pic->long_term_frame_idx = p_pic->long_term_frame_idx; + p_stored_pic->long_term_pic_num = p_pic->long_term_pic_num; + p_stored_pic->is_long_term = 0; + p_stored_pic->non_existing = p_pic->non_existing; + p_stored_pic->max_slice_id = p_pic->max_slice_id; + p_stored_pic->structure = p_pic->structure; + + p_stored_pic->mb_aff_frame_flag = p_pic->mb_aff_frame_flag; + p_stored_pic->poc = p_pic->poc; + p_stored_pic->top_poc = p_pic->top_poc; + p_stored_pic->bottom_poc = p_pic->bottom_poc; + p_stored_pic->frame_poc = p_pic->frame_poc; + p_stored_pic->is_mmco_5 = p_pic->is_mmco_5; + p_stored_pic->poc_mmco5 = p_pic->poc_mmco5; + p_stored_pic->top_poc_mmco5 = p_pic->top_poc_mmco5; + p_stored_pic->bot_poc_mmco5 = p_pic->bot_poc_mmco5; + p_stored_pic->pic_num = p_pic->pic_num; + p_stored_pic->frame_num = p_pic->frame_num; + p_stored_pic->slice_type = p_pic->slice_type; + p_stored_pic->idr_flag = p_pic->idr_flag; + p_stored_pic->no_output_of_prior_pics_flag = p_pic->no_output_of_prior_pics_flag; + p_stored_pic->long_term_reference_flag = 0; + p_stored_pic->adaptive_ref_pic_buffering_flag = 0; + p_stored_pic->dec_ref_pic_marking_buffer = NULL; + p_stored_pic->PicWidthInMbs = p_pic->PicWidthInMbs; + + p_stored_pic->chroma_format_idc = p_pic->chroma_format_idc; + p_stored_pic->frame_mbs_only_flag = p_pic->frame_mbs_only_flag; + p_stored_pic->frame_cropping_flag = p_pic->frame_cropping_flag; + if (p_stored_pic->frame_cropping_flag) { + p_stored_pic->frame_crop_left_offset = p_pic->frame_crop_left_offset; + p_stored_pic->frame_crop_right_offset = p_pic->frame_crop_right_offset; + p_stored_pic->frame_crop_top_offset = p_pic->frame_crop_top_offset; + p_stored_pic->frame_crop_bottom_offset = p_pic->frame_crop_bottom_offset; + } + // MVC-related parameters + p_stored_pic->inter_view_flag = p_pic->inter_view_flag; + p_stored_pic->anchor_pic_flag = 0; + p_stored_pic->view_id = p_pic->view_id; + p_stored_pic->layer_id = p_pic->layer_id; + p_stored_pic->proc_flag = 1; + p_stored_pic->is_output = 1; + p_stored_pic->used_for_reference = 1; + + return p_stored_pic; +__FAILED: + (void)ret; + return NULL; +} + +static MPP_RET init_mvc_picture(H264_SLICE_t *currSlice) +{ + RK_U32 i = 0; + RK_S32 poc = 0; + MPP_RET ret = MPP_ERR_UNKNOW; + H264dVideoCtx_t *p_Vid = currSlice->p_Vid; + H264_DpbBuf_t *p_Dpb = p_Vid->p_Dpb_layer[0]; + H264_StorePic_t *p_pic = NULL; + H264_FrameStore_t *fs = NULL; + H264_StorePic_t *p_clone = NULL; + + // find BL reconstructed picture + if (currSlice->structure == FRAME) { + for (i = 0; i < p_Dpb->used_size; i++) { + fs = p_Dpb->fs[i]; + if (fs->frame) { + poc = fs->frame->is_mmco_5 ? fs->frame->poc_mmco5 : fs->frame->poc; + } + if (fs->frame && (fs->frame->layer_id == 0) && (poc == currSlice->framepoc)) { + p_pic = fs->frame; + if (!fs->frame->is_mmco_5) { + break; + } + } + } + } else if (currSlice->structure == TOP_FIELD) { + for (i = 0; i < p_Dpb->used_size; i++) { + fs = p_Dpb->fs[i]; + if (fs->top_field) { + poc = fs->top_field->is_mmco_5 ? fs->top_field->top_poc_mmco5 : fs->top_field->top_poc; + } + if (fs->top_field && (fs->top_field->layer_id == 0) && (poc == currSlice->toppoc)) { + p_pic = fs->top_field; + if (!fs->top_field->is_mmco_5) { + break; + } + } + } + } else { + for (i = 0; i < p_Dpb->used_size; i++) { + fs = p_Dpb->fs[i]; + if (fs->bottom_field) { + poc = fs->bottom_field->is_mmco_5 ? fs->bottom_field->bot_poc_mmco5 : fs->bottom_field->bottom_poc; + } + if (fs->bottom_field && (fs->bottom_field->layer_id == 0) && (poc == currSlice->bottompoc)) { + p_pic = fs->bottom_field; + if (!fs->bottom_field->is_mmco_5) { + break; + } + } + } + } + if (p_pic) { + p_clone = clone_storable_picture(p_Vid, p_pic); + MEM_CHECK(ret, p_clone); + FUN_CHECK(ret = store_proc_picture_in_dpb(currSlice->p_Dpb, p_clone)); + } + + return ret = MPP_OK; +__FAILED: + return ret; +} + +static RK_U32 rkv_len_align_422(RK_U32 val) +{ + return ((5 * MPP_ALIGN(val, 16)) / 2); +} + +static MPP_RET dpb_mark_malloc(H264dVideoCtx_t *p_Vid, H264_StorePic_t *dec_pic) +{ + RK_U8 idx = 0; + MPP_RET ret = MPP_ERR_UNKNOW; + H264_DpbMark_t *cur_mark = NULL; + RK_U32 hor_stride = 0, ver_stride = 0; + H264_DecCtx_t *p_Dec = p_Vid->p_Dec; + H264_DpbMark_t *p_mark = p_Vid->p_Dec->dpb_mark; + RK_S32 structure = dec_pic->structure; + RK_S32 layer_id = dec_pic->layer_id; + if (!dec_pic->combine_flag) { + while (p_mark[idx].out_flag || p_mark[idx].top_used || p_mark[idx].bot_used) { + idx++; + } + ASSERT(idx <= MAX_MARK_SIZE); + + mpp_buf_slot_get_unused(p_Vid->p_Dec->frame_slots, &p_mark[idx].slot_idx); + if (p_mark[idx].slot_idx < 0) { + H264D_WARNNING("[dpb_mark_malloc] error, buf_slot has not get."); + ret = MPP_NOK; + goto __FAILED; + } + cur_mark = &p_mark[idx]; + + cur_mark->out_flag = 1; + { + MppFrame mframe = NULL; + mpp_frame_init(&mframe); + if ((YUV420 == p_Vid->yuv_format) && (8 == p_Vid->bit_depth_luma)) { + mpp_frame_set_fmt(mframe, MPP_FMT_YUV420SP); + } else if ((YUV420 == p_Vid->yuv_format) && (10 == p_Vid->bit_depth_luma)) { + mpp_frame_set_fmt(mframe, MPP_FMT_YUV420SP_10BIT); + } else if ((YUV422 == p_Vid->yuv_format) && (8 == p_Vid->bit_depth_luma)) { + mpp_frame_set_fmt(mframe, MPP_FMT_YUV422SP); + mpp_slots_set_prop(p_Dec->frame_slots, SLOTS_LEN_ALIGN, rkv_len_align_422); + } else if ((YUV422 == p_Vid->yuv_format) && (10 == p_Vid->bit_depth_luma)) { + mpp_frame_set_fmt(mframe, MPP_FMT_YUV422SP_10BIT); + mpp_slots_set_prop(p_Dec->frame_slots, SLOTS_LEN_ALIGN, rkv_len_align_422); + } + hor_stride = ((p_Vid->width * p_Vid->bit_depth_luma + 127) & (~127)) / 8; + ver_stride = p_Vid->height; + mpp_frame_set_hor_stride(mframe, hor_stride); // before crop + mpp_frame_set_ver_stride(mframe, ver_stride); + mpp_frame_set_width(mframe, p_Vid->width_after_crop); // after crop + mpp_frame_set_height(mframe, p_Vid->height_after_crop); + mpp_frame_set_pts(mframe, p_Vid->p_Cur->last_pts); + mpp_frame_set_dts(mframe, p_Vid->p_Cur->last_dts); + mpp_buf_slot_set_prop(p_Dec->frame_slots, cur_mark->slot_idx, SLOT_FRAME, mframe); + mpp_frame_deinit(&mframe); + mpp_buf_slot_get_prop(p_Dec->frame_slots, cur_mark->slot_idx, SLOT_FRAME_PTR, &cur_mark->mframe); + } + + p_Vid->active_dpb_mark[layer_id] = cur_mark; + } + cur_mark = p_Vid->active_dpb_mark[layer_id]; + if (structure == FRAME || structure == TOP_FIELD) { + cur_mark->top_used += 1; + } + if (structure == FRAME || structure == BOTTOM_FIELD) { + cur_mark->bot_used += 1; + } + H264D_DBG(H264D_DBG_DPB_MALLIC, "[DPB_malloc] g_framecnt=%d, com_flag=%d, mark_idx=%d, slot_idx=%d, slice_type=%d, struct=%d, lay_id=%d\n", + p_Vid->g_framecnt, dec_pic->combine_flag, cur_mark->mark_idx, cur_mark->slot_idx, dec_pic->slice_type, dec_pic->structure, layer_id); + + p_Vid->p_Dec->in_task->output = cur_mark->slot_idx; + mpp_buf_slot_set_flag(p_Dec->frame_slots, cur_mark->slot_idx, SLOT_HAL_OUTPUT); + p_Dec->last_frame_slot_idx = cur_mark->slot_idx; + dec_pic->mem_mark = p_Vid->active_dpb_mark[layer_id]; + dec_pic->mem_mark->pic = dec_pic; + + return ret = MPP_OK; +__FAILED: + dec_pic->mem_mark = NULL; + return ret; +} +static MPP_RET check_dpb_field_paired(H264_FrameStore_t *p_last, H264_StorePic_t *dec_pic, RK_S32 last_pic_structure) +{ + MPP_RET ret = MPP_ERR_UNKNOW; +#if 0 + RK_S32 cur_structure = dec_pic->structure; + //!< check illegal field paired + if (p_last && (cur_structure == TOP_FIELD || cur_structure == BOTTOM_FIELD)) { + + if ((p_last->is_used == 1 && cur_structure == TOP_FIELD) //!< Top +Top + || (p_last->is_used == 2 && cur_structure == BOTTOM_FIELD) //!< Bot + Bot + //|| ((!dec_pic->combine_flag) && p_last->is_used == 2 && cur_structure == TOP_FIELD) //!< Bot + Top + not combine + || ((!dec_pic->combine_flag) && p_last->is_used == 1 && cur_structure == BOTTOM_FIELD) //!< Top + Bot + not combine + ) { + H264D_WARNNING("[check_field_paired] (discard) combine_flag=%d, last_used=%d, curr_struct=%d", + dec_pic->combine_flag, p_last->is_used, cur_structure); + return ret = MPP_NOK; + } + } + H264D_DBG(H264D_DBG_FIELD_PAIRED, "[check_field_paired] combine_flag=%d, last_used=%d, last_pic_struct=%d, curr_struct=%d", + dec_pic->combine_flag, (p_last ? p_last->is_used : -1), last_pic_structure, cur_structure); +#else + (void)p_last; + (void)dec_pic; + (void)last_pic_structure; +#endif + return ret = MPP_OK; +} + +static MPP_RET check_dpb_discontinuous(H264_StorePic_t *p_last, H264_StorePic_t *dec_pic, H264_SLICE_t *currSlice) +{ + MPP_RET ret = MPP_ERR_UNKNOW; +#if 1 + if (p_last && dec_pic && (dec_pic->slice_type != I_SLICE)) { + RK_U32 error_flag = 0; + RK_U32 wrap_frame_num = 0; + if (p_last->used_for_reference && !dec_pic->combine_flag) { + wrap_frame_num = (p_last->frame_num + 1) % currSlice->p_Vid->max_frame_num; + } else { + wrap_frame_num = p_last->frame_num; + } + error_flag = (wrap_frame_num != dec_pic->frame_num) ? 1 : 0; + currSlice->p_Dec->errctx.cur_err_flag |= error_flag ? 1 : 0; + + H264D_DBG(H264D_DBG_DISCONTINUOUS, "[discontinuous] last_slice=%d, cur_slice=%d, last_fnum=%d, cur_fnum=%d, last_poc=%d, cur_poc=%d", + p_last->slice_type, dec_pic->slice_type, p_last->frame_num, dec_pic->frame_num, p_last->poc, dec_pic->poc); + } +#endif + return ret = MPP_OK; +} + +static MPP_RET alloc_decpic(H264_SLICE_t *currSlice) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + H264_StorePic_t *dec_pic = NULL; + + H264dVideoCtx_t *p_Vid = currSlice->p_Vid; + H264_SPS_t *active_sps = p_Vid->active_sps; + H264_DpbBuf_t *p_Dpb = currSlice->p_Dpb; + + dec_pic = alloc_storable_picture(p_Vid, currSlice->structure); + MEM_CHECK(ret, dec_pic); + currSlice->toppoc = p_Vid->last_toppoc[currSlice->layer_id]; + currSlice->bottompoc = p_Vid->last_bottompoc[currSlice->layer_id]; + currSlice->framepoc = p_Vid->last_framepoc[currSlice->layer_id]; + currSlice->ThisPOC = p_Vid->last_thispoc[currSlice->layer_id]; + FUN_CHECK(ret = decode_poc(p_Vid, currSlice)); //!< calculate POC + + dec_pic->top_poc = currSlice->toppoc; + dec_pic->bottom_poc = currSlice->bottompoc; + dec_pic->frame_poc = currSlice->framepoc; + dec_pic->ThisPOC = currSlice->ThisPOC; + + p_Vid->last_toppoc[currSlice->layer_id] = currSlice->toppoc; + p_Vid->last_bottompoc[currSlice->layer_id] = currSlice->bottompoc; + p_Vid->last_framepoc[currSlice->layer_id] = currSlice->framepoc; + p_Vid->last_thispoc[currSlice->layer_id] = currSlice->ThisPOC; + + if (currSlice->structure == FRAME) { + if (currSlice->mb_aff_frame_flag) { + dec_pic->iCodingType = FRAME_MB_PAIR_CODING; + } else { + dec_pic->iCodingType = FRAME_CODING; + } + } else { + dec_pic->iCodingType = FIELD_CODING; + } + dec_pic->layer_id = currSlice->layer_id; + dec_pic->view_id = currSlice->view_id; + dec_pic->inter_view_flag = currSlice->inter_view_flag; + dec_pic->anchor_pic_flag = currSlice->anchor_pic_flag; + if (dec_pic->layer_id == 1) { + if ((p_Vid->profile_idc == H264_PROFILE_MVC_HIGH) || (p_Vid->profile_idc == H264_PROFILE_STEREO_HIGH)) { + FUN_CHECK(ret = init_mvc_picture(currSlice)); + } + } + if (currSlice->structure == TOP_FIELD) { + dec_pic->poc = currSlice->toppoc; + } else if (currSlice->structure == BOTTOM_FIELD) { + dec_pic->poc = currSlice->bottompoc; + } else if (currSlice->structure == FRAME) { + dec_pic->poc = currSlice->framepoc; + } else { + ret = MPP_NOK; + goto __FAILED; + } + dec_pic->slice_type = p_Vid->type; + dec_pic->used_for_reference = (currSlice->nal_reference_idc != 0); + dec_pic->idr_flag = currSlice->idr_flag; + dec_pic->no_output_of_prior_pics_flag = currSlice->no_output_of_prior_pics_flag; + dec_pic->long_term_reference_flag = currSlice->long_term_reference_flag; + dec_pic->adaptive_ref_pic_buffering_flag = currSlice->adaptive_ref_pic_buffering_flag; + dec_pic->dec_ref_pic_marking_buffer = currSlice->dec_ref_pic_marking_buffer; + + currSlice->dec_ref_pic_marking_buffer = NULL; + dec_pic->mb_aff_frame_flag = currSlice->mb_aff_frame_flag; + dec_pic->PicWidthInMbs = p_Vid->PicWidthInMbs; + dec_pic->pic_num = currSlice->frame_num; + dec_pic->frame_num = currSlice->frame_num; + dec_pic->chroma_format_idc = active_sps->chroma_format_idc; + + dec_pic->frame_mbs_only_flag = active_sps->frame_mbs_only_flag; + dec_pic->frame_cropping_flag = active_sps->frame_cropping_flag; + if (dec_pic->frame_cropping_flag) { + dec_pic->frame_crop_left_offset = active_sps->frame_crop_left_offset; + dec_pic->frame_crop_right_offset = active_sps->frame_crop_right_offset; + dec_pic->frame_crop_top_offset = active_sps->frame_crop_top_offset; + dec_pic->frame_crop_bottom_offset = active_sps->frame_crop_bottom_offset; + } else { + dec_pic->frame_crop_left_offset = 0; + dec_pic->frame_crop_right_offset = 0; + dec_pic->frame_crop_top_offset = 0; + dec_pic->frame_crop_bottom_offset = 0; + } + dec_pic->width = p_Vid->width; + dec_pic->height = p_Vid->height; + dec_pic->width_after_crop = p_Vid->width_after_crop; + dec_pic->height_after_crop = p_Vid->height_after_crop; + dec_pic->combine_flag = get_filed_dpb_combine_flag(p_Dpb->last_picture, dec_pic); + FUN_CHECK(ret = dpb_mark_malloc(p_Vid, dec_pic)); //!< malloc dpb_memory + FUN_CHECK(ret = check_dpb_field_paired(p_Dpb->last_picture, dec_pic, p_Vid->last_pic_structure)); + FUN_CHECK(ret = check_dpb_discontinuous(p_Vid->last_pic, dec_pic, currSlice)); + dec_pic->mem_malloc_type = Mem_Malloc; + dec_pic->colmv_no_used_flag = 0; + p_Vid->dec_pic = dec_pic; + + return ret = MPP_OK; +__FAILED: + MPP_FREE(dec_pic); + p_Vid->dec_pic = NULL; + + return ret; +} + +static void update_pic_num(H264_SLICE_t *currSlice) +{ + RK_U32 i = 0; + H264dVideoCtx_t *p_Vid = currSlice->p_Vid; + H264_DpbBuf_t *p_Dpb = currSlice->p_Dpb; + H264_SPS_t *active_sps = p_Vid->active_sps; + + RK_S32 add_top = 0, add_bottom = 0; + RK_S32 max_frame_num = 1 << (active_sps->log2_max_frame_num_minus4 + 4); + + if (currSlice->idr_flag) { + return; + } + if (currSlice->structure == FRAME) { + for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) { + if (p_Dpb->fs_ref[i]->is_used == 3) { + if ((p_Dpb->fs_ref[i]->frame->used_for_reference) && (!p_Dpb->fs_ref[i]->frame->is_long_term)) { + if ((RK_S32)p_Dpb->fs_ref[i]->frame_num > currSlice->frame_num) { + p_Dpb->fs_ref[i]->frame_num_wrap = p_Dpb->fs_ref[i]->frame_num - max_frame_num; + } else { + p_Dpb->fs_ref[i]->frame_num_wrap = p_Dpb->fs_ref[i]->frame_num; + } + p_Dpb->fs_ref[i]->frame->pic_num = p_Dpb->fs_ref[i]->frame_num_wrap; + } + } + } + //!< update long_term_pic_num + for (i = 0; i < p_Dpb->ltref_frames_in_buffer; i++) { + if (p_Dpb->fs_ltref[i]->is_used == 3) { + if (p_Dpb->fs_ltref[i]->frame->is_long_term) { + p_Dpb->fs_ltref[i]->frame->long_term_pic_num = p_Dpb->fs_ltref[i]->frame->long_term_frame_idx; + } + } + } + } else { + if (currSlice->structure == TOP_FIELD) { + add_top = 1; + add_bottom = 0; + } else { + add_top = 0; + add_bottom = 1; + } + + for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) { + if (p_Dpb->fs_ref[i]->is_reference) { + if ((RK_S32)p_Dpb->fs_ref[i]->frame_num > currSlice->frame_num) { + p_Dpb->fs_ref[i]->frame_num_wrap = p_Dpb->fs_ref[i]->frame_num - max_frame_num; + } else { + p_Dpb->fs_ref[i]->frame_num_wrap = p_Dpb->fs_ref[i]->frame_num; + } + if (p_Dpb->fs_ref[i]->is_reference & 1) { + p_Dpb->fs_ref[i]->top_field->pic_num = (2 * p_Dpb->fs_ref[i]->frame_num_wrap) + add_top; + } + if (p_Dpb->fs_ref[i]->is_reference & 2) { + p_Dpb->fs_ref[i]->bottom_field->pic_num = (2 * p_Dpb->fs_ref[i]->frame_num_wrap) + add_bottom; + } + } + } + //!< update long_term_pic_num + for (i = 0; i < p_Dpb->ltref_frames_in_buffer; i++) { + if (p_Dpb->fs_ltref[i]->is_long_term & 1) { + p_Dpb->fs_ltref[i]->top_field->long_term_pic_num = 2 * p_Dpb->fs_ltref[i]->top_field->long_term_frame_idx + add_top; + } + if (p_Dpb->fs_ltref[i]->is_long_term & 2) { + p_Dpb->fs_ltref[i]->bottom_field->long_term_pic_num = 2 * p_Dpb->fs_ltref[i]->bottom_field->long_term_frame_idx + add_bottom; + } + } + } +} + + + + +static RK_S32 compare_pic_by_pic_num_desc(const void *arg1, const void *arg2) +{ + RK_S32 pic_num1 = (*(H264_StorePic_t**)arg1)->pic_num; + RK_S32 pic_num2 = (*(H264_StorePic_t**)arg2)->pic_num; + + if (pic_num1 < pic_num2) + return 1; + if (pic_num1 > pic_num2) + return -1; + else + return 0; +} + +static RK_S32 compare_pic_by_lt_pic_num_asc(const void *arg1, const void *arg2) +{ + RK_S32 long_term_pic_num1 = (*(H264_StorePic_t**)arg1)->long_term_pic_num; + RK_S32 long_term_pic_num2 = (*(H264_StorePic_t**)arg2)->long_term_pic_num; + + if (long_term_pic_num1 < long_term_pic_num2) + return -1; + if (long_term_pic_num1 > long_term_pic_num2) + return 1; + else + return 0; +} + +static RK_S32 compare_fs_by_frame_num_desc(const void *arg1, const void *arg2) +{ + RK_S32 frame_num_wrap1 = (*(H264_FrameStore_t**)arg1)->frame_num_wrap; + RK_S32 frame_num_wrap2 = (*(H264_FrameStore_t**)arg2)->frame_num_wrap; + if (frame_num_wrap1 < frame_num_wrap2) + return 1; + if (frame_num_wrap1 > frame_num_wrap2) + return -1; + else + return 0; +} + +static RK_S32 compare_fs_by_lt_pic_idx_asc(const void *arg1, const void *arg2) +{ + RK_S32 long_term_frame_idx1 = (*(H264_FrameStore_t**)arg1)->long_term_frame_idx; + RK_S32 long_term_frame_idx2 = (*(H264_FrameStore_t**)arg2)->long_term_frame_idx; + + if (long_term_frame_idx1 < long_term_frame_idx2) + return -1; + else if (long_term_frame_idx1 > long_term_frame_idx2) + return 1; + else + return 0; +} + +static RK_U32 is_long_ref(H264_StorePic_t *s) +{ + return ((s->used_for_reference) && (s->is_long_term)); +} + +static RK_U32 is_short_ref(H264_StorePic_t *s) +{ + return ((s->used_for_reference) && (!(s->is_long_term))); +} + +static void gen_pic_list_from_frame_list(RK_S32 currStructure, H264_FrameStore_t **fs_list, + RK_S32 list_idx, H264_StorePic_t **list, RK_U8 *list_size, RK_U32 long_term) +{ + RK_S32 top_idx = 0; + RK_S32 bot_idx = 0; + + RK_U32(*is_ref)(H264_StorePic_t * s) = (long_term) ? is_long_ref : is_short_ref; + + if (currStructure == TOP_FIELD) { + while ((top_idx < list_idx) || (bot_idx < list_idx)) { + for (; top_idx < list_idx; top_idx++) { + if (fs_list[top_idx]->is_used & 1) { + if (is_ref(fs_list[top_idx]->top_field)) { + //top_field; + (*list_size)++; + top_idx++; + break; + } + } + } + for (; bot_idx < list_idx; bot_idx++) { + if (fs_list[bot_idx]->is_used & 2) { + if (is_ref(fs_list[bot_idx]->bottom_field)) { + //bottom_field; + (*list_size)++; + bot_idx++; + break; + } + } + } + } + } + if (currStructure == BOTTOM_FIELD) { + while ((top_idx < list_idx) || (bot_idx < list_idx)) { + for (; bot_idx < list_idx; bot_idx++) { + if (fs_list[bot_idx]->is_used & 2) { + if (is_ref(fs_list[bot_idx]->bottom_field)) { + // short term ref pic + list[(RK_S16)*list_size] = fs_list[bot_idx]->bottom_field; + (*list_size)++; + bot_idx++; + break; + } + } + } + for (; top_idx < list_idx; top_idx++) { + if (fs_list[top_idx]->is_used & 1) { + if (is_ref(fs_list[top_idx]->top_field)) { + //!< short term ref pic + list[(RK_S16)*list_size] = fs_list[top_idx]->top_field; + (*list_size)++; + top_idx++; + break; + } + } + } + } + } +} + +static RK_U32 is_view_id_in_ref_view_list(RK_S32 view_id, RK_S32 *ref_view_id, RK_S32 num_ref_views) +{ + RK_S32 i; + for (i = 0; i < num_ref_views; i++) { + if (view_id == ref_view_id[i]) + break; + } + + return (num_ref_views && (i < num_ref_views)); +} + +static MPP_RET append_interview_list(H264_DpbBuf_t *p_Dpb, + RK_S32 currPicStructure, RK_S32 list_idx, H264_FrameStore_t **list, + RK_S32 *listXsize, RK_S32 currPOC, RK_S32 curr_layer_id, RK_S32 anchor_pic_flag) +{ + RK_S32 poc = 0; + RK_S32 fld_idx = 0; + RK_U32 pic_avail = 0; + RK_S32 num_ref_views = 0; + RK_S32 *ref_view_id = NULL; + MPP_RET ret = MPP_ERR_UNKNOW; + RK_S32 iVOIdx = curr_layer_id; + H264_FrameStore_t *fs = p_Dpb->fs_ilref[0]; + H264dVideoCtx_t *p_Vid = p_Dpb->p_Vid; + + VAL_CHECK(ret, iVOIdx >= 0); //!< Error: iVOIdx: %d is not less than 0 + if (anchor_pic_flag) { + num_ref_views = list_idx ? p_Vid->active_subsps->num_anchor_refs_l1[iVOIdx] : p_Vid->active_subsps->num_anchor_refs_l0[iVOIdx]; + ref_view_id = list_idx ? p_Vid->active_subsps->anchor_ref_l1[iVOIdx] : p_Vid->active_subsps->anchor_ref_l0[iVOIdx]; + } else { + num_ref_views = list_idx ? p_Vid->active_subsps->num_non_anchor_refs_l1[iVOIdx] : p_Vid->active_subsps->num_non_anchor_refs_l0[iVOIdx]; + ref_view_id = list_idx ? p_Vid->active_subsps->non_anchor_ref_l1[iVOIdx] : p_Vid->active_subsps->non_anchor_ref_l0[iVOIdx]; + } + + if (currPicStructure == BOTTOM_FIELD) + fld_idx = 1; + else + fld_idx = 0; + + if (currPicStructure == FRAME) { + pic_avail = (fs->is_used == 3); + if (pic_avail) { + poc = fs->frame->is_mmco_5 ? fs->frame->poc_mmco5 : fs->frame->poc; + } + } else if (currPicStructure == TOP_FIELD) { + pic_avail = fs->is_used & 1; + if (pic_avail) { + poc = fs->top_field->is_mmco_5 ? fs->top_field->top_poc_mmco5 : fs->top_field->poc; + } + } else if (currPicStructure == BOTTOM_FIELD) { + pic_avail = fs->is_used & 2; + if (pic_avail) { + poc = fs->bottom_field->is_mmco_5 ? fs->bottom_field->bot_poc_mmco5 : fs->bottom_field->poc; + } + } else { + pic_avail = 0; + } + + if (pic_avail && fs->inter_view_flag[fld_idx]) { + if (poc == currPOC) { + if (is_view_id_in_ref_view_list(fs->view_id, ref_view_id, num_ref_views)) { + //!< add one inter-view reference; + list[*listXsize] = fs; + //!< next; + (*listXsize)++; + } + } + } + return ret = MPP_OK; +__FAILED: + return ret; +} + +static void gen_pic_list_from_frame_interview_list(RK_S32 currStructure, + H264_FrameStore_t **fs_list, RK_S32 list_idx, H264_StorePic_t **list, RK_U8 *list_size) +{ + RK_S32 i; + + if (currStructure == TOP_FIELD) { + for (i = 0; i < list_idx; i++) { + list[(RK_S32)(*list_size)] = fs_list[i]->top_field; + (*list_size)++; + } + } + if (currStructure == BOTTOM_FIELD) { + for (i = 0; i < list_idx; i++) { + list[(RK_S32)(*list_size)] = fs_list[i]->bottom_field; + (*list_size)++; + } + } +} + +static RK_S32 compare_pic_by_poc_desc(const void *arg1, const void *arg2) +{ + RK_S32 poc1 = (*(H264_StorePic_t**)arg1)->poc; + RK_S32 poc2 = (*(H264_StorePic_t**)arg2)->poc; + + if (poc1 < poc2) + return 1; + if (poc1 > poc2) + return -1; + else + return 0; +} + +static RK_S32 compare_pic_by_poc_asc(const void *arg1, const void *arg2) +{ + RK_S32 poc1 = (*(H264_StorePic_t**)arg1)->poc; + RK_S32 poc2 = (*(H264_StorePic_t**)arg2)->poc; + + if (poc1 < poc2) + return -1; + if (poc1 > poc2) + return 1; + else + return 0; +} + +static RK_S32 compare_fs_by_poc_desc(const void *arg1, const void *arg2) +{ + RK_S32 poc1 = (*(H264_FrameStore_t**)arg1)->poc; + RK_S32 poc2 = (*(H264_FrameStore_t**)arg2)->poc; + + if (poc1 < poc2) + return 1; + else if (poc1 > poc2) + return -1; + else + return 0; +} + +static RK_S32 compare_fs_by_poc_asc(const void *arg1, const void *arg2) +{ + RK_S32 poc1 = (*(H264_FrameStore_t**)arg1)->poc; + RK_S32 poc2 = (*(H264_FrameStore_t**)arg2)->poc; + + if (poc1 < poc2) + return -1; + else if (poc1 > poc2) + return 1; + else + return 0; +} + +static MPP_RET init_lists_p_slice_mvc(H264_SLICE_t *currSlice) +{ + RK_U32 i = 0; + RK_S32 list0idx = 0; + RK_S32 listltidx = 0; + H264_FrameStore_t **fs_list0 = 0; + H264_FrameStore_t **fs_listlt = 0; + MPP_RET ret = MPP_ERR_UNKNOW; + H264dVideoCtx_t *p_Vid = currSlice->p_Vid; + H264_DpbBuf_t *p_Dpb = currSlice->p_Dpb; + RK_S32 currPOC = currSlice->ThisPOC; + RK_S32 anchor_pic_flag = currSlice->anchor_pic_flag; + + currSlice->listXsizeP[0] = 0; + currSlice->listXsizeP[1] = 0; + currSlice->listinterviewidx0 = 0; + currSlice->listinterviewidx1 = 0; + + if (currSlice->structure == FRAME) { + for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) { + if (p_Dpb->fs_ref[i]->is_used == 3) { + if ((p_Dpb->fs_ref[i]->frame->used_for_reference) && (!p_Dpb->fs_ref[i]->frame->is_long_term)) { + currSlice->listP[0][list0idx++] = p_Dpb->fs_ref[i]->frame; + } + } + } + // order list 0 by PicNum + qsort((void *)currSlice->listP[0], list0idx, sizeof(H264_StorePic_t*), compare_pic_by_pic_num_desc); + currSlice->listXsizeP[0] = (RK_U8)list0idx; + // long term handling + for (i = 0; i < p_Dpb->ltref_frames_in_buffer; i++) { + if (p_Dpb->fs_ltref[i]->is_used == 3) { + if (p_Dpb->fs_ltref[i]->frame->is_long_term) { + currSlice->listP[0][list0idx++] = p_Dpb->fs_ltref[i]->frame; + } + } + } + qsort((void *)&currSlice->listP[0][(RK_S16)currSlice->listXsizeP[0]], + list0idx - currSlice->listXsizeP[0], sizeof(H264_StorePic_t*), compare_pic_by_lt_pic_num_asc); + currSlice->listXsizeP[0] = (RK_U8)list0idx; + } else { + fs_list0 = mpp_calloc(H264_FrameStore_t*, p_Dpb->size); + fs_listlt = mpp_calloc(H264_FrameStore_t*, p_Dpb->size); + MEM_CHECK(ret, fs_list0 && fs_listlt); + for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) { + if (p_Dpb->fs_ref[i]->is_reference) { + fs_list0[list0idx++] = p_Dpb->fs_ref[i]; + } + } + qsort((void *)fs_list0, list0idx, sizeof(H264_FrameStore_t*), compare_fs_by_frame_num_desc); + currSlice->listXsizeP[0] = 0; + gen_pic_list_from_frame_list(currSlice->structure, fs_list0, list0idx, currSlice->listP[0], &currSlice->listXsizeP[0], 0); + // long term handling + for (i = 0; i < p_Dpb->ltref_frames_in_buffer; i++) { + fs_listlt[listltidx++] = p_Dpb->fs_ltref[i]; + } + qsort((void *)fs_listlt, listltidx, sizeof(H264_FrameStore_t*), compare_fs_by_lt_pic_idx_asc); + gen_pic_list_from_frame_list(currSlice->structure, fs_listlt, listltidx, currSlice->listP[0], &currSlice->listXsizeP[0], 1); + MPP_FREE(fs_list0); + MPP_FREE(fs_listlt); + } + + currSlice->listXsizeP[1] = 0; + if (currSlice->svc_extension_flag == 0) { + RK_S32 curr_layer_id = currSlice->layer_id; + currSlice->fs_listinterview0 = mpp_calloc(H264_FrameStore_t*, p_Dpb->size); + MEM_CHECK(ret, currSlice->fs_listinterview0); + list0idx = currSlice->listXsizeP[0]; + if (currSlice->structure == FRAME) { + FUN_CHECK(ret = append_interview_list(p_Vid->p_Dpb_layer[1], 0, 0, + currSlice->fs_listinterview0, &currSlice->listinterviewidx0, currPOC, curr_layer_id, anchor_pic_flag)); + for (i = 0; i < (RK_U32)currSlice->listinterviewidx0; i++) { + currSlice->listP[0][list0idx++] = currSlice->fs_listinterview0[i]->frame; + } + currSlice->listXsizeP[0] = (RK_U8)list0idx; + } else { + FUN_CHECK(ret = append_interview_list(p_Vid->p_Dpb_layer[1], currSlice->structure, 0, + currSlice->fs_listinterview0, &currSlice->listinterviewidx0, currPOC, curr_layer_id, anchor_pic_flag)); + gen_pic_list_from_frame_interview_list(currSlice->structure, currSlice->fs_listinterview0, + currSlice->listinterviewidx0, currSlice->listP[0], &currSlice->listXsizeP[0]); + } + } + // set the unused list entries to NULL + for (i = currSlice->listXsizeP[0]; i < (MAX_LIST_SIZE); i++) { + currSlice->listP[0][i] = p_Vid->no_ref_pic; + } + for (i = currSlice->listXsizeP[1]; i < (MAX_LIST_SIZE); i++) { + currSlice->listP[1][i] = p_Vid->no_ref_pic; + } + MPP_FREE(currSlice->fs_listinterview0); + + return ret = MPP_OK; +__FAILED: + MPP_FREE(fs_list0); + MPP_FREE(fs_listlt); + MPP_FREE(currSlice->fs_listinterview0); + + return ret; +} + +static MPP_RET init_lists_b_slice_mvc(H264_SLICE_t *currSlice) +{ + RK_U32 i = 0; + RK_S32 j = 0; + RK_S32 list0idx = 0; + RK_S32 list0idx_1 = 0; + RK_S32 listltidx = 0; + H264_FrameStore_t **fs_list0 = NULL; + H264_FrameStore_t **fs_list1 = NULL; + H264_FrameStore_t **fs_listlt = NULL; + MPP_RET ret = MPP_ERR_UNKNOW; + + H264dVideoCtx_t *p_Vid = currSlice->p_Vid; + H264_DpbBuf_t *p_Dpb = currSlice->p_Dpb; + RK_S32 currPOC = currSlice->ThisPOC; + RK_S32 anchor_pic_flag = currSlice->anchor_pic_flag; + + currSlice->listXsizeB[0] = 0; + currSlice->listXsizeB[1] = 0; + currSlice->listinterviewidx0 = 0; + currSlice->listinterviewidx1 = 0; + // B-Slice + if (currSlice->structure == FRAME) { + for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) { + if (p_Dpb->fs_ref[i]->is_used == 3) { + if ((p_Dpb->fs_ref[i]->frame->used_for_reference) && (!p_Dpb->fs_ref[i]->frame->is_long_term)) { + if (currSlice->framepoc >= p_Dpb->fs_ref[i]->frame->poc) { + currSlice->listB[0][list0idx++] = p_Dpb->fs_ref[i]->frame; + } + } + } + } + qsort((void *)currSlice->listB[0], list0idx, sizeof(H264_StorePic_t*), compare_pic_by_poc_desc); + list0idx_1 = list0idx; + for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) { + if (p_Dpb->fs_ref[i]->is_used == 3) { + if ((p_Dpb->fs_ref[i]->frame->used_for_reference) && (!p_Dpb->fs_ref[i]->frame->is_long_term)) { + if (currSlice->framepoc < p_Dpb->fs_ref[i]->frame->poc) { + currSlice->listB[0][list0idx++] = p_Dpb->fs_ref[i]->frame; + } + } + } + } + qsort((void *)&currSlice->listB[0][list0idx_1], list0idx - list0idx_1, sizeof(H264_StorePic_t*), compare_pic_by_poc_asc); + + for (j = 0; j < list0idx_1; j++) { + currSlice->listB[1][list0idx - list0idx_1 + j] = currSlice->listB[0][j]; + } + for (j = list0idx_1; j < list0idx; j++) { + currSlice->listB[1][j - list0idx_1] = currSlice->listB[0][j]; + } + currSlice->listXsizeB[0] = currSlice->listXsizeB[1] = (RK_U8)list0idx; + // long term handling + for (i = 0; i < p_Dpb->ltref_frames_in_buffer; i++) { + if (p_Dpb->fs_ltref[i]->is_used == 3) { + if (p_Dpb->fs_ltref[i]->frame->is_long_term) { + currSlice->listB[0][list0idx] = p_Dpb->fs_ltref[i]->frame; + currSlice->listB[1][list0idx++] = p_Dpb->fs_ltref[i]->frame; + } + } + } + qsort((void *)&currSlice->listB[0][(RK_S16)currSlice->listXsizeB[0]], + list0idx - currSlice->listXsizeB[0], sizeof(H264_StorePic_t*), compare_pic_by_lt_pic_num_asc); + qsort((void *)&currSlice->listB[1][(RK_S16)currSlice->listXsizeB[0]], + list0idx - currSlice->listXsizeB[0], sizeof(H264_StorePic_t*), compare_pic_by_lt_pic_num_asc); + currSlice->listXsizeB[0] = currSlice->listXsizeB[1] = (RK_U8)list0idx; + } else { + fs_list0 = mpp_calloc(H264_FrameStore_t*, p_Dpb->size); + fs_list1 = mpp_calloc(H264_FrameStore_t*, p_Dpb->size); + fs_listlt = mpp_calloc(H264_FrameStore_t*, p_Dpb->size); + MEM_CHECK(ret, fs_list0 && fs_list1 && fs_listlt); + currSlice->listXsizeB[0] = 0; + currSlice->listXsizeB[1] = 1; + for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) { + if (p_Dpb->fs_ref[i]->is_used) { + if (currSlice->ThisPOC >= p_Dpb->fs_ref[i]->poc) { + fs_list0[list0idx++] = p_Dpb->fs_ref[i]; + } + } + } + qsort((void *)fs_list0, list0idx, sizeof(H264_FrameStore_t*), compare_fs_by_poc_desc); + list0idx_1 = list0idx; + for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) { + if (p_Dpb->fs_ref[i]->is_used) { + if (currSlice->ThisPOC < p_Dpb->fs_ref[i]->poc) { + fs_list0[list0idx++] = p_Dpb->fs_ref[i]; + } + } + } + qsort((void *)&fs_list0[list0idx_1], list0idx - list0idx_1, sizeof(H264_FrameStore_t*), compare_fs_by_poc_asc); + + for (j = 0; j < list0idx_1; j++) { + fs_list1[list0idx - list0idx_1 + j] = fs_list0[j]; + } + for (j = list0idx_1; j < list0idx; j++) { + fs_list1[j - list0idx_1] = fs_list0[j]; + } + currSlice->listXsizeB[0] = 0; + currSlice->listXsizeB[1] = 0; + gen_pic_list_from_frame_list(currSlice->structure, fs_list0, list0idx, currSlice->listB[0], &currSlice->listXsizeB[0], 0); + gen_pic_list_from_frame_list(currSlice->structure, fs_list1, list0idx, currSlice->listB[1], &currSlice->listXsizeB[1], 0); + + // long term handling + for (i = 0; i < p_Dpb->ltref_frames_in_buffer; i++) { + fs_listlt[listltidx++] = p_Dpb->fs_ltref[i]; + } + qsort((void *)fs_listlt, listltidx, sizeof(H264_FrameStore_t*), compare_fs_by_lt_pic_idx_asc); + + gen_pic_list_from_frame_list(currSlice->structure, fs_listlt, listltidx, currSlice->listB[0], &currSlice->listXsizeB[0], 1); + gen_pic_list_from_frame_list(currSlice->structure, fs_listlt, listltidx, currSlice->listB[1], &currSlice->listXsizeB[1], 1); + + MPP_FREE(fs_list0); + MPP_FREE(fs_list1); + MPP_FREE(fs_listlt); + } + if ((currSlice->listXsizeB[0] == currSlice->listXsizeB[1]) && (currSlice->listXsizeB[0] > 1)) { + // check if lists are identical, if yes swap first two elements of currSlice->listX[1] + RK_S32 diff = 0; + for (j = 0; j < currSlice->listXsizeB[0]; j++) { + if (currSlice->listB[0][j] != currSlice->listB[1][j]) { + diff = 1; + break; + } + } + if (!diff) { + H264_StorePic_t *tmp_s = currSlice->listB[1][0]; + currSlice->listB[1][0] = currSlice->listB[1][1]; + currSlice->listB[1][1] = tmp_s; + } + } + if (currSlice->svc_extension_flag == 0) { + RK_S32 curr_layer_id = currSlice->layer_id; + // B-Slice + currSlice->fs_listinterview0 = mpp_calloc(H264_FrameStore_t*, p_Dpb->size); + currSlice->fs_listinterview1 = mpp_calloc(H264_FrameStore_t*, p_Dpb->size); + MEM_CHECK(ret, currSlice->fs_listinterview0 && currSlice->fs_listinterview1); + list0idx = currSlice->listXsizeB[0]; + if (currSlice->structure == FRAME) { + FUN_CHECK(ret = append_interview_list(p_Vid->p_Dpb_layer[1], 0, 0, + currSlice->fs_listinterview0, &currSlice->listinterviewidx0, currPOC, curr_layer_id, anchor_pic_flag)); + FUN_CHECK(ret = append_interview_list(p_Vid->p_Dpb_layer[1], 0, 1, + currSlice->fs_listinterview1, &currSlice->listinterviewidx1, currPOC, curr_layer_id, anchor_pic_flag)); + + for (i = 0; i < (RK_U32)currSlice->listinterviewidx0; i++) { + currSlice->listB[0][list0idx++] = currSlice->fs_listinterview0[i]->frame; + } + currSlice->listXsizeB[0] = (RK_U8)list0idx; + list0idx = currSlice->listXsizeB[1]; + for (i = 0; i < (RK_U32)currSlice->listinterviewidx1; i++) { + currSlice->listB[1][list0idx++] = currSlice->fs_listinterview1[i]->frame; + } + currSlice->listXsizeB[1] = (RK_U8)list0idx; + } else { + FUN_CHECK(ret = append_interview_list(p_Vid->p_Dpb_layer[1], currSlice->structure, 0, + currSlice->fs_listinterview0, &currSlice->listinterviewidx0, currPOC, curr_layer_id, anchor_pic_flag)); + gen_pic_list_from_frame_interview_list(currSlice->structure, currSlice->fs_listinterview0, + currSlice->listinterviewidx0, currSlice->listB[0], &currSlice->listXsizeB[0]); + FUN_CHECK(ret = append_interview_list(p_Vid->p_Dpb_layer[1], currSlice->structure, 1, + currSlice->fs_listinterview1, &currSlice->listinterviewidx1, currPOC, curr_layer_id, anchor_pic_flag)); + gen_pic_list_from_frame_interview_list(currSlice->structure, currSlice->fs_listinterview1, + currSlice->listinterviewidx1, currSlice->listB[1], &currSlice->listXsizeB[1]); + } + } + // set the unused list entries to NULL + for (i = currSlice->listXsizeB[0]; i < (MAX_LIST_SIZE); i++) { + currSlice->listB[0][i] = p_Vid->no_ref_pic; + } + for (i = currSlice->listXsizeB[1]; i < (MAX_LIST_SIZE); i++) { + currSlice->listB[1][i] = p_Vid->no_ref_pic; + } + MPP_FREE(currSlice->fs_listinterview0); + MPP_FREE(currSlice->fs_listinterview1); + + return ret = MPP_OK; +__FAILED: + MPP_FREE(fs_list0); + MPP_FREE(fs_list1); + MPP_FREE(fs_listlt); + MPP_FREE(currSlice->fs_listinterview0); + MPP_FREE(currSlice->fs_listinterview1); + + return ret; +} + +static RK_U32 get_short_term_pic(H264_SLICE_t *currSlice, RK_S32 picNum, H264_StorePic_t **find_pic) +{ + RK_U32 i = 0; + H264_StorePic_t *ret_pic = NULL; + H264_StorePic_t *near_pic = NULL; + H264_DpbBuf_t *p_Dpb = currSlice->p_Dpb; + + for (i = 0; i < p_Dpb->ref_frames_in_buffer; i++) { + if (currSlice->structure == FRAME) { + if ((p_Dpb->fs_ref[i]->is_reference == 3) + && (!p_Dpb->fs_ref[i]->frame->is_long_term)) { + if (p_Dpb->fs_ref[i]->frame->pic_num == picNum) { + ret_pic = p_Dpb->fs_ref[i]->frame; + break; + } else { + near_pic = p_Dpb->fs_ref[i]->frame; + } + } + } else { + if ((p_Dpb->fs_ref[i]->is_reference & 1) + && (!p_Dpb->fs_ref[i]->top_field->is_long_term)) { + if (p_Dpb->fs_ref[i]->top_field->pic_num == picNum) { + ret_pic = p_Dpb->fs_ref[i]->top_field; + break; + } else { + near_pic = p_Dpb->fs_ref[i]->top_field; + } + } + if ((p_Dpb->fs_ref[i]->is_reference & 2) + && (!p_Dpb->fs_ref[i]->bottom_field->is_long_term)) { + if (p_Dpb->fs_ref[i]->bottom_field->pic_num == picNum) { + ret_pic = p_Dpb->fs_ref[i]->bottom_field; + break; + } else { + near_pic = p_Dpb->fs_ref[i]->bottom_field; + } + } + } + } + *find_pic = ret_pic ? ret_pic : near_pic; + return (ret_pic ? 1 : 0); +} + + +static H264_StorePic_t *get_long_term_pic(H264_SLICE_t *currSlice, RK_S32 LongtermPicNum) +{ + RK_U32 i = 0; + H264_DpbBuf_t *p_Dpb = currSlice->p_Dpb; + + for (i = 0; i < p_Dpb->ltref_frames_in_buffer; i++) { + if (currSlice->structure == FRAME) { + if (p_Dpb->fs_ltref[i]->is_reference == 3) + if ((p_Dpb->fs_ltref[i]->frame->is_long_term) + && (p_Dpb->fs_ltref[i]->frame->long_term_pic_num == LongtermPicNum)) + return p_Dpb->fs_ltref[i]->frame; + } else { + if (p_Dpb->fs_ltref[i]->is_reference & 1) + if ((p_Dpb->fs_ltref[i]->top_field->is_long_term) + && (p_Dpb->fs_ltref[i]->top_field->long_term_pic_num == LongtermPicNum)) + return p_Dpb->fs_ltref[i]->top_field; + if (p_Dpb->fs_ltref[i]->is_reference & 2) + if ((p_Dpb->fs_ltref[i]->bottom_field->is_long_term) + && (p_Dpb->fs_ltref[i]->bottom_field->long_term_pic_num == LongtermPicNum)) + return p_Dpb->fs_ltref[i]->bottom_field; + } + } + return NULL; +} +static RK_U32 check_ref_pic_list(H264_SLICE_t *currSlice, RK_S32 cur_list) +{ + RK_S32 i = 0; + RK_U32 dpb_error_flag = 0; + RK_S32 maxPicNum = 0, currPicNum = 0; + RK_S32 picNumLXNoWrap = 0, picNumLXPred = 0, picNumLX = 0; + + RK_S32 *modification_of_pic_nums_idc = currSlice->modification_of_pic_nums_idc[cur_list]; + RK_S32 *abs_diff_pic_num_minus1 = currSlice->abs_diff_pic_num_minus1[cur_list]; + RK_S32 *long_term_pic_idx = currSlice->long_term_pic_idx[cur_list]; + H264dVideoCtx_t *p_Vid = currSlice->p_Vid; + + if (currSlice->structure == FRAME) { + maxPicNum = p_Vid->max_frame_num; + currPicNum = currSlice->frame_num; + } else { + maxPicNum = 2 * p_Vid->max_frame_num; + currPicNum = 2 * currSlice->frame_num + 1; + } + picNumLXPred = currPicNum; + for (i = 0; modification_of_pic_nums_idc[i] != 3; i++) { + H264_StorePic_t *tmp = NULL; + RK_U32 error_flag = 0; + if (modification_of_pic_nums_idc[i] > 3) + continue; + if (modification_of_pic_nums_idc[i] < 2) { + if (modification_of_pic_nums_idc[i] == 0) { + if ( (picNumLXPred - (abs_diff_pic_num_minus1[i] + 1)) < 0) + picNumLXNoWrap = picNumLXPred - (abs_diff_pic_num_minus1[i] + 1) + maxPicNum; + else + picNumLXNoWrap = picNumLXPred - (abs_diff_pic_num_minus1[i] + 1); + } else { //!< (modification_of_pic_nums_idc[i] == 1) + if (picNumLXPred + (abs_diff_pic_num_minus1[i] + 1) >= maxPicNum) + picNumLXNoWrap = picNumLXPred + (abs_diff_pic_num_minus1[i] + 1) - maxPicNum; + else + picNumLXNoWrap = picNumLXPred + (abs_diff_pic_num_minus1[i] + 1); + } + picNumLXPred = picNumLXNoWrap; + picNumLX = (picNumLXNoWrap > currPicNum) ? (picNumLXNoWrap - maxPicNum) : picNumLXNoWrap; + error_flag = 1; + if (get_short_term_pic(currSlice, picNumLX, &tmp)) { //!< find short reference + MppFrame mframe = NULL; + H264D_DBG(H264D_DBG_DPB_REF_ERR, "find short reference, slot_idx=%d.\n", tmp->mem_mark->slot_idx); + if (tmp && tmp->mem_mark) { + mpp_buf_slot_get_prop(p_Vid->p_Dec->frame_slots, tmp->mem_mark->slot_idx, SLOT_FRAME_PTR, &mframe); + if (mframe && !mpp_frame_get_errinfo(mframe)) { + error_flag = 0; + } + } + } + + } else { //!< (modification_of_pic_nums_idc[i] == 2) + tmp = get_long_term_pic(currSlice, long_term_pic_idx[i]); + } + dpb_error_flag |= error_flag; + } + + return dpb_error_flag; +} + +static RK_U32 check_ref_dbp_err(H264_DecCtx_t *p_Dec, H264_RefPicInfo_t *pref, RK_U32 active_refs) +{ + RK_U32 i = 0; + RK_U32 dpb_error_flag = 0; + + for (i = 0; i < MAX_REF_SIZE; i++) { + if (pref[i].valid) { + MppFrame mframe = NULL; + RK_U32 slot_idx = p_Dec->dpb_info[pref[i].dpb_idx].slot_index; + mpp_buf_slot_get_prop(p_Dec->frame_slots, slot_idx, SLOT_FRAME_PTR, &mframe); + if (mframe) { + if (i < active_refs) { + dpb_error_flag |= mpp_frame_get_errinfo(mframe); + } + H264D_DBG(H264D_DBG_DPB_REF_ERR, "[DPB_REF_ERR] slot_idx=%d, dpb_err[%d]=%d", slot_idx, i, mpp_frame_get_errinfo(mframe)); + } + } + } + return dpb_error_flag; +} + +static void check_refer_picture_lists(H264_SLICE_t *currSlice) +{ + H264_DecCtx_t *p_Dec = currSlice->p_Dec; + H264dErrCtx_t *p_err = &p_Dec->errctx; + + if (I_SLICE == currSlice->slice_type) { + p_err->dpb_err_flag = 0; + return; + } +#if 1 + + if ((currSlice->slice_type % 5) != I_SLICE + && (currSlice->slice_type % 5) != SI_SLICE) { + if (currSlice->ref_pic_list_reordering_flag[LIST_0]) { + p_err->cur_err_flag |= check_ref_pic_list(currSlice, 0) ? 1 : 0; + } + else { + RK_S32 pps_refs = currSlice->active_pps->num_ref_idx_l0_default_active_minus1 + 1; + RK_S32 over_flag = currSlice->num_ref_idx_override_flag; + RK_S32 active_l0 = over_flag ? currSlice->num_ref_idx_active[LIST_0] : pps_refs; + p_err->cur_err_flag |= check_ref_dbp_err(p_Dec, p_Dec->refpic_info_p, active_l0) ? 1 : 0; + H264D_DBG(H264D_DBG_DPB_REF_ERR, "list0 dpb: cur_err_flag=%d, pps_refs=%d, over_flag=%d, num_ref_l0=%d\n", + p_err->cur_err_flag, pps_refs, over_flag, active_l0); + } + } + if (currSlice->slice_type % 5 == B_SLICE) { + if (currSlice->ref_pic_list_reordering_flag[LIST_1]) { + p_err->cur_err_flag |= check_ref_pic_list(currSlice, 1) ? 1 : 0; + } + else { + RK_S32 pps_refs = currSlice->active_pps->num_ref_idx_l1_default_active_minus1 + 1; + RK_S32 over_flag = currSlice->num_ref_idx_override_flag; + RK_S32 active_l1 = over_flag ? currSlice->num_ref_idx_active[LIST_1] : pps_refs; + p_err->cur_err_flag |= check_ref_dbp_err(p_Dec, p_Dec->refpic_info_b[1], active_l1) ? 1 : 0; + H264D_DBG(H264D_DBG_DPB_REF_ERR, "list1 dpb: cur_err_flag=%d, pps_refs=%d, over_flag=%d, num_ref_l1=%d\n", + p_err->cur_err_flag, pps_refs, over_flag, active_l1); + } + //!< B_SLICE only has one refer + if ((currSlice->active_sps->vui_seq_parameters.num_reorder_frames > 1) + && (currSlice->p_Dpb->ref_frames_in_buffer < 2)) { + p_err->cur_err_flag |= 1; + H264D_DBG(H264D_DBG_DPB_REF_ERR, "[DPB_REF_ERR] error, B frame only has one refer"); + } + } + +#endif + +} + +static void reset_dpb_info(H264_DpbInfo_t *p) +{ + p->refpic = NULL; + p->TOP_POC = 0; + p->BOT_POC = 0; + p->field_flag = 0; + p->slot_index = -1; + p->colmv_is_used = 0; + p->frame_num = 0; + p->is_long_term = 0; + p->long_term_pic_num = 0; + p->voidx = 0; + p->view_id = 0; + p->is_used = 0; +} + +static MPP_RET prepare_init_dpb_info(H264_SLICE_t *currSlice) +{ + RK_U32 i = 0, j = 0; + H264_DpbBuf_t *p_Dpb = currSlice->p_Dpb; + H264_DecCtx_t *p_Dec = currSlice->p_Dec; + + //!< reset parameters + for (i = 0; i < MAX_DPB_SIZE; i++) { + reset_dpb_info(&p_Dec->dpb_info[i]); + } + //!< reference +#if 1 + for (i = 0, j = 0; j < p_Dpb->ref_frames_in_buffer; i++, j++) { + if (p_Dpb->fs_ref[j]->is_used == 3) { + p_Dec->dpb_info[i].refpic = p_Dpb->fs_ref[j]->frame; + if (p_Dpb->fs_ref[j]->frame->iCodingType == FIELD_CODING) { + p_Dec->dpb_info[i].TOP_POC = p_Dpb->fs_ref[j]->top_field->poc; + p_Dec->dpb_info[i].BOT_POC = p_Dpb->fs_ref[j]->bottom_field->poc; + } else { + if (p_Dpb->fs_ref[j]->frame->frame_poc != p_Dpb->fs_ref[j]->frame->poc) { + p_Dec->dpb_info[i].TOP_POC = p_Dpb->fs_ref[j]->frame->top_poc - p_Dpb->fs_ref[j]->frame->frame_poc; + p_Dec->dpb_info[i].BOT_POC = p_Dpb->fs_ref[j]->frame->bottom_poc - p_Dpb->fs_ref[j]->frame->frame_poc; + } else { + p_Dec->dpb_info[i].TOP_POC = p_Dpb->fs_ref[j]->frame->top_poc; + p_Dec->dpb_info[i].BOT_POC = p_Dpb->fs_ref[j]->frame->bottom_poc; + } + } + p_Dec->dpb_info[i].field_flag = p_Dpb->fs_ref[j]->frame->iCodingType == FIELD_CODING; + p_Dec->dpb_info[i].slot_index = p_Dpb->fs_ref[j]->frame->mem_mark->slot_idx; + p_Dec->dpb_info[i].colmv_is_used = (p_Dpb->fs_ref[j]->frame->colmv_no_used_flag ? 0 : 1); + } else if (p_Dpb->fs_ref[j]->is_used) { + if (p_Dpb->fs_ref[j]->is_used & 0x1) { // top + p_Dec->dpb_info[i].refpic = p_Dpb->fs_ref[j]->top_field; + + p_Dec->dpb_info[i].TOP_POC = p_Dpb->fs_ref[j]->top_field->poc; + p_Dec->dpb_info[i].BOT_POC = 0; + p_Dec->dpb_info[i].field_flag = 1; + p_Dec->dpb_info[i].slot_index = p_Dpb->fs_ref[j]->top_field->mem_mark->slot_idx; + p_Dec->dpb_info[i].colmv_is_used = (p_Dpb->fs_ref[j]->top_field->colmv_no_used_flag ? 0 : 1); + } else { // if(p_Dpb->fs_ref[j]->is_used & 0x2) // bottom + p_Dec->dpb_info[i].refpic = p_Dpb->fs_ref[j]->bottom_field; + p_Dec->dpb_info[i].TOP_POC = 0; + p_Dec->dpb_info[i].BOT_POC = p_Dpb->fs_ref[j]->bottom_field->poc; + p_Dec->dpb_info[i].field_flag = 1; + p_Dec->dpb_info[i].slot_index = p_Dpb->fs_ref[j]->bottom_field->mem_mark->slot_idx; + p_Dec->dpb_info[i].colmv_is_used = (p_Dpb->fs_ref[j]->bottom_field->colmv_no_used_flag ? 0 : 1); + } + } + p_Dec->dpb_info[i].frame_num = p_Dpb->fs_ref[j]->frame_num; + p_Dec->dpb_info[i].is_long_term = 0; + p_Dec->dpb_info[i].long_term_pic_num = 0; + p_Dec->dpb_info[i].long_term_frame_idx = 0; + p_Dec->dpb_info[i].voidx = p_Dpb->fs_ref[j]->layer_id; + p_Dec->dpb_info[i].view_id = p_Dpb->fs_ref[j]->view_id; + p_Dec->dpb_info[i].is_used = p_Dpb->fs_ref[j]->is_used; + } +#endif + //!<---- long term reference +#if 1 + for (j = 0; j < p_Dpb->ltref_frames_in_buffer; i++, j++) { + if (p_Dpb->fs_ltref[j]->is_used == 3) { + p_Dec->dpb_info[i].refpic = p_Dpb->fs_ltref[j]->frame; + + if (p_Dpb->fs_ltref[j]->frame->iCodingType == FIELD_CODING) { + p_Dec->dpb_info[i].TOP_POC = p_Dpb->fs_ltref[j]->top_field->poc; + p_Dec->dpb_info[i].BOT_POC = p_Dpb->fs_ltref[j]->bottom_field->poc; + } else { + if (p_Dpb->fs_ltref[j]->frame->frame_poc != p_Dpb->fs_ltref[j]->frame->poc) { + p_Dec->dpb_info[i].TOP_POC = p_Dpb->fs_ltref[j]->frame->top_poc - p_Dpb->fs_ltref[j]->frame->frame_poc; + p_Dec->dpb_info[i].BOT_POC = p_Dpb->fs_ltref[j]->frame->bottom_poc - p_Dpb->fs_ltref[j]->frame->frame_poc; + } else { + p_Dec->dpb_info[i].TOP_POC = p_Dpb->fs_ltref[j]->frame->top_poc; + p_Dec->dpb_info[i].BOT_POC = p_Dpb->fs_ltref[j]->frame->bottom_poc; + } + + } + p_Dec->dpb_info[i].field_flag = p_Dpb->fs_ltref[j]->frame->iCodingType == FIELD_CODING; + p_Dec->dpb_info[i].slot_index = p_Dpb->fs_ltref[j]->frame->mem_mark->slot_idx; + p_Dec->dpb_info[i].colmv_is_used = (p_Dpb->fs_ltref[j]->frame->colmv_no_used_flag ? 0 : 1); + p_Dec->dpb_info[i].long_term_pic_num = p_Dpb->fs_ltref[j]->frame->long_term_pic_num; + } else if (p_Dpb->fs_ltref[j]->is_used) { + if (p_Dpb->fs_ltref[j]->is_used & 0x1) { + p_Dec->dpb_info[i].refpic = p_Dpb->fs_ltref[j]->top_field; + p_Dec->dpb_info[i].TOP_POC = p_Dpb->fs_ltref[j]->top_field->poc; + p_Dec->dpb_info[i].BOT_POC = 0; + p_Dec->dpb_info[i].field_flag = 1; + p_Dec->dpb_info[i].slot_index = p_Dpb->fs_ltref[j]->top_field->mem_mark->slot_idx; + p_Dec->dpb_info[i].colmv_is_used = (p_Dpb->fs_ltref[j]->top_field->colmv_no_used_flag ? 0 : 1); + p_Dec->dpb_info[i].long_term_pic_num = p_Dpb->fs_ltref[j]->top_field->long_term_pic_num; + } else { // if(p_Dpb->fs_ref[j]->is_used & 0x2) + p_Dec->dpb_info[i].refpic = p_Dpb->fs_ltref[j]->bottom_field; + p_Dec->dpb_info[i].TOP_POC = 0; + p_Dec->dpb_info[i].BOT_POC = p_Dpb->fs_ltref[j]->bottom_field->poc; + p_Dec->dpb_info[i].field_flag = 1; + p_Dec->dpb_info[i].slot_index = p_Dpb->fs_ltref[j]->bottom_field->mem_mark->slot_idx; + p_Dec->dpb_info[i].colmv_is_used = (p_Dpb->fs_ltref[j]->bottom_field->colmv_no_used_flag ? 0 : 1); + p_Dec->dpb_info[i].long_term_pic_num = p_Dpb->fs_ltref[j]->bottom_field->long_term_pic_num; + } + } + p_Dec->dpb_info[i].frame_num = p_Dpb->fs_ltref[j]->long_term_frame_idx; //long term use long_term_frame_idx + p_Dec->dpb_info[i].is_long_term = 1; + p_Dec->dpb_info[i].long_term_frame_idx = p_Dpb->fs_ltref[j]->long_term_frame_idx; + p_Dec->dpb_info[i].voidx = p_Dpb->fs_ltref[j]->layer_id; + p_Dec->dpb_info[i].view_id = p_Dpb->fs_ltref[j]->view_id; + p_Dec->dpb_info[i].is_used = p_Dpb->fs_ltref[j]->is_used; + } +#endif + //!< inter-layer reference (for multi-layered codecs) +#if 1 + for (j = 0; j < p_Dpb->used_size_il; i++, j++) { + if (currSlice->structure == FRAME && p_Dpb->fs_ilref[j]->is_used == 3) { + if (p_Dpb->fs_ilref[j]->inter_view_flag[0] == 0 && p_Dpb->fs_ilref[j]->inter_view_flag[1] == 0) + break; + p_Dec->dpb_info[i].refpic = p_Dpb->fs_ilref[j]->frame; + + if (p_Dpb->fs_ilref[j]->frame->is_mmco_5) { + p_Dec->dpb_info[i].TOP_POC = p_Dpb->fs_ilref[j]->frame->top_poc_mmco5; + p_Dec->dpb_info[i].BOT_POC = p_Dpb->fs_ilref[j]->frame->bot_poc_mmco5; + } else { + p_Dec->dpb_info[i].TOP_POC = p_Dpb->fs_ilref[j]->frame->top_poc; + p_Dec->dpb_info[i].BOT_POC = p_Dpb->fs_ilref[j]->frame->bottom_poc; + } + p_Dec->dpb_info[i].field_flag = p_Dpb->fs_ilref[j]->frame->iCodingType == FIELD_CODING; + p_Dec->dpb_info[i].slot_index = p_Dpb->fs_ilref[j]->frame->mem_mark->slot_idx; + p_Dec->dpb_info[i].colmv_is_used = (p_Dpb->fs_ilref[j]->frame->colmv_no_used_flag ? 0 : 1); + } else if (currSlice->structure != FRAME && p_Dpb->fs_ilref[j]->is_used) { + if (p_Dpb->fs_ilref[j]->is_used == 0x3) { + if (p_Dpb->fs_ilref[j]->inter_view_flag[currSlice->structure == BOTTOM_FIELD] == 0) + break; + p_Dec->dpb_info[i].refpic = p_Dpb->fs_ilref[j]->top_field; + + if (p_Dpb->fs_ilref[j]->top_field->is_mmco_5) { + p_Dec->dpb_info[i].TOP_POC = p_Dpb->fs_ilref[j]->top_field->top_poc_mmco5; + } else { + p_Dec->dpb_info[i].TOP_POC = p_Dpb->fs_ilref[j]->top_field->top_poc; + } + if (p_Dpb->fs_ilref[j]->bottom_field->is_mmco_5) { + p_Dec->dpb_info[i].BOT_POC = p_Dpb->fs_ilref[j]->bottom_field->bot_poc_mmco5; + } else { + p_Dec->dpb_info[i].BOT_POC = p_Dpb->fs_ilref[j]->bottom_field->bottom_poc; + } + p_Dec->dpb_info[i].field_flag = p_Dpb->fs_ilref[j]->frame->iCodingType == FIELD_CODING; + p_Dec->dpb_info[i].slot_index = p_Dpb->fs_ilref[j]->frame->mem_mark->slot_idx; + p_Dec->dpb_info[i].colmv_is_used = (p_Dpb->fs_ilref[j]->frame->colmv_no_used_flag ? 0 : 1); + } + if (p_Dpb->fs_ilref[j]->is_used & 0x1) { + if (p_Dpb->fs_ilref[j]->inter_view_flag[0] == 0) + break; + p_Dec->dpb_info[i].refpic = p_Dpb->fs_ilref[j]->top_field; + + if (p_Dpb->fs_ilref[j]->top_field->is_mmco_5) { + p_Dec->dpb_info[i].TOP_POC = p_Dpb->fs_ilref[j]->top_field->top_poc_mmco5; + } else { + p_Dec->dpb_info[i].TOP_POC = p_Dpb->fs_ilref[j]->top_field->top_poc; + } + p_Dec->dpb_info[i].BOT_POC = 0; + p_Dec->dpb_info[i].field_flag = 1; + p_Dec->dpb_info[i].slot_index = p_Dpb->fs_ilref[j]->top_field->mem_mark->slot_idx; + p_Dec->dpb_info[i].colmv_is_used = (p_Dpb->fs_ilref[j]->top_field->colmv_no_used_flag ? 0 : 1); + } else { // if(p_Dpb->fs_ref[j]->is_used & 0x2) + if (p_Dpb->fs_ilref[j]->inter_view_flag[1] == 0) + break; + p_Dec->dpb_info[i].refpic = p_Dpb->fs_ilref[j]->bottom_field; + + p_Dec->dpb_info[i].TOP_POC = 0; + if (p_Dpb->fs_ilref[j]->bottom_field->is_mmco_5) { + p_Dec->dpb_info[i].BOT_POC = p_Dpb->fs_ilref[j]->bottom_field->bot_poc_mmco5; + } else { + p_Dec->dpb_info[i].BOT_POC = p_Dpb->fs_ilref[j]->bottom_field->bottom_poc; + } + p_Dec->dpb_info[i].field_flag = 1; + p_Dec->dpb_info[i].slot_index = p_Dpb->fs_ilref[j]->bottom_field->mem_mark->slot_idx; + p_Dec->dpb_info[i].colmv_is_used = (p_Dpb->fs_ilref[j]->bottom_field->colmv_no_used_flag ? 0 : 1); + } + } + p_Dec->dpb_info[i].frame_num = p_Dpb->fs_ilref[j]->frame_num; + p_Dec->dpb_info[i].is_long_term = 0;//p_Dpb->fs_ilref[j]->is_long_term; + p_Dec->dpb_info[i].is_ilt_flag = 1; + p_Dec->dpb_info[i].long_term_pic_num = 0; + p_Dec->dpb_info[i].long_term_frame_idx = 0; + p_Dec->dpb_info[i].voidx = p_Dpb->fs_ilref[j]->layer_id; + p_Dec->dpb_info[i].view_id = p_Dpb->fs_ilref[j]->view_id; + p_Dec->dpb_info[i].is_used = p_Dpb->fs_ilref[j]->is_used; + } +#endif + + return MPP_OK; +} + +static MPP_RET prepare_init_ref_info(H264_SLICE_t *currSlice) +{ + void *refpic = NULL; + RK_U32 i = 0, j = 0, k = 0; + RK_S32 poc = 0, TOP_POC = 0, BOT_POC = 0; + RK_S32 min_poc = 0, max_poc = 0; + RK_S32 layer_id = 0, voidx = 0, is_used = 0, near_dpb_idx = 0; + H264_DecCtx_t *p_Dec = currSlice->p_Dec; + + memset(p_Dec->refpic_info_p, 0, MAX_REF_SIZE * sizeof(H264_RefPicInfo_t)); + memset(p_Dec->refpic_info_b[0], 0, MAX_REF_SIZE * sizeof(H264_RefPicInfo_t)); + memset(p_Dec->refpic_info_b[1], 0, MAX_REF_SIZE * sizeof(H264_RefPicInfo_t)); + + if (currSlice->idr_flag && (currSlice->layer_id == 0)) { // idr_flag==1 && layer_id==0 + goto __RETURN; + } + //!<------ set listP ------- + near_dpb_idx = 0; + for (j = 0; j < 32; j++) { + poc = 0; + layer_id = currSlice->listP[0][j]->layer_id; + if (j < currSlice->listXsizeP[0]) { + if (currSlice->listP[0][j]->structure == FRAME) { + poc = (currSlice->listP[0][j]->is_mmco_5 && currSlice->layer_id && currSlice->listP[0][j]->layer_id == 0) + ? currSlice->listP[0][j]->poc_mmco5 : currSlice->listP[0][j]->poc; + } else if (currSlice->listP[0][j]->structure == TOP_FIELD) { + poc = (currSlice->listP[0][j]->is_mmco_5 && currSlice->layer_id && currSlice->listP[0][j]->layer_id == 0) + ? currSlice->listP[0][j]->top_poc_mmco5 : currSlice->listP[0][j]->top_poc; + } else { + poc = (currSlice->listP[0][j]->is_mmco_5 && currSlice->layer_id && currSlice->listP[0][j]->layer_id == 0) + ? currSlice->listP[0][j]->bot_poc_mmco5 : currSlice->listP[0][j]->bottom_poc; + } + for (i = 0; i < 16; i++) { + refpic = p_Dec->dpb_info[i].refpic; + TOP_POC = p_Dec->dpb_info[i].TOP_POC; + BOT_POC = p_Dec->dpb_info[i].BOT_POC; + voidx = p_Dec->dpb_info[i].voidx; + is_used = p_Dec->dpb_info[i].is_used; + if (currSlice->structure == FRAME && refpic) { + if (poc == MPP_MIN(TOP_POC, BOT_POC) && (layer_id == voidx)) + break; + } else { + if (is_used == 3) { + if ((poc == BOT_POC || poc == TOP_POC) && layer_id == voidx) + break; + } else if (is_used & 1) { + if (poc == TOP_POC && layer_id == voidx) + break; + } else if (is_used & 2) { + if (poc == BOT_POC && layer_id == voidx) + break; + } + } + } + if (i < 16) { + near_dpb_idx = i; + p_Dec->refpic_info_p[j].dpb_idx = i; + } else { + ASSERT(near_dpb_idx >= 0); + p_Dec->refpic_info_p[j].dpb_idx = near_dpb_idx; + p_Dec->errctx.cur_err_flag |= 1; + } + if (currSlice->listP[0][j]->structure == BOTTOM_FIELD) { + p_Dec->refpic_info_p[j].bottom_flag = 1; + } else { + p_Dec->refpic_info_p[j].bottom_flag = 0; + } + p_Dec->refpic_info_p[j].valid = 1; + } else { + p_Dec->refpic_info_p[j].valid = 0; + p_Dec->refpic_info_p[j].dpb_idx = 0; + p_Dec->refpic_info_p[j].bottom_flag = 0; + } + } + //!<------ set listB ------- + for (k = 0; k < 2; k++) { + min_poc = 0xFFFF; + max_poc = -0xFFFF; + near_dpb_idx = 0; + for (j = 0; j < 32; j++) { + poc = 0; + layer_id = currSlice->listB[k][j]->layer_id; + if (j < currSlice->listXsizeB[k]) { + if (currSlice->listB[k][j]->structure == FRAME) { + poc = (currSlice->listB[k][j]->is_mmco_5 && currSlice->layer_id && currSlice->listB[k][j]->layer_id == 0) + ? currSlice->listB[k][j]->poc_mmco5 : currSlice->listB[k][j]->poc; + } else if (currSlice->listB[k][j]->structure == TOP_FIELD) { + poc = (currSlice->listB[k][j]->is_mmco_5 && currSlice->layer_id && currSlice->listB[k][j]->layer_id == 0) + ? currSlice->listB[k][j]->top_poc_mmco5 : currSlice->listB[k][j]->top_poc; + } else { + poc = (currSlice->listB[k][j]->is_mmco_5 && currSlice->layer_id && currSlice->listB[k][j]->layer_id == 0) + ? currSlice->listB[k][j]->bot_poc_mmco5 : currSlice->listB[k][j]->bottom_poc; + } + + min_poc = MPP_MIN(min_poc, poc); + max_poc = MPP_MAX(max_poc, poc); + for (i = 0; i < 16; i++) { + refpic = p_Dec->dpb_info[i].refpic; + TOP_POC = p_Dec->dpb_info[i].TOP_POC; + BOT_POC = p_Dec->dpb_info[i].BOT_POC; + voidx = p_Dec->dpb_info[i].voidx; + is_used = p_Dec->dpb_info[i].is_used; + if (currSlice->structure == FRAME && refpic) { + if (poc == MPP_MIN(TOP_POC, BOT_POC) && (layer_id == voidx)) + break; + } else { + if (is_used == 3) { + if ((poc == BOT_POC || poc == TOP_POC) && layer_id == voidx) + break; + } else if (is_used & 1) { + if (poc == TOP_POC && (layer_id == voidx || (layer_id != voidx && !currSlice->bottom_field_flag))) + break; + } else if (is_used & 2) { + if (poc == BOT_POC && (layer_id == voidx || (layer_id != voidx && currSlice->bottom_field_flag))) + break; + } + } + } + if (i < 16) { + near_dpb_idx = i; + p_Dec->refpic_info_b[k][j].dpb_idx = i; + } else { + ASSERT(near_dpb_idx >= 0); + p_Dec->refpic_info_b[k][j].dpb_idx = near_dpb_idx; + p_Dec->errctx.cur_err_flag |= 1; + } + if (currSlice->listB[k][j]->structure == BOTTOM_FIELD) { + p_Dec->refpic_info_b[k][j].bottom_flag = 1; + } else { + p_Dec->refpic_info_b[k][j].bottom_flag = 0; + } + p_Dec->refpic_info_b[k][j].valid = 1; + } else { + p_Dec->refpic_info_b[k][j].valid = 0; + p_Dec->refpic_info_b[k][j].dpb_idx = 0; + p_Dec->refpic_info_b[k][j].bottom_flag = 0; + } + } + + } + //!< check dpb list poc +#if 0 + { + RK_S32 cur_poc = p_Dec->p_Vid->dec_pic->poc; + if ((currSlice->slice_type % 5) != I_SLICE + && (currSlice->slice_type % 5) != SI_SLICE) { + if (cur_poc < min_poc) { + p_Dec->errctx.cur_err_flag |= 1; + H264D_DBG(H264D_DBG_DPB_REF_ERR, "[DPB_REF_ERR] min_poc=%d, dec_poc=%d", min_poc, cur_poc); + } + } + if (currSlice->slice_type % 5 == B_SLICE) { + if (cur_poc > max_poc) { + p_Dec->errctx.cur_err_flag |= 1; + H264D_DBG(H264D_DBG_DPB_REF_ERR, "[DPB_REF_ERR] max_poc=%d, dec_poc=%d", max_poc, cur_poc); + } + } + } +#endif +__RETURN: + return MPP_OK; +} + +static MPP_RET check_refer_dpb_buf_slots(H264_SLICE_t *currSlice) +{ + RK_U32 i = 0; + RK_S32 slot_idx = 0; + RK_U32 dpb_used = 0; + H264_DecCtx_t *p_Dec = NULL; + H264_DpbMark_t *p_mark = NULL; + + p_Dec = currSlice->p_Dec; + //!< set buf slot flag + for (i = 0; i < MAX_DPB_SIZE; i++) { + if ((NULL != p_Dec->dpb_info[i].refpic) && (p_Dec->dpb_info[i].slot_index >= 0)) { + p_Dec->in_task->refer[i] = p_Dec->dpb_info[i].slot_index; + mpp_buf_slot_set_flag(p_Dec->frame_slots, p_Dec->dpb_info[i].slot_index, SLOT_HAL_INPUT); + mpp_buf_slot_set_flag(p_Dec->frame_slots, p_Dec->dpb_info[i].slot_index, SLOT_CODEC_USE); + } else { + p_Dec->in_task->refer[i] = -1; + } + } + //!< dpb info + if (rkv_h264d_parse_debug & H264D_DBG_DPB_INFO) { + H264D_DBG(H264D_DBG_DPB_INFO, "[DPB_INFO] cur_slot_idx=%d", p_Dec->in_task->output); + for (i = 0; i < MAX_DPB_SIZE; i++) { + slot_idx = p_Dec->in_task->refer[i]; + if (slot_idx >= 0) { + H264D_DBG(H264D_DBG_DPB_INFO, "[DPB_INFO] ref_slot_idx[%d]=%d", i, slot_idx); + } + } + } + //!< mark info + for (i = 0; i < MAX_MARK_SIZE; i++) { + p_mark = &p_Dec->dpb_mark[i]; + if (p_mark->out_flag && (p_mark->slot_idx >= 0)) { + dpb_used++; + if (rkv_h264d_parse_debug & H264D_DBG_DPB_INFO) { + RK_S32 fd = 0; + MppFrame mframe = NULL; + MppBuffer mbuffer = NULL; + mpp_buf_slot_get_prop(p_Dec->frame_slots, p_mark->slot_idx, SLOT_FRAME_PTR, &mframe); + mbuffer = mframe ? mpp_frame_get_buffer(mframe) : NULL; + fd = mbuffer ? mpp_buffer_get_fd(mbuffer) : 0xFF; + H264D_DBG(H264D_DBG_DPB_INFO, "[DPB_MARK_INFO] slot_idx=%d, top_used=%d, bot_used=%d, out_flag=%d, fd=0x%02x", + p_mark->slot_idx, p_mark->top_used, p_mark->bot_used, p_mark->out_flag, fd); + } + } + } + H264D_DBG(H264D_DBG_DPB_INFO, "[DPB_MARK_INFO] ---------- cur_slot=%d --------------------", p_Dec->in_task->output); + + if (dpb_used > currSlice->p_Dpb->size + 2) { + H264D_ERR("[h264d_reset_error]"); + h264d_reset((void *)p_Dec); + return MPP_NOK; + } + + return MPP_OK; +} + + +/*! +*********************************************************************** +* \brief +* flush dpb buffer slot +*********************************************************************** +*/ +//extern "C" +void flush_dpb_buf_slot(H264_DecCtx_t *p_Dec) +{ + RK_U32 i = 0; + H264_DpbMark_t *p_mark = NULL; + + for (i = 0; i < MAX_MARK_SIZE; i++) { + p_mark = &p_Dec->dpb_mark[i]; + if (p_mark && p_mark->out_flag && (p_mark->slot_idx >= 0)) { + MppFrame mframe = NULL; + mpp_buf_slot_get_prop(p_Dec->frame_slots, p_mark->slot_idx, SLOT_FRAME_PTR, &mframe); + if (mframe) { + H264D_DBG(H264D_DBG_SLOT_FLUSH, "[DPB_BUF_FLUSH] slot_idx=%d, top_used=%d, bot_used=%d", + p_mark->slot_idx, p_mark->top_used, p_mark->bot_used); + mpp_frame_set_discard(mframe, 1); + mpp_buf_slot_set_flag(p_Dec->frame_slots, p_mark->slot_idx, SLOT_QUEUE_USE); + mpp_buf_slot_enqueue(p_Dec->frame_slots, p_mark->slot_idx, QUEUE_DISPLAY); + mpp_buf_slot_clr_flag(p_Dec->frame_slots, p_mark->slot_idx, SLOT_CODEC_USE); + p_Dec->last_frame_slot_idx = p_mark->slot_idx; + } + } + reset_dpb_mark(p_mark); + } +} + +/*! +*********************************************************************** +* \brief +* reset dpb mark +*********************************************************************** +*/ +//extern "C" +MPP_RET reset_dpb_mark(H264_DpbMark_t *p_mark) +{ + if (p_mark) { + p_mark->top_used = 0; + p_mark->bot_used = 0; + p_mark->out_flag = 0; + p_mark->slot_idx = -1; + p_mark->pic = NULL; + p_mark->mframe = NULL; + } + + return MPP_OK; +} +/*! +*********************************************************************** +* \brief +* init picture +*********************************************************************** +*/ +//extern "C" +MPP_RET init_picture(H264_SLICE_t *currSlice) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + H264_DecCtx_t *p_Dec = currSlice->p_Vid->p_Dec; + H264dVideoCtx_t *p_Vid = currSlice->p_Vid; + H264dErrCtx_t *p_err = &p_Dec->errctx; + + //!< discard stream before I_SLICE + p_err->i_slice_no += ((!currSlice->layer_id) && (I_SLICE == currSlice->slice_type)) ? 1 : 0; + if (!p_err->i_slice_no) { + H264D_WARNNING("[Discard] Discard slice before I Slice. \n"); + ret = MPP_NOK; + goto __FAILED; + } + FUN_CHECK(ret = alloc_decpic(currSlice)); + if ((p_err->i_slice_no < 2) + && (!currSlice->layer_id) && (I_SLICE == currSlice->slice_type)) { + p_err->first_iframe_poc = p_Vid->dec_pic->poc; //!< recoder first i frame poc + } + //!< idr_memory_management MVC_layer, idr_flag==1 + if (currSlice->layer_id && !currSlice->svc_extension_flag && !currSlice->mvcExt.non_idr_flag) { + ASSERT(currSlice->layer_id == 1); + FUN_CHECK(ret = idr_memory_management(p_Vid->p_Dpb_layer[currSlice->layer_id], p_Vid->dec_pic)); + } + update_ref_list(p_Vid->p_Dpb_layer[currSlice->layer_id]); + update_ltref_list(p_Vid->p_Dpb_layer[currSlice->layer_id]); + update_pic_num(currSlice); + //!< reorder + if (!currSlice->idr_flag || currSlice->layer_id) { + FUN_CHECK(ret = init_lists_p_slice_mvc(currSlice)); + FUN_CHECK(ret = init_lists_b_slice_mvc(currSlice)); + } + prepare_init_dpb_info(currSlice); + prepare_init_ref_info(currSlice); + + FUN_CHECK(ret = check_refer_dpb_buf_slots(currSlice)); + check_refer_picture_lists(currSlice); + + prepare_init_scanlist(currSlice); + fill_picparams(currSlice->p_Vid, &p_Dec->dxva_ctx->pp); + fill_scanlist(currSlice->p_Vid, &p_Dec->dxva_ctx->qm); + + + return ret = MPP_OK; +__FAILED: + return ret; +} + +/*! +*********************************************************************** +* \brief +* update dpb +*********************************************************************** +*/ +//extern "C" +MPP_RET update_dpb(H264_DecCtx_t *p_Dec) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + + p_Dec->p_Vid->exit_picture_flag = 1; + p_Dec->p_Vid->have_outpicture_flag = 1; + ret = exit_picture(p_Dec->p_Vid, &p_Dec->p_Vid->dec_pic); + + p_Dec->p_Vid->iNumOfSlicesDecoded = 0; + p_Dec->p_Vid->exit_picture_flag = 0; + + return ret; +} + diff --git a/mpp/codec/dec/h264/h264d_init.h b/mpp/codec/dec/h264/h264d_init.h index eb679824..49e186f5 100644 --- a/mpp/codec/dec/h264/h264d_init.h +++ b/mpp/codec/dec/h264/h264d_init.h @@ -1,42 +1,42 @@ -/* -* -* Copyright 2015 Rockchip Electronics Co. LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#ifndef _H264D_INIT_H_ -#define _H264D_INIT_H_ - - -#include "rk_type.h" -#include "mpp_err.h" -#include "h264d_global.h" - - -#ifdef __cplusplus -extern "C" { -#endif - -MPP_RET update_dpb (H264_DecCtx_t *p_Dec); -MPP_RET init_picture (H264_SLICE_t *currSlice); -MPP_RET reset_dpb_mark(H264_DpbMark_t *p_mark); -void flush_dpb_buf_slot(H264_DecCtx_t *p_Dec); - -#ifdef __cplusplus -} -#endif - -//======================================== -#endif /* end of _RKV_H264_DECODER_INIT_H_ */ - +/* +* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef _H264D_INIT_H_ +#define _H264D_INIT_H_ + + +#include "rk_type.h" +#include "mpp_err.h" +#include "h264d_global.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +MPP_RET update_dpb (H264_DecCtx_t *p_Dec); +MPP_RET init_picture (H264_SLICE_t *currSlice); +MPP_RET reset_dpb_mark(H264_DpbMark_t *p_mark); +void flush_dpb_buf_slot(H264_DecCtx_t *p_Dec); + +#ifdef __cplusplus +} +#endif + +//======================================== +#endif /* end of _RKV_H264_DECODER_INIT_H_ */ + diff --git a/mpp/codec/dec/h264/h264d_log.c b/mpp/codec/dec/h264/h264d_log.c index 03972722..54c7595a 100644 --- a/mpp/codec/dec/h264/h264d_log.c +++ b/mpp/codec/dec/h264/h264d_log.c @@ -1,272 +1,272 @@ -/* -* -* Copyright 2015 Rockchip Electronics Co. LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#define MODULE_TAG "" - -#include -#include -#include - -#include "mpp_log.h" -#include "mpp_env.h" -#include "mpp_mem.h" -#include "mpp_common.h" - -#include "h264d_log.h" - -#define LOG_BUF_SIZE 512 - -RK_U32 g_nalu_cnt0 = 0; -RK_U32 g_nalu_cnt1 = 0; -RK_S32 g_max_bytes = 0; -RK_U32 g_max_slice_data = 0; -FILE *g_debug_file0 = NULL; -FILE *g_debug_file1 = NULL; - -RK_U32 rkv_h264d_parse_debug = 0; -RK_U32 rkv_h264d_hal_debug = 0; - -const LogEnvStr_t logenv_name = { - "h264d_log_help", - "h264d_log_show", - "h264d_log_ctrl", - "h264d_log_level", - "h264d_log_outpath", - "h264d_log_cmppath", - "h264d_log_decframe", - "h264d_log_begframe", - "h264d_log_endframe", -}; - -const char *loglevel_name[LOG_LEVEL_MAX] = { - "SILENT", - "FATAL", - "ERROR", - "WARNNING", - "INFO", - "TRACE", -}; - -const char *logctrl_name[LOG_MAX] = { - "DEBUG_EN", - "FPGA_MODE", - "LOG_PRINT", - "LOG_WRITE", - "RUN_PAESE", - "RUN_HAL", - "READ_NALU", - "READ_SPS", - "READ_SUBSPS", - "READ_PPS", - "READ_SLICE", - "WRITE_SPSPPS", - "WRITE_RPS", - "WRITE_SCANLIST", - "WRITE_STEAM", - "WRITE_REG", -}; - -/*! -*********************************************************************** -* \brief -* rewrite log_info function which in mpp_bitread.c -*********************************************************************** -*/ -static void log_info(void *ctx, ...) -{ - char *fname = NULL; - RK_U32 line = 0; - char argbuf[LOG_BUF_SIZE] = { 0 }; - - if (LogEnable(ctx, LOG_LEVEL_INFO)) { - va_list argptr; - va_start(argptr, ctx); - fname = va_arg(argptr, char*); - line = va_arg(argptr, RK_U32); - vsnprintf(argbuf, sizeof(argbuf), va_arg(argptr, char*), argptr); - writelog(ctx, "syntax", fname, line, argbuf); - va_end(argptr); - } -} -/*! -*********************************************************************** -* \brief -* get log env -*********************************************************************** -*/ - -MPP_RET get_logenv(LogEnv_t *env) -{ - //!< read env - mpp_env_get_u32(logenv_name.help, &env->help, 0); - mpp_env_get_u32(logenv_name.show, &env->show, 0); - mpp_env_get_u32(logenv_name.ctrl, &env->ctrl, 0); - mpp_env_get_u32(logenv_name.level, &env->level, 0); - mpp_env_get_u32(logenv_name.decframe, &env->decframe, 0); - mpp_env_get_u32(logenv_name.begframe, &env->begframe, 0); - mpp_env_get_u32(logenv_name.endframe, &env->endframe, 0); - mpp_env_get_str(logenv_name.outpath, &env->outpath, NULL); - - return MPP_OK; -} - -/*! -*********************************************************************** -* \brief -* print env help -*********************************************************************** -*/ -void print_env_help(LogEnv_t *env) -{ - RK_U8 i = 0; - (void)env; - - mpp_log("--------------- h264d help -------------------- \n"); - mpp_log("h264d_log_help :[num] (0/1) show help content \n"); - mpp_log("h264d_log_show :[num] (0/1) show current log setting \n"); - mpp_log("h264d_log_outpath :[str] \n"); - mpp_log("h264d_log_decframe :[num] \n"); - mpp_log("h264d_log_begframe :[num] \n"); - mpp_log("h264d_log_endframe :[num] \n"); - mpp_log("h264d_log_level :[num] \n"); - for (i = 0; i < LOG_LEVEL_MAX; i++) { - mpp_log(" (%2d) -- %s \n", i, loglevel_name[i]); - } - mpp_log("h264d_log_ctrl :[32bit] \n"); - for (i = 0; i < LOG_MAX; i++) { - mpp_log(" (%2d)bit -- %s \n", i, logctrl_name[i]); - } - mpp_log("------------------------------------------------- \n"); -} -/*! -*********************************************************************** -* \brief -* show env flags -*********************************************************************** -*/ -void show_env_flags(LogEnv_t *env) -{ - RK_U8 i = 0; - mpp_log("------------- h264d debug setting ------------- \n"); - mpp_log("outputpath : %s \n", env->outpath); - mpp_log("DecodeFrame : %d \n", env->decframe); - mpp_log("LogBeginFrame : %d \n", env->begframe); - mpp_log("LogEndFrame : %d \n", env->endframe); - mpp_log("LogLevel : %s \n", loglevel_name[env->level]); - for (i = 0; i < LOG_MAX; i++) { - mpp_log("%s: %d (%d)\n", logctrl_name[i], GetBitVal(env->ctrl, i), i); - } - mpp_log("------------------------------------------------- \n"); -} -/*! -*********************************************************************** -* \brief -* explain log ctrl flag -*********************************************************************** -*/ -MPP_RET explain_ctrl_flag(RK_U32 ctrl_val, LogFlag_t *pflag) -{ - pflag->print_en = GetBitVal(ctrl_val, LOG_PRINT ); - pflag->write_en = GetBitVal(ctrl_val, LOG_WRITE ); - pflag->debug_en = GetBitVal(ctrl_val, LOG_DEBUG ) - || GetBitVal(ctrl_val, LOG_READ_NALU ) - || GetBitVal(ctrl_val, LOG_READ_SPS ) - || GetBitVal(ctrl_val, LOG_READ_SUBSPS ) - || GetBitVal(ctrl_val, LOG_READ_PPS ) - || GetBitVal(ctrl_val, LOG_READ_SLICE ) - || GetBitVal(ctrl_val, LOG_WRITE_SPSPPS ) - || GetBitVal(ctrl_val, LOG_WRITE_RPS ) - || GetBitVal(ctrl_val, LOG_WRITE_SCANLIST) - || GetBitVal(ctrl_val, LOG_WRITE_STEAM ) - || GetBitVal(ctrl_val, LOG_WRITE_REG ); - - return MPP_OK; -} -/*! -*********************************************************************** -* \brief -* set log outpath -*********************************************************************** -*/ -void set_log_outpath(LogEnv_t *env) -{ - if (NULL == env->outpath) { - mpp_env_set_str(logenv_name.outpath, "./h264d_log" ); - mpp_env_get_str(logenv_name.outpath, &env->outpath, NULL); - } - if (access(env->outpath, 0)) { - if (mkdir(env->outpath)) { - mpp_log("ERROR: create folder,%s \n", env->outpath); - } - } -} - - -/*! -*********************************************************************** -* \brief -* write log function -*********************************************************************** -*/ -void writelog(void *in_ctx, ...) -{ -#if __DEBUG_EN - RK_U32 line = 0; - char *levelname = NULL; - char *filename = NULL; - char argmsg[LOG_BUF_SIZE] = { 0 }; - LogCtx_t *ctx = (LogCtx_t *)in_ctx; - char *pfn = NULL, *pfn0 = NULL , *pfn1 = NULL; - va_list argptr; - va_start(argptr, in_ctx); - levelname = va_arg(argptr, char*); - filename = va_arg(argptr, char*); - line = va_arg(argptr, RK_U32); - vsnprintf(argmsg, sizeof(argmsg), va_arg(argptr, char*), argptr); - - pfn0 = strrchr(filename, '/'); - pfn1 = strrchr(filename, '\\'); - pfn = pfn0 ? (pfn0 + 1) : (pfn1 ? (pfn1 + 1) : filename); - if (ctx->flag->print_en) { - mpp_log("[%s] file: %s:%d, [%s], %s", ctx->tag, pfn, line, levelname, argmsg); - } - if (ctx->fp && ctx->flag->write_en) { - //fprintf(ctx->fp, "%s\n", argmsg); - fprintf(ctx->fp, "file: %s:%d, [%s], %s\n", pfn, line, levelname, argmsg); - //fprintf(ctx->fp, "[TAG=%s] file: %s:%d, [%s], %s", ctx->tag, pfn, line, levelname, argmsg); - fflush(ctx->fp); - } - va_end(argptr); -#endif -} - -/*! -*********************************************************************** -* \brief -* set bitread log context -*********************************************************************** -*/ -void set_bitread_logctx(BitReadCtx_t *bitctx, LogCtx_t *p_ctx) -{ - bitctx->ctx = p_ctx; - bitctx->wlog = log_info; -} - - - - - +/* +* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#define MODULE_TAG "" + +#include +#include +#include + +#include "mpp_log.h" +#include "mpp_env.h" +#include "mpp_mem.h" +#include "mpp_common.h" + +#include "h264d_log.h" + +#define LOG_BUF_SIZE 512 + +RK_U32 g_nalu_cnt0 = 0; +RK_U32 g_nalu_cnt1 = 0; +RK_S32 g_max_bytes = 0; +RK_U32 g_max_slice_data = 0; +FILE *g_debug_file0 = NULL; +FILE *g_debug_file1 = NULL; + +RK_U32 rkv_h264d_parse_debug = 0; +RK_U32 rkv_h264d_hal_debug = 0; + +const LogEnvStr_t logenv_name = { + "h264d_log_help", + "h264d_log_show", + "h264d_log_ctrl", + "h264d_log_level", + "h264d_log_outpath", + "h264d_log_cmppath", + "h264d_log_decframe", + "h264d_log_begframe", + "h264d_log_endframe", +}; + +const char *loglevel_name[LOG_LEVEL_MAX] = { + "SILENT", + "FATAL", + "ERROR", + "WARNNING", + "INFO", + "TRACE", +}; + +const char *logctrl_name[LOG_MAX] = { + "DEBUG_EN", + "FPGA_MODE", + "LOG_PRINT", + "LOG_WRITE", + "RUN_PAESE", + "RUN_HAL", + "READ_NALU", + "READ_SPS", + "READ_SUBSPS", + "READ_PPS", + "READ_SLICE", + "WRITE_SPSPPS", + "WRITE_RPS", + "WRITE_SCANLIST", + "WRITE_STEAM", + "WRITE_REG", +}; + +/*! +*********************************************************************** +* \brief +* rewrite log_info function which in mpp_bitread.c +*********************************************************************** +*/ +static void log_info(void *ctx, ...) +{ + char *fname = NULL; + RK_U32 line = 0; + char argbuf[LOG_BUF_SIZE] = { 0 }; + + if (LogEnable(ctx, LOG_LEVEL_INFO)) { + va_list argptr; + va_start(argptr, ctx); + fname = va_arg(argptr, char*); + line = va_arg(argptr, RK_U32); + vsnprintf(argbuf, sizeof(argbuf), va_arg(argptr, char*), argptr); + writelog(ctx, "syntax", fname, line, argbuf); + va_end(argptr); + } +} +/*! +*********************************************************************** +* \brief +* get log env +*********************************************************************** +*/ + +MPP_RET get_logenv(LogEnv_t *env) +{ + //!< read env + mpp_env_get_u32(logenv_name.help, &env->help, 0); + mpp_env_get_u32(logenv_name.show, &env->show, 0); + mpp_env_get_u32(logenv_name.ctrl, &env->ctrl, 0); + mpp_env_get_u32(logenv_name.level, &env->level, 0); + mpp_env_get_u32(logenv_name.decframe, &env->decframe, 0); + mpp_env_get_u32(logenv_name.begframe, &env->begframe, 0); + mpp_env_get_u32(logenv_name.endframe, &env->endframe, 0); + mpp_env_get_str(logenv_name.outpath, &env->outpath, NULL); + + return MPP_OK; +} + +/*! +*********************************************************************** +* \brief +* print env help +*********************************************************************** +*/ +void print_env_help(LogEnv_t *env) +{ + RK_U8 i = 0; + (void)env; + + mpp_log("--------------- h264d help -------------------- \n"); + mpp_log("h264d_log_help :[num] (0/1) show help content \n"); + mpp_log("h264d_log_show :[num] (0/1) show current log setting \n"); + mpp_log("h264d_log_outpath :[str] \n"); + mpp_log("h264d_log_decframe :[num] \n"); + mpp_log("h264d_log_begframe :[num] \n"); + mpp_log("h264d_log_endframe :[num] \n"); + mpp_log("h264d_log_level :[num] \n"); + for (i = 0; i < LOG_LEVEL_MAX; i++) { + mpp_log(" (%2d) -- %s \n", i, loglevel_name[i]); + } + mpp_log("h264d_log_ctrl :[32bit] \n"); + for (i = 0; i < LOG_MAX; i++) { + mpp_log(" (%2d)bit -- %s \n", i, logctrl_name[i]); + } + mpp_log("------------------------------------------------- \n"); +} +/*! +*********************************************************************** +* \brief +* show env flags +*********************************************************************** +*/ +void show_env_flags(LogEnv_t *env) +{ + RK_U8 i = 0; + mpp_log("------------- h264d debug setting ------------- \n"); + mpp_log("outputpath : %s \n", env->outpath); + mpp_log("DecodeFrame : %d \n", env->decframe); + mpp_log("LogBeginFrame : %d \n", env->begframe); + mpp_log("LogEndFrame : %d \n", env->endframe); + mpp_log("LogLevel : %s \n", loglevel_name[env->level]); + for (i = 0; i < LOG_MAX; i++) { + mpp_log("%s: %d (%d)\n", logctrl_name[i], GetBitVal(env->ctrl, i), i); + } + mpp_log("------------------------------------------------- \n"); +} +/*! +*********************************************************************** +* \brief +* explain log ctrl flag +*********************************************************************** +*/ +MPP_RET explain_ctrl_flag(RK_U32 ctrl_val, LogFlag_t *pflag) +{ + pflag->print_en = GetBitVal(ctrl_val, LOG_PRINT ); + pflag->write_en = GetBitVal(ctrl_val, LOG_WRITE ); + pflag->debug_en = GetBitVal(ctrl_val, LOG_DEBUG ) + || GetBitVal(ctrl_val, LOG_READ_NALU ) + || GetBitVal(ctrl_val, LOG_READ_SPS ) + || GetBitVal(ctrl_val, LOG_READ_SUBSPS ) + || GetBitVal(ctrl_val, LOG_READ_PPS ) + || GetBitVal(ctrl_val, LOG_READ_SLICE ) + || GetBitVal(ctrl_val, LOG_WRITE_SPSPPS ) + || GetBitVal(ctrl_val, LOG_WRITE_RPS ) + || GetBitVal(ctrl_val, LOG_WRITE_SCANLIST) + || GetBitVal(ctrl_val, LOG_WRITE_STEAM ) + || GetBitVal(ctrl_val, LOG_WRITE_REG ); + + return MPP_OK; +} +/*! +*********************************************************************** +* \brief +* set log outpath +*********************************************************************** +*/ +void set_log_outpath(LogEnv_t *env) +{ + if (NULL == env->outpath) { + mpp_env_set_str(logenv_name.outpath, "./h264d_log" ); + mpp_env_get_str(logenv_name.outpath, &env->outpath, NULL); + } + if (access(env->outpath, 0)) { + if (mkdir(env->outpath)) { + mpp_log("ERROR: create folder,%s \n", env->outpath); + } + } +} + + +/*! +*********************************************************************** +* \brief +* write log function +*********************************************************************** +*/ +void writelog(void *in_ctx, ...) +{ +#if __DEBUG_EN + RK_U32 line = 0; + char *levelname = NULL; + char *filename = NULL; + char argmsg[LOG_BUF_SIZE] = { 0 }; + LogCtx_t *ctx = (LogCtx_t *)in_ctx; + char *pfn = NULL, *pfn0 = NULL , *pfn1 = NULL; + va_list argptr; + va_start(argptr, in_ctx); + levelname = va_arg(argptr, char*); + filename = va_arg(argptr, char*); + line = va_arg(argptr, RK_U32); + vsnprintf(argmsg, sizeof(argmsg), va_arg(argptr, char*), argptr); + + pfn0 = strrchr(filename, '/'); + pfn1 = strrchr(filename, '\\'); + pfn = pfn0 ? (pfn0 + 1) : (pfn1 ? (pfn1 + 1) : filename); + if (ctx->flag->print_en) { + mpp_log("[%s] file: %s:%d, [%s], %s", ctx->tag, pfn, line, levelname, argmsg); + } + if (ctx->fp && ctx->flag->write_en) { + //fprintf(ctx->fp, "%s\n", argmsg); + fprintf(ctx->fp, "file: %s:%d, [%s], %s\n", pfn, line, levelname, argmsg); + //fprintf(ctx->fp, "[TAG=%s] file: %s:%d, [%s], %s", ctx->tag, pfn, line, levelname, argmsg); + fflush(ctx->fp); + } + va_end(argptr); +#endif +} + +/*! +*********************************************************************** +* \brief +* set bitread log context +*********************************************************************** +*/ +void set_bitread_logctx(BitReadCtx_t *bitctx, LogCtx_t *p_ctx) +{ + bitctx->ctx = p_ctx; + bitctx->wlog = log_info; +} + + + + + diff --git a/mpp/codec/dec/h264/h264d_parse.h b/mpp/codec/dec/h264/h264d_parse.h index 1e259525..fa77cb3e 100644 --- a/mpp/codec/dec/h264/h264d_parse.h +++ b/mpp/codec/dec/h264/h264d_parse.h @@ -1,45 +1,45 @@ -/* -* -* Copyright 2015 Rockchip Electronics Co. LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#ifndef __H264D_PARSE_H__ -#define __H264D_PARSE_H__ -#include "rk_type.h" -#include "mpp_err.h" - -#include "h264d_global.h" - - - -#ifdef __cplusplus -extern "C" { -#endif - -MPP_RET open_stream_file(H264dInputCtx_t *p_Inp, char *path); -MPP_RET fwrite_stream_to_file(H264dInputCtx_t *p_Inp, RK_U8 *pdata, RK_U32 len); -MPP_RET close_stream_file(H264dInputCtx_t *p_Inp); -MPP_RET parse_loop(H264_DecCtx_t *p_Dec); -MPP_RET parse_prepare(H264dInputCtx_t *p_Inp, H264dCurCtx_t *p_Cur); -MPP_RET parse_prepare_fast(H264dInputCtx_t *p_Inp, H264dCurCtx_t *p_Cur); -MPP_RET parse_prepare_extra_header(H264dInputCtx_t *p_Inp, H264dCurCtx_t *p_Cur); -MPP_RET parse_prepare_extra_data(H264dInputCtx_t *p_Inp, H264dCurCtx_t *p_Cur); - -#ifdef __cplusplus -} -#endif - - -#endif /* __H264D_PARSE_H__ */ +/* +* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef __H264D_PARSE_H__ +#define __H264D_PARSE_H__ +#include "rk_type.h" +#include "mpp_err.h" + +#include "h264d_global.h" + + + +#ifdef __cplusplus +extern "C" { +#endif + +MPP_RET open_stream_file(H264dInputCtx_t *p_Inp, char *path); +MPP_RET fwrite_stream_to_file(H264dInputCtx_t *p_Inp, RK_U8 *pdata, RK_U32 len); +MPP_RET close_stream_file(H264dInputCtx_t *p_Inp); +MPP_RET parse_loop(H264_DecCtx_t *p_Dec); +MPP_RET parse_prepare(H264dInputCtx_t *p_Inp, H264dCurCtx_t *p_Cur); +MPP_RET parse_prepare_fast(H264dInputCtx_t *p_Inp, H264dCurCtx_t *p_Cur); +MPP_RET parse_prepare_extra_header(H264dInputCtx_t *p_Inp, H264dCurCtx_t *p_Cur); +MPP_RET parse_prepare_extra_data(H264dInputCtx_t *p_Inp, H264dCurCtx_t *p_Cur); + +#ifdef __cplusplus +} +#endif + + +#endif /* __H264D_PARSE_H__ */ diff --git a/mpp/codec/dec/h264/h264d_pps.c b/mpp/codec/dec/h264/h264d_pps.c index 041a6384..bf5f2502 100644 --- a/mpp/codec/dec/h264/h264d_pps.c +++ b/mpp/codec/dec/h264/h264d_pps.c @@ -1,181 +1,181 @@ -/* -* -* Copyright 2015 Rockchip Electronics Co. LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#define MODULE_TAG "h264d_pps" - -#include - -#include "mpp_err.h" - -#include "h264d_log.h" -#include "h264d_pps.h" -#include "h264d_scalist.h" -#include "h264d_dpb.h" - -static void reset_curpps_data(H264_PPS_t *cur_pps) -{ - memset(cur_pps, 0, sizeof(H264_PPS_t)); - cur_pps->seq_parameter_set_id = 0; // reset - cur_pps->pic_parameter_set_id = 0; -} - -static MPP_RET parse_pps_calingLists(BitReadCtx_t *p_bitctx, H264_SPS_t *sps, H264_PPS_t *pps) -{ - RK_S32 i = 0; - MPP_RET ret = MPP_ERR_UNKNOW; - - for (i = 0; i < 6; ++i) { - READ_ONEBIT(p_bitctx, &pps->pic_scaling_list_present_flag[i], "pic_scaling_list_present_flag"); - - if (pps->pic_scaling_list_present_flag[i]) { - FUN_CHECK (ret = parse_scalingList(p_bitctx, H264ScalingList4x4Length, - pps->ScalingList4x4[i], &pps->UseDefaultScalingMatrix4x4Flag[i])); - } - } - if (pps->transform_8x8_mode_flag) { - for (i = 0; i < ((sps->chroma_format_idc != 3) ? 2 : 6); ++i) { - READ_ONEBIT(p_bitctx, &pps->pic_scaling_list_present_flag[i + 6], "pic_scaling_list_present_flag"); - if (pps->pic_scaling_list_present_flag[i + 6]) { - FUN_CHECK(ret = parse_scalingList(p_bitctx, H264ScalingList8x8Length, - pps->ScalingList8x8[i], &pps->UseDefaultScalingMatrix8x8Flag[i])); - } - } - } - - return ret = MPP_OK; -__BITREAD_ERR: - ret = p_bitctx->ret; -__FAILED: - return ret; -} - -static MPP_RET parser_pps(BitReadCtx_t *p_bitctx, H264_SPS_t *cur_sps, H264_PPS_t *cur_pps) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - - LogInfo(p_bitctx->ctx, "----------------------------- PPS begin --------------------------------"); - READ_UE(p_bitctx, &cur_pps->pic_parameter_set_id, "pic_parameter_set_id"); - READ_UE(p_bitctx, &cur_pps->seq_parameter_set_id, "seq_parameter_set_id"); - //VAL_CHECK(ret, cur_pps->seq_parameter_set_id < 32); - if (cur_pps->seq_parameter_set_id < 0 || cur_pps->seq_parameter_set_id > 32) { - cur_pps->seq_parameter_set_id = 0; - } - if (cur_pps->pic_parameter_set_id < 0 || cur_pps->pic_parameter_set_id > 256) { - cur_pps->pic_parameter_set_id = 0; - } - READ_ONEBIT(p_bitctx, &cur_pps->entropy_coding_mode_flag, "entropy_coding_mode_flag"); - READ_ONEBIT(p_bitctx, &cur_pps->bottom_field_pic_order_in_frame_present_flag, "bottom_field_pic_order_in_frame_present_flag"); - - READ_UE(p_bitctx, &cur_pps->num_slice_groups_minus1, "num_slice_groups_minus1"); - VAL_CHECK(ret, cur_pps->num_slice_groups_minus1 <= 1); - READ_UE(p_bitctx, &cur_pps->num_ref_idx_l0_default_active_minus1, "num_ref_idx_l0_default_active_minus1"); - VAL_CHECK(ret, cur_pps->num_ref_idx_l0_default_active_minus1 < 32); - READ_UE(p_bitctx, &cur_pps->num_ref_idx_l1_default_active_minus1, "num_ref_idx_l1_default_active_minus1"); - VAL_CHECK(ret, cur_pps->num_ref_idx_l1_default_active_minus1 < 32); - READ_ONEBIT(p_bitctx, &cur_pps->weighted_pred_flag, "weighted_pred_flag"); - READ_BITS(p_bitctx, 2, &cur_pps->weighted_bipred_idc, "weighted_bipred_idc"); - VAL_CHECK(ret, cur_pps->weighted_bipred_idc < 3); - READ_SE(p_bitctx, &cur_pps->pic_init_qp_minus26, "pic_init_qp_minus26"); - CHECK_RANGE(p_bitctx, cur_pps->pic_init_qp_minus26, -26, 25); - READ_SE(p_bitctx, &cur_pps->pic_init_qs_minus26, "pic_init_qs_minus26"); - CHECK_RANGE(p_bitctx, cur_pps->pic_init_qs_minus26, -26, 25); - READ_SE(p_bitctx, &cur_pps->chroma_qp_index_offset, "chroma_qp_index_offset"); - CHECK_RANGE(p_bitctx, cur_pps->chroma_qp_index_offset, -12, 12); - cur_pps->second_chroma_qp_index_offset = cur_pps->chroma_qp_index_offset; - READ_ONEBIT(p_bitctx, &cur_pps->deblocking_filter_control_present_flag, "deblocking_filter_control_present_flag"); - READ_ONEBIT(p_bitctx, &cur_pps->constrained_intra_pred_flag, "constrained_intra_pred_flag"); - READ_ONEBIT(p_bitctx, &cur_pps->redundant_pic_cnt_present_flag, "redundant_pic_cnt_present_flag"); - VAL_CHECK(ret , cur_pps->redundant_pic_cnt_present_flag == 0); - - if (mpp_has_more_rbsp_data(p_bitctx)) { - READ_ONEBIT(p_bitctx, &cur_pps->transform_8x8_mode_flag, "transform_8x8_mode_flag"); - READ_ONEBIT(p_bitctx, &cur_pps->pic_scaling_matrix_present_flag, "pic_scaling_matrix_present_flag"); - if (cur_pps->pic_scaling_matrix_present_flag) { - LogInfo(p_bitctx->ctx, "Picture scaling matrix present."); - FUN_CHECK(ret = parse_pps_calingLists(p_bitctx, cur_sps, cur_pps)); - } - READ_SE(p_bitctx, &cur_pps->second_chroma_qp_index_offset, "second_chroma_qp_index_offset"); - } else { - cur_pps->transform_8x8_mode_flag = 0; - cur_pps->second_chroma_qp_index_offset = cur_pps->chroma_qp_index_offset; - } - cur_pps->Valid = 1; - - return ret = MPP_OK; - -__BITREAD_ERR: - ret = p_bitctx->ret; -__FAILED: - - return ret; -} - - -/*! -*********************************************************************** -* \brief -* parser pps and process pps -*********************************************************************** -*/ -//extern "C" -MPP_RET process_pps(H264_SLICE_t *currSlice) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - H264dLogCtx_t *logctx = currSlice->logctx; - H264dCurCtx_t *p_Cur = currSlice->p_Cur; - BitReadCtx_t *p_bitctx = &p_Cur->bitctx; - H264_PPS_t *cur_pps = &p_Cur->pps; - - FunctionIn(logctx->parr[RUN_PARSE]); - reset_curpps_data(cur_pps);// reset - set_bitread_logctx(p_bitctx, logctx->parr[LOG_READ_PPS]); - FUN_CHECK(ret = parser_pps(p_bitctx, &p_Cur->sps, cur_pps)); - //!< MakePPSavailable - ASSERT(cur_pps->Valid == 1); - memcpy(&currSlice->p_Vid->ppsSet[cur_pps->pic_parameter_set_id], cur_pps, sizeof(H264_PPS_t)); - - FunctionOut(logctx->parr[RUN_PARSE]); - - return ret = MPP_OK; -__FAILED: - return ret; -} - -/*! -*********************************************************************** -* \brief -* prase sps and process sps -*********************************************************************** -*/ -//extern "C" -MPP_RET activate_pps(H264dVideoCtx_t *p_Vid, H264_PPS_t *pps) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - - INP_CHECK(ret, !p_Vid && !pps); - if (p_Vid->active_pps != pps) { - if (p_Vid->dec_pic) { - //!< return if the last picture has already been finished - FUN_CHECK(ret = exit_picture(p_Vid, &p_Vid->dec_pic)); - } - p_Vid->active_pps = pps; - } -__RETURN: - return ret = MPP_OK; -__FAILED: - return ret; -} +/* +* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#define MODULE_TAG "h264d_pps" + +#include + +#include "mpp_err.h" + +#include "h264d_log.h" +#include "h264d_pps.h" +#include "h264d_scalist.h" +#include "h264d_dpb.h" + +static void reset_curpps_data(H264_PPS_t *cur_pps) +{ + memset(cur_pps, 0, sizeof(H264_PPS_t)); + cur_pps->seq_parameter_set_id = 0; // reset + cur_pps->pic_parameter_set_id = 0; +} + +static MPP_RET parse_pps_calingLists(BitReadCtx_t *p_bitctx, H264_SPS_t *sps, H264_PPS_t *pps) +{ + RK_S32 i = 0; + MPP_RET ret = MPP_ERR_UNKNOW; + + for (i = 0; i < 6; ++i) { + READ_ONEBIT(p_bitctx, &pps->pic_scaling_list_present_flag[i], "pic_scaling_list_present_flag"); + + if (pps->pic_scaling_list_present_flag[i]) { + FUN_CHECK (ret = parse_scalingList(p_bitctx, H264ScalingList4x4Length, + pps->ScalingList4x4[i], &pps->UseDefaultScalingMatrix4x4Flag[i])); + } + } + if (pps->transform_8x8_mode_flag) { + for (i = 0; i < ((sps->chroma_format_idc != 3) ? 2 : 6); ++i) { + READ_ONEBIT(p_bitctx, &pps->pic_scaling_list_present_flag[i + 6], "pic_scaling_list_present_flag"); + if (pps->pic_scaling_list_present_flag[i + 6]) { + FUN_CHECK(ret = parse_scalingList(p_bitctx, H264ScalingList8x8Length, + pps->ScalingList8x8[i], &pps->UseDefaultScalingMatrix8x8Flag[i])); + } + } + } + + return ret = MPP_OK; +__BITREAD_ERR: + ret = p_bitctx->ret; +__FAILED: + return ret; +} + +static MPP_RET parser_pps(BitReadCtx_t *p_bitctx, H264_SPS_t *cur_sps, H264_PPS_t *cur_pps) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + + LogInfo(p_bitctx->ctx, "----------------------------- PPS begin --------------------------------"); + READ_UE(p_bitctx, &cur_pps->pic_parameter_set_id, "pic_parameter_set_id"); + READ_UE(p_bitctx, &cur_pps->seq_parameter_set_id, "seq_parameter_set_id"); + //VAL_CHECK(ret, cur_pps->seq_parameter_set_id < 32); + if (cur_pps->seq_parameter_set_id < 0 || cur_pps->seq_parameter_set_id > 32) { + cur_pps->seq_parameter_set_id = 0; + } + if (cur_pps->pic_parameter_set_id < 0 || cur_pps->pic_parameter_set_id > 256) { + cur_pps->pic_parameter_set_id = 0; + } + READ_ONEBIT(p_bitctx, &cur_pps->entropy_coding_mode_flag, "entropy_coding_mode_flag"); + READ_ONEBIT(p_bitctx, &cur_pps->bottom_field_pic_order_in_frame_present_flag, "bottom_field_pic_order_in_frame_present_flag"); + + READ_UE(p_bitctx, &cur_pps->num_slice_groups_minus1, "num_slice_groups_minus1"); + VAL_CHECK(ret, cur_pps->num_slice_groups_minus1 <= 1); + READ_UE(p_bitctx, &cur_pps->num_ref_idx_l0_default_active_minus1, "num_ref_idx_l0_default_active_minus1"); + VAL_CHECK(ret, cur_pps->num_ref_idx_l0_default_active_minus1 < 32); + READ_UE(p_bitctx, &cur_pps->num_ref_idx_l1_default_active_minus1, "num_ref_idx_l1_default_active_minus1"); + VAL_CHECK(ret, cur_pps->num_ref_idx_l1_default_active_minus1 < 32); + READ_ONEBIT(p_bitctx, &cur_pps->weighted_pred_flag, "weighted_pred_flag"); + READ_BITS(p_bitctx, 2, &cur_pps->weighted_bipred_idc, "weighted_bipred_idc"); + VAL_CHECK(ret, cur_pps->weighted_bipred_idc < 3); + READ_SE(p_bitctx, &cur_pps->pic_init_qp_minus26, "pic_init_qp_minus26"); + CHECK_RANGE(p_bitctx, cur_pps->pic_init_qp_minus26, -26, 25); + READ_SE(p_bitctx, &cur_pps->pic_init_qs_minus26, "pic_init_qs_minus26"); + CHECK_RANGE(p_bitctx, cur_pps->pic_init_qs_minus26, -26, 25); + READ_SE(p_bitctx, &cur_pps->chroma_qp_index_offset, "chroma_qp_index_offset"); + CHECK_RANGE(p_bitctx, cur_pps->chroma_qp_index_offset, -12, 12); + cur_pps->second_chroma_qp_index_offset = cur_pps->chroma_qp_index_offset; + READ_ONEBIT(p_bitctx, &cur_pps->deblocking_filter_control_present_flag, "deblocking_filter_control_present_flag"); + READ_ONEBIT(p_bitctx, &cur_pps->constrained_intra_pred_flag, "constrained_intra_pred_flag"); + READ_ONEBIT(p_bitctx, &cur_pps->redundant_pic_cnt_present_flag, "redundant_pic_cnt_present_flag"); + VAL_CHECK(ret , cur_pps->redundant_pic_cnt_present_flag == 0); + + if (mpp_has_more_rbsp_data(p_bitctx)) { + READ_ONEBIT(p_bitctx, &cur_pps->transform_8x8_mode_flag, "transform_8x8_mode_flag"); + READ_ONEBIT(p_bitctx, &cur_pps->pic_scaling_matrix_present_flag, "pic_scaling_matrix_present_flag"); + if (cur_pps->pic_scaling_matrix_present_flag) { + LogInfo(p_bitctx->ctx, "Picture scaling matrix present."); + FUN_CHECK(ret = parse_pps_calingLists(p_bitctx, cur_sps, cur_pps)); + } + READ_SE(p_bitctx, &cur_pps->second_chroma_qp_index_offset, "second_chroma_qp_index_offset"); + } else { + cur_pps->transform_8x8_mode_flag = 0; + cur_pps->second_chroma_qp_index_offset = cur_pps->chroma_qp_index_offset; + } + cur_pps->Valid = 1; + + return ret = MPP_OK; + +__BITREAD_ERR: + ret = p_bitctx->ret; +__FAILED: + + return ret; +} + + +/*! +*********************************************************************** +* \brief +* parser pps and process pps +*********************************************************************** +*/ +//extern "C" +MPP_RET process_pps(H264_SLICE_t *currSlice) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + H264dLogCtx_t *logctx = currSlice->logctx; + H264dCurCtx_t *p_Cur = currSlice->p_Cur; + BitReadCtx_t *p_bitctx = &p_Cur->bitctx; + H264_PPS_t *cur_pps = &p_Cur->pps; + + FunctionIn(logctx->parr[RUN_PARSE]); + reset_curpps_data(cur_pps);// reset + set_bitread_logctx(p_bitctx, logctx->parr[LOG_READ_PPS]); + FUN_CHECK(ret = parser_pps(p_bitctx, &p_Cur->sps, cur_pps)); + //!< MakePPSavailable + ASSERT(cur_pps->Valid == 1); + memcpy(&currSlice->p_Vid->ppsSet[cur_pps->pic_parameter_set_id], cur_pps, sizeof(H264_PPS_t)); + + FunctionOut(logctx->parr[RUN_PARSE]); + + return ret = MPP_OK; +__FAILED: + return ret; +} + +/*! +*********************************************************************** +* \brief +* prase sps and process sps +*********************************************************************** +*/ +//extern "C" +MPP_RET activate_pps(H264dVideoCtx_t *p_Vid, H264_PPS_t *pps) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + + INP_CHECK(ret, !p_Vid && !pps); + if (p_Vid->active_pps != pps) { + if (p_Vid->dec_pic) { + //!< return if the last picture has already been finished + FUN_CHECK(ret = exit_picture(p_Vid, &p_Vid->dec_pic)); + } + p_Vid->active_pps = pps; + } +__RETURN: + return ret = MPP_OK; +__FAILED: + return ret; +} diff --git a/mpp/codec/dec/h264/h264d_pps.h b/mpp/codec/dec/h264/h264d_pps.h index 4789254d..96c253a5 100644 --- a/mpp/codec/dec/h264/h264d_pps.h +++ b/mpp/codec/dec/h264/h264d_pps.h @@ -1,39 +1,39 @@ -/* -* -* Copyright 2015 Rockchip Electronics Co. LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#ifndef _H264D_PPS_H_ -#define _H264D_PPS_H_ - -#include "rk_type.h" -#include "mpp_err.h" -#include "h264d_global.h" - - -#ifdef __cplusplus -extern "C" { -#endif - -MPP_RET process_pps(H264_SLICE_t *currSlice); -MPP_RET activate_pps(H264dVideoCtx_t *p_Vid, H264_PPS_t *pps); - -#ifdef __cplusplus -} -#endif - -//======================================== -#endif /* end of _H264D_PPS_H_ */ - +/* +* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef _H264D_PPS_H_ +#define _H264D_PPS_H_ + +#include "rk_type.h" +#include "mpp_err.h" +#include "h264d_global.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +MPP_RET process_pps(H264_SLICE_t *currSlice); +MPP_RET activate_pps(H264dVideoCtx_t *p_Vid, H264_PPS_t *pps); + +#ifdef __cplusplus +} +#endif + +//======================================== +#endif /* end of _H264D_PPS_H_ */ + diff --git a/mpp/codec/dec/h264/h264d_rwfile.c b/mpp/codec/dec/h264/h264d_rwfile.c index 3bfa0cdf..51f6f1b4 100644 --- a/mpp/codec/dec/h264/h264d_rwfile.c +++ b/mpp/codec/dec/h264/h264d_rwfile.c @@ -1,811 +1,811 @@ -/* -* -* Copyright 2015 Rockchip Electronics Co. LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#define MODULE_TAG "h264d_rwfile" - -#include -#include -#include - -#include "mpp_log.h" -#include "mpp_packet.h" -#include "mpp_packet_impl.h" -#include "mpp_mem.h" -#include "mpp_env.h" -#include "h264d_log.h" -#include "h264d_rwfile.h" - - -#define MAX_STRING_SIZE 512 - -#define MAX_ITEMS_TO_PARSE 32 -#define START_PREFIX_3BYTE 3 -#define MAX_ITEMS_TO_PARSE 32 - -#define RKVDEC_REG_HEADER 0x48474552 -#define RKVDEC_PPS_HEADER 0x48535050 -#define RKVDEC_SCL_HEADER 0x534c4353 -#define RKVDEC_RPS_HEADER 0x48535052 -#define RKVDEC_CRC_HEADER 0x48435243 -#define RKVDEC_STM_HEADER 0x4d525453 -#define RKVDEC_ERR_HEADER 0x524f5245 - - -static const RK_U32 IOBUFSIZE = 16 * 1024 * 1024; //524288 -static const RK_U32 STMBUFSIZE = 16 * 1024 * 1024; //524288 - -RK_U32 rkv_h264d_test_debug = 0; -//!< values for nalu_type -typedef enum { - NALU_TYPE_NULL = 0, - NALU_TYPE_SLICE = 1, - NALU_TYPE_DPA = 2, - NALU_TYPE_DPB = 3, - NALU_TYPE_DPC = 4, - NALU_TYPE_IDR = 5, - NALU_TYPE_SEI = 6, - NALU_TYPE_SPS = 7, - NALU_TYPE_PPS = 8, - NALU_TYPE_AUD = 9, // Access Unit Delimiter - NALU_TYPE_EOSEQ = 10, // end of sequence - NALU_TYPE_EOSTREAM = 11, // end of stream - NALU_TYPE_FILL = 12, - NALU_TYPE_SPSEXT = 13, - NALU_TYPE_PREFIX = 14, // prefix - NALU_TYPE_SUB_SPS = 15, - NALU_TYPE_SLICE_AUX = 19, - NALU_TYPE_SLC_EXT = 20, // slice extensive - NALU_TYPE_VDRD = 24 // View and Dependency Representation Delimiter NAL Unit - -} Nalu_type; - - -typedef struct { - RK_U8 *data_; - RK_U32 bytes_left_; - RK_S64 curr_byte_; - RK_S32 num_remaining_bits_in_curr_byte_; - RK_S64 prev_two_bytes_; - RK_S64 emulation_prevention_bytes_; - RK_S32 used_bits; - RK_U8 *buf; - RK_S32 buf_len; -} GetBitCtx_t; - -typedef struct { - RK_U32 header; - RK_U8 *data; - RK_U32 len; - RK_S32 pps_id; -} TempDataCtx_t; - -static void display_input_cmd(RK_S32 argc, char *argv[]) -{ - RK_S32 nn = 0; - char *pnamecmd = NULL; - char strcmd[MAX_STRING_SIZE] = {0}; - - strcat(strcmd, "INPUT_CMD: "); - pnamecmd = strrchr(argv[0], '/'); - pnamecmd = pnamecmd ? pnamecmd : (strrchr(argv[0], '\\')) ; - pnamecmd = pnamecmd ? strcat(strcmd, pnamecmd + 1) : argv[0]; - for (nn = 0; nn < argc; nn++) { - strcat(strcmd, " "); - strcat(strcmd, argv[nn]); - } - mpp_log("%s \n", strcmd); -} - -static void print_help_message(char *cmd) -{ - mpp_err("##### Options"); - mpp_err(" -h/--help : prints help message."); - mpp_err(" --cmppath :[string] Set golden input file store directory."); - mpp_err(" --outpath :[string] Set driver output file store directory."); - mpp_err(" -r/--raw :[number] Set bitstream raw cfg, 0/1: slice long 2:slice short."); - mpp_err(" -c/--cfg :[file] Set configure file< such as, decoder.cfg>."); - mpp_err(" -i/--input :[file] Set input bitstream file."); - mpp_err(" -n/--num :[number] Set decoded frames."); - mpp_err("##### Examples of usage:"); - mpp_err(" %s -h", cmd); - mpp_err(" %s -c decoder.cfg", cmd); - mpp_err(" %s -i input.bin -n 10 ", cmd); -} - -static RK_U8 *get_config_file_content(char *fname) -{ - FILE *fp_cfg = NULL; - RK_U8 *pbuf = NULL; - RK_U32 filesize = 0; - - if (!(fp_cfg = fopen(fname, "r"))) { - mpp_log("Cannot open configuration file %s.", fname); - goto __FAILED; - } - - if (fseek(fp_cfg, 0, SEEK_END)) { - mpp_log("Cannot fseek in configuration file %s.", fname); - goto __FAILED; - } - - filesize = ftell(fp_cfg); - - if (filesize > 150000) { - mpp_log("\n Unreasonable Filesize %d reported by ftell for configuration file %s.", filesize, fname); - goto __FAILED; - } - if (fseek(fp_cfg, 0, SEEK_SET)) { - mpp_log("Cannot fseek in configuration file %s.", fname); - goto __FAILED; - } - - if (!(pbuf = mpp_malloc_size(RK_U8, filesize + 1))) { - mpp_log("Cannot malloc content buffer for file %s.", fname); - goto __FAILED; - } - filesize = (long)fread(pbuf, 1, filesize, fp_cfg); - pbuf[filesize] = '\0'; - - FCLOSE(fp_cfg); - - return pbuf; -__FAILED: - FCLOSE(fp_cfg); - - return NULL; -} - -static MPP_RET parse_content(InputParams *p_in, RK_U8 *p) -{ - RK_S32 i = 0, item = 0; - RK_S32 InString = 0, InItem = 0; - RK_U8 *bufend = NULL; - RK_U8 *items[MAX_ITEMS_TO_PARSE] = { NULL }; - - //==== parsing - bufend = &p[strlen((const char *)p)]; - while (p < bufend) { - switch (*p) { - case 13: - ++p; - break; - case '#': // Found comment - *p = '\0'; // Replace '#' with '\0' in case of comment immediately following integer or string - while (*p != '\n' && p < bufend) // Skip till EOL or EOF, whichever comes first - ++p; - InString = 0; - InItem = 0; - break; - case '\n': - InItem = 0; - InString = 0; - *p++ = '\0'; - break; - case ' ': - case '\t': // Skip whitespace, leave state unchanged - if (InString) - p++; - else { - // Terminate non-strings once whitespace is found - *p++ = '\0'; - InItem = 0; - } - break; - - case '"': // Begin/End of String - *p++ = '\0'; - if (!InString) { - items[item++] = p; - InItem = ~InItem; - } else - InItem = 0; - InString = ~InString; // Toggle - break; - - default: - if (!InItem) { - items[item++] = p; - InItem = ~InItem; - } - p++; - } - } - item--; - //===== read syntax - for (i = 0; i < item; i += 3) { - if (!strncmp((const char*)items[i], "InputFile", 9)) { - strncpy((char *)p_in->infile_name, (const char*)items[i + 2], strlen((const char*)items[i + 2]) + 1); - } else if (!strncmp((const char*)items[i], "GoldenDataPath", 14)) { - strncpy((char *)p_in->cmp_path_dir, (const char*)items[i + 2], strlen((const char*)items[i + 2]) + 1); - } else if (!strncmp((const char*)items[i], "OutputDataPath", 14)) { - strncpy((char *)p_in->out_path_dir, (const char*)items[i + 2], strlen((const char*)items[i + 2]) + 1); - } else if (!strncmp((const char*)items[i], "DecodedFrames", 13)) { - if (!sscanf((const char*)items[i + 2], "%d", &p_in->iDecFrmNum)) { - goto __FAILED; - } - } else if (!strncmp((const char*)items[i], "BitStrmRawCfg", 13)) { - if (!sscanf((const char*)items[i + 2], "%d", &p_in->raw_cfg)) { - goto __FAILED; - } - } - } - - return MPP_OK; -__FAILED: - return MPP_NOK; -} - -static MPP_RET parse_command(InputParams *p_in, int ac, char *av[]) -{ - RK_S32 CLcount = 0; - RK_U8 *content = NULL; - char *pnamecmd = NULL; - RK_U8 have_cfg_flag = 0; - - CLcount = 1; - while (CLcount < ac) { - if (!strncmp(av[1], "-h", 2) || !strncmp(av[1], "--help", 6)) { - pnamecmd = strrchr(av[0], '/'); - pnamecmd = pnamecmd ? pnamecmd : strrchr(av[0], '\\'); - pnamecmd = pnamecmd ? (pnamecmd + 1) : av[0]; - print_help_message(pnamecmd); - goto __FAILED; - } else if (!strncmp(av[CLcount], "-n", 2) || !strncmp(av[1], "--num", 5)) { // decoded frames - if (!sscanf(av[CLcount + 1], "%d", &p_in->iDecFrmNum)) { - goto __FAILED; - } - CLcount += 2; - } else if (!strncmp(av[CLcount], "-i", 2) || !strncmp(av[1], "--input", 7)) { - strncpy(p_in->infile_name, av[CLcount + 1], strlen((const char*)av[CLcount + 1]) + 1); - CLcount += 2; - } else if (!strncmp(av[CLcount], "--cmppath", 9)) { // compare direct path - strncpy(p_in->cmp_path_dir, av[CLcount + 1], strlen((const char*)av[CLcount + 1]) + 1); - CLcount += 2; - } else if (!strncmp(av[CLcount], "--outpath", 9)) { // compare direct path - strncpy(p_in->out_path_dir, av[CLcount + 1], strlen((const char*)av[CLcount + 1]) + 1); - CLcount += 2; - } else if (!strncmp(av[1], "-r", 2) || !strncmp(av[CLcount], "--raw", 5)) { - if (!sscanf(av[CLcount + 1], "%d", &p_in->raw_cfg)) { - goto __FAILED; - } - CLcount += 2; - } else if (!strncmp(av[1], "-c", 2) || !strncmp(av[CLcount], "--cfg", 5)) { // configure file - strncpy(p_in->cfgfile_name, av[CLcount + 1], FILE_NAME_SIZE); - CLcount += 2; - have_cfg_flag = 1; - } else { - mpp_log("Error: %s cannot explain command! \n", av[CLcount]); - goto __FAILED; - } - } - if (have_cfg_flag) { - if (!(content = get_config_file_content(p_in->cfgfile_name))) { - goto __FAILED; - } - if (parse_content(p_in, content)) { - goto __FAILED; - } - MPP_FREE(content); - } - - return MPP_OK; -__FAILED: - - return MPP_NOK; -} - -static FILE *open_file(char *path, char *infile, char *sufix, const char *mode) -{ - char *pnamecmd = NULL; - char tmp_fname[FILE_NAME_SIZE] = { 0 }; - - pnamecmd = strrchr(infile, '/'); - pnamecmd = pnamecmd ? pnamecmd : strrchr(infile, '\\'); - pnamecmd = pnamecmd ? (pnamecmd + 1) : infile; - - - sprintf(tmp_fname, "%s/%s%s", path, pnamecmd, sufix); - - return fopen(tmp_fname, mode); -} - -static MPP_RET update_curr_byte(GetBitCtx_t *pStrmData) -{ - if (pStrmData->bytes_left_ < 1) - return MPP_NOK; - - // Emulation prevention three-byte detection. - // If a sequence of 0x000003 is found, skip (ignore) the last byte (0x03). - if (*pStrmData->data_ == 0x03 && (pStrmData->prev_two_bytes_ & 0xffff) == 0) { - // Detected 0x000003, skip last byte. - ++pStrmData->data_; - --pStrmData->bytes_left_; - ++pStrmData->emulation_prevention_bytes_; - // Need another full three bytes before we can detect the sequence again. - pStrmData->prev_two_bytes_ = 0xffff; - - if (pStrmData->bytes_left_ < 1) - return MPP_NOK; - } - - // Load a new byte and advance pointers. - pStrmData->curr_byte_ = *pStrmData->data_++ & 0xff; - --pStrmData->bytes_left_; - pStrmData->num_remaining_bits_in_curr_byte_ = 8; - - pStrmData->prev_two_bytes_ = (pStrmData->prev_two_bytes_ << 8) | pStrmData->curr_byte_; - - return MPP_OK; -} - -// Read |num_bits| (1 to 31 inclusive) from the stream and return them -// in |out|, with first bit in the stream as MSB in |out| at position -// (|num_bits| - 1). -static MPP_RET read_bits(GetBitCtx_t *pStrmData, RK_S32 num_bits, RK_S32 *out) -{ - RK_S32 bits_left = num_bits; - *out = 0; - ASSERT(num_bits <= 31); - - while (pStrmData->num_remaining_bits_in_curr_byte_ < bits_left) { - // Take all that's left in current byte, shift to make space for the rest. - *out |= (pStrmData->curr_byte_ << (bits_left - pStrmData->num_remaining_bits_in_curr_byte_)); - bits_left -= pStrmData->num_remaining_bits_in_curr_byte_; - - if (update_curr_byte(pStrmData)) { - return MPP_NOK; - } - } - - *out |= (pStrmData->curr_byte_ >> (pStrmData->num_remaining_bits_in_curr_byte_ - bits_left)); - *out &= ((1 << num_bits) - 1); - pStrmData->num_remaining_bits_in_curr_byte_ -= bits_left; - pStrmData->used_bits += num_bits; - - return MPP_OK; -} - -static MPP_RET read_ue(GetBitCtx_t *pStrmData, RK_U32 *val) -{ - RK_S32 num_bits = -1; - RK_S32 bit; - RK_S32 rest; - // Count the number of contiguous zero bits. - do { - if (read_bits(pStrmData, 1, &bit)) { - return MPP_NOK; - } - num_bits++; - } while (bit == 0); - - if (num_bits > 31) { - return MPP_NOK; - } - // Calculate exp-Golomb code value of size num_bits. - *val = (1 << num_bits) - 1; - - if (num_bits > 0) { - if (read_bits(pStrmData, num_bits, &rest)) { - return MPP_NOK; - } - *val += rest; - } - - return MPP_OK; -} - -static void set_streamdata(GetBitCtx_t *pStrmData, RK_U8 *data, RK_S32 size) -{ - memset(pStrmData, 0, sizeof(GetBitCtx_t)); - pStrmData->data_ = data; - pStrmData->bytes_left_ = size; - pStrmData->num_remaining_bits_in_curr_byte_ = 0; - // Initially set to 0xffff to accept all initial two-byte sequences. - pStrmData->prev_two_bytes_ = 0xffff; - pStrmData->emulation_prevention_bytes_ = 0; - // add - pStrmData->buf = data; - pStrmData->buf_len = size; - pStrmData->used_bits = 0; -} - - -static void write_nalu_prefix(InputParams *p_in) -{ - if (p_in->IO.pfxbytes > START_PREFIX_3BYTE) { - p_in->strm.pbuf[p_in->strm.strmbytes++] = 0x00; - } - p_in->strm.pbuf[p_in->strm.strmbytes++] = 0x00; - p_in->strm.pbuf[p_in->strm.strmbytes++] = 0x00; - p_in->strm.pbuf[p_in->strm.strmbytes++] = 0x01; -} - -static RK_U8 read_one_byte(InputParams *p_in) -{ - RK_U8 data = 0; - - if (0 == fread(&data, 1, 1, p_in->fp_bitstream)) { - p_in->is_eof = 1; - } - - return data; -} - -static void find_next_nalu(InputParams *p_in) -{ - RK_U8 startcode_had_find = 0; - //-- first read three bytes - if (p_in->is_fist_nalu) { - p_in->IO.pbuf[p_in->IO.offset] = read_one_byte(p_in); - p_in->IO.pbuf[p_in->IO.offset + 1] = read_one_byte(p_in); - p_in->IO.pbuf[p_in->IO.offset + 2] = read_one_byte(p_in); - p_in->is_fist_nalu = 0; - } - do { - if (startcode_had_find) { - p_in->IO.nalubytes++; - } - //--- find 0x000001 - if ((p_in->IO.pbuf[p_in->IO.offset] == 0x00) - && (p_in->IO.pbuf[p_in->IO.offset + 1] == 0x00) - && (p_in->IO.pbuf[p_in->IO.offset + 2] == 0x01)) { - if (startcode_had_find) { //-- end_code - p_in->IO.nalubytes -= START_PREFIX_3BYTE; - if (p_in->IO.pbuf[p_in->IO.offset - 1] == 0x00) { - p_in->IO.pbuf[0] = 0x00; - p_in->IO.nalubytes--; - } else { - p_in->IO.pbuf[0] = 0xFF; - } - p_in->IO.pbuf[1] = 0x00; - p_in->IO.pbuf[2] = 0x00; - p_in->IO.pbuf[3] = 0x01; - p_in->IO.offset = 1; - break; - } else { //-- find strart_code - startcode_had_find = 1; - p_in->IO.nalubytes = 0; - p_in->IO.pfxbytes = START_PREFIX_3BYTE; - p_in->IO.pNALU = &p_in->IO.pbuf[p_in->IO.offset + START_PREFIX_3BYTE]; - if (p_in->IO.offset && (p_in->IO.pbuf[p_in->IO.offset - 1] == 0x00)) { - p_in->IO.pfxbytes++; - } - } - } - p_in->IO.offset++; - p_in->IO.pbuf[p_in->IO.offset + 2] = read_one_byte(p_in); - } while (!p_in->is_eof); -} -RK_U32 g_nalu_cnt2 = 0; -static MPP_RET read_next_nalu(InputParams *p_in) -{ - RK_S32 forbidden_bit = -1; - RK_S32 nal_reference_idc = -1; - RK_S32 nalu_type = -1; - RK_S32 nalu_header_bytes = -1; - RK_U32 first_mb_in_slice = -1; - RK_S32 svc_extension_flag = -1; - - GetBitCtx_t *pStrmData = (GetBitCtx_t *)p_in->bitctx; - memset(pStrmData, 0, sizeof(GetBitCtx_t)); - set_streamdata(pStrmData, p_in->IO.pNALU, 4); - read_bits( pStrmData, 1, &forbidden_bit); - ASSERT(forbidden_bit == 0); - read_bits( pStrmData, 2, &nal_reference_idc); - read_bits( pStrmData, 5, &nalu_type); - - nalu_header_bytes = 1; - if ((nalu_type == NALU_TYPE_PREFIX) || (nalu_type == NALU_TYPE_SLC_EXT)) { - read_bits(pStrmData, 1, &svc_extension_flag); - if (!svc_extension_flag && nalu_type == NALU_TYPE_SLC_EXT) {//!< MVC - nalu_type = NALU_TYPE_SLICE; - } - nalu_header_bytes += 3; - } - //-- parse slice - if ( nalu_type == NALU_TYPE_SLICE || nalu_type == NALU_TYPE_IDR) { - set_streamdata(pStrmData, (p_in->IO.pNALU + nalu_header_bytes), 4); // reset - read_ue(pStrmData, &first_mb_in_slice); - if (!p_in->is_fist_frame && (first_mb_in_slice == 0)) { - p_in->is_new_frame = 1; - } - p_in->is_fist_frame = 0; - } - if (!p_in->is_new_frame) { - write_nalu_prefix(p_in); - memcpy(&p_in->strm.pbuf[p_in->strm.strmbytes], p_in->IO.pNALU, p_in->IO.nalubytes); - p_in->strm.strmbytes += p_in->IO.nalubytes; - } - - return MPP_OK; -} - -static void reset_tmpdata_ctx(TempDataCtx_t *tmp) -{ - tmp->header = 0; - tmp->len = 0; - tmp->pps_id = 0; -} - - -static void read_golden_data(FILE *fp, TempDataCtx_t *tmpctx, RK_U32 frame_no) -{ - RK_U32 header = 0, datasize = 0; - - reset_tmpdata_ctx(tmpctx); - fread(&header, 1, sizeof(RK_U32), fp); - fread(&datasize, 1, sizeof(RK_U32), fp); - while (!feof(fp)) { - switch (header) { - case RKVDEC_PPS_HEADER: - tmpctx->pps_id = datasize >> 16; - datasize = datasize & 0xffff; - case RKVDEC_SCL_HEADER: - case RKVDEC_RPS_HEADER: - case RKVDEC_STM_HEADER: - fseek(fp, datasize, SEEK_CUR); - break; - case RKVDEC_REG_HEADER: - fseek(fp, datasize, SEEK_CUR); - goto __RETURN; - break; - case RKVDEC_CRC_HEADER: - fread(tmpctx->data, sizeof(RK_U8), datasize, fp); - tmpctx->len = datasize; - break; - case RKVDEC_ERR_HEADER: - break; - default: - mpp_log("ERROR: frame_no=%d. \n", frame_no); - ASSERT(0); - break; - } - fread(&header, 1, sizeof(RK_U32), fp); - fread(&datasize, 1, sizeof(RK_U32), fp); - } -__RETURN: - return; -} - -static void write_bytes(FILE *fp_in, TempDataCtx_t *tmpctx, FILE *fp_out) -{ - RK_U32 i = 0; - RK_U8 temp = 0; - RK_U32 data_temp = 0; - data_temp = (tmpctx->pps_id << 16) | tmpctx->len; - - fwrite(&tmpctx->header, sizeof(RK_U32), 1, fp_out); - fwrite(&data_temp, sizeof(RK_U32), 1, fp_out); - while (i < tmpctx->len) { - fread (&temp, sizeof(RK_U8), 1, fp_in); - fwrite(&temp, sizeof(RK_U8), 1, fp_out); - i++; - } -} - - -static void write_driver_bytes(FILE *fp_out, TempDataCtx_t *in_tmpctx, FILE *fp_in, RK_U32 frame_no) -{ - RK_U32 header = 0, datasize = 0; - TempDataCtx_t m_tmpctx = { 0 }; - - fread(&header, 1, sizeof(RK_U32), fp_in); - fread(&datasize, 1, sizeof(RK_U32), fp_in); - - while (!feof(fp_in)) { - memset(&m_tmpctx, 0, sizeof(TempDataCtx_t)); - switch (header) { - case RKVDEC_PPS_HEADER: - m_tmpctx.pps_id = in_tmpctx->pps_id; - case RKVDEC_SCL_HEADER: - case RKVDEC_RPS_HEADER: - case RKVDEC_STM_HEADER: - m_tmpctx.header = header; - m_tmpctx.len = datasize; - write_bytes(fp_in, &m_tmpctx, fp_out); - break; - case RKVDEC_REG_HEADER: - m_tmpctx.header = header; - m_tmpctx.len = datasize; - header = RKVDEC_CRC_HEADER; - fwrite(&header, sizeof(RK_U32), 1, fp_out); - fwrite(&in_tmpctx->len, sizeof(RK_U32), 1, fp_out); - fwrite(in_tmpctx->data, sizeof(RK_U8), in_tmpctx->len, fp_out); - write_bytes(fp_in, &m_tmpctx, fp_out); - return; - default: - mpp_log("ERROR: frame_no=%d. \n", frame_no); - ASSERT(0); - break; - } - fread(&header, 1, sizeof(RK_U32), fp_in); - fread(&datasize, 1, sizeof(RK_U32), fp_in); - } -} - - -/*! -*********************************************************************** -* \brief -* configure function to analyze command or configure file -*********************************************************************** -*/ -MPP_RET h264d_configure(InputParams *p_in, RK_S32 ac, char *av[]) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - VAL_CHECK(ret, ac > 1); - display_input_cmd(ac, av); - FUN_CHECK (ret = parse_command(p_in, ac, av)); - - return MPP_OK; -__FAILED: - return ret; -} - - -/*! -*********************************************************************** -* \brief -* close file -*********************************************************************** -*/ -MPP_RET h264d_close_files(InputParams *p_in) -{ - FCLOSE(p_in->fp_bitstream); - FCLOSE(p_in->fp_golden_data); - FCLOSE(p_in->fp_yuv_data); - FCLOSE(p_in->fp_driver_data); - - return MPP_OK; -} - -/*! -*********************************************************************** -* \brief -* open file -*********************************************************************** -*/ -MPP_RET h264d_open_files(InputParams *p_in) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - char *outpath_dir = NULL; - mpp_env_get_str(logenv_name.outpath, &outpath_dir, NULL); - FLE_CHECK(ret, p_in->fp_bitstream = fopen(p_in->infile_name, "rb")); - p_in->fp_yuv_data = open_file(outpath_dir, p_in->infile_name, ".yuv", "wb"); - return MPP_OK; -__FAILED: - h264d_close_files(p_in); - - return ret; -} - -/*! -*********************************************************************** -* \brief -* free frame buffer -*********************************************************************** -*/ - -MPP_RET h264d_free_frame_buffer(InputParams *p_in) -{ - if (p_in) { - MPP_FREE(p_in->IO.pbuf); - MPP_FREE(p_in->bitctx); - MPP_FREE(p_in->strm.pbuf); - } - - return MPP_NOK; -} -/*! -*********************************************************************** -* \brief -* alloc frame buffer -*********************************************************************** -*/ -MPP_RET h264d_alloc_frame_buffer(InputParams *p_in) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - - p_in->IO.pbuf = mpp_malloc_size(RK_U8, IOBUFSIZE); - p_in->strm.pbuf = mpp_malloc_size(RK_U8, STMBUFSIZE); - p_in->bitctx = mpp_malloc_size(void, sizeof(GetBitCtx_t)); - MEM_CHECK(ret, p_in->IO.pbuf && p_in->strm.pbuf && p_in->bitctx); - p_in->is_fist_nalu = 1; - p_in->is_fist_frame = 1; - - return MPP_OK; -__FAILED: - return ret; -} - - -/*! -*********************************************************************** -* \brief -* read one frame -*********************************************************************** -*/ -MPP_RET h264d_read_one_frame(InputParams *p_in) -{ - p_in->strm.strmbytes = 0; - p_in->is_new_frame = 0; - //-- copy first nalu - if (!p_in->is_fist_frame) { - write_nalu_prefix(p_in); - memcpy(&p_in->strm.pbuf[p_in->strm.strmbytes], p_in->IO.pNALU, p_in->IO.nalubytes); - p_in->strm.strmbytes += p_in->IO.nalubytes; - } - //-- read one nalu and copy to stream buffer - do { - find_next_nalu(p_in); - read_next_nalu(p_in); - } while (!p_in->is_new_frame && !p_in->is_eof); - //if (first_mb_in_slice == 0) { - //FPRINT(g_debug_file0, "--- new frame ---- \n"); - //} - - return MPP_OK; -} -/*! -*********************************************************************** -* \brief -* write fpage data to file -*********************************************************************** -*/ -MPP_RET h264d_write_fpga_data(InputParams *p_in) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - TempDataCtx_t tmpctx = { 0 }; - FILE *fp_log = NULL; - RK_U32 frame_no = 0; - RK_U32 ctrl_value = 0; - RK_U32 ctrl_debug = 0; - RK_U32 ctrl_fpga = 0; - RK_U32 ctrl_write = 0; - char *outpath_dir = NULL; - char *cmppath_dir = NULL; - - mpp_env_get_u32(logenv_name.ctrl, &ctrl_value, 0); - ctrl_debug = GetBitVal(ctrl_value, LOG_DEBUG); - ctrl_fpga = GetBitVal(ctrl_value, LOG_FPGA); - ctrl_write = GetBitVal(ctrl_value, LOG_WRITE); - INP_CHECK(ret, !(ctrl_debug && ctrl_fpga && ctrl_write)); - mpp_env_get_str(logenv_name.outpath, &outpath_dir, NULL); - mpp_env_get_str(logenv_name.cmppath, &cmppath_dir, NULL); - p_in->fp_driver_data = open_file(outpath_dir, p_in->infile_name, ".dat", "wb"); - p_in->fp_golden_data = open_file(cmppath_dir, p_in->infile_name, ".dat", "rb"); - fp_log = fopen(strcat(outpath_dir, "/h264d_driver_data.dat"), "rb"); - FLE_CHECK(ret, p_in->fp_golden_data); - FLE_CHECK(ret, p_in->fp_driver_data); - FLE_CHECK(ret, p_in->fp_yuv_data); - FLE_CHECK(ret, fp_log); - tmpctx.data = mpp_calloc_size(RK_U8, 128); - MEM_CHECK(ret, tmpctx.data); //!< for read golden fpga data - while (!feof(p_in->fp_golden_data) && !feof(fp_log)) { - read_golden_data (p_in->fp_golden_data, &tmpctx, frame_no); - write_driver_bytes(p_in->fp_driver_data, &tmpctx, fp_log, frame_no); - frame_no++; - } - //remove(out_name); -__RETURN: - ret = MPP_OK; -__FAILED: - MPP_FREE(tmpctx.data); - h264d_close_files(p_in); - - return ret; -} +/* +* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#define MODULE_TAG "h264d_rwfile" + +#include +#include +#include + +#include "mpp_log.h" +#include "mpp_packet.h" +#include "mpp_packet_impl.h" +#include "mpp_mem.h" +#include "mpp_env.h" +#include "h264d_log.h" +#include "h264d_rwfile.h" + + +#define MAX_STRING_SIZE 512 + +#define MAX_ITEMS_TO_PARSE 32 +#define START_PREFIX_3BYTE 3 +#define MAX_ITEMS_TO_PARSE 32 + +#define RKVDEC_REG_HEADER 0x48474552 +#define RKVDEC_PPS_HEADER 0x48535050 +#define RKVDEC_SCL_HEADER 0x534c4353 +#define RKVDEC_RPS_HEADER 0x48535052 +#define RKVDEC_CRC_HEADER 0x48435243 +#define RKVDEC_STM_HEADER 0x4d525453 +#define RKVDEC_ERR_HEADER 0x524f5245 + + +static const RK_U32 IOBUFSIZE = 16 * 1024 * 1024; //524288 +static const RK_U32 STMBUFSIZE = 16 * 1024 * 1024; //524288 + +RK_U32 rkv_h264d_test_debug = 0; +//!< values for nalu_type +typedef enum { + NALU_TYPE_NULL = 0, + NALU_TYPE_SLICE = 1, + NALU_TYPE_DPA = 2, + NALU_TYPE_DPB = 3, + NALU_TYPE_DPC = 4, + NALU_TYPE_IDR = 5, + NALU_TYPE_SEI = 6, + NALU_TYPE_SPS = 7, + NALU_TYPE_PPS = 8, + NALU_TYPE_AUD = 9, // Access Unit Delimiter + NALU_TYPE_EOSEQ = 10, // end of sequence + NALU_TYPE_EOSTREAM = 11, // end of stream + NALU_TYPE_FILL = 12, + NALU_TYPE_SPSEXT = 13, + NALU_TYPE_PREFIX = 14, // prefix + NALU_TYPE_SUB_SPS = 15, + NALU_TYPE_SLICE_AUX = 19, + NALU_TYPE_SLC_EXT = 20, // slice extensive + NALU_TYPE_VDRD = 24 // View and Dependency Representation Delimiter NAL Unit + +} Nalu_type; + + +typedef struct { + RK_U8 *data_; + RK_U32 bytes_left_; + RK_S64 curr_byte_; + RK_S32 num_remaining_bits_in_curr_byte_; + RK_S64 prev_two_bytes_; + RK_S64 emulation_prevention_bytes_; + RK_S32 used_bits; + RK_U8 *buf; + RK_S32 buf_len; +} GetBitCtx_t; + +typedef struct { + RK_U32 header; + RK_U8 *data; + RK_U32 len; + RK_S32 pps_id; +} TempDataCtx_t; + +static void display_input_cmd(RK_S32 argc, char *argv[]) +{ + RK_S32 nn = 0; + char *pnamecmd = NULL; + char strcmd[MAX_STRING_SIZE] = {0}; + + strcat(strcmd, "INPUT_CMD: "); + pnamecmd = strrchr(argv[0], '/'); + pnamecmd = pnamecmd ? pnamecmd : (strrchr(argv[0], '\\')) ; + pnamecmd = pnamecmd ? strcat(strcmd, pnamecmd + 1) : argv[0]; + for (nn = 0; nn < argc; nn++) { + strcat(strcmd, " "); + strcat(strcmd, argv[nn]); + } + mpp_log("%s \n", strcmd); +} + +static void print_help_message(char *cmd) +{ + mpp_err("##### Options"); + mpp_err(" -h/--help : prints help message."); + mpp_err(" --cmppath :[string] Set golden input file store directory."); + mpp_err(" --outpath :[string] Set driver output file store directory."); + mpp_err(" -r/--raw :[number] Set bitstream raw cfg, 0/1: slice long 2:slice short."); + mpp_err(" -c/--cfg :[file] Set configure file< such as, decoder.cfg>."); + mpp_err(" -i/--input :[file] Set input bitstream file."); + mpp_err(" -n/--num :[number] Set decoded frames."); + mpp_err("##### Examples of usage:"); + mpp_err(" %s -h", cmd); + mpp_err(" %s -c decoder.cfg", cmd); + mpp_err(" %s -i input.bin -n 10 ", cmd); +} + +static RK_U8 *get_config_file_content(char *fname) +{ + FILE *fp_cfg = NULL; + RK_U8 *pbuf = NULL; + RK_U32 filesize = 0; + + if (!(fp_cfg = fopen(fname, "r"))) { + mpp_log("Cannot open configuration file %s.", fname); + goto __FAILED; + } + + if (fseek(fp_cfg, 0, SEEK_END)) { + mpp_log("Cannot fseek in configuration file %s.", fname); + goto __FAILED; + } + + filesize = ftell(fp_cfg); + + if (filesize > 150000) { + mpp_log("\n Unreasonable Filesize %d reported by ftell for configuration file %s.", filesize, fname); + goto __FAILED; + } + if (fseek(fp_cfg, 0, SEEK_SET)) { + mpp_log("Cannot fseek in configuration file %s.", fname); + goto __FAILED; + } + + if (!(pbuf = mpp_malloc_size(RK_U8, filesize + 1))) { + mpp_log("Cannot malloc content buffer for file %s.", fname); + goto __FAILED; + } + filesize = (long)fread(pbuf, 1, filesize, fp_cfg); + pbuf[filesize] = '\0'; + + FCLOSE(fp_cfg); + + return pbuf; +__FAILED: + FCLOSE(fp_cfg); + + return NULL; +} + +static MPP_RET parse_content(InputParams *p_in, RK_U8 *p) +{ + RK_S32 i = 0, item = 0; + RK_S32 InString = 0, InItem = 0; + RK_U8 *bufend = NULL; + RK_U8 *items[MAX_ITEMS_TO_PARSE] = { NULL }; + + //==== parsing + bufend = &p[strlen((const char *)p)]; + while (p < bufend) { + switch (*p) { + case 13: + ++p; + break; + case '#': // Found comment + *p = '\0'; // Replace '#' with '\0' in case of comment immediately following integer or string + while (*p != '\n' && p < bufend) // Skip till EOL or EOF, whichever comes first + ++p; + InString = 0; + InItem = 0; + break; + case '\n': + InItem = 0; + InString = 0; + *p++ = '\0'; + break; + case ' ': + case '\t': // Skip whitespace, leave state unchanged + if (InString) + p++; + else { + // Terminate non-strings once whitespace is found + *p++ = '\0'; + InItem = 0; + } + break; + + case '"': // Begin/End of String + *p++ = '\0'; + if (!InString) { + items[item++] = p; + InItem = ~InItem; + } else + InItem = 0; + InString = ~InString; // Toggle + break; + + default: + if (!InItem) { + items[item++] = p; + InItem = ~InItem; + } + p++; + } + } + item--; + //===== read syntax + for (i = 0; i < item; i += 3) { + if (!strncmp((const char*)items[i], "InputFile", 9)) { + strncpy((char *)p_in->infile_name, (const char*)items[i + 2], strlen((const char*)items[i + 2]) + 1); + } else if (!strncmp((const char*)items[i], "GoldenDataPath", 14)) { + strncpy((char *)p_in->cmp_path_dir, (const char*)items[i + 2], strlen((const char*)items[i + 2]) + 1); + } else if (!strncmp((const char*)items[i], "OutputDataPath", 14)) { + strncpy((char *)p_in->out_path_dir, (const char*)items[i + 2], strlen((const char*)items[i + 2]) + 1); + } else if (!strncmp((const char*)items[i], "DecodedFrames", 13)) { + if (!sscanf((const char*)items[i + 2], "%d", &p_in->iDecFrmNum)) { + goto __FAILED; + } + } else if (!strncmp((const char*)items[i], "BitStrmRawCfg", 13)) { + if (!sscanf((const char*)items[i + 2], "%d", &p_in->raw_cfg)) { + goto __FAILED; + } + } + } + + return MPP_OK; +__FAILED: + return MPP_NOK; +} + +static MPP_RET parse_command(InputParams *p_in, int ac, char *av[]) +{ + RK_S32 CLcount = 0; + RK_U8 *content = NULL; + char *pnamecmd = NULL; + RK_U8 have_cfg_flag = 0; + + CLcount = 1; + while (CLcount < ac) { + if (!strncmp(av[1], "-h", 2) || !strncmp(av[1], "--help", 6)) { + pnamecmd = strrchr(av[0], '/'); + pnamecmd = pnamecmd ? pnamecmd : strrchr(av[0], '\\'); + pnamecmd = pnamecmd ? (pnamecmd + 1) : av[0]; + print_help_message(pnamecmd); + goto __FAILED; + } else if (!strncmp(av[CLcount], "-n", 2) || !strncmp(av[1], "--num", 5)) { // decoded frames + if (!sscanf(av[CLcount + 1], "%d", &p_in->iDecFrmNum)) { + goto __FAILED; + } + CLcount += 2; + } else if (!strncmp(av[CLcount], "-i", 2) || !strncmp(av[1], "--input", 7)) { + strncpy(p_in->infile_name, av[CLcount + 1], strlen((const char*)av[CLcount + 1]) + 1); + CLcount += 2; + } else if (!strncmp(av[CLcount], "--cmppath", 9)) { // compare direct path + strncpy(p_in->cmp_path_dir, av[CLcount + 1], strlen((const char*)av[CLcount + 1]) + 1); + CLcount += 2; + } else if (!strncmp(av[CLcount], "--outpath", 9)) { // compare direct path + strncpy(p_in->out_path_dir, av[CLcount + 1], strlen((const char*)av[CLcount + 1]) + 1); + CLcount += 2; + } else if (!strncmp(av[1], "-r", 2) || !strncmp(av[CLcount], "--raw", 5)) { + if (!sscanf(av[CLcount + 1], "%d", &p_in->raw_cfg)) { + goto __FAILED; + } + CLcount += 2; + } else if (!strncmp(av[1], "-c", 2) || !strncmp(av[CLcount], "--cfg", 5)) { // configure file + strncpy(p_in->cfgfile_name, av[CLcount + 1], FILE_NAME_SIZE); + CLcount += 2; + have_cfg_flag = 1; + } else { + mpp_log("Error: %s cannot explain command! \n", av[CLcount]); + goto __FAILED; + } + } + if (have_cfg_flag) { + if (!(content = get_config_file_content(p_in->cfgfile_name))) { + goto __FAILED; + } + if (parse_content(p_in, content)) { + goto __FAILED; + } + MPP_FREE(content); + } + + return MPP_OK; +__FAILED: + + return MPP_NOK; +} + +static FILE *open_file(char *path, char *infile, char *sufix, const char *mode) +{ + char *pnamecmd = NULL; + char tmp_fname[FILE_NAME_SIZE] = { 0 }; + + pnamecmd = strrchr(infile, '/'); + pnamecmd = pnamecmd ? pnamecmd : strrchr(infile, '\\'); + pnamecmd = pnamecmd ? (pnamecmd + 1) : infile; + + + sprintf(tmp_fname, "%s/%s%s", path, pnamecmd, sufix); + + return fopen(tmp_fname, mode); +} + +static MPP_RET update_curr_byte(GetBitCtx_t *pStrmData) +{ + if (pStrmData->bytes_left_ < 1) + return MPP_NOK; + + // Emulation prevention three-byte detection. + // If a sequence of 0x000003 is found, skip (ignore) the last byte (0x03). + if (*pStrmData->data_ == 0x03 && (pStrmData->prev_two_bytes_ & 0xffff) == 0) { + // Detected 0x000003, skip last byte. + ++pStrmData->data_; + --pStrmData->bytes_left_; + ++pStrmData->emulation_prevention_bytes_; + // Need another full three bytes before we can detect the sequence again. + pStrmData->prev_two_bytes_ = 0xffff; + + if (pStrmData->bytes_left_ < 1) + return MPP_NOK; + } + + // Load a new byte and advance pointers. + pStrmData->curr_byte_ = *pStrmData->data_++ & 0xff; + --pStrmData->bytes_left_; + pStrmData->num_remaining_bits_in_curr_byte_ = 8; + + pStrmData->prev_two_bytes_ = (pStrmData->prev_two_bytes_ << 8) | pStrmData->curr_byte_; + + return MPP_OK; +} + +// Read |num_bits| (1 to 31 inclusive) from the stream and return them +// in |out|, with first bit in the stream as MSB in |out| at position +// (|num_bits| - 1). +static MPP_RET read_bits(GetBitCtx_t *pStrmData, RK_S32 num_bits, RK_S32 *out) +{ + RK_S32 bits_left = num_bits; + *out = 0; + ASSERT(num_bits <= 31); + + while (pStrmData->num_remaining_bits_in_curr_byte_ < bits_left) { + // Take all that's left in current byte, shift to make space for the rest. + *out |= (pStrmData->curr_byte_ << (bits_left - pStrmData->num_remaining_bits_in_curr_byte_)); + bits_left -= pStrmData->num_remaining_bits_in_curr_byte_; + + if (update_curr_byte(pStrmData)) { + return MPP_NOK; + } + } + + *out |= (pStrmData->curr_byte_ >> (pStrmData->num_remaining_bits_in_curr_byte_ - bits_left)); + *out &= ((1 << num_bits) - 1); + pStrmData->num_remaining_bits_in_curr_byte_ -= bits_left; + pStrmData->used_bits += num_bits; + + return MPP_OK; +} + +static MPP_RET read_ue(GetBitCtx_t *pStrmData, RK_U32 *val) +{ + RK_S32 num_bits = -1; + RK_S32 bit; + RK_S32 rest; + // Count the number of contiguous zero bits. + do { + if (read_bits(pStrmData, 1, &bit)) { + return MPP_NOK; + } + num_bits++; + } while (bit == 0); + + if (num_bits > 31) { + return MPP_NOK; + } + // Calculate exp-Golomb code value of size num_bits. + *val = (1 << num_bits) - 1; + + if (num_bits > 0) { + if (read_bits(pStrmData, num_bits, &rest)) { + return MPP_NOK; + } + *val += rest; + } + + return MPP_OK; +} + +static void set_streamdata(GetBitCtx_t *pStrmData, RK_U8 *data, RK_S32 size) +{ + memset(pStrmData, 0, sizeof(GetBitCtx_t)); + pStrmData->data_ = data; + pStrmData->bytes_left_ = size; + pStrmData->num_remaining_bits_in_curr_byte_ = 0; + // Initially set to 0xffff to accept all initial two-byte sequences. + pStrmData->prev_two_bytes_ = 0xffff; + pStrmData->emulation_prevention_bytes_ = 0; + // add + pStrmData->buf = data; + pStrmData->buf_len = size; + pStrmData->used_bits = 0; +} + + +static void write_nalu_prefix(InputParams *p_in) +{ + if (p_in->IO.pfxbytes > START_PREFIX_3BYTE) { + p_in->strm.pbuf[p_in->strm.strmbytes++] = 0x00; + } + p_in->strm.pbuf[p_in->strm.strmbytes++] = 0x00; + p_in->strm.pbuf[p_in->strm.strmbytes++] = 0x00; + p_in->strm.pbuf[p_in->strm.strmbytes++] = 0x01; +} + +static RK_U8 read_one_byte(InputParams *p_in) +{ + RK_U8 data = 0; + + if (0 == fread(&data, 1, 1, p_in->fp_bitstream)) { + p_in->is_eof = 1; + } + + return data; +} + +static void find_next_nalu(InputParams *p_in) +{ + RK_U8 startcode_had_find = 0; + //-- first read three bytes + if (p_in->is_fist_nalu) { + p_in->IO.pbuf[p_in->IO.offset] = read_one_byte(p_in); + p_in->IO.pbuf[p_in->IO.offset + 1] = read_one_byte(p_in); + p_in->IO.pbuf[p_in->IO.offset + 2] = read_one_byte(p_in); + p_in->is_fist_nalu = 0; + } + do { + if (startcode_had_find) { + p_in->IO.nalubytes++; + } + //--- find 0x000001 + if ((p_in->IO.pbuf[p_in->IO.offset] == 0x00) + && (p_in->IO.pbuf[p_in->IO.offset + 1] == 0x00) + && (p_in->IO.pbuf[p_in->IO.offset + 2] == 0x01)) { + if (startcode_had_find) { //-- end_code + p_in->IO.nalubytes -= START_PREFIX_3BYTE; + if (p_in->IO.pbuf[p_in->IO.offset - 1] == 0x00) { + p_in->IO.pbuf[0] = 0x00; + p_in->IO.nalubytes--; + } else { + p_in->IO.pbuf[0] = 0xFF; + } + p_in->IO.pbuf[1] = 0x00; + p_in->IO.pbuf[2] = 0x00; + p_in->IO.pbuf[3] = 0x01; + p_in->IO.offset = 1; + break; + } else { //-- find strart_code + startcode_had_find = 1; + p_in->IO.nalubytes = 0; + p_in->IO.pfxbytes = START_PREFIX_3BYTE; + p_in->IO.pNALU = &p_in->IO.pbuf[p_in->IO.offset + START_PREFIX_3BYTE]; + if (p_in->IO.offset && (p_in->IO.pbuf[p_in->IO.offset - 1] == 0x00)) { + p_in->IO.pfxbytes++; + } + } + } + p_in->IO.offset++; + p_in->IO.pbuf[p_in->IO.offset + 2] = read_one_byte(p_in); + } while (!p_in->is_eof); +} +RK_U32 g_nalu_cnt2 = 0; +static MPP_RET read_next_nalu(InputParams *p_in) +{ + RK_S32 forbidden_bit = -1; + RK_S32 nal_reference_idc = -1; + RK_S32 nalu_type = -1; + RK_S32 nalu_header_bytes = -1; + RK_U32 first_mb_in_slice = -1; + RK_S32 svc_extension_flag = -1; + + GetBitCtx_t *pStrmData = (GetBitCtx_t *)p_in->bitctx; + memset(pStrmData, 0, sizeof(GetBitCtx_t)); + set_streamdata(pStrmData, p_in->IO.pNALU, 4); + read_bits( pStrmData, 1, &forbidden_bit); + ASSERT(forbidden_bit == 0); + read_bits( pStrmData, 2, &nal_reference_idc); + read_bits( pStrmData, 5, &nalu_type); + + nalu_header_bytes = 1; + if ((nalu_type == NALU_TYPE_PREFIX) || (nalu_type == NALU_TYPE_SLC_EXT)) { + read_bits(pStrmData, 1, &svc_extension_flag); + if (!svc_extension_flag && nalu_type == NALU_TYPE_SLC_EXT) {//!< MVC + nalu_type = NALU_TYPE_SLICE; + } + nalu_header_bytes += 3; + } + //-- parse slice + if ( nalu_type == NALU_TYPE_SLICE || nalu_type == NALU_TYPE_IDR) { + set_streamdata(pStrmData, (p_in->IO.pNALU + nalu_header_bytes), 4); // reset + read_ue(pStrmData, &first_mb_in_slice); + if (!p_in->is_fist_frame && (first_mb_in_slice == 0)) { + p_in->is_new_frame = 1; + } + p_in->is_fist_frame = 0; + } + if (!p_in->is_new_frame) { + write_nalu_prefix(p_in); + memcpy(&p_in->strm.pbuf[p_in->strm.strmbytes], p_in->IO.pNALU, p_in->IO.nalubytes); + p_in->strm.strmbytes += p_in->IO.nalubytes; + } + + return MPP_OK; +} + +static void reset_tmpdata_ctx(TempDataCtx_t *tmp) +{ + tmp->header = 0; + tmp->len = 0; + tmp->pps_id = 0; +} + + +static void read_golden_data(FILE *fp, TempDataCtx_t *tmpctx, RK_U32 frame_no) +{ + RK_U32 header = 0, datasize = 0; + + reset_tmpdata_ctx(tmpctx); + fread(&header, 1, sizeof(RK_U32), fp); + fread(&datasize, 1, sizeof(RK_U32), fp); + while (!feof(fp)) { + switch (header) { + case RKVDEC_PPS_HEADER: + tmpctx->pps_id = datasize >> 16; + datasize = datasize & 0xffff; + case RKVDEC_SCL_HEADER: + case RKVDEC_RPS_HEADER: + case RKVDEC_STM_HEADER: + fseek(fp, datasize, SEEK_CUR); + break; + case RKVDEC_REG_HEADER: + fseek(fp, datasize, SEEK_CUR); + goto __RETURN; + break; + case RKVDEC_CRC_HEADER: + fread(tmpctx->data, sizeof(RK_U8), datasize, fp); + tmpctx->len = datasize; + break; + case RKVDEC_ERR_HEADER: + break; + default: + mpp_log("ERROR: frame_no=%d. \n", frame_no); + ASSERT(0); + break; + } + fread(&header, 1, sizeof(RK_U32), fp); + fread(&datasize, 1, sizeof(RK_U32), fp); + } +__RETURN: + return; +} + +static void write_bytes(FILE *fp_in, TempDataCtx_t *tmpctx, FILE *fp_out) +{ + RK_U32 i = 0; + RK_U8 temp = 0; + RK_U32 data_temp = 0; + data_temp = (tmpctx->pps_id << 16) | tmpctx->len; + + fwrite(&tmpctx->header, sizeof(RK_U32), 1, fp_out); + fwrite(&data_temp, sizeof(RK_U32), 1, fp_out); + while (i < tmpctx->len) { + fread (&temp, sizeof(RK_U8), 1, fp_in); + fwrite(&temp, sizeof(RK_U8), 1, fp_out); + i++; + } +} + + +static void write_driver_bytes(FILE *fp_out, TempDataCtx_t *in_tmpctx, FILE *fp_in, RK_U32 frame_no) +{ + RK_U32 header = 0, datasize = 0; + TempDataCtx_t m_tmpctx = { 0 }; + + fread(&header, 1, sizeof(RK_U32), fp_in); + fread(&datasize, 1, sizeof(RK_U32), fp_in); + + while (!feof(fp_in)) { + memset(&m_tmpctx, 0, sizeof(TempDataCtx_t)); + switch (header) { + case RKVDEC_PPS_HEADER: + m_tmpctx.pps_id = in_tmpctx->pps_id; + case RKVDEC_SCL_HEADER: + case RKVDEC_RPS_HEADER: + case RKVDEC_STM_HEADER: + m_tmpctx.header = header; + m_tmpctx.len = datasize; + write_bytes(fp_in, &m_tmpctx, fp_out); + break; + case RKVDEC_REG_HEADER: + m_tmpctx.header = header; + m_tmpctx.len = datasize; + header = RKVDEC_CRC_HEADER; + fwrite(&header, sizeof(RK_U32), 1, fp_out); + fwrite(&in_tmpctx->len, sizeof(RK_U32), 1, fp_out); + fwrite(in_tmpctx->data, sizeof(RK_U8), in_tmpctx->len, fp_out); + write_bytes(fp_in, &m_tmpctx, fp_out); + return; + default: + mpp_log("ERROR: frame_no=%d. \n", frame_no); + ASSERT(0); + break; + } + fread(&header, 1, sizeof(RK_U32), fp_in); + fread(&datasize, 1, sizeof(RK_U32), fp_in); + } +} + + +/*! +*********************************************************************** +* \brief +* configure function to analyze command or configure file +*********************************************************************** +*/ +MPP_RET h264d_configure(InputParams *p_in, RK_S32 ac, char *av[]) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + VAL_CHECK(ret, ac > 1); + display_input_cmd(ac, av); + FUN_CHECK (ret = parse_command(p_in, ac, av)); + + return MPP_OK; +__FAILED: + return ret; +} + + +/*! +*********************************************************************** +* \brief +* close file +*********************************************************************** +*/ +MPP_RET h264d_close_files(InputParams *p_in) +{ + FCLOSE(p_in->fp_bitstream); + FCLOSE(p_in->fp_golden_data); + FCLOSE(p_in->fp_yuv_data); + FCLOSE(p_in->fp_driver_data); + + return MPP_OK; +} + +/*! +*********************************************************************** +* \brief +* open file +*********************************************************************** +*/ +MPP_RET h264d_open_files(InputParams *p_in) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + char *outpath_dir = NULL; + mpp_env_get_str(logenv_name.outpath, &outpath_dir, NULL); + FLE_CHECK(ret, p_in->fp_bitstream = fopen(p_in->infile_name, "rb")); + p_in->fp_yuv_data = open_file(outpath_dir, p_in->infile_name, ".yuv", "wb"); + return MPP_OK; +__FAILED: + h264d_close_files(p_in); + + return ret; +} + +/*! +*********************************************************************** +* \brief +* free frame buffer +*********************************************************************** +*/ + +MPP_RET h264d_free_frame_buffer(InputParams *p_in) +{ + if (p_in) { + MPP_FREE(p_in->IO.pbuf); + MPP_FREE(p_in->bitctx); + MPP_FREE(p_in->strm.pbuf); + } + + return MPP_NOK; +} +/*! +*********************************************************************** +* \brief +* alloc frame buffer +*********************************************************************** +*/ +MPP_RET h264d_alloc_frame_buffer(InputParams *p_in) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + + p_in->IO.pbuf = mpp_malloc_size(RK_U8, IOBUFSIZE); + p_in->strm.pbuf = mpp_malloc_size(RK_U8, STMBUFSIZE); + p_in->bitctx = mpp_malloc_size(void, sizeof(GetBitCtx_t)); + MEM_CHECK(ret, p_in->IO.pbuf && p_in->strm.pbuf && p_in->bitctx); + p_in->is_fist_nalu = 1; + p_in->is_fist_frame = 1; + + return MPP_OK; +__FAILED: + return ret; +} + + +/*! +*********************************************************************** +* \brief +* read one frame +*********************************************************************** +*/ +MPP_RET h264d_read_one_frame(InputParams *p_in) +{ + p_in->strm.strmbytes = 0; + p_in->is_new_frame = 0; + //-- copy first nalu + if (!p_in->is_fist_frame) { + write_nalu_prefix(p_in); + memcpy(&p_in->strm.pbuf[p_in->strm.strmbytes], p_in->IO.pNALU, p_in->IO.nalubytes); + p_in->strm.strmbytes += p_in->IO.nalubytes; + } + //-- read one nalu and copy to stream buffer + do { + find_next_nalu(p_in); + read_next_nalu(p_in); + } while (!p_in->is_new_frame && !p_in->is_eof); + //if (first_mb_in_slice == 0) { + //FPRINT(g_debug_file0, "--- new frame ---- \n"); + //} + + return MPP_OK; +} +/*! +*********************************************************************** +* \brief +* write fpage data to file +*********************************************************************** +*/ +MPP_RET h264d_write_fpga_data(InputParams *p_in) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + TempDataCtx_t tmpctx = { 0 }; + FILE *fp_log = NULL; + RK_U32 frame_no = 0; + RK_U32 ctrl_value = 0; + RK_U32 ctrl_debug = 0; + RK_U32 ctrl_fpga = 0; + RK_U32 ctrl_write = 0; + char *outpath_dir = NULL; + char *cmppath_dir = NULL; + + mpp_env_get_u32(logenv_name.ctrl, &ctrl_value, 0); + ctrl_debug = GetBitVal(ctrl_value, LOG_DEBUG); + ctrl_fpga = GetBitVal(ctrl_value, LOG_FPGA); + ctrl_write = GetBitVal(ctrl_value, LOG_WRITE); + INP_CHECK(ret, !(ctrl_debug && ctrl_fpga && ctrl_write)); + mpp_env_get_str(logenv_name.outpath, &outpath_dir, NULL); + mpp_env_get_str(logenv_name.cmppath, &cmppath_dir, NULL); + p_in->fp_driver_data = open_file(outpath_dir, p_in->infile_name, ".dat", "wb"); + p_in->fp_golden_data = open_file(cmppath_dir, p_in->infile_name, ".dat", "rb"); + fp_log = fopen(strcat(outpath_dir, "/h264d_driver_data.dat"), "rb"); + FLE_CHECK(ret, p_in->fp_golden_data); + FLE_CHECK(ret, p_in->fp_driver_data); + FLE_CHECK(ret, p_in->fp_yuv_data); + FLE_CHECK(ret, fp_log); + tmpctx.data = mpp_calloc_size(RK_U8, 128); + MEM_CHECK(ret, tmpctx.data); //!< for read golden fpga data + while (!feof(p_in->fp_golden_data) && !feof(fp_log)) { + read_golden_data (p_in->fp_golden_data, &tmpctx, frame_no); + write_driver_bytes(p_in->fp_driver_data, &tmpctx, fp_log, frame_no); + frame_no++; + } + //remove(out_name); +__RETURN: + ret = MPP_OK; +__FAILED: + MPP_FREE(tmpctx.data); + h264d_close_files(p_in); + + return ret; +} diff --git a/mpp/codec/dec/h264/h264d_rwfile.h b/mpp/codec/dec/h264/h264d_rwfile.h index 933ef39d..208c21cb 100644 --- a/mpp/codec/dec/h264/h264d_rwfile.h +++ b/mpp/codec/dec/h264/h264d_rwfile.h @@ -1,97 +1,97 @@ -/* -* -* Copyright 2015 Rockchip Electronics Co. LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#include -#include "rk_type.h" -#include "mpp_err.h" -#include "mpp_log.h" - -#ifndef __H264D_RWFILE_H__ -#define __H264D_RWFILE_H__ - - -#define FILE_NAME_SIZE 256 - - -// input parameters from configuration file -typedef struct inp_par_t { - RK_U32 iDecFrmNum; //!< set the max decode frame numbers - char infile_name[FILE_NAME_SIZE]; //!< H.264 input bitstrream - char cmp_path_dir[FILE_NAME_SIZE]; //!< golen - char cfgfile_name[FILE_NAME_SIZE]; //!< input configure file - char out_path_dir[FILE_NAME_SIZE]; //!< output - //--- input file - FILE *fp_bitstream; - FILE *fp_golden_data; - FILE *fp_driver_data; - FILE *fp_yuv_data; - //--- use in read bit stream - RK_U32 raw_cfg; - RK_U32 iFrmdecoded; - RK_U8 is_fist_nalu; - RK_U8 is_fist_frame; - RK_U8 is_eof; - RK_U8 is_new_frame; - struct { - RK_U8 *pbuf; - RK_U32 offset; - - RK_U8 *pNALU; - RK_U32 nalubytes; - RK_U8 pfxbytes; // start code prefix bytes - } IO; - struct { - RK_U8 *pbuf; - RK_U32 strmbytes; - } strm; - void *bitctx; -} InputParams; - -extern RK_U32 rkv_h264d_test_debug; - - -#define H264D_TEST_TRACE (0x00000001) -#define H264D_TEST_TIME (0x00000002) -#define H264D_TEST_MUTI_THREAD (0x00000004) -#define H264D_TEST_DUMPYUV (0x00000008) -#define H264D_TEST_FPGA (0x00000010) - - -#define H264D_TEST_LOG(level, fmt, ...)\ -do {\ - if (level & rkv_h264d_test_debug)\ - { mpp_log(fmt, ## __VA_ARGS__); }\ -} while (0) - - -#ifdef __cplusplus -extern "C" { -#endif - -MPP_RET h264d_configure (InputParams *in, RK_S32 ac, char *av[]); -MPP_RET h264d_open_files (InputParams *in); -MPP_RET h264d_close_files(InputParams *in); -MPP_RET h264d_alloc_frame_buffer(InputParams *in); -MPP_RET h264d_read_one_frame (InputParams *in); -MPP_RET h264d_free_frame_buffer (InputParams *in); -MPP_RET h264d_write_fpga_data (InputParams *in); - -#ifdef __cplusplus -} -#endif - +/* +* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include +#include "rk_type.h" +#include "mpp_err.h" +#include "mpp_log.h" + +#ifndef __H264D_RWFILE_H__ +#define __H264D_RWFILE_H__ + + +#define FILE_NAME_SIZE 256 + + +// input parameters from configuration file +typedef struct inp_par_t { + RK_U32 iDecFrmNum; //!< set the max decode frame numbers + char infile_name[FILE_NAME_SIZE]; //!< H.264 input bitstrream + char cmp_path_dir[FILE_NAME_SIZE]; //!< golen + char cfgfile_name[FILE_NAME_SIZE]; //!< input configure file + char out_path_dir[FILE_NAME_SIZE]; //!< output + //--- input file + FILE *fp_bitstream; + FILE *fp_golden_data; + FILE *fp_driver_data; + FILE *fp_yuv_data; + //--- use in read bit stream + RK_U32 raw_cfg; + RK_U32 iFrmdecoded; + RK_U8 is_fist_nalu; + RK_U8 is_fist_frame; + RK_U8 is_eof; + RK_U8 is_new_frame; + struct { + RK_U8 *pbuf; + RK_U32 offset; + + RK_U8 *pNALU; + RK_U32 nalubytes; + RK_U8 pfxbytes; // start code prefix bytes + } IO; + struct { + RK_U8 *pbuf; + RK_U32 strmbytes; + } strm; + void *bitctx; +} InputParams; + +extern RK_U32 rkv_h264d_test_debug; + + +#define H264D_TEST_TRACE (0x00000001) +#define H264D_TEST_TIME (0x00000002) +#define H264D_TEST_MUTI_THREAD (0x00000004) +#define H264D_TEST_DUMPYUV (0x00000008) +#define H264D_TEST_FPGA (0x00000010) + + +#define H264D_TEST_LOG(level, fmt, ...)\ +do {\ + if (level & rkv_h264d_test_debug)\ + { mpp_log(fmt, ## __VA_ARGS__); }\ +} while (0) + + +#ifdef __cplusplus +extern "C" { +#endif + +MPP_RET h264d_configure (InputParams *in, RK_S32 ac, char *av[]); +MPP_RET h264d_open_files (InputParams *in); +MPP_RET h264d_close_files(InputParams *in); +MPP_RET h264d_alloc_frame_buffer(InputParams *in); +MPP_RET h264d_read_one_frame (InputParams *in); +MPP_RET h264d_free_frame_buffer (InputParams *in); +MPP_RET h264d_write_fpga_data (InputParams *in); + +#ifdef __cplusplus +} +#endif + #endif /* __H264D_RWFILE_H__ */ \ No newline at end of file diff --git a/mpp/codec/dec/h264/h264d_scalist.c b/mpp/codec/dec/h264/h264d_scalist.c index c9412798..483bde5e 100644 --- a/mpp/codec/dec/h264/h264d_scalist.c +++ b/mpp/codec/dec/h264/h264d_scalist.c @@ -1,349 +1,349 @@ -/* -* -* Copyright 2015 Rockchip Electronics Co. LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#include -#include - -#include "h264d_scalist.h" - - - -static RK_U8 ZZ_SCAN[16] = -{ 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15 }; - -static RK_U8 ZZ_SCAN8[64] = { - 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, - 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, - 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51, - 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63 -}; - -static RK_S32 Default4x4Intra[H264ScalingList4x4Length] = -{ 6, 13, 20, 28, 13, 20, 28, 32, 20, 28, 32, 37, 28, 32, 37, 42 }; - -static RK_S32 Default4x4Inter[H264ScalingList4x4Length] = -{ 10, 14, 20, 24, 14, 20, 24, 27, 20, 24, 27, 30, 24, 27, 30, 34 }; - -static RK_S32 Default8x8Intra[H264ScalingList8x8Length] = { - 6, 10, 13, 16, 18, 23, 25, 27, 10, 11, 16, 18, 23, 25, 27, 29, - 13, 16, 18, 23, 25, 27, 29, 31, 16, 18, 23, 25, 27, 29, 31, 33, - 18, 23, 25, 27, 29, 31, 33, 36, 23, 25, 27, 29, 31, 33, 36, 38, - 25, 27, 29, 31, 33, 36, 38, 40, 27, 29, 31, 33, 36, 38, 40, 42 -}; - -static RK_S32 Default8x8Inter[H264ScalingList8x8Length] = { - 9, 13, 15, 17, 19, 21, 22, 24, 13, 13, 17, 19, 21, 22, 24, 25, - 15, 17, 19, 21, 22, 24, 25, 27, 17, 19, 21, 22, 24, 25, 27, 28, - 19, 21, 22, 24, 25, 27, 28, 30, 21, 22, 24, 25, 27, 28, 30, 32, - 22, 24, 25, 27, 28, 30, 32, 33, 24, 25, 27, 28, 30, 32, 33, 35 -}; - -static RK_S32 Default4x4[16] = -{ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 }; - -static RK_S32 Default8x8[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 set_sps_scanlist_matrix(H264_SPS_t *sps, H264dVideoCtx_t *p_Vid) -{ - RK_S32 i = 0; - - for (i = 0; i < 6; ++i) { - if (!sps->seq_scaling_list_present_flag[i]) { // fall-back rule A - if (i == 0) { - p_Vid->qmatrix[i] = Default4x4Intra; - } else if (i == 3) { - p_Vid->qmatrix[i] = Default4x4Inter; - } else { - p_Vid->qmatrix[i] = p_Vid->qmatrix[i - 1]; - } - } else { - if (sps->UseDefaultScalingMatrix4x4Flag[i]) { - - p_Vid->qmatrix[i] = (i < 3) ? Default4x4Intra : Default4x4Inter; - } else { - p_Vid->qmatrix[i] = sps->ScalingList4x4[i]; - } - } - } - - for (i = 6; i < ((sps->chroma_format_idc != YUV444) ? 8 : 12); ++i) { - if (!sps->seq_scaling_list_present_flag[i]) { // fall-back rule A - if (i == 6) { - p_Vid->qmatrix[i] = Default8x8Intra; - } else if (i == 7) { - p_Vid->qmatrix[i] = Default8x8Inter; - } else { - p_Vid->qmatrix[i] = p_Vid->qmatrix[i - 2]; - } - } else { - if (sps->UseDefaultScalingMatrix8x8Flag[i - 6]) { - - p_Vid->qmatrix[i] = (i == 6 || i == 8 || i == 10) ? Default8x8Intra : Default8x8Inter; - } else { - p_Vid->qmatrix[i] = sps->ScalingList8x8[i - 6]; - } - } - } -} - -static void set_pps_scanlist_matrix(H264_SPS_t *sps, H264_PPS_t *pps, H264dVideoCtx_t *p_Vid) -{ - RK_S32 i = 0; - - for (i = 0; i < 6; ++i) { - if (!pps->pic_scaling_list_present_flag[i]) { // fall-back rule B - if (i == 0) { - if (!sps->seq_scaling_matrix_present_flag) { - p_Vid->qmatrix[i] = Default4x4Intra; - } - } else if (i == 3) { - if (!sps->seq_scaling_matrix_present_flag) { - p_Vid->qmatrix[i] = Default4x4Inter; - } - } else { - p_Vid->qmatrix[i] = p_Vid->qmatrix[i - 1]; - } - } else { - if (pps->UseDefaultScalingMatrix4x4Flag[i]) { - p_Vid->qmatrix[i] = (i < 3) ? Default4x4Intra : Default4x4Inter; - } else { - p_Vid->qmatrix[i] = pps->ScalingList4x4[i]; - } - } - } - for (i = 6; i < ((sps->chroma_format_idc != YUV444) ? 8 : 12); ++i) { - if (!pps->pic_scaling_list_present_flag[i]) { // fall-back rule B - if (i == 6) { - if (!sps->seq_scaling_matrix_present_flag) { - p_Vid->qmatrix[i] = Default8x8Intra; - } - } else if (i == 7) { - if (!sps->seq_scaling_matrix_present_flag) - p_Vid->qmatrix[i] = Default8x8Inter; - } else - p_Vid->qmatrix[i] = p_Vid->qmatrix[i - 2]; - } else { - if (pps->UseDefaultScalingMatrix8x8Flag[i - 6]) { - p_Vid->qmatrix[i] = (i == 6 || i == 8 || i == 10) ? Default8x8Intra : Default8x8Inter; - } else { - p_Vid->qmatrix[i] = pps->ScalingList8x8[i - 6]; - } - } - } -} - -/*! -*********************************************************************** -* \brief -* check profile -*********************************************************************** -*/ -//extern "C" -RK_U32 is_prext_profile(RK_U32 profile_idc) -{ - return (profile_idc >= H264_PROFILE_HIGH || profile_idc == H264_PROFILE_FREXT_CAVLC444) ? 1 : 0; -} - -/*! -*********************************************************************** -* \brief -* parse sps and process sps -*********************************************************************** -*/ -//extern "C" -MPP_RET parse_scalingList(BitReadCtx_t *p_bitctx, RK_S32 size, RK_S32 *scaling_list, RK_S32 *use_default) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - RK_S32 last_scale = 8; - RK_S32 next_scale = 8; - RK_S32 delta_scale = 0; - RK_S32 j = 0, scanj = 0; - - RK_U8 *zz_scan = (size > 16) ? ZZ_SCAN8 : ZZ_SCAN; - - *use_default = 0; - for (j = 0; j < size; ++j) { - scanj = zz_scan[j]; - if (next_scale != 0) { - READ_SE(p_bitctx, &delta_scale, "delta_scale"); - CHECK_RANGE(p_bitctx, delta_scale, -128, 127); - next_scale = (last_scale + delta_scale + 256) & 0xff; - *use_default = (scanj == 0 && next_scale == 0) ? 1 : 0; - } - scaling_list[scanj] = (next_scale == 0) ? last_scale : next_scale; - last_scale = scaling_list[scanj]; - } - - return ret = MPP_OK; -__BITREAD_ERR: - ret = p_bitctx->ret; - return ret; -} - - -/*! -*********************************************************************** -* \brief -* parse sps and process sps -*********************************************************************** -*/ -//extern "C" -MPP_RET get_max_dec_frame_buf_size(H264_SPS_t *sps) -{ - RK_S32 size = 0; - RK_S32 pic_size = 0; - MPP_RET ret = MPP_ERR_UNKNOW; - - - switch (sps->level_idc) { - case 9: - size = 152064; - break; - case 10: - size = 152064; - break; - case 11: - if (sps->constrained_set3_flag && !is_prext_profile(sps->profile_idc)) { - size = 152064; - } else { - size = 345600; - } - break; - case 12: - size = 912384; - break; - case 13: - size = 912384; - break; - case 20: - size = 912384; - break; - case 21: - size = 1824768; - break; - case 22: - size = 3110400; - break; - case 30: - size = 3110400; - break; - case 31: - size = 6912000; - break; - case 32: - size = 7864320; - break; - case 40: - size = 12582912; - break; - case 41: - size = 12582912; - break; - case 42: - size = 13369344; - break; - case 50: - size = 42393600; - break; - case 51: - size = 70778880; - break; - case 52: - size = 70778880; - break; - default: - ASSERT(0); // undefined level - return ret = MPP_NOK; - } - pic_size = (sps->pic_width_in_mbs_minus1 + 1) - * (sps->pic_height_in_map_units_minus1 + 1) - * (sps->frame_mbs_only_flag ? 1 : 2) * 384; - size /= pic_size; - size = MPP_MIN(size, 16); - sps->max_dec_frame_buffering = size; - - return ret = MPP_OK; -} - -/*! -*********************************************************************** -* \brief -* parse sps and process sps -*********************************************************************** -*/ -//extern "C" -MPP_RET parse_sps_scalinglists(BitReadCtx_t *p_bitctx, H264_SPS_t *sps) -{ - RK_S32 i = 0; - MPP_RET ret = MPP_ERR_UNKNOW; - // Parse scaling_list4x4. - for (i = 0; i < 6; ++i) { - READ_ONEBIT(p_bitctx, &sps->seq_scaling_list_present_flag[i], "seq_scaling_list_present_flag"); - - if (sps->seq_scaling_list_present_flag[i]) { - FUN_CHECK(ret = parse_scalingList(p_bitctx, H264ScalingList4x4Length, - sps->ScalingList4x4[i], &sps->UseDefaultScalingMatrix4x4Flag[i])); - } - } - // Parse scaling_list8x8. - for (i = 0; i < ((sps->chroma_format_idc != YUV444) ? 2 : 6); ++i) { - READ_ONEBIT(p_bitctx, &sps->seq_scaling_list_present_flag[6 + i], "seq_scaling_list_present_flag"); - if (sps->seq_scaling_list_present_flag[6 + i]) { - FUN_CHECK(ret = parse_scalingList(p_bitctx, H264ScalingList8x8Length, - sps->ScalingList8x8[i], &sps->UseDefaultScalingMatrix8x8Flag[i])); - } - } - - return ret = MPP_OK; -__BITREAD_ERR: - ret = p_bitctx->ret; -__FAILED: - return ret; -} -/*! -*********************************************************************** -* \brief -* prepare scanlist info to register syntax -*********************************************************************** -*/ -//extern "C" -MPP_RET prepare_init_scanlist(H264_SLICE_t *currSlice) -{ - RK_S32 i = 0; - H264_SPS_t *sps = currSlice->p_Vid->active_sps; - H264_PPS_t *pps = currSlice->p_Vid->active_pps; - - if (!pps->pic_scaling_matrix_present_flag && !sps->seq_scaling_matrix_present_flag) { - for (i = 0; i < 12; i++) { - currSlice->p_Vid->qmatrix[i] = (i < 6) ? Default4x4 : Default8x8; - } - } else { - if (sps->seq_scaling_matrix_present_flag) { // check sps first - set_sps_scanlist_matrix(sps, currSlice->p_Vid); - } - if (pps->pic_scaling_matrix_present_flag) { // then check pps - set_pps_scanlist_matrix(sps, pps, currSlice->p_Vid); - } - } - return MPP_OK; -} +/* +* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include +#include + +#include "h264d_scalist.h" + + + +static RK_U8 ZZ_SCAN[16] = +{ 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15 }; + +static RK_U8 ZZ_SCAN8[64] = { + 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, + 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, + 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51, + 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63 +}; + +static RK_S32 Default4x4Intra[H264ScalingList4x4Length] = +{ 6, 13, 20, 28, 13, 20, 28, 32, 20, 28, 32, 37, 28, 32, 37, 42 }; + +static RK_S32 Default4x4Inter[H264ScalingList4x4Length] = +{ 10, 14, 20, 24, 14, 20, 24, 27, 20, 24, 27, 30, 24, 27, 30, 34 }; + +static RK_S32 Default8x8Intra[H264ScalingList8x8Length] = { + 6, 10, 13, 16, 18, 23, 25, 27, 10, 11, 16, 18, 23, 25, 27, 29, + 13, 16, 18, 23, 25, 27, 29, 31, 16, 18, 23, 25, 27, 29, 31, 33, + 18, 23, 25, 27, 29, 31, 33, 36, 23, 25, 27, 29, 31, 33, 36, 38, + 25, 27, 29, 31, 33, 36, 38, 40, 27, 29, 31, 33, 36, 38, 40, 42 +}; + +static RK_S32 Default8x8Inter[H264ScalingList8x8Length] = { + 9, 13, 15, 17, 19, 21, 22, 24, 13, 13, 17, 19, 21, 22, 24, 25, + 15, 17, 19, 21, 22, 24, 25, 27, 17, 19, 21, 22, 24, 25, 27, 28, + 19, 21, 22, 24, 25, 27, 28, 30, 21, 22, 24, 25, 27, 28, 30, 32, + 22, 24, 25, 27, 28, 30, 32, 33, 24, 25, 27, 28, 30, 32, 33, 35 +}; + +static RK_S32 Default4x4[16] = +{ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16 }; + +static RK_S32 Default8x8[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 set_sps_scanlist_matrix(H264_SPS_t *sps, H264dVideoCtx_t *p_Vid) +{ + RK_S32 i = 0; + + for (i = 0; i < 6; ++i) { + if (!sps->seq_scaling_list_present_flag[i]) { // fall-back rule A + if (i == 0) { + p_Vid->qmatrix[i] = Default4x4Intra; + } else if (i == 3) { + p_Vid->qmatrix[i] = Default4x4Inter; + } else { + p_Vid->qmatrix[i] = p_Vid->qmatrix[i - 1]; + } + } else { + if (sps->UseDefaultScalingMatrix4x4Flag[i]) { + + p_Vid->qmatrix[i] = (i < 3) ? Default4x4Intra : Default4x4Inter; + } else { + p_Vid->qmatrix[i] = sps->ScalingList4x4[i]; + } + } + } + + for (i = 6; i < ((sps->chroma_format_idc != YUV444) ? 8 : 12); ++i) { + if (!sps->seq_scaling_list_present_flag[i]) { // fall-back rule A + if (i == 6) { + p_Vid->qmatrix[i] = Default8x8Intra; + } else if (i == 7) { + p_Vid->qmatrix[i] = Default8x8Inter; + } else { + p_Vid->qmatrix[i] = p_Vid->qmatrix[i - 2]; + } + } else { + if (sps->UseDefaultScalingMatrix8x8Flag[i - 6]) { + + p_Vid->qmatrix[i] = (i == 6 || i == 8 || i == 10) ? Default8x8Intra : Default8x8Inter; + } else { + p_Vid->qmatrix[i] = sps->ScalingList8x8[i - 6]; + } + } + } +} + +static void set_pps_scanlist_matrix(H264_SPS_t *sps, H264_PPS_t *pps, H264dVideoCtx_t *p_Vid) +{ + RK_S32 i = 0; + + for (i = 0; i < 6; ++i) { + if (!pps->pic_scaling_list_present_flag[i]) { // fall-back rule B + if (i == 0) { + if (!sps->seq_scaling_matrix_present_flag) { + p_Vid->qmatrix[i] = Default4x4Intra; + } + } else if (i == 3) { + if (!sps->seq_scaling_matrix_present_flag) { + p_Vid->qmatrix[i] = Default4x4Inter; + } + } else { + p_Vid->qmatrix[i] = p_Vid->qmatrix[i - 1]; + } + } else { + if (pps->UseDefaultScalingMatrix4x4Flag[i]) { + p_Vid->qmatrix[i] = (i < 3) ? Default4x4Intra : Default4x4Inter; + } else { + p_Vid->qmatrix[i] = pps->ScalingList4x4[i]; + } + } + } + for (i = 6; i < ((sps->chroma_format_idc != YUV444) ? 8 : 12); ++i) { + if (!pps->pic_scaling_list_present_flag[i]) { // fall-back rule B + if (i == 6) { + if (!sps->seq_scaling_matrix_present_flag) { + p_Vid->qmatrix[i] = Default8x8Intra; + } + } else if (i == 7) { + if (!sps->seq_scaling_matrix_present_flag) + p_Vid->qmatrix[i] = Default8x8Inter; + } else + p_Vid->qmatrix[i] = p_Vid->qmatrix[i - 2]; + } else { + if (pps->UseDefaultScalingMatrix8x8Flag[i - 6]) { + p_Vid->qmatrix[i] = (i == 6 || i == 8 || i == 10) ? Default8x8Intra : Default8x8Inter; + } else { + p_Vid->qmatrix[i] = pps->ScalingList8x8[i - 6]; + } + } + } +} + +/*! +*********************************************************************** +* \brief +* check profile +*********************************************************************** +*/ +//extern "C" +RK_U32 is_prext_profile(RK_U32 profile_idc) +{ + return (profile_idc >= H264_PROFILE_HIGH || profile_idc == H264_PROFILE_FREXT_CAVLC444) ? 1 : 0; +} + +/*! +*********************************************************************** +* \brief +* parse sps and process sps +*********************************************************************** +*/ +//extern "C" +MPP_RET parse_scalingList(BitReadCtx_t *p_bitctx, RK_S32 size, RK_S32 *scaling_list, RK_S32 *use_default) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + RK_S32 last_scale = 8; + RK_S32 next_scale = 8; + RK_S32 delta_scale = 0; + RK_S32 j = 0, scanj = 0; + + RK_U8 *zz_scan = (size > 16) ? ZZ_SCAN8 : ZZ_SCAN; + + *use_default = 0; + for (j = 0; j < size; ++j) { + scanj = zz_scan[j]; + if (next_scale != 0) { + READ_SE(p_bitctx, &delta_scale, "delta_scale"); + CHECK_RANGE(p_bitctx, delta_scale, -128, 127); + next_scale = (last_scale + delta_scale + 256) & 0xff; + *use_default = (scanj == 0 && next_scale == 0) ? 1 : 0; + } + scaling_list[scanj] = (next_scale == 0) ? last_scale : next_scale; + last_scale = scaling_list[scanj]; + } + + return ret = MPP_OK; +__BITREAD_ERR: + ret = p_bitctx->ret; + return ret; +} + + +/*! +*********************************************************************** +* \brief +* parse sps and process sps +*********************************************************************** +*/ +//extern "C" +MPP_RET get_max_dec_frame_buf_size(H264_SPS_t *sps) +{ + RK_S32 size = 0; + RK_S32 pic_size = 0; + MPP_RET ret = MPP_ERR_UNKNOW; + + + switch (sps->level_idc) { + case 9: + size = 152064; + break; + case 10: + size = 152064; + break; + case 11: + if (sps->constrained_set3_flag && !is_prext_profile(sps->profile_idc)) { + size = 152064; + } else { + size = 345600; + } + break; + case 12: + size = 912384; + break; + case 13: + size = 912384; + break; + case 20: + size = 912384; + break; + case 21: + size = 1824768; + break; + case 22: + size = 3110400; + break; + case 30: + size = 3110400; + break; + case 31: + size = 6912000; + break; + case 32: + size = 7864320; + break; + case 40: + size = 12582912; + break; + case 41: + size = 12582912; + break; + case 42: + size = 13369344; + break; + case 50: + size = 42393600; + break; + case 51: + size = 70778880; + break; + case 52: + size = 70778880; + break; + default: + ASSERT(0); // undefined level + return ret = MPP_NOK; + } + pic_size = (sps->pic_width_in_mbs_minus1 + 1) + * (sps->pic_height_in_map_units_minus1 + 1) + * (sps->frame_mbs_only_flag ? 1 : 2) * 384; + size /= pic_size; + size = MPP_MIN(size, 16); + sps->max_dec_frame_buffering = size; + + return ret = MPP_OK; +} + +/*! +*********************************************************************** +* \brief +* parse sps and process sps +*********************************************************************** +*/ +//extern "C" +MPP_RET parse_sps_scalinglists(BitReadCtx_t *p_bitctx, H264_SPS_t *sps) +{ + RK_S32 i = 0; + MPP_RET ret = MPP_ERR_UNKNOW; + // Parse scaling_list4x4. + for (i = 0; i < 6; ++i) { + READ_ONEBIT(p_bitctx, &sps->seq_scaling_list_present_flag[i], "seq_scaling_list_present_flag"); + + if (sps->seq_scaling_list_present_flag[i]) { + FUN_CHECK(ret = parse_scalingList(p_bitctx, H264ScalingList4x4Length, + sps->ScalingList4x4[i], &sps->UseDefaultScalingMatrix4x4Flag[i])); + } + } + // Parse scaling_list8x8. + for (i = 0; i < ((sps->chroma_format_idc != YUV444) ? 2 : 6); ++i) { + READ_ONEBIT(p_bitctx, &sps->seq_scaling_list_present_flag[6 + i], "seq_scaling_list_present_flag"); + if (sps->seq_scaling_list_present_flag[6 + i]) { + FUN_CHECK(ret = parse_scalingList(p_bitctx, H264ScalingList8x8Length, + sps->ScalingList8x8[i], &sps->UseDefaultScalingMatrix8x8Flag[i])); + } + } + + return ret = MPP_OK; +__BITREAD_ERR: + ret = p_bitctx->ret; +__FAILED: + return ret; +} +/*! +*********************************************************************** +* \brief +* prepare scanlist info to register syntax +*********************************************************************** +*/ +//extern "C" +MPP_RET prepare_init_scanlist(H264_SLICE_t *currSlice) +{ + RK_S32 i = 0; + H264_SPS_t *sps = currSlice->p_Vid->active_sps; + H264_PPS_t *pps = currSlice->p_Vid->active_pps; + + if (!pps->pic_scaling_matrix_present_flag && !sps->seq_scaling_matrix_present_flag) { + for (i = 0; i < 12; i++) { + currSlice->p_Vid->qmatrix[i] = (i < 6) ? Default4x4 : Default8x8; + } + } else { + if (sps->seq_scaling_matrix_present_flag) { // check sps first + set_sps_scanlist_matrix(sps, currSlice->p_Vid); + } + if (pps->pic_scaling_matrix_present_flag) { // then check pps + set_pps_scanlist_matrix(sps, pps, currSlice->p_Vid); + } + } + return MPP_OK; +} diff --git a/mpp/codec/dec/h264/h264d_scalist.h b/mpp/codec/dec/h264/h264d_scalist.h index 6744e89c..0f11640e 100644 --- a/mpp/codec/dec/h264/h264d_scalist.h +++ b/mpp/codec/dec/h264/h264d_scalist.h @@ -1,41 +1,41 @@ -/* -* -* Copyright 2015 Rockchip Electronics Co. LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - - -#ifndef _H264D_SCALIST_H_ -#define _H264D_SCALIST_H_ - -#include "rk_type.h" -#include "mpp_err.h" -#include "h264d_global.h" - - -#ifdef __cplusplus -extern "C" { -#endif -RK_U32 is_prext_profile(RK_U32 profile_idc); -MPP_RET get_max_dec_frame_buf_size(H264_SPS_t *sps); -MPP_RET parse_scalingList(BitReadCtx_t *p_bitctx, RK_S32 size, RK_S32 *scaling_list, RK_S32 *use_default); -MPP_RET parse_sps_scalinglists(BitReadCtx_t *p_bitctx, H264_SPS_t *sps); -MPP_RET prepare_init_scanlist(H264_SLICE_t *currSlice); -#ifdef __cplusplus -} -#endif - -//======================================== -#endif /* end of _H264D_SCALIST_H_ */ - +/* +* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +#ifndef _H264D_SCALIST_H_ +#define _H264D_SCALIST_H_ + +#include "rk_type.h" +#include "mpp_err.h" +#include "h264d_global.h" + + +#ifdef __cplusplus +extern "C" { +#endif +RK_U32 is_prext_profile(RK_U32 profile_idc); +MPP_RET get_max_dec_frame_buf_size(H264_SPS_t *sps); +MPP_RET parse_scalingList(BitReadCtx_t *p_bitctx, RK_S32 size, RK_S32 *scaling_list, RK_S32 *use_default); +MPP_RET parse_sps_scalinglists(BitReadCtx_t *p_bitctx, H264_SPS_t *sps); +MPP_RET prepare_init_scanlist(H264_SLICE_t *currSlice); +#ifdef __cplusplus +} +#endif + +//======================================== +#endif /* end of _H264D_SCALIST_H_ */ + diff --git a/mpp/codec/dec/h264/h264d_sei.c b/mpp/codec/dec/h264/h264d_sei.c index 49be3007..e9db3600 100644 --- a/mpp/codec/dec/h264/h264d_sei.c +++ b/mpp/codec/dec/h264/h264d_sei.c @@ -1,412 +1,412 @@ -/* -* -* Copyright 2015 Rockchip Electronics Co. LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#define MODULE_TAG "h264d_sei" - -#include -#include - -#include "vpu_api.h" - -#include "h264d_log.h" -#include "h264d_sps.h" -#include "h264d_sei.h" - - -#ifndef _WIN32 -#include -char *_strupr(char *str) -{ - char *orign = str; - for (; *str != '\0'; str++) { - *str = toupper(*str); - } - return orign; -} -#endif - -static void interpret_spare_pic() -{ - -} -static void interpret_subsequence_info() -{ - -} -static void interpret_subsequence_layer_characteristics_info() -{ - -} -static void interpret_subsequence_characteristics_info() -{ - -} -static void interpret_scene_information() -{ - -} -static void interpret_user_data_registered_itu_t_t35_info() -{ - -} - -static MPP_RET interpret_user_data_unregistered_info(RK_U8 *payload, RK_S32 size, H264_SEI_t *sei_msg) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - - H264D_DBG(H264D_DBG_SEI, "[SEI_info] user data info, size=%d", size); - ASSERT(size >= 16); - - sei_msg->user_data_DivX_flag = strstr(_strupr((char *)&payload[16]), "DIVX") ? 1 : 0; - if (sei_msg->user_data_DivX_flag) { - H264D_ERR("DivX is not supported. \n"); - sei_msg->p_Dec->errctx.un_spt_flag = 1; - ret = MPP_NOK; - goto __FAILED; - } - - return ret = MPP_OK; -__FAILED: - return ret; -} - -static void interpret_pan_scan_rect_info() -{ - -} -static void interpret_filler_payload_info() -{ - -} -static void interpret_dec_ref_pic_marking_repetition_info() -{ - -} -static void interpret_full_frame_freeze_info() -{ - -} -static void interpret_full_frame_freeze_release_info() -{ - -} -static void interpret_full_frame_snapshot_info() -{ - -} -static void interpret_progressive_refinement_start_info() -{ - -} -static void interpret_progressive_refinement_end_info() -{ - -} -static void interpret_motion_constrained_slice_group_set_info() -{ - -} -static void interpret_picture_timing_info() -{ - -} -static void interpret_film_grain_characteristics_info() -{ - -} -static void interpret_deblocking_filter_display_preference_info() -{ - -} -static void interpret_stereo_video_info_info() -{ - -} -static void interpret_post_filter_hints_info() -{ - -} -static void interpret_tone_mapping() -{ - -} -static void interpret_frame_packing_arrangement_info() -{ - -} -static void interpret_mvc_scalability_info() -{ - -} - -static MPP_RET interpret_recovery_point_info(RK_U8 *payload, RK_S32 size, BitReadCtx_t *p_bitctx, H264_SEI_t *sei_msg) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - mpp_set_bitread_ctx(p_bitctx, payload, size); - mpp_set_pre_detection(p_bitctx); - - READ_UE(p_bitctx, &sei_msg->recovery_point.recovery_frame_cnt, "recovery_frame_cnt"); - READ_ONEBIT(p_bitctx, &sei_msg->recovery_point.exact_match_flag, "exact_match_flag"); - READ_ONEBIT(p_bitctx, &sei_msg->recovery_point.broken_link_flag, "broken_link_flag"); - READ_BITS(p_bitctx, 2, &sei_msg->recovery_point.changing_slice_group_idc, "changing_slice_group_idc"); - - return ret = MPP_OK; -__BITREAD_ERR: - ret = p_bitctx->ret; - return ret; -} - - -static MPP_RET interpret_mvc_scalable_nesting_info(RK_U8 *payload, RK_S32 size, BitReadCtx_t *p_bitctx) -{ - RK_S32 i; - RK_U32 operation_point_flag; - RK_U32 all_view_components_in_au_flag; - RK_S32 num_view_components_minus1; - RK_S32 sei_view_id; - RK_S32 num_view_components_op_minus1; - RK_S32 sei_op_view_id; - RK_S32 sei_op_temporal_id; - MPP_RET ret = MPP_ERR_UNKNOW; - - BitReadCtx_t tmp_strmdata = { 0 }; - BitReadCtx_t *p_strm = &tmp_strmdata; - mpp_set_bitread_ctx(p_strm, payload, size); - mpp_set_pre_detection(p_bitctx); - - READ_ONEBIT(p_strm, &operation_point_flag, "operation_point_flag"); - if (!operation_point_flag) { - READ_ONEBIT(p_strm, &all_view_components_in_au_flag, "all_view_components_in_au_flag"); - READ_UE(p_strm, &num_view_components_minus1, "num_view_components_minus1"); - for (i = 0; i <= num_view_components_minus1; i++) { - READ_BITS(p_strm, 10, &sei_view_id, "sei_view_id"); - } - } else { - READ_UE(p_strm, &num_view_components_op_minus1, "num_view_components_op_minus1"); - for (i = 0; i <= num_view_components_op_minus1; i++) { - READ_BITS(p_strm, 10, &sei_op_view_id, "sei_op_view_id"); - } - READ_BITS(p_strm, 3, &sei_op_temporal_id, "sei_op_temporal_id"); - } - - p_bitctx->used_bits = p_strm->used_bits; - return ret = MPP_OK; -__BITREAD_ERR: - ret = p_bitctx->ret; - return ret; -} - -static MPP_RET interpret_buffering_period_info(RK_U8 *payload, RK_S32 size, BitReadCtx_t *p_bitctx, H264_SEI_t *sei_msg) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - BitReadCtx_t tmp_strmdata = { 0 }; - - p_bitctx = &tmp_strmdata; - mpp_set_bitread_ctx(p_bitctx, payload, size); - mpp_set_pre_detection(p_bitctx); - READ_UE(p_bitctx, &sei_msg->seq_parameter_set_id, "seq_parameter_set_id"); - //mpp_log("sei_msg->seq_parameter_set_id=%d \n", sei_msg->seq_parameter_set_id); - CHECK_RANGE(p_bitctx, sei_msg->seq_parameter_set_id, 0, 32); - return ret = MPP_OK; -__BITREAD_ERR: - ret = p_bitctx->ret; - return ret; - -} - -static void interpret_reserved_info(RK_U8 *payload, RK_S32 size, BitReadCtx_t *p_bitctx, H264_SEI_t *sei_msg) -{ - RK_S32 offset = 0; - RK_U8 payload_byte = 0; - - while (offset < size) { - payload_byte = payload[offset]; - offset++; - } - (void)p_bitctx; - (void)sei_msg; - (void)payload_byte; -} - -static MPP_RET parserSEI(H264_SLICE_t *cur_slice, BitReadCtx_t *p_bitctx, H264_SEI_t *sei_msg, RK_U8 *msg) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - H264dVideoCtx_t *p_Vid = cur_slice->p_Vid; - - H264D_DBG(H264D_DBG_SEI, "[SEI_info] type=%d \n", sei_msg->type); - switch (sei_msg->type) { - case SEI_BUFFERING_PERIOD: - FUN_CHECK(ret = interpret_buffering_period_info(msg, sei_msg->payload_size, p_bitctx, sei_msg)); - { - H264_SPS_t *sps = NULL; - H264_subSPS_t *subset_sps = NULL; - if (sei_msg->mvc_scalable_nesting_flag) { - p_Vid->active_mvc_sps_flag = 1; - sps = NULL; - subset_sps = &p_Vid->subspsSet[sei_msg->seq_parameter_set_id]; - } else { - p_Vid->active_mvc_sps_flag = 0; - sps = &p_Vid->spsSet[sei_msg->seq_parameter_set_id]; - subset_sps = NULL; - } - p_Vid->exit_picture_flag = 1; - FUN_CHECK(ret = activate_sps(p_Vid, sps, subset_sps)); - } - break; - case SEI_PIC_TIMING: - interpret_picture_timing_info(); - break; - case SEI_PAN_SCAN_RECT: - interpret_pan_scan_rect_info(); - break; - case SEI_FILLER_PAYLOAD: - interpret_filler_payload_info(); - break; - case SEI_USER_DATA_REGISTERED_ITU_T_T35: - interpret_user_data_registered_itu_t_t35_info(); - break; - case SEI_USER_DATA_UNREGISTERED: - FUN_CHECK(ret = interpret_user_data_unregistered_info(msg, sei_msg->payload_size, sei_msg)); - break; - case SEI_RECOVERY_POINT: - FUN_CHECK(ret = interpret_recovery_point_info(msg, sei_msg->payload_size, p_bitctx, sei_msg)); - break; - case SEI_DEC_REF_PIC_MARKING_REPETITION: - interpret_dec_ref_pic_marking_repetition_info(); - break; - case SEI_SPARE_PIC: - interpret_spare_pic(); - break; - case SEI_SCENE_INFO: - interpret_scene_information(); - break; - case SEI_SUB_SEQ_INFO: - interpret_subsequence_info(); - break; - case SEI_SUB_SEQ_LAYER_CHARACTERISTICS: - interpret_subsequence_layer_characteristics_info(); - break; - case SEI_SUB_SEQ_CHARACTERISTICS: - interpret_subsequence_characteristics_info(); - break; - case SEI_FULL_FRAME_FREEZE: - interpret_full_frame_freeze_info(); - break; - case SEI_FULL_FRAME_FREEZE_RELEASE: - interpret_full_frame_freeze_release_info(); - break; - case SEI_FULL_FRAME_SNAPSHOT: - interpret_full_frame_snapshot_info(); - break; - case SEI_PROGRESSIVE_REFINEMENT_SEGMENT_START: - interpret_progressive_refinement_start_info(); - break; - case SEI_PROGRESSIVE_REFINEMENT_SEGMENT_END: - interpret_progressive_refinement_end_info(); - break; - case SEI_MOTION_CONSTRAINED_SLICE_GROUP_SET: - interpret_motion_constrained_slice_group_set_info(); - case SEI_FILM_GRAIN_CHARACTERISTICS: - interpret_film_grain_characteristics_info(); - break; - case SEI_DEBLOCKING_FILTER_DISPLAY_PREFERENCE: - interpret_deblocking_filter_display_preference_info(); - break; - case SEI_STEREO_VIDEO_INFO: - interpret_stereo_video_info_info(); - break; - case SEI_TONE_MAPPING: - interpret_tone_mapping(); - break; - case SEI_POST_FILTER_HINTS: - interpret_post_filter_hints_info(); - break; - case SEI_FRAME_PACKING_ARRANGEMENT: - interpret_frame_packing_arrangement_info(); - break; - case SEI_MVC_SCALABLE_NESTING: - FUN_CHECK(ret = interpret_mvc_scalable_nesting_info(msg, sei_msg->payload_size, p_bitctx)); - sei_msg->mvc_scalable_nesting_flag = 1; - break; - case SEI_VIEW_SCALABILITY_INFO: - interpret_mvc_scalability_info(); - break; - default: - interpret_reserved_info(msg, sei_msg->payload_size, p_bitctx, sei_msg); - break; - } - - return ret = MPP_OK; -__FAILED: - return ret; -} -/*! -*********************************************************************** -* \brief -* parse SEI information -*********************************************************************** -*/ -//extern "C" -MPP_RET process_sei(H264_SLICE_t *currSlice) -{ - RK_S32 nn = 0; - RK_S32 tmp_byte = 0; - MPP_RET ret = MPP_ERR_UNKNOW; - H264_SEI_t *sei_msg = &currSlice->p_Cur->sei; - BitReadCtx_t *p_bitctx = &currSlice->p_Cur->bitctx; - - FunctionIn(currSlice->logctx->parr[RUN_PARSE]); - memset(sei_msg, 0, sizeof(*sei_msg)); - sei_msg->mvc_scalable_nesting_flag = 0; //init to false - sei_msg->p_Dec = currSlice->p_Dec; - do { - sei_msg->type = 0; - READ_BITS(p_bitctx, 8, &tmp_byte, "tmp_byte"); - while (tmp_byte == 0xFF) { - sei_msg->type += 255; - READ_BITS(p_bitctx, 8, &tmp_byte, "tmp_type"); - } - sei_msg->type += tmp_byte; // this is the last byte - - sei_msg->payload_size = 0; - READ_BITS(p_bitctx, 8, &tmp_byte, "tmp_type"); - while (tmp_byte == 0xFF) { - sei_msg->payload_size += 255; - READ_BITS(p_bitctx, 8, &tmp_byte, "tmp_type"); - } - sei_msg->payload_size += tmp_byte; // this is the last byte - - //--- read sei info - FUN_CHECK(ret = parserSEI(currSlice, p_bitctx, sei_msg, p_bitctx->data_)); - //--- set offset to read next sei nal - if (SEI_MVC_SCALABLE_NESTING == sei_msg->type) { - sei_msg->payload_size = ((p_bitctx->used_bits + 0x07) >> 3); - } - for (nn = 0; nn < sei_msg->payload_size; nn++) { // read bytes - READ_BITS(p_bitctx, 8, &tmp_byte, "tmp_byte"); - } - - } while ((p_bitctx->data_[0] != 0x80) && (p_bitctx->bytes_left_ > 1)); // more_rbsp_data() msg[offset] != 0x80 - - FunctionOut(currSlice->logctx->parr[RUN_PARSE]); - - return ret = MPP_OK; -__BITREAD_ERR: - ret = p_bitctx->ret; -__FAILED: - return ret; -} +/* +* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#define MODULE_TAG "h264d_sei" + +#include +#include + +#include "vpu_api.h" + +#include "h264d_log.h" +#include "h264d_sps.h" +#include "h264d_sei.h" + + +#ifndef _WIN32 +#include +char *_strupr(char *str) +{ + char *orign = str; + for (; *str != '\0'; str++) { + *str = toupper(*str); + } + return orign; +} +#endif + +static void interpret_spare_pic() +{ + +} +static void interpret_subsequence_info() +{ + +} +static void interpret_subsequence_layer_characteristics_info() +{ + +} +static void interpret_subsequence_characteristics_info() +{ + +} +static void interpret_scene_information() +{ + +} +static void interpret_user_data_registered_itu_t_t35_info() +{ + +} + +static MPP_RET interpret_user_data_unregistered_info(RK_U8 *payload, RK_S32 size, H264_SEI_t *sei_msg) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + + H264D_DBG(H264D_DBG_SEI, "[SEI_info] user data info, size=%d", size); + ASSERT(size >= 16); + + sei_msg->user_data_DivX_flag = strstr(_strupr((char *)&payload[16]), "DIVX") ? 1 : 0; + if (sei_msg->user_data_DivX_flag) { + H264D_ERR("DivX is not supported. \n"); + sei_msg->p_Dec->errctx.un_spt_flag = 1; + ret = MPP_NOK; + goto __FAILED; + } + + return ret = MPP_OK; +__FAILED: + return ret; +} + +static void interpret_pan_scan_rect_info() +{ + +} +static void interpret_filler_payload_info() +{ + +} +static void interpret_dec_ref_pic_marking_repetition_info() +{ + +} +static void interpret_full_frame_freeze_info() +{ + +} +static void interpret_full_frame_freeze_release_info() +{ + +} +static void interpret_full_frame_snapshot_info() +{ + +} +static void interpret_progressive_refinement_start_info() +{ + +} +static void interpret_progressive_refinement_end_info() +{ + +} +static void interpret_motion_constrained_slice_group_set_info() +{ + +} +static void interpret_picture_timing_info() +{ + +} +static void interpret_film_grain_characteristics_info() +{ + +} +static void interpret_deblocking_filter_display_preference_info() +{ + +} +static void interpret_stereo_video_info_info() +{ + +} +static void interpret_post_filter_hints_info() +{ + +} +static void interpret_tone_mapping() +{ + +} +static void interpret_frame_packing_arrangement_info() +{ + +} +static void interpret_mvc_scalability_info() +{ + +} + +static MPP_RET interpret_recovery_point_info(RK_U8 *payload, RK_S32 size, BitReadCtx_t *p_bitctx, H264_SEI_t *sei_msg) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + mpp_set_bitread_ctx(p_bitctx, payload, size); + mpp_set_pre_detection(p_bitctx); + + READ_UE(p_bitctx, &sei_msg->recovery_point.recovery_frame_cnt, "recovery_frame_cnt"); + READ_ONEBIT(p_bitctx, &sei_msg->recovery_point.exact_match_flag, "exact_match_flag"); + READ_ONEBIT(p_bitctx, &sei_msg->recovery_point.broken_link_flag, "broken_link_flag"); + READ_BITS(p_bitctx, 2, &sei_msg->recovery_point.changing_slice_group_idc, "changing_slice_group_idc"); + + return ret = MPP_OK; +__BITREAD_ERR: + ret = p_bitctx->ret; + return ret; +} + + +static MPP_RET interpret_mvc_scalable_nesting_info(RK_U8 *payload, RK_S32 size, BitReadCtx_t *p_bitctx) +{ + RK_S32 i; + RK_U32 operation_point_flag; + RK_U32 all_view_components_in_au_flag; + RK_S32 num_view_components_minus1; + RK_S32 sei_view_id; + RK_S32 num_view_components_op_minus1; + RK_S32 sei_op_view_id; + RK_S32 sei_op_temporal_id; + MPP_RET ret = MPP_ERR_UNKNOW; + + BitReadCtx_t tmp_strmdata = { 0 }; + BitReadCtx_t *p_strm = &tmp_strmdata; + mpp_set_bitread_ctx(p_strm, payload, size); + mpp_set_pre_detection(p_bitctx); + + READ_ONEBIT(p_strm, &operation_point_flag, "operation_point_flag"); + if (!operation_point_flag) { + READ_ONEBIT(p_strm, &all_view_components_in_au_flag, "all_view_components_in_au_flag"); + READ_UE(p_strm, &num_view_components_minus1, "num_view_components_minus1"); + for (i = 0; i <= num_view_components_minus1; i++) { + READ_BITS(p_strm, 10, &sei_view_id, "sei_view_id"); + } + } else { + READ_UE(p_strm, &num_view_components_op_minus1, "num_view_components_op_minus1"); + for (i = 0; i <= num_view_components_op_minus1; i++) { + READ_BITS(p_strm, 10, &sei_op_view_id, "sei_op_view_id"); + } + READ_BITS(p_strm, 3, &sei_op_temporal_id, "sei_op_temporal_id"); + } + + p_bitctx->used_bits = p_strm->used_bits; + return ret = MPP_OK; +__BITREAD_ERR: + ret = p_bitctx->ret; + return ret; +} + +static MPP_RET interpret_buffering_period_info(RK_U8 *payload, RK_S32 size, BitReadCtx_t *p_bitctx, H264_SEI_t *sei_msg) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + BitReadCtx_t tmp_strmdata = { 0 }; + + p_bitctx = &tmp_strmdata; + mpp_set_bitread_ctx(p_bitctx, payload, size); + mpp_set_pre_detection(p_bitctx); + READ_UE(p_bitctx, &sei_msg->seq_parameter_set_id, "seq_parameter_set_id"); + //mpp_log("sei_msg->seq_parameter_set_id=%d \n", sei_msg->seq_parameter_set_id); + CHECK_RANGE(p_bitctx, sei_msg->seq_parameter_set_id, 0, 32); + return ret = MPP_OK; +__BITREAD_ERR: + ret = p_bitctx->ret; + return ret; + +} + +static void interpret_reserved_info(RK_U8 *payload, RK_S32 size, BitReadCtx_t *p_bitctx, H264_SEI_t *sei_msg) +{ + RK_S32 offset = 0; + RK_U8 payload_byte = 0; + + while (offset < size) { + payload_byte = payload[offset]; + offset++; + } + (void)p_bitctx; + (void)sei_msg; + (void)payload_byte; +} + +static MPP_RET parserSEI(H264_SLICE_t *cur_slice, BitReadCtx_t *p_bitctx, H264_SEI_t *sei_msg, RK_U8 *msg) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + H264dVideoCtx_t *p_Vid = cur_slice->p_Vid; + + H264D_DBG(H264D_DBG_SEI, "[SEI_info] type=%d \n", sei_msg->type); + switch (sei_msg->type) { + case SEI_BUFFERING_PERIOD: + FUN_CHECK(ret = interpret_buffering_period_info(msg, sei_msg->payload_size, p_bitctx, sei_msg)); + { + H264_SPS_t *sps = NULL; + H264_subSPS_t *subset_sps = NULL; + if (sei_msg->mvc_scalable_nesting_flag) { + p_Vid->active_mvc_sps_flag = 1; + sps = NULL; + subset_sps = &p_Vid->subspsSet[sei_msg->seq_parameter_set_id]; + } else { + p_Vid->active_mvc_sps_flag = 0; + sps = &p_Vid->spsSet[sei_msg->seq_parameter_set_id]; + subset_sps = NULL; + } + p_Vid->exit_picture_flag = 1; + FUN_CHECK(ret = activate_sps(p_Vid, sps, subset_sps)); + } + break; + case SEI_PIC_TIMING: + interpret_picture_timing_info(); + break; + case SEI_PAN_SCAN_RECT: + interpret_pan_scan_rect_info(); + break; + case SEI_FILLER_PAYLOAD: + interpret_filler_payload_info(); + break; + case SEI_USER_DATA_REGISTERED_ITU_T_T35: + interpret_user_data_registered_itu_t_t35_info(); + break; + case SEI_USER_DATA_UNREGISTERED: + FUN_CHECK(ret = interpret_user_data_unregistered_info(msg, sei_msg->payload_size, sei_msg)); + break; + case SEI_RECOVERY_POINT: + FUN_CHECK(ret = interpret_recovery_point_info(msg, sei_msg->payload_size, p_bitctx, sei_msg)); + break; + case SEI_DEC_REF_PIC_MARKING_REPETITION: + interpret_dec_ref_pic_marking_repetition_info(); + break; + case SEI_SPARE_PIC: + interpret_spare_pic(); + break; + case SEI_SCENE_INFO: + interpret_scene_information(); + break; + case SEI_SUB_SEQ_INFO: + interpret_subsequence_info(); + break; + case SEI_SUB_SEQ_LAYER_CHARACTERISTICS: + interpret_subsequence_layer_characteristics_info(); + break; + case SEI_SUB_SEQ_CHARACTERISTICS: + interpret_subsequence_characteristics_info(); + break; + case SEI_FULL_FRAME_FREEZE: + interpret_full_frame_freeze_info(); + break; + case SEI_FULL_FRAME_FREEZE_RELEASE: + interpret_full_frame_freeze_release_info(); + break; + case SEI_FULL_FRAME_SNAPSHOT: + interpret_full_frame_snapshot_info(); + break; + case SEI_PROGRESSIVE_REFINEMENT_SEGMENT_START: + interpret_progressive_refinement_start_info(); + break; + case SEI_PROGRESSIVE_REFINEMENT_SEGMENT_END: + interpret_progressive_refinement_end_info(); + break; + case SEI_MOTION_CONSTRAINED_SLICE_GROUP_SET: + interpret_motion_constrained_slice_group_set_info(); + case SEI_FILM_GRAIN_CHARACTERISTICS: + interpret_film_grain_characteristics_info(); + break; + case SEI_DEBLOCKING_FILTER_DISPLAY_PREFERENCE: + interpret_deblocking_filter_display_preference_info(); + break; + case SEI_STEREO_VIDEO_INFO: + interpret_stereo_video_info_info(); + break; + case SEI_TONE_MAPPING: + interpret_tone_mapping(); + break; + case SEI_POST_FILTER_HINTS: + interpret_post_filter_hints_info(); + break; + case SEI_FRAME_PACKING_ARRANGEMENT: + interpret_frame_packing_arrangement_info(); + break; + case SEI_MVC_SCALABLE_NESTING: + FUN_CHECK(ret = interpret_mvc_scalable_nesting_info(msg, sei_msg->payload_size, p_bitctx)); + sei_msg->mvc_scalable_nesting_flag = 1; + break; + case SEI_VIEW_SCALABILITY_INFO: + interpret_mvc_scalability_info(); + break; + default: + interpret_reserved_info(msg, sei_msg->payload_size, p_bitctx, sei_msg); + break; + } + + return ret = MPP_OK; +__FAILED: + return ret; +} +/*! +*********************************************************************** +* \brief +* parse SEI information +*********************************************************************** +*/ +//extern "C" +MPP_RET process_sei(H264_SLICE_t *currSlice) +{ + RK_S32 nn = 0; + RK_S32 tmp_byte = 0; + MPP_RET ret = MPP_ERR_UNKNOW; + H264_SEI_t *sei_msg = &currSlice->p_Cur->sei; + BitReadCtx_t *p_bitctx = &currSlice->p_Cur->bitctx; + + FunctionIn(currSlice->logctx->parr[RUN_PARSE]); + memset(sei_msg, 0, sizeof(*sei_msg)); + sei_msg->mvc_scalable_nesting_flag = 0; //init to false + sei_msg->p_Dec = currSlice->p_Dec; + do { + sei_msg->type = 0; + READ_BITS(p_bitctx, 8, &tmp_byte, "tmp_byte"); + while (tmp_byte == 0xFF) { + sei_msg->type += 255; + READ_BITS(p_bitctx, 8, &tmp_byte, "tmp_type"); + } + sei_msg->type += tmp_byte; // this is the last byte + + sei_msg->payload_size = 0; + READ_BITS(p_bitctx, 8, &tmp_byte, "tmp_type"); + while (tmp_byte == 0xFF) { + sei_msg->payload_size += 255; + READ_BITS(p_bitctx, 8, &tmp_byte, "tmp_type"); + } + sei_msg->payload_size += tmp_byte; // this is the last byte + + //--- read sei info + FUN_CHECK(ret = parserSEI(currSlice, p_bitctx, sei_msg, p_bitctx->data_)); + //--- set offset to read next sei nal + if (SEI_MVC_SCALABLE_NESTING == sei_msg->type) { + sei_msg->payload_size = ((p_bitctx->used_bits + 0x07) >> 3); + } + for (nn = 0; nn < sei_msg->payload_size; nn++) { // read bytes + READ_BITS(p_bitctx, 8, &tmp_byte, "tmp_byte"); + } + + } while ((p_bitctx->data_[0] != 0x80) && (p_bitctx->bytes_left_ > 1)); // more_rbsp_data() msg[offset] != 0x80 + + FunctionOut(currSlice->logctx->parr[RUN_PARSE]); + + return ret = MPP_OK; +__BITREAD_ERR: + ret = p_bitctx->ret; +__FAILED: + return ret; +} diff --git a/mpp/codec/dec/h264/h264d_sei.h b/mpp/codec/dec/h264/h264d_sei.h index fd1fcefb..05faf5ac 100644 --- a/mpp/codec/dec/h264/h264d_sei.h +++ b/mpp/codec/dec/h264/h264d_sei.h @@ -1,37 +1,37 @@ -/* -* -* Copyright 2015 Rockchip Electronics Co. LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#ifndef _H264D_SEI_H_ -#define _H264D_SEI_H_ - -#include "rk_type.h" -#include "mpp_err.h" -#include "h264d_global.h" - -#ifdef __cplusplus -extern "C" { -#endif - -MPP_RET process_sei(H264_SLICE_t *currSlice); - -#ifdef __cplusplus -} -#endif - -//======================================== -#endif /* end of _H264D_SEI_H_ */ - +/* +* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef _H264D_SEI_H_ +#define _H264D_SEI_H_ + +#include "rk_type.h" +#include "mpp_err.h" +#include "h264d_global.h" + +#ifdef __cplusplus +extern "C" { +#endif + +MPP_RET process_sei(H264_SLICE_t *currSlice); + +#ifdef __cplusplus +} +#endif + +//======================================== +#endif /* end of _H264D_SEI_H_ */ + diff --git a/mpp/codec/dec/h264/h264d_slice.c b/mpp/codec/dec/h264/h264d_slice.c index 1cf35d35..d696944f 100644 --- a/mpp/codec/dec/h264/h264d_slice.c +++ b/mpp/codec/dec/h264/h264d_slice.c @@ -1,527 +1,527 @@ -/* -* -* Copyright 2015 Rockchip Electronics Co. LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#define MODULE_TAG "h264d_slice" - -#include "mpp_mem.h" - -#include "h264d_log.h" -#include "h264d_slice.h" -#include "h264d_sps.h" -#include "h264d_pps.h" - - - -static MPP_RET ref_pic_list_mvc_modification(H264_SLICE_t *currSlice) -{ - RK_U32 i = 0; - MPP_RET ret = MPP_ERR_UNKNOW; - RK_S32 modification_of_pic_nums_idc = 0; - BitReadCtx_t *p_bitctx = &currSlice->p_Cur->bitctx; - - if ((currSlice->slice_type % 5) != I_SLICE && (currSlice->slice_type % 5) != SI_SLICE) { - READ_ONEBIT(p_bitctx, &currSlice->ref_pic_list_reordering_flag[LIST_0], "ref_pic_list_reordering_flag"); - if (currSlice->ref_pic_list_reordering_flag[LIST_0]) { - RK_U32 size = currSlice->num_ref_idx_active[LIST_0] + 1; - i = 0; - do { - if (i >= size) { - ret = MPP_NOK; - H264D_WARNNING("ref_pic_list_reordering error, i >= num_ref_idx_active[LIST_0](%d)", size); - goto __BITREAD_ERR; - } - READ_UE(p_bitctx, &modification_of_pic_nums_idc, "modification_of_pic_nums_idc"); - currSlice->modification_of_pic_nums_idc[LIST_0][i] = modification_of_pic_nums_idc; - if (modification_of_pic_nums_idc == 0 || modification_of_pic_nums_idc == 1) { - READ_UE(p_bitctx, &currSlice->abs_diff_pic_num_minus1[LIST_0][i], "abs_diff_pic_num_minus1_lx"); - } else { - if (modification_of_pic_nums_idc == 2) { - READ_UE(p_bitctx, &currSlice->long_term_pic_idx[LIST_0][i], "long_term_pic_idx"); - } else if (modification_of_pic_nums_idc == 4 || modification_of_pic_nums_idc == 5) { - READ_UE(p_bitctx, &currSlice->abs_diff_view_idx_minus1[LIST_0][i], "abs_diff_view_idx_minus1"); - } - } - i++; - } while (modification_of_pic_nums_idc != 3); - } - } - if (currSlice->slice_type % 5 == B_SLICE) { - READ_ONEBIT(p_bitctx, &currSlice->ref_pic_list_reordering_flag[LIST_1], "ref_pic_list_reordering_flag"); - if (currSlice->ref_pic_list_reordering_flag[LIST_1]) { - RK_U32 size = currSlice->num_ref_idx_active[LIST_1] + 1; - i = 0; - do { - if (i >= size) { - ret = MPP_NOK; - H264D_WARNNING("ref_pic_list_reordering error, i >= num_ref_idx_active[LIST_1](%d)", size); - goto __BITREAD_ERR; - } - READ_UE(p_bitctx, &modification_of_pic_nums_idc, "modification_of_pic_nums_idc"); - currSlice->modification_of_pic_nums_idc[LIST_1][i] = modification_of_pic_nums_idc; - if (modification_of_pic_nums_idc == 0 || modification_of_pic_nums_idc == 1) { - READ_UE(p_bitctx, &currSlice->abs_diff_pic_num_minus1[LIST_1][i], "abs_diff_pic_num_minus1_lx"); - } else { - if (modification_of_pic_nums_idc == 2) { - READ_UE(p_bitctx, &currSlice->long_term_pic_idx[LIST_1][i], "long_term_pic_idx"); - } else if (modification_of_pic_nums_idc == 4 || modification_of_pic_nums_idc == 5) { - READ_UE(p_bitctx, &currSlice->abs_diff_view_idx_minus1[LIST_1][i], "abs_diff_view_idx_minus1"); - } - } - i++; - } while (modification_of_pic_nums_idc != 3); - } - } - ASSERT(currSlice->redundant_pic_cnt == 0); //!< not support reference index of redundant slices - - return ret = MPP_OK; -__BITREAD_ERR: - ret = p_bitctx->ret; - - return ret; -} - -static MPP_RET pred_weight_table(H264_SLICE_t *currSlice) -{ - RK_S32 se_tmp = 0; - MPP_RET ret = MPP_ERR_UNKNOW; - RK_S32 i = 0, j = 0, temp = 0; - BitReadCtx_t *p_bitctx = &currSlice->p_Cur->bitctx; - - READ_UE(p_bitctx, &temp, "log2_weight_denom"); - if (currSlice->active_sps->chroma_format_idc) { - READ_UE(p_bitctx, &temp, "log2_weight_denom"); - } - for (i = 0; i < currSlice->num_ref_idx_active[LIST_0]; i++) { - READ_ONEBIT(p_bitctx, &temp, "luma_weight_flag_l0"); - if (temp) { - READ_SE(p_bitctx, &se_tmp, "pred_weight"); //!< slice->wp_weight[LIST_0][i][0] - READ_SE(p_bitctx, &se_tmp, "pred_offset"); //!< slice->wp_offset[LIST_0][i][0] - } - if (currSlice->active_sps->chroma_format_idc) { - READ_ONEBIT(p_bitctx, &temp, "chroma_weight_flag_l0"); - for (j = 1; j < 3; j++) { - if (temp) { //!< chroma_weight_flag_l0 - READ_SE(p_bitctx, &se_tmp, "pred_weight"); //!< slice->wp_weight[LIST_0][i][j] - READ_SE(p_bitctx, &se_tmp, "pred_offset"); //!< slice->wp_offset[LIST_0][i][j] - } - } - } - } - - if ((currSlice->slice_type == B_SLICE) && currSlice->p_Vid->active_pps->weighted_bipred_idc == 1) { - for (i = 0; i < currSlice->num_ref_idx_active[LIST_1]; i++) { - READ_ONEBIT(p_bitctx, &temp, "luma_weight_flag_l1"); - if (temp) { - READ_SE(p_bitctx, &se_tmp, "pred_weight"); //!< slice->wp_weight[LIST_1][i][0] - READ_SE(p_bitctx, &se_tmp, "pred_offset"); //!< slice->wp_offset[LIST_1][i][0] - } - if (currSlice->active_sps->chroma_format_idc) { - READ_ONEBIT(p_bitctx, &temp, "chroma_weight_flag_l1"); - for (j = 1; j < 3; j++) { - if (temp) { // chroma_weight_flag_l1 - READ_SE(p_bitctx, &se_tmp, "pred_weight"); //!< slice->wp_weight[LIST_1][i][j] - READ_SE(p_bitctx, &se_tmp, "pred_offset"); //!< slice->wp_offset[LIST_1][i][j] - } - } - } - } - } - - return ret = MPP_OK; -__BITREAD_ERR: - return ret = p_bitctx->ret; -} - -static MPP_RET dec_ref_pic_marking(H264_SLICE_t *pSlice) -{ - RK_U32 val = 0; - MPP_RET ret = MPP_ERR_UNKNOW; - RK_U32 drpm_used_bits = 0; - H264_DRPM_t *tmp_drpm = NULL, *tmp_drpm2 = NULL; - H264dVideoCtx_t *p_Vid = pSlice->p_Vid; - BitReadCtx_t *p_bitctx = &pSlice->p_Cur->bitctx; - - drpm_used_bits = p_bitctx->used_bits; - pSlice->drpm_used_bitlen = 0; - - if (pSlice->idr_flag || - (pSlice->svc_extension_flag == 0 && pSlice->mvcExt.non_idr_flag == 0)) { - READ_ONEBIT(p_bitctx, &pSlice->no_output_of_prior_pics_flag, "no_output_of_prior_pics_flag"); - p_Vid->no_output_of_prior_pics_flag = pSlice->no_output_of_prior_pics_flag; - READ_ONEBIT(p_bitctx, &pSlice->long_term_reference_flag, "long_term_reference_flag"); - } else { - READ_ONEBIT(p_bitctx, &pSlice->adaptive_ref_pic_buffering_flag, "adaptive_ref_pic_buffering_flag"); - - if (pSlice->adaptive_ref_pic_buffering_flag) { - RK_U32 i = 0; - do { //!< read Memory Management Control Operation - tmp_drpm = &pSlice->p_Cur->dec_ref_pic_marking_buffer[i]; - tmp_drpm->Next = NULL; - READ_UE(p_bitctx, &val, "memory_management_control_operation"); - tmp_drpm->memory_management_control_operation = val; - - if ((val == 1) || (val == 3)) { - READ_UE(p_bitctx, &tmp_drpm->difference_of_pic_nums_minus1, "difference_of_pic_nums_minus1"); - } - if (val == 2) { - READ_UE(p_bitctx, &tmp_drpm->long_term_pic_num, "long_term_pic_num"); - } - if ((val == 3) || (val == 6)) { - READ_UE(p_bitctx, &tmp_drpm->long_term_frame_idx, "long_term_frame_idx"); - } - if (val == 4) { - READ_UE(p_bitctx, &tmp_drpm->max_long_term_frame_idx_plus1, "max_long_term_frame_idx_plus1"); - } - // add command - if (pSlice->dec_ref_pic_marking_buffer == NULL) { - pSlice->dec_ref_pic_marking_buffer = tmp_drpm; - } else { - tmp_drpm2 = pSlice->dec_ref_pic_marking_buffer; - while (tmp_drpm2->Next != NULL) { - tmp_drpm2 = tmp_drpm2->Next; - } - tmp_drpm2->Next = tmp_drpm; - } - i++; - } while (val != 0); - } - } - pSlice->drpm_used_bitlen = p_bitctx->used_bits - drpm_used_bits; - return ret = MPP_OK; -__BITREAD_ERR: - ret = p_bitctx->ret; - - return ret; -} - -static void init_slice_parmeters(H264_SLICE_t *currSlice) -{ - H264dVideoCtx_t *p_Vid = currSlice->p_Vid; - H264_Nalu_t *cur_nalu = &currSlice->p_Cur->nalu; - - //--- init slice syntax - currSlice->idr_flag = ((cur_nalu->nalu_type == NALU_TYPE_IDR) - || (currSlice->mvcExt.valid && !currSlice->mvcExt.non_idr_flag)); - currSlice->nal_reference_idc = cur_nalu->nal_reference_idc; - //!< set ref flag and dpb error flag - { - p_Vid->p_Dec->errctx.used_ref_flag = currSlice->nal_reference_idc ? 1 : 0; - if (currSlice->slice_type == I_SLICE) { - p_Vid->p_Dec->errctx.dpb_err_flag = 0; - } - } - if ((!currSlice->svc_extension_flag) || currSlice->mvcExt.iPrefixNALU) { // MVC or have prefixNALU - currSlice->view_id = currSlice->mvcExt.view_id; - currSlice->inter_view_flag = currSlice->mvcExt.inter_view_flag; - currSlice->anchor_pic_flag = currSlice->mvcExt.anchor_pic_flag; - } else if (currSlice->svc_extension_flag == -1) { // normal AVC - currSlice->view_id = currSlice->mvcExt.valid ? p_Vid->active_subsps->view_id[0] : 0; - currSlice->inter_view_flag = 1; - currSlice->anchor_pic_flag = currSlice->idr_flag; - } - currSlice->layer_id = currSlice->view_id; - if (currSlice->layer_id >= 0) { // if not found, layer_id == -1 - currSlice->p_Dpb = p_Vid->p_Dpb_layer[currSlice->layer_id]; - } -} - -static MPP_RET check_sps_pps(H264_SPS_t *sps, H264_subSPS_t *subset_sps, H264_PPS_t *pps) -{ - RK_U32 ret = 0; - - ret |= (sps->seq_parameter_set_id > 63); - ret |= (sps->separate_colour_plane_flag == 1); - ret |= (sps->chroma_format_idc == 3); - ret |= (sps->bit_depth_luma_minus8 > 2); - ret |= (sps->bit_depth_chroma_minus8 > 2); - ret |= (sps->log2_max_frame_num_minus4 > 12); - ret |= (sps->pic_order_cnt_type > 2); - ret |= (sps->log2_max_pic_order_cnt_lsb_minus4 > 12); - ret |= (sps->num_ref_frames_in_pic_order_cnt_cycle > 255); - ret |= (sps->max_num_ref_frames > 16); - ret |= (sps->pic_width_in_mbs_minus1 > 4095); - ret |= (sps->pic_height_in_map_units_minus1 > 2303); - ret |= (sps->pic_height_in_map_units_minus1 > 2303); - if (ret) { - H264D_ERR("sps has error, sps_id=%d", sps->seq_parameter_set_id); - goto __FAILED; - } - if (subset_sps) { //!< MVC - ret |= (subset_sps->num_views_minus1 != 1); - // ret |= (subset_sps->num_anchor_refs_l0[0] != 1); - if (subset_sps->num_anchor_refs_l0[0] > 0) - ret |= (subset_sps->anchor_ref_l0[0][0] != subset_sps->view_id[0]); - // ret |= (subset_sps->num_anchor_refs_l1[0] != 1); - if (subset_sps->num_anchor_refs_l1[0] > 0) - ret |= (subset_sps->anchor_ref_l1[0][0] != subset_sps->view_id[1]); - - // ret |= (subset_sps->num_non_anchor_refs_l0[0] != 1); - if (subset_sps->num_non_anchor_refs_l0[0] > 0) - ret |= (subset_sps->non_anchor_ref_l0[0][0] != subset_sps->view_id[0]); - // ret |= (subset_sps->num_non_anchor_refs_l1[0] != 1); - if (subset_sps->num_non_anchor_refs_l1[0] > 0) - ret |= (subset_sps->non_anchor_ref_l1[0][0] != subset_sps->view_id[1]); - - //ret |= (subset_sps->num_applicable_ops_minus1[0] > 1); - if (ret) { - H264D_ERR("subsps has error, sps_id=%d", sps->seq_parameter_set_id); - goto __FAILED; - } - } - //!< check PPS - ret |= (pps->pic_parameter_set_id > 255); - ret |= (pps->seq_parameter_set_id > 63); - ret |= (pps->num_slice_groups_minus1 > 0); - ret |= (pps->num_ref_idx_l0_default_active_minus1 > 31); - ret |= (pps->num_ref_idx_l1_default_active_minus1 > 31); - ret |= (pps->pic_init_qp_minus26 > 25 || pps->pic_init_qp_minus26 < -(26 + 6 * (RK_S32)sps->bit_depth_luma_minus8)); - ret |= (pps->pic_init_qs_minus26 > 25 || pps->pic_init_qs_minus26 < -26); - ret |= (pps->chroma_qp_index_offset > 12 || pps->chroma_qp_index_offset < -12); - ret |= (pps->redundant_pic_cnt_present_flag == 1); - if (ret) { - H264D_ERR("pps has error, sps_id=%d, pps_id", sps->seq_parameter_set_id, pps->pic_parameter_set_id); - goto __FAILED; - } - return MPP_OK; -__FAILED: - return MPP_NOK; -} - - -static MPP_RET set_slice_user_parmeters(H264_SLICE_t *currSlice) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - H264_PPS_t *cur_pps = NULL; - H264_SPS_t *cur_sps = NULL; - H264_subSPS_t *cur_subsps = NULL; - H264dVideoCtx_t *p_Vid = currSlice->p_Vid; - //!< use parameter set - cur_pps = &p_Vid->ppsSet[currSlice->pic_parameter_set_id]; - cur_pps = (cur_pps && cur_pps->Valid) ? cur_pps : NULL; - VAL_CHECK(ret, cur_pps != NULL); - - if (currSlice->mvcExt.valid) { - cur_sps = &p_Vid->subspsSet[cur_pps->seq_parameter_set_id].sps; - cur_subsps = &p_Vid->subspsSet[cur_pps->seq_parameter_set_id]; - if (cur_subsps->Valid) { - if ((RK_S32)currSlice->mvcExt.view_id == cur_subsps->view_id[0]) { // combine subsps to sps - p_Vid->active_mvc_sps_flag = 0; - cur_subsps = NULL; - cur_sps = &p_Vid->spsSet[cur_pps->seq_parameter_set_id]; - } else if ((RK_S32)currSlice->mvcExt.view_id == cur_subsps->view_id[1]) { - p_Vid->active_mvc_sps_flag = 1; - } - } else { - p_Vid->active_mvc_sps_flag = 0; - cur_sps = &p_Vid->spsSet[cur_pps->seq_parameter_set_id]; - cur_subsps = NULL; - } - } else { - p_Vid->active_mvc_sps_flag = 0; - cur_sps = &p_Vid->spsSet[cur_pps->seq_parameter_set_id]; - cur_subsps = NULL; - } - - if (p_Vid->active_mvc_sps_flag) { // layer_id == 1 - cur_subsps = (cur_subsps && cur_subsps->Valid) ? cur_subsps : NULL; - VAL_CHECK(ret, cur_subsps != NULL); - cur_sps = &cur_subsps->sps; - } else { //!< layer_id == 0 - cur_subsps = NULL; - cur_sps = (cur_sps && cur_sps->Valid) ? cur_sps : NULL; - VAL_CHECK(ret, cur_sps != NULL); - } - VAL_CHECK(ret, check_sps_pps(cur_sps, cur_subsps, cur_pps) != MPP_NOK); - - FUN_CHECK(ret = activate_sps(p_Vid, cur_sps, cur_subsps)); - FUN_CHECK(ret = activate_pps(p_Vid, cur_pps)); - - //!< Set SPS to the subset SPS parameters - if (currSlice->svc_extension_flag == 0) { - p_Vid->active_subsps = &p_Vid->subspsSet[cur_pps->seq_parameter_set_id]; - } - currSlice->active_sps = p_Vid->active_sps; - currSlice->active_pps = p_Vid->active_pps; - - p_Vid->type = currSlice->slice_type; - return MPP_OK; -__FAILED: - return ret; -} - - -/*! -*********************************************************************** -* \brief -* reset current slice buffer -*********************************************************************** -*/ -//extern "C" -MPP_RET reset_cur_slice(H264dCurCtx_t *p_Cur, H264_SLICE_t *p) -{ - if (p) { - p->modification_of_pic_nums_idc[LIST_0] = p_Cur->modification_of_pic_nums_idc[LIST_0]; - p->abs_diff_pic_num_minus1[LIST_0] = p_Cur->abs_diff_pic_num_minus1[LIST_0]; - p->long_term_pic_idx[LIST_0] = p_Cur->long_term_pic_idx[LIST_0]; - p->abs_diff_view_idx_minus1[LIST_0] = p_Cur->abs_diff_view_idx_minus1[LIST_0]; - - p->modification_of_pic_nums_idc[LIST_1] = p_Cur->modification_of_pic_nums_idc[LIST_1]; - p->abs_diff_pic_num_minus1[LIST_1] = p_Cur->abs_diff_pic_num_minus1[LIST_1]; - p->long_term_pic_idx[LIST_1] = p_Cur->long_term_pic_idx[LIST_1]; - p->abs_diff_view_idx_minus1[LIST_1] = p_Cur->abs_diff_view_idx_minus1[LIST_1]; - - p->dec_ref_pic_marking_buffer = NULL; - } - - return MPP_OK; -} - -/*! -*********************************************************************** -* \brief -* parse SEI information -*********************************************************************** -*/ -//extern "C" -MPP_RET process_slice(H264_SLICE_t *currSlice) -{ - RK_U32 temp = 0; - RK_U32 poc_used_bits = 0; - MPP_RET ret = MPP_ERR_UNKNOW; - H264dLogCtx_t *logctx = currSlice->logctx; - H264dVideoCtx_t *p_Vid = currSlice->p_Vid; - H264dCurCtx_t *p_Cur = currSlice->p_Cur; - BitReadCtx_t *p_bitctx = &p_Cur->bitctx; - - FunctionIn(logctx->parr[RUN_PARSE]); - //!< initial value - currSlice->p_Dpb_layer[0] = p_Vid->p_Dpb_layer[0]; - currSlice->p_Dpb_layer[1] = p_Vid->p_Dpb_layer[1]; - set_bitread_logctx(p_bitctx, logctx->parr[LOG_READ_SLICE]); - - LogInfo(p_bitctx->ctx, "----------------------------- SLICE begin --------------------------------"); - //!< read slice head syntax - READ_UE(p_bitctx, &currSlice->start_mb_nr, "first_mb_in_slice"); - READ_UE(p_bitctx, &temp, "slice_type"); - p_Vid->slice_type = currSlice->slice_type = temp % 5; - READ_UE(p_bitctx, &currSlice->pic_parameter_set_id, "slice_pic_parameter_set_id"); - init_slice_parmeters(currSlice); - FUN_CHECK(ret = set_slice_user_parmeters(currSlice)); - //!< read rest slice header syntax - { - READ_BITS(p_bitctx, currSlice->active_sps->log2_max_frame_num_minus4 + 4, &currSlice->frame_num, "frame_num"); - if (currSlice->active_sps->frame_mbs_only_flag) { //!< user in_slice info - p_Vid->structure = FRAME; - currSlice->field_pic_flag = 0; - currSlice->bottom_field_flag = 0; - } else { - READ_ONEBIT(p_bitctx, &currSlice->field_pic_flag, "field_pic_flag"); - if (currSlice->field_pic_flag) { - READ_ONEBIT(p_bitctx, &currSlice->bottom_field_flag, "field_pic_flag"); - p_Vid->structure = currSlice->bottom_field_flag ? BOTTOM_FIELD : TOP_FIELD; - } else { - p_Vid->structure = FRAME; - currSlice->bottom_field_flag = 0; - } - } - currSlice->structure = p_Vid->structure; - currSlice->mb_aff_frame_flag = (currSlice->active_sps->mb_adaptive_frame_field_flag && (currSlice->field_pic_flag == 0)); - if (currSlice->idr_flag) { - READ_UE(p_bitctx, &currSlice->idr_pic_id, "idr_pic_id"); - } else if (currSlice->svc_extension_flag == 0 && currSlice->mvcExt.non_idr_flag == 0) { - READ_UE(p_bitctx, &currSlice->idr_pic_id, "idr_pic_id"); - } - poc_used_bits = p_bitctx->used_bits; //!< init poc used bits - if (currSlice->active_sps->pic_order_cnt_type == 0) { - READ_BITS(p_bitctx, currSlice->active_sps->log2_max_pic_order_cnt_lsb_minus4 + 4, &currSlice->pic_order_cnt_lsb, "pic_order_cnt_lsb"); - if (currSlice->p_Vid->active_pps->bottom_field_pic_order_in_frame_present_flag == 1 - && !currSlice->field_pic_flag) { - READ_SE(p_bitctx, &currSlice->delta_pic_order_cnt_bottom, "delta_pic_order_cnt_bottom"); - } else { - currSlice->delta_pic_order_cnt_bottom = 0; - } - } - if (currSlice->active_sps->pic_order_cnt_type == 1) { - if (!currSlice->active_sps->delta_pic_order_always_zero_flag) { - READ_SE(p_bitctx, &currSlice->delta_pic_order_cnt[0], "delta_pic_order_cnt[0]"); - - if (currSlice->p_Vid->active_pps->bottom_field_pic_order_in_frame_present_flag == 1 && !currSlice->field_pic_flag) { - READ_SE(p_bitctx, &currSlice->delta_pic_order_cnt[1], "delta_pic_order_cnt[1]"); - } else { - currSlice->delta_pic_order_cnt[1] = 0; //!< set to zero if not in stream - } - } else { - currSlice->delta_pic_order_cnt[0] = 0; - currSlice->delta_pic_order_cnt[1] = 0; - } - } - currSlice->poc_used_bitlen = p_bitctx->used_bits - poc_used_bits; //!< calculate poc used bit length - //!< redundant_pic_cnt is missing here - ASSERT(currSlice->p_Vid->active_pps->redundant_pic_cnt_present_flag == 0); // add by dw, high 4:2:2 profile not support - if (currSlice->p_Vid->active_pps->redundant_pic_cnt_present_flag) { - READ_UE(p_bitctx, &currSlice->redundant_pic_cnt, "redundant_pic_cnt"); - } - - if (currSlice->slice_type == B_SLICE) { - READ_ONEBIT(p_bitctx, &currSlice->direct_spatial_mv_pred_flag, "direct_spatial_mv_pred_flag"); - } else { - currSlice->direct_spatial_mv_pred_flag = 0; - } - currSlice->num_ref_idx_active[LIST_0] = currSlice->p_Vid->active_pps->num_ref_idx_l0_default_active_minus1 + 1; - currSlice->num_ref_idx_active[LIST_1] = currSlice->p_Vid->active_pps->num_ref_idx_l1_default_active_minus1 + 1; - - if (currSlice->slice_type == P_SLICE - || currSlice->slice_type == SP_SLICE || currSlice->slice_type == B_SLICE) { - READ_ONEBIT(p_bitctx, &currSlice->num_ref_idx_override_flag, "num_ref_idx_override_flag"); - if (currSlice->num_ref_idx_override_flag) { - READ_UE(p_bitctx, &currSlice->num_ref_idx_active[LIST_0], "num_ref_idx_active0"); - currSlice->num_ref_idx_active[LIST_0] += 1; - if (currSlice->slice_type == B_SLICE) { - READ_UE(p_bitctx, &currSlice->num_ref_idx_active[LIST_1], "num_ref_idx_active1"); - currSlice->num_ref_idx_active[LIST_1] += 1; - } - } - } - if (currSlice->slice_type != B_SLICE) { - currSlice->num_ref_idx_active[LIST_1] = 0; - } - FUN_CHECK(ret = ref_pic_list_mvc_modification(currSlice)); - if ((currSlice->p_Vid->active_pps->weighted_pred_flag - && (currSlice->slice_type == P_SLICE || currSlice->slice_type == SP_SLICE)) - || (currSlice->p_Vid->active_pps->weighted_bipred_idc == 1 && (currSlice->slice_type == B_SLICE))) { - FUN_CHECK(ret = pred_weight_table(currSlice)); - } - currSlice->drpm_used_bitlen = 0; - if (currSlice->nal_reference_idc) { - FUN_CHECK(ret = dec_ref_pic_marking(currSlice)); - } - if (g_max_bytes < (p_bitctx->used_bits >> 3)) { - g_max_bytes = (p_bitctx->used_bits >> 3); - } - H264D_DBG(H264D_DBG_PPS_SPS, "[SLICE_HEAD] type=%d, layer_id=%d,sps_id=%d, pps_id=%d, struct=%d, frame_num=%d", - currSlice->slice_type, currSlice->layer_id, currSlice->active_sps->seq_parameter_set_id, - currSlice->active_pps->pic_parameter_set_id, currSlice->structure, currSlice->frame_num); - } - - FunctionOut(logctx->parr[RUN_PARSE]); - - return ret = MPP_OK; -__BITREAD_ERR: - ret = p_bitctx->ret; -__FAILED: - return ret; -} +/* +* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#define MODULE_TAG "h264d_slice" + +#include "mpp_mem.h" + +#include "h264d_log.h" +#include "h264d_slice.h" +#include "h264d_sps.h" +#include "h264d_pps.h" + + + +static MPP_RET ref_pic_list_mvc_modification(H264_SLICE_t *currSlice) +{ + RK_U32 i = 0; + MPP_RET ret = MPP_ERR_UNKNOW; + RK_S32 modification_of_pic_nums_idc = 0; + BitReadCtx_t *p_bitctx = &currSlice->p_Cur->bitctx; + + if ((currSlice->slice_type % 5) != I_SLICE && (currSlice->slice_type % 5) != SI_SLICE) { + READ_ONEBIT(p_bitctx, &currSlice->ref_pic_list_reordering_flag[LIST_0], "ref_pic_list_reordering_flag"); + if (currSlice->ref_pic_list_reordering_flag[LIST_0]) { + RK_U32 size = currSlice->num_ref_idx_active[LIST_0] + 1; + i = 0; + do { + if (i >= size) { + ret = MPP_NOK; + H264D_WARNNING("ref_pic_list_reordering error, i >= num_ref_idx_active[LIST_0](%d)", size); + goto __BITREAD_ERR; + } + READ_UE(p_bitctx, &modification_of_pic_nums_idc, "modification_of_pic_nums_idc"); + currSlice->modification_of_pic_nums_idc[LIST_0][i] = modification_of_pic_nums_idc; + if (modification_of_pic_nums_idc == 0 || modification_of_pic_nums_idc == 1) { + READ_UE(p_bitctx, &currSlice->abs_diff_pic_num_minus1[LIST_0][i], "abs_diff_pic_num_minus1_lx"); + } else { + if (modification_of_pic_nums_idc == 2) { + READ_UE(p_bitctx, &currSlice->long_term_pic_idx[LIST_0][i], "long_term_pic_idx"); + } else if (modification_of_pic_nums_idc == 4 || modification_of_pic_nums_idc == 5) { + READ_UE(p_bitctx, &currSlice->abs_diff_view_idx_minus1[LIST_0][i], "abs_diff_view_idx_minus1"); + } + } + i++; + } while (modification_of_pic_nums_idc != 3); + } + } + if (currSlice->slice_type % 5 == B_SLICE) { + READ_ONEBIT(p_bitctx, &currSlice->ref_pic_list_reordering_flag[LIST_1], "ref_pic_list_reordering_flag"); + if (currSlice->ref_pic_list_reordering_flag[LIST_1]) { + RK_U32 size = currSlice->num_ref_idx_active[LIST_1] + 1; + i = 0; + do { + if (i >= size) { + ret = MPP_NOK; + H264D_WARNNING("ref_pic_list_reordering error, i >= num_ref_idx_active[LIST_1](%d)", size); + goto __BITREAD_ERR; + } + READ_UE(p_bitctx, &modification_of_pic_nums_idc, "modification_of_pic_nums_idc"); + currSlice->modification_of_pic_nums_idc[LIST_1][i] = modification_of_pic_nums_idc; + if (modification_of_pic_nums_idc == 0 || modification_of_pic_nums_idc == 1) { + READ_UE(p_bitctx, &currSlice->abs_diff_pic_num_minus1[LIST_1][i], "abs_diff_pic_num_minus1_lx"); + } else { + if (modification_of_pic_nums_idc == 2) { + READ_UE(p_bitctx, &currSlice->long_term_pic_idx[LIST_1][i], "long_term_pic_idx"); + } else if (modification_of_pic_nums_idc == 4 || modification_of_pic_nums_idc == 5) { + READ_UE(p_bitctx, &currSlice->abs_diff_view_idx_minus1[LIST_1][i], "abs_diff_view_idx_minus1"); + } + } + i++; + } while (modification_of_pic_nums_idc != 3); + } + } + ASSERT(currSlice->redundant_pic_cnt == 0); //!< not support reference index of redundant slices + + return ret = MPP_OK; +__BITREAD_ERR: + ret = p_bitctx->ret; + + return ret; +} + +static MPP_RET pred_weight_table(H264_SLICE_t *currSlice) +{ + RK_S32 se_tmp = 0; + MPP_RET ret = MPP_ERR_UNKNOW; + RK_S32 i = 0, j = 0, temp = 0; + BitReadCtx_t *p_bitctx = &currSlice->p_Cur->bitctx; + + READ_UE(p_bitctx, &temp, "log2_weight_denom"); + if (currSlice->active_sps->chroma_format_idc) { + READ_UE(p_bitctx, &temp, "log2_weight_denom"); + } + for (i = 0; i < currSlice->num_ref_idx_active[LIST_0]; i++) { + READ_ONEBIT(p_bitctx, &temp, "luma_weight_flag_l0"); + if (temp) { + READ_SE(p_bitctx, &se_tmp, "pred_weight"); //!< slice->wp_weight[LIST_0][i][0] + READ_SE(p_bitctx, &se_tmp, "pred_offset"); //!< slice->wp_offset[LIST_0][i][0] + } + if (currSlice->active_sps->chroma_format_idc) { + READ_ONEBIT(p_bitctx, &temp, "chroma_weight_flag_l0"); + for (j = 1; j < 3; j++) { + if (temp) { //!< chroma_weight_flag_l0 + READ_SE(p_bitctx, &se_tmp, "pred_weight"); //!< slice->wp_weight[LIST_0][i][j] + READ_SE(p_bitctx, &se_tmp, "pred_offset"); //!< slice->wp_offset[LIST_0][i][j] + } + } + } + } + + if ((currSlice->slice_type == B_SLICE) && currSlice->p_Vid->active_pps->weighted_bipred_idc == 1) { + for (i = 0; i < currSlice->num_ref_idx_active[LIST_1]; i++) { + READ_ONEBIT(p_bitctx, &temp, "luma_weight_flag_l1"); + if (temp) { + READ_SE(p_bitctx, &se_tmp, "pred_weight"); //!< slice->wp_weight[LIST_1][i][0] + READ_SE(p_bitctx, &se_tmp, "pred_offset"); //!< slice->wp_offset[LIST_1][i][0] + } + if (currSlice->active_sps->chroma_format_idc) { + READ_ONEBIT(p_bitctx, &temp, "chroma_weight_flag_l1"); + for (j = 1; j < 3; j++) { + if (temp) { // chroma_weight_flag_l1 + READ_SE(p_bitctx, &se_tmp, "pred_weight"); //!< slice->wp_weight[LIST_1][i][j] + READ_SE(p_bitctx, &se_tmp, "pred_offset"); //!< slice->wp_offset[LIST_1][i][j] + } + } + } + } + } + + return ret = MPP_OK; +__BITREAD_ERR: + return ret = p_bitctx->ret; +} + +static MPP_RET dec_ref_pic_marking(H264_SLICE_t *pSlice) +{ + RK_U32 val = 0; + MPP_RET ret = MPP_ERR_UNKNOW; + RK_U32 drpm_used_bits = 0; + H264_DRPM_t *tmp_drpm = NULL, *tmp_drpm2 = NULL; + H264dVideoCtx_t *p_Vid = pSlice->p_Vid; + BitReadCtx_t *p_bitctx = &pSlice->p_Cur->bitctx; + + drpm_used_bits = p_bitctx->used_bits; + pSlice->drpm_used_bitlen = 0; + + if (pSlice->idr_flag || + (pSlice->svc_extension_flag == 0 && pSlice->mvcExt.non_idr_flag == 0)) { + READ_ONEBIT(p_bitctx, &pSlice->no_output_of_prior_pics_flag, "no_output_of_prior_pics_flag"); + p_Vid->no_output_of_prior_pics_flag = pSlice->no_output_of_prior_pics_flag; + READ_ONEBIT(p_bitctx, &pSlice->long_term_reference_flag, "long_term_reference_flag"); + } else { + READ_ONEBIT(p_bitctx, &pSlice->adaptive_ref_pic_buffering_flag, "adaptive_ref_pic_buffering_flag"); + + if (pSlice->adaptive_ref_pic_buffering_flag) { + RK_U32 i = 0; + do { //!< read Memory Management Control Operation + tmp_drpm = &pSlice->p_Cur->dec_ref_pic_marking_buffer[i]; + tmp_drpm->Next = NULL; + READ_UE(p_bitctx, &val, "memory_management_control_operation"); + tmp_drpm->memory_management_control_operation = val; + + if ((val == 1) || (val == 3)) { + READ_UE(p_bitctx, &tmp_drpm->difference_of_pic_nums_minus1, "difference_of_pic_nums_minus1"); + } + if (val == 2) { + READ_UE(p_bitctx, &tmp_drpm->long_term_pic_num, "long_term_pic_num"); + } + if ((val == 3) || (val == 6)) { + READ_UE(p_bitctx, &tmp_drpm->long_term_frame_idx, "long_term_frame_idx"); + } + if (val == 4) { + READ_UE(p_bitctx, &tmp_drpm->max_long_term_frame_idx_plus1, "max_long_term_frame_idx_plus1"); + } + // add command + if (pSlice->dec_ref_pic_marking_buffer == NULL) { + pSlice->dec_ref_pic_marking_buffer = tmp_drpm; + } else { + tmp_drpm2 = pSlice->dec_ref_pic_marking_buffer; + while (tmp_drpm2->Next != NULL) { + tmp_drpm2 = tmp_drpm2->Next; + } + tmp_drpm2->Next = tmp_drpm; + } + i++; + } while (val != 0); + } + } + pSlice->drpm_used_bitlen = p_bitctx->used_bits - drpm_used_bits; + return ret = MPP_OK; +__BITREAD_ERR: + ret = p_bitctx->ret; + + return ret; +} + +static void init_slice_parmeters(H264_SLICE_t *currSlice) +{ + H264dVideoCtx_t *p_Vid = currSlice->p_Vid; + H264_Nalu_t *cur_nalu = &currSlice->p_Cur->nalu; + + //--- init slice syntax + currSlice->idr_flag = ((cur_nalu->nalu_type == NALU_TYPE_IDR) + || (currSlice->mvcExt.valid && !currSlice->mvcExt.non_idr_flag)); + currSlice->nal_reference_idc = cur_nalu->nal_reference_idc; + //!< set ref flag and dpb error flag + { + p_Vid->p_Dec->errctx.used_ref_flag = currSlice->nal_reference_idc ? 1 : 0; + if (currSlice->slice_type == I_SLICE) { + p_Vid->p_Dec->errctx.dpb_err_flag = 0; + } + } + if ((!currSlice->svc_extension_flag) || currSlice->mvcExt.iPrefixNALU) { // MVC or have prefixNALU + currSlice->view_id = currSlice->mvcExt.view_id; + currSlice->inter_view_flag = currSlice->mvcExt.inter_view_flag; + currSlice->anchor_pic_flag = currSlice->mvcExt.anchor_pic_flag; + } else if (currSlice->svc_extension_flag == -1) { // normal AVC + currSlice->view_id = currSlice->mvcExt.valid ? p_Vid->active_subsps->view_id[0] : 0; + currSlice->inter_view_flag = 1; + currSlice->anchor_pic_flag = currSlice->idr_flag; + } + currSlice->layer_id = currSlice->view_id; + if (currSlice->layer_id >= 0) { // if not found, layer_id == -1 + currSlice->p_Dpb = p_Vid->p_Dpb_layer[currSlice->layer_id]; + } +} + +static MPP_RET check_sps_pps(H264_SPS_t *sps, H264_subSPS_t *subset_sps, H264_PPS_t *pps) +{ + RK_U32 ret = 0; + + ret |= (sps->seq_parameter_set_id > 63); + ret |= (sps->separate_colour_plane_flag == 1); + ret |= (sps->chroma_format_idc == 3); + ret |= (sps->bit_depth_luma_minus8 > 2); + ret |= (sps->bit_depth_chroma_minus8 > 2); + ret |= (sps->log2_max_frame_num_minus4 > 12); + ret |= (sps->pic_order_cnt_type > 2); + ret |= (sps->log2_max_pic_order_cnt_lsb_minus4 > 12); + ret |= (sps->num_ref_frames_in_pic_order_cnt_cycle > 255); + ret |= (sps->max_num_ref_frames > 16); + ret |= (sps->pic_width_in_mbs_minus1 > 4095); + ret |= (sps->pic_height_in_map_units_minus1 > 2303); + ret |= (sps->pic_height_in_map_units_minus1 > 2303); + if (ret) { + H264D_ERR("sps has error, sps_id=%d", sps->seq_parameter_set_id); + goto __FAILED; + } + if (subset_sps) { //!< MVC + ret |= (subset_sps->num_views_minus1 != 1); + // ret |= (subset_sps->num_anchor_refs_l0[0] != 1); + if (subset_sps->num_anchor_refs_l0[0] > 0) + ret |= (subset_sps->anchor_ref_l0[0][0] != subset_sps->view_id[0]); + // ret |= (subset_sps->num_anchor_refs_l1[0] != 1); + if (subset_sps->num_anchor_refs_l1[0] > 0) + ret |= (subset_sps->anchor_ref_l1[0][0] != subset_sps->view_id[1]); + + // ret |= (subset_sps->num_non_anchor_refs_l0[0] != 1); + if (subset_sps->num_non_anchor_refs_l0[0] > 0) + ret |= (subset_sps->non_anchor_ref_l0[0][0] != subset_sps->view_id[0]); + // ret |= (subset_sps->num_non_anchor_refs_l1[0] != 1); + if (subset_sps->num_non_anchor_refs_l1[0] > 0) + ret |= (subset_sps->non_anchor_ref_l1[0][0] != subset_sps->view_id[1]); + + //ret |= (subset_sps->num_applicable_ops_minus1[0] > 1); + if (ret) { + H264D_ERR("subsps has error, sps_id=%d", sps->seq_parameter_set_id); + goto __FAILED; + } + } + //!< check PPS + ret |= (pps->pic_parameter_set_id > 255); + ret |= (pps->seq_parameter_set_id > 63); + ret |= (pps->num_slice_groups_minus1 > 0); + ret |= (pps->num_ref_idx_l0_default_active_minus1 > 31); + ret |= (pps->num_ref_idx_l1_default_active_minus1 > 31); + ret |= (pps->pic_init_qp_minus26 > 25 || pps->pic_init_qp_minus26 < -(26 + 6 * (RK_S32)sps->bit_depth_luma_minus8)); + ret |= (pps->pic_init_qs_minus26 > 25 || pps->pic_init_qs_minus26 < -26); + ret |= (pps->chroma_qp_index_offset > 12 || pps->chroma_qp_index_offset < -12); + ret |= (pps->redundant_pic_cnt_present_flag == 1); + if (ret) { + H264D_ERR("pps has error, sps_id=%d, pps_id", sps->seq_parameter_set_id, pps->pic_parameter_set_id); + goto __FAILED; + } + return MPP_OK; +__FAILED: + return MPP_NOK; +} + + +static MPP_RET set_slice_user_parmeters(H264_SLICE_t *currSlice) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + H264_PPS_t *cur_pps = NULL; + H264_SPS_t *cur_sps = NULL; + H264_subSPS_t *cur_subsps = NULL; + H264dVideoCtx_t *p_Vid = currSlice->p_Vid; + //!< use parameter set + cur_pps = &p_Vid->ppsSet[currSlice->pic_parameter_set_id]; + cur_pps = (cur_pps && cur_pps->Valid) ? cur_pps : NULL; + VAL_CHECK(ret, cur_pps != NULL); + + if (currSlice->mvcExt.valid) { + cur_sps = &p_Vid->subspsSet[cur_pps->seq_parameter_set_id].sps; + cur_subsps = &p_Vid->subspsSet[cur_pps->seq_parameter_set_id]; + if (cur_subsps->Valid) { + if ((RK_S32)currSlice->mvcExt.view_id == cur_subsps->view_id[0]) { // combine subsps to sps + p_Vid->active_mvc_sps_flag = 0; + cur_subsps = NULL; + cur_sps = &p_Vid->spsSet[cur_pps->seq_parameter_set_id]; + } else if ((RK_S32)currSlice->mvcExt.view_id == cur_subsps->view_id[1]) { + p_Vid->active_mvc_sps_flag = 1; + } + } else { + p_Vid->active_mvc_sps_flag = 0; + cur_sps = &p_Vid->spsSet[cur_pps->seq_parameter_set_id]; + cur_subsps = NULL; + } + } else { + p_Vid->active_mvc_sps_flag = 0; + cur_sps = &p_Vid->spsSet[cur_pps->seq_parameter_set_id]; + cur_subsps = NULL; + } + + if (p_Vid->active_mvc_sps_flag) { // layer_id == 1 + cur_subsps = (cur_subsps && cur_subsps->Valid) ? cur_subsps : NULL; + VAL_CHECK(ret, cur_subsps != NULL); + cur_sps = &cur_subsps->sps; + } else { //!< layer_id == 0 + cur_subsps = NULL; + cur_sps = (cur_sps && cur_sps->Valid) ? cur_sps : NULL; + VAL_CHECK(ret, cur_sps != NULL); + } + VAL_CHECK(ret, check_sps_pps(cur_sps, cur_subsps, cur_pps) != MPP_NOK); + + FUN_CHECK(ret = activate_sps(p_Vid, cur_sps, cur_subsps)); + FUN_CHECK(ret = activate_pps(p_Vid, cur_pps)); + + //!< Set SPS to the subset SPS parameters + if (currSlice->svc_extension_flag == 0) { + p_Vid->active_subsps = &p_Vid->subspsSet[cur_pps->seq_parameter_set_id]; + } + currSlice->active_sps = p_Vid->active_sps; + currSlice->active_pps = p_Vid->active_pps; + + p_Vid->type = currSlice->slice_type; + return MPP_OK; +__FAILED: + return ret; +} + + +/*! +*********************************************************************** +* \brief +* reset current slice buffer +*********************************************************************** +*/ +//extern "C" +MPP_RET reset_cur_slice(H264dCurCtx_t *p_Cur, H264_SLICE_t *p) +{ + if (p) { + p->modification_of_pic_nums_idc[LIST_0] = p_Cur->modification_of_pic_nums_idc[LIST_0]; + p->abs_diff_pic_num_minus1[LIST_0] = p_Cur->abs_diff_pic_num_minus1[LIST_0]; + p->long_term_pic_idx[LIST_0] = p_Cur->long_term_pic_idx[LIST_0]; + p->abs_diff_view_idx_minus1[LIST_0] = p_Cur->abs_diff_view_idx_minus1[LIST_0]; + + p->modification_of_pic_nums_idc[LIST_1] = p_Cur->modification_of_pic_nums_idc[LIST_1]; + p->abs_diff_pic_num_minus1[LIST_1] = p_Cur->abs_diff_pic_num_minus1[LIST_1]; + p->long_term_pic_idx[LIST_1] = p_Cur->long_term_pic_idx[LIST_1]; + p->abs_diff_view_idx_minus1[LIST_1] = p_Cur->abs_diff_view_idx_minus1[LIST_1]; + + p->dec_ref_pic_marking_buffer = NULL; + } + + return MPP_OK; +} + +/*! +*********************************************************************** +* \brief +* parse SEI information +*********************************************************************** +*/ +//extern "C" +MPP_RET process_slice(H264_SLICE_t *currSlice) +{ + RK_U32 temp = 0; + RK_U32 poc_used_bits = 0; + MPP_RET ret = MPP_ERR_UNKNOW; + H264dLogCtx_t *logctx = currSlice->logctx; + H264dVideoCtx_t *p_Vid = currSlice->p_Vid; + H264dCurCtx_t *p_Cur = currSlice->p_Cur; + BitReadCtx_t *p_bitctx = &p_Cur->bitctx; + + FunctionIn(logctx->parr[RUN_PARSE]); + //!< initial value + currSlice->p_Dpb_layer[0] = p_Vid->p_Dpb_layer[0]; + currSlice->p_Dpb_layer[1] = p_Vid->p_Dpb_layer[1]; + set_bitread_logctx(p_bitctx, logctx->parr[LOG_READ_SLICE]); + + LogInfo(p_bitctx->ctx, "----------------------------- SLICE begin --------------------------------"); + //!< read slice head syntax + READ_UE(p_bitctx, &currSlice->start_mb_nr, "first_mb_in_slice"); + READ_UE(p_bitctx, &temp, "slice_type"); + p_Vid->slice_type = currSlice->slice_type = temp % 5; + READ_UE(p_bitctx, &currSlice->pic_parameter_set_id, "slice_pic_parameter_set_id"); + init_slice_parmeters(currSlice); + FUN_CHECK(ret = set_slice_user_parmeters(currSlice)); + //!< read rest slice header syntax + { + READ_BITS(p_bitctx, currSlice->active_sps->log2_max_frame_num_minus4 + 4, &currSlice->frame_num, "frame_num"); + if (currSlice->active_sps->frame_mbs_only_flag) { //!< user in_slice info + p_Vid->structure = FRAME; + currSlice->field_pic_flag = 0; + currSlice->bottom_field_flag = 0; + } else { + READ_ONEBIT(p_bitctx, &currSlice->field_pic_flag, "field_pic_flag"); + if (currSlice->field_pic_flag) { + READ_ONEBIT(p_bitctx, &currSlice->bottom_field_flag, "field_pic_flag"); + p_Vid->structure = currSlice->bottom_field_flag ? BOTTOM_FIELD : TOP_FIELD; + } else { + p_Vid->structure = FRAME; + currSlice->bottom_field_flag = 0; + } + } + currSlice->structure = p_Vid->structure; + currSlice->mb_aff_frame_flag = (currSlice->active_sps->mb_adaptive_frame_field_flag && (currSlice->field_pic_flag == 0)); + if (currSlice->idr_flag) { + READ_UE(p_bitctx, &currSlice->idr_pic_id, "idr_pic_id"); + } else if (currSlice->svc_extension_flag == 0 && currSlice->mvcExt.non_idr_flag == 0) { + READ_UE(p_bitctx, &currSlice->idr_pic_id, "idr_pic_id"); + } + poc_used_bits = p_bitctx->used_bits; //!< init poc used bits + if (currSlice->active_sps->pic_order_cnt_type == 0) { + READ_BITS(p_bitctx, currSlice->active_sps->log2_max_pic_order_cnt_lsb_minus4 + 4, &currSlice->pic_order_cnt_lsb, "pic_order_cnt_lsb"); + if (currSlice->p_Vid->active_pps->bottom_field_pic_order_in_frame_present_flag == 1 + && !currSlice->field_pic_flag) { + READ_SE(p_bitctx, &currSlice->delta_pic_order_cnt_bottom, "delta_pic_order_cnt_bottom"); + } else { + currSlice->delta_pic_order_cnt_bottom = 0; + } + } + if (currSlice->active_sps->pic_order_cnt_type == 1) { + if (!currSlice->active_sps->delta_pic_order_always_zero_flag) { + READ_SE(p_bitctx, &currSlice->delta_pic_order_cnt[0], "delta_pic_order_cnt[0]"); + + if (currSlice->p_Vid->active_pps->bottom_field_pic_order_in_frame_present_flag == 1 && !currSlice->field_pic_flag) { + READ_SE(p_bitctx, &currSlice->delta_pic_order_cnt[1], "delta_pic_order_cnt[1]"); + } else { + currSlice->delta_pic_order_cnt[1] = 0; //!< set to zero if not in stream + } + } else { + currSlice->delta_pic_order_cnt[0] = 0; + currSlice->delta_pic_order_cnt[1] = 0; + } + } + currSlice->poc_used_bitlen = p_bitctx->used_bits - poc_used_bits; //!< calculate poc used bit length + //!< redundant_pic_cnt is missing here + ASSERT(currSlice->p_Vid->active_pps->redundant_pic_cnt_present_flag == 0); // add by dw, high 4:2:2 profile not support + if (currSlice->p_Vid->active_pps->redundant_pic_cnt_present_flag) { + READ_UE(p_bitctx, &currSlice->redundant_pic_cnt, "redundant_pic_cnt"); + } + + if (currSlice->slice_type == B_SLICE) { + READ_ONEBIT(p_bitctx, &currSlice->direct_spatial_mv_pred_flag, "direct_spatial_mv_pred_flag"); + } else { + currSlice->direct_spatial_mv_pred_flag = 0; + } + currSlice->num_ref_idx_active[LIST_0] = currSlice->p_Vid->active_pps->num_ref_idx_l0_default_active_minus1 + 1; + currSlice->num_ref_idx_active[LIST_1] = currSlice->p_Vid->active_pps->num_ref_idx_l1_default_active_minus1 + 1; + + if (currSlice->slice_type == P_SLICE + || currSlice->slice_type == SP_SLICE || currSlice->slice_type == B_SLICE) { + READ_ONEBIT(p_bitctx, &currSlice->num_ref_idx_override_flag, "num_ref_idx_override_flag"); + if (currSlice->num_ref_idx_override_flag) { + READ_UE(p_bitctx, &currSlice->num_ref_idx_active[LIST_0], "num_ref_idx_active0"); + currSlice->num_ref_idx_active[LIST_0] += 1; + if (currSlice->slice_type == B_SLICE) { + READ_UE(p_bitctx, &currSlice->num_ref_idx_active[LIST_1], "num_ref_idx_active1"); + currSlice->num_ref_idx_active[LIST_1] += 1; + } + } + } + if (currSlice->slice_type != B_SLICE) { + currSlice->num_ref_idx_active[LIST_1] = 0; + } + FUN_CHECK(ret = ref_pic_list_mvc_modification(currSlice)); + if ((currSlice->p_Vid->active_pps->weighted_pred_flag + && (currSlice->slice_type == P_SLICE || currSlice->slice_type == SP_SLICE)) + || (currSlice->p_Vid->active_pps->weighted_bipred_idc == 1 && (currSlice->slice_type == B_SLICE))) { + FUN_CHECK(ret = pred_weight_table(currSlice)); + } + currSlice->drpm_used_bitlen = 0; + if (currSlice->nal_reference_idc) { + FUN_CHECK(ret = dec_ref_pic_marking(currSlice)); + } + if (g_max_bytes < (p_bitctx->used_bits >> 3)) { + g_max_bytes = (p_bitctx->used_bits >> 3); + } + H264D_DBG(H264D_DBG_PPS_SPS, "[SLICE_HEAD] type=%d, layer_id=%d,sps_id=%d, pps_id=%d, struct=%d, frame_num=%d", + currSlice->slice_type, currSlice->layer_id, currSlice->active_sps->seq_parameter_set_id, + currSlice->active_pps->pic_parameter_set_id, currSlice->structure, currSlice->frame_num); + } + + FunctionOut(logctx->parr[RUN_PARSE]); + + return ret = MPP_OK; +__BITREAD_ERR: + ret = p_bitctx->ret; +__FAILED: + return ret; +} diff --git a/mpp/codec/dec/h264/h264d_slice.h b/mpp/codec/dec/h264/h264d_slice.h index 01e3d0ca..4419af1a 100644 --- a/mpp/codec/dec/h264/h264d_slice.h +++ b/mpp/codec/dec/h264/h264d_slice.h @@ -1,42 +1,42 @@ -/* -* -* Copyright 2015 Rockchip Electronics Co. LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#ifndef __H264D_SLICE_H__ -#define __H264D_SLICE_H__ - -#include "rk_type.h" -#include "mpp_err.h" -#include "h264d_global.h" - - - - -#ifdef __cplusplus -extern "C" { -#endif - -MPP_RET process_slice(H264_SLICE_t *currSlice); - -MPP_RET reset_cur_slice(H264dCurCtx_t *p_Cur, H264_SLICE_t *p); - -#ifdef __cplusplus -} -#endif - -//======================================== -#endif /* end of __H264D_SLICE_H__ */ - +/* +* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef __H264D_SLICE_H__ +#define __H264D_SLICE_H__ + +#include "rk_type.h" +#include "mpp_err.h" +#include "h264d_global.h" + + + + +#ifdef __cplusplus +extern "C" { +#endif + +MPP_RET process_slice(H264_SLICE_t *currSlice); + +MPP_RET reset_cur_slice(H264dCurCtx_t *p_Cur, H264_SLICE_t *p); + +#ifdef __cplusplus +} +#endif + +//======================================== +#endif /* end of __H264D_SLICE_H__ */ + diff --git a/mpp/codec/dec/h264/h264d_sps.c b/mpp/codec/dec/h264/h264d_sps.c index d0c4afd2..13012932 100644 --- a/mpp/codec/dec/h264/h264d_sps.c +++ b/mpp/codec/dec/h264/h264d_sps.c @@ -1,579 +1,579 @@ -/* -* -* Copyright 2015 Rockchip Electronics Co. LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#define MODULE_TAG "h264d_sps" - -#include - -#include "mpp_mem.h" - -#include "vpu_api.h" - -#include "h264_syntax.h" -#include "h264d_log.h" -#include "h264d_sps.h" -#include "h264d_scalist.h" -#include "h264d_dpb.h" - -static void reset_cur_sps_data(H264_SPS_t *cur_sps) -{ - memset(cur_sps, 0, sizeof(H264_SPS_t)); - cur_sps->seq_parameter_set_id = 0; // reset -} - -static void reset_cur_subpps_data(H264_subSPS_t *cur_subpps) -{ - memset(cur_subpps, 0, sizeof(H264_subSPS_t)); - cur_subpps->sps.seq_parameter_set_id = 0; // reset - cur_subpps->num_views_minus1 = -1; - cur_subpps->num_level_values_signalled_minus1 = -1; -} - -static MPP_RET read_hrd_parameters(BitReadCtx_t *p_bitctx, H264_HRD_t *hrd) -{ - RK_U32 SchedSelIdx = 0; - MPP_RET ret = MPP_ERR_UNKNOW; - - READ_UE(p_bitctx, &hrd->cpb_cnt_minus1, "cpb_cnt_minus1"); - READ_BITS(p_bitctx, 4, &hrd->bit_rate_scale, "bit_rate_scale"); - READ_BITS(p_bitctx, 4, &hrd->cpb_size_scale, "cpb_size_scale"); - for (SchedSelIdx = 0; SchedSelIdx <= hrd->cpb_cnt_minus1; SchedSelIdx++) { - READ_UE(p_bitctx, &hrd->bit_rate_value_minus1[SchedSelIdx], "VUI: bit_rate_value_minus1"); - READ_UE(p_bitctx, &hrd->cpb_size_value_minus1[SchedSelIdx], "VUI: cpb_size_value_minus1"); - READ_ONEBIT(p_bitctx, &hrd->cbr_flag[SchedSelIdx], "VUI: cbr_flag"); - } - READ_BITS(p_bitctx, 5, &hrd->initial_cpb_removal_delay_length_minus1, "initial_cpb_removal_delay_length_minus1"); - READ_BITS(p_bitctx, 5, &hrd->cpb_removal_delay_length_minus1, "cpb_removal_delay_length_minus1"); - READ_BITS(p_bitctx, 5, &hrd->dpb_output_delay_length_minus1, "dpb_output_delay_length_minus1"); - READ_BITS(p_bitctx, 5, &hrd->time_offset_length, "time_offset_length"); - - return ret = MPP_OK; -__BITREAD_ERR: - return ret = p_bitctx->ret; -} - -static void init_VUI(H264_VUI_t *vui) -{ - vui->matrix_coefficients = 2; -} - -static MPP_RET read_VUI(BitReadCtx_t *p_bitctx, H264_VUI_t *vui) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - - READ_ONEBIT(p_bitctx, &vui->aspect_ratio_info_present_flag, "vui.aspect_ratio_info_present_flag"); - if (vui->aspect_ratio_info_present_flag) { - READ_BITS(p_bitctx, 8, &vui->aspect_ratio_idc, "vui.aspect_ratio_idc"); - if (255 == vui->aspect_ratio_idc) { - READ_BITS(p_bitctx, 16, &vui->sar_width, "VUI: sar_width"); - READ_BITS(p_bitctx, 16, &vui->sar_height, "VUI: sar_height"); - } - } - READ_ONEBIT(p_bitctx, &vui->overscan_info_present_flag, "VUI: overscan_info_present_flag"); - if (vui->overscan_info_present_flag) { - READ_ONEBIT(p_bitctx, &vui->overscan_appropriate_flag, "VUI: overscan_appropriate_flag"); - } - READ_ONEBIT(p_bitctx, &vui->video_signal_type_present_flag, "VUI: video_signal_type_present_flag"); - if (vui->video_signal_type_present_flag) { - READ_BITS(p_bitctx, 3, &vui->video_format, "VUI: video_format"); - READ_ONEBIT(p_bitctx, &vui->video_full_range_flag, "VUI: video_full_range_flag"); - READ_ONEBIT(p_bitctx, &vui->colour_description_present_flag, "VUI: color_description_present_flag"); - if (vui->colour_description_present_flag) { - READ_BITS(p_bitctx, 8, &vui->colour_primaries, "VUI: colour_primaries"); - READ_BITS(p_bitctx, 8, &vui->transfer_characteristics, "VUI: transfer_characteristics"); - READ_BITS(p_bitctx, 8, &vui->matrix_coefficients, "VUI: matrix_coefficients"); - } - } - READ_ONEBIT(p_bitctx, &vui->chroma_location_info_present_flag, "VUI: chroma_location_info_present_flag"); - if (vui->chroma_location_info_present_flag) { - READ_UE(p_bitctx, &vui->chroma_sample_loc_type_top_field, "VUI: chroma_sample_loc_type_top_field"); - READ_UE(p_bitctx, &vui->chroma_sample_loc_type_bottom_field, "VUI: chroma_sample_loc_type_bottom_field"); - } - READ_ONEBIT(p_bitctx, &vui->timing_info_present_flag, "VUI: timing_info_present_flag"); - if (vui->timing_info_present_flag) { - READ_BITS(p_bitctx, 16, &vui->num_units_in_tick, "VUI: num_units_in_tick(high 16bit)"); - READ_BITS(p_bitctx, 16, &vui->num_units_in_tick, "VUI: num_units_in_tick(low 16bit)"); - READ_BITS(p_bitctx, 16, &vui->time_scale, "VUI: time_scale(high 16bit)"); - READ_BITS(p_bitctx, 16, &vui->time_scale, "VUI: time_scale(low 16bit)"); - READ_ONEBIT(p_bitctx, &vui->fixed_frame_rate_flag, "VUI: fixed_frame_rate_flag"); - } - READ_ONEBIT(p_bitctx, &vui->nal_hrd_parameters_present_flag, "VUI: nal_hrd_parameters_present_flag"); - if (vui->nal_hrd_parameters_present_flag) { - FUN_CHECK(ret = read_hrd_parameters(p_bitctx, &vui->nal_hrd_parameters)); - } - READ_ONEBIT(p_bitctx, &vui->vcl_hrd_parameters_present_flag, "VUI: vcl_hrd_parameters_present_flag"); - if (vui->vcl_hrd_parameters_present_flag) { - FUN_CHECK(ret = read_hrd_parameters(p_bitctx, &vui->vcl_hrd_parameters)); - } - if (vui->nal_hrd_parameters_present_flag || vui->vcl_hrd_parameters_present_flag) { - READ_ONEBIT(p_bitctx, &vui->low_delay_hrd_flag, "VUI: low_delay_hrd_flag"); - } - READ_ONEBIT(p_bitctx, &vui->pic_struct_present_flag, "VUI: pic_struct_present_flag"); - READ_ONEBIT(p_bitctx, &vui->bitstream_restriction_flag, "VUI: bitstream_restriction_flag"); - if (vui->bitstream_restriction_flag) { - READ_ONEBIT(p_bitctx, &vui->motion_vectors_over_pic_boundaries_flag, "VUI: motion_vectors_over_pic_boundaries_flag"); - READ_UE(p_bitctx, &vui->max_bytes_per_pic_denom, "VUI: max_bytes_per_pic_denom"); - READ_UE(p_bitctx, &vui->max_bits_per_mb_denom, "VUI: max_bits_per_mb_denom"); - READ_UE(p_bitctx, &vui->log2_max_mv_length_horizontal, "VUI: log2_max_mv_length_horizontal"); - READ_UE(p_bitctx, &vui->log2_max_mv_length_vertical, "VUI: log2_max_mv_length_vertical"); - READ_UE(p_bitctx, &vui->num_reorder_frames, "VUI: num_reorder_frames"); - READ_UE(p_bitctx, &vui->max_dec_frame_buffering, "VUI: max_dec_frame_buffering"); - } - - return ret = MPP_OK; -__BITREAD_ERR: - ret = p_bitctx->ret; -__FAILED: - return ret; -} - -static MPP_RET parser_sps(BitReadCtx_t *p_bitctx, H264_SPS_t *cur_sps, H264_DecCtx_t *p_Dec) -{ - RK_S32 i = 0, temp = 0; - MPP_RET ret = MPP_ERR_UNKNOW; - //!< init Fidelity Range Extensions stuff - cur_sps->chroma_format_idc = 1; - cur_sps->bit_depth_luma_minus8 = 0; - cur_sps->bit_depth_chroma_minus8 = 0; - cur_sps->qpprime_y_zero_transform_bypass_flag = 0; - cur_sps->separate_colour_plane_flag = 0; - cur_sps->log2_max_pic_order_cnt_lsb_minus4 = 0; - cur_sps->delta_pic_order_always_zero_flag = 0; - LogInfo(p_bitctx->ctx, "----------------------------- SPS begin --------------------------------"); - READ_BITS(p_bitctx, 8, &cur_sps->profile_idc, "profile_idc"); - VAL_CHECK (ret, (cur_sps->profile_idc == H264_PROFILE_BASELINE) - || (cur_sps->profile_idc == H264_PROFILE_MAIN) - || (cur_sps->profile_idc == H264_PROFILE_EXTENDED) - || (cur_sps->profile_idc == H264_PROFILE_HIGH) - || (cur_sps->profile_idc == H264_PROFILE_HIGH10) - || (cur_sps->profile_idc == H264_PROFILE_HIGH422) - || (cur_sps->profile_idc == H264_PROFILE_HIGH444) - || (cur_sps->profile_idc == H264_PROFILE_FREXT_CAVLC444) - || (cur_sps->profile_idc == H264_PROFILE_MVC_HIGH) - || (cur_sps->profile_idc == H264_PROFILE_STEREO_HIGH) - ); - READ_ONEBIT(p_bitctx, &cur_sps->constrained_set0_flag, "constrained_set0_flag"); - READ_ONEBIT(p_bitctx, &cur_sps->constrained_set1_flag, "constrained_set1_flag"); - READ_ONEBIT(p_bitctx, &cur_sps->constrained_set2_flag, "constrained_set2_flag"); - READ_ONEBIT(p_bitctx, &cur_sps->constrained_set3_flag, "constrained_set3_flag"); - READ_ONEBIT(p_bitctx, &cur_sps->constrained_set4_flag, "constrained_set4_flag"); - READ_ONEBIT(p_bitctx, &cur_sps->constrained_set5_flag, "constrained_set5_flag"); - READ_BITS(p_bitctx, 2, &temp, "reserved_zero_2bits"); // reserved_zero_2bits - ASSERT(temp == 0); - READ_BITS(p_bitctx, 8, &cur_sps->level_idc, "level_idc"); - READ_UE(p_bitctx, &cur_sps->seq_parameter_set_id, "seq_parameter_set_id"); - if (cur_sps->seq_parameter_set_id < 0 || cur_sps->seq_parameter_set_id > 32) { - cur_sps->seq_parameter_set_id = 0; - } - if (cur_sps->profile_idc == 100 || cur_sps->profile_idc == 110 - || cur_sps->profile_idc == 122 || cur_sps->profile_idc == 244 - || cur_sps->profile_idc == 44 || cur_sps->profile_idc == 83 - || cur_sps->profile_idc == 86 || cur_sps->profile_idc == 118 - || cur_sps->profile_idc == 128 || cur_sps->profile_idc == 138) { - READ_UE(p_bitctx, &cur_sps->chroma_format_idc, "chroma_format_idc"); - if (cur_sps->chroma_format_idc > 2) { - H264D_ERR("ERROR: Not support chroma_format_idc=%d.", cur_sps->chroma_format_idc); - p_Dec->errctx.un_spt_flag = VPU_FRAME_ERR_UNSUPPORT; - goto __FAILED; - } - READ_UE(p_bitctx, &cur_sps->bit_depth_luma_minus8, "bit_depth_luma_minus8"); - ASSERT(cur_sps->bit_depth_luma_minus8 < 7); - READ_UE(p_bitctx, &cur_sps->bit_depth_chroma_minus8, "bit_depth_chroma_minus8"); - ASSERT(cur_sps->bit_depth_chroma_minus8 < 7); - READ_ONEBIT(p_bitctx, &cur_sps->qpprime_y_zero_transform_bypass_flag, "qpprime_y_zero_transform_bypass_flag"); - READ_ONEBIT(p_bitctx, &cur_sps->seq_scaling_matrix_present_flag, "seq_scaling_matrix_present_flag"); - if (cur_sps->seq_scaling_matrix_present_flag) { - LogInfo(p_bitctx->ctx, "Scaling matrix present."); - if (parse_sps_scalinglists(p_bitctx, cur_sps)) { - LogError(p_bitctx->ctx, "rkv_parse_sps_scalinglists error."); - } - } - } - READ_UE(p_bitctx, &cur_sps->log2_max_frame_num_minus4, "log2_max_frame_num_minus4"); - ASSERT(cur_sps->log2_max_frame_num_minus4 < 13); - READ_UE(p_bitctx, &cur_sps->pic_order_cnt_type, "pic_order_cnt_type"); - ASSERT(cur_sps->pic_order_cnt_type < 3); - - cur_sps->log2_max_pic_order_cnt_lsb_minus4 = 0; - cur_sps->delta_pic_order_always_zero_flag = 0; - if (0 == cur_sps->pic_order_cnt_type) { - READ_UE(p_bitctx, &cur_sps->log2_max_pic_order_cnt_lsb_minus4, "log2_max_pic_order_cnt_lsb_minus4"); - ASSERT(cur_sps->log2_max_pic_order_cnt_lsb_minus4 < 13); - } else if (1 == cur_sps->pic_order_cnt_type) { - READ_ONEBIT(p_bitctx, &cur_sps->delta_pic_order_always_zero_flag, "delta_pic_order_always_zero_flag"); - READ_SE(p_bitctx, &cur_sps->offset_for_non_ref_pic, "offset_for_non_ref_pic"); - READ_SE(p_bitctx, &cur_sps->offset_for_top_to_bottom_field, "offset_for_top_to_bottom_field"); - READ_UE(p_bitctx, &cur_sps->num_ref_frames_in_pic_order_cnt_cycle, "num_ref_frames_in_pic_order_cnt_cycle"); - ASSERT(cur_sps->num_ref_frames_in_pic_order_cnt_cycle < 256); - for (i = 0; i < cur_sps->num_ref_frames_in_pic_order_cnt_cycle; ++i) { - READ_SE(p_bitctx, &cur_sps->offset_for_ref_frame[i], "offset_for_ref_frame"); - cur_sps->expected_delta_per_pic_order_cnt_cycle += cur_sps->offset_for_ref_frame[i]; - } - } - READ_UE(p_bitctx, &cur_sps->max_num_ref_frames, "max_num_ref_frames"); - READ_ONEBIT(p_bitctx, &cur_sps->gaps_in_frame_num_value_allowed_flag, "gaps_in_frame_num_value_allowed_flag"); - READ_UE(p_bitctx, &cur_sps->pic_width_in_mbs_minus1, "pic_width_in_mbs_minus1"); - READ_UE(p_bitctx, &cur_sps->pic_height_in_map_units_minus1, "pic_height_in_map_units_minus1"); - READ_ONEBIT(p_bitctx, &cur_sps->frame_mbs_only_flag, "frame_mbs_only_flag"); - if (!cur_sps->frame_mbs_only_flag) { - READ_ONEBIT(p_bitctx, &cur_sps->mb_adaptive_frame_field_flag, "mb_adaptive_frame_field_flag"); - } - READ_ONEBIT(p_bitctx, &cur_sps->direct_8x8_inference_flag, "direct_8x8_inference_flag"); - - READ_ONEBIT(p_bitctx, &cur_sps->frame_cropping_flag, "frame_cropping_flag"); - if (cur_sps->frame_cropping_flag) { - READ_UE(p_bitctx, &cur_sps->frame_crop_left_offset, "frame_crop_left_offset"); - READ_UE(p_bitctx, &cur_sps->frame_crop_right_offset, "frame_crop_right_offset"); - READ_UE(p_bitctx, &cur_sps->frame_crop_top_offset, "frame_crop_top_offset"); - READ_UE(p_bitctx, &cur_sps->frame_crop_bottom_offset, "frame_crop_bottom_offset"); - } - READ_ONEBIT(p_bitctx, &cur_sps->vui_parameters_present_flag, "vui_parameters_present_flag"); - - init_VUI(&cur_sps->vui_seq_parameters); - if (cur_sps->vui_parameters_present_flag) { - FUN_CHECK(ret = read_VUI(p_bitctx, &cur_sps->vui_seq_parameters)); - } - cur_sps->Valid = 1; - (void)p_Dec; - - return ret = MPP_OK; -__BITREAD_ERR: - ret = p_bitctx->ret; -__FAILED: - return ret; -} - -static MPP_RET sps_mvc_extension(BitReadCtx_t *p_bitctx, H264_subSPS_t *subset_sps) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - RK_S32 i = 0, j = 0, num_views = 0; - - READ_UE(p_bitctx, &subset_sps->num_views_minus1, "SPS_MVC_EXT:num_views_minus1"); - num_views = 1 + subset_sps->num_views_minus1; - //======================== - if (num_views > 0) { - subset_sps->view_id = mpp_calloc(RK_S32, num_views); - subset_sps->num_anchor_refs_l0 = mpp_calloc(RK_S32, num_views); - subset_sps->num_anchor_refs_l1 = mpp_calloc(RK_S32, num_views); - subset_sps->anchor_ref_l0 = mpp_calloc(RK_S32*, num_views); - subset_sps->anchor_ref_l1 = mpp_calloc(RK_S32*, num_views); - subset_sps->num_non_anchor_refs_l0 = mpp_calloc(RK_S32, num_views); - subset_sps->num_non_anchor_refs_l1 = mpp_calloc(RK_S32, num_views); - subset_sps->non_anchor_ref_l0 = mpp_calloc(RK_S32*, num_views); - subset_sps->non_anchor_ref_l1 = mpp_calloc(RK_S32*, num_views); - MEM_CHECK(ret, subset_sps->view_id && subset_sps->num_anchor_refs_l0 - && subset_sps->num_anchor_refs_l1 && subset_sps->anchor_ref_l0 - && subset_sps->anchor_ref_l1 && subset_sps->num_non_anchor_refs_l0 - && subset_sps->num_non_anchor_refs_l1 && subset_sps->non_anchor_ref_l0 - && subset_sps->non_anchor_ref_l1); - } - for (i = 0; i < num_views; i++) { - READ_UE(p_bitctx, &subset_sps->view_id[i], "SPS_MVC_EXT: view_id"); - } - for (i = 1; i < num_views; i++) { - READ_UE(p_bitctx, &subset_sps->num_anchor_refs_l0[i], "SPS_MVC_EXT: num_anchor_refs_l0"); - if (subset_sps->num_anchor_refs_l0[i]) { - subset_sps->anchor_ref_l0[i] = mpp_calloc(RK_S32, subset_sps->num_anchor_refs_l0[i]); - MEM_CHECK(ret, subset_sps->anchor_ref_l0[i]); - for (j = 0; j < subset_sps->num_anchor_refs_l0[i]; j++) { - READ_UE(p_bitctx, &subset_sps->anchor_ref_l0[i][j], "SPS_MVC_EXT: anchor_ref_l0"); - } - } - READ_UE(p_bitctx, &subset_sps->num_anchor_refs_l1[i], "SPS_MVC_EXT: num_anchor_refs_l1"); - if (subset_sps->num_anchor_refs_l1[i]) { - subset_sps->anchor_ref_l1[i] = mpp_calloc(RK_S32, subset_sps->num_anchor_refs_l1[i]); - MEM_CHECK(ret, subset_sps->anchor_ref_l1[i]); - for (j = 0; j < subset_sps->num_anchor_refs_l1[i]; j++) { - READ_UE(p_bitctx, &subset_sps->anchor_ref_l1[i][j], "SPS_MVC_EXT: anchor_ref_l0"); - } - } - } - for (i = 1; i < num_views; i++) { - READ_UE(p_bitctx, &subset_sps->num_non_anchor_refs_l0[i], "SPS_MVC_EXT: num_non_anchor_refs_l0"); - if (subset_sps->num_non_anchor_refs_l0[i]) { - subset_sps->non_anchor_ref_l0[i] = mpp_calloc(RK_S32, subset_sps->num_non_anchor_refs_l0[i]); - MEM_CHECK(ret, subset_sps->non_anchor_ref_l0[i]); - for (j = 0; j < subset_sps->num_non_anchor_refs_l0[i]; j++) { - READ_UE(p_bitctx, &subset_sps->non_anchor_ref_l0[i][j], "SPS_MVC_EXT: non_anchor_ref_l0"); - } - } - READ_UE(p_bitctx, &subset_sps->num_non_anchor_refs_l1[i], "SPS_MVC_EXT: num_non_anchor_refs_l1"); - if (subset_sps->num_non_anchor_refs_l1[i]) { - subset_sps->non_anchor_ref_l1[i] = mpp_calloc(RK_S32, subset_sps->num_non_anchor_refs_l1[i]); - MEM_CHECK(ret, subset_sps->non_anchor_ref_l1[i]); - - for (j = 0; j < subset_sps->num_non_anchor_refs_l1[i]; j++) { - READ_UE(p_bitctx, &subset_sps->non_anchor_ref_l1[i][j], "SPS_MVC_EXT: non_anchor_ref_l1"); - } - } - } - return ret = MPP_OK; -__BITREAD_ERR: - ret = p_bitctx->ret; -__FAILED: - return ret; -} - -static MPP_RET parser_subsps_ext(BitReadCtx_t *p_bitctx, H264_subSPS_t *cur_subsps) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - - if ((cur_subsps->sps.profile_idc == H264_PROFILE_MVC_HIGH) - || (cur_subsps->sps.profile_idc == H264_PROFILE_STEREO_HIGH)) { - READ_ONEBIT(p_bitctx, &cur_subsps->bit_equal_to_one, "bit_equal_to_one"); - ASSERT(cur_subsps->bit_equal_to_one == 1); - FUN_CHECK(ret = sps_mvc_extension(p_bitctx, cur_subsps)); - - READ_ONEBIT(p_bitctx, &cur_subsps->mvc_vui_parameters_present_flag, "mvc_vui_parameters_present_flag"); - } - - return ret = MPP_OK; -__BITREAD_ERR: - ret = p_bitctx->ret; -__FAILED: - return ret; -} - -static void update_video_pars(H264dVideoCtx_t *p_Vid, H264_SPS_t *sps) -{ - RK_U32 crop_left = 0, crop_right = 0; - RK_U32 crop_top = 0, crop_bottom = 0; - static const RK_U32 SubWidthC [4] = { 1, 2, 2, 1}; - static const RK_U32 SubHeightC [4] = { 1, 2, 1, 1}; - - - p_Vid->max_frame_num = 1 << (sps->log2_max_frame_num_minus4 + 4); - p_Vid->PicWidthInMbs = (sps->pic_width_in_mbs_minus1 + 1); - p_Vid->FrameHeightInMbs = (2 - sps->frame_mbs_only_flag) * (sps->pic_height_in_map_units_minus1 + 1); - p_Vid->yuv_format = sps->chroma_format_idc; - - p_Vid->width = p_Vid->PicWidthInMbs * 16; - p_Vid->height = p_Vid->FrameHeightInMbs * 16; - p_Vid->bit_depth_luma = sps->bit_depth_luma_minus8 + 8; - p_Vid->bit_depth_chroma = sps->bit_depth_chroma_minus8 + 8; - - if (p_Vid->yuv_format == YUV420) { - p_Vid->width_cr = (p_Vid->width >> 1); - p_Vid->height_cr = (p_Vid->height >> 1); - } else if (p_Vid->yuv_format == YUV422) { - p_Vid->width_cr = (p_Vid->width >> 1); - p_Vid->height_cr = p_Vid->height; - } - //!< calculate frame_width_after_crop && frame_height_after_crop - if (sps->frame_cropping_flag) { - crop_left = SubWidthC [sps->chroma_format_idc] * sps->frame_crop_left_offset; - crop_right = SubWidthC [sps->chroma_format_idc] * sps->frame_crop_right_offset; - crop_top = SubHeightC[sps->chroma_format_idc] * ( 2 - sps->frame_mbs_only_flag ) * sps->frame_crop_top_offset; - crop_bottom = SubHeightC[sps->chroma_format_idc] * ( 2 - sps->frame_mbs_only_flag ) * sps->frame_crop_bottom_offset; - } else { - crop_left = crop_right = crop_top = crop_bottom = 0; - } - p_Vid->width_after_crop = p_Vid->width - crop_left - crop_right; - p_Vid->height_after_crop = p_Vid->height - crop_top - crop_bottom; -} - -static RK_U32 video_pars_changed(H264dVideoCtx_t *p_Vid, H264_SPS_t *sps, RK_U8 layer_id) -{ - RK_U32 ret = 0; - - ret |= p_Vid->p_Dpb_layer[layer_id]->num_ref_frames != sps->max_num_ref_frames; - ret |= p_Vid->last_pic_width_in_mbs_minus1[layer_id] != sps->pic_width_in_mbs_minus1; - ret |= p_Vid->last_pic_height_in_map_units_minus1[layer_id] != sps->pic_height_in_map_units_minus1; - ret |= p_Vid->last_profile_idc[layer_id] != sps->profile_idc; - ret |= p_Vid->last_level_idc[layer_id] != sps->level_idc; - ret |= !p_Vid->p_Dpb_layer[layer_id]->init_done; - - return ret; -} - -static void update_last_video_pars(H264dVideoCtx_t *p_Vid, H264_SPS_t *sps, RK_U8 layer_id) -{ - p_Vid->last_pic_width_in_mbs_minus1[layer_id] = sps->pic_width_in_mbs_minus1; - p_Vid->last_pic_height_in_map_units_minus1[layer_id] = sps->pic_height_in_map_units_minus1; - p_Vid->last_profile_idc[layer_id] = sps->profile_idc; - p_Vid->last_level_idc[layer_id] = sps->level_idc; -} - -/*! -*********************************************************************** -* \brief -* prase sps and process sps -*********************************************************************** -*/ -//extern "C" -MPP_RET process_sps(H264_SLICE_t *currSlice) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - H264dLogCtx_t *logctx = currSlice->logctx; - H264dCurCtx_t *p_Cur = currSlice->p_Cur; - BitReadCtx_t *p_bitctx = &p_Cur->bitctx; - H264_SPS_t *cur_sps = &p_Cur->sps; - - FunctionIn(logctx->parr[RUN_PARSE]); - reset_cur_sps_data(cur_sps); // reset - set_bitread_logctx(p_bitctx, logctx->parr[LOG_READ_SPS]); - //!< parse sps - FUN_CHECK(ret = parser_sps(p_bitctx, cur_sps, currSlice->p_Dec)); - //!< decide "max_dec_frame_buffering" for DPB - FUN_CHECK(ret = get_max_dec_frame_buf_size(cur_sps)); - //!< make SPS available, copy - if (cur_sps->Valid) { - memcpy(&currSlice->p_Vid->spsSet[cur_sps->seq_parameter_set_id], cur_sps, sizeof(H264_SPS_t)); - } - FunctionOut(logctx->parr[RUN_PARSE]); - - return ret = MPP_OK; -__FAILED: - return ret; -} - - -/*! -*********************************************************************** -* \brief -* prase sps and process sps -*********************************************************************** -*/ -//extern "C" -void recycle_subsps(H264_subSPS_t *subset_sps) -{ - RK_S32 i = 0, num_views = 0; - - num_views = 1 + subset_sps->num_views_minus1; - for (i = 1; i < num_views; i++) { - if (subset_sps->num_anchor_refs_l0[i] > 0) { - MPP_FREE(subset_sps->anchor_ref_l0[i]); - } - if (subset_sps->num_anchor_refs_l1[i] > 0) { - MPP_FREE(subset_sps->anchor_ref_l1[i]); - } - if (subset_sps->num_non_anchor_refs_l0[i] > 0) { - MPP_FREE(subset_sps->non_anchor_ref_l0[i]); - } - if (subset_sps->num_non_anchor_refs_l1[i] > 0) { - MPP_FREE(subset_sps->non_anchor_ref_l1[i]); - } - } - if (num_views > 0) { - MPP_FREE(subset_sps->view_id); - MPP_FREE(subset_sps->num_anchor_refs_l0); - MPP_FREE(subset_sps->num_anchor_refs_l1); - MPP_FREE(subset_sps->anchor_ref_l0); - MPP_FREE(subset_sps->anchor_ref_l1); - MPP_FREE(subset_sps->num_non_anchor_refs_l0); - MPP_FREE(subset_sps->num_non_anchor_refs_l1); - MPP_FREE(subset_sps->non_anchor_ref_l0); - MPP_FREE(subset_sps->non_anchor_ref_l1); - } - subset_sps->Valid = 0; -} - -/*! -*********************************************************************** -* \brief -* prase sps and process sps -*********************************************************************** -*/ -//extern "C" -MPP_RET process_subsps(H264_SLICE_t *currSlice) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - H264dLogCtx_t *logctx = currSlice->logctx; - BitReadCtx_t *p_bitctx = &currSlice->p_Cur->bitctx; - H264_subSPS_t *cur_subsps = &currSlice->p_Cur->subsps; - H264_subSPS_t *p_subset = NULL; - - FunctionIn(logctx->parr[RUN_PARSE]); - reset_cur_subpps_data(cur_subsps); //reset - set_bitread_logctx(p_bitctx, logctx->parr[LOG_READ_SUBSPS]); - LogInfo(p_bitctx->ctx, "----------------------------- subSPS begin --------------------------------"); - FUN_CHECK(ret = parser_sps(p_bitctx, &cur_subsps->sps, currSlice->p_Dec)); - FUN_CHECK(ret = parser_subsps_ext(p_bitctx, cur_subsps)); - if (cur_subsps->sps.Valid) { - cur_subsps->Valid = 1; - currSlice->p_Vid->profile_idc = cur_subsps->sps.profile_idc; - } - get_max_dec_frame_buf_size(&cur_subsps->sps); - //!< make subSPS available - p_subset = &currSlice->p_Vid->subspsSet[cur_subsps->sps.seq_parameter_set_id]; - if (p_subset->Valid) { - recycle_subsps(p_subset); - } - memcpy(p_subset, cur_subsps, sizeof(H264_subSPS_t)); - FunctionOut(logctx->parr[RUN_PARSE]); - - return ret = MPP_OK; -__FAILED: - recycle_subsps(&currSlice->p_Cur->subsps); - //ASSERT(0); - - return ret; -} - -/*! -*********************************************************************** -* \brief -* prase sps and process sps -*********************************************************************** -*/ -//extern "C" -MPP_RET activate_sps(H264dVideoCtx_t *p_Vid, H264_SPS_t *sps, H264_subSPS_t *subset_sps) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - INP_CHECK(ret, !p_Vid && !sps && !subset_sps); - if (p_Vid->dec_pic) { - FUN_CHECK(ret = exit_picture(p_Vid, &p_Vid->dec_pic)); - } - if (p_Vid->active_mvc_sps_flag) { // layer_id == 1 - p_Vid->active_sps = &subset_sps->sps; - p_Vid->active_subsps = subset_sps; - p_Vid->active_sps_id[0] = 0; - p_Vid->active_sps_id[1] = subset_sps->sps.seq_parameter_set_id; - VAL_CHECK(ret, subset_sps->sps.seq_parameter_set_id >= 0); - if (video_pars_changed(p_Vid, p_Vid->active_sps, 1)) { - FUN_CHECK(ret = flush_dpb(p_Vid->p_Dpb_layer[1], 2)); - FUN_CHECK(ret = init_dpb(p_Vid, p_Vid->p_Dpb_layer[1], 2)); - update_last_video_pars(p_Vid, p_Vid->active_sps, 1); - //!< init frame slots, store frame buffer size - p_Vid->dpb_size[1] = p_Vid->p_Dpb_layer[1]->size; - } - VAL_CHECK(ret, p_Vid->dpb_size[1] > 0); - } else { //!< layer_id == 0 - p_Vid->active_sps = sps; - p_Vid->active_subsps = NULL; - VAL_CHECK(ret, sps->seq_parameter_set_id >= 0); - p_Vid->active_sps_id[0] = sps->seq_parameter_set_id; - p_Vid->active_sps_id[1] = 0; - if (video_pars_changed(p_Vid, p_Vid->active_sps, 0)) { - if (!p_Vid->no_output_of_prior_pics_flag) { - FUN_CHECK(ret = flush_dpb(p_Vid->p_Dpb_layer[0], 1)); - } - FUN_CHECK(ret = init_dpb(p_Vid, p_Vid->p_Dpb_layer[0], 1)); - update_last_video_pars(p_Vid, p_Vid->active_sps, 0); - //!< init frame slots, store frame buffer size - p_Vid->dpb_size[0] = p_Vid->p_Dpb_layer[0]->size; - } - VAL_CHECK(ret, p_Vid->dpb_size[0] > 0); - } - H264D_DBG(H264D_DBG_DPB_INFO, "[DPB_size] dpb_size[0]=%d, mvc_flag=%d, dpb_size[1]=%d", - p_Vid->dpb_size[0], p_Vid->active_mvc_sps_flag, p_Vid->dpb_size[1]); - update_video_pars(p_Vid, p_Vid->active_sps); -__RETURN: - return ret = MPP_OK; -__FAILED: - return ret; -} +/* +* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#define MODULE_TAG "h264d_sps" + +#include + +#include "mpp_mem.h" + +#include "vpu_api.h" + +#include "h264_syntax.h" +#include "h264d_log.h" +#include "h264d_sps.h" +#include "h264d_scalist.h" +#include "h264d_dpb.h" + +static void reset_cur_sps_data(H264_SPS_t *cur_sps) +{ + memset(cur_sps, 0, sizeof(H264_SPS_t)); + cur_sps->seq_parameter_set_id = 0; // reset +} + +static void reset_cur_subpps_data(H264_subSPS_t *cur_subpps) +{ + memset(cur_subpps, 0, sizeof(H264_subSPS_t)); + cur_subpps->sps.seq_parameter_set_id = 0; // reset + cur_subpps->num_views_minus1 = -1; + cur_subpps->num_level_values_signalled_minus1 = -1; +} + +static MPP_RET read_hrd_parameters(BitReadCtx_t *p_bitctx, H264_HRD_t *hrd) +{ + RK_U32 SchedSelIdx = 0; + MPP_RET ret = MPP_ERR_UNKNOW; + + READ_UE(p_bitctx, &hrd->cpb_cnt_minus1, "cpb_cnt_minus1"); + READ_BITS(p_bitctx, 4, &hrd->bit_rate_scale, "bit_rate_scale"); + READ_BITS(p_bitctx, 4, &hrd->cpb_size_scale, "cpb_size_scale"); + for (SchedSelIdx = 0; SchedSelIdx <= hrd->cpb_cnt_minus1; SchedSelIdx++) { + READ_UE(p_bitctx, &hrd->bit_rate_value_minus1[SchedSelIdx], "VUI: bit_rate_value_minus1"); + READ_UE(p_bitctx, &hrd->cpb_size_value_minus1[SchedSelIdx], "VUI: cpb_size_value_minus1"); + READ_ONEBIT(p_bitctx, &hrd->cbr_flag[SchedSelIdx], "VUI: cbr_flag"); + } + READ_BITS(p_bitctx, 5, &hrd->initial_cpb_removal_delay_length_minus1, "initial_cpb_removal_delay_length_minus1"); + READ_BITS(p_bitctx, 5, &hrd->cpb_removal_delay_length_minus1, "cpb_removal_delay_length_minus1"); + READ_BITS(p_bitctx, 5, &hrd->dpb_output_delay_length_minus1, "dpb_output_delay_length_minus1"); + READ_BITS(p_bitctx, 5, &hrd->time_offset_length, "time_offset_length"); + + return ret = MPP_OK; +__BITREAD_ERR: + return ret = p_bitctx->ret; +} + +static void init_VUI(H264_VUI_t *vui) +{ + vui->matrix_coefficients = 2; +} + +static MPP_RET read_VUI(BitReadCtx_t *p_bitctx, H264_VUI_t *vui) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + + READ_ONEBIT(p_bitctx, &vui->aspect_ratio_info_present_flag, "vui.aspect_ratio_info_present_flag"); + if (vui->aspect_ratio_info_present_flag) { + READ_BITS(p_bitctx, 8, &vui->aspect_ratio_idc, "vui.aspect_ratio_idc"); + if (255 == vui->aspect_ratio_idc) { + READ_BITS(p_bitctx, 16, &vui->sar_width, "VUI: sar_width"); + READ_BITS(p_bitctx, 16, &vui->sar_height, "VUI: sar_height"); + } + } + READ_ONEBIT(p_bitctx, &vui->overscan_info_present_flag, "VUI: overscan_info_present_flag"); + if (vui->overscan_info_present_flag) { + READ_ONEBIT(p_bitctx, &vui->overscan_appropriate_flag, "VUI: overscan_appropriate_flag"); + } + READ_ONEBIT(p_bitctx, &vui->video_signal_type_present_flag, "VUI: video_signal_type_present_flag"); + if (vui->video_signal_type_present_flag) { + READ_BITS(p_bitctx, 3, &vui->video_format, "VUI: video_format"); + READ_ONEBIT(p_bitctx, &vui->video_full_range_flag, "VUI: video_full_range_flag"); + READ_ONEBIT(p_bitctx, &vui->colour_description_present_flag, "VUI: color_description_present_flag"); + if (vui->colour_description_present_flag) { + READ_BITS(p_bitctx, 8, &vui->colour_primaries, "VUI: colour_primaries"); + READ_BITS(p_bitctx, 8, &vui->transfer_characteristics, "VUI: transfer_characteristics"); + READ_BITS(p_bitctx, 8, &vui->matrix_coefficients, "VUI: matrix_coefficients"); + } + } + READ_ONEBIT(p_bitctx, &vui->chroma_location_info_present_flag, "VUI: chroma_location_info_present_flag"); + if (vui->chroma_location_info_present_flag) { + READ_UE(p_bitctx, &vui->chroma_sample_loc_type_top_field, "VUI: chroma_sample_loc_type_top_field"); + READ_UE(p_bitctx, &vui->chroma_sample_loc_type_bottom_field, "VUI: chroma_sample_loc_type_bottom_field"); + } + READ_ONEBIT(p_bitctx, &vui->timing_info_present_flag, "VUI: timing_info_present_flag"); + if (vui->timing_info_present_flag) { + READ_BITS(p_bitctx, 16, &vui->num_units_in_tick, "VUI: num_units_in_tick(high 16bit)"); + READ_BITS(p_bitctx, 16, &vui->num_units_in_tick, "VUI: num_units_in_tick(low 16bit)"); + READ_BITS(p_bitctx, 16, &vui->time_scale, "VUI: time_scale(high 16bit)"); + READ_BITS(p_bitctx, 16, &vui->time_scale, "VUI: time_scale(low 16bit)"); + READ_ONEBIT(p_bitctx, &vui->fixed_frame_rate_flag, "VUI: fixed_frame_rate_flag"); + } + READ_ONEBIT(p_bitctx, &vui->nal_hrd_parameters_present_flag, "VUI: nal_hrd_parameters_present_flag"); + if (vui->nal_hrd_parameters_present_flag) { + FUN_CHECK(ret = read_hrd_parameters(p_bitctx, &vui->nal_hrd_parameters)); + } + READ_ONEBIT(p_bitctx, &vui->vcl_hrd_parameters_present_flag, "VUI: vcl_hrd_parameters_present_flag"); + if (vui->vcl_hrd_parameters_present_flag) { + FUN_CHECK(ret = read_hrd_parameters(p_bitctx, &vui->vcl_hrd_parameters)); + } + if (vui->nal_hrd_parameters_present_flag || vui->vcl_hrd_parameters_present_flag) { + READ_ONEBIT(p_bitctx, &vui->low_delay_hrd_flag, "VUI: low_delay_hrd_flag"); + } + READ_ONEBIT(p_bitctx, &vui->pic_struct_present_flag, "VUI: pic_struct_present_flag"); + READ_ONEBIT(p_bitctx, &vui->bitstream_restriction_flag, "VUI: bitstream_restriction_flag"); + if (vui->bitstream_restriction_flag) { + READ_ONEBIT(p_bitctx, &vui->motion_vectors_over_pic_boundaries_flag, "VUI: motion_vectors_over_pic_boundaries_flag"); + READ_UE(p_bitctx, &vui->max_bytes_per_pic_denom, "VUI: max_bytes_per_pic_denom"); + READ_UE(p_bitctx, &vui->max_bits_per_mb_denom, "VUI: max_bits_per_mb_denom"); + READ_UE(p_bitctx, &vui->log2_max_mv_length_horizontal, "VUI: log2_max_mv_length_horizontal"); + READ_UE(p_bitctx, &vui->log2_max_mv_length_vertical, "VUI: log2_max_mv_length_vertical"); + READ_UE(p_bitctx, &vui->num_reorder_frames, "VUI: num_reorder_frames"); + READ_UE(p_bitctx, &vui->max_dec_frame_buffering, "VUI: max_dec_frame_buffering"); + } + + return ret = MPP_OK; +__BITREAD_ERR: + ret = p_bitctx->ret; +__FAILED: + return ret; +} + +static MPP_RET parser_sps(BitReadCtx_t *p_bitctx, H264_SPS_t *cur_sps, H264_DecCtx_t *p_Dec) +{ + RK_S32 i = 0, temp = 0; + MPP_RET ret = MPP_ERR_UNKNOW; + //!< init Fidelity Range Extensions stuff + cur_sps->chroma_format_idc = 1; + cur_sps->bit_depth_luma_minus8 = 0; + cur_sps->bit_depth_chroma_minus8 = 0; + cur_sps->qpprime_y_zero_transform_bypass_flag = 0; + cur_sps->separate_colour_plane_flag = 0; + cur_sps->log2_max_pic_order_cnt_lsb_minus4 = 0; + cur_sps->delta_pic_order_always_zero_flag = 0; + LogInfo(p_bitctx->ctx, "----------------------------- SPS begin --------------------------------"); + READ_BITS(p_bitctx, 8, &cur_sps->profile_idc, "profile_idc"); + VAL_CHECK (ret, (cur_sps->profile_idc == H264_PROFILE_BASELINE) + || (cur_sps->profile_idc == H264_PROFILE_MAIN) + || (cur_sps->profile_idc == H264_PROFILE_EXTENDED) + || (cur_sps->profile_idc == H264_PROFILE_HIGH) + || (cur_sps->profile_idc == H264_PROFILE_HIGH10) + || (cur_sps->profile_idc == H264_PROFILE_HIGH422) + || (cur_sps->profile_idc == H264_PROFILE_HIGH444) + || (cur_sps->profile_idc == H264_PROFILE_FREXT_CAVLC444) + || (cur_sps->profile_idc == H264_PROFILE_MVC_HIGH) + || (cur_sps->profile_idc == H264_PROFILE_STEREO_HIGH) + ); + READ_ONEBIT(p_bitctx, &cur_sps->constrained_set0_flag, "constrained_set0_flag"); + READ_ONEBIT(p_bitctx, &cur_sps->constrained_set1_flag, "constrained_set1_flag"); + READ_ONEBIT(p_bitctx, &cur_sps->constrained_set2_flag, "constrained_set2_flag"); + READ_ONEBIT(p_bitctx, &cur_sps->constrained_set3_flag, "constrained_set3_flag"); + READ_ONEBIT(p_bitctx, &cur_sps->constrained_set4_flag, "constrained_set4_flag"); + READ_ONEBIT(p_bitctx, &cur_sps->constrained_set5_flag, "constrained_set5_flag"); + READ_BITS(p_bitctx, 2, &temp, "reserved_zero_2bits"); // reserved_zero_2bits + ASSERT(temp == 0); + READ_BITS(p_bitctx, 8, &cur_sps->level_idc, "level_idc"); + READ_UE(p_bitctx, &cur_sps->seq_parameter_set_id, "seq_parameter_set_id"); + if (cur_sps->seq_parameter_set_id < 0 || cur_sps->seq_parameter_set_id > 32) { + cur_sps->seq_parameter_set_id = 0; + } + if (cur_sps->profile_idc == 100 || cur_sps->profile_idc == 110 + || cur_sps->profile_idc == 122 || cur_sps->profile_idc == 244 + || cur_sps->profile_idc == 44 || cur_sps->profile_idc == 83 + || cur_sps->profile_idc == 86 || cur_sps->profile_idc == 118 + || cur_sps->profile_idc == 128 || cur_sps->profile_idc == 138) { + READ_UE(p_bitctx, &cur_sps->chroma_format_idc, "chroma_format_idc"); + if (cur_sps->chroma_format_idc > 2) { + H264D_ERR("ERROR: Not support chroma_format_idc=%d.", cur_sps->chroma_format_idc); + p_Dec->errctx.un_spt_flag = VPU_FRAME_ERR_UNSUPPORT; + goto __FAILED; + } + READ_UE(p_bitctx, &cur_sps->bit_depth_luma_minus8, "bit_depth_luma_minus8"); + ASSERT(cur_sps->bit_depth_luma_minus8 < 7); + READ_UE(p_bitctx, &cur_sps->bit_depth_chroma_minus8, "bit_depth_chroma_minus8"); + ASSERT(cur_sps->bit_depth_chroma_minus8 < 7); + READ_ONEBIT(p_bitctx, &cur_sps->qpprime_y_zero_transform_bypass_flag, "qpprime_y_zero_transform_bypass_flag"); + READ_ONEBIT(p_bitctx, &cur_sps->seq_scaling_matrix_present_flag, "seq_scaling_matrix_present_flag"); + if (cur_sps->seq_scaling_matrix_present_flag) { + LogInfo(p_bitctx->ctx, "Scaling matrix present."); + if (parse_sps_scalinglists(p_bitctx, cur_sps)) { + LogError(p_bitctx->ctx, "rkv_parse_sps_scalinglists error."); + } + } + } + READ_UE(p_bitctx, &cur_sps->log2_max_frame_num_minus4, "log2_max_frame_num_minus4"); + ASSERT(cur_sps->log2_max_frame_num_minus4 < 13); + READ_UE(p_bitctx, &cur_sps->pic_order_cnt_type, "pic_order_cnt_type"); + ASSERT(cur_sps->pic_order_cnt_type < 3); + + cur_sps->log2_max_pic_order_cnt_lsb_minus4 = 0; + cur_sps->delta_pic_order_always_zero_flag = 0; + if (0 == cur_sps->pic_order_cnt_type) { + READ_UE(p_bitctx, &cur_sps->log2_max_pic_order_cnt_lsb_minus4, "log2_max_pic_order_cnt_lsb_minus4"); + ASSERT(cur_sps->log2_max_pic_order_cnt_lsb_minus4 < 13); + } else if (1 == cur_sps->pic_order_cnt_type) { + READ_ONEBIT(p_bitctx, &cur_sps->delta_pic_order_always_zero_flag, "delta_pic_order_always_zero_flag"); + READ_SE(p_bitctx, &cur_sps->offset_for_non_ref_pic, "offset_for_non_ref_pic"); + READ_SE(p_bitctx, &cur_sps->offset_for_top_to_bottom_field, "offset_for_top_to_bottom_field"); + READ_UE(p_bitctx, &cur_sps->num_ref_frames_in_pic_order_cnt_cycle, "num_ref_frames_in_pic_order_cnt_cycle"); + ASSERT(cur_sps->num_ref_frames_in_pic_order_cnt_cycle < 256); + for (i = 0; i < cur_sps->num_ref_frames_in_pic_order_cnt_cycle; ++i) { + READ_SE(p_bitctx, &cur_sps->offset_for_ref_frame[i], "offset_for_ref_frame"); + cur_sps->expected_delta_per_pic_order_cnt_cycle += cur_sps->offset_for_ref_frame[i]; + } + } + READ_UE(p_bitctx, &cur_sps->max_num_ref_frames, "max_num_ref_frames"); + READ_ONEBIT(p_bitctx, &cur_sps->gaps_in_frame_num_value_allowed_flag, "gaps_in_frame_num_value_allowed_flag"); + READ_UE(p_bitctx, &cur_sps->pic_width_in_mbs_minus1, "pic_width_in_mbs_minus1"); + READ_UE(p_bitctx, &cur_sps->pic_height_in_map_units_minus1, "pic_height_in_map_units_minus1"); + READ_ONEBIT(p_bitctx, &cur_sps->frame_mbs_only_flag, "frame_mbs_only_flag"); + if (!cur_sps->frame_mbs_only_flag) { + READ_ONEBIT(p_bitctx, &cur_sps->mb_adaptive_frame_field_flag, "mb_adaptive_frame_field_flag"); + } + READ_ONEBIT(p_bitctx, &cur_sps->direct_8x8_inference_flag, "direct_8x8_inference_flag"); + + READ_ONEBIT(p_bitctx, &cur_sps->frame_cropping_flag, "frame_cropping_flag"); + if (cur_sps->frame_cropping_flag) { + READ_UE(p_bitctx, &cur_sps->frame_crop_left_offset, "frame_crop_left_offset"); + READ_UE(p_bitctx, &cur_sps->frame_crop_right_offset, "frame_crop_right_offset"); + READ_UE(p_bitctx, &cur_sps->frame_crop_top_offset, "frame_crop_top_offset"); + READ_UE(p_bitctx, &cur_sps->frame_crop_bottom_offset, "frame_crop_bottom_offset"); + } + READ_ONEBIT(p_bitctx, &cur_sps->vui_parameters_present_flag, "vui_parameters_present_flag"); + + init_VUI(&cur_sps->vui_seq_parameters); + if (cur_sps->vui_parameters_present_flag) { + FUN_CHECK(ret = read_VUI(p_bitctx, &cur_sps->vui_seq_parameters)); + } + cur_sps->Valid = 1; + (void)p_Dec; + + return ret = MPP_OK; +__BITREAD_ERR: + ret = p_bitctx->ret; +__FAILED: + return ret; +} + +static MPP_RET sps_mvc_extension(BitReadCtx_t *p_bitctx, H264_subSPS_t *subset_sps) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + RK_S32 i = 0, j = 0, num_views = 0; + + READ_UE(p_bitctx, &subset_sps->num_views_minus1, "SPS_MVC_EXT:num_views_minus1"); + num_views = 1 + subset_sps->num_views_minus1; + //======================== + if (num_views > 0) { + subset_sps->view_id = mpp_calloc(RK_S32, num_views); + subset_sps->num_anchor_refs_l0 = mpp_calloc(RK_S32, num_views); + subset_sps->num_anchor_refs_l1 = mpp_calloc(RK_S32, num_views); + subset_sps->anchor_ref_l0 = mpp_calloc(RK_S32*, num_views); + subset_sps->anchor_ref_l1 = mpp_calloc(RK_S32*, num_views); + subset_sps->num_non_anchor_refs_l0 = mpp_calloc(RK_S32, num_views); + subset_sps->num_non_anchor_refs_l1 = mpp_calloc(RK_S32, num_views); + subset_sps->non_anchor_ref_l0 = mpp_calloc(RK_S32*, num_views); + subset_sps->non_anchor_ref_l1 = mpp_calloc(RK_S32*, num_views); + MEM_CHECK(ret, subset_sps->view_id && subset_sps->num_anchor_refs_l0 + && subset_sps->num_anchor_refs_l1 && subset_sps->anchor_ref_l0 + && subset_sps->anchor_ref_l1 && subset_sps->num_non_anchor_refs_l0 + && subset_sps->num_non_anchor_refs_l1 && subset_sps->non_anchor_ref_l0 + && subset_sps->non_anchor_ref_l1); + } + for (i = 0; i < num_views; i++) { + READ_UE(p_bitctx, &subset_sps->view_id[i], "SPS_MVC_EXT: view_id"); + } + for (i = 1; i < num_views; i++) { + READ_UE(p_bitctx, &subset_sps->num_anchor_refs_l0[i], "SPS_MVC_EXT: num_anchor_refs_l0"); + if (subset_sps->num_anchor_refs_l0[i]) { + subset_sps->anchor_ref_l0[i] = mpp_calloc(RK_S32, subset_sps->num_anchor_refs_l0[i]); + MEM_CHECK(ret, subset_sps->anchor_ref_l0[i]); + for (j = 0; j < subset_sps->num_anchor_refs_l0[i]; j++) { + READ_UE(p_bitctx, &subset_sps->anchor_ref_l0[i][j], "SPS_MVC_EXT: anchor_ref_l0"); + } + } + READ_UE(p_bitctx, &subset_sps->num_anchor_refs_l1[i], "SPS_MVC_EXT: num_anchor_refs_l1"); + if (subset_sps->num_anchor_refs_l1[i]) { + subset_sps->anchor_ref_l1[i] = mpp_calloc(RK_S32, subset_sps->num_anchor_refs_l1[i]); + MEM_CHECK(ret, subset_sps->anchor_ref_l1[i]); + for (j = 0; j < subset_sps->num_anchor_refs_l1[i]; j++) { + READ_UE(p_bitctx, &subset_sps->anchor_ref_l1[i][j], "SPS_MVC_EXT: anchor_ref_l0"); + } + } + } + for (i = 1; i < num_views; i++) { + READ_UE(p_bitctx, &subset_sps->num_non_anchor_refs_l0[i], "SPS_MVC_EXT: num_non_anchor_refs_l0"); + if (subset_sps->num_non_anchor_refs_l0[i]) { + subset_sps->non_anchor_ref_l0[i] = mpp_calloc(RK_S32, subset_sps->num_non_anchor_refs_l0[i]); + MEM_CHECK(ret, subset_sps->non_anchor_ref_l0[i]); + for (j = 0; j < subset_sps->num_non_anchor_refs_l0[i]; j++) { + READ_UE(p_bitctx, &subset_sps->non_anchor_ref_l0[i][j], "SPS_MVC_EXT: non_anchor_ref_l0"); + } + } + READ_UE(p_bitctx, &subset_sps->num_non_anchor_refs_l1[i], "SPS_MVC_EXT: num_non_anchor_refs_l1"); + if (subset_sps->num_non_anchor_refs_l1[i]) { + subset_sps->non_anchor_ref_l1[i] = mpp_calloc(RK_S32, subset_sps->num_non_anchor_refs_l1[i]); + MEM_CHECK(ret, subset_sps->non_anchor_ref_l1[i]); + + for (j = 0; j < subset_sps->num_non_anchor_refs_l1[i]; j++) { + READ_UE(p_bitctx, &subset_sps->non_anchor_ref_l1[i][j], "SPS_MVC_EXT: non_anchor_ref_l1"); + } + } + } + return ret = MPP_OK; +__BITREAD_ERR: + ret = p_bitctx->ret; +__FAILED: + return ret; +} + +static MPP_RET parser_subsps_ext(BitReadCtx_t *p_bitctx, H264_subSPS_t *cur_subsps) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + + if ((cur_subsps->sps.profile_idc == H264_PROFILE_MVC_HIGH) + || (cur_subsps->sps.profile_idc == H264_PROFILE_STEREO_HIGH)) { + READ_ONEBIT(p_bitctx, &cur_subsps->bit_equal_to_one, "bit_equal_to_one"); + ASSERT(cur_subsps->bit_equal_to_one == 1); + FUN_CHECK(ret = sps_mvc_extension(p_bitctx, cur_subsps)); + + READ_ONEBIT(p_bitctx, &cur_subsps->mvc_vui_parameters_present_flag, "mvc_vui_parameters_present_flag"); + } + + return ret = MPP_OK; +__BITREAD_ERR: + ret = p_bitctx->ret; +__FAILED: + return ret; +} + +static void update_video_pars(H264dVideoCtx_t *p_Vid, H264_SPS_t *sps) +{ + RK_U32 crop_left = 0, crop_right = 0; + RK_U32 crop_top = 0, crop_bottom = 0; + static const RK_U32 SubWidthC [4] = { 1, 2, 2, 1}; + static const RK_U32 SubHeightC [4] = { 1, 2, 1, 1}; + + + p_Vid->max_frame_num = 1 << (sps->log2_max_frame_num_minus4 + 4); + p_Vid->PicWidthInMbs = (sps->pic_width_in_mbs_minus1 + 1); + p_Vid->FrameHeightInMbs = (2 - sps->frame_mbs_only_flag) * (sps->pic_height_in_map_units_minus1 + 1); + p_Vid->yuv_format = sps->chroma_format_idc; + + p_Vid->width = p_Vid->PicWidthInMbs * 16; + p_Vid->height = p_Vid->FrameHeightInMbs * 16; + p_Vid->bit_depth_luma = sps->bit_depth_luma_minus8 + 8; + p_Vid->bit_depth_chroma = sps->bit_depth_chroma_minus8 + 8; + + if (p_Vid->yuv_format == YUV420) { + p_Vid->width_cr = (p_Vid->width >> 1); + p_Vid->height_cr = (p_Vid->height >> 1); + } else if (p_Vid->yuv_format == YUV422) { + p_Vid->width_cr = (p_Vid->width >> 1); + p_Vid->height_cr = p_Vid->height; + } + //!< calculate frame_width_after_crop && frame_height_after_crop + if (sps->frame_cropping_flag) { + crop_left = SubWidthC [sps->chroma_format_idc] * sps->frame_crop_left_offset; + crop_right = SubWidthC [sps->chroma_format_idc] * sps->frame_crop_right_offset; + crop_top = SubHeightC[sps->chroma_format_idc] * ( 2 - sps->frame_mbs_only_flag ) * sps->frame_crop_top_offset; + crop_bottom = SubHeightC[sps->chroma_format_idc] * ( 2 - sps->frame_mbs_only_flag ) * sps->frame_crop_bottom_offset; + } else { + crop_left = crop_right = crop_top = crop_bottom = 0; + } + p_Vid->width_after_crop = p_Vid->width - crop_left - crop_right; + p_Vid->height_after_crop = p_Vid->height - crop_top - crop_bottom; +} + +static RK_U32 video_pars_changed(H264dVideoCtx_t *p_Vid, H264_SPS_t *sps, RK_U8 layer_id) +{ + RK_U32 ret = 0; + + ret |= p_Vid->p_Dpb_layer[layer_id]->num_ref_frames != sps->max_num_ref_frames; + ret |= p_Vid->last_pic_width_in_mbs_minus1[layer_id] != sps->pic_width_in_mbs_minus1; + ret |= p_Vid->last_pic_height_in_map_units_minus1[layer_id] != sps->pic_height_in_map_units_minus1; + ret |= p_Vid->last_profile_idc[layer_id] != sps->profile_idc; + ret |= p_Vid->last_level_idc[layer_id] != sps->level_idc; + ret |= !p_Vid->p_Dpb_layer[layer_id]->init_done; + + return ret; +} + +static void update_last_video_pars(H264dVideoCtx_t *p_Vid, H264_SPS_t *sps, RK_U8 layer_id) +{ + p_Vid->last_pic_width_in_mbs_minus1[layer_id] = sps->pic_width_in_mbs_minus1; + p_Vid->last_pic_height_in_map_units_minus1[layer_id] = sps->pic_height_in_map_units_minus1; + p_Vid->last_profile_idc[layer_id] = sps->profile_idc; + p_Vid->last_level_idc[layer_id] = sps->level_idc; +} + +/*! +*********************************************************************** +* \brief +* prase sps and process sps +*********************************************************************** +*/ +//extern "C" +MPP_RET process_sps(H264_SLICE_t *currSlice) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + H264dLogCtx_t *logctx = currSlice->logctx; + H264dCurCtx_t *p_Cur = currSlice->p_Cur; + BitReadCtx_t *p_bitctx = &p_Cur->bitctx; + H264_SPS_t *cur_sps = &p_Cur->sps; + + FunctionIn(logctx->parr[RUN_PARSE]); + reset_cur_sps_data(cur_sps); // reset + set_bitread_logctx(p_bitctx, logctx->parr[LOG_READ_SPS]); + //!< parse sps + FUN_CHECK(ret = parser_sps(p_bitctx, cur_sps, currSlice->p_Dec)); + //!< decide "max_dec_frame_buffering" for DPB + FUN_CHECK(ret = get_max_dec_frame_buf_size(cur_sps)); + //!< make SPS available, copy + if (cur_sps->Valid) { + memcpy(&currSlice->p_Vid->spsSet[cur_sps->seq_parameter_set_id], cur_sps, sizeof(H264_SPS_t)); + } + FunctionOut(logctx->parr[RUN_PARSE]); + + return ret = MPP_OK; +__FAILED: + return ret; +} + + +/*! +*********************************************************************** +* \brief +* prase sps and process sps +*********************************************************************** +*/ +//extern "C" +void recycle_subsps(H264_subSPS_t *subset_sps) +{ + RK_S32 i = 0, num_views = 0; + + num_views = 1 + subset_sps->num_views_minus1; + for (i = 1; i < num_views; i++) { + if (subset_sps->num_anchor_refs_l0[i] > 0) { + MPP_FREE(subset_sps->anchor_ref_l0[i]); + } + if (subset_sps->num_anchor_refs_l1[i] > 0) { + MPP_FREE(subset_sps->anchor_ref_l1[i]); + } + if (subset_sps->num_non_anchor_refs_l0[i] > 0) { + MPP_FREE(subset_sps->non_anchor_ref_l0[i]); + } + if (subset_sps->num_non_anchor_refs_l1[i] > 0) { + MPP_FREE(subset_sps->non_anchor_ref_l1[i]); + } + } + if (num_views > 0) { + MPP_FREE(subset_sps->view_id); + MPP_FREE(subset_sps->num_anchor_refs_l0); + MPP_FREE(subset_sps->num_anchor_refs_l1); + MPP_FREE(subset_sps->anchor_ref_l0); + MPP_FREE(subset_sps->anchor_ref_l1); + MPP_FREE(subset_sps->num_non_anchor_refs_l0); + MPP_FREE(subset_sps->num_non_anchor_refs_l1); + MPP_FREE(subset_sps->non_anchor_ref_l0); + MPP_FREE(subset_sps->non_anchor_ref_l1); + } + subset_sps->Valid = 0; +} + +/*! +*********************************************************************** +* \brief +* prase sps and process sps +*********************************************************************** +*/ +//extern "C" +MPP_RET process_subsps(H264_SLICE_t *currSlice) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + H264dLogCtx_t *logctx = currSlice->logctx; + BitReadCtx_t *p_bitctx = &currSlice->p_Cur->bitctx; + H264_subSPS_t *cur_subsps = &currSlice->p_Cur->subsps; + H264_subSPS_t *p_subset = NULL; + + FunctionIn(logctx->parr[RUN_PARSE]); + reset_cur_subpps_data(cur_subsps); //reset + set_bitread_logctx(p_bitctx, logctx->parr[LOG_READ_SUBSPS]); + LogInfo(p_bitctx->ctx, "----------------------------- subSPS begin --------------------------------"); + FUN_CHECK(ret = parser_sps(p_bitctx, &cur_subsps->sps, currSlice->p_Dec)); + FUN_CHECK(ret = parser_subsps_ext(p_bitctx, cur_subsps)); + if (cur_subsps->sps.Valid) { + cur_subsps->Valid = 1; + currSlice->p_Vid->profile_idc = cur_subsps->sps.profile_idc; + } + get_max_dec_frame_buf_size(&cur_subsps->sps); + //!< make subSPS available + p_subset = &currSlice->p_Vid->subspsSet[cur_subsps->sps.seq_parameter_set_id]; + if (p_subset->Valid) { + recycle_subsps(p_subset); + } + memcpy(p_subset, cur_subsps, sizeof(H264_subSPS_t)); + FunctionOut(logctx->parr[RUN_PARSE]); + + return ret = MPP_OK; +__FAILED: + recycle_subsps(&currSlice->p_Cur->subsps); + //ASSERT(0); + + return ret; +} + +/*! +*********************************************************************** +* \brief +* prase sps and process sps +*********************************************************************** +*/ +//extern "C" +MPP_RET activate_sps(H264dVideoCtx_t *p_Vid, H264_SPS_t *sps, H264_subSPS_t *subset_sps) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + INP_CHECK(ret, !p_Vid && !sps && !subset_sps); + if (p_Vid->dec_pic) { + FUN_CHECK(ret = exit_picture(p_Vid, &p_Vid->dec_pic)); + } + if (p_Vid->active_mvc_sps_flag) { // layer_id == 1 + p_Vid->active_sps = &subset_sps->sps; + p_Vid->active_subsps = subset_sps; + p_Vid->active_sps_id[0] = 0; + p_Vid->active_sps_id[1] = subset_sps->sps.seq_parameter_set_id; + VAL_CHECK(ret, subset_sps->sps.seq_parameter_set_id >= 0); + if (video_pars_changed(p_Vid, p_Vid->active_sps, 1)) { + FUN_CHECK(ret = flush_dpb(p_Vid->p_Dpb_layer[1], 2)); + FUN_CHECK(ret = init_dpb(p_Vid, p_Vid->p_Dpb_layer[1], 2)); + update_last_video_pars(p_Vid, p_Vid->active_sps, 1); + //!< init frame slots, store frame buffer size + p_Vid->dpb_size[1] = p_Vid->p_Dpb_layer[1]->size; + } + VAL_CHECK(ret, p_Vid->dpb_size[1] > 0); + } else { //!< layer_id == 0 + p_Vid->active_sps = sps; + p_Vid->active_subsps = NULL; + VAL_CHECK(ret, sps->seq_parameter_set_id >= 0); + p_Vid->active_sps_id[0] = sps->seq_parameter_set_id; + p_Vid->active_sps_id[1] = 0; + if (video_pars_changed(p_Vid, p_Vid->active_sps, 0)) { + if (!p_Vid->no_output_of_prior_pics_flag) { + FUN_CHECK(ret = flush_dpb(p_Vid->p_Dpb_layer[0], 1)); + } + FUN_CHECK(ret = init_dpb(p_Vid, p_Vid->p_Dpb_layer[0], 1)); + update_last_video_pars(p_Vid, p_Vid->active_sps, 0); + //!< init frame slots, store frame buffer size + p_Vid->dpb_size[0] = p_Vid->p_Dpb_layer[0]->size; + } + VAL_CHECK(ret, p_Vid->dpb_size[0] > 0); + } + H264D_DBG(H264D_DBG_DPB_INFO, "[DPB_size] dpb_size[0]=%d, mvc_flag=%d, dpb_size[1]=%d", + p_Vid->dpb_size[0], p_Vid->active_mvc_sps_flag, p_Vid->dpb_size[1]); + update_video_pars(p_Vid, p_Vid->active_sps); +__RETURN: + return ret = MPP_OK; +__FAILED: + return ret; +} diff --git a/mpp/codec/dec/h264/h264d_sps.h b/mpp/codec/dec/h264/h264d_sps.h index 0f336bd7..6e6003df 100644 --- a/mpp/codec/dec/h264/h264d_sps.h +++ b/mpp/codec/dec/h264/h264d_sps.h @@ -1,41 +1,41 @@ -/* -* -* Copyright 2015 Rockchip Electronics Co. LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#ifndef _H264D_SPS_H_ -#define _H264D_SPS_H_ - -#include "rk_type.h" -#include "mpp_err.h" -#include "h264d_global.h" - - -#ifdef __cplusplus -extern "C" { -#endif - -MPP_RET process_sps (H264_SLICE_t *currSlice); -void recycle_subsps(H264_subSPS_t *subset_sps); -MPP_RET process_subsps(H264_SLICE_t *currSlice); -MPP_RET activate_sps(H264dVideoCtx_t *p_Vid, H264_SPS_t *sps, H264_subSPS_t *subset_sps); - -#ifdef __cplusplus -} -#endif - -//======================================== -#endif /* end of _H264D_SPS_H_ */ - +/* +* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef _H264D_SPS_H_ +#define _H264D_SPS_H_ + +#include "rk_type.h" +#include "mpp_err.h" +#include "h264d_global.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +MPP_RET process_sps (H264_SLICE_t *currSlice); +void recycle_subsps(H264_subSPS_t *subset_sps); +MPP_RET process_subsps(H264_SLICE_t *currSlice); +MPP_RET activate_sps(H264dVideoCtx_t *p_Vid, H264_SPS_t *sps, H264_subSPS_t *subset_sps); + +#ifdef __cplusplus +} +#endif + +//======================================== +#endif /* end of _H264D_SPS_H_ */ + diff --git a/mpp/codec/dec/h265/h265d_codec.h b/mpp/codec/dec/h265/h265d_codec.h index 19e3a844..c7f78f2a 100644 --- a/mpp/codec/dec/h265/h265d_codec.h +++ b/mpp/codec/dec/h265/h265d_codec.h @@ -1,181 +1,181 @@ -/* - * - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file h265d_codec.h - * @brief - * @author csy(csy@rock-chips.com) - - * @version 1.0.0 - * @history - * 2015.7.15 : Create - */ - -#ifndef __MPP_CODEC_H__ -#define __MPP_CODEC_H__ - -#include "rk_type.h" -#include "mpp_common.h" -#include "vpu_api.h" -#include "mpp_frame.h" -#include "mpp_dec.h" - -enum MppColorSpace { - MPPCOL_SPC_RGB = 0, - MPPCOL_SPC_BT709 = 1, ///< also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / SMPTE RP177 Annex B - MPPCOL_SPC_UNSPECIFIED = 2, - MPPCOL_SPC_FCC = 4, - MPPCOL_SPC_BT470BG = 5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601 - MPPCOL_SPC_SMPTE170M = 6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC / functionally identical to above - MPPCOL_SPC_SMPTE240M = 7, - MPPCOL_SPC_YCOCG = 8, ///< Used by Dirac / VC-2 and H.264 FRext, see ITU-T SG16 - MPPCOL_SPC_NB , ///< Not part of ABI -}; - -enum MppColorRange { - MPPCOL_RANGE_UNSPECIFIED = 0, - MPPCOL_RANGE_MPEG = 1, ///< the normal 219*2^(n-8) "MPEG" YUV ranges - MPPCOL_RANGE_JPEG = 2, ///< the normal 2^n-1 "JPEG" YUV ranges - MPPCOL_RANGE_NB , ///< Not part of ABI -}; - -typedef struct MppRational { - RK_S32 num; ///< numerator - RK_S32 den; ///< denominator -} MppRational_t; - -enum MppPictureStructure { - MPP_PICTURE_STRUCTURE_UNKNOWN, //< unknown - MPP_PICTURE_STRUCTURE_TOP_FIELD, //< coded as top field - MPP_PICTURE_STRUCTURE_BOTTOM_FIELD, //< coded as bottom field - MPP_PICTURE_STRUCTURE_FRAME, //< coded as frame -}; - -#define END_NOT_FOUND (-100) -#define MPP_PARSER_PTS_NB 4 - -typedef struct SplitContext { - RK_U8 *buffer; - RK_U32 buffer_size; - RK_S32 index; - RK_S32 last_index; - RK_U32 state; ///< contains the last few bytes in MSB order - RK_S32 frame_start_found; - RK_S32 overread; ///< the number of bytes which where irreversibly read from the next frame - RK_S32 overread_index; ///< the index into ParseContext.buffer of the overread bytes - RK_U64 state64; ///< contains the last 8 bytes in MSB order - RK_S64 pts; /* pts of the current frame */ - RK_S64 dts; /* dts of the current frame */ - RK_S64 frame_offset; /* offset of the current frame */ - RK_S64 cur_offset; /* current offset - (incremented by each av_parser_parse()) */ - RK_S64 next_frame_offset; /* offset of the next frame */ - /* private data */ - RK_S64 last_pts; - RK_S64 last_dts; - RK_S32 fetch_timestamp; - - RK_S32 cur_frame_start_index; - RK_S64 cur_frame_offset[MPP_PARSER_PTS_NB]; - RK_S64 cur_frame_pts[MPP_PARSER_PTS_NB]; - RK_S64 cur_frame_dts[MPP_PARSER_PTS_NB]; - - RK_S64 offset; ///< byte offset from starting packet start - RK_S64 cur_frame_end[MPP_PARSER_PTS_NB]; - /** - * Set by parser to 1 for key frames and 0 for non-key frames. - * It is initialized to -1, so if the parser doesn't set this flag, - * old-style fallback using AV_PICTURE_TYPE_I picture type as key frames - * will be used. - */ - RK_S32 key_frame; - RK_S32 eos; -} SplitContext_t; - -typedef struct H265dContext { - - void *priv_data; - - void *split_cxt; - - /** - * for rk log printf - **/ - // RK_LOG_CONTEX_t *log_ctx; - /** - * display width & height - **/ - RK_S32 width, height; - - /** - *codec decoder width & height - **/ - RK_S32 coded_width, coded_height; - - RK_U8 *extradata; - - RK_U32 extradata_size; - - VideoPacket_t *pkt; - - /** - * Pixel format - **/ - RK_U32 pix_fmt; - - RK_U32 nBitDepth; - RK_U32 err_recognition; - - /** - * sample aspect ratio (0 if unknown) - * That is the width of a pixel divided by the height of the pixel. - * Numerator and denominator must be relatively prime and smaller than 256 for some video standards. - * - decoding: Set by rkcodec. - */ - MppRational_t sample_aspect_ratio; - - /** - * YUV colorspace type. - * - decoding: Set by rkcodec - */ - enum MppColorSpace colorspace; - - /** - * MPEG vs JPEG YUV range. - * - decoding: Set by rkcodec - */ - enum MppColorRange color_range; - - void *compare_info; - - RK_U32 need_split; - -} H265dContext_t; -#ifdef __cplusplus -extern "C" { -#endif - -RK_S32 h265d_parser2_syntax(void *ctx); - -RK_S32 h265d_syntax_fill_slice(void *ctx, RK_S32 input_index); - - -#ifdef __cplusplus -} -#endif - -#endif /* __MPP_CODEC_H__ */ +/* + * + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file h265d_codec.h + * @brief + * @author csy(csy@rock-chips.com) + + * @version 1.0.0 + * @history + * 2015.7.15 : Create + */ + +#ifndef __MPP_CODEC_H__ +#define __MPP_CODEC_H__ + +#include "rk_type.h" +#include "mpp_common.h" +#include "vpu_api.h" +#include "mpp_frame.h" +#include "mpp_dec.h" + +enum MppColorSpace { + MPPCOL_SPC_RGB = 0, + MPPCOL_SPC_BT709 = 1, ///< also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / SMPTE RP177 Annex B + MPPCOL_SPC_UNSPECIFIED = 2, + MPPCOL_SPC_FCC = 4, + MPPCOL_SPC_BT470BG = 5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601 + MPPCOL_SPC_SMPTE170M = 6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC / functionally identical to above + MPPCOL_SPC_SMPTE240M = 7, + MPPCOL_SPC_YCOCG = 8, ///< Used by Dirac / VC-2 and H.264 FRext, see ITU-T SG16 + MPPCOL_SPC_NB , ///< Not part of ABI +}; + +enum MppColorRange { + MPPCOL_RANGE_UNSPECIFIED = 0, + MPPCOL_RANGE_MPEG = 1, ///< the normal 219*2^(n-8) "MPEG" YUV ranges + MPPCOL_RANGE_JPEG = 2, ///< the normal 2^n-1 "JPEG" YUV ranges + MPPCOL_RANGE_NB , ///< Not part of ABI +}; + +typedef struct MppRational { + RK_S32 num; ///< numerator + RK_S32 den; ///< denominator +} MppRational_t; + +enum MppPictureStructure { + MPP_PICTURE_STRUCTURE_UNKNOWN, //< unknown + MPP_PICTURE_STRUCTURE_TOP_FIELD, //< coded as top field + MPP_PICTURE_STRUCTURE_BOTTOM_FIELD, //< coded as bottom field + MPP_PICTURE_STRUCTURE_FRAME, //< coded as frame +}; + +#define END_NOT_FOUND (-100) +#define MPP_PARSER_PTS_NB 4 + +typedef struct SplitContext { + RK_U8 *buffer; + RK_U32 buffer_size; + RK_S32 index; + RK_S32 last_index; + RK_U32 state; ///< contains the last few bytes in MSB order + RK_S32 frame_start_found; + RK_S32 overread; ///< the number of bytes which where irreversibly read from the next frame + RK_S32 overread_index; ///< the index into ParseContext.buffer of the overread bytes + RK_U64 state64; ///< contains the last 8 bytes in MSB order + RK_S64 pts; /* pts of the current frame */ + RK_S64 dts; /* dts of the current frame */ + RK_S64 frame_offset; /* offset of the current frame */ + RK_S64 cur_offset; /* current offset + (incremented by each av_parser_parse()) */ + RK_S64 next_frame_offset; /* offset of the next frame */ + /* private data */ + RK_S64 last_pts; + RK_S64 last_dts; + RK_S32 fetch_timestamp; + + RK_S32 cur_frame_start_index; + RK_S64 cur_frame_offset[MPP_PARSER_PTS_NB]; + RK_S64 cur_frame_pts[MPP_PARSER_PTS_NB]; + RK_S64 cur_frame_dts[MPP_PARSER_PTS_NB]; + + RK_S64 offset; ///< byte offset from starting packet start + RK_S64 cur_frame_end[MPP_PARSER_PTS_NB]; + /** + * Set by parser to 1 for key frames and 0 for non-key frames. + * It is initialized to -1, so if the parser doesn't set this flag, + * old-style fallback using AV_PICTURE_TYPE_I picture type as key frames + * will be used. + */ + RK_S32 key_frame; + RK_S32 eos; +} SplitContext_t; + +typedef struct H265dContext { + + void *priv_data; + + void *split_cxt; + + /** + * for rk log printf + **/ + // RK_LOG_CONTEX_t *log_ctx; + /** + * display width & height + **/ + RK_S32 width, height; + + /** + *codec decoder width & height + **/ + RK_S32 coded_width, coded_height; + + RK_U8 *extradata; + + RK_U32 extradata_size; + + VideoPacket_t *pkt; + + /** + * Pixel format + **/ + RK_U32 pix_fmt; + + RK_U32 nBitDepth; + RK_U32 err_recognition; + + /** + * sample aspect ratio (0 if unknown) + * That is the width of a pixel divided by the height of the pixel. + * Numerator and denominator must be relatively prime and smaller than 256 for some video standards. + * - decoding: Set by rkcodec. + */ + MppRational_t sample_aspect_ratio; + + /** + * YUV colorspace type. + * - decoding: Set by rkcodec + */ + enum MppColorSpace colorspace; + + /** + * MPEG vs JPEG YUV range. + * - decoding: Set by rkcodec + */ + enum MppColorRange color_range; + + void *compare_info; + + RK_U32 need_split; + +} H265dContext_t; +#ifdef __cplusplus +extern "C" { +#endif + +RK_S32 h265d_parser2_syntax(void *ctx); + +RK_S32 h265d_syntax_fill_slice(void *ctx, RK_S32 input_index); + + +#ifdef __cplusplus +} +#endif + +#endif /* __MPP_CODEC_H__ */ diff --git a/mpp/codec/dec/h265/h265d_parser.c b/mpp/codec/dec/h265/h265d_parser.c index 551a2e87..c966adde 100644 --- a/mpp/codec/dec/h265/h265d_parser.c +++ b/mpp/codec/dec/h265/h265d_parser.c @@ -1,2040 +1,2040 @@ -/* - * - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file h265d_parser.c - * @brief - * @author csy(csy@rock-chips.com) - - * @version 1.0.0 - * @history - * 2015.7.15 : Create - */ - -#define MODULE_TAG "H265D_PARSER" - -#include "mpp_bitread.h" -#include "h265d_parser.h" -#include "mpp_mem.h" -#include "mpp_env.h" -#include "h265d_syntax.h" -#include "mpp_packet_impl.h" -#include "h265d_api.h" - -#define START_CODE 0x000001 ///< start_code_prefix_one_3bytes - -RK_U32 h265d_debug; -#ifdef dump -FILE *fp = NULL; -#endif -//static RK_U32 start_write = 0, value = 0; - -/** - * Find the end of the current frame in the bitstream. - * @return the position of the first byte of the next frame, or END_NOT_FOUND - */ -static RK_S32 hevc_find_frame_end(SplitContext_t *sc, const RK_U8 *buf, - int buf_size) -{ - RK_S32 i; - - for (i = 0; i < buf_size; i++) { - int nut, layer_id; - - sc->state64 = (sc->state64 << 8) | buf[i]; - - if (((sc->state64 >> 3 * 8) & 0xFFFFFF) != START_CODE) - continue; - nut = (sc->state64 >> (2 * 8 + 1)) & 0x3F; - layer_id = (((sc->state64 >> 2 * 8) & 0x01) << 5) + (((sc->state64 >> 1 * 8) & 0xF8) >> 3); - //mpp_log("nut = %d layer_id = %d\n",nut,layer_id); - // Beginning of access unit - if ((nut >= NAL_VPS && nut <= NAL_AUD) || nut == NAL_SEI_PREFIX || - (nut >= 41 && nut <= 44) || (nut >= 48 && nut <= 55)) { - if (sc->frame_start_found && !layer_id) { - sc->frame_start_found = 0; - return i - 5; - } - } else if (nut <= NAL_RASL_R || - (nut >= NAL_BLA_W_LP && nut <= NAL_CRA_NUT)) { - int first_slice_segment_in_pic_flag = buf[i] >> 7; - //mpp_log("nut = %d first_slice_segment_in_pic_flag %d layer_id = %d \n",nut, - // first_slice_segment_in_pic_flag, - // layer_id); - if (first_slice_segment_in_pic_flag && !layer_id) { - if (!sc->frame_start_found) { - sc->frame_start_found = 1; - } else { // First slice of next frame found - sc->frame_start_found = 0; - return i - 5; - } - } - } - } - return END_NOT_FOUND; -} - -static RK_S32 mpp_combine_frame(SplitContext_t *sc, RK_S32 next, const RK_U8 **buf, RK_S32 *buf_size) -{ - if (sc->overread) { - mpp_log("overread %d, state:%X next:%d index:%d o_index:%d\n", - sc->overread, sc->state, next, sc->index, sc->overread_index); - mpp_log("%X %X %X %X\n", (*buf)[0], (*buf)[1], (*buf)[2], (*buf)[3]); - } - - /* Copy overread bytes from last frame into buffer. */ - for (; sc->overread > 0; sc->overread--) { - sc->buffer[sc->index++] = sc->buffer[sc->overread_index++]; - } - - /* flush remaining if EOF */ - if (!*buf_size && next == END_NOT_FOUND) { - next = 0; - } - - sc->last_index = sc->index; - - /* copy into buffer end return */ - if (next == END_NOT_FOUND) { - RK_U32 min_size = (*buf_size) + sc->index + MPP_INPUT_BUFFER_PADDING_SIZE; - void* new_buffer; - if (min_size > sc->buffer_size) { - min_size = MPP_MAX(17 * min_size / 16 + 32, min_size); - new_buffer = mpp_realloc(sc->buffer, RK_U8, min_size); - if (!new_buffer) { - sc->buffer_size = 0; - return MPP_ERR_NOMEM; - } - sc->buffer_size = min_size; - sc->buffer = new_buffer; - } - - memcpy(&sc->buffer[sc->index], *buf, *buf_size); - sc->index += *buf_size; - - return -1; - } - - *buf_size = - sc->overread_index = sc->index + next; - - /* append to buffer */ - if (sc->index) { - RK_U32 min_size = next + sc->index + MPP_INPUT_BUFFER_PADDING_SIZE; - void* new_buffer; - if (min_size > sc->buffer_size) { - min_size = MPP_MAX(17 * min_size / 16 + 32, min_size); - new_buffer = mpp_realloc(sc->buffer, RK_U8, min_size); - if (!new_buffer) { - sc->buffer_size = 0; - return MPP_ERR_NOMEM; - } - sc->buffer_size = min_size; - sc->buffer = new_buffer; - } - - if (next > -MPP_INPUT_BUFFER_PADDING_SIZE) - memcpy(&sc->buffer[sc->index], *buf, - next + MPP_INPUT_BUFFER_PADDING_SIZE); - sc->index = 0; - *buf = sc->buffer; - } - - /* store overread bytes */ - for (; next < 0; next++) { - sc->state = (sc->state << 8) | sc->buffer[sc->last_index + next]; - sc->state64 = (sc->state64 << 8) | sc->buffer[sc->last_index + next]; - sc->overread++; - } - - if (sc->overread) { - mpp_log("overread %d, state:%X next:%d index:%d o_index:%d\n", - sc->overread, sc->state, next, sc->index, sc->overread_index); - mpp_log("%X %X %X %X\n", (*buf)[0], (*buf)[1], (*buf)[2], (*buf)[3]); - } - - return 0; -} - -RK_S32 h265d_split_init(void **sc) -{ - SplitContext_t *s = NULL; - if (s == NULL) { - s = mpp_calloc(SplitContext_t, 1); - if (s != NULL) { - *sc = s; - } else { - mpp_err("split alloc context fail"); - return MPP_ERR_NOMEM; - } - } - s->buffer = mpp_malloc(RK_U8, MAX_FRAME_SIZE); - s->buffer_size = MAX_FRAME_SIZE; - s->fetch_timestamp = 1; - return MPP_OK; -} - -void mpp_fetch_timestamp(SplitContext_t *s, RK_S32 off) -{ - RK_S32 i; - - s->dts = s->pts = -1; - s->offset = 0; - for (i = 0; i < MPP_PARSER_PTS_NB; i++) { - h265d_dbg(H265D_DBG_TIME, "s->cur_offset %lld s->cur_frame_offset[%d] %lld s->frame_offset %lld s->next_frame_offset %lld", - s->cur_offset, i, s->cur_frame_offset[i], s->frame_offset, s->next_frame_offset); - if ( s->cur_offset + off >= s->cur_frame_offset[i] - && (s->frame_offset < s->cur_frame_offset[i] || - (!s->frame_offset && !s->next_frame_offset)) // first field/frame - // check disabled since MPEG-TS does not send complete PES packets - && /*s->next_frame_offset + off <*/ s->cur_frame_end[i]) { - s->dts = s->cur_frame_dts[i]; - s->pts = s->cur_frame_pts[i]; - s->offset = s->next_frame_offset - s->cur_frame_offset[i]; - if (s->cur_offset + off < s->cur_frame_end[i]) - break; - } - } -} -RK_S32 h265d_split_frame(void *sc, - const RK_U8 **poutbuf, RK_S32 *poutbuf_size, - const RK_U8 *buf, RK_S32 buf_size, RK_S64 pts, RK_S64 dts) -{ - RK_S32 next, i; - - SplitContext_t *s = (SplitContext_t*)sc; - - if (s->cur_offset + buf_size != - s->cur_frame_end[s->cur_frame_start_index]) { /* skip remainder packets */ - /* add a new packet descriptor */ - i = (s->cur_frame_start_index + 1) & (MPP_PARSER_PTS_NB - 1); - s->cur_frame_start_index = i; - s->cur_frame_offset[i] = s->cur_offset; - s->cur_frame_end[i] = s->cur_offset + buf_size; - s->cur_frame_pts[i] = pts; - s->cur_frame_dts[i] = dts; - h265d_dbg(H265D_DBG_TIME, "s->cur_frame_start_index = %d,cur_frame_offset = %lld,s->cur_frame_end = %lld pts = %lld", - s->cur_frame_start_index, s->cur_frame_offset[i], s->cur_frame_end[i], pts); - } - - if (s->fetch_timestamp) { - s->fetch_timestamp = 0; - s->last_pts = s->pts; - s->last_dts = s->dts; - mpp_fetch_timestamp(s, 0); - } - - if (s->eos) { - *poutbuf = s->buffer; - *poutbuf_size = s->index; - return 0; - } - - next = hevc_find_frame_end(s, buf, buf_size); - - if (mpp_combine_frame(s, next, &buf, &buf_size) < 0) { - *poutbuf = NULL; - *poutbuf_size = 0; - s->cur_offset += buf_size; - return buf_size; - } - - *poutbuf = buf; - *poutbuf_size = buf_size; - - if (next < 0) - next = 0; - - if (*poutbuf_size) { - /* fill the data for the current frame */ - s->frame_offset = s->next_frame_offset; - - /* offset of the next frame */ - s->next_frame_offset = s->cur_offset + next; - s->fetch_timestamp = 1; - } - - s->cur_offset += next; - return next; -} - -RK_S32 h265d_split_reset(void *sc) -{ - RK_U8 *buf = NULL; - RK_U32 size = 0; - SplitContext_t *s = (SplitContext_t*)sc; - if (sc == NULL) { - return MPP_OK; - } - buf = s->buffer; - size = s->buffer_size; - memset(s, 0, sizeof(SplitContext_t)); - s->fetch_timestamp = 1; - s->buffer = buf; - s->buffer_size = size; - s->eos = 0; - return MPP_OK; -} - - -RK_S32 h265d_split_deinit(void *sc) -{ - SplitContext_t *s = (SplitContext_t *)sc; - if (s->buffer) { - mpp_free(s->buffer); - s->buffer = NULL; - } - if (s) { - mpp_free(s); - s = NULL; - } - return MPP_OK; -} - -static RK_S32 pred_weight_table(HEVCContext *s, BitReadCtx_t *gb) -{ - RK_U32 i = 0; - RK_U32 j = 0; - RK_U8 luma_weight_l0_flag[16]; - RK_U8 chroma_weight_l0_flag[16]; - RK_U8 luma_weight_l1_flag[16]; - RK_U8 chroma_weight_l1_flag[16]; - - READ_UE(gb, &s->sh.luma_log2_weight_denom); - if (s->sps->chroma_format_idc != 0) { - RK_S32 delta = 0; - READ_SE(gb, &delta); - s->sh.chroma_log2_weight_denom = mpp_clip(s->sh.luma_log2_weight_denom + delta, 0, 7); - } - - for (i = 0; i < s->sh.nb_refs[L0]; i++) { - READ_ONEBIT(gb, &luma_weight_l0_flag[i]); - if (!luma_weight_l0_flag[i]) { - s->sh.luma_weight_l0[i] = 1 << s->sh.luma_log2_weight_denom; - s->sh.luma_offset_l0[i] = 0; - } - } - - if (s->sps->chroma_format_idc != 0) { // FIXME: invert "if" and "for" - for (i = 0; i < s->sh.nb_refs[L0]; i++) { - READ_ONEBIT(gb, &chroma_weight_l0_flag[i]); - } - } else { - for (i = 0; i < s->sh.nb_refs[L0]; i++) - chroma_weight_l0_flag[i] = 0; - } - - for (i = 0; i < s->sh.nb_refs[L0]; i++) { - if (luma_weight_l0_flag[i]) { - RK_S32 delta_luma_weight_l0 = 0; - READ_SE(gb, &delta_luma_weight_l0); - s->sh.luma_weight_l0[i] = (1 << s->sh.luma_log2_weight_denom) + delta_luma_weight_l0; - READ_SE(gb, &s->sh.luma_offset_l0[i]); - } - if (chroma_weight_l0_flag[i]) { - for (j = 0; j < 2; j++) { - RK_S32 delta_chroma_weight_l0 = 0; - RK_S32 delta_chroma_offset_l0 = 0; - READ_SE(gb, &delta_chroma_weight_l0); - READ_SE(gb, &delta_chroma_offset_l0); - s->sh.chroma_weight_l0[i][j] = (1 << s->sh.chroma_log2_weight_denom) + delta_chroma_weight_l0; - s->sh.chroma_offset_l0[i][j] = mpp_clip((delta_chroma_offset_l0 - ((128 * s->sh.chroma_weight_l0[i][j]) - >> s->sh.chroma_log2_weight_denom) + 128), -128, 127); - } - } else { - s->sh.chroma_weight_l0[i][0] = 1 << s->sh.chroma_log2_weight_denom; - s->sh.chroma_offset_l0[i][0] = 0; - s->sh.chroma_weight_l0[i][1] = 1 << s->sh.chroma_log2_weight_denom; - s->sh.chroma_offset_l0[i][1] = 0; - } - } - - if (s->sh.slice_type == B_SLICE) { - for (i = 0; i < s->sh.nb_refs[L1]; i++) { - READ_ONEBIT(gb, &luma_weight_l1_flag[i]); - if (!luma_weight_l1_flag[i]) { - s->sh.luma_weight_l1[i] = 1 << s->sh.luma_log2_weight_denom; - s->sh.luma_offset_l1[i] = 0; - } - } - if (s->sps->chroma_format_idc != 0) { - for (i = 0; i < s->sh.nb_refs[L1]; i++) - READ_ONEBIT(gb, &chroma_weight_l1_flag[i]); - } else { - for (i = 0; i < s->sh.nb_refs[L1]; i++) - chroma_weight_l1_flag[i] = 0; - } - for (i = 0; i < s->sh.nb_refs[L1]; i++) { - if (luma_weight_l1_flag[i]) { - RK_S32 delta_luma_weight_l1 = 0; - READ_UE(gb, &delta_luma_weight_l1); - s->sh.luma_weight_l1[i] = (1 << s->sh.luma_log2_weight_denom) + delta_luma_weight_l1; - READ_SE(gb, &s->sh.luma_offset_l1[i]); - } - if (chroma_weight_l1_flag[i]) { - for (j = 0; j < 2; j++) { - RK_S32 delta_chroma_weight_l1 = 0; - RK_S32 delta_chroma_offset_l1 = 0; - READ_SE(gb, &delta_chroma_weight_l1); - READ_SE(gb, &delta_chroma_offset_l1); - s->sh.chroma_weight_l1[i][j] = (1 << s->sh.chroma_log2_weight_denom) + delta_chroma_weight_l1; - s->sh.chroma_offset_l1[i][j] = mpp_clip((delta_chroma_offset_l1 - ((128 * s->sh.chroma_weight_l1[i][j]) - >> s->sh.chroma_log2_weight_denom) + 128), -128, 127); - } - } else { - s->sh.chroma_weight_l1[i][0] = 1 << s->sh.chroma_log2_weight_denom; - s->sh.chroma_offset_l1[i][0] = 0; - s->sh.chroma_weight_l1[i][1] = 1 << s->sh.chroma_log2_weight_denom; - s->sh.chroma_offset_l1[i][1] = 0; - } - } - } - return 0; -__BITREAD_ERR: - return MPP_ERR_STREAM; -} - -static RK_S32 decode_lt_rps(HEVCContext *s, LongTermRPS *rps, BitReadCtx_t *gb) -{ - const HEVCSPS *sps = s->sps; - RK_S32 max_poc_lsb = 1 << sps->log2_max_poc_lsb; - RK_S32 prev_delta_msb = 0; - RK_U32 nb_sps = 0, nb_sh; - RK_S32 i; - - RK_S32 bit_begin = gb->used_bits; - s->rps_bit_offset[s->slice_idx] = - s->rps_bit_offset_st[s->slice_idx]; - - rps->nb_refs = 0; - if (!sps->long_term_ref_pics_present_flag) - return 0; - - if (sps->num_long_term_ref_pics_sps > 0) - READ_UE(gb, &nb_sps); - - READ_UE(gb, &nb_sh); - - if (nb_sh + nb_sps > MPP_ARRAY_ELEMS(rps->poc)) - return MPP_ERR_STREAM; - - rps->nb_refs = nb_sh + nb_sps; - - for (i = 0; i < rps->nb_refs; i++) { - RK_U8 delta_poc_msb_present; - - if ((RK_U32)i < nb_sps) { - RK_U8 lt_idx_sps = 0; - - if (sps->num_long_term_ref_pics_sps > 1) - READ_BITS(gb, mpp_ceil_log2(sps->num_long_term_ref_pics_sps), <_idx_sps); - - rps->poc[i] = sps->lt_ref_pic_poc_lsb_sps[lt_idx_sps]; - rps->used[i] = sps->used_by_curr_pic_lt_sps_flag[lt_idx_sps]; - } else { - READ_BITS(gb, sps->log2_max_poc_lsb, &rps->poc[i]); - READ_ONEBIT(gb, &rps->used[i]); - } - - READ_ONEBIT(gb, &delta_poc_msb_present); - if (delta_poc_msb_present) { - RK_S32 delta = 0; - - READ_UE(gb, &delta); - - if (i && (RK_U32)i != nb_sps) - delta += prev_delta_msb; - - rps->poc[i] += s->poc - delta * max_poc_lsb - s->sh.pic_order_cnt_lsb; - prev_delta_msb = delta; - } - } - - s->rps_bit_offset[s->slice_idx] - += (gb->used_bits - bit_begin); - - return 0; -__BITREAD_ERR: - return MPP_ERR_STREAM; -} - -static RK_S32 set_sps(HEVCContext *s, const HEVCSPS *sps) -{ - RK_U32 num = 0, den = 0; - - s->h265dctx->coded_width = sps->width; - s->h265dctx->coded_height = sps->height; - s->h265dctx->width = sps->output_width; - s->h265dctx->height = sps->output_height; - s->h265dctx->pix_fmt = sps->pix_fmt; - s->h265dctx->nBitDepth = sps->bit_depth; - s->h265dctx->sample_aspect_ratio = sps->vui.sar; - mpp_buf_slot_setup(s->slots, 25); - - if (sps->vui.video_signal_type_present_flag) - s->h265dctx->color_range = sps->vui.video_full_range_flag ? MPPCOL_RANGE_JPEG - : MPPCOL_RANGE_MPEG; - else - s->h265dctx->color_range = MPPCOL_RANGE_MPEG; - - if (sps->vui.colour_description_present_flag) { - s->h265dctx->colorspace = sps->vui.matrix_coeffs; - } else { - s->h265dctx->colorspace = MPPCOL_SPC_UNSPECIFIED; - } - - s->sps = sps; - s->vps = (HEVCVPS*) s->vps_list[s->sps->vps_id]; - - if (s->vps->vps_timing_info_present_flag) { - num = s->vps->vps_num_units_in_tick; - den = s->vps->vps_time_scale; - } else if (sps->vui.vui_timing_info_present_flag) { - num = sps->vui.vui_num_units_in_tick; - den = sps->vui.vui_time_scale; - } - - if (num != 0 && den != 0) { - // s->h265dctx->time_base.num = num; - // s->h265dctx->time_base.den = den; - // av_reduce(&s->h265dctx->time_base.num, &s->h265dctx->time_base.den, - // num, den, 1 << 30); - } - - return 0; - -} -static RK_S32 compare_sliceheader(SliceHeader *openhevc_sh, SliceHeader *sh) -{ - - if (openhevc_sh->pps_id != sh->pps_id) { - mpp_log(" pps_id diff \n"); - return -1; - } - - if (openhevc_sh->slice_type != sh->slice_type) { - mpp_log(" slice_type diff \n"); - return -1; - } - - if (openhevc_sh->pic_order_cnt_lsb != sh->pic_order_cnt_lsb) { - mpp_log(" pic_order_cnt_lsb diff \n"); - return -1; - } - - if (openhevc_sh->first_slice_in_pic_flag != sh->first_slice_in_pic_flag) { - mpp_log(" first_slice_in_pic_flag diff \n"); - return -1; - } - - if (openhevc_sh->dependent_slice_segment_flag != sh->dependent_slice_segment_flag) { - mpp_log(" dependent_slice_segment_flag diff \n"); - return -1; - } - - if (openhevc_sh->pic_output_flag != sh->pic_output_flag) { - mpp_log(" pic_output_flag diff \n"); - return -1; - } - - if (openhevc_sh->colour_plane_id != sh->colour_plane_id) { - mpp_log(" colour_plane_id diff \n"); - return -1; - } - - if (openhevc_sh->rpl_modification_flag[0] != sh->rpl_modification_flag[0]) { - mpp_log(" rpl_modification_flag[0] diff \n"); - return -1; - } - - if (openhevc_sh->rpl_modification_flag[1] != sh->rpl_modification_flag[1]) { - mpp_log(" rpl_modification_flag[1] diff \n"); - return -1; - } - - if (openhevc_sh->no_output_of_prior_pics_flag != sh->no_output_of_prior_pics_flag) { - mpp_log(" no_output_of_prior_pics_flag diff \n"); - return -1; - } - - if (openhevc_sh->slice_temporal_mvp_enabled_flag != sh->slice_temporal_mvp_enabled_flag) { - mpp_log(" slice_temporal_mvp_enabled_flag diff \n"); - return -1; - } - - if (openhevc_sh->nb_refs[0] != sh->nb_refs[0]) { - mpp_log(" nb_refs[0] diff \n"); - return -1; - } - - if (openhevc_sh->nb_refs[1] != sh->nb_refs[1]) { - mpp_log(" nb_refs[1] diff \n"); - return -1; - } - - if (openhevc_sh->slice_sample_adaptive_offset_flag[0] != - sh->slice_sample_adaptive_offset_flag[0]) { - mpp_log(" slice_sample_adaptive_offset_flag[0] diff \n"); - return -1; - } - - if (openhevc_sh->slice_sample_adaptive_offset_flag[1] != - sh->slice_sample_adaptive_offset_flag[1]) { - mpp_log(" slice_sample_adaptive_offset_flag[1] diff \n"); - return -1; - } - - if (openhevc_sh->slice_sample_adaptive_offset_flag[2] != - sh->slice_sample_adaptive_offset_flag[2]) { - mpp_log(" slice_sample_adaptive_offset_flag[2] diff \n"); - return -1; - } - - if (openhevc_sh->mvd_l1_zero_flag != sh->mvd_l1_zero_flag) { - mpp_log(" mvd_l1_zero_flag diff \n"); - return -1; - } - if (openhevc_sh->cabac_init_flag != sh->cabac_init_flag) { - mpp_log(" cabac_init_flag diff \n"); - return -1; - } - - if (openhevc_sh->disable_deblocking_filter_flag != - sh->disable_deblocking_filter_flag) { - mpp_log(" disable_deblocking_filter_flag diff \n"); - return -1; - } - - if (openhevc_sh->slice_loop_filter_across_slices_enabled_flag != - sh->slice_loop_filter_across_slices_enabled_flag) { - mpp_log(" slice_loop_filter_across_slices_enable diff \n"); - return -1; - } - - if (openhevc_sh->collocated_list != sh->collocated_list) { - mpp_log(" collocated_list diff \n"); - return -1; - } - - if (openhevc_sh->collocated_ref_idx != sh->collocated_ref_idx) { - mpp_log(" collocated_ref_idx diff \n"); - return -1; - } - - if (openhevc_sh->slice_qp_delta != sh->slice_qp_delta) { - mpp_log(" slice_qp_delta diff \n"); - return -1; - } - - if (openhevc_sh->slice_cb_qp_offset != sh->slice_cb_qp_offset) { - mpp_log(" slice_cb_qp_offset diff \n"); - return -1; - } - - if (openhevc_sh->slice_cr_qp_offset != sh->slice_cr_qp_offset) { - mpp_log(" slice_cr_qp_offset diff \n"); - return -1; - } - - if (openhevc_sh->beta_offset != sh->beta_offset) { - mpp_log(" beta_offset diff \n"); - return -1; - } - - if (openhevc_sh->tc_offset != sh->tc_offset) { - mpp_log(" tc_offset diff \n"); - return -1; - } - - if (openhevc_sh->max_num_merge_cand != sh->max_num_merge_cand) { - mpp_log(" max_num_merge_cand diff \n"); - return -1; - } - - if (openhevc_sh->num_entry_point_offsets != sh->num_entry_point_offsets) { - mpp_log(" num_entry_point_offsets diff \n"); - return -1; - } - - if (openhevc_sh->slice_qp != sh->slice_qp) { - mpp_log(" slice_qp diff \n"); - return -1; - } - - if (openhevc_sh->luma_log2_weight_denom != sh->luma_log2_weight_denom) { - mpp_log(" luma_log2_weight_denom diff \n"); - return -1; - } - - if (openhevc_sh->chroma_log2_weight_denom != sh->chroma_log2_weight_denom) { - mpp_log(" chroma_log2_weight_denom diff \n"); - return -1; - } - - /* if (openhevc_sh->slice_ctb_addr_rs != sh->slice_ctb_addr_rs) { - mpp_log(" slice_ctb_addr_rs diff \n"); - return -1; - }*/ - return 0; -} - -static RK_S32 hls_slice_header(HEVCContext *s) -{ - - BitReadCtx_t *gb = &s->HEVClc->gb; - SliceHeader *sh = &s->sh; - RK_S32 i, ret; - RK_S32 value, pps_id; - RK_S32 bit_begin; - -#ifdef JCTVC_M0458_INTERLAYER_RPS_SIG - int NumILRRefIdx; -#endif - - // Coded parameters - - READ_ONEBIT(gb, &sh->first_slice_in_pic_flag); - if ((IS_IDR(s) || IS_BLA(s)) && sh->first_slice_in_pic_flag) { - s->seq_decode = (s->seq_decode + 1) & 0xff; - s->max_ra = INT_MAX; - if (IS_IDR(s)) - mpp_hevc_clear_refs(s); - } - if (s->nal_unit_type >= 16 && s->nal_unit_type <= 23) - READ_ONEBIT(gb, &sh->no_output_of_prior_pics_flag); - - if (IS_IRAP(s) && s->miss_ref_flag && sh->first_slice_in_pic_flag) { - // mpp_err("s->nal_unit_type = %d s->poc %d",s->nal_unit_type,s->poc); - s->max_ra = INT_MAX; - s->miss_ref_flag = 0; - } - READ_UE(gb, &pps_id); - - if (pps_id >= MAX_PPS_COUNT || !s->pps_list[pps_id]) { - mpp_err( "PPS id out of range: %d\n", pps_id); - return MPP_ERR_STREAM; - } else { - sh->pps_id = pps_id; - } - - if (!sh->first_slice_in_pic_flag && - s->pps != (HEVCPPS*)s->pps_list[sh->pps_id]) { - mpp_err( "PPS changed between slices.\n"); - return MPP_ERR_STREAM; - } - s->pps = (HEVCPPS*)s->pps_list[sh->pps_id]; - - if (s->sps != (HEVCSPS*)s->sps_list[s->pps->sps_id]) { - s->sps = (HEVCSPS*)s->sps_list[s->pps->sps_id]; - mpp_hevc_clear_refs(s); - ret = set_sps(s, s->sps); - if (ret < 0) - return ret; - - s->seq_decode = (s->seq_decode + 1) & 0xff; - s->max_ra = INT_MAX; - } - - // s->h265dctx->profile = s->sps->ptl.general_ptl.profile_idc; - // s->h265dctx->level = s->sps->ptl.general_ptl.level_idc; - - sh->dependent_slice_segment_flag = 0; - if (!sh->first_slice_in_pic_flag) { - RK_S32 slice_address_length; - - if (s->pps->dependent_slice_segments_enabled_flag) - READ_ONEBIT(gb, &sh->dependent_slice_segment_flag); - - slice_address_length = mpp_ceil_log2(s->sps->ctb_width * - s->sps->ctb_height); - - READ_BITS(gb, slice_address_length, &sh->slice_segment_addr); - - if (sh->slice_segment_addr >= (RK_U32)(s->sps->ctb_width * s->sps->ctb_height)) { - mpp_err( - "Invalid slice segment address: %u.\n", - sh->slice_segment_addr); - return MPP_ERR_STREAM; - } - - if (!sh->dependent_slice_segment_flag) { - sh->slice_addr = sh->slice_segment_addr; - s->slice_idx++; - } - } else { - sh->slice_segment_addr = sh->slice_addr = 0; - s->slice_idx = 0; - s->slice_initialized = 0; - } - - if (!sh->dependent_slice_segment_flag) { - s->slice_initialized = 0; - - for (i = 0; i < s->pps->num_extra_slice_header_bits; i++) - SKIP_BITS(gb, 1); // slice_reserved_undetermined_flag[] - - READ_UE(gb, &sh->slice_type); - if (!(sh->slice_type == I_SLICE || - sh->slice_type == P_SLICE || - sh->slice_type == B_SLICE)) { - mpp_err( "Unknown slice type: %d.\n", - sh->slice_type); - return MPP_ERR_STREAM; - } - if (!s->decoder_id && IS_IRAP(s) && sh->slice_type != I_SLICE) { - mpp_err( "Inter slices in an IRAP frame.\n"); - return MPP_ERR_STREAM; - } - - if (s->pps->output_flag_present_flag) - READ_ONEBIT(gb, &sh->pic_output_flag); - - if (s->sps->separate_colour_plane_flag) - READ_BITS(gb, 2, &sh->colour_plane_id ); - - if (!IS_IDR(s)) { - int poc; - - READ_BITS(gb, s->sps->log2_max_poc_lsb, &sh->pic_order_cnt_lsb); - poc = mpp_hevc_compute_poc(s, sh->pic_order_cnt_lsb); - if (!sh->first_slice_in_pic_flag && poc != s->poc) { - mpp_log("Ignoring POC change between slices: %d -> %d\n", s->poc, poc); -#if 0 - if (s->h265dctx->err_recognition & AV_EF_EXPLODE) - return MPP_ERR_STREAM; -#endif - poc = s->poc; - } - s->poc = poc; - - READ_ONEBIT(gb, &sh->short_term_ref_pic_set_sps_flag); - - bit_begin = gb->used_bits; - - if (!sh->short_term_ref_pic_set_sps_flag) { - - ret = mpp_hevc_decode_short_term_rps(s, &sh->slice_rps, s->sps, 1); - if (ret < 0) - return ret; - - sh->short_term_rps = &sh->slice_rps; - } else { - RK_S32 numbits, rps_idx; - - if (!s->sps->nb_st_rps) { - mpp_err( "No ref lists in the SPS.\n"); - return MPP_ERR_STREAM; - } - - numbits = mpp_ceil_log2(s->sps->nb_st_rps); - rps_idx = 0; - if (numbits > 0) - READ_BITS(gb, numbits, &rps_idx); - - sh->short_term_rps = &s->sps->st_rps[rps_idx]; - } - - s->rps_bit_offset_st[s->slice_idx] = gb->used_bits - bit_begin; - - sh->short_term_ref_pic_set_size = s->rps_bit_offset_st[s->slice_idx]; - - ret = decode_lt_rps(s, &sh->long_term_rps, gb); - if (ret < 0) { - mpp_log("Invalid long term RPS.\n"); - // if (s->h265dctx->err_recognition & AV_EF_EXPLODE) - // return MPP_ERR_STREAM; - } - - if (s->sps->sps_temporal_mvp_enabled_flag) - READ_ONEBIT(gb, &sh->slice_temporal_mvp_enabled_flag); - else - sh->slice_temporal_mvp_enabled_flag = 0; - } else { - s->sh.short_term_rps = NULL; - s->poc = 0; - } - - /* 8.3.1 */ - if (s->temporal_id == 0 && - s->nal_unit_type != NAL_TRAIL_N && - s->nal_unit_type != NAL_TSA_N && - s->nal_unit_type != NAL_STSA_N && - s->nal_unit_type != NAL_RADL_N && - s->nal_unit_type != NAL_RADL_R && - s->nal_unit_type != NAL_RASL_N && - s->nal_unit_type != NAL_RASL_R) - s->pocTid0 = s->poc; - - if (s->sps->sao_enabled) { - READ_ONEBIT(gb, &sh->slice_sample_adaptive_offset_flag[0]); - READ_ONEBIT(gb, &sh->slice_sample_adaptive_offset_flag[1]); - sh->slice_sample_adaptive_offset_flag[2] = - sh->slice_sample_adaptive_offset_flag[1]; - } else { - sh->slice_sample_adaptive_offset_flag[0] = 0; - sh->slice_sample_adaptive_offset_flag[1] = 0; - sh->slice_sample_adaptive_offset_flag[2] = 0; - } - - sh->nb_refs[L0] = sh->nb_refs[L1] = 0; - if (sh->slice_type == P_SLICE || sh->slice_type == B_SLICE) { - int nb_refs; - - sh->nb_refs[L0] = s->pps->num_ref_idx_l0_default_active; - if (sh->slice_type == B_SLICE) - sh->nb_refs[L1] = s->pps->num_ref_idx_l1_default_active; - - READ_ONEBIT(gb, &value); - - if (value) { // num_ref_idx_active_override_flag - READ_UE(gb, &sh->nb_refs[L0]); - sh->nb_refs[L0] += 1; - if (sh->slice_type == B_SLICE) { - READ_UE(gb, &sh->nb_refs[L1]); - sh->nb_refs[L1] += 1; - } - } - if (sh->nb_refs[L0] > MAX_REFS || sh->nb_refs[L1] > MAX_REFS) { - mpp_err( "Too many refs: %d/%d.\n", - sh->nb_refs[L0], sh->nb_refs[L1]); - return MPP_ERR_STREAM; - } - - sh->rpl_modification_flag[0] = 0; - sh->rpl_modification_flag[1] = 0; - nb_refs = mpp_hevc_frame_nb_refs(s); - if (!nb_refs) { - mpp_err( "Zero refs for a frame with P or B slices.\n"); - return MPP_ERR_STREAM; - } - - if (s->pps->lists_modification_present_flag && nb_refs > 1) { - READ_ONEBIT(gb, &sh->rpl_modification_flag[0]); - if (sh->rpl_modification_flag[0]) { - for (i = 0; (RK_U32)i < sh->nb_refs[L0]; i++) - READ_BITS(gb, mpp_ceil_log2(nb_refs), &sh->list_entry_lx[0][i]); - } - - if (sh->slice_type == B_SLICE) { - READ_ONEBIT(gb, &sh->rpl_modification_flag[1]); - if (sh->rpl_modification_flag[1] == 1) - for (i = 0; (RK_U32)i < sh->nb_refs[L1]; i++) - READ_BITS(gb, mpp_ceil_log2(nb_refs), &sh->list_entry_lx[1][i]); - } - } - - if (sh->slice_type == B_SLICE) - READ_ONEBIT(gb, &sh->mvd_l1_zero_flag); - - if (s->pps->cabac_init_present_flag) - READ_ONEBIT(gb, &sh->cabac_init_flag); - else - sh->cabac_init_flag = 0; - - sh->collocated_ref_idx = 0; - if (sh->slice_temporal_mvp_enabled_flag) { - sh->collocated_list = L0; - if (sh->slice_type == B_SLICE) { - READ_ONEBIT(gb, &value); - sh->collocated_list = !value; - } - - if (sh->nb_refs[sh->collocated_list] > 1) { - READ_UE(gb, &sh->collocated_ref_idx); - if (sh->collocated_ref_idx >= sh->nb_refs[sh->collocated_list]) { - mpp_err( - "Invalid collocated_ref_idx: %d.\n", - sh->collocated_ref_idx); - return MPP_ERR_STREAM; - } - } - } - - if ((s->pps->weighted_pred_flag && sh->slice_type == P_SLICE) || - (s->pps->weighted_bipred_flag && sh->slice_type == B_SLICE)) { - pred_weight_table(s, gb); - } - - READ_UE(gb, &value); - sh->max_num_merge_cand = 5 - value; - if (sh->max_num_merge_cand < 1 || sh->max_num_merge_cand > 5) { - mpp_err( - "Invalid number of merging MVP candidates: %d.\n", - sh->max_num_merge_cand); - return MPP_ERR_STREAM; - } - } - READ_SE(gb, &sh->slice_qp_delta ); - if (s->pps->pic_slice_level_chroma_qp_offsets_present_flag) { - READ_SE(gb, &sh->slice_cb_qp_offset); - READ_SE(gb, &sh->slice_cr_qp_offset); - } else { - sh->slice_cb_qp_offset = 0; - sh->slice_cr_qp_offset = 0; - } - - if (s->pps->deblocking_filter_control_present_flag) { - int deblocking_filter_override_flag = 0; - - if (s->pps->deblocking_filter_override_enabled_flag) - READ_ONEBIT(gb, & deblocking_filter_override_flag); - - if (deblocking_filter_override_flag) { - READ_ONEBIT(gb, &sh->disable_deblocking_filter_flag); - if (!sh->disable_deblocking_filter_flag) { - READ_SE(gb, &sh->beta_offset); - sh->beta_offset = sh->beta_offset * 2; - READ_SE(gb, &sh->tc_offset); - sh->tc_offset = sh->tc_offset * 2; - } - } else { - sh->disable_deblocking_filter_flag = s->pps->disable_dbf; - sh->beta_offset = s->pps->beta_offset; - sh->tc_offset = s->pps->tc_offset; - } - } else { - sh->disable_deblocking_filter_flag = 0; - sh->beta_offset = 0; - sh->tc_offset = 0; - } - - if (s->pps->seq_loop_filter_across_slices_enabled_flag && - (sh->slice_sample_adaptive_offset_flag[0] || - sh->slice_sample_adaptive_offset_flag[1] || - !sh->disable_deblocking_filter_flag)) { - READ_ONEBIT(gb, &sh->slice_loop_filter_across_slices_enabled_flag); - } else { - sh->slice_loop_filter_across_slices_enabled_flag = s->pps->seq_loop_filter_across_slices_enabled_flag; - } - } else if (!s->slice_initialized) { - mpp_err( "Independent slice segment missing.\n"); - return MPP_ERR_STREAM; - } - - sh->num_entry_point_offsets = 0; - if (s->pps->tiles_enabled_flag || s->pps->entropy_coding_sync_enabled_flag) { - READ_UE(gb, &sh->num_entry_point_offsets); - if (s->pps->entropy_coding_sync_enabled_flag) { - if (sh->num_entry_point_offsets > s->sps->ctb_height || sh->num_entry_point_offsets < 0) { - mpp_err("The number of entries %d is higher than the number of CTB rows %d \n", - sh->num_entry_point_offsets, - s->sps->ctb_height); - return MPP_ERR_STREAM; - } - } else { - if (sh->num_entry_point_offsets > s->sps->ctb_height * s->sps->ctb_width || sh->num_entry_point_offsets < 0) { - mpp_err("The number of entries %d is higher than the number of CTBs %d \n", - sh->num_entry_point_offsets, - s->sps->ctb_height * s->sps->ctb_width); - return MPP_ERR_STREAM; - } - } - } -#if 0 - if (s->pps->slice_header_extension_present_flag) { - RK_U32 length = 0; - READ_UE(gb, &length); - for (i = 0; (RK_U32)i < length; i++) - SKIP_BITS(gb, 8); // slice_header_extension_data_byte - } -#endif - // Inferred parameters - sh->slice_qp = 26U + s->pps->pic_init_qp_minus26 + sh->slice_qp_delta; - if (sh->slice_qp > 51 || - sh->slice_qp < -s->sps->qp_bd_offset) { - mpp_err("The slice_qp %d is outside the valid range " - "[%d, 51].\n", - sh->slice_qp, - -s->sps->qp_bd_offset); - return MPP_ERR_STREAM; - } - if (s->h265dctx->compare_info != NULL && sh->first_slice_in_pic_flag) { - CurrentFameInf_t *info = (CurrentFameInf_t *)s->h265dctx->compare_info; - SliceHeader *openhevc_sh = (SliceHeader *)&info->sh; - h265d_dbg(H265D_DBG_FUNCTION, "compare_sliceheader in"); - if (compare_sliceheader(openhevc_sh, &s->sh) < 0) { - mpp_log("compare sliceHeader with openhevc diff\n"); - mpp_assert(0); - } - h265d_dbg(H265D_DBG_FUNCTION, "compare_sliceheader ok"); - } - - sh->slice_ctb_addr_rs = sh->slice_segment_addr; - - if (!s->sh.slice_ctb_addr_rs && s->sh.dependent_slice_segment_flag) { - mpp_err("Impossible slice segment.\n"); - return MPP_ERR_STREAM; - } - - s->slice_initialized = 1; - - return 0; -__BITREAD_ERR: - return MPP_ERR_STREAM; -} - -/** - * @return AV MPP_ERR_STREAM if the packet is not a valid NAL unit, - * 0 if the unit should be skipped, 1 otherwise - */ -static RK_S32 hls_nal_unit(HEVCContext *s) -{ - BitReadCtx_t*gb = &s->HEVClc->gb; - RK_S32 value = 0; - - READ_ONEBIT(gb, &value); - if ( value != 0) - return MPP_ERR_STREAM; - - READ_BITS(gb, 6, &s->nal_unit_type); - - READ_BITS(gb, 6, &s->nuh_layer_id); - - READ_BITS(gb, 3, &s->temporal_id); - - s->temporal_id = s->temporal_id - 1; - - if (s->temporal_id < 0) - return MPP_ERR_STREAM; - - h265d_dbg(H265D_DBG_GLOBAL, - "nal_unit_type: %d, nuh_layer_id: %d temporal_id: %d\n", - s->nal_unit_type, s->nuh_layer_id, s->temporal_id); - - return (s->nuh_layer_id); -__BITREAD_ERR: - return MPP_ERR_STREAM; -} - -static RK_S32 mpp_hevc_output_frame(void *ctx, int flush) -{ - - H265dContext_t *h265dctx = (H265dContext_t *)ctx; - HEVCContext *s = (HEVCContext *)h265dctx->priv_data; - - do { - RK_S32 nb_output = 0; - RK_S32 min_poc = INT_MAX; - RK_S32 min_idx = 0; - RK_U32 i; - - for (i = 0; i < MPP_ARRAY_ELEMS(s->DPB); i++) { - HEVCFrame *frame = &s->DPB[i]; - if ((frame->flags & HEVC_FRAME_FLAG_OUTPUT) && - frame->sequence == s->seq_output) { - nb_output++; - if (frame->poc < min_poc) { - min_poc = frame->poc; - min_idx = i; - } - } - } - - /* wait for more frames before output */ - if (!flush && s->seq_output == s->seq_decode && s->sps && - nb_output <= s->sps->temporal_layer[s->sps->max_sub_layers - 1].num_reorder_pics) - return 0; - - if (nb_output) { - HEVCFrame *frame = &s->DPB[min_idx]; - - frame->flags &= ~(HEVC_FRAME_FLAG_OUTPUT); - s->output_frame_idx = min_idx; - - mpp_buf_slot_set_flag(s->slots, frame->slot_index, SLOT_QUEUE_USE); - mpp_buf_slot_enqueue(s->slots, frame->slot_index, QUEUE_DISPLAY); - - h265d_dbg(H265D_DBG_REF, - "Output frame with POC %d frame->slot_index = %d\n", frame->poc, frame->slot_index); - - - return 1; - } - - if (s->seq_output != s->seq_decode) - s->seq_output = (s->seq_output + 1) & 0xff; - else - break; - } while (1); - - return 0; -} - -static RK_S32 hevc_frame_start(HEVCContext *s) -{ - - int ret; - - s->is_decoded = 0; - s->first_nal_type = s->nal_unit_type; - - ret = mpp_hevc_set_new_ref(s, &s->frame, s->poc); - - if (ret < 0) - goto fail; - - s->miss_ref_flag = 0; - ret = mpp_hevc_frame_rps(s); - if (s->miss_ref_flag) { - if (!IS_IRAP(s)) { - mpp_frame_set_errinfo(s->frame, VPU_FRAME_ERR_UNKNOW); - s->ref->error_flag = 1; - } else { - /*when found current I frame have miss refer - may be stream have error so first set current frame - no output and flush other frame output from dpb - then set current frame can as output - */ - HEVCFrame *frame = NULL; - RK_U32 i = 0; - for (i = 0; i < MPP_ARRAY_ELEMS(s->DPB); i++) { - frame = &s->DPB[i]; - if (frame->poc == s->poc ) { - frame->flags &= ~(HEVC_FRAME_FLAG_OUTPUT); - break; - } else { - frame = NULL; - } - } - do { - ret = mpp_hevc_output_frame(s->h265dctx, 1); - } while (ret); - if (frame) { - frame->flags |= HEVC_FRAME_FLAG_OUTPUT; - } - } - } - - mpp_buf_slot_set_prop(s->slots, s->ref->slot_index, SLOT_FRAME, s->ref->frame); - - if (ret < 0) { - mpp_err("Error constructing the frame RPS.\n"); - goto fail; - } - return 0; - -fail: - s->ref = NULL; - return ret; -} - -static RK_S32 parser_nal_unit(HEVCContext *s, const RK_U8 *nal, int length) -{ - - HEVCLocalContext *lc = s->HEVClc; - BitReadCtx_t *gb = &lc->gb; - RK_S32 ret; - mpp_set_bitread_ctx(gb, (RK_U8*)nal, length); - mpp_set_pre_detection(gb); - ret = hls_nal_unit(s); - if (ret < 0) { - mpp_err("Invalid NAL unit %d, skipping.\n", - s->nal_unit_type); - goto fail; - } else if (ret != (s->decoder_id) && s->nal_unit_type != NAL_VPS) - return 0; - - if (s->temporal_id > s->temporal_layer_id) - return 0; - - s->nuh_layer_id = ret; - h265d_dbg(H265D_DBG_GLOBAL, "s->nal_unit_type = %d,len = %d \n", s->nal_unit_type, length); - //mpp_log("s->nal_unit_type = %d,len = %d \n", s->nal_unit_type, length); -#if 0 - if (fp != NULL) { - if (s->nal_unit_type >= 32 && s->nal_unit_type <= 34) { - RK_U32 nal_1 = 0x01000000; - fwrite(&nal_1, 1, 4, fp); - fwrite(nal, 1, length, fp); - } - } - if (s->nb_frame > 1088 && (s->nal_unit_type >= 16 && s->nal_unit_type <= 21)) { - start_write = 1; - mpp_log("start %d", s->nb_frame); - } -#endif - - switch (s->nal_unit_type) { - case NAL_VPS: - ret = mpp_hevc_decode_nal_vps(s); - if (ret < 0) - goto fail; - break; - case NAL_SPS: - ret = mpp_hevc_decode_nal_sps(s); - if (ret < 0) - goto fail; - break; - case NAL_PPS: - ret = mpp_hevc_decode_nal_pps(s); - if (ret < 0) - goto fail; - break; - case NAL_SEI_PREFIX: - case NAL_SEI_SUFFIX: - ret = mpp_hevc_decode_nal_sei(s); - if (ret < 0) - goto fail; - break; - case NAL_TRAIL_R: - case NAL_TRAIL_N: - case NAL_TSA_N: - case NAL_TSA_R: - case NAL_STSA_N: - case NAL_STSA_R: - case NAL_BLA_W_LP: - case NAL_BLA_W_RADL: - case NAL_BLA_N_LP: - case NAL_IDR_W_RADL: - case NAL_IDR_N_LP: - case NAL_CRA_NUT: - case NAL_RADL_N: - case NAL_RADL_R: - case NAL_RASL_N: - case NAL_RASL_R: -#if 0 - if (fp != NULL && (s->nb_frame < 1200) && start_write) { - RK_U32 nal_1 = 0x01000000; - fwrite(&nal_1, 1, 4, fp); - fwrite(nal, 1, length, fp); - } -#endif - h265d_dbg(H265D_DBG_FUNCTION, "hls_slice_header in"); - ret = hls_slice_header(s); - h265d_dbg(H265D_DBG_FUNCTION, "hls_slice_header out"); - if (ret < 0) - return ret; - - if (s->max_ra == INT_MAX) { - if (s->nal_unit_type == NAL_CRA_NUT || IS_BLA(s)) { - s->max_ra = s->poc; - } else { - if (IS_IDR(s)) - s->max_ra = INT_MIN; - } - } - - if ((s->nal_unit_type == NAL_RASL_R || s->nal_unit_type == NAL_RASL_N) && - s->poc <= s->max_ra) { - s->is_decoded = 0; - break; - } else if ((s->poc < s->max_ra) && !IS_IRAP(s)) { //when seek to I slice skip the stream small then I slic poc - s->is_decoded = 0; - break; - } else { - if (s->nal_unit_type == NAL_RASL_R && s->poc > s->max_ra) - s->max_ra = INT_MIN; - } - - if (s->sh.first_slice_in_pic_flag) { - ret = hevc_frame_start(s); - if (ret < 0) - return ret; - } else if (!s->ref) { - mpp_err("First slice in a frame missing.\n"); - goto fail; - } - - if (s->nal_unit_type != s->first_nal_type) { - mpp_err("Non-matching NAL types of the VCL NALUs: %d %d\n", - s->first_nal_type, s->nal_unit_type); - goto fail; - } - - if (!s->sh.dependent_slice_segment_flag && - s->sh.slice_type != I_SLICE) { - // ret = mpp_hevc_slice_rpl(s); - if (ret < 0) { - mpp_log("Error constructing the reference lists for the current slice.\n"); - goto fail; - } - // rk_get_ref_info(s); - } - - - s->is_decoded = 1; - - break; - case NAL_EOS_NUT: - case NAL_EOB_NUT: - s->seq_decode = (s->seq_decode + 1) & 0xff; - s->max_ra = INT_MAX; - break; - case NAL_AUD: - case NAL_FD_NUT: - break; - default: - mpp_log("Skipping NAL unit %d\n", s->nal_unit_type); - } - - return 0; -fail: - // if (s->h265dctx->err_recognition & AV_EF_EXPLODE) - // return ret; - return 0; -} - - -typedef union { - RK_U32 u32; - RK_U16 u16[2]; - RK_U8 u8 [4]; - float f32; -} mpp_alias32; - -#define MPP_FAST_UNALIGNED 1 - - -#ifndef MPP_RN32A -#define MPP_RN32A(p) (((const mpp_alias32*)(p))->u32) -#endif -RK_S32 mpp_hevc_extract_rbsp(HEVCContext *s, const RK_U8 *src, int length, - HEVCNAL *nal) -{ - RK_S32 i; - - s->skipped_bytes = 0; - -#define STARTCODE_TEST \ - if (i + 2 < length && src[i + 1] == 0 && src[i + 2] < 3) { \ - /* startcode, so we must be past the end */ \ - length = i; \ - break; \ - } - -#if MPP_FAST_UNALIGNED -#define FIND_FIRST_ZERO \ - if (i > 0 && !src[i]) \ - i--; \ - while (src[i]) \ - i++ - - for (i = 0; i + 1 < length; i += 5) { - if (!((~MPP_RN32A(src + i) & - (MPP_RN32A(src + i) - 0x01000101U)) & - 0x80008080U)) - continue; - - FIND_FIRST_ZERO; - - STARTCODE_TEST; - i -= 3; - } -#else - for (i = 0; i + 1 < length; i += 2) { - if (src[i]) - continue; - if (i > 0 && src[i - 1] == 0) - i--; - STARTCODE_TEST; - } -#endif - - if (length + MPP_INPUT_BUFFER_PADDING_SIZE > nal->rbsp_buffer_size) { - RK_S32 min_size = length + MPP_INPUT_BUFFER_PADDING_SIZE; - mpp_free(nal->rbsp_buffer); - nal->rbsp_buffer = NULL; - min_size = MPP_MAX(17 * min_size / 16 + 32, min_size); - nal->rbsp_buffer = mpp_malloc(RK_U8, min_size); - if (nal->rbsp_buffer == NULL) { - min_size = 0; - } - nal->rbsp_buffer_size = min_size; - } - - memcpy(nal->rbsp_buffer, src, length); - nal->data = nal->rbsp_buffer; - nal->size = length; - - memset(nal->rbsp_buffer + length, 0, MPP_INPUT_BUFFER_PADDING_SIZE); - return length; -} - -static RK_S32 split_nal_units(HEVCContext *s, RK_U8 *buf, RK_U32 length) -{ - RK_S32 i, consumed; - MPP_RET ret = MPP_OK; - s->nb_nals = 0; - while (length >= 4) { - HEVCNAL *nal; - RK_S32 extract_length = 0; - - if (s->is_nalff) { - for (i = 0; i < s->nal_length_size; i++) - extract_length = (extract_length << 8) | buf[i]; - buf += s->nal_length_size; - length -= s->nal_length_size; - - if ((RK_U32)extract_length > length) { - mpp_err( "Invalid NAL unit size.\n"); - ret = MPP_ERR_STREAM; - goto fail; - } - } else { - /* search start code */ - if (buf[2] == 0) { - length--; - buf++; - continue; - } - if (buf[0] != 0 || buf[1] != 0 || buf[2] != 1) { - RK_U32 state = (RK_U32) - 1; - int has_nal = 0; - for (i = 0; i < (RK_S32)length; i++) { - state = (state << 8) | buf[i]; - if (((state >> 8) & 0xFFFFFF) == START_CODE) { - has_nal = 1; - i = i - 3; - break; - } - } - - if (has_nal) { - length -= i; - buf += i; - continue; - } - mpp_err( "No start code is found.\n"); - ret = MPP_ERR_STREAM; - goto fail; - } - - buf += 3; - length -= 3; - } - - if (!s->is_nalff) - extract_length = length; - - if (!extract_length) { - return MPP_OK; - } - if (s->nals_allocated < 1) { - RK_S32 new_size = s->nals_allocated + 10; - HEVCNAL *tmp = mpp_malloc(HEVCNAL, new_size); - memset((void*)tmp, 0, new_size * sizeof(HEVCNAL)); - s->nals_allocated = new_size; - s->nals = tmp; - } - if (s->nals_allocated < s->nb_nals + 1) { - int new_size = s->nals_allocated + 10; - HEVCNAL *tmp = mpp_malloc(HEVCNAL, new_size); - memset((void*)tmp, 0, new_size * sizeof(HEVCNAL)); - if (!tmp) { - mpp_err("return enomm new_size %d", new_size); - ret = MPP_ERR_NOMEM; - goto fail; - } - memcpy((void*)tmp, (void*)s->nals, (new_size - 10)*sizeof(HEVCNAL)); - mpp_free(s->nals); - s->nals = NULL; - s->nals = tmp; - memset(s->nals + s->nals_allocated, 0, - (new_size - s->nals_allocated) * sizeof(*tmp)); - s->nals_allocated = new_size; - } - nal = &s->nals[s->nb_nals]; - - consumed = mpp_hevc_extract_rbsp(s, buf, extract_length, nal); - - s->nb_nals++; - - if (consumed <= 0) { - ret = MPP_ERR_STREAM; - goto fail; - } - - mpp_set_bitread_ctx(&s->HEVClc->gb, (RK_U8 *)nal->data, nal->size); - mpp_set_pre_detection(&s->HEVClc->gb); - hls_nal_unit(s); - - if (s->nal_unit_type < NAL_VPS) { - - if (nal->size != consumed) - h265d_dbg(H265D_DBG_GLOBAL, "tag_stream: nal.size=%d, consumed=%d\n", nal->size, consumed); - - } - - /* if (s->nal_unit_type == NAL_EOB_NUT || - s->nal_unit_type == NAL_EOS_NUT) - s->eos = 1;*/ - - buf += consumed; - length -= consumed; - } -fail: - return ret; - -} -static RK_S32 parser_nal_units(HEVCContext *s) -{ - /* parse the NAL units */ - RK_S32 i, ret = 0; - for (i = 0; i < s->nb_nals; i++) { - ret = parser_nal_unit(s, s->nals[i].data, s->nals[i].size); - if (ret < 0) { - mpp_log("Error parsing NAL unit #%d.\n", i); - ret = 0; - goto fail; - } - } -fail: - return ret; -} - -RK_U16 U16_AT(const RK_U8 *ptr) -{ - return ptr[0] << 8 | ptr[1]; -} - -static RK_S32 hevc_parser_extradata(HEVCContext *s) -{ - H265dContext_t *h265dctx = s->h265dctx; - RK_S32 ret = MPP_SUCCESS; - if (h265dctx->extradata_size > 3 && - (h265dctx->extradata[0] || h265dctx->extradata[1] || - h265dctx->extradata[2] > 1)) { - /* It seems the extradata is encoded as hvcC format. - * Temporarily, we support configurationVersion==0 until 14496-15 3rd - * is finalized. When finalized, configurationVersion will be 1 and we - * can recognize hvcC by checking if h265dctx->extradata[0]==1 or not. */ - const RK_U8 *ptr = (const RK_U8 *)h265dctx->extradata; - RK_U32 size = h265dctx->extradata_size; - RK_U32 numofArrays = 0, numofNals = 0; - RK_U32 j = 0, i = 0; - if (size < 7) { - return MPP_NOK; - } - - mpp_log("extradata is encoded as hvcC format"); - s->is_nalff = 1; - s->nal_length_size = 1 + (ptr[14 + 7] & 3); - ptr += 22; - size -= 22; - numofArrays = (char)ptr[0]; - ptr += 1; - size -= 1; - for (i = 0; i < numofArrays; i++) { - ptr += 1; - size -= 1; - // Num of nals - numofNals = U16_AT(ptr); - ptr += 2; - size -= 2; - - for (j = 0; j < numofNals; j++) { - RK_U32 length = 0; - if (size < 2) { - return MPP_NOK; - } - - length = U16_AT(ptr); - - ptr += 2; - size -= 2; - if (size < length) { - return MPP_NOK; - } - parser_nal_unit(s, ptr, length); - ptr += length; - size -= length; - } - } - } else { - s->is_nalff = 0; - ret = split_nal_units(s, h265dctx->extradata, h265dctx->extradata_size); - if (ret < 0) - return ret; - ret = parser_nal_units(s); - if (ret < 0) - return ret; - } - return ret; -} - -MPP_RET h265d_prepare(void *ctx, MppPacket pkt, HalDecTask *task) -{ - - MPP_RET ret = MPP_OK; - H265dContext_t *h265dctx = (H265dContext_t *)ctx; - HEVCContext *s = (HEVCContext *)h265dctx->priv_data; - SplitContext_t *sc = (SplitContext_t*)h265dctx->split_cxt; - RK_S64 pts = -1, dts = -1; - RK_U8 *buf = NULL; - void *pos = NULL; - RK_S32 length = 0; - - //task->valid = 0; - s->eos = mpp_packet_get_eos(pkt); - if (sc != NULL) { - sc->eos = s->eos; - } - buf = (RK_U8 *)mpp_packet_get_pos(pkt); - pts = mpp_packet_get_pts(pkt); - dts = mpp_packet_get_dts(pkt); - h265d_dbg(H265D_DBG_TIME, "prepare get pts %lld", pts); - length = (RK_S32)mpp_packet_get_length(pkt); - - if (mpp_packet_get_flag(pkt)& MPP_PACKET_FLAG_EXTRA_DATA) { - - h265dctx->extradata_size = length; - h265dctx->extradata = buf; - hevc_parser_extradata(s); - pos = buf + length; - mpp_packet_set_pos(pkt, pos); - return MPP_OK; - } - - if (h265dctx->need_split && !s->is_nalff) { - - RK_S32 consume = 0; - RK_U8 *split_out_buf = NULL; - RK_S32 split_size = 0; - - consume = h265d_split_frame(h265dctx->split_cxt, (const RK_U8**)&split_out_buf, &split_size, - (const RK_U8*)buf, length, pts, dts); - pos = buf + consume; - mpp_packet_set_pos(pkt, pos); - if (split_size) { - buf = split_out_buf; - length = split_size; - s->checksum_buf = buf; //check with openhevc - s->checksum_buf_size = split_size; - h265d_dbg(H265D_DBG_TIME, "split frame get pts %lld", sc->pts); - s->pts = sc->pts; - } else { - return MPP_FAIL_SPLIT_FRAME; - } - } else { - pos = buf + length; - s->pts = pts; - mpp_packet_set_pos(pkt, pos); - if (s->eos && !length) { - task->valid = 0; - task->flags.eos = 1; - mpp_log("hevc flush eos"); - h265d_flush(ctx); - return ret; - } - } -#ifdef dump - if (s->nb_frame < 10 && fp != NULL) { - fwrite(buf, 1, length, fp); - } -#endif - ret = (MPP_RET)split_nal_units(s, buf, length); - - if (MPP_OK == ret) { - if (MPP_OK == h265d_syntax_fill_slice(s->h265dctx, task->input)) { - task->valid = 1; - task->input_packet = s->input_packet; - } - } - return ret; - -} - -MPP_RET h265d_get_stream(void *ctx, RK_U8 **buf, RK_S32 *size) -{ - MPP_RET ret = MPP_OK; - H265dContext_t *h265dctx = (H265dContext_t *)ctx; - HEVCContext *s = h265dctx->priv_data; - *buf = s->checksum_buf; - *size = s->checksum_buf_size; - return ret; -} - -MPP_RET h265d_set_compare_info(void *ctx, void *info) -{ - MPP_RET ret = MPP_OK; - H265dContext_t *h265dctx = (H265dContext_t *)ctx; - h265dctx->compare_info = info; - return ret; -} - - -MPP_RET h265d_parse(void *ctx, HalDecTask *task) -{ - MPP_RET ret; - H265dContext_t *h265dctx = (H265dContext_t *)ctx; - HEVCContext *s = h265dctx->priv_data; - - s->got_frame = 0; - s->task = task; - s->ref = NULL; - ret = parser_nal_units(s); - if (ret < 0) { - if (ret == MPP_ERR_STREAM) { - mpp_log("current stream is no right skip it"); - ret = 0; - } - return ret; - } - h265d_dbg(H265D_DBG_GLOBAL, "decode poc = %d", s->poc); - if (s->ref) { - h265d_parser2_syntax(h265dctx); - s->task->syntax.data = s->hal_pic_private; - s->task->syntax.number = 1; - s->task->valid = 1; - if (s->eos) { - s->task->flags.eos = 1; - } - } else { - if (s->eos) { - h265d_flush(ctx); - s->task->flags.eos = 1; - } - } - s->nb_frame++; - if (s->is_decoded) { - h265d_dbg(H265D_DBG_GLOBAL, "Decoded frame with POC %d.\n", s->poc); - s->is_decoded = 0; - } - mpp_hevc_output_frame(ctx, 0); - return MPP_OK; -} - -MPP_RET h265d_deinit(void *ctx) -{ - H265dContext_t *h265dctx = (H265dContext_t *)ctx; - HEVCContext *s = h265dctx->priv_data; - SplitContext_t *sc = h265dctx->split_cxt; - RK_U8 *buf = NULL; - int i; - - for (i = 0; i < MAX_DPB_SIZE; i++) { - mpp_hevc_unref_frame(s, &s->DPB[i], ~0); - mpp_frame_deinit(&s->DPB[i].frame); - } - - for (i = 0; i < MAX_VPS_COUNT; i++) - mpp_free(s->vps_list[i]); - for (i = 0; i < MAX_SPS_COUNT; i++) - mpp_free(s->sps_list[i]); - for (i = 0; i < MAX_PPS_COUNT; i++) - mpp_hevc_pps_free(s->pps_list[i]); - - mpp_free(s->HEVClc); - - s->HEVClc = NULL; - - for (i = 0; i < s->nals_allocated; i++) - mpp_free(s->nals[i].rbsp_buffer); - - if (s->nals) { - mpp_free(s->nals); - } - - s->nals_allocated = 0; - - if (s->hal_pic_private) { - mpp_free(s->hal_pic_private); - } - if (s->input_packet) { - buf = mpp_packet_get_data(s->input_packet); - mpp_free(buf); - mpp_packet_deinit(&s->input_packet); - } - - if (s) { - mpp_free(s); - } - - if (sc) { - h265d_split_deinit(sc); - } - return 0; -} - -static RK_S32 hevc_init_context(H265dContext_t *h265dctx) -{ - HEVCContext *s = h265dctx->priv_data; - RK_U32 i; - - s->h265dctx = h265dctx; - - s->HEVClc = (HEVCLocalContext*)mpp_calloc(HEVCLocalContext, 1); - if (!s->HEVClc) - goto fail; - - for (i = 0; i < MPP_ARRAY_ELEMS(s->DPB); i++) { - s->DPB[i].slot_index = 0xff; - s->DPB[i].poc = INT_MAX; - s->DPB[i].error_flag = 0; - mpp_frame_init(&s->DPB[i].frame); - if (!s->DPB[i].frame) - goto fail; - } - - s->max_ra = INT_MAX; - - - s->temporal_layer_id = 8; - s->context_initialized = 1; - - return 0; - -fail: - h265d_deinit(h265dctx); - return MPP_ERR_NOMEM; -} - - -MPP_RET h265d_init(void *ctx, ParserCfg *parser_cfg) -{ - - H265dContext_t *h265dctx = (H265dContext_t *)ctx; - HEVCContext *s = (HEVCContext *)h265dctx->priv_data; - SplitContext_t *sc = (SplitContext_t*)h265dctx->split_cxt; - RK_S32 ret; - RK_U8 *buf = NULL; - RK_S32 size = SZ_512K; - if (s == NULL) { - s = (HEVCContext*)mpp_calloc(HEVCContext, 1); - if (s == NULL) { - mpp_err("hevc contxt malloc fail"); - return MPP_ERR_NOMEM; - } - h265dctx->priv_data = s; - } - - h265dctx->need_split = parser_cfg->need_split; - - if (sc == NULL && h265dctx->need_split) { - h265d_split_init((void**)&sc); - if (sc == NULL) { - mpp_err("split contxt malloc fail"); - return MPP_ERR_NOMEM; - } - h265dctx->split_cxt = sc; - } - - // mpp_env_set_u32("h265d_debug", H265D_DBG_REF); - mpp_env_get_u32("h265d_debug", &h265d_debug, 0); - - ret = hevc_init_context(h265dctx); - - s->hal_pic_private = mpp_calloc_size(void, sizeof(h265d_dxva2_picture_context_t)); - - if (ret < 0) - return ret; - - s->picture_struct = 0; - - s->slots = parser_cfg->frame_slots; - - s->packet_slots = parser_cfg->packet_slots; - s->notify_cb = parser_cfg->notify_cb; - - if (h265dctx->extradata_size > 0 && h265dctx->extradata) { - ret = hevc_parser_extradata(s); - if (ret < 0) { - h265d_deinit(h265dctx); - return ret; - } - } - - buf = mpp_malloc(RK_U8, size); - - if (buf == NULL) { - return MPP_ERR_NOMEM; - } - - if (MPP_OK != mpp_packet_init(&s->input_packet, (void*)buf, size)) { - return MPP_ERR_NOMEM; - } -#ifdef dump - fp = fopen("/data/dump1.bin", "wb+"); -#endif - return 0; -} - -MPP_RET h265d_flush(void *ctx) -{ - RK_S32 ret = 0; - do { - ret = mpp_hevc_output_frame(ctx, 1); - } while (ret); - return MPP_OK; -} - -MPP_RET h265d_reset(void *ctx) -{ - H265dContext_t *h265dctx = (H265dContext_t *)ctx; - HEVCContext *s = (HEVCContext *)h265dctx->priv_data; - RK_S32 ret = 0; - do { - ret = mpp_hevc_output_frame(ctx, 1); - } while (ret); - mpp_hevc_flush_dpb(s); - h265d_split_reset(h265dctx->split_cxt); - s->max_ra = INT_MAX; - s->eos = 0; - return MPP_OK; -} - -MPP_RET h265d_control(void *ctx, RK_S32 cmd, void *param) -{ - (void)ctx; - (void)cmd; - (void)param; - return MPP_OK; -} - -MPP_RET h265d_callback(void *ctx, void *err_info) -{ - H265dContext_t *h265dctx = (H265dContext_t *)ctx; - HEVCContext *s = (HEVCContext *)h265dctx->priv_data; - MppFrame frame = NULL; - RK_U32 i = 0; - - if (s->first_nal_type >= 16 && s->first_nal_type <= 23) { - mpp_log("IS_IRAP frame found error"); - s->max_ra = INT_MAX; - } - // s->miss_ref_flag = 1; - mpp_buf_slot_get_prop(s->slots, s->ref->slot_index, SLOT_FRAME_PTR, &frame); - mpp_frame_set_errinfo(frame, VPU_FRAME_ERR_UNKNOW); - for (i = 0; i < MPP_ARRAY_ELEMS(s->DPB); i++) { - if (s->DPB[i].slot_index == s->ref->slot_index) { - s->DPB[i].error_flag = 1; - } - - } - (void) err_info; - - return MPP_OK; -} - - - -const ParserApi api_h265d_parser = { - "h265d_parse", - MPP_VIDEO_CodingHEVC, - sizeof(H265dContext_t), - 0, - h265d_init, - h265d_deinit, - h265d_prepare, - h265d_parse, - h265d_reset, - h265d_flush, - h265d_control, - h265d_callback, -}; - - +/* + * + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file h265d_parser.c + * @brief + * @author csy(csy@rock-chips.com) + + * @version 1.0.0 + * @history + * 2015.7.15 : Create + */ + +#define MODULE_TAG "H265D_PARSER" + +#include "mpp_bitread.h" +#include "h265d_parser.h" +#include "mpp_mem.h" +#include "mpp_env.h" +#include "h265d_syntax.h" +#include "mpp_packet_impl.h" +#include "h265d_api.h" + +#define START_CODE 0x000001 ///< start_code_prefix_one_3bytes + +RK_U32 h265d_debug; +#ifdef dump +FILE *fp = NULL; +#endif +//static RK_U32 start_write = 0, value = 0; + +/** + * Find the end of the current frame in the bitstream. + * @return the position of the first byte of the next frame, or END_NOT_FOUND + */ +static RK_S32 hevc_find_frame_end(SplitContext_t *sc, const RK_U8 *buf, + int buf_size) +{ + RK_S32 i; + + for (i = 0; i < buf_size; i++) { + int nut, layer_id; + + sc->state64 = (sc->state64 << 8) | buf[i]; + + if (((sc->state64 >> 3 * 8) & 0xFFFFFF) != START_CODE) + continue; + nut = (sc->state64 >> (2 * 8 + 1)) & 0x3F; + layer_id = (((sc->state64 >> 2 * 8) & 0x01) << 5) + (((sc->state64 >> 1 * 8) & 0xF8) >> 3); + //mpp_log("nut = %d layer_id = %d\n",nut,layer_id); + // Beginning of access unit + if ((nut >= NAL_VPS && nut <= NAL_AUD) || nut == NAL_SEI_PREFIX || + (nut >= 41 && nut <= 44) || (nut >= 48 && nut <= 55)) { + if (sc->frame_start_found && !layer_id) { + sc->frame_start_found = 0; + return i - 5; + } + } else if (nut <= NAL_RASL_R || + (nut >= NAL_BLA_W_LP && nut <= NAL_CRA_NUT)) { + int first_slice_segment_in_pic_flag = buf[i] >> 7; + //mpp_log("nut = %d first_slice_segment_in_pic_flag %d layer_id = %d \n",nut, + // first_slice_segment_in_pic_flag, + // layer_id); + if (first_slice_segment_in_pic_flag && !layer_id) { + if (!sc->frame_start_found) { + sc->frame_start_found = 1; + } else { // First slice of next frame found + sc->frame_start_found = 0; + return i - 5; + } + } + } + } + return END_NOT_FOUND; +} + +static RK_S32 mpp_combine_frame(SplitContext_t *sc, RK_S32 next, const RK_U8 **buf, RK_S32 *buf_size) +{ + if (sc->overread) { + mpp_log("overread %d, state:%X next:%d index:%d o_index:%d\n", + sc->overread, sc->state, next, sc->index, sc->overread_index); + mpp_log("%X %X %X %X\n", (*buf)[0], (*buf)[1], (*buf)[2], (*buf)[3]); + } + + /* Copy overread bytes from last frame into buffer. */ + for (; sc->overread > 0; sc->overread--) { + sc->buffer[sc->index++] = sc->buffer[sc->overread_index++]; + } + + /* flush remaining if EOF */ + if (!*buf_size && next == END_NOT_FOUND) { + next = 0; + } + + sc->last_index = sc->index; + + /* copy into buffer end return */ + if (next == END_NOT_FOUND) { + RK_U32 min_size = (*buf_size) + sc->index + MPP_INPUT_BUFFER_PADDING_SIZE; + void* new_buffer; + if (min_size > sc->buffer_size) { + min_size = MPP_MAX(17 * min_size / 16 + 32, min_size); + new_buffer = mpp_realloc(sc->buffer, RK_U8, min_size); + if (!new_buffer) { + sc->buffer_size = 0; + return MPP_ERR_NOMEM; + } + sc->buffer_size = min_size; + sc->buffer = new_buffer; + } + + memcpy(&sc->buffer[sc->index], *buf, *buf_size); + sc->index += *buf_size; + + return -1; + } + + *buf_size = + sc->overread_index = sc->index + next; + + /* append to buffer */ + if (sc->index) { + RK_U32 min_size = next + sc->index + MPP_INPUT_BUFFER_PADDING_SIZE; + void* new_buffer; + if (min_size > sc->buffer_size) { + min_size = MPP_MAX(17 * min_size / 16 + 32, min_size); + new_buffer = mpp_realloc(sc->buffer, RK_U8, min_size); + if (!new_buffer) { + sc->buffer_size = 0; + return MPP_ERR_NOMEM; + } + sc->buffer_size = min_size; + sc->buffer = new_buffer; + } + + if (next > -MPP_INPUT_BUFFER_PADDING_SIZE) + memcpy(&sc->buffer[sc->index], *buf, + next + MPP_INPUT_BUFFER_PADDING_SIZE); + sc->index = 0; + *buf = sc->buffer; + } + + /* store overread bytes */ + for (; next < 0; next++) { + sc->state = (sc->state << 8) | sc->buffer[sc->last_index + next]; + sc->state64 = (sc->state64 << 8) | sc->buffer[sc->last_index + next]; + sc->overread++; + } + + if (sc->overread) { + mpp_log("overread %d, state:%X next:%d index:%d o_index:%d\n", + sc->overread, sc->state, next, sc->index, sc->overread_index); + mpp_log("%X %X %X %X\n", (*buf)[0], (*buf)[1], (*buf)[2], (*buf)[3]); + } + + return 0; +} + +RK_S32 h265d_split_init(void **sc) +{ + SplitContext_t *s = NULL; + if (s == NULL) { + s = mpp_calloc(SplitContext_t, 1); + if (s != NULL) { + *sc = s; + } else { + mpp_err("split alloc context fail"); + return MPP_ERR_NOMEM; + } + } + s->buffer = mpp_malloc(RK_U8, MAX_FRAME_SIZE); + s->buffer_size = MAX_FRAME_SIZE; + s->fetch_timestamp = 1; + return MPP_OK; +} + +void mpp_fetch_timestamp(SplitContext_t *s, RK_S32 off) +{ + RK_S32 i; + + s->dts = s->pts = -1; + s->offset = 0; + for (i = 0; i < MPP_PARSER_PTS_NB; i++) { + h265d_dbg(H265D_DBG_TIME, "s->cur_offset %lld s->cur_frame_offset[%d] %lld s->frame_offset %lld s->next_frame_offset %lld", + s->cur_offset, i, s->cur_frame_offset[i], s->frame_offset, s->next_frame_offset); + if ( s->cur_offset + off >= s->cur_frame_offset[i] + && (s->frame_offset < s->cur_frame_offset[i] || + (!s->frame_offset && !s->next_frame_offset)) // first field/frame + // check disabled since MPEG-TS does not send complete PES packets + && /*s->next_frame_offset + off <*/ s->cur_frame_end[i]) { + s->dts = s->cur_frame_dts[i]; + s->pts = s->cur_frame_pts[i]; + s->offset = s->next_frame_offset - s->cur_frame_offset[i]; + if (s->cur_offset + off < s->cur_frame_end[i]) + break; + } + } +} +RK_S32 h265d_split_frame(void *sc, + const RK_U8 **poutbuf, RK_S32 *poutbuf_size, + const RK_U8 *buf, RK_S32 buf_size, RK_S64 pts, RK_S64 dts) +{ + RK_S32 next, i; + + SplitContext_t *s = (SplitContext_t*)sc; + + if (s->cur_offset + buf_size != + s->cur_frame_end[s->cur_frame_start_index]) { /* skip remainder packets */ + /* add a new packet descriptor */ + i = (s->cur_frame_start_index + 1) & (MPP_PARSER_PTS_NB - 1); + s->cur_frame_start_index = i; + s->cur_frame_offset[i] = s->cur_offset; + s->cur_frame_end[i] = s->cur_offset + buf_size; + s->cur_frame_pts[i] = pts; + s->cur_frame_dts[i] = dts; + h265d_dbg(H265D_DBG_TIME, "s->cur_frame_start_index = %d,cur_frame_offset = %lld,s->cur_frame_end = %lld pts = %lld", + s->cur_frame_start_index, s->cur_frame_offset[i], s->cur_frame_end[i], pts); + } + + if (s->fetch_timestamp) { + s->fetch_timestamp = 0; + s->last_pts = s->pts; + s->last_dts = s->dts; + mpp_fetch_timestamp(s, 0); + } + + if (s->eos) { + *poutbuf = s->buffer; + *poutbuf_size = s->index; + return 0; + } + + next = hevc_find_frame_end(s, buf, buf_size); + + if (mpp_combine_frame(s, next, &buf, &buf_size) < 0) { + *poutbuf = NULL; + *poutbuf_size = 0; + s->cur_offset += buf_size; + return buf_size; + } + + *poutbuf = buf; + *poutbuf_size = buf_size; + + if (next < 0) + next = 0; + + if (*poutbuf_size) { + /* fill the data for the current frame */ + s->frame_offset = s->next_frame_offset; + + /* offset of the next frame */ + s->next_frame_offset = s->cur_offset + next; + s->fetch_timestamp = 1; + } + + s->cur_offset += next; + return next; +} + +RK_S32 h265d_split_reset(void *sc) +{ + RK_U8 *buf = NULL; + RK_U32 size = 0; + SplitContext_t *s = (SplitContext_t*)sc; + if (sc == NULL) { + return MPP_OK; + } + buf = s->buffer; + size = s->buffer_size; + memset(s, 0, sizeof(SplitContext_t)); + s->fetch_timestamp = 1; + s->buffer = buf; + s->buffer_size = size; + s->eos = 0; + return MPP_OK; +} + + +RK_S32 h265d_split_deinit(void *sc) +{ + SplitContext_t *s = (SplitContext_t *)sc; + if (s->buffer) { + mpp_free(s->buffer); + s->buffer = NULL; + } + if (s) { + mpp_free(s); + s = NULL; + } + return MPP_OK; +} + +static RK_S32 pred_weight_table(HEVCContext *s, BitReadCtx_t *gb) +{ + RK_U32 i = 0; + RK_U32 j = 0; + RK_U8 luma_weight_l0_flag[16]; + RK_U8 chroma_weight_l0_flag[16]; + RK_U8 luma_weight_l1_flag[16]; + RK_U8 chroma_weight_l1_flag[16]; + + READ_UE(gb, &s->sh.luma_log2_weight_denom); + if (s->sps->chroma_format_idc != 0) { + RK_S32 delta = 0; + READ_SE(gb, &delta); + s->sh.chroma_log2_weight_denom = mpp_clip(s->sh.luma_log2_weight_denom + delta, 0, 7); + } + + for (i = 0; i < s->sh.nb_refs[L0]; i++) { + READ_ONEBIT(gb, &luma_weight_l0_flag[i]); + if (!luma_weight_l0_flag[i]) { + s->sh.luma_weight_l0[i] = 1 << s->sh.luma_log2_weight_denom; + s->sh.luma_offset_l0[i] = 0; + } + } + + if (s->sps->chroma_format_idc != 0) { // FIXME: invert "if" and "for" + for (i = 0; i < s->sh.nb_refs[L0]; i++) { + READ_ONEBIT(gb, &chroma_weight_l0_flag[i]); + } + } else { + for (i = 0; i < s->sh.nb_refs[L0]; i++) + chroma_weight_l0_flag[i] = 0; + } + + for (i = 0; i < s->sh.nb_refs[L0]; i++) { + if (luma_weight_l0_flag[i]) { + RK_S32 delta_luma_weight_l0 = 0; + READ_SE(gb, &delta_luma_weight_l0); + s->sh.luma_weight_l0[i] = (1 << s->sh.luma_log2_weight_denom) + delta_luma_weight_l0; + READ_SE(gb, &s->sh.luma_offset_l0[i]); + } + if (chroma_weight_l0_flag[i]) { + for (j = 0; j < 2; j++) { + RK_S32 delta_chroma_weight_l0 = 0; + RK_S32 delta_chroma_offset_l0 = 0; + READ_SE(gb, &delta_chroma_weight_l0); + READ_SE(gb, &delta_chroma_offset_l0); + s->sh.chroma_weight_l0[i][j] = (1 << s->sh.chroma_log2_weight_denom) + delta_chroma_weight_l0; + s->sh.chroma_offset_l0[i][j] = mpp_clip((delta_chroma_offset_l0 - ((128 * s->sh.chroma_weight_l0[i][j]) + >> s->sh.chroma_log2_weight_denom) + 128), -128, 127); + } + } else { + s->sh.chroma_weight_l0[i][0] = 1 << s->sh.chroma_log2_weight_denom; + s->sh.chroma_offset_l0[i][0] = 0; + s->sh.chroma_weight_l0[i][1] = 1 << s->sh.chroma_log2_weight_denom; + s->sh.chroma_offset_l0[i][1] = 0; + } + } + + if (s->sh.slice_type == B_SLICE) { + for (i = 0; i < s->sh.nb_refs[L1]; i++) { + READ_ONEBIT(gb, &luma_weight_l1_flag[i]); + if (!luma_weight_l1_flag[i]) { + s->sh.luma_weight_l1[i] = 1 << s->sh.luma_log2_weight_denom; + s->sh.luma_offset_l1[i] = 0; + } + } + if (s->sps->chroma_format_idc != 0) { + for (i = 0; i < s->sh.nb_refs[L1]; i++) + READ_ONEBIT(gb, &chroma_weight_l1_flag[i]); + } else { + for (i = 0; i < s->sh.nb_refs[L1]; i++) + chroma_weight_l1_flag[i] = 0; + } + for (i = 0; i < s->sh.nb_refs[L1]; i++) { + if (luma_weight_l1_flag[i]) { + RK_S32 delta_luma_weight_l1 = 0; + READ_UE(gb, &delta_luma_weight_l1); + s->sh.luma_weight_l1[i] = (1 << s->sh.luma_log2_weight_denom) + delta_luma_weight_l1; + READ_SE(gb, &s->sh.luma_offset_l1[i]); + } + if (chroma_weight_l1_flag[i]) { + for (j = 0; j < 2; j++) { + RK_S32 delta_chroma_weight_l1 = 0; + RK_S32 delta_chroma_offset_l1 = 0; + READ_SE(gb, &delta_chroma_weight_l1); + READ_SE(gb, &delta_chroma_offset_l1); + s->sh.chroma_weight_l1[i][j] = (1 << s->sh.chroma_log2_weight_denom) + delta_chroma_weight_l1; + s->sh.chroma_offset_l1[i][j] = mpp_clip((delta_chroma_offset_l1 - ((128 * s->sh.chroma_weight_l1[i][j]) + >> s->sh.chroma_log2_weight_denom) + 128), -128, 127); + } + } else { + s->sh.chroma_weight_l1[i][0] = 1 << s->sh.chroma_log2_weight_denom; + s->sh.chroma_offset_l1[i][0] = 0; + s->sh.chroma_weight_l1[i][1] = 1 << s->sh.chroma_log2_weight_denom; + s->sh.chroma_offset_l1[i][1] = 0; + } + } + } + return 0; +__BITREAD_ERR: + return MPP_ERR_STREAM; +} + +static RK_S32 decode_lt_rps(HEVCContext *s, LongTermRPS *rps, BitReadCtx_t *gb) +{ + const HEVCSPS *sps = s->sps; + RK_S32 max_poc_lsb = 1 << sps->log2_max_poc_lsb; + RK_S32 prev_delta_msb = 0; + RK_U32 nb_sps = 0, nb_sh; + RK_S32 i; + + RK_S32 bit_begin = gb->used_bits; + s->rps_bit_offset[s->slice_idx] = + s->rps_bit_offset_st[s->slice_idx]; + + rps->nb_refs = 0; + if (!sps->long_term_ref_pics_present_flag) + return 0; + + if (sps->num_long_term_ref_pics_sps > 0) + READ_UE(gb, &nb_sps); + + READ_UE(gb, &nb_sh); + + if (nb_sh + nb_sps > MPP_ARRAY_ELEMS(rps->poc)) + return MPP_ERR_STREAM; + + rps->nb_refs = nb_sh + nb_sps; + + for (i = 0; i < rps->nb_refs; i++) { + RK_U8 delta_poc_msb_present; + + if ((RK_U32)i < nb_sps) { + RK_U8 lt_idx_sps = 0; + + if (sps->num_long_term_ref_pics_sps > 1) + READ_BITS(gb, mpp_ceil_log2(sps->num_long_term_ref_pics_sps), <_idx_sps); + + rps->poc[i] = sps->lt_ref_pic_poc_lsb_sps[lt_idx_sps]; + rps->used[i] = sps->used_by_curr_pic_lt_sps_flag[lt_idx_sps]; + } else { + READ_BITS(gb, sps->log2_max_poc_lsb, &rps->poc[i]); + READ_ONEBIT(gb, &rps->used[i]); + } + + READ_ONEBIT(gb, &delta_poc_msb_present); + if (delta_poc_msb_present) { + RK_S32 delta = 0; + + READ_UE(gb, &delta); + + if (i && (RK_U32)i != nb_sps) + delta += prev_delta_msb; + + rps->poc[i] += s->poc - delta * max_poc_lsb - s->sh.pic_order_cnt_lsb; + prev_delta_msb = delta; + } + } + + s->rps_bit_offset[s->slice_idx] + += (gb->used_bits - bit_begin); + + return 0; +__BITREAD_ERR: + return MPP_ERR_STREAM; +} + +static RK_S32 set_sps(HEVCContext *s, const HEVCSPS *sps) +{ + RK_U32 num = 0, den = 0; + + s->h265dctx->coded_width = sps->width; + s->h265dctx->coded_height = sps->height; + s->h265dctx->width = sps->output_width; + s->h265dctx->height = sps->output_height; + s->h265dctx->pix_fmt = sps->pix_fmt; + s->h265dctx->nBitDepth = sps->bit_depth; + s->h265dctx->sample_aspect_ratio = sps->vui.sar; + mpp_buf_slot_setup(s->slots, 25); + + if (sps->vui.video_signal_type_present_flag) + s->h265dctx->color_range = sps->vui.video_full_range_flag ? MPPCOL_RANGE_JPEG + : MPPCOL_RANGE_MPEG; + else + s->h265dctx->color_range = MPPCOL_RANGE_MPEG; + + if (sps->vui.colour_description_present_flag) { + s->h265dctx->colorspace = sps->vui.matrix_coeffs; + } else { + s->h265dctx->colorspace = MPPCOL_SPC_UNSPECIFIED; + } + + s->sps = sps; + s->vps = (HEVCVPS*) s->vps_list[s->sps->vps_id]; + + if (s->vps->vps_timing_info_present_flag) { + num = s->vps->vps_num_units_in_tick; + den = s->vps->vps_time_scale; + } else if (sps->vui.vui_timing_info_present_flag) { + num = sps->vui.vui_num_units_in_tick; + den = sps->vui.vui_time_scale; + } + + if (num != 0 && den != 0) { + // s->h265dctx->time_base.num = num; + // s->h265dctx->time_base.den = den; + // av_reduce(&s->h265dctx->time_base.num, &s->h265dctx->time_base.den, + // num, den, 1 << 30); + } + + return 0; + +} +static RK_S32 compare_sliceheader(SliceHeader *openhevc_sh, SliceHeader *sh) +{ + + if (openhevc_sh->pps_id != sh->pps_id) { + mpp_log(" pps_id diff \n"); + return -1; + } + + if (openhevc_sh->slice_type != sh->slice_type) { + mpp_log(" slice_type diff \n"); + return -1; + } + + if (openhevc_sh->pic_order_cnt_lsb != sh->pic_order_cnt_lsb) { + mpp_log(" pic_order_cnt_lsb diff \n"); + return -1; + } + + if (openhevc_sh->first_slice_in_pic_flag != sh->first_slice_in_pic_flag) { + mpp_log(" first_slice_in_pic_flag diff \n"); + return -1; + } + + if (openhevc_sh->dependent_slice_segment_flag != sh->dependent_slice_segment_flag) { + mpp_log(" dependent_slice_segment_flag diff \n"); + return -1; + } + + if (openhevc_sh->pic_output_flag != sh->pic_output_flag) { + mpp_log(" pic_output_flag diff \n"); + return -1; + } + + if (openhevc_sh->colour_plane_id != sh->colour_plane_id) { + mpp_log(" colour_plane_id diff \n"); + return -1; + } + + if (openhevc_sh->rpl_modification_flag[0] != sh->rpl_modification_flag[0]) { + mpp_log(" rpl_modification_flag[0] diff \n"); + return -1; + } + + if (openhevc_sh->rpl_modification_flag[1] != sh->rpl_modification_flag[1]) { + mpp_log(" rpl_modification_flag[1] diff \n"); + return -1; + } + + if (openhevc_sh->no_output_of_prior_pics_flag != sh->no_output_of_prior_pics_flag) { + mpp_log(" no_output_of_prior_pics_flag diff \n"); + return -1; + } + + if (openhevc_sh->slice_temporal_mvp_enabled_flag != sh->slice_temporal_mvp_enabled_flag) { + mpp_log(" slice_temporal_mvp_enabled_flag diff \n"); + return -1; + } + + if (openhevc_sh->nb_refs[0] != sh->nb_refs[0]) { + mpp_log(" nb_refs[0] diff \n"); + return -1; + } + + if (openhevc_sh->nb_refs[1] != sh->nb_refs[1]) { + mpp_log(" nb_refs[1] diff \n"); + return -1; + } + + if (openhevc_sh->slice_sample_adaptive_offset_flag[0] != + sh->slice_sample_adaptive_offset_flag[0]) { + mpp_log(" slice_sample_adaptive_offset_flag[0] diff \n"); + return -1; + } + + if (openhevc_sh->slice_sample_adaptive_offset_flag[1] != + sh->slice_sample_adaptive_offset_flag[1]) { + mpp_log(" slice_sample_adaptive_offset_flag[1] diff \n"); + return -1; + } + + if (openhevc_sh->slice_sample_adaptive_offset_flag[2] != + sh->slice_sample_adaptive_offset_flag[2]) { + mpp_log(" slice_sample_adaptive_offset_flag[2] diff \n"); + return -1; + } + + if (openhevc_sh->mvd_l1_zero_flag != sh->mvd_l1_zero_flag) { + mpp_log(" mvd_l1_zero_flag diff \n"); + return -1; + } + if (openhevc_sh->cabac_init_flag != sh->cabac_init_flag) { + mpp_log(" cabac_init_flag diff \n"); + return -1; + } + + if (openhevc_sh->disable_deblocking_filter_flag != + sh->disable_deblocking_filter_flag) { + mpp_log(" disable_deblocking_filter_flag diff \n"); + return -1; + } + + if (openhevc_sh->slice_loop_filter_across_slices_enabled_flag != + sh->slice_loop_filter_across_slices_enabled_flag) { + mpp_log(" slice_loop_filter_across_slices_enable diff \n"); + return -1; + } + + if (openhevc_sh->collocated_list != sh->collocated_list) { + mpp_log(" collocated_list diff \n"); + return -1; + } + + if (openhevc_sh->collocated_ref_idx != sh->collocated_ref_idx) { + mpp_log(" collocated_ref_idx diff \n"); + return -1; + } + + if (openhevc_sh->slice_qp_delta != sh->slice_qp_delta) { + mpp_log(" slice_qp_delta diff \n"); + return -1; + } + + if (openhevc_sh->slice_cb_qp_offset != sh->slice_cb_qp_offset) { + mpp_log(" slice_cb_qp_offset diff \n"); + return -1; + } + + if (openhevc_sh->slice_cr_qp_offset != sh->slice_cr_qp_offset) { + mpp_log(" slice_cr_qp_offset diff \n"); + return -1; + } + + if (openhevc_sh->beta_offset != sh->beta_offset) { + mpp_log(" beta_offset diff \n"); + return -1; + } + + if (openhevc_sh->tc_offset != sh->tc_offset) { + mpp_log(" tc_offset diff \n"); + return -1; + } + + if (openhevc_sh->max_num_merge_cand != sh->max_num_merge_cand) { + mpp_log(" max_num_merge_cand diff \n"); + return -1; + } + + if (openhevc_sh->num_entry_point_offsets != sh->num_entry_point_offsets) { + mpp_log(" num_entry_point_offsets diff \n"); + return -1; + } + + if (openhevc_sh->slice_qp != sh->slice_qp) { + mpp_log(" slice_qp diff \n"); + return -1; + } + + if (openhevc_sh->luma_log2_weight_denom != sh->luma_log2_weight_denom) { + mpp_log(" luma_log2_weight_denom diff \n"); + return -1; + } + + if (openhevc_sh->chroma_log2_weight_denom != sh->chroma_log2_weight_denom) { + mpp_log(" chroma_log2_weight_denom diff \n"); + return -1; + } + + /* if (openhevc_sh->slice_ctb_addr_rs != sh->slice_ctb_addr_rs) { + mpp_log(" slice_ctb_addr_rs diff \n"); + return -1; + }*/ + return 0; +} + +static RK_S32 hls_slice_header(HEVCContext *s) +{ + + BitReadCtx_t *gb = &s->HEVClc->gb; + SliceHeader *sh = &s->sh; + RK_S32 i, ret; + RK_S32 value, pps_id; + RK_S32 bit_begin; + +#ifdef JCTVC_M0458_INTERLAYER_RPS_SIG + int NumILRRefIdx; +#endif + + // Coded parameters + + READ_ONEBIT(gb, &sh->first_slice_in_pic_flag); + if ((IS_IDR(s) || IS_BLA(s)) && sh->first_slice_in_pic_flag) { + s->seq_decode = (s->seq_decode + 1) & 0xff; + s->max_ra = INT_MAX; + if (IS_IDR(s)) + mpp_hevc_clear_refs(s); + } + if (s->nal_unit_type >= 16 && s->nal_unit_type <= 23) + READ_ONEBIT(gb, &sh->no_output_of_prior_pics_flag); + + if (IS_IRAP(s) && s->miss_ref_flag && sh->first_slice_in_pic_flag) { + // mpp_err("s->nal_unit_type = %d s->poc %d",s->nal_unit_type,s->poc); + s->max_ra = INT_MAX; + s->miss_ref_flag = 0; + } + READ_UE(gb, &pps_id); + + if (pps_id >= MAX_PPS_COUNT || !s->pps_list[pps_id]) { + mpp_err( "PPS id out of range: %d\n", pps_id); + return MPP_ERR_STREAM; + } else { + sh->pps_id = pps_id; + } + + if (!sh->first_slice_in_pic_flag && + s->pps != (HEVCPPS*)s->pps_list[sh->pps_id]) { + mpp_err( "PPS changed between slices.\n"); + return MPP_ERR_STREAM; + } + s->pps = (HEVCPPS*)s->pps_list[sh->pps_id]; + + if (s->sps != (HEVCSPS*)s->sps_list[s->pps->sps_id]) { + s->sps = (HEVCSPS*)s->sps_list[s->pps->sps_id]; + mpp_hevc_clear_refs(s); + ret = set_sps(s, s->sps); + if (ret < 0) + return ret; + + s->seq_decode = (s->seq_decode + 1) & 0xff; + s->max_ra = INT_MAX; + } + + // s->h265dctx->profile = s->sps->ptl.general_ptl.profile_idc; + // s->h265dctx->level = s->sps->ptl.general_ptl.level_idc; + + sh->dependent_slice_segment_flag = 0; + if (!sh->first_slice_in_pic_flag) { + RK_S32 slice_address_length; + + if (s->pps->dependent_slice_segments_enabled_flag) + READ_ONEBIT(gb, &sh->dependent_slice_segment_flag); + + slice_address_length = mpp_ceil_log2(s->sps->ctb_width * + s->sps->ctb_height); + + READ_BITS(gb, slice_address_length, &sh->slice_segment_addr); + + if (sh->slice_segment_addr >= (RK_U32)(s->sps->ctb_width * s->sps->ctb_height)) { + mpp_err( + "Invalid slice segment address: %u.\n", + sh->slice_segment_addr); + return MPP_ERR_STREAM; + } + + if (!sh->dependent_slice_segment_flag) { + sh->slice_addr = sh->slice_segment_addr; + s->slice_idx++; + } + } else { + sh->slice_segment_addr = sh->slice_addr = 0; + s->slice_idx = 0; + s->slice_initialized = 0; + } + + if (!sh->dependent_slice_segment_flag) { + s->slice_initialized = 0; + + for (i = 0; i < s->pps->num_extra_slice_header_bits; i++) + SKIP_BITS(gb, 1); // slice_reserved_undetermined_flag[] + + READ_UE(gb, &sh->slice_type); + if (!(sh->slice_type == I_SLICE || + sh->slice_type == P_SLICE || + sh->slice_type == B_SLICE)) { + mpp_err( "Unknown slice type: %d.\n", + sh->slice_type); + return MPP_ERR_STREAM; + } + if (!s->decoder_id && IS_IRAP(s) && sh->slice_type != I_SLICE) { + mpp_err( "Inter slices in an IRAP frame.\n"); + return MPP_ERR_STREAM; + } + + if (s->pps->output_flag_present_flag) + READ_ONEBIT(gb, &sh->pic_output_flag); + + if (s->sps->separate_colour_plane_flag) + READ_BITS(gb, 2, &sh->colour_plane_id ); + + if (!IS_IDR(s)) { + int poc; + + READ_BITS(gb, s->sps->log2_max_poc_lsb, &sh->pic_order_cnt_lsb); + poc = mpp_hevc_compute_poc(s, sh->pic_order_cnt_lsb); + if (!sh->first_slice_in_pic_flag && poc != s->poc) { + mpp_log("Ignoring POC change between slices: %d -> %d\n", s->poc, poc); +#if 0 + if (s->h265dctx->err_recognition & AV_EF_EXPLODE) + return MPP_ERR_STREAM; +#endif + poc = s->poc; + } + s->poc = poc; + + READ_ONEBIT(gb, &sh->short_term_ref_pic_set_sps_flag); + + bit_begin = gb->used_bits; + + if (!sh->short_term_ref_pic_set_sps_flag) { + + ret = mpp_hevc_decode_short_term_rps(s, &sh->slice_rps, s->sps, 1); + if (ret < 0) + return ret; + + sh->short_term_rps = &sh->slice_rps; + } else { + RK_S32 numbits, rps_idx; + + if (!s->sps->nb_st_rps) { + mpp_err( "No ref lists in the SPS.\n"); + return MPP_ERR_STREAM; + } + + numbits = mpp_ceil_log2(s->sps->nb_st_rps); + rps_idx = 0; + if (numbits > 0) + READ_BITS(gb, numbits, &rps_idx); + + sh->short_term_rps = &s->sps->st_rps[rps_idx]; + } + + s->rps_bit_offset_st[s->slice_idx] = gb->used_bits - bit_begin; + + sh->short_term_ref_pic_set_size = s->rps_bit_offset_st[s->slice_idx]; + + ret = decode_lt_rps(s, &sh->long_term_rps, gb); + if (ret < 0) { + mpp_log("Invalid long term RPS.\n"); + // if (s->h265dctx->err_recognition & AV_EF_EXPLODE) + // return MPP_ERR_STREAM; + } + + if (s->sps->sps_temporal_mvp_enabled_flag) + READ_ONEBIT(gb, &sh->slice_temporal_mvp_enabled_flag); + else + sh->slice_temporal_mvp_enabled_flag = 0; + } else { + s->sh.short_term_rps = NULL; + s->poc = 0; + } + + /* 8.3.1 */ + if (s->temporal_id == 0 && + s->nal_unit_type != NAL_TRAIL_N && + s->nal_unit_type != NAL_TSA_N && + s->nal_unit_type != NAL_STSA_N && + s->nal_unit_type != NAL_RADL_N && + s->nal_unit_type != NAL_RADL_R && + s->nal_unit_type != NAL_RASL_N && + s->nal_unit_type != NAL_RASL_R) + s->pocTid0 = s->poc; + + if (s->sps->sao_enabled) { + READ_ONEBIT(gb, &sh->slice_sample_adaptive_offset_flag[0]); + READ_ONEBIT(gb, &sh->slice_sample_adaptive_offset_flag[1]); + sh->slice_sample_adaptive_offset_flag[2] = + sh->slice_sample_adaptive_offset_flag[1]; + } else { + sh->slice_sample_adaptive_offset_flag[0] = 0; + sh->slice_sample_adaptive_offset_flag[1] = 0; + sh->slice_sample_adaptive_offset_flag[2] = 0; + } + + sh->nb_refs[L0] = sh->nb_refs[L1] = 0; + if (sh->slice_type == P_SLICE || sh->slice_type == B_SLICE) { + int nb_refs; + + sh->nb_refs[L0] = s->pps->num_ref_idx_l0_default_active; + if (sh->slice_type == B_SLICE) + sh->nb_refs[L1] = s->pps->num_ref_idx_l1_default_active; + + READ_ONEBIT(gb, &value); + + if (value) { // num_ref_idx_active_override_flag + READ_UE(gb, &sh->nb_refs[L0]); + sh->nb_refs[L0] += 1; + if (sh->slice_type == B_SLICE) { + READ_UE(gb, &sh->nb_refs[L1]); + sh->nb_refs[L1] += 1; + } + } + if (sh->nb_refs[L0] > MAX_REFS || sh->nb_refs[L1] > MAX_REFS) { + mpp_err( "Too many refs: %d/%d.\n", + sh->nb_refs[L0], sh->nb_refs[L1]); + return MPP_ERR_STREAM; + } + + sh->rpl_modification_flag[0] = 0; + sh->rpl_modification_flag[1] = 0; + nb_refs = mpp_hevc_frame_nb_refs(s); + if (!nb_refs) { + mpp_err( "Zero refs for a frame with P or B slices.\n"); + return MPP_ERR_STREAM; + } + + if (s->pps->lists_modification_present_flag && nb_refs > 1) { + READ_ONEBIT(gb, &sh->rpl_modification_flag[0]); + if (sh->rpl_modification_flag[0]) { + for (i = 0; (RK_U32)i < sh->nb_refs[L0]; i++) + READ_BITS(gb, mpp_ceil_log2(nb_refs), &sh->list_entry_lx[0][i]); + } + + if (sh->slice_type == B_SLICE) { + READ_ONEBIT(gb, &sh->rpl_modification_flag[1]); + if (sh->rpl_modification_flag[1] == 1) + for (i = 0; (RK_U32)i < sh->nb_refs[L1]; i++) + READ_BITS(gb, mpp_ceil_log2(nb_refs), &sh->list_entry_lx[1][i]); + } + } + + if (sh->slice_type == B_SLICE) + READ_ONEBIT(gb, &sh->mvd_l1_zero_flag); + + if (s->pps->cabac_init_present_flag) + READ_ONEBIT(gb, &sh->cabac_init_flag); + else + sh->cabac_init_flag = 0; + + sh->collocated_ref_idx = 0; + if (sh->slice_temporal_mvp_enabled_flag) { + sh->collocated_list = L0; + if (sh->slice_type == B_SLICE) { + READ_ONEBIT(gb, &value); + sh->collocated_list = !value; + } + + if (sh->nb_refs[sh->collocated_list] > 1) { + READ_UE(gb, &sh->collocated_ref_idx); + if (sh->collocated_ref_idx >= sh->nb_refs[sh->collocated_list]) { + mpp_err( + "Invalid collocated_ref_idx: %d.\n", + sh->collocated_ref_idx); + return MPP_ERR_STREAM; + } + } + } + + if ((s->pps->weighted_pred_flag && sh->slice_type == P_SLICE) || + (s->pps->weighted_bipred_flag && sh->slice_type == B_SLICE)) { + pred_weight_table(s, gb); + } + + READ_UE(gb, &value); + sh->max_num_merge_cand = 5 - value; + if (sh->max_num_merge_cand < 1 || sh->max_num_merge_cand > 5) { + mpp_err( + "Invalid number of merging MVP candidates: %d.\n", + sh->max_num_merge_cand); + return MPP_ERR_STREAM; + } + } + READ_SE(gb, &sh->slice_qp_delta ); + if (s->pps->pic_slice_level_chroma_qp_offsets_present_flag) { + READ_SE(gb, &sh->slice_cb_qp_offset); + READ_SE(gb, &sh->slice_cr_qp_offset); + } else { + sh->slice_cb_qp_offset = 0; + sh->slice_cr_qp_offset = 0; + } + + if (s->pps->deblocking_filter_control_present_flag) { + int deblocking_filter_override_flag = 0; + + if (s->pps->deblocking_filter_override_enabled_flag) + READ_ONEBIT(gb, & deblocking_filter_override_flag); + + if (deblocking_filter_override_flag) { + READ_ONEBIT(gb, &sh->disable_deblocking_filter_flag); + if (!sh->disable_deblocking_filter_flag) { + READ_SE(gb, &sh->beta_offset); + sh->beta_offset = sh->beta_offset * 2; + READ_SE(gb, &sh->tc_offset); + sh->tc_offset = sh->tc_offset * 2; + } + } else { + sh->disable_deblocking_filter_flag = s->pps->disable_dbf; + sh->beta_offset = s->pps->beta_offset; + sh->tc_offset = s->pps->tc_offset; + } + } else { + sh->disable_deblocking_filter_flag = 0; + sh->beta_offset = 0; + sh->tc_offset = 0; + } + + if (s->pps->seq_loop_filter_across_slices_enabled_flag && + (sh->slice_sample_adaptive_offset_flag[0] || + sh->slice_sample_adaptive_offset_flag[1] || + !sh->disable_deblocking_filter_flag)) { + READ_ONEBIT(gb, &sh->slice_loop_filter_across_slices_enabled_flag); + } else { + sh->slice_loop_filter_across_slices_enabled_flag = s->pps->seq_loop_filter_across_slices_enabled_flag; + } + } else if (!s->slice_initialized) { + mpp_err( "Independent slice segment missing.\n"); + return MPP_ERR_STREAM; + } + + sh->num_entry_point_offsets = 0; + if (s->pps->tiles_enabled_flag || s->pps->entropy_coding_sync_enabled_flag) { + READ_UE(gb, &sh->num_entry_point_offsets); + if (s->pps->entropy_coding_sync_enabled_flag) { + if (sh->num_entry_point_offsets > s->sps->ctb_height || sh->num_entry_point_offsets < 0) { + mpp_err("The number of entries %d is higher than the number of CTB rows %d \n", + sh->num_entry_point_offsets, + s->sps->ctb_height); + return MPP_ERR_STREAM; + } + } else { + if (sh->num_entry_point_offsets > s->sps->ctb_height * s->sps->ctb_width || sh->num_entry_point_offsets < 0) { + mpp_err("The number of entries %d is higher than the number of CTBs %d \n", + sh->num_entry_point_offsets, + s->sps->ctb_height * s->sps->ctb_width); + return MPP_ERR_STREAM; + } + } + } +#if 0 + if (s->pps->slice_header_extension_present_flag) { + RK_U32 length = 0; + READ_UE(gb, &length); + for (i = 0; (RK_U32)i < length; i++) + SKIP_BITS(gb, 8); // slice_header_extension_data_byte + } +#endif + // Inferred parameters + sh->slice_qp = 26U + s->pps->pic_init_qp_minus26 + sh->slice_qp_delta; + if (sh->slice_qp > 51 || + sh->slice_qp < -s->sps->qp_bd_offset) { + mpp_err("The slice_qp %d is outside the valid range " + "[%d, 51].\n", + sh->slice_qp, + -s->sps->qp_bd_offset); + return MPP_ERR_STREAM; + } + if (s->h265dctx->compare_info != NULL && sh->first_slice_in_pic_flag) { + CurrentFameInf_t *info = (CurrentFameInf_t *)s->h265dctx->compare_info; + SliceHeader *openhevc_sh = (SliceHeader *)&info->sh; + h265d_dbg(H265D_DBG_FUNCTION, "compare_sliceheader in"); + if (compare_sliceheader(openhevc_sh, &s->sh) < 0) { + mpp_log("compare sliceHeader with openhevc diff\n"); + mpp_assert(0); + } + h265d_dbg(H265D_DBG_FUNCTION, "compare_sliceheader ok"); + } + + sh->slice_ctb_addr_rs = sh->slice_segment_addr; + + if (!s->sh.slice_ctb_addr_rs && s->sh.dependent_slice_segment_flag) { + mpp_err("Impossible slice segment.\n"); + return MPP_ERR_STREAM; + } + + s->slice_initialized = 1; + + return 0; +__BITREAD_ERR: + return MPP_ERR_STREAM; +} + +/** + * @return AV MPP_ERR_STREAM if the packet is not a valid NAL unit, + * 0 if the unit should be skipped, 1 otherwise + */ +static RK_S32 hls_nal_unit(HEVCContext *s) +{ + BitReadCtx_t*gb = &s->HEVClc->gb; + RK_S32 value = 0; + + READ_ONEBIT(gb, &value); + if ( value != 0) + return MPP_ERR_STREAM; + + READ_BITS(gb, 6, &s->nal_unit_type); + + READ_BITS(gb, 6, &s->nuh_layer_id); + + READ_BITS(gb, 3, &s->temporal_id); + + s->temporal_id = s->temporal_id - 1; + + if (s->temporal_id < 0) + return MPP_ERR_STREAM; + + h265d_dbg(H265D_DBG_GLOBAL, + "nal_unit_type: %d, nuh_layer_id: %d temporal_id: %d\n", + s->nal_unit_type, s->nuh_layer_id, s->temporal_id); + + return (s->nuh_layer_id); +__BITREAD_ERR: + return MPP_ERR_STREAM; +} + +static RK_S32 mpp_hevc_output_frame(void *ctx, int flush) +{ + + H265dContext_t *h265dctx = (H265dContext_t *)ctx; + HEVCContext *s = (HEVCContext *)h265dctx->priv_data; + + do { + RK_S32 nb_output = 0; + RK_S32 min_poc = INT_MAX; + RK_S32 min_idx = 0; + RK_U32 i; + + for (i = 0; i < MPP_ARRAY_ELEMS(s->DPB); i++) { + HEVCFrame *frame = &s->DPB[i]; + if ((frame->flags & HEVC_FRAME_FLAG_OUTPUT) && + frame->sequence == s->seq_output) { + nb_output++; + if (frame->poc < min_poc) { + min_poc = frame->poc; + min_idx = i; + } + } + } + + /* wait for more frames before output */ + if (!flush && s->seq_output == s->seq_decode && s->sps && + nb_output <= s->sps->temporal_layer[s->sps->max_sub_layers - 1].num_reorder_pics) + return 0; + + if (nb_output) { + HEVCFrame *frame = &s->DPB[min_idx]; + + frame->flags &= ~(HEVC_FRAME_FLAG_OUTPUT); + s->output_frame_idx = min_idx; + + mpp_buf_slot_set_flag(s->slots, frame->slot_index, SLOT_QUEUE_USE); + mpp_buf_slot_enqueue(s->slots, frame->slot_index, QUEUE_DISPLAY); + + h265d_dbg(H265D_DBG_REF, + "Output frame with POC %d frame->slot_index = %d\n", frame->poc, frame->slot_index); + + + return 1; + } + + if (s->seq_output != s->seq_decode) + s->seq_output = (s->seq_output + 1) & 0xff; + else + break; + } while (1); + + return 0; +} + +static RK_S32 hevc_frame_start(HEVCContext *s) +{ + + int ret; + + s->is_decoded = 0; + s->first_nal_type = s->nal_unit_type; + + ret = mpp_hevc_set_new_ref(s, &s->frame, s->poc); + + if (ret < 0) + goto fail; + + s->miss_ref_flag = 0; + ret = mpp_hevc_frame_rps(s); + if (s->miss_ref_flag) { + if (!IS_IRAP(s)) { + mpp_frame_set_errinfo(s->frame, VPU_FRAME_ERR_UNKNOW); + s->ref->error_flag = 1; + } else { + /*when found current I frame have miss refer + may be stream have error so first set current frame + no output and flush other frame output from dpb + then set current frame can as output + */ + HEVCFrame *frame = NULL; + RK_U32 i = 0; + for (i = 0; i < MPP_ARRAY_ELEMS(s->DPB); i++) { + frame = &s->DPB[i]; + if (frame->poc == s->poc ) { + frame->flags &= ~(HEVC_FRAME_FLAG_OUTPUT); + break; + } else { + frame = NULL; + } + } + do { + ret = mpp_hevc_output_frame(s->h265dctx, 1); + } while (ret); + if (frame) { + frame->flags |= HEVC_FRAME_FLAG_OUTPUT; + } + } + } + + mpp_buf_slot_set_prop(s->slots, s->ref->slot_index, SLOT_FRAME, s->ref->frame); + + if (ret < 0) { + mpp_err("Error constructing the frame RPS.\n"); + goto fail; + } + return 0; + +fail: + s->ref = NULL; + return ret; +} + +static RK_S32 parser_nal_unit(HEVCContext *s, const RK_U8 *nal, int length) +{ + + HEVCLocalContext *lc = s->HEVClc; + BitReadCtx_t *gb = &lc->gb; + RK_S32 ret; + mpp_set_bitread_ctx(gb, (RK_U8*)nal, length); + mpp_set_pre_detection(gb); + ret = hls_nal_unit(s); + if (ret < 0) { + mpp_err("Invalid NAL unit %d, skipping.\n", + s->nal_unit_type); + goto fail; + } else if (ret != (s->decoder_id) && s->nal_unit_type != NAL_VPS) + return 0; + + if (s->temporal_id > s->temporal_layer_id) + return 0; + + s->nuh_layer_id = ret; + h265d_dbg(H265D_DBG_GLOBAL, "s->nal_unit_type = %d,len = %d \n", s->nal_unit_type, length); + //mpp_log("s->nal_unit_type = %d,len = %d \n", s->nal_unit_type, length); +#if 0 + if (fp != NULL) { + if (s->nal_unit_type >= 32 && s->nal_unit_type <= 34) { + RK_U32 nal_1 = 0x01000000; + fwrite(&nal_1, 1, 4, fp); + fwrite(nal, 1, length, fp); + } + } + if (s->nb_frame > 1088 && (s->nal_unit_type >= 16 && s->nal_unit_type <= 21)) { + start_write = 1; + mpp_log("start %d", s->nb_frame); + } +#endif + + switch (s->nal_unit_type) { + case NAL_VPS: + ret = mpp_hevc_decode_nal_vps(s); + if (ret < 0) + goto fail; + break; + case NAL_SPS: + ret = mpp_hevc_decode_nal_sps(s); + if (ret < 0) + goto fail; + break; + case NAL_PPS: + ret = mpp_hevc_decode_nal_pps(s); + if (ret < 0) + goto fail; + break; + case NAL_SEI_PREFIX: + case NAL_SEI_SUFFIX: + ret = mpp_hevc_decode_nal_sei(s); + if (ret < 0) + goto fail; + break; + case NAL_TRAIL_R: + case NAL_TRAIL_N: + case NAL_TSA_N: + case NAL_TSA_R: + case NAL_STSA_N: + case NAL_STSA_R: + case NAL_BLA_W_LP: + case NAL_BLA_W_RADL: + case NAL_BLA_N_LP: + case NAL_IDR_W_RADL: + case NAL_IDR_N_LP: + case NAL_CRA_NUT: + case NAL_RADL_N: + case NAL_RADL_R: + case NAL_RASL_N: + case NAL_RASL_R: +#if 0 + if (fp != NULL && (s->nb_frame < 1200) && start_write) { + RK_U32 nal_1 = 0x01000000; + fwrite(&nal_1, 1, 4, fp); + fwrite(nal, 1, length, fp); + } +#endif + h265d_dbg(H265D_DBG_FUNCTION, "hls_slice_header in"); + ret = hls_slice_header(s); + h265d_dbg(H265D_DBG_FUNCTION, "hls_slice_header out"); + if (ret < 0) + return ret; + + if (s->max_ra == INT_MAX) { + if (s->nal_unit_type == NAL_CRA_NUT || IS_BLA(s)) { + s->max_ra = s->poc; + } else { + if (IS_IDR(s)) + s->max_ra = INT_MIN; + } + } + + if ((s->nal_unit_type == NAL_RASL_R || s->nal_unit_type == NAL_RASL_N) && + s->poc <= s->max_ra) { + s->is_decoded = 0; + break; + } else if ((s->poc < s->max_ra) && !IS_IRAP(s)) { //when seek to I slice skip the stream small then I slic poc + s->is_decoded = 0; + break; + } else { + if (s->nal_unit_type == NAL_RASL_R && s->poc > s->max_ra) + s->max_ra = INT_MIN; + } + + if (s->sh.first_slice_in_pic_flag) { + ret = hevc_frame_start(s); + if (ret < 0) + return ret; + } else if (!s->ref) { + mpp_err("First slice in a frame missing.\n"); + goto fail; + } + + if (s->nal_unit_type != s->first_nal_type) { + mpp_err("Non-matching NAL types of the VCL NALUs: %d %d\n", + s->first_nal_type, s->nal_unit_type); + goto fail; + } + + if (!s->sh.dependent_slice_segment_flag && + s->sh.slice_type != I_SLICE) { + // ret = mpp_hevc_slice_rpl(s); + if (ret < 0) { + mpp_log("Error constructing the reference lists for the current slice.\n"); + goto fail; + } + // rk_get_ref_info(s); + } + + + s->is_decoded = 1; + + break; + case NAL_EOS_NUT: + case NAL_EOB_NUT: + s->seq_decode = (s->seq_decode + 1) & 0xff; + s->max_ra = INT_MAX; + break; + case NAL_AUD: + case NAL_FD_NUT: + break; + default: + mpp_log("Skipping NAL unit %d\n", s->nal_unit_type); + } + + return 0; +fail: + // if (s->h265dctx->err_recognition & AV_EF_EXPLODE) + // return ret; + return 0; +} + + +typedef union { + RK_U32 u32; + RK_U16 u16[2]; + RK_U8 u8 [4]; + float f32; +} mpp_alias32; + +#define MPP_FAST_UNALIGNED 1 + + +#ifndef MPP_RN32A +#define MPP_RN32A(p) (((const mpp_alias32*)(p))->u32) +#endif +RK_S32 mpp_hevc_extract_rbsp(HEVCContext *s, const RK_U8 *src, int length, + HEVCNAL *nal) +{ + RK_S32 i; + + s->skipped_bytes = 0; + +#define STARTCODE_TEST \ + if (i + 2 < length && src[i + 1] == 0 && src[i + 2] < 3) { \ + /* startcode, so we must be past the end */ \ + length = i; \ + break; \ + } + +#if MPP_FAST_UNALIGNED +#define FIND_FIRST_ZERO \ + if (i > 0 && !src[i]) \ + i--; \ + while (src[i]) \ + i++ + + for (i = 0; i + 1 < length; i += 5) { + if (!((~MPP_RN32A(src + i) & + (MPP_RN32A(src + i) - 0x01000101U)) & + 0x80008080U)) + continue; + + FIND_FIRST_ZERO; + + STARTCODE_TEST; + i -= 3; + } +#else + for (i = 0; i + 1 < length; i += 2) { + if (src[i]) + continue; + if (i > 0 && src[i - 1] == 0) + i--; + STARTCODE_TEST; + } +#endif + + if (length + MPP_INPUT_BUFFER_PADDING_SIZE > nal->rbsp_buffer_size) { + RK_S32 min_size = length + MPP_INPUT_BUFFER_PADDING_SIZE; + mpp_free(nal->rbsp_buffer); + nal->rbsp_buffer = NULL; + min_size = MPP_MAX(17 * min_size / 16 + 32, min_size); + nal->rbsp_buffer = mpp_malloc(RK_U8, min_size); + if (nal->rbsp_buffer == NULL) { + min_size = 0; + } + nal->rbsp_buffer_size = min_size; + } + + memcpy(nal->rbsp_buffer, src, length); + nal->data = nal->rbsp_buffer; + nal->size = length; + + memset(nal->rbsp_buffer + length, 0, MPP_INPUT_BUFFER_PADDING_SIZE); + return length; +} + +static RK_S32 split_nal_units(HEVCContext *s, RK_U8 *buf, RK_U32 length) +{ + RK_S32 i, consumed; + MPP_RET ret = MPP_OK; + s->nb_nals = 0; + while (length >= 4) { + HEVCNAL *nal; + RK_S32 extract_length = 0; + + if (s->is_nalff) { + for (i = 0; i < s->nal_length_size; i++) + extract_length = (extract_length << 8) | buf[i]; + buf += s->nal_length_size; + length -= s->nal_length_size; + + if ((RK_U32)extract_length > length) { + mpp_err( "Invalid NAL unit size.\n"); + ret = MPP_ERR_STREAM; + goto fail; + } + } else { + /* search start code */ + if (buf[2] == 0) { + length--; + buf++; + continue; + } + if (buf[0] != 0 || buf[1] != 0 || buf[2] != 1) { + RK_U32 state = (RK_U32) - 1; + int has_nal = 0; + for (i = 0; i < (RK_S32)length; i++) { + state = (state << 8) | buf[i]; + if (((state >> 8) & 0xFFFFFF) == START_CODE) { + has_nal = 1; + i = i - 3; + break; + } + } + + if (has_nal) { + length -= i; + buf += i; + continue; + } + mpp_err( "No start code is found.\n"); + ret = MPP_ERR_STREAM; + goto fail; + } + + buf += 3; + length -= 3; + } + + if (!s->is_nalff) + extract_length = length; + + if (!extract_length) { + return MPP_OK; + } + if (s->nals_allocated < 1) { + RK_S32 new_size = s->nals_allocated + 10; + HEVCNAL *tmp = mpp_malloc(HEVCNAL, new_size); + memset((void*)tmp, 0, new_size * sizeof(HEVCNAL)); + s->nals_allocated = new_size; + s->nals = tmp; + } + if (s->nals_allocated < s->nb_nals + 1) { + int new_size = s->nals_allocated + 10; + HEVCNAL *tmp = mpp_malloc(HEVCNAL, new_size); + memset((void*)tmp, 0, new_size * sizeof(HEVCNAL)); + if (!tmp) { + mpp_err("return enomm new_size %d", new_size); + ret = MPP_ERR_NOMEM; + goto fail; + } + memcpy((void*)tmp, (void*)s->nals, (new_size - 10)*sizeof(HEVCNAL)); + mpp_free(s->nals); + s->nals = NULL; + s->nals = tmp; + memset(s->nals + s->nals_allocated, 0, + (new_size - s->nals_allocated) * sizeof(*tmp)); + s->nals_allocated = new_size; + } + nal = &s->nals[s->nb_nals]; + + consumed = mpp_hevc_extract_rbsp(s, buf, extract_length, nal); + + s->nb_nals++; + + if (consumed <= 0) { + ret = MPP_ERR_STREAM; + goto fail; + } + + mpp_set_bitread_ctx(&s->HEVClc->gb, (RK_U8 *)nal->data, nal->size); + mpp_set_pre_detection(&s->HEVClc->gb); + hls_nal_unit(s); + + if (s->nal_unit_type < NAL_VPS) { + + if (nal->size != consumed) + h265d_dbg(H265D_DBG_GLOBAL, "tag_stream: nal.size=%d, consumed=%d\n", nal->size, consumed); + + } + + /* if (s->nal_unit_type == NAL_EOB_NUT || + s->nal_unit_type == NAL_EOS_NUT) + s->eos = 1;*/ + + buf += consumed; + length -= consumed; + } +fail: + return ret; + +} +static RK_S32 parser_nal_units(HEVCContext *s) +{ + /* parse the NAL units */ + RK_S32 i, ret = 0; + for (i = 0; i < s->nb_nals; i++) { + ret = parser_nal_unit(s, s->nals[i].data, s->nals[i].size); + if (ret < 0) { + mpp_log("Error parsing NAL unit #%d.\n", i); + ret = 0; + goto fail; + } + } +fail: + return ret; +} + +RK_U16 U16_AT(const RK_U8 *ptr) +{ + return ptr[0] << 8 | ptr[1]; +} + +static RK_S32 hevc_parser_extradata(HEVCContext *s) +{ + H265dContext_t *h265dctx = s->h265dctx; + RK_S32 ret = MPP_SUCCESS; + if (h265dctx->extradata_size > 3 && + (h265dctx->extradata[0] || h265dctx->extradata[1] || + h265dctx->extradata[2] > 1)) { + /* It seems the extradata is encoded as hvcC format. + * Temporarily, we support configurationVersion==0 until 14496-15 3rd + * is finalized. When finalized, configurationVersion will be 1 and we + * can recognize hvcC by checking if h265dctx->extradata[0]==1 or not. */ + const RK_U8 *ptr = (const RK_U8 *)h265dctx->extradata; + RK_U32 size = h265dctx->extradata_size; + RK_U32 numofArrays = 0, numofNals = 0; + RK_U32 j = 0, i = 0; + if (size < 7) { + return MPP_NOK; + } + + mpp_log("extradata is encoded as hvcC format"); + s->is_nalff = 1; + s->nal_length_size = 1 + (ptr[14 + 7] & 3); + ptr += 22; + size -= 22; + numofArrays = (char)ptr[0]; + ptr += 1; + size -= 1; + for (i = 0; i < numofArrays; i++) { + ptr += 1; + size -= 1; + // Num of nals + numofNals = U16_AT(ptr); + ptr += 2; + size -= 2; + + for (j = 0; j < numofNals; j++) { + RK_U32 length = 0; + if (size < 2) { + return MPP_NOK; + } + + length = U16_AT(ptr); + + ptr += 2; + size -= 2; + if (size < length) { + return MPP_NOK; + } + parser_nal_unit(s, ptr, length); + ptr += length; + size -= length; + } + } + } else { + s->is_nalff = 0; + ret = split_nal_units(s, h265dctx->extradata, h265dctx->extradata_size); + if (ret < 0) + return ret; + ret = parser_nal_units(s); + if (ret < 0) + return ret; + } + return ret; +} + +MPP_RET h265d_prepare(void *ctx, MppPacket pkt, HalDecTask *task) +{ + + MPP_RET ret = MPP_OK; + H265dContext_t *h265dctx = (H265dContext_t *)ctx; + HEVCContext *s = (HEVCContext *)h265dctx->priv_data; + SplitContext_t *sc = (SplitContext_t*)h265dctx->split_cxt; + RK_S64 pts = -1, dts = -1; + RK_U8 *buf = NULL; + void *pos = NULL; + RK_S32 length = 0; + + //task->valid = 0; + s->eos = mpp_packet_get_eos(pkt); + if (sc != NULL) { + sc->eos = s->eos; + } + buf = (RK_U8 *)mpp_packet_get_pos(pkt); + pts = mpp_packet_get_pts(pkt); + dts = mpp_packet_get_dts(pkt); + h265d_dbg(H265D_DBG_TIME, "prepare get pts %lld", pts); + length = (RK_S32)mpp_packet_get_length(pkt); + + if (mpp_packet_get_flag(pkt)& MPP_PACKET_FLAG_EXTRA_DATA) { + + h265dctx->extradata_size = length; + h265dctx->extradata = buf; + hevc_parser_extradata(s); + pos = buf + length; + mpp_packet_set_pos(pkt, pos); + return MPP_OK; + } + + if (h265dctx->need_split && !s->is_nalff) { + + RK_S32 consume = 0; + RK_U8 *split_out_buf = NULL; + RK_S32 split_size = 0; + + consume = h265d_split_frame(h265dctx->split_cxt, (const RK_U8**)&split_out_buf, &split_size, + (const RK_U8*)buf, length, pts, dts); + pos = buf + consume; + mpp_packet_set_pos(pkt, pos); + if (split_size) { + buf = split_out_buf; + length = split_size; + s->checksum_buf = buf; //check with openhevc + s->checksum_buf_size = split_size; + h265d_dbg(H265D_DBG_TIME, "split frame get pts %lld", sc->pts); + s->pts = sc->pts; + } else { + return MPP_FAIL_SPLIT_FRAME; + } + } else { + pos = buf + length; + s->pts = pts; + mpp_packet_set_pos(pkt, pos); + if (s->eos && !length) { + task->valid = 0; + task->flags.eos = 1; + mpp_log("hevc flush eos"); + h265d_flush(ctx); + return ret; + } + } +#ifdef dump + if (s->nb_frame < 10 && fp != NULL) { + fwrite(buf, 1, length, fp); + } +#endif + ret = (MPP_RET)split_nal_units(s, buf, length); + + if (MPP_OK == ret) { + if (MPP_OK == h265d_syntax_fill_slice(s->h265dctx, task->input)) { + task->valid = 1; + task->input_packet = s->input_packet; + } + } + return ret; + +} + +MPP_RET h265d_get_stream(void *ctx, RK_U8 **buf, RK_S32 *size) +{ + MPP_RET ret = MPP_OK; + H265dContext_t *h265dctx = (H265dContext_t *)ctx; + HEVCContext *s = h265dctx->priv_data; + *buf = s->checksum_buf; + *size = s->checksum_buf_size; + return ret; +} + +MPP_RET h265d_set_compare_info(void *ctx, void *info) +{ + MPP_RET ret = MPP_OK; + H265dContext_t *h265dctx = (H265dContext_t *)ctx; + h265dctx->compare_info = info; + return ret; +} + + +MPP_RET h265d_parse(void *ctx, HalDecTask *task) +{ + MPP_RET ret; + H265dContext_t *h265dctx = (H265dContext_t *)ctx; + HEVCContext *s = h265dctx->priv_data; + + s->got_frame = 0; + s->task = task; + s->ref = NULL; + ret = parser_nal_units(s); + if (ret < 0) { + if (ret == MPP_ERR_STREAM) { + mpp_log("current stream is no right skip it"); + ret = 0; + } + return ret; + } + h265d_dbg(H265D_DBG_GLOBAL, "decode poc = %d", s->poc); + if (s->ref) { + h265d_parser2_syntax(h265dctx); + s->task->syntax.data = s->hal_pic_private; + s->task->syntax.number = 1; + s->task->valid = 1; + if (s->eos) { + s->task->flags.eos = 1; + } + } else { + if (s->eos) { + h265d_flush(ctx); + s->task->flags.eos = 1; + } + } + s->nb_frame++; + if (s->is_decoded) { + h265d_dbg(H265D_DBG_GLOBAL, "Decoded frame with POC %d.\n", s->poc); + s->is_decoded = 0; + } + mpp_hevc_output_frame(ctx, 0); + return MPP_OK; +} + +MPP_RET h265d_deinit(void *ctx) +{ + H265dContext_t *h265dctx = (H265dContext_t *)ctx; + HEVCContext *s = h265dctx->priv_data; + SplitContext_t *sc = h265dctx->split_cxt; + RK_U8 *buf = NULL; + int i; + + for (i = 0; i < MAX_DPB_SIZE; i++) { + mpp_hevc_unref_frame(s, &s->DPB[i], ~0); + mpp_frame_deinit(&s->DPB[i].frame); + } + + for (i = 0; i < MAX_VPS_COUNT; i++) + mpp_free(s->vps_list[i]); + for (i = 0; i < MAX_SPS_COUNT; i++) + mpp_free(s->sps_list[i]); + for (i = 0; i < MAX_PPS_COUNT; i++) + mpp_hevc_pps_free(s->pps_list[i]); + + mpp_free(s->HEVClc); + + s->HEVClc = NULL; + + for (i = 0; i < s->nals_allocated; i++) + mpp_free(s->nals[i].rbsp_buffer); + + if (s->nals) { + mpp_free(s->nals); + } + + s->nals_allocated = 0; + + if (s->hal_pic_private) { + mpp_free(s->hal_pic_private); + } + if (s->input_packet) { + buf = mpp_packet_get_data(s->input_packet); + mpp_free(buf); + mpp_packet_deinit(&s->input_packet); + } + + if (s) { + mpp_free(s); + } + + if (sc) { + h265d_split_deinit(sc); + } + return 0; +} + +static RK_S32 hevc_init_context(H265dContext_t *h265dctx) +{ + HEVCContext *s = h265dctx->priv_data; + RK_U32 i; + + s->h265dctx = h265dctx; + + s->HEVClc = (HEVCLocalContext*)mpp_calloc(HEVCLocalContext, 1); + if (!s->HEVClc) + goto fail; + + for (i = 0; i < MPP_ARRAY_ELEMS(s->DPB); i++) { + s->DPB[i].slot_index = 0xff; + s->DPB[i].poc = INT_MAX; + s->DPB[i].error_flag = 0; + mpp_frame_init(&s->DPB[i].frame); + if (!s->DPB[i].frame) + goto fail; + } + + s->max_ra = INT_MAX; + + + s->temporal_layer_id = 8; + s->context_initialized = 1; + + return 0; + +fail: + h265d_deinit(h265dctx); + return MPP_ERR_NOMEM; +} + + +MPP_RET h265d_init(void *ctx, ParserCfg *parser_cfg) +{ + + H265dContext_t *h265dctx = (H265dContext_t *)ctx; + HEVCContext *s = (HEVCContext *)h265dctx->priv_data; + SplitContext_t *sc = (SplitContext_t*)h265dctx->split_cxt; + RK_S32 ret; + RK_U8 *buf = NULL; + RK_S32 size = SZ_512K; + if (s == NULL) { + s = (HEVCContext*)mpp_calloc(HEVCContext, 1); + if (s == NULL) { + mpp_err("hevc contxt malloc fail"); + return MPP_ERR_NOMEM; + } + h265dctx->priv_data = s; + } + + h265dctx->need_split = parser_cfg->need_split; + + if (sc == NULL && h265dctx->need_split) { + h265d_split_init((void**)&sc); + if (sc == NULL) { + mpp_err("split contxt malloc fail"); + return MPP_ERR_NOMEM; + } + h265dctx->split_cxt = sc; + } + + // mpp_env_set_u32("h265d_debug", H265D_DBG_REF); + mpp_env_get_u32("h265d_debug", &h265d_debug, 0); + + ret = hevc_init_context(h265dctx); + + s->hal_pic_private = mpp_calloc_size(void, sizeof(h265d_dxva2_picture_context_t)); + + if (ret < 0) + return ret; + + s->picture_struct = 0; + + s->slots = parser_cfg->frame_slots; + + s->packet_slots = parser_cfg->packet_slots; + s->notify_cb = parser_cfg->notify_cb; + + if (h265dctx->extradata_size > 0 && h265dctx->extradata) { + ret = hevc_parser_extradata(s); + if (ret < 0) { + h265d_deinit(h265dctx); + return ret; + } + } + + buf = mpp_malloc(RK_U8, size); + + if (buf == NULL) { + return MPP_ERR_NOMEM; + } + + if (MPP_OK != mpp_packet_init(&s->input_packet, (void*)buf, size)) { + return MPP_ERR_NOMEM; + } +#ifdef dump + fp = fopen("/data/dump1.bin", "wb+"); +#endif + return 0; +} + +MPP_RET h265d_flush(void *ctx) +{ + RK_S32 ret = 0; + do { + ret = mpp_hevc_output_frame(ctx, 1); + } while (ret); + return MPP_OK; +} + +MPP_RET h265d_reset(void *ctx) +{ + H265dContext_t *h265dctx = (H265dContext_t *)ctx; + HEVCContext *s = (HEVCContext *)h265dctx->priv_data; + RK_S32 ret = 0; + do { + ret = mpp_hevc_output_frame(ctx, 1); + } while (ret); + mpp_hevc_flush_dpb(s); + h265d_split_reset(h265dctx->split_cxt); + s->max_ra = INT_MAX; + s->eos = 0; + return MPP_OK; +} + +MPP_RET h265d_control(void *ctx, RK_S32 cmd, void *param) +{ + (void)ctx; + (void)cmd; + (void)param; + return MPP_OK; +} + +MPP_RET h265d_callback(void *ctx, void *err_info) +{ + H265dContext_t *h265dctx = (H265dContext_t *)ctx; + HEVCContext *s = (HEVCContext *)h265dctx->priv_data; + MppFrame frame = NULL; + RK_U32 i = 0; + + if (s->first_nal_type >= 16 && s->first_nal_type <= 23) { + mpp_log("IS_IRAP frame found error"); + s->max_ra = INT_MAX; + } + // s->miss_ref_flag = 1; + mpp_buf_slot_get_prop(s->slots, s->ref->slot_index, SLOT_FRAME_PTR, &frame); + mpp_frame_set_errinfo(frame, VPU_FRAME_ERR_UNKNOW); + for (i = 0; i < MPP_ARRAY_ELEMS(s->DPB); i++) { + if (s->DPB[i].slot_index == s->ref->slot_index) { + s->DPB[i].error_flag = 1; + } + + } + (void) err_info; + + return MPP_OK; +} + + + +const ParserApi api_h265d_parser = { + "h265d_parse", + MPP_VIDEO_CodingHEVC, + sizeof(H265dContext_t), + 0, + h265d_init, + h265d_deinit, + h265d_prepare, + h265d_parse, + h265d_reset, + h265d_flush, + h265d_control, + h265d_callback, +}; + + diff --git a/mpp/codec/dec/h265/test/openHevcWrapper.h b/mpp/codec/dec/h265/test/openHevcWrapper.h index 5777c2c3..60ecf79a 100644 --- a/mpp/codec/dec/h265/test/openHevcWrapper.h +++ b/mpp/codec/dec/h265/test/openHevcWrapper.h @@ -1,100 +1,100 @@ -/* - * openhevc.h wrapper to openhevc or ffmpeg - * Copyright (c) 2012-2013 Raulet, Wassim Hamidouche, Gildas Cocherel, Pierre Edouard Lepere - * - * This file is part of openhevc. - * - * openHevc 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. - * - * openhevc 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 openhevc; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef OPEN_HEVC_WRAPPER_H -#define OPEN_HEVC_WRAPPER_H - -#define NV_VERSION "1.2" ///< Current software version - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -typedef void* OpenHevc_Handle; - -typedef struct OpenHevc_Rational { - int num; ///< numerator - int den; ///< denominator -} OpenHevc_Rational; - -typedef struct OpenHevc_FrameInfo { - int nYPitch; - int nUPitch; - int nVPitch; - int nBitDepth; - int nWidth; - int nHeight; - int nDisplayWidth; - int nDisplayHeight; - OpenHevc_Rational sample_aspect_ratio; - OpenHevc_Rational frameRate; - int display_picture_number; - int flag; //progressive, interlaced, interlaced top field first, interlaced bottom field first. - int64_t nTimeStamp; -} OpenHevc_FrameInfo; - -typedef struct OpenHevc_Frame { - void** pvY; - void** pvU; - void** pvV; - OpenHevc_FrameInfo frameInfo; -} OpenHevc_Frame; - -typedef struct OpenHevc_Frame_cpy { - void* pvY; - void* pvU; - void* pvV; - OpenHevc_FrameInfo frameInfo; -} OpenHevc_Frame_cpy; - -OpenHevc_Handle libOpenHevcInit(int nb_pthreads, int thread_type); -int libOpenHevcStartDecoder(OpenHevc_Handle openHevcHandle); -int libOpenHevcDecode(OpenHevc_Handle openHevcHandle, const unsigned char *buff, int nal_len, int64_t pts); -void libOpenHevcGetPictureInfo(OpenHevc_Handle openHevcHandle, OpenHevc_FrameInfo *openHevcFrameInfo); -void libOpenHevcCopyExtraData(OpenHevc_Handle openHevcHandle, unsigned char *extra_data, int extra_size_alloc); - -void libOpenHevcGetPictureSize2(OpenHevc_Handle openHevcHandle, OpenHevc_FrameInfo *openHevcFrameInfo); -int libOpenHevcGetOutput(OpenHevc_Handle openHevcHandle, int got_picture, OpenHevc_Frame *openHevcFrame); -int libOpenHevcGetOutputCpy(OpenHevc_Handle openHevcHandle, int got_picture, OpenHevc_Frame_cpy *openHevcFrame); -void libOpenHevcSetCheckMD5(OpenHevc_Handle openHevcHandle, int val); -void libOpenHevcSetDebugMode(OpenHevc_Handle openHevcHandle, int val); -void libOpenHevcSetTemporalLayer_id(OpenHevc_Handle openHevcHandle, int val); -void libOpenHevcSetNoCropping(OpenHevc_Handle openHevcHandle, int val); -void libOpenHevcSetActiveDecoders(OpenHevc_Handle openHevcHandle, int val); - -void libOpenHevcClose(OpenHevc_Handle openHevcHandle); -void libOpenHevcFlush(OpenHevc_Handle openHevcHandle); -const char *libOpenHevcVersion(OpenHevc_Handle openHevcHandle); -int libOpenHevcControl(OpenHevc_Handle openHevcHandle, int cmd, void* parm); -OpenHevc_Handle libHevcParserInit(); -int libHevcParser(OpenHevc_Handle openHevcHandle, void* vpacket, void *vparsepacket); -void libHevcParserClose(OpenHevc_Handle openHevcHandle); -void libHevcParserflush(OpenHevc_Handle openHevcHandle); -void* libOpenHevcGetSliceInfo(OpenHevc_Handle openHevcHandle); - - -#ifdef __cplusplus -} -#endif - -#endif // OPEN_HEVC_WRAPPER_H +/* + * openhevc.h wrapper to openhevc or ffmpeg + * Copyright (c) 2012-2013 Raulet, Wassim Hamidouche, Gildas Cocherel, Pierre Edouard Lepere + * + * This file is part of openhevc. + * + * openHevc 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. + * + * openhevc 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 openhevc; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef OPEN_HEVC_WRAPPER_H +#define OPEN_HEVC_WRAPPER_H + +#define NV_VERSION "1.2" ///< Current software version + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +typedef void* OpenHevc_Handle; + +typedef struct OpenHevc_Rational { + int num; ///< numerator + int den; ///< denominator +} OpenHevc_Rational; + +typedef struct OpenHevc_FrameInfo { + int nYPitch; + int nUPitch; + int nVPitch; + int nBitDepth; + int nWidth; + int nHeight; + int nDisplayWidth; + int nDisplayHeight; + OpenHevc_Rational sample_aspect_ratio; + OpenHevc_Rational frameRate; + int display_picture_number; + int flag; //progressive, interlaced, interlaced top field first, interlaced bottom field first. + int64_t nTimeStamp; +} OpenHevc_FrameInfo; + +typedef struct OpenHevc_Frame { + void** pvY; + void** pvU; + void** pvV; + OpenHevc_FrameInfo frameInfo; +} OpenHevc_Frame; + +typedef struct OpenHevc_Frame_cpy { + void* pvY; + void* pvU; + void* pvV; + OpenHevc_FrameInfo frameInfo; +} OpenHevc_Frame_cpy; + +OpenHevc_Handle libOpenHevcInit(int nb_pthreads, int thread_type); +int libOpenHevcStartDecoder(OpenHevc_Handle openHevcHandle); +int libOpenHevcDecode(OpenHevc_Handle openHevcHandle, const unsigned char *buff, int nal_len, int64_t pts); +void libOpenHevcGetPictureInfo(OpenHevc_Handle openHevcHandle, OpenHevc_FrameInfo *openHevcFrameInfo); +void libOpenHevcCopyExtraData(OpenHevc_Handle openHevcHandle, unsigned char *extra_data, int extra_size_alloc); + +void libOpenHevcGetPictureSize2(OpenHevc_Handle openHevcHandle, OpenHevc_FrameInfo *openHevcFrameInfo); +int libOpenHevcGetOutput(OpenHevc_Handle openHevcHandle, int got_picture, OpenHevc_Frame *openHevcFrame); +int libOpenHevcGetOutputCpy(OpenHevc_Handle openHevcHandle, int got_picture, OpenHevc_Frame_cpy *openHevcFrame); +void libOpenHevcSetCheckMD5(OpenHevc_Handle openHevcHandle, int val); +void libOpenHevcSetDebugMode(OpenHevc_Handle openHevcHandle, int val); +void libOpenHevcSetTemporalLayer_id(OpenHevc_Handle openHevcHandle, int val); +void libOpenHevcSetNoCropping(OpenHevc_Handle openHevcHandle, int val); +void libOpenHevcSetActiveDecoders(OpenHevc_Handle openHevcHandle, int val); + +void libOpenHevcClose(OpenHevc_Handle openHevcHandle); +void libOpenHevcFlush(OpenHevc_Handle openHevcHandle); +const char *libOpenHevcVersion(OpenHevc_Handle openHevcHandle); +int libOpenHevcControl(OpenHevc_Handle openHevcHandle, int cmd, void* parm); +OpenHevc_Handle libHevcParserInit(); +int libHevcParser(OpenHevc_Handle openHevcHandle, void* vpacket, void *vparsepacket); +void libHevcParserClose(OpenHevc_Handle openHevcHandle); +void libHevcParserflush(OpenHevc_Handle openHevcHandle); +void* libOpenHevcGetSliceInfo(OpenHevc_Handle openHevcHandle); + + +#ifdef __cplusplus +} +#endif + +#endif // OPEN_HEVC_WRAPPER_H diff --git a/mpp/codec/dec/jpeg/CMakeLists.txt b/mpp/codec/dec/jpeg/CMakeLists.txt index 7c6a4521..64f0dcc1 100644 --- a/mpp/codec/dec/jpeg/CMakeLists.txt +++ b/mpp/codec/dec/jpeg/CMakeLists.txt @@ -1,17 +1,17 @@ -# vim: syntax=cmake -set(JPEGD_PARSER_HDR - jpegd_parser.h - ) - -set(JPEGD_PARSER_SRC - jpegd_parser.c - ) -add_library(codec_jpegd STATIC - ${JPEGD_PARSER_SRC} ${JPEGD_PARSER_HDR} - ) - -set_target_properties(codec_jpegd PROPERTIES FOLDER "mpp/codec") - -target_link_libraries(codec_jpegd mpp_base) - -#add_subdirectory(test) +# vim: syntax=cmake +set(JPEGD_PARSER_HDR + jpegd_parser.h + ) + +set(JPEGD_PARSER_SRC + jpegd_parser.c + ) +add_library(codec_jpegd STATIC + ${JPEGD_PARSER_SRC} ${JPEGD_PARSER_HDR} + ) + +set_target_properties(codec_jpegd PROPERTIES FOLDER "mpp/codec") + +target_link_libraries(codec_jpegd mpp_base) + +#add_subdirectory(test) diff --git a/mpp/codec/dec/jpeg/jpegd_parser.c b/mpp/codec/dec/jpeg/jpegd_parser.c index 66d48aea..d4024651 100644 --- a/mpp/codec/dec/jpeg/jpegd_parser.c +++ b/mpp/codec/dec/jpeg/jpegd_parser.c @@ -1,2736 +1,2736 @@ -/* - * - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define MODULE_TAG "jpegd_parser" - -#include "mpp_bitread.h" -#include "mpp_mem.h" -#include "mpp_env.h" -#include "mpp_packet_impl.h" - -#include "jpegd_api.h" -#include "jpegd_parser.h" - - -#define STRM_ERROR 0xFFFFFFFFU -RK_U32 jpegd_log = 0; - -/*------------------------------------------------------------------------------ - Function name: jpegd_get_byte - - Functional description: - Reads one byte (8 bits) from stream and returns the bits - - Note! This function does not skip the 0x00 byte if the previous - byte value was 0xFF!!! - - Inputs: - StreamStorage *pStream Pointer to structure - - Outputs: - Returns 8 bit value if ok - else returns STRM_ERROR (0xFFFFFFFF) -------------------------------------------------------------------------------*/ -RK_U32 jpegd_get_byte(StreamStorage * pStream) -{ - RK_U32 tmp; - - if ((pStream->readBits + 8) > (8 * pStream->streamLength)) - return (STRM_ERROR); - - tmp = *(pStream->pCurrPos)++; - tmp = (tmp << 8) | *(pStream->pCurrPos); - tmp = (tmp >> (8 - pStream->bitPosInByte)) & 0xFF; - pStream->readBits += 8; - return (tmp); -} - -/*------------------------------------------------------------------------------ - Function name: jpegd_get_two_bytes - - Functional description: - Reads two bytes (16 bits) from stream and returns the bits - - Note! This function does not skip the 0x00 byte if the previous - byte value was 0xFF!!! - - Inputs: - StreamStorage *pStream Pointer to structure - - Outputs: - Returns 16 bit value -------------------------------------------------------------------------------*/ -RK_U32 jpegd_get_two_bytes(StreamStorage * pStream) -{ - RK_U32 tmp; - - if ((pStream->readBits + 16) > (8 * pStream->streamLength)) - return (STRM_ERROR); - - tmp = *(pStream->pCurrPos)++; - tmp = (tmp << 8) | *(pStream->pCurrPos)++; - tmp = (tmp << 8) | *(pStream->pCurrPos); - tmp = (tmp >> (8 - pStream->bitPosInByte)) & 0xFFFF; - pStream->readBits += 16; - return (tmp); -} - -/*------------------------------------------------------------------------------ - Function name: jpegd_show_bits - - Functional description: - Reads 32 bits from stream and returns the bits, does not update - stream pointers. If there are not enough bits in data buffer it - reads the rest of the data buffer bits and fills the lsb of return - value with zero bits. - - Note! This function will skip the byte valued 0x00 if the previous - byte value was 0xFF!!! - - Inputs: - StreamStorage *pStream Pointer to structure - - Outputs: - Returns 32 bit value -------------------------------------------------------------------------------*/ -RK_U32 jpegd_show_bits(StreamStorage * pStream) -{ - RK_S32 bits; - RK_U32 readBits; - RK_U32 out = 0; - RK_U8 *pData = pStream->pCurrPos; - - /* bits left in buffer */ - bits = (RK_S32) (8 * pStream->streamLength - pStream->readBits); - if (!bits) - return (0); - - readBits = 0; - do { - if (pData > pStream->pStartOfStream) { - /* FF 00 bytes in stream -> jump over 00 byte */ - if ((pData[-1] == 0xFF) && (pData[0] == 0x00)) { - pData++; - bits -= 8; - } - } - if (readBits == 32 && pStream->bitPosInByte) { - out <<= pStream->bitPosInByte; - out |= *pData >> (8 - pStream->bitPosInByte); - readBits = 0; - break; - } - out = (out << 8) | *pData++; - readBits += 8; - bits -= 8; - } while (readBits < (32 + pStream->bitPosInByte) && bits > 0); - - if (bits <= 0 && - ((readBits + pStream->readBits) >= (pStream->streamLength * 8))) { - /* not enough bits in stream, fill with zeros */ - out = (out << (32 - (readBits - pStream->bitPosInByte))); - } - - return (out); -} - -/*------------------------------------------------------------------------------ - Function name: jpegd_flush_bits - - Functional description: - Updates stream pointers, flushes bits from stream - - Note! This function will skip the byte valued 0x00 if the previous - byte value was 0xFF!!! - - Inputs: - StreamStorage *pStream Pointer to structure - RK_U32 bits Number of bits to be flushed - - Outputs: - OK - STRM_ERROR -------------------------------------------------------------------------------*/ -RK_U32 jpegd_flush_bits(StreamStorage * pStream, RK_U32 bits) -{ - RK_U32 tmp; - RK_U32 extraBits = 0; - - if ((pStream->readBits + bits) > (8 * pStream->streamLength)) { - /* there are not so many bits left in buffer */ - /* stream pointers to the end of the stream */ - /* and return value STRM_ERROR */ - pStream->readBits = 8 * pStream->streamLength; - pStream->bitPosInByte = 0; - pStream->pCurrPos = pStream->pStartOfStream + pStream->streamLength; - return (STRM_ERROR); - } else { - tmp = 0; - while (tmp < bits) { - if (bits - tmp < 8) { - if ((8 - pStream->bitPosInByte) > (bits - tmp)) { - /* inside one byte */ - pStream->bitPosInByte += bits - tmp; - tmp = bits; - } else { - if (pStream->pCurrPos[0] == 0xFF && - pStream->pCurrPos[1] == 0x00) { - extraBits += 8; - pStream->pCurrPos += 2; - } else { - pStream->pCurrPos++; - } - tmp += 8 - pStream->bitPosInByte; - pStream->bitPosInByte = 0; - pStream->bitPosInByte = bits - tmp; - tmp = bits; - } - } else { - tmp += 8; - if (pStream->appnFlag) { - pStream->pCurrPos++; - } else { - if (pStream->pCurrPos[0] == 0xFF && - pStream->pCurrPos[1] == 0x00) { - extraBits += 8; - pStream->pCurrPos += 2; - } else { - pStream->pCurrPos++; - } - } - } - } - /* update stream pointers */ - pStream->readBits += bits + extraBits; - return (MPP_OK); - } -} - -JpegDecRet jpegd_set_yuv_mode(JpegSyntaxParam *pSyntax) -{ - /* check input format */ - if (pSyntax->frame.Nf == 3) { - if (pSyntax->frame.component[0].H == 2 && - pSyntax->frame.component[0].V == 2 && - pSyntax->frame.component[1].H == 1 && - pSyntax->frame.component[1].V == 1 && - pSyntax->frame.component[2].H == 1 && - pSyntax->frame.component[2].V == 1) { - JPEGD_INFO_LOG("YCbCr Format: YUV420(2*2:1*1:1*1)"); - pSyntax->info.yCbCrMode = JPEGDEC_YUV420; - pSyntax->info.X = pSyntax->frame.hwX; - pSyntax->info.Y = pSyntax->frame.hwY; - } else if (pSyntax->frame.component[0].H == 2 && pSyntax->frame.component[0].V == 1 && - pSyntax->frame.component[1].H == 1 && pSyntax->frame.component[1].V == 1 && - pSyntax->frame.component[2].H == 1 && pSyntax->frame.component[2].V == 1) { - JPEGD_INFO_LOG("YCbCr Format: YUV422(%d*%d:%d*%d:%d*%d)", - pSyntax->frame.component[0].H, pSyntax->frame.component[0].V, - pSyntax->frame.component[1].H, pSyntax->frame.component[1].V, - pSyntax->frame.component[2].H, pSyntax->frame.component[2].V); - pSyntax->info.yCbCrMode = JPEGDEC_YUV422; - pSyntax->info.X = (pSyntax->frame.hwX); - pSyntax->info.Y = (pSyntax->frame.hwY); - - /* check if fill needed */ - if ((pSyntax->frame.Y & 0xF) && (pSyntax->frame.Y & 0xF) <= 8) - pSyntax->info.fillBottom = 1; - } else if (pSyntax->frame.component[0].H == 1 && - pSyntax->frame.component[0].V == 2 && - pSyntax->frame.component[1].H == 1 && - pSyntax->frame.component[1].V == 1 && - pSyntax->frame.component[2].H == 1 && - pSyntax->frame.component[2].V == 1) { - JPEGD_INFO_LOG("YCbCr Format: YUV440(1*2:1*1:1*1)"); - pSyntax->info.yCbCrMode = JPEGDEC_YUV440; - pSyntax->info.X = (pSyntax->frame.hwX); - pSyntax->info.Y = (pSyntax->frame.hwY); - - /* check if fill needed */ - if ((pSyntax->frame.X & 0xF) && (pSyntax->frame.X & 0xF) <= 8) - pSyntax->info.fillRight = 1; - } - /* JPEG_YCBCR444 : NOT SUPPORTED */ - else if (pSyntax->frame.component[0].H == 1 && - pSyntax->frame.component[0].V == 1 && - pSyntax->frame.component[1].H == 1 && - pSyntax->frame.component[1].V == 1 && - pSyntax->frame.component[2].H == 1 && - pSyntax->frame.component[2].V == 1) { - JPEGD_INFO_LOG("YCbCr Format: YUV444(1*1:1*1:1*1)"); - pSyntax->info.yCbCrMode = JPEGDEC_YUV444; - pSyntax->info.X = pSyntax->frame.hwX; - pSyntax->info.Y = pSyntax->frame.hwY; - - /* check if fill needed */ - if ((pSyntax->frame.X & 0xF) && (pSyntax->frame.X & 0xF) <= 8) - pSyntax->info.fillRight = 1; - - if ((pSyntax->frame.Y & 0xF) && (pSyntax->frame.Y & 0xF) <= 8) - pSyntax->info.fillBottom = 1; - } else if (pSyntax->frame.component[0].H == 4 && - pSyntax->frame.component[0].V == 1 && - pSyntax->frame.component[1].H == 1 && - pSyntax->frame.component[1].V == 1 && - pSyntax->frame.component[2].H == 1 && - pSyntax->frame.component[2].V == 1) { - JPEGD_INFO_LOG("YCbCr Format: YUV411(4*1:1*1:1*1)"); - pSyntax->info.yCbCrMode = JPEGDEC_YUV411; - pSyntax->info.X = (pSyntax->frame.hwX); - pSyntax->info.Y = (pSyntax->frame.hwY); - - /* check if fill needed */ - if ((pSyntax->frame.Y & 0xF) && (pSyntax->frame.Y & 0xF) <= 8) - pSyntax->info.fillBottom = 1; - } else { - JPEGD_ERROR_LOG("Unsupported YCbCr Format: (%d*%d:%d*%d:%d*%d)", pSyntax->frame.component[0].H, pSyntax->frame.component[0].V, - pSyntax->frame.component[1].H, pSyntax->frame.component[1].V, - pSyntax->frame.component[2].H, pSyntax->frame.component[2].V); - return (JPEGDEC_UNSUPPORTED); - } - } else if (pSyntax->frame.Nf == 1) { - /* 4:0:0 */ - if ((pSyntax->frame.component[0].V == 1) || - (pSyntax->frame.component[0].H == 1)) { - pSyntax->info.yCbCrMode = JPEGDEC_YUV400; - pSyntax->info.X = (pSyntax->frame.hwX); - pSyntax->info.Y = (pSyntax->frame.hwY); - - /* check if fill needed */ - if ((pSyntax->frame.X & 0xF) && (pSyntax->frame.X & 0xF) <= 8) - pSyntax->info.fillRight = 1; - - if ((pSyntax->frame.Y & 0xF) && (pSyntax->frame.Y & 0xF) <= 8) - pSyntax->info.fillBottom = 1; - } else { - JPEGD_ERROR_LOG("unsupported format"); - return (JPEGDEC_UNSUPPORTED); - } - } else { - JPEGD_ERROR_LOG("unsupported format"); - return (JPEGDEC_UNSUPPORTED); - } - - /* save the original sampling format for progressive use */ - pSyntax->info.yCbCrModeOrig = pSyntax->info.yCbCrMode; - - return (JPEGDEC_OK); -} - -JpegDecRet jpegd_decode_frame_header(JpegParserContext *ctx) -{ - FUN_TEST("Enter"); - JpegParserContext *pCtx = ctx; - if (NULL == pCtx) { - JPEGD_ERROR_LOG("NULL pointer"); - return MPP_ERR_NULL_PTR; - } - - RK_U32 i; - RK_U32 width, height; - RK_U32 tmp1, tmp2; - RK_U32 Hmax = 0; - RK_U32 Vmax = 0; - RK_U32 size = 0; - JpegDecRet retCode; - - JpegSyntaxParam *pSyntax = pCtx->pSyntax; - StreamStorage *pStream = &(pSyntax->stream); - - retCode = JPEGDEC_OK; - - /* frame header length */ - pSyntax->frame.Lf = jpegd_get_two_bytes(pStream); - - /* check if there is enough data */ - if (((pSyntax->stream.readBits / 8) + pSyntax->frame.Lf) > - pSyntax->stream.streamLength) - return (JPEGDEC_STRM_ERROR); - - /* Sample precision */ - pSyntax->frame.P = jpegd_get_byte(pStream); - if (pSyntax->frame.P != 8) { - JPEGD_ERROR_LOG("frame.P(%d) is not supported", pSyntax->frame.P); - return (JPEGDEC_UNSUPPORTED); - } - /* Number of Lines */ - pSyntax->frame.Y = jpegd_get_two_bytes(pStream); - if (pSyntax->frame.Y < 1) { - return (JPEGDEC_UNSUPPORTED); - } - pSyntax->frame.hwY = pSyntax->frame.Y; - - /* round up to next multiple-of-16 */ - pSyntax->frame.hwY += 0xf; - pSyntax->frame.hwY &= ~(0xf); - JPEGD_INFO_LOG("Height, frame.Y:%d, frame.hwY:%d", pSyntax->frame.Y, pSyntax->frame.hwY); - - /* Number of samples per line */ - pSyntax->frame.X = jpegd_get_two_bytes(pStream); - if (pSyntax->frame.X < 1) { - return (JPEGDEC_UNSUPPORTED); - } - pSyntax->frame.hwX = pSyntax->frame.X; - - /* round up to next multiple-of-16 */ - pSyntax->frame.hwX += 0xf; - pSyntax->frame.hwX &= ~(0xf); - JPEGD_INFO_LOG("Width, frame.X:%d, frame.hwX:%d", pSyntax->frame.X, pSyntax->frame.hwX); - - /* for internal() */ - pSyntax->info.X = pSyntax->frame.hwX; - pSyntax->info.Y = pSyntax->frame.hwY; - - /* check for minimum and maximum dimensions */ - if (pSyntax->frame.hwX < pCtx->minSupportedWidth || - pSyntax->frame.hwY < pCtx->minSupportedHeight || - pSyntax->frame.hwX > pCtx->maxSupportedWidth || - pSyntax->frame.hwY > pCtx->maxSupportedHeight || - (pSyntax->frame.hwX * pSyntax->frame.hwY) > pCtx->maxSupportedPixelAmount) { - JPEGD_ERROR_LOG("FRAME(%d*%d): Unsupported size\n", pSyntax->frame.hwX, pSyntax->frame.hwY); - return (JPEGDEC_UNSUPPORTED); - } - - /* Number of components */ - pSyntax->frame.Nf = jpegd_get_byte(pStream); - if ((pSyntax->frame.Nf != 3) && (pSyntax->frame.Nf != 1)) { - JPEGD_ERROR_LOG("frame.Nf(%d) is unsupported", pSyntax->frame.Nf); - return (JPEGDEC_UNSUPPORTED); - } - - /* save component specific data */ - /* Nf == number of components */ - for (i = 0; i < pSyntax->frame.Nf; i++) { - pSyntax->frame.component[i].C = jpegd_get_byte(pStream); - if (i == 0) { /* for the first component */ - /* if first component id is something else than 1 (jfif) */ - pSyntax->scan.index = pSyntax->frame.component[i].C; - } else { - /* if component ids 'jumps' */ - if ((pSyntax->frame.component[i - 1].C + 1) != pSyntax->frame.component[i].C) { - JPEGD_ERROR_LOG("component ids 'jumps'\n"); - return (JPEGDEC_UNSUPPORTED); - } - } - tmp1 = jpegd_get_byte(pStream); - pSyntax->frame.component[i].H = tmp1 >> 4; - if (pSyntax->frame.component[i].H > Hmax) { - Hmax = pSyntax->frame.component[i].H; - } - pSyntax->frame.component[i].V = tmp1 & 0xF; - if (pSyntax->frame.component[i].V > Vmax) { - Vmax = pSyntax->frame.component[i].V; - } - - pSyntax->frame.component[i].Tq = jpegd_get_byte(pStream); - } - - if (pSyntax->frame.Nf == 1) { - Hmax = Vmax = 1; - pSyntax->frame.component[0].H = 1; - pSyntax->frame.component[0].V = 1; - } else if (Hmax == 0 || Vmax == 0) { - JPEGD_ERROR_LOG("Hmax(%d),Vmax(%d) is unsupported", Hmax, Vmax); - return (JPEGDEC_UNSUPPORTED); - } - - /* JPEG_YCBCR411 horizontal size has to be multiple of 32 pels */ - if (Hmax == 4 && (pSyntax->frame.hwX & 0x1F)) { - /* round up to next multiple-of-32 */ - pSyntax->frame.hwX += 16; - pSyntax->info.X = pSyntax->frame.hwX; - - /* check for minimum and maximum dimensions */ - if (pSyntax->frame.hwX > pCtx->maxSupportedWidth || - (pSyntax->frame.hwX * pSyntax->frame.hwY) > pCtx->maxSupportedPixelAmount) { - JPEGD_ERROR_LOG("FRAME(%d*%d): Unsupported size\n", pSyntax->frame.hwX, pSyntax->frame.hwY); - return (JPEGDEC_UNSUPPORTED); - } - } - - /* set image pointers, calculate pixelPerRow for each component */ - width = ((pSyntax->frame.hwX + Hmax * 8 - 1) / (Hmax * 8)) * Hmax * 8; - height = ((pSyntax->frame.hwY + Vmax * 8 - 1) / (Vmax * 8)) * Vmax * 8; - JPEGD_VERBOSE_LOG("width:%d, height:%d", width, height); - - /* calculate numMcuInRow and numMcuInFrame */ - JPEGD_ASSERT(Hmax != 0); - JPEGD_ASSERT(Vmax != 0); - pSyntax->frame.numMcuInRow = width / (8 * Hmax); - pSyntax->frame.numMcuInFrame = pSyntax->frame.numMcuInRow * (height / (8 * Vmax)); - JPEGD_VERBOSE_LOG("numMcuInRow:%d, numMcuInFrame:%d", pSyntax->frame.numMcuInRow, pSyntax->frame.numMcuInFrame); - - /* reset mcuNumbers */ - pSyntax->frame.mcuNumber = 0; - pSyntax->frame.row = pSyntax->frame.col = 0; - - for (i = 0; i < pSyntax->frame.Nf; i++) { - JPEGD_ASSERT(i <= 2); - tmp1 = (width * pSyntax->frame.component[i].H + Hmax - 1) / Hmax; - tmp2 = (height * pSyntax->frame.component[i].V + Vmax - 1) / Vmax; - size += tmp1 * tmp2; - - /* pixels per row */ - pSyntax->image.pixelsPerRow[i] = tmp1; - pSyntax->image.columns[i] = tmp2; - pSyntax->frame.numBlocks[i] = - (((pSyntax->frame.hwX * pSyntax->frame.component[i].H) / Hmax + 7) >> 3) * - (((pSyntax->frame.hwY * pSyntax->frame.component[i].V) / Vmax + 7) >> 3); - - if (i == 0) { - pSyntax->image.sizeLuma = size; - } - } - - pSyntax->image.size = size; - pSyntax->image.sizeChroma = size - pSyntax->image.sizeLuma; - JPEGD_VERBOSE_LOG("sizeLuma:%d", pSyntax->image.sizeLuma); - JPEGD_VERBOSE_LOG("image.size:%d, sizeChroma:%d", pSyntax->image.size, pSyntax->image.sizeChroma); - - /* set YUV mode & calculate rlc tmp size */ - retCode = jpegd_set_yuv_mode(pSyntax); - if (retCode != JPEGDEC_OK) { - JPEGD_ERROR_LOG("set YUV mode failed"); - return (retCode); - } - - return (JPEGDEC_OK); - FUN_TEST("Exit"); -} - -JpegDecRet jpegd_decode_scan_header(JpegParserContext *ctx) -{ - FUN_TEST("Enter"); - JpegParserContext *pCtx = ctx; - if (NULL == pCtx) { - JPEGD_ERROR_LOG("NULL pointer"); - return MPP_ERR_NULL_PTR; - } - - RK_U32 i; - RK_U32 tmp; - - JpegSyntaxParam *pSyntax = pCtx->pSyntax; - StreamStorage *pStream = &(pSyntax->stream); - - pSyntax->scan.Ls = jpegd_get_two_bytes(pStream); - - /* check if there is enough data */ - if (((pStream->readBits / 8) + pSyntax->scan.Ls) > pStream->streamLength) { - JPEGD_ERROR_LOG("no enough data"); - return (JPEGDEC_STRM_ERROR); - } - - pSyntax->scan.Ns = jpegd_get_byte(pStream); - - pSyntax->info.fillX = pSyntax->info.fillY = 0; - if (pSyntax->scan.Ns == 1) { - JPEGD_INFO_LOG("scan.Ns == 1"); - /* Reset to non-interleaved baseline operation type */ - if (pSyntax->info.operationType == JPEGDEC_BASELINE && - pSyntax->info.yCbCrMode != JPEGDEC_YUV400) - pSyntax->info.operationType = JPEGDEC_NONINTERLEAVED; - - tmp = jpegd_get_byte(pStream); - pSyntax->frame.cIndex = tmp - 1; - pSyntax->info.componentId = pSyntax->frame.cIndex; - pSyntax->scan.Cs[pSyntax->frame.cIndex] = tmp; - tmp = jpegd_get_byte(pStream); - pSyntax->scan.Td[pSyntax->frame.cIndex] = tmp >> 4; - pSyntax->scan.Ta[pSyntax->frame.cIndex] = tmp & 0x0F; - - /* check/update component info */ - if (pSyntax->frame.Nf == 3) { - pSyntax->info.fillRight = 0; - pSyntax->info.fillBottom = 0; - pSyntax->info.pfNeeded[pSyntax->scan.Cs[pSyntax->frame.cIndex] - 1] = 0; - if (pSyntax->scan.Cs[pSyntax->frame.cIndex] == 2 || - pSyntax->scan.Cs[pSyntax->frame.cIndex] == 3) { - if (pSyntax->info.operationType == JPEGDEC_PROGRESSIVE || - pSyntax->info.operationType == JPEGDEC_NONINTERLEAVED || - pSyntax->info.nonInterleavedScanReady) { - if (pSyntax->info.yCbCrModeOrig == JPEGDEC_YUV420) { - pSyntax->info.X = pSyntax->frame.hwX >> 1; - pSyntax->info.Y = pSyntax->frame.hwY >> 1; - } else if (pSyntax->info.yCbCrModeOrig == JPEGDEC_YUV422) { - pSyntax->info.X = pSyntax->frame.hwX >> 1; - } else if (pSyntax->info.yCbCrModeOrig == JPEGDEC_YUV440) { - pSyntax->info.Y = pSyntax->frame.hwY >> 1; - } else { - pSyntax->info.yCbCrMode = 0; - return (JPEGDEC_UNSUPPORTED); - } - } - - pSyntax->info.yCbCrMode = 0; - } else if (pSyntax->scan.Cs[pSyntax->frame.cIndex] == 1) { /* YCbCr 4:2:0 */ - pSyntax->info.X = pSyntax->frame.hwX; - pSyntax->info.Y = pSyntax->frame.hwY; - if (pSyntax->info.yCbCrMode == JPEGDEC_YUV420) { - pSyntax->info.yCbCrMode = 1; - } else if (pSyntax->info.yCbCrMode == JPEGDEC_YUV422) { - pSyntax->info.yCbCrMode = 0; - if (pSyntax->frame.cIndex == 0) { - JPEGD_INFO_LOG("SCAN: #YUV422 FLAG\n"); - pSyntax->info.yCbCr422 = 1; - } - } else if (pSyntax->info.yCbCrMode == JPEGDEC_YUV444) { - pSyntax->info.yCbCrMode = 0; - return (JPEGDEC_UNSUPPORTED); - } - } else { - pSyntax->info.yCbCrMode = 0; - return (JPEGDEC_UNSUPPORTED); - } - - if (pSyntax->info.X & 0xF) { - pSyntax->info.X += 8; - pSyntax->info.fillX = 1; - } else if ((pSyntax->scan.Cs[pSyntax->frame.cIndex] == 1 || - pSyntax->info.yCbCrModeOrig == JPEGDEC_YUV440) && - (pSyntax->frame.X & 0xF) && (pSyntax->frame.X & 0xF) <= 8) { - pSyntax->info.fillRight = 1; - } - - if (pSyntax->info.Y & 0xF) { - pSyntax->info.Y += 8; - pSyntax->info.fillY = 1; - } else if ((pSyntax->scan.Cs[pSyntax->frame.cIndex] == 1 || - pSyntax->info.yCbCrModeOrig == JPEGDEC_YUV422) && - (pSyntax->frame.Y & 0xF) && (pSyntax->frame.Y & 0xF) <= 8) { - pSyntax->info.fillBottom = 1; - } - } else if (pSyntax->frame.Nf == 1) { - JPEGD_INFO_LOG("SCAN: #YUV422 FLAG\n"); - pSyntax->info.yCbCr422 = 0; - } - - /* decoding info */ - if (pSyntax->info.operationType == JPEGDEC_PROGRESSIVE || - pSyntax->info.operationType == JPEGDEC_NONINTERLEAVED) { - pSyntax->info.yCbCrMode = 0; - } - } else { - for (i = 0; i < pSyntax->scan.Ns; i++) { - pSyntax->scan.Cs[i] = jpegd_get_byte(pStream); - tmp = jpegd_get_byte(pStream); - pSyntax->scan.Td[i] = tmp >> 4; /* which DC table */ - pSyntax->scan.Ta[i] = tmp & 0x0F; /* which AC table */ - pSyntax->info.pfNeeded[i] = 1; - } - pSyntax->info.X = pSyntax->frame.hwX; - pSyntax->info.Y = pSyntax->frame.hwY; - pSyntax->frame.cIndex = 0; - pSyntax->info.yCbCrMode = pSyntax->info.yCbCrModeOrig; - } - - pSyntax->scan.Ss = jpegd_get_byte(pStream); - pSyntax->scan.Se = jpegd_get_byte(pStream); - tmp = jpegd_get_byte(pStream); - pSyntax->scan.Ah = tmp >> 4; - pSyntax->scan.Al = tmp & 0x0F; - - if (pSyntax->frame.codingType == SOF0) { - /* baseline */ - if (pSyntax->scan.Ss != 0) - return (JPEGDEC_UNSUPPORTED); - if (pSyntax->scan.Se != 63) - return (JPEGDEC_UNSUPPORTED); - if (pSyntax->scan.Ah != 0) - return (JPEGDEC_UNSUPPORTED); - if (pSyntax->scan.Al != 0) - return (JPEGDEC_UNSUPPORTED); - - /* update scan decoding parameters */ - /* interleaved/non-interleaved */ - if (pSyntax->info.operationType == JPEGDEC_BASELINE) - pSyntax->info.nonInterleaved = 0; - else - pSyntax->info.nonInterleaved = 1; - /* decoding info */ - if ((pSyntax->frame.Nf == 3 && pSyntax->scan.Ns == 1) || - (pSyntax->frame.Nf == 1 && pSyntax->scan.Ns == 1)) - pSyntax->info.amountOfQTables = 1; - else - pSyntax->info.amountOfQTables = 3; - } - - if (pSyntax->frame.codingType == SOF2) { - /* progressive */ - if (pSyntax->scan.Ss == 0 && pSyntax->scan.Se != 0) - return (JPEGDEC_UNSUPPORTED); - if (/*pSyntax->scan.Ah < 0 ||*/ pSyntax->scan.Ah > 13) - return (JPEGDEC_UNSUPPORTED); - if (/*pSyntax->scan.Al < 0 ||*/ pSyntax->scan.Al > 13) - return (JPEGDEC_UNSUPPORTED); - - /* update scan decoding parameters */ - /* TODO! What if 2 components, possible??? */ - /* interleaved/non-interleaved */ - if (pSyntax->scan.Ns == 1) { - pSyntax->info.nonInterleaved = 1; - /* component ID */ - pSyntax->info.componentId = pSyntax->frame.cIndex; - pSyntax->info.amountOfQTables = 1; - } else { - pSyntax->info.nonInterleaved = 0; - /* component ID ==> set to luma ==> interleaved */ - pSyntax->info.componentId = 0; - pSyntax->info.amountOfQTables = 3; - } - - } - - FUN_TEST("Exit"); - return (JPEGDEC_OK); -} - -JpegDecRet jpegd_decode_scan(JpegParserContext *ctx) -{ - FUN_TEST("Enter"); - JpegParserContext *pCtx = ctx; - if (NULL == pCtx) { - JPEGD_ERROR_LOG("NULL pointer"); - return MPP_ERR_NULL_PTR; - } - - JpegDecRet retCode; - JpegSyntaxParam *pSyntax = pCtx->pSyntax; - retCode = JPEGDEC_ERROR; - - retCode = jpegd_decode_scan_header(pCtx); - if (retCode != JPEGDEC_OK) { - JPEGD_ERROR_LOG("Decode Scan Header Failed"); - return (retCode); - } - - JPEGD_VERBOSE_LOG("SCAN: MODE: %d\n", pSyntax->frame.codingType); - FUN_TEST("Exit"); - return (JPEGDEC_OK); -} - -JpegDecRet jpegd_decode_huffman_tables(JpegParserContext *ctx) -{ - FUN_TEST("Enter"); - JpegParserContext *pCtx = ctx; - if (NULL == pCtx) { - JPEGD_ERROR_LOG("NULL pointer"); - return MPP_ERR_NULL_PTR; - } - - RK_U32 i, len, Tc, Th, tmp; - RK_S32 j; - JpegSyntaxParam *pSyntax = pCtx->pSyntax; - StreamStorage *pStream = &(pSyntax->stream); - - pSyntax->vlc.Lh = jpegd_get_two_bytes(pStream); - - /* check if there is enough data for tables */ - if (((pStream->readBits / 8) + pSyntax->vlc.Lh) > pStream->streamLength) { - JPEGD_ERROR_LOG("no enough data for tables"); - return (JPEGDEC_STRM_ERROR); - } - - /* four bytes already read in */ - len = 4; - - while (len < pSyntax->vlc.Lh) { - tmp = jpegd_get_byte(pStream); - len++; - Tc = tmp >> 4; /* Table class: DC or AC */ - if (Tc != 0 && Tc != 1) { - JPEGD_ERROR_LOG("Tc(%d) is unsupported", Tc); - return (JPEGDEC_UNSUPPORTED); - } - Th = tmp & 0xF; /* Huffman table identifier: 0 or 1 .(Baseline)*/ - /* only two tables in baseline allowed */ - if ((pSyntax->frame.codingType == SOF0) && (Th > 1)) { - JPEGD_ERROR_LOG("Th(%d) is unsupported", Th); - return (JPEGDEC_UNSUPPORTED); - } - /* four tables in progressive allowed */ - if ((pSyntax->frame.codingType == SOF2) && (Th > 3)) { - JPEGD_ERROR_LOG("Th(%d) is unsupported", Th); - return (JPEGDEC_UNSUPPORTED); - } - - /* set the table pointer */ - if (Tc) { - /* AC table */ - switch (Th) { - case 0: - JPEGD_VERBOSE_LOG("ac0\n"); - pSyntax->vlc.table = &(pSyntax->vlc.acTable0); - break; - case 1: - JPEGD_VERBOSE_LOG("ac1\n"); - pSyntax->vlc.table = &(pSyntax->vlc.acTable1); - break; - case 2: - JPEGD_VERBOSE_LOG("ac2\n"); - pSyntax->vlc.table = &(pSyntax->vlc.acTable2); - break; - case 3: - JPEGD_VERBOSE_LOG("ac3\n"); - pSyntax->vlc.table = &(pSyntax->vlc.acTable3); - break; - default: - JPEGD_ERROR_LOG("Th(%d) is unsupported", Th); - return (JPEGDEC_UNSUPPORTED); - } - } else { - /* DC table */ - switch (Th) { - case 0: - JPEGD_VERBOSE_LOG("dc0\n"); - pSyntax->vlc.table = &(pSyntax->vlc.dcTable0); - break; - case 1: - JPEGD_VERBOSE_LOG("dc1\n"); - pSyntax->vlc.table = &(pSyntax->vlc.dcTable1); - break; - case 2: - JPEGD_VERBOSE_LOG("dc2\n"); - pSyntax->vlc.table = &(pSyntax->vlc.dcTable2); - break; - case 3: - JPEGD_VERBOSE_LOG("dc3\n"); - pSyntax->vlc.table = &(pSyntax->vlc.dcTable3); - break; - default: - JPEGD_ERROR_LOG("Th(%d) is unsupported", Th); - return (JPEGDEC_UNSUPPORTED); - } - } - - tmp = 0; - /* read in the values of list BITS */ - for (i = 0; i < 16; i++) { - tmp += pSyntax->vlc.table->bits[i] = jpegd_get_byte(pStream); - len++; - } - /* allocate memory for HUFFVALs */ - if (pSyntax->vlc.table->vals != NULL) { - /* free previously reserved table */ - mpp_free(pSyntax->vlc.table->vals); - } - - pSyntax->vlc.table->vals = (RK_U32 *) mpp_calloc(RK_U32, tmp); - - /* set the table length */ - pSyntax->vlc.table->tableLength = tmp; - /* read in the HUFFVALs */ - for (i = 0; i < tmp; i++) { - pSyntax->vlc.table->vals[i] = jpegd_get_byte(pStream); - len++; - } - /* first and last lengths */ - for (i = 0; i < 16; i++) { - if (pSyntax->vlc.table->bits[i] != 0) { - pSyntax->vlc.table->start = i; - break; - } - } - for (j = 15; j >= 0; j--) { - if (pSyntax->vlc.table->bits[j] != 0) { - pSyntax->vlc.table->last = ((RK_U32) j + 1); - break; - } - } - } - - return (JPEGDEC_OK); - FUN_TEST("Exit"); -} - -JpegDecRet jpegd_decode_quant_tables(JpegParserContext *ctx) -{ - FUN_TEST("Enter"); - JpegParserContext *pCtx = ctx; - if (NULL == pCtx) { - JPEGD_ERROR_LOG("NULL pointer"); - return MPP_ERR_NULL_PTR; - } - - RK_U32 t, tmp, i; - JpegSyntaxParam *pSyntax = pCtx->pSyntax; - StreamStorage *pStream = &(pSyntax->stream); - - pSyntax->quant.Lq = jpegd_get_two_bytes(pStream); - - /* check if there is enough data for tables */ - if (((pStream->readBits / 8) + pSyntax->quant.Lq) > pStream->streamLength) { - JPEGD_ERROR_LOG("no enough data for tables"); - return (JPEGDEC_STRM_ERROR); - } - - t = 4; - - while (t < pSyntax->quant.Lq) { - /* Tq value selects what table the components use */ - - /* read tables and write to decData->quant */ - tmp = jpegd_get_byte(pStream); - t++; - /* supporting only 8 bits / sample */ - if ((tmp >> 4) != 0) { - JPEGD_ERROR_LOG("Pq(%d) is not supported!", (tmp >> 4)); - return (JPEGDEC_UNSUPPORTED); - } - - tmp &= 0xF; /* Tq */ - /* set the quantisation table pointer */ - - if (tmp == 0) { - JPEGD_VERBOSE_LOG("qtable0\n"); - pSyntax->quant.table = pSyntax->quant.table0; - } else if (tmp == 1) { - JPEGD_VERBOSE_LOG("qtable1\n"); - pSyntax->quant.table = pSyntax->quant.table1; - } else if (tmp == 2) { - JPEGD_VERBOSE_LOG("qtable2\n"); - pSyntax->quant.table = pSyntax->quant.table2; - } else if (tmp == 3) { - JPEGD_VERBOSE_LOG("qtable3\n"); - pSyntax->quant.table = pSyntax->quant.table3; - } else { - JPEGD_ERROR_LOG("Tq(%d) is not supported!", tmp); - return (JPEGDEC_UNSUPPORTED); - } - for (i = 0; i < 64; i++) { - pSyntax->quant.table[i] = jpegd_get_byte(pStream); - t++; - } - } - - return (MPP_OK); - FUN_TEST("Exit"); -} - -JpegDecRet jpegd_default_huffman_tables(JpegParserContext *ctx) -{ - FUN_TEST("Enter"); - JpegParserContext *pCtx = ctx; - if (NULL == pCtx) { - JPEGD_ERROR_LOG("NULL pointer"); - return MPP_ERR_NULL_PTR; - } - JpegSyntaxParam *pSyntax = pCtx->pSyntax; - - /* Set up the standard Huffman tables (cf. JPEG standard section K.3) */ - /* IMPORTANT: these are only valid for 8-bit data precision! */ - uint8_t ff_mjpeg_bits_dc_luminance[17] = - { /* 0-base */ 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 }; - uint8_t ff_mjpeg_val_dc[12] = //luminance and chrominance all use it - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; - - uint8_t ff_mjpeg_bits_dc_chrominance[17] = - { /* 0-base */ 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 }; - - uint8_t ff_mjpeg_bits_ac_luminance[17] = - { /* 0-base */ 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d }; - uint8_t ff_mjpeg_val_ac_luminance[] = { - 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, - 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, - 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, - 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, - 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, - 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, - 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, - 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, - 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, - 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, - 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, - 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, - 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, - 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, - 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, - 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, - 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, - 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, - 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, - 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, - 0xf9, 0xfa - }; - - uint8_t ff_mjpeg_bits_ac_chrominance[17] = - { /* 0-base */ 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 }; - - uint8_t ff_mjpeg_val_ac_chrominance[] = { - 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, - 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, - 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, - 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, - 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, - 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, - 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, - 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, - 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, - 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, - 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, - 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, - 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, - 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, - 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, - 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, - 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, - 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, - 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, - 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, - 0xf9, 0xfa - }; - - RK_U32 i, len, tmp, k; - RK_S32 j; - uint8_t *bitstable[4] = {ff_mjpeg_bits_dc_luminance, ff_mjpeg_bits_ac_luminance, ff_mjpeg_bits_dc_chrominance, ff_mjpeg_bits_ac_chrominance}; - uint8_t *valtable[4] = {ff_mjpeg_val_dc, ff_mjpeg_val_ac_luminance, ff_mjpeg_val_dc, ff_mjpeg_val_ac_chrominance}; - uint8_t *bitstmp; - uint8_t *valtmp; - - for (k = 0; k < 4; k++) { - bitstmp = bitstable[k]; - valtmp = valtable[k]; - - if (k == 0) - pSyntax->vlc.table = &(pSyntax->vlc.dcTable0); - else if (k == 1) - pSyntax->vlc.table = &(pSyntax->vlc.acTable0); - else if (k == 2) - pSyntax->vlc.table = &(pSyntax->vlc.dcTable1); - else - pSyntax->vlc.table = &(pSyntax->vlc.acTable1); - - tmp = 0; - /* read in the values of list BITS */ - for (i = 0; i < 16; i++) { - tmp += pSyntax->vlc.table->bits[i] = bitstmp[i + 1]; - len++; - } - /* allocate memory for HUFFVALs */ - if (pSyntax->vlc.table->vals != NULL) { - /* free previously reserved table */ - mpp_free(pSyntax->vlc.table->vals); - } - - pSyntax->vlc.table->vals = (RK_U32 *) mpp_calloc(RK_U32, tmp); - - /* set the table length */ - pSyntax->vlc.table->tableLength = tmp; - /* read in the HUFFVALs */ - for (i = 0; i < tmp; i++) { - pSyntax->vlc.table->vals[i] = valtmp[i]; - len++; - } - /* first and last lengths */ - for (i = 0; i < 16; i++) { - if (pSyntax->vlc.table->bits[i] != 0) { - pSyntax->vlc.table->start = i; - break; - } - } - for (j = 15; j >= 0; j--) { - if (pSyntax->vlc.table->bits[j] != 0) { - pSyntax->vlc.table->last = ((RK_U32) j + 1); - break; - } - } - } - - FUN_TEST("Exit"); - return MPP_OK; -} - -MPP_RET jpegd_parser_split_frame(RK_U8 *src, RK_U32 src_size, RK_U8 *dst, RK_U32 *dst_size) -{ - FUN_TEST("Enter"); - MPP_RET ret = MPP_OK; - if (NULL == src || NULL == dst || src_size <= 0) { - JPEGD_ERROR_LOG("NULL pointer or wrong src_size(%d)", src_size); - return MPP_ERR_NULL_PTR; - } - RK_U8 *end; - RK_U8 *tmp; - RK_U32 str_size = (src_size + 255) & (~255); - end = dst + src_size; - - if (src[6] == 0x41 && src[7] == 0x56 && src[8] == 0x49 && src[9] == 0x31) { - //distinguish 310 from 210 camera - RK_U32 i; - RK_U32 copy_len = 0; - tmp = src; - JPEGD_INFO_LOG("distinguish 310 from 210 camera"); - - for (i = 0; i < src_size - 4; i++) { - if (tmp[i] == 0xff) { - if (tmp[i + 1] == 0x00 && tmp[i + 2] == 0xff && ((tmp[i + 3] & 0xf0) == 0xd0)) - i += 2; - } - *dst++ = tmp[i]; - copy_len++; - } - for (; i < src_size; i++) { - *dst++ = tmp[i]; - copy_len++; - } - if (copy_len < src_size) - memset(dst, 0, src_size - copy_len); - *dst_size = copy_len; - } else { - memcpy(dst, src, src_size); - memset(dst + src_size, 0, str_size - src_size); - *dst_size = src_size; - } - - /* NOTE: hardware bug, need to remove tailing FF 00 before FF D9 end flag */ - if (end[-1] == 0xD9 && end[-2] == 0xFF) { - end -= 2; - - do { - if (end[-1] == 0xFF) { - end--; - continue; - } - if (end[-1] == 0x00 && end [-2] == 0xFF) { - end -= 2; - continue; - } - break; - } while (1); - - JPEGD_INFO_LOG("remove tailing FF 00 before FF D9 end flag."); - end[0] = 0xff; - end[1] = 0xD9; - } - - FUN_TEST("Exit"); - return ret; -} - -MPP_RET jpegd_prepare(void *ctx, MppPacket pkt, HalDecTask *task) -{ - FUN_TEST("Enter"); - MPP_RET ret = MPP_OK; - JpegParserContext *JpegParserCtx = (JpegParserContext *)ctx; - MppPacket input_packet = JpegParserCtx->input_packet; - RK_U32 pkt_length = 0; - RK_U32 copy_length = 0; - void *pPacket = NULL; - RK_U8 *pPos = NULL; - - task->valid = 0; - - JpegParserCtx->pts = mpp_packet_get_pts(pkt); - JpegParserCtx->eos = mpp_packet_get_eos(pkt); - pkt_length = (RK_U32)mpp_packet_get_length(pkt); - pPacket = pPos = mpp_packet_get_pos(pkt); - - if (JpegParserCtx->eos) { - - JPEGD_INFO_LOG("it is end of stream."); - task->flags.eos = 1; - return ret; - } - - if (pkt_length > JpegParserCtx->bufferSize) { - JPEGD_INFO_LOG("Huge Frame(%d Bytes)! bufferSize:%d", pkt_length, JpegParserCtx->bufferSize); - mpp_free(JpegParserCtx->recv_buffer); - JpegParserCtx->recv_buffer = NULL; - - JpegParserCtx->recv_buffer = mpp_calloc(RK_U8, pkt_length + 1024); - if (NULL == JpegParserCtx->recv_buffer) { - JPEGD_ERROR_LOG("no memory!"); - return MPP_ERR_NOMEM; - } - - JpegParserCtx->bufferSize = pkt_length + 1024; - } - - jpegd_parser_split_frame(pPacket, pkt_length, JpegParserCtx->recv_buffer, ©_length); - - pPos += pkt_length; - mpp_packet_set_pos(pkt, pPos); - if (copy_length != pkt_length) { - JPEGD_INFO_LOG("there seems to be something wrong with split_frame. pkt_length:%d, copy_length:%d", pkt_length, copy_length); - } - - /* debug information */ - if (JpegParserCtx->parser_debug_enable && JpegParserCtx->input_jpeg_count < 3) { - static FILE *jpg_file; - static char name[32]; - - snprintf(name, sizeof(name), "/data/input%02d.jpg", JpegParserCtx->input_jpeg_count); - jpg_file = fopen(name, "wb+"); - if (jpg_file) { - JPEGD_INFO_LOG("input jpeg(%d Bytes) saving to %s\n", pkt_length, name); - fwrite(pPacket, pkt_length, 1, jpg_file); - fclose(jpg_file); - JpegParserCtx->input_jpeg_count++; - } - } - - mpp_packet_set_data(input_packet, JpegParserCtx->recv_buffer); - mpp_packet_set_size(input_packet, pkt_length); - mpp_packet_set_length(input_packet, pkt_length); - - JpegParserCtx->streamLength = pkt_length; - task->input_packet = input_packet; - task->valid = 1; - JPEGD_VERBOSE_LOG("input_packet:%p, recv_buffer:%p, pkt_length:%d", input_packet, - JpegParserCtx->recv_buffer, pkt_length); - - FUN_TEST("Exit"); - return ret; -} - -MPP_RET jpegd_read_decode_parameters(JpegParserContext *ctx, StreamStorage *pStream) -{ - FUN_TEST("Enter"); - if (NULL == ctx || NULL == pStream) { - JPEGD_ERROR_LOG("NULL pointer"); - return MPP_ERR_NULL_PTR; - } - - JpegParserContext *pCtx = ctx; - JpegDecImageInfo *pImageInfo = (JpegDecImageInfo *) & (pCtx->pSyntax->imageInfo); - JpegSyntaxParam *pSyntax = pCtx->pSyntax; - RK_U32 Nf = 0, Ns = 0, NsThumb = 0; - RK_U32 i, j = 0, init = 0, initThumb = 0; - RK_U32 H[MAX_NUMBER_OF_COMPONENTS]; - RK_U32 V[MAX_NUMBER_OF_COMPONENTS]; - RK_U32 Htn[MAX_NUMBER_OF_COMPONENTS]; - RK_U32 Vtn[MAX_NUMBER_OF_COMPONENTS]; - RK_U32 Hmax = 0, Vmax = 0, headerLength = 0; - RK_U32 currentByte = 0, currentBytes = 0; - RK_U32 appLength = 0, appBits = 0; - RK_U32 thumbnail = 0, errorCode = 0; - - /* reset sampling factors */ - for (i = 0; i < MAX_NUMBER_OF_COMPONENTS; i++) { - H[i] = 0; - V[i] = 0; - Htn[i] = 0; - Vtn[i] = 0; - } - - /* Read decoding parameters */ - for (pStream->readBits = 0; (pStream->readBits / 8) < pStream->streamLength; pStream->readBits++) { - /* Look for marker prefix byte from stream */ - if ((currentByte == 0xFF) || jpegd_get_byte(pStream) == 0xFF) { - currentByte = jpegd_get_byte(pStream); - - switch (currentByte) { /* switch to certain header decoding */ - case SOF0: /* baseline marker */ - case SOF2: { /* progresive marker */ - JPEGD_VERBOSE_LOG("SOF, currentByte:0x%x", currentByte); - if (currentByte == SOF0) { - pImageInfo->codingMode = pSyntax->info.operationType = JPEGDEC_BASELINE; - } else { - pImageInfo->codingMode = pSyntax->info.operationType = JPEGDEC_PROGRESSIVE; - } - - /* Frame header */ - i++; - Hmax = 0; - Vmax = 0; - - /* SOF0/SOF2 length */ - headerLength = jpegd_get_two_bytes(pStream); - if (headerLength == STRM_ERROR || - ((pStream->readBits + ((headerLength * 8) - 16)) > (8 * pStream->streamLength))) { - errorCode = 1; - break; - } - - /* Sample precision (only 8 bits/sample supported) */ - currentByte = jpegd_get_byte(pStream); - if (currentByte != 8) { - JPEGD_ERROR_LOG("Sample precision"); - return (JPEGDEC_UNSUPPORTED); - } - - /* Number of Lines */ - pImageInfo->outputHeight = jpegd_get_two_bytes(pStream); - pImageInfo->displayHeight = pImageInfo->outputHeight; - if (pImageInfo->outputHeight < 1) { - JPEGD_ERROR_LOG("pImageInfo->outputHeight(%d) Unsupported", pImageInfo->outputHeight); - return (JPEGDEC_UNSUPPORTED); - } - - /* round up to next multiple-of-16 */ - pImageInfo->outputHeight += 0xf; - pImageInfo->outputHeight &= ~(0xf); - pSyntax->frame.hwY = pImageInfo->outputHeight; - - /* Number of Samples per Line */ - pImageInfo->outputWidth = jpegd_get_two_bytes(pStream); - pImageInfo->displayWidth = pImageInfo->outputWidth; - if (pImageInfo->outputWidth < 1) { - JPEGD_ERROR_LOG("pImageInfo->outputWidth(%d) Unsupported", pImageInfo->outputWidth); - return (JPEGDEC_UNSUPPORTED); - } - pImageInfo->outputWidth += 0xf; - pImageInfo->outputWidth &= ~(0xf); - pSyntax->frame.hwX = pImageInfo->outputWidth; - - /* check for minimum and maximum dimensions */ - if (pImageInfo->outputWidth < pCtx->minSupportedWidth || - pImageInfo->outputHeight < pCtx->minSupportedHeight || - pImageInfo->outputWidth > pCtx->maxSupportedWidth || - pImageInfo->outputHeight > pCtx->maxSupportedHeight || - (pImageInfo->outputWidth * pImageInfo->outputHeight) > pCtx->maxSupportedPixelAmount) { - JPEGD_ERROR_LOG("Unsupported size(%d*%d)", pImageInfo->outputWidth, pImageInfo->outputHeight); - return (JPEGDEC_UNSUPPORTED); - } - - /* Number of Image Components per Frame */ - Nf = jpegd_get_byte(pStream); - if (Nf != 3 && Nf != 1) { - JPEGD_ERROR_LOG("Number of Image Components per Frame: %d", Nf); - return (JPEGDEC_UNSUPPORTED); - } - for (j = 0; j < Nf; j++) { - if (jpegd_flush_bits(pStream, 8) == STRM_ERROR) { /* jump over component identifier */ - errorCode = 1; - break; - } - - currentByte = jpegd_get_byte(pStream); - H[j] = (currentByte >> 4); /* Horizontal sampling factor */ - V[j] = (currentByte & 0xF); /* Vertical sampling factor */ - - if (jpegd_flush_bits(pStream, 8) == STRM_ERROR) { /* jump over Tq */ - errorCode = 1; - break; - } - - if (H[j] > Hmax) - Hmax = H[j]; - if (V[j] > Vmax) - Vmax = V[j]; - } - if (Hmax == 0 || Vmax == 0) { - JPEGD_ERROR_LOG("Hmax(%d), Vmax(%d)", Hmax, Vmax); - return (JPEGDEC_UNSUPPORTED); - } - - /* check format */ - if (H[0] == 2 && V[0] == 2 && - H[1] == 1 && V[1] == 1 && H[2] == 1 && V[2] == 1) { - pImageInfo->outputFormat = MPP_FMT_YUV420SP; - pSyntax->frame.numMcuInRow = (pSyntax->frame.hwX / 16); - pSyntax->frame.numMcuInFrame = ((pSyntax->frame.hwX * pSyntax->frame.hwY) / 256); - } else if (H[0] == 2 && V[0] == 1 && H[1] == 1 && V[1] == 1 && H[2] == 1 && V[2] == 1) { - pImageInfo->outputFormat = MPP_FMT_YUV422SP; - pSyntax->frame.numMcuInRow = (pSyntax->frame.hwX / 16); - pSyntax->frame.numMcuInFrame = ((pSyntax->frame.hwX * pSyntax->frame.hwY) / 128); - } else if (H[0] == 1 && V[0] == 2 && - H[1] == 1 && V[1] == 1 && H[2] == 1 && V[2] == 1) { - pImageInfo->outputFormat = JPEGDEC_YCbCr440; - pSyntax->frame.numMcuInRow = (pSyntax->frame.hwX / 8); - pSyntax->frame.numMcuInFrame = ((pSyntax->frame.hwX * pSyntax->frame.hwY) / 128); - } else if (H[0] == 1 && V[0] == 1 && - H[1] == 0 && V[1] == 0 && H[2] == 0 && V[2] == 0) { - pImageInfo->outputFormat = JPEGDEC_YCbCr400; - pSyntax->frame.numMcuInRow = (pSyntax->frame.hwX / 8); - pSyntax->frame.numMcuInFrame = ((pSyntax->frame.hwX * pSyntax->frame.hwY) / 64); - } else if (pCtx->extensionsSupported && - H[0] == 4 && V[0] == 1 && - H[1] == 1 && V[1] == 1 && H[2] == 1 && V[2] == 1) { - /* YUV411 output has to be 32 pixel multiple */ - if (pImageInfo->outputWidth & 0x1F) { - pImageInfo->outputWidth += 16; - pSyntax->frame.hwX = pImageInfo->outputWidth; - } - - /* check for maximum dimensions */ - if (pImageInfo->outputWidth > pCtx->maxSupportedWidth || - (pImageInfo->outputWidth * pImageInfo->outputHeight) > pCtx->maxSupportedPixelAmount) { - JPEGD_ERROR_LOG("Unsupported size(%d*%d)", pImageInfo->outputWidth, pImageInfo->outputHeight); - return (JPEGDEC_UNSUPPORTED); - } - - pImageInfo->outputFormat = JPEGDEC_YCbCr411_SEMIPLANAR; - pSyntax->frame.numMcuInRow = (pSyntax->frame.hwX / 32); - pSyntax->frame.numMcuInFrame = ((pSyntax->frame.hwX * pSyntax->frame.hwY) / 256); - } else if (pCtx->extensionsSupported && - H[0] == 1 && V[0] == 1 && - H[1] == 1 && V[1] == 1 && H[2] == 1 && V[2] == 1) { - pImageInfo->outputFormat = JPEGDEC_YCbCr444_SEMIPLANAR; - pSyntax->frame.numMcuInRow = (pSyntax->frame.hwX / 8); - pSyntax->frame.numMcuInFrame = ((pSyntax->frame.hwX * pSyntax->frame.hwY) / 64); - } else { - JPEGD_ERROR_LOG("Unsupported YCbCr format"); - return (JPEGDEC_UNSUPPORTED); - } - - /* restore output format */ - pSyntax->info.yCbCrMode = pSyntax->info.getInfoYCbCrMode = pImageInfo->outputFormat; - break; - } - case SOS: { - JPEGD_VERBOSE_LOG("SOS, currentByte:0x%x", currentByte); - /* SOS length */ - headerLength = jpegd_get_two_bytes(pStream); - JPEGD_VERBOSE_LOG("Length of is %d", headerLength); - if (headerLength == STRM_ERROR || - ((pStream->readBits + ((headerLength * 8) - 16)) > (8 * pStream->streamLength))) { - JPEGD_ERROR_LOG("readBits:%d, headerLength:%d, streamLength:%d", pStream->readBits, headerLength, pStream->streamLength); - errorCode = 1; - break; - } - - /* check if interleaved or non-ibnterleaved */ - Ns = jpegd_get_byte(pStream); - if (Ns == MIN_NUMBER_OF_COMPONENTS && - pImageInfo->outputFormat != JPEGDEC_YCbCr400 && pImageInfo->codingMode == JPEGDEC_BASELINE) { - pImageInfo->codingMode = pSyntax->info.operationType = JPEGDEC_NONINTERLEAVED; - } - - /* jump over SOS header */ - if (headerLength != 0) { - pStream->readBits += ((headerLength * 8) - 16); - pStream->pCurrPos += (((headerLength * 8) - 16) / 8); - } - - if ((pStream->readBits + 8) < (8 * pStream->streamLength)) { - pSyntax->info.init = 1; - init = 1; - } else { - JPEGD_ERROR_LOG("Needs to increase input buffer"); - return (JPEGDEC_INCREASE_INPUT_BUFFER); - } - break; - } - case DQT: { - JPEGD_VERBOSE_LOG("DQT, currentByte:0x%x", currentByte); - /* DQT length */ - headerLength = jpegd_get_two_bytes(pStream); - JPEGD_VERBOSE_LOG("Length of Define Quantization Table is %d", headerLength); - if (headerLength == STRM_ERROR || - ((pStream->readBits + ((headerLength * 8) - 16)) > (8 * pStream->streamLength))) { - JPEGD_ERROR_LOG("readBits:%d, headerLength:%d, streamLength:%d", pStream->readBits, headerLength, pStream->streamLength); - errorCode = 1; - break; - } - - /* jump over DQT header */ - if (headerLength != 0) { - pStream->readBits += ((headerLength * 8) - 16); - pStream->pCurrPos += (((headerLength * 8) - 16) / 8); - } - break; - } - case DHT: { - JPEGD_VERBOSE_LOG("DHT, currentByte:0x%x", currentByte); - /* DHT length */ - headerLength = jpegd_get_two_bytes(pStream); - JPEGD_VERBOSE_LOG("Length of Define Huffman Table is %d", headerLength); - if (headerLength == STRM_ERROR || - ((pStream->readBits + ((headerLength * 8) - 16)) > (8 * pStream->streamLength))) { - JPEGD_ERROR_LOG("readBits:%d, headerLength:%d, streamLength:%d", pStream->readBits, headerLength, pStream->streamLength); - errorCode = 1; - break; - } - /* jump over DHT header */ - if (headerLength != 0) { - pStream->readBits += ((headerLength * 8) - 16); - pStream->pCurrPos += (((headerLength * 8) - 16) / 8); - } - break; - } - case DRI: { - JPEGD_VERBOSE_LOG("DRI, currentByte:0x%x", currentByte); - /* DRI length */ - headerLength = jpegd_get_two_bytes(pStream); - JPEGD_VERBOSE_LOG("Length of Define Restart Interval(must be 4 Bytes) is %d", headerLength); - if (headerLength == STRM_ERROR || - ((pStream->readBits + ((headerLength * 8) - 16)) > (8 * pStream->streamLength))) { - JPEGD_ERROR_LOG("readBits:%d, headerLength:%d, streamLength:%d", pStream->readBits, headerLength, pStream->streamLength); - errorCode = 1; - break; - } - - headerLength = jpegd_get_two_bytes(pStream); - JPEGD_VERBOSE_LOG("Restart Interval:%d", headerLength); - if (headerLength == STRM_ERROR || - ((pStream->readBits + ((headerLength * 8) - 16)) > (8 * pStream->streamLength))) { - /* may optimize one day */ - JPEGD_ERROR_LOG("readBits:%d, headerLength:%d, streamLength:%d", pStream->readBits, headerLength, pStream->streamLength); - errorCode = 1; - break; - } - pSyntax->frame.Ri = headerLength; - break; - } - case APP0: { /* application segments */ - JPEGD_VERBOSE_LOG("APP0, currentByte:0x%x", currentByte); - /* reset */ - appBits = 0; - appLength = 0; - pStream->appnFlag = 0; - - /* APP0 length */ - headerLength = jpegd_get_two_bytes(pStream); - JPEGD_VERBOSE_LOG("headerLength:%d", headerLength); - if (headerLength == STRM_ERROR || - ((pStream->readBits + ((headerLength * 8) - 16)) > (8 * pStream->streamLength))) { - JPEGD_ERROR_LOG("readBits:%d, headerLength:%d, streamLength:%d", pStream->readBits, headerLength, pStream->streamLength); - errorCode = 1; - break; - } - - appLength = headerLength; - if (appLength < 16) { - pStream->appnFlag = 1; - if (jpegd_flush_bits(pStream, ((appLength * 8) - 16)) == STRM_ERROR) { - JPEGD_ERROR_LOG("flush bits failed"); - errorCode = 1; - break; - } - break; - } - appBits += 16; - - /* check identifier: 0x4A 0x46 0x49 0x46 0x00 */ - currentBytes = jpegd_get_two_bytes(pStream); - JPEGD_VERBOSE_LOG("currentBytes:%x", currentBytes); - appBits += 16; - if (currentBytes != 0x4A46) { - pStream->appnFlag = 1; - if (jpegd_flush_bits(pStream, ((appLength * 8) - appBits)) == STRM_ERROR) { - JPEGD_ERROR_LOG("flush bits failed"); - errorCode = 1; - break; - } - break; - } - - currentBytes = jpegd_get_two_bytes(pStream); - JPEGD_VERBOSE_LOG("currentBytes:%x", currentBytes); - appBits += 16; - if (currentBytes != 0x4946 && currentBytes != 0x5858) { - pStream->appnFlag = 1; - if (jpegd_flush_bits(pStream, ((appLength * 8) - appBits)) == STRM_ERROR) { - JPEGD_ERROR_LOG("flush bits failed"); - errorCode = 1; - break; - } - break; - } - - /* APP0 Extended */ - if (currentBytes == 0x5858) { - JPEGD_VERBOSE_LOG("APP0 Extended"); - thumbnail = 1; - } - currentByte = jpegd_get_byte(pStream); - JPEGD_VERBOSE_LOG("currentBytes:%x", currentBytes); - appBits += 8; - if (currentByte != 0x00) { - pStream->appnFlag = 1; - if (jpegd_flush_bits(pStream, ((appLength * 8) - appBits)) == STRM_ERROR) { - JPEGD_ERROR_LOG("flush bits failed"); - errorCode = 1; - break; - } - pStream->appnFlag = 0; - break; - } - - /* APP0 Extended thumb type */ - if (thumbnail) { - /* extension code */ - currentByte = jpegd_get_byte(pStream); - JPEGD_VERBOSE_LOG("APP0 Extended thumb type, currentBytes:%x", currentBytes); - if (currentByte == JPEGDEC_THUMBNAIL_JPEG) { - pImageInfo->thumbnailType = JPEGDEC_THUMBNAIL_JPEG; - appBits += 8; - pStream->appnFlag = 1; - - /* check thumbnail data */ - Hmax = 0; - Vmax = 0; - - /* Read decoding parameters */ - for (; (pStream->readBits / 8) < pStream->streamLength; pStream->readBits++) { - appBits += 8; /* Look for marker prefix byte from stream */ - if (jpegd_get_byte(pStream) == 0xFF) { - appBits += 8; - - currentByte = jpegd_get_byte(pStream); - switch (currentByte) { /* switch to certain header decoding */ - case SOF0: /* baseline marker */ - case SOF2: { /* progresive marker */ - if (currentByte == SOF0) - pImageInfo->codingModeThumb = pSyntax->info.operationTypeThumb = JPEGDEC_BASELINE; - else - pImageInfo->codingModeThumb = pSyntax->info.operationTypeThumb = JPEGDEC_PROGRESSIVE; - - /* Frame header */ - i++; - - /* jump over Lf field */ - if (jpegd_flush_bits(pStream, 16) == STRM_ERROR) { - errorCode = 1; - break; - } - appBits += 16; - - /* Sample precision (only 8 bits/sample supported) */ - currentByte = jpegd_get_byte(pStream); - appBits += 8; - if (currentByte != 8) { - JPEGD_ERROR_LOG("Thumbnail Sample precision"); - return (JPEGDEC_UNSUPPORTED); - } - - /* Number of Lines */ - pImageInfo->outputHeightThumb = jpegd_get_two_bytes(pStream); - appBits += 16; - pImageInfo->displayHeightThumb = pImageInfo->outputHeightThumb; - if (pImageInfo->outputHeightThumb < 1) { - JPEGD_ERROR_LOG("pImageInfo->outputHeightThumb unsupported"); - return (JPEGDEC_UNSUPPORTED); - } - - /* round up to next multiple-of-16 */ - pImageInfo->outputHeightThumb += 0xf; - pImageInfo->outputHeightThumb &= ~(0xf); - - /* Number of Samples per Line */ - pImageInfo->outputWidthThumb = jpegd_get_two_bytes(pStream); - appBits += 16; - pImageInfo->displayWidthThumb = pImageInfo->outputWidthThumb; - if (pImageInfo->outputWidthThumb < 1) { - JPEGD_ERROR_LOG("pImageInfo->outputWidthThumb unsupported"); - return (JPEGDEC_UNSUPPORTED); - } - - pImageInfo->outputWidthThumb += 0xf; - pImageInfo->outputWidthThumb &= ~(0xf); - if (pImageInfo->outputWidthThumb < pCtx->minSupportedWidth || - pImageInfo->outputHeightThumb < pCtx->minSupportedHeight || - pImageInfo->outputWidthThumb > JPEGDEC_MAX_WIDTH_TN || - pImageInfo->outputHeightThumb > JPEGDEC_MAX_HEIGHT_TN) { - JPEGD_ERROR_LOG("Thumbnail Unsupported size"); - return (JPEGDEC_UNSUPPORTED); - } - - /* Number of Image Components per Frame */ - Nf = jpegd_get_byte(pStream); - appBits += 8; - if (Nf != 3 && Nf != 1) { - JPEGD_ERROR_LOG("Thumbnail Number of Image Components per Frame"); - return (JPEGDEC_UNSUPPORTED); - } - for (j = 0; j < Nf; j++) { - /* jump over component identifier */ - if (jpegd_flush_bits(pStream, 8) == STRM_ERROR) { - errorCode = 1; - break; - } - appBits += 8; - - currentByte = jpegd_get_byte(pStream); - appBits += 8; - Htn[j] = (currentByte >> 4); /* Horizontal sampling factor */ - Vtn[j] = (currentByte & 0xF); /* Vertical sampling factor */ - - if (jpegd_flush_bits(pStream, 8) == STRM_ERROR) { /* jump over Tq */ - errorCode = 1; - break; - } - appBits += 8; - - if (Htn[j] > Hmax) - Hmax = Htn[j]; - if (Vtn[j] > Vmax) - Vmax = Vtn[j]; - } - if (Hmax == 0 || Vmax == 0) { - JPEGD_ERROR_LOG("Thumbnail Hmax == 0 || Vmax == 0"); - return (JPEGDEC_UNSUPPORTED); - } - - /* check format */ - if (Htn[0] == 2 && Vtn[0] == 2 && - Htn[1] == 1 && Vtn[1] == 1 && Htn[2] == 1 && Vtn[2] == 1) { - pImageInfo->outputFormatThumb = MPP_FMT_YUV420SP; - } else if (Htn[0] == 2 && Vtn[0] == 1 && - Htn[1] == 1 && Vtn[1] == 1 && Htn[2] == 1 && Vtn[2] == 1) { - pImageInfo->outputFormatThumb = MPP_FMT_YUV422SP; - } else if (Htn[0] == 1 && Vtn[0] == 2 && - Htn[1] == 1 && Vtn[1] == 1 && Htn[2] == 1 && Vtn[2] == 1) { - pImageInfo->outputFormatThumb = JPEGDEC_YCbCr440; - } else if (Htn[0] == 1 && Vtn[0] == 1 && - Htn[1] == 0 && Vtn[1] == 0 && Htn[2] == 0 && Vtn[2] == 0) { - pImageInfo->outputFormatThumb = JPEGDEC_YCbCr400; - } else if (Htn[0] == 4 && Vtn[0] == 1 && - Htn[1] == 1 && Vtn[1] == 1 && Htn[2] == 1 && Vtn[2] == 1) { - pImageInfo->outputFormatThumb = JPEGDEC_YCbCr411_SEMIPLANAR; - } else if (Htn[0] == 1 && Vtn[0] == 1 && - Htn[1] == 1 && Vtn[1] == 1 && Htn[2] == 1 && Vtn[2] == 1) { - pImageInfo->outputFormatThumb = JPEGDEC_YCbCr444_SEMIPLANAR; - } else { - JPEGD_ERROR_LOG("Thumbnail Unsupported YCbCr format"); - return (JPEGDEC_UNSUPPORTED); - } - pSyntax->info.initThumb = 1; - initThumb = 1; - break; - } - case SOS: { - /* SOS length */ - headerLength = jpegd_get_two_bytes(pStream); - if (headerLength == STRM_ERROR || - ((pStream->readBits + ((headerLength * 8) - 16)) > (8 * pStream->streamLength))) { - errorCode = 1; - break; - } - - /* check if interleaved or non-ibnterleaved */ - NsThumb = jpegd_get_byte(pStream); - if (NsThumb == MIN_NUMBER_OF_COMPONENTS && - pImageInfo->outputFormatThumb != JPEGDEC_YCbCr400 && - pImageInfo->codingModeThumb == JPEGDEC_BASELINE) { - pImageInfo->codingModeThumb = pSyntax->info.operationTypeThumb = JPEGDEC_NONINTERLEAVED; - } - - /* jump over SOS header */ - if (headerLength != 0) { - pStream->readBits += ((headerLength * 8) - 16); - pStream->pCurrPos += (((headerLength * 8) - 16) / 8); - } - - if ((pStream->readBits + 8) < (8 * pStream->streamLength)) { - pSyntax->info.init = 1; - init = 1; - } else { - JPEGD_ERROR_LOG("Needs to increase input buffer"); - return (JPEGDEC_INCREASE_INPUT_BUFFER); - } - break; - } - case DQT: { - /* DQT length */ - headerLength = jpegd_get_two_bytes(pStream); - if (headerLength == STRM_ERROR) { - errorCode = 1; - break; - } - /* jump over DQT header */ - if (headerLength != 0) { - pStream->readBits += ((headerLength * 8) - 16); - pStream->pCurrPos += (((headerLength * 8) - 16) / 8); - } - appBits += (headerLength * 8); - break; - } - case DHT: { - /* DHT length */ - headerLength = jpegd_get_two_bytes(pStream); - if (headerLength == STRM_ERROR) { - errorCode = 1; - break; - } - /* jump over DHT header */ - if (headerLength != 0) { - pStream->readBits += ((headerLength * 8) - 16); - pStream->pCurrPos += (((headerLength * 8) - 16) / 8); - } - appBits += (headerLength * 8); - break; - } - case DRI: { - /* DRI length */ - headerLength = jpegd_get_two_bytes(pStream); - if (headerLength == STRM_ERROR) { - errorCode = 1; - break; - } - /* jump over DRI header */ - if (headerLength != 0) { - pStream->readBits += ((headerLength * 8) - 16); - pStream->pCurrPos += (((headerLength * 8) - 16) / 8); - } - appBits += (headerLength * 8); - break; - } - case APP0: - case APP1: - case APP2: - case APP3: - case APP4: - case APP5: - case APP6: - case APP7: - case APP8: - case APP9: - case APP10: - case APP11: - case APP12: - case APP13: - case APP14: - case APP15: { - /* APPn length */ - headerLength = jpegd_get_two_bytes(pStream); - if (headerLength == STRM_ERROR) { - errorCode = 1; - break; - } - /* jump over APPn header */ - if (headerLength != 0) { - pStream->readBits += ((headerLength * 8) - 16); - pStream->pCurrPos += (((headerLength * 8) - 16) / 8); - } - appBits += (headerLength * 8); - break; - } - case DNL: { - /* DNL length */ - headerLength = jpegd_get_two_bytes(pStream); - if (headerLength == STRM_ERROR) { - errorCode = 1; - break; - } - /* jump over DNL header */ - if (headerLength != 0) { - pStream->readBits += ((headerLength * 8) - 16); - pStream->pCurrPos += (((headerLength * 8) - 16) / 8); - } - appBits += (headerLength * 8); - break; - } - case COM: { - /* COM length */ - headerLength = jpegd_get_two_bytes(pStream); - if (headerLength == STRM_ERROR) { - errorCode = 1; - break; - } - /* jump over COM header */ - if (headerLength != 0) { - pStream->readBits += ((headerLength * 8) - 16); - pStream->pCurrPos += (((headerLength * 8) - 16) / 8); - } - appBits += (headerLength * 8); - break; - } - case SOF1: /* unsupported coding styles */ - case SOF3: - case SOF5: - case SOF6: - case SOF7: - case SOF9: - case SOF10: - case SOF11: - case SOF13: - case SOF14: - case SOF15: - case DAC: - case DHP: { - JPEGD_ERROR_LOG("Unsupported coding styles"); - return (JPEGDEC_UNSUPPORTED); - } - default: - break; - } - - if (pSyntax->info.initThumb && initThumb) { - /* flush the rest of thumbnail data */ - if (jpegd_flush_bits(pStream, ((appLength * 8) - appBits)) == STRM_ERROR) { - errorCode = 1; - break; - } - pStream->appnFlag = 0; - break; - } - } else { - if (!pSyntax->info.initThumb && pCtx->bufferSize) - return (JPEGDEC_INCREASE_INPUT_BUFFER); - else - return (JPEGDEC_STRM_ERROR); - } - } - break; - } else { - appBits += 8; - pImageInfo->thumbnailType = JPEGDEC_THUMBNAIL_NOT_SUPPORTED_FORMAT; - pStream->appnFlag = 1; - if (jpegd_flush_bits(pStream, ((appLength * 8) - appBits)) == STRM_ERROR) { - errorCode = 1; - break; - } - pStream->appnFlag = 0; - break; - } - } else { - /* version */ - pImageInfo->version = jpegd_get_two_bytes(pStream); - JPEGD_VERBOSE_LOG("APP0, version:%x", pImageInfo->version); - appBits += 16; - - /* units */ - currentByte = jpegd_get_byte(pStream); - if (currentByte == 0) { - pImageInfo->units = JPEGDEC_NO_UNITS; - } else if (currentByte == 1) { - pImageInfo->units = JPEGDEC_DOTS_PER_INCH; - } else if (currentByte == 2) { - pImageInfo->units = JPEGDEC_DOTS_PER_CM; - } - appBits += 8; - - /* Xdensity */ - pImageInfo->xDensity = jpegd_get_two_bytes(pStream); - appBits += 16; - - /* Ydensity */ - pImageInfo->yDensity = jpegd_get_two_bytes(pStream); - appBits += 16; - - /* jump over rest of header data */ - pStream->appnFlag = 1; - if (jpegd_flush_bits(pStream, ((appLength * 8) - appBits)) == STRM_ERROR) { - errorCode = 1; - break; - } - pStream->appnFlag = 0; - break; - } - } - case APP1: - case APP2: - case APP3: - case APP4: - case APP5: - case APP6: - case APP7: - case APP8: - case APP9: - case APP10: - case APP11: - case APP12: - case APP13: - case APP14: - case APP15: { - JPEGD_VERBOSE_LOG("APPn, currentByte:0x%x", currentByte); - /* APPn length */ - headerLength = jpegd_get_two_bytes(pStream); - JPEGD_VERBOSE_LOG("APPn length, headerLength:%x", headerLength); - if (headerLength == STRM_ERROR || - ((pStream->readBits + ((headerLength * 8) - 16)) > (8 * pStream->streamLength))) { - JPEGD_ERROR_LOG("readBits:%d, headerLength:%d, streamLength:%d", pStream->readBits, headerLength, pStream->streamLength); - errorCode = 1; - break; - } - /* jump over APPn header */ - if (headerLength != 0) { - pStream->readBits += ((headerLength * 8) - 16); - pStream->pCurrPos += (((headerLength * 8) - 16) / 8); - } - break; - } - case DNL: { - JPEGD_VERBOSE_LOG("DNL, currentByte:0x%x", currentByte); - /* DNL length */ - headerLength = jpegd_get_two_bytes(pStream); - JPEGD_VERBOSE_LOG("DNL, headerLength:%x", headerLength); - if (headerLength == STRM_ERROR || - ((pStream->readBits + ((headerLength * 8) - 16)) > (8 * pStream->streamLength))) { - JPEGD_ERROR_LOG("readBits:%d, headerLength:%d, streamLength:%d", pStream->readBits, headerLength, pStream->streamLength); - errorCode = 1; - break; - } - /* jump over DNL header */ - if (headerLength != 0) { - pStream->readBits += ((headerLength * 8) - 16); - pStream->pCurrPos += (((headerLength * 8) - 16) / 8); - } - break; - } - case COM: { - JPEGD_VERBOSE_LOG("COM, currentByte:0x%x", currentByte); - headerLength = jpegd_get_two_bytes(pStream); - JPEGD_VERBOSE_LOG("COM, headerLength:%x", headerLength); - if (headerLength == STRM_ERROR || - ((pStream->readBits + ((headerLength * 8) - 16)) > (8 * pStream->streamLength))) { - JPEGD_ERROR_LOG("readBits:%d, headerLength:%d, streamLength:%d", pStream->readBits, headerLength, pStream->streamLength); - errorCode = 1; - break; - } - /* jump over COM header */ - if (headerLength != 0) { - pStream->readBits += ((headerLength * 8) - 16); - pStream->pCurrPos += (((headerLength * 8) - 16) / 8); - } - break; - } - case SOF1: /* unsupported coding styles */ - case SOF3: - case SOF5: - case SOF6: - case SOF7: - case SOF9: - case SOF10: - case SOF11: - case SOF13: - case SOF14: - case SOF15: - case DAC: - case DHP: { - JPEGD_ERROR_LOG("SOF, currentByte:0x%x", currentByte); - JPEGD_ERROR_LOG("Unsupported coding styles"); - return (JPEGDEC_UNSUPPORTED); - } - default: - break; - } - if (pSyntax->info.init && init) - break; - - if (errorCode) { - if (pCtx->bufferSize) { - JPEGD_ERROR_LOG("get image info failed!"); - return (JPEGDEC_INCREASE_INPUT_BUFFER); - } else { - JPEGD_ERROR_LOG("Stream error"); - return (JPEGDEC_STRM_ERROR); - } - } - } else { - JPEGD_ERROR_LOG("Could not get marker"); - if (!pSyntax->info.init) - return (JPEGDEC_INCREASE_INPUT_BUFFER); - else - return (JPEGDEC_STRM_ERROR); - } - } - - FUN_TEST("Exit"); - return MPP_OK; -} - -MPP_RET jpegd_get_image_info(JpegParserContext *ctx) -{ - FUN_TEST("Enter"); - JpegParserContext *pCtx = ctx; - if (NULL == pCtx) { - JPEGD_ERROR_LOG("NULL pointer"); - return MPP_ERR_NULL_PTR; - } - - MPP_RET ret = MPP_OK; - JpegSyntaxParam *pSyntax = pCtx->pSyntax; - StreamStorage stream; - - if (pCtx->streamLength < 1) { - JPEGD_ERROR_LOG("streamLength:%d", pCtx->streamLength); - return MPP_ERR_VALUE; - } - - if ((pCtx->streamLength > DEC_MAX_STREAM) && - (pCtx->bufferSize < JPEGDEC_MIN_BUFFER || pCtx->bufferSize > JPEGDEC_MAX_BUFFER)) { - JPEGD_ERROR_LOG("bufferSize = %d,streamLength = %d\n", pCtx->bufferSize, pCtx->streamLength); - return MPP_ERR_VALUE; - } - - if (pCtx->bufferSize && (pCtx->bufferSize < JPEGDEC_MIN_BUFFER || - pCtx->bufferSize > JPEGDEC_MAX_BUFFER)) { - JPEGD_ERROR_LOG("bufferSize = %d\n", pCtx->bufferSize); - return MPP_ERR_VALUE; - } - - pSyntax->imageInfo.thumbnailType = JPEGDEC_NO_THUMBNAIL; - - /* utils initialization */ - stream.bitPosInByte = 0; - stream.pCurrPos = (RK_U8 *)mpp_packet_get_data(pCtx->input_packet); - stream.pStartOfStream = (RK_U8 *)mpp_packet_get_data(pCtx->input_packet); - stream.streamLength = (RK_U32)mpp_packet_get_size(pCtx->input_packet); - stream.readBits = 0; - stream.appnFlag = 0; - - ret = jpegd_read_decode_parameters(pCtx, &stream); - if (ret != MPP_OK) { - JPEGD_ERROR_LOG("read decode parameters failed, ret:%d", ret); - return ret; - } - - FUN_TEST("Exit"); - return ret; -} - -MPP_RET jpegd_decode_frame_impl(JpegParserContext *ctx) -{ - FUN_TEST("Enter"); - JpegParserContext *pCtx = ctx; - if (NULL == pCtx) { - JPEGD_ERROR_LOG("NULL pointer"); - return MPP_ERR_NULL_PTR; - } - - RK_U32 i = 0; - RK_U32 currentByte = 0; - RK_U32 currentBytes = 0; - RK_U32 appLength = 0; - RK_U32 appBits = 0; - JpegDecRet retCode; - RK_U32 findhufftable = 0; - - JpegSyntaxParam *pSyntax = pCtx->pSyntax; - StreamStorage *pStream = (StreamStorage *) & (pSyntax->stream); - - do { - /* if slice mode/slice done return to hw handling */ - if (pSyntax->image.headerReady && pSyntax->info.SliceReadyForPause) - break; - - /* Look for marker prefix byte from stream */ - if ((currentByte == 0xFF) || (jpegd_get_byte(pStream) == 0xFF)) { - currentByte = jpegd_get_byte(pStream); - - /* switch to certain header decoding */ - switch (currentByte) { - case 0x00: { - JPEGD_VERBOSE_LOG("currentByte:0x00"); - break; - } - case SOF0: - case SOF2: { - JPEGD_VERBOSE_LOG("SOF, currentByte:0x%x", currentByte); - /* Baseline/Progressive */ - pSyntax->frame.codingType = currentByte; - /* Set operation type */ - if (pSyntax->frame.codingType == SOF0) - pSyntax->info.operationType = JPEGDEC_BASELINE; - else - pSyntax->info.operationType = JPEGDEC_PROGRESSIVE; - - retCode = jpegd_decode_frame_header(pCtx); - if (retCode != JPEGDEC_OK) { - if (retCode == JPEGDEC_STRM_ERROR) { - JPEGD_ERROR_LOG("Stream Error"); - return (retCode); - } else { - JPEGD_ERROR_LOG("Decode Frame Header Error"); - return (retCode); - } - } - break; - } - case SOS: { /* Start of Scan */ - JPEGD_VERBOSE_LOG("SOS, currentByte:0x%x", currentByte); - /* reset image ready */ - pSyntax->image.imageReady = 0; - retCode = jpegd_decode_scan(pCtx); - pSyntax->image.headerReady = 1; - if (retCode != JPEGDEC_OK) { - if (retCode == JPEGDEC_STRM_ERROR) { - JPEGD_ERROR_LOG("Stream Error"); - return (retCode); - } else { - JPEGD_ERROR_LOG("Decode Scan Error\n"); - return (retCode); - } - } - - if (pSyntax->stream.bitPosInByte) { - /* delete stuffing bits */ - currentByte = (8 - pSyntax->stream.bitPosInByte); - if (jpegd_flush_bits(pStream, 8 - pSyntax->stream.bitPosInByte) == STRM_ERROR) { - JPEGD_ERROR_LOG("Stream Error"); - return (JPEGDEC_STRM_ERROR); - } - } - JPEGD_VERBOSE_LOG("Stuffing bits deleted\n"); - break; - } - case DHT: { /* Start of Huffman tables */ - JPEGD_VERBOSE_LOG("DHT, currentByte:0x%x", currentByte); - retCode = jpegd_decode_huffman_tables(pCtx); - if (retCode != JPEGDEC_OK) { - if (retCode == JPEGDEC_STRM_ERROR) { - JPEGD_ERROR_LOG("Stream Error"); - return (retCode); - } else { - JPEGD_ERROR_LOG("Decode Huffman Tables Error"); - return (retCode); - } - } - findhufftable = 1; - break; - } - case DQT: { /* start of Quantisation Tables */ - JPEGD_VERBOSE_LOG("DQT, currentByte:0x%x", currentByte); - retCode = jpegd_decode_quant_tables(pCtx); - if (retCode != JPEGDEC_OK) { - if (retCode == JPEGDEC_STRM_ERROR) { - JPEGD_ERROR_LOG("Stream Error"); - return (retCode); - } else { - JPEGD_ERROR_LOG("Decode Quant Tables Error"); - return (retCode); - } - } - break; - } - case SOI: { /* Start of Image */ - /* no actions needed, continue */ - break; - } - case EOI: { /* End of Image */ - JPEGD_VERBOSE_LOG("EOI, currentByte:0x%x", currentByte); - if (pSyntax->image.imageReady) { - JPEGD_ERROR_LOG("EOI: OK\n"); - return (JPEGDEC_FRAME_READY); - } else { - JPEGD_ERROR_LOG("EOI: NOK\n"); - return (JPEGDEC_ERROR); - } - } - case DRI: { /* Define Restart Interval */ - JPEGD_VERBOSE_LOG("DRI, currentByte:0x%x", currentByte); - currentBytes = jpegd_get_two_bytes(pStream); - if (currentBytes == STRM_ERROR) { - JPEGD_ERROR_LOG("Read bits "); - return (JPEGDEC_STRM_ERROR); - } - pSyntax->frame.Ri = jpegd_get_two_bytes(pStream); - break; - } - case RST0: /* Restart with modulo 8 count m */ - case RST1: - case RST2: - case RST3: - case RST4: - case RST5: - case RST6: - case RST7: { - JPEGD_VERBOSE_LOG("RST, currentByte:0x%x", currentByte); - /* initialisation of DC predictors to zero value !!! */ - for (i = 0; i < MAX_NUMBER_OF_COMPONENTS; i++) { - pSyntax->scan.pred[i] = 0; - } - break; - } - case DNL: /* unsupported features */ - case SOF1: - case SOF3: - case SOF5: - case SOF6: - case SOF7: - case SOF9: - case SOF10: - case SOF11: - case SOF13: - case SOF14: - case SOF15: - case DAC: - case DHP: - case TEM: { - JPEGD_ERROR_LOG("Unsupported Features, currentByte:0x%x", currentByte); - return (JPEGDEC_UNSUPPORTED); - } - case APP0: { /* application data & comments */ - JPEGD_VERBOSE_LOG("APP0, currentByte:0x%x", currentByte); - /* APP0 Extended Thumbnail */ - if (pCtx->decImageType == JPEGDEC_THUMBNAIL) { - /* reset */ - appBits = 0; - appLength = 0; - - /* length */ - appLength = jpegd_get_two_bytes(pStream); - appBits += 16; - - /* check identifier */ - currentBytes = jpegd_get_two_bytes(pStream); - appBits += 16; - if (currentBytes != 0x4A46) { - pSyntax->stream.appnFlag = 1; - if (jpegd_flush_bits(pStream, ((appLength * 8) - appBits)) == STRM_ERROR) { - JPEGD_ERROR_LOG("Stream Error"); - return (JPEGDEC_STRM_ERROR); - } - pSyntax->stream.appnFlag = 0; - break; - } - - currentBytes = jpegd_get_two_bytes(pStream); - appBits += 16; - if (currentBytes != 0x5858) { - pSyntax->stream.appnFlag = 1; - if (jpegd_flush_bits(pStream, ((appLength * 8) - appBits)) == STRM_ERROR) { - JPEGD_ERROR_LOG("Stream Error"); - return (JPEGDEC_STRM_ERROR); - } - pSyntax->stream.appnFlag = 0; - break; - } - - currentByte = jpegd_get_byte(pStream); - appBits += 8; - if (currentByte != 0x00) { - pSyntax->stream.appnFlag = 1; - if (jpegd_flush_bits(pStream, ((appLength * 8) - appBits)) == STRM_ERROR) { - JPEGD_ERROR_LOG("Stream Error"); - return (JPEGDEC_STRM_ERROR); - } - pSyntax->stream.appnFlag = 0; - break; - } - - /* extension code */ - currentByte = jpegd_get_byte(pStream); - pSyntax->stream.appnFlag = 0; - if (currentByte != JPEGDEC_THUMBNAIL_JPEG) { - JPEGD_ERROR_LOG("thumbnail unsupported"); - return (JPEGDEC_UNSUPPORTED); - } - - /* thumbnail mode */ - JPEGD_VERBOSE_LOG("Thumbnail data ok!"); - pSyntax->stream.thumbnail = 1; - break; - } else { - /* Flush unsupported thumbnail */ - currentBytes = jpegd_get_two_bytes(pStream); - pSyntax->stream.appnFlag = 1; - if (jpegd_flush_bits(pStream, ((currentBytes - 2) * 8)) == STRM_ERROR) { - JPEGD_ERROR_LOG("Stream Error"); - return (JPEGDEC_STRM_ERROR); - } - pSyntax->stream.appnFlag = 0; - break; - } - } - case APP1: - case APP2: - case APP3: - case APP4: - case APP5: - case APP6: - case APP7: - case APP8: - case APP9: - case APP10: - case APP11: - case APP12: - case APP13: - case APP14: - case APP15: - case COM: { - JPEGD_VERBOSE_LOG("APPn, currentByte:0x%x", currentByte); - currentBytes = jpegd_get_two_bytes(pStream); - if (currentBytes == STRM_ERROR) { - JPEGD_ERROR_LOG("Read bits "); - return (JPEGDEC_STRM_ERROR); - } - /* jump over not supported header */ - if (currentBytes != 0) { - pSyntax->stream.readBits += ((currentBytes * 8) - 16); - pSyntax->stream.pCurrPos += (((currentBytes * 8) - 16) / 8); - } - break; - } - default: - break; - } - } else { - if (currentByte == 0xFFFFFFFF) { - break; - } - } - - if (pSyntax->image.headerReady) - break; - } while ((pSyntax->stream.readBits >> 3) <= pSyntax->stream.streamLength); - - if (!findhufftable) { - JPEGD_VERBOSE_LOG("do not find Huffman Tables"); - jpegd_default_huffman_tables(pCtx); - } - - return MPP_OK; - FUN_TEST("Exit"); -} - -MPP_RET jpegd_allocate_frame(JpegParserContext *ctx) -{ - FUN_TEST("Enter"); - JpegParserContext *pCtx = ctx; - if (NULL == pCtx) { - JPEGD_ERROR_LOG("NULL pointer"); - return MPP_ERR_NULL_PTR; - } - - if (pCtx->frame_slot_index == -1) { - mpp_frame_set_width(pCtx->output_frame, pCtx->pSyntax->frame.X); - mpp_frame_set_height(pCtx->output_frame, pCtx->pSyntax->frame.Y); - mpp_frame_set_hor_stride(pCtx->output_frame, pCtx->pSyntax->frame.X); - mpp_frame_set_ver_stride(pCtx->output_frame, pCtx->pSyntax->frame.Y); - mpp_frame_set_pts(pCtx->output_frame, pCtx->pts); - - mpp_buf_slot_get_unused(pCtx->frame_slots, &pCtx->frame_slot_index); - JPEGD_INFO_LOG("frame_slot_index:%d, X:%d, Y:%d", pCtx->frame_slot_index, pCtx->pSyntax->frame.X, pCtx->pSyntax->frame.Y); - - mpp_buf_slot_set_prop(pCtx->frame_slots, pCtx->frame_slot_index, SLOT_FRAME, pCtx->output_frame); - mpp_buf_slot_set_flag(pCtx->frame_slots, pCtx->frame_slot_index, SLOT_CODEC_USE); - mpp_buf_slot_set_flag(pCtx->frame_slots, pCtx->frame_slot_index, SLOT_HAL_OUTPUT); - } - - FUN_TEST("Exit"); - return MPP_OK; -} - -MPP_RET jpegd_update_frame(JpegParserContext *ctx) -{ - FUN_TEST("Enter"); - JpegParserContext *pCtx = ctx; - if (NULL == pCtx) { - JPEGD_ERROR_LOG("NULL pointer"); - return MPP_ERR_NULL_PTR; - } - - mpp_buf_slot_set_flag(pCtx->frame_slots, pCtx->frame_slot_index, SLOT_QUEUE_USE); - mpp_buf_slot_enqueue(pCtx->frame_slots, pCtx->frame_slot_index, QUEUE_DISPLAY); - mpp_buf_slot_clr_flag(pCtx->frame_slots, pCtx->frame_slot_index, SLOT_CODEC_USE); - pCtx->frame_slot_index = -1; - - FUN_TEST("Exit"); - return MPP_OK; -} - -MPP_RET jpegd_decode_frame(JpegParserContext *ctx) -{ - FUN_TEST("Enter"); - MPP_RET ret = MPP_OK; - JpegParserContext *pCtx = ctx; - if (NULL == pCtx) { - JPEGD_ERROR_LOG("NULL pointer"); - return MPP_ERR_NULL_PTR; - } - - JpegSyntaxParam *pSyntax = pCtx->pSyntax; - - /* Store the stream parameters */ - if (pSyntax->info.progressiveScanReady == 0 && - pSyntax->info.nonInterleavedScanReady == 0) { - pSyntax->stream.bitPosInByte = 0; - pSyntax->stream.pCurrPos = (RK_U8 *) mpp_packet_get_data(pCtx->input_packet); - pSyntax->stream.pStartOfStream = (RK_U8 *)mpp_packet_get_data(pCtx->input_packet); - pSyntax->stream.readBits = 0; - pSyntax->stream.streamLength = (RK_U32)mpp_packet_get_size(pCtx->input_packet); - pSyntax->stream.appnFlag = 0; - } else { - pSyntax->image.headerReady = 0; - } - - if (pSyntax->info.operationType == JPEGDEC_PROGRESSIVE) { - JPEGD_ERROR_LOG ("Operation type not supported"); - return (JPEGDEC_UNSUPPORTED); - } - - /* check if frame size over 16M */ - if ((pSyntax->frame.hwX * pSyntax->frame.hwY) > JPEGDEC_MAX_PIXEL_AMOUNT) { - JPEGD_ERROR_LOG ("Resolution > 16M ==> use slice mode!"); - return (JPEGDEC_PARAM_ERROR); - } - - /* check if input streaming used */ - if (!pSyntax->info.SliceReadyForPause && - !pSyntax->info.inputBufferEmpty && pCtx->bufferSize) { - pSyntax->info.inputStreaming = 1; - pSyntax->info.inputBufferLen = pCtx->bufferSize; - pSyntax->info.decodedStreamLen += pSyntax->info.inputBufferLen; - } - - ret = jpegd_decode_frame_impl(pCtx); - - FUN_TEST("Exit"); - return ret; -} - -void jpegd_free_huffman_tables(void *ctx) -{ - FUN_TEST("Enter"); - JpegParserContext *JpegParserCtx = (JpegParserContext *)ctx; - - if (JpegParserCtx->pSyntax->vlc.acTable0.vals) { - mpp_free(JpegParserCtx->pSyntax->vlc.acTable0.vals); - JpegParserCtx->pSyntax->vlc.acTable0.vals = NULL; - } - - if (JpegParserCtx->pSyntax->vlc.acTable1.vals) { - mpp_free(JpegParserCtx->pSyntax->vlc.acTable1.vals); - JpegParserCtx->pSyntax->vlc.acTable1.vals = NULL; - } - - if (JpegParserCtx->pSyntax->vlc.acTable2.vals) { - mpp_free(JpegParserCtx->pSyntax->vlc.acTable2.vals); - JpegParserCtx->pSyntax->vlc.acTable2.vals = NULL; - } - - if (JpegParserCtx->pSyntax->vlc.acTable3.vals) { - mpp_free(JpegParserCtx->pSyntax->vlc.acTable3.vals); - JpegParserCtx->pSyntax->vlc.acTable3.vals = NULL; - } - - if (JpegParserCtx->pSyntax->vlc.dcTable0.vals) { - mpp_free(JpegParserCtx->pSyntax->vlc.dcTable0.vals); - JpegParserCtx->pSyntax->vlc.dcTable0.vals = NULL; - } - - if (JpegParserCtx->pSyntax->vlc.dcTable1.vals) { - mpp_free(JpegParserCtx->pSyntax->vlc.dcTable1.vals); - JpegParserCtx->pSyntax->vlc.dcTable1.vals = NULL; - } - - if (JpegParserCtx->pSyntax->vlc.dcTable2.vals) { - mpp_free(JpegParserCtx->pSyntax->vlc.dcTable2.vals); - JpegParserCtx->pSyntax->vlc.dcTable2.vals = NULL; - } - - if (JpegParserCtx->pSyntax->vlc.dcTable3.vals) { - mpp_free(JpegParserCtx->pSyntax->vlc.dcTable3.vals); - JpegParserCtx->pSyntax->vlc.dcTable3.vals = NULL; - } - - FUN_TEST("Exit"); -} - - -MPP_RET jpegd_parse(void *ctx, HalDecTask *task) -{ - FUN_TEST("Enter"); - MPP_RET ret = MPP_OK; - JpegParserContext *JpegParserCtx = (JpegParserContext *)ctx; - task->valid = 0; - - jpegd_free_huffman_tables(JpegParserCtx); - memset(JpegParserCtx->pSyntax, 0, sizeof(JpegSyntaxParam)); - jpegd_get_image_info(JpegParserCtx); - ret = jpegd_decode_frame(JpegParserCtx); - - if (MPP_OK == ret) { - jpegd_allocate_frame(JpegParserCtx); - task->syntax.data = (void *)JpegParserCtx->pSyntax; - task->syntax.number = sizeof(JpegSyntaxParam); - task->output = JpegParserCtx->frame_slot_index; - task->valid = 1; - jpegd_update_frame(JpegParserCtx); - } - - //mpp_show_mem_status(); - - FUN_TEST("Exit"); - return ret; -} - -MPP_RET jpegd_deinit(void *ctx) -{ - FUN_TEST("Enter"); - JpegParserContext *JpegParserCtx = (JpegParserContext *)ctx; - - if (JpegParserCtx->recv_buffer) { - mpp_free(JpegParserCtx->recv_buffer); - JpegParserCtx->recv_buffer = NULL; - } - - jpegd_free_huffman_tables(JpegParserCtx); - - if (JpegParserCtx->pSyntax) { - mpp_free(JpegParserCtx->pSyntax); - JpegParserCtx->pSyntax = NULL; - } - - if (JpegParserCtx->output_frame) { - mpp_free(JpegParserCtx->output_frame); - } - - if (JpegParserCtx->input_packet) { - mpp_packet_deinit(&JpegParserCtx->input_packet); - } - - JpegParserCtx->output_fmt = MPP_FMT_YUV420SP; - JpegParserCtx->pts = 0; - JpegParserCtx->eos = 0; - JpegParserCtx->parser_debug_enable = 0; - JpegParserCtx->input_jpeg_count = 0; - - FUN_TEST("Exit"); - return 0; -} - -MPP_RET reset_jpeg_parser_context(JpegParserContext *ctx) -{ - FUN_TEST("Enter"); - JpegParserContext *pCtx = ctx; - if (NULL == pCtx) { - JPEGD_ERROR_LOG("NULL pointer"); - return MPP_ERR_NULL_PTR; - } - - pCtx->packet_slots = NULL; - pCtx->frame_slots = NULL; - pCtx->recv_buffer = NULL; - - /* resolution */ - pCtx->minSupportedWidth = 0; - pCtx->minSupportedHeight = 0; - pCtx->maxSupportedWidth = 0; - pCtx->maxSupportedHeight = 0; - pCtx->maxSupportedPixelAmount = 0; - pCtx->maxSupportedSliceSize = 0; - - FUN_TEST("Exit"); - return MPP_OK; -} - -MPP_RET jpegd_init(void *ctx, ParserCfg *parser_cfg) -{ - FUN_TEST("Enter"); - JpegParserContext *JpegParserCtx = (JpegParserContext *)ctx; - if (NULL == JpegParserCtx) { - JpegParserCtx = (JpegParserContext *)mpp_calloc(JpegParserContext, 1); - if (NULL == JpegParserCtx) { - JPEGD_ERROR_LOG("NULL pointer"); - return MPP_ERR_NULL_PTR; - } - } - mpp_env_get_u32("jpegd_log", &jpegd_log, JPEGD_ERR_LOG); - - reset_jpeg_parser_context(JpegParserCtx); - JpegParserCtx->frame_slots = parser_cfg->frame_slots; - JpegParserCtx->packet_slots = parser_cfg->packet_slots; - JpegParserCtx->frame_slot_index = -1; - mpp_buf_slot_setup(JpegParserCtx->frame_slots, 16); - - JpegParserCtx->recv_buffer = mpp_calloc(RK_U8, JPEGD_STREAM_BUFF_SIZE); - if (NULL == JpegParserCtx->recv_buffer) { - JPEGD_ERROR_LOG("no memory!"); - return MPP_ERR_NOMEM; - } - JpegParserCtx->bufferSize = JPEGD_STREAM_BUFF_SIZE; - mpp_packet_init(&JpegParserCtx->input_packet, JpegParserCtx->recv_buffer, JPEGD_STREAM_BUFF_SIZE); - - mpp_frame_init(&JpegParserCtx->output_frame); - if (!JpegParserCtx->output_frame) { - JPEGD_ERROR_LOG("Failed to allocate output frame buffer"); - return MPP_ERR_NOMEM; - } - - JpegParserCtx->pSyntax = mpp_calloc(JpegSyntaxParam, 1); - if (NULL == JpegParserCtx->pSyntax) { - JPEGD_ERROR_LOG("NULL pointer"); - return MPP_ERR_NULL_PTR; - } - - memset(JpegParserCtx->pSyntax, 0, sizeof(JpegSyntaxParam)); - JpegParserCtx->pSyntax->ppInstance = (void *)0; /* will be changed when need pp */ - - JpegParserCtx->decImageType = JPEGDEC_IMAGE; /* FULL MODEs */ - JpegParserCtx->output_fmt = MPP_FMT_YUV420SP; - - /* max */ - JpegParserCtx->maxSupportedWidth = JPEGDEC_MAX_WIDTH_8190; - JpegParserCtx->maxSupportedHeight = JPEGDEC_MAX_HEIGHT_8190; - JpegParserCtx->maxSupportedPixelAmount = JPEGDEC_MAX_PIXEL_AMOUNT_8190; - JpegParserCtx->maxSupportedSliceSize = JPEGDEC_MAX_SLICE_SIZE_8190; - - /* min */ - JpegParserCtx->minSupportedWidth = JPEGDEC_MIN_WIDTH; - JpegParserCtx->minSupportedHeight = JPEGDEC_MIN_HEIGHT; - - JpegParserCtx->extensionsSupported = 1; - - JpegParserCtx->pts = 0; - JpegParserCtx->eos = 0; - JpegParserCtx->parser_debug_enable = 0; - JpegParserCtx->input_jpeg_count = 0; - - FUN_TEST("Exit"); - return MPP_OK; -} - -MPP_RET jpegd_flush(void *ctx) -{ - FUN_TEST("Enter"); - JpegParserContext *JpegParserCtx = (JpegParserContext *)ctx; - (void)JpegParserCtx; - FUN_TEST("Exit"); - return MPP_OK; -} - -MPP_RET jpegd_reset(void *ctx) -{ - FUN_TEST("Enter"); - JpegParserContext *JpegParserCtx = (JpegParserContext *)ctx; - - (void)JpegParserCtx; - - FUN_TEST("Exit"); - return MPP_OK; -} - -MPP_RET jpegd_control(void *ctx, RK_S32 cmd, void *param) -{ - FUN_TEST("Enter"); - MPP_RET ret = MPP_OK; - JpegParserContext *JpegParserCtx = (JpegParserContext *)ctx; - if (NULL == JpegParserCtx) { - JPEGD_ERROR_LOG("NULL pointer"); - return MPP_ERR_NULL_PTR; - } - - switch (cmd) { - case MPP_DEC_SET_OUTPUT_FORMAT: { - JpegParserCtx->output_fmt = *((RK_U32 *)param); - JPEGD_INFO_LOG("output_format:%d\n", JpegParserCtx->output_fmt); - } break; - default : - ret = MPP_NOK; - } - FUN_TEST("Exit"); - return ret; -} - -MPP_RET jpegd_callback(void *ctx, void *err_info) -{ - FUN_TEST("Enter"); - (void) ctx; - (void) err_info; - FUN_TEST("Exit"); - return MPP_OK; -} - -const ParserApi api_jpegd_parser = { - "jpegd_parse", - MPP_VIDEO_CodingMJPEG, - sizeof(JpegParserContext), - 0, - jpegd_init, - jpegd_deinit, - jpegd_prepare, - jpegd_parse, - jpegd_reset, - jpegd_flush, - jpegd_control, - jpegd_callback, -}; - - +/* + * + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define MODULE_TAG "jpegd_parser" + +#include "mpp_bitread.h" +#include "mpp_mem.h" +#include "mpp_env.h" +#include "mpp_packet_impl.h" + +#include "jpegd_api.h" +#include "jpegd_parser.h" + + +#define STRM_ERROR 0xFFFFFFFFU +RK_U32 jpegd_log = 0; + +/*------------------------------------------------------------------------------ + Function name: jpegd_get_byte + + Functional description: + Reads one byte (8 bits) from stream and returns the bits + + Note! This function does not skip the 0x00 byte if the previous + byte value was 0xFF!!! + + Inputs: + StreamStorage *pStream Pointer to structure + + Outputs: + Returns 8 bit value if ok + else returns STRM_ERROR (0xFFFFFFFF) +------------------------------------------------------------------------------*/ +RK_U32 jpegd_get_byte(StreamStorage * pStream) +{ + RK_U32 tmp; + + if ((pStream->readBits + 8) > (8 * pStream->streamLength)) + return (STRM_ERROR); + + tmp = *(pStream->pCurrPos)++; + tmp = (tmp << 8) | *(pStream->pCurrPos); + tmp = (tmp >> (8 - pStream->bitPosInByte)) & 0xFF; + pStream->readBits += 8; + return (tmp); +} + +/*------------------------------------------------------------------------------ + Function name: jpegd_get_two_bytes + + Functional description: + Reads two bytes (16 bits) from stream and returns the bits + + Note! This function does not skip the 0x00 byte if the previous + byte value was 0xFF!!! + + Inputs: + StreamStorage *pStream Pointer to structure + + Outputs: + Returns 16 bit value +------------------------------------------------------------------------------*/ +RK_U32 jpegd_get_two_bytes(StreamStorage * pStream) +{ + RK_U32 tmp; + + if ((pStream->readBits + 16) > (8 * pStream->streamLength)) + return (STRM_ERROR); + + tmp = *(pStream->pCurrPos)++; + tmp = (tmp << 8) | *(pStream->pCurrPos)++; + tmp = (tmp << 8) | *(pStream->pCurrPos); + tmp = (tmp >> (8 - pStream->bitPosInByte)) & 0xFFFF; + pStream->readBits += 16; + return (tmp); +} + +/*------------------------------------------------------------------------------ + Function name: jpegd_show_bits + + Functional description: + Reads 32 bits from stream and returns the bits, does not update + stream pointers. If there are not enough bits in data buffer it + reads the rest of the data buffer bits and fills the lsb of return + value with zero bits. + + Note! This function will skip the byte valued 0x00 if the previous + byte value was 0xFF!!! + + Inputs: + StreamStorage *pStream Pointer to structure + + Outputs: + Returns 32 bit value +------------------------------------------------------------------------------*/ +RK_U32 jpegd_show_bits(StreamStorage * pStream) +{ + RK_S32 bits; + RK_U32 readBits; + RK_U32 out = 0; + RK_U8 *pData = pStream->pCurrPos; + + /* bits left in buffer */ + bits = (RK_S32) (8 * pStream->streamLength - pStream->readBits); + if (!bits) + return (0); + + readBits = 0; + do { + if (pData > pStream->pStartOfStream) { + /* FF 00 bytes in stream -> jump over 00 byte */ + if ((pData[-1] == 0xFF) && (pData[0] == 0x00)) { + pData++; + bits -= 8; + } + } + if (readBits == 32 && pStream->bitPosInByte) { + out <<= pStream->bitPosInByte; + out |= *pData >> (8 - pStream->bitPosInByte); + readBits = 0; + break; + } + out = (out << 8) | *pData++; + readBits += 8; + bits -= 8; + } while (readBits < (32 + pStream->bitPosInByte) && bits > 0); + + if (bits <= 0 && + ((readBits + pStream->readBits) >= (pStream->streamLength * 8))) { + /* not enough bits in stream, fill with zeros */ + out = (out << (32 - (readBits - pStream->bitPosInByte))); + } + + return (out); +} + +/*------------------------------------------------------------------------------ + Function name: jpegd_flush_bits + + Functional description: + Updates stream pointers, flushes bits from stream + + Note! This function will skip the byte valued 0x00 if the previous + byte value was 0xFF!!! + + Inputs: + StreamStorage *pStream Pointer to structure + RK_U32 bits Number of bits to be flushed + + Outputs: + OK + STRM_ERROR +------------------------------------------------------------------------------*/ +RK_U32 jpegd_flush_bits(StreamStorage * pStream, RK_U32 bits) +{ + RK_U32 tmp; + RK_U32 extraBits = 0; + + if ((pStream->readBits + bits) > (8 * pStream->streamLength)) { + /* there are not so many bits left in buffer */ + /* stream pointers to the end of the stream */ + /* and return value STRM_ERROR */ + pStream->readBits = 8 * pStream->streamLength; + pStream->bitPosInByte = 0; + pStream->pCurrPos = pStream->pStartOfStream + pStream->streamLength; + return (STRM_ERROR); + } else { + tmp = 0; + while (tmp < bits) { + if (bits - tmp < 8) { + if ((8 - pStream->bitPosInByte) > (bits - tmp)) { + /* inside one byte */ + pStream->bitPosInByte += bits - tmp; + tmp = bits; + } else { + if (pStream->pCurrPos[0] == 0xFF && + pStream->pCurrPos[1] == 0x00) { + extraBits += 8; + pStream->pCurrPos += 2; + } else { + pStream->pCurrPos++; + } + tmp += 8 - pStream->bitPosInByte; + pStream->bitPosInByte = 0; + pStream->bitPosInByte = bits - tmp; + tmp = bits; + } + } else { + tmp += 8; + if (pStream->appnFlag) { + pStream->pCurrPos++; + } else { + if (pStream->pCurrPos[0] == 0xFF && + pStream->pCurrPos[1] == 0x00) { + extraBits += 8; + pStream->pCurrPos += 2; + } else { + pStream->pCurrPos++; + } + } + } + } + /* update stream pointers */ + pStream->readBits += bits + extraBits; + return (MPP_OK); + } +} + +JpegDecRet jpegd_set_yuv_mode(JpegSyntaxParam *pSyntax) +{ + /* check input format */ + if (pSyntax->frame.Nf == 3) { + if (pSyntax->frame.component[0].H == 2 && + pSyntax->frame.component[0].V == 2 && + pSyntax->frame.component[1].H == 1 && + pSyntax->frame.component[1].V == 1 && + pSyntax->frame.component[2].H == 1 && + pSyntax->frame.component[2].V == 1) { + JPEGD_INFO_LOG("YCbCr Format: YUV420(2*2:1*1:1*1)"); + pSyntax->info.yCbCrMode = JPEGDEC_YUV420; + pSyntax->info.X = pSyntax->frame.hwX; + pSyntax->info.Y = pSyntax->frame.hwY; + } else if (pSyntax->frame.component[0].H == 2 && pSyntax->frame.component[0].V == 1 && + pSyntax->frame.component[1].H == 1 && pSyntax->frame.component[1].V == 1 && + pSyntax->frame.component[2].H == 1 && pSyntax->frame.component[2].V == 1) { + JPEGD_INFO_LOG("YCbCr Format: YUV422(%d*%d:%d*%d:%d*%d)", + pSyntax->frame.component[0].H, pSyntax->frame.component[0].V, + pSyntax->frame.component[1].H, pSyntax->frame.component[1].V, + pSyntax->frame.component[2].H, pSyntax->frame.component[2].V); + pSyntax->info.yCbCrMode = JPEGDEC_YUV422; + pSyntax->info.X = (pSyntax->frame.hwX); + pSyntax->info.Y = (pSyntax->frame.hwY); + + /* check if fill needed */ + if ((pSyntax->frame.Y & 0xF) && (pSyntax->frame.Y & 0xF) <= 8) + pSyntax->info.fillBottom = 1; + } else if (pSyntax->frame.component[0].H == 1 && + pSyntax->frame.component[0].V == 2 && + pSyntax->frame.component[1].H == 1 && + pSyntax->frame.component[1].V == 1 && + pSyntax->frame.component[2].H == 1 && + pSyntax->frame.component[2].V == 1) { + JPEGD_INFO_LOG("YCbCr Format: YUV440(1*2:1*1:1*1)"); + pSyntax->info.yCbCrMode = JPEGDEC_YUV440; + pSyntax->info.X = (pSyntax->frame.hwX); + pSyntax->info.Y = (pSyntax->frame.hwY); + + /* check if fill needed */ + if ((pSyntax->frame.X & 0xF) && (pSyntax->frame.X & 0xF) <= 8) + pSyntax->info.fillRight = 1; + } + /* JPEG_YCBCR444 : NOT SUPPORTED */ + else if (pSyntax->frame.component[0].H == 1 && + pSyntax->frame.component[0].V == 1 && + pSyntax->frame.component[1].H == 1 && + pSyntax->frame.component[1].V == 1 && + pSyntax->frame.component[2].H == 1 && + pSyntax->frame.component[2].V == 1) { + JPEGD_INFO_LOG("YCbCr Format: YUV444(1*1:1*1:1*1)"); + pSyntax->info.yCbCrMode = JPEGDEC_YUV444; + pSyntax->info.X = pSyntax->frame.hwX; + pSyntax->info.Y = pSyntax->frame.hwY; + + /* check if fill needed */ + if ((pSyntax->frame.X & 0xF) && (pSyntax->frame.X & 0xF) <= 8) + pSyntax->info.fillRight = 1; + + if ((pSyntax->frame.Y & 0xF) && (pSyntax->frame.Y & 0xF) <= 8) + pSyntax->info.fillBottom = 1; + } else if (pSyntax->frame.component[0].H == 4 && + pSyntax->frame.component[0].V == 1 && + pSyntax->frame.component[1].H == 1 && + pSyntax->frame.component[1].V == 1 && + pSyntax->frame.component[2].H == 1 && + pSyntax->frame.component[2].V == 1) { + JPEGD_INFO_LOG("YCbCr Format: YUV411(4*1:1*1:1*1)"); + pSyntax->info.yCbCrMode = JPEGDEC_YUV411; + pSyntax->info.X = (pSyntax->frame.hwX); + pSyntax->info.Y = (pSyntax->frame.hwY); + + /* check if fill needed */ + if ((pSyntax->frame.Y & 0xF) && (pSyntax->frame.Y & 0xF) <= 8) + pSyntax->info.fillBottom = 1; + } else { + JPEGD_ERROR_LOG("Unsupported YCbCr Format: (%d*%d:%d*%d:%d*%d)", pSyntax->frame.component[0].H, pSyntax->frame.component[0].V, + pSyntax->frame.component[1].H, pSyntax->frame.component[1].V, + pSyntax->frame.component[2].H, pSyntax->frame.component[2].V); + return (JPEGDEC_UNSUPPORTED); + } + } else if (pSyntax->frame.Nf == 1) { + /* 4:0:0 */ + if ((pSyntax->frame.component[0].V == 1) || + (pSyntax->frame.component[0].H == 1)) { + pSyntax->info.yCbCrMode = JPEGDEC_YUV400; + pSyntax->info.X = (pSyntax->frame.hwX); + pSyntax->info.Y = (pSyntax->frame.hwY); + + /* check if fill needed */ + if ((pSyntax->frame.X & 0xF) && (pSyntax->frame.X & 0xF) <= 8) + pSyntax->info.fillRight = 1; + + if ((pSyntax->frame.Y & 0xF) && (pSyntax->frame.Y & 0xF) <= 8) + pSyntax->info.fillBottom = 1; + } else { + JPEGD_ERROR_LOG("unsupported format"); + return (JPEGDEC_UNSUPPORTED); + } + } else { + JPEGD_ERROR_LOG("unsupported format"); + return (JPEGDEC_UNSUPPORTED); + } + + /* save the original sampling format for progressive use */ + pSyntax->info.yCbCrModeOrig = pSyntax->info.yCbCrMode; + + return (JPEGDEC_OK); +} + +JpegDecRet jpegd_decode_frame_header(JpegParserContext *ctx) +{ + FUN_TEST("Enter"); + JpegParserContext *pCtx = ctx; + if (NULL == pCtx) { + JPEGD_ERROR_LOG("NULL pointer"); + return MPP_ERR_NULL_PTR; + } + + RK_U32 i; + RK_U32 width, height; + RK_U32 tmp1, tmp2; + RK_U32 Hmax = 0; + RK_U32 Vmax = 0; + RK_U32 size = 0; + JpegDecRet retCode; + + JpegSyntaxParam *pSyntax = pCtx->pSyntax; + StreamStorage *pStream = &(pSyntax->stream); + + retCode = JPEGDEC_OK; + + /* frame header length */ + pSyntax->frame.Lf = jpegd_get_two_bytes(pStream); + + /* check if there is enough data */ + if (((pSyntax->stream.readBits / 8) + pSyntax->frame.Lf) > + pSyntax->stream.streamLength) + return (JPEGDEC_STRM_ERROR); + + /* Sample precision */ + pSyntax->frame.P = jpegd_get_byte(pStream); + if (pSyntax->frame.P != 8) { + JPEGD_ERROR_LOG("frame.P(%d) is not supported", pSyntax->frame.P); + return (JPEGDEC_UNSUPPORTED); + } + /* Number of Lines */ + pSyntax->frame.Y = jpegd_get_two_bytes(pStream); + if (pSyntax->frame.Y < 1) { + return (JPEGDEC_UNSUPPORTED); + } + pSyntax->frame.hwY = pSyntax->frame.Y; + + /* round up to next multiple-of-16 */ + pSyntax->frame.hwY += 0xf; + pSyntax->frame.hwY &= ~(0xf); + JPEGD_INFO_LOG("Height, frame.Y:%d, frame.hwY:%d", pSyntax->frame.Y, pSyntax->frame.hwY); + + /* Number of samples per line */ + pSyntax->frame.X = jpegd_get_two_bytes(pStream); + if (pSyntax->frame.X < 1) { + return (JPEGDEC_UNSUPPORTED); + } + pSyntax->frame.hwX = pSyntax->frame.X; + + /* round up to next multiple-of-16 */ + pSyntax->frame.hwX += 0xf; + pSyntax->frame.hwX &= ~(0xf); + JPEGD_INFO_LOG("Width, frame.X:%d, frame.hwX:%d", pSyntax->frame.X, pSyntax->frame.hwX); + + /* for internal() */ + pSyntax->info.X = pSyntax->frame.hwX; + pSyntax->info.Y = pSyntax->frame.hwY; + + /* check for minimum and maximum dimensions */ + if (pSyntax->frame.hwX < pCtx->minSupportedWidth || + pSyntax->frame.hwY < pCtx->minSupportedHeight || + pSyntax->frame.hwX > pCtx->maxSupportedWidth || + pSyntax->frame.hwY > pCtx->maxSupportedHeight || + (pSyntax->frame.hwX * pSyntax->frame.hwY) > pCtx->maxSupportedPixelAmount) { + JPEGD_ERROR_LOG("FRAME(%d*%d): Unsupported size\n", pSyntax->frame.hwX, pSyntax->frame.hwY); + return (JPEGDEC_UNSUPPORTED); + } + + /* Number of components */ + pSyntax->frame.Nf = jpegd_get_byte(pStream); + if ((pSyntax->frame.Nf != 3) && (pSyntax->frame.Nf != 1)) { + JPEGD_ERROR_LOG("frame.Nf(%d) is unsupported", pSyntax->frame.Nf); + return (JPEGDEC_UNSUPPORTED); + } + + /* save component specific data */ + /* Nf == number of components */ + for (i = 0; i < pSyntax->frame.Nf; i++) { + pSyntax->frame.component[i].C = jpegd_get_byte(pStream); + if (i == 0) { /* for the first component */ + /* if first component id is something else than 1 (jfif) */ + pSyntax->scan.index = pSyntax->frame.component[i].C; + } else { + /* if component ids 'jumps' */ + if ((pSyntax->frame.component[i - 1].C + 1) != pSyntax->frame.component[i].C) { + JPEGD_ERROR_LOG("component ids 'jumps'\n"); + return (JPEGDEC_UNSUPPORTED); + } + } + tmp1 = jpegd_get_byte(pStream); + pSyntax->frame.component[i].H = tmp1 >> 4; + if (pSyntax->frame.component[i].H > Hmax) { + Hmax = pSyntax->frame.component[i].H; + } + pSyntax->frame.component[i].V = tmp1 & 0xF; + if (pSyntax->frame.component[i].V > Vmax) { + Vmax = pSyntax->frame.component[i].V; + } + + pSyntax->frame.component[i].Tq = jpegd_get_byte(pStream); + } + + if (pSyntax->frame.Nf == 1) { + Hmax = Vmax = 1; + pSyntax->frame.component[0].H = 1; + pSyntax->frame.component[0].V = 1; + } else if (Hmax == 0 || Vmax == 0) { + JPEGD_ERROR_LOG("Hmax(%d),Vmax(%d) is unsupported", Hmax, Vmax); + return (JPEGDEC_UNSUPPORTED); + } + + /* JPEG_YCBCR411 horizontal size has to be multiple of 32 pels */ + if (Hmax == 4 && (pSyntax->frame.hwX & 0x1F)) { + /* round up to next multiple-of-32 */ + pSyntax->frame.hwX += 16; + pSyntax->info.X = pSyntax->frame.hwX; + + /* check for minimum and maximum dimensions */ + if (pSyntax->frame.hwX > pCtx->maxSupportedWidth || + (pSyntax->frame.hwX * pSyntax->frame.hwY) > pCtx->maxSupportedPixelAmount) { + JPEGD_ERROR_LOG("FRAME(%d*%d): Unsupported size\n", pSyntax->frame.hwX, pSyntax->frame.hwY); + return (JPEGDEC_UNSUPPORTED); + } + } + + /* set image pointers, calculate pixelPerRow for each component */ + width = ((pSyntax->frame.hwX + Hmax * 8 - 1) / (Hmax * 8)) * Hmax * 8; + height = ((pSyntax->frame.hwY + Vmax * 8 - 1) / (Vmax * 8)) * Vmax * 8; + JPEGD_VERBOSE_LOG("width:%d, height:%d", width, height); + + /* calculate numMcuInRow and numMcuInFrame */ + JPEGD_ASSERT(Hmax != 0); + JPEGD_ASSERT(Vmax != 0); + pSyntax->frame.numMcuInRow = width / (8 * Hmax); + pSyntax->frame.numMcuInFrame = pSyntax->frame.numMcuInRow * (height / (8 * Vmax)); + JPEGD_VERBOSE_LOG("numMcuInRow:%d, numMcuInFrame:%d", pSyntax->frame.numMcuInRow, pSyntax->frame.numMcuInFrame); + + /* reset mcuNumbers */ + pSyntax->frame.mcuNumber = 0; + pSyntax->frame.row = pSyntax->frame.col = 0; + + for (i = 0; i < pSyntax->frame.Nf; i++) { + JPEGD_ASSERT(i <= 2); + tmp1 = (width * pSyntax->frame.component[i].H + Hmax - 1) / Hmax; + tmp2 = (height * pSyntax->frame.component[i].V + Vmax - 1) / Vmax; + size += tmp1 * tmp2; + + /* pixels per row */ + pSyntax->image.pixelsPerRow[i] = tmp1; + pSyntax->image.columns[i] = tmp2; + pSyntax->frame.numBlocks[i] = + (((pSyntax->frame.hwX * pSyntax->frame.component[i].H) / Hmax + 7) >> 3) * + (((pSyntax->frame.hwY * pSyntax->frame.component[i].V) / Vmax + 7) >> 3); + + if (i == 0) { + pSyntax->image.sizeLuma = size; + } + } + + pSyntax->image.size = size; + pSyntax->image.sizeChroma = size - pSyntax->image.sizeLuma; + JPEGD_VERBOSE_LOG("sizeLuma:%d", pSyntax->image.sizeLuma); + JPEGD_VERBOSE_LOG("image.size:%d, sizeChroma:%d", pSyntax->image.size, pSyntax->image.sizeChroma); + + /* set YUV mode & calculate rlc tmp size */ + retCode = jpegd_set_yuv_mode(pSyntax); + if (retCode != JPEGDEC_OK) { + JPEGD_ERROR_LOG("set YUV mode failed"); + return (retCode); + } + + return (JPEGDEC_OK); + FUN_TEST("Exit"); +} + +JpegDecRet jpegd_decode_scan_header(JpegParserContext *ctx) +{ + FUN_TEST("Enter"); + JpegParserContext *pCtx = ctx; + if (NULL == pCtx) { + JPEGD_ERROR_LOG("NULL pointer"); + return MPP_ERR_NULL_PTR; + } + + RK_U32 i; + RK_U32 tmp; + + JpegSyntaxParam *pSyntax = pCtx->pSyntax; + StreamStorage *pStream = &(pSyntax->stream); + + pSyntax->scan.Ls = jpegd_get_two_bytes(pStream); + + /* check if there is enough data */ + if (((pStream->readBits / 8) + pSyntax->scan.Ls) > pStream->streamLength) { + JPEGD_ERROR_LOG("no enough data"); + return (JPEGDEC_STRM_ERROR); + } + + pSyntax->scan.Ns = jpegd_get_byte(pStream); + + pSyntax->info.fillX = pSyntax->info.fillY = 0; + if (pSyntax->scan.Ns == 1) { + JPEGD_INFO_LOG("scan.Ns == 1"); + /* Reset to non-interleaved baseline operation type */ + if (pSyntax->info.operationType == JPEGDEC_BASELINE && + pSyntax->info.yCbCrMode != JPEGDEC_YUV400) + pSyntax->info.operationType = JPEGDEC_NONINTERLEAVED; + + tmp = jpegd_get_byte(pStream); + pSyntax->frame.cIndex = tmp - 1; + pSyntax->info.componentId = pSyntax->frame.cIndex; + pSyntax->scan.Cs[pSyntax->frame.cIndex] = tmp; + tmp = jpegd_get_byte(pStream); + pSyntax->scan.Td[pSyntax->frame.cIndex] = tmp >> 4; + pSyntax->scan.Ta[pSyntax->frame.cIndex] = tmp & 0x0F; + + /* check/update component info */ + if (pSyntax->frame.Nf == 3) { + pSyntax->info.fillRight = 0; + pSyntax->info.fillBottom = 0; + pSyntax->info.pfNeeded[pSyntax->scan.Cs[pSyntax->frame.cIndex] - 1] = 0; + if (pSyntax->scan.Cs[pSyntax->frame.cIndex] == 2 || + pSyntax->scan.Cs[pSyntax->frame.cIndex] == 3) { + if (pSyntax->info.operationType == JPEGDEC_PROGRESSIVE || + pSyntax->info.operationType == JPEGDEC_NONINTERLEAVED || + pSyntax->info.nonInterleavedScanReady) { + if (pSyntax->info.yCbCrModeOrig == JPEGDEC_YUV420) { + pSyntax->info.X = pSyntax->frame.hwX >> 1; + pSyntax->info.Y = pSyntax->frame.hwY >> 1; + } else if (pSyntax->info.yCbCrModeOrig == JPEGDEC_YUV422) { + pSyntax->info.X = pSyntax->frame.hwX >> 1; + } else if (pSyntax->info.yCbCrModeOrig == JPEGDEC_YUV440) { + pSyntax->info.Y = pSyntax->frame.hwY >> 1; + } else { + pSyntax->info.yCbCrMode = 0; + return (JPEGDEC_UNSUPPORTED); + } + } + + pSyntax->info.yCbCrMode = 0; + } else if (pSyntax->scan.Cs[pSyntax->frame.cIndex] == 1) { /* YCbCr 4:2:0 */ + pSyntax->info.X = pSyntax->frame.hwX; + pSyntax->info.Y = pSyntax->frame.hwY; + if (pSyntax->info.yCbCrMode == JPEGDEC_YUV420) { + pSyntax->info.yCbCrMode = 1; + } else if (pSyntax->info.yCbCrMode == JPEGDEC_YUV422) { + pSyntax->info.yCbCrMode = 0; + if (pSyntax->frame.cIndex == 0) { + JPEGD_INFO_LOG("SCAN: #YUV422 FLAG\n"); + pSyntax->info.yCbCr422 = 1; + } + } else if (pSyntax->info.yCbCrMode == JPEGDEC_YUV444) { + pSyntax->info.yCbCrMode = 0; + return (JPEGDEC_UNSUPPORTED); + } + } else { + pSyntax->info.yCbCrMode = 0; + return (JPEGDEC_UNSUPPORTED); + } + + if (pSyntax->info.X & 0xF) { + pSyntax->info.X += 8; + pSyntax->info.fillX = 1; + } else if ((pSyntax->scan.Cs[pSyntax->frame.cIndex] == 1 || + pSyntax->info.yCbCrModeOrig == JPEGDEC_YUV440) && + (pSyntax->frame.X & 0xF) && (pSyntax->frame.X & 0xF) <= 8) { + pSyntax->info.fillRight = 1; + } + + if (pSyntax->info.Y & 0xF) { + pSyntax->info.Y += 8; + pSyntax->info.fillY = 1; + } else if ((pSyntax->scan.Cs[pSyntax->frame.cIndex] == 1 || + pSyntax->info.yCbCrModeOrig == JPEGDEC_YUV422) && + (pSyntax->frame.Y & 0xF) && (pSyntax->frame.Y & 0xF) <= 8) { + pSyntax->info.fillBottom = 1; + } + } else if (pSyntax->frame.Nf == 1) { + JPEGD_INFO_LOG("SCAN: #YUV422 FLAG\n"); + pSyntax->info.yCbCr422 = 0; + } + + /* decoding info */ + if (pSyntax->info.operationType == JPEGDEC_PROGRESSIVE || + pSyntax->info.operationType == JPEGDEC_NONINTERLEAVED) { + pSyntax->info.yCbCrMode = 0; + } + } else { + for (i = 0; i < pSyntax->scan.Ns; i++) { + pSyntax->scan.Cs[i] = jpegd_get_byte(pStream); + tmp = jpegd_get_byte(pStream); + pSyntax->scan.Td[i] = tmp >> 4; /* which DC table */ + pSyntax->scan.Ta[i] = tmp & 0x0F; /* which AC table */ + pSyntax->info.pfNeeded[i] = 1; + } + pSyntax->info.X = pSyntax->frame.hwX; + pSyntax->info.Y = pSyntax->frame.hwY; + pSyntax->frame.cIndex = 0; + pSyntax->info.yCbCrMode = pSyntax->info.yCbCrModeOrig; + } + + pSyntax->scan.Ss = jpegd_get_byte(pStream); + pSyntax->scan.Se = jpegd_get_byte(pStream); + tmp = jpegd_get_byte(pStream); + pSyntax->scan.Ah = tmp >> 4; + pSyntax->scan.Al = tmp & 0x0F; + + if (pSyntax->frame.codingType == SOF0) { + /* baseline */ + if (pSyntax->scan.Ss != 0) + return (JPEGDEC_UNSUPPORTED); + if (pSyntax->scan.Se != 63) + return (JPEGDEC_UNSUPPORTED); + if (pSyntax->scan.Ah != 0) + return (JPEGDEC_UNSUPPORTED); + if (pSyntax->scan.Al != 0) + return (JPEGDEC_UNSUPPORTED); + + /* update scan decoding parameters */ + /* interleaved/non-interleaved */ + if (pSyntax->info.operationType == JPEGDEC_BASELINE) + pSyntax->info.nonInterleaved = 0; + else + pSyntax->info.nonInterleaved = 1; + /* decoding info */ + if ((pSyntax->frame.Nf == 3 && pSyntax->scan.Ns == 1) || + (pSyntax->frame.Nf == 1 && pSyntax->scan.Ns == 1)) + pSyntax->info.amountOfQTables = 1; + else + pSyntax->info.amountOfQTables = 3; + } + + if (pSyntax->frame.codingType == SOF2) { + /* progressive */ + if (pSyntax->scan.Ss == 0 && pSyntax->scan.Se != 0) + return (JPEGDEC_UNSUPPORTED); + if (/*pSyntax->scan.Ah < 0 ||*/ pSyntax->scan.Ah > 13) + return (JPEGDEC_UNSUPPORTED); + if (/*pSyntax->scan.Al < 0 ||*/ pSyntax->scan.Al > 13) + return (JPEGDEC_UNSUPPORTED); + + /* update scan decoding parameters */ + /* TODO! What if 2 components, possible??? */ + /* interleaved/non-interleaved */ + if (pSyntax->scan.Ns == 1) { + pSyntax->info.nonInterleaved = 1; + /* component ID */ + pSyntax->info.componentId = pSyntax->frame.cIndex; + pSyntax->info.amountOfQTables = 1; + } else { + pSyntax->info.nonInterleaved = 0; + /* component ID ==> set to luma ==> interleaved */ + pSyntax->info.componentId = 0; + pSyntax->info.amountOfQTables = 3; + } + + } + + FUN_TEST("Exit"); + return (JPEGDEC_OK); +} + +JpegDecRet jpegd_decode_scan(JpegParserContext *ctx) +{ + FUN_TEST("Enter"); + JpegParserContext *pCtx = ctx; + if (NULL == pCtx) { + JPEGD_ERROR_LOG("NULL pointer"); + return MPP_ERR_NULL_PTR; + } + + JpegDecRet retCode; + JpegSyntaxParam *pSyntax = pCtx->pSyntax; + retCode = JPEGDEC_ERROR; + + retCode = jpegd_decode_scan_header(pCtx); + if (retCode != JPEGDEC_OK) { + JPEGD_ERROR_LOG("Decode Scan Header Failed"); + return (retCode); + } + + JPEGD_VERBOSE_LOG("SCAN: MODE: %d\n", pSyntax->frame.codingType); + FUN_TEST("Exit"); + return (JPEGDEC_OK); +} + +JpegDecRet jpegd_decode_huffman_tables(JpegParserContext *ctx) +{ + FUN_TEST("Enter"); + JpegParserContext *pCtx = ctx; + if (NULL == pCtx) { + JPEGD_ERROR_LOG("NULL pointer"); + return MPP_ERR_NULL_PTR; + } + + RK_U32 i, len, Tc, Th, tmp; + RK_S32 j; + JpegSyntaxParam *pSyntax = pCtx->pSyntax; + StreamStorage *pStream = &(pSyntax->stream); + + pSyntax->vlc.Lh = jpegd_get_two_bytes(pStream); + + /* check if there is enough data for tables */ + if (((pStream->readBits / 8) + pSyntax->vlc.Lh) > pStream->streamLength) { + JPEGD_ERROR_LOG("no enough data for tables"); + return (JPEGDEC_STRM_ERROR); + } + + /* four bytes already read in */ + len = 4; + + while (len < pSyntax->vlc.Lh) { + tmp = jpegd_get_byte(pStream); + len++; + Tc = tmp >> 4; /* Table class: DC or AC */ + if (Tc != 0 && Tc != 1) { + JPEGD_ERROR_LOG("Tc(%d) is unsupported", Tc); + return (JPEGDEC_UNSUPPORTED); + } + Th = tmp & 0xF; /* Huffman table identifier: 0 or 1 .(Baseline)*/ + /* only two tables in baseline allowed */ + if ((pSyntax->frame.codingType == SOF0) && (Th > 1)) { + JPEGD_ERROR_LOG("Th(%d) is unsupported", Th); + return (JPEGDEC_UNSUPPORTED); + } + /* four tables in progressive allowed */ + if ((pSyntax->frame.codingType == SOF2) && (Th > 3)) { + JPEGD_ERROR_LOG("Th(%d) is unsupported", Th); + return (JPEGDEC_UNSUPPORTED); + } + + /* set the table pointer */ + if (Tc) { + /* AC table */ + switch (Th) { + case 0: + JPEGD_VERBOSE_LOG("ac0\n"); + pSyntax->vlc.table = &(pSyntax->vlc.acTable0); + break; + case 1: + JPEGD_VERBOSE_LOG("ac1\n"); + pSyntax->vlc.table = &(pSyntax->vlc.acTable1); + break; + case 2: + JPEGD_VERBOSE_LOG("ac2\n"); + pSyntax->vlc.table = &(pSyntax->vlc.acTable2); + break; + case 3: + JPEGD_VERBOSE_LOG("ac3\n"); + pSyntax->vlc.table = &(pSyntax->vlc.acTable3); + break; + default: + JPEGD_ERROR_LOG("Th(%d) is unsupported", Th); + return (JPEGDEC_UNSUPPORTED); + } + } else { + /* DC table */ + switch (Th) { + case 0: + JPEGD_VERBOSE_LOG("dc0\n"); + pSyntax->vlc.table = &(pSyntax->vlc.dcTable0); + break; + case 1: + JPEGD_VERBOSE_LOG("dc1\n"); + pSyntax->vlc.table = &(pSyntax->vlc.dcTable1); + break; + case 2: + JPEGD_VERBOSE_LOG("dc2\n"); + pSyntax->vlc.table = &(pSyntax->vlc.dcTable2); + break; + case 3: + JPEGD_VERBOSE_LOG("dc3\n"); + pSyntax->vlc.table = &(pSyntax->vlc.dcTable3); + break; + default: + JPEGD_ERROR_LOG("Th(%d) is unsupported", Th); + return (JPEGDEC_UNSUPPORTED); + } + } + + tmp = 0; + /* read in the values of list BITS */ + for (i = 0; i < 16; i++) { + tmp += pSyntax->vlc.table->bits[i] = jpegd_get_byte(pStream); + len++; + } + /* allocate memory for HUFFVALs */ + if (pSyntax->vlc.table->vals != NULL) { + /* free previously reserved table */ + mpp_free(pSyntax->vlc.table->vals); + } + + pSyntax->vlc.table->vals = (RK_U32 *) mpp_calloc(RK_U32, tmp); + + /* set the table length */ + pSyntax->vlc.table->tableLength = tmp; + /* read in the HUFFVALs */ + for (i = 0; i < tmp; i++) { + pSyntax->vlc.table->vals[i] = jpegd_get_byte(pStream); + len++; + } + /* first and last lengths */ + for (i = 0; i < 16; i++) { + if (pSyntax->vlc.table->bits[i] != 0) { + pSyntax->vlc.table->start = i; + break; + } + } + for (j = 15; j >= 0; j--) { + if (pSyntax->vlc.table->bits[j] != 0) { + pSyntax->vlc.table->last = ((RK_U32) j + 1); + break; + } + } + } + + return (JPEGDEC_OK); + FUN_TEST("Exit"); +} + +JpegDecRet jpegd_decode_quant_tables(JpegParserContext *ctx) +{ + FUN_TEST("Enter"); + JpegParserContext *pCtx = ctx; + if (NULL == pCtx) { + JPEGD_ERROR_LOG("NULL pointer"); + return MPP_ERR_NULL_PTR; + } + + RK_U32 t, tmp, i; + JpegSyntaxParam *pSyntax = pCtx->pSyntax; + StreamStorage *pStream = &(pSyntax->stream); + + pSyntax->quant.Lq = jpegd_get_two_bytes(pStream); + + /* check if there is enough data for tables */ + if (((pStream->readBits / 8) + pSyntax->quant.Lq) > pStream->streamLength) { + JPEGD_ERROR_LOG("no enough data for tables"); + return (JPEGDEC_STRM_ERROR); + } + + t = 4; + + while (t < pSyntax->quant.Lq) { + /* Tq value selects what table the components use */ + + /* read tables and write to decData->quant */ + tmp = jpegd_get_byte(pStream); + t++; + /* supporting only 8 bits / sample */ + if ((tmp >> 4) != 0) { + JPEGD_ERROR_LOG("Pq(%d) is not supported!", (tmp >> 4)); + return (JPEGDEC_UNSUPPORTED); + } + + tmp &= 0xF; /* Tq */ + /* set the quantisation table pointer */ + + if (tmp == 0) { + JPEGD_VERBOSE_LOG("qtable0\n"); + pSyntax->quant.table = pSyntax->quant.table0; + } else if (tmp == 1) { + JPEGD_VERBOSE_LOG("qtable1\n"); + pSyntax->quant.table = pSyntax->quant.table1; + } else if (tmp == 2) { + JPEGD_VERBOSE_LOG("qtable2\n"); + pSyntax->quant.table = pSyntax->quant.table2; + } else if (tmp == 3) { + JPEGD_VERBOSE_LOG("qtable3\n"); + pSyntax->quant.table = pSyntax->quant.table3; + } else { + JPEGD_ERROR_LOG("Tq(%d) is not supported!", tmp); + return (JPEGDEC_UNSUPPORTED); + } + for (i = 0; i < 64; i++) { + pSyntax->quant.table[i] = jpegd_get_byte(pStream); + t++; + } + } + + return (MPP_OK); + FUN_TEST("Exit"); +} + +JpegDecRet jpegd_default_huffman_tables(JpegParserContext *ctx) +{ + FUN_TEST("Enter"); + JpegParserContext *pCtx = ctx; + if (NULL == pCtx) { + JPEGD_ERROR_LOG("NULL pointer"); + return MPP_ERR_NULL_PTR; + } + JpegSyntaxParam *pSyntax = pCtx->pSyntax; + + /* Set up the standard Huffman tables (cf. JPEG standard section K.3) */ + /* IMPORTANT: these are only valid for 8-bit data precision! */ + uint8_t ff_mjpeg_bits_dc_luminance[17] = + { /* 0-base */ 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 }; + uint8_t ff_mjpeg_val_dc[12] = //luminance and chrominance all use it + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }; + + uint8_t ff_mjpeg_bits_dc_chrominance[17] = + { /* 0-base */ 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 }; + + uint8_t ff_mjpeg_bits_ac_luminance[17] = + { /* 0-base */ 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d }; + uint8_t ff_mjpeg_val_ac_luminance[] = { + 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, + 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, + 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, + 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, + 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, + 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, + 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, + 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, + 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, + 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, + 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, + 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, + 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, + 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, + 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, + 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, + 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, + 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, + 0xf9, 0xfa + }; + + uint8_t ff_mjpeg_bits_ac_chrominance[17] = + { /* 0-base */ 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 }; + + uint8_t ff_mjpeg_val_ac_chrominance[] = { + 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, + 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, + 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, + 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, + 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, + 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, + 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, + 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, + 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, + 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, + 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, + 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, + 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, + 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, + 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, + 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, + 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, + 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, + 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, + 0xf9, 0xfa + }; + + RK_U32 i, len, tmp, k; + RK_S32 j; + uint8_t *bitstable[4] = {ff_mjpeg_bits_dc_luminance, ff_mjpeg_bits_ac_luminance, ff_mjpeg_bits_dc_chrominance, ff_mjpeg_bits_ac_chrominance}; + uint8_t *valtable[4] = {ff_mjpeg_val_dc, ff_mjpeg_val_ac_luminance, ff_mjpeg_val_dc, ff_mjpeg_val_ac_chrominance}; + uint8_t *bitstmp; + uint8_t *valtmp; + + for (k = 0; k < 4; k++) { + bitstmp = bitstable[k]; + valtmp = valtable[k]; + + if (k == 0) + pSyntax->vlc.table = &(pSyntax->vlc.dcTable0); + else if (k == 1) + pSyntax->vlc.table = &(pSyntax->vlc.acTable0); + else if (k == 2) + pSyntax->vlc.table = &(pSyntax->vlc.dcTable1); + else + pSyntax->vlc.table = &(pSyntax->vlc.acTable1); + + tmp = 0; + /* read in the values of list BITS */ + for (i = 0; i < 16; i++) { + tmp += pSyntax->vlc.table->bits[i] = bitstmp[i + 1]; + len++; + } + /* allocate memory for HUFFVALs */ + if (pSyntax->vlc.table->vals != NULL) { + /* free previously reserved table */ + mpp_free(pSyntax->vlc.table->vals); + } + + pSyntax->vlc.table->vals = (RK_U32 *) mpp_calloc(RK_U32, tmp); + + /* set the table length */ + pSyntax->vlc.table->tableLength = tmp; + /* read in the HUFFVALs */ + for (i = 0; i < tmp; i++) { + pSyntax->vlc.table->vals[i] = valtmp[i]; + len++; + } + /* first and last lengths */ + for (i = 0; i < 16; i++) { + if (pSyntax->vlc.table->bits[i] != 0) { + pSyntax->vlc.table->start = i; + break; + } + } + for (j = 15; j >= 0; j--) { + if (pSyntax->vlc.table->bits[j] != 0) { + pSyntax->vlc.table->last = ((RK_U32) j + 1); + break; + } + } + } + + FUN_TEST("Exit"); + return MPP_OK; +} + +MPP_RET jpegd_parser_split_frame(RK_U8 *src, RK_U32 src_size, RK_U8 *dst, RK_U32 *dst_size) +{ + FUN_TEST("Enter"); + MPP_RET ret = MPP_OK; + if (NULL == src || NULL == dst || src_size <= 0) { + JPEGD_ERROR_LOG("NULL pointer or wrong src_size(%d)", src_size); + return MPP_ERR_NULL_PTR; + } + RK_U8 *end; + RK_U8 *tmp; + RK_U32 str_size = (src_size + 255) & (~255); + end = dst + src_size; + + if (src[6] == 0x41 && src[7] == 0x56 && src[8] == 0x49 && src[9] == 0x31) { + //distinguish 310 from 210 camera + RK_U32 i; + RK_U32 copy_len = 0; + tmp = src; + JPEGD_INFO_LOG("distinguish 310 from 210 camera"); + + for (i = 0; i < src_size - 4; i++) { + if (tmp[i] == 0xff) { + if (tmp[i + 1] == 0x00 && tmp[i + 2] == 0xff && ((tmp[i + 3] & 0xf0) == 0xd0)) + i += 2; + } + *dst++ = tmp[i]; + copy_len++; + } + for (; i < src_size; i++) { + *dst++ = tmp[i]; + copy_len++; + } + if (copy_len < src_size) + memset(dst, 0, src_size - copy_len); + *dst_size = copy_len; + } else { + memcpy(dst, src, src_size); + memset(dst + src_size, 0, str_size - src_size); + *dst_size = src_size; + } + + /* NOTE: hardware bug, need to remove tailing FF 00 before FF D9 end flag */ + if (end[-1] == 0xD9 && end[-2] == 0xFF) { + end -= 2; + + do { + if (end[-1] == 0xFF) { + end--; + continue; + } + if (end[-1] == 0x00 && end [-2] == 0xFF) { + end -= 2; + continue; + } + break; + } while (1); + + JPEGD_INFO_LOG("remove tailing FF 00 before FF D9 end flag."); + end[0] = 0xff; + end[1] = 0xD9; + } + + FUN_TEST("Exit"); + return ret; +} + +MPP_RET jpegd_prepare(void *ctx, MppPacket pkt, HalDecTask *task) +{ + FUN_TEST("Enter"); + MPP_RET ret = MPP_OK; + JpegParserContext *JpegParserCtx = (JpegParserContext *)ctx; + MppPacket input_packet = JpegParserCtx->input_packet; + RK_U32 pkt_length = 0; + RK_U32 copy_length = 0; + void *pPacket = NULL; + RK_U8 *pPos = NULL; + + task->valid = 0; + + JpegParserCtx->pts = mpp_packet_get_pts(pkt); + JpegParserCtx->eos = mpp_packet_get_eos(pkt); + pkt_length = (RK_U32)mpp_packet_get_length(pkt); + pPacket = pPos = mpp_packet_get_pos(pkt); + + if (JpegParserCtx->eos) { + + JPEGD_INFO_LOG("it is end of stream."); + task->flags.eos = 1; + return ret; + } + + if (pkt_length > JpegParserCtx->bufferSize) { + JPEGD_INFO_LOG("Huge Frame(%d Bytes)! bufferSize:%d", pkt_length, JpegParserCtx->bufferSize); + mpp_free(JpegParserCtx->recv_buffer); + JpegParserCtx->recv_buffer = NULL; + + JpegParserCtx->recv_buffer = mpp_calloc(RK_U8, pkt_length + 1024); + if (NULL == JpegParserCtx->recv_buffer) { + JPEGD_ERROR_LOG("no memory!"); + return MPP_ERR_NOMEM; + } + + JpegParserCtx->bufferSize = pkt_length + 1024; + } + + jpegd_parser_split_frame(pPacket, pkt_length, JpegParserCtx->recv_buffer, ©_length); + + pPos += pkt_length; + mpp_packet_set_pos(pkt, pPos); + if (copy_length != pkt_length) { + JPEGD_INFO_LOG("there seems to be something wrong with split_frame. pkt_length:%d, copy_length:%d", pkt_length, copy_length); + } + + /* debug information */ + if (JpegParserCtx->parser_debug_enable && JpegParserCtx->input_jpeg_count < 3) { + static FILE *jpg_file; + static char name[32]; + + snprintf(name, sizeof(name), "/data/input%02d.jpg", JpegParserCtx->input_jpeg_count); + jpg_file = fopen(name, "wb+"); + if (jpg_file) { + JPEGD_INFO_LOG("input jpeg(%d Bytes) saving to %s\n", pkt_length, name); + fwrite(pPacket, pkt_length, 1, jpg_file); + fclose(jpg_file); + JpegParserCtx->input_jpeg_count++; + } + } + + mpp_packet_set_data(input_packet, JpegParserCtx->recv_buffer); + mpp_packet_set_size(input_packet, pkt_length); + mpp_packet_set_length(input_packet, pkt_length); + + JpegParserCtx->streamLength = pkt_length; + task->input_packet = input_packet; + task->valid = 1; + JPEGD_VERBOSE_LOG("input_packet:%p, recv_buffer:%p, pkt_length:%d", input_packet, + JpegParserCtx->recv_buffer, pkt_length); + + FUN_TEST("Exit"); + return ret; +} + +MPP_RET jpegd_read_decode_parameters(JpegParserContext *ctx, StreamStorage *pStream) +{ + FUN_TEST("Enter"); + if (NULL == ctx || NULL == pStream) { + JPEGD_ERROR_LOG("NULL pointer"); + return MPP_ERR_NULL_PTR; + } + + JpegParserContext *pCtx = ctx; + JpegDecImageInfo *pImageInfo = (JpegDecImageInfo *) & (pCtx->pSyntax->imageInfo); + JpegSyntaxParam *pSyntax = pCtx->pSyntax; + RK_U32 Nf = 0, Ns = 0, NsThumb = 0; + RK_U32 i, j = 0, init = 0, initThumb = 0; + RK_U32 H[MAX_NUMBER_OF_COMPONENTS]; + RK_U32 V[MAX_NUMBER_OF_COMPONENTS]; + RK_U32 Htn[MAX_NUMBER_OF_COMPONENTS]; + RK_U32 Vtn[MAX_NUMBER_OF_COMPONENTS]; + RK_U32 Hmax = 0, Vmax = 0, headerLength = 0; + RK_U32 currentByte = 0, currentBytes = 0; + RK_U32 appLength = 0, appBits = 0; + RK_U32 thumbnail = 0, errorCode = 0; + + /* reset sampling factors */ + for (i = 0; i < MAX_NUMBER_OF_COMPONENTS; i++) { + H[i] = 0; + V[i] = 0; + Htn[i] = 0; + Vtn[i] = 0; + } + + /* Read decoding parameters */ + for (pStream->readBits = 0; (pStream->readBits / 8) < pStream->streamLength; pStream->readBits++) { + /* Look for marker prefix byte from stream */ + if ((currentByte == 0xFF) || jpegd_get_byte(pStream) == 0xFF) { + currentByte = jpegd_get_byte(pStream); + + switch (currentByte) { /* switch to certain header decoding */ + case SOF0: /* baseline marker */ + case SOF2: { /* progresive marker */ + JPEGD_VERBOSE_LOG("SOF, currentByte:0x%x", currentByte); + if (currentByte == SOF0) { + pImageInfo->codingMode = pSyntax->info.operationType = JPEGDEC_BASELINE; + } else { + pImageInfo->codingMode = pSyntax->info.operationType = JPEGDEC_PROGRESSIVE; + } + + /* Frame header */ + i++; + Hmax = 0; + Vmax = 0; + + /* SOF0/SOF2 length */ + headerLength = jpegd_get_two_bytes(pStream); + if (headerLength == STRM_ERROR || + ((pStream->readBits + ((headerLength * 8) - 16)) > (8 * pStream->streamLength))) { + errorCode = 1; + break; + } + + /* Sample precision (only 8 bits/sample supported) */ + currentByte = jpegd_get_byte(pStream); + if (currentByte != 8) { + JPEGD_ERROR_LOG("Sample precision"); + return (JPEGDEC_UNSUPPORTED); + } + + /* Number of Lines */ + pImageInfo->outputHeight = jpegd_get_two_bytes(pStream); + pImageInfo->displayHeight = pImageInfo->outputHeight; + if (pImageInfo->outputHeight < 1) { + JPEGD_ERROR_LOG("pImageInfo->outputHeight(%d) Unsupported", pImageInfo->outputHeight); + return (JPEGDEC_UNSUPPORTED); + } + + /* round up to next multiple-of-16 */ + pImageInfo->outputHeight += 0xf; + pImageInfo->outputHeight &= ~(0xf); + pSyntax->frame.hwY = pImageInfo->outputHeight; + + /* Number of Samples per Line */ + pImageInfo->outputWidth = jpegd_get_two_bytes(pStream); + pImageInfo->displayWidth = pImageInfo->outputWidth; + if (pImageInfo->outputWidth < 1) { + JPEGD_ERROR_LOG("pImageInfo->outputWidth(%d) Unsupported", pImageInfo->outputWidth); + return (JPEGDEC_UNSUPPORTED); + } + pImageInfo->outputWidth += 0xf; + pImageInfo->outputWidth &= ~(0xf); + pSyntax->frame.hwX = pImageInfo->outputWidth; + + /* check for minimum and maximum dimensions */ + if (pImageInfo->outputWidth < pCtx->minSupportedWidth || + pImageInfo->outputHeight < pCtx->minSupportedHeight || + pImageInfo->outputWidth > pCtx->maxSupportedWidth || + pImageInfo->outputHeight > pCtx->maxSupportedHeight || + (pImageInfo->outputWidth * pImageInfo->outputHeight) > pCtx->maxSupportedPixelAmount) { + JPEGD_ERROR_LOG("Unsupported size(%d*%d)", pImageInfo->outputWidth, pImageInfo->outputHeight); + return (JPEGDEC_UNSUPPORTED); + } + + /* Number of Image Components per Frame */ + Nf = jpegd_get_byte(pStream); + if (Nf != 3 && Nf != 1) { + JPEGD_ERROR_LOG("Number of Image Components per Frame: %d", Nf); + return (JPEGDEC_UNSUPPORTED); + } + for (j = 0; j < Nf; j++) { + if (jpegd_flush_bits(pStream, 8) == STRM_ERROR) { /* jump over component identifier */ + errorCode = 1; + break; + } + + currentByte = jpegd_get_byte(pStream); + H[j] = (currentByte >> 4); /* Horizontal sampling factor */ + V[j] = (currentByte & 0xF); /* Vertical sampling factor */ + + if (jpegd_flush_bits(pStream, 8) == STRM_ERROR) { /* jump over Tq */ + errorCode = 1; + break; + } + + if (H[j] > Hmax) + Hmax = H[j]; + if (V[j] > Vmax) + Vmax = V[j]; + } + if (Hmax == 0 || Vmax == 0) { + JPEGD_ERROR_LOG("Hmax(%d), Vmax(%d)", Hmax, Vmax); + return (JPEGDEC_UNSUPPORTED); + } + + /* check format */ + if (H[0] == 2 && V[0] == 2 && + H[1] == 1 && V[1] == 1 && H[2] == 1 && V[2] == 1) { + pImageInfo->outputFormat = MPP_FMT_YUV420SP; + pSyntax->frame.numMcuInRow = (pSyntax->frame.hwX / 16); + pSyntax->frame.numMcuInFrame = ((pSyntax->frame.hwX * pSyntax->frame.hwY) / 256); + } else if (H[0] == 2 && V[0] == 1 && H[1] == 1 && V[1] == 1 && H[2] == 1 && V[2] == 1) { + pImageInfo->outputFormat = MPP_FMT_YUV422SP; + pSyntax->frame.numMcuInRow = (pSyntax->frame.hwX / 16); + pSyntax->frame.numMcuInFrame = ((pSyntax->frame.hwX * pSyntax->frame.hwY) / 128); + } else if (H[0] == 1 && V[0] == 2 && + H[1] == 1 && V[1] == 1 && H[2] == 1 && V[2] == 1) { + pImageInfo->outputFormat = JPEGDEC_YCbCr440; + pSyntax->frame.numMcuInRow = (pSyntax->frame.hwX / 8); + pSyntax->frame.numMcuInFrame = ((pSyntax->frame.hwX * pSyntax->frame.hwY) / 128); + } else if (H[0] == 1 && V[0] == 1 && + H[1] == 0 && V[1] == 0 && H[2] == 0 && V[2] == 0) { + pImageInfo->outputFormat = JPEGDEC_YCbCr400; + pSyntax->frame.numMcuInRow = (pSyntax->frame.hwX / 8); + pSyntax->frame.numMcuInFrame = ((pSyntax->frame.hwX * pSyntax->frame.hwY) / 64); + } else if (pCtx->extensionsSupported && + H[0] == 4 && V[0] == 1 && + H[1] == 1 && V[1] == 1 && H[2] == 1 && V[2] == 1) { + /* YUV411 output has to be 32 pixel multiple */ + if (pImageInfo->outputWidth & 0x1F) { + pImageInfo->outputWidth += 16; + pSyntax->frame.hwX = pImageInfo->outputWidth; + } + + /* check for maximum dimensions */ + if (pImageInfo->outputWidth > pCtx->maxSupportedWidth || + (pImageInfo->outputWidth * pImageInfo->outputHeight) > pCtx->maxSupportedPixelAmount) { + JPEGD_ERROR_LOG("Unsupported size(%d*%d)", pImageInfo->outputWidth, pImageInfo->outputHeight); + return (JPEGDEC_UNSUPPORTED); + } + + pImageInfo->outputFormat = JPEGDEC_YCbCr411_SEMIPLANAR; + pSyntax->frame.numMcuInRow = (pSyntax->frame.hwX / 32); + pSyntax->frame.numMcuInFrame = ((pSyntax->frame.hwX * pSyntax->frame.hwY) / 256); + } else if (pCtx->extensionsSupported && + H[0] == 1 && V[0] == 1 && + H[1] == 1 && V[1] == 1 && H[2] == 1 && V[2] == 1) { + pImageInfo->outputFormat = JPEGDEC_YCbCr444_SEMIPLANAR; + pSyntax->frame.numMcuInRow = (pSyntax->frame.hwX / 8); + pSyntax->frame.numMcuInFrame = ((pSyntax->frame.hwX * pSyntax->frame.hwY) / 64); + } else { + JPEGD_ERROR_LOG("Unsupported YCbCr format"); + return (JPEGDEC_UNSUPPORTED); + } + + /* restore output format */ + pSyntax->info.yCbCrMode = pSyntax->info.getInfoYCbCrMode = pImageInfo->outputFormat; + break; + } + case SOS: { + JPEGD_VERBOSE_LOG("SOS, currentByte:0x%x", currentByte); + /* SOS length */ + headerLength = jpegd_get_two_bytes(pStream); + JPEGD_VERBOSE_LOG("Length of is %d", headerLength); + if (headerLength == STRM_ERROR || + ((pStream->readBits + ((headerLength * 8) - 16)) > (8 * pStream->streamLength))) { + JPEGD_ERROR_LOG("readBits:%d, headerLength:%d, streamLength:%d", pStream->readBits, headerLength, pStream->streamLength); + errorCode = 1; + break; + } + + /* check if interleaved or non-ibnterleaved */ + Ns = jpegd_get_byte(pStream); + if (Ns == MIN_NUMBER_OF_COMPONENTS && + pImageInfo->outputFormat != JPEGDEC_YCbCr400 && pImageInfo->codingMode == JPEGDEC_BASELINE) { + pImageInfo->codingMode = pSyntax->info.operationType = JPEGDEC_NONINTERLEAVED; + } + + /* jump over SOS header */ + if (headerLength != 0) { + pStream->readBits += ((headerLength * 8) - 16); + pStream->pCurrPos += (((headerLength * 8) - 16) / 8); + } + + if ((pStream->readBits + 8) < (8 * pStream->streamLength)) { + pSyntax->info.init = 1; + init = 1; + } else { + JPEGD_ERROR_LOG("Needs to increase input buffer"); + return (JPEGDEC_INCREASE_INPUT_BUFFER); + } + break; + } + case DQT: { + JPEGD_VERBOSE_LOG("DQT, currentByte:0x%x", currentByte); + /* DQT length */ + headerLength = jpegd_get_two_bytes(pStream); + JPEGD_VERBOSE_LOG("Length of Define Quantization Table is %d", headerLength); + if (headerLength == STRM_ERROR || + ((pStream->readBits + ((headerLength * 8) - 16)) > (8 * pStream->streamLength))) { + JPEGD_ERROR_LOG("readBits:%d, headerLength:%d, streamLength:%d", pStream->readBits, headerLength, pStream->streamLength); + errorCode = 1; + break; + } + + /* jump over DQT header */ + if (headerLength != 0) { + pStream->readBits += ((headerLength * 8) - 16); + pStream->pCurrPos += (((headerLength * 8) - 16) / 8); + } + break; + } + case DHT: { + JPEGD_VERBOSE_LOG("DHT, currentByte:0x%x", currentByte); + /* DHT length */ + headerLength = jpegd_get_two_bytes(pStream); + JPEGD_VERBOSE_LOG("Length of Define Huffman Table is %d", headerLength); + if (headerLength == STRM_ERROR || + ((pStream->readBits + ((headerLength * 8) - 16)) > (8 * pStream->streamLength))) { + JPEGD_ERROR_LOG("readBits:%d, headerLength:%d, streamLength:%d", pStream->readBits, headerLength, pStream->streamLength); + errorCode = 1; + break; + } + /* jump over DHT header */ + if (headerLength != 0) { + pStream->readBits += ((headerLength * 8) - 16); + pStream->pCurrPos += (((headerLength * 8) - 16) / 8); + } + break; + } + case DRI: { + JPEGD_VERBOSE_LOG("DRI, currentByte:0x%x", currentByte); + /* DRI length */ + headerLength = jpegd_get_two_bytes(pStream); + JPEGD_VERBOSE_LOG("Length of Define Restart Interval(must be 4 Bytes) is %d", headerLength); + if (headerLength == STRM_ERROR || + ((pStream->readBits + ((headerLength * 8) - 16)) > (8 * pStream->streamLength))) { + JPEGD_ERROR_LOG("readBits:%d, headerLength:%d, streamLength:%d", pStream->readBits, headerLength, pStream->streamLength); + errorCode = 1; + break; + } + + headerLength = jpegd_get_two_bytes(pStream); + JPEGD_VERBOSE_LOG("Restart Interval:%d", headerLength); + if (headerLength == STRM_ERROR || + ((pStream->readBits + ((headerLength * 8) - 16)) > (8 * pStream->streamLength))) { + /* may optimize one day */ + JPEGD_ERROR_LOG("readBits:%d, headerLength:%d, streamLength:%d", pStream->readBits, headerLength, pStream->streamLength); + errorCode = 1; + break; + } + pSyntax->frame.Ri = headerLength; + break; + } + case APP0: { /* application segments */ + JPEGD_VERBOSE_LOG("APP0, currentByte:0x%x", currentByte); + /* reset */ + appBits = 0; + appLength = 0; + pStream->appnFlag = 0; + + /* APP0 length */ + headerLength = jpegd_get_two_bytes(pStream); + JPEGD_VERBOSE_LOG("headerLength:%d", headerLength); + if (headerLength == STRM_ERROR || + ((pStream->readBits + ((headerLength * 8) - 16)) > (8 * pStream->streamLength))) { + JPEGD_ERROR_LOG("readBits:%d, headerLength:%d, streamLength:%d", pStream->readBits, headerLength, pStream->streamLength); + errorCode = 1; + break; + } + + appLength = headerLength; + if (appLength < 16) { + pStream->appnFlag = 1; + if (jpegd_flush_bits(pStream, ((appLength * 8) - 16)) == STRM_ERROR) { + JPEGD_ERROR_LOG("flush bits failed"); + errorCode = 1; + break; + } + break; + } + appBits += 16; + + /* check identifier: 0x4A 0x46 0x49 0x46 0x00 */ + currentBytes = jpegd_get_two_bytes(pStream); + JPEGD_VERBOSE_LOG("currentBytes:%x", currentBytes); + appBits += 16; + if (currentBytes != 0x4A46) { + pStream->appnFlag = 1; + if (jpegd_flush_bits(pStream, ((appLength * 8) - appBits)) == STRM_ERROR) { + JPEGD_ERROR_LOG("flush bits failed"); + errorCode = 1; + break; + } + break; + } + + currentBytes = jpegd_get_two_bytes(pStream); + JPEGD_VERBOSE_LOG("currentBytes:%x", currentBytes); + appBits += 16; + if (currentBytes != 0x4946 && currentBytes != 0x5858) { + pStream->appnFlag = 1; + if (jpegd_flush_bits(pStream, ((appLength * 8) - appBits)) == STRM_ERROR) { + JPEGD_ERROR_LOG("flush bits failed"); + errorCode = 1; + break; + } + break; + } + + /* APP0 Extended */ + if (currentBytes == 0x5858) { + JPEGD_VERBOSE_LOG("APP0 Extended"); + thumbnail = 1; + } + currentByte = jpegd_get_byte(pStream); + JPEGD_VERBOSE_LOG("currentBytes:%x", currentBytes); + appBits += 8; + if (currentByte != 0x00) { + pStream->appnFlag = 1; + if (jpegd_flush_bits(pStream, ((appLength * 8) - appBits)) == STRM_ERROR) { + JPEGD_ERROR_LOG("flush bits failed"); + errorCode = 1; + break; + } + pStream->appnFlag = 0; + break; + } + + /* APP0 Extended thumb type */ + if (thumbnail) { + /* extension code */ + currentByte = jpegd_get_byte(pStream); + JPEGD_VERBOSE_LOG("APP0 Extended thumb type, currentBytes:%x", currentBytes); + if (currentByte == JPEGDEC_THUMBNAIL_JPEG) { + pImageInfo->thumbnailType = JPEGDEC_THUMBNAIL_JPEG; + appBits += 8; + pStream->appnFlag = 1; + + /* check thumbnail data */ + Hmax = 0; + Vmax = 0; + + /* Read decoding parameters */ + for (; (pStream->readBits / 8) < pStream->streamLength; pStream->readBits++) { + appBits += 8; /* Look for marker prefix byte from stream */ + if (jpegd_get_byte(pStream) == 0xFF) { + appBits += 8; + + currentByte = jpegd_get_byte(pStream); + switch (currentByte) { /* switch to certain header decoding */ + case SOF0: /* baseline marker */ + case SOF2: { /* progresive marker */ + if (currentByte == SOF0) + pImageInfo->codingModeThumb = pSyntax->info.operationTypeThumb = JPEGDEC_BASELINE; + else + pImageInfo->codingModeThumb = pSyntax->info.operationTypeThumb = JPEGDEC_PROGRESSIVE; + + /* Frame header */ + i++; + + /* jump over Lf field */ + if (jpegd_flush_bits(pStream, 16) == STRM_ERROR) { + errorCode = 1; + break; + } + appBits += 16; + + /* Sample precision (only 8 bits/sample supported) */ + currentByte = jpegd_get_byte(pStream); + appBits += 8; + if (currentByte != 8) { + JPEGD_ERROR_LOG("Thumbnail Sample precision"); + return (JPEGDEC_UNSUPPORTED); + } + + /* Number of Lines */ + pImageInfo->outputHeightThumb = jpegd_get_two_bytes(pStream); + appBits += 16; + pImageInfo->displayHeightThumb = pImageInfo->outputHeightThumb; + if (pImageInfo->outputHeightThumb < 1) { + JPEGD_ERROR_LOG("pImageInfo->outputHeightThumb unsupported"); + return (JPEGDEC_UNSUPPORTED); + } + + /* round up to next multiple-of-16 */ + pImageInfo->outputHeightThumb += 0xf; + pImageInfo->outputHeightThumb &= ~(0xf); + + /* Number of Samples per Line */ + pImageInfo->outputWidthThumb = jpegd_get_two_bytes(pStream); + appBits += 16; + pImageInfo->displayWidthThumb = pImageInfo->outputWidthThumb; + if (pImageInfo->outputWidthThumb < 1) { + JPEGD_ERROR_LOG("pImageInfo->outputWidthThumb unsupported"); + return (JPEGDEC_UNSUPPORTED); + } + + pImageInfo->outputWidthThumb += 0xf; + pImageInfo->outputWidthThumb &= ~(0xf); + if (pImageInfo->outputWidthThumb < pCtx->minSupportedWidth || + pImageInfo->outputHeightThumb < pCtx->minSupportedHeight || + pImageInfo->outputWidthThumb > JPEGDEC_MAX_WIDTH_TN || + pImageInfo->outputHeightThumb > JPEGDEC_MAX_HEIGHT_TN) { + JPEGD_ERROR_LOG("Thumbnail Unsupported size"); + return (JPEGDEC_UNSUPPORTED); + } + + /* Number of Image Components per Frame */ + Nf = jpegd_get_byte(pStream); + appBits += 8; + if (Nf != 3 && Nf != 1) { + JPEGD_ERROR_LOG("Thumbnail Number of Image Components per Frame"); + return (JPEGDEC_UNSUPPORTED); + } + for (j = 0; j < Nf; j++) { + /* jump over component identifier */ + if (jpegd_flush_bits(pStream, 8) == STRM_ERROR) { + errorCode = 1; + break; + } + appBits += 8; + + currentByte = jpegd_get_byte(pStream); + appBits += 8; + Htn[j] = (currentByte >> 4); /* Horizontal sampling factor */ + Vtn[j] = (currentByte & 0xF); /* Vertical sampling factor */ + + if (jpegd_flush_bits(pStream, 8) == STRM_ERROR) { /* jump over Tq */ + errorCode = 1; + break; + } + appBits += 8; + + if (Htn[j] > Hmax) + Hmax = Htn[j]; + if (Vtn[j] > Vmax) + Vmax = Vtn[j]; + } + if (Hmax == 0 || Vmax == 0) { + JPEGD_ERROR_LOG("Thumbnail Hmax == 0 || Vmax == 0"); + return (JPEGDEC_UNSUPPORTED); + } + + /* check format */ + if (Htn[0] == 2 && Vtn[0] == 2 && + Htn[1] == 1 && Vtn[1] == 1 && Htn[2] == 1 && Vtn[2] == 1) { + pImageInfo->outputFormatThumb = MPP_FMT_YUV420SP; + } else if (Htn[0] == 2 && Vtn[0] == 1 && + Htn[1] == 1 && Vtn[1] == 1 && Htn[2] == 1 && Vtn[2] == 1) { + pImageInfo->outputFormatThumb = MPP_FMT_YUV422SP; + } else if (Htn[0] == 1 && Vtn[0] == 2 && + Htn[1] == 1 && Vtn[1] == 1 && Htn[2] == 1 && Vtn[2] == 1) { + pImageInfo->outputFormatThumb = JPEGDEC_YCbCr440; + } else if (Htn[0] == 1 && Vtn[0] == 1 && + Htn[1] == 0 && Vtn[1] == 0 && Htn[2] == 0 && Vtn[2] == 0) { + pImageInfo->outputFormatThumb = JPEGDEC_YCbCr400; + } else if (Htn[0] == 4 && Vtn[0] == 1 && + Htn[1] == 1 && Vtn[1] == 1 && Htn[2] == 1 && Vtn[2] == 1) { + pImageInfo->outputFormatThumb = JPEGDEC_YCbCr411_SEMIPLANAR; + } else if (Htn[0] == 1 && Vtn[0] == 1 && + Htn[1] == 1 && Vtn[1] == 1 && Htn[2] == 1 && Vtn[2] == 1) { + pImageInfo->outputFormatThumb = JPEGDEC_YCbCr444_SEMIPLANAR; + } else { + JPEGD_ERROR_LOG("Thumbnail Unsupported YCbCr format"); + return (JPEGDEC_UNSUPPORTED); + } + pSyntax->info.initThumb = 1; + initThumb = 1; + break; + } + case SOS: { + /* SOS length */ + headerLength = jpegd_get_two_bytes(pStream); + if (headerLength == STRM_ERROR || + ((pStream->readBits + ((headerLength * 8) - 16)) > (8 * pStream->streamLength))) { + errorCode = 1; + break; + } + + /* check if interleaved or non-ibnterleaved */ + NsThumb = jpegd_get_byte(pStream); + if (NsThumb == MIN_NUMBER_OF_COMPONENTS && + pImageInfo->outputFormatThumb != JPEGDEC_YCbCr400 && + pImageInfo->codingModeThumb == JPEGDEC_BASELINE) { + pImageInfo->codingModeThumb = pSyntax->info.operationTypeThumb = JPEGDEC_NONINTERLEAVED; + } + + /* jump over SOS header */ + if (headerLength != 0) { + pStream->readBits += ((headerLength * 8) - 16); + pStream->pCurrPos += (((headerLength * 8) - 16) / 8); + } + + if ((pStream->readBits + 8) < (8 * pStream->streamLength)) { + pSyntax->info.init = 1; + init = 1; + } else { + JPEGD_ERROR_LOG("Needs to increase input buffer"); + return (JPEGDEC_INCREASE_INPUT_BUFFER); + } + break; + } + case DQT: { + /* DQT length */ + headerLength = jpegd_get_two_bytes(pStream); + if (headerLength == STRM_ERROR) { + errorCode = 1; + break; + } + /* jump over DQT header */ + if (headerLength != 0) { + pStream->readBits += ((headerLength * 8) - 16); + pStream->pCurrPos += (((headerLength * 8) - 16) / 8); + } + appBits += (headerLength * 8); + break; + } + case DHT: { + /* DHT length */ + headerLength = jpegd_get_two_bytes(pStream); + if (headerLength == STRM_ERROR) { + errorCode = 1; + break; + } + /* jump over DHT header */ + if (headerLength != 0) { + pStream->readBits += ((headerLength * 8) - 16); + pStream->pCurrPos += (((headerLength * 8) - 16) / 8); + } + appBits += (headerLength * 8); + break; + } + case DRI: { + /* DRI length */ + headerLength = jpegd_get_two_bytes(pStream); + if (headerLength == STRM_ERROR) { + errorCode = 1; + break; + } + /* jump over DRI header */ + if (headerLength != 0) { + pStream->readBits += ((headerLength * 8) - 16); + pStream->pCurrPos += (((headerLength * 8) - 16) / 8); + } + appBits += (headerLength * 8); + break; + } + case APP0: + case APP1: + case APP2: + case APP3: + case APP4: + case APP5: + case APP6: + case APP7: + case APP8: + case APP9: + case APP10: + case APP11: + case APP12: + case APP13: + case APP14: + case APP15: { + /* APPn length */ + headerLength = jpegd_get_two_bytes(pStream); + if (headerLength == STRM_ERROR) { + errorCode = 1; + break; + } + /* jump over APPn header */ + if (headerLength != 0) { + pStream->readBits += ((headerLength * 8) - 16); + pStream->pCurrPos += (((headerLength * 8) - 16) / 8); + } + appBits += (headerLength * 8); + break; + } + case DNL: { + /* DNL length */ + headerLength = jpegd_get_two_bytes(pStream); + if (headerLength == STRM_ERROR) { + errorCode = 1; + break; + } + /* jump over DNL header */ + if (headerLength != 0) { + pStream->readBits += ((headerLength * 8) - 16); + pStream->pCurrPos += (((headerLength * 8) - 16) / 8); + } + appBits += (headerLength * 8); + break; + } + case COM: { + /* COM length */ + headerLength = jpegd_get_two_bytes(pStream); + if (headerLength == STRM_ERROR) { + errorCode = 1; + break; + } + /* jump over COM header */ + if (headerLength != 0) { + pStream->readBits += ((headerLength * 8) - 16); + pStream->pCurrPos += (((headerLength * 8) - 16) / 8); + } + appBits += (headerLength * 8); + break; + } + case SOF1: /* unsupported coding styles */ + case SOF3: + case SOF5: + case SOF6: + case SOF7: + case SOF9: + case SOF10: + case SOF11: + case SOF13: + case SOF14: + case SOF15: + case DAC: + case DHP: { + JPEGD_ERROR_LOG("Unsupported coding styles"); + return (JPEGDEC_UNSUPPORTED); + } + default: + break; + } + + if (pSyntax->info.initThumb && initThumb) { + /* flush the rest of thumbnail data */ + if (jpegd_flush_bits(pStream, ((appLength * 8) - appBits)) == STRM_ERROR) { + errorCode = 1; + break; + } + pStream->appnFlag = 0; + break; + } + } else { + if (!pSyntax->info.initThumb && pCtx->bufferSize) + return (JPEGDEC_INCREASE_INPUT_BUFFER); + else + return (JPEGDEC_STRM_ERROR); + } + } + break; + } else { + appBits += 8; + pImageInfo->thumbnailType = JPEGDEC_THUMBNAIL_NOT_SUPPORTED_FORMAT; + pStream->appnFlag = 1; + if (jpegd_flush_bits(pStream, ((appLength * 8) - appBits)) == STRM_ERROR) { + errorCode = 1; + break; + } + pStream->appnFlag = 0; + break; + } + } else { + /* version */ + pImageInfo->version = jpegd_get_two_bytes(pStream); + JPEGD_VERBOSE_LOG("APP0, version:%x", pImageInfo->version); + appBits += 16; + + /* units */ + currentByte = jpegd_get_byte(pStream); + if (currentByte == 0) { + pImageInfo->units = JPEGDEC_NO_UNITS; + } else if (currentByte == 1) { + pImageInfo->units = JPEGDEC_DOTS_PER_INCH; + } else if (currentByte == 2) { + pImageInfo->units = JPEGDEC_DOTS_PER_CM; + } + appBits += 8; + + /* Xdensity */ + pImageInfo->xDensity = jpegd_get_two_bytes(pStream); + appBits += 16; + + /* Ydensity */ + pImageInfo->yDensity = jpegd_get_two_bytes(pStream); + appBits += 16; + + /* jump over rest of header data */ + pStream->appnFlag = 1; + if (jpegd_flush_bits(pStream, ((appLength * 8) - appBits)) == STRM_ERROR) { + errorCode = 1; + break; + } + pStream->appnFlag = 0; + break; + } + } + case APP1: + case APP2: + case APP3: + case APP4: + case APP5: + case APP6: + case APP7: + case APP8: + case APP9: + case APP10: + case APP11: + case APP12: + case APP13: + case APP14: + case APP15: { + JPEGD_VERBOSE_LOG("APPn, currentByte:0x%x", currentByte); + /* APPn length */ + headerLength = jpegd_get_two_bytes(pStream); + JPEGD_VERBOSE_LOG("APPn length, headerLength:%x", headerLength); + if (headerLength == STRM_ERROR || + ((pStream->readBits + ((headerLength * 8) - 16)) > (8 * pStream->streamLength))) { + JPEGD_ERROR_LOG("readBits:%d, headerLength:%d, streamLength:%d", pStream->readBits, headerLength, pStream->streamLength); + errorCode = 1; + break; + } + /* jump over APPn header */ + if (headerLength != 0) { + pStream->readBits += ((headerLength * 8) - 16); + pStream->pCurrPos += (((headerLength * 8) - 16) / 8); + } + break; + } + case DNL: { + JPEGD_VERBOSE_LOG("DNL, currentByte:0x%x", currentByte); + /* DNL length */ + headerLength = jpegd_get_two_bytes(pStream); + JPEGD_VERBOSE_LOG("DNL, headerLength:%x", headerLength); + if (headerLength == STRM_ERROR || + ((pStream->readBits + ((headerLength * 8) - 16)) > (8 * pStream->streamLength))) { + JPEGD_ERROR_LOG("readBits:%d, headerLength:%d, streamLength:%d", pStream->readBits, headerLength, pStream->streamLength); + errorCode = 1; + break; + } + /* jump over DNL header */ + if (headerLength != 0) { + pStream->readBits += ((headerLength * 8) - 16); + pStream->pCurrPos += (((headerLength * 8) - 16) / 8); + } + break; + } + case COM: { + JPEGD_VERBOSE_LOG("COM, currentByte:0x%x", currentByte); + headerLength = jpegd_get_two_bytes(pStream); + JPEGD_VERBOSE_LOG("COM, headerLength:%x", headerLength); + if (headerLength == STRM_ERROR || + ((pStream->readBits + ((headerLength * 8) - 16)) > (8 * pStream->streamLength))) { + JPEGD_ERROR_LOG("readBits:%d, headerLength:%d, streamLength:%d", pStream->readBits, headerLength, pStream->streamLength); + errorCode = 1; + break; + } + /* jump over COM header */ + if (headerLength != 0) { + pStream->readBits += ((headerLength * 8) - 16); + pStream->pCurrPos += (((headerLength * 8) - 16) / 8); + } + break; + } + case SOF1: /* unsupported coding styles */ + case SOF3: + case SOF5: + case SOF6: + case SOF7: + case SOF9: + case SOF10: + case SOF11: + case SOF13: + case SOF14: + case SOF15: + case DAC: + case DHP: { + JPEGD_ERROR_LOG("SOF, currentByte:0x%x", currentByte); + JPEGD_ERROR_LOG("Unsupported coding styles"); + return (JPEGDEC_UNSUPPORTED); + } + default: + break; + } + if (pSyntax->info.init && init) + break; + + if (errorCode) { + if (pCtx->bufferSize) { + JPEGD_ERROR_LOG("get image info failed!"); + return (JPEGDEC_INCREASE_INPUT_BUFFER); + } else { + JPEGD_ERROR_LOG("Stream error"); + return (JPEGDEC_STRM_ERROR); + } + } + } else { + JPEGD_ERROR_LOG("Could not get marker"); + if (!pSyntax->info.init) + return (JPEGDEC_INCREASE_INPUT_BUFFER); + else + return (JPEGDEC_STRM_ERROR); + } + } + + FUN_TEST("Exit"); + return MPP_OK; +} + +MPP_RET jpegd_get_image_info(JpegParserContext *ctx) +{ + FUN_TEST("Enter"); + JpegParserContext *pCtx = ctx; + if (NULL == pCtx) { + JPEGD_ERROR_LOG("NULL pointer"); + return MPP_ERR_NULL_PTR; + } + + MPP_RET ret = MPP_OK; + JpegSyntaxParam *pSyntax = pCtx->pSyntax; + StreamStorage stream; + + if (pCtx->streamLength < 1) { + JPEGD_ERROR_LOG("streamLength:%d", pCtx->streamLength); + return MPP_ERR_VALUE; + } + + if ((pCtx->streamLength > DEC_MAX_STREAM) && + (pCtx->bufferSize < JPEGDEC_MIN_BUFFER || pCtx->bufferSize > JPEGDEC_MAX_BUFFER)) { + JPEGD_ERROR_LOG("bufferSize = %d,streamLength = %d\n", pCtx->bufferSize, pCtx->streamLength); + return MPP_ERR_VALUE; + } + + if (pCtx->bufferSize && (pCtx->bufferSize < JPEGDEC_MIN_BUFFER || + pCtx->bufferSize > JPEGDEC_MAX_BUFFER)) { + JPEGD_ERROR_LOG("bufferSize = %d\n", pCtx->bufferSize); + return MPP_ERR_VALUE; + } + + pSyntax->imageInfo.thumbnailType = JPEGDEC_NO_THUMBNAIL; + + /* utils initialization */ + stream.bitPosInByte = 0; + stream.pCurrPos = (RK_U8 *)mpp_packet_get_data(pCtx->input_packet); + stream.pStartOfStream = (RK_U8 *)mpp_packet_get_data(pCtx->input_packet); + stream.streamLength = (RK_U32)mpp_packet_get_size(pCtx->input_packet); + stream.readBits = 0; + stream.appnFlag = 0; + + ret = jpegd_read_decode_parameters(pCtx, &stream); + if (ret != MPP_OK) { + JPEGD_ERROR_LOG("read decode parameters failed, ret:%d", ret); + return ret; + } + + FUN_TEST("Exit"); + return ret; +} + +MPP_RET jpegd_decode_frame_impl(JpegParserContext *ctx) +{ + FUN_TEST("Enter"); + JpegParserContext *pCtx = ctx; + if (NULL == pCtx) { + JPEGD_ERROR_LOG("NULL pointer"); + return MPP_ERR_NULL_PTR; + } + + RK_U32 i = 0; + RK_U32 currentByte = 0; + RK_U32 currentBytes = 0; + RK_U32 appLength = 0; + RK_U32 appBits = 0; + JpegDecRet retCode; + RK_U32 findhufftable = 0; + + JpegSyntaxParam *pSyntax = pCtx->pSyntax; + StreamStorage *pStream = (StreamStorage *) & (pSyntax->stream); + + do { + /* if slice mode/slice done return to hw handling */ + if (pSyntax->image.headerReady && pSyntax->info.SliceReadyForPause) + break; + + /* Look for marker prefix byte from stream */ + if ((currentByte == 0xFF) || (jpegd_get_byte(pStream) == 0xFF)) { + currentByte = jpegd_get_byte(pStream); + + /* switch to certain header decoding */ + switch (currentByte) { + case 0x00: { + JPEGD_VERBOSE_LOG("currentByte:0x00"); + break; + } + case SOF0: + case SOF2: { + JPEGD_VERBOSE_LOG("SOF, currentByte:0x%x", currentByte); + /* Baseline/Progressive */ + pSyntax->frame.codingType = currentByte; + /* Set operation type */ + if (pSyntax->frame.codingType == SOF0) + pSyntax->info.operationType = JPEGDEC_BASELINE; + else + pSyntax->info.operationType = JPEGDEC_PROGRESSIVE; + + retCode = jpegd_decode_frame_header(pCtx); + if (retCode != JPEGDEC_OK) { + if (retCode == JPEGDEC_STRM_ERROR) { + JPEGD_ERROR_LOG("Stream Error"); + return (retCode); + } else { + JPEGD_ERROR_LOG("Decode Frame Header Error"); + return (retCode); + } + } + break; + } + case SOS: { /* Start of Scan */ + JPEGD_VERBOSE_LOG("SOS, currentByte:0x%x", currentByte); + /* reset image ready */ + pSyntax->image.imageReady = 0; + retCode = jpegd_decode_scan(pCtx); + pSyntax->image.headerReady = 1; + if (retCode != JPEGDEC_OK) { + if (retCode == JPEGDEC_STRM_ERROR) { + JPEGD_ERROR_LOG("Stream Error"); + return (retCode); + } else { + JPEGD_ERROR_LOG("Decode Scan Error\n"); + return (retCode); + } + } + + if (pSyntax->stream.bitPosInByte) { + /* delete stuffing bits */ + currentByte = (8 - pSyntax->stream.bitPosInByte); + if (jpegd_flush_bits(pStream, 8 - pSyntax->stream.bitPosInByte) == STRM_ERROR) { + JPEGD_ERROR_LOG("Stream Error"); + return (JPEGDEC_STRM_ERROR); + } + } + JPEGD_VERBOSE_LOG("Stuffing bits deleted\n"); + break; + } + case DHT: { /* Start of Huffman tables */ + JPEGD_VERBOSE_LOG("DHT, currentByte:0x%x", currentByte); + retCode = jpegd_decode_huffman_tables(pCtx); + if (retCode != JPEGDEC_OK) { + if (retCode == JPEGDEC_STRM_ERROR) { + JPEGD_ERROR_LOG("Stream Error"); + return (retCode); + } else { + JPEGD_ERROR_LOG("Decode Huffman Tables Error"); + return (retCode); + } + } + findhufftable = 1; + break; + } + case DQT: { /* start of Quantisation Tables */ + JPEGD_VERBOSE_LOG("DQT, currentByte:0x%x", currentByte); + retCode = jpegd_decode_quant_tables(pCtx); + if (retCode != JPEGDEC_OK) { + if (retCode == JPEGDEC_STRM_ERROR) { + JPEGD_ERROR_LOG("Stream Error"); + return (retCode); + } else { + JPEGD_ERROR_LOG("Decode Quant Tables Error"); + return (retCode); + } + } + break; + } + case SOI: { /* Start of Image */ + /* no actions needed, continue */ + break; + } + case EOI: { /* End of Image */ + JPEGD_VERBOSE_LOG("EOI, currentByte:0x%x", currentByte); + if (pSyntax->image.imageReady) { + JPEGD_ERROR_LOG("EOI: OK\n"); + return (JPEGDEC_FRAME_READY); + } else { + JPEGD_ERROR_LOG("EOI: NOK\n"); + return (JPEGDEC_ERROR); + } + } + case DRI: { /* Define Restart Interval */ + JPEGD_VERBOSE_LOG("DRI, currentByte:0x%x", currentByte); + currentBytes = jpegd_get_two_bytes(pStream); + if (currentBytes == STRM_ERROR) { + JPEGD_ERROR_LOG("Read bits "); + return (JPEGDEC_STRM_ERROR); + } + pSyntax->frame.Ri = jpegd_get_two_bytes(pStream); + break; + } + case RST0: /* Restart with modulo 8 count m */ + case RST1: + case RST2: + case RST3: + case RST4: + case RST5: + case RST6: + case RST7: { + JPEGD_VERBOSE_LOG("RST, currentByte:0x%x", currentByte); + /* initialisation of DC predictors to zero value !!! */ + for (i = 0; i < MAX_NUMBER_OF_COMPONENTS; i++) { + pSyntax->scan.pred[i] = 0; + } + break; + } + case DNL: /* unsupported features */ + case SOF1: + case SOF3: + case SOF5: + case SOF6: + case SOF7: + case SOF9: + case SOF10: + case SOF11: + case SOF13: + case SOF14: + case SOF15: + case DAC: + case DHP: + case TEM: { + JPEGD_ERROR_LOG("Unsupported Features, currentByte:0x%x", currentByte); + return (JPEGDEC_UNSUPPORTED); + } + case APP0: { /* application data & comments */ + JPEGD_VERBOSE_LOG("APP0, currentByte:0x%x", currentByte); + /* APP0 Extended Thumbnail */ + if (pCtx->decImageType == JPEGDEC_THUMBNAIL) { + /* reset */ + appBits = 0; + appLength = 0; + + /* length */ + appLength = jpegd_get_two_bytes(pStream); + appBits += 16; + + /* check identifier */ + currentBytes = jpegd_get_two_bytes(pStream); + appBits += 16; + if (currentBytes != 0x4A46) { + pSyntax->stream.appnFlag = 1; + if (jpegd_flush_bits(pStream, ((appLength * 8) - appBits)) == STRM_ERROR) { + JPEGD_ERROR_LOG("Stream Error"); + return (JPEGDEC_STRM_ERROR); + } + pSyntax->stream.appnFlag = 0; + break; + } + + currentBytes = jpegd_get_two_bytes(pStream); + appBits += 16; + if (currentBytes != 0x5858) { + pSyntax->stream.appnFlag = 1; + if (jpegd_flush_bits(pStream, ((appLength * 8) - appBits)) == STRM_ERROR) { + JPEGD_ERROR_LOG("Stream Error"); + return (JPEGDEC_STRM_ERROR); + } + pSyntax->stream.appnFlag = 0; + break; + } + + currentByte = jpegd_get_byte(pStream); + appBits += 8; + if (currentByte != 0x00) { + pSyntax->stream.appnFlag = 1; + if (jpegd_flush_bits(pStream, ((appLength * 8) - appBits)) == STRM_ERROR) { + JPEGD_ERROR_LOG("Stream Error"); + return (JPEGDEC_STRM_ERROR); + } + pSyntax->stream.appnFlag = 0; + break; + } + + /* extension code */ + currentByte = jpegd_get_byte(pStream); + pSyntax->stream.appnFlag = 0; + if (currentByte != JPEGDEC_THUMBNAIL_JPEG) { + JPEGD_ERROR_LOG("thumbnail unsupported"); + return (JPEGDEC_UNSUPPORTED); + } + + /* thumbnail mode */ + JPEGD_VERBOSE_LOG("Thumbnail data ok!"); + pSyntax->stream.thumbnail = 1; + break; + } else { + /* Flush unsupported thumbnail */ + currentBytes = jpegd_get_two_bytes(pStream); + pSyntax->stream.appnFlag = 1; + if (jpegd_flush_bits(pStream, ((currentBytes - 2) * 8)) == STRM_ERROR) { + JPEGD_ERROR_LOG("Stream Error"); + return (JPEGDEC_STRM_ERROR); + } + pSyntax->stream.appnFlag = 0; + break; + } + } + case APP1: + case APP2: + case APP3: + case APP4: + case APP5: + case APP6: + case APP7: + case APP8: + case APP9: + case APP10: + case APP11: + case APP12: + case APP13: + case APP14: + case APP15: + case COM: { + JPEGD_VERBOSE_LOG("APPn, currentByte:0x%x", currentByte); + currentBytes = jpegd_get_two_bytes(pStream); + if (currentBytes == STRM_ERROR) { + JPEGD_ERROR_LOG("Read bits "); + return (JPEGDEC_STRM_ERROR); + } + /* jump over not supported header */ + if (currentBytes != 0) { + pSyntax->stream.readBits += ((currentBytes * 8) - 16); + pSyntax->stream.pCurrPos += (((currentBytes * 8) - 16) / 8); + } + break; + } + default: + break; + } + } else { + if (currentByte == 0xFFFFFFFF) { + break; + } + } + + if (pSyntax->image.headerReady) + break; + } while ((pSyntax->stream.readBits >> 3) <= pSyntax->stream.streamLength); + + if (!findhufftable) { + JPEGD_VERBOSE_LOG("do not find Huffman Tables"); + jpegd_default_huffman_tables(pCtx); + } + + return MPP_OK; + FUN_TEST("Exit"); +} + +MPP_RET jpegd_allocate_frame(JpegParserContext *ctx) +{ + FUN_TEST("Enter"); + JpegParserContext *pCtx = ctx; + if (NULL == pCtx) { + JPEGD_ERROR_LOG("NULL pointer"); + return MPP_ERR_NULL_PTR; + } + + if (pCtx->frame_slot_index == -1) { + mpp_frame_set_width(pCtx->output_frame, pCtx->pSyntax->frame.X); + mpp_frame_set_height(pCtx->output_frame, pCtx->pSyntax->frame.Y); + mpp_frame_set_hor_stride(pCtx->output_frame, pCtx->pSyntax->frame.X); + mpp_frame_set_ver_stride(pCtx->output_frame, pCtx->pSyntax->frame.Y); + mpp_frame_set_pts(pCtx->output_frame, pCtx->pts); + + mpp_buf_slot_get_unused(pCtx->frame_slots, &pCtx->frame_slot_index); + JPEGD_INFO_LOG("frame_slot_index:%d, X:%d, Y:%d", pCtx->frame_slot_index, pCtx->pSyntax->frame.X, pCtx->pSyntax->frame.Y); + + mpp_buf_slot_set_prop(pCtx->frame_slots, pCtx->frame_slot_index, SLOT_FRAME, pCtx->output_frame); + mpp_buf_slot_set_flag(pCtx->frame_slots, pCtx->frame_slot_index, SLOT_CODEC_USE); + mpp_buf_slot_set_flag(pCtx->frame_slots, pCtx->frame_slot_index, SLOT_HAL_OUTPUT); + } + + FUN_TEST("Exit"); + return MPP_OK; +} + +MPP_RET jpegd_update_frame(JpegParserContext *ctx) +{ + FUN_TEST("Enter"); + JpegParserContext *pCtx = ctx; + if (NULL == pCtx) { + JPEGD_ERROR_LOG("NULL pointer"); + return MPP_ERR_NULL_PTR; + } + + mpp_buf_slot_set_flag(pCtx->frame_slots, pCtx->frame_slot_index, SLOT_QUEUE_USE); + mpp_buf_slot_enqueue(pCtx->frame_slots, pCtx->frame_slot_index, QUEUE_DISPLAY); + mpp_buf_slot_clr_flag(pCtx->frame_slots, pCtx->frame_slot_index, SLOT_CODEC_USE); + pCtx->frame_slot_index = -1; + + FUN_TEST("Exit"); + return MPP_OK; +} + +MPP_RET jpegd_decode_frame(JpegParserContext *ctx) +{ + FUN_TEST("Enter"); + MPP_RET ret = MPP_OK; + JpegParserContext *pCtx = ctx; + if (NULL == pCtx) { + JPEGD_ERROR_LOG("NULL pointer"); + return MPP_ERR_NULL_PTR; + } + + JpegSyntaxParam *pSyntax = pCtx->pSyntax; + + /* Store the stream parameters */ + if (pSyntax->info.progressiveScanReady == 0 && + pSyntax->info.nonInterleavedScanReady == 0) { + pSyntax->stream.bitPosInByte = 0; + pSyntax->stream.pCurrPos = (RK_U8 *) mpp_packet_get_data(pCtx->input_packet); + pSyntax->stream.pStartOfStream = (RK_U8 *)mpp_packet_get_data(pCtx->input_packet); + pSyntax->stream.readBits = 0; + pSyntax->stream.streamLength = (RK_U32)mpp_packet_get_size(pCtx->input_packet); + pSyntax->stream.appnFlag = 0; + } else { + pSyntax->image.headerReady = 0; + } + + if (pSyntax->info.operationType == JPEGDEC_PROGRESSIVE) { + JPEGD_ERROR_LOG ("Operation type not supported"); + return (JPEGDEC_UNSUPPORTED); + } + + /* check if frame size over 16M */ + if ((pSyntax->frame.hwX * pSyntax->frame.hwY) > JPEGDEC_MAX_PIXEL_AMOUNT) { + JPEGD_ERROR_LOG ("Resolution > 16M ==> use slice mode!"); + return (JPEGDEC_PARAM_ERROR); + } + + /* check if input streaming used */ + if (!pSyntax->info.SliceReadyForPause && + !pSyntax->info.inputBufferEmpty && pCtx->bufferSize) { + pSyntax->info.inputStreaming = 1; + pSyntax->info.inputBufferLen = pCtx->bufferSize; + pSyntax->info.decodedStreamLen += pSyntax->info.inputBufferLen; + } + + ret = jpegd_decode_frame_impl(pCtx); + + FUN_TEST("Exit"); + return ret; +} + +void jpegd_free_huffman_tables(void *ctx) +{ + FUN_TEST("Enter"); + JpegParserContext *JpegParserCtx = (JpegParserContext *)ctx; + + if (JpegParserCtx->pSyntax->vlc.acTable0.vals) { + mpp_free(JpegParserCtx->pSyntax->vlc.acTable0.vals); + JpegParserCtx->pSyntax->vlc.acTable0.vals = NULL; + } + + if (JpegParserCtx->pSyntax->vlc.acTable1.vals) { + mpp_free(JpegParserCtx->pSyntax->vlc.acTable1.vals); + JpegParserCtx->pSyntax->vlc.acTable1.vals = NULL; + } + + if (JpegParserCtx->pSyntax->vlc.acTable2.vals) { + mpp_free(JpegParserCtx->pSyntax->vlc.acTable2.vals); + JpegParserCtx->pSyntax->vlc.acTable2.vals = NULL; + } + + if (JpegParserCtx->pSyntax->vlc.acTable3.vals) { + mpp_free(JpegParserCtx->pSyntax->vlc.acTable3.vals); + JpegParserCtx->pSyntax->vlc.acTable3.vals = NULL; + } + + if (JpegParserCtx->pSyntax->vlc.dcTable0.vals) { + mpp_free(JpegParserCtx->pSyntax->vlc.dcTable0.vals); + JpegParserCtx->pSyntax->vlc.dcTable0.vals = NULL; + } + + if (JpegParserCtx->pSyntax->vlc.dcTable1.vals) { + mpp_free(JpegParserCtx->pSyntax->vlc.dcTable1.vals); + JpegParserCtx->pSyntax->vlc.dcTable1.vals = NULL; + } + + if (JpegParserCtx->pSyntax->vlc.dcTable2.vals) { + mpp_free(JpegParserCtx->pSyntax->vlc.dcTable2.vals); + JpegParserCtx->pSyntax->vlc.dcTable2.vals = NULL; + } + + if (JpegParserCtx->pSyntax->vlc.dcTable3.vals) { + mpp_free(JpegParserCtx->pSyntax->vlc.dcTable3.vals); + JpegParserCtx->pSyntax->vlc.dcTable3.vals = NULL; + } + + FUN_TEST("Exit"); +} + + +MPP_RET jpegd_parse(void *ctx, HalDecTask *task) +{ + FUN_TEST("Enter"); + MPP_RET ret = MPP_OK; + JpegParserContext *JpegParserCtx = (JpegParserContext *)ctx; + task->valid = 0; + + jpegd_free_huffman_tables(JpegParserCtx); + memset(JpegParserCtx->pSyntax, 0, sizeof(JpegSyntaxParam)); + jpegd_get_image_info(JpegParserCtx); + ret = jpegd_decode_frame(JpegParserCtx); + + if (MPP_OK == ret) { + jpegd_allocate_frame(JpegParserCtx); + task->syntax.data = (void *)JpegParserCtx->pSyntax; + task->syntax.number = sizeof(JpegSyntaxParam); + task->output = JpegParserCtx->frame_slot_index; + task->valid = 1; + jpegd_update_frame(JpegParserCtx); + } + + //mpp_show_mem_status(); + + FUN_TEST("Exit"); + return ret; +} + +MPP_RET jpegd_deinit(void *ctx) +{ + FUN_TEST("Enter"); + JpegParserContext *JpegParserCtx = (JpegParserContext *)ctx; + + if (JpegParserCtx->recv_buffer) { + mpp_free(JpegParserCtx->recv_buffer); + JpegParserCtx->recv_buffer = NULL; + } + + jpegd_free_huffman_tables(JpegParserCtx); + + if (JpegParserCtx->pSyntax) { + mpp_free(JpegParserCtx->pSyntax); + JpegParserCtx->pSyntax = NULL; + } + + if (JpegParserCtx->output_frame) { + mpp_free(JpegParserCtx->output_frame); + } + + if (JpegParserCtx->input_packet) { + mpp_packet_deinit(&JpegParserCtx->input_packet); + } + + JpegParserCtx->output_fmt = MPP_FMT_YUV420SP; + JpegParserCtx->pts = 0; + JpegParserCtx->eos = 0; + JpegParserCtx->parser_debug_enable = 0; + JpegParserCtx->input_jpeg_count = 0; + + FUN_TEST("Exit"); + return 0; +} + +MPP_RET reset_jpeg_parser_context(JpegParserContext *ctx) +{ + FUN_TEST("Enter"); + JpegParserContext *pCtx = ctx; + if (NULL == pCtx) { + JPEGD_ERROR_LOG("NULL pointer"); + return MPP_ERR_NULL_PTR; + } + + pCtx->packet_slots = NULL; + pCtx->frame_slots = NULL; + pCtx->recv_buffer = NULL; + + /* resolution */ + pCtx->minSupportedWidth = 0; + pCtx->minSupportedHeight = 0; + pCtx->maxSupportedWidth = 0; + pCtx->maxSupportedHeight = 0; + pCtx->maxSupportedPixelAmount = 0; + pCtx->maxSupportedSliceSize = 0; + + FUN_TEST("Exit"); + return MPP_OK; +} + +MPP_RET jpegd_init(void *ctx, ParserCfg *parser_cfg) +{ + FUN_TEST("Enter"); + JpegParserContext *JpegParserCtx = (JpegParserContext *)ctx; + if (NULL == JpegParserCtx) { + JpegParserCtx = (JpegParserContext *)mpp_calloc(JpegParserContext, 1); + if (NULL == JpegParserCtx) { + JPEGD_ERROR_LOG("NULL pointer"); + return MPP_ERR_NULL_PTR; + } + } + mpp_env_get_u32("jpegd_log", &jpegd_log, JPEGD_ERR_LOG); + + reset_jpeg_parser_context(JpegParserCtx); + JpegParserCtx->frame_slots = parser_cfg->frame_slots; + JpegParserCtx->packet_slots = parser_cfg->packet_slots; + JpegParserCtx->frame_slot_index = -1; + mpp_buf_slot_setup(JpegParserCtx->frame_slots, 16); + + JpegParserCtx->recv_buffer = mpp_calloc(RK_U8, JPEGD_STREAM_BUFF_SIZE); + if (NULL == JpegParserCtx->recv_buffer) { + JPEGD_ERROR_LOG("no memory!"); + return MPP_ERR_NOMEM; + } + JpegParserCtx->bufferSize = JPEGD_STREAM_BUFF_SIZE; + mpp_packet_init(&JpegParserCtx->input_packet, JpegParserCtx->recv_buffer, JPEGD_STREAM_BUFF_SIZE); + + mpp_frame_init(&JpegParserCtx->output_frame); + if (!JpegParserCtx->output_frame) { + JPEGD_ERROR_LOG("Failed to allocate output frame buffer"); + return MPP_ERR_NOMEM; + } + + JpegParserCtx->pSyntax = mpp_calloc(JpegSyntaxParam, 1); + if (NULL == JpegParserCtx->pSyntax) { + JPEGD_ERROR_LOG("NULL pointer"); + return MPP_ERR_NULL_PTR; + } + + memset(JpegParserCtx->pSyntax, 0, sizeof(JpegSyntaxParam)); + JpegParserCtx->pSyntax->ppInstance = (void *)0; /* will be changed when need pp */ + + JpegParserCtx->decImageType = JPEGDEC_IMAGE; /* FULL MODEs */ + JpegParserCtx->output_fmt = MPP_FMT_YUV420SP; + + /* max */ + JpegParserCtx->maxSupportedWidth = JPEGDEC_MAX_WIDTH_8190; + JpegParserCtx->maxSupportedHeight = JPEGDEC_MAX_HEIGHT_8190; + JpegParserCtx->maxSupportedPixelAmount = JPEGDEC_MAX_PIXEL_AMOUNT_8190; + JpegParserCtx->maxSupportedSliceSize = JPEGDEC_MAX_SLICE_SIZE_8190; + + /* min */ + JpegParserCtx->minSupportedWidth = JPEGDEC_MIN_WIDTH; + JpegParserCtx->minSupportedHeight = JPEGDEC_MIN_HEIGHT; + + JpegParserCtx->extensionsSupported = 1; + + JpegParserCtx->pts = 0; + JpegParserCtx->eos = 0; + JpegParserCtx->parser_debug_enable = 0; + JpegParserCtx->input_jpeg_count = 0; + + FUN_TEST("Exit"); + return MPP_OK; +} + +MPP_RET jpegd_flush(void *ctx) +{ + FUN_TEST("Enter"); + JpegParserContext *JpegParserCtx = (JpegParserContext *)ctx; + (void)JpegParserCtx; + FUN_TEST("Exit"); + return MPP_OK; +} + +MPP_RET jpegd_reset(void *ctx) +{ + FUN_TEST("Enter"); + JpegParserContext *JpegParserCtx = (JpegParserContext *)ctx; + + (void)JpegParserCtx; + + FUN_TEST("Exit"); + return MPP_OK; +} + +MPP_RET jpegd_control(void *ctx, RK_S32 cmd, void *param) +{ + FUN_TEST("Enter"); + MPP_RET ret = MPP_OK; + JpegParserContext *JpegParserCtx = (JpegParserContext *)ctx; + if (NULL == JpegParserCtx) { + JPEGD_ERROR_LOG("NULL pointer"); + return MPP_ERR_NULL_PTR; + } + + switch (cmd) { + case MPP_DEC_SET_OUTPUT_FORMAT: { + JpegParserCtx->output_fmt = *((RK_U32 *)param); + JPEGD_INFO_LOG("output_format:%d\n", JpegParserCtx->output_fmt); + } break; + default : + ret = MPP_NOK; + } + FUN_TEST("Exit"); + return ret; +} + +MPP_RET jpegd_callback(void *ctx, void *err_info) +{ + FUN_TEST("Enter"); + (void) ctx; + (void) err_info; + FUN_TEST("Exit"); + return MPP_OK; +} + +const ParserApi api_jpegd_parser = { + "jpegd_parse", + MPP_VIDEO_CodingMJPEG, + sizeof(JpegParserContext), + 0, + jpegd_init, + jpegd_deinit, + jpegd_prepare, + jpegd_parse, + jpegd_reset, + jpegd_flush, + jpegd_control, + jpegd_callback, +}; + + diff --git a/mpp/codec/dec/jpeg/jpegd_parser.h b/mpp/codec/dec/jpeg/jpegd_parser.h index fba331b3..ffbdbdc9 100644 --- a/mpp/codec/dec/jpeg/jpegd_parser.h +++ b/mpp/codec/dec/jpeg/jpegd_parser.h @@ -1,190 +1,190 @@ -/* - * - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __JPEGD_PARSER_H__ -#define __JPEGD_PARSER_H__ - -#include "mpp_bitread.h" -#include "mpp_common.h" -#include "mpp_frame.h" -#include "limits.h" -#include -#include -#include "mpp_dec.h" -#include "mpp_buf_slot.h" -#include "mpp_packet.h" - -#include "jpegd_syntax.h" - -/* Max amount of stream */ -#define DEC_MAX_STREAM ((1<<24)-1) - -#define JPEGDEC_MIN_BUFFER 256 -#define JPEGDEC_MAX_BUFFER 16776960 -#define JPEGDEC_MAX_SLICE_SIZE 4096 -#define JPEGDEC_TABLE_SIZE 544 -#define JPEGDEC_MIN_WIDTH 48 -#define JPEGDEC_MIN_HEIGHT 48 -#define JPEGDEC_MAX_WIDTH 4672 -#define JPEGDEC_MAX_HEIGHT 4672 -#define JPEGDEC_MAX_PIXEL_AMOUNT 16370688 -#define JPEGDEC_MAX_WIDTH_8190 8176 -#define JPEGDEC_MAX_HEIGHT_8190 8176 -#define JPEGDEC_MAX_PIXEL_AMOUNT_8190 66846976 -#define JPEGDEC_MAX_SLICE_SIZE_8190 8100 -#define JPEGDEC_MAX_WIDTH_TN 256 -#define JPEGDEC_MAX_HEIGHT_TN 256 - -#define JPEGDEC_QP_BASE 32 -#define JPEGDEC_AC1_BASE 48 -#define JPEGDEC_AC2_BASE 88 -#define JPEGDEC_DC1_BASE 129 -#define JPEGDEC_DC2_BASE 132 -#define JPEGDEC_DC3_BASE 135 - -#define PP_IN_FORMAT_YUV422INTERLAVE 0 -#define PP_IN_FORMAT_YUV420SEMI 1 -#define PP_IN_FORMAT_YUV420PLANAR 2 -#define PP_IN_FORMAT_YUV400 3 -#define PP_IN_FORMAT_YUV422SEMI 4 -#define PP_IN_FORMAT_YUV420SEMITIELED 5 -#define PP_IN_FORMAT_YUV440SEMI 6 -#define PP_IN_FORMAT_YUV444_SEMI 7 -#define PP_IN_FORMAT_YUV411_SEMI 8 - -#define PP_OUT_FORMAT_RGB565 0 -#define PP_OUT_FORMAT_ARGB 1 -#define PP_OUT_FORMAT_YUV422INTERLAVE 3 -#define PP_OUT_FORMAT_YUV420INTERLAVE 5 - -/* progressive */ -#define JPEGDEC_COEFF_SIZE 96 - -enum { - JPEGDEC_NO_UNITS = 0, /* No units, X and Y specify - * the pixel aspect ratio */ - JPEGDEC_DOTS_PER_INCH = 1, /* X and Y are dots per inch */ - JPEGDEC_DOTS_PER_CM = 2 /* X and Y are dots per cm */ -}; - -enum { - JPEGDEC_THUMBNAIL_JPEG = 0x10, - JPEGDEC_THUMBNAIL_NOT_SUPPORTED_FORMAT = 0x11, - JPEGDEC_NO_THUMBNAIL = 0x12 -}; - -enum { - JPEGDEC_IMAGE = 0, - JPEGDEC_THUMBNAIL = 1 -}; - -enum { - SOF0 = 0xC0, - SOF1 = 0xC1, - SOF2 = 0xC2, - SOF3 = 0xC3, - SOF5 = 0xC5, - SOF6 = 0xC6, - SOF7 = 0xC7, - SOF9 = 0xC8, - SOF10 = 0xCA, - SOF11 = 0xCB, - SOF13 = 0xCD, - SOF14 = 0xCE, - SOF15 = 0xCF, - JPG = 0xC8, - DHT = 0xC4, - DAC = 0xCC, - SOI = 0xD8, - EOI = 0xD9, - SOS = 0xDA, - DQT = 0xDB, - DNL = 0xDC, - DRI = 0xDD, - DHP = 0xDE, - EXP = 0xDF, - APP0 = 0xE0, - APP1 = 0xE1, - APP2 = 0xE2, - APP3 = 0xE3, - APP4 = 0xE4, - APP5 = 0xE5, - APP6 = 0xE6, - APP7 = 0xE7, - APP8 = 0xE8, - APP9 = 0xE9, - APP10 = 0xEA, - APP11 = 0xEB, - APP12 = 0xEC, - APP13 = 0xED, - APP14 = 0xEE, - APP15 = 0xEF, - JPG0 = 0xF0, - JPG1 = 0xF1, - JPG2 = 0xF2, - JPG3 = 0xF3, - JPG4 = 0xF4, - JPG5 = 0xF5, - JPG6 = 0xF6, - JPG7 = 0xF7, - JPG8 = 0xF8, - JPG9 = 0xF9, - JPG10 = 0xFA, - JPG11 = 0xFB, - JPG12 = 0xFC, - JPG13 = 0xFD, - COM = 0xFE, - TEM = 0x01, - RST0 = 0xD0, - RST1 = 0xD1, - RST2 = 0xD2, - RST3 = 0xD3, - RST4 = 0xD4, - RST5 = 0xD5, - RST6 = 0xD6, - RST7 = 0xD7 -}; - -typedef struct JpegParserContext { - MppBufSlots packet_slots; - MppBufSlots frame_slots; - RK_S32 frame_slot_index; /* slot index for output */ - RK_U8 *recv_buffer; - JpegSyntaxParam *pSyntax; - - RK_U32 streamLength; /* input stream length or buffer size */ - RK_U32 bufferSize; /* input stream buffer size */ - RK_U32 decImageType; /* Full image or Thumbnail to be decoded */ - MppFrameFormat output_fmt; - - MppPacket input_packet; - MppFrame output_frame; - RK_U32 minSupportedWidth; - RK_U32 minSupportedHeight; - RK_U32 maxSupportedWidth; - RK_U32 maxSupportedHeight; - RK_U32 maxSupportedPixelAmount; - RK_U32 maxSupportedSliceSize; - RK_U32 extensionsSupported; - - RK_S64 pts; - RK_U32 eos; - RK_U32 parser_debug_enable; - RK_U32 input_jpeg_count; -} JpegParserContext; - -#endif /* __JPEGD_PARSER_H__ */ +/* + * + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __JPEGD_PARSER_H__ +#define __JPEGD_PARSER_H__ + +#include "mpp_bitread.h" +#include "mpp_common.h" +#include "mpp_frame.h" +#include "limits.h" +#include +#include +#include "mpp_dec.h" +#include "mpp_buf_slot.h" +#include "mpp_packet.h" + +#include "jpegd_syntax.h" + +/* Max amount of stream */ +#define DEC_MAX_STREAM ((1<<24)-1) + +#define JPEGDEC_MIN_BUFFER 256 +#define JPEGDEC_MAX_BUFFER 16776960 +#define JPEGDEC_MAX_SLICE_SIZE 4096 +#define JPEGDEC_TABLE_SIZE 544 +#define JPEGDEC_MIN_WIDTH 48 +#define JPEGDEC_MIN_HEIGHT 48 +#define JPEGDEC_MAX_WIDTH 4672 +#define JPEGDEC_MAX_HEIGHT 4672 +#define JPEGDEC_MAX_PIXEL_AMOUNT 16370688 +#define JPEGDEC_MAX_WIDTH_8190 8176 +#define JPEGDEC_MAX_HEIGHT_8190 8176 +#define JPEGDEC_MAX_PIXEL_AMOUNT_8190 66846976 +#define JPEGDEC_MAX_SLICE_SIZE_8190 8100 +#define JPEGDEC_MAX_WIDTH_TN 256 +#define JPEGDEC_MAX_HEIGHT_TN 256 + +#define JPEGDEC_QP_BASE 32 +#define JPEGDEC_AC1_BASE 48 +#define JPEGDEC_AC2_BASE 88 +#define JPEGDEC_DC1_BASE 129 +#define JPEGDEC_DC2_BASE 132 +#define JPEGDEC_DC3_BASE 135 + +#define PP_IN_FORMAT_YUV422INTERLAVE 0 +#define PP_IN_FORMAT_YUV420SEMI 1 +#define PP_IN_FORMAT_YUV420PLANAR 2 +#define PP_IN_FORMAT_YUV400 3 +#define PP_IN_FORMAT_YUV422SEMI 4 +#define PP_IN_FORMAT_YUV420SEMITIELED 5 +#define PP_IN_FORMAT_YUV440SEMI 6 +#define PP_IN_FORMAT_YUV444_SEMI 7 +#define PP_IN_FORMAT_YUV411_SEMI 8 + +#define PP_OUT_FORMAT_RGB565 0 +#define PP_OUT_FORMAT_ARGB 1 +#define PP_OUT_FORMAT_YUV422INTERLAVE 3 +#define PP_OUT_FORMAT_YUV420INTERLAVE 5 + +/* progressive */ +#define JPEGDEC_COEFF_SIZE 96 + +enum { + JPEGDEC_NO_UNITS = 0, /* No units, X and Y specify + * the pixel aspect ratio */ + JPEGDEC_DOTS_PER_INCH = 1, /* X and Y are dots per inch */ + JPEGDEC_DOTS_PER_CM = 2 /* X and Y are dots per cm */ +}; + +enum { + JPEGDEC_THUMBNAIL_JPEG = 0x10, + JPEGDEC_THUMBNAIL_NOT_SUPPORTED_FORMAT = 0x11, + JPEGDEC_NO_THUMBNAIL = 0x12 +}; + +enum { + JPEGDEC_IMAGE = 0, + JPEGDEC_THUMBNAIL = 1 +}; + +enum { + SOF0 = 0xC0, + SOF1 = 0xC1, + SOF2 = 0xC2, + SOF3 = 0xC3, + SOF5 = 0xC5, + SOF6 = 0xC6, + SOF7 = 0xC7, + SOF9 = 0xC8, + SOF10 = 0xCA, + SOF11 = 0xCB, + SOF13 = 0xCD, + SOF14 = 0xCE, + SOF15 = 0xCF, + JPG = 0xC8, + DHT = 0xC4, + DAC = 0xCC, + SOI = 0xD8, + EOI = 0xD9, + SOS = 0xDA, + DQT = 0xDB, + DNL = 0xDC, + DRI = 0xDD, + DHP = 0xDE, + EXP = 0xDF, + APP0 = 0xE0, + APP1 = 0xE1, + APP2 = 0xE2, + APP3 = 0xE3, + APP4 = 0xE4, + APP5 = 0xE5, + APP6 = 0xE6, + APP7 = 0xE7, + APP8 = 0xE8, + APP9 = 0xE9, + APP10 = 0xEA, + APP11 = 0xEB, + APP12 = 0xEC, + APP13 = 0xED, + APP14 = 0xEE, + APP15 = 0xEF, + JPG0 = 0xF0, + JPG1 = 0xF1, + JPG2 = 0xF2, + JPG3 = 0xF3, + JPG4 = 0xF4, + JPG5 = 0xF5, + JPG6 = 0xF6, + JPG7 = 0xF7, + JPG8 = 0xF8, + JPG9 = 0xF9, + JPG10 = 0xFA, + JPG11 = 0xFB, + JPG12 = 0xFC, + JPG13 = 0xFD, + COM = 0xFE, + TEM = 0x01, + RST0 = 0xD0, + RST1 = 0xD1, + RST2 = 0xD2, + RST3 = 0xD3, + RST4 = 0xD4, + RST5 = 0xD5, + RST6 = 0xD6, + RST7 = 0xD7 +}; + +typedef struct JpegParserContext { + MppBufSlots packet_slots; + MppBufSlots frame_slots; + RK_S32 frame_slot_index; /* slot index for output */ + RK_U8 *recv_buffer; + JpegSyntaxParam *pSyntax; + + RK_U32 streamLength; /* input stream length or buffer size */ + RK_U32 bufferSize; /* input stream buffer size */ + RK_U32 decImageType; /* Full image or Thumbnail to be decoded */ + MppFrameFormat output_fmt; + + MppPacket input_packet; + MppFrame output_frame; + RK_U32 minSupportedWidth; + RK_U32 minSupportedHeight; + RK_U32 maxSupportedWidth; + RK_U32 maxSupportedHeight; + RK_U32 maxSupportedPixelAmount; + RK_U32 maxSupportedSliceSize; + RK_U32 extensionsSupported; + + RK_S64 pts; + RK_U32 eos; + RK_U32 parser_debug_enable; + RK_U32 input_jpeg_count; +} JpegParserContext; + +#endif /* __JPEGD_PARSER_H__ */ diff --git a/mpp/codec/dec/m2v/m2vd_api.c b/mpp/codec/dec/m2v/m2vd_api.c index d6f2c747..81a41e83 100644 --- a/mpp/codec/dec/m2v/m2vd_api.c +++ b/mpp/codec/dec/m2v/m2vd_api.c @@ -1,47 +1,47 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define MODULE_TAG "m2vd_api" - -#include -#include "mpp_env.h" -#include "mpp_packet.h" -#include "mpp_packet_impl.h" -#include "mpp_mem.h" -#include "mpp_log.h" - -#include "m2vd_api.h" -#include "m2vd_parser.h" -#include "m2vd_codec.h" - -const ParserApi api_m2vd_parser = { - "m2vd_parse", - MPP_VIDEO_CodingMPEG2, - sizeof(M2VDContext), - 0, - m2vd_parser_init, - m2vd_parser_deinit, - m2vd_parser_prepare, - m2vd_parser_parse, - m2vd_parser_reset, - m2vd_parser_flush, - m2vd_parser_control, - m2vd_parser_callback, -}; - - - - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define MODULE_TAG "m2vd_api" + +#include +#include "mpp_env.h" +#include "mpp_packet.h" +#include "mpp_packet_impl.h" +#include "mpp_mem.h" +#include "mpp_log.h" + +#include "m2vd_api.h" +#include "m2vd_parser.h" +#include "m2vd_codec.h" + +const ParserApi api_m2vd_parser = { + "m2vd_parse", + MPP_VIDEO_CodingMPEG2, + sizeof(M2VDContext), + 0, + m2vd_parser_init, + m2vd_parser_deinit, + m2vd_parser_prepare, + m2vd_parser_parse, + m2vd_parser_reset, + m2vd_parser_flush, + m2vd_parser_control, + m2vd_parser_callback, +}; + + + + diff --git a/mpp/codec/dec/m2v/m2vd_codec.h b/mpp/codec/dec/m2v/m2vd_codec.h index 01ee12fd..b1955de2 100644 --- a/mpp/codec/dec/m2v/m2vd_codec.h +++ b/mpp/codec/dec/m2v/m2vd_codec.h @@ -1,32 +1,32 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __M2VD_CODEC_H__ -#define __M2VD_CODEC_H__ - -#include "rk_type.h" -#include "mpp_common.h" -#include "mpp_frame.h" -#include "mpp_dec.h" -#include "mpp_packet.h" - - -typedef struct M2VDContext_t { - void *parse_ctx; - -} M2VDContext; - -#endif +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __M2VD_CODEC_H__ +#define __M2VD_CODEC_H__ + +#include "rk_type.h" +#include "mpp_common.h" +#include "mpp_frame.h" +#include "mpp_dec.h" +#include "mpp_packet.h" + + +typedef struct M2VDContext_t { + void *parse_ctx; + +} M2VDContext; + +#endif diff --git a/mpp/codec/dec/m2v/m2vd_com.h b/mpp/codec/dec/m2v/m2vd_com.h index 17c050e4..39febc9c 100644 --- a/mpp/codec/dec/m2v/m2vd_com.h +++ b/mpp/codec/dec/m2v/m2vd_com.h @@ -1,132 +1,132 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __M2VD_COM_H__ -#define __M2VD_COM_H__ - -#include -#include - -#include "rk_type.h" -#include "mpp_log.h" - -#define M2VD_DEMO_MODE 0 - -//------------------------ temp --------------------------------- -#define M2VD_TEST_TRACE (0x00000001) -#define M2VD_TEST_TIME (0x00000002) -#define M2VD_TEST_MUTI_THREAD (0x00000004) -#define M2VD_TEST_DUMPYUV (0x00000008) -#define M2VD_TEST_FPGA (0x00000010) - -//log of diff -#define M2VD_DBG_FUNCTION (0x00000001) -#define M2VD_DBG_ASSERT (0x00000002) -#define M2VD_DBG_WARNNING (0x00000004) -#define M2VD_DBG_LOG (0x00000008) -#define M2VD_DBG_SEC_HEADER (0x00000010) -#define M2VD_DBG_DUMP_REG (0x00000020) - - - - -extern RK_U32 m2vd_debug; - -#define M2VD_ERR(fmt, ...)\ -do {\ - { mpp_log(fmt, ## __VA_ARGS__); }\ -} while (0) - -#define M2VD_ASSERT(val)\ -do {\ - if (M2VD_DBG_ASSERT & m2vd_debug)\ - { mpp_assert(val); }\ -} while (0) - -#define M2VD_WARNNING(fmt, ...)\ -do {\ - if (M2VD_DBG_WARNNING & m2vd_debug)\ - { mpp_log(fmt, ## __VA_ARGS__); }\ -} while (0) - -#define M2VD_LOG(fmt, ...)\ -do {\ - if (M2VD_DBG_LOG & m2vd_debug)\ - { mpp_log(fmt, ## __VA_ARGS__); }\ -} while (0) - - -//check function return -#define CHK_F(val) \ - do{ \ - if((val) < 0) { \ - ret = (val); \ - M2VD_WARNNING("func return error(L%d), ret:%d\n", __LINE__, ret); \ - goto __FAILED; \ - } \ - } while (0) - -//check value if is zero or NULL -#define CHK_V(val, ...)\ - do{ if(!(val)){\ - ret = MPP_ERR_VALUE;\ - M2VD_WARNNING("value error(L%d), val:%d\n", __LINE__, val);\ - goto __FAILED;\ - } } while (0) - -//memory malloc check -#define CHK_M(val, ...)\ - do{ if(!(val)) {\ - ret = MPP_ERR_MALLOC;\ - M2VD_ERR("malloc buffer error(%d), pointer:%p\n", __LINE__, val);\ - M2VD_ASSERT(0); goto __FAILED;\ - } } while (0) - -//file check -#define CHK_FILE(val, path, ...)\ - do{ if(!(val)) {\ - ret = MPP_ERR_OPEN_FILE;\ - M2VD_WARNNING("open file error(line%d): %s\n", __LINE__, path);\ - M2VD_ASSERT(0); goto __FAILED;\ - } } while (0) - -//!< input check -#define CHK_I(val, ...)\ - do{ if(!(val)) {\ - ret = MPP_ERR_INIT;\ - M2VD_WARNNING("input empty(%d), val:%d\n", __LINE__, val);\ - goto __FAILED;\ - } } while (0) - -#define FUN_T(tag) \ - do {\ - if (M2VD_DBG_FUNCTION & m2vd_debug)\ - { mpp_log("%s: line(%d), func(%s)", tag, __LINE__, __FUNCTION__); }\ - } while (0) - - - -#define M2VD_TEST_LOG(level, fmt, ...)\ -do {\ - if (level & rkv_h264d_test_debug)\ - { mpp_log(fmt, ## __VA_ARGS__); }\ -} while (0) - - - -#define M2VD_FCLOSE(fp) do{ if(fp) fclose(fp); fp = NULL; } while (0) - -#endif +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __M2VD_COM_H__ +#define __M2VD_COM_H__ + +#include +#include + +#include "rk_type.h" +#include "mpp_log.h" + +#define M2VD_DEMO_MODE 0 + +//------------------------ temp --------------------------------- +#define M2VD_TEST_TRACE (0x00000001) +#define M2VD_TEST_TIME (0x00000002) +#define M2VD_TEST_MUTI_THREAD (0x00000004) +#define M2VD_TEST_DUMPYUV (0x00000008) +#define M2VD_TEST_FPGA (0x00000010) + +//log of diff +#define M2VD_DBG_FUNCTION (0x00000001) +#define M2VD_DBG_ASSERT (0x00000002) +#define M2VD_DBG_WARNNING (0x00000004) +#define M2VD_DBG_LOG (0x00000008) +#define M2VD_DBG_SEC_HEADER (0x00000010) +#define M2VD_DBG_DUMP_REG (0x00000020) + + + + +extern RK_U32 m2vd_debug; + +#define M2VD_ERR(fmt, ...)\ +do {\ + { mpp_log(fmt, ## __VA_ARGS__); }\ +} while (0) + +#define M2VD_ASSERT(val)\ +do {\ + if (M2VD_DBG_ASSERT & m2vd_debug)\ + { mpp_assert(val); }\ +} while (0) + +#define M2VD_WARNNING(fmt, ...)\ +do {\ + if (M2VD_DBG_WARNNING & m2vd_debug)\ + { mpp_log(fmt, ## __VA_ARGS__); }\ +} while (0) + +#define M2VD_LOG(fmt, ...)\ +do {\ + if (M2VD_DBG_LOG & m2vd_debug)\ + { mpp_log(fmt, ## __VA_ARGS__); }\ +} while (0) + + +//check function return +#define CHK_F(val) \ + do{ \ + if((val) < 0) { \ + ret = (val); \ + M2VD_WARNNING("func return error(L%d), ret:%d\n", __LINE__, ret); \ + goto __FAILED; \ + } \ + } while (0) + +//check value if is zero or NULL +#define CHK_V(val, ...)\ + do{ if(!(val)){\ + ret = MPP_ERR_VALUE;\ + M2VD_WARNNING("value error(L%d), val:%d\n", __LINE__, val);\ + goto __FAILED;\ + } } while (0) + +//memory malloc check +#define CHK_M(val, ...)\ + do{ if(!(val)) {\ + ret = MPP_ERR_MALLOC;\ + M2VD_ERR("malloc buffer error(%d), pointer:%p\n", __LINE__, val);\ + M2VD_ASSERT(0); goto __FAILED;\ + } } while (0) + +//file check +#define CHK_FILE(val, path, ...)\ + do{ if(!(val)) {\ + ret = MPP_ERR_OPEN_FILE;\ + M2VD_WARNNING("open file error(line%d): %s\n", __LINE__, path);\ + M2VD_ASSERT(0); goto __FAILED;\ + } } while (0) + +//!< input check +#define CHK_I(val, ...)\ + do{ if(!(val)) {\ + ret = MPP_ERR_INIT;\ + M2VD_WARNNING("input empty(%d), val:%d\n", __LINE__, val);\ + goto __FAILED;\ + } } while (0) + +#define FUN_T(tag) \ + do {\ + if (M2VD_DBG_FUNCTION & m2vd_debug)\ + { mpp_log("%s: line(%d), func(%s)", tag, __LINE__, __FUNCTION__); }\ + } while (0) + + + +#define M2VD_TEST_LOG(level, fmt, ...)\ +do {\ + if (level & rkv_h264d_test_debug)\ + { mpp_log(fmt, ## __VA_ARGS__); }\ +} while (0) + + + +#define M2VD_FCLOSE(fp) do{ if(fp) fclose(fp); fp = NULL; } while (0) + +#endif diff --git a/mpp/codec/dec/m2v/m2vd_parser.c b/mpp/codec/dec/m2v/m2vd_parser.c index 2938d6f7..98650803 100644 --- a/mpp/codec/dec/m2v/m2vd_parser.c +++ b/mpp/codec/dec/m2v/m2vd_parser.c @@ -1,1370 +1,1370 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define MODULE_TAG "m2vd_parser" -#include - -#include "m2vd_parser.h" -#include "m2vd_codec.h" - -#include "mpp_frame.h" -#include "mpp_env.h" - -RK_U32 m2vd_debug = 0x0; - -RK_U8 scanOrder[2][64] = { - { /* zig-zag */ - 0, 1, 8, 16, 9, 2, 3, 10, - 17, 24, 32, 25, 18, 11, 4, 5, - 12, 19, 26, 33, 40, 48, 41, 34, - 27, 20, 13, 6, 7, 14, 21, 28, - 35, 42, 49, 56, 57, 50, 43, 36, - 29, 22, 15, 23, 30, 37, 44, 51, - 58, 59, 52, 45, 38, 31, 39, 46, - 53, 60, 61, 54, 47, 55, 62, 63 - }, - - { /* Alternate */ - 0, 8, 16, 24, 1, 9, 2, 10, - 17, 25, 32, 40, 48, 56, 57, 49, - 41, 33, 26, 18, 3, 11, 4, 12, - 19, 27, 34, 42, 50, 58, 35, 43, - 51, 59, 20, 28, 5, 13, 6, 14, - 21, 29, 36, 44, 52, 60, 37, 45, - 53, 61, 22, 30, 7, 15, 23, 31, - 38, 46, 54, 62, 39, 47, 55, 63 - } -}; - -RK_U8 intraDefaultQMatrix[64] = { - 8, 16, 19, 22, 26, 27, 29, 34, - 16, 16, 22, 24, 27, 29, 34, 37, - 19, 22, 26, 27, 29, 34, 34, 38, - 22, 22, 26, 27, 29, 34, 37, 40, - 22, 26, 27, 29, 32, 35, 40, 48, - 26, 27, 29, 32, 35, 40, 48, 58, - 26, 27, 29, 34, 38, 46, 56, 69, - 27, 29, 35, 38, 46, 56, 69, 83 -}; - - -int frame_period_Table[16] = { - 1, - 11142, - 10667, - 10240, - 8542, - 8533, - 5120, - 4271, - 4267, - - 1, - 1, - 1, - 1, - 1, - 1, - 1 -}; - -static RK_S32 m2vd_get_readbits(BitReadCtx_t *bx) -{ - return bx->used_bits; -} - -static RK_S32 m2vd_get_leftbits(BitReadCtx_t *bx) -{ - return (bx->bytes_left_ * 8 + bx->num_remaining_bits_in_curr_byte_); -} - -static RK_S32 m2vd_read_bits(BitReadCtx_t *bx, RK_U32 bits) -{ - RK_S32 ret = 0; - if (bits < 32) - mpp_read_bits(bx, bits, &ret); - else - mpp_read_longbits(bx, bits, (RK_U32 *)&ret); - return ret; -} - -static RK_S32 m2vd_show_bits(BitReadCtx_t *bx, RK_U32 bits) -{ - RK_S32 ret = 0; - mpp_show_bits(bx, bits, &ret); - return ret; -} - - -RK_S32 m2vd_parser_read_one_frame(M2VDParserContext *ctx) -{ - (void)ctx; - return MPP_OK; -} - -static MPP_RET m2vd_parser_init_ctx(M2VDParserContext *ctx, ParserCfg *cfg) -{ - MPP_RET ret = MPP_OK; - RK_S32 i = 0; - FUN_T("FUN_I"); - - CHK_I(ctx); - memset(ctx, 0, sizeof(*ctx)); - - ctx->dxva_ctx = mpp_calloc(M2VDDxvaParam, 1); - ctx->bitread_ctx = mpp_calloc(BitReadCtx_t, 1); - - ctx->packet_slots = cfg->packet_slots; - ctx->frame_slots = cfg->frame_slots; - - ctx->notify_cb = cfg->notify_cb; - - mpp_buf_slot_setup(ctx->frame_slots, 16); - - ctx->initFlag = 0; - - /* copy from mpeg2decoder::mpeg2decoder */ - memset(&ctx->Framehead, 0, 3 * sizeof(M2VDFrameHead)); - - ctx->frame_ref0 = &ctx->Framehead[0]; - ctx->frame_ref1 = &ctx->Framehead[1]; - ctx->frame_cur = &ctx->Framehead[2]; - for (i = 0; i < 3; i++) { - mpp_frame_init(&ctx->Framehead[i].f); - if (!ctx->Framehead[i].f) { - mpp_err("Failed to allocate frame buffer %d\n", i); - return MPP_ERR_NOMEM; - } - ctx->Framehead[i].picCodingType = 0xffffffff; - ctx->Framehead[i].slot_index = 0xff; - } -#if M2VD_SKIP_ERROR_FRAME_EN - ctx->mHwDecStatus = MPP_OK; -#endif - ctx->resetFlag = 0; - ctx->flush_dpb_eos = 0; - ctx->pic_head.pre_temporal_reference = 0; - ctx->pic_head.pre_picture_coding_type = 0; - ctx->pic_head.picture_coding_type = 0; - - /* copy form mpeg2decoder::decoder_init */ - //---------------------------------------------------- - ctx->bitstream_sw_buf = mpp_calloc(RK_U8, M2VD_BUF_SIZE_BITMEM); - mpp_packet_init(&ctx->input_packet, ctx->bitstream_sw_buf, M2VD_BUF_SIZE_BITMEM); - - ctx->qp_tab_sw_buf = mpp_calloc(RK_U8, M2VD_BUF_SIZE_QPTAB); - ctx->seq_head.pIntra_table = ctx->qp_tab_sw_buf; - ctx->seq_head.pInter_table = ctx->seq_head.pIntra_table + 64; - - ctx->MPEG2_Flag = 0; - ctx->seq_ext_head.progressive_sequence = 1; - ctx->pic_code_ext_head.progressive_frame = 1; - ctx->pic_code_ext_head.picture_structure = M2VD_PIC_STRUCT_FRAME; - ctx->pic_head.pre_picture_coding_type = M2VD_CODING_TYPE_D; - ctx->top_first_cnt = 0; - ctx->bottom_first_cnt = 0; - ctx->pic_code_ext_head.frame_pred_frame_dct = 1; - ctx->seq_ext_head.chroma_format = 1; - ctx->seq_disp_ext_head.matrix_coefficients = 5; - ctx->PreGetFrameTime = 0; - ctx->maxFrame_inGOP = 0; - ctx->preframe_period = 0; - ctx->mHeaderDecFlag = 0; - ctx->max_stream_size = M2VD_BUF_SIZE_BITMEM; - ctx->ref_frame_cnt = 0; - - - if (M2VD_DBG_DUMP_REG & m2vd_debug) { - RK_S32 k = 0; - for (k = 0; k < M2VD_DBG_FILE_NUM; k++) - ctx->fp_dbg_file[k] = NULL; - - ctx->fp_dbg_file[0] = fopen("/sdcard/m2vd_dbg_stream.txt", "wb"); - if (!ctx->fp_dbg_file[0]) - mpp_log("open file failed: %s", "/sdcard/m2vd_dbg_stream.txt"); - - ctx->fp_dbg_yuv = fopen("/sdcard/m2vd_dbg_yuv_out.txt", "wb"); - if (!ctx->fp_dbg_yuv) - mpp_log("open file failed: %s", "/sdcard/m2vd_dbg_yuv_out.txt"); - } else { - RK_S32 k = 0; - for (k = 0; k < M2VD_DBG_FILE_NUM; k++) - ctx->fp_dbg_file[k] = NULL; - } - - - FUN_T("FUN_O"); -__FAILED: - - return ret; -} - - -MPP_RET m2vd_parser_init(void *ctx, ParserCfg *parser_cfg) -{ - MPP_RET ret = MPP_OK; - M2VDContext *c = (M2VDContext *)ctx; - M2VDParserContext *p = (M2VDParserContext *)c->parse_ctx; - FUN_T("FUN_I"); - if (p == NULL) { - CHK_M(p = (M2VDParserContext*)mpp_calloc(M2VDParserContext, 1)); - c->parse_ctx = p; - } - - CHK_F(m2vd_parser_init_ctx(p, parser_cfg)); - - mpp_env_get_u32("m2vd_debug", &m2vd_debug, 0); - - FUN_T("FUN_O"); -__FAILED: - return ret; -} - - -MPP_RET m2vd_parser_deinit(void *ctx) -{ - RK_U32 k = 0; - MPP_RET ret = MPP_OK; - M2VDContext *c = (M2VDContext *)ctx; - M2VDParserContext *p = (M2VDParserContext *)c->parse_ctx; - - FUN_T("FUN_I"); - - for (k = 0; k < M2VD_DBG_FILE_NUM; k++) { - M2VD_FCLOSE(p->fp_dbg_file[k]); - } - M2VD_FCLOSE(p->fp_dbg_yuv); - - if (p->bitstream_sw_buf) { - mpp_free(p->bitstream_sw_buf); - p->bitstream_sw_buf = NULL; - } - if (p->qp_tab_sw_buf) { - mpp_free(p->qp_tab_sw_buf); - p->qp_tab_sw_buf = NULL; - } - - if (p->input_packet) { - mpp_packet_deinit(&p->input_packet); - } - - if (p->dxva_ctx) { - mpp_free(p->dxva_ctx); - p->dxva_ctx = NULL; - } - if (p->bitread_ctx) { - mpp_free(p->bitread_ctx); - p->bitread_ctx = NULL; - } - - for (k = 0; k < 3; k++) { - mpp_free(p->Framehead[k].f); - } - - if (p) { - mpp_free(p); - } - - FUN_T("FUN_O"); - return ret; -} -/*! -*********************************************************************** -* \brief -* reset -*********************************************************************** -*/ -MPP_RET m2vd_parser_reset(void *ctx) -{ - MPP_RET ret = MPP_OK; - M2VDContext *c = (M2VDContext *)ctx; - M2VDParserContext *p = (M2VDParserContext *)c->parse_ctx; - FUN_T("FUN_I"); - if (p->frame_cur->slot_index != 0xff) { -#if 0 - MppBuffer framebuf = NULL; //current buf may alloc - mpp_buf_slot_get_prop(p->frame_slots, p->frame_cur->slot_index, SLOT_BUFFER, &framebuf); - mpp_buffer_put(framebuf); -#endif - mpp_buf_slot_clr_flag(p->frame_slots, p->frame_cur->slot_index, SLOT_CODEC_USE); - } - - if (p->frame_ref0->slot_index != 0xff ) { - - if (p->frame_ref0->flags) { - mpp_buf_slot_set_flag(p->frame_slots, p->frame_ref0->slot_index, SLOT_QUEUE_USE); - mpp_buf_slot_enqueue(p->frame_slots, p->frame_ref0->slot_index, QUEUE_DISPLAY); - p->frame_ref0->flags = 0; - } - mpp_buf_slot_clr_flag(p->frame_slots, p->frame_ref0->slot_index, SLOT_CODEC_USE); - } - - if (p->frame_ref1->slot_index != 0xff) { - mpp_buf_slot_clr_flag(p->frame_slots, p->frame_ref1->slot_index, SLOT_CODEC_USE); - } - - p->frame_cur->slot_index = 0xff; - p->frame_ref0->slot_index = 0xff; - p->frame_ref1->slot_index = 0xff; - p->ref_frame_cnt = 0; - p->resetFlag = 1; - p->eos = 0; - FUN_T("FUN_O"); - return ret; -} - -/*! -*********************************************************************** -* \brief -* flush -*********************************************************************** -*/ -MPP_RET m2vd_parser_flush(void *ctx) -{ - MPP_RET ret = MPP_OK; - M2VDContext *c = (M2VDContext *)ctx; - M2VDParserContext *p = (M2VDParserContext *)c->parse_ctx; - FUN_T("FUN_I"); - if (p->frame_ref0->slot_index == 0xff) { - goto exit; - } - mpp_buf_slot_set_flag(p->frame_slots, p->frame_ref0->slot_index, SLOT_QUEUE_USE); - mpp_buf_slot_enqueue(p->frame_slots, p->frame_ref0->slot_index, QUEUE_DISPLAY); - p->frame_ref0->flags = 0; -exit: -#if 0 - if (p->eos) { - if ( p->frame_ref0->slot_index < 0xff) { - mpp_buf_slot_set_prop(p->frame_slots, p->frame_ref0->slot_index, SLOT_EOS, &p->eos); - } else { - if (p->notify_cb.callBack != NULL) { - p->notify_cb.callBack(p->notify_cb.opaque, NULL); - } - } - } -#endif - return ret; -} - -/*! -*********************************************************************** -* \brief -* control/perform -*********************************************************************** -*/ -MPP_RET m2vd_parser_control(void *ctx, RK_S32 cmd_type, void *param) -{ - MPP_RET ret = MPP_OK; - FUN_T("FUN_I"); - (void)ctx; - (void)cmd_type; - (void)param; - FUN_T("FUN_O"); - return ret; -} - - -/*! -*********************************************************************** -* \brief -* prepare -*********************************************************************** -*/ - -MPP_RET m2vd_parser_split_frame(RK_U8 *src, RK_U32 src_size, RK_U8 *dst, RK_U32 *dst_size) -{ - MPP_RET ret = MPP_OK; - RK_U32 val = 0; - val = *((RK_U32*)src); - -#define VPU_BITSTREAM_START_CODE (0x42564b52) /* RKVB, rockchip video bitstream */ - - if (VPU_BITSTREAM_START_CODE == val) { // if input data is rk format styl skip those 32 byte - memcpy(dst, src + 32, src_size - 32); - *dst_size = src_size - 32; - } else { - memcpy(dst, src, src_size); - *dst_size = src_size; - } - - (void)dst; - - return ret; -} - - -MPP_RET m2vd_parser_prepare(void *ctx, MppPacket pkt, HalDecTask *task) -{ - MPP_RET ret = MPP_OK; - M2VDContext *c = (M2VDContext *)ctx; - M2VDParserContext *p = (M2VDParserContext *)c->parse_ctx; - MppPacket input_packet = p->input_packet; - RK_U32 out_size = 0, len_in; - RK_U8 *pos = NULL; - RK_U8 *buf = NULL; - - - buf = pos = mpp_packet_get_pos(pkt); - p->pts = mpp_packet_get_pts(pkt); - - - //MppPacketImpl *packet = (MppPacketImpl *)pkt; - //uint32_t stream_count = 0; - - FUN_T("FUN_I"); - task->valid = 0; - len_in = (RK_U32)mpp_packet_get_length(pkt), - p->eos = mpp_packet_get_eos(pkt); - // mpp_log("len_in = %d",len_in); - if (len_in > p->max_stream_size) { - mpp_free(p->bitstream_sw_buf); - p->bitstream_sw_buf = NULL; - p->bitstream_sw_buf = mpp_malloc(RK_U8, (len_in + 1024)); - if (NULL == p->bitstream_sw_buf) { - mpp_err("m2vd_parser realloc fail"); - return MPP_ERR_NOMEM; - } - p->max_stream_size = len_in + 1024; - } - - pos += out_size; - - m2vd_parser_split_frame(buf, - len_in, - p->bitstream_sw_buf, - &out_size); - pos += out_size; - - mpp_packet_set_pos(pkt, pos); - - if (out_size == 0 && p->eos) { - m2vd_parser_flush(ctx); - task->flags.eos = 1; - return ret; - } - - if (M2VD_DBG_SEC_HEADER & m2vd_debug) { - mpp_log("p->bitstream_sw_buf = 0x%x", p->bitstream_sw_buf); - mpp_log("out_size = 0x%x", out_size); - } - - mpp_packet_set_data(input_packet, p->bitstream_sw_buf); - mpp_packet_set_size(input_packet, p->max_stream_size); - mpp_packet_set_length(input_packet, out_size); - - task->input_packet = input_packet; - -#if M2VD_DBG_FILE_W - if (p->fp_dbg_file[0]) { - RK_S32 size = (RK_S32)mpp_packet_get_size(pkt); - RK_U8 *data = (RK_U8 *)mpp_packet_get_data(pkt); - fwrite(&size, 4, 1, p->fp_dbg_file[0]); - fwrite(data, 1, size, p->fp_dbg_file[0]); - fflush(p->fp_dbg_file[0]); - } -#endif - - task->valid = 1; - FUN_T("FUN_O"); - return ret; -} - - -/*! -*********************************************************************** -* \brief -* parser -*********************************************************************** -*/ - -static RK_U32 m2vd_search_header(BitReadCtx_t *bx) -{ - mpp_align_get_bits(bx); - while (m2vd_show_bits(bx, 24) != 0x01) { - mpp_skip_bits(bx, 8); - if (m2vd_get_leftbits(bx) < 32) { - if (M2VD_DBG_SEC_HEADER & m2vd_debug) { - mpp_log("[m2v]: seach_header: str.leftbit()[%d] < 32", m2vd_get_leftbits(bx)); - } - return NO_MORE_STREAM; - } - } - return m2vd_show_bits(bx, 32); -} - - -int m2vd_decode_seq_ext_header(M2VDParserContext *ctx) -{ - BitReadCtx_t *bx = ctx->bitread_ctx; - FUN_T("FUN_I"); - ctx->MPEG2_Flag = 1; - ctx->seq_ext_head.profile_and_level_indication = m2vd_read_bits(bx, 8); - ctx->seq_ext_head.progressive_sequence = m2vd_read_bits(bx, 1); - ctx->seq_ext_head.chroma_format = m2vd_read_bits(bx, 2); - if (ctx->seq_ext_head.chroma_format != 1) - return M2VD_DEC_UNSURPORT; - ctx->seq_ext_head.horizontal_size_extension = m2vd_read_bits(bx, 2); - ctx->seq_ext_head.vertical_size_extension = m2vd_read_bits(bx, 2); - ctx->seq_ext_head.bit_rate_extension = m2vd_read_bits(bx, 12); - mpp_skip_bits(bx, 1); - ctx->seq_ext_head.vbv_buffer_size_extension = m2vd_read_bits(bx, 8); - ctx->seq_ext_head.low_delay = m2vd_read_bits(bx, 1); - ctx->seq_ext_head.frame_rate_extension_n = m2vd_read_bits(bx, 2); - ctx->seq_ext_head.frame_rate_extension_d = m2vd_read_bits(bx, 5); - - ctx->seq_head.bit_rate_value |= (ctx->seq_ext_head.bit_rate_extension << 18); - ctx->seq_head.vbv_buffer_size += (ctx->seq_ext_head.vbv_buffer_size_extension << 10); - - FUN_T("FUN_O"); - return M2VD_DEC_OK; -} - -int m2vd_decode_seqdisp_ext_header(M2VDParserContext *ctx) -{ - BitReadCtx_t *bx = ctx->bitread_ctx; - ctx->seq_disp_ext_head.video_format = m2vd_read_bits(bx, 3); - ctx->seq_disp_ext_head.color_description = m2vd_read_bits(bx, 1); - - if (ctx->seq_disp_ext_head.color_description) { - ctx->seq_disp_ext_head.color_primaries = m2vd_read_bits(bx, 8); - ctx->seq_disp_ext_head.transfer_characteristics = m2vd_read_bits(bx, 8); - ctx->seq_disp_ext_head.matrix_coefficients = m2vd_read_bits(bx, 8); - } - - m2vd_read_bits(bx, 14); - mpp_skip_bits(bx, 1); - m2vd_read_bits(bx, 14); - return M2VD_DEC_OK; -} - -int m2vd_decode_matrix_ext_header(M2VDParserContext *ctx) -{ - RK_U32 load_intra_quantizer_matrix; - RK_U32 load_non_intra_quantizer_matrix; - RK_U32 load_chroma_intra_quantizer_matrix; - RK_U32 load_chroma_non_intra_quantizer_matrix; - RK_U32 i; - BitReadCtx_t *bx = ctx->bitread_ctx; - - load_intra_quantizer_matrix = m2vd_read_bits(bx, 1); - if (load_intra_quantizer_matrix) { - for (i = 0; i < 64; i++) - ctx->seq_head.pIntra_table[scanOrder[0][i]] = (unsigned char)m2vd_read_bits(bx, 8); - - } - load_non_intra_quantizer_matrix = m2vd_read_bits(bx, 1); - if (load_non_intra_quantizer_matrix) { - for (i = 0; i < 64; i++) - ctx->seq_head.pInter_table[scanOrder[0][i]] = (unsigned char)m2vd_read_bits(bx, 8); - } - load_chroma_intra_quantizer_matrix = m2vd_read_bits(bx, 1); - if (load_chroma_intra_quantizer_matrix) { - return M2VD_DEC_UNSURPORT; - } - load_chroma_non_intra_quantizer_matrix = m2vd_read_bits(bx, 1); - if (load_chroma_non_intra_quantizer_matrix) { - return M2VD_DEC_UNSURPORT; - } - return M2VD_DEC_OK; -} - - -int m2vd_decode_scalable_ext_header(M2VDParserContext *ctx) -{ - /* ISO/IEC 13818-2 section 6.2.2.5: sequence_scalable_extension() header */ - int layer_id; - int lower_layer_prediction_horizontal_size; - int lower_layer_prediction_vertical_size; - int horizontal_subsampling_factor_m; - int horizontal_subsampling_factor_n; - int vertical_subsampling_factor_m; - int vertical_subsampling_factor_n; - int scalable_mode; - BitReadCtx_t *bx = ctx->bitread_ctx; - - /* scalable_mode */ -#define SC_NONE 0 -#define SC_DP 1 -#define SC_SPAT 2 -#define SC_SNR 3 -#define SC_TEMP 4 - - scalable_mode = m2vd_read_bits(bx, 2) + 1; /* add 1 to make SC_DP != SC_NONE */ - - layer_id = m2vd_read_bits(bx, 4); - - if (scalable_mode == SC_SPAT) { - lower_layer_prediction_horizontal_size = m2vd_read_bits(bx, 14); - mpp_skip_bits(bx, 1); - lower_layer_prediction_vertical_size = m2vd_read_bits(bx, 14); - horizontal_subsampling_factor_m = m2vd_read_bits(bx, 5); - horizontal_subsampling_factor_n = m2vd_read_bits(bx, 5); - vertical_subsampling_factor_m = m2vd_read_bits(bx, 5); - vertical_subsampling_factor_n = m2vd_read_bits(bx, 5); - } - - (void)layer_id; - (void)lower_layer_prediction_horizontal_size; - (void)lower_layer_prediction_vertical_size; - (void)horizontal_subsampling_factor_m; - (void)horizontal_subsampling_factor_n; - (void)vertical_subsampling_factor_m; - (void)vertical_subsampling_factor_n; - - - if (scalable_mode == SC_TEMP) - return M2VD_DEC_UNSURPORT; - else - return M2VD_DEC_OK; -} - - -int m2vd_decode_picdisp_ext_header(M2VDParserContext *ctx) -{ - int i; - int number_of_frame_center_offsets; - BitReadCtx_t *bx = ctx->bitread_ctx; - /* based on ISO/IEC 13818-2 section 6.3.12 - (November 1994) Picture display extensions */ - - /* derive number_of_frame_center_offsets */ - if (ctx->seq_ext_head.progressive_sequence) { - if (ctx->pic_code_ext_head.repeat_first_field) { - if (ctx->pic_code_ext_head.top_field_first) - number_of_frame_center_offsets = 3; - else - number_of_frame_center_offsets = 2; - } else { - number_of_frame_center_offsets = 1; - } - } else { - if (ctx->pic_code_ext_head.picture_structure != M2VD_PIC_STRUCT_FRAME) { - number_of_frame_center_offsets = 1; - } else { - if (ctx->pic_code_ext_head.repeat_first_field) - number_of_frame_center_offsets = 3; - else - number_of_frame_center_offsets = 2; - } - } - - /* now parse */ - for (i = 0; i < number_of_frame_center_offsets; i++) { - ctx->pic_disp_ext_head.frame_center_horizontal_offset[i] = m2vd_read_bits(bx, 16); - mpp_skip_bits(bx, 1); - - ctx->pic_disp_ext_head.frame_center_vertical_offset[i] = m2vd_read_bits(bx, 16); - mpp_skip_bits(bx, 1); - } - return M2VD_DEC_OK; -} - - -int m2vd_decode_spatial_ext_header(M2VDParserContext *ctx) -{ - /* ISO/IEC 13818-2 section 6.2.3.5: picture_spatial_scalable_extension() header */ - int lower_layer_temporal_reference; - int lower_layer_horizontal_offset; - int lower_layer_vertical_offset; - int spatial_temporal_weight_code_table_index; - int lower_layer_progressive_frame; - int lower_layer_deinterlaced_field_select; - BitReadCtx_t *bx = ctx->bitread_ctx; - - lower_layer_temporal_reference = m2vd_read_bits(bx, 10); - mpp_skip_bits(bx, 1); - lower_layer_horizontal_offset = m2vd_read_bits(bx, 15); - if (lower_layer_horizontal_offset >= 16384) - lower_layer_horizontal_offset -= 32768; - mpp_skip_bits(bx, 1); - lower_layer_vertical_offset = m2vd_read_bits(bx, 15); - if (lower_layer_vertical_offset >= 16384) - lower_layer_vertical_offset -= 32768; - spatial_temporal_weight_code_table_index = m2vd_read_bits(bx, 2); - lower_layer_progressive_frame = m2vd_read_bits(bx, 1); - lower_layer_deinterlaced_field_select = m2vd_read_bits(bx, 1); - - (void)lower_layer_temporal_reference; - (void)lower_layer_vertical_offset; - (void)spatial_temporal_weight_code_table_index; - (void)lower_layer_progressive_frame; - (void)lower_layer_deinterlaced_field_select; - - - return M2VD_DEC_OK; -} - - - -int m2vd_decode_pic_ext_header(M2VDParserContext *ctx) -{ - BitReadCtx_t *bx = ctx->bitread_ctx; - ctx->pic_code_ext_head.f_code[0][0] = m2vd_read_bits(bx, 4); - ctx->pic_code_ext_head.f_code[0][1] = m2vd_read_bits(bx, 4); - ctx->pic_code_ext_head.f_code[1][0] = m2vd_read_bits(bx, 4); - ctx->pic_code_ext_head.f_code[1][1] = m2vd_read_bits(bx, 4); - if (ctx->MPEG2_Flag) { - ctx->pic_head.full_pel_forward_vector = ctx->pic_code_ext_head.f_code[0][0]; - ctx->pic_head.forward_f_code = ctx->pic_code_ext_head.f_code[0][1]; - ctx->pic_head.full_pel_backward_vector = ctx->pic_code_ext_head.f_code[1][0]; - ctx->pic_head.backward_f_code = ctx->pic_code_ext_head.f_code[1][1]; - } - - ctx->pic_code_ext_head.intra_dc_precision = m2vd_read_bits(bx, 2); - ctx->pic_code_ext_head.picture_structure = m2vd_read_bits(bx, 2); - if (ctx->pic_code_ext_head.picture_structure == M2VD_PIC_STRUCT_FRAME) - ctx->pic_code_ext_head.top_field_first = m2vd_read_bits(bx, 1); - else { - m2vd_read_bits(bx, 1); - if ((ctx->pic_head.pre_picture_coding_type != ctx->pic_head.picture_coding_type) && - (ctx->pic_head.pre_picture_coding_type != M2VD_CODING_TYPE_I)) { - if (ctx->pic_code_ext_head.picture_structure == M2VD_PIC_STRUCT_TOP_FIELD) - ctx->top_first_cnt++; - else - ctx->bottom_first_cnt++; - } - if (ctx->top_first_cnt >= ctx->bottom_first_cnt) - ctx->pic_code_ext_head.top_field_first = 1; - else - ctx->pic_code_ext_head.top_field_first = 0; - } - ctx->pic_code_ext_head.frame_pred_frame_dct = m2vd_read_bits(bx, 1); - ctx->pic_code_ext_head.concealment_motion_vectors = m2vd_read_bits(bx, 1); - ctx->pic_code_ext_head.q_scale_type = m2vd_read_bits(bx, 1); - ctx->pic_code_ext_head.intra_vlc_format = m2vd_read_bits(bx, 1); - ctx->pic_code_ext_head.alternate_scan = m2vd_read_bits(bx, 1); - ctx->pic_code_ext_head.repeat_first_field = m2vd_read_bits(bx, 1); - ctx->pic_code_ext_head.chroma_420_type = m2vd_read_bits(bx, 1); - ctx->pic_code_ext_head.progressive_frame = m2vd_read_bits(bx, 1); - ctx->pic_code_ext_head.composite_display_flag = m2vd_read_bits(bx, 1); - if (ctx->pic_code_ext_head.composite_display_flag) { - ctx->pic_code_ext_head.v_axis = m2vd_read_bits(bx, 1); - ctx->pic_code_ext_head.field_sequence = m2vd_read_bits(bx, 3); - ctx->pic_code_ext_head.sub_carrier = m2vd_read_bits(bx, 1); - ctx->pic_code_ext_head.burst_amplitude = m2vd_read_bits(bx, 7); - ctx->pic_code_ext_head.sub_carrier_phase = m2vd_read_bits(bx, 8); - } - return M2VD_DEC_OK; -} - - -int m2vd_decode_temp_ext_header(void) -{ - return M2VD_DEC_UNSURPORT; -} - - -int m2vd_decode_copyright_ext_header(M2VDParserContext *ctx) -{ - int copyright_flag; - int copyright_identifier; - int original_or_copy; - int copyright_number_1; - int copyright_number_2; - int copyright_number_3; - int reserved_data; - BitReadCtx_t *bx = ctx->bitread_ctx; - - copyright_flag = m2vd_read_bits(bx, 1); - copyright_identifier = m2vd_read_bits(bx, 8); - original_or_copy = m2vd_read_bits(bx, 1); - - /* reserved */ - reserved_data = m2vd_read_bits(bx, 7); - - mpp_skip_bits(bx, 1); - copyright_number_1 = m2vd_read_bits(bx, 20); - mpp_skip_bits(bx, 1); - copyright_number_2 = m2vd_read_bits(bx, 22); - mpp_skip_bits(bx, 1); - copyright_number_3 = m2vd_read_bits(bx, 22); - - (void)copyright_flag; - (void)copyright_identifier; - (void)original_or_copy; - (void)copyright_number_1; - (void)copyright_number_2; - (void)copyright_number_3; - (void)reserved_data; - - return M2VD_DEC_OK; -} - - - -int m2vd_decode_ext_header(M2VDParserContext *ctx) -{ - RK_U32 code; - RK_U32 ext_ID; - int result; - BitReadCtx_t *bx = ctx->bitread_ctx; - - code = m2vd_search_header(bx); - - if (M2VD_DBG_SEC_HEADER & m2vd_debug) { - mpp_log("[m2v]: decoder_ext_header : seach_header return code: %#03x", code); - } - while (code == EXTENSION_START_CODE || code == USER_DATA_START_CODE) { - if (code == EXTENSION_START_CODE) { - mpp_skip_bits(bx, 32); - ext_ID = m2vd_read_bits(bx, 4); - if (M2VD_DBG_SEC_HEADER & m2vd_debug) { - mpp_log("[m2v]: decoder_ext_header : ext_ID: %d", ext_ID); - } - switch (ext_ID) { - case SEQUENCE_EXTENSION_ID: - result = m2vd_decode_seq_ext_header(ctx); - break; - case SEQUENCE_DISPLAY_EXTENSION_ID: - result = m2vd_decode_seqdisp_ext_header(ctx); - break; - case QUANT_MATRIX_EXTENSION_ID: - result = m2vd_decode_matrix_ext_header(ctx); - break; - case SEQUENCE_SCALABLE_EXTENSION_ID: - result = m2vd_decode_scalable_ext_header(ctx); - break; - case PICTURE_DISPLAY_EXTENSION_ID: - result = m2vd_decode_picdisp_ext_header(ctx); - break; - case PICTURE_CODING_EXTENSION_ID: - result = m2vd_decode_pic_ext_header(ctx); - break; - case PICTURE_SPATIAL_SCALABLE_EXTENSION_ID: - result = m2vd_decode_spatial_ext_header(ctx); - break; - case PICTURE_TEMPORAL_SCALABLE_EXTENSION_ID: - result = m2vd_decode_temp_ext_header(); - break; - case COPYRIGHT_EXTENSION_ID: - result = m2vd_decode_copyright_ext_header(ctx); - break; - case NO_MORE_STREAM: - break; - default: - break; - } - - if (M2VD_DBG_SEC_HEADER & m2vd_debug) { - mpp_log("[m2v]: decoder_ext_header result: %d", result); - } - if (result) - return result; - } else { - mpp_skip_bits(bx, 32); - } - code = m2vd_search_header(bx); - } - - return MPP_OK; -} - -static int m2vd_decode_gop_header(M2VDParserContext *ctx) -{ - BitReadCtx_t *bx = ctx->bitread_ctx; - - ctx->gop_head.drop_flag = m2vd_read_bits(bx, 1); - ctx->gop_head.hour = m2vd_read_bits(bx, 5); - ctx->gop_head.minute = m2vd_read_bits(bx, 6); - - mpp_skip_bits(bx, 1); - - ctx->gop_head.sec = m2vd_read_bits(bx, 6); - ctx->gop_head.frame = m2vd_read_bits(bx, 6); - ctx->gop_head.closed_gop = m2vd_read_bits(bx, 1); - ctx->gop_head.broken_link = m2vd_read_bits(bx, 1); - - return m2vd_decode_ext_header(ctx); -} - - -int m2vd_decode_seq_header(M2VDParserContext *ctx) -{ - RK_U32 i; - BitReadCtx_t *bx = ctx->bitread_ctx; - ctx->seq_head.decode_width = m2vd_read_bits(bx, 12); - ctx->seq_head.decode_height = m2vd_read_bits(bx, 12); - ctx->display_width = ctx->seq_head.decode_width; - ctx->display_height = ctx->seq_head.decode_height; - ctx->seq_head.aspect_ratio_information = m2vd_read_bits(bx, 4); - ctx->seq_head.frame_rate_code = m2vd_read_bits(bx, 4); - if (!ctx->frame_period) - ctx->frame_period = frame_period_Table[ctx->seq_head.frame_rate_code]; - ctx->seq_head.bit_rate_value = m2vd_read_bits(bx, 18); - mpp_skip_bits(bx, 1); - ctx->seq_head.vbv_buffer_size = m2vd_read_bits(bx, 10); - ctx->seq_head.constrained_parameters_flag = m2vd_read_bits(bx, 1); - ctx->seq_head.load_intra_quantizer_matrix = m2vd_read_bits(bx, 1); - if (ctx->seq_head.load_intra_quantizer_matrix) { - for (i = 0; i < 64; i++) - ctx->seq_head.pIntra_table[scanOrder[0][i]] = (unsigned char)m2vd_read_bits(bx, 8); - } else { - for (i = 0; i < 64; i++) - ctx->seq_head.pIntra_table[i] = intraDefaultQMatrix[i]; - } - - ctx->seq_head.load_non_intra_quantizer_matrix = m2vd_read_bits(bx, 1); - if (ctx->seq_head.load_non_intra_quantizer_matrix) { - for (i = 0; i < 64; i++) - ctx->seq_head.pInter_table[scanOrder[0][i]] = (unsigned char)m2vd_read_bits(bx, 8); - - } else { - for (i = 0; i < 64; i++) - ctx->seq_head.pInter_table[i] = 16; - - } - - - return m2vd_decode_ext_header(ctx); -} - - -int m2vd_extra_bit_information(M2VDParserContext *ctx) -{ - BitReadCtx_t *bx = ctx->bitread_ctx; - while (m2vd_read_bits(bx, 1)) { - mpp_skip_bits(bx, 8); - } - return M2VD_DEC_OK; -} - -int m2vd_decode_pic_header(M2VDParserContext *ctx) -{ - BitReadCtx_t *bx = ctx->bitread_ctx; - ctx->pic_head.temporal_reference = m2vd_read_bits(bx, 10); - ctx->pic_head.picture_coding_type = m2vd_read_bits(bx, 3); - ctx->pic_head.vbv_delay = m2vd_read_bits(bx, 16); - if (ctx->pic_head.temporal_reference > 50) { - ctx->pic_head.temporal_reference = ctx->pretemporal_reference; - } - //if ((maxFrame_inGOP < temporal_reference)&&(temporal_reference<60)) - // maxFrame_inGOP = temporal_reference; - if (((RK_S32)ctx->maxFrame_inGOP < ctx->pic_head.temporal_reference) && (ctx->pic_head.temporal_reference < 60)) - ctx->maxFrame_inGOP = ctx->pic_head.temporal_reference; - - - if (ctx->pic_head.picture_coding_type == M2VD_CODING_TYPE_P || - ctx->pic_head.picture_coding_type == M2VD_CODING_TYPE_B) { - ctx->pic_head.full_pel_forward_vector = m2vd_read_bits(bx, 1); - ctx->pic_head.forward_f_code = m2vd_read_bits(bx, 3); - } - if (ctx->pic_head.picture_coding_type == M2VD_CODING_TYPE_B) { - ctx->pic_head.full_pel_backward_vector = m2vd_read_bits(bx, 1); - ctx->pic_head.backward_f_code = m2vd_read_bits(bx, 3); - } - - m2vd_extra_bit_information(ctx); - - return m2vd_decode_ext_header(ctx); -} - - - -MPP_RET m2vd_decode_head(M2VDParserContext *ctx) -{ - RK_U32 code; - int ret = 0; - BitReadCtx_t *bx = ctx->bitread_ctx; - - FUN_T("FUN_I"); - while (1) { - code = m2vd_search_header(bx); - if (M2VD_DBG_SEC_HEADER & m2vd_debug) { - mpp_log("[m2v]: decoder_header : seach_header return code: 0x%3x", code); - } - if (code == NO_MORE_STREAM) - return M2VD_DEC_FILE_END; - code = m2vd_read_bits(bx, 32); - - switch (code) { - case SEQUENCE_HEADER_CODE: - ret = m2vd_decode_seq_header(ctx); - if (!ret) { - ctx->mHeaderDecFlag = 1; - } - break; - case GROUP_START_CODE: - ret = m2vd_decode_gop_header(ctx); - break; - case PICTURE_START_CODE: - ret = m2vd_decode_pic_header(ctx); - ret = M2VD_DEC_PICHEAD_OK; - break; - case SEQUENCE_END_CODE: - ret = M2VD_DEC_STREAM_END; - break; - default: - if (M2VD_DBG_SEC_HEADER & m2vd_debug) { - mpp_log("code=%x,leftbit=%d", code, m2vd_get_leftbits(bx)); - } - break; - } - if (ret) - break; - } - FUN_T("FUN_O"); - - return ret; -} - -MPP_RET m2vd_alloc_frame(M2VDParserContext *ctx) -{ - RK_U32 pts = (RK_U32)(ctx->pts / 1000); - if (ctx->resetFlag && ctx->pic_head.picture_coding_type != M2VD_CODING_TYPE_I) { - mpp_log("[m2v]: resetFlag[%d] && picture_coding_type[%d] != I_TYPE", ctx->resetFlag, ctx->pic_head.picture_coding_type); - return MPP_NOK; - } else { - ctx->resetFlag = 0; - } - if ((ctx->pic_code_ext_head.picture_structure == M2VD_PIC_STRUCT_FRAME ) || - ((ctx->pic_code_ext_head.picture_structure == M2VD_PIC_STRUCT_TOP_FIELD) && ctx->pic_code_ext_head.top_field_first) || - ((ctx->pic_code_ext_head.picture_structure == M2VD_PIC_STRUCT_BOTTOM_FIELD) && (!ctx->pic_code_ext_head.top_field_first)) || - (ctx->frame_cur->slot_index == 0xff)) { - RK_S32 Time; - if (ctx->PreGetFrameTime != pts) { - RK_U32 tmp_frame_period; - if (ctx->GroupFrameCnt) { - ctx->GroupFrameCnt = ctx->GroupFrameCnt + ctx->pic_head.temporal_reference; - } else if (ctx->pic_head.temporal_reference == (RK_S32)ctx->PreChangeTime_index) - ctx->GroupFrameCnt = ctx->max_temporal_reference + 1; - else if (ctx->pic_head.temporal_reference) - ctx->GroupFrameCnt = ctx->pic_head.temporal_reference - ctx->PreChangeTime_index; - else - ctx->GroupFrameCnt = ctx->max_temporal_reference - ctx->PreChangeTime_index + 1; - - tmp_frame_period = pts - ctx->PreGetFrameTime; - if ((pts > ctx->PreGetFrameTime) && (ctx->GroupFrameCnt > 0)) { - tmp_frame_period = (tmp_frame_period * 256) / ctx->GroupFrameCnt; - if ((tmp_frame_period > 4200) && (tmp_frame_period < 11200) && (abs(ctx->frame_period - tmp_frame_period) > 128)) { - if (abs(ctx->preframe_period - tmp_frame_period) > 128) - ctx->preframe_period = tmp_frame_period; - else - ctx->frame_period = tmp_frame_period; - } - } - ctx->Group_start_Time = pts - (ctx->pic_head.temporal_reference * ctx->frame_period / 256); - if (ctx->Group_start_Time < 0) - ctx->Group_start_Time = 0; - ctx->PreGetFrameTime = pts; - ctx->PreChangeTime_index = ctx->pic_head.temporal_reference; - ctx->GroupFrameCnt = 0; - } else if ((RK_S32)ctx->pretemporal_reference > ctx->pic_head.temporal_reference + 5) { - ctx->Group_start_Time += ((ctx->max_temporal_reference + 1) * ctx->frame_period / 256); - ctx->GroupFrameCnt = ctx->max_temporal_reference - ctx->PreChangeTime_index + 1; - ctx->max_temporal_reference = 0; - } - if ((RK_S32)ctx->pretemporal_reference > ctx->pic_head.temporal_reference + 5) - ctx->max_temporal_reference = 0; - if (ctx->pic_head.temporal_reference > (RK_S32)ctx->max_temporal_reference) - ctx->max_temporal_reference = ctx->pic_head.temporal_reference; - ctx->pretemporal_reference = ctx->pic_head.temporal_reference; - /*if(picture_coding_type == I_TYPE) - { - if (Video_Bitsream.Slice_Time.low_part >= (RK_U32)(frame_period/128)) - Group_start_Time = Video_Bitsream.Slice_Time.low_part - (RK_U32)(frame_period/128); - else - Group_start_Time = Video_Bitsream.Slice_Time.low_part; - }*/ - Time = ctx->Group_start_Time; - Time += ((ctx->pic_head.temporal_reference * ctx->frame_period) / 256); - if (Time < 0) { - Time = 0; - } - //base.Current_frame->ShowTime = Time;//Video_Bitsream.Slice_Time.low_part; - - if (ctx->pic_head.picture_coding_type != M2VD_CODING_TYPE_I && ctx->pic_head.pre_picture_coding_type == ctx->pic_head.picture_coding_type) { - if ((ctx->pic_head.temporal_reference - ctx->pic_head.pre_temporal_reference > 3) || (ctx->pic_head.temporal_reference - ctx->pic_head.pre_temporal_reference < -3)) { - if (ctx->frame_cur->error_info == 0) - ctx->frame_cur->error_info = 1; - } - } else { - ctx->frame_cur->error_info = 0; - } - ctx->pic_head.pre_temporal_reference = ctx->pic_head.temporal_reference; - ctx->pic_head.pre_picture_coding_type = ctx->pic_head.picture_coding_type; - - ctx->frame_cur->picCodingType = ctx->pic_head.picture_coding_type; - ctx->seq_head.decode_height = (ctx->seq_head.decode_height + 15) & (~15); - ctx->seq_head.decode_width = (ctx->seq_head.decode_width + 15) & (~15); - if (ctx->frame_cur->slot_index == 0xff) { - RK_U32 frametype = 0; - mpp_frame_set_width(ctx->frame_cur->f, ctx->display_width); - mpp_frame_set_height(ctx->frame_cur->f, ctx->display_height); - mpp_frame_set_hor_stride(ctx->frame_cur->f, ctx->display_width); - mpp_frame_set_ver_stride(ctx->frame_cur->f, ctx->display_height); - mpp_frame_set_errinfo(ctx->frame_cur->f, 0); - mpp_frame_set_pts(ctx->frame_cur->f, Time * 1000); - mpp_buf_slot_get_unused(ctx->frame_slots, &ctx->frame_cur->slot_index); - mpp_buf_slot_set_prop(ctx->frame_slots, ctx->frame_cur->slot_index, SLOT_FRAME, ctx->frame_cur->f); - mpp_buf_slot_set_flag(ctx->frame_slots, ctx->frame_cur->slot_index, SLOT_CODEC_USE); - mpp_buf_slot_set_flag(ctx->frame_slots, ctx->frame_cur->slot_index, SLOT_HAL_OUTPUT); - ctx->frame_cur->flags = M2V_OUT_FLAG; - if (ctx->seq_ext_head.progressive_sequence) { - frametype = MPP_FRAME_FLAG_FRAME; - } else { - frametype = MPP_FRAME_FLAG_PAIRED_FIELD; - if (ctx->pic_code_ext_head.top_field_first) - frametype |= MPP_FRAME_FLAG_TOP_FIRST; - else - frametype |= MPP_FRAME_FLAG_BOT_FIRST; - } - mpp_frame_set_mode(ctx->frame_cur->f, frametype); - } - } - //alloc frame space - if ((ctx->ref_frame_cnt < 2) && (ctx->frame_cur->picCodingType == M2VD_CODING_TYPE_B)) { - mpp_log("[m2v]: (ref_frame_cnt[%d] < 2) && (frame_cur->picCodingType[%d] == B_TYPE)", ctx->ref_frame_cnt, ctx->frame_cur->picCodingType); - return MPP_NOK; - } - - return MPP_OK; -} -MPP_RET m2v_update_ref_frame(M2VDParserContext *p) -{ - - MPP_RET ret = MPP_OK; - FUN_T("FUN_I"); - //push frame - if ((p->pic_code_ext_head.picture_structure == M2VD_PIC_STRUCT_FRAME) || - ((p->pic_code_ext_head.picture_structure == M2VD_PIC_STRUCT_BOTTOM_FIELD) && p->pic_code_ext_head.top_field_first ) || - ((p->pic_code_ext_head.picture_structure == M2VD_PIC_STRUCT_TOP_FIELD) && (!p->pic_code_ext_head.top_field_first))) { - - if (p->frame_cur->picCodingType == M2VD_CODING_TYPE_B) { - mpp_buf_slot_set_flag(p->frame_slots, p->frame_cur->slot_index, SLOT_QUEUE_USE); - mpp_buf_slot_enqueue(p->frame_slots, p->frame_cur->slot_index, QUEUE_DISPLAY); - mpp_buf_slot_clr_flag(p->frame_slots, p->frame_cur->slot_index, SLOT_CODEC_USE); - p->frame_cur->slot_index = 0xFF; - } else if (p->frame_cur->picCodingType != 0xffffffff) { - M2VDFrameHead *tmpHD = NULL; - p->ref_frame_cnt++; - if (p->frame_ref0->slot_index < 0x7f) { - mpp_buf_slot_set_flag(p->frame_slots, p->frame_ref0->slot_index, SLOT_QUEUE_USE); - mpp_buf_slot_enqueue(p->frame_slots, p->frame_ref0->slot_index, QUEUE_DISPLAY); - p->frame_ref0->flags = 0; - } - if (p->frame_ref1->slot_index < 0x7f) { - mpp_buf_slot_clr_flag(p->frame_slots, p->frame_ref1->slot_index, SLOT_CODEC_USE); - p->frame_ref1->slot_index = 0xff; - } - tmpHD = p->frame_ref1; - p->frame_ref1 = p->frame_ref0; - p->frame_ref0 = p->frame_cur; - p->frame_cur = tmpHD; - } - } - return ret; -} - -MPP_RET m2vd_convert_to_dxva(M2VDParserContext *p) -{ - MPP_RET ret = MPP_OK; - FUN_T("FUN_I"); - M2VDDxvaParam *dst = p->dxva_ctx; - M2VDFrameHead *pfw = p->frame_ref1; - M2VDFrameHead *pbw = p->frame_ref0; - BitReadCtx_t *bx = p->bitread_ctx; - RK_U32 i = 0; - RK_S32 readbits = m2vd_get_readbits(bx); - - dst->seq.decode_width = p->seq_head.decode_width; - dst->seq.decode_height = p->seq_head.decode_height; - dst->seq.aspect_ratio_information = p->seq_head.aspect_ratio_information; - dst->seq.frame_rate_code = p->seq_head.frame_rate_code; - dst->seq.bit_rate_value = p->seq_head.bit_rate_value; - dst->seq.vbv_buffer_size = p->seq_head.vbv_buffer_size; - dst->seq.constrained_parameters_flag = p->seq_head.constrained_parameters_flag; - dst->seq.load_intra_quantizer_matrix = p->seq_head.load_intra_quantizer_matrix; - dst->seq.load_non_intra_quantizer_matrix = p->seq_head.load_non_intra_quantizer_matrix; - - dst->seq_ext.profile_and_level_indication = p->seq_ext_head.profile_and_level_indication; - dst->seq_ext.progressive_sequence = p->seq_ext_head.progressive_sequence; - dst->seq_ext.chroma_format = p->seq_ext_head.chroma_format; - dst->seq_ext.low_delay = p->seq_ext_head.low_delay; - dst->seq_ext.frame_rate_extension_n = p->seq_ext_head.frame_rate_extension_n; - dst->seq_ext.frame_rate_extension_d = p->seq_ext_head.frame_rate_extension_d; - - - dst->gop.drop_flag = p->gop_head.drop_flag; - dst->gop.hour = p->gop_head.hour; - dst->gop.minute = p->gop_head.minute; - dst->gop.sec = p->gop_head.sec; - dst->gop.frame = p->gop_head.frame; - dst->gop.closed_gop = p->gop_head.closed_gop; - dst->gop.broken_link = p->gop_head.broken_link; - - - dst->pic.temporal_reference = p->pic_head.temporal_reference; - dst->pic.picture_coding_type = p->pic_head.picture_coding_type; - dst->pic.pre_picture_coding_type = p->pic_head.pre_picture_coding_type; - dst->pic.vbv_delay = p->pic_head.vbv_delay; - dst->pic.full_pel_forward_vector = p->pic_head.full_pel_forward_vector; - dst->pic.forward_f_code = p->pic_head.forward_f_code; - dst->pic.full_pel_backward_vector = p->pic_head.full_pel_backward_vector; - dst->pic.backward_f_code = p->pic_head.backward_f_code; - dst->pic.pre_temporal_reference = p->pic_head.pre_temporal_reference; - - dst->seq_disp_ext.video_format = p->seq_disp_ext_head.video_format; - dst->seq_disp_ext.color_description = p->seq_disp_ext_head.color_description; - dst->seq_disp_ext.color_primaries = p->seq_disp_ext_head.color_primaries; - dst->seq_disp_ext.transfer_characteristics = p->seq_disp_ext_head.transfer_characteristics; - dst->seq_disp_ext.matrix_coefficients = p->seq_disp_ext_head.matrix_coefficients; - - memcpy(dst->pic_code_ext.f_code, p->pic_code_ext_head.f_code, 2 * 2 * sizeof(RK_S32)); - dst->pic_code_ext.intra_dc_precision = p->pic_code_ext_head.intra_dc_precision; - dst->pic_code_ext.picture_structure = p->pic_code_ext_head.picture_structure; - dst->pic_code_ext.top_field_first = p->pic_code_ext_head.top_field_first; - dst->pic_code_ext.frame_pred_frame_dct = p->pic_code_ext_head.frame_pred_frame_dct; - dst->pic_code_ext.concealment_motion_vectors = p->pic_code_ext_head.concealment_motion_vectors; - dst->pic_code_ext.q_scale_type = p->pic_code_ext_head.q_scale_type; - dst->pic_code_ext.intra_vlc_format = p->pic_code_ext_head.intra_vlc_format; - dst->pic_code_ext.alternate_scan = p->pic_code_ext_head.alternate_scan; - dst->pic_code_ext.repeat_first_field = p->pic_code_ext_head.repeat_first_field; - dst->pic_code_ext.chroma_420_type = p->pic_code_ext_head.chroma_420_type; - dst->pic_code_ext.progressive_frame = p->pic_code_ext_head.progressive_frame; - dst->pic_code_ext.composite_display_flag = p->pic_code_ext_head.composite_display_flag; - dst->pic_code_ext.v_axis = p->pic_code_ext_head.v_axis; - dst->pic_code_ext.field_sequence = p->pic_code_ext_head.field_sequence; - dst->pic_code_ext.sub_carrier = p->pic_code_ext_head.sub_carrier; - dst->pic_code_ext.burst_amplitude = p->pic_code_ext_head.burst_amplitude; - dst->pic_code_ext.sub_carrier_phase = p->pic_code_ext_head.sub_carrier_phase; - - memcpy(dst->pic_disp_ext.frame_center_horizontal_offset, p->pic_disp_ext_head.frame_center_horizontal_offset, 3 * sizeof(RK_S32)); - memcpy(dst->pic_disp_ext.frame_center_vertical_offset, p->pic_disp_ext_head.frame_center_vertical_offset, 3 * sizeof(RK_S32)); - - dst->bitstream_length = p->frame_size - ((readbits >> 3) & (~7)); - dst->bitstream_offset = ((readbits >> 3) & (~7)); - dst->bitstream_start_bit = readbits & 0x3f; - dst->qp_tab = p->qp_tab_sw_buf; - dst->CurrPic.Index7Bits = p->frame_cur->slot_index; - - if (p->frame_ref0->slot_index == 0xff) { - pbw = p->frame_cur; - } - if (p->frame_ref1->slot_index == 0xff) { - pfw = pbw; - } - - for (i = 0; i < 4; i++) { - dst->frame_refs[i].bPicEntry = 0xff; - } - if (p->pic_head.picture_coding_type == M2VD_CODING_TYPE_B) { - dst->frame_refs[0].Index7Bits = pfw->slot_index; - dst->frame_refs[1].Index7Bits = pfw->slot_index; - dst->frame_refs[2].Index7Bits = pbw->slot_index; - dst->frame_refs[3].Index7Bits = pbw->slot_index; - //p->frame_cur->->ErrorInfo = pfw->frame_space->ErrorInfo | pbw->frame_space->ErrorInfo; - } else { - if ((p->pic_code_ext_head.picture_structure == M2VD_PIC_STRUCT_FRAME) || - ((p->pic_code_ext_head.picture_structure == M2VD_PIC_STRUCT_TOP_FIELD) && p->pic_code_ext_head.top_field_first) || - ((p->pic_code_ext_head.picture_structure == M2VD_PIC_STRUCT_BOTTOM_FIELD) && (!p->pic_code_ext_head.top_field_first))) { - dst->frame_refs[0].Index7Bits = pbw->slot_index; - dst->frame_refs[1].Index7Bits = pbw->slot_index; - } else if (p->pic_code_ext_head.picture_structure == M2VD_PIC_STRUCT_TOP_FIELD) { - dst->frame_refs[0].Index7Bits = pbw->slot_index; - dst->frame_refs[1].Index7Bits = p->frame_cur->slot_index; - } else if (p->pic_code_ext_head.picture_structure == M2VD_PIC_STRUCT_BOTTOM_FIELD) { - dst->frame_refs[0].Index7Bits = p->frame_cur->slot_index; - dst->frame_refs[1].Index7Bits = pbw->slot_index; - } - dst->frame_refs[2].Index7Bits = p->frame_cur->slot_index; - dst->frame_refs[3].Index7Bits = p->frame_cur->slot_index; -// p->frame_cur->frame_space->ErrorInfo = pbw->frame_space->ErrorInfo; - } - dst->seq_ext_head_dec_flag = p->MPEG2_Flag; - FUN_T("FUN_O"); - return ret; -} - - -MPP_RET m2vd_parser_parse(void *ctx, HalDecTask *in_task) -{ - MPP_RET ret = MPP_OK; - int rev = 0; - M2VDContext *c = (M2VDContext *)ctx; - M2VDParserContext *p = (M2VDParserContext *)c->parse_ctx; - FUN_T("FUN_I"); - - CHK_I(in_task->valid); - - in_task->valid = 0; - - p->flush_dpb_eos = 0; - - p->frame_size = (RK_U32)mpp_packet_get_length(in_task->input_packet); - - mpp_set_bitread_ctx(p->bitread_ctx, p->bitstream_sw_buf, p->frame_size); - - rev = m2vd_decode_head(p); - - if (!p->mHeaderDecFlag) { - mpp_log("[m2v]: !mHeaderDecFlag"); - goto __FAILED; - } - - p->mb_width = (p->seq_head.decode_width + 15) >> 4; - p->mb_height = (p->seq_head.decode_height + 15) >> 4; - - if (rev < M2VD_DEC_OK) { - if (M2VD_DBG_SEC_HEADER & m2vd_debug) { - mpp_log("decoder_header error rev %d", rev); - } - goto __FAILED; - } - - if (rev == M2VD_DEC_PICHEAD_OK) { - if (MPP_OK != m2vd_alloc_frame(p)) { - mpp_err("m2vd_alloc_frame not OK"); - goto __FAILED; - } - m2vd_convert_to_dxva(p); - in_task->syntax.data = (void *)p->dxva_ctx; - in_task->syntax.number = sizeof(M2VDDxvaParam); - in_task->output = p->frame_cur->slot_index; - p->pic_head.pre_picture_coding_type = p->pic_head.picture_coding_type; - - if (p->frame_ref0->slot_index < 0x7f && - (p->frame_ref0->slot_index != p->frame_cur->slot_index)) { - mpp_buf_slot_set_flag(p->frame_slots, p->frame_ref0->slot_index, SLOT_HAL_INPUT); - in_task->refer[0] = p->frame_ref0->slot_index; - } - - if (p->frame_ref1->slot_index < 0x7f && (p->frame_ref1->slot_index != p->frame_cur->slot_index)) { - mpp_buf_slot_set_flag(p->frame_slots, p->frame_ref1->slot_index, SLOT_HAL_INPUT); - in_task->refer[1] = p->frame_ref1->slot_index; - } - in_task->valid = 1; - m2v_update_ref_frame(p); - } - -__FAILED: - if (p->eos) { - m2vd_parser_flush(ctx); - } - - FUN_T("FUN_O"); - - return ret; -} - -MPP_RET m2vd_parser_callback(void *ctx, void *errinfo) -{ - MPP_RET ret = MPP_OK; - FUN_T("FUN_I"); - (void)ctx; - (void)errinfo; - FUN_T("FUN_O"); - return ret; -} +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define MODULE_TAG "m2vd_parser" +#include + +#include "m2vd_parser.h" +#include "m2vd_codec.h" + +#include "mpp_frame.h" +#include "mpp_env.h" + +RK_U32 m2vd_debug = 0x0; + +RK_U8 scanOrder[2][64] = { + { /* zig-zag */ + 0, 1, 8, 16, 9, 2, 3, 10, + 17, 24, 32, 25, 18, 11, 4, 5, + 12, 19, 26, 33, 40, 48, 41, 34, + 27, 20, 13, 6, 7, 14, 21, 28, + 35, 42, 49, 56, 57, 50, 43, 36, + 29, 22, 15, 23, 30, 37, 44, 51, + 58, 59, 52, 45, 38, 31, 39, 46, + 53, 60, 61, 54, 47, 55, 62, 63 + }, + + { /* Alternate */ + 0, 8, 16, 24, 1, 9, 2, 10, + 17, 25, 32, 40, 48, 56, 57, 49, + 41, 33, 26, 18, 3, 11, 4, 12, + 19, 27, 34, 42, 50, 58, 35, 43, + 51, 59, 20, 28, 5, 13, 6, 14, + 21, 29, 36, 44, 52, 60, 37, 45, + 53, 61, 22, 30, 7, 15, 23, 31, + 38, 46, 54, 62, 39, 47, 55, 63 + } +}; + +RK_U8 intraDefaultQMatrix[64] = { + 8, 16, 19, 22, 26, 27, 29, 34, + 16, 16, 22, 24, 27, 29, 34, 37, + 19, 22, 26, 27, 29, 34, 34, 38, + 22, 22, 26, 27, 29, 34, 37, 40, + 22, 26, 27, 29, 32, 35, 40, 48, + 26, 27, 29, 32, 35, 40, 48, 58, + 26, 27, 29, 34, 38, 46, 56, 69, + 27, 29, 35, 38, 46, 56, 69, 83 +}; + + +int frame_period_Table[16] = { + 1, + 11142, + 10667, + 10240, + 8542, + 8533, + 5120, + 4271, + 4267, + + 1, + 1, + 1, + 1, + 1, + 1, + 1 +}; + +static RK_S32 m2vd_get_readbits(BitReadCtx_t *bx) +{ + return bx->used_bits; +} + +static RK_S32 m2vd_get_leftbits(BitReadCtx_t *bx) +{ + return (bx->bytes_left_ * 8 + bx->num_remaining_bits_in_curr_byte_); +} + +static RK_S32 m2vd_read_bits(BitReadCtx_t *bx, RK_U32 bits) +{ + RK_S32 ret = 0; + if (bits < 32) + mpp_read_bits(bx, bits, &ret); + else + mpp_read_longbits(bx, bits, (RK_U32 *)&ret); + return ret; +} + +static RK_S32 m2vd_show_bits(BitReadCtx_t *bx, RK_U32 bits) +{ + RK_S32 ret = 0; + mpp_show_bits(bx, bits, &ret); + return ret; +} + + +RK_S32 m2vd_parser_read_one_frame(M2VDParserContext *ctx) +{ + (void)ctx; + return MPP_OK; +} + +static MPP_RET m2vd_parser_init_ctx(M2VDParserContext *ctx, ParserCfg *cfg) +{ + MPP_RET ret = MPP_OK; + RK_S32 i = 0; + FUN_T("FUN_I"); + + CHK_I(ctx); + memset(ctx, 0, sizeof(*ctx)); + + ctx->dxva_ctx = mpp_calloc(M2VDDxvaParam, 1); + ctx->bitread_ctx = mpp_calloc(BitReadCtx_t, 1); + + ctx->packet_slots = cfg->packet_slots; + ctx->frame_slots = cfg->frame_slots; + + ctx->notify_cb = cfg->notify_cb; + + mpp_buf_slot_setup(ctx->frame_slots, 16); + + ctx->initFlag = 0; + + /* copy from mpeg2decoder::mpeg2decoder */ + memset(&ctx->Framehead, 0, 3 * sizeof(M2VDFrameHead)); + + ctx->frame_ref0 = &ctx->Framehead[0]; + ctx->frame_ref1 = &ctx->Framehead[1]; + ctx->frame_cur = &ctx->Framehead[2]; + for (i = 0; i < 3; i++) { + mpp_frame_init(&ctx->Framehead[i].f); + if (!ctx->Framehead[i].f) { + mpp_err("Failed to allocate frame buffer %d\n", i); + return MPP_ERR_NOMEM; + } + ctx->Framehead[i].picCodingType = 0xffffffff; + ctx->Framehead[i].slot_index = 0xff; + } +#if M2VD_SKIP_ERROR_FRAME_EN + ctx->mHwDecStatus = MPP_OK; +#endif + ctx->resetFlag = 0; + ctx->flush_dpb_eos = 0; + ctx->pic_head.pre_temporal_reference = 0; + ctx->pic_head.pre_picture_coding_type = 0; + ctx->pic_head.picture_coding_type = 0; + + /* copy form mpeg2decoder::decoder_init */ + //---------------------------------------------------- + ctx->bitstream_sw_buf = mpp_calloc(RK_U8, M2VD_BUF_SIZE_BITMEM); + mpp_packet_init(&ctx->input_packet, ctx->bitstream_sw_buf, M2VD_BUF_SIZE_BITMEM); + + ctx->qp_tab_sw_buf = mpp_calloc(RK_U8, M2VD_BUF_SIZE_QPTAB); + ctx->seq_head.pIntra_table = ctx->qp_tab_sw_buf; + ctx->seq_head.pInter_table = ctx->seq_head.pIntra_table + 64; + + ctx->MPEG2_Flag = 0; + ctx->seq_ext_head.progressive_sequence = 1; + ctx->pic_code_ext_head.progressive_frame = 1; + ctx->pic_code_ext_head.picture_structure = M2VD_PIC_STRUCT_FRAME; + ctx->pic_head.pre_picture_coding_type = M2VD_CODING_TYPE_D; + ctx->top_first_cnt = 0; + ctx->bottom_first_cnt = 0; + ctx->pic_code_ext_head.frame_pred_frame_dct = 1; + ctx->seq_ext_head.chroma_format = 1; + ctx->seq_disp_ext_head.matrix_coefficients = 5; + ctx->PreGetFrameTime = 0; + ctx->maxFrame_inGOP = 0; + ctx->preframe_period = 0; + ctx->mHeaderDecFlag = 0; + ctx->max_stream_size = M2VD_BUF_SIZE_BITMEM; + ctx->ref_frame_cnt = 0; + + + if (M2VD_DBG_DUMP_REG & m2vd_debug) { + RK_S32 k = 0; + for (k = 0; k < M2VD_DBG_FILE_NUM; k++) + ctx->fp_dbg_file[k] = NULL; + + ctx->fp_dbg_file[0] = fopen("/sdcard/m2vd_dbg_stream.txt", "wb"); + if (!ctx->fp_dbg_file[0]) + mpp_log("open file failed: %s", "/sdcard/m2vd_dbg_stream.txt"); + + ctx->fp_dbg_yuv = fopen("/sdcard/m2vd_dbg_yuv_out.txt", "wb"); + if (!ctx->fp_dbg_yuv) + mpp_log("open file failed: %s", "/sdcard/m2vd_dbg_yuv_out.txt"); + } else { + RK_S32 k = 0; + for (k = 0; k < M2VD_DBG_FILE_NUM; k++) + ctx->fp_dbg_file[k] = NULL; + } + + + FUN_T("FUN_O"); +__FAILED: + + return ret; +} + + +MPP_RET m2vd_parser_init(void *ctx, ParserCfg *parser_cfg) +{ + MPP_RET ret = MPP_OK; + M2VDContext *c = (M2VDContext *)ctx; + M2VDParserContext *p = (M2VDParserContext *)c->parse_ctx; + FUN_T("FUN_I"); + if (p == NULL) { + CHK_M(p = (M2VDParserContext*)mpp_calloc(M2VDParserContext, 1)); + c->parse_ctx = p; + } + + CHK_F(m2vd_parser_init_ctx(p, parser_cfg)); + + mpp_env_get_u32("m2vd_debug", &m2vd_debug, 0); + + FUN_T("FUN_O"); +__FAILED: + return ret; +} + + +MPP_RET m2vd_parser_deinit(void *ctx) +{ + RK_U32 k = 0; + MPP_RET ret = MPP_OK; + M2VDContext *c = (M2VDContext *)ctx; + M2VDParserContext *p = (M2VDParserContext *)c->parse_ctx; + + FUN_T("FUN_I"); + + for (k = 0; k < M2VD_DBG_FILE_NUM; k++) { + M2VD_FCLOSE(p->fp_dbg_file[k]); + } + M2VD_FCLOSE(p->fp_dbg_yuv); + + if (p->bitstream_sw_buf) { + mpp_free(p->bitstream_sw_buf); + p->bitstream_sw_buf = NULL; + } + if (p->qp_tab_sw_buf) { + mpp_free(p->qp_tab_sw_buf); + p->qp_tab_sw_buf = NULL; + } + + if (p->input_packet) { + mpp_packet_deinit(&p->input_packet); + } + + if (p->dxva_ctx) { + mpp_free(p->dxva_ctx); + p->dxva_ctx = NULL; + } + if (p->bitread_ctx) { + mpp_free(p->bitread_ctx); + p->bitread_ctx = NULL; + } + + for (k = 0; k < 3; k++) { + mpp_free(p->Framehead[k].f); + } + + if (p) { + mpp_free(p); + } + + FUN_T("FUN_O"); + return ret; +} +/*! +*********************************************************************** +* \brief +* reset +*********************************************************************** +*/ +MPP_RET m2vd_parser_reset(void *ctx) +{ + MPP_RET ret = MPP_OK; + M2VDContext *c = (M2VDContext *)ctx; + M2VDParserContext *p = (M2VDParserContext *)c->parse_ctx; + FUN_T("FUN_I"); + if (p->frame_cur->slot_index != 0xff) { +#if 0 + MppBuffer framebuf = NULL; //current buf may alloc + mpp_buf_slot_get_prop(p->frame_slots, p->frame_cur->slot_index, SLOT_BUFFER, &framebuf); + mpp_buffer_put(framebuf); +#endif + mpp_buf_slot_clr_flag(p->frame_slots, p->frame_cur->slot_index, SLOT_CODEC_USE); + } + + if (p->frame_ref0->slot_index != 0xff ) { + + if (p->frame_ref0->flags) { + mpp_buf_slot_set_flag(p->frame_slots, p->frame_ref0->slot_index, SLOT_QUEUE_USE); + mpp_buf_slot_enqueue(p->frame_slots, p->frame_ref0->slot_index, QUEUE_DISPLAY); + p->frame_ref0->flags = 0; + } + mpp_buf_slot_clr_flag(p->frame_slots, p->frame_ref0->slot_index, SLOT_CODEC_USE); + } + + if (p->frame_ref1->slot_index != 0xff) { + mpp_buf_slot_clr_flag(p->frame_slots, p->frame_ref1->slot_index, SLOT_CODEC_USE); + } + + p->frame_cur->slot_index = 0xff; + p->frame_ref0->slot_index = 0xff; + p->frame_ref1->slot_index = 0xff; + p->ref_frame_cnt = 0; + p->resetFlag = 1; + p->eos = 0; + FUN_T("FUN_O"); + return ret; +} + +/*! +*********************************************************************** +* \brief +* flush +*********************************************************************** +*/ +MPP_RET m2vd_parser_flush(void *ctx) +{ + MPP_RET ret = MPP_OK; + M2VDContext *c = (M2VDContext *)ctx; + M2VDParserContext *p = (M2VDParserContext *)c->parse_ctx; + FUN_T("FUN_I"); + if (p->frame_ref0->slot_index == 0xff) { + goto exit; + } + mpp_buf_slot_set_flag(p->frame_slots, p->frame_ref0->slot_index, SLOT_QUEUE_USE); + mpp_buf_slot_enqueue(p->frame_slots, p->frame_ref0->slot_index, QUEUE_DISPLAY); + p->frame_ref0->flags = 0; +exit: +#if 0 + if (p->eos) { + if ( p->frame_ref0->slot_index < 0xff) { + mpp_buf_slot_set_prop(p->frame_slots, p->frame_ref0->slot_index, SLOT_EOS, &p->eos); + } else { + if (p->notify_cb.callBack != NULL) { + p->notify_cb.callBack(p->notify_cb.opaque, NULL); + } + } + } +#endif + return ret; +} + +/*! +*********************************************************************** +* \brief +* control/perform +*********************************************************************** +*/ +MPP_RET m2vd_parser_control(void *ctx, RK_S32 cmd_type, void *param) +{ + MPP_RET ret = MPP_OK; + FUN_T("FUN_I"); + (void)ctx; + (void)cmd_type; + (void)param; + FUN_T("FUN_O"); + return ret; +} + + +/*! +*********************************************************************** +* \brief +* prepare +*********************************************************************** +*/ + +MPP_RET m2vd_parser_split_frame(RK_U8 *src, RK_U32 src_size, RK_U8 *dst, RK_U32 *dst_size) +{ + MPP_RET ret = MPP_OK; + RK_U32 val = 0; + val = *((RK_U32*)src); + +#define VPU_BITSTREAM_START_CODE (0x42564b52) /* RKVB, rockchip video bitstream */ + + if (VPU_BITSTREAM_START_CODE == val) { // if input data is rk format styl skip those 32 byte + memcpy(dst, src + 32, src_size - 32); + *dst_size = src_size - 32; + } else { + memcpy(dst, src, src_size); + *dst_size = src_size; + } + + (void)dst; + + return ret; +} + + +MPP_RET m2vd_parser_prepare(void *ctx, MppPacket pkt, HalDecTask *task) +{ + MPP_RET ret = MPP_OK; + M2VDContext *c = (M2VDContext *)ctx; + M2VDParserContext *p = (M2VDParserContext *)c->parse_ctx; + MppPacket input_packet = p->input_packet; + RK_U32 out_size = 0, len_in; + RK_U8 *pos = NULL; + RK_U8 *buf = NULL; + + + buf = pos = mpp_packet_get_pos(pkt); + p->pts = mpp_packet_get_pts(pkt); + + + //MppPacketImpl *packet = (MppPacketImpl *)pkt; + //uint32_t stream_count = 0; + + FUN_T("FUN_I"); + task->valid = 0; + len_in = (RK_U32)mpp_packet_get_length(pkt), + p->eos = mpp_packet_get_eos(pkt); + // mpp_log("len_in = %d",len_in); + if (len_in > p->max_stream_size) { + mpp_free(p->bitstream_sw_buf); + p->bitstream_sw_buf = NULL; + p->bitstream_sw_buf = mpp_malloc(RK_U8, (len_in + 1024)); + if (NULL == p->bitstream_sw_buf) { + mpp_err("m2vd_parser realloc fail"); + return MPP_ERR_NOMEM; + } + p->max_stream_size = len_in + 1024; + } + + pos += out_size; + + m2vd_parser_split_frame(buf, + len_in, + p->bitstream_sw_buf, + &out_size); + pos += out_size; + + mpp_packet_set_pos(pkt, pos); + + if (out_size == 0 && p->eos) { + m2vd_parser_flush(ctx); + task->flags.eos = 1; + return ret; + } + + if (M2VD_DBG_SEC_HEADER & m2vd_debug) { + mpp_log("p->bitstream_sw_buf = 0x%x", p->bitstream_sw_buf); + mpp_log("out_size = 0x%x", out_size); + } + + mpp_packet_set_data(input_packet, p->bitstream_sw_buf); + mpp_packet_set_size(input_packet, p->max_stream_size); + mpp_packet_set_length(input_packet, out_size); + + task->input_packet = input_packet; + +#if M2VD_DBG_FILE_W + if (p->fp_dbg_file[0]) { + RK_S32 size = (RK_S32)mpp_packet_get_size(pkt); + RK_U8 *data = (RK_U8 *)mpp_packet_get_data(pkt); + fwrite(&size, 4, 1, p->fp_dbg_file[0]); + fwrite(data, 1, size, p->fp_dbg_file[0]); + fflush(p->fp_dbg_file[0]); + } +#endif + + task->valid = 1; + FUN_T("FUN_O"); + return ret; +} + + +/*! +*********************************************************************** +* \brief +* parser +*********************************************************************** +*/ + +static RK_U32 m2vd_search_header(BitReadCtx_t *bx) +{ + mpp_align_get_bits(bx); + while (m2vd_show_bits(bx, 24) != 0x01) { + mpp_skip_bits(bx, 8); + if (m2vd_get_leftbits(bx) < 32) { + if (M2VD_DBG_SEC_HEADER & m2vd_debug) { + mpp_log("[m2v]: seach_header: str.leftbit()[%d] < 32", m2vd_get_leftbits(bx)); + } + return NO_MORE_STREAM; + } + } + return m2vd_show_bits(bx, 32); +} + + +int m2vd_decode_seq_ext_header(M2VDParserContext *ctx) +{ + BitReadCtx_t *bx = ctx->bitread_ctx; + FUN_T("FUN_I"); + ctx->MPEG2_Flag = 1; + ctx->seq_ext_head.profile_and_level_indication = m2vd_read_bits(bx, 8); + ctx->seq_ext_head.progressive_sequence = m2vd_read_bits(bx, 1); + ctx->seq_ext_head.chroma_format = m2vd_read_bits(bx, 2); + if (ctx->seq_ext_head.chroma_format != 1) + return M2VD_DEC_UNSURPORT; + ctx->seq_ext_head.horizontal_size_extension = m2vd_read_bits(bx, 2); + ctx->seq_ext_head.vertical_size_extension = m2vd_read_bits(bx, 2); + ctx->seq_ext_head.bit_rate_extension = m2vd_read_bits(bx, 12); + mpp_skip_bits(bx, 1); + ctx->seq_ext_head.vbv_buffer_size_extension = m2vd_read_bits(bx, 8); + ctx->seq_ext_head.low_delay = m2vd_read_bits(bx, 1); + ctx->seq_ext_head.frame_rate_extension_n = m2vd_read_bits(bx, 2); + ctx->seq_ext_head.frame_rate_extension_d = m2vd_read_bits(bx, 5); + + ctx->seq_head.bit_rate_value |= (ctx->seq_ext_head.bit_rate_extension << 18); + ctx->seq_head.vbv_buffer_size += (ctx->seq_ext_head.vbv_buffer_size_extension << 10); + + FUN_T("FUN_O"); + return M2VD_DEC_OK; +} + +int m2vd_decode_seqdisp_ext_header(M2VDParserContext *ctx) +{ + BitReadCtx_t *bx = ctx->bitread_ctx; + ctx->seq_disp_ext_head.video_format = m2vd_read_bits(bx, 3); + ctx->seq_disp_ext_head.color_description = m2vd_read_bits(bx, 1); + + if (ctx->seq_disp_ext_head.color_description) { + ctx->seq_disp_ext_head.color_primaries = m2vd_read_bits(bx, 8); + ctx->seq_disp_ext_head.transfer_characteristics = m2vd_read_bits(bx, 8); + ctx->seq_disp_ext_head.matrix_coefficients = m2vd_read_bits(bx, 8); + } + + m2vd_read_bits(bx, 14); + mpp_skip_bits(bx, 1); + m2vd_read_bits(bx, 14); + return M2VD_DEC_OK; +} + +int m2vd_decode_matrix_ext_header(M2VDParserContext *ctx) +{ + RK_U32 load_intra_quantizer_matrix; + RK_U32 load_non_intra_quantizer_matrix; + RK_U32 load_chroma_intra_quantizer_matrix; + RK_U32 load_chroma_non_intra_quantizer_matrix; + RK_U32 i; + BitReadCtx_t *bx = ctx->bitread_ctx; + + load_intra_quantizer_matrix = m2vd_read_bits(bx, 1); + if (load_intra_quantizer_matrix) { + for (i = 0; i < 64; i++) + ctx->seq_head.pIntra_table[scanOrder[0][i]] = (unsigned char)m2vd_read_bits(bx, 8); + + } + load_non_intra_quantizer_matrix = m2vd_read_bits(bx, 1); + if (load_non_intra_quantizer_matrix) { + for (i = 0; i < 64; i++) + ctx->seq_head.pInter_table[scanOrder[0][i]] = (unsigned char)m2vd_read_bits(bx, 8); + } + load_chroma_intra_quantizer_matrix = m2vd_read_bits(bx, 1); + if (load_chroma_intra_quantizer_matrix) { + return M2VD_DEC_UNSURPORT; + } + load_chroma_non_intra_quantizer_matrix = m2vd_read_bits(bx, 1); + if (load_chroma_non_intra_quantizer_matrix) { + return M2VD_DEC_UNSURPORT; + } + return M2VD_DEC_OK; +} + + +int m2vd_decode_scalable_ext_header(M2VDParserContext *ctx) +{ + /* ISO/IEC 13818-2 section 6.2.2.5: sequence_scalable_extension() header */ + int layer_id; + int lower_layer_prediction_horizontal_size; + int lower_layer_prediction_vertical_size; + int horizontal_subsampling_factor_m; + int horizontal_subsampling_factor_n; + int vertical_subsampling_factor_m; + int vertical_subsampling_factor_n; + int scalable_mode; + BitReadCtx_t *bx = ctx->bitread_ctx; + + /* scalable_mode */ +#define SC_NONE 0 +#define SC_DP 1 +#define SC_SPAT 2 +#define SC_SNR 3 +#define SC_TEMP 4 + + scalable_mode = m2vd_read_bits(bx, 2) + 1; /* add 1 to make SC_DP != SC_NONE */ + + layer_id = m2vd_read_bits(bx, 4); + + if (scalable_mode == SC_SPAT) { + lower_layer_prediction_horizontal_size = m2vd_read_bits(bx, 14); + mpp_skip_bits(bx, 1); + lower_layer_prediction_vertical_size = m2vd_read_bits(bx, 14); + horizontal_subsampling_factor_m = m2vd_read_bits(bx, 5); + horizontal_subsampling_factor_n = m2vd_read_bits(bx, 5); + vertical_subsampling_factor_m = m2vd_read_bits(bx, 5); + vertical_subsampling_factor_n = m2vd_read_bits(bx, 5); + } + + (void)layer_id; + (void)lower_layer_prediction_horizontal_size; + (void)lower_layer_prediction_vertical_size; + (void)horizontal_subsampling_factor_m; + (void)horizontal_subsampling_factor_n; + (void)vertical_subsampling_factor_m; + (void)vertical_subsampling_factor_n; + + + if (scalable_mode == SC_TEMP) + return M2VD_DEC_UNSURPORT; + else + return M2VD_DEC_OK; +} + + +int m2vd_decode_picdisp_ext_header(M2VDParserContext *ctx) +{ + int i; + int number_of_frame_center_offsets; + BitReadCtx_t *bx = ctx->bitread_ctx; + /* based on ISO/IEC 13818-2 section 6.3.12 + (November 1994) Picture display extensions */ + + /* derive number_of_frame_center_offsets */ + if (ctx->seq_ext_head.progressive_sequence) { + if (ctx->pic_code_ext_head.repeat_first_field) { + if (ctx->pic_code_ext_head.top_field_first) + number_of_frame_center_offsets = 3; + else + number_of_frame_center_offsets = 2; + } else { + number_of_frame_center_offsets = 1; + } + } else { + if (ctx->pic_code_ext_head.picture_structure != M2VD_PIC_STRUCT_FRAME) { + number_of_frame_center_offsets = 1; + } else { + if (ctx->pic_code_ext_head.repeat_first_field) + number_of_frame_center_offsets = 3; + else + number_of_frame_center_offsets = 2; + } + } + + /* now parse */ + for (i = 0; i < number_of_frame_center_offsets; i++) { + ctx->pic_disp_ext_head.frame_center_horizontal_offset[i] = m2vd_read_bits(bx, 16); + mpp_skip_bits(bx, 1); + + ctx->pic_disp_ext_head.frame_center_vertical_offset[i] = m2vd_read_bits(bx, 16); + mpp_skip_bits(bx, 1); + } + return M2VD_DEC_OK; +} + + +int m2vd_decode_spatial_ext_header(M2VDParserContext *ctx) +{ + /* ISO/IEC 13818-2 section 6.2.3.5: picture_spatial_scalable_extension() header */ + int lower_layer_temporal_reference; + int lower_layer_horizontal_offset; + int lower_layer_vertical_offset; + int spatial_temporal_weight_code_table_index; + int lower_layer_progressive_frame; + int lower_layer_deinterlaced_field_select; + BitReadCtx_t *bx = ctx->bitread_ctx; + + lower_layer_temporal_reference = m2vd_read_bits(bx, 10); + mpp_skip_bits(bx, 1); + lower_layer_horizontal_offset = m2vd_read_bits(bx, 15); + if (lower_layer_horizontal_offset >= 16384) + lower_layer_horizontal_offset -= 32768; + mpp_skip_bits(bx, 1); + lower_layer_vertical_offset = m2vd_read_bits(bx, 15); + if (lower_layer_vertical_offset >= 16384) + lower_layer_vertical_offset -= 32768; + spatial_temporal_weight_code_table_index = m2vd_read_bits(bx, 2); + lower_layer_progressive_frame = m2vd_read_bits(bx, 1); + lower_layer_deinterlaced_field_select = m2vd_read_bits(bx, 1); + + (void)lower_layer_temporal_reference; + (void)lower_layer_vertical_offset; + (void)spatial_temporal_weight_code_table_index; + (void)lower_layer_progressive_frame; + (void)lower_layer_deinterlaced_field_select; + + + return M2VD_DEC_OK; +} + + + +int m2vd_decode_pic_ext_header(M2VDParserContext *ctx) +{ + BitReadCtx_t *bx = ctx->bitread_ctx; + ctx->pic_code_ext_head.f_code[0][0] = m2vd_read_bits(bx, 4); + ctx->pic_code_ext_head.f_code[0][1] = m2vd_read_bits(bx, 4); + ctx->pic_code_ext_head.f_code[1][0] = m2vd_read_bits(bx, 4); + ctx->pic_code_ext_head.f_code[1][1] = m2vd_read_bits(bx, 4); + if (ctx->MPEG2_Flag) { + ctx->pic_head.full_pel_forward_vector = ctx->pic_code_ext_head.f_code[0][0]; + ctx->pic_head.forward_f_code = ctx->pic_code_ext_head.f_code[0][1]; + ctx->pic_head.full_pel_backward_vector = ctx->pic_code_ext_head.f_code[1][0]; + ctx->pic_head.backward_f_code = ctx->pic_code_ext_head.f_code[1][1]; + } + + ctx->pic_code_ext_head.intra_dc_precision = m2vd_read_bits(bx, 2); + ctx->pic_code_ext_head.picture_structure = m2vd_read_bits(bx, 2); + if (ctx->pic_code_ext_head.picture_structure == M2VD_PIC_STRUCT_FRAME) + ctx->pic_code_ext_head.top_field_first = m2vd_read_bits(bx, 1); + else { + m2vd_read_bits(bx, 1); + if ((ctx->pic_head.pre_picture_coding_type != ctx->pic_head.picture_coding_type) && + (ctx->pic_head.pre_picture_coding_type != M2VD_CODING_TYPE_I)) { + if (ctx->pic_code_ext_head.picture_structure == M2VD_PIC_STRUCT_TOP_FIELD) + ctx->top_first_cnt++; + else + ctx->bottom_first_cnt++; + } + if (ctx->top_first_cnt >= ctx->bottom_first_cnt) + ctx->pic_code_ext_head.top_field_first = 1; + else + ctx->pic_code_ext_head.top_field_first = 0; + } + ctx->pic_code_ext_head.frame_pred_frame_dct = m2vd_read_bits(bx, 1); + ctx->pic_code_ext_head.concealment_motion_vectors = m2vd_read_bits(bx, 1); + ctx->pic_code_ext_head.q_scale_type = m2vd_read_bits(bx, 1); + ctx->pic_code_ext_head.intra_vlc_format = m2vd_read_bits(bx, 1); + ctx->pic_code_ext_head.alternate_scan = m2vd_read_bits(bx, 1); + ctx->pic_code_ext_head.repeat_first_field = m2vd_read_bits(bx, 1); + ctx->pic_code_ext_head.chroma_420_type = m2vd_read_bits(bx, 1); + ctx->pic_code_ext_head.progressive_frame = m2vd_read_bits(bx, 1); + ctx->pic_code_ext_head.composite_display_flag = m2vd_read_bits(bx, 1); + if (ctx->pic_code_ext_head.composite_display_flag) { + ctx->pic_code_ext_head.v_axis = m2vd_read_bits(bx, 1); + ctx->pic_code_ext_head.field_sequence = m2vd_read_bits(bx, 3); + ctx->pic_code_ext_head.sub_carrier = m2vd_read_bits(bx, 1); + ctx->pic_code_ext_head.burst_amplitude = m2vd_read_bits(bx, 7); + ctx->pic_code_ext_head.sub_carrier_phase = m2vd_read_bits(bx, 8); + } + return M2VD_DEC_OK; +} + + +int m2vd_decode_temp_ext_header(void) +{ + return M2VD_DEC_UNSURPORT; +} + + +int m2vd_decode_copyright_ext_header(M2VDParserContext *ctx) +{ + int copyright_flag; + int copyright_identifier; + int original_or_copy; + int copyright_number_1; + int copyright_number_2; + int copyright_number_3; + int reserved_data; + BitReadCtx_t *bx = ctx->bitread_ctx; + + copyright_flag = m2vd_read_bits(bx, 1); + copyright_identifier = m2vd_read_bits(bx, 8); + original_or_copy = m2vd_read_bits(bx, 1); + + /* reserved */ + reserved_data = m2vd_read_bits(bx, 7); + + mpp_skip_bits(bx, 1); + copyright_number_1 = m2vd_read_bits(bx, 20); + mpp_skip_bits(bx, 1); + copyright_number_2 = m2vd_read_bits(bx, 22); + mpp_skip_bits(bx, 1); + copyright_number_3 = m2vd_read_bits(bx, 22); + + (void)copyright_flag; + (void)copyright_identifier; + (void)original_or_copy; + (void)copyright_number_1; + (void)copyright_number_2; + (void)copyright_number_3; + (void)reserved_data; + + return M2VD_DEC_OK; +} + + + +int m2vd_decode_ext_header(M2VDParserContext *ctx) +{ + RK_U32 code; + RK_U32 ext_ID; + int result; + BitReadCtx_t *bx = ctx->bitread_ctx; + + code = m2vd_search_header(bx); + + if (M2VD_DBG_SEC_HEADER & m2vd_debug) { + mpp_log("[m2v]: decoder_ext_header : seach_header return code: %#03x", code); + } + while (code == EXTENSION_START_CODE || code == USER_DATA_START_CODE) { + if (code == EXTENSION_START_CODE) { + mpp_skip_bits(bx, 32); + ext_ID = m2vd_read_bits(bx, 4); + if (M2VD_DBG_SEC_HEADER & m2vd_debug) { + mpp_log("[m2v]: decoder_ext_header : ext_ID: %d", ext_ID); + } + switch (ext_ID) { + case SEQUENCE_EXTENSION_ID: + result = m2vd_decode_seq_ext_header(ctx); + break; + case SEQUENCE_DISPLAY_EXTENSION_ID: + result = m2vd_decode_seqdisp_ext_header(ctx); + break; + case QUANT_MATRIX_EXTENSION_ID: + result = m2vd_decode_matrix_ext_header(ctx); + break; + case SEQUENCE_SCALABLE_EXTENSION_ID: + result = m2vd_decode_scalable_ext_header(ctx); + break; + case PICTURE_DISPLAY_EXTENSION_ID: + result = m2vd_decode_picdisp_ext_header(ctx); + break; + case PICTURE_CODING_EXTENSION_ID: + result = m2vd_decode_pic_ext_header(ctx); + break; + case PICTURE_SPATIAL_SCALABLE_EXTENSION_ID: + result = m2vd_decode_spatial_ext_header(ctx); + break; + case PICTURE_TEMPORAL_SCALABLE_EXTENSION_ID: + result = m2vd_decode_temp_ext_header(); + break; + case COPYRIGHT_EXTENSION_ID: + result = m2vd_decode_copyright_ext_header(ctx); + break; + case NO_MORE_STREAM: + break; + default: + break; + } + + if (M2VD_DBG_SEC_HEADER & m2vd_debug) { + mpp_log("[m2v]: decoder_ext_header result: %d", result); + } + if (result) + return result; + } else { + mpp_skip_bits(bx, 32); + } + code = m2vd_search_header(bx); + } + + return MPP_OK; +} + +static int m2vd_decode_gop_header(M2VDParserContext *ctx) +{ + BitReadCtx_t *bx = ctx->bitread_ctx; + + ctx->gop_head.drop_flag = m2vd_read_bits(bx, 1); + ctx->gop_head.hour = m2vd_read_bits(bx, 5); + ctx->gop_head.minute = m2vd_read_bits(bx, 6); + + mpp_skip_bits(bx, 1); + + ctx->gop_head.sec = m2vd_read_bits(bx, 6); + ctx->gop_head.frame = m2vd_read_bits(bx, 6); + ctx->gop_head.closed_gop = m2vd_read_bits(bx, 1); + ctx->gop_head.broken_link = m2vd_read_bits(bx, 1); + + return m2vd_decode_ext_header(ctx); +} + + +int m2vd_decode_seq_header(M2VDParserContext *ctx) +{ + RK_U32 i; + BitReadCtx_t *bx = ctx->bitread_ctx; + ctx->seq_head.decode_width = m2vd_read_bits(bx, 12); + ctx->seq_head.decode_height = m2vd_read_bits(bx, 12); + ctx->display_width = ctx->seq_head.decode_width; + ctx->display_height = ctx->seq_head.decode_height; + ctx->seq_head.aspect_ratio_information = m2vd_read_bits(bx, 4); + ctx->seq_head.frame_rate_code = m2vd_read_bits(bx, 4); + if (!ctx->frame_period) + ctx->frame_period = frame_period_Table[ctx->seq_head.frame_rate_code]; + ctx->seq_head.bit_rate_value = m2vd_read_bits(bx, 18); + mpp_skip_bits(bx, 1); + ctx->seq_head.vbv_buffer_size = m2vd_read_bits(bx, 10); + ctx->seq_head.constrained_parameters_flag = m2vd_read_bits(bx, 1); + ctx->seq_head.load_intra_quantizer_matrix = m2vd_read_bits(bx, 1); + if (ctx->seq_head.load_intra_quantizer_matrix) { + for (i = 0; i < 64; i++) + ctx->seq_head.pIntra_table[scanOrder[0][i]] = (unsigned char)m2vd_read_bits(bx, 8); + } else { + for (i = 0; i < 64; i++) + ctx->seq_head.pIntra_table[i] = intraDefaultQMatrix[i]; + } + + ctx->seq_head.load_non_intra_quantizer_matrix = m2vd_read_bits(bx, 1); + if (ctx->seq_head.load_non_intra_quantizer_matrix) { + for (i = 0; i < 64; i++) + ctx->seq_head.pInter_table[scanOrder[0][i]] = (unsigned char)m2vd_read_bits(bx, 8); + + } else { + for (i = 0; i < 64; i++) + ctx->seq_head.pInter_table[i] = 16; + + } + + + return m2vd_decode_ext_header(ctx); +} + + +int m2vd_extra_bit_information(M2VDParserContext *ctx) +{ + BitReadCtx_t *bx = ctx->bitread_ctx; + while (m2vd_read_bits(bx, 1)) { + mpp_skip_bits(bx, 8); + } + return M2VD_DEC_OK; +} + +int m2vd_decode_pic_header(M2VDParserContext *ctx) +{ + BitReadCtx_t *bx = ctx->bitread_ctx; + ctx->pic_head.temporal_reference = m2vd_read_bits(bx, 10); + ctx->pic_head.picture_coding_type = m2vd_read_bits(bx, 3); + ctx->pic_head.vbv_delay = m2vd_read_bits(bx, 16); + if (ctx->pic_head.temporal_reference > 50) { + ctx->pic_head.temporal_reference = ctx->pretemporal_reference; + } + //if ((maxFrame_inGOP < temporal_reference)&&(temporal_reference<60)) + // maxFrame_inGOP = temporal_reference; + if (((RK_S32)ctx->maxFrame_inGOP < ctx->pic_head.temporal_reference) && (ctx->pic_head.temporal_reference < 60)) + ctx->maxFrame_inGOP = ctx->pic_head.temporal_reference; + + + if (ctx->pic_head.picture_coding_type == M2VD_CODING_TYPE_P || + ctx->pic_head.picture_coding_type == M2VD_CODING_TYPE_B) { + ctx->pic_head.full_pel_forward_vector = m2vd_read_bits(bx, 1); + ctx->pic_head.forward_f_code = m2vd_read_bits(bx, 3); + } + if (ctx->pic_head.picture_coding_type == M2VD_CODING_TYPE_B) { + ctx->pic_head.full_pel_backward_vector = m2vd_read_bits(bx, 1); + ctx->pic_head.backward_f_code = m2vd_read_bits(bx, 3); + } + + m2vd_extra_bit_information(ctx); + + return m2vd_decode_ext_header(ctx); +} + + + +MPP_RET m2vd_decode_head(M2VDParserContext *ctx) +{ + RK_U32 code; + int ret = 0; + BitReadCtx_t *bx = ctx->bitread_ctx; + + FUN_T("FUN_I"); + while (1) { + code = m2vd_search_header(bx); + if (M2VD_DBG_SEC_HEADER & m2vd_debug) { + mpp_log("[m2v]: decoder_header : seach_header return code: 0x%3x", code); + } + if (code == NO_MORE_STREAM) + return M2VD_DEC_FILE_END; + code = m2vd_read_bits(bx, 32); + + switch (code) { + case SEQUENCE_HEADER_CODE: + ret = m2vd_decode_seq_header(ctx); + if (!ret) { + ctx->mHeaderDecFlag = 1; + } + break; + case GROUP_START_CODE: + ret = m2vd_decode_gop_header(ctx); + break; + case PICTURE_START_CODE: + ret = m2vd_decode_pic_header(ctx); + ret = M2VD_DEC_PICHEAD_OK; + break; + case SEQUENCE_END_CODE: + ret = M2VD_DEC_STREAM_END; + break; + default: + if (M2VD_DBG_SEC_HEADER & m2vd_debug) { + mpp_log("code=%x,leftbit=%d", code, m2vd_get_leftbits(bx)); + } + break; + } + if (ret) + break; + } + FUN_T("FUN_O"); + + return ret; +} + +MPP_RET m2vd_alloc_frame(M2VDParserContext *ctx) +{ + RK_U32 pts = (RK_U32)(ctx->pts / 1000); + if (ctx->resetFlag && ctx->pic_head.picture_coding_type != M2VD_CODING_TYPE_I) { + mpp_log("[m2v]: resetFlag[%d] && picture_coding_type[%d] != I_TYPE", ctx->resetFlag, ctx->pic_head.picture_coding_type); + return MPP_NOK; + } else { + ctx->resetFlag = 0; + } + if ((ctx->pic_code_ext_head.picture_structure == M2VD_PIC_STRUCT_FRAME ) || + ((ctx->pic_code_ext_head.picture_structure == M2VD_PIC_STRUCT_TOP_FIELD) && ctx->pic_code_ext_head.top_field_first) || + ((ctx->pic_code_ext_head.picture_structure == M2VD_PIC_STRUCT_BOTTOM_FIELD) && (!ctx->pic_code_ext_head.top_field_first)) || + (ctx->frame_cur->slot_index == 0xff)) { + RK_S32 Time; + if (ctx->PreGetFrameTime != pts) { + RK_U32 tmp_frame_period; + if (ctx->GroupFrameCnt) { + ctx->GroupFrameCnt = ctx->GroupFrameCnt + ctx->pic_head.temporal_reference; + } else if (ctx->pic_head.temporal_reference == (RK_S32)ctx->PreChangeTime_index) + ctx->GroupFrameCnt = ctx->max_temporal_reference + 1; + else if (ctx->pic_head.temporal_reference) + ctx->GroupFrameCnt = ctx->pic_head.temporal_reference - ctx->PreChangeTime_index; + else + ctx->GroupFrameCnt = ctx->max_temporal_reference - ctx->PreChangeTime_index + 1; + + tmp_frame_period = pts - ctx->PreGetFrameTime; + if ((pts > ctx->PreGetFrameTime) && (ctx->GroupFrameCnt > 0)) { + tmp_frame_period = (tmp_frame_period * 256) / ctx->GroupFrameCnt; + if ((tmp_frame_period > 4200) && (tmp_frame_period < 11200) && (abs(ctx->frame_period - tmp_frame_period) > 128)) { + if (abs(ctx->preframe_period - tmp_frame_period) > 128) + ctx->preframe_period = tmp_frame_period; + else + ctx->frame_period = tmp_frame_period; + } + } + ctx->Group_start_Time = pts - (ctx->pic_head.temporal_reference * ctx->frame_period / 256); + if (ctx->Group_start_Time < 0) + ctx->Group_start_Time = 0; + ctx->PreGetFrameTime = pts; + ctx->PreChangeTime_index = ctx->pic_head.temporal_reference; + ctx->GroupFrameCnt = 0; + } else if ((RK_S32)ctx->pretemporal_reference > ctx->pic_head.temporal_reference + 5) { + ctx->Group_start_Time += ((ctx->max_temporal_reference + 1) * ctx->frame_period / 256); + ctx->GroupFrameCnt = ctx->max_temporal_reference - ctx->PreChangeTime_index + 1; + ctx->max_temporal_reference = 0; + } + if ((RK_S32)ctx->pretemporal_reference > ctx->pic_head.temporal_reference + 5) + ctx->max_temporal_reference = 0; + if (ctx->pic_head.temporal_reference > (RK_S32)ctx->max_temporal_reference) + ctx->max_temporal_reference = ctx->pic_head.temporal_reference; + ctx->pretemporal_reference = ctx->pic_head.temporal_reference; + /*if(picture_coding_type == I_TYPE) + { + if (Video_Bitsream.Slice_Time.low_part >= (RK_U32)(frame_period/128)) + Group_start_Time = Video_Bitsream.Slice_Time.low_part - (RK_U32)(frame_period/128); + else + Group_start_Time = Video_Bitsream.Slice_Time.low_part; + }*/ + Time = ctx->Group_start_Time; + Time += ((ctx->pic_head.temporal_reference * ctx->frame_period) / 256); + if (Time < 0) { + Time = 0; + } + //base.Current_frame->ShowTime = Time;//Video_Bitsream.Slice_Time.low_part; + + if (ctx->pic_head.picture_coding_type != M2VD_CODING_TYPE_I && ctx->pic_head.pre_picture_coding_type == ctx->pic_head.picture_coding_type) { + if ((ctx->pic_head.temporal_reference - ctx->pic_head.pre_temporal_reference > 3) || (ctx->pic_head.temporal_reference - ctx->pic_head.pre_temporal_reference < -3)) { + if (ctx->frame_cur->error_info == 0) + ctx->frame_cur->error_info = 1; + } + } else { + ctx->frame_cur->error_info = 0; + } + ctx->pic_head.pre_temporal_reference = ctx->pic_head.temporal_reference; + ctx->pic_head.pre_picture_coding_type = ctx->pic_head.picture_coding_type; + + ctx->frame_cur->picCodingType = ctx->pic_head.picture_coding_type; + ctx->seq_head.decode_height = (ctx->seq_head.decode_height + 15) & (~15); + ctx->seq_head.decode_width = (ctx->seq_head.decode_width + 15) & (~15); + if (ctx->frame_cur->slot_index == 0xff) { + RK_U32 frametype = 0; + mpp_frame_set_width(ctx->frame_cur->f, ctx->display_width); + mpp_frame_set_height(ctx->frame_cur->f, ctx->display_height); + mpp_frame_set_hor_stride(ctx->frame_cur->f, ctx->display_width); + mpp_frame_set_ver_stride(ctx->frame_cur->f, ctx->display_height); + mpp_frame_set_errinfo(ctx->frame_cur->f, 0); + mpp_frame_set_pts(ctx->frame_cur->f, Time * 1000); + mpp_buf_slot_get_unused(ctx->frame_slots, &ctx->frame_cur->slot_index); + mpp_buf_slot_set_prop(ctx->frame_slots, ctx->frame_cur->slot_index, SLOT_FRAME, ctx->frame_cur->f); + mpp_buf_slot_set_flag(ctx->frame_slots, ctx->frame_cur->slot_index, SLOT_CODEC_USE); + mpp_buf_slot_set_flag(ctx->frame_slots, ctx->frame_cur->slot_index, SLOT_HAL_OUTPUT); + ctx->frame_cur->flags = M2V_OUT_FLAG; + if (ctx->seq_ext_head.progressive_sequence) { + frametype = MPP_FRAME_FLAG_FRAME; + } else { + frametype = MPP_FRAME_FLAG_PAIRED_FIELD; + if (ctx->pic_code_ext_head.top_field_first) + frametype |= MPP_FRAME_FLAG_TOP_FIRST; + else + frametype |= MPP_FRAME_FLAG_BOT_FIRST; + } + mpp_frame_set_mode(ctx->frame_cur->f, frametype); + } + } + //alloc frame space + if ((ctx->ref_frame_cnt < 2) && (ctx->frame_cur->picCodingType == M2VD_CODING_TYPE_B)) { + mpp_log("[m2v]: (ref_frame_cnt[%d] < 2) && (frame_cur->picCodingType[%d] == B_TYPE)", ctx->ref_frame_cnt, ctx->frame_cur->picCodingType); + return MPP_NOK; + } + + return MPP_OK; +} +MPP_RET m2v_update_ref_frame(M2VDParserContext *p) +{ + + MPP_RET ret = MPP_OK; + FUN_T("FUN_I"); + //push frame + if ((p->pic_code_ext_head.picture_structure == M2VD_PIC_STRUCT_FRAME) || + ((p->pic_code_ext_head.picture_structure == M2VD_PIC_STRUCT_BOTTOM_FIELD) && p->pic_code_ext_head.top_field_first ) || + ((p->pic_code_ext_head.picture_structure == M2VD_PIC_STRUCT_TOP_FIELD) && (!p->pic_code_ext_head.top_field_first))) { + + if (p->frame_cur->picCodingType == M2VD_CODING_TYPE_B) { + mpp_buf_slot_set_flag(p->frame_slots, p->frame_cur->slot_index, SLOT_QUEUE_USE); + mpp_buf_slot_enqueue(p->frame_slots, p->frame_cur->slot_index, QUEUE_DISPLAY); + mpp_buf_slot_clr_flag(p->frame_slots, p->frame_cur->slot_index, SLOT_CODEC_USE); + p->frame_cur->slot_index = 0xFF; + } else if (p->frame_cur->picCodingType != 0xffffffff) { + M2VDFrameHead *tmpHD = NULL; + p->ref_frame_cnt++; + if (p->frame_ref0->slot_index < 0x7f) { + mpp_buf_slot_set_flag(p->frame_slots, p->frame_ref0->slot_index, SLOT_QUEUE_USE); + mpp_buf_slot_enqueue(p->frame_slots, p->frame_ref0->slot_index, QUEUE_DISPLAY); + p->frame_ref0->flags = 0; + } + if (p->frame_ref1->slot_index < 0x7f) { + mpp_buf_slot_clr_flag(p->frame_slots, p->frame_ref1->slot_index, SLOT_CODEC_USE); + p->frame_ref1->slot_index = 0xff; + } + tmpHD = p->frame_ref1; + p->frame_ref1 = p->frame_ref0; + p->frame_ref0 = p->frame_cur; + p->frame_cur = tmpHD; + } + } + return ret; +} + +MPP_RET m2vd_convert_to_dxva(M2VDParserContext *p) +{ + MPP_RET ret = MPP_OK; + FUN_T("FUN_I"); + M2VDDxvaParam *dst = p->dxva_ctx; + M2VDFrameHead *pfw = p->frame_ref1; + M2VDFrameHead *pbw = p->frame_ref0; + BitReadCtx_t *bx = p->bitread_ctx; + RK_U32 i = 0; + RK_S32 readbits = m2vd_get_readbits(bx); + + dst->seq.decode_width = p->seq_head.decode_width; + dst->seq.decode_height = p->seq_head.decode_height; + dst->seq.aspect_ratio_information = p->seq_head.aspect_ratio_information; + dst->seq.frame_rate_code = p->seq_head.frame_rate_code; + dst->seq.bit_rate_value = p->seq_head.bit_rate_value; + dst->seq.vbv_buffer_size = p->seq_head.vbv_buffer_size; + dst->seq.constrained_parameters_flag = p->seq_head.constrained_parameters_flag; + dst->seq.load_intra_quantizer_matrix = p->seq_head.load_intra_quantizer_matrix; + dst->seq.load_non_intra_quantizer_matrix = p->seq_head.load_non_intra_quantizer_matrix; + + dst->seq_ext.profile_and_level_indication = p->seq_ext_head.profile_and_level_indication; + dst->seq_ext.progressive_sequence = p->seq_ext_head.progressive_sequence; + dst->seq_ext.chroma_format = p->seq_ext_head.chroma_format; + dst->seq_ext.low_delay = p->seq_ext_head.low_delay; + dst->seq_ext.frame_rate_extension_n = p->seq_ext_head.frame_rate_extension_n; + dst->seq_ext.frame_rate_extension_d = p->seq_ext_head.frame_rate_extension_d; + + + dst->gop.drop_flag = p->gop_head.drop_flag; + dst->gop.hour = p->gop_head.hour; + dst->gop.minute = p->gop_head.minute; + dst->gop.sec = p->gop_head.sec; + dst->gop.frame = p->gop_head.frame; + dst->gop.closed_gop = p->gop_head.closed_gop; + dst->gop.broken_link = p->gop_head.broken_link; + + + dst->pic.temporal_reference = p->pic_head.temporal_reference; + dst->pic.picture_coding_type = p->pic_head.picture_coding_type; + dst->pic.pre_picture_coding_type = p->pic_head.pre_picture_coding_type; + dst->pic.vbv_delay = p->pic_head.vbv_delay; + dst->pic.full_pel_forward_vector = p->pic_head.full_pel_forward_vector; + dst->pic.forward_f_code = p->pic_head.forward_f_code; + dst->pic.full_pel_backward_vector = p->pic_head.full_pel_backward_vector; + dst->pic.backward_f_code = p->pic_head.backward_f_code; + dst->pic.pre_temporal_reference = p->pic_head.pre_temporal_reference; + + dst->seq_disp_ext.video_format = p->seq_disp_ext_head.video_format; + dst->seq_disp_ext.color_description = p->seq_disp_ext_head.color_description; + dst->seq_disp_ext.color_primaries = p->seq_disp_ext_head.color_primaries; + dst->seq_disp_ext.transfer_characteristics = p->seq_disp_ext_head.transfer_characteristics; + dst->seq_disp_ext.matrix_coefficients = p->seq_disp_ext_head.matrix_coefficients; + + memcpy(dst->pic_code_ext.f_code, p->pic_code_ext_head.f_code, 2 * 2 * sizeof(RK_S32)); + dst->pic_code_ext.intra_dc_precision = p->pic_code_ext_head.intra_dc_precision; + dst->pic_code_ext.picture_structure = p->pic_code_ext_head.picture_structure; + dst->pic_code_ext.top_field_first = p->pic_code_ext_head.top_field_first; + dst->pic_code_ext.frame_pred_frame_dct = p->pic_code_ext_head.frame_pred_frame_dct; + dst->pic_code_ext.concealment_motion_vectors = p->pic_code_ext_head.concealment_motion_vectors; + dst->pic_code_ext.q_scale_type = p->pic_code_ext_head.q_scale_type; + dst->pic_code_ext.intra_vlc_format = p->pic_code_ext_head.intra_vlc_format; + dst->pic_code_ext.alternate_scan = p->pic_code_ext_head.alternate_scan; + dst->pic_code_ext.repeat_first_field = p->pic_code_ext_head.repeat_first_field; + dst->pic_code_ext.chroma_420_type = p->pic_code_ext_head.chroma_420_type; + dst->pic_code_ext.progressive_frame = p->pic_code_ext_head.progressive_frame; + dst->pic_code_ext.composite_display_flag = p->pic_code_ext_head.composite_display_flag; + dst->pic_code_ext.v_axis = p->pic_code_ext_head.v_axis; + dst->pic_code_ext.field_sequence = p->pic_code_ext_head.field_sequence; + dst->pic_code_ext.sub_carrier = p->pic_code_ext_head.sub_carrier; + dst->pic_code_ext.burst_amplitude = p->pic_code_ext_head.burst_amplitude; + dst->pic_code_ext.sub_carrier_phase = p->pic_code_ext_head.sub_carrier_phase; + + memcpy(dst->pic_disp_ext.frame_center_horizontal_offset, p->pic_disp_ext_head.frame_center_horizontal_offset, 3 * sizeof(RK_S32)); + memcpy(dst->pic_disp_ext.frame_center_vertical_offset, p->pic_disp_ext_head.frame_center_vertical_offset, 3 * sizeof(RK_S32)); + + dst->bitstream_length = p->frame_size - ((readbits >> 3) & (~7)); + dst->bitstream_offset = ((readbits >> 3) & (~7)); + dst->bitstream_start_bit = readbits & 0x3f; + dst->qp_tab = p->qp_tab_sw_buf; + dst->CurrPic.Index7Bits = p->frame_cur->slot_index; + + if (p->frame_ref0->slot_index == 0xff) { + pbw = p->frame_cur; + } + if (p->frame_ref1->slot_index == 0xff) { + pfw = pbw; + } + + for (i = 0; i < 4; i++) { + dst->frame_refs[i].bPicEntry = 0xff; + } + if (p->pic_head.picture_coding_type == M2VD_CODING_TYPE_B) { + dst->frame_refs[0].Index7Bits = pfw->slot_index; + dst->frame_refs[1].Index7Bits = pfw->slot_index; + dst->frame_refs[2].Index7Bits = pbw->slot_index; + dst->frame_refs[3].Index7Bits = pbw->slot_index; + //p->frame_cur->->ErrorInfo = pfw->frame_space->ErrorInfo | pbw->frame_space->ErrorInfo; + } else { + if ((p->pic_code_ext_head.picture_structure == M2VD_PIC_STRUCT_FRAME) || + ((p->pic_code_ext_head.picture_structure == M2VD_PIC_STRUCT_TOP_FIELD) && p->pic_code_ext_head.top_field_first) || + ((p->pic_code_ext_head.picture_structure == M2VD_PIC_STRUCT_BOTTOM_FIELD) && (!p->pic_code_ext_head.top_field_first))) { + dst->frame_refs[0].Index7Bits = pbw->slot_index; + dst->frame_refs[1].Index7Bits = pbw->slot_index; + } else if (p->pic_code_ext_head.picture_structure == M2VD_PIC_STRUCT_TOP_FIELD) { + dst->frame_refs[0].Index7Bits = pbw->slot_index; + dst->frame_refs[1].Index7Bits = p->frame_cur->slot_index; + } else if (p->pic_code_ext_head.picture_structure == M2VD_PIC_STRUCT_BOTTOM_FIELD) { + dst->frame_refs[0].Index7Bits = p->frame_cur->slot_index; + dst->frame_refs[1].Index7Bits = pbw->slot_index; + } + dst->frame_refs[2].Index7Bits = p->frame_cur->slot_index; + dst->frame_refs[3].Index7Bits = p->frame_cur->slot_index; +// p->frame_cur->frame_space->ErrorInfo = pbw->frame_space->ErrorInfo; + } + dst->seq_ext_head_dec_flag = p->MPEG2_Flag; + FUN_T("FUN_O"); + return ret; +} + + +MPP_RET m2vd_parser_parse(void *ctx, HalDecTask *in_task) +{ + MPP_RET ret = MPP_OK; + int rev = 0; + M2VDContext *c = (M2VDContext *)ctx; + M2VDParserContext *p = (M2VDParserContext *)c->parse_ctx; + FUN_T("FUN_I"); + + CHK_I(in_task->valid); + + in_task->valid = 0; + + p->flush_dpb_eos = 0; + + p->frame_size = (RK_U32)mpp_packet_get_length(in_task->input_packet); + + mpp_set_bitread_ctx(p->bitread_ctx, p->bitstream_sw_buf, p->frame_size); + + rev = m2vd_decode_head(p); + + if (!p->mHeaderDecFlag) { + mpp_log("[m2v]: !mHeaderDecFlag"); + goto __FAILED; + } + + p->mb_width = (p->seq_head.decode_width + 15) >> 4; + p->mb_height = (p->seq_head.decode_height + 15) >> 4; + + if (rev < M2VD_DEC_OK) { + if (M2VD_DBG_SEC_HEADER & m2vd_debug) { + mpp_log("decoder_header error rev %d", rev); + } + goto __FAILED; + } + + if (rev == M2VD_DEC_PICHEAD_OK) { + if (MPP_OK != m2vd_alloc_frame(p)) { + mpp_err("m2vd_alloc_frame not OK"); + goto __FAILED; + } + m2vd_convert_to_dxva(p); + in_task->syntax.data = (void *)p->dxva_ctx; + in_task->syntax.number = sizeof(M2VDDxvaParam); + in_task->output = p->frame_cur->slot_index; + p->pic_head.pre_picture_coding_type = p->pic_head.picture_coding_type; + + if (p->frame_ref0->slot_index < 0x7f && + (p->frame_ref0->slot_index != p->frame_cur->slot_index)) { + mpp_buf_slot_set_flag(p->frame_slots, p->frame_ref0->slot_index, SLOT_HAL_INPUT); + in_task->refer[0] = p->frame_ref0->slot_index; + } + + if (p->frame_ref1->slot_index < 0x7f && (p->frame_ref1->slot_index != p->frame_cur->slot_index)) { + mpp_buf_slot_set_flag(p->frame_slots, p->frame_ref1->slot_index, SLOT_HAL_INPUT); + in_task->refer[1] = p->frame_ref1->slot_index; + } + in_task->valid = 1; + m2v_update_ref_frame(p); + } + +__FAILED: + if (p->eos) { + m2vd_parser_flush(ctx); + } + + FUN_T("FUN_O"); + + return ret; +} + +MPP_RET m2vd_parser_callback(void *ctx, void *errinfo) +{ + MPP_RET ret = MPP_OK; + FUN_T("FUN_I"); + (void)ctx; + (void)errinfo; + FUN_T("FUN_O"); + return ret; +} diff --git a/mpp/codec/dec/m2v/m2vd_parser.h b/mpp/codec/dec/m2v/m2vd_parser.h index 034125a8..438cabd7 100644 --- a/mpp/codec/dec/m2v/m2vd_parser.h +++ b/mpp/codec/dec/m2v/m2vd_parser.h @@ -1,306 +1,306 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file m2vd_parser.h - * @brief - * @author lks(lks@rock-chips.com) - - * @version 1.0.0 - * @history - * 2015.7.15 : Create - */ - -#ifndef __M2VD_PARSER_H__ -#define __M2VD_PARSER_H__ - -#include "mpp_common.h" -#include "mpp_mem.h" -#include "mpp_bitread.h" - -#include "mpp_frame.h" -#include "mpp_packet.h" - -#include "mpp_dec.h" -#include "m2vd_syntax.h" -#include "m2vd_com.h" - -#define M2VD_SKIP_ERROR_FRAME_EN 1 -#define M2VD_DEC_OK 0 -#define M2VD_IFNO_CHG 0x10 -#define M2VD_DEC_UNSURPORT -1 -#define M2VD_DEC_MEMORY_FAIL -2 -#define M2VD_DEC_FILE_END -3 -#define M2VD_HW_DEC_UNKNOW_ERROR -4 -#define M2VD_DEC_PICHEAD_OK 1 -#define M2VD_DEC_STREAM_END 2 - -#define TEMP_DBG_FM 0 - - -#define PICTURE_START_CODE 0x100 -#define SLICE_START_CODE_MIN 0x101 -#define SLICE_START_CODE_MAX 0x1AF -#define USER_DATA_START_CODE 0x1B2 -#define SEQUENCE_HEADER_CODE 0x1B3 -#define SEQUENCE_ERROR_CODE 0x1B4 -#define EXTENSION_START_CODE 0x1B5 -#define SEQUENCE_END_CODE 0x1B7 -#define GROUP_START_CODE 0x1B8 -#define SYSTEM_START_CODE_MIN 0x1B9 -#define SYSTEM_START_CODE_MAX 0x1FF - -#define ISO_END_CODE 0x1B9 -#define PACK_START_CODE 0x1BA -#define SYSTEM_START_CODE 0x1BB - -#define VIDEO_ELEMENTARY_STREAM 0x1e0 -#define NO_MORE_STREAM 0xffffffff - -#define SEQUENCE_EXTENSION_ID 1 -#define SEQUENCE_DISPLAY_EXTENSION_ID 2 -#define QUANT_MATRIX_EXTENSION_ID 3 -#define COPYRIGHT_EXTENSION_ID 4 -#define SEQUENCE_SCALABLE_EXTENSION_ID 5 -#define PICTURE_DISPLAY_EXTENSION_ID 7 -#define PICTURE_CODING_EXTENSION_ID 8 -#define PICTURE_SPATIAL_SCALABLE_EXTENSION_ID 9 -#define PICTURE_TEMPORAL_SCALABLE_EXTENSION_ID 10 - - -typedef enum M2VDPicCodingType_t { - M2VD_CODING_TYPE_I = 1, - M2VD_CODING_TYPE_P = 2, - M2VD_CODING_TYPE_B = 3, - M2VD_CODING_TYPE_D = 4 -} M2VDPicCodingType; - -typedef enum M2VDPicStruct_t { - M2VD_PIC_STRUCT_TOP_FIELD = 1, - M2VD_PIC_STRUCT_BOTTOM_FIELD = 2, - M2VD_PIC_STRUCT_FRAME = 3 -} M2VDPicStruct; - -#define M2VD_DBG_FILE_NUM 1 -#define M2VD_DBG_FILE_W 1 -#define M2VD_BUF_SIZE_BITMEM (512 * 1024) -#define M2VD_BUF_SIZE_QPTAB (256) -#define M2V_OUT_FLAG 0x1; - -typedef enum M2VDBufGrpIdx_t { - M2VD_BUF_GRP_BITMEM, - M2VD_BUF_GRP_QPTAB, - M2VD_BUF_GRP_BUTT, -} M2VDBufGrpIdx; - -typedef struct M2VFrameHead_t { - RK_U32 frameNumber; - RK_U32 tr; - RK_U32 picCodingType; - RK_U32 totalMbInFrame; - RK_U32 frameWidth; /* in macro blocks */ - RK_U32 frameHeight; /* in macro blocks */ - RK_U32 mb_width; - RK_U32 mb_height; - RK_U32 vlcSet; - RK_U32 qp; - RK_U32 frame_codelen; - // VPU_FRAME *frame_space; - MppFrame f; - RK_U32 flags; - RK_S32 slot_index; - RK_U32 error_info; -} M2VDFrameHead; - - -/* ISO/IEC 13818-2 section 6.2.2.1: sequence_header() */ -typedef struct M2VDHeadSeq_t { - RK_U32 decode_width; //horizontal_size_value - RK_U32 decode_height; //vertical_size_value - RK_S32 aspect_ratio_information; - RK_S32 frame_rate_code; - RK_S32 bit_rate_value; - RK_S32 vbv_buffer_size; - RK_S32 constrained_parameters_flag; - RK_U32 load_intra_quantizer_matrix; //[TEMP] - RK_U32 load_non_intra_quantizer_matrix; //[TEMP] - RK_U8 *pIntra_table; //intra_quantiser_matrix[64] - RK_U8 *pInter_table; //non_intra_quantiser_matrix[64] -} M2VDHeadSeq; - -/* ISO/IEC 13818-2 section 6.2.2.3: sequence_extension() */ -typedef struct M2VDHeadSeqExt_t { - RK_U32 horizontal_size_extension; //[TEMP] - RK_U32 vertical_size_extension; //[TEMP] - RK_U32 bit_rate_extension; //[TEMP] - RK_U32 vbv_buffer_size_extension; //[TEMP] - RK_S32 profile_and_level_indication; - RK_S32 progressive_sequence; - RK_S32 chroma_format; - RK_S32 low_delay; - RK_S32 frame_rate_extension_n; - RK_S32 frame_rate_extension_d; -} M2VDHeadSeqExt; - -/* ISO/IEC 13818-2 section 6.2.2.6: group_of_pictures_header() */ -typedef struct M2VDHeadGop_t { - RK_S32 drop_flag; - RK_S32 hour; - RK_S32 minute; - RK_S32 sec; - RK_S32 frame; - RK_S32 closed_gop; - RK_S32 broken_link; -} M2VDHeadGop; - - -/* ISO/IEC 13818-2 section 6.2.3: picture_header() */ -typedef struct M2VDHeadPic_t { - RK_S32 temporal_reference; - RK_S32 picture_coding_type; - RK_S32 pre_picture_coding_type; - RK_S32 vbv_delay; - RK_S32 full_pel_forward_vector; - RK_S32 forward_f_code; - RK_S32 full_pel_backward_vector; - RK_S32 backward_f_code; - RK_S32 pre_temporal_reference; -} M2VDHeadPic; - - -/* ISO/IEC 13818-2 section 6.2.2.4: sequence_display_extension() */ -typedef struct M2VDHeadSeqDispExt_t { - RK_S32 video_format; - RK_S32 color_description; - RK_S32 color_primaries; - RK_S32 transfer_characteristics; - RK_S32 matrix_coefficients; -} M2VDHeadSeqDispExt; - -/* ISO/IEC 13818-2 section 6.2.3.1: picture_coding_extension() header */ -typedef struct M2VDHeadPicCodeExt_t { - RK_S32 f_code[2][2]; - RK_S32 intra_dc_precision; - RK_S32 picture_structure; - RK_S32 top_field_first; - RK_S32 frame_pred_frame_dct; - RK_S32 concealment_motion_vectors; - RK_S32 q_scale_type; - RK_S32 intra_vlc_format; - RK_S32 alternate_scan; - RK_S32 repeat_first_field; - RK_S32 chroma_420_type; - RK_S32 progressive_frame; - RK_S32 composite_display_flag; - RK_S32 v_axis; - RK_S32 field_sequence; - RK_S32 sub_carrier; - RK_S32 burst_amplitude; - RK_S32 sub_carrier_phase; -} M2VDHeadPicCodeExt; - - -/* ISO/IEC 13818-2 section 6.2.3.3: picture_display_extension() header */ -typedef struct M2VDHeadPicDispExt_t { - RK_S32 frame_center_horizontal_offset[3]; - RK_S32 frame_center_vertical_offset[3]; -} M2VDHeadPicDispExt; - -typedef struct M2VDCombMem_t { - MppBuffer hw_buf; - RK_U8* sw_buf; - RK_U8 buf_size; - RK_U8* sw_pos; - RK_U32 length; -} M2VDCombMem; - -typedef struct M2VDParserContext_t { - M2VDDxvaParam *dxva_ctx; - BitReadCtx_t *bitread_ctx; - RK_U8 *bitstream_sw_buf; - RK_U8 *qp_tab_sw_buf; - RK_U32 max_stream_size; - - RK_U32 frame_size; - - RK_U32 display_width; - RK_U32 display_height; - RK_U32 frame_width; - RK_U32 frame_height; - RK_U32 mb_width; - RK_U32 mb_height; - RK_U32 MPEG2_Flag; - - M2VDHeadSeq seq_head; - M2VDHeadSeqExt seq_ext_head; - M2VDHeadGop gop_head; - M2VDHeadPic pic_head; - M2VDHeadSeqDispExt seq_disp_ext_head; - M2VDHeadPicCodeExt pic_code_ext_head; - M2VDHeadPicDispExt pic_disp_ext_head; - - RK_S32 resetFlag; - - RK_U32 PreGetFrameTime; - RK_S32 Group_start_Time; - RK_U32 GroupFrameCnt; - RK_U32 pretemporal_reference; - RK_U32 pretime_temporal; - RK_U32 max_temporal_reference; - RK_U32 PreChangeTime_index; - RK_U32 frame_period; - RK_U32 preframe_period; - RK_U32 maxFrame_inGOP; - RK_U32 ref_frame_cnt; - long long top_first_cnt; - long long bottom_first_cnt; - RK_S32 mHeaderDecFlag; - M2VDFrameHead Framehead[3]; - M2VDFrameHead *frame_ref0; - M2VDFrameHead *frame_ref1; - M2VDFrameHead *frame_cur; -#if M2VD_SKIP_ERROR_FRAME_EN - RK_S32 mHwDecStatus; -#endif - RK_S32 flush_dpb_eos; - - MppPacket input_packet; - RK_U32 eos; - - RK_S32 initFlag; - RK_S32 decoder_err; - - MppBufSlots packet_slots; - MppBufSlots frame_slots; - IOInterruptCB notify_cb; - - RK_U64 pts; - - FILE *fp_dbg_file[M2VD_DBG_FILE_NUM]; - FILE *fp_dbg_yuv; -} M2VDParserContext; - -MPP_RET m2vd_parser_init (void *ctx, ParserCfg *cfg); -MPP_RET m2vd_parser_deinit (void *ctx); -MPP_RET m2vd_parser_reset (void *ctx); -MPP_RET m2vd_parser_flush (void *ctx); -MPP_RET m2vd_parser_control(void *ctx, RK_S32 cmd_type, void *param); -MPP_RET m2vd_parser_prepare(void *ctx, MppPacket pkt, HalDecTask *task); -MPP_RET m2vd_parser_parse (void *ctx, HalDecTask *task); -MPP_RET m2vd_parser_callback(void *ctx, void *err_info); - -#endif - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file m2vd_parser.h + * @brief + * @author lks(lks@rock-chips.com) + + * @version 1.0.0 + * @history + * 2015.7.15 : Create + */ + +#ifndef __M2VD_PARSER_H__ +#define __M2VD_PARSER_H__ + +#include "mpp_common.h" +#include "mpp_mem.h" +#include "mpp_bitread.h" + +#include "mpp_frame.h" +#include "mpp_packet.h" + +#include "mpp_dec.h" +#include "m2vd_syntax.h" +#include "m2vd_com.h" + +#define M2VD_SKIP_ERROR_FRAME_EN 1 +#define M2VD_DEC_OK 0 +#define M2VD_IFNO_CHG 0x10 +#define M2VD_DEC_UNSURPORT -1 +#define M2VD_DEC_MEMORY_FAIL -2 +#define M2VD_DEC_FILE_END -3 +#define M2VD_HW_DEC_UNKNOW_ERROR -4 +#define M2VD_DEC_PICHEAD_OK 1 +#define M2VD_DEC_STREAM_END 2 + +#define TEMP_DBG_FM 0 + + +#define PICTURE_START_CODE 0x100 +#define SLICE_START_CODE_MIN 0x101 +#define SLICE_START_CODE_MAX 0x1AF +#define USER_DATA_START_CODE 0x1B2 +#define SEQUENCE_HEADER_CODE 0x1B3 +#define SEQUENCE_ERROR_CODE 0x1B4 +#define EXTENSION_START_CODE 0x1B5 +#define SEQUENCE_END_CODE 0x1B7 +#define GROUP_START_CODE 0x1B8 +#define SYSTEM_START_CODE_MIN 0x1B9 +#define SYSTEM_START_CODE_MAX 0x1FF + +#define ISO_END_CODE 0x1B9 +#define PACK_START_CODE 0x1BA +#define SYSTEM_START_CODE 0x1BB + +#define VIDEO_ELEMENTARY_STREAM 0x1e0 +#define NO_MORE_STREAM 0xffffffff + +#define SEQUENCE_EXTENSION_ID 1 +#define SEQUENCE_DISPLAY_EXTENSION_ID 2 +#define QUANT_MATRIX_EXTENSION_ID 3 +#define COPYRIGHT_EXTENSION_ID 4 +#define SEQUENCE_SCALABLE_EXTENSION_ID 5 +#define PICTURE_DISPLAY_EXTENSION_ID 7 +#define PICTURE_CODING_EXTENSION_ID 8 +#define PICTURE_SPATIAL_SCALABLE_EXTENSION_ID 9 +#define PICTURE_TEMPORAL_SCALABLE_EXTENSION_ID 10 + + +typedef enum M2VDPicCodingType_t { + M2VD_CODING_TYPE_I = 1, + M2VD_CODING_TYPE_P = 2, + M2VD_CODING_TYPE_B = 3, + M2VD_CODING_TYPE_D = 4 +} M2VDPicCodingType; + +typedef enum M2VDPicStruct_t { + M2VD_PIC_STRUCT_TOP_FIELD = 1, + M2VD_PIC_STRUCT_BOTTOM_FIELD = 2, + M2VD_PIC_STRUCT_FRAME = 3 +} M2VDPicStruct; + +#define M2VD_DBG_FILE_NUM 1 +#define M2VD_DBG_FILE_W 1 +#define M2VD_BUF_SIZE_BITMEM (512 * 1024) +#define M2VD_BUF_SIZE_QPTAB (256) +#define M2V_OUT_FLAG 0x1; + +typedef enum M2VDBufGrpIdx_t { + M2VD_BUF_GRP_BITMEM, + M2VD_BUF_GRP_QPTAB, + M2VD_BUF_GRP_BUTT, +} M2VDBufGrpIdx; + +typedef struct M2VFrameHead_t { + RK_U32 frameNumber; + RK_U32 tr; + RK_U32 picCodingType; + RK_U32 totalMbInFrame; + RK_U32 frameWidth; /* in macro blocks */ + RK_U32 frameHeight; /* in macro blocks */ + RK_U32 mb_width; + RK_U32 mb_height; + RK_U32 vlcSet; + RK_U32 qp; + RK_U32 frame_codelen; + // VPU_FRAME *frame_space; + MppFrame f; + RK_U32 flags; + RK_S32 slot_index; + RK_U32 error_info; +} M2VDFrameHead; + + +/* ISO/IEC 13818-2 section 6.2.2.1: sequence_header() */ +typedef struct M2VDHeadSeq_t { + RK_U32 decode_width; //horizontal_size_value + RK_U32 decode_height; //vertical_size_value + RK_S32 aspect_ratio_information; + RK_S32 frame_rate_code; + RK_S32 bit_rate_value; + RK_S32 vbv_buffer_size; + RK_S32 constrained_parameters_flag; + RK_U32 load_intra_quantizer_matrix; //[TEMP] + RK_U32 load_non_intra_quantizer_matrix; //[TEMP] + RK_U8 *pIntra_table; //intra_quantiser_matrix[64] + RK_U8 *pInter_table; //non_intra_quantiser_matrix[64] +} M2VDHeadSeq; + +/* ISO/IEC 13818-2 section 6.2.2.3: sequence_extension() */ +typedef struct M2VDHeadSeqExt_t { + RK_U32 horizontal_size_extension; //[TEMP] + RK_U32 vertical_size_extension; //[TEMP] + RK_U32 bit_rate_extension; //[TEMP] + RK_U32 vbv_buffer_size_extension; //[TEMP] + RK_S32 profile_and_level_indication; + RK_S32 progressive_sequence; + RK_S32 chroma_format; + RK_S32 low_delay; + RK_S32 frame_rate_extension_n; + RK_S32 frame_rate_extension_d; +} M2VDHeadSeqExt; + +/* ISO/IEC 13818-2 section 6.2.2.6: group_of_pictures_header() */ +typedef struct M2VDHeadGop_t { + RK_S32 drop_flag; + RK_S32 hour; + RK_S32 minute; + RK_S32 sec; + RK_S32 frame; + RK_S32 closed_gop; + RK_S32 broken_link; +} M2VDHeadGop; + + +/* ISO/IEC 13818-2 section 6.2.3: picture_header() */ +typedef struct M2VDHeadPic_t { + RK_S32 temporal_reference; + RK_S32 picture_coding_type; + RK_S32 pre_picture_coding_type; + RK_S32 vbv_delay; + RK_S32 full_pel_forward_vector; + RK_S32 forward_f_code; + RK_S32 full_pel_backward_vector; + RK_S32 backward_f_code; + RK_S32 pre_temporal_reference; +} M2VDHeadPic; + + +/* ISO/IEC 13818-2 section 6.2.2.4: sequence_display_extension() */ +typedef struct M2VDHeadSeqDispExt_t { + RK_S32 video_format; + RK_S32 color_description; + RK_S32 color_primaries; + RK_S32 transfer_characteristics; + RK_S32 matrix_coefficients; +} M2VDHeadSeqDispExt; + +/* ISO/IEC 13818-2 section 6.2.3.1: picture_coding_extension() header */ +typedef struct M2VDHeadPicCodeExt_t { + RK_S32 f_code[2][2]; + RK_S32 intra_dc_precision; + RK_S32 picture_structure; + RK_S32 top_field_first; + RK_S32 frame_pred_frame_dct; + RK_S32 concealment_motion_vectors; + RK_S32 q_scale_type; + RK_S32 intra_vlc_format; + RK_S32 alternate_scan; + RK_S32 repeat_first_field; + RK_S32 chroma_420_type; + RK_S32 progressive_frame; + RK_S32 composite_display_flag; + RK_S32 v_axis; + RK_S32 field_sequence; + RK_S32 sub_carrier; + RK_S32 burst_amplitude; + RK_S32 sub_carrier_phase; +} M2VDHeadPicCodeExt; + + +/* ISO/IEC 13818-2 section 6.2.3.3: picture_display_extension() header */ +typedef struct M2VDHeadPicDispExt_t { + RK_S32 frame_center_horizontal_offset[3]; + RK_S32 frame_center_vertical_offset[3]; +} M2VDHeadPicDispExt; + +typedef struct M2VDCombMem_t { + MppBuffer hw_buf; + RK_U8* sw_buf; + RK_U8 buf_size; + RK_U8* sw_pos; + RK_U32 length; +} M2VDCombMem; + +typedef struct M2VDParserContext_t { + M2VDDxvaParam *dxva_ctx; + BitReadCtx_t *bitread_ctx; + RK_U8 *bitstream_sw_buf; + RK_U8 *qp_tab_sw_buf; + RK_U32 max_stream_size; + + RK_U32 frame_size; + + RK_U32 display_width; + RK_U32 display_height; + RK_U32 frame_width; + RK_U32 frame_height; + RK_U32 mb_width; + RK_U32 mb_height; + RK_U32 MPEG2_Flag; + + M2VDHeadSeq seq_head; + M2VDHeadSeqExt seq_ext_head; + M2VDHeadGop gop_head; + M2VDHeadPic pic_head; + M2VDHeadSeqDispExt seq_disp_ext_head; + M2VDHeadPicCodeExt pic_code_ext_head; + M2VDHeadPicDispExt pic_disp_ext_head; + + RK_S32 resetFlag; + + RK_U32 PreGetFrameTime; + RK_S32 Group_start_Time; + RK_U32 GroupFrameCnt; + RK_U32 pretemporal_reference; + RK_U32 pretime_temporal; + RK_U32 max_temporal_reference; + RK_U32 PreChangeTime_index; + RK_U32 frame_period; + RK_U32 preframe_period; + RK_U32 maxFrame_inGOP; + RK_U32 ref_frame_cnt; + long long top_first_cnt; + long long bottom_first_cnt; + RK_S32 mHeaderDecFlag; + M2VDFrameHead Framehead[3]; + M2VDFrameHead *frame_ref0; + M2VDFrameHead *frame_ref1; + M2VDFrameHead *frame_cur; +#if M2VD_SKIP_ERROR_FRAME_EN + RK_S32 mHwDecStatus; +#endif + RK_S32 flush_dpb_eos; + + MppPacket input_packet; + RK_U32 eos; + + RK_S32 initFlag; + RK_S32 decoder_err; + + MppBufSlots packet_slots; + MppBufSlots frame_slots; + IOInterruptCB notify_cb; + + RK_U64 pts; + + FILE *fp_dbg_file[M2VD_DBG_FILE_NUM]; + FILE *fp_dbg_yuv; +} M2VDParserContext; + +MPP_RET m2vd_parser_init (void *ctx, ParserCfg *cfg); +MPP_RET m2vd_parser_deinit (void *ctx); +MPP_RET m2vd_parser_reset (void *ctx); +MPP_RET m2vd_parser_flush (void *ctx); +MPP_RET m2vd_parser_control(void *ctx, RK_S32 cmd_type, void *param); +MPP_RET m2vd_parser_prepare(void *ctx, MppPacket pkt, HalDecTask *task); +MPP_RET m2vd_parser_parse (void *ctx, HalDecTask *task); +MPP_RET m2vd_parser_callback(void *ctx, void *err_info); + +#endif + diff --git a/mpp/codec/dec/mpg4/mpg4d_api.c b/mpp/codec/dec/mpg4/mpg4d_api.c index bdba6803..59f5c122 100644 --- a/mpp/codec/dec/mpg4/mpg4d_api.c +++ b/mpp/codec/dec/mpg4/mpg4d_api.c @@ -1,337 +1,337 @@ -/* -* -* Copyright 2015 Rockchip Electronics Co. LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#define MODULE_TAG "mpg4d_api" - -#include - -#include "rk_mpi.h" - -#include "mpp_log.h" -#include "mpp_mem.h" -#include "mpp_common.h" - -#include "mpg4d_api.h" -#include "mpg4d_parser.h" - -#define MPG4D_INIT_STREAM_SIZE SZ_64K - -typedef struct { - // parameter interact with mpp_dec - MppBufSlots frame_slots; - MppBufSlots packet_slots; - RK_S32 task_count; - RK_U8 *stream; - size_t stream_size; - MppPacket task_pkt; - RK_S64 task_pts; - RK_U32 task_eos; - - // runtime parameter - RK_U32 need_split; - RK_U32 frame_count; - RK_U32 internal_pts; - IOInterruptCB notify_cb; - - // parser context - Mpg4dParser parser; -} Mpg4dCtx; - -MPP_RET mpg4d_init(void *dec, ParserCfg *cfg) -{ - Mpg4dParser parser = NULL; - MppPacket task_pkt = NULL; - Mpg4dCtx *p; - MPP_RET ret; - RK_U8 *stream; - size_t stream_size = MPG4D_INIT_STREAM_SIZE; - - if (NULL == dec) { - mpp_err_f("found NULL intput dec %p cfg %p\n", dec, cfg); - return MPP_ERR_NULL_PTR; - } - - stream = mpp_malloc_size(RK_U8, stream_size); - if (NULL == stream) { - mpp_err_f("failed to malloc stream buffer size %d\n", stream_size); - return MPP_ERR_MALLOC; - } - - ret = mpp_packet_init(&task_pkt, stream, stream_size); - if (ret) { - mpp_err_f("failed to create mpp_packet for task\n"); - goto ERR_RET; - } - - // reset task packet length to zero - // NOTE: set length must after set pos - mpp_packet_set_pos(task_pkt, stream); - mpp_packet_set_length(task_pkt, 0); - - ret = mpp_mpg4_parser_init(&parser, cfg->frame_slots); - if (ret) { - mpp_err_f("failed to init parser\n"); - goto ERR_RET; - } - - p = (Mpg4dCtx *)dec; - p->frame_slots = cfg->frame_slots; - p->packet_slots = cfg->packet_slots; - p->task_count = cfg->task_count = 2; - p->need_split = cfg->need_split; - p->internal_pts = cfg->internal_pts; - p->notify_cb = cfg->notify_cb; - p->stream = stream; - p->stream_size = stream_size; - p->task_pkt = task_pkt; - p->parser = parser; - - return MPP_OK; -ERR_RET: - if (task_pkt) { - mpp_packet_deinit(&task_pkt); - } - if (stream) { - mpp_free(stream); - stream = NULL; - } - return ret; -} - -MPP_RET mpg4d_deinit(void *dec) -{ - Mpg4dCtx *p; - if (NULL == dec) { - mpp_err_f("found NULL intput\n"); - return MPP_ERR_NULL_PTR; - } - - p = (Mpg4dCtx *)dec; - if (p->parser) { - mpp_mpg4_parser_deinit(p->parser); - p->parser = NULL; - } - - if (p->task_pkt) { - mpp_packet_deinit(&p->task_pkt); - } - - if (p->stream) { - mpp_free(p->stream); - p->stream = NULL; - } - return MPP_OK; -} - -MPP_RET mpg4d_reset(void *dec) -{ - if (NULL == dec) { - mpp_err_f("found NULL intput\n"); - return MPP_ERR_NULL_PTR; - } - - Mpg4dCtx *p = (Mpg4dCtx *)dec; - return mpp_mpg4_parser_reset(p->parser); -} - - -MPP_RET mpg4d_flush(void *dec) -{ - if (NULL == dec) { - mpp_err_f("found NULL intput\n"); - return MPP_ERR_NULL_PTR; - } - - Mpg4dCtx *p = (Mpg4dCtx *)dec; - return mpp_mpg4_parser_flush(p->parser); -} - - -MPP_RET mpg4d_control(void *dec, RK_S32 cmd_type, void *param) -{ - Mpg4dCtx *p; - - if (NULL == dec) { - mpp_err_f("found NULL intput\n"); - return MPP_ERR_NULL_PTR; - } - - p = (Mpg4dCtx *)dec; - switch (cmd_type) { - case MPP_DEC_SET_INTERNAL_PTS_ENABLE : { - mpp_mpg4_parser_set_pts_mode(p->parser, 0); - } break; - } - (void)param; - return MPP_OK; -} - -MPP_RET mpg4d_prepare(void *dec, MppPacket pkt, HalDecTask *task) -{ - Mpg4dCtx *p; - RK_U8 *pos; - size_t length; - RK_U32 eos; - - if (NULL == dec || NULL == pkt || NULL == task) { - mpp_err_f("found NULL intput dec %p pkt %p task %p\n", dec, pkt, task); - return MPP_ERR_NULL_PTR; - } - - p = (Mpg4dCtx *)dec; - pos = mpp_packet_get_pos(pkt); - length = mpp_packet_get_length(pkt); - eos = mpp_packet_get_eos(pkt); - - if (eos && !length) { - task->valid = 0; - task->flags.eos = 1; - mpp_log("mpeg4d flush eos"); - mpg4d_flush(dec); - return MPP_OK; - } - - if (NULL == p->stream) { - mpp_err("failed to malloc task buffer for hardware with size %d\n", length); - return MPP_ERR_UNKNOW; - } - - if (!p->need_split) { - /* - * Copy packet mode: - * Decoder's user will insure each packet is one frame for process - * Parser will just copy packet to the beginning of stream buffer - */ - if (length > p->stream_size) { - // NOTE: here we double the buffer length to reduce frequency of realloc - do { - p->stream_size <<= 1; - } while (length > p->stream_size); - - mpp_free(p->stream); - p->stream = mpp_malloc_size(RK_U8, p->stream_size); - mpp_assert(p->stream); - mpp_packet_set_data(p->task_pkt, p->stream); - mpp_packet_set_size(p->task_pkt, p->stream_size); - } - - memcpy(p->stream, pos, length); - mpp_packet_set_pos(p->task_pkt, p->stream); - mpp_packet_set_length(p->task_pkt, length); - // set input packet length to 0 here - // indicate that the input packet has been all consumed - mpp_packet_set_pos(pkt, pos + length); - // always use latest pts for current packet - p->task_pts = mpp_packet_get_pts(pkt); - p->task_eos = mpp_packet_get_eos(pkt); - /* this step will enable the task and goto parse stage */ - task->valid = 1; - } else { - /* - * Split packet mode: - * Input packet can be any length and no need to be bound of on frame - * Parser will do split frame operation to find the beginning and end of one frame - */ - /* - * NOTE: on split mode total length is the left size plus the new incoming - * packet length. - */ - size_t remain_length = mpp_packet_get_length(p->task_pkt); - size_t total_length = remain_length + length; - if (total_length > p->stream_size) { - RK_U8 *dst; - do { - p->stream_size <<= 1; - } while (length > p->stream_size); - - // NOTE; split mode need to copy remaining stream to new buffer - dst = mpp_malloc_size(RK_U8, p->stream_size); - mpp_assert(dst); - - memcpy(dst, p->stream, remain_length); - mpp_free(p->stream); - p->stream = dst; - mpp_packet_set_data(p->task_pkt, p->stream); - mpp_packet_set_size(p->task_pkt, p->stream_size); - } - - // start parser split - if (MPP_OK == mpp_mpg4_parser_split(p->parser, p->task_pkt, pkt)) { - task->valid = 1; - } - p->task_pts = mpp_packet_get_pts(p->task_pkt); - p->task_eos = mpp_packet_get_eos(p->task_pkt); - } - - mpp_packet_set_pts(p->task_pkt, p->task_pts); - task->input_packet = p->task_pkt; - task->flags.eos = p->task_eos; - - return MPP_OK; -} - -MPP_RET mpg4d_parse(void *dec, HalDecTask *task) -{ - MPP_RET ret; - Mpg4dCtx *p; - - if (NULL == dec || NULL == task) { - mpp_err_f("found NULL intput dec %p task %p\n", dec, task); - return MPP_ERR_NULL_PTR; - } - p = (Mpg4dCtx *)dec; - ret = mpp_mpg4_parser_decode(p->parser, task->input_packet); - if (ret) { - // found error on decoding drop this task and clear remaining length - task->valid = 0; - task->output = -1; - mpp_packet_set_length(task->input_packet, 0); - return MPP_NOK; - } - - mpp_mpg4_parser_setup_syntax(p->parser, &task->syntax); - mpp_mpg4_parser_setup_hal_output(p->parser, &task->output); - mpp_mpg4_parser_setup_refer(p->parser, task->refer, MAX_DEC_REF_NUM); - mpp_mpg4_parser_update_dpb(p->parser); - - p->frame_count++; - - return MPP_OK; -} - -MPP_RET mpg4d_callback(void *dec, void *err_info) -{ - (void)dec; - (void)err_info; - return MPP_OK; -} - -const ParserApi api_mpg4d_parser = { - "api_mpg4d_parser", - MPP_VIDEO_CodingMPEG4, - sizeof(Mpg4dCtx), - 0, - mpg4d_init, - mpg4d_deinit, - mpg4d_prepare, - mpg4d_parse, - mpg4d_reset, - mpg4d_flush, - mpg4d_control, - mpg4d_callback, -}; - +/* +* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#define MODULE_TAG "mpg4d_api" + +#include + +#include "rk_mpi.h" + +#include "mpp_log.h" +#include "mpp_mem.h" +#include "mpp_common.h" + +#include "mpg4d_api.h" +#include "mpg4d_parser.h" + +#define MPG4D_INIT_STREAM_SIZE SZ_64K + +typedef struct { + // parameter interact with mpp_dec + MppBufSlots frame_slots; + MppBufSlots packet_slots; + RK_S32 task_count; + RK_U8 *stream; + size_t stream_size; + MppPacket task_pkt; + RK_S64 task_pts; + RK_U32 task_eos; + + // runtime parameter + RK_U32 need_split; + RK_U32 frame_count; + RK_U32 internal_pts; + IOInterruptCB notify_cb; + + // parser context + Mpg4dParser parser; +} Mpg4dCtx; + +MPP_RET mpg4d_init(void *dec, ParserCfg *cfg) +{ + Mpg4dParser parser = NULL; + MppPacket task_pkt = NULL; + Mpg4dCtx *p; + MPP_RET ret; + RK_U8 *stream; + size_t stream_size = MPG4D_INIT_STREAM_SIZE; + + if (NULL == dec) { + mpp_err_f("found NULL intput dec %p cfg %p\n", dec, cfg); + return MPP_ERR_NULL_PTR; + } + + stream = mpp_malloc_size(RK_U8, stream_size); + if (NULL == stream) { + mpp_err_f("failed to malloc stream buffer size %d\n", stream_size); + return MPP_ERR_MALLOC; + } + + ret = mpp_packet_init(&task_pkt, stream, stream_size); + if (ret) { + mpp_err_f("failed to create mpp_packet for task\n"); + goto ERR_RET; + } + + // reset task packet length to zero + // NOTE: set length must after set pos + mpp_packet_set_pos(task_pkt, stream); + mpp_packet_set_length(task_pkt, 0); + + ret = mpp_mpg4_parser_init(&parser, cfg->frame_slots); + if (ret) { + mpp_err_f("failed to init parser\n"); + goto ERR_RET; + } + + p = (Mpg4dCtx *)dec; + p->frame_slots = cfg->frame_slots; + p->packet_slots = cfg->packet_slots; + p->task_count = cfg->task_count = 2; + p->need_split = cfg->need_split; + p->internal_pts = cfg->internal_pts; + p->notify_cb = cfg->notify_cb; + p->stream = stream; + p->stream_size = stream_size; + p->task_pkt = task_pkt; + p->parser = parser; + + return MPP_OK; +ERR_RET: + if (task_pkt) { + mpp_packet_deinit(&task_pkt); + } + if (stream) { + mpp_free(stream); + stream = NULL; + } + return ret; +} + +MPP_RET mpg4d_deinit(void *dec) +{ + Mpg4dCtx *p; + if (NULL == dec) { + mpp_err_f("found NULL intput\n"); + return MPP_ERR_NULL_PTR; + } + + p = (Mpg4dCtx *)dec; + if (p->parser) { + mpp_mpg4_parser_deinit(p->parser); + p->parser = NULL; + } + + if (p->task_pkt) { + mpp_packet_deinit(&p->task_pkt); + } + + if (p->stream) { + mpp_free(p->stream); + p->stream = NULL; + } + return MPP_OK; +} + +MPP_RET mpg4d_reset(void *dec) +{ + if (NULL == dec) { + mpp_err_f("found NULL intput\n"); + return MPP_ERR_NULL_PTR; + } + + Mpg4dCtx *p = (Mpg4dCtx *)dec; + return mpp_mpg4_parser_reset(p->parser); +} + + +MPP_RET mpg4d_flush(void *dec) +{ + if (NULL == dec) { + mpp_err_f("found NULL intput\n"); + return MPP_ERR_NULL_PTR; + } + + Mpg4dCtx *p = (Mpg4dCtx *)dec; + return mpp_mpg4_parser_flush(p->parser); +} + + +MPP_RET mpg4d_control(void *dec, RK_S32 cmd_type, void *param) +{ + Mpg4dCtx *p; + + if (NULL == dec) { + mpp_err_f("found NULL intput\n"); + return MPP_ERR_NULL_PTR; + } + + p = (Mpg4dCtx *)dec; + switch (cmd_type) { + case MPP_DEC_SET_INTERNAL_PTS_ENABLE : { + mpp_mpg4_parser_set_pts_mode(p->parser, 0); + } break; + } + (void)param; + return MPP_OK; +} + +MPP_RET mpg4d_prepare(void *dec, MppPacket pkt, HalDecTask *task) +{ + Mpg4dCtx *p; + RK_U8 *pos; + size_t length; + RK_U32 eos; + + if (NULL == dec || NULL == pkt || NULL == task) { + mpp_err_f("found NULL intput dec %p pkt %p task %p\n", dec, pkt, task); + return MPP_ERR_NULL_PTR; + } + + p = (Mpg4dCtx *)dec; + pos = mpp_packet_get_pos(pkt); + length = mpp_packet_get_length(pkt); + eos = mpp_packet_get_eos(pkt); + + if (eos && !length) { + task->valid = 0; + task->flags.eos = 1; + mpp_log("mpeg4d flush eos"); + mpg4d_flush(dec); + return MPP_OK; + } + + if (NULL == p->stream) { + mpp_err("failed to malloc task buffer for hardware with size %d\n", length); + return MPP_ERR_UNKNOW; + } + + if (!p->need_split) { + /* + * Copy packet mode: + * Decoder's user will insure each packet is one frame for process + * Parser will just copy packet to the beginning of stream buffer + */ + if (length > p->stream_size) { + // NOTE: here we double the buffer length to reduce frequency of realloc + do { + p->stream_size <<= 1; + } while (length > p->stream_size); + + mpp_free(p->stream); + p->stream = mpp_malloc_size(RK_U8, p->stream_size); + mpp_assert(p->stream); + mpp_packet_set_data(p->task_pkt, p->stream); + mpp_packet_set_size(p->task_pkt, p->stream_size); + } + + memcpy(p->stream, pos, length); + mpp_packet_set_pos(p->task_pkt, p->stream); + mpp_packet_set_length(p->task_pkt, length); + // set input packet length to 0 here + // indicate that the input packet has been all consumed + mpp_packet_set_pos(pkt, pos + length); + // always use latest pts for current packet + p->task_pts = mpp_packet_get_pts(pkt); + p->task_eos = mpp_packet_get_eos(pkt); + /* this step will enable the task and goto parse stage */ + task->valid = 1; + } else { + /* + * Split packet mode: + * Input packet can be any length and no need to be bound of on frame + * Parser will do split frame operation to find the beginning and end of one frame + */ + /* + * NOTE: on split mode total length is the left size plus the new incoming + * packet length. + */ + size_t remain_length = mpp_packet_get_length(p->task_pkt); + size_t total_length = remain_length + length; + if (total_length > p->stream_size) { + RK_U8 *dst; + do { + p->stream_size <<= 1; + } while (length > p->stream_size); + + // NOTE; split mode need to copy remaining stream to new buffer + dst = mpp_malloc_size(RK_U8, p->stream_size); + mpp_assert(dst); + + memcpy(dst, p->stream, remain_length); + mpp_free(p->stream); + p->stream = dst; + mpp_packet_set_data(p->task_pkt, p->stream); + mpp_packet_set_size(p->task_pkt, p->stream_size); + } + + // start parser split + if (MPP_OK == mpp_mpg4_parser_split(p->parser, p->task_pkt, pkt)) { + task->valid = 1; + } + p->task_pts = mpp_packet_get_pts(p->task_pkt); + p->task_eos = mpp_packet_get_eos(p->task_pkt); + } + + mpp_packet_set_pts(p->task_pkt, p->task_pts); + task->input_packet = p->task_pkt; + task->flags.eos = p->task_eos; + + return MPP_OK; +} + +MPP_RET mpg4d_parse(void *dec, HalDecTask *task) +{ + MPP_RET ret; + Mpg4dCtx *p; + + if (NULL == dec || NULL == task) { + mpp_err_f("found NULL intput dec %p task %p\n", dec, task); + return MPP_ERR_NULL_PTR; + } + p = (Mpg4dCtx *)dec; + ret = mpp_mpg4_parser_decode(p->parser, task->input_packet); + if (ret) { + // found error on decoding drop this task and clear remaining length + task->valid = 0; + task->output = -1; + mpp_packet_set_length(task->input_packet, 0); + return MPP_NOK; + } + + mpp_mpg4_parser_setup_syntax(p->parser, &task->syntax); + mpp_mpg4_parser_setup_hal_output(p->parser, &task->output); + mpp_mpg4_parser_setup_refer(p->parser, task->refer, MAX_DEC_REF_NUM); + mpp_mpg4_parser_update_dpb(p->parser); + + p->frame_count++; + + return MPP_OK; +} + +MPP_RET mpg4d_callback(void *dec, void *err_info) +{ + (void)dec; + (void)err_info; + return MPP_OK; +} + +const ParserApi api_mpg4d_parser = { + "api_mpg4d_parser", + MPP_VIDEO_CodingMPEG4, + sizeof(Mpg4dCtx), + 0, + mpg4d_init, + mpg4d_deinit, + mpg4d_prepare, + mpg4d_parse, + mpg4d_reset, + mpg4d_flush, + mpg4d_control, + mpg4d_callback, +}; + diff --git a/mpp/codec/dec/mpg4/mpg4d_parser.c b/mpp/codec/dec/mpg4/mpg4d_parser.c index 462a01a4..d0af36f8 100644 --- a/mpp/codec/dec/mpg4/mpg4d_parser.c +++ b/mpp/codec/dec/mpg4/mpg4d_parser.c @@ -1,1589 +1,1589 @@ -/* - * - * Copyright 2010 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define MODULE_TAG "mpg4d_parser" - -#include - -#include "mpp_env.h" -#include "mpp_log.h" -#include "mpp_mem.h" -#include "mpp_packet.h" - -#include "mpp_bitread.h" -#include "mpg4d_parser.h" -#include "mpg4d_syntax.h" - - -RK_U32 mpg4d_debug = 0; -#define mpg4d_dbg(flag, fmt, ...) _mpp_dbg(mpg4d_debug, flag, fmt, ## __VA_ARGS__) -#define mpg4d_dbg_f(flag, fmt, ...) _mpp_dbg_f(mpg4d_debug, flag, fmt, ## __VA_ARGS__) - -#define mpg4d_dbg_func(fmt, ...) mpg4d_dbg_f(MPG4D_DBG_FUNCTION, fmt, ## __VA_ARGS__) -#define mpg4d_dbg_bit(fmt, ...) mpg4d_dbg(MPG4D_DBG_BITS, fmt, ## __VA_ARGS__) -#define mpg4d_dbg_result(fmt, ...) mpg4d_dbg(MPG4D_DBG_RESULT, fmt, ## __VA_ARGS__) - -#define MPEG4_VIDOBJ_START_CODE 0x00000100 /* ..0x0000011f */ -#define MPEG4_VIDOBJLAY_START_CODE 0x00000120 /* ..0x0000012f */ -#define MPEG4_VISOBJSEQ_START_CODE 0x000001b0 -#define MPEG4_VISOBJSEQ_STOP_CODE 0x000001b1 -#define MPEG4_USERDATA_START_CODE 0x000001b2 -#define MPEG4_GRPOFVOP_START_CODE 0x000001b3 -#define MPEG4_VISOBJ_START_CODE 0x000001b5 -#define MPEG4_VOP_START_CODE 0x000001b6 - -#define MPG4_VOL_STARTCODE 0x120 -#define MPG4_VOL_STOPCODE 0x12F -#define MPG4_VOS_STARTCODE 0x1B0 -#define MPG4_VOS_STOPCODE 0x1B1 -#define MPG4_USER_DATA_STARTCODE 0x1B2 -#define MPG4_GOP_STARTCODE 0x1B3 -#define MPG4_VISUAL_OBJ_STARTCODE 0x1B5 -#define MPG4_VOP_STARTCODE 0x1B6 - -typedef struct { - RK_S32 method; - - RK_S32 opaque; - RK_S32 transparent; - RK_S32 intra_cae; - RK_S32 inter_cae; - RK_S32 no_update; - RK_S32 upsampling; - - RK_S32 intra_blocks; - RK_S32 inter_blocks; - RK_S32 inter4v_blocks; - RK_S32 gmc_blocks; - RK_S32 not_coded_blocks; - - RK_S32 dct_coefs; - RK_S32 dct_lines; - RK_S32 vlc_symbols; - RK_S32 vlc_bits; - - RK_S32 apm; - RK_S32 npm; - RK_S32 interpolate_mc_q; - RK_S32 forw_back_mc_q; - RK_S32 halfpel2; - RK_S32 halfpel4; - - RK_S32 sadct; - RK_S32 quarterpel; -} Mpeg4Estimation; - -typedef struct Mp4HdrVol_t { - RK_S32 vo_type; - RK_U32 low_delay; - RK_U32 shape; - RK_S32 time_inc_resolution; - RK_U32 time_inc_bits; - RK_S32 width; - RK_S32 height; - RK_U32 mb_width; - RK_U32 mb_height; - RK_S32 hor_stride; - RK_S32 ver_stride; - RK_U32 totalMbInVop; - RK_U32 interlacing; - RK_S32 sprite_enable; - RK_U32 quant_bits; - RK_U32 quant_type; - RK_S32 quarter_sample; - RK_S32 complexity_estimation_disable; - RK_U32 resync_marker_disable; - RK_S32 newpred_enable; - RK_S32 reduced_resolution_enable; - RK_S32 scalability; - RK_S32 ver_id; -} Mp4HdrVol; - -typedef struct Mp4HdrUserData_t { - RK_S32 packed_mode; /* bframes packed bits? (1 = yes) */ -} Mp4HdrUserData; - -typedef struct Mp4HdrVop_t { - RK_S32 coding_type; - RK_U32 frameNumber; - RK_U32 rounding; - RK_U32 intra_dc_vlc_threshold; - RK_U32 top_field_first; - RK_U32 alternate_vertical_scan; - RK_U32 fcode_forward; - RK_U32 fcode_backward; - RK_U32 quant; // OFFSET_OF_QUANT_IN_DEC - RK_U32 hdr_bits; -} Mp4HdrVop; - -typedef struct Mpg4Hdr_t { - // vol parameter - Mp4HdrVol vol; - - // user data parameter - Mp4HdrUserData usr; - - // vop header parameter - Mp4HdrVop vop; - - // frame related parameter - RK_S64 pts; - RK_S32 slot_idx; - RK_U32 enqueued; - - RK_U32 last_time_base; - RK_U32 time_base; - RK_U32 time; - RK_U32 time_pp; - RK_U32 time_bp; - RK_U32 last_non_b_time; -} Mpg4Hdr; - - -typedef struct { - // global paramter - MppBufSlots frame_slots; - RK_U32 use_internal_pts; - RK_U32 found_vol; - RK_U32 found_vop; - RK_U32 found_i_vop; - - // frame size parameter - RK_S32 width; - RK_S32 height; - RK_S32 hor_stride; - RK_S32 ver_stride; - RK_U32 info_change; - RK_U32 eos; - - // spliter parameter - RK_S32 pos_frm_start; // negtive - not found; non-negtive - position of frame start - RK_S32 pos_frm_end; // negtive - not found; non-negtive - position of frame end - - // bit read context - BitReadCtx_t *bit_ctx; - // vos infomation - RK_U32 profile; - RK_U32 level; - RK_U32 custorm_version; - - // commom buffer for header information - /* - * NOTE: We assume that quant matrix only used for current frame decoding - * So we use only one quant matrix buffer and only support - */ - RK_U32 new_qm[2]; // [0] - intra [1] - inter - RK_U8 quant_matrices[128]; // 0-63: intra 64-127: inter - Mpeg4Estimation estimation; - Mpg4Hdr hdr_curr; /* header for current decoding frame */ - Mpg4Hdr hdr_ref0; /* header for reference frame 0 */ - Mpg4Hdr hdr_ref1; /* header for reference frame 1 */ - - // dpb/output information - RK_S32 output; - RK_S64 last_pts; - RK_S64 pts_inc; - RK_S64 pts; - RK_U32 frame_num; - - // syntax for hal - mpeg4d_dxva2_picture_context_t *syntax; -} Mpg4dParserImpl; - -static RK_S32 log2bin(RK_U32 value) -{ - RK_S32 n = 0; - - while (value) { - value >>= 1; - n++; - } - - return n; -} - -static MPP_RET mpg4d_parse_matrix(BitReadCtx_t *gb, RK_U8 * matrix) -{ - RK_S32 i = 0; - RK_S32 last, value = 0; - - do { - last = value; - READ_BITS(gb, 8, &value); - matrix[i++] = value; - } while (value != 0 && i < 64); - - if (value != 0) - return MPP_ERR_STREAM; - - i--; - - while (i < 64) { - matrix[i++ ] = last; - } - - return MPP_OK; - -__BITREAD_ERR: - return MPP_ERR_STREAM; -} - -static void mpg4d_set_intra_matrix(RK_U8 * quant_matrices, RK_U8 * matrix) -{ - RK_S32 i; - RK_U8 *intra_matrix = quant_matrices + 0 * 64; - - for (i = 0; i < 64; i++) { - intra_matrix[i] = (!i) ? (RK_U8)8 : (RK_U8)matrix[i]; - } -} - -static void mpg4d_set_inter_matrix(RK_U8 * quant_matrices, RK_U8 * matrix) -{ - RK_S32 i; - RK_U8 *inter_matrix = quant_matrices + 1 * 64; - - for (i = 0; i < 64; i++) { - inter_matrix[i] = (RK_U8) (matrix[i]); - } -} - -static MPP_RET read_vol_complexity_estimation_header(Mpeg4Estimation *e, BitReadCtx_t *gb) -{ - RK_U32 val; - - READ_BITS(gb, 2, &(e->method)); /* estimation_method */ - - if (e->method == 0 || e->method == 1) { - READ_BITS(gb, 1, &val); - if (!val) { /* shape_complexity_estimation_disable */ - READ_BITS(gb, 1, &(e->opaque)); /* opaque */ - READ_BITS(gb, 1, &(e->transparent)); /* transparent */ - READ_BITS(gb, 1, &(e->intra_cae)); /* intra_cae */ - READ_BITS(gb, 1, &(e->inter_cae)); /* inter_cae */ - READ_BITS(gb, 1, &(e->no_update)); /* no_update */ - READ_BITS(gb, 1, &(e->upsampling)); /* upsampling */ - } - - READ_BITS(gb, 1, &val); - if (!val) { /* texture_complexity_estimation_set_1_disable */ - READ_BITS(gb, 1, &(e->intra_blocks)); /* intra_blocks */ - READ_BITS(gb, 1, &(e->inter_blocks)); /* inter_blocks */ - READ_BITS(gb, 1, &(e->inter4v_blocks)); /* inter4v_blocks */ - READ_BITS(gb, 1, &(e->not_coded_blocks)); /* not_coded_blocks */ - } - } - - SKIP_BITS(gb, 1); - - READ_BITS(gb, 1, &val); - if (!val) { /* texture_complexity_estimation_set_2_disable */ - READ_BITS(gb, 1, &(e->dct_coefs)); /* dct_coefs */ - READ_BITS(gb, 1, &(e->dct_lines)); /* dct_lines */ - READ_BITS(gb, 1, &(e->vlc_symbols)); /* vlc_symbols */ - READ_BITS(gb, 1, &(e->vlc_bits)); /* vlc_bits */ - } - - READ_BITS(gb, 1, &val); - if (!val) { /* motion_compensation_complexity_disable */ - READ_BITS(gb, 1, &(e->apm)); /* apm */ - READ_BITS(gb, 1, &(e->npm)); /* npm */ - READ_BITS(gb, 1, &(e->interpolate_mc_q)); /* interpolate_mc_q */ - READ_BITS(gb, 1, &(e->forw_back_mc_q)); /* forw_back_mc_q */ - READ_BITS(gb, 1, &(e->halfpel2)); /* halfpel2 */ - READ_BITS(gb, 1, &(e->halfpel4)); /* halfpel4 */ - } - - SKIP_BITS(gb, 1); - - if (e->method == 1) { - READ_BITS(gb, 1, &val); - if (!val) { /* version2_complexity_estimation_disable */ - READ_BITS(gb, 1, &(e->sadct)); /* sadct */ - READ_BITS(gb, 1, &(e->quarterpel)); /* quarterpel */ - } - } - - return MPP_OK; - -__BITREAD_ERR: - return MPP_ERR_STREAM; -} - -/* vop estimation header */ -static MPP_RET read_vop_complexity_estimation_header(Mpeg4Estimation *e, BitReadCtx_t *gb, Mpg4Hdr *mp4Hdr, int coding_type) -{ - if (e->method == 0 || e->method == 1) { - if (coding_type == MPEG4_I_VOP) { - if (e->opaque) SKIP_BITS(gb, 8); /* dcecs_opaque */ - if (e->transparent) SKIP_BITS(gb, 8); /* */ - if (e->intra_cae) SKIP_BITS(gb, 8); /* */ - if (e->inter_cae) SKIP_BITS(gb, 8); /* */ - if (e->no_update) SKIP_BITS(gb, 8); /* */ - if (e->upsampling) SKIP_BITS(gb, 8); /* */ - if (e->intra_blocks) SKIP_BITS(gb, 8); /* */ - if (e->not_coded_blocks) SKIP_BITS(gb, 8); /* */ - if (e->dct_coefs) SKIP_BITS(gb, 8); /* */ - if (e->dct_lines) SKIP_BITS(gb, 8); /* */ - if (e->vlc_symbols) SKIP_BITS(gb, 8); /* */ - if (e->vlc_bits) SKIP_BITS(gb, 8); /* */ - if (e->sadct) SKIP_BITS(gb, 8); /* */ - } - - if (coding_type == MPEG4_P_VOP) { - if (e->opaque) SKIP_BITS(gb, 8); /* */ - if (e->transparent) SKIP_BITS(gb, 8); /* */ - if (e->intra_cae) SKIP_BITS(gb, 8); /* */ - if (e->inter_cae) SKIP_BITS(gb, 8); /* */ - if (e->no_update) SKIP_BITS(gb, 8); /* */ - if (e->upsampling) SKIP_BITS(gb, 8); /* */ - if (e->intra_blocks) SKIP_BITS(gb, 8); /* */ - if (e->not_coded_blocks) SKIP_BITS(gb, 8); /* */ - if (e->dct_coefs) SKIP_BITS(gb, 8); /* */ - if (e->dct_lines) SKIP_BITS(gb, 8); /* */ - if (e->vlc_symbols) SKIP_BITS(gb, 8); /* */ - if (e->vlc_bits) SKIP_BITS(gb, 8); /* */ - if (e->inter_blocks) SKIP_BITS(gb, 8); /* */ - if (e->inter4v_blocks) SKIP_BITS(gb, 8); /* */ - if (e->apm) SKIP_BITS(gb, 8); /* */ - if (e->npm) SKIP_BITS(gb, 8); /* */ - if (e->forw_back_mc_q) SKIP_BITS(gb, 8); /* */ - if (e->halfpel2) SKIP_BITS(gb, 8); /* */ - if (e->halfpel4) SKIP_BITS(gb, 8); /* */ - if (e->sadct) SKIP_BITS(gb, 8); /* */ - if (e->quarterpel) SKIP_BITS(gb, 8); /* */ - } - - if (coding_type == MPEG4_B_VOP) { - if (e->opaque) SKIP_BITS(gb, 8); /* */ - if (e->transparent) SKIP_BITS(gb, 8); /* */ - if (e->intra_cae) SKIP_BITS(gb, 8); /* */ - if (e->inter_cae) SKIP_BITS(gb, 8); /* */ - if (e->no_update) SKIP_BITS(gb, 8); /* */ - if (e->upsampling) SKIP_BITS(gb, 8); /* */ - if (e->intra_blocks) SKIP_BITS(gb, 8); /* */ - if (e->not_coded_blocks) SKIP_BITS(gb, 8); /* */ - if (e->dct_coefs) SKIP_BITS(gb, 8); /* */ - if (e->dct_lines) SKIP_BITS(gb, 8); /* */ - if (e->vlc_symbols) SKIP_BITS(gb, 8); /* */ - if (e->vlc_bits) SKIP_BITS(gb, 8); /* */ - if (e->inter_blocks) SKIP_BITS(gb, 8); /* */ - if (e->inter4v_blocks) SKIP_BITS(gb, 8); /* */ - if (e->apm) SKIP_BITS(gb, 8); /* */ - if (e->npm) SKIP_BITS(gb, 8); /* */ - if (e->forw_back_mc_q) SKIP_BITS(gb, 8); /* */ - if (e->halfpel2) SKIP_BITS(gb, 8); /* */ - if (e->halfpel4) SKIP_BITS(gb, 8); /* */ - if (e->interpolate_mc_q) SKIP_BITS(gb, 8); /* */ - if (e->sadct) SKIP_BITS(gb, 8); /* */ - if (e->quarterpel) SKIP_BITS(gb, 8); /* */ - } - -#ifdef GMC_SUPPORT - if (coding_type == MPEG4_S_VOP && mp4Hdr->vol.sprite_enable == MPEG4_SPRITE_STATIC) { - if (e->intra_blocks) SKIP_BITS(gb, 8); /* */ - if (e->not_coded_blocks) SKIP_BITS(gb, 8); /* */ - if (e->dct_coefs) SKIP_BITS(gb, 8); /* */ - if (e->dct_lines) SKIP_BITS(gb, 8); /* */ - if (e->vlc_symbols) SKIP_BITS(gb, 8); /* */ - if (e->vlc_bits) SKIP_BITS(gb, 8); /* */ - if (e->inter_blocks) SKIP_BITS(gb, 8); /* */ - if (e->inter4v_blocks) SKIP_BITS(gb, 8); /* */ - if (e->apm) SKIP_BITS(gb, 8); /* */ - if (e->npm) SKIP_BITS(gb, 8); /* */ - if (e->forw_back_mc_q) SKIP_BITS(gb, 8); /* */ - if (e->halfpel2) SKIP_BITS(gb, 8); /* */ - if (e->halfpel4) SKIP_BITS(gb, 8); /* */ - if (e->interpolate_mc_q) SKIP_BITS(gb, 8); /* */ - } -#else - (void)mp4Hdr; -#endif - } - - return MPP_OK; - -__BITREAD_ERR: - return MPP_ERR_STREAM; -} - -static void init_mpg4_hdr_vol(Mpg4Hdr *header) -{ - memset(&header->vol, 0, sizeof(header->vol)); - header->vol.ver_id = 1; -} - -static void init_mpg4_hdr_vop(Mpg4Hdr *header) -{ - memset(&header->vop, 0, sizeof(header->vop)); - header->vop.coding_type = MPEG4_INVALID_VOP; -} - -static void init_mpg4_header(Mpg4Hdr *header) -{ - init_mpg4_hdr_vol(header); - header->usr.packed_mode = 0; - init_mpg4_hdr_vop(header); - header->pts = 0; - header->slot_idx = -1; - header->enqueued = 0; -} - -static MPP_RET mpg4d_parse_vol_header(Mpg4dParserImpl *p, BitReadCtx_t *cb) -{ - RK_U32 val = 0; - Mpg4Hdr *mp4Hdr = &p->hdr_curr; - RK_S32 vol_ver_id; - RK_S32 aspect_ratio; - RK_S32 vol_control_parameters; - - SKIP_BITS(cb, 1); /* random_accessible_vol */ - READ_BITS(cb, 8, &(mp4Hdr->vol.vo_type), "vo_type"); - - READ_BITS(cb, 1, &val, "is_object_layer_identifier"); - if (val) { - READ_BITS(cb, 4, &vol_ver_id, "video_object_layer_verid"); - SKIP_BITS(cb, 3); /* video_object_layer_priority */ - } else { - vol_ver_id = mp4Hdr->vol.ver_id; - } - - READ_BITS(cb, 4, &aspect_ratio); - - if (aspect_ratio == MPEG4_VIDOBJLAY_AR_EXTPAR) { /* aspect_ratio_info */ - RK_S32 par_width, par_height; - - READ_BITS(cb, 8, &par_width); /* par_width */ - READ_BITS(cb, 8, &par_height); /* par_height */ - } - - READ_BITS(cb, 1, &vol_control_parameters); - - if (vol_control_parameters) { /* vol_control_parameters */ - SKIP_BITS(cb, 2); /* chroma_format */ - READ_BITS(cb, 1, &(mp4Hdr->vol.low_delay)); /* low_delay flage (1 means no B_VOP) */ - - READ_BITS(cb, 1, &val, "vbv_parameters"); - if (val) { - RK_U32 bitrate; - RK_U32 buffer_size; - RK_U32 occupancy; - - READ_BITS(cb, 15, &val, "first_half_bit_rate"); - bitrate = val << 15; - SKIP_BITS(cb, 1); - READ_BITS(cb, 15, &val, "latter_half_bit_rate"); - bitrate |= val; - SKIP_BITS(cb, 1); - - READ_BITS(cb, 15, &val, "first_half_vbv_buffer_size"); - buffer_size = val << 3; - SKIP_BITS(cb, 1); - READ_BITS(cb, 3, &val); - buffer_size |= val; /* latter_half_vbv_buffer_size */ - - READ_BITS(cb, 11, &val); - occupancy = val << 15; /* first_half_vbv_occupancy */ - SKIP_BITS(cb, 1); - READ_BITS(cb, 15, &val); - occupancy |= val; /* latter_half_vbv_occupancy */ - SKIP_BITS(cb, 1); - } - } else { - mp4Hdr->vol.low_delay = 0; - } - - if (mp4Hdr->vol.vo_type == 0 && vol_control_parameters == 0 && mp4Hdr->vop.frameNumber == 0) { - mpp_log("looks like this file was encoded with (divx4/(old)xvid/opendivx)\n"); - return MPP_NOK; - } - - READ_BITS(cb, 2, &(mp4Hdr->vol.shape)); /* video_object_layer_shape */ - - if (mp4Hdr->vol.shape != MPEG4_VIDOBJLAY_SHAPE_RECTANGULAR) { - mpp_log("unsupported shape %d\n", mp4Hdr->vol.shape); - return MPP_NOK; - } - - if (mp4Hdr->vol.shape == MPEG4_VIDOBJLAY_SHAPE_GRAYSCALE && vol_ver_id != 1) { - SKIP_BITS(cb, 4); /* video_object_layer_shape_extension */ - } - - SKIP_BITS(cb, 1); - - READ_BITS(cb, 16, &(mp4Hdr->vol.time_inc_resolution)); /* vop_time_increment_resolution */ - - if (mp4Hdr->vol.time_inc_resolution > 0) { - mp4Hdr->vol.time_inc_bits = MPP_MAX(log2bin(mp4Hdr->vol.time_inc_resolution - 1), 1); - } else { - /* for "old" xvid compatibility, set time_inc_bits = 1 */ - mp4Hdr->vol.time_inc_bits = 1; - } - - SKIP_BITS(cb, 1); - - READ_BITS(cb, 1, &val); - if (val) { /* fixed_vop_rate */ - SKIP_BITS(cb, mp4Hdr->vol.time_inc_bits); /* fixed_vop_time_increment */ - } - - if (mp4Hdr->vol.shape != MPEG4_VIDOBJLAY_SHAPE_BINARY_ONLY) { - if (mp4Hdr->vol.shape == MPEG4_VIDOBJLAY_SHAPE_RECTANGULAR) { - RK_S32 width, height; - - SKIP_BITS(cb, 1); - READ_BITS(cb, 13, &width); /* video_object_layer_width */ - SKIP_BITS(cb, 1); - READ_BITS(cb, 13, &height); /* video_object_layer_height */ - SKIP_BITS(cb, 1); - - mpg4d_dbg_bit("width %4d height %4d\n", width, height); - - mp4Hdr->vol.width = width; - mp4Hdr->vol.height = height; - mp4Hdr->vol.mb_width = (mp4Hdr->vol.width + 15) >> 4; - mp4Hdr->vol.mb_height = (mp4Hdr->vol.height + 15) >> 4; - mp4Hdr->vol.totalMbInVop = mp4Hdr->vol.mb_width * mp4Hdr->vol.mb_height; - mp4Hdr->vol.hor_stride = 16 * mp4Hdr->vol.mb_width; - mp4Hdr->vol.ver_stride = 16 * mp4Hdr->vol.mb_height; - } - - READ_BITS(cb, 1, &(mp4Hdr->vol.interlacing)); - - READ_BITS(cb, 1, &val); - if (!val) { /* obmc_disable */ - /* TODO */ - /* fucking divx4.02 has this enabled */ - } - - /* sprite_enable */ - READ_BITS(cb, (vol_ver_id == 1 ? 1 : 2), &(mp4Hdr->vol.sprite_enable)); - - if (mp4Hdr->vol.sprite_enable != MPEG4_SPRITE_NONE) { - mpp_err("GMC is not supported\n"); - return MPP_ERR_PROTOL; - } - - if (vol_ver_id != 1 && - mp4Hdr->vol.shape != MPEG4_VIDOBJLAY_SHAPE_RECTANGULAR) { - SKIP_BITS(cb, 1); /* sadct_disable */ - } - - READ_BITS(cb, 1, &val); - if (val) { /* not_8_bit */ - READ_BITS(cb, 4, &(mp4Hdr->vol.quant_bits));/* quant_precision */ - SKIP_BITS(cb, 4); /* bits_per_pixel */ - } else { - mp4Hdr->vol.quant_bits = 5; - } - - if (mp4Hdr->vol.shape == MPEG4_VIDOBJLAY_SHAPE_GRAYSCALE) { - SKIP_BITS(cb, 1); /* no_gray_quant_update */ - SKIP_BITS(cb, 1); /* composition_method */ - SKIP_BITS(cb, 1); /* linear_composition */ - } - - READ_BITS(cb, 1, &(mp4Hdr->vol.quant_type)); /* quant_type */ - - if (mp4Hdr->vol.quant_type) { - RK_U8 matrix[64]; - - READ_BITS(cb, 1, &val); - p->new_qm[0] = val; - if (val) { /* load_intra_quant_mat */ - mpg4d_parse_matrix(cb, matrix); - mpg4d_set_intra_matrix(p->quant_matrices, matrix); - } - - READ_BITS(cb, 1, &val); - p->new_qm[1] = val; - if (val) { /* load_inter_quant_mat */ - mpg4d_parse_matrix(cb, matrix); - mpg4d_set_inter_matrix(p->quant_matrices, matrix); - } - - if (mp4Hdr->vol.shape == MPEG4_VIDOBJLAY_SHAPE_GRAYSCALE) { - mpp_err("SHAPE_GRAYSCALE is not supported\n"); - return MPP_NOK; - } - } else { - p->new_qm[0] = 0; - p->new_qm[1] = 0; - } - - if (vol_ver_id != 1) { - READ_BITS(cb, 1, &(mp4Hdr->vol.quarter_sample), "quarter_sample"); - } else - mp4Hdr->vol.quarter_sample = 0; - - /* complexity estimation disable */ - READ_BITS(cb, 1, &(mp4Hdr->vol.complexity_estimation_disable)); - - if (!mp4Hdr->vol.complexity_estimation_disable) { - mpg4d_dbg_bit("read_vol_complexity_estimation_header\n"); - if (read_vol_complexity_estimation_header(&p->estimation, cb)) - return MPP_ERR_STREAM; - } - - /* resync_marker_disable */ - READ_BITS(cb, 1, &(mp4Hdr->vol.resync_marker_disable)); - if (!mp4Hdr->vol.resync_marker_disable) { - mpp_log("resync marker enabled\n"); - // return MPEG4_RESYNC_VOP; - } - - READ_BITS(cb, 1, &val); - if (val) { /* data_partitioned */ - SKIP_BITS(cb, 1); /* reversible_vlc */ - } - - if (vol_ver_id != 1) { - READ_BITS(cb, 1, &(mp4Hdr->vol.newpred_enable)); - - if (mp4Hdr->vol.newpred_enable) { /* newpred_enable */ - SKIP_BITS(cb, 2); /* requested_upstream_message_type */ - SKIP_BITS(cb, 1); /* newpred_segment_type */ - } - - /* reduced_resolution_vop_enable */ - READ_BITS(cb, 1, &(mp4Hdr->vol.reduced_resolution_enable)); - } else { - mp4Hdr->vol.newpred_enable = 0; - mp4Hdr->vol.reduced_resolution_enable = 0; - } - - READ_BITS(cb, 1, &mp4Hdr->vol.scalability); /* scalability */ - - if (mp4Hdr->vol.scalability) { - SKIP_BITS(cb, 1); /* hierarchy_type */ - SKIP_BITS(cb, 4); /* ref_layer_id */ - SKIP_BITS(cb, 1); /* ref_layer_sampling_direc */ - SKIP_BITS(cb, 5); /* hor_sampling_factor_n */ - SKIP_BITS(cb, 5); /* hor_sampling_factor_m */ - SKIP_BITS(cb, 5); /* vert_sampling_factor_n */ - SKIP_BITS(cb, 5); /* vert_sampling_factor_m */ - SKIP_BITS(cb, 1); /* enhancement_type */ - - if (mp4Hdr->vol.shape == MPEG4_VIDOBJLAY_SHAPE_BINARY /* && hierarchy_type==0 */) { - /* use_ref_shape and so on*/ - SKIP_BITS(cb, ( 1 + 1 + 1 + 5 + 5 + 5 + 5)); - } - - mpp_err("scalability is not supported\n"); - return MPP_NOK; - } - } else { /* mp4Hdr->shape == BINARY_ONLY */ - mpp_err("shape %d is not supported\n"); - return MPP_NOK; - } - - return MPP_OK; - -__BITREAD_ERR: - return MPP_ERR_STREAM; -} - -static MPP_RET mpg4d_parse_user_data(Mpg4dParserImpl *p, BitReadCtx_t *gb) -{ - RK_U8 tmp[256]; - Mpg4Hdr *mp4Hdr = &p->hdr_curr; - RK_U32 remain_bit = gb->bytes_left_ * 8 + gb->num_remaining_bits_in_curr_byte_; - RK_S32 i; - - memset(tmp, 0, 256); - - for (i = 0; i < 256 && gb->bytes_left_; i++) { - RK_U32 show_bit = MPP_MIN(remain_bit, 23); - RK_U32 val; - - SHOW_BITS(gb, show_bit, &val); - if (val == 0) - break; - - READ_BITS(gb, 8, &val); - tmp[i] = val; - remain_bit -= 8; - } - - tmp[i] = 0; - - if (!mp4Hdr->usr.packed_mode) { - RK_U32 packed = 0; - - if ((tmp[0] == 'D') && - (tmp[1] == 'i') && - (tmp[2] == 'v') && - (tmp[3] == 'X')) { - RK_U32 j = 4; - - if (tmp[j] <= '4') { - p->custorm_version = 4; - } else { - p->custorm_version = 5; - } - - while ((tmp[j] >= '0') && - (tmp[j] <= '9')) - j++; - - if (tmp[j] == 'b') { - j++; - - while ((tmp[j] >= '0') && - (tmp[j] <= '9')) - j++; - - packed = tmp[j]; - } else if ((tmp[j + 0] == 'B') && - (tmp[j + 1] == 'u') && - (tmp[j + 2] == 'i') && - (tmp[j + 3] == 'l') && - (tmp[j + 4] == 'd')) { - j += 5; - - while ((tmp[j] >= '0') && (tmp[j] <= '9')) - j++; - - packed = tmp[j]; - } - - mp4Hdr->usr.packed_mode = ((packed == 'p') ? (1) : (0)); - } else { - mp4Hdr->usr.packed_mode = 0; - } - } - - return MPP_OK; - -__BITREAD_ERR: - return MPP_ERR_STREAM; -} - -static MPP_RET mpeg4_parse_gop_header(Mpg4dParserImpl *p, BitReadCtx_t *gb) -{ - (void) p; - RK_S32 hours, minutes, seconds; - - READ_BITS(gb, 5, &hours); - READ_BITS(gb, 6, &minutes); - SKIP_BITS(gb, 1); - READ_BITS(gb, 6, &seconds); - - SKIP_BITS(gb, 1); /* closed_gov */ - SKIP_BITS(gb, 1); /* broken_link */ - - return MPP_OK; - -__BITREAD_ERR: - return MPP_ERR_STREAM; -} - -static MPP_RET mpeg4_parse_profile_level(Mpg4dParserImpl *p, BitReadCtx_t *bc) -{ - READ_BITS(bc, 4, &p->profile); - READ_BITS(bc, 4, &p->level); - mpp_log("mpeg4 stream profile %d level %d\n", p->profile, p->level); - return MPP_OK; - -__BITREAD_ERR: - return MPP_ERR_STREAM; -} - -static MPP_RET mpeg4_parse_vop_header(Mpg4dParserImpl *p, BitReadCtx_t *gb) -{ - RK_U32 val; - RK_U32 time_incr = 0; - RK_S32 time_increment = 0; - Mpg4Hdr *mp4Hdr = &p->hdr_curr; - - READ_BITS(gb, 2, &(mp4Hdr->vop.coding_type)); /* vop_coding_type */ - - READ_BITS(gb, 1, &val); - while (val != 0) { - time_incr++; /* time_base */ - READ_BITS(gb, 1, &val); - } - - SKIP_BITS(gb, 1); - - if (mp4Hdr->vol.time_inc_bits) { - /* vop_time_increment */ - READ_BITS(gb, mp4Hdr->vol.time_inc_bits, &time_increment); - } - - if (mp4Hdr->vop.coding_type != MPEG4_B_VOP) { - mp4Hdr->last_time_base = mp4Hdr->time_base; - mp4Hdr->time_base += time_incr; - mp4Hdr->time = mp4Hdr->time_base * mp4Hdr->vol.time_inc_resolution + time_increment; - mp4Hdr->time_pp = (RK_S32)(mp4Hdr->time - mp4Hdr->last_non_b_time); - mp4Hdr->last_non_b_time = mp4Hdr->time; - } else { - mp4Hdr->time = (mp4Hdr->last_time_base + time_incr) * mp4Hdr->vol.time_inc_resolution + time_increment; - mp4Hdr->time_bp = mp4Hdr->time_pp - (RK_S32)(mp4Hdr->last_non_b_time - mp4Hdr->time); - } - - mp4Hdr->pts = (RK_S64)mp4Hdr->time; - - if (p->use_internal_pts) { - p->pts = mp4Hdr->time; - } - - SKIP_BITS(gb, 1); - - READ_BITS(gb, 1, &val); - if (!val) { /* vop_coded */ - mp4Hdr->vop.coding_type = MPEG4_N_VOP; - mpg4d_dbg_result("found N frame\n"); - return MPP_OK; - } - /* do coding_type detection here in order to save time_bp / time_pp */ - if (mp4Hdr->vop.coding_type == MPEG4_B_VOP && - (p->hdr_ref0.slot_idx == -1 || p->hdr_ref1.slot_idx == -1)) { - mpg4d_dbg_result("MPEG4 DIVX 5 PBBI case found!\n"); - return MPP_NOK; - } - if (mp4Hdr->vop.coding_type == MPEG4_I_VOP) - p->found_i_vop = 1; - - if (mp4Hdr->vol.newpred_enable) { - RK_S32 vop_id; - RK_S32 vop_id_for_prediction; - - READ_BITS(gb, (MPP_MIN(mp4Hdr->vol.time_inc_bits + 3, 15)), &vop_id); - - READ_BITS(gb, 1, &val); - if (val) { - /* vop_id_for_prediction_indication */ - READ_BITS(gb, MPP_MIN(mp4Hdr->vol.time_inc_bits + 3, 15), &vop_id_for_prediction); - } - - SKIP_BITS(gb, 1); - } - - if ((mp4Hdr->vol.shape != MPEG4_VIDOBJLAY_SHAPE_BINARY_ONLY) && - ((mp4Hdr->vop.coding_type == MPEG4_P_VOP) || - (mp4Hdr->vop.coding_type == MPEG4_S_VOP && - mp4Hdr->vol.sprite_enable == MPEG4_SPRITE_GMC))) { - READ_BITS(gb, 1, &(mp4Hdr->vop.rounding)); /* rounding_type */ - } - - if (mp4Hdr->vol.reduced_resolution_enable && - mp4Hdr->vol.shape == MPEG4_VIDOBJLAY_SHAPE_RECTANGULAR && - (mp4Hdr->vop.coding_type == MPEG4_P_VOP || mp4Hdr->vop.coding_type == MPEG4_I_VOP)) { - - READ_BITS(gb, 1, &val); - } - - mpp_assert(mp4Hdr->vol.shape == MPEG4_VIDOBJLAY_SHAPE_RECTANGULAR); - - if (mp4Hdr->vol.shape != MPEG4_VIDOBJLAY_SHAPE_BINARY_ONLY) { - if (!mp4Hdr->vol.complexity_estimation_disable) { - read_vop_complexity_estimation_header(&p->estimation, gb, mp4Hdr, mp4Hdr->vop.coding_type); - } - - READ_BITS(gb, 3, &val); - /* intra_dc_vlc_threshold */ - mp4Hdr->vop.intra_dc_vlc_threshold = val; - mp4Hdr->vop.top_field_first = 0; - mp4Hdr->vop.alternate_vertical_scan = 0; - - if (mp4Hdr->vol.interlacing) { - READ_BITS(gb, 1, &(mp4Hdr->vop.top_field_first)); - READ_BITS(gb, 1, &(mp4Hdr->vop.alternate_vertical_scan)); - } - } - - if ((mp4Hdr->vol.sprite_enable == MPEG4_SPRITE_STATIC || - mp4Hdr->vol.sprite_enable == MPEG4_SPRITE_GMC) && - mp4Hdr->vop.coding_type == MPEG4_S_VOP) { - mpp_err("unsupport split mode %d coding type %d\n", - mp4Hdr->vol.sprite_enable, mp4Hdr->vop.coding_type); - return MPP_ERR_STREAM; - } - - READ_BITS(gb, mp4Hdr->vol.quant_bits, &(mp4Hdr->vop.quant)); - if (mp4Hdr->vop.quant < 1) /* vop_quant */ - mp4Hdr->vop.quant = 1; - - if (mp4Hdr->vop.coding_type != MPEG4_I_VOP) { - READ_BITS(gb, 3, &(mp4Hdr->vop.fcode_forward)); /* fcode_forward */ - } - - if (mp4Hdr->vop.coding_type == MPEG4_B_VOP) { - READ_BITS(gb, 3, &(mp4Hdr->vop.fcode_backward)); /* fcode_backward */ - } - - if (!mp4Hdr->vol.scalability) { - if ((mp4Hdr->vol.shape != MPEG4_VIDOBJLAY_SHAPE_RECTANGULAR) && - (mp4Hdr->vop.coding_type != MPEG4_I_VOP)) { - SKIP_BITS(gb, 1); /* vop_shape_coding_type */ - } - } - - // NOTE: record header used bits here - mp4Hdr->vop.hdr_bits = gb->used_bits; - - return MPP_OK; -__BITREAD_ERR: - return MPP_ERR_STREAM; -} - -static void mpg4d_fill_picture_parameters(const Mpg4dParserImpl *p, - DXVA_PicParams_MPEG4_PART2 *pp) -{ - const Mpg4Hdr *hdr_curr = &p->hdr_curr; - const Mpg4Hdr *hdr_ref0 = &p->hdr_ref0; - const Mpg4Hdr *hdr_ref1 = &p->hdr_ref1; - - pp->short_video_header = 0; - pp->vop_coding_type = hdr_curr->vop.coding_type; - pp->vop_quant = hdr_curr->vop.quant; - pp->wDecodedPictureIndex = hdr_curr->slot_idx; - pp->wForwardRefPictureIndex = hdr_ref0->slot_idx; - pp->wBackwardRefPictureIndex = hdr_ref1->slot_idx; - pp->vop_time_increment_resolution = hdr_curr->vol.time_inc_resolution; - pp->TRB[0] = 0; /* FIXME: */ - pp->TRD[0] = 0; /* FIXME: */ - pp->unPicPostProc = 0; /* FIXME: */ - pp->interlaced = hdr_curr->vol.interlacing; - pp->quant_type = hdr_curr->vol.quant_type; - pp->quarter_sample = hdr_curr->vol.quarter_sample; - pp->resync_marker_disable = 0; /* FIXME: */ - pp->data_partitioned = 0; /* FIXME: */ - pp->reversible_vlc = 0; /* FIXME: */ - pp->reduced_resolution_vop_enable = hdr_curr->vol.reduced_resolution_enable; - pp->vop_coded = (hdr_curr->vop.coding_type != MPEG4_N_VOP); - pp->vop_rounding_type = hdr_curr->vop.rounding; - pp->intra_dc_vlc_thr = hdr_curr->vop.intra_dc_vlc_threshold; - pp->top_field_first = hdr_curr->vop.top_field_first; - pp->alternate_vertical_scan_flag = hdr_curr->vop.alternate_vertical_scan; - pp->profile_and_level_indication = (p->profile << 4) | p->level; - pp->video_object_layer_verid = hdr_curr->vol.ver_id; - pp->vop_width = hdr_curr->vol.width; - pp->vop_height = hdr_curr->vol.height; - pp->sprite_enable = hdr_curr->vol.sprite_enable; - pp->no_of_sprite_warping_points = 0; /* FIXME: */ - pp->sprite_warping_accuracy = 0; /* FIXME: */ - memset(pp->warping_mv, 0, sizeof(pp->warping_mv)); - pp->vop_fcode_forward = hdr_curr->vop.fcode_forward; - pp->vop_fcode_backward = hdr_curr->vop.fcode_backward; - pp->StatusReportFeedbackNumber = 0; /* FIXME: */ - pp->Reserved16BitsA = 0; /* FIXME: */ - pp->Reserved16BitsB = 0; /* FIXME: */ - - // Rockchip special data - pp->custorm_version = p->custorm_version; - pp->prev_coding_type = (hdr_ref0->vop.coding_type == MPEG4_INVALID_VOP) ? (0) : (hdr_ref0->vop.coding_type); - pp->time_bp = hdr_curr->time_bp; - pp->time_pp = hdr_curr->time_pp; - pp->header_bits = hdr_curr->vop.hdr_bits; -} - -static void mpg4d_fill_quantization_matrices(const Mpg4dParserImpl *p, - DXVA_QmatrixData *qm) -{ - RK_S32 i = 0; - - qm->bNewQmatrix[0] = p->new_qm[0]; - qm->bNewQmatrix[1] = p->new_qm[1]; - qm->bNewQmatrix[2] = 0; - qm->bNewQmatrix[3] = 0; - - // intra Y - if (p->new_qm[0]) { - for (i = 0; i < 64; i++) { - qm->Qmatrix[0][i] = p->quant_matrices[i]; - } - } else { - memset(qm->Qmatrix[0], 0, sizeof(qm->Qmatrix[0])); - } - - // inter Y - if (p->new_qm[1]) { - for (i = 0; i < 64; i++) { - qm->Qmatrix[1][i] = p->quant_matrices[64 + i]; - } - } else { - memset(qm->Qmatrix[1], 0, sizeof(qm->Qmatrix[1])); - } - - memset(qm->Qmatrix[2], 0, sizeof(qm->Qmatrix[2])); - memset(qm->Qmatrix[3], 0, sizeof(qm->Qmatrix[3])); -} - -static void mpg4_syntax_init(mpeg4d_dxva2_picture_context_t *syntax) -{ - DXVA2_DecodeBufferDesc *data = &syntax->desc[0]; - - //!< commit picture paramters - memset(data, 0, sizeof(*data)); - data->CompressedBufferType = DXVA2_PictureParametersBufferType; - data->pvPVPState = (void *)&syntax->pp; - data->DataSize = sizeof(syntax->pp); - syntax->data[0] = data; - - //!< commit Qmatrix - data = &syntax->desc[1]; - memset(data, 0, sizeof(*data)); - data->CompressedBufferType = DXVA2_InverseQuantizationMatrixBufferType; - data->pvPVPState = (void *)&syntax->qm; - data->DataSize = sizeof(syntax->qm); - data->NumMBsInBuffer = 0; - syntax->data[1] = data; - - //!< commit bitstream - data = &syntax->desc[2]; - memset(data, 0, sizeof(*data)); - data->CompressedBufferType = DXVA2_BitStreamDateBufferType; - syntax->data[2] = data; -} - -MPP_RET mpp_mpg4_parser_init(Mpg4dParser *ctx, MppBufSlots frame_slots) -{ - BitReadCtx_t *bit_ctx = mpp_calloc(BitReadCtx_t, 1); - Mpg4dParserImpl *p = mpp_calloc(Mpg4dParserImpl, 1); - mpeg4d_dxva2_picture_context_t *syntax = mpp_calloc(mpeg4d_dxva2_picture_context_t, 1); - - if (NULL == p || NULL == bit_ctx || NULL == syntax) { - mpp_err_f("malloc context failed\n"); - if (p) - mpp_free(p); - if (bit_ctx) - mpp_free(bit_ctx); - if (syntax) - mpp_free(syntax); - return MPP_NOK; - } - - mpg4d_dbg_func("in\n"); - - mpp_buf_slot_setup(frame_slots, 8); - p->frame_slots = frame_slots; - p->use_internal_pts = 0; - p->pos_frm_start = -1; - p->pos_frm_end = -1; - p->bit_ctx = bit_ctx; - init_mpg4_header(&p->hdr_curr); - init_mpg4_header(&p->hdr_ref0); - init_mpg4_header(&p->hdr_ref1); - mpg4_syntax_init(syntax); - p->syntax = syntax; - - mpp_env_get_u32("mpg4d_debug", &mpg4d_debug, 0); - - mpg4d_dbg_func("out\n"); - - *ctx = p; - return MPP_OK; -} - -MPP_RET mpp_mpg4_parser_deinit(Mpg4dParser ctx) -{ - Mpg4dParserImpl *p = (Mpg4dParserImpl *)ctx; - - mpg4d_dbg_func("in\n"); - - if (p) { - if (p->bit_ctx) { - mpp_free(p->bit_ctx); - p->bit_ctx = NULL; - } - if (p->syntax) { - mpp_free(p->syntax); - p->syntax = NULL; - } - mpp_free(p); - } - - mpg4d_dbg_func("out\n"); - - return MPP_OK; -} - -MPP_RET mpp_mpg4_parser_flush(Mpg4dParser ctx) -{ - Mpg4dParserImpl *p = (Mpg4dParserImpl *)ctx; - MppBufSlots slots = p->frame_slots; - Mpg4Hdr *hdr_ref0 = &p->hdr_ref0; - RK_S32 index = hdr_ref0->slot_idx; - - mpg4d_dbg_func("in\n"); - - if (!hdr_ref0->enqueued && index >= 0) { - mpp_buf_slot_set_flag(slots, index, SLOT_QUEUE_USE); - mpp_buf_slot_enqueue(slots, index, QUEUE_DISPLAY); - hdr_ref0->enqueued = 1; - } - - mpg4d_dbg_func("out\n"); - - return MPP_OK; -} - -MPP_RET mpp_mpg4_parser_reset(Mpg4dParser ctx) -{ - Mpg4dParserImpl *p = (Mpg4dParserImpl *)ctx; - MppBufSlots slots = p->frame_slots; - Mpg4Hdr *hdr_ref0 = &p->hdr_ref0; - Mpg4Hdr *hdr_ref1 = &p->hdr_ref1; - RK_S32 index = hdr_ref0->slot_idx; - - mpg4d_dbg_func("in\n"); - - if (index >= 0) { - if (!hdr_ref0->enqueued) { - mpp_buf_slot_set_flag(slots, index, SLOT_QUEUE_USE); - mpp_buf_slot_enqueue(slots, index, QUEUE_DISPLAY); - hdr_ref0->enqueued = 1; - } - mpp_buf_slot_clr_flag(slots, index, SLOT_CODEC_USE); - hdr_ref0->slot_idx = -1; - } - - index = hdr_ref1->slot_idx; - if (index >= 0) { - mpp_buf_slot_clr_flag(slots, index, SLOT_CODEC_USE); - hdr_ref1->slot_idx = -1; - } - - p->found_i_vop = 0; - p->found_vop = 0; - - mpg4d_dbg_func("out\n"); - - return MPP_OK; -} - -MPP_RET mpp_mpg4_parser_split(Mpg4dParser ctx, MppPacket dst, MppPacket src) -{ - MPP_RET ret = MPP_NOK; - Mpg4dParserImpl *p = (Mpg4dParserImpl *)ctx; - RK_U8 *dst_buf = mpp_packet_get_data(dst); - size_t dst_len = mpp_packet_get_length(dst); - RK_U8 *src_buf = mpp_packet_get_pos(src); - RK_S32 src_len = (RK_S32)mpp_packet_get_length(src); - RK_S32 pos_frm_start = p->pos_frm_start; - RK_S32 pos_frm_end = p->pos_frm_end; - RK_U32 src_eos = mpp_packet_get_eos(src); - RK_S32 src_pos = 0; - RK_U32 state = (RK_U32) - 1; - - mpg4d_dbg_func("in\n"); - - mpp_assert(src_len); - - if (dst_len) { - mpp_assert(dst_len >= 4); - state = ((RK_U32)(dst_buf[dst_len - 1]) << 0) | - ((RK_U32)(dst_buf[dst_len - 2]) << 8) | - ((RK_U32)(dst_buf[dst_len - 3]) << 16) | - ((RK_U32)(dst_buf[dst_len - 4]) << 24); - } - - if (pos_frm_start < 0) { - // scan for frame start - for (src_pos = 0; src_pos < src_len; src_pos++) { - state = (state << 8) | src_buf[src_pos]; - if (state == MPG4_VOP_STARTCODE) { - src_pos++; - pos_frm_start = src_pos - 4; - break; - } - } - } - - if (pos_frm_start >= 0) { - // scan for frame end - for (; src_pos < src_len; src_pos++) { - state = (state << 8) | src_buf[src_pos]; - - if ((state & 0xFFFFFFFF) == MPG4_VOP_STARTCODE) { - pos_frm_end = src_pos - 3; - break; - } - } - if (src_eos && src_pos == src_len) { - pos_frm_end = src_len; - mpp_packet_set_eos(dst); - } - } - - //mpp_log("pkt pos: start %d end %d len: left %d in %d\n", - // pos_frm_start, pos_frm_end, dst_len, src_len); - - if (pos_frm_start < 0 || pos_frm_end < 0) { - // do not found frame start or do not found frame end, just copy the hold buffer to dst - memcpy(dst_buf + dst_len, src_buf, src_len); - // update dst buffer length - mpp_packet_set_length(dst, dst_len + src_len); - // set src buffer pos to end to src buffer - mpp_packet_set_pos(src, src_buf + src_len); - } else { - // found both frame start and frame end - only copy frame - memcpy(dst_buf + dst_len, src_buf, pos_frm_end); - mpp_packet_set_length(dst, dst_len + pos_frm_end); - - // set src buffer pos to end to src buffer - mpp_packet_set_pos(src, src_buf + pos_frm_end); - mpp_assert((RK_S32)mpp_packet_get_length(src) == (src_len - pos_frm_end)); - mpp_packet_set_length(src, src_len - pos_frm_end); - - // return ok indicate the frame is ready and reset frame start/end position - ret = MPP_OK; - pos_frm_start = -1; - pos_frm_end = -1; - } - - p->pos_frm_start = pos_frm_start; - p->pos_frm_end = pos_frm_end; - - mpg4d_dbg_func("out\n"); - - return ret; -} - -MPP_RET mpp_mpg4_parser_decode(Mpg4dParser ctx, MppPacket pkt) -{ - MPP_RET ret = MPP_OK; - Mpg4dParserImpl *p = (Mpg4dParserImpl *)ctx; - BitReadCtx_t *gb = p->bit_ctx; - RK_U8 *buf = mpp_packet_get_data(pkt); - RK_S32 len = (RK_S32)mpp_packet_get_length(pkt); - RK_U32 startcode = 0xff; - - mpg4d_dbg_func("in\n"); - - // setup bit read context - mpp_set_bitread_ctx(gb, buf, len); - p->found_vop = 0; - - while (gb->bytes_left_) { - RK_U32 val = 0; - - READ_BITS(gb, 8, &val); - startcode = (startcode << 8) | val; - - if ((startcode & 0xFFFFFF00) != 0x100) - continue; - - mpg4d_dbg_bit("found startcode at byte %d\n", gb->used_bits >> 3); - - if (mpg4d_debug & MPG4D_DBG_STARTCODE) { - mpp_log_f("start code %03x\n", startcode); - if (startcode <= 0x11F) - mpp_log_f("Video Object Start"); - else if (startcode <= 0x12F) - mpp_log_f("Video Object Layer Start"); - else if (startcode <= 0x13F) - mpp_log_f("Reserved"); - else if (startcode <= 0x15F) - mpp_log_f("FGS bp start"); - else if (startcode <= 0x1AF) - mpp_log_f("Reserved"); - else if (startcode == 0x1B0) - mpp_log_f("Visual Object Seq Start"); - else if (startcode == 0x1B1) - mpp_log_f("Visual Object Seq End"); - else if (startcode == 0x1B2) - mpp_log_f("User Data"); - else if (startcode == 0x1B3) - mpp_log_f("Group of VOP start"); - else if (startcode == 0x1B4) - mpp_log_f("Video Session Error"); - else if (startcode == 0x1B5) - mpp_log_f("Visual Object Start"); - else if (startcode == 0x1B6) - mpp_log_f("Video Object Plane start"); - else if (startcode == 0x1B7) - mpp_log_f("slice start"); - else if (startcode == 0x1B8) - mpp_log_f("extension start"); - else if (startcode == 0x1B9) - mpp_log_f("fgs start"); - else if (startcode == 0x1BA) - mpp_log_f("FBA Object start"); - else if (startcode == 0x1BB) - mpp_log_f("FBA Object Plane start"); - else if (startcode == 0x1BC) - mpp_log_f("Mesh Object start"); - else if (startcode == 0x1BD) - mpp_log_f("Mesh Object Plane start"); - else if (startcode == 0x1BE) - mpp_log_f("Still Texture Object start"); - else if (startcode == 0x1BF) - mpp_log_f("Texture Spatial Layer start"); - else if (startcode == 0x1C0) - mpp_log_f("Texture SNR Layer start"); - else if (startcode == 0x1C1) - mpp_log_f("Texture Tile start"); - else if (startcode == 0x1C2) - mpp_log_f("Texture Shape Layer start"); - else if (startcode == 0x1C3) - mpp_log_f("stuffing start"); - else if (startcode <= 0x1C5) - mpp_log_f("reserved"); - else if (startcode <= 0x1FF) - mpp_log_f("System start"); - } - - if (startcode >= MPG4_VOL_STARTCODE && startcode <= MPG4_VOL_STOPCODE) { - ret = mpg4d_parse_vol_header(p, gb); - if (!p->found_vol) - p->found_vol = (ret == MPP_OK); - } else if (startcode == MPG4_USER_DATA_STARTCODE) { - ret = mpg4d_parse_user_data(p, gb); - } else if (startcode == MPG4_GOP_STARTCODE) { - ret = mpeg4_parse_gop_header(p, gb); - } else if (startcode == MPG4_VOS_STARTCODE) { - ret = mpeg4_parse_profile_level(p, gb); - } else if (startcode == MPG4_VOP_STARTCODE) { - ret = mpeg4_parse_vop_header(p, gb); - if (MPP_OK == ret) { - RK_S32 coding_type = p->hdr_curr.vop.coding_type; - mpg4d_dbg_bit("frame %d coding_type %d\n", p->frame_num, coding_type); - p->frame_num++; - - if (coding_type == MPEG4_N_VOP) { - ret = MPP_OK; - mpp_align_get_bits(gb); - continue; - } - - p->found_vop = p->found_i_vop; - } - } - - if (ret) - goto __BITREAD_ERR; - - mpp_align_get_bits(gb); - - if (p->found_vol && p->found_vop) - break; - } - - if (p->found_vol) { - mpg4d_dbg_result("found vol w %d h %d\n", p->hdr_curr.vol.width, p->hdr_curr.vol.height); - p->width = p->hdr_curr.vol.width; - p->height = p->hdr_curr.vol.height; - } - - if (!p->use_internal_pts) - p->pts = mpp_packet_get_pts(pkt); - - ret = (p->found_vol && p->found_vop) ? (MPP_OK) : (MPP_NOK); - -__BITREAD_ERR: - mpg4d_dbg_result("found vol %d vop %d ret %d\n", p->found_vol, p->found_vop, ret); - - if (ret) { - mpp_packet_set_pos(pkt, buf); - mpp_packet_set_length(pkt, 0); - } else { - RK_U32 used_bytes = gb->used_bits >> 3; - mpp_packet_set_pos(pkt, buf + used_bytes); - } - - p->eos = mpp_packet_get_eos(pkt); - - mpg4d_dbg_func("out\n"); - - return ret; -} - -MPP_RET mpp_mpg4_parser_setup_syntax(Mpg4dParser ctx, MppSyntax *syntax) -{ - Mpg4dParserImpl *p = (Mpg4dParserImpl *)ctx; - mpeg4d_dxva2_picture_context_t *syn = p->syntax; - - mpg4d_dbg_func("in\n"); - - mpg4d_fill_picture_parameters(p, &syn->pp); - mpg4d_fill_quantization_matrices(p, &syn->qm); - - // fill bit stream parameter - syn->data[2]->DataSize = p->bit_ctx->buf_len; - syn->data[2]->DataOffset = p->hdr_curr.vop.hdr_bits; - syn->data[2]->pvPVPState = p->bit_ctx->buf; - - syntax->number = 3; - syntax->data = syn->data; - - mpg4d_dbg_func("out\n"); - - return MPP_OK; -} - -MPP_RET mpp_mpg4_parser_setup_hal_output(Mpg4dParser ctx, RK_S32 *output) -{ - Mpg4dParserImpl *p = (Mpg4dParserImpl *)ctx; - Mpg4Hdr *hdr_curr = &p->hdr_curr; - RK_S32 index = -1; - - mpg4d_dbg_func("in\n"); - - if (p->found_i_vop && hdr_curr->vop.coding_type != MPEG4_N_VOP) { - MppBufSlots slots = p->frame_slots; - RK_U32 frame_mode = MPP_FRAME_FLAG_FRAME; - MppFrame frame = NULL; - - mpp_frame_init(&frame); - mpp_frame_set_width(frame, p->width); - mpp_frame_set_height(frame, p->height); - mpp_frame_set_hor_stride(frame, MPP_ALIGN(p->width, 16)); - mpp_frame_set_ver_stride(frame, MPP_ALIGN(p->height, 16)); - - /* - * set slots information - * 1. output index MUST be set - * 2. get unused index for output if needed - * 3. set output index as hal_input - * 4. set frame information to output index - * 5. if one frame can be display, it SHOULD be enqueued to display queue - */ - mpp_buf_slot_get_unused(slots, &index); - mpp_buf_slot_set_flag(slots, index, SLOT_HAL_OUTPUT); - mpp_frame_set_pts(frame, p->pts); - - if (hdr_curr->vol.interlacing) { - frame_mode = MPP_FRAME_FLAG_PAIRED_FIELD; - if (hdr_curr->vop.top_field_first) - frame_mode |= MPP_FRAME_FLAG_TOP_FIRST; - else - frame_mode |= MPP_FRAME_FLAG_BOT_FIRST; - } - mpp_frame_set_mode(frame, frame_mode); - - mpp_buf_slot_set_prop(slots, index, SLOT_FRAME, frame); - mpp_frame_deinit(&frame); - mpp_assert(NULL == frame); - - hdr_curr->slot_idx = index; - } - - p->output = index; - *output = index; - - mpg4d_dbg_func("out\n"); - - return MPP_OK; -} - -MPP_RET mpp_mpg4_parser_setup_refer(Mpg4dParser ctx, RK_S32 *refer, RK_S32 max_ref) -{ - Mpg4dParserImpl *p = (Mpg4dParserImpl *)ctx; - Mpg4Hdr *hdr_curr = &p->hdr_curr; - MppBufSlots slots = p->frame_slots; - RK_S32 index; - - mpg4d_dbg_func("in\n"); - - memset(refer, -1, sizeof(max_ref * sizeof(*refer))); - if (hdr_curr->vop.coding_type != MPEG4_N_VOP) { - index = p->hdr_ref0.slot_idx; - if (index >= 0) { - mpp_buf_slot_set_flag(slots, index, SLOT_HAL_INPUT); - refer[0] = index; - } - index = p->hdr_ref1.slot_idx; - if (index >= 0) { - mpp_buf_slot_set_flag(slots, index, SLOT_HAL_INPUT); - refer[1] = index; - } - } - - mpg4d_dbg_func("out\n"); - - return MPP_OK; -} - -MPP_RET mpp_mpg4_parser_update_dpb(Mpg4dParser ctx) -{ - Mpg4dParserImpl *p = (Mpg4dParserImpl *)ctx; - MppBufSlots slots = p->frame_slots; - Mpg4Hdr *hdr_curr = &p->hdr_curr; - Mpg4Hdr *hdr_ref0 = &p->hdr_ref0; - Mpg4Hdr *hdr_ref1 = &p->hdr_ref1; - RK_S32 coding_type = hdr_curr->vop.coding_type; - RK_S32 index = p->output; - - mpg4d_dbg_func("in\n"); - - // update pts increacement - if (p->pts != p->last_pts) - p->pts_inc = p->pts - p->last_pts; - - switch (coding_type) { - case MPEG4_B_VOP : { - mpp_assert((hdr_ref0->slot_idx >= 0) && (hdr_ref1->slot_idx >= 0)); - // B frame -> index current frame - // output current frame and do not change ref0 and ref1 - index = hdr_curr->slot_idx; - mpp_buf_slot_set_flag(slots, index, SLOT_QUEUE_USE); - mpp_buf_slot_enqueue(slots, index, QUEUE_DISPLAY); - } - /* - * NOTE: here fallback to N vop - do nothing - */ - case MPEG4_INVALID_VOP : - case MPEG4_N_VOP : { - } break; - case MPEG4_I_VOP : - case MPEG4_P_VOP : - case MPEG4_S_VOP : - // the other case -> index reference 0 - index = hdr_ref0->slot_idx; - if (!hdr_ref0->enqueued && index >= 0) { - mpp_buf_slot_set_flag(slots, index, SLOT_QUEUE_USE); - mpp_buf_slot_enqueue(slots, index, QUEUE_DISPLAY); - } - // non B frame send this frame to reference queue - mpp_buf_slot_set_flag(slots, hdr_curr->slot_idx, SLOT_CODEC_USE); - - // release ref1 - index = hdr_ref1->slot_idx; - if (index >= 0) - mpp_buf_slot_clr_flag(slots, index, SLOT_CODEC_USE); - - // swap ref0 to ref1, current to ref0 - *hdr_ref1 = *hdr_ref0; - *hdr_ref0 = *hdr_curr; - hdr_curr->pts = 0; - } - - init_mpg4_hdr_vop(hdr_curr); - hdr_curr->slot_idx = -1; - p->last_pts = p->pts; - - mpg4d_dbg_func("out\n"); - - return MPP_OK; -} - -MPP_RET mpp_mpg4_parser_set_pts_mode(Mpg4dParser ctx, RK_U32 use_internal_pts) -{ - Mpg4dParserImpl *p = (Mpg4dParserImpl *)ctx; - - mpg4d_dbg_func("in\n"); - - p->use_internal_pts = use_internal_pts; - - mpg4d_dbg_func("out\n"); - - return MPP_OK; -} - +/* + * + * Copyright 2010 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define MODULE_TAG "mpg4d_parser" + +#include + +#include "mpp_env.h" +#include "mpp_log.h" +#include "mpp_mem.h" +#include "mpp_packet.h" + +#include "mpp_bitread.h" +#include "mpg4d_parser.h" +#include "mpg4d_syntax.h" + + +RK_U32 mpg4d_debug = 0; +#define mpg4d_dbg(flag, fmt, ...) _mpp_dbg(mpg4d_debug, flag, fmt, ## __VA_ARGS__) +#define mpg4d_dbg_f(flag, fmt, ...) _mpp_dbg_f(mpg4d_debug, flag, fmt, ## __VA_ARGS__) + +#define mpg4d_dbg_func(fmt, ...) mpg4d_dbg_f(MPG4D_DBG_FUNCTION, fmt, ## __VA_ARGS__) +#define mpg4d_dbg_bit(fmt, ...) mpg4d_dbg(MPG4D_DBG_BITS, fmt, ## __VA_ARGS__) +#define mpg4d_dbg_result(fmt, ...) mpg4d_dbg(MPG4D_DBG_RESULT, fmt, ## __VA_ARGS__) + +#define MPEG4_VIDOBJ_START_CODE 0x00000100 /* ..0x0000011f */ +#define MPEG4_VIDOBJLAY_START_CODE 0x00000120 /* ..0x0000012f */ +#define MPEG4_VISOBJSEQ_START_CODE 0x000001b0 +#define MPEG4_VISOBJSEQ_STOP_CODE 0x000001b1 +#define MPEG4_USERDATA_START_CODE 0x000001b2 +#define MPEG4_GRPOFVOP_START_CODE 0x000001b3 +#define MPEG4_VISOBJ_START_CODE 0x000001b5 +#define MPEG4_VOP_START_CODE 0x000001b6 + +#define MPG4_VOL_STARTCODE 0x120 +#define MPG4_VOL_STOPCODE 0x12F +#define MPG4_VOS_STARTCODE 0x1B0 +#define MPG4_VOS_STOPCODE 0x1B1 +#define MPG4_USER_DATA_STARTCODE 0x1B2 +#define MPG4_GOP_STARTCODE 0x1B3 +#define MPG4_VISUAL_OBJ_STARTCODE 0x1B5 +#define MPG4_VOP_STARTCODE 0x1B6 + +typedef struct { + RK_S32 method; + + RK_S32 opaque; + RK_S32 transparent; + RK_S32 intra_cae; + RK_S32 inter_cae; + RK_S32 no_update; + RK_S32 upsampling; + + RK_S32 intra_blocks; + RK_S32 inter_blocks; + RK_S32 inter4v_blocks; + RK_S32 gmc_blocks; + RK_S32 not_coded_blocks; + + RK_S32 dct_coefs; + RK_S32 dct_lines; + RK_S32 vlc_symbols; + RK_S32 vlc_bits; + + RK_S32 apm; + RK_S32 npm; + RK_S32 interpolate_mc_q; + RK_S32 forw_back_mc_q; + RK_S32 halfpel2; + RK_S32 halfpel4; + + RK_S32 sadct; + RK_S32 quarterpel; +} Mpeg4Estimation; + +typedef struct Mp4HdrVol_t { + RK_S32 vo_type; + RK_U32 low_delay; + RK_U32 shape; + RK_S32 time_inc_resolution; + RK_U32 time_inc_bits; + RK_S32 width; + RK_S32 height; + RK_U32 mb_width; + RK_U32 mb_height; + RK_S32 hor_stride; + RK_S32 ver_stride; + RK_U32 totalMbInVop; + RK_U32 interlacing; + RK_S32 sprite_enable; + RK_U32 quant_bits; + RK_U32 quant_type; + RK_S32 quarter_sample; + RK_S32 complexity_estimation_disable; + RK_U32 resync_marker_disable; + RK_S32 newpred_enable; + RK_S32 reduced_resolution_enable; + RK_S32 scalability; + RK_S32 ver_id; +} Mp4HdrVol; + +typedef struct Mp4HdrUserData_t { + RK_S32 packed_mode; /* bframes packed bits? (1 = yes) */ +} Mp4HdrUserData; + +typedef struct Mp4HdrVop_t { + RK_S32 coding_type; + RK_U32 frameNumber; + RK_U32 rounding; + RK_U32 intra_dc_vlc_threshold; + RK_U32 top_field_first; + RK_U32 alternate_vertical_scan; + RK_U32 fcode_forward; + RK_U32 fcode_backward; + RK_U32 quant; // OFFSET_OF_QUANT_IN_DEC + RK_U32 hdr_bits; +} Mp4HdrVop; + +typedef struct Mpg4Hdr_t { + // vol parameter + Mp4HdrVol vol; + + // user data parameter + Mp4HdrUserData usr; + + // vop header parameter + Mp4HdrVop vop; + + // frame related parameter + RK_S64 pts; + RK_S32 slot_idx; + RK_U32 enqueued; + + RK_U32 last_time_base; + RK_U32 time_base; + RK_U32 time; + RK_U32 time_pp; + RK_U32 time_bp; + RK_U32 last_non_b_time; +} Mpg4Hdr; + + +typedef struct { + // global paramter + MppBufSlots frame_slots; + RK_U32 use_internal_pts; + RK_U32 found_vol; + RK_U32 found_vop; + RK_U32 found_i_vop; + + // frame size parameter + RK_S32 width; + RK_S32 height; + RK_S32 hor_stride; + RK_S32 ver_stride; + RK_U32 info_change; + RK_U32 eos; + + // spliter parameter + RK_S32 pos_frm_start; // negtive - not found; non-negtive - position of frame start + RK_S32 pos_frm_end; // negtive - not found; non-negtive - position of frame end + + // bit read context + BitReadCtx_t *bit_ctx; + // vos infomation + RK_U32 profile; + RK_U32 level; + RK_U32 custorm_version; + + // commom buffer for header information + /* + * NOTE: We assume that quant matrix only used for current frame decoding + * So we use only one quant matrix buffer and only support + */ + RK_U32 new_qm[2]; // [0] - intra [1] - inter + RK_U8 quant_matrices[128]; // 0-63: intra 64-127: inter + Mpeg4Estimation estimation; + Mpg4Hdr hdr_curr; /* header for current decoding frame */ + Mpg4Hdr hdr_ref0; /* header for reference frame 0 */ + Mpg4Hdr hdr_ref1; /* header for reference frame 1 */ + + // dpb/output information + RK_S32 output; + RK_S64 last_pts; + RK_S64 pts_inc; + RK_S64 pts; + RK_U32 frame_num; + + // syntax for hal + mpeg4d_dxva2_picture_context_t *syntax; +} Mpg4dParserImpl; + +static RK_S32 log2bin(RK_U32 value) +{ + RK_S32 n = 0; + + while (value) { + value >>= 1; + n++; + } + + return n; +} + +static MPP_RET mpg4d_parse_matrix(BitReadCtx_t *gb, RK_U8 * matrix) +{ + RK_S32 i = 0; + RK_S32 last, value = 0; + + do { + last = value; + READ_BITS(gb, 8, &value); + matrix[i++] = value; + } while (value != 0 && i < 64); + + if (value != 0) + return MPP_ERR_STREAM; + + i--; + + while (i < 64) { + matrix[i++ ] = last; + } + + return MPP_OK; + +__BITREAD_ERR: + return MPP_ERR_STREAM; +} + +static void mpg4d_set_intra_matrix(RK_U8 * quant_matrices, RK_U8 * matrix) +{ + RK_S32 i; + RK_U8 *intra_matrix = quant_matrices + 0 * 64; + + for (i = 0; i < 64; i++) { + intra_matrix[i] = (!i) ? (RK_U8)8 : (RK_U8)matrix[i]; + } +} + +static void mpg4d_set_inter_matrix(RK_U8 * quant_matrices, RK_U8 * matrix) +{ + RK_S32 i; + RK_U8 *inter_matrix = quant_matrices + 1 * 64; + + for (i = 0; i < 64; i++) { + inter_matrix[i] = (RK_U8) (matrix[i]); + } +} + +static MPP_RET read_vol_complexity_estimation_header(Mpeg4Estimation *e, BitReadCtx_t *gb) +{ + RK_U32 val; + + READ_BITS(gb, 2, &(e->method)); /* estimation_method */ + + if (e->method == 0 || e->method == 1) { + READ_BITS(gb, 1, &val); + if (!val) { /* shape_complexity_estimation_disable */ + READ_BITS(gb, 1, &(e->opaque)); /* opaque */ + READ_BITS(gb, 1, &(e->transparent)); /* transparent */ + READ_BITS(gb, 1, &(e->intra_cae)); /* intra_cae */ + READ_BITS(gb, 1, &(e->inter_cae)); /* inter_cae */ + READ_BITS(gb, 1, &(e->no_update)); /* no_update */ + READ_BITS(gb, 1, &(e->upsampling)); /* upsampling */ + } + + READ_BITS(gb, 1, &val); + if (!val) { /* texture_complexity_estimation_set_1_disable */ + READ_BITS(gb, 1, &(e->intra_blocks)); /* intra_blocks */ + READ_BITS(gb, 1, &(e->inter_blocks)); /* inter_blocks */ + READ_BITS(gb, 1, &(e->inter4v_blocks)); /* inter4v_blocks */ + READ_BITS(gb, 1, &(e->not_coded_blocks)); /* not_coded_blocks */ + } + } + + SKIP_BITS(gb, 1); + + READ_BITS(gb, 1, &val); + if (!val) { /* texture_complexity_estimation_set_2_disable */ + READ_BITS(gb, 1, &(e->dct_coefs)); /* dct_coefs */ + READ_BITS(gb, 1, &(e->dct_lines)); /* dct_lines */ + READ_BITS(gb, 1, &(e->vlc_symbols)); /* vlc_symbols */ + READ_BITS(gb, 1, &(e->vlc_bits)); /* vlc_bits */ + } + + READ_BITS(gb, 1, &val); + if (!val) { /* motion_compensation_complexity_disable */ + READ_BITS(gb, 1, &(e->apm)); /* apm */ + READ_BITS(gb, 1, &(e->npm)); /* npm */ + READ_BITS(gb, 1, &(e->interpolate_mc_q)); /* interpolate_mc_q */ + READ_BITS(gb, 1, &(e->forw_back_mc_q)); /* forw_back_mc_q */ + READ_BITS(gb, 1, &(e->halfpel2)); /* halfpel2 */ + READ_BITS(gb, 1, &(e->halfpel4)); /* halfpel4 */ + } + + SKIP_BITS(gb, 1); + + if (e->method == 1) { + READ_BITS(gb, 1, &val); + if (!val) { /* version2_complexity_estimation_disable */ + READ_BITS(gb, 1, &(e->sadct)); /* sadct */ + READ_BITS(gb, 1, &(e->quarterpel)); /* quarterpel */ + } + } + + return MPP_OK; + +__BITREAD_ERR: + return MPP_ERR_STREAM; +} + +/* vop estimation header */ +static MPP_RET read_vop_complexity_estimation_header(Mpeg4Estimation *e, BitReadCtx_t *gb, Mpg4Hdr *mp4Hdr, int coding_type) +{ + if (e->method == 0 || e->method == 1) { + if (coding_type == MPEG4_I_VOP) { + if (e->opaque) SKIP_BITS(gb, 8); /* dcecs_opaque */ + if (e->transparent) SKIP_BITS(gb, 8); /* */ + if (e->intra_cae) SKIP_BITS(gb, 8); /* */ + if (e->inter_cae) SKIP_BITS(gb, 8); /* */ + if (e->no_update) SKIP_BITS(gb, 8); /* */ + if (e->upsampling) SKIP_BITS(gb, 8); /* */ + if (e->intra_blocks) SKIP_BITS(gb, 8); /* */ + if (e->not_coded_blocks) SKIP_BITS(gb, 8); /* */ + if (e->dct_coefs) SKIP_BITS(gb, 8); /* */ + if (e->dct_lines) SKIP_BITS(gb, 8); /* */ + if (e->vlc_symbols) SKIP_BITS(gb, 8); /* */ + if (e->vlc_bits) SKIP_BITS(gb, 8); /* */ + if (e->sadct) SKIP_BITS(gb, 8); /* */ + } + + if (coding_type == MPEG4_P_VOP) { + if (e->opaque) SKIP_BITS(gb, 8); /* */ + if (e->transparent) SKIP_BITS(gb, 8); /* */ + if (e->intra_cae) SKIP_BITS(gb, 8); /* */ + if (e->inter_cae) SKIP_BITS(gb, 8); /* */ + if (e->no_update) SKIP_BITS(gb, 8); /* */ + if (e->upsampling) SKIP_BITS(gb, 8); /* */ + if (e->intra_blocks) SKIP_BITS(gb, 8); /* */ + if (e->not_coded_blocks) SKIP_BITS(gb, 8); /* */ + if (e->dct_coefs) SKIP_BITS(gb, 8); /* */ + if (e->dct_lines) SKIP_BITS(gb, 8); /* */ + if (e->vlc_symbols) SKIP_BITS(gb, 8); /* */ + if (e->vlc_bits) SKIP_BITS(gb, 8); /* */ + if (e->inter_blocks) SKIP_BITS(gb, 8); /* */ + if (e->inter4v_blocks) SKIP_BITS(gb, 8); /* */ + if (e->apm) SKIP_BITS(gb, 8); /* */ + if (e->npm) SKIP_BITS(gb, 8); /* */ + if (e->forw_back_mc_q) SKIP_BITS(gb, 8); /* */ + if (e->halfpel2) SKIP_BITS(gb, 8); /* */ + if (e->halfpel4) SKIP_BITS(gb, 8); /* */ + if (e->sadct) SKIP_BITS(gb, 8); /* */ + if (e->quarterpel) SKIP_BITS(gb, 8); /* */ + } + + if (coding_type == MPEG4_B_VOP) { + if (e->opaque) SKIP_BITS(gb, 8); /* */ + if (e->transparent) SKIP_BITS(gb, 8); /* */ + if (e->intra_cae) SKIP_BITS(gb, 8); /* */ + if (e->inter_cae) SKIP_BITS(gb, 8); /* */ + if (e->no_update) SKIP_BITS(gb, 8); /* */ + if (e->upsampling) SKIP_BITS(gb, 8); /* */ + if (e->intra_blocks) SKIP_BITS(gb, 8); /* */ + if (e->not_coded_blocks) SKIP_BITS(gb, 8); /* */ + if (e->dct_coefs) SKIP_BITS(gb, 8); /* */ + if (e->dct_lines) SKIP_BITS(gb, 8); /* */ + if (e->vlc_symbols) SKIP_BITS(gb, 8); /* */ + if (e->vlc_bits) SKIP_BITS(gb, 8); /* */ + if (e->inter_blocks) SKIP_BITS(gb, 8); /* */ + if (e->inter4v_blocks) SKIP_BITS(gb, 8); /* */ + if (e->apm) SKIP_BITS(gb, 8); /* */ + if (e->npm) SKIP_BITS(gb, 8); /* */ + if (e->forw_back_mc_q) SKIP_BITS(gb, 8); /* */ + if (e->halfpel2) SKIP_BITS(gb, 8); /* */ + if (e->halfpel4) SKIP_BITS(gb, 8); /* */ + if (e->interpolate_mc_q) SKIP_BITS(gb, 8); /* */ + if (e->sadct) SKIP_BITS(gb, 8); /* */ + if (e->quarterpel) SKIP_BITS(gb, 8); /* */ + } + +#ifdef GMC_SUPPORT + if (coding_type == MPEG4_S_VOP && mp4Hdr->vol.sprite_enable == MPEG4_SPRITE_STATIC) { + if (e->intra_blocks) SKIP_BITS(gb, 8); /* */ + if (e->not_coded_blocks) SKIP_BITS(gb, 8); /* */ + if (e->dct_coefs) SKIP_BITS(gb, 8); /* */ + if (e->dct_lines) SKIP_BITS(gb, 8); /* */ + if (e->vlc_symbols) SKIP_BITS(gb, 8); /* */ + if (e->vlc_bits) SKIP_BITS(gb, 8); /* */ + if (e->inter_blocks) SKIP_BITS(gb, 8); /* */ + if (e->inter4v_blocks) SKIP_BITS(gb, 8); /* */ + if (e->apm) SKIP_BITS(gb, 8); /* */ + if (e->npm) SKIP_BITS(gb, 8); /* */ + if (e->forw_back_mc_q) SKIP_BITS(gb, 8); /* */ + if (e->halfpel2) SKIP_BITS(gb, 8); /* */ + if (e->halfpel4) SKIP_BITS(gb, 8); /* */ + if (e->interpolate_mc_q) SKIP_BITS(gb, 8); /* */ + } +#else + (void)mp4Hdr; +#endif + } + + return MPP_OK; + +__BITREAD_ERR: + return MPP_ERR_STREAM; +} + +static void init_mpg4_hdr_vol(Mpg4Hdr *header) +{ + memset(&header->vol, 0, sizeof(header->vol)); + header->vol.ver_id = 1; +} + +static void init_mpg4_hdr_vop(Mpg4Hdr *header) +{ + memset(&header->vop, 0, sizeof(header->vop)); + header->vop.coding_type = MPEG4_INVALID_VOP; +} + +static void init_mpg4_header(Mpg4Hdr *header) +{ + init_mpg4_hdr_vol(header); + header->usr.packed_mode = 0; + init_mpg4_hdr_vop(header); + header->pts = 0; + header->slot_idx = -1; + header->enqueued = 0; +} + +static MPP_RET mpg4d_parse_vol_header(Mpg4dParserImpl *p, BitReadCtx_t *cb) +{ + RK_U32 val = 0; + Mpg4Hdr *mp4Hdr = &p->hdr_curr; + RK_S32 vol_ver_id; + RK_S32 aspect_ratio; + RK_S32 vol_control_parameters; + + SKIP_BITS(cb, 1); /* random_accessible_vol */ + READ_BITS(cb, 8, &(mp4Hdr->vol.vo_type), "vo_type"); + + READ_BITS(cb, 1, &val, "is_object_layer_identifier"); + if (val) { + READ_BITS(cb, 4, &vol_ver_id, "video_object_layer_verid"); + SKIP_BITS(cb, 3); /* video_object_layer_priority */ + } else { + vol_ver_id = mp4Hdr->vol.ver_id; + } + + READ_BITS(cb, 4, &aspect_ratio); + + if (aspect_ratio == MPEG4_VIDOBJLAY_AR_EXTPAR) { /* aspect_ratio_info */ + RK_S32 par_width, par_height; + + READ_BITS(cb, 8, &par_width); /* par_width */ + READ_BITS(cb, 8, &par_height); /* par_height */ + } + + READ_BITS(cb, 1, &vol_control_parameters); + + if (vol_control_parameters) { /* vol_control_parameters */ + SKIP_BITS(cb, 2); /* chroma_format */ + READ_BITS(cb, 1, &(mp4Hdr->vol.low_delay)); /* low_delay flage (1 means no B_VOP) */ + + READ_BITS(cb, 1, &val, "vbv_parameters"); + if (val) { + RK_U32 bitrate; + RK_U32 buffer_size; + RK_U32 occupancy; + + READ_BITS(cb, 15, &val, "first_half_bit_rate"); + bitrate = val << 15; + SKIP_BITS(cb, 1); + READ_BITS(cb, 15, &val, "latter_half_bit_rate"); + bitrate |= val; + SKIP_BITS(cb, 1); + + READ_BITS(cb, 15, &val, "first_half_vbv_buffer_size"); + buffer_size = val << 3; + SKIP_BITS(cb, 1); + READ_BITS(cb, 3, &val); + buffer_size |= val; /* latter_half_vbv_buffer_size */ + + READ_BITS(cb, 11, &val); + occupancy = val << 15; /* first_half_vbv_occupancy */ + SKIP_BITS(cb, 1); + READ_BITS(cb, 15, &val); + occupancy |= val; /* latter_half_vbv_occupancy */ + SKIP_BITS(cb, 1); + } + } else { + mp4Hdr->vol.low_delay = 0; + } + + if (mp4Hdr->vol.vo_type == 0 && vol_control_parameters == 0 && mp4Hdr->vop.frameNumber == 0) { + mpp_log("looks like this file was encoded with (divx4/(old)xvid/opendivx)\n"); + return MPP_NOK; + } + + READ_BITS(cb, 2, &(mp4Hdr->vol.shape)); /* video_object_layer_shape */ + + if (mp4Hdr->vol.shape != MPEG4_VIDOBJLAY_SHAPE_RECTANGULAR) { + mpp_log("unsupported shape %d\n", mp4Hdr->vol.shape); + return MPP_NOK; + } + + if (mp4Hdr->vol.shape == MPEG4_VIDOBJLAY_SHAPE_GRAYSCALE && vol_ver_id != 1) { + SKIP_BITS(cb, 4); /* video_object_layer_shape_extension */ + } + + SKIP_BITS(cb, 1); + + READ_BITS(cb, 16, &(mp4Hdr->vol.time_inc_resolution)); /* vop_time_increment_resolution */ + + if (mp4Hdr->vol.time_inc_resolution > 0) { + mp4Hdr->vol.time_inc_bits = MPP_MAX(log2bin(mp4Hdr->vol.time_inc_resolution - 1), 1); + } else { + /* for "old" xvid compatibility, set time_inc_bits = 1 */ + mp4Hdr->vol.time_inc_bits = 1; + } + + SKIP_BITS(cb, 1); + + READ_BITS(cb, 1, &val); + if (val) { /* fixed_vop_rate */ + SKIP_BITS(cb, mp4Hdr->vol.time_inc_bits); /* fixed_vop_time_increment */ + } + + if (mp4Hdr->vol.shape != MPEG4_VIDOBJLAY_SHAPE_BINARY_ONLY) { + if (mp4Hdr->vol.shape == MPEG4_VIDOBJLAY_SHAPE_RECTANGULAR) { + RK_S32 width, height; + + SKIP_BITS(cb, 1); + READ_BITS(cb, 13, &width); /* video_object_layer_width */ + SKIP_BITS(cb, 1); + READ_BITS(cb, 13, &height); /* video_object_layer_height */ + SKIP_BITS(cb, 1); + + mpg4d_dbg_bit("width %4d height %4d\n", width, height); + + mp4Hdr->vol.width = width; + mp4Hdr->vol.height = height; + mp4Hdr->vol.mb_width = (mp4Hdr->vol.width + 15) >> 4; + mp4Hdr->vol.mb_height = (mp4Hdr->vol.height + 15) >> 4; + mp4Hdr->vol.totalMbInVop = mp4Hdr->vol.mb_width * mp4Hdr->vol.mb_height; + mp4Hdr->vol.hor_stride = 16 * mp4Hdr->vol.mb_width; + mp4Hdr->vol.ver_stride = 16 * mp4Hdr->vol.mb_height; + } + + READ_BITS(cb, 1, &(mp4Hdr->vol.interlacing)); + + READ_BITS(cb, 1, &val); + if (!val) { /* obmc_disable */ + /* TODO */ + /* fucking divx4.02 has this enabled */ + } + + /* sprite_enable */ + READ_BITS(cb, (vol_ver_id == 1 ? 1 : 2), &(mp4Hdr->vol.sprite_enable)); + + if (mp4Hdr->vol.sprite_enable != MPEG4_SPRITE_NONE) { + mpp_err("GMC is not supported\n"); + return MPP_ERR_PROTOL; + } + + if (vol_ver_id != 1 && + mp4Hdr->vol.shape != MPEG4_VIDOBJLAY_SHAPE_RECTANGULAR) { + SKIP_BITS(cb, 1); /* sadct_disable */ + } + + READ_BITS(cb, 1, &val); + if (val) { /* not_8_bit */ + READ_BITS(cb, 4, &(mp4Hdr->vol.quant_bits));/* quant_precision */ + SKIP_BITS(cb, 4); /* bits_per_pixel */ + } else { + mp4Hdr->vol.quant_bits = 5; + } + + if (mp4Hdr->vol.shape == MPEG4_VIDOBJLAY_SHAPE_GRAYSCALE) { + SKIP_BITS(cb, 1); /* no_gray_quant_update */ + SKIP_BITS(cb, 1); /* composition_method */ + SKIP_BITS(cb, 1); /* linear_composition */ + } + + READ_BITS(cb, 1, &(mp4Hdr->vol.quant_type)); /* quant_type */ + + if (mp4Hdr->vol.quant_type) { + RK_U8 matrix[64]; + + READ_BITS(cb, 1, &val); + p->new_qm[0] = val; + if (val) { /* load_intra_quant_mat */ + mpg4d_parse_matrix(cb, matrix); + mpg4d_set_intra_matrix(p->quant_matrices, matrix); + } + + READ_BITS(cb, 1, &val); + p->new_qm[1] = val; + if (val) { /* load_inter_quant_mat */ + mpg4d_parse_matrix(cb, matrix); + mpg4d_set_inter_matrix(p->quant_matrices, matrix); + } + + if (mp4Hdr->vol.shape == MPEG4_VIDOBJLAY_SHAPE_GRAYSCALE) { + mpp_err("SHAPE_GRAYSCALE is not supported\n"); + return MPP_NOK; + } + } else { + p->new_qm[0] = 0; + p->new_qm[1] = 0; + } + + if (vol_ver_id != 1) { + READ_BITS(cb, 1, &(mp4Hdr->vol.quarter_sample), "quarter_sample"); + } else + mp4Hdr->vol.quarter_sample = 0; + + /* complexity estimation disable */ + READ_BITS(cb, 1, &(mp4Hdr->vol.complexity_estimation_disable)); + + if (!mp4Hdr->vol.complexity_estimation_disable) { + mpg4d_dbg_bit("read_vol_complexity_estimation_header\n"); + if (read_vol_complexity_estimation_header(&p->estimation, cb)) + return MPP_ERR_STREAM; + } + + /* resync_marker_disable */ + READ_BITS(cb, 1, &(mp4Hdr->vol.resync_marker_disable)); + if (!mp4Hdr->vol.resync_marker_disable) { + mpp_log("resync marker enabled\n"); + // return MPEG4_RESYNC_VOP; + } + + READ_BITS(cb, 1, &val); + if (val) { /* data_partitioned */ + SKIP_BITS(cb, 1); /* reversible_vlc */ + } + + if (vol_ver_id != 1) { + READ_BITS(cb, 1, &(mp4Hdr->vol.newpred_enable)); + + if (mp4Hdr->vol.newpred_enable) { /* newpred_enable */ + SKIP_BITS(cb, 2); /* requested_upstream_message_type */ + SKIP_BITS(cb, 1); /* newpred_segment_type */ + } + + /* reduced_resolution_vop_enable */ + READ_BITS(cb, 1, &(mp4Hdr->vol.reduced_resolution_enable)); + } else { + mp4Hdr->vol.newpred_enable = 0; + mp4Hdr->vol.reduced_resolution_enable = 0; + } + + READ_BITS(cb, 1, &mp4Hdr->vol.scalability); /* scalability */ + + if (mp4Hdr->vol.scalability) { + SKIP_BITS(cb, 1); /* hierarchy_type */ + SKIP_BITS(cb, 4); /* ref_layer_id */ + SKIP_BITS(cb, 1); /* ref_layer_sampling_direc */ + SKIP_BITS(cb, 5); /* hor_sampling_factor_n */ + SKIP_BITS(cb, 5); /* hor_sampling_factor_m */ + SKIP_BITS(cb, 5); /* vert_sampling_factor_n */ + SKIP_BITS(cb, 5); /* vert_sampling_factor_m */ + SKIP_BITS(cb, 1); /* enhancement_type */ + + if (mp4Hdr->vol.shape == MPEG4_VIDOBJLAY_SHAPE_BINARY /* && hierarchy_type==0 */) { + /* use_ref_shape and so on*/ + SKIP_BITS(cb, ( 1 + 1 + 1 + 5 + 5 + 5 + 5)); + } + + mpp_err("scalability is not supported\n"); + return MPP_NOK; + } + } else { /* mp4Hdr->shape == BINARY_ONLY */ + mpp_err("shape %d is not supported\n"); + return MPP_NOK; + } + + return MPP_OK; + +__BITREAD_ERR: + return MPP_ERR_STREAM; +} + +static MPP_RET mpg4d_parse_user_data(Mpg4dParserImpl *p, BitReadCtx_t *gb) +{ + RK_U8 tmp[256]; + Mpg4Hdr *mp4Hdr = &p->hdr_curr; + RK_U32 remain_bit = gb->bytes_left_ * 8 + gb->num_remaining_bits_in_curr_byte_; + RK_S32 i; + + memset(tmp, 0, 256); + + for (i = 0; i < 256 && gb->bytes_left_; i++) { + RK_U32 show_bit = MPP_MIN(remain_bit, 23); + RK_U32 val; + + SHOW_BITS(gb, show_bit, &val); + if (val == 0) + break; + + READ_BITS(gb, 8, &val); + tmp[i] = val; + remain_bit -= 8; + } + + tmp[i] = 0; + + if (!mp4Hdr->usr.packed_mode) { + RK_U32 packed = 0; + + if ((tmp[0] == 'D') && + (tmp[1] == 'i') && + (tmp[2] == 'v') && + (tmp[3] == 'X')) { + RK_U32 j = 4; + + if (tmp[j] <= '4') { + p->custorm_version = 4; + } else { + p->custorm_version = 5; + } + + while ((tmp[j] >= '0') && + (tmp[j] <= '9')) + j++; + + if (tmp[j] == 'b') { + j++; + + while ((tmp[j] >= '0') && + (tmp[j] <= '9')) + j++; + + packed = tmp[j]; + } else if ((tmp[j + 0] == 'B') && + (tmp[j + 1] == 'u') && + (tmp[j + 2] == 'i') && + (tmp[j + 3] == 'l') && + (tmp[j + 4] == 'd')) { + j += 5; + + while ((tmp[j] >= '0') && (tmp[j] <= '9')) + j++; + + packed = tmp[j]; + } + + mp4Hdr->usr.packed_mode = ((packed == 'p') ? (1) : (0)); + } else { + mp4Hdr->usr.packed_mode = 0; + } + } + + return MPP_OK; + +__BITREAD_ERR: + return MPP_ERR_STREAM; +} + +static MPP_RET mpeg4_parse_gop_header(Mpg4dParserImpl *p, BitReadCtx_t *gb) +{ + (void) p; + RK_S32 hours, minutes, seconds; + + READ_BITS(gb, 5, &hours); + READ_BITS(gb, 6, &minutes); + SKIP_BITS(gb, 1); + READ_BITS(gb, 6, &seconds); + + SKIP_BITS(gb, 1); /* closed_gov */ + SKIP_BITS(gb, 1); /* broken_link */ + + return MPP_OK; + +__BITREAD_ERR: + return MPP_ERR_STREAM; +} + +static MPP_RET mpeg4_parse_profile_level(Mpg4dParserImpl *p, BitReadCtx_t *bc) +{ + READ_BITS(bc, 4, &p->profile); + READ_BITS(bc, 4, &p->level); + mpp_log("mpeg4 stream profile %d level %d\n", p->profile, p->level); + return MPP_OK; + +__BITREAD_ERR: + return MPP_ERR_STREAM; +} + +static MPP_RET mpeg4_parse_vop_header(Mpg4dParserImpl *p, BitReadCtx_t *gb) +{ + RK_U32 val; + RK_U32 time_incr = 0; + RK_S32 time_increment = 0; + Mpg4Hdr *mp4Hdr = &p->hdr_curr; + + READ_BITS(gb, 2, &(mp4Hdr->vop.coding_type)); /* vop_coding_type */ + + READ_BITS(gb, 1, &val); + while (val != 0) { + time_incr++; /* time_base */ + READ_BITS(gb, 1, &val); + } + + SKIP_BITS(gb, 1); + + if (mp4Hdr->vol.time_inc_bits) { + /* vop_time_increment */ + READ_BITS(gb, mp4Hdr->vol.time_inc_bits, &time_increment); + } + + if (mp4Hdr->vop.coding_type != MPEG4_B_VOP) { + mp4Hdr->last_time_base = mp4Hdr->time_base; + mp4Hdr->time_base += time_incr; + mp4Hdr->time = mp4Hdr->time_base * mp4Hdr->vol.time_inc_resolution + time_increment; + mp4Hdr->time_pp = (RK_S32)(mp4Hdr->time - mp4Hdr->last_non_b_time); + mp4Hdr->last_non_b_time = mp4Hdr->time; + } else { + mp4Hdr->time = (mp4Hdr->last_time_base + time_incr) * mp4Hdr->vol.time_inc_resolution + time_increment; + mp4Hdr->time_bp = mp4Hdr->time_pp - (RK_S32)(mp4Hdr->last_non_b_time - mp4Hdr->time); + } + + mp4Hdr->pts = (RK_S64)mp4Hdr->time; + + if (p->use_internal_pts) { + p->pts = mp4Hdr->time; + } + + SKIP_BITS(gb, 1); + + READ_BITS(gb, 1, &val); + if (!val) { /* vop_coded */ + mp4Hdr->vop.coding_type = MPEG4_N_VOP; + mpg4d_dbg_result("found N frame\n"); + return MPP_OK; + } + /* do coding_type detection here in order to save time_bp / time_pp */ + if (mp4Hdr->vop.coding_type == MPEG4_B_VOP && + (p->hdr_ref0.slot_idx == -1 || p->hdr_ref1.slot_idx == -1)) { + mpg4d_dbg_result("MPEG4 DIVX 5 PBBI case found!\n"); + return MPP_NOK; + } + if (mp4Hdr->vop.coding_type == MPEG4_I_VOP) + p->found_i_vop = 1; + + if (mp4Hdr->vol.newpred_enable) { + RK_S32 vop_id; + RK_S32 vop_id_for_prediction; + + READ_BITS(gb, (MPP_MIN(mp4Hdr->vol.time_inc_bits + 3, 15)), &vop_id); + + READ_BITS(gb, 1, &val); + if (val) { + /* vop_id_for_prediction_indication */ + READ_BITS(gb, MPP_MIN(mp4Hdr->vol.time_inc_bits + 3, 15), &vop_id_for_prediction); + } + + SKIP_BITS(gb, 1); + } + + if ((mp4Hdr->vol.shape != MPEG4_VIDOBJLAY_SHAPE_BINARY_ONLY) && + ((mp4Hdr->vop.coding_type == MPEG4_P_VOP) || + (mp4Hdr->vop.coding_type == MPEG4_S_VOP && + mp4Hdr->vol.sprite_enable == MPEG4_SPRITE_GMC))) { + READ_BITS(gb, 1, &(mp4Hdr->vop.rounding)); /* rounding_type */ + } + + if (mp4Hdr->vol.reduced_resolution_enable && + mp4Hdr->vol.shape == MPEG4_VIDOBJLAY_SHAPE_RECTANGULAR && + (mp4Hdr->vop.coding_type == MPEG4_P_VOP || mp4Hdr->vop.coding_type == MPEG4_I_VOP)) { + + READ_BITS(gb, 1, &val); + } + + mpp_assert(mp4Hdr->vol.shape == MPEG4_VIDOBJLAY_SHAPE_RECTANGULAR); + + if (mp4Hdr->vol.shape != MPEG4_VIDOBJLAY_SHAPE_BINARY_ONLY) { + if (!mp4Hdr->vol.complexity_estimation_disable) { + read_vop_complexity_estimation_header(&p->estimation, gb, mp4Hdr, mp4Hdr->vop.coding_type); + } + + READ_BITS(gb, 3, &val); + /* intra_dc_vlc_threshold */ + mp4Hdr->vop.intra_dc_vlc_threshold = val; + mp4Hdr->vop.top_field_first = 0; + mp4Hdr->vop.alternate_vertical_scan = 0; + + if (mp4Hdr->vol.interlacing) { + READ_BITS(gb, 1, &(mp4Hdr->vop.top_field_first)); + READ_BITS(gb, 1, &(mp4Hdr->vop.alternate_vertical_scan)); + } + } + + if ((mp4Hdr->vol.sprite_enable == MPEG4_SPRITE_STATIC || + mp4Hdr->vol.sprite_enable == MPEG4_SPRITE_GMC) && + mp4Hdr->vop.coding_type == MPEG4_S_VOP) { + mpp_err("unsupport split mode %d coding type %d\n", + mp4Hdr->vol.sprite_enable, mp4Hdr->vop.coding_type); + return MPP_ERR_STREAM; + } + + READ_BITS(gb, mp4Hdr->vol.quant_bits, &(mp4Hdr->vop.quant)); + if (mp4Hdr->vop.quant < 1) /* vop_quant */ + mp4Hdr->vop.quant = 1; + + if (mp4Hdr->vop.coding_type != MPEG4_I_VOP) { + READ_BITS(gb, 3, &(mp4Hdr->vop.fcode_forward)); /* fcode_forward */ + } + + if (mp4Hdr->vop.coding_type == MPEG4_B_VOP) { + READ_BITS(gb, 3, &(mp4Hdr->vop.fcode_backward)); /* fcode_backward */ + } + + if (!mp4Hdr->vol.scalability) { + if ((mp4Hdr->vol.shape != MPEG4_VIDOBJLAY_SHAPE_RECTANGULAR) && + (mp4Hdr->vop.coding_type != MPEG4_I_VOP)) { + SKIP_BITS(gb, 1); /* vop_shape_coding_type */ + } + } + + // NOTE: record header used bits here + mp4Hdr->vop.hdr_bits = gb->used_bits; + + return MPP_OK; +__BITREAD_ERR: + return MPP_ERR_STREAM; +} + +static void mpg4d_fill_picture_parameters(const Mpg4dParserImpl *p, + DXVA_PicParams_MPEG4_PART2 *pp) +{ + const Mpg4Hdr *hdr_curr = &p->hdr_curr; + const Mpg4Hdr *hdr_ref0 = &p->hdr_ref0; + const Mpg4Hdr *hdr_ref1 = &p->hdr_ref1; + + pp->short_video_header = 0; + pp->vop_coding_type = hdr_curr->vop.coding_type; + pp->vop_quant = hdr_curr->vop.quant; + pp->wDecodedPictureIndex = hdr_curr->slot_idx; + pp->wForwardRefPictureIndex = hdr_ref0->slot_idx; + pp->wBackwardRefPictureIndex = hdr_ref1->slot_idx; + pp->vop_time_increment_resolution = hdr_curr->vol.time_inc_resolution; + pp->TRB[0] = 0; /* FIXME: */ + pp->TRD[0] = 0; /* FIXME: */ + pp->unPicPostProc = 0; /* FIXME: */ + pp->interlaced = hdr_curr->vol.interlacing; + pp->quant_type = hdr_curr->vol.quant_type; + pp->quarter_sample = hdr_curr->vol.quarter_sample; + pp->resync_marker_disable = 0; /* FIXME: */ + pp->data_partitioned = 0; /* FIXME: */ + pp->reversible_vlc = 0; /* FIXME: */ + pp->reduced_resolution_vop_enable = hdr_curr->vol.reduced_resolution_enable; + pp->vop_coded = (hdr_curr->vop.coding_type != MPEG4_N_VOP); + pp->vop_rounding_type = hdr_curr->vop.rounding; + pp->intra_dc_vlc_thr = hdr_curr->vop.intra_dc_vlc_threshold; + pp->top_field_first = hdr_curr->vop.top_field_first; + pp->alternate_vertical_scan_flag = hdr_curr->vop.alternate_vertical_scan; + pp->profile_and_level_indication = (p->profile << 4) | p->level; + pp->video_object_layer_verid = hdr_curr->vol.ver_id; + pp->vop_width = hdr_curr->vol.width; + pp->vop_height = hdr_curr->vol.height; + pp->sprite_enable = hdr_curr->vol.sprite_enable; + pp->no_of_sprite_warping_points = 0; /* FIXME: */ + pp->sprite_warping_accuracy = 0; /* FIXME: */ + memset(pp->warping_mv, 0, sizeof(pp->warping_mv)); + pp->vop_fcode_forward = hdr_curr->vop.fcode_forward; + pp->vop_fcode_backward = hdr_curr->vop.fcode_backward; + pp->StatusReportFeedbackNumber = 0; /* FIXME: */ + pp->Reserved16BitsA = 0; /* FIXME: */ + pp->Reserved16BitsB = 0; /* FIXME: */ + + // Rockchip special data + pp->custorm_version = p->custorm_version; + pp->prev_coding_type = (hdr_ref0->vop.coding_type == MPEG4_INVALID_VOP) ? (0) : (hdr_ref0->vop.coding_type); + pp->time_bp = hdr_curr->time_bp; + pp->time_pp = hdr_curr->time_pp; + pp->header_bits = hdr_curr->vop.hdr_bits; +} + +static void mpg4d_fill_quantization_matrices(const Mpg4dParserImpl *p, + DXVA_QmatrixData *qm) +{ + RK_S32 i = 0; + + qm->bNewQmatrix[0] = p->new_qm[0]; + qm->bNewQmatrix[1] = p->new_qm[1]; + qm->bNewQmatrix[2] = 0; + qm->bNewQmatrix[3] = 0; + + // intra Y + if (p->new_qm[0]) { + for (i = 0; i < 64; i++) { + qm->Qmatrix[0][i] = p->quant_matrices[i]; + } + } else { + memset(qm->Qmatrix[0], 0, sizeof(qm->Qmatrix[0])); + } + + // inter Y + if (p->new_qm[1]) { + for (i = 0; i < 64; i++) { + qm->Qmatrix[1][i] = p->quant_matrices[64 + i]; + } + } else { + memset(qm->Qmatrix[1], 0, sizeof(qm->Qmatrix[1])); + } + + memset(qm->Qmatrix[2], 0, sizeof(qm->Qmatrix[2])); + memset(qm->Qmatrix[3], 0, sizeof(qm->Qmatrix[3])); +} + +static void mpg4_syntax_init(mpeg4d_dxva2_picture_context_t *syntax) +{ + DXVA2_DecodeBufferDesc *data = &syntax->desc[0]; + + //!< commit picture paramters + memset(data, 0, sizeof(*data)); + data->CompressedBufferType = DXVA2_PictureParametersBufferType; + data->pvPVPState = (void *)&syntax->pp; + data->DataSize = sizeof(syntax->pp); + syntax->data[0] = data; + + //!< commit Qmatrix + data = &syntax->desc[1]; + memset(data, 0, sizeof(*data)); + data->CompressedBufferType = DXVA2_InverseQuantizationMatrixBufferType; + data->pvPVPState = (void *)&syntax->qm; + data->DataSize = sizeof(syntax->qm); + data->NumMBsInBuffer = 0; + syntax->data[1] = data; + + //!< commit bitstream + data = &syntax->desc[2]; + memset(data, 0, sizeof(*data)); + data->CompressedBufferType = DXVA2_BitStreamDateBufferType; + syntax->data[2] = data; +} + +MPP_RET mpp_mpg4_parser_init(Mpg4dParser *ctx, MppBufSlots frame_slots) +{ + BitReadCtx_t *bit_ctx = mpp_calloc(BitReadCtx_t, 1); + Mpg4dParserImpl *p = mpp_calloc(Mpg4dParserImpl, 1); + mpeg4d_dxva2_picture_context_t *syntax = mpp_calloc(mpeg4d_dxva2_picture_context_t, 1); + + if (NULL == p || NULL == bit_ctx || NULL == syntax) { + mpp_err_f("malloc context failed\n"); + if (p) + mpp_free(p); + if (bit_ctx) + mpp_free(bit_ctx); + if (syntax) + mpp_free(syntax); + return MPP_NOK; + } + + mpg4d_dbg_func("in\n"); + + mpp_buf_slot_setup(frame_slots, 8); + p->frame_slots = frame_slots; + p->use_internal_pts = 0; + p->pos_frm_start = -1; + p->pos_frm_end = -1; + p->bit_ctx = bit_ctx; + init_mpg4_header(&p->hdr_curr); + init_mpg4_header(&p->hdr_ref0); + init_mpg4_header(&p->hdr_ref1); + mpg4_syntax_init(syntax); + p->syntax = syntax; + + mpp_env_get_u32("mpg4d_debug", &mpg4d_debug, 0); + + mpg4d_dbg_func("out\n"); + + *ctx = p; + return MPP_OK; +} + +MPP_RET mpp_mpg4_parser_deinit(Mpg4dParser ctx) +{ + Mpg4dParserImpl *p = (Mpg4dParserImpl *)ctx; + + mpg4d_dbg_func("in\n"); + + if (p) { + if (p->bit_ctx) { + mpp_free(p->bit_ctx); + p->bit_ctx = NULL; + } + if (p->syntax) { + mpp_free(p->syntax); + p->syntax = NULL; + } + mpp_free(p); + } + + mpg4d_dbg_func("out\n"); + + return MPP_OK; +} + +MPP_RET mpp_mpg4_parser_flush(Mpg4dParser ctx) +{ + Mpg4dParserImpl *p = (Mpg4dParserImpl *)ctx; + MppBufSlots slots = p->frame_slots; + Mpg4Hdr *hdr_ref0 = &p->hdr_ref0; + RK_S32 index = hdr_ref0->slot_idx; + + mpg4d_dbg_func("in\n"); + + if (!hdr_ref0->enqueued && index >= 0) { + mpp_buf_slot_set_flag(slots, index, SLOT_QUEUE_USE); + mpp_buf_slot_enqueue(slots, index, QUEUE_DISPLAY); + hdr_ref0->enqueued = 1; + } + + mpg4d_dbg_func("out\n"); + + return MPP_OK; +} + +MPP_RET mpp_mpg4_parser_reset(Mpg4dParser ctx) +{ + Mpg4dParserImpl *p = (Mpg4dParserImpl *)ctx; + MppBufSlots slots = p->frame_slots; + Mpg4Hdr *hdr_ref0 = &p->hdr_ref0; + Mpg4Hdr *hdr_ref1 = &p->hdr_ref1; + RK_S32 index = hdr_ref0->slot_idx; + + mpg4d_dbg_func("in\n"); + + if (index >= 0) { + if (!hdr_ref0->enqueued) { + mpp_buf_slot_set_flag(slots, index, SLOT_QUEUE_USE); + mpp_buf_slot_enqueue(slots, index, QUEUE_DISPLAY); + hdr_ref0->enqueued = 1; + } + mpp_buf_slot_clr_flag(slots, index, SLOT_CODEC_USE); + hdr_ref0->slot_idx = -1; + } + + index = hdr_ref1->slot_idx; + if (index >= 0) { + mpp_buf_slot_clr_flag(slots, index, SLOT_CODEC_USE); + hdr_ref1->slot_idx = -1; + } + + p->found_i_vop = 0; + p->found_vop = 0; + + mpg4d_dbg_func("out\n"); + + return MPP_OK; +} + +MPP_RET mpp_mpg4_parser_split(Mpg4dParser ctx, MppPacket dst, MppPacket src) +{ + MPP_RET ret = MPP_NOK; + Mpg4dParserImpl *p = (Mpg4dParserImpl *)ctx; + RK_U8 *dst_buf = mpp_packet_get_data(dst); + size_t dst_len = mpp_packet_get_length(dst); + RK_U8 *src_buf = mpp_packet_get_pos(src); + RK_S32 src_len = (RK_S32)mpp_packet_get_length(src); + RK_S32 pos_frm_start = p->pos_frm_start; + RK_S32 pos_frm_end = p->pos_frm_end; + RK_U32 src_eos = mpp_packet_get_eos(src); + RK_S32 src_pos = 0; + RK_U32 state = (RK_U32) - 1; + + mpg4d_dbg_func("in\n"); + + mpp_assert(src_len); + + if (dst_len) { + mpp_assert(dst_len >= 4); + state = ((RK_U32)(dst_buf[dst_len - 1]) << 0) | + ((RK_U32)(dst_buf[dst_len - 2]) << 8) | + ((RK_U32)(dst_buf[dst_len - 3]) << 16) | + ((RK_U32)(dst_buf[dst_len - 4]) << 24); + } + + if (pos_frm_start < 0) { + // scan for frame start + for (src_pos = 0; src_pos < src_len; src_pos++) { + state = (state << 8) | src_buf[src_pos]; + if (state == MPG4_VOP_STARTCODE) { + src_pos++; + pos_frm_start = src_pos - 4; + break; + } + } + } + + if (pos_frm_start >= 0) { + // scan for frame end + for (; src_pos < src_len; src_pos++) { + state = (state << 8) | src_buf[src_pos]; + + if ((state & 0xFFFFFFFF) == MPG4_VOP_STARTCODE) { + pos_frm_end = src_pos - 3; + break; + } + } + if (src_eos && src_pos == src_len) { + pos_frm_end = src_len; + mpp_packet_set_eos(dst); + } + } + + //mpp_log("pkt pos: start %d end %d len: left %d in %d\n", + // pos_frm_start, pos_frm_end, dst_len, src_len); + + if (pos_frm_start < 0 || pos_frm_end < 0) { + // do not found frame start or do not found frame end, just copy the hold buffer to dst + memcpy(dst_buf + dst_len, src_buf, src_len); + // update dst buffer length + mpp_packet_set_length(dst, dst_len + src_len); + // set src buffer pos to end to src buffer + mpp_packet_set_pos(src, src_buf + src_len); + } else { + // found both frame start and frame end - only copy frame + memcpy(dst_buf + dst_len, src_buf, pos_frm_end); + mpp_packet_set_length(dst, dst_len + pos_frm_end); + + // set src buffer pos to end to src buffer + mpp_packet_set_pos(src, src_buf + pos_frm_end); + mpp_assert((RK_S32)mpp_packet_get_length(src) == (src_len - pos_frm_end)); + mpp_packet_set_length(src, src_len - pos_frm_end); + + // return ok indicate the frame is ready and reset frame start/end position + ret = MPP_OK; + pos_frm_start = -1; + pos_frm_end = -1; + } + + p->pos_frm_start = pos_frm_start; + p->pos_frm_end = pos_frm_end; + + mpg4d_dbg_func("out\n"); + + return ret; +} + +MPP_RET mpp_mpg4_parser_decode(Mpg4dParser ctx, MppPacket pkt) +{ + MPP_RET ret = MPP_OK; + Mpg4dParserImpl *p = (Mpg4dParserImpl *)ctx; + BitReadCtx_t *gb = p->bit_ctx; + RK_U8 *buf = mpp_packet_get_data(pkt); + RK_S32 len = (RK_S32)mpp_packet_get_length(pkt); + RK_U32 startcode = 0xff; + + mpg4d_dbg_func("in\n"); + + // setup bit read context + mpp_set_bitread_ctx(gb, buf, len); + p->found_vop = 0; + + while (gb->bytes_left_) { + RK_U32 val = 0; + + READ_BITS(gb, 8, &val); + startcode = (startcode << 8) | val; + + if ((startcode & 0xFFFFFF00) != 0x100) + continue; + + mpg4d_dbg_bit("found startcode at byte %d\n", gb->used_bits >> 3); + + if (mpg4d_debug & MPG4D_DBG_STARTCODE) { + mpp_log_f("start code %03x\n", startcode); + if (startcode <= 0x11F) + mpp_log_f("Video Object Start"); + else if (startcode <= 0x12F) + mpp_log_f("Video Object Layer Start"); + else if (startcode <= 0x13F) + mpp_log_f("Reserved"); + else if (startcode <= 0x15F) + mpp_log_f("FGS bp start"); + else if (startcode <= 0x1AF) + mpp_log_f("Reserved"); + else if (startcode == 0x1B0) + mpp_log_f("Visual Object Seq Start"); + else if (startcode == 0x1B1) + mpp_log_f("Visual Object Seq End"); + else if (startcode == 0x1B2) + mpp_log_f("User Data"); + else if (startcode == 0x1B3) + mpp_log_f("Group of VOP start"); + else if (startcode == 0x1B4) + mpp_log_f("Video Session Error"); + else if (startcode == 0x1B5) + mpp_log_f("Visual Object Start"); + else if (startcode == 0x1B6) + mpp_log_f("Video Object Plane start"); + else if (startcode == 0x1B7) + mpp_log_f("slice start"); + else if (startcode == 0x1B8) + mpp_log_f("extension start"); + else if (startcode == 0x1B9) + mpp_log_f("fgs start"); + else if (startcode == 0x1BA) + mpp_log_f("FBA Object start"); + else if (startcode == 0x1BB) + mpp_log_f("FBA Object Plane start"); + else if (startcode == 0x1BC) + mpp_log_f("Mesh Object start"); + else if (startcode == 0x1BD) + mpp_log_f("Mesh Object Plane start"); + else if (startcode == 0x1BE) + mpp_log_f("Still Texture Object start"); + else if (startcode == 0x1BF) + mpp_log_f("Texture Spatial Layer start"); + else if (startcode == 0x1C0) + mpp_log_f("Texture SNR Layer start"); + else if (startcode == 0x1C1) + mpp_log_f("Texture Tile start"); + else if (startcode == 0x1C2) + mpp_log_f("Texture Shape Layer start"); + else if (startcode == 0x1C3) + mpp_log_f("stuffing start"); + else if (startcode <= 0x1C5) + mpp_log_f("reserved"); + else if (startcode <= 0x1FF) + mpp_log_f("System start"); + } + + if (startcode >= MPG4_VOL_STARTCODE && startcode <= MPG4_VOL_STOPCODE) { + ret = mpg4d_parse_vol_header(p, gb); + if (!p->found_vol) + p->found_vol = (ret == MPP_OK); + } else if (startcode == MPG4_USER_DATA_STARTCODE) { + ret = mpg4d_parse_user_data(p, gb); + } else if (startcode == MPG4_GOP_STARTCODE) { + ret = mpeg4_parse_gop_header(p, gb); + } else if (startcode == MPG4_VOS_STARTCODE) { + ret = mpeg4_parse_profile_level(p, gb); + } else if (startcode == MPG4_VOP_STARTCODE) { + ret = mpeg4_parse_vop_header(p, gb); + if (MPP_OK == ret) { + RK_S32 coding_type = p->hdr_curr.vop.coding_type; + mpg4d_dbg_bit("frame %d coding_type %d\n", p->frame_num, coding_type); + p->frame_num++; + + if (coding_type == MPEG4_N_VOP) { + ret = MPP_OK; + mpp_align_get_bits(gb); + continue; + } + + p->found_vop = p->found_i_vop; + } + } + + if (ret) + goto __BITREAD_ERR; + + mpp_align_get_bits(gb); + + if (p->found_vol && p->found_vop) + break; + } + + if (p->found_vol) { + mpg4d_dbg_result("found vol w %d h %d\n", p->hdr_curr.vol.width, p->hdr_curr.vol.height); + p->width = p->hdr_curr.vol.width; + p->height = p->hdr_curr.vol.height; + } + + if (!p->use_internal_pts) + p->pts = mpp_packet_get_pts(pkt); + + ret = (p->found_vol && p->found_vop) ? (MPP_OK) : (MPP_NOK); + +__BITREAD_ERR: + mpg4d_dbg_result("found vol %d vop %d ret %d\n", p->found_vol, p->found_vop, ret); + + if (ret) { + mpp_packet_set_pos(pkt, buf); + mpp_packet_set_length(pkt, 0); + } else { + RK_U32 used_bytes = gb->used_bits >> 3; + mpp_packet_set_pos(pkt, buf + used_bytes); + } + + p->eos = mpp_packet_get_eos(pkt); + + mpg4d_dbg_func("out\n"); + + return ret; +} + +MPP_RET mpp_mpg4_parser_setup_syntax(Mpg4dParser ctx, MppSyntax *syntax) +{ + Mpg4dParserImpl *p = (Mpg4dParserImpl *)ctx; + mpeg4d_dxva2_picture_context_t *syn = p->syntax; + + mpg4d_dbg_func("in\n"); + + mpg4d_fill_picture_parameters(p, &syn->pp); + mpg4d_fill_quantization_matrices(p, &syn->qm); + + // fill bit stream parameter + syn->data[2]->DataSize = p->bit_ctx->buf_len; + syn->data[2]->DataOffset = p->hdr_curr.vop.hdr_bits; + syn->data[2]->pvPVPState = p->bit_ctx->buf; + + syntax->number = 3; + syntax->data = syn->data; + + mpg4d_dbg_func("out\n"); + + return MPP_OK; +} + +MPP_RET mpp_mpg4_parser_setup_hal_output(Mpg4dParser ctx, RK_S32 *output) +{ + Mpg4dParserImpl *p = (Mpg4dParserImpl *)ctx; + Mpg4Hdr *hdr_curr = &p->hdr_curr; + RK_S32 index = -1; + + mpg4d_dbg_func("in\n"); + + if (p->found_i_vop && hdr_curr->vop.coding_type != MPEG4_N_VOP) { + MppBufSlots slots = p->frame_slots; + RK_U32 frame_mode = MPP_FRAME_FLAG_FRAME; + MppFrame frame = NULL; + + mpp_frame_init(&frame); + mpp_frame_set_width(frame, p->width); + mpp_frame_set_height(frame, p->height); + mpp_frame_set_hor_stride(frame, MPP_ALIGN(p->width, 16)); + mpp_frame_set_ver_stride(frame, MPP_ALIGN(p->height, 16)); + + /* + * set slots information + * 1. output index MUST be set + * 2. get unused index for output if needed + * 3. set output index as hal_input + * 4. set frame information to output index + * 5. if one frame can be display, it SHOULD be enqueued to display queue + */ + mpp_buf_slot_get_unused(slots, &index); + mpp_buf_slot_set_flag(slots, index, SLOT_HAL_OUTPUT); + mpp_frame_set_pts(frame, p->pts); + + if (hdr_curr->vol.interlacing) { + frame_mode = MPP_FRAME_FLAG_PAIRED_FIELD; + if (hdr_curr->vop.top_field_first) + frame_mode |= MPP_FRAME_FLAG_TOP_FIRST; + else + frame_mode |= MPP_FRAME_FLAG_BOT_FIRST; + } + mpp_frame_set_mode(frame, frame_mode); + + mpp_buf_slot_set_prop(slots, index, SLOT_FRAME, frame); + mpp_frame_deinit(&frame); + mpp_assert(NULL == frame); + + hdr_curr->slot_idx = index; + } + + p->output = index; + *output = index; + + mpg4d_dbg_func("out\n"); + + return MPP_OK; +} + +MPP_RET mpp_mpg4_parser_setup_refer(Mpg4dParser ctx, RK_S32 *refer, RK_S32 max_ref) +{ + Mpg4dParserImpl *p = (Mpg4dParserImpl *)ctx; + Mpg4Hdr *hdr_curr = &p->hdr_curr; + MppBufSlots slots = p->frame_slots; + RK_S32 index; + + mpg4d_dbg_func("in\n"); + + memset(refer, -1, sizeof(max_ref * sizeof(*refer))); + if (hdr_curr->vop.coding_type != MPEG4_N_VOP) { + index = p->hdr_ref0.slot_idx; + if (index >= 0) { + mpp_buf_slot_set_flag(slots, index, SLOT_HAL_INPUT); + refer[0] = index; + } + index = p->hdr_ref1.slot_idx; + if (index >= 0) { + mpp_buf_slot_set_flag(slots, index, SLOT_HAL_INPUT); + refer[1] = index; + } + } + + mpg4d_dbg_func("out\n"); + + return MPP_OK; +} + +MPP_RET mpp_mpg4_parser_update_dpb(Mpg4dParser ctx) +{ + Mpg4dParserImpl *p = (Mpg4dParserImpl *)ctx; + MppBufSlots slots = p->frame_slots; + Mpg4Hdr *hdr_curr = &p->hdr_curr; + Mpg4Hdr *hdr_ref0 = &p->hdr_ref0; + Mpg4Hdr *hdr_ref1 = &p->hdr_ref1; + RK_S32 coding_type = hdr_curr->vop.coding_type; + RK_S32 index = p->output; + + mpg4d_dbg_func("in\n"); + + // update pts increacement + if (p->pts != p->last_pts) + p->pts_inc = p->pts - p->last_pts; + + switch (coding_type) { + case MPEG4_B_VOP : { + mpp_assert((hdr_ref0->slot_idx >= 0) && (hdr_ref1->slot_idx >= 0)); + // B frame -> index current frame + // output current frame and do not change ref0 and ref1 + index = hdr_curr->slot_idx; + mpp_buf_slot_set_flag(slots, index, SLOT_QUEUE_USE); + mpp_buf_slot_enqueue(slots, index, QUEUE_DISPLAY); + } + /* + * NOTE: here fallback to N vop - do nothing + */ + case MPEG4_INVALID_VOP : + case MPEG4_N_VOP : { + } break; + case MPEG4_I_VOP : + case MPEG4_P_VOP : + case MPEG4_S_VOP : + // the other case -> index reference 0 + index = hdr_ref0->slot_idx; + if (!hdr_ref0->enqueued && index >= 0) { + mpp_buf_slot_set_flag(slots, index, SLOT_QUEUE_USE); + mpp_buf_slot_enqueue(slots, index, QUEUE_DISPLAY); + } + // non B frame send this frame to reference queue + mpp_buf_slot_set_flag(slots, hdr_curr->slot_idx, SLOT_CODEC_USE); + + // release ref1 + index = hdr_ref1->slot_idx; + if (index >= 0) + mpp_buf_slot_clr_flag(slots, index, SLOT_CODEC_USE); + + // swap ref0 to ref1, current to ref0 + *hdr_ref1 = *hdr_ref0; + *hdr_ref0 = *hdr_curr; + hdr_curr->pts = 0; + } + + init_mpg4_hdr_vop(hdr_curr); + hdr_curr->slot_idx = -1; + p->last_pts = p->pts; + + mpg4d_dbg_func("out\n"); + + return MPP_OK; +} + +MPP_RET mpp_mpg4_parser_set_pts_mode(Mpg4dParser ctx, RK_U32 use_internal_pts) +{ + Mpg4dParserImpl *p = (Mpg4dParserImpl *)ctx; + + mpg4d_dbg_func("in\n"); + + p->use_internal_pts = use_internal_pts; + + mpg4d_dbg_func("out\n"); + + return MPP_OK; +} + diff --git a/mpp/codec/dec/vp8/vp8d_api.c b/mpp/codec/dec/vp8/vp8d_api.c index 6ea0c548..c89aba62 100644 --- a/mpp/codec/dec/vp8/vp8d_api.c +++ b/mpp/codec/dec/vp8/vp8d_api.c @@ -1,44 +1,44 @@ -/* -* -* Copyright 2015 Rockchip Electronics Co. LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#define MODULE_TAG "vp8d_api" - -#include -#include "vpu_api.h" -#include "mpp_env.h" -#include "mpp_packet.h" -#include "mpp_packet_impl.h" -#include "mpp_mem.h" -#include "mpp_log.h" -#include "vp8d_api.h" -#include "vp8d_parser.h" -#include "vp8d_codec.h" - -const ParserApi api_vp8d_parser = { - "vp8d_parse", - MPP_VIDEO_CodingVP8, - sizeof(VP8DContext), - 0, - vp8d_parser_init, - vp8d_parser_deinit, - vp8d_parser_prepare, - vp8d_parser_parse, - vp8d_parser_reset, - vp8d_parser_flush, - vp8d_parser_control, - vp8d_parser_callback, -}; +/* +* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#define MODULE_TAG "vp8d_api" + +#include +#include "vpu_api.h" +#include "mpp_env.h" +#include "mpp_packet.h" +#include "mpp_packet_impl.h" +#include "mpp_mem.h" +#include "mpp_log.h" +#include "vp8d_api.h" +#include "vp8d_parser.h" +#include "vp8d_codec.h" + +const ParserApi api_vp8d_parser = { + "vp8d_parse", + MPP_VIDEO_CodingVP8, + sizeof(VP8DContext), + 0, + vp8d_parser_init, + vp8d_parser_deinit, + vp8d_parser_prepare, + vp8d_parser_parse, + vp8d_parser_reset, + vp8d_parser_flush, + vp8d_parser_control, + vp8d_parser_callback, +}; diff --git a/mpp/codec/dec/vp8/vp8d_codec.h b/mpp/codec/dec/vp8/vp8d_codec.h index 996d9896..337a892d 100644 --- a/mpp/codec/dec/vp8/vp8d_codec.h +++ b/mpp/codec/dec/vp8/vp8d_codec.h @@ -1,34 +1,34 @@ -/* - * - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __VP8D_CODEC_H__ -#define __VP8D_CODEC_H__ - -#include "rk_type.h" -#include "mpp_common.h" -#include "vpu_api.h" -#include "mpp_frame.h" -#include "mpp_dec.h" -#include "mpp_packet.h" - - -typedef struct VP8DContext_t { - void *parse_ctx; - -} VP8DContext; - -#endif +/* + * + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __VP8D_CODEC_H__ +#define __VP8D_CODEC_H__ + +#include "rk_type.h" +#include "mpp_common.h" +#include "vpu_api.h" +#include "mpp_frame.h" +#include "mpp_dec.h" +#include "mpp_packet.h" + + +typedef struct VP8DContext_t { + void *parse_ctx; + +} VP8DContext; + +#endif diff --git a/mpp/codec/dec/vp8/vp8d_data.h b/mpp/codec/dec/vp8/vp8d_data.h index 09f473f6..96f0be85 100644 --- a/mpp/codec/dec/vp8/vp8d_data.h +++ b/mpp/codec/dec/vp8/vp8d_data.h @@ -1,407 +1,407 @@ -/* - * - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include "rk_type.h" - -#ifndef __VP8D_DATA_H__ -#define __VP8D_DATA_H__ - -#define VP7_MV_PROBS_PER_COMPONENT (17) -#define VP8_MV_PROBS_PER_COMPONENT (19) - - -#define swap32bit(x) ((x>>24)|((x>>8)&0xff00)|((x<<8)&0xff0000)|(x<<24)) - -static const RK_U8 MvUpdateProbs[2][VP8_MV_PROBS_PER_COMPONENT] = { - { - 237, 246, 253, 253, 254, 254, 254, 254, 254, - 254, 254, 254, 254, 254, 250, 250, 252, 254, 254 - }, - { - 231, 243, 245, 253, 254, 254, 254, 254, 254, - 254, 254, 254, 254, 254, 251, 251, 254, 254, 254 - } -}; - -static const RK_U8 Vp8DefaultMvProbs[2][VP8_MV_PROBS_PER_COMPONENT] = { - { - 162, 128, 225, 146, 172, 147, 214, 39, 156, - 128, 129, 132, 75, 145, 178, 206, 239, 254, 254 - }, - { - 164, 128, 204, 170, 119, 235, 140, 230, 228, - 128, 130, 130, 74, 148, 180, 203, 236, 254, 254 - } -}; - -static const RK_U8 Vp7DefaultMvProbs[2][VP7_MV_PROBS_PER_COMPONENT] = { - { - 162, 128, 225, 146, 172, 147, 214, 39, 156, - 247, 210, 135, 68, 138, 220, 239, 246 - }, - { - 164, 128, 204, 170, 119, 235, 140, 230, 228, - 244, 184, 201, 44, 173, 221, 239, 253 - } -}; - -static const RK_U8 CoeffUpdateProbs[4][8][3][11] = { - { - { - {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - }, - { - {176, 246, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {223, 241, 252, 255, 255, 255, 255, 255, 255, 255, 255, }, - {249, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255, }, - }, - { - {255, 244, 252, 255, 255, 255, 255, 255, 255, 255, 255, }, - {234, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, - {253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - }, - { - {255, 246, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, - {239, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, - {254, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, - }, - { - {255, 248, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, - {251, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, - {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - }, - { - {255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, - {251, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, - {254, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, - }, - { - {255, 254, 253, 255, 254, 255, 255, 255, 255, 255, 255, }, - {250, 255, 254, 255, 254, 255, 255, 255, 255, 255, 255, }, - {254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - }, - { - {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - }, - }, - { - { - {217, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {225, 252, 241, 253, 255, 255, 254, 255, 255, 255, 255, }, - {234, 250, 241, 250, 253, 255, 253, 254, 255, 255, 255, }, - }, - { - {255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {223, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, - {238, 253, 254, 254, 255, 255, 255, 255, 255, 255, 255, }, - }, - { - {255, 248, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, - {249, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - }, - { - {255, 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {247, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - }, - { - {255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, - {252, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - }, - { - {255, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, - {253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - }, - { - {255, 254, 253, 255, 255, 255, 255, 255, 255, 255, 255, }, - {250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - }, - { - {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - }, - }, - { - { - {186, 251, 250, 255, 255, 255, 255, 255, 255, 255, 255, }, - {234, 251, 244, 254, 255, 255, 255, 255, 255, 255, 255, }, - {251, 251, 243, 253, 254, 255, 254, 255, 255, 255, 255, }, - }, - { - {255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, - {236, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, - {251, 253, 253, 254, 254, 255, 255, 255, 255, 255, 255, }, - }, - { - {255, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, - {254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, - {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - }, - { - {255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - }, - { - {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - }, - { - {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - }, - { - {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - }, - { - {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - }, - }, - { - { - {248, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {250, 254, 252, 254, 255, 255, 255, 255, 255, 255, 255, }, - {248, 254, 249, 253, 255, 255, 255, 255, 255, 255, 255, }, - }, - { - {255, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255, }, - {246, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255, }, - {252, 254, 251, 254, 254, 255, 255, 255, 255, 255, 255, }, - }, - { - {255, 254, 252, 255, 255, 255, 255, 255, 255, 255, 255, }, - {248, 254, 253, 255, 255, 255, 255, 255, 255, 255, 255, }, - {253, 255, 254, 254, 255, 255, 255, 255, 255, 255, 255, }, - }, - { - {255, 251, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, - {245, 251, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, - {253, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, - }, - { - {255, 251, 253, 255, 255, 255, 255, 255, 255, 255, 255, }, - {252, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, - {255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - }, - { - {255, 252, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {249, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, - {255, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, - }, - { - {255, 255, 253, 255, 255, 255, 255, 255, 255, 255, 255, }, - {250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - }, - { - {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, - }, - }, -}; - - -static const RK_U8 DefaultCoeffProbs [4][8][3][11] = { - { - { - { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128}, - { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128}, - { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128} - }, - { - { 253, 136, 254, 255, 228, 219, 128, 128, 128, 128, 128}, - { 189, 129, 242, 255, 227, 213, 255, 219, 128, 128, 128}, - { 106, 126, 227, 252, 214, 209, 255, 255, 128, 128, 128} - }, - { - { 1, 98, 248, 255, 236, 226, 255, 255, 128, 128, 128}, - { 181, 133, 238, 254, 221, 234, 255, 154, 128, 128, 128}, - { 78, 134, 202, 247, 198, 180, 255, 219, 128, 128, 128} - }, - { - { 1, 185, 249, 255, 243, 255, 128, 128, 128, 128, 128}, - { 184, 150, 247, 255, 236, 224, 128, 128, 128, 128, 128}, - { 77, 110, 216, 255, 236, 230, 128, 128, 128, 128, 128} - }, - { - { 1, 101, 251, 255, 241, 255, 128, 128, 128, 128, 128}, - { 170, 139, 241, 252, 236, 209, 255, 255, 128, 128, 128}, - { 37, 116, 196, 243, 228, 255, 255, 255, 128, 128, 128} - }, - { - { 1, 204, 254, 255, 245, 255, 128, 128, 128, 128, 128}, - { 207, 160, 250, 255, 238, 128, 128, 128, 128, 128, 128}, - { 102, 103, 231, 255, 211, 171, 128, 128, 128, 128, 128} - }, - { - { 1, 152, 252, 255, 240, 255, 128, 128, 128, 128, 128}, - { 177, 135, 243, 255, 234, 225, 128, 128, 128, 128, 128}, - { 80, 129, 211, 255, 194, 224, 128, 128, 128, 128, 128} - }, - { - { 1, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128}, - { 246, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128}, - { 255, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128} - } - }, - { - { - { 198, 35, 237, 223, 193, 187, 162, 160, 145, 155, 62}, - { 131, 45, 198, 221, 172, 176, 220, 157, 252, 221, 1}, - { 68, 47, 146, 208, 149, 167, 221, 162, 255, 223, 128} - }, - { - { 1, 149, 241, 255, 221, 224, 255, 255, 128, 128, 128}, - { 184, 141, 234, 253, 222, 220, 255, 199, 128, 128, 128}, - { 81, 99, 181, 242, 176, 190, 249, 202, 255, 255, 128} - }, - { - { 1, 129, 232, 253, 214, 197, 242, 196, 255, 255, 128}, - { 99, 121, 210, 250, 201, 198, 255, 202, 128, 128, 128}, - { 23, 91, 163, 242, 170, 187, 247, 210, 255, 255, 128} - }, - { - { 1, 200, 246, 255, 234, 255, 128, 128, 128, 128, 128}, - { 109, 178, 241, 255, 231, 245, 255, 255, 128, 128, 128}, - { 44, 130, 201, 253, 205, 192, 255, 255, 128, 128, 128} - }, - { - { 1, 132, 239, 251, 219, 209, 255, 165, 128, 128, 128}, - { 94, 136, 225, 251, 218, 190, 255, 255, 128, 128, 128}, - { 22, 100, 174, 245, 186, 161, 255, 199, 128, 128, 128} - }, - { - { 1, 182, 249, 255, 232, 235, 128, 128, 128, 128, 128}, - { 124, 143, 241, 255, 227, 234, 128, 128, 128, 128, 128}, - { 35, 77, 181, 251, 193, 211, 255, 205, 128, 128, 128} - }, - { - { 1, 157, 247, 255, 236, 231, 255, 255, 128, 128, 128}, - { 121, 141, 235, 255, 225, 227, 255, 255, 128, 128, 128}, - { 45, 99, 188, 251, 195, 217, 255, 224, 128, 128, 128} - }, - { - { 1, 1, 251, 255, 213, 255, 128, 128, 128, 128, 128}, - { 203, 1, 248, 255, 255, 128, 128, 128, 128, 128, 128}, - { 137, 1, 177, 255, 224, 255, 128, 128, 128, 128, 128} - } - }, - { - { - { 253, 9, 248, 251, 207, 208, 255, 192, 128, 128, 128}, - { 175, 13, 224, 243, 193, 185, 249, 198, 255, 255, 128}, - { 73, 17, 171, 221, 161, 179, 236, 167, 255, 234, 128} - }, - { - { 1, 95, 247, 253, 212, 183, 255, 255, 128, 128, 128}, - { 239, 90, 244, 250, 211, 209, 255, 255, 128, 128, 128}, - { 155, 77, 195, 248, 188, 195, 255, 255, 128, 128, 128} - }, - { - { 1, 24, 239, 251, 218, 219, 255, 205, 128, 128, 128}, - { 201, 51, 219, 255, 196, 186, 128, 128, 128, 128, 128}, - { 69, 46, 190, 239, 201, 218, 255, 228, 128, 128, 128} - }, - { - { 1, 191, 251, 255, 255, 128, 128, 128, 128, 128, 128}, - { 223, 165, 249, 255, 213, 255, 128, 128, 128, 128, 128}, - { 141, 124, 248, 255, 255, 128, 128, 128, 128, 128, 128} - }, - { - { 1, 16, 248, 255, 255, 128, 128, 128, 128, 128, 128}, - { 190, 36, 230, 255, 236, 255, 128, 128, 128, 128, 128}, - { 149, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128} - }, - { - { 1, 226, 255, 128, 128, 128, 128, 128, 128, 128, 128}, - { 247, 192, 255, 128, 128, 128, 128, 128, 128, 128, 128}, - { 240, 128, 255, 128, 128, 128, 128, 128, 128, 128, 128} - }, - { - { 1, 134, 252, 255, 255, 128, 128, 128, 128, 128, 128}, - { 213, 62, 250, 255, 255, 128, 128, 128, 128, 128, 128}, - { 55, 93, 255, 128, 128, 128, 128, 128, 128, 128, 128} - }, - { - { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128}, - { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128}, - { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128} - } - }, - { - { - { 202, 24, 213, 235, 186, 191, 220, 160, 240, 175, 255}, - { 126, 38, 182, 232, 169, 184, 228, 174, 255, 187, 128}, - { 61, 46, 138, 219, 151, 178, 240, 170, 255, 216, 128} - }, - { - { 1, 112, 230, 250, 199, 191, 247, 159, 255, 255, 128}, - { 166, 109, 228, 252, 211, 215, 255, 174, 128, 128, 128}, - { 39, 77, 162, 232, 172, 180, 245, 178, 255, 255, 128} - }, - { - { 1, 52, 220, 246, 198, 199, 249, 220, 255, 255, 128}, - { 124, 74, 191, 243, 183, 193, 250, 221, 255, 255, 128}, - { 24, 71, 130, 219, 154, 170, 243, 182, 255, 255, 128} - }, - { - { 1, 182, 225, 249, 219, 240, 255, 224, 128, 128, 128}, - { 149, 150, 226, 252, 216, 205, 255, 171, 128, 128, 128}, - { 28, 108, 170, 242, 183, 194, 254, 223, 255, 255, 128} - }, - { - { 1, 81, 230, 252, 204, 203, 255, 192, 128, 128, 128}, - { 123, 102, 209, 247, 188, 196, 255, 233, 128, 128, 128}, - { 20, 95, 153, 243, 164, 173, 255, 203, 128, 128, 128} - }, - { - { 1, 222, 248, 255, 216, 213, 128, 128, 128, 128, 128}, - { 168, 175, 246, 252, 235, 205, 255, 255, 128, 128, 128}, - { 47, 116, 215, 255, 211, 212, 255, 255, 128, 128, 128} - }, - { - { 1, 121, 236, 253, 212, 214, 255, 255, 128, 128, 128}, - { 141, 84, 213, 252, 201, 202, 255, 219, 128, 128, 128}, - { 42, 80, 160, 240, 162, 185, 255, 205, 128, 128, 128} - }, - { - { 1, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128}, - { 244, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128}, - { 238, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128} - } - } -}; - - -#endif +/* + * + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "rk_type.h" + +#ifndef __VP8D_DATA_H__ +#define __VP8D_DATA_H__ + +#define VP7_MV_PROBS_PER_COMPONENT (17) +#define VP8_MV_PROBS_PER_COMPONENT (19) + + +#define swap32bit(x) ((x>>24)|((x>>8)&0xff00)|((x<<8)&0xff0000)|(x<<24)) + +static const RK_U8 MvUpdateProbs[2][VP8_MV_PROBS_PER_COMPONENT] = { + { + 237, 246, 253, 253, 254, 254, 254, 254, 254, + 254, 254, 254, 254, 254, 250, 250, 252, 254, 254 + }, + { + 231, 243, 245, 253, 254, 254, 254, 254, 254, + 254, 254, 254, 254, 254, 251, 251, 254, 254, 254 + } +}; + +static const RK_U8 Vp8DefaultMvProbs[2][VP8_MV_PROBS_PER_COMPONENT] = { + { + 162, 128, 225, 146, 172, 147, 214, 39, 156, + 128, 129, 132, 75, 145, 178, 206, 239, 254, 254 + }, + { + 164, 128, 204, 170, 119, 235, 140, 230, 228, + 128, 130, 130, 74, 148, 180, 203, 236, 254, 254 + } +}; + +static const RK_U8 Vp7DefaultMvProbs[2][VP7_MV_PROBS_PER_COMPONENT] = { + { + 162, 128, 225, 146, 172, 147, 214, 39, 156, + 247, 210, 135, 68, 138, 220, 239, 246 + }, + { + 164, 128, 204, 170, 119, 235, 140, 230, 228, + 244, 184, 201, 44, 173, 221, 239, 253 + } +}; + +static const RK_U8 CoeffUpdateProbs[4][8][3][11] = { + { + { + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + }, + { + {176, 246, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {223, 241, 252, 255, 255, 255, 255, 255, 255, 255, 255, }, + {249, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255, }, + }, + { + {255, 244, 252, 255, 255, 255, 255, 255, 255, 255, 255, }, + {234, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, + {253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + }, + { + {255, 246, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, + {239, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, + {254, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, + }, + { + {255, 248, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, + {251, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + }, + { + {255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, + {251, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, + {254, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, + }, + { + {255, 254, 253, 255, 254, 255, 255, 255, 255, 255, 255, }, + {250, 255, 254, 255, 254, 255, 255, 255, 255, 255, 255, }, + {254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + }, + { + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + }, + }, + { + { + {217, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {225, 252, 241, 253, 255, 255, 254, 255, 255, 255, 255, }, + {234, 250, 241, 250, 253, 255, 253, 254, 255, 255, 255, }, + }, + { + {255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {223, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, + {238, 253, 254, 254, 255, 255, 255, 255, 255, 255, 255, }, + }, + { + {255, 248, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, + {249, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + }, + { + {255, 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {247, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + }, + { + {255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, + {252, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + }, + { + {255, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, + {253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + }, + { + {255, 254, 253, 255, 255, 255, 255, 255, 255, 255, 255, }, + {250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + }, + { + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + }, + }, + { + { + {186, 251, 250, 255, 255, 255, 255, 255, 255, 255, 255, }, + {234, 251, 244, 254, 255, 255, 255, 255, 255, 255, 255, }, + {251, 251, 243, 253, 254, 255, 254, 255, 255, 255, 255, }, + }, + { + {255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, + {236, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, + {251, 253, 253, 254, 254, 255, 255, 255, 255, 255, 255, }, + }, + { + {255, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, + {254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + }, + { + {255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + }, + { + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + }, + { + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + }, + { + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + }, + { + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + }, + }, + { + { + {248, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {250, 254, 252, 254, 255, 255, 255, 255, 255, 255, 255, }, + {248, 254, 249, 253, 255, 255, 255, 255, 255, 255, 255, }, + }, + { + {255, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255, }, + {246, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255, }, + {252, 254, 251, 254, 254, 255, 255, 255, 255, 255, 255, }, + }, + { + {255, 254, 252, 255, 255, 255, 255, 255, 255, 255, 255, }, + {248, 254, 253, 255, 255, 255, 255, 255, 255, 255, 255, }, + {253, 255, 254, 254, 255, 255, 255, 255, 255, 255, 255, }, + }, + { + {255, 251, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, + {245, 251, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, + {253, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, + }, + { + {255, 251, 253, 255, 255, 255, 255, 255, 255, 255, 255, }, + {252, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, + {255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + }, + { + {255, 252, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {249, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, + {255, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, + }, + { + {255, 255, 253, 255, 255, 255, 255, 255, 255, 255, 255, }, + {250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + }, + { + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, + }, + }, +}; + + +static const RK_U8 DefaultCoeffProbs [4][8][3][11] = { + { + { + { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128}, + { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128}, + { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128} + }, + { + { 253, 136, 254, 255, 228, 219, 128, 128, 128, 128, 128}, + { 189, 129, 242, 255, 227, 213, 255, 219, 128, 128, 128}, + { 106, 126, 227, 252, 214, 209, 255, 255, 128, 128, 128} + }, + { + { 1, 98, 248, 255, 236, 226, 255, 255, 128, 128, 128}, + { 181, 133, 238, 254, 221, 234, 255, 154, 128, 128, 128}, + { 78, 134, 202, 247, 198, 180, 255, 219, 128, 128, 128} + }, + { + { 1, 185, 249, 255, 243, 255, 128, 128, 128, 128, 128}, + { 184, 150, 247, 255, 236, 224, 128, 128, 128, 128, 128}, + { 77, 110, 216, 255, 236, 230, 128, 128, 128, 128, 128} + }, + { + { 1, 101, 251, 255, 241, 255, 128, 128, 128, 128, 128}, + { 170, 139, 241, 252, 236, 209, 255, 255, 128, 128, 128}, + { 37, 116, 196, 243, 228, 255, 255, 255, 128, 128, 128} + }, + { + { 1, 204, 254, 255, 245, 255, 128, 128, 128, 128, 128}, + { 207, 160, 250, 255, 238, 128, 128, 128, 128, 128, 128}, + { 102, 103, 231, 255, 211, 171, 128, 128, 128, 128, 128} + }, + { + { 1, 152, 252, 255, 240, 255, 128, 128, 128, 128, 128}, + { 177, 135, 243, 255, 234, 225, 128, 128, 128, 128, 128}, + { 80, 129, 211, 255, 194, 224, 128, 128, 128, 128, 128} + }, + { + { 1, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128}, + { 246, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128}, + { 255, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128} + } + }, + { + { + { 198, 35, 237, 223, 193, 187, 162, 160, 145, 155, 62}, + { 131, 45, 198, 221, 172, 176, 220, 157, 252, 221, 1}, + { 68, 47, 146, 208, 149, 167, 221, 162, 255, 223, 128} + }, + { + { 1, 149, 241, 255, 221, 224, 255, 255, 128, 128, 128}, + { 184, 141, 234, 253, 222, 220, 255, 199, 128, 128, 128}, + { 81, 99, 181, 242, 176, 190, 249, 202, 255, 255, 128} + }, + { + { 1, 129, 232, 253, 214, 197, 242, 196, 255, 255, 128}, + { 99, 121, 210, 250, 201, 198, 255, 202, 128, 128, 128}, + { 23, 91, 163, 242, 170, 187, 247, 210, 255, 255, 128} + }, + { + { 1, 200, 246, 255, 234, 255, 128, 128, 128, 128, 128}, + { 109, 178, 241, 255, 231, 245, 255, 255, 128, 128, 128}, + { 44, 130, 201, 253, 205, 192, 255, 255, 128, 128, 128} + }, + { + { 1, 132, 239, 251, 219, 209, 255, 165, 128, 128, 128}, + { 94, 136, 225, 251, 218, 190, 255, 255, 128, 128, 128}, + { 22, 100, 174, 245, 186, 161, 255, 199, 128, 128, 128} + }, + { + { 1, 182, 249, 255, 232, 235, 128, 128, 128, 128, 128}, + { 124, 143, 241, 255, 227, 234, 128, 128, 128, 128, 128}, + { 35, 77, 181, 251, 193, 211, 255, 205, 128, 128, 128} + }, + { + { 1, 157, 247, 255, 236, 231, 255, 255, 128, 128, 128}, + { 121, 141, 235, 255, 225, 227, 255, 255, 128, 128, 128}, + { 45, 99, 188, 251, 195, 217, 255, 224, 128, 128, 128} + }, + { + { 1, 1, 251, 255, 213, 255, 128, 128, 128, 128, 128}, + { 203, 1, 248, 255, 255, 128, 128, 128, 128, 128, 128}, + { 137, 1, 177, 255, 224, 255, 128, 128, 128, 128, 128} + } + }, + { + { + { 253, 9, 248, 251, 207, 208, 255, 192, 128, 128, 128}, + { 175, 13, 224, 243, 193, 185, 249, 198, 255, 255, 128}, + { 73, 17, 171, 221, 161, 179, 236, 167, 255, 234, 128} + }, + { + { 1, 95, 247, 253, 212, 183, 255, 255, 128, 128, 128}, + { 239, 90, 244, 250, 211, 209, 255, 255, 128, 128, 128}, + { 155, 77, 195, 248, 188, 195, 255, 255, 128, 128, 128} + }, + { + { 1, 24, 239, 251, 218, 219, 255, 205, 128, 128, 128}, + { 201, 51, 219, 255, 196, 186, 128, 128, 128, 128, 128}, + { 69, 46, 190, 239, 201, 218, 255, 228, 128, 128, 128} + }, + { + { 1, 191, 251, 255, 255, 128, 128, 128, 128, 128, 128}, + { 223, 165, 249, 255, 213, 255, 128, 128, 128, 128, 128}, + { 141, 124, 248, 255, 255, 128, 128, 128, 128, 128, 128} + }, + { + { 1, 16, 248, 255, 255, 128, 128, 128, 128, 128, 128}, + { 190, 36, 230, 255, 236, 255, 128, 128, 128, 128, 128}, + { 149, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128} + }, + { + { 1, 226, 255, 128, 128, 128, 128, 128, 128, 128, 128}, + { 247, 192, 255, 128, 128, 128, 128, 128, 128, 128, 128}, + { 240, 128, 255, 128, 128, 128, 128, 128, 128, 128, 128} + }, + { + { 1, 134, 252, 255, 255, 128, 128, 128, 128, 128, 128}, + { 213, 62, 250, 255, 255, 128, 128, 128, 128, 128, 128}, + { 55, 93, 255, 128, 128, 128, 128, 128, 128, 128, 128} + }, + { + { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128}, + { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128}, + { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128} + } + }, + { + { + { 202, 24, 213, 235, 186, 191, 220, 160, 240, 175, 255}, + { 126, 38, 182, 232, 169, 184, 228, 174, 255, 187, 128}, + { 61, 46, 138, 219, 151, 178, 240, 170, 255, 216, 128} + }, + { + { 1, 112, 230, 250, 199, 191, 247, 159, 255, 255, 128}, + { 166, 109, 228, 252, 211, 215, 255, 174, 128, 128, 128}, + { 39, 77, 162, 232, 172, 180, 245, 178, 255, 255, 128} + }, + { + { 1, 52, 220, 246, 198, 199, 249, 220, 255, 255, 128}, + { 124, 74, 191, 243, 183, 193, 250, 221, 255, 255, 128}, + { 24, 71, 130, 219, 154, 170, 243, 182, 255, 255, 128} + }, + { + { 1, 182, 225, 249, 219, 240, 255, 224, 128, 128, 128}, + { 149, 150, 226, 252, 216, 205, 255, 171, 128, 128, 128}, + { 28, 108, 170, 242, 183, 194, 254, 223, 255, 255, 128} + }, + { + { 1, 81, 230, 252, 204, 203, 255, 192, 128, 128, 128}, + { 123, 102, 209, 247, 188, 196, 255, 233, 128, 128, 128}, + { 20, 95, 153, 243, 164, 173, 255, 203, 128, 128, 128} + }, + { + { 1, 222, 248, 255, 216, 213, 128, 128, 128, 128, 128}, + { 168, 175, 246, 252, 235, 205, 255, 255, 128, 128, 128}, + { 47, 116, 215, 255, 211, 212, 255, 255, 128, 128, 128} + }, + { + { 1, 121, 236, 253, 212, 214, 255, 255, 128, 128, 128}, + { 141, 84, 213, 252, 201, 202, 255, 219, 128, 128, 128}, + { 42, 80, 160, 240, 162, 185, 255, 205, 128, 128, 128} + }, + { + { 1, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128}, + { 244, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128}, + { 238, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128} + } + } +}; + + +#endif diff --git a/mpp/codec/dec/vp8/vp8d_parser.c b/mpp/codec/dec/vp8/vp8d_parser.c index 3174613e..b32e605a 100644 --- a/mpp/codec/dec/vp8/vp8d_parser.c +++ b/mpp/codec/dec/vp8/vp8d_parser.c @@ -1,1214 +1,1214 @@ -/* - * - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define MODULE_TAG "vp8d_parser" -#include - -#include "vp8d_parser.h" -#include "vp8d_codec.h" -#include "mpp_frame.h" -#include "mpp_env.h" - -RK_U32 vp8d_debug = 0x0; - -#define FUN_T(tag) \ - do {\ - if (VP8D_DBG_FUNCTION & vp8d_debug)\ - { mpp_log("%s: line(%d), func(%s)", tag, __LINE__, __FUNCTION__); }\ - } while (0) - - -void vp8hwdBoolStart(vpBoolCoder_t *bit_ctx, RK_U8 *buffer, RK_U32 len) -{ - FUN_T("FUN_IN"); - bit_ctx->lowvalue = 0; - bit_ctx->range = 255; - bit_ctx->count = 8; - bit_ctx->buffer = buffer; - bit_ctx->pos = 0; - - bit_ctx->value = (bit_ctx->buffer[0] << 24) + (bit_ctx->buffer[1] << 16) + (bit_ctx->buffer[2] << 8) + (bit_ctx->buffer[3]); - - bit_ctx->pos += 4; - - bit_ctx->streamEndPos = len; - bit_ctx->strmError = bit_ctx->pos > bit_ctx->streamEndPos; - - FUN_T("FUN_OUT"); -} - -RK_U32 vp8hwdDecodeBool(vpBoolCoder_t *bit_ctx, RK_S32 probability) -{ - RK_U32 bit = 0; - RK_U32 split; - RK_U32 bigsplit; - RK_U32 count = bit_ctx->count; - RK_U32 range = bit_ctx->range; - RK_U32 value = bit_ctx->value; - - FUN_T("FUN_IN"); - split = 1 + (((range - 1) * probability) >> 8); - bigsplit = (split << 24); - range = split; - - if (value >= bigsplit) { - range = bit_ctx->range - split; - value = value - bigsplit; - bit = 1; - } - - if (range >= 0x80) { - bit_ctx->value = value; - bit_ctx->range = range; - return bit; - } else { - do { - range += range; - value += value; - - if (!--count) { - /* no more stream to read? */ - if (bit_ctx->pos >= bit_ctx->streamEndPos) { - bit_ctx->strmError = 1; - mpp_log("vp8hwdDecodeBool read end"); - break; - } - count = 8; - value |= bit_ctx->buffer[bit_ctx->pos]; - bit_ctx->pos++; - } - } while (range < 0x80); - } - - - bit_ctx->count = count; - bit_ctx->value = value; - bit_ctx->range = range; - - FUN_T("FUN_OUT"); - return bit; -} - -RK_U32 vp8hwdDecodeBool128(vpBoolCoder_t *bit_ctx) -{ - RK_U32 bit = 0; - RK_U32 split; - RK_U32 bigsplit; - RK_U32 count = bit_ctx->count; - RK_U32 range = bit_ctx->range; - RK_U32 value = bit_ctx->value; - - FUN_T("FUN_IN"); - split = (range + 1) >> 1; - bigsplit = (split << 24); - range = split; - - if (value >= bigsplit) { - range = (bit_ctx->range - split); - value = (value - bigsplit); - bit = 1; - } - - if (range >= 0x80) { - bit_ctx->value = value; - bit_ctx->range = range; - - FUN_T("FUN_OUT"); - return bit; - } else { - range <<= 1; - value <<= 1; - - if (!--count) { - /* no more stream to read? */ - if (bit_ctx->pos >= bit_ctx->streamEndPos) { - bit_ctx->strmError = 1; - mpp_log("vp8hwdDecodeBool128 read end"); - return 0; /* any value, not valid */ - } - count = 8; - value |= bit_ctx->buffer[bit_ctx->pos]; - bit_ctx->pos++; - } - } - - bit_ctx->count = count; - bit_ctx->value = value; - bit_ctx->range = range; - - FUN_T("FUN_OUT"); - return bit; -} - -RK_U32 vp8hwdReadBits(vpBoolCoder_t *bit_ctx, RK_S32 bits) -{ - RK_U32 z = 0; - RK_S32 bit; - - FUN_T("FUN_IN"); - for (bit = bits - 1; bit >= 0; bit--) { - z |= (vp8hwdDecodeBool128(bit_ctx) << bit); - } - - FUN_T("FUN_OUT"); - return z; -} - -RK_U32 ScaleDimension( RK_U32 orig, RK_U32 scale ) -{ - - FUN_T("FUN_IN"); - switch (scale) { - case 0: - return orig; - break; - case 1: /* 5/4 */ - return (5 * orig) / 4; - break; - case 2: /* 5/3 */ - return (5 * orig) / 3; - break; - case 3: /* 2 */ - return 2 * orig; - break; - } - - FUN_T("FUN_OUT"); - return orig; -} - -RK_S32 DecodeQuantizerDelta(vpBoolCoder_t *bit_ctx) -{ - RK_S32 result = 0; - - FUN_T("FUN_IN"); - if (vp8hwdDecodeBool128(bit_ctx)) { - result = vp8hwdReadBits(bit_ctx, 4); - if (vp8hwdDecodeBool128(bit_ctx)) - result = -result; - } - - FUN_T("FUN_OUT"); - return result; -} - -MPP_RET vp8d_parser_init(void *ctx, ParserCfg *parser_cfg) -{ - MPP_RET ret = MPP_OK; - VP8DContext *c = (VP8DContext *)ctx; - VP8DParserContext_t *p = (VP8DParserContext_t *)c->parse_ctx; - - FUN_T("FUN_IN"); - if (p == NULL) { - p = (VP8DParserContext_t*)mpp_calloc(VP8DParserContext_t, 1); - if (NULL == p) { - mpp_err("vp8d malloc VP8DParserContext_t fail"); - FUN_T("FUN_OUT"); - return MPP_ERR_NOMEM; - } - c->parse_ctx = p; - } - p->packet_slots = parser_cfg->packet_slots; - p->frame_slots = parser_cfg->frame_slots; - p->notify_cb = parser_cfg->notify_cb; - - mpp_buf_slot_setup(p->frame_slots, 15); - - p->dxva_ctx = mpp_calloc(DXVA_PicParams_VP8, 1); - - if (NULL == p->dxva_ctx) { - mpp_err("vp8d malloc dxva_ctx fail"); - FUN_T("FUN_OUT"); - return MPP_ERR_NOMEM; - } - p->decMode = VP8HWD_VP8; - p->bitstream_sw_buf = mpp_malloc(RK_U8, VP8D_BUF_SIZE_BITMEM); - mpp_packet_init(&p->input_packet, p->bitstream_sw_buf, VP8D_BUF_SIZE_BITMEM); - p->max_stream_size = VP8D_BUF_SIZE_BITMEM; - - FUN_T("FUN_OUT"); - return ret; -} - -void vp8d_unref_frame(VP8DParserContext_t *p, VP8Frame *frame) -{ - - FUN_T("FUN_IN"); - if (NULL == frame || frame->ref_count <= 0 - || frame->slot_index >= 0x7f) { - mpp_err("ref count alreay is zero"); - FUN_T("FUN_OUT"); - return; - } - frame->ref_count--; - if (!frame->ref_count && frame->slot_index < 0x7f) { - mpp_buf_slot_clr_flag(p->frame_slots, frame->slot_index, SLOT_CODEC_USE); - frame->slot_index = 0xff; - mpp_free(frame->f); - mpp_free(frame); - frame = NULL; - } - - FUN_T("FUN_OUT"); - return; -} - -void vp8d_unref_allframe(VP8DParserContext_t *p) -{ - - FUN_T("FUN_IN"); - if (NULL != p->frame_out) { - vp8d_unref_frame(p, p->frame_out); - p->frame_out = NULL; - } - - if (NULL != p->frame_ref) { - vp8d_unref_frame(p, p->frame_ref); - p->frame_ref = NULL; - } - - if (NULL != p->frame_golden) { - vp8d_unref_frame(p, p->frame_golden); - p->frame_golden = NULL; - } - - if (NULL != p->frame_alternate) { - vp8d_unref_frame(p, p->frame_alternate); - p->frame_alternate = NULL; - } - - FUN_T("FUN_OUT"); - return; -} - -MPP_RET vp8d_parser_deinit(void *ctx) -{ - MPP_RET ret = MPP_OK; - VP8DContext *c = (VP8DContext *)ctx; - VP8DParserContext_t *p = (VP8DParserContext_t *)c->parse_ctx; - - FUN_T("FUN_IN"); - - if (NULL != p->bitstream_sw_buf) { - mpp_free(p->bitstream_sw_buf); - p->bitstream_sw_buf = NULL; - } - - if (NULL != p->dxva_ctx) { - mpp_free(p->dxva_ctx); - p->dxva_ctx = NULL; - } - - vp8d_unref_allframe(p); - - if ( NULL != p) { - mpp_free(p); - } - FUN_T("FUN_OUT"); - return ret; -} -/*! -*********************************************************************** -* \brief -* reset -*********************************************************************** -*/ -MPP_RET vp8d_parser_reset(void *ctx) -{ - MPP_RET ret = MPP_OK; - VP8DContext *c = (VP8DContext *)ctx; - VP8DParserContext_t *p = (VP8DParserContext_t *)c->parse_ctx; - - FUN_T("FUN_IN"); - vp8d_unref_allframe(p); - p->needKeyFrame = 0; - p->eos = 0; - FUN_T("FUN_OUT"); - return ret; -} - -/*! -*********************************************************************** -* \brief -* flush -*********************************************************************** -*/ -MPP_RET vp8d_parser_flush(void *ctx) -{ - MPP_RET ret = MPP_OK; - - FUN_T("FUN_IN"); - (void) ctx; - FUN_T("FUN_OUT"); - return ret; -} - -/*! -*********************************************************************** -* \brief -* control/perform -*********************************************************************** -*/ -MPP_RET vp8d_parser_control(void *ctx, RK_S32 cmd_type, void *param) -{ - MPP_RET ret = MPP_OK; - - FUN_T("FUN_IN"); - (void)ctx; - (void)cmd_type; - (void)param; - - FUN_T("FUN_OUT"); - return ret; -} - - -/*! -*********************************************************************** -* \brief -* prepare -*********************************************************************** -*/ - -MPP_RET vp8d_parser_split_frame(RK_U8 *src, RK_U32 src_size, RK_U8 *dst, RK_U32 *dst_size) -{ - MPP_RET ret = MPP_OK; - - FUN_T("FUN_IN"); - memcpy(dst, src, src_size);; - *dst_size = src_size; - - (void)dst; - - FUN_T("FUN_OUT"); - return ret; -} - - -MPP_RET vp8d_parser_prepare(void *ctx, MppPacket pkt, HalDecTask *task) -{ - MPP_RET ret = MPP_OK; - RK_U32 out_size = 0, len_in = 0; - RK_U8 * pos = NULL; - RK_U8 *buf = NULL; - VP8DContext *c = (VP8DContext *)ctx; - - VP8DParserContext_t *p = (VP8DParserContext_t *)c->parse_ctx; - MppPacket input_packet = p->input_packet; - - FUN_T("FUN_IN"); - task->valid = 0; - - - buf = pos = mpp_packet_get_pos(pkt); - p->pts = mpp_packet_get_pts(pkt); - - len_in = (RK_U32)mpp_packet_get_length(pkt), - p->eos = mpp_packet_get_eos(pkt); - // mpp_log("len_in = %d",len_in); - if (len_in > p->max_stream_size) { - mpp_free(p->bitstream_sw_buf); - p->bitstream_sw_buf = NULL; - p->bitstream_sw_buf = mpp_malloc(RK_U8, (len_in + 1024)); - if (NULL == p->bitstream_sw_buf) { - mpp_err("vp8d_parser realloc fail"); - return MPP_ERR_NOMEM; - } - p->max_stream_size = len_in + 1024; - } - - vp8d_parser_split_frame(buf, - len_in, - p->bitstream_sw_buf, - &out_size); - pos += out_size; - - mpp_packet_set_pos(pkt, pos); - - if (out_size == 0 && p->eos) { - task->flags.eos = p->eos; - return ret; - } - - - - // mpp_log("p->bitstream_sw_buf = 0x%x", p->bitstream_sw_buf); - // mpp_log("out_size = 0x%x", out_size); - mpp_packet_set_data(input_packet, p->bitstream_sw_buf); - mpp_packet_set_size(input_packet, p->max_stream_size); - mpp_packet_set_length(input_packet, out_size); - p->stream_size = out_size; - task->input_packet = input_packet; - task->valid = 1; - - FUN_T("FUN_OUT"); - return ret; -} - -MPP_RET vp8d_convert_to_syntx( VP8DParserContext_t *p, HalDecTask *in_task) -{ - MPP_RET ret = MPP_OK; - RK_U32 i, tmp; - RK_U32 byteOffset = 0, extraBytesPacked = 0; - DXVA_PicParams_VP8 *pic_param = p->dxva_ctx; - - FUN_T("FUN_IN"); - tmp = (p->bitstr.pos) * 8 + (8 - p->bitstr.count); - - if (p->frameTagSize == 4) - tmp += 8; - - if (p->decMode == VP8HWD_VP8 && p->keyFrame) - extraBytesPacked += 7; - - tmp += extraBytesPacked * 8; - byteOffset = tmp / 8; - pic_param->stream_start_bit = (byteOffset & 0x07U) * 8; - byteOffset &= (~0x07U); /* align the base */ - pic_param->stream_start_offset = byteOffset; - - pic_param->stream_start_bit += (tmp & 0x7); - - pic_param->frame_type = !p->keyFrame; - pic_param->stVP8Segments.segmentation_enabled = p->segmentationEnabled; - pic_param->stVP8Segments.update_mb_segmentation_map = p->segmentationMapUpdate; - pic_param->mode_ref_lf_delta_enabled = p->modeRefLfEnabled; - pic_param->mb_no_coeff_skip = p->coeffSkipMode; - pic_param->width = p->width; - pic_param->height = p->height; - pic_param->decMode = p->decMode; - pic_param->filter_type = p->loopFilterType; - pic_param->sharpness = p->loopFilterSharpness; - pic_param->filter_level = p->loopFilterLevel; - pic_param->stVP8Segments.update_mb_segmentation_data = p->segmentFeatureMode; - pic_param->version = p->vpVersion; - pic_param->bool_value = ((p->bitstr.value >> 24) & (0xFFU)); - pic_param->bool_range = (p->bitstr.range & (0xFFU)); - pic_param->frameTagSize = p->frameTagSize; - pic_param->streamEndPos = p->bitstr.streamEndPos; - pic_param->log2_nbr_of_dct_partitions = p->nbrDctPartitions; - pic_param->offsetToDctParts = p->offsetToDctParts; - - pic_param->y1ac_delta_q = p->qpYAc; - pic_param->y1dc_delta_q = p->qpYDc; - pic_param->y2ac_delta_q = p->qpY2Ac; - pic_param->y2dc_delta_q = p->qpY2Dc; - pic_param->uvac_delta_q = p->qpChAc; - pic_param->uvdc_delta_q = p->qpChDc; - pic_param->probe_skip_false = p->probMbSkipFalse; - pic_param->prob_intra = p->probIntra; - pic_param->prob_last = p->probRefLast; - pic_param->prob_golden = p->probRefGolden; - - memcpy(pic_param->vp8_coef_update_probs, p->entropy.probCoeffs, sizeof(pic_param->vp8_coef_update_probs)); - memcpy(pic_param->vp8_mv_update_probs, p->entropy.probMvContext, sizeof(pic_param->vp8_mv_update_probs)); - - for ( i = 0; i < 3; i++) { - pic_param->intra_chroma_prob[i] = p->entropy.probChromaPredMode[i]; - pic_param->stVP8Segments.mb_segment_tree_probs[i] = p->probSegment[i]; - } - - pic_param->ref_frame_sign_bias_golden = p->refFrameSignBias[0]; - pic_param->ref_frame_sign_bias_altref = p->refFrameSignBias[1]; - - - for (i = 0; i < 4; i++) { - pic_param->stVP8Segments.segment_feature_data[0][i] = p->segmentQp[i]; - pic_param->ref_lf_deltas[i] = p->mbRefLfDelta[i]; - pic_param->mode_lf_deltas[i] = p->mbModeLfDelta[i]; - pic_param->stVP8Segments.segment_feature_data[1][i] = p->segmentLoopfilter[i]; - pic_param->intra_16x16_prob[i] = p->entropy.probLuma16x16PredMode[i]; - } - - p->dxva_ctx->CurrPic.Index7Bits = p->frame_out->slot_index; - memset(in_task->refer, -1, sizeof(in_task->refer)); - - if (p->frame_ref != NULL) { - pic_param->lst_fb_idx.Index7Bits = p->frame_ref->slot_index; - mpp_buf_slot_set_flag(p->frame_slots, p->frame_ref->slot_index, SLOT_HAL_INPUT); - in_task->refer[0] = p->frame_ref->slot_index; - } else { - pic_param->lst_fb_idx.Index7Bits = 0x7f; - } - - if (p->frame_golden != NULL) { - pic_param->gld_fb_idx.Index7Bits = p->frame_golden->slot_index; - mpp_buf_slot_set_flag(p->frame_slots, p->frame_golden->slot_index, SLOT_HAL_INPUT); - in_task->refer[1] = p->frame_golden->slot_index; - } else { - pic_param->gld_fb_idx.Index7Bits = 0x7f; - } - - if (p->frame_alternate != NULL) { - pic_param->alt_fb_idx.Index7Bits = p->frame_alternate->slot_index; - mpp_buf_slot_set_flag(p->frame_slots, p->frame_alternate->slot_index, SLOT_HAL_INPUT); - in_task->refer[2] = p->frame_alternate->slot_index; - } else { - pic_param->alt_fb_idx.Index7Bits = 0x7f; - } - - memcpy(pic_param->dctPartitionOffsets, p->dctPartitionOffsets, sizeof(p->dctPartitionOffsets)); - - FUN_T("FUN_OUT"); - return ret; -} - -MPP_RET vp8d_alloc_frame(VP8DParserContext_t *p) -{ - MPP_RET ret = MPP_OK; - - FUN_T("FUN_IN"); - if (NULL == p->frame_out) { - p->frame_out = mpp_calloc(VP8Frame, 1); - if (NULL == p->frame_out) { - mpp_err("alloc vp8 frame fail"); - return MPP_ERR_NOMEM; - } - - if (NULL == p->frame_out->f) { - mpp_frame_init(&p->frame_out->f); - if (NULL == p->frame_out->f) { - mpp_err("alloc vp8 mpp frame fail"); - return MPP_ERR_NOMEM; - } - } - p->frame_out->slot_index = 0xff; - } - - if (p->frame_out->slot_index == 0xff) { - mpp_frame_set_width(p->frame_out->f, p->width); - mpp_frame_set_height(p->frame_out->f, p->height); - mpp_frame_set_hor_stride(p->frame_out->f, p->width); - mpp_frame_set_ver_stride(p->frame_out->f, p->height); - mpp_frame_set_errinfo(p->frame_out->f, 0); - mpp_frame_set_pts(p->frame_out->f, p->pts); - ret = mpp_buf_slot_get_unused(p->frame_slots, &p->frame_out->slot_index); - if (MPP_OK != ret) { - mpp_err("vp8 buf_slot_get_unused get fail"); - return ret; - } - mpp_buf_slot_set_prop(p->frame_slots, p->frame_out->slot_index, SLOT_FRAME, p->frame_out->f); - mpp_buf_slot_set_flag(p->frame_slots, p->frame_out->slot_index, SLOT_CODEC_USE); - mpp_buf_slot_set_flag(p->frame_slots, p->frame_out->slot_index, SLOT_HAL_OUTPUT); - mpp_frame_set_mode(p->frame_out->f, 0); - - if (p->showFrame) { - mpp_buf_slot_set_flag(p->frame_slots, p->frame_out->slot_index, SLOT_QUEUE_USE); - mpp_buf_slot_enqueue(p->frame_slots, p->frame_out->slot_index, QUEUE_DISPLAY); - } - p->frame_out->ref_count++; - } - - FUN_T("FUN_OUT"); - return ret; -} - -void vp8d_ref_frame(VP8Frame *frame) -{ - - FUN_T("FUN_IN"); - if ((NULL == frame) || (frame->slot_index >= 0x7f)) { - mpp_err("frame is null or slot_index is no valid"); - return; - } - frame->ref_count++; - - FUN_T("FUN_OUT"); -} - - -MPP_RET vp8d_ref_update(VP8DParserContext_t *p) -{ - - FUN_T("FUN_IN"); - if (p->decMode != VP8HWD_WEBP) { - if (p->copyBufferToAlternate == 1) { - if (NULL != p->frame_alternate) { - vp8d_unref_frame(p, p->frame_alternate); - p->frame_alternate = NULL; - } - p->frame_alternate = p->frame_ref; - vp8d_ref_frame(p->frame_alternate); - } else if (p->copyBufferToAlternate == 2) { - if (NULL != p->frame_alternate) { - vp8d_unref_frame(p, p->frame_alternate); - p->frame_alternate = NULL; - } - p->frame_alternate = p->frame_golden; - vp8d_ref_frame(p->frame_alternate); - } - - if (p->copyBufferToGolden == 1) { - if (NULL != p->frame_golden) { - vp8d_unref_frame(p, p->frame_golden); - p->frame_golden = NULL; - } - p->frame_golden = p->frame_ref; - vp8d_ref_frame(p->frame_golden); - } else if (p->copyBufferToGolden == 2) { - if (NULL != p->frame_golden) { - vp8d_unref_frame(p, p->frame_golden); - p->frame_golden = NULL; - } - p->frame_golden = p->frame_alternate; - vp8d_ref_frame(p->frame_golden); - } - - if (p->refreshGolden) { - if (NULL != p->frame_golden) { - vp8d_unref_frame(p, p->frame_golden); - p->frame_golden = NULL; - } - p->frame_golden = p->frame_out; - vp8d_ref_frame(p->frame_golden); - } - - if (p->refreshAlternate) { - if (NULL != p->frame_alternate) { - vp8d_unref_frame(p, p->frame_alternate); - p->frame_alternate = NULL; - } - p->frame_alternate = p->frame_out; - vp8d_ref_frame(p->frame_out); - } - - if (p->refreshLast) { - if (NULL != p->frame_ref) { - vp8d_unref_frame(p, p->frame_ref); - p->frame_ref = NULL; - } - p->frame_ref = p->frame_out; - vp8d_ref_frame(p->frame_ref); - } - vp8d_unref_frame(p, p->frame_out); - p->frame_out = NULL; - } - - FUN_T("FUN_OUT"); - return 0; -} - -void vp8hwdResetProbs(VP8DParserContext_t *p) -{ - RK_U32 i, j, k, l; - static const RK_U32 Vp7DefaultScan[] = { - 0, 1, 4, 8, 5, 2, 3, 6, - 9, 12, 13, 10, 7, 11, 14, 15, - }; - - FUN_T("FUN_IN"); - for ( i = 0 ; i < 16 ; ++i ) - p->vp7ScanOrder[i] = Vp7DefaultScan[i]; - - - /* Intra-prediction modes */ - p->entropy.probLuma16x16PredMode[0] = 112; - p->entropy.probLuma16x16PredMode[1] = 86; - p->entropy.probLuma16x16PredMode[2] = 140; - p->entropy.probLuma16x16PredMode[3] = 37; - p->entropy.probChromaPredMode[0] = 162; - p->entropy.probChromaPredMode[1] = 101; - p->entropy.probChromaPredMode[2] = 204; - - for (i = 0; i < MAX_NBR_OF_MB_REF_LF_DELTAS; i++) - p->mbRefLfDelta[i] = 0; - - for (i = 0; i < MAX_NBR_OF_MB_MODE_LF_DELTAS; i++) - p->mbModeLfDelta[i] = 0; - - /* MV context */ - k = 0; - if (p->decMode == VP8HWD_VP8) { - for ( i = 0 ; i < 2 ; ++i ) - for ( j = 0 ; j < VP8_MV_PROBS_PER_COMPONENT ; ++j, ++k ) - p->entropy.probMvContext[i][j] = Vp8DefaultMvProbs[i][j]; - } else { - for ( i = 0 ; i < 2 ; ++i ) - for ( j = 0 ; j < VP7_MV_PROBS_PER_COMPONENT ; ++j, ++k ) - p->entropy.probMvContext[i][j] = Vp7DefaultMvProbs[i][j]; - } - - /* Coefficients */ - for ( i = 0 ; i < 4 ; ++i ) - for ( j = 0 ; j < 8 ; ++j ) - for ( k = 0 ; k < 3 ; ++k ) - for ( l = 0 ; l < 11 ; ++l ) - p->entropy.probCoeffs[i][j][k][l] = DefaultCoeffProbs[i][j][k][l]; - - FUN_T("FUN_OUT"); -} - -void vp8hwdDecodeCoeffUpdate(VP8DParserContext_t *p) -{ - RK_U32 i, j, k, l; - - FUN_T("FUN_IN"); - for ( i = 0; i < 4; i++ ) { - for ( j = 0; j < 8; j++ ) { - for ( k = 0; k < 3; k++ ) { - for ( l = 0; l < 11; l++ ) { - if (vp8hwdDecodeBool(&p->bitstr, CoeffUpdateProbs[i][j][k][l])) - p->entropy.probCoeffs[i][j][k][l] = vp8hwdReadBits(&p->bitstr, 8); - } - } - } - } - FUN_T("FUN_OUT"); -} - -MPP_RET vp8_header_parser(VP8DParserContext_t *p, RK_U8 *pbase, RK_U32 size) -{ - RK_U32 tmp; - int i, j; - vpBoolCoder_t *bit_ctx = &p->bitstr; - - FUN_T("FUN_IN"); - if (p->keyFrame) { - tmp = (pbase[0] << 16) | (pbase[1] << 8) | (pbase[2] << 0); - if (tmp != VP8_KEY_FRAME_START_CODE) - return MPP_ERR_PROTOL; - tmp = (pbase[3] << 0) | (pbase[4] << 8); - p->width = tmp & 0x3fff; - p->scaledWidth = ScaleDimension(p->width, tmp >> 14); - tmp = (pbase[5] << 0) | (pbase[6] << 8); - p->height = tmp & 0x3fff; - p->scaledHeight = ScaleDimension(p->height, tmp >> 14); - pbase += 7; - size -= 7; - } - vp8hwdBoolStart(bit_ctx, pbase, size); - if (p->keyFrame) { - p->colorSpace = (vpColorSpace_e)vp8hwdDecodeBool128(bit_ctx); - p->clamping = vp8hwdDecodeBool128(bit_ctx); - } - p->segmentationEnabled = vp8hwdDecodeBool128(bit_ctx); - p->segmentationMapUpdate = 0; - if (p->segmentationEnabled) { - p->segmentationMapUpdate = vp8hwdDecodeBool128(bit_ctx); - if (vp8hwdDecodeBool128(bit_ctx)) { /* Segmentation map update */ - p->segmentFeatureMode = vp8hwdDecodeBool128(bit_ctx); - memset(&p->segmentQp[0], 0, MAX_NBR_OF_SEGMENTS * sizeof(RK_S32)); - memset(&p->segmentLoopfilter[0], 0, MAX_NBR_OF_SEGMENTS * sizeof(RK_S32)); - for (i = 0; i < MAX_NBR_OF_SEGMENTS; i++) { - if (vp8hwdDecodeBool128(bit_ctx)) { - p->segmentQp[i] = vp8hwdReadBits(bit_ctx, 7); - if (vp8hwdDecodeBool128(bit_ctx)) - p->segmentQp[i] = -p->segmentQp[i]; - } - } - for (i = 0; i < MAX_NBR_OF_SEGMENTS; i++) { - if (vp8hwdDecodeBool128(bit_ctx)) { - p->segmentLoopfilter[i] = vp8hwdReadBits(bit_ctx, 6); - if (vp8hwdDecodeBool128(bit_ctx)) - p->segmentLoopfilter[i] = -p->segmentLoopfilter[i]; - } - } - } - if (p->segmentationMapUpdate) { - p->probSegment[0] = 255; - p->probSegment[1] = 255; - p->probSegment[2] = 255; - for (i = 0; i < 3; i++) { - if (vp8hwdDecodeBool128(bit_ctx)) { - p->probSegment[i] = vp8hwdReadBits(bit_ctx, 8); - } - } - } - if (bit_ctx->strmError) { - mpp_err_f("paser header stream no enough"); - FUN_T("FUN_OUT"); - return MPP_ERR_STREAM; - } - } - p->loopFilterType = vp8hwdDecodeBool128(bit_ctx); - p->loopFilterLevel = vp8hwdReadBits(bit_ctx, 6); - p->loopFilterSharpness = vp8hwdReadBits(bit_ctx, 3); - p->modeRefLfEnabled = vp8hwdDecodeBool128(bit_ctx); - if (p->modeRefLfEnabled) { - if (vp8hwdDecodeBool128(bit_ctx)) { - for (i = 0; i < MAX_NBR_OF_MB_REF_LF_DELTAS; i++) { - if (vp8hwdDecodeBool128(bit_ctx)) { - p->mbRefLfDelta[i] = vp8hwdReadBits(bit_ctx, 6); - if (vp8hwdDecodeBool128(bit_ctx)) - p->mbRefLfDelta[i] = -p->mbRefLfDelta[i]; - } - } - for (i = 0; i < MAX_NBR_OF_MB_MODE_LF_DELTAS; i++) { - if (vp8hwdDecodeBool128(&p->bitstr)) { - p->mbModeLfDelta[i] = vp8hwdReadBits(bit_ctx, 6); - if (vp8hwdDecodeBool128(bit_ctx)) - p->mbModeLfDelta[i] = -p->mbModeLfDelta[i]; - } - } - } - } - if (bit_ctx->strmError) { - mpp_err_f("paser header stream no enough"); - FUN_T("FUN_OUT"); - return MPP_ERR_STREAM; - } - p->nbrDctPartitions = vp8hwdReadBits(bit_ctx, 2); - p->qpYAc = vp8hwdReadBits(bit_ctx, 7); - p->qpYDc = DecodeQuantizerDelta(bit_ctx); - p->qpY2Dc = DecodeQuantizerDelta(bit_ctx); - p->qpY2Ac = DecodeQuantizerDelta(bit_ctx); - p->qpChDc = DecodeQuantizerDelta(bit_ctx); - p->qpChAc = DecodeQuantizerDelta(bit_ctx); - if (p->keyFrame) { - p->refreshGolden = 1; - p->refreshAlternate = 1; - p->copyBufferToGolden = 0; - p->copyBufferToAlternate = 0; - - /* Refresh entropy probs */ - p->refreshEntropyProbs = vp8hwdDecodeBool128(bit_ctx); - - p->refFrameSignBias[0] = 0; - p->refFrameSignBias[1] = 0; - p->refreshLast = 1; - } else { - /* Refresh golden */ - p->refreshGolden = vp8hwdDecodeBool128(bit_ctx); - /* Refresh alternate */ - p->refreshAlternate = vp8hwdDecodeBool128(bit_ctx); - if ( p->refreshGolden == 0 ) { - /* Copy to golden */ - p->copyBufferToGolden = vp8hwdReadBits(bit_ctx, 2); - } else - p->copyBufferToGolden = 0; - - if ( p->refreshAlternate == 0 ) { - /* Copy to alternate */ - p->copyBufferToAlternate = vp8hwdReadBits(bit_ctx, 2); - } else - p->copyBufferToAlternate = 0; - - /* Sign bias for golden frame */ - p->refFrameSignBias[0] = vp8hwdDecodeBool128(bit_ctx); - /* Sign bias for alternate frame */ - p->refFrameSignBias[1] = vp8hwdDecodeBool128(bit_ctx); - /* Refresh entropy probs */ - p->refreshEntropyProbs = vp8hwdDecodeBool128(bit_ctx); - /* Refresh last */ - p->refreshLast = vp8hwdDecodeBool128(bit_ctx); - } - - /* Make a "backup" of current entropy probabilities if refresh is not set */ - if (p->refreshEntropyProbs == 0) { - memcpy((void*)&p->entropyLast, (void*)&p->entropy, (unsigned long)sizeof(vp8EntropyProbs_t)); - memcpy( (void*)p->vp7PrevScanOrder, (void*)p->vp7ScanOrder, (unsigned long)sizeof(p->vp7ScanOrder)); - } - - vp8hwdDecodeCoeffUpdate(p); - p->coeffSkipMode = vp8hwdDecodeBool128(bit_ctx); - if (!p->keyFrame) { - RK_U32 mvProbs; - - p->probMbSkipFalse = vp8hwdReadBits(bit_ctx, 8); - p->probIntra = vp8hwdReadBits(bit_ctx, 8); - p->probRefLast = vp8hwdReadBits(bit_ctx, 8); - p->probRefGolden = vp8hwdReadBits(bit_ctx, 8); - if (vp8hwdDecodeBool128(bit_ctx)) { - for (i = 0; i < 4; i++) - p->entropy.probLuma16x16PredMode[i] = vp8hwdReadBits(bit_ctx, 8); - } - if (vp8hwdDecodeBool128(bit_ctx)) { - for (i = 0; i < 3; i++) - p->entropy.probChromaPredMode[i] = vp8hwdReadBits(bit_ctx, 8); - } - mvProbs = VP8_MV_PROBS_PER_COMPONENT; - for ( i = 0 ; i < 2 ; ++i ) { - for ( j = 0 ; j < (RK_S32)mvProbs ; ++j ) { - if (vp8hwdDecodeBool(bit_ctx, MvUpdateProbs[i][j]) == 1) { - tmp = vp8hwdReadBits(bit_ctx, 7); - if ( tmp ) - tmp = tmp << 1; - else - tmp = 1; - p->entropy.probMvContext[i][j] = tmp; - } - } - } - } else { - p->probMbSkipFalse = vp8hwdReadBits(bit_ctx, 8); - } - if (bit_ctx->strmError) { - mpp_err_f("paser header stream no enough"); - FUN_T("FUN_OUT"); - return MPP_ERR_STREAM; - } - FUN_T("FUN_OUT"); - return MPP_OK; -} - -MPP_RET vp7_header_parser(VP8DParserContext_t *p, RK_U8 *pbase, RK_U32 size) -{ - RK_U32 tmp; - int i, j; - - FUN_T("FUN_IN"); - vpBoolCoder_t *bit_ctx = &p->bitstr; - vp8hwdBoolStart(bit_ctx, pbase, size); - - if (p->keyFrame) { - p->width = vp8hwdReadBits(bit_ctx, 12); - p->height = vp8hwdReadBits(bit_ctx, 12); - tmp = vp8hwdReadBits(bit_ctx, 2); - p->scaledWidth = ScaleDimension(p->width, tmp); - tmp = vp8hwdReadBits(bit_ctx, 2); - p->scaledHeight = ScaleDimension(p->height, tmp); - } - { - const RK_U32 vp70FeatureBits[4] = { 7, 6, 0, 8 }; - const RK_U32 vp71FeatureBits[4] = { 7, 6, 0, 5 }; - const RK_U32 *featureBits; - if (p->vpVersion == 0) - featureBits = vp70FeatureBits; - else - featureBits = vp71FeatureBits; - for (i = 0; i < MAX_NBR_OF_VP7_MB_FEATURES; i++) { - if (vp8hwdDecodeBool128(bit_ctx)) { - tmp = vp8hwdReadBits(bit_ctx, 8); - for (j = 0; j < 3; j++) { - if (vp8hwdDecodeBool128(bit_ctx)) - tmp = vp8hwdReadBits(bit_ctx, 8); - } - if (featureBits[i]) { - for (j = 0; j < 4; j++) { - if (vp8hwdDecodeBool128(bit_ctx)) - tmp = vp8hwdReadBits(bit_ctx, featureBits[i]); - } - } - FUN_T("FUN_OUT"); - return MPP_ERR_PROTOL; - } - - } - p->nbrDctPartitions = 0; - } - p->qpYAc = (RK_S32)vp8hwdReadBits(bit_ctx, 7 ); - p->qpYDc = vp8hwdReadBits(bit_ctx, 1 ) ? (RK_S32)vp8hwdReadBits(bit_ctx, 7 ) : p->qpYAc; - p->qpY2Dc = vp8hwdReadBits(bit_ctx, 1 ) ? (RK_S32)vp8hwdReadBits(bit_ctx, 7 ) : p->qpYAc; - p->qpY2Ac = vp8hwdReadBits(bit_ctx, 1 ) ? (RK_S32)vp8hwdReadBits(bit_ctx, 7 ) : p->qpYAc; - p->qpChDc = vp8hwdReadBits(bit_ctx, 1 ) ? (RK_S32)vp8hwdReadBits(bit_ctx, 7 ) : p->qpYAc; - p->qpChAc = vp8hwdReadBits(bit_ctx, 1 ) ? (RK_S32)vp8hwdReadBits(bit_ctx, 7 ) : p->qpYAc; - if (!p->keyFrame) { - p->refreshGolden = vp8hwdDecodeBool128(bit_ctx); - if (p->vpVersion >= 1) { - p->refreshEntropyProbs = vp8hwdDecodeBool128(bit_ctx); - p->refreshLast = vp8hwdDecodeBool128(bit_ctx); - } else { - p->refreshEntropyProbs = 1; - p->refreshLast = 1; - } - } else { - p->refreshGolden = 1; - p->refreshAlternate = 1; - p->copyBufferToGolden = 0; - p->copyBufferToAlternate = 0; - if (p->vpVersion >= 1) - p->refreshEntropyProbs = vp8hwdDecodeBool128(bit_ctx); - else - p->refreshEntropyProbs = 1; - p->refFrameSignBias[0] = 0; - p->refFrameSignBias[1] = 0; - p->refreshLast = 1; - } - - if (!p->refreshEntropyProbs) { - memcpy(&p->entropyLast, &p->entropy, (unsigned long)sizeof(vp8EntropyProbs_t)); - memcpy(p->vp7PrevScanOrder, p->vp7ScanOrder, (unsigned long)sizeof(p->vp7ScanOrder)); - } - if (p->refreshLast) { - if (vp8hwdDecodeBool128(bit_ctx)) { - tmp = vp8hwdReadBits(bit_ctx, 8); - tmp = vp8hwdReadBits(bit_ctx, 8); - FUN_T("FUN_OUT"); - return MPP_ERR_STREAM; - } - } - if (p->vpVersion == 0) { - p->loopFilterType = vp8hwdDecodeBool128(bit_ctx); - } - if (vp8hwdDecodeBool128(bit_ctx)) { - static const RK_U32 Vp7DefaultScan[] = { - 0, 1, 4, 8, 5, 2, 3, 6, - 9, 12, 13, 10, 7, 11, 14, 15, - }; - p->vp7ScanOrder[0] = 0; - for (i = 1; i < 16; i++) - p->vp7ScanOrder[i] = Vp7DefaultScan[vp8hwdReadBits(bit_ctx, 4)]; - } - if (p->vpVersion >= 1) - p->loopFilterType = vp8hwdDecodeBool128(bit_ctx); - p->loopFilterLevel = vp8hwdReadBits(bit_ctx, 6); - p->loopFilterSharpness = vp8hwdReadBits(bit_ctx, 3); - vp8hwdDecodeCoeffUpdate(p); - if (!p->keyFrame) { - p->probIntra = vp8hwdReadBits(bit_ctx, 8); - p->probRefLast = vp8hwdReadBits(bit_ctx, 8); - if (vp8hwdDecodeBool128(bit_ctx)) { - for (i = 0; i < 4; i++) - p->entropy.probLuma16x16PredMode[i] = vp8hwdReadBits(bit_ctx, 8); - } - if (vp8hwdDecodeBool128(bit_ctx)) { - for (i = 0; i < 3; i++) - p->entropy.probChromaPredMode[i] = vp8hwdReadBits(bit_ctx, 8); - } - for ( i = 0 ; i < 2 ; ++i ) { - for ( j = 0 ; j < VP7_MV_PROBS_PER_COMPONENT ; ++j ) { - if (vp8hwdDecodeBool(bit_ctx, MvUpdateProbs[i][j])) { - tmp = vp8hwdReadBits(bit_ctx, 7); - if ( tmp ) - tmp = tmp << 1; - else - tmp = 1; - p->entropy.probMvContext[i][j] = tmp; - } - } - } - } - if (bit_ctx->strmError) { - FUN_T("FUN_OUT"); - return MPP_ERR_PROTOL; - } - - FUN_T("FUN_OUT"); - return MPP_OK; -} - -MPP_RET vp8hwdSetPartitionOffsets(VP8DParserContext_t *p, RK_U8 *stream, RK_U32 len) -{ - RK_U32 i = 0; - RK_U32 offset = 0; - RK_U32 baseOffset; - RK_U32 extraBytesPacked = 0; - - FUN_T("FUN_IN"); - if (p->decMode == VP8HWD_VP8 && p->keyFrame) - extraBytesPacked += 7; - - stream += p->frameTagSize; - - baseOffset = p->frameTagSize + p->offsetToDctParts + 3 * ( (1 << p->nbrDctPartitions) - 1); - - stream += p->offsetToDctParts + extraBytesPacked; - for ( i = 0 ; i < (RK_U32)(1 << p->nbrDctPartitions) - 1 ; ++i ) { - RK_U32 tmp; - - p->dctPartitionOffsets[i] = baseOffset + offset; - tmp = stream[0] | (stream[1] << 8) | (stream[2] << 16); - offset += tmp; - stream += 3; - } - p->dctPartitionOffsets[i] = baseOffset + offset; - - return (p->dctPartitionOffsets[i] < len ? MPP_OK : MPP_ERR_STREAM); -} - - - -MPP_RET decoder_frame_header(VP8DParserContext_t *p, RK_U8 *pbase, RK_U32 size) -{ - MPP_RET ret; - - FUN_T("FUN_IN"); - p->keyFrame = !(pbase[0] & 1); - p->vpVersion = (pbase[0] >> 1) & 7; - p->showFrame = 1; - if (p->keyFrame && !p->needKeyFrame) { - p->needKeyFrame = 1; - } else { - if (!p->needKeyFrame) { - mpp_err("no found key frame"); - return MPP_NOK; - } - } - if (p->decMode == VP8HWD_VP7) { - p->offsetToDctParts = (pbase[0] >> 4) | (pbase[1] << 4) | (pbase[2] << 12); - p->frameTagSize = p->vpVersion >= 1 ? 3 : 4; - } else { - p->offsetToDctParts = (pbase[0] >> 5) | (pbase[1] << 3) | (pbase[2] << 11); - // mpp_log("offsetToDctParts %d pbase[0] = 0x%x pbase[1] = 0x%x pbase[2] = 0x%x ", p->offsetToDctParts, pbase[0], - // pbase[1], pbase[2]); - p->showFrame = (pbase[0] >> 4) & 1; - p->frameTagSize = 3; - } - pbase += p->frameTagSize; - size -= p->frameTagSize; - if (p->keyFrame) - vp8hwdResetProbs(p); - //mpp_log_f("p->decMode = %d", p->decMode); - if (p->decMode == VP8HWD_VP8) { - ret = vp8_header_parser(p, pbase, size); - } else { - ret = vp7_header_parser(p, pbase, size); - } - if (ret != MPP_OK) { - return ret; - } - return MPP_OK; -} - - -MPP_RET vp8d_parser_parse(void *ctx, HalDecTask *in_task) -{ - MPP_RET ret = MPP_OK; - VP8DContext *c = (VP8DContext *)ctx; - VP8DParserContext_t *p = (VP8DParserContext_t *)c->parse_ctx; - FUN_T("FUN_IN"); - - ret = decoder_frame_header(p, p->bitstream_sw_buf, p->stream_size); - - if (MPP_OK != ret) { - mpp_err("decoder_frame_header err ret %d", ret); - FUN_T("FUN_OUT"); - return ret; - } - - vp8hwdSetPartitionOffsets(p, p->bitstream_sw_buf, p->stream_size); - - ret = vp8d_alloc_frame(p); - if (MPP_OK != ret) { - mpp_err("vp8d_alloc_frame err ret %d", ret); - FUN_T("FUN_OUT"); - return ret; - } - - vp8d_convert_to_syntx(p, in_task); - in_task->syntax.data = (void *)p->dxva_ctx; - in_task->syntax.number = 1; - in_task->output = p->frame_out->slot_index; - in_task->valid = 1; - if (p->eos) { - in_task->flags.eos = p->eos; - } - vp8d_ref_update(p); - - FUN_T("FUN_OUT"); - return ret; -} - -MPP_RET vp8d_parser_callback(void *ctx, void *hal_info) -{ - MPP_RET ret = MPP_OK; - FUN_T("FUN_IN"); - (void)ctx; - (void)hal_info; - FUN_T("FUN_OUT"); - return ret; -} +/* + * + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define MODULE_TAG "vp8d_parser" +#include + +#include "vp8d_parser.h" +#include "vp8d_codec.h" +#include "mpp_frame.h" +#include "mpp_env.h" + +RK_U32 vp8d_debug = 0x0; + +#define FUN_T(tag) \ + do {\ + if (VP8D_DBG_FUNCTION & vp8d_debug)\ + { mpp_log("%s: line(%d), func(%s)", tag, __LINE__, __FUNCTION__); }\ + } while (0) + + +void vp8hwdBoolStart(vpBoolCoder_t *bit_ctx, RK_U8 *buffer, RK_U32 len) +{ + FUN_T("FUN_IN"); + bit_ctx->lowvalue = 0; + bit_ctx->range = 255; + bit_ctx->count = 8; + bit_ctx->buffer = buffer; + bit_ctx->pos = 0; + + bit_ctx->value = (bit_ctx->buffer[0] << 24) + (bit_ctx->buffer[1] << 16) + (bit_ctx->buffer[2] << 8) + (bit_ctx->buffer[3]); + + bit_ctx->pos += 4; + + bit_ctx->streamEndPos = len; + bit_ctx->strmError = bit_ctx->pos > bit_ctx->streamEndPos; + + FUN_T("FUN_OUT"); +} + +RK_U32 vp8hwdDecodeBool(vpBoolCoder_t *bit_ctx, RK_S32 probability) +{ + RK_U32 bit = 0; + RK_U32 split; + RK_U32 bigsplit; + RK_U32 count = bit_ctx->count; + RK_U32 range = bit_ctx->range; + RK_U32 value = bit_ctx->value; + + FUN_T("FUN_IN"); + split = 1 + (((range - 1) * probability) >> 8); + bigsplit = (split << 24); + range = split; + + if (value >= bigsplit) { + range = bit_ctx->range - split; + value = value - bigsplit; + bit = 1; + } + + if (range >= 0x80) { + bit_ctx->value = value; + bit_ctx->range = range; + return bit; + } else { + do { + range += range; + value += value; + + if (!--count) { + /* no more stream to read? */ + if (bit_ctx->pos >= bit_ctx->streamEndPos) { + bit_ctx->strmError = 1; + mpp_log("vp8hwdDecodeBool read end"); + break; + } + count = 8; + value |= bit_ctx->buffer[bit_ctx->pos]; + bit_ctx->pos++; + } + } while (range < 0x80); + } + + + bit_ctx->count = count; + bit_ctx->value = value; + bit_ctx->range = range; + + FUN_T("FUN_OUT"); + return bit; +} + +RK_U32 vp8hwdDecodeBool128(vpBoolCoder_t *bit_ctx) +{ + RK_U32 bit = 0; + RK_U32 split; + RK_U32 bigsplit; + RK_U32 count = bit_ctx->count; + RK_U32 range = bit_ctx->range; + RK_U32 value = bit_ctx->value; + + FUN_T("FUN_IN"); + split = (range + 1) >> 1; + bigsplit = (split << 24); + range = split; + + if (value >= bigsplit) { + range = (bit_ctx->range - split); + value = (value - bigsplit); + bit = 1; + } + + if (range >= 0x80) { + bit_ctx->value = value; + bit_ctx->range = range; + + FUN_T("FUN_OUT"); + return bit; + } else { + range <<= 1; + value <<= 1; + + if (!--count) { + /* no more stream to read? */ + if (bit_ctx->pos >= bit_ctx->streamEndPos) { + bit_ctx->strmError = 1; + mpp_log("vp8hwdDecodeBool128 read end"); + return 0; /* any value, not valid */ + } + count = 8; + value |= bit_ctx->buffer[bit_ctx->pos]; + bit_ctx->pos++; + } + } + + bit_ctx->count = count; + bit_ctx->value = value; + bit_ctx->range = range; + + FUN_T("FUN_OUT"); + return bit; +} + +RK_U32 vp8hwdReadBits(vpBoolCoder_t *bit_ctx, RK_S32 bits) +{ + RK_U32 z = 0; + RK_S32 bit; + + FUN_T("FUN_IN"); + for (bit = bits - 1; bit >= 0; bit--) { + z |= (vp8hwdDecodeBool128(bit_ctx) << bit); + } + + FUN_T("FUN_OUT"); + return z; +} + +RK_U32 ScaleDimension( RK_U32 orig, RK_U32 scale ) +{ + + FUN_T("FUN_IN"); + switch (scale) { + case 0: + return orig; + break; + case 1: /* 5/4 */ + return (5 * orig) / 4; + break; + case 2: /* 5/3 */ + return (5 * orig) / 3; + break; + case 3: /* 2 */ + return 2 * orig; + break; + } + + FUN_T("FUN_OUT"); + return orig; +} + +RK_S32 DecodeQuantizerDelta(vpBoolCoder_t *bit_ctx) +{ + RK_S32 result = 0; + + FUN_T("FUN_IN"); + if (vp8hwdDecodeBool128(bit_ctx)) { + result = vp8hwdReadBits(bit_ctx, 4); + if (vp8hwdDecodeBool128(bit_ctx)) + result = -result; + } + + FUN_T("FUN_OUT"); + return result; +} + +MPP_RET vp8d_parser_init(void *ctx, ParserCfg *parser_cfg) +{ + MPP_RET ret = MPP_OK; + VP8DContext *c = (VP8DContext *)ctx; + VP8DParserContext_t *p = (VP8DParserContext_t *)c->parse_ctx; + + FUN_T("FUN_IN"); + if (p == NULL) { + p = (VP8DParserContext_t*)mpp_calloc(VP8DParserContext_t, 1); + if (NULL == p) { + mpp_err("vp8d malloc VP8DParserContext_t fail"); + FUN_T("FUN_OUT"); + return MPP_ERR_NOMEM; + } + c->parse_ctx = p; + } + p->packet_slots = parser_cfg->packet_slots; + p->frame_slots = parser_cfg->frame_slots; + p->notify_cb = parser_cfg->notify_cb; + + mpp_buf_slot_setup(p->frame_slots, 15); + + p->dxva_ctx = mpp_calloc(DXVA_PicParams_VP8, 1); + + if (NULL == p->dxva_ctx) { + mpp_err("vp8d malloc dxva_ctx fail"); + FUN_T("FUN_OUT"); + return MPP_ERR_NOMEM; + } + p->decMode = VP8HWD_VP8; + p->bitstream_sw_buf = mpp_malloc(RK_U8, VP8D_BUF_SIZE_BITMEM); + mpp_packet_init(&p->input_packet, p->bitstream_sw_buf, VP8D_BUF_SIZE_BITMEM); + p->max_stream_size = VP8D_BUF_SIZE_BITMEM; + + FUN_T("FUN_OUT"); + return ret; +} + +void vp8d_unref_frame(VP8DParserContext_t *p, VP8Frame *frame) +{ + + FUN_T("FUN_IN"); + if (NULL == frame || frame->ref_count <= 0 + || frame->slot_index >= 0x7f) { + mpp_err("ref count alreay is zero"); + FUN_T("FUN_OUT"); + return; + } + frame->ref_count--; + if (!frame->ref_count && frame->slot_index < 0x7f) { + mpp_buf_slot_clr_flag(p->frame_slots, frame->slot_index, SLOT_CODEC_USE); + frame->slot_index = 0xff; + mpp_free(frame->f); + mpp_free(frame); + frame = NULL; + } + + FUN_T("FUN_OUT"); + return; +} + +void vp8d_unref_allframe(VP8DParserContext_t *p) +{ + + FUN_T("FUN_IN"); + if (NULL != p->frame_out) { + vp8d_unref_frame(p, p->frame_out); + p->frame_out = NULL; + } + + if (NULL != p->frame_ref) { + vp8d_unref_frame(p, p->frame_ref); + p->frame_ref = NULL; + } + + if (NULL != p->frame_golden) { + vp8d_unref_frame(p, p->frame_golden); + p->frame_golden = NULL; + } + + if (NULL != p->frame_alternate) { + vp8d_unref_frame(p, p->frame_alternate); + p->frame_alternate = NULL; + } + + FUN_T("FUN_OUT"); + return; +} + +MPP_RET vp8d_parser_deinit(void *ctx) +{ + MPP_RET ret = MPP_OK; + VP8DContext *c = (VP8DContext *)ctx; + VP8DParserContext_t *p = (VP8DParserContext_t *)c->parse_ctx; + + FUN_T("FUN_IN"); + + if (NULL != p->bitstream_sw_buf) { + mpp_free(p->bitstream_sw_buf); + p->bitstream_sw_buf = NULL; + } + + if (NULL != p->dxva_ctx) { + mpp_free(p->dxva_ctx); + p->dxva_ctx = NULL; + } + + vp8d_unref_allframe(p); + + if ( NULL != p) { + mpp_free(p); + } + FUN_T("FUN_OUT"); + return ret; +} +/*! +*********************************************************************** +* \brief +* reset +*********************************************************************** +*/ +MPP_RET vp8d_parser_reset(void *ctx) +{ + MPP_RET ret = MPP_OK; + VP8DContext *c = (VP8DContext *)ctx; + VP8DParserContext_t *p = (VP8DParserContext_t *)c->parse_ctx; + + FUN_T("FUN_IN"); + vp8d_unref_allframe(p); + p->needKeyFrame = 0; + p->eos = 0; + FUN_T("FUN_OUT"); + return ret; +} + +/*! +*********************************************************************** +* \brief +* flush +*********************************************************************** +*/ +MPP_RET vp8d_parser_flush(void *ctx) +{ + MPP_RET ret = MPP_OK; + + FUN_T("FUN_IN"); + (void) ctx; + FUN_T("FUN_OUT"); + return ret; +} + +/*! +*********************************************************************** +* \brief +* control/perform +*********************************************************************** +*/ +MPP_RET vp8d_parser_control(void *ctx, RK_S32 cmd_type, void *param) +{ + MPP_RET ret = MPP_OK; + + FUN_T("FUN_IN"); + (void)ctx; + (void)cmd_type; + (void)param; + + FUN_T("FUN_OUT"); + return ret; +} + + +/*! +*********************************************************************** +* \brief +* prepare +*********************************************************************** +*/ + +MPP_RET vp8d_parser_split_frame(RK_U8 *src, RK_U32 src_size, RK_U8 *dst, RK_U32 *dst_size) +{ + MPP_RET ret = MPP_OK; + + FUN_T("FUN_IN"); + memcpy(dst, src, src_size);; + *dst_size = src_size; + + (void)dst; + + FUN_T("FUN_OUT"); + return ret; +} + + +MPP_RET vp8d_parser_prepare(void *ctx, MppPacket pkt, HalDecTask *task) +{ + MPP_RET ret = MPP_OK; + RK_U32 out_size = 0, len_in = 0; + RK_U8 * pos = NULL; + RK_U8 *buf = NULL; + VP8DContext *c = (VP8DContext *)ctx; + + VP8DParserContext_t *p = (VP8DParserContext_t *)c->parse_ctx; + MppPacket input_packet = p->input_packet; + + FUN_T("FUN_IN"); + task->valid = 0; + + + buf = pos = mpp_packet_get_pos(pkt); + p->pts = mpp_packet_get_pts(pkt); + + len_in = (RK_U32)mpp_packet_get_length(pkt), + p->eos = mpp_packet_get_eos(pkt); + // mpp_log("len_in = %d",len_in); + if (len_in > p->max_stream_size) { + mpp_free(p->bitstream_sw_buf); + p->bitstream_sw_buf = NULL; + p->bitstream_sw_buf = mpp_malloc(RK_U8, (len_in + 1024)); + if (NULL == p->bitstream_sw_buf) { + mpp_err("vp8d_parser realloc fail"); + return MPP_ERR_NOMEM; + } + p->max_stream_size = len_in + 1024; + } + + vp8d_parser_split_frame(buf, + len_in, + p->bitstream_sw_buf, + &out_size); + pos += out_size; + + mpp_packet_set_pos(pkt, pos); + + if (out_size == 0 && p->eos) { + task->flags.eos = p->eos; + return ret; + } + + + + // mpp_log("p->bitstream_sw_buf = 0x%x", p->bitstream_sw_buf); + // mpp_log("out_size = 0x%x", out_size); + mpp_packet_set_data(input_packet, p->bitstream_sw_buf); + mpp_packet_set_size(input_packet, p->max_stream_size); + mpp_packet_set_length(input_packet, out_size); + p->stream_size = out_size; + task->input_packet = input_packet; + task->valid = 1; + + FUN_T("FUN_OUT"); + return ret; +} + +MPP_RET vp8d_convert_to_syntx( VP8DParserContext_t *p, HalDecTask *in_task) +{ + MPP_RET ret = MPP_OK; + RK_U32 i, tmp; + RK_U32 byteOffset = 0, extraBytesPacked = 0; + DXVA_PicParams_VP8 *pic_param = p->dxva_ctx; + + FUN_T("FUN_IN"); + tmp = (p->bitstr.pos) * 8 + (8 - p->bitstr.count); + + if (p->frameTagSize == 4) + tmp += 8; + + if (p->decMode == VP8HWD_VP8 && p->keyFrame) + extraBytesPacked += 7; + + tmp += extraBytesPacked * 8; + byteOffset = tmp / 8; + pic_param->stream_start_bit = (byteOffset & 0x07U) * 8; + byteOffset &= (~0x07U); /* align the base */ + pic_param->stream_start_offset = byteOffset; + + pic_param->stream_start_bit += (tmp & 0x7); + + pic_param->frame_type = !p->keyFrame; + pic_param->stVP8Segments.segmentation_enabled = p->segmentationEnabled; + pic_param->stVP8Segments.update_mb_segmentation_map = p->segmentationMapUpdate; + pic_param->mode_ref_lf_delta_enabled = p->modeRefLfEnabled; + pic_param->mb_no_coeff_skip = p->coeffSkipMode; + pic_param->width = p->width; + pic_param->height = p->height; + pic_param->decMode = p->decMode; + pic_param->filter_type = p->loopFilterType; + pic_param->sharpness = p->loopFilterSharpness; + pic_param->filter_level = p->loopFilterLevel; + pic_param->stVP8Segments.update_mb_segmentation_data = p->segmentFeatureMode; + pic_param->version = p->vpVersion; + pic_param->bool_value = ((p->bitstr.value >> 24) & (0xFFU)); + pic_param->bool_range = (p->bitstr.range & (0xFFU)); + pic_param->frameTagSize = p->frameTagSize; + pic_param->streamEndPos = p->bitstr.streamEndPos; + pic_param->log2_nbr_of_dct_partitions = p->nbrDctPartitions; + pic_param->offsetToDctParts = p->offsetToDctParts; + + pic_param->y1ac_delta_q = p->qpYAc; + pic_param->y1dc_delta_q = p->qpYDc; + pic_param->y2ac_delta_q = p->qpY2Ac; + pic_param->y2dc_delta_q = p->qpY2Dc; + pic_param->uvac_delta_q = p->qpChAc; + pic_param->uvdc_delta_q = p->qpChDc; + pic_param->probe_skip_false = p->probMbSkipFalse; + pic_param->prob_intra = p->probIntra; + pic_param->prob_last = p->probRefLast; + pic_param->prob_golden = p->probRefGolden; + + memcpy(pic_param->vp8_coef_update_probs, p->entropy.probCoeffs, sizeof(pic_param->vp8_coef_update_probs)); + memcpy(pic_param->vp8_mv_update_probs, p->entropy.probMvContext, sizeof(pic_param->vp8_mv_update_probs)); + + for ( i = 0; i < 3; i++) { + pic_param->intra_chroma_prob[i] = p->entropy.probChromaPredMode[i]; + pic_param->stVP8Segments.mb_segment_tree_probs[i] = p->probSegment[i]; + } + + pic_param->ref_frame_sign_bias_golden = p->refFrameSignBias[0]; + pic_param->ref_frame_sign_bias_altref = p->refFrameSignBias[1]; + + + for (i = 0; i < 4; i++) { + pic_param->stVP8Segments.segment_feature_data[0][i] = p->segmentQp[i]; + pic_param->ref_lf_deltas[i] = p->mbRefLfDelta[i]; + pic_param->mode_lf_deltas[i] = p->mbModeLfDelta[i]; + pic_param->stVP8Segments.segment_feature_data[1][i] = p->segmentLoopfilter[i]; + pic_param->intra_16x16_prob[i] = p->entropy.probLuma16x16PredMode[i]; + } + + p->dxva_ctx->CurrPic.Index7Bits = p->frame_out->slot_index; + memset(in_task->refer, -1, sizeof(in_task->refer)); + + if (p->frame_ref != NULL) { + pic_param->lst_fb_idx.Index7Bits = p->frame_ref->slot_index; + mpp_buf_slot_set_flag(p->frame_slots, p->frame_ref->slot_index, SLOT_HAL_INPUT); + in_task->refer[0] = p->frame_ref->slot_index; + } else { + pic_param->lst_fb_idx.Index7Bits = 0x7f; + } + + if (p->frame_golden != NULL) { + pic_param->gld_fb_idx.Index7Bits = p->frame_golden->slot_index; + mpp_buf_slot_set_flag(p->frame_slots, p->frame_golden->slot_index, SLOT_HAL_INPUT); + in_task->refer[1] = p->frame_golden->slot_index; + } else { + pic_param->gld_fb_idx.Index7Bits = 0x7f; + } + + if (p->frame_alternate != NULL) { + pic_param->alt_fb_idx.Index7Bits = p->frame_alternate->slot_index; + mpp_buf_slot_set_flag(p->frame_slots, p->frame_alternate->slot_index, SLOT_HAL_INPUT); + in_task->refer[2] = p->frame_alternate->slot_index; + } else { + pic_param->alt_fb_idx.Index7Bits = 0x7f; + } + + memcpy(pic_param->dctPartitionOffsets, p->dctPartitionOffsets, sizeof(p->dctPartitionOffsets)); + + FUN_T("FUN_OUT"); + return ret; +} + +MPP_RET vp8d_alloc_frame(VP8DParserContext_t *p) +{ + MPP_RET ret = MPP_OK; + + FUN_T("FUN_IN"); + if (NULL == p->frame_out) { + p->frame_out = mpp_calloc(VP8Frame, 1); + if (NULL == p->frame_out) { + mpp_err("alloc vp8 frame fail"); + return MPP_ERR_NOMEM; + } + + if (NULL == p->frame_out->f) { + mpp_frame_init(&p->frame_out->f); + if (NULL == p->frame_out->f) { + mpp_err("alloc vp8 mpp frame fail"); + return MPP_ERR_NOMEM; + } + } + p->frame_out->slot_index = 0xff; + } + + if (p->frame_out->slot_index == 0xff) { + mpp_frame_set_width(p->frame_out->f, p->width); + mpp_frame_set_height(p->frame_out->f, p->height); + mpp_frame_set_hor_stride(p->frame_out->f, p->width); + mpp_frame_set_ver_stride(p->frame_out->f, p->height); + mpp_frame_set_errinfo(p->frame_out->f, 0); + mpp_frame_set_pts(p->frame_out->f, p->pts); + ret = mpp_buf_slot_get_unused(p->frame_slots, &p->frame_out->slot_index); + if (MPP_OK != ret) { + mpp_err("vp8 buf_slot_get_unused get fail"); + return ret; + } + mpp_buf_slot_set_prop(p->frame_slots, p->frame_out->slot_index, SLOT_FRAME, p->frame_out->f); + mpp_buf_slot_set_flag(p->frame_slots, p->frame_out->slot_index, SLOT_CODEC_USE); + mpp_buf_slot_set_flag(p->frame_slots, p->frame_out->slot_index, SLOT_HAL_OUTPUT); + mpp_frame_set_mode(p->frame_out->f, 0); + + if (p->showFrame) { + mpp_buf_slot_set_flag(p->frame_slots, p->frame_out->slot_index, SLOT_QUEUE_USE); + mpp_buf_slot_enqueue(p->frame_slots, p->frame_out->slot_index, QUEUE_DISPLAY); + } + p->frame_out->ref_count++; + } + + FUN_T("FUN_OUT"); + return ret; +} + +void vp8d_ref_frame(VP8Frame *frame) +{ + + FUN_T("FUN_IN"); + if ((NULL == frame) || (frame->slot_index >= 0x7f)) { + mpp_err("frame is null or slot_index is no valid"); + return; + } + frame->ref_count++; + + FUN_T("FUN_OUT"); +} + + +MPP_RET vp8d_ref_update(VP8DParserContext_t *p) +{ + + FUN_T("FUN_IN"); + if (p->decMode != VP8HWD_WEBP) { + if (p->copyBufferToAlternate == 1) { + if (NULL != p->frame_alternate) { + vp8d_unref_frame(p, p->frame_alternate); + p->frame_alternate = NULL; + } + p->frame_alternate = p->frame_ref; + vp8d_ref_frame(p->frame_alternate); + } else if (p->copyBufferToAlternate == 2) { + if (NULL != p->frame_alternate) { + vp8d_unref_frame(p, p->frame_alternate); + p->frame_alternate = NULL; + } + p->frame_alternate = p->frame_golden; + vp8d_ref_frame(p->frame_alternate); + } + + if (p->copyBufferToGolden == 1) { + if (NULL != p->frame_golden) { + vp8d_unref_frame(p, p->frame_golden); + p->frame_golden = NULL; + } + p->frame_golden = p->frame_ref; + vp8d_ref_frame(p->frame_golden); + } else if (p->copyBufferToGolden == 2) { + if (NULL != p->frame_golden) { + vp8d_unref_frame(p, p->frame_golden); + p->frame_golden = NULL; + } + p->frame_golden = p->frame_alternate; + vp8d_ref_frame(p->frame_golden); + } + + if (p->refreshGolden) { + if (NULL != p->frame_golden) { + vp8d_unref_frame(p, p->frame_golden); + p->frame_golden = NULL; + } + p->frame_golden = p->frame_out; + vp8d_ref_frame(p->frame_golden); + } + + if (p->refreshAlternate) { + if (NULL != p->frame_alternate) { + vp8d_unref_frame(p, p->frame_alternate); + p->frame_alternate = NULL; + } + p->frame_alternate = p->frame_out; + vp8d_ref_frame(p->frame_out); + } + + if (p->refreshLast) { + if (NULL != p->frame_ref) { + vp8d_unref_frame(p, p->frame_ref); + p->frame_ref = NULL; + } + p->frame_ref = p->frame_out; + vp8d_ref_frame(p->frame_ref); + } + vp8d_unref_frame(p, p->frame_out); + p->frame_out = NULL; + } + + FUN_T("FUN_OUT"); + return 0; +} + +void vp8hwdResetProbs(VP8DParserContext_t *p) +{ + RK_U32 i, j, k, l; + static const RK_U32 Vp7DefaultScan[] = { + 0, 1, 4, 8, 5, 2, 3, 6, + 9, 12, 13, 10, 7, 11, 14, 15, + }; + + FUN_T("FUN_IN"); + for ( i = 0 ; i < 16 ; ++i ) + p->vp7ScanOrder[i] = Vp7DefaultScan[i]; + + + /* Intra-prediction modes */ + p->entropy.probLuma16x16PredMode[0] = 112; + p->entropy.probLuma16x16PredMode[1] = 86; + p->entropy.probLuma16x16PredMode[2] = 140; + p->entropy.probLuma16x16PredMode[3] = 37; + p->entropy.probChromaPredMode[0] = 162; + p->entropy.probChromaPredMode[1] = 101; + p->entropy.probChromaPredMode[2] = 204; + + for (i = 0; i < MAX_NBR_OF_MB_REF_LF_DELTAS; i++) + p->mbRefLfDelta[i] = 0; + + for (i = 0; i < MAX_NBR_OF_MB_MODE_LF_DELTAS; i++) + p->mbModeLfDelta[i] = 0; + + /* MV context */ + k = 0; + if (p->decMode == VP8HWD_VP8) { + for ( i = 0 ; i < 2 ; ++i ) + for ( j = 0 ; j < VP8_MV_PROBS_PER_COMPONENT ; ++j, ++k ) + p->entropy.probMvContext[i][j] = Vp8DefaultMvProbs[i][j]; + } else { + for ( i = 0 ; i < 2 ; ++i ) + for ( j = 0 ; j < VP7_MV_PROBS_PER_COMPONENT ; ++j, ++k ) + p->entropy.probMvContext[i][j] = Vp7DefaultMvProbs[i][j]; + } + + /* Coefficients */ + for ( i = 0 ; i < 4 ; ++i ) + for ( j = 0 ; j < 8 ; ++j ) + for ( k = 0 ; k < 3 ; ++k ) + for ( l = 0 ; l < 11 ; ++l ) + p->entropy.probCoeffs[i][j][k][l] = DefaultCoeffProbs[i][j][k][l]; + + FUN_T("FUN_OUT"); +} + +void vp8hwdDecodeCoeffUpdate(VP8DParserContext_t *p) +{ + RK_U32 i, j, k, l; + + FUN_T("FUN_IN"); + for ( i = 0; i < 4; i++ ) { + for ( j = 0; j < 8; j++ ) { + for ( k = 0; k < 3; k++ ) { + for ( l = 0; l < 11; l++ ) { + if (vp8hwdDecodeBool(&p->bitstr, CoeffUpdateProbs[i][j][k][l])) + p->entropy.probCoeffs[i][j][k][l] = vp8hwdReadBits(&p->bitstr, 8); + } + } + } + } + FUN_T("FUN_OUT"); +} + +MPP_RET vp8_header_parser(VP8DParserContext_t *p, RK_U8 *pbase, RK_U32 size) +{ + RK_U32 tmp; + int i, j; + vpBoolCoder_t *bit_ctx = &p->bitstr; + + FUN_T("FUN_IN"); + if (p->keyFrame) { + tmp = (pbase[0] << 16) | (pbase[1] << 8) | (pbase[2] << 0); + if (tmp != VP8_KEY_FRAME_START_CODE) + return MPP_ERR_PROTOL; + tmp = (pbase[3] << 0) | (pbase[4] << 8); + p->width = tmp & 0x3fff; + p->scaledWidth = ScaleDimension(p->width, tmp >> 14); + tmp = (pbase[5] << 0) | (pbase[6] << 8); + p->height = tmp & 0x3fff; + p->scaledHeight = ScaleDimension(p->height, tmp >> 14); + pbase += 7; + size -= 7; + } + vp8hwdBoolStart(bit_ctx, pbase, size); + if (p->keyFrame) { + p->colorSpace = (vpColorSpace_e)vp8hwdDecodeBool128(bit_ctx); + p->clamping = vp8hwdDecodeBool128(bit_ctx); + } + p->segmentationEnabled = vp8hwdDecodeBool128(bit_ctx); + p->segmentationMapUpdate = 0; + if (p->segmentationEnabled) { + p->segmentationMapUpdate = vp8hwdDecodeBool128(bit_ctx); + if (vp8hwdDecodeBool128(bit_ctx)) { /* Segmentation map update */ + p->segmentFeatureMode = vp8hwdDecodeBool128(bit_ctx); + memset(&p->segmentQp[0], 0, MAX_NBR_OF_SEGMENTS * sizeof(RK_S32)); + memset(&p->segmentLoopfilter[0], 0, MAX_NBR_OF_SEGMENTS * sizeof(RK_S32)); + for (i = 0; i < MAX_NBR_OF_SEGMENTS; i++) { + if (vp8hwdDecodeBool128(bit_ctx)) { + p->segmentQp[i] = vp8hwdReadBits(bit_ctx, 7); + if (vp8hwdDecodeBool128(bit_ctx)) + p->segmentQp[i] = -p->segmentQp[i]; + } + } + for (i = 0; i < MAX_NBR_OF_SEGMENTS; i++) { + if (vp8hwdDecodeBool128(bit_ctx)) { + p->segmentLoopfilter[i] = vp8hwdReadBits(bit_ctx, 6); + if (vp8hwdDecodeBool128(bit_ctx)) + p->segmentLoopfilter[i] = -p->segmentLoopfilter[i]; + } + } + } + if (p->segmentationMapUpdate) { + p->probSegment[0] = 255; + p->probSegment[1] = 255; + p->probSegment[2] = 255; + for (i = 0; i < 3; i++) { + if (vp8hwdDecodeBool128(bit_ctx)) { + p->probSegment[i] = vp8hwdReadBits(bit_ctx, 8); + } + } + } + if (bit_ctx->strmError) { + mpp_err_f("paser header stream no enough"); + FUN_T("FUN_OUT"); + return MPP_ERR_STREAM; + } + } + p->loopFilterType = vp8hwdDecodeBool128(bit_ctx); + p->loopFilterLevel = vp8hwdReadBits(bit_ctx, 6); + p->loopFilterSharpness = vp8hwdReadBits(bit_ctx, 3); + p->modeRefLfEnabled = vp8hwdDecodeBool128(bit_ctx); + if (p->modeRefLfEnabled) { + if (vp8hwdDecodeBool128(bit_ctx)) { + for (i = 0; i < MAX_NBR_OF_MB_REF_LF_DELTAS; i++) { + if (vp8hwdDecodeBool128(bit_ctx)) { + p->mbRefLfDelta[i] = vp8hwdReadBits(bit_ctx, 6); + if (vp8hwdDecodeBool128(bit_ctx)) + p->mbRefLfDelta[i] = -p->mbRefLfDelta[i]; + } + } + for (i = 0; i < MAX_NBR_OF_MB_MODE_LF_DELTAS; i++) { + if (vp8hwdDecodeBool128(&p->bitstr)) { + p->mbModeLfDelta[i] = vp8hwdReadBits(bit_ctx, 6); + if (vp8hwdDecodeBool128(bit_ctx)) + p->mbModeLfDelta[i] = -p->mbModeLfDelta[i]; + } + } + } + } + if (bit_ctx->strmError) { + mpp_err_f("paser header stream no enough"); + FUN_T("FUN_OUT"); + return MPP_ERR_STREAM; + } + p->nbrDctPartitions = vp8hwdReadBits(bit_ctx, 2); + p->qpYAc = vp8hwdReadBits(bit_ctx, 7); + p->qpYDc = DecodeQuantizerDelta(bit_ctx); + p->qpY2Dc = DecodeQuantizerDelta(bit_ctx); + p->qpY2Ac = DecodeQuantizerDelta(bit_ctx); + p->qpChDc = DecodeQuantizerDelta(bit_ctx); + p->qpChAc = DecodeQuantizerDelta(bit_ctx); + if (p->keyFrame) { + p->refreshGolden = 1; + p->refreshAlternate = 1; + p->copyBufferToGolden = 0; + p->copyBufferToAlternate = 0; + + /* Refresh entropy probs */ + p->refreshEntropyProbs = vp8hwdDecodeBool128(bit_ctx); + + p->refFrameSignBias[0] = 0; + p->refFrameSignBias[1] = 0; + p->refreshLast = 1; + } else { + /* Refresh golden */ + p->refreshGolden = vp8hwdDecodeBool128(bit_ctx); + /* Refresh alternate */ + p->refreshAlternate = vp8hwdDecodeBool128(bit_ctx); + if ( p->refreshGolden == 0 ) { + /* Copy to golden */ + p->copyBufferToGolden = vp8hwdReadBits(bit_ctx, 2); + } else + p->copyBufferToGolden = 0; + + if ( p->refreshAlternate == 0 ) { + /* Copy to alternate */ + p->copyBufferToAlternate = vp8hwdReadBits(bit_ctx, 2); + } else + p->copyBufferToAlternate = 0; + + /* Sign bias for golden frame */ + p->refFrameSignBias[0] = vp8hwdDecodeBool128(bit_ctx); + /* Sign bias for alternate frame */ + p->refFrameSignBias[1] = vp8hwdDecodeBool128(bit_ctx); + /* Refresh entropy probs */ + p->refreshEntropyProbs = vp8hwdDecodeBool128(bit_ctx); + /* Refresh last */ + p->refreshLast = vp8hwdDecodeBool128(bit_ctx); + } + + /* Make a "backup" of current entropy probabilities if refresh is not set */ + if (p->refreshEntropyProbs == 0) { + memcpy((void*)&p->entropyLast, (void*)&p->entropy, (unsigned long)sizeof(vp8EntropyProbs_t)); + memcpy( (void*)p->vp7PrevScanOrder, (void*)p->vp7ScanOrder, (unsigned long)sizeof(p->vp7ScanOrder)); + } + + vp8hwdDecodeCoeffUpdate(p); + p->coeffSkipMode = vp8hwdDecodeBool128(bit_ctx); + if (!p->keyFrame) { + RK_U32 mvProbs; + + p->probMbSkipFalse = vp8hwdReadBits(bit_ctx, 8); + p->probIntra = vp8hwdReadBits(bit_ctx, 8); + p->probRefLast = vp8hwdReadBits(bit_ctx, 8); + p->probRefGolden = vp8hwdReadBits(bit_ctx, 8); + if (vp8hwdDecodeBool128(bit_ctx)) { + for (i = 0; i < 4; i++) + p->entropy.probLuma16x16PredMode[i] = vp8hwdReadBits(bit_ctx, 8); + } + if (vp8hwdDecodeBool128(bit_ctx)) { + for (i = 0; i < 3; i++) + p->entropy.probChromaPredMode[i] = vp8hwdReadBits(bit_ctx, 8); + } + mvProbs = VP8_MV_PROBS_PER_COMPONENT; + for ( i = 0 ; i < 2 ; ++i ) { + for ( j = 0 ; j < (RK_S32)mvProbs ; ++j ) { + if (vp8hwdDecodeBool(bit_ctx, MvUpdateProbs[i][j]) == 1) { + tmp = vp8hwdReadBits(bit_ctx, 7); + if ( tmp ) + tmp = tmp << 1; + else + tmp = 1; + p->entropy.probMvContext[i][j] = tmp; + } + } + } + } else { + p->probMbSkipFalse = vp8hwdReadBits(bit_ctx, 8); + } + if (bit_ctx->strmError) { + mpp_err_f("paser header stream no enough"); + FUN_T("FUN_OUT"); + return MPP_ERR_STREAM; + } + FUN_T("FUN_OUT"); + return MPP_OK; +} + +MPP_RET vp7_header_parser(VP8DParserContext_t *p, RK_U8 *pbase, RK_U32 size) +{ + RK_U32 tmp; + int i, j; + + FUN_T("FUN_IN"); + vpBoolCoder_t *bit_ctx = &p->bitstr; + vp8hwdBoolStart(bit_ctx, pbase, size); + + if (p->keyFrame) { + p->width = vp8hwdReadBits(bit_ctx, 12); + p->height = vp8hwdReadBits(bit_ctx, 12); + tmp = vp8hwdReadBits(bit_ctx, 2); + p->scaledWidth = ScaleDimension(p->width, tmp); + tmp = vp8hwdReadBits(bit_ctx, 2); + p->scaledHeight = ScaleDimension(p->height, tmp); + } + { + const RK_U32 vp70FeatureBits[4] = { 7, 6, 0, 8 }; + const RK_U32 vp71FeatureBits[4] = { 7, 6, 0, 5 }; + const RK_U32 *featureBits; + if (p->vpVersion == 0) + featureBits = vp70FeatureBits; + else + featureBits = vp71FeatureBits; + for (i = 0; i < MAX_NBR_OF_VP7_MB_FEATURES; i++) { + if (vp8hwdDecodeBool128(bit_ctx)) { + tmp = vp8hwdReadBits(bit_ctx, 8); + for (j = 0; j < 3; j++) { + if (vp8hwdDecodeBool128(bit_ctx)) + tmp = vp8hwdReadBits(bit_ctx, 8); + } + if (featureBits[i]) { + for (j = 0; j < 4; j++) { + if (vp8hwdDecodeBool128(bit_ctx)) + tmp = vp8hwdReadBits(bit_ctx, featureBits[i]); + } + } + FUN_T("FUN_OUT"); + return MPP_ERR_PROTOL; + } + + } + p->nbrDctPartitions = 0; + } + p->qpYAc = (RK_S32)vp8hwdReadBits(bit_ctx, 7 ); + p->qpYDc = vp8hwdReadBits(bit_ctx, 1 ) ? (RK_S32)vp8hwdReadBits(bit_ctx, 7 ) : p->qpYAc; + p->qpY2Dc = vp8hwdReadBits(bit_ctx, 1 ) ? (RK_S32)vp8hwdReadBits(bit_ctx, 7 ) : p->qpYAc; + p->qpY2Ac = vp8hwdReadBits(bit_ctx, 1 ) ? (RK_S32)vp8hwdReadBits(bit_ctx, 7 ) : p->qpYAc; + p->qpChDc = vp8hwdReadBits(bit_ctx, 1 ) ? (RK_S32)vp8hwdReadBits(bit_ctx, 7 ) : p->qpYAc; + p->qpChAc = vp8hwdReadBits(bit_ctx, 1 ) ? (RK_S32)vp8hwdReadBits(bit_ctx, 7 ) : p->qpYAc; + if (!p->keyFrame) { + p->refreshGolden = vp8hwdDecodeBool128(bit_ctx); + if (p->vpVersion >= 1) { + p->refreshEntropyProbs = vp8hwdDecodeBool128(bit_ctx); + p->refreshLast = vp8hwdDecodeBool128(bit_ctx); + } else { + p->refreshEntropyProbs = 1; + p->refreshLast = 1; + } + } else { + p->refreshGolden = 1; + p->refreshAlternate = 1; + p->copyBufferToGolden = 0; + p->copyBufferToAlternate = 0; + if (p->vpVersion >= 1) + p->refreshEntropyProbs = vp8hwdDecodeBool128(bit_ctx); + else + p->refreshEntropyProbs = 1; + p->refFrameSignBias[0] = 0; + p->refFrameSignBias[1] = 0; + p->refreshLast = 1; + } + + if (!p->refreshEntropyProbs) { + memcpy(&p->entropyLast, &p->entropy, (unsigned long)sizeof(vp8EntropyProbs_t)); + memcpy(p->vp7PrevScanOrder, p->vp7ScanOrder, (unsigned long)sizeof(p->vp7ScanOrder)); + } + if (p->refreshLast) { + if (vp8hwdDecodeBool128(bit_ctx)) { + tmp = vp8hwdReadBits(bit_ctx, 8); + tmp = vp8hwdReadBits(bit_ctx, 8); + FUN_T("FUN_OUT"); + return MPP_ERR_STREAM; + } + } + if (p->vpVersion == 0) { + p->loopFilterType = vp8hwdDecodeBool128(bit_ctx); + } + if (vp8hwdDecodeBool128(bit_ctx)) { + static const RK_U32 Vp7DefaultScan[] = { + 0, 1, 4, 8, 5, 2, 3, 6, + 9, 12, 13, 10, 7, 11, 14, 15, + }; + p->vp7ScanOrder[0] = 0; + for (i = 1; i < 16; i++) + p->vp7ScanOrder[i] = Vp7DefaultScan[vp8hwdReadBits(bit_ctx, 4)]; + } + if (p->vpVersion >= 1) + p->loopFilterType = vp8hwdDecodeBool128(bit_ctx); + p->loopFilterLevel = vp8hwdReadBits(bit_ctx, 6); + p->loopFilterSharpness = vp8hwdReadBits(bit_ctx, 3); + vp8hwdDecodeCoeffUpdate(p); + if (!p->keyFrame) { + p->probIntra = vp8hwdReadBits(bit_ctx, 8); + p->probRefLast = vp8hwdReadBits(bit_ctx, 8); + if (vp8hwdDecodeBool128(bit_ctx)) { + for (i = 0; i < 4; i++) + p->entropy.probLuma16x16PredMode[i] = vp8hwdReadBits(bit_ctx, 8); + } + if (vp8hwdDecodeBool128(bit_ctx)) { + for (i = 0; i < 3; i++) + p->entropy.probChromaPredMode[i] = vp8hwdReadBits(bit_ctx, 8); + } + for ( i = 0 ; i < 2 ; ++i ) { + for ( j = 0 ; j < VP7_MV_PROBS_PER_COMPONENT ; ++j ) { + if (vp8hwdDecodeBool(bit_ctx, MvUpdateProbs[i][j])) { + tmp = vp8hwdReadBits(bit_ctx, 7); + if ( tmp ) + tmp = tmp << 1; + else + tmp = 1; + p->entropy.probMvContext[i][j] = tmp; + } + } + } + } + if (bit_ctx->strmError) { + FUN_T("FUN_OUT"); + return MPP_ERR_PROTOL; + } + + FUN_T("FUN_OUT"); + return MPP_OK; +} + +MPP_RET vp8hwdSetPartitionOffsets(VP8DParserContext_t *p, RK_U8 *stream, RK_U32 len) +{ + RK_U32 i = 0; + RK_U32 offset = 0; + RK_U32 baseOffset; + RK_U32 extraBytesPacked = 0; + + FUN_T("FUN_IN"); + if (p->decMode == VP8HWD_VP8 && p->keyFrame) + extraBytesPacked += 7; + + stream += p->frameTagSize; + + baseOffset = p->frameTagSize + p->offsetToDctParts + 3 * ( (1 << p->nbrDctPartitions) - 1); + + stream += p->offsetToDctParts + extraBytesPacked; + for ( i = 0 ; i < (RK_U32)(1 << p->nbrDctPartitions) - 1 ; ++i ) { + RK_U32 tmp; + + p->dctPartitionOffsets[i] = baseOffset + offset; + tmp = stream[0] | (stream[1] << 8) | (stream[2] << 16); + offset += tmp; + stream += 3; + } + p->dctPartitionOffsets[i] = baseOffset + offset; + + return (p->dctPartitionOffsets[i] < len ? MPP_OK : MPP_ERR_STREAM); +} + + + +MPP_RET decoder_frame_header(VP8DParserContext_t *p, RK_U8 *pbase, RK_U32 size) +{ + MPP_RET ret; + + FUN_T("FUN_IN"); + p->keyFrame = !(pbase[0] & 1); + p->vpVersion = (pbase[0] >> 1) & 7; + p->showFrame = 1; + if (p->keyFrame && !p->needKeyFrame) { + p->needKeyFrame = 1; + } else { + if (!p->needKeyFrame) { + mpp_err("no found key frame"); + return MPP_NOK; + } + } + if (p->decMode == VP8HWD_VP7) { + p->offsetToDctParts = (pbase[0] >> 4) | (pbase[1] << 4) | (pbase[2] << 12); + p->frameTagSize = p->vpVersion >= 1 ? 3 : 4; + } else { + p->offsetToDctParts = (pbase[0] >> 5) | (pbase[1] << 3) | (pbase[2] << 11); + // mpp_log("offsetToDctParts %d pbase[0] = 0x%x pbase[1] = 0x%x pbase[2] = 0x%x ", p->offsetToDctParts, pbase[0], + // pbase[1], pbase[2]); + p->showFrame = (pbase[0] >> 4) & 1; + p->frameTagSize = 3; + } + pbase += p->frameTagSize; + size -= p->frameTagSize; + if (p->keyFrame) + vp8hwdResetProbs(p); + //mpp_log_f("p->decMode = %d", p->decMode); + if (p->decMode == VP8HWD_VP8) { + ret = vp8_header_parser(p, pbase, size); + } else { + ret = vp7_header_parser(p, pbase, size); + } + if (ret != MPP_OK) { + return ret; + } + return MPP_OK; +} + + +MPP_RET vp8d_parser_parse(void *ctx, HalDecTask *in_task) +{ + MPP_RET ret = MPP_OK; + VP8DContext *c = (VP8DContext *)ctx; + VP8DParserContext_t *p = (VP8DParserContext_t *)c->parse_ctx; + FUN_T("FUN_IN"); + + ret = decoder_frame_header(p, p->bitstream_sw_buf, p->stream_size); + + if (MPP_OK != ret) { + mpp_err("decoder_frame_header err ret %d", ret); + FUN_T("FUN_OUT"); + return ret; + } + + vp8hwdSetPartitionOffsets(p, p->bitstream_sw_buf, p->stream_size); + + ret = vp8d_alloc_frame(p); + if (MPP_OK != ret) { + mpp_err("vp8d_alloc_frame err ret %d", ret); + FUN_T("FUN_OUT"); + return ret; + } + + vp8d_convert_to_syntx(p, in_task); + in_task->syntax.data = (void *)p->dxva_ctx; + in_task->syntax.number = 1; + in_task->output = p->frame_out->slot_index; + in_task->valid = 1; + if (p->eos) { + in_task->flags.eos = p->eos; + } + vp8d_ref_update(p); + + FUN_T("FUN_OUT"); + return ret; +} + +MPP_RET vp8d_parser_callback(void *ctx, void *hal_info) +{ + MPP_RET ret = MPP_OK; + FUN_T("FUN_IN"); + (void)ctx; + (void)hal_info; + FUN_T("FUN_OUT"); + return ret; +} diff --git a/mpp/codec/dec/vp8/vp8d_parser.h b/mpp/codec/dec/vp8/vp8d_parser.h index 79f21880..97c0f422 100644 --- a/mpp/codec/dec/vp8/vp8d_parser.h +++ b/mpp/codec/dec/vp8/vp8d_parser.h @@ -1,200 +1,200 @@ -/* - * - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __VP8D_PARSER_H__ -#define __VP8D_PARSER_H__ - -#include "mpp_bitread.h" -#include "mpp_common.h" -#include "mpp_frame.h" -#include "mpp_mem.h" -#include "mpp_dec.h" -#include "mpp_packet.h" - -#include "vp8d_syntax.h" -#include "vp8d_data.h" - -#define VP8HWD_VP7 1 -#define VP8HWD_VP8 2 -#define VP8HWD_WEBP 3 - -#define DEC_MODE_VP7 9 -#define DEC_MODE_VP8 10 - -#define MAX_NBR_OF_SEGMENTS (4) -#define MAX_NBR_OF_MB_REF_LF_DELTAS (4) -#define MAX_NBR_OF_MB_MODE_LF_DELTAS (4) - -#define MAX_NBR_OF_DCT_PARTITIONS (8) - -#define MAX_NBR_OF_VP7_MB_FEATURES (4) - -#define VP8D_BUF_SIZE_BITMEM (512 * 1024) -#define VP8D_PROB_TABLE_SIZE (1<<16) /* TODO */ -#define VP8D_MAX_SEGMAP_SIZE (2048 + 1024) //1920*1080 /* TODO */ -#define VP8_KEY_FRAME_START_CODE 0x9d012a - -#define VP8D_DBG_FUNCTION (0x00000001) -#define VP8D_DBG_WARNNING (0x00000004) -#define VP8D_DBG_LOG (0x00000008) -#define VP8D_DBG_SEC_HEADER (0x00000010) - - -typedef enum { - VP8_YCbCr_BT601, - VP8_CUSTOM -} vpColorSpace_e; - -typedef struct { - RK_U32 lowvalue; - RK_U32 range; - RK_U32 value; - RK_S32 count; - RK_U32 pos; - RK_U8 *buffer; - RK_U32 BitCounter; - RK_U32 streamEndPos; - RK_U32 strmError; -} vpBoolCoder_t; - -typedef struct { - RK_U8 probLuma16x16PredMode[4]; - RK_U8 probChromaPredMode[3]; - RK_U8 probMvContext[2][VP8_MV_PROBS_PER_COMPONENT]; - RK_U8 probCoeffs[4][8][3][11]; -} vp8EntropyProbs_t; - -typedef struct VP8Frame { - MppFrame f; - RK_S32 slot_index; - RK_S8 ref_count; -} VP8Frame; - - -typedef struct VP8DParserContext { - DXVA_PicParams_VP8 *dxva_ctx; - RK_U8 *bitstream_sw_buf; - RK_U32 max_stream_size; - RK_U32 stream_size; - - VP8Frame *frame_out; - VP8Frame *frame_ref; - VP8Frame *frame_golden; - VP8Frame *frame_alternate; - - vpBoolCoder_t bitstr; - - RK_U32 decMode; - - /* Current frame dimensions */ - RK_U32 width; - RK_U32 height; - RK_U32 scaledWidth; - RK_U32 scaledHeight; - - RK_U8 vpVersion; - RK_U32 vpProfile; - - RK_U32 keyFrame; - - RK_U8 coeffSkipMode; - - /* DCT coefficient partitions */ - RK_U32 offsetToDctParts; - RK_U32 nbrDctPartitions; - RK_U32 dctPartitionOffsets[MAX_NBR_OF_DCT_PARTITIONS]; - - vpColorSpace_e colorSpace; - RK_U32 clamping; - RK_U32 showFrame; - - - RK_U32 refreshGolden; - RK_U32 refreshAlternate; - RK_U32 refreshLast; - RK_U32 refreshEntropyProbs; - RK_U32 copyBufferToGolden; - RK_U32 copyBufferToAlternate; - - RK_U32 refFrameSignBias[2]; - RK_U32 useAsReference; - RK_U32 loopFilterType; - RK_U32 loopFilterLevel; - RK_U32 loopFilterSharpness; - - /* Quantization parameters */ - RK_S8 qpYAc, qpYDc, qpY2Ac, qpY2Dc, qpChAc, qpChDc; - - /* From here down, frame-to-frame persisting stuff */ - RK_U32 vp7ScanOrder[16]; - RK_U32 vp7PrevScanOrder[16]; - - /* Probabilities */ - RK_U32 probIntra; - RK_U32 probRefLast; - RK_U32 probRefGolden; - RK_U32 probMbSkipFalse; - RK_U32 probSegment[3]; - vp8EntropyProbs_t entropy, entropyLast; - - /* Segment and macroblock specific values */ - RK_U32 segmentationEnabled; - RK_U32 segmentationMapUpdate; - RK_U32 segmentFeatureMode; /* delta/abs */ - RK_S32 segmentQp[MAX_NBR_OF_SEGMENTS]; - RK_S32 segmentLoopfilter[MAX_NBR_OF_SEGMENTS]; - RK_U32 modeRefLfEnabled; - RK_S32 mbRefLfDelta[MAX_NBR_OF_MB_REF_LF_DELTAS]; - RK_S32 mbModeLfDelta[MAX_NBR_OF_MB_MODE_LF_DELTAS]; - - RK_U32 frameTagSize; - - /* Value to remember last frames prediction for hits into most - * probable reference frame */ - RK_U32 refbuPredHits; - - - RK_S32 dcPred[2]; - RK_S32 dcMatch[2]; - - RK_U32 frame_cnt; - RK_U64 pts; - - RK_U32 needKeyFrame; - MppPacket input_packet; - RK_U32 eos; - - MppBufSlots packet_slots; - MppBufSlots frame_slots; - - IOInterruptCB notify_cb; - - // FILE *fp_dbg_file[VP8D_DBG_FILE_NUM]; - FILE *fp_dbg_yuv; -} VP8DParserContext_t; - -MPP_RET vp8d_parser_init (void *ctx, ParserCfg *cfg); -MPP_RET vp8d_parser_deinit (void *ctx); -MPP_RET vp8d_parser_reset (void *ctx); -MPP_RET vp8d_parser_flush (void *ctx); -MPP_RET vp8d_parser_control(void *ctx, RK_S32 cmd_type, void *param); -MPP_RET vp8d_parser_prepare(void *ctx, MppPacket pkt, HalDecTask *task); -MPP_RET vp8d_parser_parse (void *ctx, HalDecTask *task); -MPP_RET vp8d_parser_callback(void *ctx, void *hal_info); - -#endif - +/* + * + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __VP8D_PARSER_H__ +#define __VP8D_PARSER_H__ + +#include "mpp_bitread.h" +#include "mpp_common.h" +#include "mpp_frame.h" +#include "mpp_mem.h" +#include "mpp_dec.h" +#include "mpp_packet.h" + +#include "vp8d_syntax.h" +#include "vp8d_data.h" + +#define VP8HWD_VP7 1 +#define VP8HWD_VP8 2 +#define VP8HWD_WEBP 3 + +#define DEC_MODE_VP7 9 +#define DEC_MODE_VP8 10 + +#define MAX_NBR_OF_SEGMENTS (4) +#define MAX_NBR_OF_MB_REF_LF_DELTAS (4) +#define MAX_NBR_OF_MB_MODE_LF_DELTAS (4) + +#define MAX_NBR_OF_DCT_PARTITIONS (8) + +#define MAX_NBR_OF_VP7_MB_FEATURES (4) + +#define VP8D_BUF_SIZE_BITMEM (512 * 1024) +#define VP8D_PROB_TABLE_SIZE (1<<16) /* TODO */ +#define VP8D_MAX_SEGMAP_SIZE (2048 + 1024) //1920*1080 /* TODO */ +#define VP8_KEY_FRAME_START_CODE 0x9d012a + +#define VP8D_DBG_FUNCTION (0x00000001) +#define VP8D_DBG_WARNNING (0x00000004) +#define VP8D_DBG_LOG (0x00000008) +#define VP8D_DBG_SEC_HEADER (0x00000010) + + +typedef enum { + VP8_YCbCr_BT601, + VP8_CUSTOM +} vpColorSpace_e; + +typedef struct { + RK_U32 lowvalue; + RK_U32 range; + RK_U32 value; + RK_S32 count; + RK_U32 pos; + RK_U8 *buffer; + RK_U32 BitCounter; + RK_U32 streamEndPos; + RK_U32 strmError; +} vpBoolCoder_t; + +typedef struct { + RK_U8 probLuma16x16PredMode[4]; + RK_U8 probChromaPredMode[3]; + RK_U8 probMvContext[2][VP8_MV_PROBS_PER_COMPONENT]; + RK_U8 probCoeffs[4][8][3][11]; +} vp8EntropyProbs_t; + +typedef struct VP8Frame { + MppFrame f; + RK_S32 slot_index; + RK_S8 ref_count; +} VP8Frame; + + +typedef struct VP8DParserContext { + DXVA_PicParams_VP8 *dxva_ctx; + RK_U8 *bitstream_sw_buf; + RK_U32 max_stream_size; + RK_U32 stream_size; + + VP8Frame *frame_out; + VP8Frame *frame_ref; + VP8Frame *frame_golden; + VP8Frame *frame_alternate; + + vpBoolCoder_t bitstr; + + RK_U32 decMode; + + /* Current frame dimensions */ + RK_U32 width; + RK_U32 height; + RK_U32 scaledWidth; + RK_U32 scaledHeight; + + RK_U8 vpVersion; + RK_U32 vpProfile; + + RK_U32 keyFrame; + + RK_U8 coeffSkipMode; + + /* DCT coefficient partitions */ + RK_U32 offsetToDctParts; + RK_U32 nbrDctPartitions; + RK_U32 dctPartitionOffsets[MAX_NBR_OF_DCT_PARTITIONS]; + + vpColorSpace_e colorSpace; + RK_U32 clamping; + RK_U32 showFrame; + + + RK_U32 refreshGolden; + RK_U32 refreshAlternate; + RK_U32 refreshLast; + RK_U32 refreshEntropyProbs; + RK_U32 copyBufferToGolden; + RK_U32 copyBufferToAlternate; + + RK_U32 refFrameSignBias[2]; + RK_U32 useAsReference; + RK_U32 loopFilterType; + RK_U32 loopFilterLevel; + RK_U32 loopFilterSharpness; + + /* Quantization parameters */ + RK_S8 qpYAc, qpYDc, qpY2Ac, qpY2Dc, qpChAc, qpChDc; + + /* From here down, frame-to-frame persisting stuff */ + RK_U32 vp7ScanOrder[16]; + RK_U32 vp7PrevScanOrder[16]; + + /* Probabilities */ + RK_U32 probIntra; + RK_U32 probRefLast; + RK_U32 probRefGolden; + RK_U32 probMbSkipFalse; + RK_U32 probSegment[3]; + vp8EntropyProbs_t entropy, entropyLast; + + /* Segment and macroblock specific values */ + RK_U32 segmentationEnabled; + RK_U32 segmentationMapUpdate; + RK_U32 segmentFeatureMode; /* delta/abs */ + RK_S32 segmentQp[MAX_NBR_OF_SEGMENTS]; + RK_S32 segmentLoopfilter[MAX_NBR_OF_SEGMENTS]; + RK_U32 modeRefLfEnabled; + RK_S32 mbRefLfDelta[MAX_NBR_OF_MB_REF_LF_DELTAS]; + RK_S32 mbModeLfDelta[MAX_NBR_OF_MB_MODE_LF_DELTAS]; + + RK_U32 frameTagSize; + + /* Value to remember last frames prediction for hits into most + * probable reference frame */ + RK_U32 refbuPredHits; + + + RK_S32 dcPred[2]; + RK_S32 dcMatch[2]; + + RK_U32 frame_cnt; + RK_U64 pts; + + RK_U32 needKeyFrame; + MppPacket input_packet; + RK_U32 eos; + + MppBufSlots packet_slots; + MppBufSlots frame_slots; + + IOInterruptCB notify_cb; + + // FILE *fp_dbg_file[VP8D_DBG_FILE_NUM]; + FILE *fp_dbg_yuv; +} VP8DParserContext_t; + +MPP_RET vp8d_parser_init (void *ctx, ParserCfg *cfg); +MPP_RET vp8d_parser_deinit (void *ctx); +MPP_RET vp8d_parser_reset (void *ctx); +MPP_RET vp8d_parser_flush (void *ctx); +MPP_RET vp8d_parser_control(void *ctx, RK_S32 cmd_type, void *param); +MPP_RET vp8d_parser_prepare(void *ctx, MppPacket pkt, HalDecTask *task); +MPP_RET vp8d_parser_parse (void *ctx, HalDecTask *task); +MPP_RET vp8d_parser_callback(void *ctx, void *hal_info); + +#endif + diff --git a/mpp/codec/dec/vp9/vp9d_api.c b/mpp/codec/dec/vp9/vp9d_api.c index 90b944e9..e549e34c 100644 --- a/mpp/codec/dec/vp9/vp9d_api.c +++ b/mpp/codec/dec/vp9/vp9d_api.c @@ -1,247 +1,247 @@ -/* -* -* Copyright 2015 Rockchip Electronics Co. LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#define MODULE_TAG "vp9d_api" - -#include -#include -#include - -//#include "common.h" -#include "mpp_packet.h" -#include "mpp_packet_impl.h" -#include "mpp_mem.h" -#include "mpp_log.h" -#include "vp9d_codec.h" -#include "vp9d_parser.h" -#include "vp9d_api.h" - -/*! -*********************************************************************** -* \brief -* alloc all buffer -*********************************************************************** -*/ - -MPP_RET vp9d_init(void *ctx, ParserCfg *init) -{ - MPP_RET ret = MPP_OK; - RK_U8 *buf = NULL; - RK_S32 size = SZ_512K; - Vp9CodecContext *vp9_ctx = (Vp9CodecContext *)ctx; - - if (!vp9_ctx || !init) { - mpp_err("vp9d init fail"); - return MPP_ERR_NULL_PTR; - } - - if ((ret = vp9d_parser_init(vp9_ctx, init)) != MPP_OK) - goto _err_exit; - - vp9_ctx->notify_cb = init->notify_cb; - if ((ret = vp9d_split_init(vp9_ctx)) != MPP_OK) - goto _err_exit; - - buf = mpp_malloc(RK_U8, size); - if (!buf) { - mpp_err("vp9 init malloc stream buffer fail"); - ret = MPP_ERR_NOMEM; - goto _err_exit; - } - - if ((ret = mpp_packet_init(&vp9_ctx->pkt, (void *)buf, size)) != MPP_OK) - goto _err_exit; - - return ret; - -_err_exit: - vp9d_deinit(vp9_ctx); - return ret; -} - -/*! -*********************************************************************** -* \brief -* free all buffer -*********************************************************************** -*/ -MPP_RET vp9d_deinit(void *ctx) -{ - RK_U8 *buf = NULL; - Vp9CodecContext *vp9_ctx = (Vp9CodecContext *)ctx; - - if (vp9_ctx) { - vp9d_parser_deinit(vp9_ctx); - vp9d_split_deinit(vp9_ctx); - if (vp9_ctx->pkt) { - buf = mpp_packet_get_data(vp9_ctx->pkt); - MPP_FREE(buf); - mpp_packet_deinit(&vp9_ctx->pkt); - } - } - - return MPP_OK; -} - -/*! -*********************************************************************** -* \brief -* reset -*********************************************************************** -*/ -MPP_RET vp9d_reset(void *ctx) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - - Vp9CodecContext *vp9_ctx = (Vp9CodecContext *)ctx; - vp9d_paser_reset(vp9_ctx); - return ret = MPP_OK; -} - -/*! -*********************************************************************** -* \brief -* flush -*********************************************************************** -*/ -MPP_RET vp9d_flush(void *ctx) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - - (void)ctx; - return ret = MPP_OK; -} - -/*! -*********************************************************************** -* \brief -* control/perform -*********************************************************************** -*/ -MPP_RET vp9d_control(void *ctx, RK_S32 cmd_type, void *param) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - - (void)ctx; - (void)cmd_type; - (void)param; - - return ret = MPP_OK; -} - - -/*! -*********************************************************************** -* \brief -* prepare -*********************************************************************** -*/ -MPP_RET vp9d_prepare(void *ctx, MppPacket pkt, HalDecTask *task) -{ - MPP_RET ret = MPP_OK; - Vp9CodecContext *vp9_ctx = (Vp9CodecContext *)ctx; - SplitContext_t *ps = (SplitContext_t *)vp9_ctx->priv_data2; - RK_S64 pts = -1; - RK_S64 dts = -1; - RK_U8 *buf = NULL; - RK_S32 length = 0; - RK_U8 *out_data = NULL; - RK_S32 out_size = -1; - RK_S32 consumed = 0; - RK_U8 *pos = NULL; - task->valid = -1; - - pts = mpp_packet_get_pts(pkt); - dts = mpp_packet_get_dts(pkt); - vp9_ctx->eos = mpp_packet_get_eos(pkt); - buf = pos = mpp_packet_get_pos(pkt); - length = (RK_S32)mpp_packet_get_length(pkt); - - consumed = vp9d_split_frame(ps, &out_data, &out_size, buf, length); - pos += consumed; - mpp_packet_set_pos(pkt, pos); - - vp9d_get_frame_stream(vp9_ctx, out_data, out_size); - if (out_size > 0) { - task->input_packet = vp9_ctx->pkt; - task->valid = 1; - mpp_packet_set_pts(vp9_ctx->pkt, pts); - mpp_packet_set_dts(vp9_ctx->pkt, dts); - task->flags.eos = vp9_ctx->eos; - } else { - task->valid = 0; - task->flags.eos = vp9_ctx->eos; - } - - (void)pts; - (void)dts; - (void)task; - return ret = MPP_OK; -} - - -/*! -*********************************************************************** -* \brief -* parser -*********************************************************************** -*/ -MPP_RET vp9d_parse(void *ctx, HalDecTask *in_task) -{ - Vp9CodecContext *vp9_ctx = (Vp9CodecContext *)ctx; - MPP_RET ret = MPP_OK; - vp9_parser_frame(vp9_ctx, in_task); - - return ret; -} -/*! -*********************************************************************** -* \brief -* callback -*********************************************************************** -*/ -MPP_RET vp9d_callback(void *decoder, void *info) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - Vp9CodecContext *vp9_ctx = (Vp9CodecContext *)decoder; - vp9_parser_update(vp9_ctx, info); - - return ret = MPP_OK; -} - -/*! -*********************************************************************** -* \brief -* api struct interface -*********************************************************************** -*/ - -const ParserApi api_vp9d_parser = { - "vp9d_parse", - MPP_VIDEO_CodingVP9, - sizeof(Vp9CodecContext), - 0, - vp9d_init, - vp9d_deinit, - vp9d_prepare, - vp9d_parse, - vp9d_reset, - vp9d_flush, - vp9d_control, - vp9d_callback, -}; - +/* +* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#define MODULE_TAG "vp9d_api" + +#include +#include +#include + +//#include "common.h" +#include "mpp_packet.h" +#include "mpp_packet_impl.h" +#include "mpp_mem.h" +#include "mpp_log.h" +#include "vp9d_codec.h" +#include "vp9d_parser.h" +#include "vp9d_api.h" + +/*! +*********************************************************************** +* \brief +* alloc all buffer +*********************************************************************** +*/ + +MPP_RET vp9d_init(void *ctx, ParserCfg *init) +{ + MPP_RET ret = MPP_OK; + RK_U8 *buf = NULL; + RK_S32 size = SZ_512K; + Vp9CodecContext *vp9_ctx = (Vp9CodecContext *)ctx; + + if (!vp9_ctx || !init) { + mpp_err("vp9d init fail"); + return MPP_ERR_NULL_PTR; + } + + if ((ret = vp9d_parser_init(vp9_ctx, init)) != MPP_OK) + goto _err_exit; + + vp9_ctx->notify_cb = init->notify_cb; + if ((ret = vp9d_split_init(vp9_ctx)) != MPP_OK) + goto _err_exit; + + buf = mpp_malloc(RK_U8, size); + if (!buf) { + mpp_err("vp9 init malloc stream buffer fail"); + ret = MPP_ERR_NOMEM; + goto _err_exit; + } + + if ((ret = mpp_packet_init(&vp9_ctx->pkt, (void *)buf, size)) != MPP_OK) + goto _err_exit; + + return ret; + +_err_exit: + vp9d_deinit(vp9_ctx); + return ret; +} + +/*! +*********************************************************************** +* \brief +* free all buffer +*********************************************************************** +*/ +MPP_RET vp9d_deinit(void *ctx) +{ + RK_U8 *buf = NULL; + Vp9CodecContext *vp9_ctx = (Vp9CodecContext *)ctx; + + if (vp9_ctx) { + vp9d_parser_deinit(vp9_ctx); + vp9d_split_deinit(vp9_ctx); + if (vp9_ctx->pkt) { + buf = mpp_packet_get_data(vp9_ctx->pkt); + MPP_FREE(buf); + mpp_packet_deinit(&vp9_ctx->pkt); + } + } + + return MPP_OK; +} + +/*! +*********************************************************************** +* \brief +* reset +*********************************************************************** +*/ +MPP_RET vp9d_reset(void *ctx) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + + Vp9CodecContext *vp9_ctx = (Vp9CodecContext *)ctx; + vp9d_paser_reset(vp9_ctx); + return ret = MPP_OK; +} + +/*! +*********************************************************************** +* \brief +* flush +*********************************************************************** +*/ +MPP_RET vp9d_flush(void *ctx) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + + (void)ctx; + return ret = MPP_OK; +} + +/*! +*********************************************************************** +* \brief +* control/perform +*********************************************************************** +*/ +MPP_RET vp9d_control(void *ctx, RK_S32 cmd_type, void *param) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + + (void)ctx; + (void)cmd_type; + (void)param; + + return ret = MPP_OK; +} + + +/*! +*********************************************************************** +* \brief +* prepare +*********************************************************************** +*/ +MPP_RET vp9d_prepare(void *ctx, MppPacket pkt, HalDecTask *task) +{ + MPP_RET ret = MPP_OK; + Vp9CodecContext *vp9_ctx = (Vp9CodecContext *)ctx; + SplitContext_t *ps = (SplitContext_t *)vp9_ctx->priv_data2; + RK_S64 pts = -1; + RK_S64 dts = -1; + RK_U8 *buf = NULL; + RK_S32 length = 0; + RK_U8 *out_data = NULL; + RK_S32 out_size = -1; + RK_S32 consumed = 0; + RK_U8 *pos = NULL; + task->valid = -1; + + pts = mpp_packet_get_pts(pkt); + dts = mpp_packet_get_dts(pkt); + vp9_ctx->eos = mpp_packet_get_eos(pkt); + buf = pos = mpp_packet_get_pos(pkt); + length = (RK_S32)mpp_packet_get_length(pkt); + + consumed = vp9d_split_frame(ps, &out_data, &out_size, buf, length); + pos += consumed; + mpp_packet_set_pos(pkt, pos); + + vp9d_get_frame_stream(vp9_ctx, out_data, out_size); + if (out_size > 0) { + task->input_packet = vp9_ctx->pkt; + task->valid = 1; + mpp_packet_set_pts(vp9_ctx->pkt, pts); + mpp_packet_set_dts(vp9_ctx->pkt, dts); + task->flags.eos = vp9_ctx->eos; + } else { + task->valid = 0; + task->flags.eos = vp9_ctx->eos; + } + + (void)pts; + (void)dts; + (void)task; + return ret = MPP_OK; +} + + +/*! +*********************************************************************** +* \brief +* parser +*********************************************************************** +*/ +MPP_RET vp9d_parse(void *ctx, HalDecTask *in_task) +{ + Vp9CodecContext *vp9_ctx = (Vp9CodecContext *)ctx; + MPP_RET ret = MPP_OK; + vp9_parser_frame(vp9_ctx, in_task); + + return ret; +} +/*! +*********************************************************************** +* \brief +* callback +*********************************************************************** +*/ +MPP_RET vp9d_callback(void *decoder, void *info) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + Vp9CodecContext *vp9_ctx = (Vp9CodecContext *)decoder; + vp9_parser_update(vp9_ctx, info); + + return ret = MPP_OK; +} + +/*! +*********************************************************************** +* \brief +* api struct interface +*********************************************************************** +*/ + +const ParserApi api_vp9d_parser = { + "vp9d_parse", + MPP_VIDEO_CodingVP9, + sizeof(Vp9CodecContext), + 0, + vp9d_init, + vp9d_deinit, + vp9d_prepare, + vp9d_parse, + vp9d_reset, + vp9d_flush, + vp9d_control, + vp9d_callback, +}; + diff --git a/mpp/codec/enc/dummy/dummy_enc_api.c b/mpp/codec/enc/dummy/dummy_enc_api.c index 29cc8693..5d05d1f7 100644 --- a/mpp/codec/enc/dummy/dummy_enc_api.c +++ b/mpp/codec/enc/dummy/dummy_enc_api.c @@ -1,22 +1,22 @@ -/* -* -* Copyright 2015 Rockchip Electronics Co. LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -#define MODULE_TAG "dummy_enc_api" - -#include "dummy_enc_api.h" - - - +/* +* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#define MODULE_TAG "dummy_enc_api" + +#include "dummy_enc_api.h" + + + diff --git a/mpp/codec/inc/avsd_api.h b/mpp/codec/inc/avsd_api.h index 64ed7185..b1b5d478 100644 --- a/mpp/codec/inc/avsd_api.h +++ b/mpp/codec/inc/avsd_api.h @@ -1,109 +1,109 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __AVSD_API_H__ -#define __AVSD_API_H__ - -#include "parser_api.h" - - -#define AVSD_DBG_ERROR (0x00000001) -#define AVSD_DBG_ASSERT (0x00000002) -#define AVSD_DBG_WARNNING (0x00000004) -#define AVSD_DBG_TRACE (0x00000008) - - -#define AVSD_DBG_INPUT (0x00000010) //!< input packet - - -#define AVSD_DBG_TIME (0x00000020) //!< input packet - -#define AVSD_DBG_CALLBACK (0x00008000) - - - - -extern RK_U32 avsd_parse_debug; - -#define AVSD_PARSE_TRACE(fmt, ...)\ -do {\ - if (AVSD_DBG_TRACE & avsd_parse_debug)\ - { mpp_log_f(fmt, ## __VA_ARGS__); }\ -} while (0) - - -#define AVSD_DBG(level, fmt, ...)\ -do {\ - if (level & avsd_parse_debug)\ - { mpp_log(fmt, ## __VA_ARGS__); }\ -} while (0) - -#ifdef INP_CHECK -#undef INP_CHECK -#endif -//!< input check -#define INP_CHECK(ret, val, ...)\ -do{\ - if ((val)) {\ - ret = MPP_ERR_INIT; \ - AVSD_DBG(AVSD_DBG_WARNNING, "input empty(%d).\n", __LINE__); \ - goto __RETURN; \ -}} while (0) -#ifdef MEM_CHECK -#undef MEM_CHECK -#endif -//!< memory malloc check -#define MEM_CHECK(ret, val, ...)\ -do{\ - if(!(val)) {\ - ret = MPP_ERR_MALLOC;\ - AVSD_DBG(AVSD_DBG_ERROR, "malloc buffer error(%d).\n", __LINE__); \ - goto __FAILED; \ -}} while (0) -#ifdef FUN_CHECK -#undef FUN_CHECK -#endif -//!< function return check -#define FUN_CHECK(val)\ -do{\ -if ((val) < 0) {\ - AVSD_DBG(AVSD_DBG_WARNNING, "Function error(%d).\n", __LINE__); \ - goto __FAILED; \ -}} while (0) - - - - -#ifdef __cplusplus -extern "C" { -#endif - -extern const ParserApi api_avsd_parser; - -MPP_RET avsd_init (void *decoder, ParserCfg *cfg); -MPP_RET avsd_deinit (void *decoder); -MPP_RET avsd_reset (void *decoder); -MPP_RET avsd_flush (void *decoder); -MPP_RET avsd_control(void *decoder, RK_S32 cmd_type, void *param); -MPP_RET avsd_prepare(void *decoder, MppPacket pkt, HalDecTask *task); -MPP_RET avsd_parse (void *decoder, HalDecTask *task); -MPP_RET avsd_callback(void *decoder, void *err_info); - -#ifdef __cplusplus -} -#endif - -#endif /*__AVSD_API_H__*/ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __AVSD_API_H__ +#define __AVSD_API_H__ + +#include "parser_api.h" + + +#define AVSD_DBG_ERROR (0x00000001) +#define AVSD_DBG_ASSERT (0x00000002) +#define AVSD_DBG_WARNNING (0x00000004) +#define AVSD_DBG_TRACE (0x00000008) + + +#define AVSD_DBG_INPUT (0x00000010) //!< input packet + + +#define AVSD_DBG_TIME (0x00000020) //!< input packet + +#define AVSD_DBG_CALLBACK (0x00008000) + + + + +extern RK_U32 avsd_parse_debug; + +#define AVSD_PARSE_TRACE(fmt, ...)\ +do {\ + if (AVSD_DBG_TRACE & avsd_parse_debug)\ + { mpp_log_f(fmt, ## __VA_ARGS__); }\ +} while (0) + + +#define AVSD_DBG(level, fmt, ...)\ +do {\ + if (level & avsd_parse_debug)\ + { mpp_log(fmt, ## __VA_ARGS__); }\ +} while (0) + +#ifdef INP_CHECK +#undef INP_CHECK +#endif +//!< input check +#define INP_CHECK(ret, val, ...)\ +do{\ + if ((val)) {\ + ret = MPP_ERR_INIT; \ + AVSD_DBG(AVSD_DBG_WARNNING, "input empty(%d).\n", __LINE__); \ + goto __RETURN; \ +}} while (0) +#ifdef MEM_CHECK +#undef MEM_CHECK +#endif +//!< memory malloc check +#define MEM_CHECK(ret, val, ...)\ +do{\ + if(!(val)) {\ + ret = MPP_ERR_MALLOC;\ + AVSD_DBG(AVSD_DBG_ERROR, "malloc buffer error(%d).\n", __LINE__); \ + goto __FAILED; \ +}} while (0) +#ifdef FUN_CHECK +#undef FUN_CHECK +#endif +//!< function return check +#define FUN_CHECK(val)\ +do{\ +if ((val) < 0) {\ + AVSD_DBG(AVSD_DBG_WARNNING, "Function error(%d).\n", __LINE__); \ + goto __FAILED; \ +}} while (0) + + + + +#ifdef __cplusplus +extern "C" { +#endif + +extern const ParserApi api_avsd_parser; + +MPP_RET avsd_init (void *decoder, ParserCfg *cfg); +MPP_RET avsd_deinit (void *decoder); +MPP_RET avsd_reset (void *decoder); +MPP_RET avsd_flush (void *decoder); +MPP_RET avsd_control(void *decoder, RK_S32 cmd_type, void *param); +MPP_RET avsd_prepare(void *decoder, MppPacket pkt, HalDecTask *task); +MPP_RET avsd_parse (void *decoder, HalDecTask *task); +MPP_RET avsd_callback(void *decoder, void *err_info); + +#ifdef __cplusplus +} +#endif + +#endif /*__AVSD_API_H__*/ diff --git a/mpp/codec/inc/dummy_dec_api.h b/mpp/codec/inc/dummy_dec_api.h index a16957e4..c49a9001 100644 --- a/mpp/codec/inc/dummy_dec_api.h +++ b/mpp/codec/inc/dummy_dec_api.h @@ -1,41 +1,41 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __DUMMY_DEC_API_H__ -#define __DUMMY_DEC_API_H__ - -#include "parser_api.h" - -#ifdef __cplusplus -extern "C" { -#endif - -extern const ParserApi dummy_dec_parser; - -MPP_RET dummy_dec_init (void *dec, ParserCfg *cfg); -MPP_RET dummy_dec_deinit (void *dec); -MPP_RET dummy_dec_reset (void *dec); -MPP_RET dummy_dec_flush (void *dec); -MPP_RET dummy_dec_control(void *dec, RK_S32 cmd_type, void *param); -MPP_RET dummy_dec_prepare(void *dec, MppPacket pkt, HalDecTask *task); -MPP_RET dummy_dec_parse (void *dec, HalDecTask *task); -MPP_RET dummy_dec_callback(void *dec, void *err_info); - -#ifdef __cplusplus -} -#endif - -#endif /*__DUMMY_DEC_API_H__*/ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __DUMMY_DEC_API_H__ +#define __DUMMY_DEC_API_H__ + +#include "parser_api.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern const ParserApi dummy_dec_parser; + +MPP_RET dummy_dec_init (void *dec, ParserCfg *cfg); +MPP_RET dummy_dec_deinit (void *dec); +MPP_RET dummy_dec_reset (void *dec); +MPP_RET dummy_dec_flush (void *dec); +MPP_RET dummy_dec_control(void *dec, RK_S32 cmd_type, void *param); +MPP_RET dummy_dec_prepare(void *dec, MppPacket pkt, HalDecTask *task); +MPP_RET dummy_dec_parse (void *dec, HalDecTask *task); +MPP_RET dummy_dec_callback(void *dec, void *err_info); + +#ifdef __cplusplus +} +#endif + +#endif /*__DUMMY_DEC_API_H__*/ diff --git a/mpp/codec/inc/dummy_enc_api.h b/mpp/codec/inc/dummy_enc_api.h index 32246935..5b8fe647 100644 --- a/mpp/codec/inc/dummy_enc_api.h +++ b/mpp/codec/inc/dummy_enc_api.h @@ -1,31 +1,31 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __DUMMY_ENC_API_H__ -#define __DUMMY_ENC_API_H__ - -#include "mpp_enc.h" - -#ifdef __cplusplus -extern "C" { -#endif - - -#ifdef __cplusplus -} -#endif - -#endif /*__DUMMY_ENC_API_H__*/ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __DUMMY_ENC_API_H__ +#define __DUMMY_ENC_API_H__ + +#include "mpp_enc.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +#ifdef __cplusplus +} +#endif + +#endif /*__DUMMY_ENC_API_H__*/ diff --git a/mpp/codec/inc/encoder_codec_api.h b/mpp/codec/inc/encoder_codec_api.h index 549c089b..6146fa28 100644 --- a/mpp/codec/inc/encoder_codec_api.h +++ b/mpp/codec/inc/encoder_codec_api.h @@ -1,81 +1,81 @@ -/* - * Copyright 2010 Rockchip Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __CONTROL_API_H__ -#define __CONTROL_API_H__ - -#include "rk_mpi.h" -#include "mpp_buf_slot.h" -#include "hal_task.h" - -// TODO -#include "../enc/h264/include/h264encapi.h" - -// config cmd -typedef enum EncCfgCmd_t { - CHK_ENC_CFG, - SET_ENC_CFG, - SET_ENC_RC_CFG, - GET_ENC_EXTRA_INFO, - GET_OUTPUT_STREAM_SIZE, -} EncCfgCmd; - -/* - * the reset wait for extension - */ -typedef struct EncControllerInitCfg_t { - // input - MppCodingType coding; - - // output - RK_S32 task_count; - IOInterruptCB notify_cb; -} ControllerCfg; - -/* - * ControlApi is the data structure provided from different encoders - * - * They will be static register to mpp_enc for scaning - * name - encoder name - * coding - encoder coding type - * ctx_size - encoder context size, mpp_dec will use this to malloc memory - * flag - reserve - * - * init - encoder initialization function - * deinit - encoder de-initialization function - * encoder - encoder main working function, mpp_dec will input packet and get output syntax - * reset - encoder reset function - * flush - encoder output all frames - * control - encoder configure function - */ -typedef struct ControlApi_t { - char *name; - MppCodingType coding; - RK_U32 ctx_size; - RK_U32 flag; - - MPP_RET (*init)(void *ctx, ControllerCfg *ctrlCfg); - MPP_RET (*deinit)(void *ctx); - - MPP_RET (*encode)(void *ctx, HalEncTask *task); - - MPP_RET (*reset)(void *ctx); - MPP_RET (*flush)(void *ctx); - MPP_RET (*config)(void *ctx, RK_S32 cmd, void *param); - MPP_RET (*callback)(void *ctx, void *feedback); -} ControlApi; - -#endif /*__CONTROL_API_H__*/ +/* + * Copyright 2010 Rockchip Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CONTROL_API_H__ +#define __CONTROL_API_H__ + +#include "rk_mpi.h" +#include "mpp_buf_slot.h" +#include "hal_task.h" + +// TODO +#include "../enc/h264/include/h264encapi.h" + +// config cmd +typedef enum EncCfgCmd_t { + CHK_ENC_CFG, + SET_ENC_CFG, + SET_ENC_RC_CFG, + GET_ENC_EXTRA_INFO, + GET_OUTPUT_STREAM_SIZE, +} EncCfgCmd; + +/* + * the reset wait for extension + */ +typedef struct EncControllerInitCfg_t { + // input + MppCodingType coding; + + // output + RK_S32 task_count; + IOInterruptCB notify_cb; +} ControllerCfg; + +/* + * ControlApi is the data structure provided from different encoders + * + * They will be static register to mpp_enc for scaning + * name - encoder name + * coding - encoder coding type + * ctx_size - encoder context size, mpp_dec will use this to malloc memory + * flag - reserve + * + * init - encoder initialization function + * deinit - encoder de-initialization function + * encoder - encoder main working function, mpp_dec will input packet and get output syntax + * reset - encoder reset function + * flush - encoder output all frames + * control - encoder configure function + */ +typedef struct ControlApi_t { + char *name; + MppCodingType coding; + RK_U32 ctx_size; + RK_U32 flag; + + MPP_RET (*init)(void *ctx, ControllerCfg *ctrlCfg); + MPP_RET (*deinit)(void *ctx); + + MPP_RET (*encode)(void *ctx, HalEncTask *task); + + MPP_RET (*reset)(void *ctx); + MPP_RET (*flush)(void *ctx); + MPP_RET (*config)(void *ctx, RK_S32 cmd, void *param); + MPP_RET (*callback)(void *ctx, void *feedback); +} ControlApi; + +#endif /*__CONTROL_API_H__*/ diff --git a/mpp/codec/inc/h263d_api.h b/mpp/codec/inc/h263d_api.h index baae6d33..5299203a 100644 --- a/mpp/codec/inc/h263d_api.h +++ b/mpp/codec/inc/h263d_api.h @@ -1,17 +1,17 @@ -#ifndef __H263D_API_H__ -#define __H263D_API_H__ - -#include "parser_api.h" - -#ifdef __cplusplus -extern "C" { -#endif - -extern const ParserApi api_h263d_parser; - -#ifdef __cplusplus -} -#endif - -#endif - +#ifndef __H263D_API_H__ +#define __H263D_API_H__ + +#include "parser_api.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern const ParserApi api_h263d_parser; + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/mpp/codec/inc/h264d_api.h b/mpp/codec/inc/h264d_api.h index c48ca5c0..50b92677 100644 --- a/mpp/codec/inc/h264d_api.h +++ b/mpp/codec/inc/h264d_api.h @@ -1,51 +1,51 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __H264D_API_H__ -#define __H264D_API_H__ - -#include "parser_api.h" - - - -typedef enum mpp_decmtd_type { - MPP_DEC_NULL = 0, - MPP_DEC_BY_SLICE = 0x1, - MPP_DEC_BY_FRAME = 0x2, - MPP_DEC_MAX, -} MppDecMtd_type; - - -#ifdef __cplusplus -extern "C" { -#endif - -extern const ParserApi api_h264d_parser; - -MPP_RET h264d_init (void *decoder, ParserCfg *cfg); -MPP_RET h264d_deinit (void *decoder); -MPP_RET h264d_reset (void *decoder); -MPP_RET h264d_flush (void *decoder); -MPP_RET h264d_control(void *decoder, RK_S32 cmd_type, void *param); -MPP_RET h264d_prepare(void *decoder, MppPacket pkt, HalDecTask *task); -MPP_RET h264d_parse (void *decoder, HalDecTask *task); -MPP_RET h264d_callback(void *decoder, void *err_info); - -#ifdef __cplusplus -} -#endif - -#endif /*__H264D_API_H__*/ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __H264D_API_H__ +#define __H264D_API_H__ + +#include "parser_api.h" + + + +typedef enum mpp_decmtd_type { + MPP_DEC_NULL = 0, + MPP_DEC_BY_SLICE = 0x1, + MPP_DEC_BY_FRAME = 0x2, + MPP_DEC_MAX, +} MppDecMtd_type; + + +#ifdef __cplusplus +extern "C" { +#endif + +extern const ParserApi api_h264d_parser; + +MPP_RET h264d_init (void *decoder, ParserCfg *cfg); +MPP_RET h264d_deinit (void *decoder); +MPP_RET h264d_reset (void *decoder); +MPP_RET h264d_flush (void *decoder); +MPP_RET h264d_control(void *decoder, RK_S32 cmd_type, void *param); +MPP_RET h264d_prepare(void *decoder, MppPacket pkt, HalDecTask *task); +MPP_RET h264d_parse (void *decoder, HalDecTask *task); +MPP_RET h264d_callback(void *decoder, void *err_info); + +#ifdef __cplusplus +} +#endif + +#endif /*__H264D_API_H__*/ diff --git a/mpp/codec/inc/h264e_api.h b/mpp/codec/inc/h264e_api.h index 31067dd9..1a5723d0 100644 --- a/mpp/codec/inc/h264e_api.h +++ b/mpp/codec/inc/h264e_api.h @@ -1,40 +1,40 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __H264E_API_H__ -#define __H264E_API_H__ - -#include "encoder_codec_api.h" - -#ifdef __cplusplus -extern "C" { -#endif - -extern const ControlApi api_h264e_controller; - -MPP_RET h264e_init(void *ctx, ControllerCfg *ctrlCfg); -MPP_RET h264e_deinit(void *ctx); -MPP_RET h264e_encode(void *ctx, HalEncTask *task); -MPP_RET h264e_reset(void *ctx); -MPP_RET h264e_flush(void *ctx); -MPP_RET h264e_config(void *ctx, RK_S32 cmd, void *param); -MPP_RET h264e_callback(void *ctx, void *feedback); - -#ifdef __cplusplus -} -#endif - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __H264E_API_H__ +#define __H264E_API_H__ + +#include "encoder_codec_api.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern const ControlApi api_h264e_controller; + +MPP_RET h264e_init(void *ctx, ControllerCfg *ctrlCfg); +MPP_RET h264e_deinit(void *ctx); +MPP_RET h264e_encode(void *ctx, HalEncTask *task); +MPP_RET h264e_reset(void *ctx); +MPP_RET h264e_flush(void *ctx); +MPP_RET h264e_config(void *ctx, RK_S32 cmd, void *param); +MPP_RET h264e_callback(void *ctx, void *feedback); + +#ifdef __cplusplus +} +#endif + #endif /*__H264E_API_H__*/ diff --git a/mpp/codec/inc/h265d_api.h b/mpp/codec/inc/h265d_api.h index 15e25a87..2f56f9c5 100644 --- a/mpp/codec/inc/h265d_api.h +++ b/mpp/codec/inc/h265d_api.h @@ -1,47 +1,47 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __H265D_API_H__ -#define __H265D_API_H__ -#include "parser_api.h" - -#ifdef __cplusplus -extern "C" { -#endif - -extern const ParserApi api_h265d_parser; - -MPP_RET h265d_prepare(void *ctx, MppPacket pkt, HalDecTask *task); -MPP_RET h265d_init(void *ctx, ParserCfg *parser_cfg); -MPP_RET h265d_parse(void *ctx, HalDecTask *task); -MPP_RET h265d_deinit(void *ctx); -MPP_RET h265d_flush(void *ctx); -MPP_RET h265d_reset(void *ctx); -MPP_RET h265d_control(void *ctx, RK_S32 cmd, void *param); -MPP_RET h265d_callback(void *ctx, void *err_info); -RK_S32 mpp_hevc_split_frame(void *sc, - const RK_U8 **poutbuf, RK_S32 *poutbuf_size, - const RK_U8 *buf, RK_S32 buf_size); - -MPP_RET h265d_get_stream(void *ctx, RK_U8 **buf, RK_S32 *size); // used for compare openhevc -MPP_RET h265d_set_compare_info(void *ctx, void *info); - - -#ifdef __cplusplus -} -#endif - -#endif /*__H265D_API_H__*/ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __H265D_API_H__ +#define __H265D_API_H__ +#include "parser_api.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern const ParserApi api_h265d_parser; + +MPP_RET h265d_prepare(void *ctx, MppPacket pkt, HalDecTask *task); +MPP_RET h265d_init(void *ctx, ParserCfg *parser_cfg); +MPP_RET h265d_parse(void *ctx, HalDecTask *task); +MPP_RET h265d_deinit(void *ctx); +MPP_RET h265d_flush(void *ctx); +MPP_RET h265d_reset(void *ctx); +MPP_RET h265d_control(void *ctx, RK_S32 cmd, void *param); +MPP_RET h265d_callback(void *ctx, void *err_info); +RK_S32 mpp_hevc_split_frame(void *sc, + const RK_U8 **poutbuf, RK_S32 *poutbuf_size, + const RK_U8 *buf, RK_S32 buf_size); + +MPP_RET h265d_get_stream(void *ctx, RK_U8 **buf, RK_S32 *size); // used for compare openhevc +MPP_RET h265d_set_compare_info(void *ctx, void *info); + + +#ifdef __cplusplus +} +#endif + +#endif /*__H265D_API_H__*/ diff --git a/mpp/codec/inc/jpegd_api.h b/mpp/codec/inc/jpegd_api.h index 9a0c1b84..69190b1e 100644 --- a/mpp/codec/inc/jpegd_api.h +++ b/mpp/codec/inc/jpegd_api.h @@ -1,104 +1,104 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __JPEGD_API_H__ -#define __JPEGD_API_H__ -#include "parser_api.h" - -#ifdef __cplusplus -extern "C" { -#endif - -extern const ParserApi api_jpegd_parser; - -extern RK_U32 jpegd_log; -#define JPEGD_VBE_LOG (0x01) -#define JPEGD_DBG_LOG (0x02) -#define JPEGD_INF_LOG (0x04) -#define JPEGD_ERR_LOG (0x08) -#define JPEGD_DBG_ASSERT (1) - -#define FUN_TEST(tag) \ - do {\ - if (JPEGD_VBE_LOG & jpegd_log)\ - { mpp_log("[Verbose] %s: line(%d), func(%s)", tag, __LINE__, __FUNCTION__); }\ - } while (0) - - -#define JPEGD_ASSERT(val)\ - do {\ - if (JPEGD_DBG_ASSERT)\ - { mpp_assert(val); }\ - } while (0) - - -//check function return -#define CHECK_FUN(val) \ - do{ \ - if((val) < 0) { \ - ret = (val); \ - mpp_log("func return error(Line %d), ret:%d\n", __LINE__, ret); \ - goto __FAILED; \ - } \ - } while (0) - -//memory malloc check -#define CHECK_MEM(val, ...)\ - do{ if(!(val)) {\ - ret = MPP_ERR_MALLOC;\ - mpp_log("malloc buffer error(Line %d), pointer:%p\n", __LINE__, val);\ - goto __FAILED;\ - } } while (0) - -#define JPEGD_VERBOSE_LOG(fmt, ...) \ - do {\ - if (JPEGD_VBE_LOG & jpegd_log)\ - { mpp_log("[Verbose] func(%s), line(%d), "fmt"", __FUNCTION__, __LINE__, ##__VA_ARGS__); }\ - } while (0) - -#define JPEGD_DEBUG_LOG(fmt, ...) \ - do {\ - if (JPEGD_DBG_LOG & jpegd_log)\ - { mpp_log("[Debug] func(%s), line(%d), "fmt"", __FUNCTION__, __LINE__, ##__VA_ARGS__); }\ - } while (0) - -#define JPEGD_INFO_LOG(fmt, ...) \ - do {\ - if (JPEGD_INF_LOG & jpegd_log)\ - { mpp_log("[Info] func(%s), line(%d), "fmt"", __FUNCTION__, __LINE__, ##__VA_ARGS__); }\ - } while (0) - -#define JPEGD_ERROR_LOG(fmt, ...) \ - do {\ - if (JPEGD_ERR_LOG & jpegd_log)\ - { mpp_log("[Error] func(%s), line(%d), "fmt"", __FUNCTION__, __LINE__, ##__VA_ARGS__); }\ - } while (0) - - -MPP_RET jpegd_prepare(void *ctx, MppPacket pkt, HalDecTask *task); -MPP_RET jpegd_init(void *ctx, ParserCfg *parser_cfg); -MPP_RET jpegd_parse(void *ctx, HalDecTask *task); -MPP_RET jpegd_deinit(void *ctx); -MPP_RET jpegd_flush(void *ctx); -MPP_RET jpegd_reset(void *ctx); -MPP_RET jpegd_control(void *ctx, RK_S32 cmd, void *param); -MPP_RET jpegd_callback(void *ctx, void *err_info); - -#ifdef __cplusplus -} -#endif - -#endif /*__JPEGD_API_H__*/ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __JPEGD_API_H__ +#define __JPEGD_API_H__ +#include "parser_api.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern const ParserApi api_jpegd_parser; + +extern RK_U32 jpegd_log; +#define JPEGD_VBE_LOG (0x01) +#define JPEGD_DBG_LOG (0x02) +#define JPEGD_INF_LOG (0x04) +#define JPEGD_ERR_LOG (0x08) +#define JPEGD_DBG_ASSERT (1) + +#define FUN_TEST(tag) \ + do {\ + if (JPEGD_VBE_LOG & jpegd_log)\ + { mpp_log("[Verbose] %s: line(%d), func(%s)", tag, __LINE__, __FUNCTION__); }\ + } while (0) + + +#define JPEGD_ASSERT(val)\ + do {\ + if (JPEGD_DBG_ASSERT)\ + { mpp_assert(val); }\ + } while (0) + + +//check function return +#define CHECK_FUN(val) \ + do{ \ + if((val) < 0) { \ + ret = (val); \ + mpp_log("func return error(Line %d), ret:%d\n", __LINE__, ret); \ + goto __FAILED; \ + } \ + } while (0) + +//memory malloc check +#define CHECK_MEM(val, ...)\ + do{ if(!(val)) {\ + ret = MPP_ERR_MALLOC;\ + mpp_log("malloc buffer error(Line %d), pointer:%p\n", __LINE__, val);\ + goto __FAILED;\ + } } while (0) + +#define JPEGD_VERBOSE_LOG(fmt, ...) \ + do {\ + if (JPEGD_VBE_LOG & jpegd_log)\ + { mpp_log("[Verbose] func(%s), line(%d), "fmt"", __FUNCTION__, __LINE__, ##__VA_ARGS__); }\ + } while (0) + +#define JPEGD_DEBUG_LOG(fmt, ...) \ + do {\ + if (JPEGD_DBG_LOG & jpegd_log)\ + { mpp_log("[Debug] func(%s), line(%d), "fmt"", __FUNCTION__, __LINE__, ##__VA_ARGS__); }\ + } while (0) + +#define JPEGD_INFO_LOG(fmt, ...) \ + do {\ + if (JPEGD_INF_LOG & jpegd_log)\ + { mpp_log("[Info] func(%s), line(%d), "fmt"", __FUNCTION__, __LINE__, ##__VA_ARGS__); }\ + } while (0) + +#define JPEGD_ERROR_LOG(fmt, ...) \ + do {\ + if (JPEGD_ERR_LOG & jpegd_log)\ + { mpp_log("[Error] func(%s), line(%d), "fmt"", __FUNCTION__, __LINE__, ##__VA_ARGS__); }\ + } while (0) + + +MPP_RET jpegd_prepare(void *ctx, MppPacket pkt, HalDecTask *task); +MPP_RET jpegd_init(void *ctx, ParserCfg *parser_cfg); +MPP_RET jpegd_parse(void *ctx, HalDecTask *task); +MPP_RET jpegd_deinit(void *ctx); +MPP_RET jpegd_flush(void *ctx); +MPP_RET jpegd_reset(void *ctx); +MPP_RET jpegd_control(void *ctx, RK_S32 cmd, void *param); +MPP_RET jpegd_callback(void *ctx, void *err_info); + +#ifdef __cplusplus +} +#endif + +#endif /*__JPEGD_API_H__*/ diff --git a/mpp/codec/inc/m2vd_api.h b/mpp/codec/inc/m2vd_api.h index 5571abe3..ef52da0c 100644 --- a/mpp/codec/inc/m2vd_api.h +++ b/mpp/codec/inc/m2vd_api.h @@ -1,32 +1,32 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __M2VD_API_H__ -#define __M2VD_API_H__ - -#include "parser_api.h" - -#ifdef __cplusplus -extern "C" { -#endif - -extern const ParserApi api_m2vd_parser; - -#ifdef __cplusplus -} -#endif - -#endif +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __M2VD_API_H__ +#define __M2VD_API_H__ + +#include "parser_api.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern const ParserApi api_m2vd_parser; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/mpp/codec/inc/mpg4d_api.h b/mpp/codec/inc/mpg4d_api.h index 269ed30e..1711d1e9 100644 --- a/mpp/codec/inc/mpg4d_api.h +++ b/mpp/codec/inc/mpg4d_api.h @@ -1,17 +1,17 @@ -#ifndef __MPG4D_API_H__ -#define __MPG4D_API_H__ - -#include "parser_api.h" - -#ifdef __cplusplus -extern "C" { -#endif - -extern const ParserApi api_mpg4d_parser; - -#ifdef __cplusplus -} -#endif - -#endif - +#ifndef __MPG4D_API_H__ +#define __MPG4D_API_H__ + +#include "parser_api.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern const ParserApi api_mpg4d_parser; + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/mpp/codec/inc/mpp_dec.h b/mpp/codec/inc/mpp_dec.h index 07400bb8..0576d395 100644 --- a/mpp/codec/inc/mpp_dec.h +++ b/mpp/codec/inc/mpp_dec.h @@ -1,82 +1,82 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __MPP_DEC_H__ -#define __MPP_DEC_H__ - -#include "mpp_parser.h" -#include "mpp_hal.h" - -typedef struct MppDec_t MppDec; - -struct MppDec_t { - MppCodingType coding; - - Parser parser; - MppHal hal; - - // common resource - MppBufSlots frame_slots; - MppBufSlots packet_slots; - HalTaskGroup tasks; - - // status flag - RK_U32 reset_flag; - - // work mode flag - RK_U32 parser_need_split; - RK_U32 parser_fast_mode; - RK_U32 parser_internal_pts; - - // dec parser thread runtime resource context - MppPacket mpp_pkt_in; - void *mpp; -}; - -typedef struct { - MppCodingType coding; - RK_U32 fast_mode; - RK_U32 need_split; - RK_U32 internal_pts; - void *mpp; -} MppDecCfg; - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * main thread for all decoder. This thread will connect parser / hal / mpp - */ -void *mpp_dec_parser_thread(void *data); -void *mpp_dec_hal_thread(void *data); - -/* - * - */ -MPP_RET mpp_dec_init(MppDec **dec, MppDecCfg *cfg); -MPP_RET mpp_dec_deinit(MppDec *dec); - -MPP_RET mpp_dec_reset(MppDec *dec); -MPP_RET mpp_dec_flush(MppDec *dec); -MPP_RET mpp_dec_control(MppDec *dec, MpiCmd cmd, void *param); -MPP_RET mpp_dec_notify(void *ctx, void *info); - -#ifdef __cplusplus -} -#endif - -#endif /*__MPP_DEC_H__*/ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPP_DEC_H__ +#define __MPP_DEC_H__ + +#include "mpp_parser.h" +#include "mpp_hal.h" + +typedef struct MppDec_t MppDec; + +struct MppDec_t { + MppCodingType coding; + + Parser parser; + MppHal hal; + + // common resource + MppBufSlots frame_slots; + MppBufSlots packet_slots; + HalTaskGroup tasks; + + // status flag + RK_U32 reset_flag; + + // work mode flag + RK_U32 parser_need_split; + RK_U32 parser_fast_mode; + RK_U32 parser_internal_pts; + + // dec parser thread runtime resource context + MppPacket mpp_pkt_in; + void *mpp; +}; + +typedef struct { + MppCodingType coding; + RK_U32 fast_mode; + RK_U32 need_split; + RK_U32 internal_pts; + void *mpp; +} MppDecCfg; + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * main thread for all decoder. This thread will connect parser / hal / mpp + */ +void *mpp_dec_parser_thread(void *data); +void *mpp_dec_hal_thread(void *data); + +/* + * + */ +MPP_RET mpp_dec_init(MppDec **dec, MppDecCfg *cfg); +MPP_RET mpp_dec_deinit(MppDec *dec); + +MPP_RET mpp_dec_reset(MppDec *dec); +MPP_RET mpp_dec_flush(MppDec *dec); +MPP_RET mpp_dec_control(MppDec *dec, MpiCmd cmd, void *param); +MPP_RET mpp_dec_notify(void *ctx, void *info); + +#ifdef __cplusplus +} +#endif + +#endif /*__MPP_DEC_H__*/ diff --git a/mpp/codec/inc/mpp_enc.h b/mpp/codec/inc/mpp_enc.h index 2a451b18..31d45c57 100644 --- a/mpp/codec/inc/mpp_enc.h +++ b/mpp/codec/inc/mpp_enc.h @@ -1,65 +1,65 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __MPP_ENC_H__ -#define __MPP_ENC_H__ - -#include "rk_mpi.h" -#include "mpp_controller.h" -#include "mpp_hal.h" - -typedef struct MppEnc_t MppEnc; - -struct MppEnc_t { - MppCodingType coding; - Controller controller; - MppHal hal; - - // common resource - MppBufSlots frame_slots; - MppBufSlots packet_slots; - HalTaskGroup tasks; - - RK_U32 reset_flag; - void *mpp; - - /* - * configuration parameter to controller and hal - */ - MppEncConfig mpp_cfg; -}; - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * main thread for all encoder. This thread will connect encoder / hal / mpp - */ -void *mpp_enc_control_thread(void *data); -void *mpp_enc_hal_thread(void *data); - -MPP_RET mpp_enc_init(MppEnc **enc, MppCodingType coding); -MPP_RET mpp_enc_deinit(MppEnc *enc); -MPP_RET mpp_enc_control(MppEnc *enc, MpiCmd cmd, void *param); -MPP_RET mpp_enc_notify(void *ctx, void *info); -MPP_RET mpp_enc_reset(MppEnc *enc); - -#ifdef __cplusplus -} -#endif - -#endif /*__MPP_ENC_H__*/ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPP_ENC_H__ +#define __MPP_ENC_H__ + +#include "rk_mpi.h" +#include "mpp_controller.h" +#include "mpp_hal.h" + +typedef struct MppEnc_t MppEnc; + +struct MppEnc_t { + MppCodingType coding; + Controller controller; + MppHal hal; + + // common resource + MppBufSlots frame_slots; + MppBufSlots packet_slots; + HalTaskGroup tasks; + + RK_U32 reset_flag; + void *mpp; + + /* + * configuration parameter to controller and hal + */ + MppEncConfig mpp_cfg; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * main thread for all encoder. This thread will connect encoder / hal / mpp + */ +void *mpp_enc_control_thread(void *data); +void *mpp_enc_hal_thread(void *data); + +MPP_RET mpp_enc_init(MppEnc **enc, MppCodingType coding); +MPP_RET mpp_enc_deinit(MppEnc *enc); +MPP_RET mpp_enc_control(MppEnc *enc, MpiCmd cmd, void *param); +MPP_RET mpp_enc_notify(void *ctx, void *info); +MPP_RET mpp_enc_reset(MppEnc *enc); + +#ifdef __cplusplus +} +#endif + +#endif /*__MPP_ENC_H__*/ diff --git a/mpp/codec/inc/mpp_parser.h b/mpp/codec/inc/mpp_parser.h index 9845ac24..27fda0ff 100644 --- a/mpp/codec/inc/mpp_parser.h +++ b/mpp/codec/inc/mpp_parser.h @@ -1,43 +1,43 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __MPP_PARSER_H__ -#define __MPP_PARSER_H__ - -#include "parser_api.h" - -typedef void* Parser; - -#ifdef __cplusplus -extern "C" { -#endif - -MPP_RET parser_init(Parser *prs, ParserCfg *cfg); -MPP_RET parser_deinit(Parser prs); - -MPP_RET parser_prepare(Parser prs, MppPacket pkt, HalDecTask *task); -MPP_RET parser_parse(Parser prs, HalDecTask *task); - -MPP_RET parser_reset(Parser prs); -MPP_RET parser_flush(Parser prs); -MPP_RET parser_control(Parser prs, RK_S32 cmd, void *para); -MPP_RET hal_callback(void* prs, void *err_info); - -#ifdef __cplusplus -} -#endif - -#endif /*__MPP_PARSER_H__*/ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPP_PARSER_H__ +#define __MPP_PARSER_H__ + +#include "parser_api.h" + +typedef void* Parser; + +#ifdef __cplusplus +extern "C" { +#endif + +MPP_RET parser_init(Parser *prs, ParserCfg *cfg); +MPP_RET parser_deinit(Parser prs); + +MPP_RET parser_prepare(Parser prs, MppPacket pkt, HalDecTask *task); +MPP_RET parser_parse(Parser prs, HalDecTask *task); + +MPP_RET parser_reset(Parser prs); +MPP_RET parser_flush(Parser prs); +MPP_RET parser_control(Parser prs, RK_S32 cmd, void *para); +MPP_RET hal_callback(void* prs, void *err_info); + +#ifdef __cplusplus +} +#endif + +#endif /*__MPP_PARSER_H__*/ diff --git a/mpp/codec/inc/parser_api.h b/mpp/codec/inc/parser_api.h index d7ebe58e..eda8a5ae 100644 --- a/mpp/codec/inc/parser_api.h +++ b/mpp/codec/inc/parser_api.h @@ -1,80 +1,80 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __PARSER_API_H__ -#define __PARSER_API_H__ - -#include "rk_mpi.h" -#include "mpp_packet.h" -#include "mpp_buf_slot.h" -#include "hal_task.h" - -/* - * slots - all decoder need a slots interface to sync its internal dpb management - * with buffer group in mpp_dec - * - * the reset wait for extension - */ -typedef struct DecParserInitCfg_t { - // input - MppCodingType coding; - MppBufSlots frame_slots; - MppBufSlots packet_slots; - - // output - RK_S32 task_count; - RK_U32 need_split; - RK_U32 internal_pts; - IOInterruptCB notify_cb; -} ParserCfg; - - -/* - * Parser is the data structure provided from different decoders - * - * They will be static register to mpp_dec for scaning - * name - decoder name - * coding - decoder coding type - * ctx_size - decoder context size, mpp_dec will use this to malloc memory - * flag - reserve - * - * init - decoder initialization function - * deinit - decoder de-initialization function - * parse - decoder main working function, mpp_dec will input packet and get output syntax - * reset - decoder reset function - * flush - decoder output all frames - * control - decoder configure function - */ -typedef struct ParserApi_t { - char *name; - MppCodingType coding; - RK_U32 ctx_size; - RK_U32 flag; - - MPP_RET (*init)(void *ctx, ParserCfg *cfg); - MPP_RET (*deinit)(void *ctx); - - MPP_RET (*prepare)(void *ctx, MppPacket pkt, HalDecTask *task); - MPP_RET (*parse)(void *ctx, HalDecTask *task); - - MPP_RET (*reset)(void *ctx); - MPP_RET (*flush)(void *ctx); - MPP_RET (*control)(void *ctx, RK_S32 cmd, void *param); - MPP_RET (*callback)(void *ctx, void *err_info); -} ParserApi; - - -#endif /*__PARSER_API_H__*/ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __PARSER_API_H__ +#define __PARSER_API_H__ + +#include "rk_mpi.h" +#include "mpp_packet.h" +#include "mpp_buf_slot.h" +#include "hal_task.h" + +/* + * slots - all decoder need a slots interface to sync its internal dpb management + * with buffer group in mpp_dec + * + * the reset wait for extension + */ +typedef struct DecParserInitCfg_t { + // input + MppCodingType coding; + MppBufSlots frame_slots; + MppBufSlots packet_slots; + + // output + RK_S32 task_count; + RK_U32 need_split; + RK_U32 internal_pts; + IOInterruptCB notify_cb; +} ParserCfg; + + +/* + * Parser is the data structure provided from different decoders + * + * They will be static register to mpp_dec for scaning + * name - decoder name + * coding - decoder coding type + * ctx_size - decoder context size, mpp_dec will use this to malloc memory + * flag - reserve + * + * init - decoder initialization function + * deinit - decoder de-initialization function + * parse - decoder main working function, mpp_dec will input packet and get output syntax + * reset - decoder reset function + * flush - decoder output all frames + * control - decoder configure function + */ +typedef struct ParserApi_t { + char *name; + MppCodingType coding; + RK_U32 ctx_size; + RK_U32 flag; + + MPP_RET (*init)(void *ctx, ParserCfg *cfg); + MPP_RET (*deinit)(void *ctx); + + MPP_RET (*prepare)(void *ctx, MppPacket pkt, HalDecTask *task); + MPP_RET (*parse)(void *ctx, HalDecTask *task); + + MPP_RET (*reset)(void *ctx); + MPP_RET (*flush)(void *ctx); + MPP_RET (*control)(void *ctx, RK_S32 cmd, void *param); + MPP_RET (*callback)(void *ctx, void *err_info); +} ParserApi; + + +#endif /*__PARSER_API_H__*/ diff --git a/mpp/codec/inc/vp8d_api.h b/mpp/codec/inc/vp8d_api.h index c2c5a045..cd0edee6 100644 --- a/mpp/codec/inc/vp8d_api.h +++ b/mpp/codec/inc/vp8d_api.h @@ -1,28 +1,28 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __VP8D_API_H__ -#define __VP8D_API_H__ - -#include "parser_api.h" -#ifdef __cplusplus -extern "C" { -#endif -extern const ParserApi api_vp8d_parser; -#ifdef __cplusplus -} -#endif +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __VP8D_API_H__ +#define __VP8D_API_H__ + +#include "parser_api.h" +#ifdef __cplusplus +extern "C" { +#endif +extern const ParserApi api_vp8d_parser; +#ifdef __cplusplus +} +#endif #endif /*__VP8D_API_H__*/ \ No newline at end of file diff --git a/mpp/codec/inc/vp8e_api.h b/mpp/codec/inc/vp8e_api.h index f8d624f6..546a72c4 100644 --- a/mpp/codec/inc/vp8e_api.h +++ b/mpp/codec/inc/vp8e_api.h @@ -1,22 +1,22 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __VP8E_API_H__ -#define __VP8E_API_H__ - - - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __VP8E_API_H__ +#define __VP8E_API_H__ + + + #endif /*__VP8E_API_H__*/ \ No newline at end of file diff --git a/mpp/codec/inc/vp9d_api.h b/mpp/codec/inc/vp9d_api.h index 54c100e9..793be1d5 100644 --- a/mpp/codec/inc/vp9d_api.h +++ b/mpp/codec/inc/vp9d_api.h @@ -1,43 +1,43 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __VP9D_API_H__ -#define __VP9D_API_H__ - -#include "parser_api.h" - - - -#ifdef __cplusplus -extern "C" { -#endif - -extern const ParserApi api_vp9d_parser; - -MPP_RET vp9d_init (void *decoder, ParserCfg *cfg); -MPP_RET vp9d_deinit (void *decoder); -MPP_RET vp9d_reset (void *decoder); -MPP_RET vp9d_flush (void *decoder); -MPP_RET vp9d_control(void *decoder, RK_S32 cmd_type, void *param); -MPP_RET vp9d_prepare(void *decoder, MppPacket pkt, HalDecTask *task); -MPP_RET vp9d_parse (void *decoder, HalDecTask *task); -MPP_RET vp9d_callback(void *decoder, void *info); - -#ifdef __cplusplus -} -#endif - -#endif /* __VP9D_API_H__*/ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __VP9D_API_H__ +#define __VP9D_API_H__ + +#include "parser_api.h" + + + +#ifdef __cplusplus +extern "C" { +#endif + +extern const ParserApi api_vp9d_parser; + +MPP_RET vp9d_init (void *decoder, ParserCfg *cfg); +MPP_RET vp9d_deinit (void *decoder); +MPP_RET vp9d_reset (void *decoder); +MPP_RET vp9d_flush (void *decoder); +MPP_RET vp9d_control(void *decoder, RK_S32 cmd_type, void *param); +MPP_RET vp9d_prepare(void *decoder, MppPacket pkt, HalDecTask *task); +MPP_RET vp9d_parse (void *decoder, HalDecTask *task); +MPP_RET vp9d_callback(void *decoder, void *info); + +#ifdef __cplusplus +} +#endif + +#endif /* __VP9D_API_H__*/ diff --git a/mpp/codec/mpp_dec.cpp b/mpp/codec/mpp_dec.cpp index 619dd8ad..1a97aba4 100644 --- a/mpp/codec/mpp_dec.cpp +++ b/mpp/codec/mpp_dec.cpp @@ -1,999 +1,999 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define MODULE_TAG "mpp_dec" - -#include - -#include "mpp_mem.h" -#include "mpp_log.h" -#include "mpp_time.h" -#include "mpp_common.h" - -#include "mpp.h" -#include "mpp_frame.h" -#include "mpp_buffer_impl.h" -#include "mpp_packet_impl.h" -#include "mpp_frame_impl.h" - -#include "vpu_api.h" - -typedef union PaserTaskWait_u { - RK_U32 val; - struct { - RK_U32 task_hnd : 1; - RK_U32 mpp_pkt_in : 1; - RK_U32 dec_pkt_idx : 1; - RK_U32 dec_pkt_buf : 1; - RK_U32 prev_task : 1; - RK_U32 info_change : 1; - RK_U32 dec_pic_buf : 1; - }; -} PaserTaskWait; - -typedef union DecTaskStatus_u { - RK_U32 val; - struct { - RK_U32 task_hnd_rdy : 1; - RK_U32 mpp_pkt_in_rdy : 1; - RK_U32 dec_pkt_idx_rdy : 1; - RK_U32 dec_pkt_buf_rdy : 1; - RK_U32 task_valid_rdy : 1; - RK_U32 dec_pkt_copy_rdy : 1; - RK_U32 prev_task_rdy : 1; - RK_U32 info_task_gen_rdy : 1; - RK_U32 curr_task_rdy : 1; - RK_U32 task_parsed_rdy : 1; - }; -} DecTaskStatus; - -typedef struct DecTask_t { - HalTaskHnd hnd; - - DecTaskStatus status; - PaserTaskWait wait; - - RK_S32 hal_pkt_idx_in; - RK_S32 hal_frm_idx_out; - - MppBuffer hal_pkt_buf_in; - MppBuffer hal_frm_buf_out; - - HalTaskInfo info; -} DecTask; - -static void dec_task_init(DecTask *task) -{ - task->hnd = NULL; - task->status.val = 0; - task->wait.val = 0; - task->status.prev_task_rdy = 1; - - task->hal_pkt_idx_in = -1; - task->hal_frm_idx_out = -1; - - task->hal_pkt_buf_in = NULL; - task->hal_frm_buf_out = NULL; - - hal_task_info_init(&task->info, MPP_CTX_DEC); -} -#if 0 -static void dec_task_reset(MppDec *dec, DecTask *task) -{ - task->hnd = NULL; - task->status.val = 0; - task->wait.val = 0; - task->status.prev_task_rdy = 1; - - if (task->hal_pkt_idx_in >= 0) { - mpp_buf_slot_clr_flag(dec->frame_slots, task->hal_pkt_idx_in, SLOT_HAL_INPUT); - task->hal_pkt_idx_in = -1; - } - - if (task->hal_frm_idx_out >= 0) { - mpp_buf_slot_clr_flag(dec->frame_slots, task->hal_frm_idx_out, SLOT_HAL_INPUT); - task->hal_frm_idx_out = -1; - } - - if (task->hal_pkt_buf_in) { - mpp_buffer_put(task->hal_pkt_buf_in); - task->hal_pkt_buf_in = NULL; - } - - if (task->hal_frm_buf_out) { - mpp_buffer_put(task->hal_frm_buf_out); - task->hal_frm_buf_out = NULL; - } - - hal_task_info_init(&task->info, MPP_CTX_DEC); -} -#endif -/* - * return MPP_OK for not wait - * return MPP_NOK for wait - */ -static MPP_RET check_task_wait(MppDec *dec, DecTask *task) -{ - if (dec->reset_flag) { - return MPP_OK; - } - - if (task->wait.task_hnd || - task->wait.mpp_pkt_in || - task->wait.prev_task || - task->wait.info_change || - task->wait.dec_pic_buf) - return MPP_NOK; - - return MPP_OK; -} - -static RK_U32 reset_dec_task(Mpp *mpp, DecTask *task) -{ - MppThread *parser = mpp->mThreadCodec; - MppDec *dec = mpp->mDec; - HalTaskGroup tasks = dec->tasks; - MppBufSlots frame_slots = dec->frame_slots; - MppBufSlots packet_slots = dec->packet_slots; - HalDecTask *task_dec = &task->info.dec; - - if (!dec->parser_fast_mode) { - if (!task->status.prev_task_rdy) { - HalTaskHnd task_prev = NULL; - hal_task_get_hnd(tasks, TASK_PROC_DONE, &task_prev); - if (task_prev) { - task->status.prev_task_rdy = 1; - hal_task_hnd_set_status(task_prev, TASK_IDLE); - task_prev = NULL; - task->wait.prev_task = 0; - } else { - msleep(5); - task->wait.prev_task = 1; - return MPP_NOK; - } - } - } else { - if (hal_task_check_empty(tasks, TASK_PROCESSING)) { - msleep(5); - return MPP_NOK; - } - } - - { - RK_S32 index; - parser->lock(THREAD_RESET); - task->status.curr_task_rdy = 0; - task_dec->valid = 0; - parser_reset(dec->parser); - mpp_hal_reset(dec->hal); - dec->reset_flag = 0; - if (task->wait.info_change) { - mpp_log("reset add info change status"); - mpp_buf_slot_reset(frame_slots, task_dec->output); - - } - if (task->status.task_parsed_rdy) { - mpp_log("task no send to hal que must clr current frame hal status"); - mpp_buf_slot_clr_flag(frame_slots, task_dec->output, SLOT_HAL_OUTPUT); - for (RK_U32 i = 0; i < MPP_ARRAY_ELEMS(task_dec->refer); i++) { - index = task_dec->refer[i]; - if (index >= 0) - mpp_buf_slot_clr_flag(frame_slots, index, SLOT_HAL_INPUT); - } - } - if (dec->mpp_pkt_in) { - mpp_packet_deinit(&dec->mpp_pkt_in); - dec->mpp_pkt_in = NULL; - } - while (MPP_OK == mpp_buf_slot_dequeue(frame_slots, &index, QUEUE_DISPLAY)) { - /* release extra ref in slot's MppBuffer */ - MppBuffer buffer = NULL; - mpp_buf_slot_get_prop(frame_slots, index, SLOT_BUFFER, &buffer); - if (buffer) - mpp_buffer_put(buffer); - mpp_buf_slot_clr_flag(frame_slots, index, SLOT_QUEUE_USE); - } - if (task->status.dec_pkt_copy_rdy) { - mpp_buf_slot_clr_flag(packet_slots, task_dec->input, SLOT_HAL_INPUT); - task->status.dec_pkt_copy_rdy = 0; - task_dec->input = -1; - } - - - task->status.task_parsed_rdy = 0; - parser->unlock(THREAD_RESET); - parser->signal(THREAD_RESET); - } - - dec_task_init(task); - - return MPP_OK; -} - -static void mpp_put_frame(Mpp *mpp, MppFrame frame) -{ - mpp_list *list = mpp->mFrames; - - list->lock(); - list->add_at_tail(&frame, sizeof(frame)); - - if (mpp_debug & MPP_DBG_PTS) - mpp_log("output frame pts %lld\n", mpp_frame_get_pts(frame)); - - mpp->mFramePutCount++; - list->signal(); - list->unlock(); -} - -static void mpp_put_frame_eos(Mpp *mpp) -{ - MppFrame info_frame = NULL; - mpp_frame_init(&info_frame); - mpp_assert(NULL == mpp_frame_get_buffer(info_frame)); - mpp_frame_set_eos(info_frame, 1); - mpp_put_frame((Mpp*)mpp, info_frame); - return; -} - -static void mpp_dec_push_display(Mpp *mpp) -{ - RK_S32 index; - MppDec *dec = mpp->mDec; - MppBufSlots frame_slots = dec->frame_slots; - mpp->mThreadHal->lock(THREAD_QUE_DISPLAY); - while (MPP_OK == mpp_buf_slot_dequeue(frame_slots, &index, QUEUE_DISPLAY)) { - MppFrame frame = NULL; - mpp_buf_slot_get_prop(frame_slots, index, SLOT_FRAME, &frame); - if (!dec->reset_flag) { - mpp_put_frame(mpp, frame); - } else { - /* release extra ref in slot's MppBuffer */ - MppBuffer buffer = mpp_frame_get_buffer(frame); - if (buffer) - mpp_buffer_put(buffer); - } - mpp_buf_slot_clr_flag(frame_slots, index, SLOT_QUEUE_USE); - } - mpp->mThreadHal->unlock(THREAD_QUE_DISPLAY); -} - -static void mpp_dec_push_eos_task(Mpp *mpp, DecTask *task) -{ - hal_task_hnd_set_info(task->hnd, &task->info); - mpp->mThreadHal->lock(); - hal_task_hnd_set_status(task->hnd, TASK_PROCESSING); - mpp->mThreadHal->unlock(); - mpp->mThreadHal->signal(); -} - -static MPP_RET try_proc_dec_task(Mpp *mpp, DecTask *task) -{ - MppDec *dec = mpp->mDec; - HalTaskGroup tasks = dec->tasks; - MppBufSlots frame_slots = dec->frame_slots; - MppBufSlots packet_slots = dec->packet_slots; - size_t stream_size = 0; - HalDecTask *task_dec = &task->info.dec; - - - /* - * 1. get task handle from hal for parsing one frame - */ - if (!task->hnd) { - hal_task_get_hnd(tasks, TASK_IDLE, &task->hnd); - if (task->hnd) { - task->wait.task_hnd = 0; - } else { - task->wait.task_hnd = 1; - return MPP_NOK; - } - } - - - /* - * 2. get packet for parser preparing - */ - if (!dec->mpp_pkt_in && !task->status.curr_task_rdy) { - mpp_list *packets = mpp->mPackets; - AutoMutex autoLock(packets->mutex()); - if (packets->list_size()) { - /* - * packet will be destroyed outside, here just copy the content - */ - packets->del_at_head(&dec->mpp_pkt_in, sizeof(dec->mpp_pkt_in)); - mpp->mPacketGetCount++; - task->wait.mpp_pkt_in = 0; - } else { - task->wait.mpp_pkt_in = 1; - return MPP_NOK; - } - } - - /* - * 3. send packet data to parser for prepare - * - * parser_prepare functioin input / output - * input: input MppPacket data from user - * output: one packet which contains one frame for hardware processing - * output information will be stored in task_dec->input_packet - * output data can be stored inside of parser. - * - * NOTE: - * 1. Prepare process is controlled by need_split flag - * If need_split flag is zero prepare function is just copy the input - * packet to task_dec->input_packet - * If need_split flag is non-zero prepare function will call split funciton - * of different coding type and find the start and end of one frame. Then - * copy data to task_dec->input_packet - * 2. On need_split mode if one input MppPacket contain multiple frame for - * decoding one parser_prepare call will only frame for task. Then input - * MppPacket->pos/length will be updated. The input MppPacket will not be - * released until it is totally consumed. - * 3. On spliting frame if one frame contain multiple slices and these multiple - * slices have different pts/dts the output frame will use the last pts/dts - * as the output frame's pts/dts. - * - */ - if (!task->status.curr_task_rdy) { - RK_S64 p_e, p_s, diff; - p_s = mpp_time(); - - if (mpp_debug & MPP_DBG_PTS) - mpp_log("input packet pts %lld\n", mpp_packet_get_pts(dec->mpp_pkt_in)); - - parser_prepare(dec->parser, dec->mpp_pkt_in, task_dec); - p_e = mpp_time(); - if (mpp_debug & MPP_DBG_TIMING) { - diff = (p_e - p_s) / 1000; - if (diff > 15) { - mpp_log("waring mpp prepare stream consume %lld big than 15ms ", diff); - } - } - if (0 == mpp_packet_get_length(dec->mpp_pkt_in)) { - mpp_packet_deinit(&dec->mpp_pkt_in); - dec->mpp_pkt_in = NULL; - } - } - - task->status.curr_task_rdy = task_dec->valid; - /* - * We may find eos in prepare step and there will be no anymore vaild task generated. - * So here we try push eos task to hal, hal will push all frame to display then - * push a eos frame to tell all frame decoded - */ - // mpp_dec_push_display(mpp); - if (task_dec->flags.eos && !task_dec->valid) { - mpp_dec_push_eos_task(mpp, task); - task->hnd = NULL; - } - - if (!task->status.curr_task_rdy) - return MPP_NOK; - - // NOTE: packet in task should be ready now - mpp_assert(task_dec->input_packet); - - /* - * 4. look for a unused packet slot index - */ - if (task_dec->input < 0) { - mpp_buf_slot_get_unused(packet_slots, &task_dec->input); - } - - task->wait.dec_pkt_idx = (task_dec->input < 0); - if (task->wait.dec_pkt_idx) - return MPP_NOK; - - /* - * 5. malloc hardware buffer for the packet slot index - */ - task->hal_pkt_idx_in = task_dec->input; - stream_size = mpp_packet_get_size(task_dec->input_packet); - - MppBuffer hal_buf_in; - mpp_buf_slot_get_prop(packet_slots, task->hal_pkt_idx_in, SLOT_BUFFER, &hal_buf_in); - if (NULL == hal_buf_in) { - mpp_buffer_get(mpp->mPacketGroup, &hal_buf_in, stream_size); - if (hal_buf_in) { - mpp_buf_slot_set_prop(packet_slots, task->hal_pkt_idx_in, SLOT_BUFFER, hal_buf_in); - mpp_buffer_put(hal_buf_in); - } - } else { - MppBufferImpl *buf = (MppBufferImpl *)hal_buf_in; - mpp_assert(buf->info.size >= stream_size); - } - - task->hal_pkt_buf_in = hal_buf_in; - task->wait.dec_pkt_buf = (NULL == hal_buf_in); - if (task->wait.dec_pkt_buf) - return MPP_NOK; - - /* - * 6. copy prepared stream to hardware buffer - */ - if (!task->status.dec_pkt_copy_rdy) { - MppBufferImpl *buf = (MppBufferImpl *)task->hal_pkt_buf_in; - void *src = mpp_packet_get_data(task_dec->input_packet); - size_t length = mpp_packet_get_length(task_dec->input_packet); - memcpy(buf->info.ptr, src, length); - mpp_buf_slot_set_flag(packet_slots, task_dec->input, SLOT_CODEC_READY); - mpp_buf_slot_set_flag(packet_slots, task_dec->input, SLOT_HAL_INPUT); - task->status.dec_pkt_copy_rdy = 1; - } - - /* - * 7. if not fast mode wait previous task done here - */ - if (!dec->parser_fast_mode) { - // wait previous task done - if (!task->status.prev_task_rdy) { - HalTaskHnd task_prev = NULL; - hal_task_get_hnd(tasks, TASK_PROC_DONE, &task_prev); - if (task_prev) { - task->status.prev_task_rdy = 1; - task->wait.prev_task = 0; - hal_task_hnd_set_status(task_prev, TASK_IDLE); - task_prev = NULL; - } else { - task->wait.prev_task = 1; - return MPP_NOK; - } - } - } - - /* - * 7. look for a unused hardware buffer for output - */ - if (mpp->mFrameGroup) { - task->wait.dec_pic_buf = (mpp_buffer_group_unused(mpp->mFrameGroup) < 1); - if (task->wait.dec_pic_buf) - return MPP_NOK; - } - - /* - * We may find eos in prepare step and there will be no anymore vaild task generated. - * So here we try push all frames to display to avoid eos no notify to display - */ - // mpp_dec_push_display(mpp); - - /* - * 8. send packet data to parser - * - * parser prepare functioin input / output - * input: packet data - * output: dec task output information (with dxva output slot) - * buffer slot usage informatioin - * - * NOTE: - * 1. dpb slot will be set internally in parser process. - * 2. parse function need to set valid flag when one frame is ready. - * 3. if packet size is zero then next packet is needed. - * - */ - if (!task->status.task_parsed_rdy) { - parser_parse(dec->parser, task_dec); - task->status.task_parsed_rdy = 1; - } - - /* - * 9. parse local task and slot to check whether new buffer or info change is needed. - * - * a. first detect info change from frame slot - * b. then detect whether output index has MppBuffer - */ - if (mpp_buf_slot_is_changed(frame_slots)) { - if (!task->status.info_task_gen_rdy) { - task_dec->flags.info_change = 1; - hal_task_hnd_set_info(task->hnd, &task->info); - mpp->mThreadHal->lock(); - hal_task_hnd_set_status(task->hnd, TASK_PROCESSING); - mpp->mThreadHal->unlock(); - mpp->mThreadHal->signal(); - mpp->mTaskPutCount++; - task->hnd = NULL; - task->status.info_task_gen_rdy = 1; - return MPP_NOK; - } - } - - task->wait.info_change = mpp_buf_slot_is_changed(frame_slots); - if (task->wait.info_change) { - return MPP_NOK; - } else { - task->status.info_task_gen_rdy = 0; - task_dec->flags.info_change = 0; - // NOTE: check the task must be ready - mpp_assert(task->hnd); - } - - - if (task_dec->output < 0) { - /* - * We may find eos in parser step and there will be no anymore vaild task generated. - * So here we try push eos task to hal, hal will push all frame to display then - * push a eos frame to tell all frame decoded - */ - if (task_dec->flags.eos) { - mpp_dec_push_eos_task(mpp, task); - } else { - hal_task_hnd_set_status(task->hnd, TASK_IDLE); - } - - mpp->mTaskPutCount++; - task->hnd = NULL; - if (task->status.dec_pkt_copy_rdy) { - mpp_buf_slot_clr_flag(packet_slots, task_dec->input, SLOT_HAL_INPUT); - task->status.dec_pkt_copy_rdy = 0; - } - task->status.curr_task_rdy = 0; - task->status.task_parsed_rdy = 0; - hal_task_info_init(&task->info, MPP_CTX_DEC); - return MPP_NOK; - } - - /* - * 5. chekc frame buffer group is internal or external - */ - if (NULL == mpp->mFrameGroup) { - mpp_log("mpp_dec use internal frame buffer group\n"); - mpp_buffer_group_get_internal(&mpp->mFrameGroup, MPP_BUFFER_TYPE_ION); - } - - /* - * 5. do buffer operation according to usage information - * - * possible case: - * a. normal case - * - wait and alloc a normal frame buffer - * b. field mode case - * - two field may reuse a same buffer, no need to alloc - * c. info change case - * - need buffer in different side, need to send a info change - * frame to hal loop. - */ - RK_S32 output = task_dec->output; - MppBuffer hal_buf_out; - mpp_buf_slot_get_prop(frame_slots, output, SLOT_BUFFER, &hal_buf_out); - if (NULL == hal_buf_out) { - size_t size = mpp_buf_slot_get_size(frame_slots); - mpp_buffer_get(mpp->mFrameGroup, &hal_buf_out, size); - if (hal_buf_out) - mpp_buf_slot_set_prop(frame_slots, output, SLOT_BUFFER, hal_buf_out); - - } - - task->hal_frm_buf_out = hal_buf_out; - task->wait.dec_pic_buf = (NULL == hal_buf_out); - if (task->wait.dec_pic_buf) - return MPP_NOK; - - // register genertation - mpp_hal_reg_gen(dec->hal, &task->info); - - /* - * wait previous register set done - */ - //mpp_hal_hw_wait(dec->hal_ctx, &task_local); - - /* - * send current register set to hardware - */ - //mpp_hal_hw_start(dec->hal_ctx, &task_local); - - mpp_hal_hw_start(dec->hal, &task->info); - - /* - * 6. send dxva output information and buffer information to hal thread - * combinate video codec dxva output and buffer information - */ - hal_task_hnd_set_info(task->hnd, &task->info); - mpp->mThreadHal->lock(); - hal_task_hnd_set_status(task->hnd, TASK_PROCESSING); - mpp->mThreadHal->unlock(); - mpp->mThreadHal->signal(); - - mpp->mTaskPutCount++; - task->hnd = NULL; - task->status.dec_pkt_copy_rdy = 0; - task->status.curr_task_rdy = 0; - task->status.task_parsed_rdy = 0; - task->status.prev_task_rdy = 0; - hal_task_info_init(&task->info, MPP_CTX_DEC); - - return MPP_OK; -} - - - -void *mpp_dec_parser_thread(void *data) -{ - Mpp *mpp = (Mpp*)data; - MppThread *parser = mpp->mThreadCodec; - MppDec *dec = mpp->mDec; - MppBufSlots packet_slots = dec->packet_slots; - - /* - * parser thread need to wait at cases below: - * 1. no task slot for output - * 2. no packet for parsing - * 3. info change on progress - * 3. no buffer on analyzing output task - */ - DecTask task; - HalDecTask *task_dec = &task.info.dec; - - dec_task_init(&task); - - while (MPP_THREAD_RUNNING == parser->get_status()) { - /* - * wait for stream input - */ - if (dec->reset_flag) { - if (reset_dec_task(mpp, &task)) - continue; - } - - parser->lock(); - if (MPP_THREAD_RUNNING == parser->get_status()) { - if (check_task_wait(dec, &task)) - parser->wait(); - } - parser->unlock(); - - - if (try_proc_dec_task(mpp, &task)) - continue; - - } - mpp_log("mpp_dec_parser_thread exit"); - if (NULL != task.hnd && task_dec->valid) { - mpp_buf_slot_set_flag(packet_slots, task_dec->input, SLOT_CODEC_READY); - mpp_buf_slot_set_flag(packet_slots, task_dec->input, SLOT_HAL_INPUT); - mpp_buf_slot_clr_flag(packet_slots, task_dec->input, SLOT_HAL_INPUT); - } - mpp_buffer_group_clear(mpp->mPacketGroup); - mpp_log("mpp_dec_parser_thread exit ok"); - return NULL; -} - -void *mpp_dec_hal_thread(void *data) -{ - Mpp *mpp = (Mpp*)data; - MppThread *hal = mpp->mThreadHal; - MppDec *dec = mpp->mDec; - HalTaskGroup tasks = dec->tasks; - MppBufSlots frame_slots = dec->frame_slots; - MppBufSlots packet_slots = dec->packet_slots; - - /* - * hal thread need to wait at cases below: - * 1. no task slot for work - */ - HalTaskHnd task = NULL; - HalTaskInfo task_info; - HalDecTask *task_dec = &task_info.dec; - RK_S64 cur_deat = 0; - RK_U64 dec_no = 0, total_time = 0; - RK_S64 p_s, p_e; - - p_s = mpp_time(); - while (MPP_THREAD_RUNNING == hal->get_status()) { - /* - * hal thread wait for dxva interface intput firt - */ - hal->lock(); - if (MPP_THREAD_RUNNING == hal->get_status()) { - if (hal_task_get_hnd(tasks, TASK_PROCESSING, &task)) - hal->wait(); - } - hal->unlock(); - - if (task) { - mpp->mTaskGetCount++; - - hal_task_hnd_get_info(task, &task_info); - /* - * check info change flag - * if this is a info change frame, only output the mpp_frame for info change. - */ - - if (task_dec->flags.info_change) { - MppFrame info_frame = NULL; - mpp_dec_flush(dec); - mpp_dec_push_display(mpp); - mpp_buf_slot_get_prop(frame_slots, task_dec->output, SLOT_FRAME, &info_frame); - mpp_assert(info_frame); - mpp_assert(NULL == mpp_frame_get_buffer(info_frame)); - mpp_frame_set_info_change(info_frame, 1); - mpp_frame_set_errinfo(info_frame, 0); - mpp_put_frame(mpp, info_frame); - - hal_task_hnd_set_status(task, TASK_IDLE); - task = NULL; - mpp->mThreadCodec->signal(); - continue; - } - /* - * check eos task - * if this task is invalid then eos flag come we will flush display que - * then push eos frame to tell all frame decoded - */ - if (task_dec->flags.eos && !task_dec->valid) { - mpp_dec_push_display(mpp); - mpp_put_frame_eos(mpp); - hal_task_hnd_set_status(task, TASK_IDLE); - mpp->mThreadCodec->signal(); - task = NULL; - continue; - } - mpp_hal_hw_wait(dec->hal, &task_info); - p_e = mpp_time(); - cur_deat = (p_e - p_s); - total_time += cur_deat; - //mpp_log("[Cal_time] dec_no=%lld, time=%d ms, av_time=%lld ms. \n", dec_no, cur_deat, total_time/(dec_no + 1)); - dec_no++; - p_s = p_e; - /* - * when hardware decoding is done: - * 1. clear decoding flag (mark buffer is ready) - * 2. use get_display to get a new frame with buffer - * 3. add frame to output list - * repeat 2 and 3 until not frame can be output - */ - mpp_buf_slot_clr_flag(packet_slots, task_dec->input, SLOT_HAL_INPUT); - - // TODO: may have risk here - hal_task_hnd_set_status(task, TASK_PROC_DONE); - task = NULL; - if (dec->parser_fast_mode) { - hal_task_get_hnd(tasks, TASK_PROC_DONE, &task); - if (task) { - hal_task_hnd_set_status(task, TASK_IDLE); - } - } - mpp->mThreadCodec->signal(); - - mpp_buf_slot_clr_flag(frame_slots, task_dec->output, SLOT_HAL_OUTPUT); - for (RK_U32 i = 0; i < MPP_ARRAY_ELEMS(task_dec->refer); i++) { - RK_S32 index = task_dec->refer[i]; - if (index >= 0) - mpp_buf_slot_clr_flag(frame_slots, index, SLOT_HAL_INPUT); - } - if (task_dec->flags.eos) { - mpp_dec_flush(dec); - } - mpp_dec_push_display(mpp); - /* - * check eos task - * if this task is valid then eos flag come we will flush display que - * then push eos frame to tell all frame decoded - */ - if (task_dec->flags.eos) { - mpp_put_frame_eos(mpp); - } - } - } - - mpp_log("mpp_dec_hal_thread exit ok"); - return NULL; -} - -MPP_RET mpp_dec_init(MppDec **dec, MppDecCfg *cfg) -{ - MPP_RET ret; - MppCodingType coding; - MppBufSlots frame_slots = NULL; - MppBufSlots packet_slots = NULL; - Parser parser = NULL; - MppHal hal = NULL; - RK_S32 hal_task_count = 0; - MppDec *p = NULL; - IOInterruptCB cb = {NULL, NULL}; - - if (NULL == dec || NULL == cfg) { - mpp_err_f("invalid input dec %p cfg %p\n", dec, cfg); - return MPP_ERR_NULL_PTR; - } - - *dec = NULL; - - p = mpp_calloc(MppDec, 1); - if (NULL == p) { - mpp_err_f("failed to malloc context\n"); - return MPP_ERR_MALLOC; - } - - coding = cfg->coding; - hal_task_count = (cfg->fast_mode) ? (3) : (2); - - do { - ret = mpp_buf_slot_init(&frame_slots); - if (ret) { - mpp_err_f("could not init frame buffer slot\n"); - break; - } - - ret = mpp_buf_slot_init(&packet_slots); - if (ret) { - mpp_err_f("could not init packet buffer slot\n"); - break; - } - - mpp_buf_slot_setup(packet_slots, hal_task_count); - cb.callBack = mpp_dec_notify; - cb.opaque = p; - ParserCfg parser_cfg = { - coding, - frame_slots, - packet_slots, - hal_task_count, - cfg->need_split, - cfg->internal_pts, - cb, - }; - - ret = parser_init(&parser, &parser_cfg); - if (ret) { - mpp_err_f("could not init parser\n"); - break; - } - cb.callBack = hal_callback; - cb.opaque = parser; - // then init hal with task count from parser - MppHalCfg hal_cfg = { - MPP_CTX_DEC, - coding, - HAL_MODE_LIBVPU, - HAL_RKVDEC, - frame_slots, - packet_slots, - NULL, - parser_cfg.task_count, - cfg->fast_mode, - cb, - }; - - ret = mpp_hal_init(&hal, &hal_cfg); - if (ret) { - mpp_err_f("could not init hal\n"); - break; - } - - p->coding = coding; - p->parser = parser; - p->hal = hal; - p->tasks = hal_cfg.tasks; - p->frame_slots = frame_slots; - p->packet_slots = packet_slots; - - p->mpp = cfg->mpp; - p->parser_need_split = cfg->need_split; - p->parser_fast_mode = cfg->fast_mode; - p->parser_internal_pts = cfg->internal_pts; - *dec = p; - return MPP_OK; - } while (0); - - mpp_dec_deinit(p); - return MPP_NOK; -} - -MPP_RET mpp_dec_deinit(MppDec *dec) -{ - if (NULL == dec) { - mpp_err_f("found NULL input\n"); - return MPP_ERR_NULL_PTR; - } - - if (dec->parser) { - parser_deinit(dec->parser); - dec->parser = NULL; - } - - if (dec->hal) { - mpp_hal_deinit(dec->hal); - dec->hal = NULL; - } - - if (dec->frame_slots) { - mpp_buf_slot_deinit(dec->frame_slots); - dec->frame_slots = NULL; - } - - if (dec->packet_slots) { - mpp_buf_slot_deinit(dec->packet_slots); - dec->packet_slots = NULL; - } - - mpp_free(dec); - return MPP_OK; -} - -MPP_RET mpp_dec_reset(MppDec *dec) -{ - if (NULL == dec) { - mpp_err_f("found NULL input dec %p\n", dec); - return MPP_ERR_NULL_PTR; - } - dec->reset_flag = 1; - - // parser_reset(dec->parser); - // mpp_hal_reset(dec->hal); - - return MPP_OK; -} - -MPP_RET mpp_dec_flush(MppDec *dec) -{ - if (NULL == dec) { - mpp_err_f("found NULL input dec %p\n", dec); - return MPP_ERR_NULL_PTR; - } - - parser_flush(dec->parser); - mpp_hal_flush(dec->hal); - - return MPP_OK; -} - -MPP_RET mpp_dec_notify(void *ctx, void *info) -{ - MppDec *dec = (MppDec *)ctx; - MppFrame info_frame = NULL; - mpp_frame_init(&info_frame); - mpp_assert(NULL == mpp_frame_get_buffer(info_frame)); - mpp_frame_set_eos(info_frame, 1); - mpp_put_frame((Mpp*)dec->mpp, info_frame); - (void)info; - return MPP_OK; -} - -MPP_RET mpp_dec_control(MppDec *dec, MpiCmd cmd, void *param) -{ - if (NULL == dec) { - mpp_err_f("found NULL input dec %p\n", dec); - return MPP_ERR_NULL_PTR; - } - parser_control(dec->parser, cmd, param); - mpp_hal_control(dec->hal, cmd, param); - - switch (cmd) { - case MPP_DEC_SET_FRAME_INFO : { - VPU_GENERIC *p = (VPU_GENERIC *)param; - MppFrame frame = NULL; - mpp_frame_init(&frame); - mpp_frame_set_width(frame, p->ImgWidth); - mpp_frame_set_height(frame, p->ImgHeight); - mpp_frame_set_hor_stride(frame, p->ImgHorStride); - mpp_frame_set_ver_stride(frame, p->ImgVerStride); - mpp_frame_set_fmt(frame, (MppFrameFormat)p->CodecType); - mpp_log("setting default w %4d h %4d\n", p->ImgWidth, p->ImgHeight); - mpp_slots_set_prop(dec->frame_slots, SLOTS_FRAME_INFO, frame); - mpp_frame_deinit(&frame); - } break; - case MPP_DEC_GET_VPUMEM_USED_COUNT: { - RK_S32 *p = (RK_S32 *)param; - *p = mpp_buf_slot_get_used_size(dec->frame_slots); - } break; - default : { - } break; - } - - - - return MPP_OK; -} - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define MODULE_TAG "mpp_dec" + +#include + +#include "mpp_mem.h" +#include "mpp_log.h" +#include "mpp_time.h" +#include "mpp_common.h" + +#include "mpp.h" +#include "mpp_frame.h" +#include "mpp_buffer_impl.h" +#include "mpp_packet_impl.h" +#include "mpp_frame_impl.h" + +#include "vpu_api.h" + +typedef union PaserTaskWait_u { + RK_U32 val; + struct { + RK_U32 task_hnd : 1; + RK_U32 mpp_pkt_in : 1; + RK_U32 dec_pkt_idx : 1; + RK_U32 dec_pkt_buf : 1; + RK_U32 prev_task : 1; + RK_U32 info_change : 1; + RK_U32 dec_pic_buf : 1; + }; +} PaserTaskWait; + +typedef union DecTaskStatus_u { + RK_U32 val; + struct { + RK_U32 task_hnd_rdy : 1; + RK_U32 mpp_pkt_in_rdy : 1; + RK_U32 dec_pkt_idx_rdy : 1; + RK_U32 dec_pkt_buf_rdy : 1; + RK_U32 task_valid_rdy : 1; + RK_U32 dec_pkt_copy_rdy : 1; + RK_U32 prev_task_rdy : 1; + RK_U32 info_task_gen_rdy : 1; + RK_U32 curr_task_rdy : 1; + RK_U32 task_parsed_rdy : 1; + }; +} DecTaskStatus; + +typedef struct DecTask_t { + HalTaskHnd hnd; + + DecTaskStatus status; + PaserTaskWait wait; + + RK_S32 hal_pkt_idx_in; + RK_S32 hal_frm_idx_out; + + MppBuffer hal_pkt_buf_in; + MppBuffer hal_frm_buf_out; + + HalTaskInfo info; +} DecTask; + +static void dec_task_init(DecTask *task) +{ + task->hnd = NULL; + task->status.val = 0; + task->wait.val = 0; + task->status.prev_task_rdy = 1; + + task->hal_pkt_idx_in = -1; + task->hal_frm_idx_out = -1; + + task->hal_pkt_buf_in = NULL; + task->hal_frm_buf_out = NULL; + + hal_task_info_init(&task->info, MPP_CTX_DEC); +} +#if 0 +static void dec_task_reset(MppDec *dec, DecTask *task) +{ + task->hnd = NULL; + task->status.val = 0; + task->wait.val = 0; + task->status.prev_task_rdy = 1; + + if (task->hal_pkt_idx_in >= 0) { + mpp_buf_slot_clr_flag(dec->frame_slots, task->hal_pkt_idx_in, SLOT_HAL_INPUT); + task->hal_pkt_idx_in = -1; + } + + if (task->hal_frm_idx_out >= 0) { + mpp_buf_slot_clr_flag(dec->frame_slots, task->hal_frm_idx_out, SLOT_HAL_INPUT); + task->hal_frm_idx_out = -1; + } + + if (task->hal_pkt_buf_in) { + mpp_buffer_put(task->hal_pkt_buf_in); + task->hal_pkt_buf_in = NULL; + } + + if (task->hal_frm_buf_out) { + mpp_buffer_put(task->hal_frm_buf_out); + task->hal_frm_buf_out = NULL; + } + + hal_task_info_init(&task->info, MPP_CTX_DEC); +} +#endif +/* + * return MPP_OK for not wait + * return MPP_NOK for wait + */ +static MPP_RET check_task_wait(MppDec *dec, DecTask *task) +{ + if (dec->reset_flag) { + return MPP_OK; + } + + if (task->wait.task_hnd || + task->wait.mpp_pkt_in || + task->wait.prev_task || + task->wait.info_change || + task->wait.dec_pic_buf) + return MPP_NOK; + + return MPP_OK; +} + +static RK_U32 reset_dec_task(Mpp *mpp, DecTask *task) +{ + MppThread *parser = mpp->mThreadCodec; + MppDec *dec = mpp->mDec; + HalTaskGroup tasks = dec->tasks; + MppBufSlots frame_slots = dec->frame_slots; + MppBufSlots packet_slots = dec->packet_slots; + HalDecTask *task_dec = &task->info.dec; + + if (!dec->parser_fast_mode) { + if (!task->status.prev_task_rdy) { + HalTaskHnd task_prev = NULL; + hal_task_get_hnd(tasks, TASK_PROC_DONE, &task_prev); + if (task_prev) { + task->status.prev_task_rdy = 1; + hal_task_hnd_set_status(task_prev, TASK_IDLE); + task_prev = NULL; + task->wait.prev_task = 0; + } else { + msleep(5); + task->wait.prev_task = 1; + return MPP_NOK; + } + } + } else { + if (hal_task_check_empty(tasks, TASK_PROCESSING)) { + msleep(5); + return MPP_NOK; + } + } + + { + RK_S32 index; + parser->lock(THREAD_RESET); + task->status.curr_task_rdy = 0; + task_dec->valid = 0; + parser_reset(dec->parser); + mpp_hal_reset(dec->hal); + dec->reset_flag = 0; + if (task->wait.info_change) { + mpp_log("reset add info change status"); + mpp_buf_slot_reset(frame_slots, task_dec->output); + + } + if (task->status.task_parsed_rdy) { + mpp_log("task no send to hal que must clr current frame hal status"); + mpp_buf_slot_clr_flag(frame_slots, task_dec->output, SLOT_HAL_OUTPUT); + for (RK_U32 i = 0; i < MPP_ARRAY_ELEMS(task_dec->refer); i++) { + index = task_dec->refer[i]; + if (index >= 0) + mpp_buf_slot_clr_flag(frame_slots, index, SLOT_HAL_INPUT); + } + } + if (dec->mpp_pkt_in) { + mpp_packet_deinit(&dec->mpp_pkt_in); + dec->mpp_pkt_in = NULL; + } + while (MPP_OK == mpp_buf_slot_dequeue(frame_slots, &index, QUEUE_DISPLAY)) { + /* release extra ref in slot's MppBuffer */ + MppBuffer buffer = NULL; + mpp_buf_slot_get_prop(frame_slots, index, SLOT_BUFFER, &buffer); + if (buffer) + mpp_buffer_put(buffer); + mpp_buf_slot_clr_flag(frame_slots, index, SLOT_QUEUE_USE); + } + if (task->status.dec_pkt_copy_rdy) { + mpp_buf_slot_clr_flag(packet_slots, task_dec->input, SLOT_HAL_INPUT); + task->status.dec_pkt_copy_rdy = 0; + task_dec->input = -1; + } + + + task->status.task_parsed_rdy = 0; + parser->unlock(THREAD_RESET); + parser->signal(THREAD_RESET); + } + + dec_task_init(task); + + return MPP_OK; +} + +static void mpp_put_frame(Mpp *mpp, MppFrame frame) +{ + mpp_list *list = mpp->mFrames; + + list->lock(); + list->add_at_tail(&frame, sizeof(frame)); + + if (mpp_debug & MPP_DBG_PTS) + mpp_log("output frame pts %lld\n", mpp_frame_get_pts(frame)); + + mpp->mFramePutCount++; + list->signal(); + list->unlock(); +} + +static void mpp_put_frame_eos(Mpp *mpp) +{ + MppFrame info_frame = NULL; + mpp_frame_init(&info_frame); + mpp_assert(NULL == mpp_frame_get_buffer(info_frame)); + mpp_frame_set_eos(info_frame, 1); + mpp_put_frame((Mpp*)mpp, info_frame); + return; +} + +static void mpp_dec_push_display(Mpp *mpp) +{ + RK_S32 index; + MppDec *dec = mpp->mDec; + MppBufSlots frame_slots = dec->frame_slots; + mpp->mThreadHal->lock(THREAD_QUE_DISPLAY); + while (MPP_OK == mpp_buf_slot_dequeue(frame_slots, &index, QUEUE_DISPLAY)) { + MppFrame frame = NULL; + mpp_buf_slot_get_prop(frame_slots, index, SLOT_FRAME, &frame); + if (!dec->reset_flag) { + mpp_put_frame(mpp, frame); + } else { + /* release extra ref in slot's MppBuffer */ + MppBuffer buffer = mpp_frame_get_buffer(frame); + if (buffer) + mpp_buffer_put(buffer); + } + mpp_buf_slot_clr_flag(frame_slots, index, SLOT_QUEUE_USE); + } + mpp->mThreadHal->unlock(THREAD_QUE_DISPLAY); +} + +static void mpp_dec_push_eos_task(Mpp *mpp, DecTask *task) +{ + hal_task_hnd_set_info(task->hnd, &task->info); + mpp->mThreadHal->lock(); + hal_task_hnd_set_status(task->hnd, TASK_PROCESSING); + mpp->mThreadHal->unlock(); + mpp->mThreadHal->signal(); +} + +static MPP_RET try_proc_dec_task(Mpp *mpp, DecTask *task) +{ + MppDec *dec = mpp->mDec; + HalTaskGroup tasks = dec->tasks; + MppBufSlots frame_slots = dec->frame_slots; + MppBufSlots packet_slots = dec->packet_slots; + size_t stream_size = 0; + HalDecTask *task_dec = &task->info.dec; + + + /* + * 1. get task handle from hal for parsing one frame + */ + if (!task->hnd) { + hal_task_get_hnd(tasks, TASK_IDLE, &task->hnd); + if (task->hnd) { + task->wait.task_hnd = 0; + } else { + task->wait.task_hnd = 1; + return MPP_NOK; + } + } + + + /* + * 2. get packet for parser preparing + */ + if (!dec->mpp_pkt_in && !task->status.curr_task_rdy) { + mpp_list *packets = mpp->mPackets; + AutoMutex autoLock(packets->mutex()); + if (packets->list_size()) { + /* + * packet will be destroyed outside, here just copy the content + */ + packets->del_at_head(&dec->mpp_pkt_in, sizeof(dec->mpp_pkt_in)); + mpp->mPacketGetCount++; + task->wait.mpp_pkt_in = 0; + } else { + task->wait.mpp_pkt_in = 1; + return MPP_NOK; + } + } + + /* + * 3. send packet data to parser for prepare + * + * parser_prepare functioin input / output + * input: input MppPacket data from user + * output: one packet which contains one frame for hardware processing + * output information will be stored in task_dec->input_packet + * output data can be stored inside of parser. + * + * NOTE: + * 1. Prepare process is controlled by need_split flag + * If need_split flag is zero prepare function is just copy the input + * packet to task_dec->input_packet + * If need_split flag is non-zero prepare function will call split funciton + * of different coding type and find the start and end of one frame. Then + * copy data to task_dec->input_packet + * 2. On need_split mode if one input MppPacket contain multiple frame for + * decoding one parser_prepare call will only frame for task. Then input + * MppPacket->pos/length will be updated. The input MppPacket will not be + * released until it is totally consumed. + * 3. On spliting frame if one frame contain multiple slices and these multiple + * slices have different pts/dts the output frame will use the last pts/dts + * as the output frame's pts/dts. + * + */ + if (!task->status.curr_task_rdy) { + RK_S64 p_e, p_s, diff; + p_s = mpp_time(); + + if (mpp_debug & MPP_DBG_PTS) + mpp_log("input packet pts %lld\n", mpp_packet_get_pts(dec->mpp_pkt_in)); + + parser_prepare(dec->parser, dec->mpp_pkt_in, task_dec); + p_e = mpp_time(); + if (mpp_debug & MPP_DBG_TIMING) { + diff = (p_e - p_s) / 1000; + if (diff > 15) { + mpp_log("waring mpp prepare stream consume %lld big than 15ms ", diff); + } + } + if (0 == mpp_packet_get_length(dec->mpp_pkt_in)) { + mpp_packet_deinit(&dec->mpp_pkt_in); + dec->mpp_pkt_in = NULL; + } + } + + task->status.curr_task_rdy = task_dec->valid; + /* + * We may find eos in prepare step and there will be no anymore vaild task generated. + * So here we try push eos task to hal, hal will push all frame to display then + * push a eos frame to tell all frame decoded + */ + // mpp_dec_push_display(mpp); + if (task_dec->flags.eos && !task_dec->valid) { + mpp_dec_push_eos_task(mpp, task); + task->hnd = NULL; + } + + if (!task->status.curr_task_rdy) + return MPP_NOK; + + // NOTE: packet in task should be ready now + mpp_assert(task_dec->input_packet); + + /* + * 4. look for a unused packet slot index + */ + if (task_dec->input < 0) { + mpp_buf_slot_get_unused(packet_slots, &task_dec->input); + } + + task->wait.dec_pkt_idx = (task_dec->input < 0); + if (task->wait.dec_pkt_idx) + return MPP_NOK; + + /* + * 5. malloc hardware buffer for the packet slot index + */ + task->hal_pkt_idx_in = task_dec->input; + stream_size = mpp_packet_get_size(task_dec->input_packet); + + MppBuffer hal_buf_in; + mpp_buf_slot_get_prop(packet_slots, task->hal_pkt_idx_in, SLOT_BUFFER, &hal_buf_in); + if (NULL == hal_buf_in) { + mpp_buffer_get(mpp->mPacketGroup, &hal_buf_in, stream_size); + if (hal_buf_in) { + mpp_buf_slot_set_prop(packet_slots, task->hal_pkt_idx_in, SLOT_BUFFER, hal_buf_in); + mpp_buffer_put(hal_buf_in); + } + } else { + MppBufferImpl *buf = (MppBufferImpl *)hal_buf_in; + mpp_assert(buf->info.size >= stream_size); + } + + task->hal_pkt_buf_in = hal_buf_in; + task->wait.dec_pkt_buf = (NULL == hal_buf_in); + if (task->wait.dec_pkt_buf) + return MPP_NOK; + + /* + * 6. copy prepared stream to hardware buffer + */ + if (!task->status.dec_pkt_copy_rdy) { + MppBufferImpl *buf = (MppBufferImpl *)task->hal_pkt_buf_in; + void *src = mpp_packet_get_data(task_dec->input_packet); + size_t length = mpp_packet_get_length(task_dec->input_packet); + memcpy(buf->info.ptr, src, length); + mpp_buf_slot_set_flag(packet_slots, task_dec->input, SLOT_CODEC_READY); + mpp_buf_slot_set_flag(packet_slots, task_dec->input, SLOT_HAL_INPUT); + task->status.dec_pkt_copy_rdy = 1; + } + + /* + * 7. if not fast mode wait previous task done here + */ + if (!dec->parser_fast_mode) { + // wait previous task done + if (!task->status.prev_task_rdy) { + HalTaskHnd task_prev = NULL; + hal_task_get_hnd(tasks, TASK_PROC_DONE, &task_prev); + if (task_prev) { + task->status.prev_task_rdy = 1; + task->wait.prev_task = 0; + hal_task_hnd_set_status(task_prev, TASK_IDLE); + task_prev = NULL; + } else { + task->wait.prev_task = 1; + return MPP_NOK; + } + } + } + + /* + * 7. look for a unused hardware buffer for output + */ + if (mpp->mFrameGroup) { + task->wait.dec_pic_buf = (mpp_buffer_group_unused(mpp->mFrameGroup) < 1); + if (task->wait.dec_pic_buf) + return MPP_NOK; + } + + /* + * We may find eos in prepare step and there will be no anymore vaild task generated. + * So here we try push all frames to display to avoid eos no notify to display + */ + // mpp_dec_push_display(mpp); + + /* + * 8. send packet data to parser + * + * parser prepare functioin input / output + * input: packet data + * output: dec task output information (with dxva output slot) + * buffer slot usage informatioin + * + * NOTE: + * 1. dpb slot will be set internally in parser process. + * 2. parse function need to set valid flag when one frame is ready. + * 3. if packet size is zero then next packet is needed. + * + */ + if (!task->status.task_parsed_rdy) { + parser_parse(dec->parser, task_dec); + task->status.task_parsed_rdy = 1; + } + + /* + * 9. parse local task and slot to check whether new buffer or info change is needed. + * + * a. first detect info change from frame slot + * b. then detect whether output index has MppBuffer + */ + if (mpp_buf_slot_is_changed(frame_slots)) { + if (!task->status.info_task_gen_rdy) { + task_dec->flags.info_change = 1; + hal_task_hnd_set_info(task->hnd, &task->info); + mpp->mThreadHal->lock(); + hal_task_hnd_set_status(task->hnd, TASK_PROCESSING); + mpp->mThreadHal->unlock(); + mpp->mThreadHal->signal(); + mpp->mTaskPutCount++; + task->hnd = NULL; + task->status.info_task_gen_rdy = 1; + return MPP_NOK; + } + } + + task->wait.info_change = mpp_buf_slot_is_changed(frame_slots); + if (task->wait.info_change) { + return MPP_NOK; + } else { + task->status.info_task_gen_rdy = 0; + task_dec->flags.info_change = 0; + // NOTE: check the task must be ready + mpp_assert(task->hnd); + } + + + if (task_dec->output < 0) { + /* + * We may find eos in parser step and there will be no anymore vaild task generated. + * So here we try push eos task to hal, hal will push all frame to display then + * push a eos frame to tell all frame decoded + */ + if (task_dec->flags.eos) { + mpp_dec_push_eos_task(mpp, task); + } else { + hal_task_hnd_set_status(task->hnd, TASK_IDLE); + } + + mpp->mTaskPutCount++; + task->hnd = NULL; + if (task->status.dec_pkt_copy_rdy) { + mpp_buf_slot_clr_flag(packet_slots, task_dec->input, SLOT_HAL_INPUT); + task->status.dec_pkt_copy_rdy = 0; + } + task->status.curr_task_rdy = 0; + task->status.task_parsed_rdy = 0; + hal_task_info_init(&task->info, MPP_CTX_DEC); + return MPP_NOK; + } + + /* + * 5. chekc frame buffer group is internal or external + */ + if (NULL == mpp->mFrameGroup) { + mpp_log("mpp_dec use internal frame buffer group\n"); + mpp_buffer_group_get_internal(&mpp->mFrameGroup, MPP_BUFFER_TYPE_ION); + } + + /* + * 5. do buffer operation according to usage information + * + * possible case: + * a. normal case + * - wait and alloc a normal frame buffer + * b. field mode case + * - two field may reuse a same buffer, no need to alloc + * c. info change case + * - need buffer in different side, need to send a info change + * frame to hal loop. + */ + RK_S32 output = task_dec->output; + MppBuffer hal_buf_out; + mpp_buf_slot_get_prop(frame_slots, output, SLOT_BUFFER, &hal_buf_out); + if (NULL == hal_buf_out) { + size_t size = mpp_buf_slot_get_size(frame_slots); + mpp_buffer_get(mpp->mFrameGroup, &hal_buf_out, size); + if (hal_buf_out) + mpp_buf_slot_set_prop(frame_slots, output, SLOT_BUFFER, hal_buf_out); + + } + + task->hal_frm_buf_out = hal_buf_out; + task->wait.dec_pic_buf = (NULL == hal_buf_out); + if (task->wait.dec_pic_buf) + return MPP_NOK; + + // register genertation + mpp_hal_reg_gen(dec->hal, &task->info); + + /* + * wait previous register set done + */ + //mpp_hal_hw_wait(dec->hal_ctx, &task_local); + + /* + * send current register set to hardware + */ + //mpp_hal_hw_start(dec->hal_ctx, &task_local); + + mpp_hal_hw_start(dec->hal, &task->info); + + /* + * 6. send dxva output information and buffer information to hal thread + * combinate video codec dxva output and buffer information + */ + hal_task_hnd_set_info(task->hnd, &task->info); + mpp->mThreadHal->lock(); + hal_task_hnd_set_status(task->hnd, TASK_PROCESSING); + mpp->mThreadHal->unlock(); + mpp->mThreadHal->signal(); + + mpp->mTaskPutCount++; + task->hnd = NULL; + task->status.dec_pkt_copy_rdy = 0; + task->status.curr_task_rdy = 0; + task->status.task_parsed_rdy = 0; + task->status.prev_task_rdy = 0; + hal_task_info_init(&task->info, MPP_CTX_DEC); + + return MPP_OK; +} + + + +void *mpp_dec_parser_thread(void *data) +{ + Mpp *mpp = (Mpp*)data; + MppThread *parser = mpp->mThreadCodec; + MppDec *dec = mpp->mDec; + MppBufSlots packet_slots = dec->packet_slots; + + /* + * parser thread need to wait at cases below: + * 1. no task slot for output + * 2. no packet for parsing + * 3. info change on progress + * 3. no buffer on analyzing output task + */ + DecTask task; + HalDecTask *task_dec = &task.info.dec; + + dec_task_init(&task); + + while (MPP_THREAD_RUNNING == parser->get_status()) { + /* + * wait for stream input + */ + if (dec->reset_flag) { + if (reset_dec_task(mpp, &task)) + continue; + } + + parser->lock(); + if (MPP_THREAD_RUNNING == parser->get_status()) { + if (check_task_wait(dec, &task)) + parser->wait(); + } + parser->unlock(); + + + if (try_proc_dec_task(mpp, &task)) + continue; + + } + mpp_log("mpp_dec_parser_thread exit"); + if (NULL != task.hnd && task_dec->valid) { + mpp_buf_slot_set_flag(packet_slots, task_dec->input, SLOT_CODEC_READY); + mpp_buf_slot_set_flag(packet_slots, task_dec->input, SLOT_HAL_INPUT); + mpp_buf_slot_clr_flag(packet_slots, task_dec->input, SLOT_HAL_INPUT); + } + mpp_buffer_group_clear(mpp->mPacketGroup); + mpp_log("mpp_dec_parser_thread exit ok"); + return NULL; +} + +void *mpp_dec_hal_thread(void *data) +{ + Mpp *mpp = (Mpp*)data; + MppThread *hal = mpp->mThreadHal; + MppDec *dec = mpp->mDec; + HalTaskGroup tasks = dec->tasks; + MppBufSlots frame_slots = dec->frame_slots; + MppBufSlots packet_slots = dec->packet_slots; + + /* + * hal thread need to wait at cases below: + * 1. no task slot for work + */ + HalTaskHnd task = NULL; + HalTaskInfo task_info; + HalDecTask *task_dec = &task_info.dec; + RK_S64 cur_deat = 0; + RK_U64 dec_no = 0, total_time = 0; + RK_S64 p_s, p_e; + + p_s = mpp_time(); + while (MPP_THREAD_RUNNING == hal->get_status()) { + /* + * hal thread wait for dxva interface intput firt + */ + hal->lock(); + if (MPP_THREAD_RUNNING == hal->get_status()) { + if (hal_task_get_hnd(tasks, TASK_PROCESSING, &task)) + hal->wait(); + } + hal->unlock(); + + if (task) { + mpp->mTaskGetCount++; + + hal_task_hnd_get_info(task, &task_info); + /* + * check info change flag + * if this is a info change frame, only output the mpp_frame for info change. + */ + + if (task_dec->flags.info_change) { + MppFrame info_frame = NULL; + mpp_dec_flush(dec); + mpp_dec_push_display(mpp); + mpp_buf_slot_get_prop(frame_slots, task_dec->output, SLOT_FRAME, &info_frame); + mpp_assert(info_frame); + mpp_assert(NULL == mpp_frame_get_buffer(info_frame)); + mpp_frame_set_info_change(info_frame, 1); + mpp_frame_set_errinfo(info_frame, 0); + mpp_put_frame(mpp, info_frame); + + hal_task_hnd_set_status(task, TASK_IDLE); + task = NULL; + mpp->mThreadCodec->signal(); + continue; + } + /* + * check eos task + * if this task is invalid then eos flag come we will flush display que + * then push eos frame to tell all frame decoded + */ + if (task_dec->flags.eos && !task_dec->valid) { + mpp_dec_push_display(mpp); + mpp_put_frame_eos(mpp); + hal_task_hnd_set_status(task, TASK_IDLE); + mpp->mThreadCodec->signal(); + task = NULL; + continue; + } + mpp_hal_hw_wait(dec->hal, &task_info); + p_e = mpp_time(); + cur_deat = (p_e - p_s); + total_time += cur_deat; + //mpp_log("[Cal_time] dec_no=%lld, time=%d ms, av_time=%lld ms. \n", dec_no, cur_deat, total_time/(dec_no + 1)); + dec_no++; + p_s = p_e; + /* + * when hardware decoding is done: + * 1. clear decoding flag (mark buffer is ready) + * 2. use get_display to get a new frame with buffer + * 3. add frame to output list + * repeat 2 and 3 until not frame can be output + */ + mpp_buf_slot_clr_flag(packet_slots, task_dec->input, SLOT_HAL_INPUT); + + // TODO: may have risk here + hal_task_hnd_set_status(task, TASK_PROC_DONE); + task = NULL; + if (dec->parser_fast_mode) { + hal_task_get_hnd(tasks, TASK_PROC_DONE, &task); + if (task) { + hal_task_hnd_set_status(task, TASK_IDLE); + } + } + mpp->mThreadCodec->signal(); + + mpp_buf_slot_clr_flag(frame_slots, task_dec->output, SLOT_HAL_OUTPUT); + for (RK_U32 i = 0; i < MPP_ARRAY_ELEMS(task_dec->refer); i++) { + RK_S32 index = task_dec->refer[i]; + if (index >= 0) + mpp_buf_slot_clr_flag(frame_slots, index, SLOT_HAL_INPUT); + } + if (task_dec->flags.eos) { + mpp_dec_flush(dec); + } + mpp_dec_push_display(mpp); + /* + * check eos task + * if this task is valid then eos flag come we will flush display que + * then push eos frame to tell all frame decoded + */ + if (task_dec->flags.eos) { + mpp_put_frame_eos(mpp); + } + } + } + + mpp_log("mpp_dec_hal_thread exit ok"); + return NULL; +} + +MPP_RET mpp_dec_init(MppDec **dec, MppDecCfg *cfg) +{ + MPP_RET ret; + MppCodingType coding; + MppBufSlots frame_slots = NULL; + MppBufSlots packet_slots = NULL; + Parser parser = NULL; + MppHal hal = NULL; + RK_S32 hal_task_count = 0; + MppDec *p = NULL; + IOInterruptCB cb = {NULL, NULL}; + + if (NULL == dec || NULL == cfg) { + mpp_err_f("invalid input dec %p cfg %p\n", dec, cfg); + return MPP_ERR_NULL_PTR; + } + + *dec = NULL; + + p = mpp_calloc(MppDec, 1); + if (NULL == p) { + mpp_err_f("failed to malloc context\n"); + return MPP_ERR_MALLOC; + } + + coding = cfg->coding; + hal_task_count = (cfg->fast_mode) ? (3) : (2); + + do { + ret = mpp_buf_slot_init(&frame_slots); + if (ret) { + mpp_err_f("could not init frame buffer slot\n"); + break; + } + + ret = mpp_buf_slot_init(&packet_slots); + if (ret) { + mpp_err_f("could not init packet buffer slot\n"); + break; + } + + mpp_buf_slot_setup(packet_slots, hal_task_count); + cb.callBack = mpp_dec_notify; + cb.opaque = p; + ParserCfg parser_cfg = { + coding, + frame_slots, + packet_slots, + hal_task_count, + cfg->need_split, + cfg->internal_pts, + cb, + }; + + ret = parser_init(&parser, &parser_cfg); + if (ret) { + mpp_err_f("could not init parser\n"); + break; + } + cb.callBack = hal_callback; + cb.opaque = parser; + // then init hal with task count from parser + MppHalCfg hal_cfg = { + MPP_CTX_DEC, + coding, + HAL_MODE_LIBVPU, + HAL_RKVDEC, + frame_slots, + packet_slots, + NULL, + parser_cfg.task_count, + cfg->fast_mode, + cb, + }; + + ret = mpp_hal_init(&hal, &hal_cfg); + if (ret) { + mpp_err_f("could not init hal\n"); + break; + } + + p->coding = coding; + p->parser = parser; + p->hal = hal; + p->tasks = hal_cfg.tasks; + p->frame_slots = frame_slots; + p->packet_slots = packet_slots; + + p->mpp = cfg->mpp; + p->parser_need_split = cfg->need_split; + p->parser_fast_mode = cfg->fast_mode; + p->parser_internal_pts = cfg->internal_pts; + *dec = p; + return MPP_OK; + } while (0); + + mpp_dec_deinit(p); + return MPP_NOK; +} + +MPP_RET mpp_dec_deinit(MppDec *dec) +{ + if (NULL == dec) { + mpp_err_f("found NULL input\n"); + return MPP_ERR_NULL_PTR; + } + + if (dec->parser) { + parser_deinit(dec->parser); + dec->parser = NULL; + } + + if (dec->hal) { + mpp_hal_deinit(dec->hal); + dec->hal = NULL; + } + + if (dec->frame_slots) { + mpp_buf_slot_deinit(dec->frame_slots); + dec->frame_slots = NULL; + } + + if (dec->packet_slots) { + mpp_buf_slot_deinit(dec->packet_slots); + dec->packet_slots = NULL; + } + + mpp_free(dec); + return MPP_OK; +} + +MPP_RET mpp_dec_reset(MppDec *dec) +{ + if (NULL == dec) { + mpp_err_f("found NULL input dec %p\n", dec); + return MPP_ERR_NULL_PTR; + } + dec->reset_flag = 1; + + // parser_reset(dec->parser); + // mpp_hal_reset(dec->hal); + + return MPP_OK; +} + +MPP_RET mpp_dec_flush(MppDec *dec) +{ + if (NULL == dec) { + mpp_err_f("found NULL input dec %p\n", dec); + return MPP_ERR_NULL_PTR; + } + + parser_flush(dec->parser); + mpp_hal_flush(dec->hal); + + return MPP_OK; +} + +MPP_RET mpp_dec_notify(void *ctx, void *info) +{ + MppDec *dec = (MppDec *)ctx; + MppFrame info_frame = NULL; + mpp_frame_init(&info_frame); + mpp_assert(NULL == mpp_frame_get_buffer(info_frame)); + mpp_frame_set_eos(info_frame, 1); + mpp_put_frame((Mpp*)dec->mpp, info_frame); + (void)info; + return MPP_OK; +} + +MPP_RET mpp_dec_control(MppDec *dec, MpiCmd cmd, void *param) +{ + if (NULL == dec) { + mpp_err_f("found NULL input dec %p\n", dec); + return MPP_ERR_NULL_PTR; + } + parser_control(dec->parser, cmd, param); + mpp_hal_control(dec->hal, cmd, param); + + switch (cmd) { + case MPP_DEC_SET_FRAME_INFO : { + VPU_GENERIC *p = (VPU_GENERIC *)param; + MppFrame frame = NULL; + mpp_frame_init(&frame); + mpp_frame_set_width(frame, p->ImgWidth); + mpp_frame_set_height(frame, p->ImgHeight); + mpp_frame_set_hor_stride(frame, p->ImgHorStride); + mpp_frame_set_ver_stride(frame, p->ImgVerStride); + mpp_frame_set_fmt(frame, (MppFrameFormat)p->CodecType); + mpp_log("setting default w %4d h %4d\n", p->ImgWidth, p->ImgHeight); + mpp_slots_set_prop(dec->frame_slots, SLOTS_FRAME_INFO, frame); + mpp_frame_deinit(&frame); + } break; + case MPP_DEC_GET_VPUMEM_USED_COUNT: { + RK_S32 *p = (RK_S32 *)param; + *p = mpp_buf_slot_get_used_size(dec->frame_slots); + } break; + default : { + } break; + } + + + + return MPP_OK; +} + diff --git a/mpp/codec/mpp_enc.cpp b/mpp/codec/mpp_enc.cpp index 511d4c3d..4862e049 100644 --- a/mpp/codec/mpp_enc.cpp +++ b/mpp/codec/mpp_enc.cpp @@ -1,429 +1,429 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define MODULE_TAG "mpp_enc" - -#include "string.h" - -#include "mpp_log.h" -#include "mpp_mem.h" -#include "mpp_common.h" - -#include "mpp.h" -#include "mpp_frame_impl.h" -#include "mpp_packet.h" -#include "mpp_packet_impl.h" -#include "hal_h264e_api.h" - -static void reset_hal_enc_task(HalEncTask *task) -{ - memset(task, 0, sizeof(*task)); -} - -static MPP_RET release_task_in_port(MppPort port) -{ - MPP_RET ret = MPP_OK; - MppPacket packet = NULL; - MppFrame frame = NULL; - MppTask mpp_task; - - do { - ret = mpp_port_dequeue(port, &mpp_task); - if (ret) - break; - - if (mpp_task) { - packet = NULL; - frame = NULL; - ret = mpp_task_meta_get_frame(mpp_task, MPP_META_KEY_INPUT_FRM, &frame); - if (frame) { - mpp_frame_deinit(&frame); - frame = NULL; - } - ret = mpp_task_meta_get_packet(mpp_task, MPP_META_KEY_OUTPUT_PKT, &packet); - if (packet) { - mpp_packet_deinit(&packet); - packet = NULL; - } - - mpp_port_enqueue(port, mpp_task); - mpp_task = NULL; - } else - break; - } while (1); - - return ret; -} - -void *mpp_enc_control_thread(void *data) -{ - Mpp *mpp = (Mpp*)data; - MppEnc *enc = mpp->mEnc; - MppThread *thd_enc = mpp->mThreadCodec; - HalTaskInfo task_info; - HalEncTask *enc_task = &task_info.enc; - MppPort input = mpp_task_queue_get_port(mpp->mInputTaskQueue, MPP_PORT_OUTPUT); - MppPort output = mpp_task_queue_get_port(mpp->mOutputTaskQueue, MPP_PORT_INPUT); - MppTask mpp_task = NULL; - MPP_RET ret = MPP_OK; - MppFrame frame = NULL; - MppPacket packet = NULL; - - memset(&task_info, 0, sizeof(HalTaskInfo)); - - while (MPP_THREAD_RUNNING == thd_enc->get_status()) { - thd_enc->lock(); - ret = mpp_port_dequeue(input, &mpp_task); - if (ret || NULL == mpp_task) { - thd_enc->wait(); - } - thd_enc->unlock(); - - if (mpp_task != NULL) { - mpp_task_meta_get_frame (mpp_task, MPP_META_KEY_INPUT_FRM, &frame); - mpp_task_meta_get_packet(mpp_task, MPP_META_KEY_OUTPUT_PKT, &packet); - - if (NULL == frame) { - mpp_port_enqueue(input, mpp_task); - continue; - } - - reset_hal_enc_task(enc_task); - - if (mpp_frame_get_buffer(frame)) { - /* - * if there is available buffer in the input frame do encoding - */ - if (NULL == packet) { - RK_U32 width = enc->mpp_cfg.width; - RK_U32 height = enc->mpp_cfg.height; - RK_U32 size = width * height; - MppBuffer buffer = NULL; - - mpp_buffer_get(mpp->mPacketGroup, &buffer, size); - mpp_log("create buffer size %d fd %d\n", size, mpp_buffer_get_fd(buffer)); - mpp_packet_init_with_buffer(&packet, buffer); - mpp_buffer_put(buffer); - } - mpp_assert(packet); - - mpp_packet_set_pts(packet, mpp_frame_get_pts(frame)); - - enc_task->input = mpp_frame_get_buffer(frame); - enc_task->output = mpp_packet_get_buffer(packet); - controller_encode(mpp->mEnc->controller, enc_task); - - mpp_hal_reg_gen((mpp->mEnc->hal), &task_info); - mpp_hal_hw_start((mpp->mEnc->hal), &task_info); - mpp_hal_hw_wait((mpp->mEnc->hal), &task_info); - - RK_U32 outputStreamSize = 0; - controller_config(mpp->mEnc->controller, GET_OUTPUT_STREAM_SIZE, (void*)&outputStreamSize); - - mpp_packet_set_length(packet, outputStreamSize); - } else { - /* - * else init a empty packet for output - */ - mpp_packet_new(&packet); - } - - if (mpp_frame_get_eos(frame)) - mpp_packet_set_eos(packet); - - /* - * first clear output packet - * then enqueue task back to input port - * final user will release the mpp_frame they had input - */ - mpp_task_meta_set_frame(mpp_task, MPP_META_KEY_INPUT_FRM, frame); - mpp_port_enqueue(input, mpp_task); - mpp_task = NULL; - - // send finished task to output port - mpp_port_dequeue(output, &mpp_task); - mpp_task_meta_set_packet(mpp_task, MPP_META_KEY_OUTPUT_PKT, packet); - - { - RK_S32 is_intra = enc_task->is_intra; - RK_U32 flag = mpp_packet_get_flag(packet); - - mpp_task_meta_set_s32(mpp_task, MPP_META_KEY_OUTPUT_INTRA, is_intra); - if (is_intra) { - mpp_packet_set_flag(packet, flag | MPP_PACKET_FLAG_INTRA); - } - } - - // setup output task here - mpp_port_enqueue(output, mpp_task); - mpp_task = NULL; - packet = NULL; - frame = NULL; - } - } - - // clear remain task in output port - release_task_in_port(input); - release_task_in_port(mpp->mOutputPort); - - return NULL; -} - -void *mpp_enc_hal_thread(void *data) -{ - Mpp *mpp = (Mpp*)data; - MppThread *hal = mpp->mThreadHal; - mpp_list *frames = mpp->mFrames; - mpp_list *tasks = mpp->mTasks; - - while (MPP_THREAD_RUNNING == hal->get_status()) { - /* - * hal thread wait for dxva interface intput firt - */ - hal->lock(); - if (0 == tasks->list_size()) - hal->wait(); - hal->unlock(); - - // get_config - // register genertation - if (tasks->list_size()) { - HalDecTask *task; - tasks->lock(); - tasks->del_at_head(&task, sizeof(task)); - mpp->mTaskGetCount++; - tasks->unlock(); - - // hal->mpp_hal_reg_gen(current); - - /* - * wait previous register set done - */ - // hal->mpp_hal_hw_wait(previous); - - /* - * send current register set to hardware - */ - // hal->mpp_hal_hw_start(current); - - /* - * mark previous buffer is complete - */ - // change dpb slot status - // signal() - // mark frame in output queue - // wait up output thread to get a output frame - - // for test - MppBuffer buffer; - mpp_buffer_get(mpp->mFrameGroup, &buffer, SZ_1M); - - MppFrame frame; - mpp_frame_init(&frame); - mpp_frame_set_buffer(frame, buffer); - frames->lock(); - frames->add_at_tail(&frame, sizeof(frame)); - mpp->mFramePutCount++; - frames->signal(); - frames->unlock(); - } - } - - return NULL; -} - -MPP_RET mpp_enc_init(MppEnc **enc, MppCodingType coding) -{ - MPP_RET ret; - MppBufSlots frame_slots = NULL; - MppBufSlots packet_slots = NULL; - Controller controller = NULL; - MppHal hal = NULL; - MppEnc *p = NULL; - RK_S32 task_count = 2; - IOInterruptCB cb = {NULL, NULL}; - - if (NULL == enc) { - mpp_err_f("failed to malloc context\n"); - return MPP_ERR_NULL_PTR; - } - - *enc = NULL; - - p = mpp_calloc(MppEnc, 1); - if (NULL == p) { - mpp_err_f("failed to malloc context\n"); - return MPP_ERR_MALLOC; - } - - do { - ret = mpp_buf_slot_init(&frame_slots); - if (ret) { - mpp_err_f("could not init frame buffer slot\n"); - break; - } - - ret = mpp_buf_slot_init(&packet_slots); - if (ret) { - mpp_err_f("could not init packet buffer slot\n"); - break; - } - - mpp_buf_slot_setup(packet_slots, task_count); - cb.callBack = mpp_enc_notify; - cb.opaque = p; - - ControllerCfg controller_cfg = { - coding, - task_count, - cb, - }; - - ret = controller_init(&controller, &controller_cfg); - if (ret) { - mpp_err_f("could not init controller\n"); - break; - } - cb.callBack = hal_enc_callback; - cb.opaque = controller; - // then init hal with task count from controller - MppHalCfg hal_cfg = { - MPP_CTX_ENC, - coding, - HAL_MODE_LIBVPU, - HAL_VEPU, - frame_slots, - packet_slots, - NULL, - 1/*controller_cfg.task_count*/, // TODO - 0, - cb, - }; - - ret = mpp_hal_init(&hal, &hal_cfg); - if (ret) { - mpp_err_f("could not init hal\n"); - break; - } - - p->coding = coding; - p->controller = controller; - p->hal = hal; - p->tasks = hal_cfg.tasks; - p->frame_slots = frame_slots; - p->packet_slots = packet_slots; - p->mpp_cfg.size = sizeof(p->mpp_cfg); - *enc = p; - return MPP_OK; - } while (0); - - mpp_enc_deinit(p); - return MPP_NOK; - -} - -MPP_RET mpp_enc_deinit(MppEnc *enc) -{ - if (NULL == enc) { - mpp_err_f("found NULL input\n"); - return MPP_ERR_NULL_PTR; - } - - if (enc->controller) { - controller_deinit(enc->controller); - enc->controller = NULL; - } - - if (enc->hal) { - mpp_hal_deinit(enc->hal); - enc->hal = NULL; - } - - if (enc->frame_slots) { - mpp_buf_slot_deinit(enc->frame_slots); - enc->frame_slots = NULL; - } - - if (enc->packet_slots) { - mpp_buf_slot_deinit(enc->packet_slots); - enc->packet_slots = NULL; - } - - mpp_free(enc); - return MPP_OK; -} - -MPP_RET mpp_enc_reset(MppEnc *enc) -{ - (void)enc; - return MPP_OK; -} - -MPP_RET mpp_enc_notify(void *ctx, void *info) -{ - // TODO - (void)ctx; - (void)info; - return MPP_OK; -} - -MPP_RET mpp_enc_control(MppEnc *enc, MpiCmd cmd, void *param) -{ - if (NULL == enc) { - mpp_err_f("found NULL input enc %p\n", enc); - return MPP_ERR_NULL_PTR; - } - - MPP_RET ret = MPP_NOK; - - switch (cmd) { - case MPP_ENC_SET_CFG : { - MppEncConfig *mpp_cfg = &enc->mpp_cfg; - void *extra_info_cfg = NULL; - - memcpy(mpp_cfg, param, sizeof(enc->mpp_cfg)); - - /* before set config to controller check it first */ - ret = controller_config(enc->controller, CHK_ENC_CFG, (void *)mpp_cfg); - if (ret) { - mpp_err("config check failed ret %d\n", ret); - break; - } - controller_config(enc->controller, SET_ENC_CFG, (void *)mpp_cfg); - controller_config(enc->controller, SET_ENC_RC_CFG, (void *)mpp_cfg); - controller_config(enc->controller, GET_ENC_EXTRA_INFO, (void *)&extra_info_cfg); - - ret = mpp_hal_control(enc->hal, MPP_ENC_SET_EXTRA_INFO, extra_info_cfg); - - } break; - case MPP_ENC_GET_CFG : { - MppEncConfig *mpp_cfg = (MppEncConfig *)param; - - mpp_assert(mpp_cfg->size == sizeof(enc->mpp_cfg)); - - *mpp_cfg = enc->mpp_cfg; - ret = MPP_OK; - } break; - case MPP_ENC_GET_EXTRA_INFO : { - ret = mpp_hal_control(enc->hal, cmd, param); - } break; - default : { - } break; - } - - return ret; -} - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define MODULE_TAG "mpp_enc" + +#include "string.h" + +#include "mpp_log.h" +#include "mpp_mem.h" +#include "mpp_common.h" + +#include "mpp.h" +#include "mpp_frame_impl.h" +#include "mpp_packet.h" +#include "mpp_packet_impl.h" +#include "hal_h264e_api.h" + +static void reset_hal_enc_task(HalEncTask *task) +{ + memset(task, 0, sizeof(*task)); +} + +static MPP_RET release_task_in_port(MppPort port) +{ + MPP_RET ret = MPP_OK; + MppPacket packet = NULL; + MppFrame frame = NULL; + MppTask mpp_task; + + do { + ret = mpp_port_dequeue(port, &mpp_task); + if (ret) + break; + + if (mpp_task) { + packet = NULL; + frame = NULL; + ret = mpp_task_meta_get_frame(mpp_task, MPP_META_KEY_INPUT_FRM, &frame); + if (frame) { + mpp_frame_deinit(&frame); + frame = NULL; + } + ret = mpp_task_meta_get_packet(mpp_task, MPP_META_KEY_OUTPUT_PKT, &packet); + if (packet) { + mpp_packet_deinit(&packet); + packet = NULL; + } + + mpp_port_enqueue(port, mpp_task); + mpp_task = NULL; + } else + break; + } while (1); + + return ret; +} + +void *mpp_enc_control_thread(void *data) +{ + Mpp *mpp = (Mpp*)data; + MppEnc *enc = mpp->mEnc; + MppThread *thd_enc = mpp->mThreadCodec; + HalTaskInfo task_info; + HalEncTask *enc_task = &task_info.enc; + MppPort input = mpp_task_queue_get_port(mpp->mInputTaskQueue, MPP_PORT_OUTPUT); + MppPort output = mpp_task_queue_get_port(mpp->mOutputTaskQueue, MPP_PORT_INPUT); + MppTask mpp_task = NULL; + MPP_RET ret = MPP_OK; + MppFrame frame = NULL; + MppPacket packet = NULL; + + memset(&task_info, 0, sizeof(HalTaskInfo)); + + while (MPP_THREAD_RUNNING == thd_enc->get_status()) { + thd_enc->lock(); + ret = mpp_port_dequeue(input, &mpp_task); + if (ret || NULL == mpp_task) { + thd_enc->wait(); + } + thd_enc->unlock(); + + if (mpp_task != NULL) { + mpp_task_meta_get_frame (mpp_task, MPP_META_KEY_INPUT_FRM, &frame); + mpp_task_meta_get_packet(mpp_task, MPP_META_KEY_OUTPUT_PKT, &packet); + + if (NULL == frame) { + mpp_port_enqueue(input, mpp_task); + continue; + } + + reset_hal_enc_task(enc_task); + + if (mpp_frame_get_buffer(frame)) { + /* + * if there is available buffer in the input frame do encoding + */ + if (NULL == packet) { + RK_U32 width = enc->mpp_cfg.width; + RK_U32 height = enc->mpp_cfg.height; + RK_U32 size = width * height; + MppBuffer buffer = NULL; + + mpp_buffer_get(mpp->mPacketGroup, &buffer, size); + mpp_log("create buffer size %d fd %d\n", size, mpp_buffer_get_fd(buffer)); + mpp_packet_init_with_buffer(&packet, buffer); + mpp_buffer_put(buffer); + } + mpp_assert(packet); + + mpp_packet_set_pts(packet, mpp_frame_get_pts(frame)); + + enc_task->input = mpp_frame_get_buffer(frame); + enc_task->output = mpp_packet_get_buffer(packet); + controller_encode(mpp->mEnc->controller, enc_task); + + mpp_hal_reg_gen((mpp->mEnc->hal), &task_info); + mpp_hal_hw_start((mpp->mEnc->hal), &task_info); + mpp_hal_hw_wait((mpp->mEnc->hal), &task_info); + + RK_U32 outputStreamSize = 0; + controller_config(mpp->mEnc->controller, GET_OUTPUT_STREAM_SIZE, (void*)&outputStreamSize); + + mpp_packet_set_length(packet, outputStreamSize); + } else { + /* + * else init a empty packet for output + */ + mpp_packet_new(&packet); + } + + if (mpp_frame_get_eos(frame)) + mpp_packet_set_eos(packet); + + /* + * first clear output packet + * then enqueue task back to input port + * final user will release the mpp_frame they had input + */ + mpp_task_meta_set_frame(mpp_task, MPP_META_KEY_INPUT_FRM, frame); + mpp_port_enqueue(input, mpp_task); + mpp_task = NULL; + + // send finished task to output port + mpp_port_dequeue(output, &mpp_task); + mpp_task_meta_set_packet(mpp_task, MPP_META_KEY_OUTPUT_PKT, packet); + + { + RK_S32 is_intra = enc_task->is_intra; + RK_U32 flag = mpp_packet_get_flag(packet); + + mpp_task_meta_set_s32(mpp_task, MPP_META_KEY_OUTPUT_INTRA, is_intra); + if (is_intra) { + mpp_packet_set_flag(packet, flag | MPP_PACKET_FLAG_INTRA); + } + } + + // setup output task here + mpp_port_enqueue(output, mpp_task); + mpp_task = NULL; + packet = NULL; + frame = NULL; + } + } + + // clear remain task in output port + release_task_in_port(input); + release_task_in_port(mpp->mOutputPort); + + return NULL; +} + +void *mpp_enc_hal_thread(void *data) +{ + Mpp *mpp = (Mpp*)data; + MppThread *hal = mpp->mThreadHal; + mpp_list *frames = mpp->mFrames; + mpp_list *tasks = mpp->mTasks; + + while (MPP_THREAD_RUNNING == hal->get_status()) { + /* + * hal thread wait for dxva interface intput firt + */ + hal->lock(); + if (0 == tasks->list_size()) + hal->wait(); + hal->unlock(); + + // get_config + // register genertation + if (tasks->list_size()) { + HalDecTask *task; + tasks->lock(); + tasks->del_at_head(&task, sizeof(task)); + mpp->mTaskGetCount++; + tasks->unlock(); + + // hal->mpp_hal_reg_gen(current); + + /* + * wait previous register set done + */ + // hal->mpp_hal_hw_wait(previous); + + /* + * send current register set to hardware + */ + // hal->mpp_hal_hw_start(current); + + /* + * mark previous buffer is complete + */ + // change dpb slot status + // signal() + // mark frame in output queue + // wait up output thread to get a output frame + + // for test + MppBuffer buffer; + mpp_buffer_get(mpp->mFrameGroup, &buffer, SZ_1M); + + MppFrame frame; + mpp_frame_init(&frame); + mpp_frame_set_buffer(frame, buffer); + frames->lock(); + frames->add_at_tail(&frame, sizeof(frame)); + mpp->mFramePutCount++; + frames->signal(); + frames->unlock(); + } + } + + return NULL; +} + +MPP_RET mpp_enc_init(MppEnc **enc, MppCodingType coding) +{ + MPP_RET ret; + MppBufSlots frame_slots = NULL; + MppBufSlots packet_slots = NULL; + Controller controller = NULL; + MppHal hal = NULL; + MppEnc *p = NULL; + RK_S32 task_count = 2; + IOInterruptCB cb = {NULL, NULL}; + + if (NULL == enc) { + mpp_err_f("failed to malloc context\n"); + return MPP_ERR_NULL_PTR; + } + + *enc = NULL; + + p = mpp_calloc(MppEnc, 1); + if (NULL == p) { + mpp_err_f("failed to malloc context\n"); + return MPP_ERR_MALLOC; + } + + do { + ret = mpp_buf_slot_init(&frame_slots); + if (ret) { + mpp_err_f("could not init frame buffer slot\n"); + break; + } + + ret = mpp_buf_slot_init(&packet_slots); + if (ret) { + mpp_err_f("could not init packet buffer slot\n"); + break; + } + + mpp_buf_slot_setup(packet_slots, task_count); + cb.callBack = mpp_enc_notify; + cb.opaque = p; + + ControllerCfg controller_cfg = { + coding, + task_count, + cb, + }; + + ret = controller_init(&controller, &controller_cfg); + if (ret) { + mpp_err_f("could not init controller\n"); + break; + } + cb.callBack = hal_enc_callback; + cb.opaque = controller; + // then init hal with task count from controller + MppHalCfg hal_cfg = { + MPP_CTX_ENC, + coding, + HAL_MODE_LIBVPU, + HAL_VEPU, + frame_slots, + packet_slots, + NULL, + 1/*controller_cfg.task_count*/, // TODO + 0, + cb, + }; + + ret = mpp_hal_init(&hal, &hal_cfg); + if (ret) { + mpp_err_f("could not init hal\n"); + break; + } + + p->coding = coding; + p->controller = controller; + p->hal = hal; + p->tasks = hal_cfg.tasks; + p->frame_slots = frame_slots; + p->packet_slots = packet_slots; + p->mpp_cfg.size = sizeof(p->mpp_cfg); + *enc = p; + return MPP_OK; + } while (0); + + mpp_enc_deinit(p); + return MPP_NOK; + +} + +MPP_RET mpp_enc_deinit(MppEnc *enc) +{ + if (NULL == enc) { + mpp_err_f("found NULL input\n"); + return MPP_ERR_NULL_PTR; + } + + if (enc->controller) { + controller_deinit(enc->controller); + enc->controller = NULL; + } + + if (enc->hal) { + mpp_hal_deinit(enc->hal); + enc->hal = NULL; + } + + if (enc->frame_slots) { + mpp_buf_slot_deinit(enc->frame_slots); + enc->frame_slots = NULL; + } + + if (enc->packet_slots) { + mpp_buf_slot_deinit(enc->packet_slots); + enc->packet_slots = NULL; + } + + mpp_free(enc); + return MPP_OK; +} + +MPP_RET mpp_enc_reset(MppEnc *enc) +{ + (void)enc; + return MPP_OK; +} + +MPP_RET mpp_enc_notify(void *ctx, void *info) +{ + // TODO + (void)ctx; + (void)info; + return MPP_OK; +} + +MPP_RET mpp_enc_control(MppEnc *enc, MpiCmd cmd, void *param) +{ + if (NULL == enc) { + mpp_err_f("found NULL input enc %p\n", enc); + return MPP_ERR_NULL_PTR; + } + + MPP_RET ret = MPP_NOK; + + switch (cmd) { + case MPP_ENC_SET_CFG : { + MppEncConfig *mpp_cfg = &enc->mpp_cfg; + void *extra_info_cfg = NULL; + + memcpy(mpp_cfg, param, sizeof(enc->mpp_cfg)); + + /* before set config to controller check it first */ + ret = controller_config(enc->controller, CHK_ENC_CFG, (void *)mpp_cfg); + if (ret) { + mpp_err("config check failed ret %d\n", ret); + break; + } + controller_config(enc->controller, SET_ENC_CFG, (void *)mpp_cfg); + controller_config(enc->controller, SET_ENC_RC_CFG, (void *)mpp_cfg); + controller_config(enc->controller, GET_ENC_EXTRA_INFO, (void *)&extra_info_cfg); + + ret = mpp_hal_control(enc->hal, MPP_ENC_SET_EXTRA_INFO, extra_info_cfg); + + } break; + case MPP_ENC_GET_CFG : { + MppEncConfig *mpp_cfg = (MppEncConfig *)param; + + mpp_assert(mpp_cfg->size == sizeof(enc->mpp_cfg)); + + *mpp_cfg = enc->mpp_cfg; + ret = MPP_OK; + } break; + case MPP_ENC_GET_EXTRA_INFO : { + ret = mpp_hal_control(enc->hal, cmd, param); + } break; + default : { + } break; + } + + return ret; +} + diff --git a/mpp/codec/mpp_parser.cpp b/mpp/codec/mpp_parser.cpp index 50d1c4ba..d133f1c1 100644 --- a/mpp/codec/mpp_parser.cpp +++ b/mpp/codec/mpp_parser.cpp @@ -1,200 +1,200 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define MODULE_TAG "mpp_dec" - -#include - -#include "mpp_mem.h" -#include "mpp_log.h" -#include "mpp_common.h" - -#include "mpp_parser.h" - -#include "h263d_api.h" -#include "h264d_api.h" -#include "h265d_api.h" -#include "vp9d_api.h" -#include "avsd_api.h" -#include "m2vd_api.h" -#include "mpg4d_api.h" -#include "vp8d_api.h" -#include "jpegd_api.h" -// for test and demo -#include "dummy_dec_api.h" - -/* - * all decoder static register here - */ -static const ParserApi *parsers[] = { -#if HAVE_AVSD - &api_avsd_parser, -#endif - &api_h263d_parser, - &api_h264d_parser, - &api_h265d_parser, - &api_m2vd_parser, - &api_mpg4d_parser, - &api_vp8d_parser, - &api_vp9d_parser, - &api_jpegd_parser, - &dummy_dec_parser, -}; - -typedef struct ParserImpl_t { - ParserCfg cfg; - - const ParserApi *api; - void *ctx; -} ParserImpl; - -MPP_RET parser_init(Parser *prs, ParserCfg *cfg) -{ - if (NULL == prs || NULL == cfg) { - mpp_err_f("found NULL input parser %p config %p\n", prs, cfg); - return MPP_ERR_NULL_PTR; - } - - *prs = NULL; - - RK_U32 i; - for (i = 0; i < MPP_ARRAY_ELEMS(parsers); i++) { - const ParserApi *api = parsers[i]; - if (cfg->coding == api->coding) { - ParserImpl *p = mpp_calloc(ParserImpl, 1); - void *ctx = mpp_calloc_size(void, api->ctx_size); - if (NULL == ctx || NULL == p) { - mpp_err_f("failed to alloc parser context\n"); - mpp_free(p); - mpp_free(ctx); - return MPP_ERR_MALLOC; - } - - MPP_RET ret = api->init(ctx, cfg); - if (MPP_OK != ret) { - mpp_err_f("failed to init parser\n"); - mpp_free(p); - mpp_free(ctx); - return ret; - } - - p->cfg = *cfg; - p->api = api; - p->ctx = ctx; - *prs = p; - return MPP_OK; - } - } - return MPP_NOK; -} - -MPP_RET parser_deinit(Parser prs) -{ - if (NULL == prs) { - mpp_err_f("found NULL input\n"); - return MPP_ERR_NULL_PTR; - } - - ParserImpl *p = (ParserImpl *)prs; - if (p->api->deinit) - p->api->deinit(p->ctx); - - mpp_free(p->ctx); - mpp_free(p); - return MPP_OK; -} - -MPP_RET parser_prepare(Parser prs, MppPacket pkt, HalDecTask *task) -{ - if (NULL == prs || NULL == pkt) { - mpp_err_f("found NULL input\n"); - return MPP_ERR_NULL_PTR; - } - - ParserImpl *p = (ParserImpl *)prs; - if (!p->api->prepare) - return MPP_OK; - - return p->api->prepare(p->ctx, pkt, task); -} - -MPP_RET parser_parse(Parser prs, HalDecTask *task) -{ - if (NULL == prs || NULL == task) { - mpp_err_f("found NULL input\n"); - return MPP_ERR_NULL_PTR; - } - - ParserImpl *p = (ParserImpl *)prs; - if (!p->api->parse) - return MPP_OK; - - return p->api->parse(p->ctx, task); -} - -MPP_RET hal_callback(void *prs, void *err_info) -{ - if (NULL == prs) { - mpp_err_f("found NULL input\n"); - return MPP_ERR_NULL_PTR; - } - ParserImpl *p = (ParserImpl *)prs; - if (!p->api->callback) - return MPP_OK; - return p->api->callback(p->ctx, err_info); -} -MPP_RET parser_reset(Parser prs) -{ - if (NULL == prs) { - mpp_err_f("found NULL input\n"); - return MPP_ERR_NULL_PTR; - } - - ParserImpl *p = (ParserImpl *)prs; - if (!p->api->reset) - return MPP_OK; - - return p->api->reset(p->ctx); -} - -MPP_RET parser_flush(Parser prs) -{ - if (NULL == prs) { - mpp_err_f("found NULL input\n"); - return MPP_ERR_NULL_PTR; - } - - ParserImpl *p = (ParserImpl *)prs; - if (!p->api->flush) - return MPP_OK; - - return p->api->flush(p->ctx); -} - -MPP_RET parser_control(Parser prs, RK_S32 cmd, void *para) -{ - if (NULL == prs) { - mpp_err_f("found NULL input\n"); - return MPP_ERR_NULL_PTR; - } - - ParserImpl *p = (ParserImpl *)prs; - if (!p->api->control) - return MPP_OK; - - return p->api->control(p->ctx, cmd, para); -} - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define MODULE_TAG "mpp_dec" + +#include + +#include "mpp_mem.h" +#include "mpp_log.h" +#include "mpp_common.h" + +#include "mpp_parser.h" + +#include "h263d_api.h" +#include "h264d_api.h" +#include "h265d_api.h" +#include "vp9d_api.h" +#include "avsd_api.h" +#include "m2vd_api.h" +#include "mpg4d_api.h" +#include "vp8d_api.h" +#include "jpegd_api.h" +// for test and demo +#include "dummy_dec_api.h" + +/* + * all decoder static register here + */ +static const ParserApi *parsers[] = { +#if HAVE_AVSD + &api_avsd_parser, +#endif + &api_h263d_parser, + &api_h264d_parser, + &api_h265d_parser, + &api_m2vd_parser, + &api_mpg4d_parser, + &api_vp8d_parser, + &api_vp9d_parser, + &api_jpegd_parser, + &dummy_dec_parser, +}; + +typedef struct ParserImpl_t { + ParserCfg cfg; + + const ParserApi *api; + void *ctx; +} ParserImpl; + +MPP_RET parser_init(Parser *prs, ParserCfg *cfg) +{ + if (NULL == prs || NULL == cfg) { + mpp_err_f("found NULL input parser %p config %p\n", prs, cfg); + return MPP_ERR_NULL_PTR; + } + + *prs = NULL; + + RK_U32 i; + for (i = 0; i < MPP_ARRAY_ELEMS(parsers); i++) { + const ParserApi *api = parsers[i]; + if (cfg->coding == api->coding) { + ParserImpl *p = mpp_calloc(ParserImpl, 1); + void *ctx = mpp_calloc_size(void, api->ctx_size); + if (NULL == ctx || NULL == p) { + mpp_err_f("failed to alloc parser context\n"); + mpp_free(p); + mpp_free(ctx); + return MPP_ERR_MALLOC; + } + + MPP_RET ret = api->init(ctx, cfg); + if (MPP_OK != ret) { + mpp_err_f("failed to init parser\n"); + mpp_free(p); + mpp_free(ctx); + return ret; + } + + p->cfg = *cfg; + p->api = api; + p->ctx = ctx; + *prs = p; + return MPP_OK; + } + } + return MPP_NOK; +} + +MPP_RET parser_deinit(Parser prs) +{ + if (NULL == prs) { + mpp_err_f("found NULL input\n"); + return MPP_ERR_NULL_PTR; + } + + ParserImpl *p = (ParserImpl *)prs; + if (p->api->deinit) + p->api->deinit(p->ctx); + + mpp_free(p->ctx); + mpp_free(p); + return MPP_OK; +} + +MPP_RET parser_prepare(Parser prs, MppPacket pkt, HalDecTask *task) +{ + if (NULL == prs || NULL == pkt) { + mpp_err_f("found NULL input\n"); + return MPP_ERR_NULL_PTR; + } + + ParserImpl *p = (ParserImpl *)prs; + if (!p->api->prepare) + return MPP_OK; + + return p->api->prepare(p->ctx, pkt, task); +} + +MPP_RET parser_parse(Parser prs, HalDecTask *task) +{ + if (NULL == prs || NULL == task) { + mpp_err_f("found NULL input\n"); + return MPP_ERR_NULL_PTR; + } + + ParserImpl *p = (ParserImpl *)prs; + if (!p->api->parse) + return MPP_OK; + + return p->api->parse(p->ctx, task); +} + +MPP_RET hal_callback(void *prs, void *err_info) +{ + if (NULL == prs) { + mpp_err_f("found NULL input\n"); + return MPP_ERR_NULL_PTR; + } + ParserImpl *p = (ParserImpl *)prs; + if (!p->api->callback) + return MPP_OK; + return p->api->callback(p->ctx, err_info); +} +MPP_RET parser_reset(Parser prs) +{ + if (NULL == prs) { + mpp_err_f("found NULL input\n"); + return MPP_ERR_NULL_PTR; + } + + ParserImpl *p = (ParserImpl *)prs; + if (!p->api->reset) + return MPP_OK; + + return p->api->reset(p->ctx); +} + +MPP_RET parser_flush(Parser prs) +{ + if (NULL == prs) { + mpp_err_f("found NULL input\n"); + return MPP_ERR_NULL_PTR; + } + + ParserImpl *p = (ParserImpl *)prs; + if (!p->api->flush) + return MPP_OK; + + return p->api->flush(p->ctx); +} + +MPP_RET parser_control(Parser prs, RK_S32 cmd, void *para) +{ + if (NULL == prs) { + mpp_err_f("found NULL input\n"); + return MPP_ERR_NULL_PTR; + } + + ParserImpl *p = (ParserImpl *)prs; + if (!p->api->control) + return MPP_OK; + + return p->api->control(p->ctx, cmd, para); +} + diff --git a/mpp/common/dxva_syntax.h b/mpp/common/dxva_syntax.h index c48c8687..828e1bc8 100644 --- a/mpp/common/dxva_syntax.h +++ b/mpp/common/dxva_syntax.h @@ -1,70 +1,70 @@ -/* -* -* Copyright 2015 Rockchip Electronics Co. LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#ifndef __DXVA_SYNTAX_H__ -#define __DXVA_SYNTAX_H__ - -#include "rk_type.h" - -enum __MIDL___MIDL_itf_dxva2api_0000_0000_0012 { - DXVA2_PictureParametersBufferType = 0, - DXVA2_MacroBlockControlBufferType = 1, - DXVA2_ResidualDifferenceBufferType = 2, - DXVA2_DeblockingControlBufferType = 3, - DXVA2_InverseQuantizationMatrixBufferType = 4, - DXVA2_SliceControlBufferType = 5, - DXVA2_BitStreamDateBufferType = 6, - DXVA2_MotionVectorBuffer = 7, - DXVA2_FilmGrainBuffer = 8 -}; - -typedef struct _DXVA2_ConfigPictureDecode { - //GUID guidConfigBitstreamEncryption; - //GUID guidConfigMBcontrolEncryption; - //GUID guidConfigResidDiffEncryption; - RK_U32 ConfigBitstreamRaw; - //UINT ConfigMBcontrolRasterOrder; - //UINT ConfigResidDiffHost; - //UINT ConfigSpatialResid8; - //UINT ConfigResid8Subtraction; - //UINT ConfigSpatialHost8or9Clipping; - //UINT ConfigSpatialResidInterleaved; - //UINT ConfigIntraResidUnsigned; - //UINT ConfigResidDiffAccelerator; - //UINT ConfigHostInverseScan; - //UINT ConfigSpecificIDCT; - //UINT Config4GroupedCoefs; - //USHORT ConfigMinRenderTargetBuffCount; - //USHORT ConfigDecoderSpecific; -} DXVA2_ConfigPictureDecode; - -typedef struct _DXVA2_DecodeBufferDesc { - RK_U32 CompressedBufferType; - RK_U32 BufferIndex; - RK_U32 DataOffset; - RK_U32 DataSize; - RK_U32 FirstMBaddress; - RK_U32 NumMBsInBuffer; - RK_U32 Width; - RK_U32 Height; - RK_U32 Stride; - RK_U32 ReservedBits; - void *pvPVPState; -} DXVA2_DecodeBufferDesc; - -#endif /*__DXVA_SYNTAX_H__*/ - +/* +* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef __DXVA_SYNTAX_H__ +#define __DXVA_SYNTAX_H__ + +#include "rk_type.h" + +enum __MIDL___MIDL_itf_dxva2api_0000_0000_0012 { + DXVA2_PictureParametersBufferType = 0, + DXVA2_MacroBlockControlBufferType = 1, + DXVA2_ResidualDifferenceBufferType = 2, + DXVA2_DeblockingControlBufferType = 3, + DXVA2_InverseQuantizationMatrixBufferType = 4, + DXVA2_SliceControlBufferType = 5, + DXVA2_BitStreamDateBufferType = 6, + DXVA2_MotionVectorBuffer = 7, + DXVA2_FilmGrainBuffer = 8 +}; + +typedef struct _DXVA2_ConfigPictureDecode { + //GUID guidConfigBitstreamEncryption; + //GUID guidConfigMBcontrolEncryption; + //GUID guidConfigResidDiffEncryption; + RK_U32 ConfigBitstreamRaw; + //UINT ConfigMBcontrolRasterOrder; + //UINT ConfigResidDiffHost; + //UINT ConfigSpatialResid8; + //UINT ConfigResid8Subtraction; + //UINT ConfigSpatialHost8or9Clipping; + //UINT ConfigSpatialResidInterleaved; + //UINT ConfigIntraResidUnsigned; + //UINT ConfigResidDiffAccelerator; + //UINT ConfigHostInverseScan; + //UINT ConfigSpecificIDCT; + //UINT Config4GroupedCoefs; + //USHORT ConfigMinRenderTargetBuffCount; + //USHORT ConfigDecoderSpecific; +} DXVA2_ConfigPictureDecode; + +typedef struct _DXVA2_DecodeBufferDesc { + RK_U32 CompressedBufferType; + RK_U32 BufferIndex; + RK_U32 DataOffset; + RK_U32 DataSize; + RK_U32 FirstMBaddress; + RK_U32 NumMBsInBuffer; + RK_U32 Width; + RK_U32 Height; + RK_U32 Stride; + RK_U32 ReservedBits; + void *pvPVPState; +} DXVA2_DecodeBufferDesc; + +#endif /*__DXVA_SYNTAX_H__*/ + diff --git a/mpp/common/h263d_syntax.h b/mpp/common/h263d_syntax.h index 62252f39..0b13ff38 100644 --- a/mpp/common/h263d_syntax.h +++ b/mpp/common/h263d_syntax.h @@ -1,98 +1,98 @@ -/* - * - * Copyright 2010 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __H263D_SYNTAX__ -#define __H263D_SYNTAX__ - -#include "dxva_syntax.h" - -/*video vop specific*/ -typedef enum { - H263_INVALID_VOP = -1, - H263_I_VOP = 0, - H263_P_VOP = 1, -} H263VOPType; - -/* H263PT2 Picture Parameter structure */ -typedef struct _DXVA_PicParams_H263 { - RK_U8 short_video_header; - RK_U8 vop_coding_type; - RK_U8 vop_quant; - RK_U16 wDecodedPictureIndex; - RK_U16 wDeblockedPictureIndex; - RK_U16 wForwardRefPictureIndex; - RK_U16 wBackwardRefPictureIndex; - RK_U16 vop_time_increment_resolution; - RK_U32 TRB[2]; - RK_U32 TRD[2]; - - union { - struct { - RK_U16 unPicPostProc : 2; - RK_U16 interlaced : 1; - RK_U16 quant_type : 1; - RK_U16 quarter_sample : 1; - RK_U16 resync_marker_disable : 1; - RK_U16 data_partitioned : 1; - RK_U16 reversible_vlc : 1; - RK_U16 reduced_resolution_vop_enable : 1; - RK_U16 vop_coded : 1; - RK_U16 vop_rounding_type : 1; - RK_U16 intra_dc_vlc_thr : 3; - RK_U16 top_field_first : 1; - RK_U16 alternate_vertical_scan_flag : 1; - }; - RK_U16 wPicFlagBitFields; - }; - RK_U8 profile_and_level_indication; - RK_U8 video_object_layer_verid; - RK_U16 vop_width; - RK_U16 vop_height; - union { - struct { - RK_U16 sprite_enable : 2; - RK_U16 no_of_sprite_warping_points : 6; - RK_U16 sprite_warping_accuracy : 2; - }; - RK_U16 wSpriteBitFields; - }; - RK_S16 warping_mv[4][2]; - union { - struct { - RK_U8 vop_fcode_forward : 3; - RK_U8 vop_fcode_backward : 3; - }; - RK_U8 wFcodeBitFields; - }; - RK_U16 StatusReportFeedbackNumber; - RK_U16 Reserved16BitsA; - RK_U16 Reserved16BitsB; - - // FIXME: added for rockchip hardware information - RK_U32 prev_coding_type; - RK_U32 header_bits; -} DXVA_PicParams_H263, *LPDXVA_PicParams_H263; - -typedef struct h263d_dxva2_picture_context { - DXVA_PicParams_H263 pp; - - // pointer and storage for buffer descriptor - DXVA2_DecodeBufferDesc *data[2]; - DXVA2_DecodeBufferDesc desc[2]; -} h263d_dxva2_picture_context_t; - -#endif /*__H263D_SYNTAX__*/ +/* + * + * Copyright 2010 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __H263D_SYNTAX__ +#define __H263D_SYNTAX__ + +#include "dxva_syntax.h" + +/*video vop specific*/ +typedef enum { + H263_INVALID_VOP = -1, + H263_I_VOP = 0, + H263_P_VOP = 1, +} H263VOPType; + +/* H263PT2 Picture Parameter structure */ +typedef struct _DXVA_PicParams_H263 { + RK_U8 short_video_header; + RK_U8 vop_coding_type; + RK_U8 vop_quant; + RK_U16 wDecodedPictureIndex; + RK_U16 wDeblockedPictureIndex; + RK_U16 wForwardRefPictureIndex; + RK_U16 wBackwardRefPictureIndex; + RK_U16 vop_time_increment_resolution; + RK_U32 TRB[2]; + RK_U32 TRD[2]; + + union { + struct { + RK_U16 unPicPostProc : 2; + RK_U16 interlaced : 1; + RK_U16 quant_type : 1; + RK_U16 quarter_sample : 1; + RK_U16 resync_marker_disable : 1; + RK_U16 data_partitioned : 1; + RK_U16 reversible_vlc : 1; + RK_U16 reduced_resolution_vop_enable : 1; + RK_U16 vop_coded : 1; + RK_U16 vop_rounding_type : 1; + RK_U16 intra_dc_vlc_thr : 3; + RK_U16 top_field_first : 1; + RK_U16 alternate_vertical_scan_flag : 1; + }; + RK_U16 wPicFlagBitFields; + }; + RK_U8 profile_and_level_indication; + RK_U8 video_object_layer_verid; + RK_U16 vop_width; + RK_U16 vop_height; + union { + struct { + RK_U16 sprite_enable : 2; + RK_U16 no_of_sprite_warping_points : 6; + RK_U16 sprite_warping_accuracy : 2; + }; + RK_U16 wSpriteBitFields; + }; + RK_S16 warping_mv[4][2]; + union { + struct { + RK_U8 vop_fcode_forward : 3; + RK_U8 vop_fcode_backward : 3; + }; + RK_U8 wFcodeBitFields; + }; + RK_U16 StatusReportFeedbackNumber; + RK_U16 Reserved16BitsA; + RK_U16 Reserved16BitsB; + + // FIXME: added for rockchip hardware information + RK_U32 prev_coding_type; + RK_U32 header_bits; +} DXVA_PicParams_H263, *LPDXVA_PicParams_H263; + +typedef struct h263d_dxva2_picture_context { + DXVA_PicParams_H263 pp; + + // pointer and storage for buffer descriptor + DXVA2_DecodeBufferDesc *data[2]; + DXVA2_DecodeBufferDesc desc[2]; +} h263d_dxva2_picture_context_t; + +#endif /*__H263D_SYNTAX__*/ diff --git a/mpp/common/h264_syntax.h b/mpp/common/h264_syntax.h index b0f6b28a..8b8c9968 100644 --- a/mpp/common/h264_syntax.h +++ b/mpp/common/h264_syntax.h @@ -1,94 +1,94 @@ -/* -* -* Copyright 2015 Rockchip Electronics Co. LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - - -#ifndef __H264_SYNTAX_H__ -#define __H264_SYNTAX_H__ - -/* H.264/AVC-specific definition */ - -//!< define -#define MAXSPS 32 -#define MAXPPS 256 - -//!< AVC Profile IDC definitions -typedef enum h264e_profile_t { - H264_PROFILE_FREXT_CAVLC444 = 44, //!< YUV 4:4:4/14 "CAVLC 4:4:4" - H264_PROFILE_BASELINE = 66, //!< YUV 4:2:0/8 "Baseline" - H264_PROFILE_MAIN = 77, //!< YUV 4:2:0/8 "Main" - H264_PROFILE_EXTENDED = 88, //!< YUV 4:2:0/8 "Extended" - H264_PROFILE_HIGH = 100, //!< YUV 4:2:0/8 "High" - H264_PROFILE_HIGH10 = 110, //!< YUV 4:2:0/10 "High 10" - H264_PROFILE_HIGH422 = 122, //!< YUV 4:2:2/10 "High 4:2:2" - H264_PROFILE_HIGH444 = 244, //!< YUV 4:4:4/14 "High 4:4:4" - H264_PROFILE_MVC_HIGH = 118, //!< YUV 4:2:0/8 "Multiview High" - H264_PROFILE_STEREO_HIGH = 128 //!< YUV 4:2:0/8 "Stereo High" -} H264Profile; - -//!< AVC Level IDC definitions -typedef enum { - H264_LEVEL_1_0 = 10, - H264_LEVEL_1_b = 99, - H264_LEVEL_1_1 = 11, - H264_LEVEL_1_2 = 12, - H264_LEVEL_1_3 = 13, - H264_LEVEL_2_0 = 20, - H264_LEVEL_2_1 = 21, - H264_LEVEL_2_2 = 22, - H264_LEVEL_3_0 = 30, - H264_LEVEL_3_1 = 31, - H264_LEVEL_3_2 = 32, - H264_LEVEL_4_0 = 40, - H264_LEVEL_4_1 = 41, - H264_LEVEL_4_2 = 42, - H264_LEVEL_5_0 = 50, - H264_LEVEL_5_1 = 51, -} H264Level; - -//!< values for nalu_type -typedef enum { - NALU_TYPE_NULL = 0, - NALU_TYPE_SLICE = 1, - NALU_TYPE_DPA = 2, - NALU_TYPE_DPB = 3, - NALU_TYPE_DPC = 4, - NALU_TYPE_IDR = 5, - NALU_TYPE_SEI = 6, - NALU_TYPE_SPS = 7, - NALU_TYPE_PPS = 8, - NALU_TYPE_AUD = 9, // Access Unit Delimiter - NALU_TYPE_EOSEQ = 10, // end of sequence - NALU_TYPE_EOSTREAM = 11, // end of stream - NALU_TYPE_FILL = 12, - NALU_TYPE_SPSEXT = 13, - NALU_TYPE_PREFIX = 14, // prefix - NALU_TYPE_SUB_SPS = 15, - NALU_TYPE_SLICE_AUX = 19, - NALU_TYPE_SLC_EXT = 20, // slice extensive - NALU_TYPE_VDRD = 24 // View and Dependency Representation Delimiter NAL Unit -} Nalu_type; - -//!< values for nal_ref_idc -typedef enum { - NALU_PRIORITY_HIGHEST = 3, - NALU_PRIORITY_HIGH = 2, - NALU_PRIORITY_LOW = 1, - NALU_PRIORITY_DISPOSABLE = 0 -} NalRefIdc_type; - -#endif /*__H264_SYNTAX_H__*/ - +/* +* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +#ifndef __H264_SYNTAX_H__ +#define __H264_SYNTAX_H__ + +/* H.264/AVC-specific definition */ + +//!< define +#define MAXSPS 32 +#define MAXPPS 256 + +//!< AVC Profile IDC definitions +typedef enum h264e_profile_t { + H264_PROFILE_FREXT_CAVLC444 = 44, //!< YUV 4:4:4/14 "CAVLC 4:4:4" + H264_PROFILE_BASELINE = 66, //!< YUV 4:2:0/8 "Baseline" + H264_PROFILE_MAIN = 77, //!< YUV 4:2:0/8 "Main" + H264_PROFILE_EXTENDED = 88, //!< YUV 4:2:0/8 "Extended" + H264_PROFILE_HIGH = 100, //!< YUV 4:2:0/8 "High" + H264_PROFILE_HIGH10 = 110, //!< YUV 4:2:0/10 "High 10" + H264_PROFILE_HIGH422 = 122, //!< YUV 4:2:2/10 "High 4:2:2" + H264_PROFILE_HIGH444 = 244, //!< YUV 4:4:4/14 "High 4:4:4" + H264_PROFILE_MVC_HIGH = 118, //!< YUV 4:2:0/8 "Multiview High" + H264_PROFILE_STEREO_HIGH = 128 //!< YUV 4:2:0/8 "Stereo High" +} H264Profile; + +//!< AVC Level IDC definitions +typedef enum { + H264_LEVEL_1_0 = 10, + H264_LEVEL_1_b = 99, + H264_LEVEL_1_1 = 11, + H264_LEVEL_1_2 = 12, + H264_LEVEL_1_3 = 13, + H264_LEVEL_2_0 = 20, + H264_LEVEL_2_1 = 21, + H264_LEVEL_2_2 = 22, + H264_LEVEL_3_0 = 30, + H264_LEVEL_3_1 = 31, + H264_LEVEL_3_2 = 32, + H264_LEVEL_4_0 = 40, + H264_LEVEL_4_1 = 41, + H264_LEVEL_4_2 = 42, + H264_LEVEL_5_0 = 50, + H264_LEVEL_5_1 = 51, +} H264Level; + +//!< values for nalu_type +typedef enum { + NALU_TYPE_NULL = 0, + NALU_TYPE_SLICE = 1, + NALU_TYPE_DPA = 2, + NALU_TYPE_DPB = 3, + NALU_TYPE_DPC = 4, + NALU_TYPE_IDR = 5, + NALU_TYPE_SEI = 6, + NALU_TYPE_SPS = 7, + NALU_TYPE_PPS = 8, + NALU_TYPE_AUD = 9, // Access Unit Delimiter + NALU_TYPE_EOSEQ = 10, // end of sequence + NALU_TYPE_EOSTREAM = 11, // end of stream + NALU_TYPE_FILL = 12, + NALU_TYPE_SPSEXT = 13, + NALU_TYPE_PREFIX = 14, // prefix + NALU_TYPE_SUB_SPS = 15, + NALU_TYPE_SLICE_AUX = 19, + NALU_TYPE_SLC_EXT = 20, // slice extensive + NALU_TYPE_VDRD = 24 // View and Dependency Representation Delimiter NAL Unit +} Nalu_type; + +//!< values for nal_ref_idc +typedef enum { + NALU_PRIORITY_HIGHEST = 3, + NALU_PRIORITY_HIGH = 2, + NALU_PRIORITY_LOW = 1, + NALU_PRIORITY_DISPOSABLE = 0 +} NalRefIdc_type; + +#endif /*__H264_SYNTAX_H__*/ + diff --git a/mpp/common/h264d_log.h b/mpp/common/h264d_log.h index 1f715d75..8a24a225 100644 --- a/mpp/common/h264d_log.h +++ b/mpp/common/h264d_log.h @@ -1,292 +1,292 @@ -/* -* -* Copyright 2015 Rockchip Electronics Co. LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -#ifndef __H264D_LOG_H__ -#define __H264D_LOG_H__ - -#include -#include - -#include "rk_type.h" -#include "mpp_err.h" -#include "mpp_log.h" -#include "mpp_bitread.h" - - -#define H264D_DBG_ERROR (0x00000001) -#define H264D_DBG_ASSERT (0x00000002) -#define H264D_DBG_WARNNING (0x00000004) -#define H264D_DBG_LOG (0x00000008) - -#define H264D_DBG_INPUT (0x00000010) //!< input packet -#define H264D_DBG_PPS_SPS (0x00000020) -#define H264D_DBG_LOOP_STATE (0x00000040) -#define H264D_DBG_PARSE_NALU (0x00000080) - -#define H264D_DBG_DPB_INFO (0x00000100) //!< size, -#define H264D_DBG_DPB_MALLIC (0x00000200) //!< malloc - - -#define H264D_DBG_DPB_REF_ERR (0x00001000) -#define H264D_DBG_SLOT_FLUSH (0x00002000) //!< dpb buffer slot remain -#define H264D_DBG_SEI (0x00004000) -#define H264D_DBG_CALLBACK (0x00008000) - -#define H264D_DBG_WRITE_ES_EN (0x00010000) //!< write input ts stream -#define H264D_DBG_FIELD_PAIRED (0x00020000) -#define H264D_DBG_DISCONTINUOUS (0x00040000) -#define H264D_DBG_ERR_DUMP (0x00080000) -//!< hal marco -#define H264D_DBG_GEN_REGS (0x01000000) -#define H264D_DBG_RET_REGS (0x02000000) -#define H264D_DBG_DECOUT_INFO (0x04000000) - -extern RK_U32 rkv_h264d_parse_debug; - -extern RK_U32 rkv_h264d_hal_debug; - - -#define H264D_DBG(level, fmt, ...)\ -do {\ - if (level & rkv_h264d_parse_debug)\ - { mpp_log(fmt, ## __VA_ARGS__);}\ -} while (0) - - -#define H264D_ERR(fmt, ...)\ -do {\ - if (H264D_DBG_ERROR & rkv_h264d_parse_debug)\ - { mpp_log(fmt, ## __VA_ARGS__); }\ -} while (0) - -#define ASSERT(val)\ -do {\ - if (H264D_DBG_ASSERT & rkv_h264d_parse_debug)\ - { mpp_assert(val); }\ -} while (0) - -#define H264D_WARNNING(fmt, ...)\ -do {\ - if (H264D_DBG_WARNNING & rkv_h264d_parse_debug)\ - { mpp_log(fmt, ## __VA_ARGS__); }\ -} while (0) - -#define H264D_LOG(fmt, ...)\ -do {\ - if (H264D_DBG_LOG & rkv_h264d_parse_debug)\ - { mpp_log(fmt, ## __VA_ARGS__); }\ -} while (0) - - - -#define __DEBUG_EN 1 - - -//!< get bit value -#define GetBitVal(val, pos) ( ( (val)>>(pos) ) & 0x1 & (val) ) - - -typedef enum { - LOG_LEVEL_SILENT = 0, - LOG_LEVEL_FATAL , - LOG_LEVEL_ERROR , - LOG_LEVEL_WARNNING , - LOG_LEVEL_INFO , - LOG_LEVEL_TRACE , - LOG_LEVEL_MAX , -} LogLevel_type; - -typedef enum { - LOG_DEBUG = 0, - LOG_FPGA , - LOG_PRINT , - LOG_WRITE , - RUN_PARSE , - RUN_HAL , - LOG_READ_NALU , - LOG_READ_SPS , - LOG_READ_SUBSPS , - LOG_READ_PPS , - LOG_READ_SLICE , - LOG_WRITE_SPSPPS , - LOG_WRITE_RPS , - LOG_WRITE_SCANLIST , - LOG_WRITE_STEAM , - LOG_WRITE_REG , - LOG_MAX , -} LogCtrl_type; - -typedef struct log_flag_t { - RK_U8 debug_en; - RK_U8 print_en; - RK_U8 write_en; - RK_U32 level; -} LogFlag_t; - -typedef struct log_ctx_t { - const char *tag; - LogFlag_t *flag; - FILE *fp; -} LogCtx_t; - -typedef struct log_env_str_t { - char *help; - char *show; - char *ctrl; - char *level; - char *outpath; - char *cmppath; - char *decframe; - char *begframe; - char *endframe; -} LogEnvStr_t; - - -typedef struct log_env_ctx_t { - RK_U32 help; - RK_U32 show; - RK_U32 ctrl; - RK_U32 level; - RK_U32 decframe; - RK_U32 begframe; - RK_U32 endframe; - char *outpath; - //!< files - FILE *fp_driver; - FILE *fp_syn_parse; - FILE *fp_syn_hal; - FILE *fp_run_parse; - FILE *fp_run_hal; - -} LogEnv_t; - -typedef struct h264d_logctx_t { - LogEnv_t env; - LogFlag_t log_flag; - LogCtx_t *parr[LOG_MAX]; -} H264dLogCtx_t; - -//!< write log -#define LogEnable(ctx, loglevel) ( ctx && ((LogCtx_t*)ctx)->flag->debug_en && (((LogCtx_t*)ctx)->flag->level & loglevel) ) - -#define LogTrace(ctx, ...)\ - do{ if(LogEnable(ctx, LOG_LEVEL_TRACE)) {\ - writelog(ctx, "TRACE", __FILE__, __LINE__, ##__VA_ARGS__);\ - } }while (0) -#define LogInfo(ctx, ...)\ - do{ if(LogEnable(ctx, LOG_LEVEL_INFO)) {\ - writelog(ctx, "INFO",__FILE__, __LINE__, ##__VA_ARGS__);\ - } }while (0) - -#define LogWarnning(ctx, ...)\ - do{ if(LogEnable(ctx, LOG_LEVEL_WARNNING)) {\ - writelog(ctx, "WARNNING",__FILE__, __LINE__, ##__VA_ARGS__);\ - } }while (0) - -#define LogError(ctx, ...)\ - do{ if(LogEnable(ctx, LOG_LEVEL_ERROR)) {\ - writelog(ctx, "ERROR",__FILE__, __LINE__, ##__VA_ARGS__);\ - ASSERT(0);\ - } }while (0) -#define LogFatal(ctx, ...)\ - do{ if(LogEnable(ctx, LOG_LEVEL_ERROR)) {\ - writelog(ctx, "FATAL", __FILE__, __LINE__, ##__VA_ARGS__);\ - ASSERT(0);\ - } }while (0) - -#define FunctionIn(ctx)\ - do{ if(LogEnable(ctx, LOG_LEVEL_TRACE)) {\ - writelog(ctx, "FunIn",__FILE__, __LINE__, __FUNCTION__);\ - } } while (0) - -#define FunctionOut(ctx)\ - do{if(LogEnable(ctx, LOG_LEVEL_TRACE)) {\ - writelog(ctx, "FunOut", __FILE__, __LINE__, __FUNCTION__);\ - } } while (0) - -//!< vaule check -#define VAL_CHECK(ret, val, ...)\ - do{ if(!(val)){\ - ret = MPP_ERR_VALUE;\ - H264D_WARNNING("value error(%d).\n", __LINE__);\ - goto __FAILED;\ - } } while (0) -//!< memory malloc check -#define MEM_CHECK(ret, val, ...)\ - do{ if(!(val)) {\ - ret = MPP_ERR_MALLOC;\ - H264D_ERR("malloc buffer error(%d).\n", __LINE__);\ - ASSERT(0); goto __FAILED;\ - } } while (0) -//!< file check -#define FLE_CHECK(ret, val, ...)\ - do{ if(!(val)) {\ - ret = MPP_ERR_OPEN_FILE;\ - H264D_WARNNING("open file error(%d).\n", __LINE__);\ - ASSERT(0); goto __FAILED;\ - } } while (0) - -//!< input check -#define INP_CHECK(ret, val, ...)\ - do{ if((val)) {\ - ret = MPP_ERR_INIT;\ - H264D_WARNNING("input empty(%d).\n", __LINE__);\ - goto __RETURN;\ - } } while (0) -//!< function return check -#define FUN_CHECK(val)\ - do{ if((val) < 0) {\ - H264D_WARNNING("Function error(%d).\n", __LINE__); \ - goto __FAILED;\ - } } while (0) - -#ifdef ANDROID -#define FPRINT(fp, ...) //{ { mpp_log(__VA_ARGS__); } if (fp) { fprintf(fp, ##__VA_ARGS__); fflush(fp);} } -#else -#define FPRINT(fp, ...) { if (fp) { fprintf(fp, ##__VA_ARGS__); fflush(fp);} } -#endif - -#define FCLOSE(fp) do{ if(fp) fclose(fp); fp = NULL; } while (0) - -extern RK_U32 g_nalu_cnt0; -extern RK_U32 g_nalu_cnt1; -extern RK_S32 g_max_bytes; -extern RK_U32 g_max_slice_data; -extern FILE *g_debug_file0; -extern FILE *g_debug_file1; -#ifdef __cplusplus -extern "C" { -#endif - -extern const LogEnvStr_t logenv_name; -extern const char *logctrl_name[LOG_MAX]; -extern const char *loglevel_name[LOG_LEVEL_MAX]; - -void print_env_help(LogEnv_t *env); -void show_env_flags(LogEnv_t *env); - -MPP_RET get_logenv(LogEnv_t *env); -MPP_RET explain_ctrl_flag(RK_U32 ctrl_val, LogFlag_t *pflag); - -void set_log_outpath(LogEnv_t *env); -void set_bitread_logctx(BitReadCtx_t *bitctx, LogCtx_t *p_ctx); -void writelog(void *ctx, ...); - -#ifdef __cplusplus -} -#endif - +/* +* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#ifndef __H264D_LOG_H__ +#define __H264D_LOG_H__ + +#include +#include + +#include "rk_type.h" +#include "mpp_err.h" +#include "mpp_log.h" +#include "mpp_bitread.h" + + +#define H264D_DBG_ERROR (0x00000001) +#define H264D_DBG_ASSERT (0x00000002) +#define H264D_DBG_WARNNING (0x00000004) +#define H264D_DBG_LOG (0x00000008) + +#define H264D_DBG_INPUT (0x00000010) //!< input packet +#define H264D_DBG_PPS_SPS (0x00000020) +#define H264D_DBG_LOOP_STATE (0x00000040) +#define H264D_DBG_PARSE_NALU (0x00000080) + +#define H264D_DBG_DPB_INFO (0x00000100) //!< size, +#define H264D_DBG_DPB_MALLIC (0x00000200) //!< malloc + + +#define H264D_DBG_DPB_REF_ERR (0x00001000) +#define H264D_DBG_SLOT_FLUSH (0x00002000) //!< dpb buffer slot remain +#define H264D_DBG_SEI (0x00004000) +#define H264D_DBG_CALLBACK (0x00008000) + +#define H264D_DBG_WRITE_ES_EN (0x00010000) //!< write input ts stream +#define H264D_DBG_FIELD_PAIRED (0x00020000) +#define H264D_DBG_DISCONTINUOUS (0x00040000) +#define H264D_DBG_ERR_DUMP (0x00080000) +//!< hal marco +#define H264D_DBG_GEN_REGS (0x01000000) +#define H264D_DBG_RET_REGS (0x02000000) +#define H264D_DBG_DECOUT_INFO (0x04000000) + +extern RK_U32 rkv_h264d_parse_debug; + +extern RK_U32 rkv_h264d_hal_debug; + + +#define H264D_DBG(level, fmt, ...)\ +do {\ + if (level & rkv_h264d_parse_debug)\ + { mpp_log(fmt, ## __VA_ARGS__);}\ +} while (0) + + +#define H264D_ERR(fmt, ...)\ +do {\ + if (H264D_DBG_ERROR & rkv_h264d_parse_debug)\ + { mpp_log(fmt, ## __VA_ARGS__); }\ +} while (0) + +#define ASSERT(val)\ +do {\ + if (H264D_DBG_ASSERT & rkv_h264d_parse_debug)\ + { mpp_assert(val); }\ +} while (0) + +#define H264D_WARNNING(fmt, ...)\ +do {\ + if (H264D_DBG_WARNNING & rkv_h264d_parse_debug)\ + { mpp_log(fmt, ## __VA_ARGS__); }\ +} while (0) + +#define H264D_LOG(fmt, ...)\ +do {\ + if (H264D_DBG_LOG & rkv_h264d_parse_debug)\ + { mpp_log(fmt, ## __VA_ARGS__); }\ +} while (0) + + + +#define __DEBUG_EN 1 + + +//!< get bit value +#define GetBitVal(val, pos) ( ( (val)>>(pos) ) & 0x1 & (val) ) + + +typedef enum { + LOG_LEVEL_SILENT = 0, + LOG_LEVEL_FATAL , + LOG_LEVEL_ERROR , + LOG_LEVEL_WARNNING , + LOG_LEVEL_INFO , + LOG_LEVEL_TRACE , + LOG_LEVEL_MAX , +} LogLevel_type; + +typedef enum { + LOG_DEBUG = 0, + LOG_FPGA , + LOG_PRINT , + LOG_WRITE , + RUN_PARSE , + RUN_HAL , + LOG_READ_NALU , + LOG_READ_SPS , + LOG_READ_SUBSPS , + LOG_READ_PPS , + LOG_READ_SLICE , + LOG_WRITE_SPSPPS , + LOG_WRITE_RPS , + LOG_WRITE_SCANLIST , + LOG_WRITE_STEAM , + LOG_WRITE_REG , + LOG_MAX , +} LogCtrl_type; + +typedef struct log_flag_t { + RK_U8 debug_en; + RK_U8 print_en; + RK_U8 write_en; + RK_U32 level; +} LogFlag_t; + +typedef struct log_ctx_t { + const char *tag; + LogFlag_t *flag; + FILE *fp; +} LogCtx_t; + +typedef struct log_env_str_t { + char *help; + char *show; + char *ctrl; + char *level; + char *outpath; + char *cmppath; + char *decframe; + char *begframe; + char *endframe; +} LogEnvStr_t; + + +typedef struct log_env_ctx_t { + RK_U32 help; + RK_U32 show; + RK_U32 ctrl; + RK_U32 level; + RK_U32 decframe; + RK_U32 begframe; + RK_U32 endframe; + char *outpath; + //!< files + FILE *fp_driver; + FILE *fp_syn_parse; + FILE *fp_syn_hal; + FILE *fp_run_parse; + FILE *fp_run_hal; + +} LogEnv_t; + +typedef struct h264d_logctx_t { + LogEnv_t env; + LogFlag_t log_flag; + LogCtx_t *parr[LOG_MAX]; +} H264dLogCtx_t; + +//!< write log +#define LogEnable(ctx, loglevel) ( ctx && ((LogCtx_t*)ctx)->flag->debug_en && (((LogCtx_t*)ctx)->flag->level & loglevel) ) + +#define LogTrace(ctx, ...)\ + do{ if(LogEnable(ctx, LOG_LEVEL_TRACE)) {\ + writelog(ctx, "TRACE", __FILE__, __LINE__, ##__VA_ARGS__);\ + } }while (0) +#define LogInfo(ctx, ...)\ + do{ if(LogEnable(ctx, LOG_LEVEL_INFO)) {\ + writelog(ctx, "INFO",__FILE__, __LINE__, ##__VA_ARGS__);\ + } }while (0) + +#define LogWarnning(ctx, ...)\ + do{ if(LogEnable(ctx, LOG_LEVEL_WARNNING)) {\ + writelog(ctx, "WARNNING",__FILE__, __LINE__, ##__VA_ARGS__);\ + } }while (0) + +#define LogError(ctx, ...)\ + do{ if(LogEnable(ctx, LOG_LEVEL_ERROR)) {\ + writelog(ctx, "ERROR",__FILE__, __LINE__, ##__VA_ARGS__);\ + ASSERT(0);\ + } }while (0) +#define LogFatal(ctx, ...)\ + do{ if(LogEnable(ctx, LOG_LEVEL_ERROR)) {\ + writelog(ctx, "FATAL", __FILE__, __LINE__, ##__VA_ARGS__);\ + ASSERT(0);\ + } }while (0) + +#define FunctionIn(ctx)\ + do{ if(LogEnable(ctx, LOG_LEVEL_TRACE)) {\ + writelog(ctx, "FunIn",__FILE__, __LINE__, __FUNCTION__);\ + } } while (0) + +#define FunctionOut(ctx)\ + do{if(LogEnable(ctx, LOG_LEVEL_TRACE)) {\ + writelog(ctx, "FunOut", __FILE__, __LINE__, __FUNCTION__);\ + } } while (0) + +//!< vaule check +#define VAL_CHECK(ret, val, ...)\ + do{ if(!(val)){\ + ret = MPP_ERR_VALUE;\ + H264D_WARNNING("value error(%d).\n", __LINE__);\ + goto __FAILED;\ + } } while (0) +//!< memory malloc check +#define MEM_CHECK(ret, val, ...)\ + do{ if(!(val)) {\ + ret = MPP_ERR_MALLOC;\ + H264D_ERR("malloc buffer error(%d).\n", __LINE__);\ + ASSERT(0); goto __FAILED;\ + } } while (0) +//!< file check +#define FLE_CHECK(ret, val, ...)\ + do{ if(!(val)) {\ + ret = MPP_ERR_OPEN_FILE;\ + H264D_WARNNING("open file error(%d).\n", __LINE__);\ + ASSERT(0); goto __FAILED;\ + } } while (0) + +//!< input check +#define INP_CHECK(ret, val, ...)\ + do{ if((val)) {\ + ret = MPP_ERR_INIT;\ + H264D_WARNNING("input empty(%d).\n", __LINE__);\ + goto __RETURN;\ + } } while (0) +//!< function return check +#define FUN_CHECK(val)\ + do{ if((val) < 0) {\ + H264D_WARNNING("Function error(%d).\n", __LINE__); \ + goto __FAILED;\ + } } while (0) + +#ifdef ANDROID +#define FPRINT(fp, ...) //{ { mpp_log(__VA_ARGS__); } if (fp) { fprintf(fp, ##__VA_ARGS__); fflush(fp);} } +#else +#define FPRINT(fp, ...) { if (fp) { fprintf(fp, ##__VA_ARGS__); fflush(fp);} } +#endif + +#define FCLOSE(fp) do{ if(fp) fclose(fp); fp = NULL; } while (0) + +extern RK_U32 g_nalu_cnt0; +extern RK_U32 g_nalu_cnt1; +extern RK_S32 g_max_bytes; +extern RK_U32 g_max_slice_data; +extern FILE *g_debug_file0; +extern FILE *g_debug_file1; +#ifdef __cplusplus +extern "C" { +#endif + +extern const LogEnvStr_t logenv_name; +extern const char *logctrl_name[LOG_MAX]; +extern const char *loglevel_name[LOG_LEVEL_MAX]; + +void print_env_help(LogEnv_t *env); +void show_env_flags(LogEnv_t *env); + +MPP_RET get_logenv(LogEnv_t *env); +MPP_RET explain_ctrl_flag(RK_U32 ctrl_val, LogFlag_t *pflag); + +void set_log_outpath(LogEnv_t *env); +void set_bitread_logctx(BitReadCtx_t *bitctx, LogCtx_t *p_ctx); +void writelog(void *ctx, ...); + +#ifdef __cplusplus +} +#endif + #endif /* __H264D_LOG_H__ */ \ No newline at end of file diff --git a/mpp/common/h264d_syntax.h b/mpp/common/h264d_syntax.h index 4f0e1162..eece4ce2 100644 --- a/mpp/common/h264d_syntax.h +++ b/mpp/common/h264d_syntax.h @@ -1,435 +1,435 @@ -/* -* -* Copyright 2015 Rockchip Electronics Co. LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - - -#ifndef __H264D_SYNTAX_H__ -#define __H264D_SYNTAX_H__ - -#include "h264_syntax.h" -#include "dxva_syntax.h" - -/* H.264/AVC-specific structures */ - -/* H.264/AVC picture entry data structure */ -typedef struct _DXVA_PicEntry_H264 { - union { - struct { - RK_U8 Index7Bits : 7; - RK_U8 AssociatedFlag : 1; - }; - RK_U8 bPicEntry; - }; -} DXVA_PicEntry_H264, *LPDXVA_PicEntry_H264; /* 1 byte */ - -/* H.264/AVC picture parameters structure */ -typedef struct _DXVA_PicParams_H264 { - RK_U16 wFrameWidthInMbsMinus1; - RK_U16 wFrameHeightInMbsMinus1; - DXVA_PicEntry_H264 CurrPic; /* flag is bot field flag */ - RK_U8 num_ref_frames; - - union { - struct { - RK_U16 field_pic_flag : 1; - RK_U16 MbaffFrameFlag : 1; - RK_U16 residual_colour_transform_flag : 1; - RK_U16 sp_for_switch_flag : 1; - RK_U16 chroma_format_idc : 2; - RK_U16 RefPicFlag : 1; - RK_U16 constrained_intra_pred_flag : 1; - - RK_U16 weighted_pred_flag : 1; - RK_U16 weighted_bipred_idc : 2; - RK_U16 MbsConsecutiveFlag : 1; - RK_U16 frame_mbs_only_flag : 1; - RK_U16 transform_8x8_mode_flag : 1; - RK_U16 MinLumaBipredSize8x8Flag : 1; - RK_U16 IntraPicFlag : 1; - }; - RK_U16 wBitFields; - }; - RK_U8 bit_depth_luma_minus8; - RK_U8 bit_depth_chroma_minus8; - - RK_U16 Reserved16Bits; - RK_U32 StatusReportFeedbackNumber; - - DXVA_PicEntry_H264 RefFrameList[16]; /* flag LT */ - RK_S32 CurrFieldOrderCnt[2]; - RK_S32 FieldOrderCntList[16][2]; - - RK_S8 pic_init_qs_minus26; - RK_S8 chroma_qp_index_offset; /* also used for QScb */ - RK_S8 second_chroma_qp_index_offset; /* also for QScr */ - RK_U8 ContinuationFlag; - - /* remainder for parsing */ - RK_S8 pic_init_qp_minus26; - RK_U8 num_ref_idx_l0_active_minus1; - RK_U8 num_ref_idx_l1_active_minus1; - RK_U8 Reserved8BitsA; - - RK_U16 FrameNumList[16]; - RK_U32 UsedForReferenceFlags; - RK_U16 NonExistingFrameFlags; - RK_U16 frame_num; - - RK_U8 log2_max_frame_num_minus4; - RK_U8 pic_order_cnt_type; - RK_U8 log2_max_pic_order_cnt_lsb_minus4; - RK_U8 delta_pic_order_always_zero_flag; - - RK_U8 direct_8x8_inference_flag; - RK_U8 entropy_coding_mode_flag; - RK_U8 pic_order_present_flag; - RK_U8 num_slice_groups_minus1; - - RK_U8 slice_group_map_type; - RK_U8 deblocking_filter_control_present_flag; - RK_U8 redundant_pic_cnt_present_flag; - RK_U8 Reserved8BitsB; - - RK_U16 slice_group_change_rate_minus1; - - //RK_U8 SliceGroupMap[810]; /* 4b/sgmu, Size BT.601 */ - -} DXVA_PicParams_H264, *LPDXVA_PicParams_H264; - -/* H.264/AVC quantization weighting matrix data structure */ -typedef struct _DXVA_Qmatrix_H264 { - RK_U8 bScalingLists4x4[6][16]; - RK_U8 bScalingLists8x8[6][64]; - -} DXVA_Qmatrix_H264, *LPDXVA_Qmatrix_H264; - -/* H.264/AVC slice control data structure - short form */ -typedef struct _DXVA_Slice_H264_Short { - RK_U32 BSNALunitDataLocation; /* type 1..5 */ - RK_U32 SliceBytesInBuffer; /* for off-host parse */ - RK_U16 wBadSliceChopping; /* for off-host parse */ -} DXVA_Slice_H264_Short, *LPDXVA_Slice_H264_Short; - -/* H.264/AVC picture entry data structure - long form */ -typedef struct _DXVA_Slice_H264_Long { - RK_U32 BSNALunitDataLocation; /* type 1..5 */ - RK_U32 SliceBytesInBuffer; /* for off-host parse */ - RK_U16 wBadSliceChopping; /* for off-host parse */ - - RK_U16 first_mb_in_slice; - RK_U16 NumMbsForSlice; - - RK_U16 BitOffsetToSliceData; /* after CABAC alignment */ - - RK_U8 slice_type; - RK_U8 luma_log2_weight_denom; - RK_U8 chroma_log2_weight_denom; - RK_U8 num_ref_idx_l0_active_minus1; - RK_U8 num_ref_idx_l1_active_minus1; - RK_S8 slice_alpha_c0_offset_div2; - RK_S8 slice_beta_offset_div2; - RK_U8 Reserved8Bits; - DXVA_PicEntry_H264 RefPicList[3][32]; /* L0 & L1 */ - RK_S16 Weights[2][32][3][2]; /* L0 & L1; Y, Cb, Cr */ - RK_S8 slice_qs_delta; - /* rest off-host parse */ - RK_S8 slice_qp_delta; - RK_U8 redundant_pic_cnt; - RK_U8 direct_spatial_mv_pred_flag; - RK_U8 cabac_init_idc; - RK_U8 disable_deblocking_filter_idc; - RK_U16 slice_id; - /* add parameter for setting hardware */ - RK_U32 active_sps_id; - RK_U32 active_pps_id; - RK_U32 idr_pic_id; - RK_U32 idr_flag; - RK_U32 drpm_used_bitlen; - RK_U32 poc_used_bitlen; - RK_U32 nal_ref_idc; - RK_U32 profileIdc; -} DXVA_Slice_H264_Long, *LPDXVA_Slice_H264_Long; - -/* H.264/AVC macro block control command data structure */ -typedef struct _DXVA_MBctrl_H264 { - union { - struct { - RK_U32 bSliceID : 8; /* 1 byte */ - RK_U32 MbType5Bits : 5; - RK_U32 IntraMbFlag : 1; - RK_U32 mb_field_decoding_flag : 1; - RK_U32 transform_size_8x8_flag : 1; /* 2 bytes */ - RK_U32 HostResidDiff : 1; - RK_U32 DcBlockCodedCrFlag : 1; - RK_U32 DcBlockCodedCbFlag : 1; - RK_U32 DcBlockCodedYFlag : 1; - RK_U32 FilterInternalEdgesFlag : 1; - RK_U32 FilterLeftMbEdgeFlag : 1; - RK_U32 FilterTopMbEdgeFlag : 1; - RK_U32 ReservedBit : 1; - RK_U32 bMvQuantity : 8; /* 4 bytes */ - }; - RK_U32 dwMBtype; /* 4 bytes so far */ - }; - RK_U16 CurrMbAddr; /* 6 bytes so far */ - RK_U16 wPatternCode[3];/* YCbCr, 16 4x4 blks, 1b each */ - /* 12 bytes so far */ - RK_U8 bQpPrime[3]; /* Y, Cb, Cr, need just 7b QpY */ - RK_U8 bMBresidDataQuantity; - RK_U32 dwMBdataLocation; /* offset into resid buffer */ - /* 20 bytes so far */ - union { - struct { - /* start here for Intra MB's (9 useful bytes in branch) */ - RK_U16 LumaIntraPredModes[4];/* 16 blocks, 4b each */ - /* 28 bytes so far */ - union { - struct { - RK_U8 intra_chroma_pred_mode : 2; - RK_U8 IntraPredAvailFlags : 5; - RK_U8 ReservedIntraBit : 1; - }; - RK_U8 bMbIntraStruct; /* 29 bytes so far */ - }; - RK_U8 ReservedIntra24Bits[3]; /* 32 bytes total */ - }; - struct { - /* start here for non-Intra MB's (12 bytes in branch) */ - RK_U8 bSubMbShapes; /* 4 subMbs, 2b each */ - RK_U8 bSubMbPredModes; /* 4 subMBs, 2b each */ - /* 22 bytes so far */ - RK_U16 wMvBuffOffset; /* offset into MV buffer */ - RK_U8 bRefPicSelect[2][4]; /* 32 bytes total */ - }; - }; -} DXVA_MBctrl_H264, *LPDXVA_MBctrl_H264; - -/* H.264/AVC IndexA and IndexB data structure */ -typedef struct _DXVA_DeblockIndexAB_H264 { - RK_U8 bIndexAinternal; /* 6b - could get from MB CC */ - RK_U8 bIndexBinternal; /* 6b - could get from MB CC */ - - RK_U8 bIndexAleft0; - RK_U8 bIndexBleft0; - - RK_U8 bIndexAleft1; - RK_U8 bIndexBleft1; - - RK_U8 bIndexAtop0; - RK_U8 bIndexBtop0; - - RK_U8 bIndexAtop1; - RK_U8 bIndexBtop1; -} DXVA_DeblockIndexAB_H264, *LPDXVA_DeblockIndexAB_H264; -/* 10 bytes in struct */ - -/* H.264/AVC deblocking filter control data structure */ -typedef struct _DXVA_Deblock_H264 { - RK_U16 CurrMbAddr; /* dup info */ /* 2 bytes so far */ - union { - struct { - RK_U8 ReservedBit : 1; - RK_U8 FieldModeCurrentMbFlag : 1; /* dup info */ - RK_U8 FieldModeLeftMbFlag : 1; - RK_U8 FieldModeAboveMbFlag : 1; - RK_U8 FilterInternal8x8EdgesFlag : 1; - RK_U8 FilterInternal4x4EdgesFlag : 1; - RK_U8 FilterLeftMbEdgeFlag : 1; - RK_U8 FilterTopMbEdgeFlag : 1; - }; - RK_U8 FirstByte; - }; - RK_U8 Reserved8Bits; /* 4 bytes so far */ - - RK_U8 bbSinternalLeftVert; /* 2 bits per bS */ - RK_U8 bbSinternalMidVert; - - RK_U8 bbSinternalRightVert; - RK_U8 bbSinternalTopHorz; /* 8 bytes so far */ - - RK_U8 bbSinternalMidHorz; - RK_U8 bbSinternalBotHorz; /* 10 bytes so far */ - - RK_U16 wbSLeft0; /* 4 bits per bS (1 wasted) */ - RK_U16 wbSLeft1; /* 4 bits per bS (1 wasted) */ - - RK_U16 wbSTop0; /* 4 bits per bS (1 wasted) */ - RK_U16 wbSTop1; /* 4b (2 wasted) 18 bytes so far*/ - - DXVA_DeblockIndexAB_H264 IndexAB[3]; /* Y, Cb, Cr */ - -} DXVA_Deblock_H264, *LPDXVA_Deblock_H264;/* 48 bytes */ - -/* H.264/AVC film grain characteristics data structure */ -typedef struct _DXVA_FilmGrainCharacteristics { - - RK_U16 wFrameWidthInMbsMinus1; - RK_U16 wFrameHeightInMbsMinus1; - - DXVA_PicEntry_H264 InPic; /* flag is bot field flag */ - DXVA_PicEntry_H264 OutPic; /* flag is field pic flag */ - - RK_U16 PicOrderCnt_offset; - RK_S32 CurrPicOrderCnt; - RK_U32 StatusReportFeedbackNumber; - - RK_U8 model_id; - RK_U8 separate_colour_description_present_flag; - RK_U8 film_grain_bit_depth_luma_minus8; - RK_U8 film_grain_bit_depth_chroma_minus8; - - RK_U8 film_grain_full_range_flag; - RK_U8 film_grain_colour_primaries; - RK_U8 film_grain_transfer_characteristics; - RK_U8 film_grain_matrix_coefficients; - - RK_U8 blending_mode_id; - RK_U8 log2_scale_factor; - - RK_U8 comp_model_present_flag[4]; - RK_U8 num_intensity_intervals_minus1[4]; - RK_U8 num_model_values_minus1[4]; - - RK_U8 intensity_interval_lower_bound[3][16]; - RK_U8 intensity_interval_upper_bound[3][16]; - RK_S16 comp_model_value[3][16][8]; -} DXVA_FilmGrainChar_H264, *LPDXVA_FilmGrainChar_H264; - -/* H.264/AVC status reporting data structure */ -typedef struct _DXVA_Status_H264 { - RK_U32 StatusReportFeedbackNumber; - DXVA_PicEntry_H264 CurrPic; /* flag is bot field flag */ - RK_U8 field_pic_flag; - RK_U8 bDXVA_Func; - RK_U8 bBufType; - RK_U8 bStatus; - RK_U8 bReserved8Bits; - RK_U16 wNumMbsAffected; -} DXVA_Status_H264, *LPDXVA_Status_H264; - -/* H.264 MVC picture parameters structure */ -typedef struct _DXVA_PicParams_H264_MVC { - RK_U16 wFrameWidthInMbsMinus1; - RK_U16 wFrameHeightInMbsMinus1; - DXVA_PicEntry_H264 CurrPic; /* flag is bot field flag */ - RK_U8 num_ref_frames; - - union { - struct { - RK_U16 field_pic_flag : 1; - RK_U16 MbaffFrameFlag : 1; - RK_U16 residual_colour_transform_flag : 1; - RK_U16 sp_for_switch_flag : 1; - RK_U16 chroma_format_idc : 2; - RK_U16 RefPicFlag : 1; - RK_U16 constrained_intra_pred_flag : 1; - - RK_U16 weighted_pred_flag : 1; - RK_U16 weighted_bipred_idc : 2; - RK_U16 MbsConsecutiveFlag : 1; - RK_U16 frame_mbs_only_flag : 1; - RK_U16 transform_8x8_mode_flag : 1; - RK_U16 MinLumaBipredSize8x8Flag : 1; - RK_U16 IntraPicFlag : 1; - }; - RK_U16 wBitFields; - }; - RK_U8 bit_depth_luma_minus8; - RK_U8 bit_depth_chroma_minus8; - - RK_U16 Reserved16Bits; - RK_U32 StatusReportFeedbackNumber; - - DXVA_PicEntry_H264 RefFrameList[16]; /* flag LT */ - RK_S32 CurrFieldOrderCnt[2]; - RK_S32 FieldOrderCntList[16][2]; - - RK_S8 pic_init_qs_minus26; - RK_S8 chroma_qp_index_offset; /* also used for QScb */ - RK_S8 second_chroma_qp_index_offset; /* also for QScr */ - RK_U8 ContinuationFlag; - - /* remainder for parsing */ - RK_S8 pic_init_qp_minus26; - RK_U8 num_ref_idx_l0_active_minus1; - RK_U8 num_ref_idx_l1_active_minus1; - RK_U8 Reserved8BitsA; - - RK_U16 FrameNumList[16]; - RK_U16 LongTermPicNumList[16]; - RK_U32 UsedForReferenceFlags; - RK_U16 NonExistingFrameFlags; - RK_U16 frame_num; - - RK_U8 log2_max_frame_num_minus4; - RK_U8 pic_order_cnt_type; - RK_U8 log2_max_pic_order_cnt_lsb_minus4; - RK_U8 delta_pic_order_always_zero_flag; - - RK_U8 direct_8x8_inference_flag; - RK_U8 entropy_coding_mode_flag; - RK_U8 pic_order_present_flag; - RK_U8 num_slice_groups_minus1; - - RK_U8 slice_group_map_type; - RK_U8 deblocking_filter_control_present_flag; - RK_U8 redundant_pic_cnt_present_flag; - RK_U8 Reserved8BitsB; - /* SliceGroupMap is not needed for MVC, as MVC is for high profile only */ - RK_U16 slice_group_change_rate_minus1; - /* Following are H.264 MVC Specific parameters */ - RK_U8 num_views_minus1; - RK_U16 view_id[16]; - RK_U8 num_anchor_refs_l0[16]; - RK_U16 anchor_ref_l0[16][16]; - RK_U8 num_anchor_refs_l1[16]; - RK_U16 anchor_ref_l1[16][16]; - RK_U8 num_non_anchor_refs_l0[16]; - RK_U16 non_anchor_ref_l0[16][16]; - RK_U8 num_non_anchor_refs_l1[16]; - RK_U16 non_anchor_ref_l1[16][16]; - - RK_U16 curr_view_id; - RK_U8 anchor_pic_flag; - RK_U8 inter_view_flag; - RK_U16 ViewIDList[16]; - //!< add in Rock-Chip RKVDEC IP - RK_U16 curr_layer_id; - RK_U16 RefPicColmvUsedFlags; - RK_U16 RefPicFiledFlags; - RK_U8 RefPicLayerIdList[16]; - RK_U8 scaleing_list_enable_flag; - RK_U16 UsedForInTerviewflags; - - ////!< for fpga test - //USHORT seq_parameter_set_id; - //USHORT pps_seq_parameter_set_id; - //USHORT profile_idc; - //UCHAR constraint_set3_flag; - //UCHAR qpprime_y_zero_transform_bypass_flag; - //UCHAR mvc_extension_enable; - -} DXVA_PicParams_H264_MVC, *LPDXVA_PicParams_H264_MVC; - - - -typedef struct h264d_syntax_t { - RK_U32 num; - DXVA2_DecodeBufferDesc *buf; -} H264dSyntax_t; - -#endif /*__H264D_SYNTAX_H__*/ - +/* +* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +#ifndef __H264D_SYNTAX_H__ +#define __H264D_SYNTAX_H__ + +#include "h264_syntax.h" +#include "dxva_syntax.h" + +/* H.264/AVC-specific structures */ + +/* H.264/AVC picture entry data structure */ +typedef struct _DXVA_PicEntry_H264 { + union { + struct { + RK_U8 Index7Bits : 7; + RK_U8 AssociatedFlag : 1; + }; + RK_U8 bPicEntry; + }; +} DXVA_PicEntry_H264, *LPDXVA_PicEntry_H264; /* 1 byte */ + +/* H.264/AVC picture parameters structure */ +typedef struct _DXVA_PicParams_H264 { + RK_U16 wFrameWidthInMbsMinus1; + RK_U16 wFrameHeightInMbsMinus1; + DXVA_PicEntry_H264 CurrPic; /* flag is bot field flag */ + RK_U8 num_ref_frames; + + union { + struct { + RK_U16 field_pic_flag : 1; + RK_U16 MbaffFrameFlag : 1; + RK_U16 residual_colour_transform_flag : 1; + RK_U16 sp_for_switch_flag : 1; + RK_U16 chroma_format_idc : 2; + RK_U16 RefPicFlag : 1; + RK_U16 constrained_intra_pred_flag : 1; + + RK_U16 weighted_pred_flag : 1; + RK_U16 weighted_bipred_idc : 2; + RK_U16 MbsConsecutiveFlag : 1; + RK_U16 frame_mbs_only_flag : 1; + RK_U16 transform_8x8_mode_flag : 1; + RK_U16 MinLumaBipredSize8x8Flag : 1; + RK_U16 IntraPicFlag : 1; + }; + RK_U16 wBitFields; + }; + RK_U8 bit_depth_luma_minus8; + RK_U8 bit_depth_chroma_minus8; + + RK_U16 Reserved16Bits; + RK_U32 StatusReportFeedbackNumber; + + DXVA_PicEntry_H264 RefFrameList[16]; /* flag LT */ + RK_S32 CurrFieldOrderCnt[2]; + RK_S32 FieldOrderCntList[16][2]; + + RK_S8 pic_init_qs_minus26; + RK_S8 chroma_qp_index_offset; /* also used for QScb */ + RK_S8 second_chroma_qp_index_offset; /* also for QScr */ + RK_U8 ContinuationFlag; + + /* remainder for parsing */ + RK_S8 pic_init_qp_minus26; + RK_U8 num_ref_idx_l0_active_minus1; + RK_U8 num_ref_idx_l1_active_minus1; + RK_U8 Reserved8BitsA; + + RK_U16 FrameNumList[16]; + RK_U32 UsedForReferenceFlags; + RK_U16 NonExistingFrameFlags; + RK_U16 frame_num; + + RK_U8 log2_max_frame_num_minus4; + RK_U8 pic_order_cnt_type; + RK_U8 log2_max_pic_order_cnt_lsb_minus4; + RK_U8 delta_pic_order_always_zero_flag; + + RK_U8 direct_8x8_inference_flag; + RK_U8 entropy_coding_mode_flag; + RK_U8 pic_order_present_flag; + RK_U8 num_slice_groups_minus1; + + RK_U8 slice_group_map_type; + RK_U8 deblocking_filter_control_present_flag; + RK_U8 redundant_pic_cnt_present_flag; + RK_U8 Reserved8BitsB; + + RK_U16 slice_group_change_rate_minus1; + + //RK_U8 SliceGroupMap[810]; /* 4b/sgmu, Size BT.601 */ + +} DXVA_PicParams_H264, *LPDXVA_PicParams_H264; + +/* H.264/AVC quantization weighting matrix data structure */ +typedef struct _DXVA_Qmatrix_H264 { + RK_U8 bScalingLists4x4[6][16]; + RK_U8 bScalingLists8x8[6][64]; + +} DXVA_Qmatrix_H264, *LPDXVA_Qmatrix_H264; + +/* H.264/AVC slice control data structure - short form */ +typedef struct _DXVA_Slice_H264_Short { + RK_U32 BSNALunitDataLocation; /* type 1..5 */ + RK_U32 SliceBytesInBuffer; /* for off-host parse */ + RK_U16 wBadSliceChopping; /* for off-host parse */ +} DXVA_Slice_H264_Short, *LPDXVA_Slice_H264_Short; + +/* H.264/AVC picture entry data structure - long form */ +typedef struct _DXVA_Slice_H264_Long { + RK_U32 BSNALunitDataLocation; /* type 1..5 */ + RK_U32 SliceBytesInBuffer; /* for off-host parse */ + RK_U16 wBadSliceChopping; /* for off-host parse */ + + RK_U16 first_mb_in_slice; + RK_U16 NumMbsForSlice; + + RK_U16 BitOffsetToSliceData; /* after CABAC alignment */ + + RK_U8 slice_type; + RK_U8 luma_log2_weight_denom; + RK_U8 chroma_log2_weight_denom; + RK_U8 num_ref_idx_l0_active_minus1; + RK_U8 num_ref_idx_l1_active_minus1; + RK_S8 slice_alpha_c0_offset_div2; + RK_S8 slice_beta_offset_div2; + RK_U8 Reserved8Bits; + DXVA_PicEntry_H264 RefPicList[3][32]; /* L0 & L1 */ + RK_S16 Weights[2][32][3][2]; /* L0 & L1; Y, Cb, Cr */ + RK_S8 slice_qs_delta; + /* rest off-host parse */ + RK_S8 slice_qp_delta; + RK_U8 redundant_pic_cnt; + RK_U8 direct_spatial_mv_pred_flag; + RK_U8 cabac_init_idc; + RK_U8 disable_deblocking_filter_idc; + RK_U16 slice_id; + /* add parameter for setting hardware */ + RK_U32 active_sps_id; + RK_U32 active_pps_id; + RK_U32 idr_pic_id; + RK_U32 idr_flag; + RK_U32 drpm_used_bitlen; + RK_U32 poc_used_bitlen; + RK_U32 nal_ref_idc; + RK_U32 profileIdc; +} DXVA_Slice_H264_Long, *LPDXVA_Slice_H264_Long; + +/* H.264/AVC macro block control command data structure */ +typedef struct _DXVA_MBctrl_H264 { + union { + struct { + RK_U32 bSliceID : 8; /* 1 byte */ + RK_U32 MbType5Bits : 5; + RK_U32 IntraMbFlag : 1; + RK_U32 mb_field_decoding_flag : 1; + RK_U32 transform_size_8x8_flag : 1; /* 2 bytes */ + RK_U32 HostResidDiff : 1; + RK_U32 DcBlockCodedCrFlag : 1; + RK_U32 DcBlockCodedCbFlag : 1; + RK_U32 DcBlockCodedYFlag : 1; + RK_U32 FilterInternalEdgesFlag : 1; + RK_U32 FilterLeftMbEdgeFlag : 1; + RK_U32 FilterTopMbEdgeFlag : 1; + RK_U32 ReservedBit : 1; + RK_U32 bMvQuantity : 8; /* 4 bytes */ + }; + RK_U32 dwMBtype; /* 4 bytes so far */ + }; + RK_U16 CurrMbAddr; /* 6 bytes so far */ + RK_U16 wPatternCode[3];/* YCbCr, 16 4x4 blks, 1b each */ + /* 12 bytes so far */ + RK_U8 bQpPrime[3]; /* Y, Cb, Cr, need just 7b QpY */ + RK_U8 bMBresidDataQuantity; + RK_U32 dwMBdataLocation; /* offset into resid buffer */ + /* 20 bytes so far */ + union { + struct { + /* start here for Intra MB's (9 useful bytes in branch) */ + RK_U16 LumaIntraPredModes[4];/* 16 blocks, 4b each */ + /* 28 bytes so far */ + union { + struct { + RK_U8 intra_chroma_pred_mode : 2; + RK_U8 IntraPredAvailFlags : 5; + RK_U8 ReservedIntraBit : 1; + }; + RK_U8 bMbIntraStruct; /* 29 bytes so far */ + }; + RK_U8 ReservedIntra24Bits[3]; /* 32 bytes total */ + }; + struct { + /* start here for non-Intra MB's (12 bytes in branch) */ + RK_U8 bSubMbShapes; /* 4 subMbs, 2b each */ + RK_U8 bSubMbPredModes; /* 4 subMBs, 2b each */ + /* 22 bytes so far */ + RK_U16 wMvBuffOffset; /* offset into MV buffer */ + RK_U8 bRefPicSelect[2][4]; /* 32 bytes total */ + }; + }; +} DXVA_MBctrl_H264, *LPDXVA_MBctrl_H264; + +/* H.264/AVC IndexA and IndexB data structure */ +typedef struct _DXVA_DeblockIndexAB_H264 { + RK_U8 bIndexAinternal; /* 6b - could get from MB CC */ + RK_U8 bIndexBinternal; /* 6b - could get from MB CC */ + + RK_U8 bIndexAleft0; + RK_U8 bIndexBleft0; + + RK_U8 bIndexAleft1; + RK_U8 bIndexBleft1; + + RK_U8 bIndexAtop0; + RK_U8 bIndexBtop0; + + RK_U8 bIndexAtop1; + RK_U8 bIndexBtop1; +} DXVA_DeblockIndexAB_H264, *LPDXVA_DeblockIndexAB_H264; +/* 10 bytes in struct */ + +/* H.264/AVC deblocking filter control data structure */ +typedef struct _DXVA_Deblock_H264 { + RK_U16 CurrMbAddr; /* dup info */ /* 2 bytes so far */ + union { + struct { + RK_U8 ReservedBit : 1; + RK_U8 FieldModeCurrentMbFlag : 1; /* dup info */ + RK_U8 FieldModeLeftMbFlag : 1; + RK_U8 FieldModeAboveMbFlag : 1; + RK_U8 FilterInternal8x8EdgesFlag : 1; + RK_U8 FilterInternal4x4EdgesFlag : 1; + RK_U8 FilterLeftMbEdgeFlag : 1; + RK_U8 FilterTopMbEdgeFlag : 1; + }; + RK_U8 FirstByte; + }; + RK_U8 Reserved8Bits; /* 4 bytes so far */ + + RK_U8 bbSinternalLeftVert; /* 2 bits per bS */ + RK_U8 bbSinternalMidVert; + + RK_U8 bbSinternalRightVert; + RK_U8 bbSinternalTopHorz; /* 8 bytes so far */ + + RK_U8 bbSinternalMidHorz; + RK_U8 bbSinternalBotHorz; /* 10 bytes so far */ + + RK_U16 wbSLeft0; /* 4 bits per bS (1 wasted) */ + RK_U16 wbSLeft1; /* 4 bits per bS (1 wasted) */ + + RK_U16 wbSTop0; /* 4 bits per bS (1 wasted) */ + RK_U16 wbSTop1; /* 4b (2 wasted) 18 bytes so far*/ + + DXVA_DeblockIndexAB_H264 IndexAB[3]; /* Y, Cb, Cr */ + +} DXVA_Deblock_H264, *LPDXVA_Deblock_H264;/* 48 bytes */ + +/* H.264/AVC film grain characteristics data structure */ +typedef struct _DXVA_FilmGrainCharacteristics { + + RK_U16 wFrameWidthInMbsMinus1; + RK_U16 wFrameHeightInMbsMinus1; + + DXVA_PicEntry_H264 InPic; /* flag is bot field flag */ + DXVA_PicEntry_H264 OutPic; /* flag is field pic flag */ + + RK_U16 PicOrderCnt_offset; + RK_S32 CurrPicOrderCnt; + RK_U32 StatusReportFeedbackNumber; + + RK_U8 model_id; + RK_U8 separate_colour_description_present_flag; + RK_U8 film_grain_bit_depth_luma_minus8; + RK_U8 film_grain_bit_depth_chroma_minus8; + + RK_U8 film_grain_full_range_flag; + RK_U8 film_grain_colour_primaries; + RK_U8 film_grain_transfer_characteristics; + RK_U8 film_grain_matrix_coefficients; + + RK_U8 blending_mode_id; + RK_U8 log2_scale_factor; + + RK_U8 comp_model_present_flag[4]; + RK_U8 num_intensity_intervals_minus1[4]; + RK_U8 num_model_values_minus1[4]; + + RK_U8 intensity_interval_lower_bound[3][16]; + RK_U8 intensity_interval_upper_bound[3][16]; + RK_S16 comp_model_value[3][16][8]; +} DXVA_FilmGrainChar_H264, *LPDXVA_FilmGrainChar_H264; + +/* H.264/AVC status reporting data structure */ +typedef struct _DXVA_Status_H264 { + RK_U32 StatusReportFeedbackNumber; + DXVA_PicEntry_H264 CurrPic; /* flag is bot field flag */ + RK_U8 field_pic_flag; + RK_U8 bDXVA_Func; + RK_U8 bBufType; + RK_U8 bStatus; + RK_U8 bReserved8Bits; + RK_U16 wNumMbsAffected; +} DXVA_Status_H264, *LPDXVA_Status_H264; + +/* H.264 MVC picture parameters structure */ +typedef struct _DXVA_PicParams_H264_MVC { + RK_U16 wFrameWidthInMbsMinus1; + RK_U16 wFrameHeightInMbsMinus1; + DXVA_PicEntry_H264 CurrPic; /* flag is bot field flag */ + RK_U8 num_ref_frames; + + union { + struct { + RK_U16 field_pic_flag : 1; + RK_U16 MbaffFrameFlag : 1; + RK_U16 residual_colour_transform_flag : 1; + RK_U16 sp_for_switch_flag : 1; + RK_U16 chroma_format_idc : 2; + RK_U16 RefPicFlag : 1; + RK_U16 constrained_intra_pred_flag : 1; + + RK_U16 weighted_pred_flag : 1; + RK_U16 weighted_bipred_idc : 2; + RK_U16 MbsConsecutiveFlag : 1; + RK_U16 frame_mbs_only_flag : 1; + RK_U16 transform_8x8_mode_flag : 1; + RK_U16 MinLumaBipredSize8x8Flag : 1; + RK_U16 IntraPicFlag : 1; + }; + RK_U16 wBitFields; + }; + RK_U8 bit_depth_luma_minus8; + RK_U8 bit_depth_chroma_minus8; + + RK_U16 Reserved16Bits; + RK_U32 StatusReportFeedbackNumber; + + DXVA_PicEntry_H264 RefFrameList[16]; /* flag LT */ + RK_S32 CurrFieldOrderCnt[2]; + RK_S32 FieldOrderCntList[16][2]; + + RK_S8 pic_init_qs_minus26; + RK_S8 chroma_qp_index_offset; /* also used for QScb */ + RK_S8 second_chroma_qp_index_offset; /* also for QScr */ + RK_U8 ContinuationFlag; + + /* remainder for parsing */ + RK_S8 pic_init_qp_minus26; + RK_U8 num_ref_idx_l0_active_minus1; + RK_U8 num_ref_idx_l1_active_minus1; + RK_U8 Reserved8BitsA; + + RK_U16 FrameNumList[16]; + RK_U16 LongTermPicNumList[16]; + RK_U32 UsedForReferenceFlags; + RK_U16 NonExistingFrameFlags; + RK_U16 frame_num; + + RK_U8 log2_max_frame_num_minus4; + RK_U8 pic_order_cnt_type; + RK_U8 log2_max_pic_order_cnt_lsb_minus4; + RK_U8 delta_pic_order_always_zero_flag; + + RK_U8 direct_8x8_inference_flag; + RK_U8 entropy_coding_mode_flag; + RK_U8 pic_order_present_flag; + RK_U8 num_slice_groups_minus1; + + RK_U8 slice_group_map_type; + RK_U8 deblocking_filter_control_present_flag; + RK_U8 redundant_pic_cnt_present_flag; + RK_U8 Reserved8BitsB; + /* SliceGroupMap is not needed for MVC, as MVC is for high profile only */ + RK_U16 slice_group_change_rate_minus1; + /* Following are H.264 MVC Specific parameters */ + RK_U8 num_views_minus1; + RK_U16 view_id[16]; + RK_U8 num_anchor_refs_l0[16]; + RK_U16 anchor_ref_l0[16][16]; + RK_U8 num_anchor_refs_l1[16]; + RK_U16 anchor_ref_l1[16][16]; + RK_U8 num_non_anchor_refs_l0[16]; + RK_U16 non_anchor_ref_l0[16][16]; + RK_U8 num_non_anchor_refs_l1[16]; + RK_U16 non_anchor_ref_l1[16][16]; + + RK_U16 curr_view_id; + RK_U8 anchor_pic_flag; + RK_U8 inter_view_flag; + RK_U16 ViewIDList[16]; + //!< add in Rock-Chip RKVDEC IP + RK_U16 curr_layer_id; + RK_U16 RefPicColmvUsedFlags; + RK_U16 RefPicFiledFlags; + RK_U8 RefPicLayerIdList[16]; + RK_U8 scaleing_list_enable_flag; + RK_U16 UsedForInTerviewflags; + + ////!< for fpga test + //USHORT seq_parameter_set_id; + //USHORT pps_seq_parameter_set_id; + //USHORT profile_idc; + //UCHAR constraint_set3_flag; + //UCHAR qpprime_y_zero_transform_bypass_flag; + //UCHAR mvc_extension_enable; + +} DXVA_PicParams_H264_MVC, *LPDXVA_PicParams_H264_MVC; + + + +typedef struct h264d_syntax_t { + RK_U32 num; + DXVA2_DecodeBufferDesc *buf; +} H264dSyntax_t; + +#endif /*__H264D_SYNTAX_H__*/ + diff --git a/mpp/common/h264e_syntax.h b/mpp/common/h264e_syntax.h index 4ac89325..23360657 100644 --- a/mpp/common/h264e_syntax.h +++ b/mpp/common/h264e_syntax.h @@ -1,115 +1,115 @@ -#ifndef __H264E_SYNTAX_H__ -#define __H264E_SYNTAX_H__ - -#include "rk_type.h" -#include "h264_syntax.h" - -#define H264_BIT_DEPTH 8 -#define H264_QP_BD_OFFSET (6*(H264_BIT_DEPTH-8)) - -typedef struct h264e_osd_pos_t { - RK_U32 lt_pos_x : 8; - RK_U32 lt_pos_y : 8; - RK_U32 rd_pos_x : 8; - RK_U32 rd_pos_y : 8; -} h264e_osd_pos; //OSD_POS0-7 - -typedef struct h264e_syntax_t { - RK_U32 frame_coding_type; //(VEPU)0: inter, 1: intra (RKVENC)RKVENC_FRAME_TYPE_* - RK_U32 slice_type; - RK_S32 pic_init_qp; //COMB, TODO: merge with swreg59.pic_init_qp - RK_S32 slice_alpha_offset; //COMB TODO: merge with swreg62.sli_beta_ofst - RK_S32 slice_beta_offset; //COMB TODO: merge with swreg62.sli_alph_ofst - RK_S32 chroma_qp_index_offset; //COMB - RK_S32 second_chroma_qp_index_offset; //TODO: may be removed later, get from sps/pps instead - RK_S32 deblocking_filter_control; //COMB - RK_S32 disable_deblocking_filter_idc; - RK_S32 filter_disable; //TODO: merge width disable_deblocking_filter_idc above - RK_U16 idr_pic_id; //COMB - RK_S32 pps_id; //COMB TODO: merge with swreg60.pps_id //TODO: may be removed later, get from sps/pps instead - RK_S32 frame_num; //COMB TODO: swreg60.frm_num - RK_S32 slice_size_mb_rows; - RK_S32 h264_inter4x4_disabled; //COMB - RK_S32 enable_cabac; //COMB - RK_S32 transform8x8_mode; //COMB - RK_S32 cabac_init_idc; //COMB TODO: merge with swreg60.cbc_init_idc - RK_S32 pic_order_cnt_lsb; - - /* rate control relevant */ - RK_S32 qp; - RK_S32 mad_qp_delta; - RK_S32 mad_threshold; - RK_S32 qp_min; //COMB, TODO: merge width swreg54.rc_min_qp - RK_S32 qp_max; //COMB, TODO: merge width swreg54.rc_max_qp - RK_S32 cp_distance_mbs; - RK_S32 cp_target[10]; - RK_S32 target_error[7]; - RK_S32 delta_qp[7]; - - - RK_U32 output_strm_limit_size; // outputStrmSize - RK_U32 output_strm_addr; // outputStrmBase - RK_U32 pic_luma_width; // preProcess->lumWidth - RK_U32 pic_luma_height; // preProcess->lumHeight - RK_U32 input_luma_addr; // inputLumBase - RK_U32 input_cb_addr; // inputCbBase - RK_U32 input_cr_addr; // inputCrBase - RK_U32 input_image_format; // inputImageFormat - RK_U32 color_conversion_coeff_a; //colorConversionCoeffA - RK_U32 color_conversion_coeff_b; //colorConversionCoeffB - RK_U32 color_conversion_coeff_c; //colorConversionCoeffC - RK_U32 color_conversion_coeff_e; //colorConversionCoeffE - RK_U32 color_conversion_coeff_f; //colorConversionCoeffF - - /* RKVENC extra syntax below */ - RK_S32 profile_idc; //TODO: may be removed later, get from sps/pps instead - RK_S32 level_idc; //TODO: may be removed later, get from sps/pps instead - RK_S32 link_table_en; - RK_S32 keyframe_max_interval; - - RK_S32 mb_rc_mode; //0:frame/slice 1:mb; //0: disable mbrc, 1:slice/frame rc, 2:MB rc. - RK_S32 roi_en; - RK_S32 osd_mode; //0: disable osd, 1:palette type 0(congfigurable mode), 2:palette type 1(fixed mode). - RK_S32 preproc_en; -} h264e_syntax; - -typedef struct h264e_feedback_t { - /* rc */ - RK_U32 hw_status; /* 0:corret, 1:error */ - RK_S32 qp_sum; - RK_S32 cp[10]; - RK_S32 mad_count; - RK_S32 rlc_count; - RK_U32 out_strm_size; - - /* for VEPU future extansion */ - //TODO: add nal size table feedback -} h264e_feedback; - - -typedef struct h264e_control_extra_info_cfg_t { - /* common cfg */ - RK_U32 pic_luma_width; - RK_U32 pic_luma_height; - RK_S32 enable_cabac; - RK_S32 transform8x8_mode; - RK_S32 chroma_qp_index_offset; - RK_S32 pic_init_qp; - //RK_S32 rotation_enable; //0: 0/180 degrees, 1: 90/270 degrees //TODO: add rotation - - /* additional cfg only for rkv */ - RK_U32 input_image_format; - RK_S32 profile_idc; - RK_S32 level_idc; //TODO: may be removed later, get from sps/pps instead - RK_S32 keyframe_max_interval; - RK_S32 second_chroma_qp_index_offset; - RK_S32 pps_id; //TODO: may be removed later, get from sps/pps instead -} h264e_control_extra_info_cfg; - - -typedef struct h264e_control_extra_info_t { - RK_U32 size; // preProcess->lumWidth - RK_U8 buf[256]; // preProcess-> -} h264e_control_extra_info; - -#endif +#ifndef __H264E_SYNTAX_H__ +#define __H264E_SYNTAX_H__ + +#include "rk_type.h" +#include "h264_syntax.h" + +#define H264_BIT_DEPTH 8 +#define H264_QP_BD_OFFSET (6*(H264_BIT_DEPTH-8)) + +typedef struct h264e_osd_pos_t { + RK_U32 lt_pos_x : 8; + RK_U32 lt_pos_y : 8; + RK_U32 rd_pos_x : 8; + RK_U32 rd_pos_y : 8; +} h264e_osd_pos; //OSD_POS0-7 + +typedef struct h264e_syntax_t { + RK_U32 frame_coding_type; //(VEPU)0: inter, 1: intra (RKVENC)RKVENC_FRAME_TYPE_* + RK_U32 slice_type; + RK_S32 pic_init_qp; //COMB, TODO: merge with swreg59.pic_init_qp + RK_S32 slice_alpha_offset; //COMB TODO: merge with swreg62.sli_beta_ofst + RK_S32 slice_beta_offset; //COMB TODO: merge with swreg62.sli_alph_ofst + RK_S32 chroma_qp_index_offset; //COMB + RK_S32 second_chroma_qp_index_offset; //TODO: may be removed later, get from sps/pps instead + RK_S32 deblocking_filter_control; //COMB + RK_S32 disable_deblocking_filter_idc; + RK_S32 filter_disable; //TODO: merge width disable_deblocking_filter_idc above + RK_U16 idr_pic_id; //COMB + RK_S32 pps_id; //COMB TODO: merge with swreg60.pps_id //TODO: may be removed later, get from sps/pps instead + RK_S32 frame_num; //COMB TODO: swreg60.frm_num + RK_S32 slice_size_mb_rows; + RK_S32 h264_inter4x4_disabled; //COMB + RK_S32 enable_cabac; //COMB + RK_S32 transform8x8_mode; //COMB + RK_S32 cabac_init_idc; //COMB TODO: merge with swreg60.cbc_init_idc + RK_S32 pic_order_cnt_lsb; + + /* rate control relevant */ + RK_S32 qp; + RK_S32 mad_qp_delta; + RK_S32 mad_threshold; + RK_S32 qp_min; //COMB, TODO: merge width swreg54.rc_min_qp + RK_S32 qp_max; //COMB, TODO: merge width swreg54.rc_max_qp + RK_S32 cp_distance_mbs; + RK_S32 cp_target[10]; + RK_S32 target_error[7]; + RK_S32 delta_qp[7]; + + + RK_U32 output_strm_limit_size; // outputStrmSize + RK_U32 output_strm_addr; // outputStrmBase + RK_U32 pic_luma_width; // preProcess->lumWidth + RK_U32 pic_luma_height; // preProcess->lumHeight + RK_U32 input_luma_addr; // inputLumBase + RK_U32 input_cb_addr; // inputCbBase + RK_U32 input_cr_addr; // inputCrBase + RK_U32 input_image_format; // inputImageFormat + RK_U32 color_conversion_coeff_a; //colorConversionCoeffA + RK_U32 color_conversion_coeff_b; //colorConversionCoeffB + RK_U32 color_conversion_coeff_c; //colorConversionCoeffC + RK_U32 color_conversion_coeff_e; //colorConversionCoeffE + RK_U32 color_conversion_coeff_f; //colorConversionCoeffF + + /* RKVENC extra syntax below */ + RK_S32 profile_idc; //TODO: may be removed later, get from sps/pps instead + RK_S32 level_idc; //TODO: may be removed later, get from sps/pps instead + RK_S32 link_table_en; + RK_S32 keyframe_max_interval; + + RK_S32 mb_rc_mode; //0:frame/slice 1:mb; //0: disable mbrc, 1:slice/frame rc, 2:MB rc. + RK_S32 roi_en; + RK_S32 osd_mode; //0: disable osd, 1:palette type 0(congfigurable mode), 2:palette type 1(fixed mode). + RK_S32 preproc_en; +} h264e_syntax; + +typedef struct h264e_feedback_t { + /* rc */ + RK_U32 hw_status; /* 0:corret, 1:error */ + RK_S32 qp_sum; + RK_S32 cp[10]; + RK_S32 mad_count; + RK_S32 rlc_count; + RK_U32 out_strm_size; + + /* for VEPU future extansion */ + //TODO: add nal size table feedback +} h264e_feedback; + + +typedef struct h264e_control_extra_info_cfg_t { + /* common cfg */ + RK_U32 pic_luma_width; + RK_U32 pic_luma_height; + RK_S32 enable_cabac; + RK_S32 transform8x8_mode; + RK_S32 chroma_qp_index_offset; + RK_S32 pic_init_qp; + //RK_S32 rotation_enable; //0: 0/180 degrees, 1: 90/270 degrees //TODO: add rotation + + /* additional cfg only for rkv */ + RK_U32 input_image_format; + RK_S32 profile_idc; + RK_S32 level_idc; //TODO: may be removed later, get from sps/pps instead + RK_S32 keyframe_max_interval; + RK_S32 second_chroma_qp_index_offset; + RK_S32 pps_id; //TODO: may be removed later, get from sps/pps instead +} h264e_control_extra_info_cfg; + + +typedef struct h264e_control_extra_info_t { + RK_U32 size; // preProcess->lumWidth + RK_U8 buf[256]; // preProcess-> +} h264e_control_extra_info; + +#endif diff --git a/mpp/common/h265d_syntax.h b/mpp/common/h265d_syntax.h index 674e3c9c..52b1d080 100644 --- a/mpp/common/h265d_syntax.h +++ b/mpp/common/h265d_syntax.h @@ -1,193 +1,193 @@ -/* - * - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file h265d_syntax.h - * @brief - * @author csy(csy@rock-chips.com) - - * @version 1.0.0 - * @history - * 2015.7.15 : Create - */ -#ifndef __H265D_SYNTAX__ -#define __H265D_SYNTAX__ -typedef unsigned long DWORD; -typedef unsigned char BYTE; -typedef unsigned short WORD; -typedef unsigned long ULONG; -typedef unsigned short USHORT; -typedef unsigned char UCHAR; -typedef unsigned int UINT; -typedef unsigned int UINT32; - -typedef signed int BOOL; -typedef signed int INT; -typedef signed char CHAR; -typedef signed short SHORT; -typedef signed long LONG; -typedef void *PVOID; - -/* HEVC Picture Entry structure */ -#define MAX_SLICES 600 -typedef struct _DXVA_PicEntry_HEVC { - union { - struct { - UCHAR Index7Bits : 7; - UCHAR AssociatedFlag : 1; - }; - UCHAR bPicEntry; - }; -} DXVA_PicEntry_HEVC, *LPDXVA_PicEntry_HEVC; - -/* HEVC Picture Parameter structure */ -typedef struct _DXVA_PicParams_HEVC { - USHORT PicWidthInMinCbsY; - USHORT PicHeightInMinCbsY; - union { - struct { - USHORT chroma_format_idc : 2; - USHORT separate_colour_plane_flag : 1; - USHORT bit_depth_luma_minus8 : 3; - USHORT bit_depth_chroma_minus8 : 3; - USHORT log2_max_pic_order_cnt_lsb_minus4 : 4; - USHORT NoPicReorderingFlag : 1; - USHORT NoBiPredFlag : 1; - USHORT ReservedBits1 : 1; - }; - USHORT wFormatAndSequenceInfoFlags; - }; - DXVA_PicEntry_HEVC CurrPic; - UCHAR sps_max_dec_pic_buffering_minus1; - UCHAR log2_min_luma_coding_block_size_minus3; - UCHAR log2_diff_max_min_luma_coding_block_size; - UCHAR log2_min_transform_block_size_minus2; - UCHAR log2_diff_max_min_transform_block_size; - UCHAR max_transform_hierarchy_depth_inter; - UCHAR max_transform_hierarchy_depth_intra; - UCHAR num_short_term_ref_pic_sets; - UCHAR num_long_term_ref_pics_sps; - UCHAR num_ref_idx_l0_default_active_minus1; - UCHAR num_ref_idx_l1_default_active_minus1; - CHAR init_qp_minus26; - UCHAR ucNumDeltaPocsOfRefRpsIdx; - USHORT wNumBitsForShortTermRPSInSlice; - USHORT ReservedBits2; - - union { - struct { - UINT32 scaling_list_enabled_flag : 1; - UINT32 amp_enabled_flag : 1; - UINT32 sample_adaptive_offset_enabled_flag : 1; - UINT32 pcm_enabled_flag : 1; - UINT32 pcm_sample_bit_depth_luma_minus1 : 4; - UINT32 pcm_sample_bit_depth_chroma_minus1 : 4; - UINT32 log2_min_pcm_luma_coding_block_size_minus3 : 2; - UINT32 log2_diff_max_min_pcm_luma_coding_block_size : 2; - UINT32 pcm_loop_filter_disabled_flag : 1; - UINT32 long_term_ref_pics_present_flag : 1; - UINT32 sps_temporal_mvp_enabled_flag : 1; - UINT32 strong_intra_smoothing_enabled_flag : 1; - UINT32 dependent_slice_segments_enabled_flag : 1; - UINT32 output_flag_present_flag : 1; - UINT32 num_extra_slice_header_bits : 3; - UINT32 sign_data_hiding_enabled_flag : 1; - UINT32 cabac_init_present_flag : 1; - UINT32 ReservedBits3 : 5; - }; - UINT32 dwCodingParamToolFlags; - }; - - union { - struct { - UINT32 constrained_intra_pred_flag : 1; - UINT32 transform_skip_enabled_flag : 1; - UINT32 cu_qp_delta_enabled_flag : 1; - UINT32 pps_slice_chroma_qp_offsets_present_flag : 1; - UINT32 weighted_pred_flag : 1; - UINT32 weighted_bipred_flag : 1; - UINT32 transquant_bypass_enabled_flag : 1; - UINT32 tiles_enabled_flag : 1; - UINT32 entropy_coding_sync_enabled_flag : 1; - UINT32 uniform_spacing_flag : 1; - UINT32 loop_filter_across_tiles_enabled_flag : 1; - UINT32 pps_loop_filter_across_slices_enabled_flag : 1; - UINT32 deblocking_filter_override_enabled_flag : 1; - UINT32 pps_deblocking_filter_disabled_flag : 1; - UINT32 lists_modification_present_flag : 1; - UINT32 slice_segment_header_extension_present_flag : 1; - UINT32 IrapPicFlag : 1; - UINT32 IdrPicFlag : 1; - UINT32 IntraPicFlag : 1; - UINT32 ReservedBits4 : 13; - }; - UINT32 dwCodingSettingPicturePropertyFlags; - }; - CHAR pps_cb_qp_offset; - CHAR pps_cr_qp_offset; - UCHAR num_tile_columns_minus1; - UCHAR num_tile_rows_minus1; - USHORT column_width_minus1[19]; - USHORT row_height_minus1[21]; - UCHAR diff_cu_qp_delta_depth; - CHAR pps_beta_offset_div2; - CHAR pps_tc_offset_div2; - UCHAR log2_parallel_merge_level_minus2; - INT CurrPicOrderCntVal; - DXVA_PicEntry_HEVC RefPicList[15]; - UCHAR ReservedBits5; - INT PicOrderCntValList[15]; - UCHAR RefPicSetStCurrBefore[8]; - UCHAR RefPicSetStCurrAfter[8]; - UCHAR RefPicSetLtCurr[8]; - USHORT ReservedBits6; - USHORT ReservedBits7; - UINT StatusReportFeedbackNumber; - UINT32 vps_id; - UINT32 pps_id; - UINT32 sps_id; - UCHAR scaling_list_data_present_flag; -} DXVA_PicParams_HEVC, *LPDXVA_PicParams_HEVC; - -/* HEVC Quantizatiuon Matrix structure */ -typedef struct _DXVA_Qmatrix_HEVC { - UCHAR ucScalingLists0[6][16]; - UCHAR ucScalingLists1[6][64]; - UCHAR ucScalingLists2[6][64]; - UCHAR ucScalingLists3[2][64]; - UCHAR ucScalingListDCCoefSizeID2[6]; - UCHAR ucScalingListDCCoefSizeID3[2]; -} DXVA_Qmatrix_HEVC, *LPDXVA_Qmatrix_HEVC; - - -/* HEVC Slice Control Structure */ -typedef struct _DXVA_Slice_HEVC_Short { - UINT BSNALunitDataLocation; - UINT SliceBytesInBuffer; - USHORT wBadSliceChopping; -} DXVA_Slice_HEVC_Short, *LPDXVA_Slice_HEVC_Short; - -typedef struct h265d_dxva2_picture_context { - DXVA_PicParams_HEVC pp; - DXVA_Qmatrix_HEVC qm; - UINT32 slice_count; - DXVA_Slice_HEVC_Short slice_short[MAX_SLICES]; - const UCHAR *bitstream; - UINT32 bitstream_size; -} h265d_dxva2_picture_context_t; - +/* + * + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file h265d_syntax.h + * @brief + * @author csy(csy@rock-chips.com) + + * @version 1.0.0 + * @history + * 2015.7.15 : Create + */ +#ifndef __H265D_SYNTAX__ +#define __H265D_SYNTAX__ +typedef unsigned long DWORD; +typedef unsigned char BYTE; +typedef unsigned short WORD; +typedef unsigned long ULONG; +typedef unsigned short USHORT; +typedef unsigned char UCHAR; +typedef unsigned int UINT; +typedef unsigned int UINT32; + +typedef signed int BOOL; +typedef signed int INT; +typedef signed char CHAR; +typedef signed short SHORT; +typedef signed long LONG; +typedef void *PVOID; + +/* HEVC Picture Entry structure */ +#define MAX_SLICES 600 +typedef struct _DXVA_PicEntry_HEVC { + union { + struct { + UCHAR Index7Bits : 7; + UCHAR AssociatedFlag : 1; + }; + UCHAR bPicEntry; + }; +} DXVA_PicEntry_HEVC, *LPDXVA_PicEntry_HEVC; + +/* HEVC Picture Parameter structure */ +typedef struct _DXVA_PicParams_HEVC { + USHORT PicWidthInMinCbsY; + USHORT PicHeightInMinCbsY; + union { + struct { + USHORT chroma_format_idc : 2; + USHORT separate_colour_plane_flag : 1; + USHORT bit_depth_luma_minus8 : 3; + USHORT bit_depth_chroma_minus8 : 3; + USHORT log2_max_pic_order_cnt_lsb_minus4 : 4; + USHORT NoPicReorderingFlag : 1; + USHORT NoBiPredFlag : 1; + USHORT ReservedBits1 : 1; + }; + USHORT wFormatAndSequenceInfoFlags; + }; + DXVA_PicEntry_HEVC CurrPic; + UCHAR sps_max_dec_pic_buffering_minus1; + UCHAR log2_min_luma_coding_block_size_minus3; + UCHAR log2_diff_max_min_luma_coding_block_size; + UCHAR log2_min_transform_block_size_minus2; + UCHAR log2_diff_max_min_transform_block_size; + UCHAR max_transform_hierarchy_depth_inter; + UCHAR max_transform_hierarchy_depth_intra; + UCHAR num_short_term_ref_pic_sets; + UCHAR num_long_term_ref_pics_sps; + UCHAR num_ref_idx_l0_default_active_minus1; + UCHAR num_ref_idx_l1_default_active_minus1; + CHAR init_qp_minus26; + UCHAR ucNumDeltaPocsOfRefRpsIdx; + USHORT wNumBitsForShortTermRPSInSlice; + USHORT ReservedBits2; + + union { + struct { + UINT32 scaling_list_enabled_flag : 1; + UINT32 amp_enabled_flag : 1; + UINT32 sample_adaptive_offset_enabled_flag : 1; + UINT32 pcm_enabled_flag : 1; + UINT32 pcm_sample_bit_depth_luma_minus1 : 4; + UINT32 pcm_sample_bit_depth_chroma_minus1 : 4; + UINT32 log2_min_pcm_luma_coding_block_size_minus3 : 2; + UINT32 log2_diff_max_min_pcm_luma_coding_block_size : 2; + UINT32 pcm_loop_filter_disabled_flag : 1; + UINT32 long_term_ref_pics_present_flag : 1; + UINT32 sps_temporal_mvp_enabled_flag : 1; + UINT32 strong_intra_smoothing_enabled_flag : 1; + UINT32 dependent_slice_segments_enabled_flag : 1; + UINT32 output_flag_present_flag : 1; + UINT32 num_extra_slice_header_bits : 3; + UINT32 sign_data_hiding_enabled_flag : 1; + UINT32 cabac_init_present_flag : 1; + UINT32 ReservedBits3 : 5; + }; + UINT32 dwCodingParamToolFlags; + }; + + union { + struct { + UINT32 constrained_intra_pred_flag : 1; + UINT32 transform_skip_enabled_flag : 1; + UINT32 cu_qp_delta_enabled_flag : 1; + UINT32 pps_slice_chroma_qp_offsets_present_flag : 1; + UINT32 weighted_pred_flag : 1; + UINT32 weighted_bipred_flag : 1; + UINT32 transquant_bypass_enabled_flag : 1; + UINT32 tiles_enabled_flag : 1; + UINT32 entropy_coding_sync_enabled_flag : 1; + UINT32 uniform_spacing_flag : 1; + UINT32 loop_filter_across_tiles_enabled_flag : 1; + UINT32 pps_loop_filter_across_slices_enabled_flag : 1; + UINT32 deblocking_filter_override_enabled_flag : 1; + UINT32 pps_deblocking_filter_disabled_flag : 1; + UINT32 lists_modification_present_flag : 1; + UINT32 slice_segment_header_extension_present_flag : 1; + UINT32 IrapPicFlag : 1; + UINT32 IdrPicFlag : 1; + UINT32 IntraPicFlag : 1; + UINT32 ReservedBits4 : 13; + }; + UINT32 dwCodingSettingPicturePropertyFlags; + }; + CHAR pps_cb_qp_offset; + CHAR pps_cr_qp_offset; + UCHAR num_tile_columns_minus1; + UCHAR num_tile_rows_minus1; + USHORT column_width_minus1[19]; + USHORT row_height_minus1[21]; + UCHAR diff_cu_qp_delta_depth; + CHAR pps_beta_offset_div2; + CHAR pps_tc_offset_div2; + UCHAR log2_parallel_merge_level_minus2; + INT CurrPicOrderCntVal; + DXVA_PicEntry_HEVC RefPicList[15]; + UCHAR ReservedBits5; + INT PicOrderCntValList[15]; + UCHAR RefPicSetStCurrBefore[8]; + UCHAR RefPicSetStCurrAfter[8]; + UCHAR RefPicSetLtCurr[8]; + USHORT ReservedBits6; + USHORT ReservedBits7; + UINT StatusReportFeedbackNumber; + UINT32 vps_id; + UINT32 pps_id; + UINT32 sps_id; + UCHAR scaling_list_data_present_flag; +} DXVA_PicParams_HEVC, *LPDXVA_PicParams_HEVC; + +/* HEVC Quantizatiuon Matrix structure */ +typedef struct _DXVA_Qmatrix_HEVC { + UCHAR ucScalingLists0[6][16]; + UCHAR ucScalingLists1[6][64]; + UCHAR ucScalingLists2[6][64]; + UCHAR ucScalingLists3[2][64]; + UCHAR ucScalingListDCCoefSizeID2[6]; + UCHAR ucScalingListDCCoefSizeID3[2]; +} DXVA_Qmatrix_HEVC, *LPDXVA_Qmatrix_HEVC; + + +/* HEVC Slice Control Structure */ +typedef struct _DXVA_Slice_HEVC_Short { + UINT BSNALunitDataLocation; + UINT SliceBytesInBuffer; + USHORT wBadSliceChopping; +} DXVA_Slice_HEVC_Short, *LPDXVA_Slice_HEVC_Short; + +typedef struct h265d_dxva2_picture_context { + DXVA_PicParams_HEVC pp; + DXVA_Qmatrix_HEVC qm; + UINT32 slice_count; + DXVA_Slice_HEVC_Short slice_short[MAX_SLICES]; + const UCHAR *bitstream; + UINT32 bitstream_size; +} h265d_dxva2_picture_context_t; + #endif /*__H265D_SYNTAX__*/ \ No newline at end of file diff --git a/mpp/common/m2vd_syntax.h b/mpp/common/m2vd_syntax.h index 8bce3f99..4f72a991 100644 --- a/mpp/common/m2vd_syntax.h +++ b/mpp/common/m2vd_syntax.h @@ -1,141 +1,141 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __M2VD_SYNTAX_H__ -#define __M2VD_SYNTAX_H__ - -#include "rk_type.h" - -typedef struct _DXVA_PicEntry_M2V { - union { - struct { - RK_U8 Index7Bits : 7; - RK_U8 AssociatedFlag : 1; - }; - RK_U8 bPicEntry; - }; -} DXVA_PicEntry_M2V; - - -/* ISO/IEC 13818-2 section 6.2.2.1: sequence_Dxvaer() */ -typedef struct M2VDDxvaSeq_t { - RK_U32 decode_width; //horizontal_size_value - RK_U32 decode_height; //vertical_size_value - RK_S32 aspect_ratio_information; - RK_S32 frame_rate_code; - RK_S32 bit_rate_value; - RK_S32 vbv_buffer_size; - RK_S32 constrained_parameters_flag; - RK_U32 load_intra_quantizer_matrix; //[TEMP] - RK_U32 load_non_intra_quantizer_matrix; //[TEMP] -} M2VDDxvaSeq; - -/* ISO/IEC 13818-2 section 6.2.2.3: sequence_extension() */ -typedef struct M2VDDxvaSeqExt_t { - RK_S32 profile_and_level_indication; - RK_S32 progressive_sequence; - RK_S32 chroma_format; - RK_S32 low_delay; - RK_S32 frame_rate_extension_n; - RK_S32 frame_rate_extension_d; -} M2VDDxvaSeqExt; - -/* ISO/IEC 13818-2 section 6.2.2.6: group_of_pictures_Dxvaer() */ -typedef struct M2VDDxvaGop_t { - RK_S32 drop_flag; - RK_S32 hour; - RK_S32 minute; - RK_S32 sec; - RK_S32 frame; - RK_S32 closed_gop; - RK_S32 broken_link; -} M2VDDxvaGop; - - -/* ISO/IEC 13818-2 section 6.2.3: picture_Dxvaer() */ -typedef struct M2VDDxvaPic_t { - RK_S32 temporal_reference; - RK_S32 picture_coding_type; - RK_S32 pre_picture_coding_type; - RK_S32 vbv_delay; - RK_S32 full_pel_forward_vector; - RK_S32 forward_f_code; - RK_S32 full_pel_backward_vector; - RK_S32 backward_f_code; - RK_S32 pre_temporal_reference; -} M2VDDxvaPic; - - -/* ISO/IEC 13818-2 section 6.2.2.4: sequence_display_extension() */ -typedef struct M2VDDxvaSeqDispExt_t { - RK_S32 video_format; - RK_S32 color_description; - RK_S32 color_primaries; - RK_S32 transfer_characteristics; - RK_S32 matrix_coefficients; -} M2VDDxvaSeqDispExt; - -/* ISO/IEC 13818-2 section 6.2.3.1: picture_coding_extension() Dxvaer */ -typedef struct M2VDDxvaPicCodeExt_t { - RK_S32 f_code[2][2]; - RK_S32 intra_dc_precision; - RK_S32 picture_structure; - RK_S32 top_field_first; - RK_S32 frame_pred_frame_dct; - RK_S32 concealment_motion_vectors; - RK_S32 q_scale_type; - RK_S32 intra_vlc_format; - RK_S32 alternate_scan; - RK_S32 repeat_first_field; - RK_S32 chroma_420_type; - RK_S32 progressive_frame; - RK_S32 composite_display_flag; - RK_S32 v_axis; - RK_S32 field_sequence; - RK_S32 sub_carrier; - RK_S32 burst_amplitude; - RK_S32 sub_carrier_phase; -} M2VDDxvaPicCodeExt; - - -/* ISO/IEC 13818-2 section 6.2.3.3: picture_display_extension() Dxvaer */ -typedef struct M2VDDxvaPicDispExt_t { - RK_S32 frame_center_horizontal_offset[3]; - RK_S32 frame_center_vertical_offset[3]; -} M2VDDxvaPicDispExt; - - -typedef struct M2VDDxvaParam_t { - RK_U32 bitstream_length; - RK_U32 bitstream_start_bit; - RK_U32 bitstream_offset; - RK_U8 *qp_tab; - - DXVA_PicEntry_M2V CurrPic; - DXVA_PicEntry_M2V frame_refs[4]; - - RK_U32 seq_ext_head_dec_flag; - - M2VDDxvaSeq seq; - M2VDDxvaSeqExt seq_ext; - M2VDDxvaGop gop; - M2VDDxvaPic pic; - M2VDDxvaSeqDispExt seq_disp_ext; - M2VDDxvaPicCodeExt pic_code_ext; - M2VDDxvaPicDispExt pic_disp_ext; -} M2VDDxvaParam; - -#endif +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __M2VD_SYNTAX_H__ +#define __M2VD_SYNTAX_H__ + +#include "rk_type.h" + +typedef struct _DXVA_PicEntry_M2V { + union { + struct { + RK_U8 Index7Bits : 7; + RK_U8 AssociatedFlag : 1; + }; + RK_U8 bPicEntry; + }; +} DXVA_PicEntry_M2V; + + +/* ISO/IEC 13818-2 section 6.2.2.1: sequence_Dxvaer() */ +typedef struct M2VDDxvaSeq_t { + RK_U32 decode_width; //horizontal_size_value + RK_U32 decode_height; //vertical_size_value + RK_S32 aspect_ratio_information; + RK_S32 frame_rate_code; + RK_S32 bit_rate_value; + RK_S32 vbv_buffer_size; + RK_S32 constrained_parameters_flag; + RK_U32 load_intra_quantizer_matrix; //[TEMP] + RK_U32 load_non_intra_quantizer_matrix; //[TEMP] +} M2VDDxvaSeq; + +/* ISO/IEC 13818-2 section 6.2.2.3: sequence_extension() */ +typedef struct M2VDDxvaSeqExt_t { + RK_S32 profile_and_level_indication; + RK_S32 progressive_sequence; + RK_S32 chroma_format; + RK_S32 low_delay; + RK_S32 frame_rate_extension_n; + RK_S32 frame_rate_extension_d; +} M2VDDxvaSeqExt; + +/* ISO/IEC 13818-2 section 6.2.2.6: group_of_pictures_Dxvaer() */ +typedef struct M2VDDxvaGop_t { + RK_S32 drop_flag; + RK_S32 hour; + RK_S32 minute; + RK_S32 sec; + RK_S32 frame; + RK_S32 closed_gop; + RK_S32 broken_link; +} M2VDDxvaGop; + + +/* ISO/IEC 13818-2 section 6.2.3: picture_Dxvaer() */ +typedef struct M2VDDxvaPic_t { + RK_S32 temporal_reference; + RK_S32 picture_coding_type; + RK_S32 pre_picture_coding_type; + RK_S32 vbv_delay; + RK_S32 full_pel_forward_vector; + RK_S32 forward_f_code; + RK_S32 full_pel_backward_vector; + RK_S32 backward_f_code; + RK_S32 pre_temporal_reference; +} M2VDDxvaPic; + + +/* ISO/IEC 13818-2 section 6.2.2.4: sequence_display_extension() */ +typedef struct M2VDDxvaSeqDispExt_t { + RK_S32 video_format; + RK_S32 color_description; + RK_S32 color_primaries; + RK_S32 transfer_characteristics; + RK_S32 matrix_coefficients; +} M2VDDxvaSeqDispExt; + +/* ISO/IEC 13818-2 section 6.2.3.1: picture_coding_extension() Dxvaer */ +typedef struct M2VDDxvaPicCodeExt_t { + RK_S32 f_code[2][2]; + RK_S32 intra_dc_precision; + RK_S32 picture_structure; + RK_S32 top_field_first; + RK_S32 frame_pred_frame_dct; + RK_S32 concealment_motion_vectors; + RK_S32 q_scale_type; + RK_S32 intra_vlc_format; + RK_S32 alternate_scan; + RK_S32 repeat_first_field; + RK_S32 chroma_420_type; + RK_S32 progressive_frame; + RK_S32 composite_display_flag; + RK_S32 v_axis; + RK_S32 field_sequence; + RK_S32 sub_carrier; + RK_S32 burst_amplitude; + RK_S32 sub_carrier_phase; +} M2VDDxvaPicCodeExt; + + +/* ISO/IEC 13818-2 section 6.2.3.3: picture_display_extension() Dxvaer */ +typedef struct M2VDDxvaPicDispExt_t { + RK_S32 frame_center_horizontal_offset[3]; + RK_S32 frame_center_vertical_offset[3]; +} M2VDDxvaPicDispExt; + + +typedef struct M2VDDxvaParam_t { + RK_U32 bitstream_length; + RK_U32 bitstream_start_bit; + RK_U32 bitstream_offset; + RK_U8 *qp_tab; + + DXVA_PicEntry_M2V CurrPic; + DXVA_PicEntry_M2V frame_refs[4]; + + RK_U32 seq_ext_head_dec_flag; + + M2VDDxvaSeq seq; + M2VDDxvaSeqExt seq_ext; + M2VDDxvaGop gop; + M2VDDxvaPic pic; + M2VDDxvaSeqDispExt seq_disp_ext; + M2VDDxvaPicCodeExt pic_code_ext; + M2VDDxvaPicDispExt pic_disp_ext; +} M2VDDxvaParam; + +#endif diff --git a/mpp/common/mpg4d_syntax.h b/mpp/common/mpg4d_syntax.h index 8f780af0..10b6c881 100644 --- a/mpp/common/mpg4d_syntax.h +++ b/mpp/common/mpg4d_syntax.h @@ -1,148 +1,148 @@ -/* - * - * Copyright 2010 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file mpeg4d_syntax.h - * @brief - * @author gzl(gzl@rock-chips.com) - * @version 1.0.0 - * @history - * 2016.04.06 : Create - */ -#ifndef __MPG4D_SYNTAX__ -#define __MPG4D_SYNTAX__ - -#include "dxva_syntax.h" - -#define MPEG4_VIDOBJLAY_AR_SQUARE 1 -#define MPEG4_VIDOBJLAY_AR_625TYPE_43 2 -#define MPEG4_VIDOBJLAY_AR_525TYPE_43 3 -#define MPEG4_VIDOBJLAY_AR_625TYPE_169 8 -#define MPEG4_VIDOBJLAY_AR_525TYPE_169 9 -#define MPEG4_VIDOBJLAY_AR_EXTPAR 15 - -#define MPEG4_VIDOBJLAY_SHAPE_RECTANGULAR 0 -#define MPEG4_VIDOBJLAY_SHAPE_BINARY 1 -#define MPEG4_VIDOBJLAY_SHAPE_BINARY_ONLY 2 -#define MPEG4_VIDOBJLAY_SHAPE_GRAYSCALE 3 - -/*video sprite specific*/ -#define MPEG4_SPRITE_NONE 0 -#define MPEG4_SPRITE_STATIC 1 -#define MPEG4_SPRITE_GMC 2 - -/*video vop specific*/ -typedef enum { - MPEG4_RESYNC_VOP = -2, - MPEG4_INVALID_VOP = -1, - MPEG4_I_VOP = 0, - MPEG4_P_VOP = 1, - MPEG4_B_VOP = 2, - MPEG4_S_VOP = 3, - MPEG4_N_VOP = 4, - MPEG4_D_VOP = 5, /*Drop Frame*/ -} MPEG4VOPType; - -#define MPEG4_HDR_ERR -2 -#define MPEG4_DEC_ERR -4 -#define MPEG4_VLD_ERR -5 -#define MPEG4_FORMAT_ERR -6 -#define MPEG4_DIVX_PBBI -7 -#define MPEG4_INFO_CHANGE -10 - -/* MPEG4PT2 Picture Parameter structure */ -typedef struct _DXVA_PicParams_MPEG4_PART2 { - RK_U8 short_video_header; - RK_U8 vop_coding_type; - RK_U8 vop_quant; - RK_U16 wDecodedPictureIndex; - RK_U16 wDeblockedPictureIndex; - RK_U16 wForwardRefPictureIndex; - RK_U16 wBackwardRefPictureIndex; - RK_U16 vop_time_increment_resolution; - RK_U32 TRB[2]; - RK_U32 TRD[2]; - - union { - struct { - RK_U16 unPicPostProc : 2; - RK_U16 interlaced : 1; - RK_U16 quant_type : 1; - RK_U16 quarter_sample : 1; - RK_U16 resync_marker_disable : 1; - RK_U16 data_partitioned : 1; - RK_U16 reversible_vlc : 1; - RK_U16 reduced_resolution_vop_enable : 1; - RK_U16 vop_coded : 1; - RK_U16 vop_rounding_type : 1; - RK_U16 intra_dc_vlc_thr : 3; - RK_U16 top_field_first : 1; - RK_U16 alternate_vertical_scan_flag : 1; - }; - RK_U16 wPicFlagBitFields; - }; - RK_U8 profile_and_level_indication; - RK_U8 video_object_layer_verid; - RK_U16 vop_width; - RK_U16 vop_height; - union { - struct { - RK_U16 sprite_enable : 2; - RK_U16 no_of_sprite_warping_points : 6; - RK_U16 sprite_warping_accuracy : 2; - }; - RK_U16 wSpriteBitFields; - }; - RK_S16 warping_mv[4][2]; - union { - struct { - RK_U8 vop_fcode_forward : 3; - RK_U8 vop_fcode_backward : 3; - }; - RK_U8 wFcodeBitFields; - }; - RK_U16 StatusReportFeedbackNumber; - RK_U16 Reserved16BitsA; - RK_U16 Reserved16BitsB; - - // FIXME: added for rockchip hardware information - RK_U32 custorm_version; - RK_U32 prev_coding_type; - RK_U32 time_bp; - RK_U32 time_pp; - RK_U32 header_bits; -} DXVA_PicParams_MPEG4_PART2, *LPDXVA_PicParams_MPEG4_PART2; - -typedef struct _DXVA_QmatrixData { - RK_U8 bNewQmatrix[4]; // intra Y, inter Y, intra chroma, inter chroma - RK_U8 Qmatrix[4][64]; // NOTE: here we change U16 to U8 -} DXVA_QmatrixData, *LPDXVA_QmatrixData; - -typedef struct mpeg4d_dxva2_picture_context { - DXVA_PicParams_MPEG4_PART2 pp; - DXVA_QmatrixData qm; - - // pointer and storage for buffer descriptor - DXVA2_DecodeBufferDesc *data[3]; - DXVA2_DecodeBufferDesc desc[3]; - - RK_U32 frame_count; - const RK_U8 *bitstream; - RK_U32 bitstream_size; -} mpeg4d_dxva2_picture_context_t; - -#endif /*__MPG4D_SYNTAX__*/ +/* + * + * Copyright 2010 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file mpeg4d_syntax.h + * @brief + * @author gzl(gzl@rock-chips.com) + * @version 1.0.0 + * @history + * 2016.04.06 : Create + */ +#ifndef __MPG4D_SYNTAX__ +#define __MPG4D_SYNTAX__ + +#include "dxva_syntax.h" + +#define MPEG4_VIDOBJLAY_AR_SQUARE 1 +#define MPEG4_VIDOBJLAY_AR_625TYPE_43 2 +#define MPEG4_VIDOBJLAY_AR_525TYPE_43 3 +#define MPEG4_VIDOBJLAY_AR_625TYPE_169 8 +#define MPEG4_VIDOBJLAY_AR_525TYPE_169 9 +#define MPEG4_VIDOBJLAY_AR_EXTPAR 15 + +#define MPEG4_VIDOBJLAY_SHAPE_RECTANGULAR 0 +#define MPEG4_VIDOBJLAY_SHAPE_BINARY 1 +#define MPEG4_VIDOBJLAY_SHAPE_BINARY_ONLY 2 +#define MPEG4_VIDOBJLAY_SHAPE_GRAYSCALE 3 + +/*video sprite specific*/ +#define MPEG4_SPRITE_NONE 0 +#define MPEG4_SPRITE_STATIC 1 +#define MPEG4_SPRITE_GMC 2 + +/*video vop specific*/ +typedef enum { + MPEG4_RESYNC_VOP = -2, + MPEG4_INVALID_VOP = -1, + MPEG4_I_VOP = 0, + MPEG4_P_VOP = 1, + MPEG4_B_VOP = 2, + MPEG4_S_VOP = 3, + MPEG4_N_VOP = 4, + MPEG4_D_VOP = 5, /*Drop Frame*/ +} MPEG4VOPType; + +#define MPEG4_HDR_ERR -2 +#define MPEG4_DEC_ERR -4 +#define MPEG4_VLD_ERR -5 +#define MPEG4_FORMAT_ERR -6 +#define MPEG4_DIVX_PBBI -7 +#define MPEG4_INFO_CHANGE -10 + +/* MPEG4PT2 Picture Parameter structure */ +typedef struct _DXVA_PicParams_MPEG4_PART2 { + RK_U8 short_video_header; + RK_U8 vop_coding_type; + RK_U8 vop_quant; + RK_U16 wDecodedPictureIndex; + RK_U16 wDeblockedPictureIndex; + RK_U16 wForwardRefPictureIndex; + RK_U16 wBackwardRefPictureIndex; + RK_U16 vop_time_increment_resolution; + RK_U32 TRB[2]; + RK_U32 TRD[2]; + + union { + struct { + RK_U16 unPicPostProc : 2; + RK_U16 interlaced : 1; + RK_U16 quant_type : 1; + RK_U16 quarter_sample : 1; + RK_U16 resync_marker_disable : 1; + RK_U16 data_partitioned : 1; + RK_U16 reversible_vlc : 1; + RK_U16 reduced_resolution_vop_enable : 1; + RK_U16 vop_coded : 1; + RK_U16 vop_rounding_type : 1; + RK_U16 intra_dc_vlc_thr : 3; + RK_U16 top_field_first : 1; + RK_U16 alternate_vertical_scan_flag : 1; + }; + RK_U16 wPicFlagBitFields; + }; + RK_U8 profile_and_level_indication; + RK_U8 video_object_layer_verid; + RK_U16 vop_width; + RK_U16 vop_height; + union { + struct { + RK_U16 sprite_enable : 2; + RK_U16 no_of_sprite_warping_points : 6; + RK_U16 sprite_warping_accuracy : 2; + }; + RK_U16 wSpriteBitFields; + }; + RK_S16 warping_mv[4][2]; + union { + struct { + RK_U8 vop_fcode_forward : 3; + RK_U8 vop_fcode_backward : 3; + }; + RK_U8 wFcodeBitFields; + }; + RK_U16 StatusReportFeedbackNumber; + RK_U16 Reserved16BitsA; + RK_U16 Reserved16BitsB; + + // FIXME: added for rockchip hardware information + RK_U32 custorm_version; + RK_U32 prev_coding_type; + RK_U32 time_bp; + RK_U32 time_pp; + RK_U32 header_bits; +} DXVA_PicParams_MPEG4_PART2, *LPDXVA_PicParams_MPEG4_PART2; + +typedef struct _DXVA_QmatrixData { + RK_U8 bNewQmatrix[4]; // intra Y, inter Y, intra chroma, inter chroma + RK_U8 Qmatrix[4][64]; // NOTE: here we change U16 to U8 +} DXVA_QmatrixData, *LPDXVA_QmatrixData; + +typedef struct mpeg4d_dxva2_picture_context { + DXVA_PicParams_MPEG4_PART2 pp; + DXVA_QmatrixData qm; + + // pointer and storage for buffer descriptor + DXVA2_DecodeBufferDesc *data[3]; + DXVA2_DecodeBufferDesc desc[3]; + + RK_U32 frame_count; + const RK_U8 *bitstream; + RK_U32 bitstream_size; +} mpeg4d_dxva2_picture_context_t; + +#endif /*__MPG4D_SYNTAX__*/ diff --git a/mpp/common/vp8d_syntax.h b/mpp/common/vp8d_syntax.h index 25fc1bea..143a9886 100644 --- a/mpp/common/vp8d_syntax.h +++ b/mpp/common/vp8d_syntax.h @@ -1,170 +1,170 @@ -/* - * - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __VP8D_SYNTAX_H__ -#define __VP8D_SYNTAX_H__ - -#include "rk_type.h" - -typedef struct _DXVA_PicEntry_VP8 { - union { - struct { - RK_U8 Index7Bits : 7; - RK_U8 AssociatedFlag : 1; - }; - RK_U8 bPicEntry; - }; -} DXVA_PicEntry_VP8; -typedef struct _segmentation_Vp8 { - union { - struct { - RK_U8 segmentation_enabled : 1; - RK_U8 update_mb_segmentation_map : 1; - RK_U8 update_mb_segmentation_data : 1; - RK_U8 mb_segement_abs_delta : 1; - RK_U8 ReservedSegmentFlags4Bits : 4; - }; - RK_U8 wSegmentFlags; - }; - RK_S8 segment_feature_data[2][4]; - RK_U8 mb_segment_tree_probs[3]; -} DXVA_segmentation_VP8; - -typedef struct VP8DDxvaParam_t { - RK_U32 first_part_size; - RK_U32 width; - RK_U32 height; - DXVA_PicEntry_VP8 CurrPic; - union { - struct { - RK_U8 frame_type : 1; - RK_U8 version : 3; - RK_U8 show_frame : 1; - RK_U8 clamp_type : 1; - RK_U8 ReservedFrameTag2Bits: 2; - }; - RK_U8 wFrameTagFlags; - }; - DXVA_segmentation_VP8 stVP8Segments; - RK_U8 filter_type; - RK_U8 filter_level; - RK_U8 sharpness; - RK_U8 mode_ref_lf_delta_enabled; - RK_U8 mode_ref_lf_delta_update; - RK_S8 ref_lf_deltas[4]; - RK_S8 mode_lf_deltas[4]; - RK_U8 log2_nbr_of_dct_partitions; - RK_U8 base_qindex; - RK_S8 y1dc_delta_q; - RK_S8 y1ac_delta_q; - RK_S8 y2dc_delta_q; - RK_S8 y2ac_delta_q; - RK_S8 uvdc_delta_q; - RK_S8 uvac_delta_q; - - DXVA_PicEntry_VP8 alt_fb_idx; - DXVA_PicEntry_VP8 gld_fb_idx; - DXVA_PicEntry_VP8 lst_fb_idx; - - RK_U8 ref_frame_sign_bias_golden; - RK_U8 ref_frame_sign_bias_altref; - RK_U8 refresh_entropy_probs; - - RK_U8 vp8_coef_update_probs[4][8][3][11]; - RK_U8 probe_skip_false; - RK_U8 mb_no_coeff_skip; - RK_U8 prob_intra; - RK_U8 prob_last; - RK_U8 prob_golden; - RK_U8 intra_16x16_prob[4]; - RK_U8 intra_chroma_prob[3]; - RK_U8 vp8_mv_update_probs[2][19]; - - RK_U32 decMode; - RK_U32 bool_value; - RK_U32 bool_range; - RK_U32 stream_start_offset; - RK_U32 dctPartitionOffsets[8]; - RK_U32 bitstream_length; - RK_U32 stream_start_bit; - RK_U32 frameTagSize; - RK_U32 streamEndPos; - RK_U32 offsetToDctParts; -} DXVA_PicParams_VP8; - -#if 0 -typedef struct VP8DDxvaParam_t { - RK_U32 first_part_size; - RK_U32 width; - RK_U32 height; - DXVA_PicEntry_VP8 CurrPic; - union { - struct { - RK_U8 key_frame : 1; - RK_U8 segmentationEnabled : 1; - RK_U8 segmentationMapUpdate : 1; - RK_U8 modeRefLfEnabled : 1; - RK_U8 coeffSkipMode: 1; - RK_U8 reservedFormatInfo: 3; - }; - RK_U8 wFormatAndPictureInfoFlags; - }; - RK_U32 decMode; - RK_U32 loopFilterType; - RK_U32 loopFilterSharpness; - RK_U32 loopFilterLevel; - RK_U32 segmentFeatureMode; - RK_U32 vpVersion; - RK_U32 bool_value; - RK_U32 bool_range; - RK_U32 stream_start_offset; - RK_U32 stream_start_bit; - RK_U32 frameTagSize; - RK_U32 streamEndPos; - RK_U32 nbrDctPartitions; - RK_U32 offsetToDctParts; - - RK_S8 qpYAc; - RK_S8 qpYDc; - RK_S8 qpY2Ac; - RK_S8 qpY2Dc; - RK_S8 qpChAc; - RK_S8 qpChDc; - RK_U8 vp8_coef_update_probs[4][8][3][11]; - RK_U8 probe_skip_false; - RK_U8 prob_intra; - RK_U8 prob_last; - RK_U8 prob_golden; - RK_U8 intra_16x16_prob[4]; - RK_U8 intra_chroma_prob[3]; - RK_U8 vp8_mv_update_probs[2][19]; - RK_U8 vp8_segment_prob[3]; - - RK_U32 refFrameSignBias[2]; - RK_S32 dcPred[2]; - RK_S32 dcMatch[2]; - RK_S32 segmentQp[4]; - RK_S32 mbRefLfDelta[4]; - RK_S32 mbModeLfDelta[4]; - RK_U32 vp7ScanOrder[16]; - RK_S32 segmentLoopfilter[4]; - RK_U32 dctPartitionOffsets[8]; - RK_U32 bitstream_length; - DXVA_PicEntry_VP8 frame_refs[3]; -} DXVA_PicParams_VP8; -#endif -#endif +/* + * + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __VP8D_SYNTAX_H__ +#define __VP8D_SYNTAX_H__ + +#include "rk_type.h" + +typedef struct _DXVA_PicEntry_VP8 { + union { + struct { + RK_U8 Index7Bits : 7; + RK_U8 AssociatedFlag : 1; + }; + RK_U8 bPicEntry; + }; +} DXVA_PicEntry_VP8; +typedef struct _segmentation_Vp8 { + union { + struct { + RK_U8 segmentation_enabled : 1; + RK_U8 update_mb_segmentation_map : 1; + RK_U8 update_mb_segmentation_data : 1; + RK_U8 mb_segement_abs_delta : 1; + RK_U8 ReservedSegmentFlags4Bits : 4; + }; + RK_U8 wSegmentFlags; + }; + RK_S8 segment_feature_data[2][4]; + RK_U8 mb_segment_tree_probs[3]; +} DXVA_segmentation_VP8; + +typedef struct VP8DDxvaParam_t { + RK_U32 first_part_size; + RK_U32 width; + RK_U32 height; + DXVA_PicEntry_VP8 CurrPic; + union { + struct { + RK_U8 frame_type : 1; + RK_U8 version : 3; + RK_U8 show_frame : 1; + RK_U8 clamp_type : 1; + RK_U8 ReservedFrameTag2Bits: 2; + }; + RK_U8 wFrameTagFlags; + }; + DXVA_segmentation_VP8 stVP8Segments; + RK_U8 filter_type; + RK_U8 filter_level; + RK_U8 sharpness; + RK_U8 mode_ref_lf_delta_enabled; + RK_U8 mode_ref_lf_delta_update; + RK_S8 ref_lf_deltas[4]; + RK_S8 mode_lf_deltas[4]; + RK_U8 log2_nbr_of_dct_partitions; + RK_U8 base_qindex; + RK_S8 y1dc_delta_q; + RK_S8 y1ac_delta_q; + RK_S8 y2dc_delta_q; + RK_S8 y2ac_delta_q; + RK_S8 uvdc_delta_q; + RK_S8 uvac_delta_q; + + DXVA_PicEntry_VP8 alt_fb_idx; + DXVA_PicEntry_VP8 gld_fb_idx; + DXVA_PicEntry_VP8 lst_fb_idx; + + RK_U8 ref_frame_sign_bias_golden; + RK_U8 ref_frame_sign_bias_altref; + RK_U8 refresh_entropy_probs; + + RK_U8 vp8_coef_update_probs[4][8][3][11]; + RK_U8 probe_skip_false; + RK_U8 mb_no_coeff_skip; + RK_U8 prob_intra; + RK_U8 prob_last; + RK_U8 prob_golden; + RK_U8 intra_16x16_prob[4]; + RK_U8 intra_chroma_prob[3]; + RK_U8 vp8_mv_update_probs[2][19]; + + RK_U32 decMode; + RK_U32 bool_value; + RK_U32 bool_range; + RK_U32 stream_start_offset; + RK_U32 dctPartitionOffsets[8]; + RK_U32 bitstream_length; + RK_U32 stream_start_bit; + RK_U32 frameTagSize; + RK_U32 streamEndPos; + RK_U32 offsetToDctParts; +} DXVA_PicParams_VP8; + +#if 0 +typedef struct VP8DDxvaParam_t { + RK_U32 first_part_size; + RK_U32 width; + RK_U32 height; + DXVA_PicEntry_VP8 CurrPic; + union { + struct { + RK_U8 key_frame : 1; + RK_U8 segmentationEnabled : 1; + RK_U8 segmentationMapUpdate : 1; + RK_U8 modeRefLfEnabled : 1; + RK_U8 coeffSkipMode: 1; + RK_U8 reservedFormatInfo: 3; + }; + RK_U8 wFormatAndPictureInfoFlags; + }; + RK_U32 decMode; + RK_U32 loopFilterType; + RK_U32 loopFilterSharpness; + RK_U32 loopFilterLevel; + RK_U32 segmentFeatureMode; + RK_U32 vpVersion; + RK_U32 bool_value; + RK_U32 bool_range; + RK_U32 stream_start_offset; + RK_U32 stream_start_bit; + RK_U32 frameTagSize; + RK_U32 streamEndPos; + RK_U32 nbrDctPartitions; + RK_U32 offsetToDctParts; + + RK_S8 qpYAc; + RK_S8 qpYDc; + RK_S8 qpY2Ac; + RK_S8 qpY2Dc; + RK_S8 qpChAc; + RK_S8 qpChDc; + RK_U8 vp8_coef_update_probs[4][8][3][11]; + RK_U8 probe_skip_false; + RK_U8 prob_intra; + RK_U8 prob_last; + RK_U8 prob_golden; + RK_U8 intra_16x16_prob[4]; + RK_U8 intra_chroma_prob[3]; + RK_U8 vp8_mv_update_probs[2][19]; + RK_U8 vp8_segment_prob[3]; + + RK_U32 refFrameSignBias[2]; + RK_S32 dcPred[2]; + RK_S32 dcMatch[2]; + RK_S32 segmentQp[4]; + RK_S32 mbRefLfDelta[4]; + RK_S32 mbModeLfDelta[4]; + RK_U32 vp7ScanOrder[16]; + RK_S32 segmentLoopfilter[4]; + RK_U32 dctPartitionOffsets[8]; + RK_U32 bitstream_length; + DXVA_PicEntry_VP8 frame_refs[3]; +} DXVA_PicParams_VP8; +#endif +#endif diff --git a/mpp/hal/dummy/hal_dummy_dec_api.c b/mpp/hal/dummy/hal_dummy_dec_api.c index bcc831e8..627f37b9 100644 --- a/mpp/hal/dummy/hal_dummy_dec_api.c +++ b/mpp/hal/dummy/hal_dummy_dec_api.c @@ -1,91 +1,91 @@ -/* -* -* Copyright 2015 Rockchip Electronics Co. LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#define MODULE_TAG "hal_dummy_dec" - -#include "hal_dummy_dec_api.h" - - -MPP_RET hal_dummy_dec_init(void *hal, MppHalCfg *cfg) -{ - (void)hal; - (void)cfg; - return MPP_OK; -} - -MPP_RET hal_dummy_dec_deinit(void *hal) -{ - (void)hal; - return MPP_OK; -} - -MPP_RET hal_dummy_dec_gen_regs(void *hal, HalTaskInfo *task) -{ - (void)hal; - (void)task; - return MPP_OK; -} -MPP_RET hal_dummy_dec_start(void *hal, HalTaskInfo *task) -{ - (void)hal; - (void)task; - return MPP_OK; -} - -MPP_RET hal_dummy_dec_wait(void *hal, HalTaskInfo *task) -{ - (void)hal; - (void)task; - return MPP_OK; -} - -MPP_RET hal_dummy_dec_reset(void *hal) -{ - (void)hal; - return MPP_OK; -} - -MPP_RET hal_dummy_dec_flush(void *hal) -{ - (void)hal; - return MPP_OK; -} - -MPP_RET hal_dummy_dec_control(void *hal, RK_S32 cmd_type, void *param) -{ - (void)hal; - (void)cmd_type; - (void)param; - return MPP_OK; -} - -const MppHalApi hal_api_dummy_dec = { - "dummy_hw_dec", - MPP_CTX_DEC, - MPP_VIDEO_CodingUnused, - 0, - 0, - hal_dummy_dec_init, - hal_dummy_dec_deinit, - hal_dummy_dec_gen_regs, - hal_dummy_dec_start, - hal_dummy_dec_wait, - hal_dummy_dec_reset, - hal_dummy_dec_flush, - hal_dummy_dec_control, -}; - +/* +* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#define MODULE_TAG "hal_dummy_dec" + +#include "hal_dummy_dec_api.h" + + +MPP_RET hal_dummy_dec_init(void *hal, MppHalCfg *cfg) +{ + (void)hal; + (void)cfg; + return MPP_OK; +} + +MPP_RET hal_dummy_dec_deinit(void *hal) +{ + (void)hal; + return MPP_OK; +} + +MPP_RET hal_dummy_dec_gen_regs(void *hal, HalTaskInfo *task) +{ + (void)hal; + (void)task; + return MPP_OK; +} +MPP_RET hal_dummy_dec_start(void *hal, HalTaskInfo *task) +{ + (void)hal; + (void)task; + return MPP_OK; +} + +MPP_RET hal_dummy_dec_wait(void *hal, HalTaskInfo *task) +{ + (void)hal; + (void)task; + return MPP_OK; +} + +MPP_RET hal_dummy_dec_reset(void *hal) +{ + (void)hal; + return MPP_OK; +} + +MPP_RET hal_dummy_dec_flush(void *hal) +{ + (void)hal; + return MPP_OK; +} + +MPP_RET hal_dummy_dec_control(void *hal, RK_S32 cmd_type, void *param) +{ + (void)hal; + (void)cmd_type; + (void)param; + return MPP_OK; +} + +const MppHalApi hal_api_dummy_dec = { + "dummy_hw_dec", + MPP_CTX_DEC, + MPP_VIDEO_CodingUnused, + 0, + 0, + hal_dummy_dec_init, + hal_dummy_dec_deinit, + hal_dummy_dec_gen_regs, + hal_dummy_dec_start, + hal_dummy_dec_wait, + hal_dummy_dec_reset, + hal_dummy_dec_flush, + hal_dummy_dec_control, +}; + diff --git a/mpp/hal/dummy/hal_dummy_enc_api.c b/mpp/hal/dummy/hal_dummy_enc_api.c index 89f84ec7..07f41269 100644 --- a/mpp/hal/dummy/hal_dummy_enc_api.c +++ b/mpp/hal/dummy/hal_dummy_enc_api.c @@ -1,91 +1,91 @@ -/* -* -* Copyright 2015 Rockchip Electronics Co. LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#define MODULE_TAG "hal_dummy_enc" - -#include "hal_dummy_enc_api.h" - - -MPP_RET hal_dummy_enc_init(void *hal, MppHalCfg *cfg) -{ - (void)hal; - (void)cfg; - return MPP_OK; -} - -MPP_RET hal_dummy_enc_deinit(void *hal) -{ - (void)hal; - return MPP_OK; -} - -MPP_RET hal_dummy_enc_gen_regs(void *hal, HalTaskInfo *task) -{ - (void)hal; - (void)task; - return MPP_OK; -} -MPP_RET hal_dummy_enc_start(void *hal, HalTaskInfo *task) -{ - (void)hal; - (void)task; - return MPP_OK; -} - -MPP_RET hal_dummy_enc_wait(void *hal, HalTaskInfo *task) -{ - (void)hal; - (void)task; - return MPP_OK; -} - -MPP_RET hal_dummy_enc_reset(void *hal) -{ - (void)hal; - return MPP_OK; -} - -MPP_RET hal_dummy_enc_flush(void *hal) -{ - (void)hal; - return MPP_OK; -} - -MPP_RET hal_dummy_enc_control(void *hal, RK_S32 cmd_type, void *param) -{ - (void)hal; - (void)cmd_type; - (void)param; - return MPP_OK; -} - -const MppHalApi hal_api_dummy_enc = { - "dummy_hw_enc", - MPP_CTX_ENC, - MPP_VIDEO_CodingUnused, - 0, - 0, - hal_dummy_enc_init, - hal_dummy_enc_deinit, - hal_dummy_enc_gen_regs, - hal_dummy_enc_start, - hal_dummy_enc_wait, - hal_dummy_enc_reset, - hal_dummy_enc_flush, - hal_dummy_enc_control, -}; - +/* +* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#define MODULE_TAG "hal_dummy_enc" + +#include "hal_dummy_enc_api.h" + + +MPP_RET hal_dummy_enc_init(void *hal, MppHalCfg *cfg) +{ + (void)hal; + (void)cfg; + return MPP_OK; +} + +MPP_RET hal_dummy_enc_deinit(void *hal) +{ + (void)hal; + return MPP_OK; +} + +MPP_RET hal_dummy_enc_gen_regs(void *hal, HalTaskInfo *task) +{ + (void)hal; + (void)task; + return MPP_OK; +} +MPP_RET hal_dummy_enc_start(void *hal, HalTaskInfo *task) +{ + (void)hal; + (void)task; + return MPP_OK; +} + +MPP_RET hal_dummy_enc_wait(void *hal, HalTaskInfo *task) +{ + (void)hal; + (void)task; + return MPP_OK; +} + +MPP_RET hal_dummy_enc_reset(void *hal) +{ + (void)hal; + return MPP_OK; +} + +MPP_RET hal_dummy_enc_flush(void *hal) +{ + (void)hal; + return MPP_OK; +} + +MPP_RET hal_dummy_enc_control(void *hal, RK_S32 cmd_type, void *param) +{ + (void)hal; + (void)cmd_type; + (void)param; + return MPP_OK; +} + +const MppHalApi hal_api_dummy_enc = { + "dummy_hw_enc", + MPP_CTX_ENC, + MPP_VIDEO_CodingUnused, + 0, + 0, + hal_dummy_enc_init, + hal_dummy_enc_deinit, + hal_dummy_enc_gen_regs, + hal_dummy_enc_start, + hal_dummy_enc_wait, + hal_dummy_enc_reset, + hal_dummy_enc_flush, + hal_dummy_enc_control, +}; + diff --git a/mpp/hal/hal_regdrv.c b/mpp/hal/hal_regdrv.c index b258e75c..4d337406 100644 --- a/mpp/hal/hal_regdrv.c +++ b/mpp/hal/hal_regdrv.c @@ -1,196 +1,196 @@ -/* -* -* Copyright 2015 Rockchip Electronics Co. LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#define MODULE_TAG "hal_regdrv" -#include -#include -#include "rk_type.h" - -#include "mpp_log.h" -#include "mpp_mem.h" -#include "hal_regdrv.h" - - - -static const RK_U32 reg_mask[33] = { 0x00000000, - 0x00000001, 0x00000003, 0x00000007, 0x0000000F, - 0x0000001F, 0x0000003F, 0x0000007F, 0x000000FF, - 0x000001FF, 0x000003FF, 0x000007FF, 0x00000FFF, - 0x00001FFF, 0x00003FFF, 0x00007FFF, 0x0000FFFF, - 0x0001FFFF, 0x0003FFFF, 0x0007FFFF, 0x000FFFFF, - 0x001FFFFF, 0x003FFFFF, 0x007FFFFF, 0x00FFFFFF, - 0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF, 0x0FFFFFFF, - 0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF - }; - - -/*! -*********************************************************************** -* \brief -* Print register -*********************************************************************** -*/ -//MPP_RET hal_deinit_regdrv (HalRegDrvCtx_t *ctx) -//{ -// if (NULL == ctx) { -// mpp_err_f("found NULL input\n"); -// return MPP_ERR_NULL_PTR; -// } -// MPP_FREE(ctx->p_syn); -// MPP_FREE(ctx->p_reg); -// -// return MPP_OK; -//} - -/*! -*********************************************************************** -* \brief -* Init context -*********************************************************************** -*/ - -//MPP_RET hal_init_regdrv(HalRegDrvCtx_t *ctx) -//{ -// if (NULL == ctx) { -// mpp_err_f("found NULL input\n"); -// return MPP_ERR_NULL_PTR; -// } -// -// if (ctx->reg_size && ctx->syn_size) { -// ctx->p_syn = mpp_malloc(HalRegDrv_t, ctx->syn_size); -// ctx->p_reg = mpp_malloc(RK_U32, ctx->reg_size); -// if ((NULL == ctx->p_syn) ||(NULL == ctx->p_reg)){ -// mpp_err_f("malloc buffer\n"); -// return MPP_ERR_MALLOC; -// } -// } -// -// return MPP_OK; -//} -/*! -*********************************************************************** -* \brief -* set syntax element to the register position -*********************************************************************** -*/ -MPP_RET hal_set_regdrv(HalRegDrvCtx_t *ctx, RK_U32 syn_id, RK_U32 val) -{ - RK_U32 reg_id = 0; - RK_U32 bitpos = 0; - RK_U32 bitlen = 0; - RK_U32 valtmp = 0; - - if (NULL == ctx) { - mpp_err_f("found NULL input\n"); - return MPP_ERR_NULL_PTR; - } - mpp_assert(syn_id < ctx->emt_size); - reg_id = ctx->p_emt[syn_id].reg_id; - bitpos = ctx->p_emt[syn_id].bitpos; - bitlen = ctx->p_emt[syn_id].bitlen; - - valtmp = ctx->p_reg[reg_id]; - valtmp &= ~(reg_mask[bitlen] << bitpos); - valtmp |= (val & reg_mask[bitlen]) << bitpos; - ctx->p_reg[reg_id] = valtmp; - - return MPP_OK; -} -/*! -*********************************************************************** -* \brief -* Get register value from the positon -*********************************************************************** -*/ -MPP_RET hal_get_regdrv(HalRegDrvCtx_t *ctx, RK_U32 syn_id, RK_U32 *pval) -{ - RK_U32 reg_id = 0; - RK_U32 bitpos = 0; - RK_U32 bitlen = 0; - RK_U32 valtmp = 0; - - if (NULL == ctx) { - mpp_err_f("found NULL input\n"); - return MPP_ERR_NULL_PTR; - } - mpp_assert(syn_id < ctx->emt_size); - reg_id = ctx->p_emt[syn_id].reg_id; - bitpos = ctx->p_emt[syn_id].bitpos; - bitlen = ctx->p_emt[syn_id].bitlen; - - valtmp = ctx->p_reg[reg_id]; - valtmp = valtmp >> bitpos; - valtmp &= reg_mask[bitlen]; - - *pval = valtmp; - - return MPP_OK; -} -/*! -*********************************************************************** -* \brief -* Print register -*********************************************************************** -*/ -//MPP_RET hal_print_regdrv(HalRegDrvCtx_t *ctx, RK_U32 syn_id) -//{ -// MPP_RET ret = MPP_ERR_UNKNOW; -// RK_U32 val = 0; -// -// if (NULL == ctx) { -// mpp_err_f("found NULL input\n"); -// return MPP_ERR_NULL_PTR; -// } -// if(ret = hal_get_regdrv(ctx, syn_id, &val)) { -// return ret; -// } -// //if (NULL != ctx->fp) { -// // fprintf(ctx->fp, "%48s = %10d \n", ctx->p_syn[syn_id].name, val); -// //} -// return MPP_OK; -//} - -/*! -*********************************************************************** -* \brief -* get regsize -*********************************************************************** -*/ -RK_U32 hal_get_regsize(HalRegDrvCtx_t *ctx) -{ - if (NULL == ctx) { - mpp_err_f("found NULL input\n"); - return MPP_ERR_NULL_PTR; - } - - return ctx->reg_size; -} -/*! -*********************************************************************** -* \brief -* get reg data -*********************************************************************** -*/ -RK_U32 *hal_get_regptr(HalRegDrvCtx_t *ctx) -{ - if (NULL == ctx) { - mpp_err_f("found NULL input\n"); - return NULL; - } - - return ctx->p_reg; +/* +* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#define MODULE_TAG "hal_regdrv" +#include +#include +#include "rk_type.h" + +#include "mpp_log.h" +#include "mpp_mem.h" +#include "hal_regdrv.h" + + + +static const RK_U32 reg_mask[33] = { 0x00000000, + 0x00000001, 0x00000003, 0x00000007, 0x0000000F, + 0x0000001F, 0x0000003F, 0x0000007F, 0x000000FF, + 0x000001FF, 0x000003FF, 0x000007FF, 0x00000FFF, + 0x00001FFF, 0x00003FFF, 0x00007FFF, 0x0000FFFF, + 0x0001FFFF, 0x0003FFFF, 0x0007FFFF, 0x000FFFFF, + 0x001FFFFF, 0x003FFFFF, 0x007FFFFF, 0x00FFFFFF, + 0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF, 0x0FFFFFFF, + 0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF + }; + + +/*! +*********************************************************************** +* \brief +* Print register +*********************************************************************** +*/ +//MPP_RET hal_deinit_regdrv (HalRegDrvCtx_t *ctx) +//{ +// if (NULL == ctx) { +// mpp_err_f("found NULL input\n"); +// return MPP_ERR_NULL_PTR; +// } +// MPP_FREE(ctx->p_syn); +// MPP_FREE(ctx->p_reg); +// +// return MPP_OK; +//} + +/*! +*********************************************************************** +* \brief +* Init context +*********************************************************************** +*/ + +//MPP_RET hal_init_regdrv(HalRegDrvCtx_t *ctx) +//{ +// if (NULL == ctx) { +// mpp_err_f("found NULL input\n"); +// return MPP_ERR_NULL_PTR; +// } +// +// if (ctx->reg_size && ctx->syn_size) { +// ctx->p_syn = mpp_malloc(HalRegDrv_t, ctx->syn_size); +// ctx->p_reg = mpp_malloc(RK_U32, ctx->reg_size); +// if ((NULL == ctx->p_syn) ||(NULL == ctx->p_reg)){ +// mpp_err_f("malloc buffer\n"); +// return MPP_ERR_MALLOC; +// } +// } +// +// return MPP_OK; +//} +/*! +*********************************************************************** +* \brief +* set syntax element to the register position +*********************************************************************** +*/ +MPP_RET hal_set_regdrv(HalRegDrvCtx_t *ctx, RK_U32 syn_id, RK_U32 val) +{ + RK_U32 reg_id = 0; + RK_U32 bitpos = 0; + RK_U32 bitlen = 0; + RK_U32 valtmp = 0; + + if (NULL == ctx) { + mpp_err_f("found NULL input\n"); + return MPP_ERR_NULL_PTR; + } + mpp_assert(syn_id < ctx->emt_size); + reg_id = ctx->p_emt[syn_id].reg_id; + bitpos = ctx->p_emt[syn_id].bitpos; + bitlen = ctx->p_emt[syn_id].bitlen; + + valtmp = ctx->p_reg[reg_id]; + valtmp &= ~(reg_mask[bitlen] << bitpos); + valtmp |= (val & reg_mask[bitlen]) << bitpos; + ctx->p_reg[reg_id] = valtmp; + + return MPP_OK; +} +/*! +*********************************************************************** +* \brief +* Get register value from the positon +*********************************************************************** +*/ +MPP_RET hal_get_regdrv(HalRegDrvCtx_t *ctx, RK_U32 syn_id, RK_U32 *pval) +{ + RK_U32 reg_id = 0; + RK_U32 bitpos = 0; + RK_U32 bitlen = 0; + RK_U32 valtmp = 0; + + if (NULL == ctx) { + mpp_err_f("found NULL input\n"); + return MPP_ERR_NULL_PTR; + } + mpp_assert(syn_id < ctx->emt_size); + reg_id = ctx->p_emt[syn_id].reg_id; + bitpos = ctx->p_emt[syn_id].bitpos; + bitlen = ctx->p_emt[syn_id].bitlen; + + valtmp = ctx->p_reg[reg_id]; + valtmp = valtmp >> bitpos; + valtmp &= reg_mask[bitlen]; + + *pval = valtmp; + + return MPP_OK; +} +/*! +*********************************************************************** +* \brief +* Print register +*********************************************************************** +*/ +//MPP_RET hal_print_regdrv(HalRegDrvCtx_t *ctx, RK_U32 syn_id) +//{ +// MPP_RET ret = MPP_ERR_UNKNOW; +// RK_U32 val = 0; +// +// if (NULL == ctx) { +// mpp_err_f("found NULL input\n"); +// return MPP_ERR_NULL_PTR; +// } +// if(ret = hal_get_regdrv(ctx, syn_id, &val)) { +// return ret; +// } +// //if (NULL != ctx->fp) { +// // fprintf(ctx->fp, "%48s = %10d \n", ctx->p_syn[syn_id].name, val); +// //} +// return MPP_OK; +//} + +/*! +*********************************************************************** +* \brief +* get regsize +*********************************************************************** +*/ +RK_U32 hal_get_regsize(HalRegDrvCtx_t *ctx) +{ + if (NULL == ctx) { + mpp_err_f("found NULL input\n"); + return MPP_ERR_NULL_PTR; + } + + return ctx->reg_size; +} +/*! +*********************************************************************** +* \brief +* get reg data +*********************************************************************** +*/ +RK_U32 *hal_get_regptr(HalRegDrvCtx_t *ctx) +{ + if (NULL == ctx) { + mpp_err_f("found NULL input\n"); + return NULL; + } + + return ctx->p_reg; } \ No newline at end of file diff --git a/mpp/hal/hal_task.cpp b/mpp/hal/hal_task.cpp index 2d8ac63d..255b3dbb 100644 --- a/mpp/hal/hal_task.cpp +++ b/mpp/hal/hal_task.cpp @@ -1,244 +1,244 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define MODULE_TAG "hal_task" - -#include - -#include "mpp_mem.h" -#include "mpp_log.h" -#include "mpp_list.h" - -#include "hal_task.h" - -typedef struct HalTaskImpl_t HalTaskImpl; -typedef struct HalTaskGroupImpl_t HalTaskGroupImpl; - -struct HalTaskImpl_t { - struct list_head list; - HalTaskGroupImpl *group; - RK_S32 index; - HalTaskStatus status; - HalTaskInfo task; -}; - -struct HalTaskGroupImpl_t { - MppCtxType type; - RK_S32 task_count; - - Mutex *lock; - - HalTaskImpl *tasks; - struct list_head list[TASK_BUTT]; - RK_U32 count[TASK_BUTT]; -}; - -MPP_RET hal_task_group_init(HalTaskGroup *group, MppCtxType type, RK_S32 count) -{ - if (NULL == group) { - mpp_err_f("found invalid input group %p count %d\n", group, count); - return MPP_ERR_UNKNOW; - } - - HalTaskGroupImpl *p = NULL; - HalTaskImpl *tasks = NULL; - Mutex *lock = NULL; - - do { - p = mpp_calloc(HalTaskGroupImpl, 1); - if (NULL == p) { - mpp_err_f("malloc group failed\n"); - break; - } - lock = new Mutex(); - if (NULL == lock) { - mpp_err_f("new lock failed\n"); - break;; - } - tasks = mpp_calloc(HalTaskImpl, count); - if (NULL == tasks) { - mpp_err_f("malloc tasks list failed\n"); - break;; - } - - p->type = type; - p->task_count = count; - p->lock = lock; - p->tasks = tasks; - - for (RK_U32 i = 0; i < TASK_BUTT; i++) - INIT_LIST_HEAD(&p->list[i]); - - for (RK_S32 i = 0; i < count; i++) { - INIT_LIST_HEAD(&tasks[i].list); - tasks[i].index = i; - tasks[i].group = p; - tasks[i].status = TASK_IDLE; - list_add_tail(&tasks[i].list, &p->list[TASK_IDLE]); - p->count[TASK_IDLE]++; - } - *group = p; - return MPP_OK; - } while (0); - - if (p) - mpp_free(p); - if (lock) - delete lock; - if (tasks) - mpp_free(tasks); - - *group = NULL; - return MPP_NOK; -} - -MPP_RET hal_task_group_deinit(HalTaskGroup group) -{ - if (NULL == group) { - mpp_err_f("found NULL input group\n"); - return MPP_ERR_NULL_PTR; - } - - HalTaskGroupImpl *p = (HalTaskGroupImpl *)group; - if (p->tasks) - mpp_free(p->tasks); - if (p->lock) - delete p->lock; - mpp_free(p); - return MPP_OK; -} - -MPP_RET hal_task_get_hnd(HalTaskGroup group, HalTaskStatus status, HalTaskHnd *hnd) -{ - if (NULL == group || status >= TASK_BUTT || NULL == hnd) { - mpp_err_f("found invaid input group %p status %d hnd %p\n", group, status, hnd); - return MPP_ERR_UNKNOW; - } - - *hnd = NULL; - HalTaskGroupImpl *p = (HalTaskGroupImpl *)group; - AutoMutex auto_lock(p->lock); - struct list_head *list = &p->list[status]; - if (list_empty(list)) - return MPP_NOK; - - HalTaskImpl *task = list_entry(list->next, HalTaskImpl, list); - mpp_assert(task->status == status); - *hnd = task; - return MPP_OK; -} - -MPP_RET hal_task_check_empty(HalTaskGroup group, HalTaskStatus status) -{ - if (NULL == group || status >= TASK_BUTT) { - mpp_err_f("found invaid input group %p status %d \n", group, status); - return MPP_ERR_UNKNOW; - } - HalTaskGroupImpl *p = (HalTaskGroupImpl *)group; - AutoMutex auto_lock(p->lock); - struct list_head *list = &p->list[status]; - if (list_empty(list)) { - return MPP_OK; - } - return MPP_NOK; -} -MPP_RET hal_task_get_count(HalTaskGroup group, HalTaskStatus status, RK_U32 *count) -{ - if (NULL == group || status >= TASK_BUTT || NULL == count) { - mpp_err_f("found invaid input group %p status %d count %p\n", group, status, count); - return MPP_ERR_UNKNOW; - } - - HalTaskGroupImpl *p = (HalTaskGroupImpl *)group; - AutoMutex auto_lock(p->lock); - *count = p->count[status]; - return MPP_OK; -} - -MPP_RET hal_task_hnd_set_status(HalTaskHnd hnd, HalTaskStatus status) -{ - if (NULL == hnd || status >= TASK_BUTT) { - mpp_err_f("found invaid input hnd %p status %d\n", hnd, status); - return MPP_ERR_UNKNOW; - } - - HalTaskImpl *impl = (HalTaskImpl *)hnd; - HalTaskGroupImpl *group = impl->group; - mpp_assert(group); - mpp_assert(impl->index < group->task_count); - - AutoMutex auto_lock(group->lock); - list_del_init(&impl->list); - list_add_tail(&impl->list, &group->list[status]); - group->count[impl->status]--; - group->count[status]++; - impl->status = status; - return MPP_OK; -} - -MPP_RET hal_task_hnd_set_info(HalTaskHnd hnd, HalTaskInfo *task) -{ - if (NULL == hnd || NULL == task) { - mpp_err_f("found invaid input hnd %p task %p\n", hnd, task); - return MPP_ERR_UNKNOW; - } - - HalTaskImpl *impl = (HalTaskImpl *)hnd; - HalTaskGroupImpl *group = impl->group; - mpp_assert(impl->index < group->task_count); - AutoMutex auto_lock(group->lock); - memcpy(&impl->task, task, sizeof(impl->task)); - return MPP_OK; -} - -MPP_RET hal_task_hnd_get_info(HalTaskHnd hnd, HalTaskInfo *task) -{ - if (NULL == hnd || NULL == task) { - mpp_err_f("found invaid input hnd %p task %p\n", hnd, task); - return MPP_ERR_UNKNOW; - } - - HalTaskImpl *impl = (HalTaskImpl *)hnd; - HalTaskGroupImpl *group = impl->group; - mpp_assert(impl->index < group->task_count); - AutoMutex auto_lock(group->lock); - memcpy(task, &impl->task, sizeof(impl->task)); - return MPP_OK; -} - -MPP_RET hal_task_info_init(HalTaskInfo *task, MppCtxType type) -{ - if (NULL == task || type >= MPP_CTX_BUTT) { - mpp_err_f("found invalid input task %p type %d\n", task, type); - return MPP_ERR_UNKNOW; - } - if (MPP_CTX_DEC == type) { - HalDecTask *p = &task->dec; - p->valid = 0; - p->flags.val = 0; - p->flags.eos = 0; - p->prev_status = 0; - p->input_packet = NULL; - p->output = -1; - p->input = -1; - memset(&task->dec.syntax, 0, sizeof(task->dec.syntax)); - memset(task->dec.refer, -1, sizeof(task->dec.refer)); - } else { - memset(&task->enc, 0, sizeof(task->enc)); - } - return MPP_OK; -} - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define MODULE_TAG "hal_task" + +#include + +#include "mpp_mem.h" +#include "mpp_log.h" +#include "mpp_list.h" + +#include "hal_task.h" + +typedef struct HalTaskImpl_t HalTaskImpl; +typedef struct HalTaskGroupImpl_t HalTaskGroupImpl; + +struct HalTaskImpl_t { + struct list_head list; + HalTaskGroupImpl *group; + RK_S32 index; + HalTaskStatus status; + HalTaskInfo task; +}; + +struct HalTaskGroupImpl_t { + MppCtxType type; + RK_S32 task_count; + + Mutex *lock; + + HalTaskImpl *tasks; + struct list_head list[TASK_BUTT]; + RK_U32 count[TASK_BUTT]; +}; + +MPP_RET hal_task_group_init(HalTaskGroup *group, MppCtxType type, RK_S32 count) +{ + if (NULL == group) { + mpp_err_f("found invalid input group %p count %d\n", group, count); + return MPP_ERR_UNKNOW; + } + + HalTaskGroupImpl *p = NULL; + HalTaskImpl *tasks = NULL; + Mutex *lock = NULL; + + do { + p = mpp_calloc(HalTaskGroupImpl, 1); + if (NULL == p) { + mpp_err_f("malloc group failed\n"); + break; + } + lock = new Mutex(); + if (NULL == lock) { + mpp_err_f("new lock failed\n"); + break;; + } + tasks = mpp_calloc(HalTaskImpl, count); + if (NULL == tasks) { + mpp_err_f("malloc tasks list failed\n"); + break;; + } + + p->type = type; + p->task_count = count; + p->lock = lock; + p->tasks = tasks; + + for (RK_U32 i = 0; i < TASK_BUTT; i++) + INIT_LIST_HEAD(&p->list[i]); + + for (RK_S32 i = 0; i < count; i++) { + INIT_LIST_HEAD(&tasks[i].list); + tasks[i].index = i; + tasks[i].group = p; + tasks[i].status = TASK_IDLE; + list_add_tail(&tasks[i].list, &p->list[TASK_IDLE]); + p->count[TASK_IDLE]++; + } + *group = p; + return MPP_OK; + } while (0); + + if (p) + mpp_free(p); + if (lock) + delete lock; + if (tasks) + mpp_free(tasks); + + *group = NULL; + return MPP_NOK; +} + +MPP_RET hal_task_group_deinit(HalTaskGroup group) +{ + if (NULL == group) { + mpp_err_f("found NULL input group\n"); + return MPP_ERR_NULL_PTR; + } + + HalTaskGroupImpl *p = (HalTaskGroupImpl *)group; + if (p->tasks) + mpp_free(p->tasks); + if (p->lock) + delete p->lock; + mpp_free(p); + return MPP_OK; +} + +MPP_RET hal_task_get_hnd(HalTaskGroup group, HalTaskStatus status, HalTaskHnd *hnd) +{ + if (NULL == group || status >= TASK_BUTT || NULL == hnd) { + mpp_err_f("found invaid input group %p status %d hnd %p\n", group, status, hnd); + return MPP_ERR_UNKNOW; + } + + *hnd = NULL; + HalTaskGroupImpl *p = (HalTaskGroupImpl *)group; + AutoMutex auto_lock(p->lock); + struct list_head *list = &p->list[status]; + if (list_empty(list)) + return MPP_NOK; + + HalTaskImpl *task = list_entry(list->next, HalTaskImpl, list); + mpp_assert(task->status == status); + *hnd = task; + return MPP_OK; +} + +MPP_RET hal_task_check_empty(HalTaskGroup group, HalTaskStatus status) +{ + if (NULL == group || status >= TASK_BUTT) { + mpp_err_f("found invaid input group %p status %d \n", group, status); + return MPP_ERR_UNKNOW; + } + HalTaskGroupImpl *p = (HalTaskGroupImpl *)group; + AutoMutex auto_lock(p->lock); + struct list_head *list = &p->list[status]; + if (list_empty(list)) { + return MPP_OK; + } + return MPP_NOK; +} +MPP_RET hal_task_get_count(HalTaskGroup group, HalTaskStatus status, RK_U32 *count) +{ + if (NULL == group || status >= TASK_BUTT || NULL == count) { + mpp_err_f("found invaid input group %p status %d count %p\n", group, status, count); + return MPP_ERR_UNKNOW; + } + + HalTaskGroupImpl *p = (HalTaskGroupImpl *)group; + AutoMutex auto_lock(p->lock); + *count = p->count[status]; + return MPP_OK; +} + +MPP_RET hal_task_hnd_set_status(HalTaskHnd hnd, HalTaskStatus status) +{ + if (NULL == hnd || status >= TASK_BUTT) { + mpp_err_f("found invaid input hnd %p status %d\n", hnd, status); + return MPP_ERR_UNKNOW; + } + + HalTaskImpl *impl = (HalTaskImpl *)hnd; + HalTaskGroupImpl *group = impl->group; + mpp_assert(group); + mpp_assert(impl->index < group->task_count); + + AutoMutex auto_lock(group->lock); + list_del_init(&impl->list); + list_add_tail(&impl->list, &group->list[status]); + group->count[impl->status]--; + group->count[status]++; + impl->status = status; + return MPP_OK; +} + +MPP_RET hal_task_hnd_set_info(HalTaskHnd hnd, HalTaskInfo *task) +{ + if (NULL == hnd || NULL == task) { + mpp_err_f("found invaid input hnd %p task %p\n", hnd, task); + return MPP_ERR_UNKNOW; + } + + HalTaskImpl *impl = (HalTaskImpl *)hnd; + HalTaskGroupImpl *group = impl->group; + mpp_assert(impl->index < group->task_count); + AutoMutex auto_lock(group->lock); + memcpy(&impl->task, task, sizeof(impl->task)); + return MPP_OK; +} + +MPP_RET hal_task_hnd_get_info(HalTaskHnd hnd, HalTaskInfo *task) +{ + if (NULL == hnd || NULL == task) { + mpp_err_f("found invaid input hnd %p task %p\n", hnd, task); + return MPP_ERR_UNKNOW; + } + + HalTaskImpl *impl = (HalTaskImpl *)hnd; + HalTaskGroupImpl *group = impl->group; + mpp_assert(impl->index < group->task_count); + AutoMutex auto_lock(group->lock); + memcpy(task, &impl->task, sizeof(impl->task)); + return MPP_OK; +} + +MPP_RET hal_task_info_init(HalTaskInfo *task, MppCtxType type) +{ + if (NULL == task || type >= MPP_CTX_BUTT) { + mpp_err_f("found invalid input task %p type %d\n", task, type); + return MPP_ERR_UNKNOW; + } + if (MPP_CTX_DEC == type) { + HalDecTask *p = &task->dec; + p->valid = 0; + p->flags.val = 0; + p->flags.eos = 0; + p->prev_status = 0; + p->input_packet = NULL; + p->output = -1; + p->input = -1; + memset(&task->dec.syntax, 0, sizeof(task->dec.syntax)); + memset(task->dec.refer, -1, sizeof(task->dec.refer)); + } else { + memset(&task->enc, 0, sizeof(task->enc)); + } + return MPP_OK; +} + diff --git a/mpp/hal/inc/hal_avsd_api.h b/mpp/hal/inc/hal_avsd_api.h index f7adb755..7f890e54 100644 --- a/mpp/hal/inc/hal_avsd_api.h +++ b/mpp/hal/inc/hal_avsd_api.h @@ -1,96 +1,96 @@ -/* -* -* Copyright 2015 Rockchip Electronics Co. LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - - -#ifndef __HAL_AVSD_API_H__ -#define __HAL_AVSD_API_H__ - -#include "rk_type.h" -#include "mpp_err.h" -#include "mpp_hal.h" - - - -#define AVSD_HAL_DBG_ERROR (0x00000001) -#define AVSD_HAL_DBG_ASSERT (0x00000002) -#define AVSD_HAL_DBG_WARNNING (0x00000004) -#define AVSD_HAL_DBG_TRACE (0x00000008) - - - -extern RK_U32 avsd_hal_debug; - - - -#define AVSD_HAL_DBG(level, fmt, ...)\ -do {\ - if (level & avsd_hal_debug)\ - { mpp_log(fmt, ## __VA_ARGS__); }\ -} while (0) - - -#define AVSD_HAL_TRACE(fmt, ...)\ -do {\ - if (AVSD_HAL_DBG_TRACE & avsd_hal_debug)\ - { mpp_log_f(fmt, ## __VA_ARGS__); }\ -} while (0) - -#ifdef INP_CHECK -#undef INP_CHECK -#endif - -//!< input check -#define INP_CHECK(ret, val, ...)\ -do{\ -if ((val)) { \ - ret = MPP_ERR_INIT; \ - AVSD_HAL_DBG(AVSD_HAL_DBG_WARNNING, "input empty(%d).\n", __LINE__); \ - goto __RETURN; \ -}} while (0) - - -typedef struct avsd_hal_ctx_t { - - MppBufSlots frame_slots; - MppBufSlots packet_slots; - IOInterruptCB init_cb; - -} AvsdHalCtx_t; - - - - -#ifdef __cplusplus -extern "C" { -#endif - -extern const MppHalApi hal_api_avsd; - -MPP_RET hal_avsd_init (void *decoder, MppHalCfg *cfg); -MPP_RET hal_avsd_deinit (void *decoder); -MPP_RET hal_avsd_gen_regs(void *decoder, HalTaskInfo *task); -MPP_RET hal_avsd_start (void *decoder, HalTaskInfo *task); -MPP_RET hal_avsd_wait (void *decoder, HalTaskInfo *task); -MPP_RET hal_avsd_reset (void *decoder); -MPP_RET hal_avsd_flush (void *decoder); -MPP_RET hal_avsd_control (void *decoder, RK_S32 cmd_type, void *param); - -#ifdef __cplusplus -} -#endif - -#endif /*__HAL_AVSD_API_H__*/ +/* +* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +#ifndef __HAL_AVSD_API_H__ +#define __HAL_AVSD_API_H__ + +#include "rk_type.h" +#include "mpp_err.h" +#include "mpp_hal.h" + + + +#define AVSD_HAL_DBG_ERROR (0x00000001) +#define AVSD_HAL_DBG_ASSERT (0x00000002) +#define AVSD_HAL_DBG_WARNNING (0x00000004) +#define AVSD_HAL_DBG_TRACE (0x00000008) + + + +extern RK_U32 avsd_hal_debug; + + + +#define AVSD_HAL_DBG(level, fmt, ...)\ +do {\ + if (level & avsd_hal_debug)\ + { mpp_log(fmt, ## __VA_ARGS__); }\ +} while (0) + + +#define AVSD_HAL_TRACE(fmt, ...)\ +do {\ + if (AVSD_HAL_DBG_TRACE & avsd_hal_debug)\ + { mpp_log_f(fmt, ## __VA_ARGS__); }\ +} while (0) + +#ifdef INP_CHECK +#undef INP_CHECK +#endif + +//!< input check +#define INP_CHECK(ret, val, ...)\ +do{\ +if ((val)) { \ + ret = MPP_ERR_INIT; \ + AVSD_HAL_DBG(AVSD_HAL_DBG_WARNNING, "input empty(%d).\n", __LINE__); \ + goto __RETURN; \ +}} while (0) + + +typedef struct avsd_hal_ctx_t { + + MppBufSlots frame_slots; + MppBufSlots packet_slots; + IOInterruptCB init_cb; + +} AvsdHalCtx_t; + + + + +#ifdef __cplusplus +extern "C" { +#endif + +extern const MppHalApi hal_api_avsd; + +MPP_RET hal_avsd_init (void *decoder, MppHalCfg *cfg); +MPP_RET hal_avsd_deinit (void *decoder); +MPP_RET hal_avsd_gen_regs(void *decoder, HalTaskInfo *task); +MPP_RET hal_avsd_start (void *decoder, HalTaskInfo *task); +MPP_RET hal_avsd_wait (void *decoder, HalTaskInfo *task); +MPP_RET hal_avsd_reset (void *decoder); +MPP_RET hal_avsd_flush (void *decoder); +MPP_RET hal_avsd_control (void *decoder, RK_S32 cmd_type, void *param); + +#ifdef __cplusplus +} +#endif + +#endif /*__HAL_AVSD_API_H__*/ diff --git a/mpp/hal/inc/hal_dummy_dec_api.h b/mpp/hal/inc/hal_dummy_dec_api.h index 4f9c6cfa..03927732 100644 --- a/mpp/hal/inc/hal_dummy_dec_api.h +++ b/mpp/hal/inc/hal_dummy_dec_api.h @@ -1,34 +1,34 @@ -/* -* -* Copyright 2015 Rockchip Electronics Co. LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - - -#ifndef __HAL_DUMMY_DEC_API_H__ -#define __HAL_DUMMY_DEC_API_H__ - -#include "mpp_hal.h" - -#ifdef __cplusplus -extern "C" { -#endif - -extern const MppHalApi hal_api_dummy_dec; - -#ifdef __cplusplus -} -#endif - -#endif /*__HAL_DUMMY_DEC_API_H__*/ +/* +* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +#ifndef __HAL_DUMMY_DEC_API_H__ +#define __HAL_DUMMY_DEC_API_H__ + +#include "mpp_hal.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern const MppHalApi hal_api_dummy_dec; + +#ifdef __cplusplus +} +#endif + +#endif /*__HAL_DUMMY_DEC_API_H__*/ diff --git a/mpp/hal/inc/hal_dummy_enc_api.h b/mpp/hal/inc/hal_dummy_enc_api.h index 19be92e4..37429045 100644 --- a/mpp/hal/inc/hal_dummy_enc_api.h +++ b/mpp/hal/inc/hal_dummy_enc_api.h @@ -1,34 +1,34 @@ -/* -* -* Copyright 2015 Rockchip Electronics Co. LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - - -#ifndef __HAL_DUMMY_ENC_API_H__ -#define __HAL_DUMMY_ENC_API_H__ - -#include "mpp_hal.h" - -#ifdef __cplusplus -extern "C" { -#endif - -extern const MppHalApi hal_api_dummy_enc; - -#ifdef __cplusplus -} -#endif - -#endif /*__HAL_DUMMY_ENC_API_H__*/ +/* +* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +#ifndef __HAL_DUMMY_ENC_API_H__ +#define __HAL_DUMMY_ENC_API_H__ + +#include "mpp_hal.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern const MppHalApi hal_api_dummy_enc; + +#ifdef __cplusplus +} +#endif + +#endif /*__HAL_DUMMY_ENC_API_H__*/ diff --git a/mpp/hal/inc/hal_h264d_api.h b/mpp/hal/inc/hal_h264d_api.h index 87a446f2..492a7e9e 100644 --- a/mpp/hal/inc/hal_h264d_api.h +++ b/mpp/hal/inc/hal_h264d_api.h @@ -1,47 +1,47 @@ -/* -* -* Copyright 2015 Rockchip Electronics Co. LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - - -#ifndef __HAL_H264D_API_H__ -#define __HAL_H264D_API_H__ - -#include "rk_type.h" -#include "mpp_err.h" -#include "mpp_hal.h" - - - -#ifdef __cplusplus -extern "C" { -#endif - -extern const MppHalApi hal_api_h264d; - -MPP_RET hal_h264d_init (void *hal, MppHalCfg *cfg); -MPP_RET hal_h264d_deinit (void *hal); -MPP_RET hal_h264d_gen_regs(void *hal, HalTaskInfo *task); -MPP_RET hal_h264d_start (void *hal, HalTaskInfo *task); -MPP_RET hal_h264d_wait (void *hal, HalTaskInfo *task); -MPP_RET hal_h264d_reset (void *hal); -MPP_RET hal_h264d_flush (void *hal); -MPP_RET hal_h264d_control (void *hal, RK_S32 cmd_type, void *param); - -#ifdef __cplusplus -} -#endif - -#endif /*__HAL_H264D_API_H__*/ +/* +* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +#ifndef __HAL_H264D_API_H__ +#define __HAL_H264D_API_H__ + +#include "rk_type.h" +#include "mpp_err.h" +#include "mpp_hal.h" + + + +#ifdef __cplusplus +extern "C" { +#endif + +extern const MppHalApi hal_api_h264d; + +MPP_RET hal_h264d_init (void *hal, MppHalCfg *cfg); +MPP_RET hal_h264d_deinit (void *hal); +MPP_RET hal_h264d_gen_regs(void *hal, HalTaskInfo *task); +MPP_RET hal_h264d_start (void *hal, HalTaskInfo *task); +MPP_RET hal_h264d_wait (void *hal, HalTaskInfo *task); +MPP_RET hal_h264d_reset (void *hal); +MPP_RET hal_h264d_flush (void *hal); +MPP_RET hal_h264d_control (void *hal, RK_S32 cmd_type, void *param); + +#ifdef __cplusplus +} +#endif + +#endif /*__HAL_H264D_API_H__*/ diff --git a/mpp/hal/inc/hal_h264e_api.h b/mpp/hal/inc/hal_h264e_api.h index c6015bbd..480e50a2 100644 --- a/mpp/hal/inc/hal_h264e_api.h +++ b/mpp/hal/inc/hal_h264e_api.h @@ -1,25 +1,25 @@ -#ifndef __HAL_H264E_API_H__ -#define __HAL_H264E_API_H__ - -#include "mpp_hal.h" - -#ifdef __cplusplus -extern "C" { -#endif - -extern const MppHalApi hal_api_h264e; - -MPP_RET hal_h264e_init (void *hal, MppHalCfg *cfg); -MPP_RET hal_h264e_deinit (void *hal); -MPP_RET hal_h264e_gen_regs(void *hal, HalTaskInfo *task); -MPP_RET hal_h264e_start (void *hal, HalTaskInfo *task); -MPP_RET hal_h264e_wait (void *hal, HalTaskInfo *task); -MPP_RET hal_h264e_reset (void *hal); -MPP_RET hal_h264e_flush (void *hal); -MPP_RET hal_h264e_control (void *hal, RK_S32 cmd_type, void *param); - -#ifdef __cplusplus -} -#endif - +#ifndef __HAL_H264E_API_H__ +#define __HAL_H264E_API_H__ + +#include "mpp_hal.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern const MppHalApi hal_api_h264e; + +MPP_RET hal_h264e_init (void *hal, MppHalCfg *cfg); +MPP_RET hal_h264e_deinit (void *hal); +MPP_RET hal_h264e_gen_regs(void *hal, HalTaskInfo *task); +MPP_RET hal_h264e_start (void *hal, HalTaskInfo *task); +MPP_RET hal_h264e_wait (void *hal, HalTaskInfo *task); +MPP_RET hal_h264e_reset (void *hal); +MPP_RET hal_h264e_flush (void *hal); +MPP_RET hal_h264e_control (void *hal, RK_S32 cmd_type, void *param); + +#ifdef __cplusplus +} +#endif + #endif \ No newline at end of file diff --git a/mpp/hal/inc/hal_h265d_api.h b/mpp/hal/inc/hal_h265d_api.h index f9c4eb71..4a21dbda 100644 --- a/mpp/hal/inc/hal_h265d_api.h +++ b/mpp/hal/inc/hal_h265d_api.h @@ -1,47 +1,47 @@ -/* -* -* Copyright 2015 Rockchip Electronics Co. LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - - -#ifndef __HAL_H265D_API_H__ -#define __HAL_H265D_API_H__ - -#include "rk_type.h" -#include "mpp_err.h" -#include "mpp_hal.h" - - - -#ifdef __cplusplus -extern "C" { -#endif - -extern const MppHalApi hal_api_h265d; - -RK_S32 hal_h265d_init(void *hal, MppHalCfg *cfg); -RK_S32 hal_h265d_gen_regs(void *hal, HalTaskInfo *syn); -RK_S32 hal_h265d_deinit(void *hal); -MPP_RET hal_h265d_start(void *hal, HalTaskInfo *task); -MPP_RET hal_h265d_wait(void *hal, HalTaskInfo *task); -MPP_RET hal_h265d_reset(void *hal); -MPP_RET hal_h265d_flush(void *hal); -MPP_RET hal_h265d_control(void *hal, RK_S32 cmd_type, void *param); - -#ifdef __cplusplus -} -#endif - -#endif /*__HAL_H265D_API_H__*/ +/* +* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +#ifndef __HAL_H265D_API_H__ +#define __HAL_H265D_API_H__ + +#include "rk_type.h" +#include "mpp_err.h" +#include "mpp_hal.h" + + + +#ifdef __cplusplus +extern "C" { +#endif + +extern const MppHalApi hal_api_h265d; + +RK_S32 hal_h265d_init(void *hal, MppHalCfg *cfg); +RK_S32 hal_h265d_gen_regs(void *hal, HalTaskInfo *syn); +RK_S32 hal_h265d_deinit(void *hal); +MPP_RET hal_h265d_start(void *hal, HalTaskInfo *task); +MPP_RET hal_h265d_wait(void *hal, HalTaskInfo *task); +MPP_RET hal_h265d_reset(void *hal); +MPP_RET hal_h265d_flush(void *hal); +MPP_RET hal_h265d_control(void *hal, RK_S32 cmd_type, void *param); + +#ifdef __cplusplus +} +#endif + +#endif /*__HAL_H265D_API_H__*/ diff --git a/mpp/hal/inc/hal_jpegd_api.h b/mpp/hal/inc/hal_jpegd_api.h index 93bf2657..ad0e8610 100644 --- a/mpp/hal/inc/hal_jpegd_api.h +++ b/mpp/hal/inc/hal_jpegd_api.h @@ -1,47 +1,47 @@ -/* -* -* Copyright 2015 Rockchip Electronics Co. LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - - -#ifndef __HAL_JPEGD_API_H__ -#define __HAL_JPEGD_API_H__ - -#include "rk_type.h" -#include "mpp_err.h" -#include "mpp_hal.h" - - - -#ifdef __cplusplus -extern "C" { -#endif - -extern const MppHalApi hal_api_jpegd; - -RK_S32 hal_jpegd_init(void *hal, MppHalCfg *cfg); -RK_S32 hal_jpegd_gen_regs(void *hal, HalTaskInfo *syn); -RK_S32 hal_jpegd_deinit(void *hal); -MPP_RET hal_jpegd_start(void *hal, HalTaskInfo *task); -MPP_RET hal_jpegd_wait(void *hal, HalTaskInfo *task); -MPP_RET hal_jpegd_reset(void *hal); -MPP_RET hal_jpegd_flush(void *hal); -MPP_RET hal_jpegd_control(void *hal, RK_S32 cmd_type, void *param); - -#ifdef __cplusplus -} -#endif - -#endif /*__HAL_JPEGD_API_H__*/ +/* +* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +#ifndef __HAL_JPEGD_API_H__ +#define __HAL_JPEGD_API_H__ + +#include "rk_type.h" +#include "mpp_err.h" +#include "mpp_hal.h" + + + +#ifdef __cplusplus +extern "C" { +#endif + +extern const MppHalApi hal_api_jpegd; + +RK_S32 hal_jpegd_init(void *hal, MppHalCfg *cfg); +RK_S32 hal_jpegd_gen_regs(void *hal, HalTaskInfo *syn); +RK_S32 hal_jpegd_deinit(void *hal); +MPP_RET hal_jpegd_start(void *hal, HalTaskInfo *task); +MPP_RET hal_jpegd_wait(void *hal, HalTaskInfo *task); +MPP_RET hal_jpegd_reset(void *hal); +MPP_RET hal_jpegd_flush(void *hal); +MPP_RET hal_jpegd_control(void *hal, RK_S32 cmd_type, void *param); + +#ifdef __cplusplus +} +#endif + +#endif /*__HAL_JPEGD_API_H__*/ diff --git a/mpp/hal/inc/hal_m2vd_api.h b/mpp/hal/inc/hal_m2vd_api.h index 62064760..def0d6c2 100644 --- a/mpp/hal/inc/hal_m2vd_api.h +++ b/mpp/hal/inc/hal_m2vd_api.h @@ -1,32 +1,32 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __HAL_M2VD_API_H__ -#define __HAL_M2VD_API_H__ - -#include "mpp_hal.h" - -#ifdef __cplusplus -extern "C" { -#endif - -extern const MppHalApi hal_api_m2vd; - -#ifdef __cplusplus -} -#endif - -#endif /*__HAL_M2VD_API_H__*/ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __HAL_M2VD_API_H__ +#define __HAL_M2VD_API_H__ + +#include "mpp_hal.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern const MppHalApi hal_api_m2vd; + +#ifdef __cplusplus +} +#endif + +#endif /*__HAL_M2VD_API_H__*/ diff --git a/mpp/hal/inc/hal_regdrv.h b/mpp/hal/inc/hal_regdrv.h index b9ce2d98..c7711979 100644 --- a/mpp/hal/inc/hal_regdrv.h +++ b/mpp/hal/inc/hal_regdrv.h @@ -1,67 +1,67 @@ -/* -* -* Copyright 2015 Rockchip Electronics Co. LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -#ifndef __HAL_REGDRV_H__ -#define __HAL_REGDRV_H__ - -#include -#include "rk_type.h" -#include "mpp_err.h" -#include "rk_mpi.h" - - - -typedef struct hal_regdrv_t { - RK_U32 syn_id; - RK_U32 reg_id; - RK_U32 bitlen; - RK_U32 bitpos; - char *name; -} HalRegDrv_t; - - - -typedef struct hal_regctx_t { - MppCtxType type; - MppCodingType coding; - RK_U32 reg_size; //!< hard regs count - RK_U32 *p_reg; - RK_U32 emt_size; //!< last reg syntax - HalRegDrv_t *p_emt; - void *log; //!< for debug -} HalRegDrvCtx_t; - - - -#ifdef __cplusplus -extern "C" { -#endif - -//MPP_RET hal_init_regdrv (HalRegDrvCtx_t *ctx); -MPP_RET hal_set_regdrv (HalRegDrvCtx_t *ctx, RK_U32 syn_id, RK_U32 val); -MPP_RET hal_get_regdrv (HalRegDrvCtx_t *ctx, RK_U32 syn_id, RK_U32 *pval); -//MPP_RET hal_print_regdrv (HalRegDrvCtx_t *ctx, RK_U32 syn_id); -//MPP_RET hal_deinit_regdrv (HalRegDrvCtx_t *ctx); - -RK_U32 hal_get_regsize (HalRegDrvCtx_t *ctx); -RK_U32 *hal_get_regptr (HalRegDrvCtx_t *ctx); - -#ifdef __cplusplus -} -#endif - - -#endif /* __HAL_REGDRV_H__ */ +/* +* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#ifndef __HAL_REGDRV_H__ +#define __HAL_REGDRV_H__ + +#include +#include "rk_type.h" +#include "mpp_err.h" +#include "rk_mpi.h" + + + +typedef struct hal_regdrv_t { + RK_U32 syn_id; + RK_U32 reg_id; + RK_U32 bitlen; + RK_U32 bitpos; + char *name; +} HalRegDrv_t; + + + +typedef struct hal_regctx_t { + MppCtxType type; + MppCodingType coding; + RK_U32 reg_size; //!< hard regs count + RK_U32 *p_reg; + RK_U32 emt_size; //!< last reg syntax + HalRegDrv_t *p_emt; + void *log; //!< for debug +} HalRegDrvCtx_t; + + + +#ifdef __cplusplus +extern "C" { +#endif + +//MPP_RET hal_init_regdrv (HalRegDrvCtx_t *ctx); +MPP_RET hal_set_regdrv (HalRegDrvCtx_t *ctx, RK_U32 syn_id, RK_U32 val); +MPP_RET hal_get_regdrv (HalRegDrvCtx_t *ctx, RK_U32 syn_id, RK_U32 *pval); +//MPP_RET hal_print_regdrv (HalRegDrvCtx_t *ctx, RK_U32 syn_id); +//MPP_RET hal_deinit_regdrv (HalRegDrvCtx_t *ctx); + +RK_U32 hal_get_regsize (HalRegDrvCtx_t *ctx); +RK_U32 *hal_get_regptr (HalRegDrvCtx_t *ctx); + +#ifdef __cplusplus +} +#endif + + +#endif /* __HAL_REGDRV_H__ */ diff --git a/mpp/hal/inc/hal_task.h b/mpp/hal/inc/hal_task.h index 59a9c4b6..6f349696 100644 --- a/mpp/hal/inc/hal_task.h +++ b/mpp/hal/inc/hal_task.h @@ -1,207 +1,207 @@ -/* -* -* Copyright 2015 Rockchip Electronics Co. LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#ifndef __HAL_TASK__ -#define __HAL_TASK__ - -#include "rk_mpi.h" - -#define MAX_DEC_REF_NUM 17 - -typedef enum HalTaskStatus_e { - TASK_IDLE, - TASK_PREPARE, - TASK_WAIT_PROC, - TASK_PROCESSING, - TASK_PROC_DONE, - TASK_BUTT, -} HalTaskStatus; - -typedef struct IOInterruptCB { - MPP_RET (*callBack)(void*, void*); - void *opaque; -} IOInterruptCB; - -typedef struct IOCallbackCtx_t { - RK_U32 device_id; - void *task; - RK_U32 *regs; - RK_U32 hard_err; -} IOCallbackCtx; - -/* - * modified by parser - * - * number : the number of the data pointer array element - * data : the address of the pointer array, parser will add its data here - */ -typedef struct MppSyntax_t { - RK_U32 number; - void *data; -} MppSyntax; - -/* - * HalTask memory layout: - * - * +----^----+ +----------------------+ +----^----+ - * | | context type | | - * | +----------------------+ | - * + | coding type | | - * header +----------------------+ | - * + | size | | - * | +----------------------+ | - * | | pointer count | | - * +----v----+ +----------------------+ | - * | | | - * | pointers | | - * | | + - * +----------------------+ size - * | | + - * | data_0 | | - * | | | - * +----------------------+ | - * | | | - * | data_1 | | - * | | | - * +----------------------+ | - * | | | - * | | | - * | data_2 | | - * | | | - * | | | - * +----------------------+ +----v----+ - */ - -typedef union HalDecTaskFlag_t { - RK_U32 val; - struct { - RK_U32 eos : 1; - RK_U32 info_change : 1; - RK_U32 had_error : 1; - RK_U32 used_for_ref : 1; - }; -} HalDecTaskFlag; - -typedef struct HalDecTask_t { - // set by parser to signal that it is valid - RK_U32 valid; - HalDecTaskFlag flags; - - // previous task hardware working status - // when hardware error happen status is not zero - RK_U32 prev_status; - // current tesk protocol syntax information - MppSyntax syntax; - - // packet need to be copied to hardware buffer - // parser will create this packet and mpp_dec will copy it to hardware bufffer - MppPacket input_packet; - - // current task input slot index - RK_S32 input; - - RK_S32 reg_index; - // for test purpose - // current tesk output slot index - RK_S32 output; - // current task reference slot index, -1 for unused - RK_S32 refer[MAX_DEC_REF_NUM]; -} HalDecTask; - -typedef struct HalEncTask_t { - RK_U32 valid; - - // current tesk protocol syntax information - MppSyntax syntax; - - // current tesk output stream buffer - MppBuffer output; - - // current tesk input slot buffer - MppBuffer input; - - RK_U32 is_intra; -} HalEncTask; - - -typedef struct HalTask_u { - RK_S64 codec_prepare[2]; - RK_S64 codec_parse[2]; - RK_S64 hal_gen[2]; - RK_S64 hal_start[2]; - RK_S64 hal_wait[2]; - - union { - HalDecTask dec; - HalEncTask enc; - }; -} HalTaskInfo; - -typedef void* HalTaskHnd; -typedef void* HalTaskGroup; - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * group init / deinit will be called by hal - * - * NOTE: use mpp_list to implement - * the count means the max task waiting for process - */ -MPP_RET hal_task_group_init(HalTaskGroup *group, MppCtxType type, RK_S32 count); -MPP_RET hal_task_group_deinit(HalTaskGroup group); - -/* - * normal working flow: - * - * dec: - * - * - codec - * hal_task_get_hnd(group, idle, hnd) - dec try get idle task to work - * hal_task_hnd_set_status(hnd, prepare) - dec prepare the task - * codec prepare task - * hal_task_hnd_set_status(hnd, wait_proc) - dec send the task to hardware queue - * - * - hal - * hal_task_get_hnd(group, wait_proc, hnd) - hal get task on wait_proc status - * hal start task - * hal_task_set_hnd(hnd, processing) - hal send task to hardware for process - * hal wait task done - * hal_task_set_hnd(hnd, proc_done) - hal mark task is finished - * - * - codec - * hal_task_get_hnd(group, task_done, hnd) - codec query the previous finished task - * codec do error process on task - * hal_task_set_hnd(hnd, idle) - codec mark task is idle - * - */ -MPP_RET hal_task_get_hnd(HalTaskGroup group, HalTaskStatus status, HalTaskHnd *hnd); -MPP_RET hal_task_get_count(HalTaskGroup group, HalTaskStatus status, RK_U32 *count); -MPP_RET hal_task_hnd_set_status(HalTaskHnd hnd, HalTaskStatus status); -MPP_RET hal_task_hnd_set_info(HalTaskHnd hnd, HalTaskInfo *task); -MPP_RET hal_task_hnd_get_info(HalTaskHnd hnd, HalTaskInfo *task); -MPP_RET hal_task_info_init(HalTaskInfo *task, MppCtxType type); -MPP_RET hal_task_check_empty(HalTaskGroup group, HalTaskStatus status); - -#ifdef __cplusplus -} -#endif - -#endif /*__HAL_TASK__*/ - +/* +* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef __HAL_TASK__ +#define __HAL_TASK__ + +#include "rk_mpi.h" + +#define MAX_DEC_REF_NUM 17 + +typedef enum HalTaskStatus_e { + TASK_IDLE, + TASK_PREPARE, + TASK_WAIT_PROC, + TASK_PROCESSING, + TASK_PROC_DONE, + TASK_BUTT, +} HalTaskStatus; + +typedef struct IOInterruptCB { + MPP_RET (*callBack)(void*, void*); + void *opaque; +} IOInterruptCB; + +typedef struct IOCallbackCtx_t { + RK_U32 device_id; + void *task; + RK_U32 *regs; + RK_U32 hard_err; +} IOCallbackCtx; + +/* + * modified by parser + * + * number : the number of the data pointer array element + * data : the address of the pointer array, parser will add its data here + */ +typedef struct MppSyntax_t { + RK_U32 number; + void *data; +} MppSyntax; + +/* + * HalTask memory layout: + * + * +----^----+ +----------------------+ +----^----+ + * | | context type | | + * | +----------------------+ | + * + | coding type | | + * header +----------------------+ | + * + | size | | + * | +----------------------+ | + * | | pointer count | | + * +----v----+ +----------------------+ | + * | | | + * | pointers | | + * | | + + * +----------------------+ size + * | | + + * | data_0 | | + * | | | + * +----------------------+ | + * | | | + * | data_1 | | + * | | | + * +----------------------+ | + * | | | + * | | | + * | data_2 | | + * | | | + * | | | + * +----------------------+ +----v----+ + */ + +typedef union HalDecTaskFlag_t { + RK_U32 val; + struct { + RK_U32 eos : 1; + RK_U32 info_change : 1; + RK_U32 had_error : 1; + RK_U32 used_for_ref : 1; + }; +} HalDecTaskFlag; + +typedef struct HalDecTask_t { + // set by parser to signal that it is valid + RK_U32 valid; + HalDecTaskFlag flags; + + // previous task hardware working status + // when hardware error happen status is not zero + RK_U32 prev_status; + // current tesk protocol syntax information + MppSyntax syntax; + + // packet need to be copied to hardware buffer + // parser will create this packet and mpp_dec will copy it to hardware bufffer + MppPacket input_packet; + + // current task input slot index + RK_S32 input; + + RK_S32 reg_index; + // for test purpose + // current tesk output slot index + RK_S32 output; + // current task reference slot index, -1 for unused + RK_S32 refer[MAX_DEC_REF_NUM]; +} HalDecTask; + +typedef struct HalEncTask_t { + RK_U32 valid; + + // current tesk protocol syntax information + MppSyntax syntax; + + // current tesk output stream buffer + MppBuffer output; + + // current tesk input slot buffer + MppBuffer input; + + RK_U32 is_intra; +} HalEncTask; + + +typedef struct HalTask_u { + RK_S64 codec_prepare[2]; + RK_S64 codec_parse[2]; + RK_S64 hal_gen[2]; + RK_S64 hal_start[2]; + RK_S64 hal_wait[2]; + + union { + HalDecTask dec; + HalEncTask enc; + }; +} HalTaskInfo; + +typedef void* HalTaskHnd; +typedef void* HalTaskGroup; + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * group init / deinit will be called by hal + * + * NOTE: use mpp_list to implement + * the count means the max task waiting for process + */ +MPP_RET hal_task_group_init(HalTaskGroup *group, MppCtxType type, RK_S32 count); +MPP_RET hal_task_group_deinit(HalTaskGroup group); + +/* + * normal working flow: + * + * dec: + * + * - codec + * hal_task_get_hnd(group, idle, hnd) - dec try get idle task to work + * hal_task_hnd_set_status(hnd, prepare) - dec prepare the task + * codec prepare task + * hal_task_hnd_set_status(hnd, wait_proc) - dec send the task to hardware queue + * + * - hal + * hal_task_get_hnd(group, wait_proc, hnd) - hal get task on wait_proc status + * hal start task + * hal_task_set_hnd(hnd, processing) - hal send task to hardware for process + * hal wait task done + * hal_task_set_hnd(hnd, proc_done) - hal mark task is finished + * + * - codec + * hal_task_get_hnd(group, task_done, hnd) - codec query the previous finished task + * codec do error process on task + * hal_task_set_hnd(hnd, idle) - codec mark task is idle + * + */ +MPP_RET hal_task_get_hnd(HalTaskGroup group, HalTaskStatus status, HalTaskHnd *hnd); +MPP_RET hal_task_get_count(HalTaskGroup group, HalTaskStatus status, RK_U32 *count); +MPP_RET hal_task_hnd_set_status(HalTaskHnd hnd, HalTaskStatus status); +MPP_RET hal_task_hnd_set_info(HalTaskHnd hnd, HalTaskInfo *task); +MPP_RET hal_task_hnd_get_info(HalTaskHnd hnd, HalTaskInfo *task); +MPP_RET hal_task_info_init(HalTaskInfo *task, MppCtxType type); +MPP_RET hal_task_check_empty(HalTaskGroup group, HalTaskStatus status); + +#ifdef __cplusplus +} +#endif + +#endif /*__HAL_TASK__*/ + diff --git a/mpp/hal/inc/hal_vp8d_api.h b/mpp/hal/inc/hal_vp8d_api.h index 7cacad60..3e980230 100644 --- a/mpp/hal/inc/hal_vp8d_api.h +++ b/mpp/hal/inc/hal_vp8d_api.h @@ -1,34 +1,34 @@ -/* -* -* Copyright 2015 Rockchip Electronics Co. LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - - -#ifndef __HAL_VP8D_API_H__ -#define __HAL_VP8D_API_H__ - -#include "mpp_hal.h" - -#ifdef __cplusplus -extern "C" { -#endif - -extern const MppHalApi hal_api_vp8d; - -#ifdef __cplusplus -} -#endif - -#endif /*__HAL_VP8D_API_H__*/ +/* +* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +#ifndef __HAL_VP8D_API_H__ +#define __HAL_VP8D_API_H__ + +#include "mpp_hal.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern const MppHalApi hal_api_vp8d; + +#ifdef __cplusplus +} +#endif + +#endif /*__HAL_VP8D_API_H__*/ diff --git a/mpp/hal/inc/hal_vp9d_api.h b/mpp/hal/inc/hal_vp9d_api.h index 4b8ab096..c9a1a8a4 100644 --- a/mpp/hal/inc/hal_vp9d_api.h +++ b/mpp/hal/inc/hal_vp9d_api.h @@ -1,47 +1,47 @@ -/* -* -* Copyright 2015 Rockchip Electronics Co. LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - - -#ifndef __HAL_VP9D_API_H__ -#define __HAL_VP9D_API_H__ - -#include "rk_type.h" -#include "mpp_err.h" -#include "mpp_hal.h" - - - -#ifdef __cplusplus -extern "C" { -#endif - -extern const MppHalApi hal_api_vp9d; - -MPP_RET hal_vp9d_init (void *hal, MppHalCfg *cfg); -MPP_RET hal_vp9d_deinit (void *hal); -MPP_RET hal_vp9d_gen_regs(void *hal, HalTaskInfo *task); -MPP_RET hal_vp9d_start (void *hal, HalTaskInfo *task); -MPP_RET hal_vp9d_wait (void *hal, HalTaskInfo *task); -MPP_RET hal_vp9d_reset (void *hal); -MPP_RET hal_vp9d_flush (void *hal); -MPP_RET hal_vp9d_control (void *hal, RK_S32 cmd_type, void *param); - -#ifdef __cplusplus -} -#endif - -#endif /*__HAL_VP9D_API_H__*/ +/* +* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +#ifndef __HAL_VP9D_API_H__ +#define __HAL_VP9D_API_H__ + +#include "rk_type.h" +#include "mpp_err.h" +#include "mpp_hal.h" + + + +#ifdef __cplusplus +extern "C" { +#endif + +extern const MppHalApi hal_api_vp9d; + +MPP_RET hal_vp9d_init (void *hal, MppHalCfg *cfg); +MPP_RET hal_vp9d_deinit (void *hal); +MPP_RET hal_vp9d_gen_regs(void *hal, HalTaskInfo *task); +MPP_RET hal_vp9d_start (void *hal, HalTaskInfo *task); +MPP_RET hal_vp9d_wait (void *hal, HalTaskInfo *task); +MPP_RET hal_vp9d_reset (void *hal); +MPP_RET hal_vp9d_flush (void *hal); +MPP_RET hal_vp9d_control (void *hal, RK_S32 cmd_type, void *param); + +#ifdef __cplusplus +} +#endif + +#endif /*__HAL_VP9D_API_H__*/ diff --git a/mpp/hal/inc/mpp_hal.h b/mpp/hal/inc/mpp_hal.h index 679dfe98..5d039091 100644 --- a/mpp/hal/inc/mpp_hal.h +++ b/mpp/hal/inc/mpp_hal.h @@ -1,102 +1,102 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __MPP_HAL_H__ -#define __MPP_HAL_H__ - -#include "hal_task.h" -#include "mpp_buf_slot.h" - -typedef enum MppHalType_e { - HAL_MODE_LIBVPU, - HAL_MODE_V4L2, - HAL_MODE_BUTT, -} HalWorkMode; - - -typedef enum MppHalHardType_e { - HAL_VDPU, //!< vpu combined decoder - HAL_VEPU, //!< vpu combined encoder - HAL_RKVDEC, //!< rock-chip h264 h265 vp9 combined decoder - HAL_RKVENC, //!< rock-chip h264 h265 combined encoder - HAL_DEVICE_BUTT, -} HalDeviceId; - - -typedef void* MppHalCtx; - - -typedef struct MppHalCfg_t { - // input - MppCtxType type; - MppCodingType coding; - HalWorkMode work_mode; - HalDeviceId device_id; - MppBufSlots frame_slots; - MppBufSlots packet_slots; - - // output - HalTaskGroup tasks; - RK_S32 task_count; - RK_U32 fast_mode; - IOInterruptCB hal_int_cb; -} MppHalCfg; - -typedef struct MppHalApi_t { - char *name; - MppCtxType type; - MppCodingType coding; - RK_U32 ctx_size; - RK_U32 flag; - - MPP_RET (*init)(void *ctx, MppHalCfg *cfg); - MPP_RET (*deinit)(void *ctx); - - // task preprocess function - MPP_RET (*reg_gen)(void *ctx, HalTaskInfo *syn); - - // hw operation function - MPP_RET (*start)(void *ctx, HalTaskInfo *task); - MPP_RET (*wait)(void *ctx, HalTaskInfo *task); - - MPP_RET (*reset)(void *ctx); - MPP_RET (*flush)(void *ctx); - MPP_RET (*control)(void *ctx, RK_S32 cmd, void *param); -} MppHalApi; - -typedef void* MppHal; - -#ifdef __cplusplus -extern "C" { -#endif - -MPP_RET mpp_hal_init(MppHal *ctx, MppHalCfg *cfg); -MPP_RET mpp_hal_deinit(MppHal ctx); - -MPP_RET mpp_hal_reg_gen(MppHal ctx, HalTaskInfo *task); -MPP_RET mpp_hal_hw_start(MppHal ctx, HalTaskInfo *task); -MPP_RET mpp_hal_hw_wait(MppHal ctx, HalTaskInfo *task); - -MPP_RET mpp_hal_reset(MppHal ctx); -MPP_RET mpp_hal_flush(MppHal ctx); -MPP_RET mpp_hal_control(MppHal ctx, RK_S32 cmd, void *param); - -#ifdef __cplusplus -} -#endif - -#endif /*__MPP_HAL_H__*/ - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPP_HAL_H__ +#define __MPP_HAL_H__ + +#include "hal_task.h" +#include "mpp_buf_slot.h" + +typedef enum MppHalType_e { + HAL_MODE_LIBVPU, + HAL_MODE_V4L2, + HAL_MODE_BUTT, +} HalWorkMode; + + +typedef enum MppHalHardType_e { + HAL_VDPU, //!< vpu combined decoder + HAL_VEPU, //!< vpu combined encoder + HAL_RKVDEC, //!< rock-chip h264 h265 vp9 combined decoder + HAL_RKVENC, //!< rock-chip h264 h265 combined encoder + HAL_DEVICE_BUTT, +} HalDeviceId; + + +typedef void* MppHalCtx; + + +typedef struct MppHalCfg_t { + // input + MppCtxType type; + MppCodingType coding; + HalWorkMode work_mode; + HalDeviceId device_id; + MppBufSlots frame_slots; + MppBufSlots packet_slots; + + // output + HalTaskGroup tasks; + RK_S32 task_count; + RK_U32 fast_mode; + IOInterruptCB hal_int_cb; +} MppHalCfg; + +typedef struct MppHalApi_t { + char *name; + MppCtxType type; + MppCodingType coding; + RK_U32 ctx_size; + RK_U32 flag; + + MPP_RET (*init)(void *ctx, MppHalCfg *cfg); + MPP_RET (*deinit)(void *ctx); + + // task preprocess function + MPP_RET (*reg_gen)(void *ctx, HalTaskInfo *syn); + + // hw operation function + MPP_RET (*start)(void *ctx, HalTaskInfo *task); + MPP_RET (*wait)(void *ctx, HalTaskInfo *task); + + MPP_RET (*reset)(void *ctx); + MPP_RET (*flush)(void *ctx); + MPP_RET (*control)(void *ctx, RK_S32 cmd, void *param); +} MppHalApi; + +typedef void* MppHal; + +#ifdef __cplusplus +extern "C" { +#endif + +MPP_RET mpp_hal_init(MppHal *ctx, MppHalCfg *cfg); +MPP_RET mpp_hal_deinit(MppHal ctx); + +MPP_RET mpp_hal_reg_gen(MppHal ctx, HalTaskInfo *task); +MPP_RET mpp_hal_hw_start(MppHal ctx, HalTaskInfo *task); +MPP_RET mpp_hal_hw_wait(MppHal ctx, HalTaskInfo *task); + +MPP_RET mpp_hal_reset(MppHal ctx); +MPP_RET mpp_hal_flush(MppHal ctx); +MPP_RET mpp_hal_control(MppHal ctx, RK_S32 cmd, void *param); + +#ifdef __cplusplus +} +#endif + +#endif /*__MPP_HAL_H__*/ + diff --git a/mpp/hal/mpp_hal.cpp b/mpp/hal/mpp_hal.cpp index e9e69032..09a9b085 100644 --- a/mpp/hal/mpp_hal.cpp +++ b/mpp/hal/mpp_hal.cpp @@ -1,209 +1,209 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define MODULE_TAG "mpp_hal" - -#include "mpp_mem.h" -#include "mpp_log.h" -#include "mpp_time.h" -#include "mpp_common.h" - -#include "mpp.h" -#include "mpp_hal.h" -#include "mpp_frame_impl.h" - -#include "hal_h263d_api.h" -#include "hal_h264d_api.h" -#include "hal_h264e_api.h" -#include "hal_h265d_api.h" -#include "hal_vp8d_api.h" -#include "hal_vp9d_api.h" -#include "hal_avsd_api.h" -#include "hal_m2vd_api.h" -#include "hal_mpg4d_api.h" -#include "hal_jpegd_api.h" -#include "hal_jpege_api.h" - -// for test and demo -#include "hal_dummy_dec_api.h" -#include "hal_dummy_enc_api.h" - -/* - * all hardware api static register here - */ -static const MppHalApi *hw_apis[] = { - &hal_api_avsd, - &hal_api_h263d, - &hal_api_h264d, - &hal_api_h265d, - &hal_api_m2vd, - &hal_api_mpg4d, - &hal_api_vp8d, - &hal_api_vp9d, - &hal_api_jpegd, - &hal_api_h264e, - &hal_api_jpege, - &hal_api_dummy_dec, - &hal_api_dummy_enc, -}; - -typedef struct MppHalImpl_t { - MppCtxType type; - MppCodingType coding; - MppBufSlots frame_slots; - MppBufSlots packet_slots; - - void *ctx; - const MppHalApi *api; - - HalTaskGroup tasks; - RK_S32 task_count; -} MppHalImpl; - - -MPP_RET mpp_hal_init(MppHal *ctx, MppHalCfg *cfg) -{ - if (NULL == ctx || NULL == cfg) { - mpp_err_f("found NULL input ctx %p cfg %p\n", ctx, cfg); - return MPP_ERR_NULL_PTR; - } - *ctx = NULL; - - MppHalImpl *p = mpp_calloc(MppHalImpl, 1); - if (NULL == p) { - mpp_err_f("malloc failed\n"); - return MPP_ERR_MALLOC; - } - - RK_U32 i; - for (i = 0; i < MPP_ARRAY_ELEMS(hw_apis); i++) { - if (cfg->type == hw_apis[i]->type && - cfg->coding == hw_apis[i]->coding) { - mpp_assert(cfg->task_count > 0); - p->type = cfg->type; - p->coding = cfg->coding; - p->frame_slots = cfg->frame_slots; - p->packet_slots = cfg->packet_slots; - p->api = hw_apis[i]; - p->task_count = cfg->task_count; - p->ctx = mpp_calloc_size(void, p->api->ctx_size); - p->api->init(p->ctx, cfg); - - MPP_RET ret = hal_task_group_init(&p->tasks, p->type, p->task_count); - if (ret) { - mpp_err_f("hal_task_group_init failed ret %d\n", ret); - break; - } - - cfg->tasks = p->tasks; - *ctx = p; - return MPP_OK; - } - } - - mpp_err_f("could not found coding type %d\n", cfg->coding); - mpp_free(p->ctx); - mpp_free(p); - - return MPP_NOK; -} - -MPP_RET mpp_hal_deinit(MppHal ctx) -{ - if (NULL == ctx) { - mpp_err_f("found NULL input\n"); - return MPP_ERR_NULL_PTR; - } - - MppHalImpl *p = (MppHalImpl*)ctx; - p->api->deinit(p->ctx); - mpp_free(p->ctx); - if (p->tasks) - hal_task_group_deinit(p->tasks); - mpp_free(p); - return MPP_OK; -} - -MPP_RET mpp_hal_reg_gen(MppHal ctx, HalTaskInfo *task) -{ - if (NULL == ctx || NULL == task) { - mpp_err_f("found NULL input ctx %p task %p\n", ctx, task); - return MPP_ERR_NULL_PTR; - } - - MppHalImpl *p = (MppHalImpl*)ctx; - MPP_RET ret = p->api->reg_gen(p->ctx, task); - return ret; -} - -MPP_RET mpp_hal_hw_start(MppHal ctx, HalTaskInfo *task) -{ - if (NULL == ctx || NULL == task) { - mpp_err_f("found NULL input ctx %p task %p\n", ctx, task); - return MPP_ERR_NULL_PTR; - } - - MppHalImpl *p = (MppHalImpl*)ctx; - MPP_RET ret = p->api->start(p->ctx, task); - return ret; -} - -MPP_RET mpp_hal_hw_wait(MppHal ctx, HalTaskInfo *task) -{ - if (NULL == ctx || NULL == task) { - mpp_err_f("found NULL input ctx %p task %p\n", ctx, task); - return MPP_ERR_NULL_PTR; - } - - MppHalImpl *p = (MppHalImpl*)ctx; - MPP_RET ret = p->api->wait(p->ctx, task); - - return ret; -} - -MPP_RET mpp_hal_reset(MppHal ctx) -{ - if (NULL == ctx) { - mpp_err_f("found NULL input\n"); - return MPP_ERR_NULL_PTR; - } - - MppHalImpl *p = (MppHalImpl*)ctx; - return p->api->reset(p->ctx); -} - -MPP_RET mpp_hal_flush(MppHal ctx) -{ - if (NULL == ctx) { - mpp_err_f("found NULL input\n"); - return MPP_ERR_NULL_PTR; - } - - MppHalImpl *p = (MppHalImpl*)ctx; - return p->api->flush(p->ctx); -} - -MPP_RET mpp_hal_control(MppHal ctx, RK_S32 cmd, void *param) -{ - if (NULL == ctx) { - mpp_err_f("found NULL input\n"); - return MPP_ERR_NULL_PTR; - } - - MppHalImpl *p = (MppHalImpl*)ctx; - return p->api->control(p->ctx, cmd, param); -} - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define MODULE_TAG "mpp_hal" + +#include "mpp_mem.h" +#include "mpp_log.h" +#include "mpp_time.h" +#include "mpp_common.h" + +#include "mpp.h" +#include "mpp_hal.h" +#include "mpp_frame_impl.h" + +#include "hal_h263d_api.h" +#include "hal_h264d_api.h" +#include "hal_h264e_api.h" +#include "hal_h265d_api.h" +#include "hal_vp8d_api.h" +#include "hal_vp9d_api.h" +#include "hal_avsd_api.h" +#include "hal_m2vd_api.h" +#include "hal_mpg4d_api.h" +#include "hal_jpegd_api.h" +#include "hal_jpege_api.h" + +// for test and demo +#include "hal_dummy_dec_api.h" +#include "hal_dummy_enc_api.h" + +/* + * all hardware api static register here + */ +static const MppHalApi *hw_apis[] = { + &hal_api_avsd, + &hal_api_h263d, + &hal_api_h264d, + &hal_api_h265d, + &hal_api_m2vd, + &hal_api_mpg4d, + &hal_api_vp8d, + &hal_api_vp9d, + &hal_api_jpegd, + &hal_api_h264e, + &hal_api_jpege, + &hal_api_dummy_dec, + &hal_api_dummy_enc, +}; + +typedef struct MppHalImpl_t { + MppCtxType type; + MppCodingType coding; + MppBufSlots frame_slots; + MppBufSlots packet_slots; + + void *ctx; + const MppHalApi *api; + + HalTaskGroup tasks; + RK_S32 task_count; +} MppHalImpl; + + +MPP_RET mpp_hal_init(MppHal *ctx, MppHalCfg *cfg) +{ + if (NULL == ctx || NULL == cfg) { + mpp_err_f("found NULL input ctx %p cfg %p\n", ctx, cfg); + return MPP_ERR_NULL_PTR; + } + *ctx = NULL; + + MppHalImpl *p = mpp_calloc(MppHalImpl, 1); + if (NULL == p) { + mpp_err_f("malloc failed\n"); + return MPP_ERR_MALLOC; + } + + RK_U32 i; + for (i = 0; i < MPP_ARRAY_ELEMS(hw_apis); i++) { + if (cfg->type == hw_apis[i]->type && + cfg->coding == hw_apis[i]->coding) { + mpp_assert(cfg->task_count > 0); + p->type = cfg->type; + p->coding = cfg->coding; + p->frame_slots = cfg->frame_slots; + p->packet_slots = cfg->packet_slots; + p->api = hw_apis[i]; + p->task_count = cfg->task_count; + p->ctx = mpp_calloc_size(void, p->api->ctx_size); + p->api->init(p->ctx, cfg); + + MPP_RET ret = hal_task_group_init(&p->tasks, p->type, p->task_count); + if (ret) { + mpp_err_f("hal_task_group_init failed ret %d\n", ret); + break; + } + + cfg->tasks = p->tasks; + *ctx = p; + return MPP_OK; + } + } + + mpp_err_f("could not found coding type %d\n", cfg->coding); + mpp_free(p->ctx); + mpp_free(p); + + return MPP_NOK; +} + +MPP_RET mpp_hal_deinit(MppHal ctx) +{ + if (NULL == ctx) { + mpp_err_f("found NULL input\n"); + return MPP_ERR_NULL_PTR; + } + + MppHalImpl *p = (MppHalImpl*)ctx; + p->api->deinit(p->ctx); + mpp_free(p->ctx); + if (p->tasks) + hal_task_group_deinit(p->tasks); + mpp_free(p); + return MPP_OK; +} + +MPP_RET mpp_hal_reg_gen(MppHal ctx, HalTaskInfo *task) +{ + if (NULL == ctx || NULL == task) { + mpp_err_f("found NULL input ctx %p task %p\n", ctx, task); + return MPP_ERR_NULL_PTR; + } + + MppHalImpl *p = (MppHalImpl*)ctx; + MPP_RET ret = p->api->reg_gen(p->ctx, task); + return ret; +} + +MPP_RET mpp_hal_hw_start(MppHal ctx, HalTaskInfo *task) +{ + if (NULL == ctx || NULL == task) { + mpp_err_f("found NULL input ctx %p task %p\n", ctx, task); + return MPP_ERR_NULL_PTR; + } + + MppHalImpl *p = (MppHalImpl*)ctx; + MPP_RET ret = p->api->start(p->ctx, task); + return ret; +} + +MPP_RET mpp_hal_hw_wait(MppHal ctx, HalTaskInfo *task) +{ + if (NULL == ctx || NULL == task) { + mpp_err_f("found NULL input ctx %p task %p\n", ctx, task); + return MPP_ERR_NULL_PTR; + } + + MppHalImpl *p = (MppHalImpl*)ctx; + MPP_RET ret = p->api->wait(p->ctx, task); + + return ret; +} + +MPP_RET mpp_hal_reset(MppHal ctx) +{ + if (NULL == ctx) { + mpp_err_f("found NULL input\n"); + return MPP_ERR_NULL_PTR; + } + + MppHalImpl *p = (MppHalImpl*)ctx; + return p->api->reset(p->ctx); +} + +MPP_RET mpp_hal_flush(MppHal ctx) +{ + if (NULL == ctx) { + mpp_err_f("found NULL input\n"); + return MPP_ERR_NULL_PTR; + } + + MppHalImpl *p = (MppHalImpl*)ctx; + return p->api->flush(p->ctx); +} + +MPP_RET mpp_hal_control(MppHal ctx, RK_S32 cmd, void *param) +{ + if (NULL == ctx) { + mpp_err_f("found NULL input\n"); + return MPP_ERR_NULL_PTR; + } + + MppHalImpl *p = (MppHalImpl*)ctx; + return p->api->control(p->ctx, cmd, param); +} + diff --git a/mpp/hal/rkdec/avsd/hal_avsd_api.c b/mpp/hal/rkdec/avsd/hal_avsd_api.c index 3579c0b8..e02c7224 100644 --- a/mpp/hal/rkdec/avsd/hal_avsd_api.c +++ b/mpp/hal/rkdec/avsd/hal_avsd_api.c @@ -1,249 +1,249 @@ -/* -* -* Copyright 2015 Rockchip Electronics Co. LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - - -#define MODULE_TAG "hal_avsd_api" - -#include -#include -#include - -#include "rk_type.h" -#include "vpu.h" -#include "mpp_log.h" -#include "mpp_err.h" -#include "mpp_mem.h" -#include "mpp_env.h" -#include "mpp_common.h" - -#include "hal_avsd_api.h" - - -RK_U32 avsd_hal_debug = 0; - -static RK_U32 avsd_ver_align(RK_U32 val) -{ - return MPP_ALIGN(val, 16); -} - -static RK_U32 avsd_hor_align(RK_U32 val) -{ - return MPP_ALIGN(val, 16); -} - -static RK_U32 avsd_len_align(RK_U32 val) -{ - return (2 * MPP_ALIGN(val, 16)); -} -/*! -*********************************************************************** -* \brief -* init -*********************************************************************** -*/ -//extern "C" -MPP_RET hal_avsd_init(void *decoder, MppHalCfg *cfg) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - AvsdHalCtx_t *p_hal = NULL; - - AVSD_HAL_TRACE("In."); - INP_CHECK(ret, NULL == decoder); - - mpp_env_get_u32("avsd_debug", &avsd_hal_debug, 0); - - p_hal = (AvsdHalCtx_t *)decoder; - memset(p_hal, 0, sizeof(AvsdHalCtx_t)); - - p_hal->frame_slots = cfg->frame_slots; - p_hal->packet_slots = cfg->packet_slots; - //!< callback function to parser module - p_hal->init_cb = cfg->hal_int_cb; - - mpp_slots_set_prop(p_hal->frame_slots, SLOTS_HOR_ALIGN, avsd_hor_align); - mpp_slots_set_prop(p_hal->frame_slots, SLOTS_VER_ALIGN, avsd_ver_align); - mpp_slots_set_prop(p_hal->frame_slots, SLOTS_LEN_ALIGN, avsd_len_align); - -__RETURN: - AVSD_HAL_TRACE("Out."); - (void)decoder; - (void)cfg; - return ret = MPP_OK; -} -/*! -*********************************************************************** -* \brief -* deinit -*********************************************************************** -*/ -//extern "C" -MPP_RET hal_avsd_deinit(void *decoder) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - - AVSD_HAL_TRACE("In."); - - AVSD_HAL_TRACE("Out."); - (void)decoder; - return ret = MPP_OK; -} -/*! -*********************************************************************** -* \brief -* generate register -*********************************************************************** -*/ -//extern "C" -MPP_RET hal_avsd_gen_regs(void *decoder, HalTaskInfo *task) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - AvsdHalCtx_t *p_hal = NULL; - - AVSD_HAL_TRACE("In."); - INP_CHECK(ret, NULL == decoder); - - p_hal = (AvsdHalCtx_t *)decoder; - - if (p_hal->init_cb.callBack) { - p_hal->init_cb.callBack(p_hal->init_cb.opaque, task); - } - -__RETURN: - AVSD_HAL_TRACE("Out."); - - - - (void)decoder; - (void)task; - return ret = MPP_OK; -} -/*! -*********************************************************************** -* \brief h -* start hard -*********************************************************************** -*/ -//extern "C" -MPP_RET hal_avsd_start(void *decoder, HalTaskInfo *task) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - - AVSD_HAL_TRACE("In."); - INP_CHECK(ret, NULL == decoder); - -__RETURN: - AVSD_HAL_TRACE("Out."); - (void)decoder; - (void)task; - return ret = MPP_OK; -} -/*! -*********************************************************************** -* \brief -* wait hard -*********************************************************************** -*/ -//extern "C" -MPP_RET hal_avsd_wait(void *decoder, HalTaskInfo *task) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - //AvsdHalCtx_t *p_hal = NULL; - - AVSD_HAL_TRACE("In."); - - INP_CHECK(ret, NULL == decoder); - //p_hal = (AvsdHalCtx_t *)decoder; - - //if (p_hal->init_cb.callBack) { - // p_hal->init_cb.callBack(p_hal->init_cb.opaque, task); - //} - -__RETURN: - AVSD_HAL_TRACE("Out."); - (void)decoder; - (void)task; - return ret = MPP_OK; -} -/*! -*********************************************************************** -* \brief -* reset -*********************************************************************** -*/ -//extern "C" -MPP_RET hal_avsd_reset(void *decoder) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - - AVSD_HAL_TRACE("In."); - - (void)decoder; - return ret = MPP_OK; -} -/*! -*********************************************************************** -* \brief -* flush -*********************************************************************** -*/ -//extern "C" -MPP_RET hal_avsd_flush(void *decoder) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - - AVSD_HAL_TRACE("In."); - - (void)decoder; - return ret = MPP_OK; -} -/*! -*********************************************************************** -* \brief -* control -*********************************************************************** -*/ -//extern "C" -MPP_RET hal_avsd_control(void *decoder, RK_S32 cmd_type, void *param) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - - AVSD_HAL_TRACE("In."); - - (void)decoder; - (void)cmd_type; - (void)param; - - return ret = MPP_OK; -} - - -const MppHalApi hal_api_avsd = { - "avsd_rkdec", - MPP_CTX_DEC, - MPP_VIDEO_CodingAVS, - sizeof(AvsdHalCtx_t), - 0, - hal_avsd_init, - hal_avsd_deinit, - hal_avsd_gen_regs, - hal_avsd_start, - hal_avsd_wait, - hal_avsd_reset, - hal_avsd_flush, - hal_avsd_control, -}; - +/* +* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +#define MODULE_TAG "hal_avsd_api" + +#include +#include +#include + +#include "rk_type.h" +#include "vpu.h" +#include "mpp_log.h" +#include "mpp_err.h" +#include "mpp_mem.h" +#include "mpp_env.h" +#include "mpp_common.h" + +#include "hal_avsd_api.h" + + +RK_U32 avsd_hal_debug = 0; + +static RK_U32 avsd_ver_align(RK_U32 val) +{ + return MPP_ALIGN(val, 16); +} + +static RK_U32 avsd_hor_align(RK_U32 val) +{ + return MPP_ALIGN(val, 16); +} + +static RK_U32 avsd_len_align(RK_U32 val) +{ + return (2 * MPP_ALIGN(val, 16)); +} +/*! +*********************************************************************** +* \brief +* init +*********************************************************************** +*/ +//extern "C" +MPP_RET hal_avsd_init(void *decoder, MppHalCfg *cfg) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + AvsdHalCtx_t *p_hal = NULL; + + AVSD_HAL_TRACE("In."); + INP_CHECK(ret, NULL == decoder); + + mpp_env_get_u32("avsd_debug", &avsd_hal_debug, 0); + + p_hal = (AvsdHalCtx_t *)decoder; + memset(p_hal, 0, sizeof(AvsdHalCtx_t)); + + p_hal->frame_slots = cfg->frame_slots; + p_hal->packet_slots = cfg->packet_slots; + //!< callback function to parser module + p_hal->init_cb = cfg->hal_int_cb; + + mpp_slots_set_prop(p_hal->frame_slots, SLOTS_HOR_ALIGN, avsd_hor_align); + mpp_slots_set_prop(p_hal->frame_slots, SLOTS_VER_ALIGN, avsd_ver_align); + mpp_slots_set_prop(p_hal->frame_slots, SLOTS_LEN_ALIGN, avsd_len_align); + +__RETURN: + AVSD_HAL_TRACE("Out."); + (void)decoder; + (void)cfg; + return ret = MPP_OK; +} +/*! +*********************************************************************** +* \brief +* deinit +*********************************************************************** +*/ +//extern "C" +MPP_RET hal_avsd_deinit(void *decoder) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + + AVSD_HAL_TRACE("In."); + + AVSD_HAL_TRACE("Out."); + (void)decoder; + return ret = MPP_OK; +} +/*! +*********************************************************************** +* \brief +* generate register +*********************************************************************** +*/ +//extern "C" +MPP_RET hal_avsd_gen_regs(void *decoder, HalTaskInfo *task) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + AvsdHalCtx_t *p_hal = NULL; + + AVSD_HAL_TRACE("In."); + INP_CHECK(ret, NULL == decoder); + + p_hal = (AvsdHalCtx_t *)decoder; + + if (p_hal->init_cb.callBack) { + p_hal->init_cb.callBack(p_hal->init_cb.opaque, task); + } + +__RETURN: + AVSD_HAL_TRACE("Out."); + + + + (void)decoder; + (void)task; + return ret = MPP_OK; +} +/*! +*********************************************************************** +* \brief h +* start hard +*********************************************************************** +*/ +//extern "C" +MPP_RET hal_avsd_start(void *decoder, HalTaskInfo *task) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + + AVSD_HAL_TRACE("In."); + INP_CHECK(ret, NULL == decoder); + +__RETURN: + AVSD_HAL_TRACE("Out."); + (void)decoder; + (void)task; + return ret = MPP_OK; +} +/*! +*********************************************************************** +* \brief +* wait hard +*********************************************************************** +*/ +//extern "C" +MPP_RET hal_avsd_wait(void *decoder, HalTaskInfo *task) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + //AvsdHalCtx_t *p_hal = NULL; + + AVSD_HAL_TRACE("In."); + + INP_CHECK(ret, NULL == decoder); + //p_hal = (AvsdHalCtx_t *)decoder; + + //if (p_hal->init_cb.callBack) { + // p_hal->init_cb.callBack(p_hal->init_cb.opaque, task); + //} + +__RETURN: + AVSD_HAL_TRACE("Out."); + (void)decoder; + (void)task; + return ret = MPP_OK; +} +/*! +*********************************************************************** +* \brief +* reset +*********************************************************************** +*/ +//extern "C" +MPP_RET hal_avsd_reset(void *decoder) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + + AVSD_HAL_TRACE("In."); + + (void)decoder; + return ret = MPP_OK; +} +/*! +*********************************************************************** +* \brief +* flush +*********************************************************************** +*/ +//extern "C" +MPP_RET hal_avsd_flush(void *decoder) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + + AVSD_HAL_TRACE("In."); + + (void)decoder; + return ret = MPP_OK; +} +/*! +*********************************************************************** +* \brief +* control +*********************************************************************** +*/ +//extern "C" +MPP_RET hal_avsd_control(void *decoder, RK_S32 cmd_type, void *param) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + + AVSD_HAL_TRACE("In."); + + (void)decoder; + (void)cmd_type; + (void)param; + + return ret = MPP_OK; +} + + +const MppHalApi hal_api_avsd = { + "avsd_rkdec", + MPP_CTX_DEC, + MPP_VIDEO_CodingAVS, + sizeof(AvsdHalCtx_t), + 0, + hal_avsd_init, + hal_avsd_deinit, + hal_avsd_gen_regs, + hal_avsd_start, + hal_avsd_wait, + hal_avsd_reset, + hal_avsd_flush, + hal_avsd_control, +}; + diff --git a/mpp/hal/rkdec/h264d/hal_h264d_api.c b/mpp/hal/rkdec/h264d/hal_h264d_api.c index 413b7f27..e02feb2e 100644 --- a/mpp/hal/rkdec/h264d/hal_h264d_api.c +++ b/mpp/hal/rkdec/h264d/hal_h264d_api.c @@ -1,415 +1,415 @@ -/* -* -* Copyright 2015 Rockchip Electronics Co. LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - - -#define MODULE_TAG "hal_h264d_api" - -#include -#include -#include - -#include "rk_type.h" -#include "vpu.h" -#include "mpp_log.h" -#include "mpp_err.h" -#include "mpp_mem.h" -#include "mpp_env.h" - -#include "dxva_syntax.h" -#include "h264d_syntax.h" -#include "h264d_log.h" - -#include "hal_h264d_global.h" -#include "hal_h264d_api.h" - -#include "hal_h264d_rkv_reg.h" -#include "hal_h264d_vdpu_reg.h" - - - - -static void close_log_files(LogEnv_t *env) -{ - FCLOSE(env->fp_driver); - FCLOSE(env->fp_syn_hal); - FCLOSE(env->fp_run_hal); -} -static MPP_RET open_log_files(LogEnv_t *env, LogFlag_t *pflag) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - char fname[128] = { 0 }; - - INP_CHECK(ret, !pflag->write_en); - set_log_outpath(env); - //!< runlog file - if (GetBitVal(env->ctrl, LOG_DEBUG)) { - sprintf(fname, "%s/h264d_hal_runlog.dat", env->outpath); - FLE_CHECK(ret, env->fp_run_hal = fopen(fname, "wb")); - } - //!< fpga drive file - if (GetBitVal(env->ctrl, LOG_FPGA)) { - sprintf(fname, "%s/h264d_driver_data.dat", env->outpath); - FLE_CHECK(ret, env->fp_driver = fopen(fname, "wb")); - } - //!< write syntax - if ( GetBitVal(env->ctrl, LOG_WRITE_SPSPPS ) - || GetBitVal(env->ctrl, LOG_WRITE_RPS ) - || GetBitVal(env->ctrl, LOG_WRITE_SCANLIST) - || GetBitVal(env->ctrl, LOG_WRITE_STEAM ) - || GetBitVal(env->ctrl, LOG_WRITE_REG ) ) { - sprintf(fname, "%s/h264d_write_syntax.dat", env->outpath); - FLE_CHECK(ret, env->fp_syn_hal = fopen(fname, "wb")); - } - -__RETURN: - return MPP_OK; - -__FAILED: - return ret; -} - -static MPP_RET logctx_deinit(H264dLogCtx_t *logctx) -{ - close_log_files(&logctx->env); - - return MPP_OK; -} - -static MPP_RET logctx_init(H264dLogCtx_t *logctx, LogCtx_t *logbuf) -{ - RK_U8 i = 0; - MPP_RET ret = MPP_ERR_UNKNOW; - LogCtx_t *pcur = NULL; - - FUN_CHECK(ret = get_logenv(&logctx->env)); - - FUN_CHECK(ret = explain_ctrl_flag(logctx->env.ctrl, &logctx->log_flag)); - if ( !logctx->log_flag.debug_en - && !logctx->log_flag.print_en && !logctx->log_flag.write_en ) { - logctx->log_flag.debug_en = 0; - goto __RETURN; - } - logctx->log_flag.level = (1 << logctx->env.level) - 1; - //!< open file - FUN_CHECK(ret = open_log_files(&logctx->env, &logctx->log_flag)); - //!< set logctx - while (i < LOG_MAX) { - if (GetBitVal(logctx->env.ctrl, i)) { - pcur = logctx->parr[i] = &logbuf[i]; - pcur->tag = logctrl_name[i]; - pcur->flag = &logctx->log_flag; - - switch (i) { - case LOG_FPGA: - pcur->fp = logctx->env.fp_driver; - break; - case RUN_HAL: - pcur->fp = logctx->env.fp_run_hal; - break; - case LOG_WRITE_SPSPPS: - case LOG_WRITE_RPS: - case LOG_WRITE_SCANLIST: - case LOG_WRITE_STEAM: - case LOG_WRITE_REG: - pcur->fp = logctx->env.fp_syn_hal; - default: - break; - } - } - i++; - } -__RETURN: - return ret = MPP_OK; -__FAILED: - logctx->log_flag.debug_en = 0; - logctx_deinit(logctx); - - return ret; -} - -static void explain_input_buffer(void *hal, HalDecTask *task) -{ - RK_U32 i = 0; - H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal; - DXVA2_DecodeBufferDesc *pdes = (DXVA2_DecodeBufferDesc *)task->syntax.data; - for (i = 0; i < task->syntax.number; i++) { - switch (pdes[i].CompressedBufferType) { - case DXVA2_PictureParametersBufferType: - p_hal->pp = (DXVA_PicParams_H264_MVC *)pdes[i].pvPVPState; - break; - case DXVA2_InverseQuantizationMatrixBufferType: - p_hal->qm = (DXVA_Qmatrix_H264 *)pdes[i].pvPVPState; - break; - case DXVA2_SliceControlBufferType: - p_hal->slice_num = pdes[i].DataSize / sizeof(DXVA_Slice_H264_Long); - p_hal->slice_long = (DXVA_Slice_H264_Long *)pdes[i].pvPVPState; - break; - case DXVA2_BitStreamDateBufferType: - p_hal->bitstream = (RK_U8 *)pdes[i].pvPVPState; - p_hal->strm_len = pdes[i].DataSize; - break; - default: - break; - } - } -} - - -/*! -*********************************************************************** -* \brief -* VPUClientGetIOMMUStatus -*********************************************************************** -*/ -//extern "C" -#ifndef RKPLATFORM -RK_S32 VPUClientGetIOMMUStatus() -{ - return 0; -} -#endif -/*! -*********************************************************************** -* \brief -* init -*********************************************************************** -*/ -//extern "C" -#define RKV_MODE (0x1) -#define VDPU_MODE (0x2) -MPP_RET hal_h264d_init(void *hal, MppHalCfg *cfg) -{ - MppHalApi *p_api = NULL; - VPU_CLIENT_TYPE vpu_client = VPU_DEC_RKV; - MPP_RET ret = MPP_ERR_UNKNOW; - H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal; - - INP_CHECK(ret, NULL == p_hal); - memset(p_hal, 0, sizeof(H264dHalCtx_t)); - - p_api = &p_hal->hal_api; - - p_hal->frame_slots = cfg->frame_slots; - p_hal->packet_slots = cfg->packet_slots; - - //!< choose hard mode -#ifdef RKPLATFORM - { - RK_U32 mode = 0; - RK_S32 value = 0; - mpp_env_get_u32("use_mpp_mode", &mode, 0); - value = (!!access("/dev/rkvdec", F_OK)); - cfg->device_id = (value || (mode & VDPU_MODE)) ? HAL_VDPU : HAL_RKVDEC; - } -#endif - switch (cfg->device_id) { - case HAL_RKVDEC: - p_api->init = rkv_h264d_init; - p_api->deinit = rkv_h264d_deinit; - p_api->reg_gen = rkv_h264d_gen_regs; - p_api->start = rkv_h264d_start; - p_api->wait = rkv_h264d_wait; - p_api->reset = rkv_h264d_reset; - p_api->flush = rkv_h264d_flush; - p_api->control = rkv_h264d_control; - vpu_client = VPU_DEC_RKV; - break; - case HAL_VDPU: - p_api->init = vdpu_h264d_init; - p_api->deinit = vdpu_h264d_deinit; - p_api->reg_gen = vdpu_h264d_gen_regs; - p_api->start = vdpu_h264d_start; - p_api->wait = vdpu_h264d_wait; - p_api->reset = vdpu_h264d_reset; - p_api->flush = vdpu_h264d_flush; - p_api->control = vdpu_h264d_control; - vpu_client = VPU_DEC; - default: - break; - } - //!< callback function to parser module - p_hal->init_cb = cfg->hal_int_cb; - mpp_env_get_u32("rkv_h264d_debug", &rkv_h264d_hal_debug, 0); - //!< init logctx - FUN_CHECK(ret = logctx_init(&p_hal->logctx, p_hal->logctxbuf)); - //!< VPUClientInit -#ifdef RKPLATFORM - if (p_hal->vpu_socket <= 0) { - p_hal->vpu_socket = VPUClientInit(vpu_client); - if (p_hal->vpu_socket <= 0) { - mpp_err("p_hal->vpu_socket <= 0\n"); - ret = MPP_ERR_UNKNOW; - goto __FAILED; - } - } -#endif - //< get buffer group - if (p_hal->buf_group == NULL) { -#ifdef RKPLATFORM - mpp_log_f("mpp_buffer_group_get_internal used ion In"); - FUN_CHECK(ret = mpp_buffer_group_get_internal(&p_hal->buf_group, MPP_BUFFER_TYPE_ION)); -#else - FUN_CHECK(ret = mpp_buffer_group_get_internal(&p_hal->buf_group, MPP_BUFFER_TYPE_NORMAL)); -#endif - } - - //!< run init funtion - FUN_CHECK(ret = p_api->init(hal, cfg)); - (void)vpu_client; -__RETURN: - return MPP_OK; -__FAILED: - return ret; -} -/*! -*********************************************************************** -* \brief -* deinit -*********************************************************************** -*/ -//extern "C" -MPP_RET hal_h264d_deinit(void *hal) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal; - - FUN_CHECK(ret = p_hal->hal_api.deinit(hal)); - FUN_CHECK(ret = logctx_deinit(&p_hal->logctx)); - //!< VPUClientInit -#ifdef RKPLATFORM - if (p_hal->vpu_socket >= 0) { - VPUClientRelease(p_hal->vpu_socket); - } -#endif - if (p_hal->buf_group) { - FUN_CHECK(ret = mpp_buffer_group_put(p_hal->buf_group)); - } - - return MPP_OK; -__FAILED: - return ret; -} -/*! -*********************************************************************** -* \brief -* generate register -*********************************************************************** -*/ -//extern "C" -MPP_RET hal_h264d_gen_regs(void *hal, HalTaskInfo *task) -{ - //RK_U32 i = 0, j = 0; - //RK_U8 *pdata = NULL; - - H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal; - - //const RK_U32 *ptr = (RK_U32 *)H264_RKV_Cabac_table; - //for (i = 0; i< 155; i++) { - // for (j = 0; j< 6;j++) { - // pdata = (RK_U8 *)&ptr[j + i*6]; - // FPRINT(g_debug_file1, "0x%02x%02x%02x%02x, ", pdata[3], pdata[2], pdata[1], pdata[0]); - // } - // FPRINT(g_debug_file1, "\n"); - //} - //FPRINT(g_debug_file1, "\n"); - explain_input_buffer(hal, &task->dec); - - return p_hal->hal_api.reg_gen(hal, task); -} -/*! -*********************************************************************** -* \brief h -* start hard -*********************************************************************** -*/ -//extern "C" -MPP_RET hal_h264d_start(void *hal, HalTaskInfo *task) -{ - H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal; - - return p_hal->hal_api.start(hal, task); -} -/*! -*********************************************************************** -* \brief -* wait hard -*********************************************************************** -*/ -//extern "C" -MPP_RET hal_h264d_wait(void *hal, HalTaskInfo *task) -{ - H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal; - - return p_hal->hal_api.wait(hal, task); -} -/*! -*********************************************************************** -* \brief -* reset -*********************************************************************** -*/ -//extern "C" -MPP_RET hal_h264d_reset(void *hal) -{ - H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal; - - return p_hal->hal_api.reset(hal); -} -/*! -*********************************************************************** -* \brief -* flush -*********************************************************************** -*/ -//extern "C" -MPP_RET hal_h264d_flush(void *hal) -{ - H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal; - - return p_hal->hal_api.flush(hal); -} -/*! -*********************************************************************** -* \brief -* control -*********************************************************************** -*/ -//extern "C" -MPP_RET hal_h264d_control(void *hal, RK_S32 cmd_type, void *param) -{ - H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal; - - return p_hal->hal_api.control(hal, cmd_type, param); -} - - -const MppHalApi hal_api_h264d = { - "h264d_rkdec", - MPP_CTX_DEC, - MPP_VIDEO_CodingAVC, - sizeof(H264dHalCtx_t), - 0, - hal_h264d_init, - hal_h264d_deinit, - hal_h264d_gen_regs, - hal_h264d_start, - hal_h264d_wait, - hal_h264d_reset, - hal_h264d_flush, - hal_h264d_control, -}; - +/* +* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +#define MODULE_TAG "hal_h264d_api" + +#include +#include +#include + +#include "rk_type.h" +#include "vpu.h" +#include "mpp_log.h" +#include "mpp_err.h" +#include "mpp_mem.h" +#include "mpp_env.h" + +#include "dxva_syntax.h" +#include "h264d_syntax.h" +#include "h264d_log.h" + +#include "hal_h264d_global.h" +#include "hal_h264d_api.h" + +#include "hal_h264d_rkv_reg.h" +#include "hal_h264d_vdpu_reg.h" + + + + +static void close_log_files(LogEnv_t *env) +{ + FCLOSE(env->fp_driver); + FCLOSE(env->fp_syn_hal); + FCLOSE(env->fp_run_hal); +} +static MPP_RET open_log_files(LogEnv_t *env, LogFlag_t *pflag) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + char fname[128] = { 0 }; + + INP_CHECK(ret, !pflag->write_en); + set_log_outpath(env); + //!< runlog file + if (GetBitVal(env->ctrl, LOG_DEBUG)) { + sprintf(fname, "%s/h264d_hal_runlog.dat", env->outpath); + FLE_CHECK(ret, env->fp_run_hal = fopen(fname, "wb")); + } + //!< fpga drive file + if (GetBitVal(env->ctrl, LOG_FPGA)) { + sprintf(fname, "%s/h264d_driver_data.dat", env->outpath); + FLE_CHECK(ret, env->fp_driver = fopen(fname, "wb")); + } + //!< write syntax + if ( GetBitVal(env->ctrl, LOG_WRITE_SPSPPS ) + || GetBitVal(env->ctrl, LOG_WRITE_RPS ) + || GetBitVal(env->ctrl, LOG_WRITE_SCANLIST) + || GetBitVal(env->ctrl, LOG_WRITE_STEAM ) + || GetBitVal(env->ctrl, LOG_WRITE_REG ) ) { + sprintf(fname, "%s/h264d_write_syntax.dat", env->outpath); + FLE_CHECK(ret, env->fp_syn_hal = fopen(fname, "wb")); + } + +__RETURN: + return MPP_OK; + +__FAILED: + return ret; +} + +static MPP_RET logctx_deinit(H264dLogCtx_t *logctx) +{ + close_log_files(&logctx->env); + + return MPP_OK; +} + +static MPP_RET logctx_init(H264dLogCtx_t *logctx, LogCtx_t *logbuf) +{ + RK_U8 i = 0; + MPP_RET ret = MPP_ERR_UNKNOW; + LogCtx_t *pcur = NULL; + + FUN_CHECK(ret = get_logenv(&logctx->env)); + + FUN_CHECK(ret = explain_ctrl_flag(logctx->env.ctrl, &logctx->log_flag)); + if ( !logctx->log_flag.debug_en + && !logctx->log_flag.print_en && !logctx->log_flag.write_en ) { + logctx->log_flag.debug_en = 0; + goto __RETURN; + } + logctx->log_flag.level = (1 << logctx->env.level) - 1; + //!< open file + FUN_CHECK(ret = open_log_files(&logctx->env, &logctx->log_flag)); + //!< set logctx + while (i < LOG_MAX) { + if (GetBitVal(logctx->env.ctrl, i)) { + pcur = logctx->parr[i] = &logbuf[i]; + pcur->tag = logctrl_name[i]; + pcur->flag = &logctx->log_flag; + + switch (i) { + case LOG_FPGA: + pcur->fp = logctx->env.fp_driver; + break; + case RUN_HAL: + pcur->fp = logctx->env.fp_run_hal; + break; + case LOG_WRITE_SPSPPS: + case LOG_WRITE_RPS: + case LOG_WRITE_SCANLIST: + case LOG_WRITE_STEAM: + case LOG_WRITE_REG: + pcur->fp = logctx->env.fp_syn_hal; + default: + break; + } + } + i++; + } +__RETURN: + return ret = MPP_OK; +__FAILED: + logctx->log_flag.debug_en = 0; + logctx_deinit(logctx); + + return ret; +} + +static void explain_input_buffer(void *hal, HalDecTask *task) +{ + RK_U32 i = 0; + H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal; + DXVA2_DecodeBufferDesc *pdes = (DXVA2_DecodeBufferDesc *)task->syntax.data; + for (i = 0; i < task->syntax.number; i++) { + switch (pdes[i].CompressedBufferType) { + case DXVA2_PictureParametersBufferType: + p_hal->pp = (DXVA_PicParams_H264_MVC *)pdes[i].pvPVPState; + break; + case DXVA2_InverseQuantizationMatrixBufferType: + p_hal->qm = (DXVA_Qmatrix_H264 *)pdes[i].pvPVPState; + break; + case DXVA2_SliceControlBufferType: + p_hal->slice_num = pdes[i].DataSize / sizeof(DXVA_Slice_H264_Long); + p_hal->slice_long = (DXVA_Slice_H264_Long *)pdes[i].pvPVPState; + break; + case DXVA2_BitStreamDateBufferType: + p_hal->bitstream = (RK_U8 *)pdes[i].pvPVPState; + p_hal->strm_len = pdes[i].DataSize; + break; + default: + break; + } + } +} + + +/*! +*********************************************************************** +* \brief +* VPUClientGetIOMMUStatus +*********************************************************************** +*/ +//extern "C" +#ifndef RKPLATFORM +RK_S32 VPUClientGetIOMMUStatus() +{ + return 0; +} +#endif +/*! +*********************************************************************** +* \brief +* init +*********************************************************************** +*/ +//extern "C" +#define RKV_MODE (0x1) +#define VDPU_MODE (0x2) +MPP_RET hal_h264d_init(void *hal, MppHalCfg *cfg) +{ + MppHalApi *p_api = NULL; + VPU_CLIENT_TYPE vpu_client = VPU_DEC_RKV; + MPP_RET ret = MPP_ERR_UNKNOW; + H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal; + + INP_CHECK(ret, NULL == p_hal); + memset(p_hal, 0, sizeof(H264dHalCtx_t)); + + p_api = &p_hal->hal_api; + + p_hal->frame_slots = cfg->frame_slots; + p_hal->packet_slots = cfg->packet_slots; + + //!< choose hard mode +#ifdef RKPLATFORM + { + RK_U32 mode = 0; + RK_S32 value = 0; + mpp_env_get_u32("use_mpp_mode", &mode, 0); + value = (!!access("/dev/rkvdec", F_OK)); + cfg->device_id = (value || (mode & VDPU_MODE)) ? HAL_VDPU : HAL_RKVDEC; + } +#endif + switch (cfg->device_id) { + case HAL_RKVDEC: + p_api->init = rkv_h264d_init; + p_api->deinit = rkv_h264d_deinit; + p_api->reg_gen = rkv_h264d_gen_regs; + p_api->start = rkv_h264d_start; + p_api->wait = rkv_h264d_wait; + p_api->reset = rkv_h264d_reset; + p_api->flush = rkv_h264d_flush; + p_api->control = rkv_h264d_control; + vpu_client = VPU_DEC_RKV; + break; + case HAL_VDPU: + p_api->init = vdpu_h264d_init; + p_api->deinit = vdpu_h264d_deinit; + p_api->reg_gen = vdpu_h264d_gen_regs; + p_api->start = vdpu_h264d_start; + p_api->wait = vdpu_h264d_wait; + p_api->reset = vdpu_h264d_reset; + p_api->flush = vdpu_h264d_flush; + p_api->control = vdpu_h264d_control; + vpu_client = VPU_DEC; + default: + break; + } + //!< callback function to parser module + p_hal->init_cb = cfg->hal_int_cb; + mpp_env_get_u32("rkv_h264d_debug", &rkv_h264d_hal_debug, 0); + //!< init logctx + FUN_CHECK(ret = logctx_init(&p_hal->logctx, p_hal->logctxbuf)); + //!< VPUClientInit +#ifdef RKPLATFORM + if (p_hal->vpu_socket <= 0) { + p_hal->vpu_socket = VPUClientInit(vpu_client); + if (p_hal->vpu_socket <= 0) { + mpp_err("p_hal->vpu_socket <= 0\n"); + ret = MPP_ERR_UNKNOW; + goto __FAILED; + } + } +#endif + //< get buffer group + if (p_hal->buf_group == NULL) { +#ifdef RKPLATFORM + mpp_log_f("mpp_buffer_group_get_internal used ion In"); + FUN_CHECK(ret = mpp_buffer_group_get_internal(&p_hal->buf_group, MPP_BUFFER_TYPE_ION)); +#else + FUN_CHECK(ret = mpp_buffer_group_get_internal(&p_hal->buf_group, MPP_BUFFER_TYPE_NORMAL)); +#endif + } + + //!< run init funtion + FUN_CHECK(ret = p_api->init(hal, cfg)); + (void)vpu_client; +__RETURN: + return MPP_OK; +__FAILED: + return ret; +} +/*! +*********************************************************************** +* \brief +* deinit +*********************************************************************** +*/ +//extern "C" +MPP_RET hal_h264d_deinit(void *hal) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal; + + FUN_CHECK(ret = p_hal->hal_api.deinit(hal)); + FUN_CHECK(ret = logctx_deinit(&p_hal->logctx)); + //!< VPUClientInit +#ifdef RKPLATFORM + if (p_hal->vpu_socket >= 0) { + VPUClientRelease(p_hal->vpu_socket); + } +#endif + if (p_hal->buf_group) { + FUN_CHECK(ret = mpp_buffer_group_put(p_hal->buf_group)); + } + + return MPP_OK; +__FAILED: + return ret; +} +/*! +*********************************************************************** +* \brief +* generate register +*********************************************************************** +*/ +//extern "C" +MPP_RET hal_h264d_gen_regs(void *hal, HalTaskInfo *task) +{ + //RK_U32 i = 0, j = 0; + //RK_U8 *pdata = NULL; + + H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal; + + //const RK_U32 *ptr = (RK_U32 *)H264_RKV_Cabac_table; + //for (i = 0; i< 155; i++) { + // for (j = 0; j< 6;j++) { + // pdata = (RK_U8 *)&ptr[j + i*6]; + // FPRINT(g_debug_file1, "0x%02x%02x%02x%02x, ", pdata[3], pdata[2], pdata[1], pdata[0]); + // } + // FPRINT(g_debug_file1, "\n"); + //} + //FPRINT(g_debug_file1, "\n"); + explain_input_buffer(hal, &task->dec); + + return p_hal->hal_api.reg_gen(hal, task); +} +/*! +*********************************************************************** +* \brief h +* start hard +*********************************************************************** +*/ +//extern "C" +MPP_RET hal_h264d_start(void *hal, HalTaskInfo *task) +{ + H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal; + + return p_hal->hal_api.start(hal, task); +} +/*! +*********************************************************************** +* \brief +* wait hard +*********************************************************************** +*/ +//extern "C" +MPP_RET hal_h264d_wait(void *hal, HalTaskInfo *task) +{ + H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal; + + return p_hal->hal_api.wait(hal, task); +} +/*! +*********************************************************************** +* \brief +* reset +*********************************************************************** +*/ +//extern "C" +MPP_RET hal_h264d_reset(void *hal) +{ + H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal; + + return p_hal->hal_api.reset(hal); +} +/*! +*********************************************************************** +* \brief +* flush +*********************************************************************** +*/ +//extern "C" +MPP_RET hal_h264d_flush(void *hal) +{ + H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal; + + return p_hal->hal_api.flush(hal); +} +/*! +*********************************************************************** +* \brief +* control +*********************************************************************** +*/ +//extern "C" +MPP_RET hal_h264d_control(void *hal, RK_S32 cmd_type, void *param) +{ + H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal; + + return p_hal->hal_api.control(hal, cmd_type, param); +} + + +const MppHalApi hal_api_h264d = { + "h264d_rkdec", + MPP_CTX_DEC, + MPP_VIDEO_CodingAVC, + sizeof(H264dHalCtx_t), + 0, + hal_h264d_init, + hal_h264d_deinit, + hal_h264d_gen_regs, + hal_h264d_start, + hal_h264d_wait, + hal_h264d_reset, + hal_h264d_flush, + hal_h264d_control, +}; + diff --git a/mpp/hal/rkdec/h264d/hal_h264d_fifo.c b/mpp/hal/rkdec/h264d/hal_h264d_fifo.c index d626c75b..e3bae406 100644 --- a/mpp/hal/rkdec/h264d/hal_h264d_fifo.c +++ b/mpp/hal/rkdec/h264d/hal_h264d_fifo.c @@ -1,221 +1,221 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define MODULE_TAG "hal_h264d_fifo" - -#include -#include - -#include "mpp_log.h" -#include "mpp_mem.h" - -#include "h264d_log.h" -#include "hal_h264d_fifo.h" - -/*! -*********************************************************************** -* \brief -* write fifo data to file -*********************************************************************** -*/ -//extern "C" -void fifo_fwrite(FILE *fp, void *psrc, RK_U32 size) -{ - fwrite(psrc, 1, size, fp); - fflush(fp); -} - -/*! -*********************************************************************** -* \brief -* flush left bytes to fifo -*********************************************************************** -*/ -//extern "C" -void fifo_flush_bits(FifoCtx_t *pkt) -{ - if (pkt->bitpos) { - fifo_write_bits(pkt, 0, (64 - pkt->bitpos), "flush"); - pkt->index++; - pkt->bitpos = 0; - } -} - -//void fifo_fwrite_header(FifoCtx_t *pkt, RK_S32 pkt_size) -//{ -// if (pkt->fp_data) -// { -// pkt->size = pkt_size; -// fifo_fwrite(pkt->fp_data, &pkt->header, sizeof(RK_U32)); -// fifo_fwrite(pkt->fp_data, &pkt->size, sizeof(RK_U32)); -// } -//} - -/*! -*********************************************************************** -* \brief -* fwrite header and data -*********************************************************************** -*/ -//extern "C" -void fifo_fwrite_data(FifoCtx_t *pkt) -{ - RK_U32 pkt_size = 0; - - if (pkt->fp_data) { - pkt_size = pkt->index * sizeof(RK_U64); - fifo_fwrite(pkt->fp_data, &pkt->header, sizeof(RK_U32)); - fifo_fwrite(pkt->fp_data, &pkt_size, sizeof(RK_U32)); - fifo_fwrite(pkt->fp_data, pkt->pbuf, pkt->index * sizeof(RK_U64)); - } -} - -/*! -*********************************************************************** -* \brief -* write bits to fifo -*********************************************************************** -*/ -//extern "C" -void fifo_write_bits(FifoCtx_t *pkt, RK_U64 invalue, RK_U8 lbits, const char *name) -{ - RK_U8 hbits = 0; - - if (!lbits) return; - - hbits = 64 - lbits; - invalue = (invalue << hbits) >> hbits; - LogInfo(pkt->logctx, "%48s = %10d (bits=%d)", name, invalue, lbits); - pkt->bvalue |= invalue << pkt->bitpos; // high bits value - if ((pkt->bitpos + lbits) >= 64) { - pkt->pbuf[pkt->index] = pkt->bvalue; - pkt->bvalue = invalue >> (64 - pkt->bitpos); // low bits value - pkt->index++; - ASSERT(pkt->index <= pkt->buflen); - } - pkt->pbuf[pkt->index] = pkt->bvalue; - pkt->bitpos = (pkt->bitpos + lbits) & 63; -} -/*! -*********************************************************************** -* \brief -* align fifo bits -*********************************************************************** -*/ -//extern "C" -void fifo_align_bits(FifoCtx_t *pkt, RK_U8 align_bits) -{ - RK_U32 word_offset = 0, bits_offset = 0, bitlen = 0; - - word_offset = (align_bits >= 64) ? ((pkt->index & (((align_bits & 0xfe0) >> 6) - 1)) << 6) : 0; - bits_offset = (align_bits - (word_offset + (pkt->bitpos % align_bits))) % align_bits; - while (bits_offset > 0) { - bitlen = (bits_offset >= 8) ? 8 : bits_offset; - fifo_write_bits(pkt, 0, bitlen, "align"); - bits_offset -= bitlen; - } -} -/*! -*********************************************************************** -* \brief -* write bytes to fifo -*********************************************************************** -*/ -//extern "C" -void fifo_write_bytes(FifoCtx_t *pkt, void *psrc, RK_U32 size) -{ - RK_U8 hbits = 0; - RK_U32 bitslen = 0; - RK_U8 *pdst = NULL; - - hbits = 64 - pkt->bitpos; - pkt->pbuf[pkt->index] = pkt->bitpos ? ((pkt->bvalue << hbits) >> hbits) : 0; - if (size) { - pdst = (RK_U8 *)&pkt->pbuf[pkt->index]; - pdst += pkt->bitpos / 8; - - memcpy(pdst, psrc, size); - bitslen = size * 8 + pkt->bitpos; - - pkt->index += bitslen / 64; - pkt->bitpos = bitslen & 63; - - hbits = 64 - pkt->bitpos; - pkt->bvalue = pkt->bitpos ? ((pkt->pbuf[pkt->index] << hbits) >> hbits) : 0; - } -} -/*! -*********************************************************************** -* \brief -* reset fifo packet -*********************************************************************** -*/ -//extern "C" -void fifo_packet_reset(FifoCtx_t *pkt) -{ - pkt->index = 0; - pkt->bitpos = 0; - pkt->bvalue = 0; - pkt->size = 0; -} -/*! -*********************************************************************** -* \brief -* init fifo packet -*********************************************************************** -*/ -//extern "C" -void fifo_packet_init(FifoCtx_t *pkt, void *p_start, RK_S32 size) -{ - pkt->index = 0; - pkt->bitpos = 0; - pkt->bvalue = 0; - pkt->size = size; - pkt->buflen = (pkt->size + 7) / 8; // align 64bit - pkt->pbuf = (RK_U64 *)p_start; -} - - -/*! -*********************************************************************** -* \brief -* alloc fifo packet -*********************************************************************** -*/ -//extern "C" -MPP_RET fifo_packet_alloc(FifoCtx_t *pkt, RK_S32 header, RK_S32 size) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - - pkt->header = header; - pkt->index = 0; - pkt->bitpos = 0; - pkt->bvalue = 0; - pkt->size = size; - pkt->buflen = (pkt->size + 7) / 8; // align 64bit - pkt->pbuf = NULL; - if (pkt->buflen) { - pkt->pbuf = mpp_calloc(RK_U64, pkt->buflen); - MEM_CHECK(ret, pkt->pbuf); - } - - return MPP_OK; - -__FAILED: - return ret; -} - - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define MODULE_TAG "hal_h264d_fifo" + +#include +#include + +#include "mpp_log.h" +#include "mpp_mem.h" + +#include "h264d_log.h" +#include "hal_h264d_fifo.h" + +/*! +*********************************************************************** +* \brief +* write fifo data to file +*********************************************************************** +*/ +//extern "C" +void fifo_fwrite(FILE *fp, void *psrc, RK_U32 size) +{ + fwrite(psrc, 1, size, fp); + fflush(fp); +} + +/*! +*********************************************************************** +* \brief +* flush left bytes to fifo +*********************************************************************** +*/ +//extern "C" +void fifo_flush_bits(FifoCtx_t *pkt) +{ + if (pkt->bitpos) { + fifo_write_bits(pkt, 0, (64 - pkt->bitpos), "flush"); + pkt->index++; + pkt->bitpos = 0; + } +} + +//void fifo_fwrite_header(FifoCtx_t *pkt, RK_S32 pkt_size) +//{ +// if (pkt->fp_data) +// { +// pkt->size = pkt_size; +// fifo_fwrite(pkt->fp_data, &pkt->header, sizeof(RK_U32)); +// fifo_fwrite(pkt->fp_data, &pkt->size, sizeof(RK_U32)); +// } +//} + +/*! +*********************************************************************** +* \brief +* fwrite header and data +*********************************************************************** +*/ +//extern "C" +void fifo_fwrite_data(FifoCtx_t *pkt) +{ + RK_U32 pkt_size = 0; + + if (pkt->fp_data) { + pkt_size = pkt->index * sizeof(RK_U64); + fifo_fwrite(pkt->fp_data, &pkt->header, sizeof(RK_U32)); + fifo_fwrite(pkt->fp_data, &pkt_size, sizeof(RK_U32)); + fifo_fwrite(pkt->fp_data, pkt->pbuf, pkt->index * sizeof(RK_U64)); + } +} + +/*! +*********************************************************************** +* \brief +* write bits to fifo +*********************************************************************** +*/ +//extern "C" +void fifo_write_bits(FifoCtx_t *pkt, RK_U64 invalue, RK_U8 lbits, const char *name) +{ + RK_U8 hbits = 0; + + if (!lbits) return; + + hbits = 64 - lbits; + invalue = (invalue << hbits) >> hbits; + LogInfo(pkt->logctx, "%48s = %10d (bits=%d)", name, invalue, lbits); + pkt->bvalue |= invalue << pkt->bitpos; // high bits value + if ((pkt->bitpos + lbits) >= 64) { + pkt->pbuf[pkt->index] = pkt->bvalue; + pkt->bvalue = invalue >> (64 - pkt->bitpos); // low bits value + pkt->index++; + ASSERT(pkt->index <= pkt->buflen); + } + pkt->pbuf[pkt->index] = pkt->bvalue; + pkt->bitpos = (pkt->bitpos + lbits) & 63; +} +/*! +*********************************************************************** +* \brief +* align fifo bits +*********************************************************************** +*/ +//extern "C" +void fifo_align_bits(FifoCtx_t *pkt, RK_U8 align_bits) +{ + RK_U32 word_offset = 0, bits_offset = 0, bitlen = 0; + + word_offset = (align_bits >= 64) ? ((pkt->index & (((align_bits & 0xfe0) >> 6) - 1)) << 6) : 0; + bits_offset = (align_bits - (word_offset + (pkt->bitpos % align_bits))) % align_bits; + while (bits_offset > 0) { + bitlen = (bits_offset >= 8) ? 8 : bits_offset; + fifo_write_bits(pkt, 0, bitlen, "align"); + bits_offset -= bitlen; + } +} +/*! +*********************************************************************** +* \brief +* write bytes to fifo +*********************************************************************** +*/ +//extern "C" +void fifo_write_bytes(FifoCtx_t *pkt, void *psrc, RK_U32 size) +{ + RK_U8 hbits = 0; + RK_U32 bitslen = 0; + RK_U8 *pdst = NULL; + + hbits = 64 - pkt->bitpos; + pkt->pbuf[pkt->index] = pkt->bitpos ? ((pkt->bvalue << hbits) >> hbits) : 0; + if (size) { + pdst = (RK_U8 *)&pkt->pbuf[pkt->index]; + pdst += pkt->bitpos / 8; + + memcpy(pdst, psrc, size); + bitslen = size * 8 + pkt->bitpos; + + pkt->index += bitslen / 64; + pkt->bitpos = bitslen & 63; + + hbits = 64 - pkt->bitpos; + pkt->bvalue = pkt->bitpos ? ((pkt->pbuf[pkt->index] << hbits) >> hbits) : 0; + } +} +/*! +*********************************************************************** +* \brief +* reset fifo packet +*********************************************************************** +*/ +//extern "C" +void fifo_packet_reset(FifoCtx_t *pkt) +{ + pkt->index = 0; + pkt->bitpos = 0; + pkt->bvalue = 0; + pkt->size = 0; +} +/*! +*********************************************************************** +* \brief +* init fifo packet +*********************************************************************** +*/ +//extern "C" +void fifo_packet_init(FifoCtx_t *pkt, void *p_start, RK_S32 size) +{ + pkt->index = 0; + pkt->bitpos = 0; + pkt->bvalue = 0; + pkt->size = size; + pkt->buflen = (pkt->size + 7) / 8; // align 64bit + pkt->pbuf = (RK_U64 *)p_start; +} + + +/*! +*********************************************************************** +* \brief +* alloc fifo packet +*********************************************************************** +*/ +//extern "C" +MPP_RET fifo_packet_alloc(FifoCtx_t *pkt, RK_S32 header, RK_S32 size) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + + pkt->header = header; + pkt->index = 0; + pkt->bitpos = 0; + pkt->bvalue = 0; + pkt->size = size; + pkt->buflen = (pkt->size + 7) / 8; // align 64bit + pkt->pbuf = NULL; + if (pkt->buflen) { + pkt->pbuf = mpp_calloc(RK_U64, pkt->buflen); + MEM_CHECK(ret, pkt->pbuf); + } + + return MPP_OK; + +__FAILED: + return ret; +} + + diff --git a/mpp/hal/rkdec/h264d/hal_h264d_fifo.h b/mpp/hal/rkdec/h264d/hal_h264d_fifo.h index abce8077..e8315899 100644 --- a/mpp/hal/rkdec/h264d/hal_h264d_fifo.h +++ b/mpp/hal/rkdec/h264d/hal_h264d_fifo.h @@ -1,46 +1,46 @@ -#ifndef __HAL_H264D_FIFO_H__ -#define __HAL_H264D_FIFO_H__ - -#include "rk_type.h" -#include "mpp_err.h" -#include "h264d_log.h" - - -typedef struct { - RK_U32 header; - RK_U32 buflen; //!< max buf length, 64bit uint - RK_U32 index; //!< current uint position - RK_U64 *pbuf; //!< outpacket data - RK_U64 bvalue; //!< buffer value, 64 bit - RK_U8 bitpos; //!< bit pos in 64bit - RK_U32 size; //!< data size,except header - LogCtx_t *logctx; //!< for debug - FILE *fp_data; //!< for fpga -} FifoCtx_t; - - -#ifdef __cplusplus -extern "C" { -#endif - -void fifo_packet_reset (FifoCtx_t *pkt); -void fifo_fwrite_header(FifoCtx_t *pkt, RK_S32 pkt_size); -void fifo_fwrite_data (FifoCtx_t *pkt); -void fifo_write_bits (FifoCtx_t *pkt, RK_U64 invalue, RK_U8 lbits, const char *name); -void fifo_flush_bits (FifoCtx_t *pkt); -void fifo_align_bits (FifoCtx_t *pkt, RK_U8 align_bits); -void fifo_write_bytes (FifoCtx_t *pkt, void *psrc, RK_U32 size); -void fifo_fwrite (FILE *fp, void *psrc, RK_U32 size); -void fifo_packet_init (FifoCtx_t *pkt, void *p_start, RK_S32 size); -MPP_RET fifo_packet_alloc (FifoCtx_t *pkt, RK_S32 header, RK_S32 size); -#ifdef __cplusplus -} -#endif - - - -//!<============================ -#endif //!<__HAL_H264D_FIFO_H__ - - - +#ifndef __HAL_H264D_FIFO_H__ +#define __HAL_H264D_FIFO_H__ + +#include "rk_type.h" +#include "mpp_err.h" +#include "h264d_log.h" + + +typedef struct { + RK_U32 header; + RK_U32 buflen; //!< max buf length, 64bit uint + RK_U32 index; //!< current uint position + RK_U64 *pbuf; //!< outpacket data + RK_U64 bvalue; //!< buffer value, 64 bit + RK_U8 bitpos; //!< bit pos in 64bit + RK_U32 size; //!< data size,except header + LogCtx_t *logctx; //!< for debug + FILE *fp_data; //!< for fpga +} FifoCtx_t; + + +#ifdef __cplusplus +extern "C" { +#endif + +void fifo_packet_reset (FifoCtx_t *pkt); +void fifo_fwrite_header(FifoCtx_t *pkt, RK_S32 pkt_size); +void fifo_fwrite_data (FifoCtx_t *pkt); +void fifo_write_bits (FifoCtx_t *pkt, RK_U64 invalue, RK_U8 lbits, const char *name); +void fifo_flush_bits (FifoCtx_t *pkt); +void fifo_align_bits (FifoCtx_t *pkt, RK_U8 align_bits); +void fifo_write_bytes (FifoCtx_t *pkt, void *psrc, RK_U32 size); +void fifo_fwrite (FILE *fp, void *psrc, RK_U32 size); +void fifo_packet_init (FifoCtx_t *pkt, void *p_start, RK_S32 size); +MPP_RET fifo_packet_alloc (FifoCtx_t *pkt, RK_S32 header, RK_S32 size); +#ifdef __cplusplus +} +#endif + + + +//!<============================ +#endif //!<__HAL_H264D_FIFO_H__ + + + diff --git a/mpp/hal/rkdec/h264d/hal_h264d_global.h b/mpp/hal/rkdec/h264d/hal_h264d_global.h index d89e3c8f..f7df9a8d 100644 --- a/mpp/hal/rkdec/h264d/hal_h264d_global.h +++ b/mpp/hal/rkdec/h264d/hal_h264d_global.h @@ -1,63 +1,63 @@ -/* -* -* Copyright 2015 Rockchip Electronics Co. LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - - -#ifndef __HAL_H264D_GLOBAL_H__ -#define __HAL_H264D_GLOBAL_H__ - -#include "mpp_hal.h" -#include "dxva_syntax.h" -#include "h264d_syntax.h" - -#include "h264d_log.h" -#include "hal_h264d_fifo.h" - - - -typedef struct h264d_hal_ctx_t { - MppHalApi hal_api; - void *regs; - void *pkts; - void *dump; - RK_U8 spt_BitstrmRaw; - RK_U8 set_BitstrmRaw; - - DXVA_PicParams_H264_MVC *pp; - DXVA_Qmatrix_H264 *qm; - RK_U32 slice_num; - DXVA_Slice_H264_Short *slice_short; //!< MAX_SLICES - DXVA_Slice_H264_Long *slice_long; //!< MAX_SLICES - RK_U8 *bitstream; - RK_U32 strm_len; - H264dLogCtx_t logctx; //!< debug log file - LogCtx_t logctxbuf[LOG_MAX]; - void *priv; //!< resert data for extent - //!< add - HalDecTask *in_task; - MppBufSlots frame_slots; - MppBufSlots packet_slots; - MppBufferGroup buf_group; - MppBuffer cabac_buf; - RK_S32 vpu_socket; - RK_U64 total_time; - RK_U64 iDecodedNum; - IOInterruptCB init_cb; -} H264dHalCtx_t; - - - -#endif /*__HAL_H264D_REG_H__*/ +/* +* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +#ifndef __HAL_H264D_GLOBAL_H__ +#define __HAL_H264D_GLOBAL_H__ + +#include "mpp_hal.h" +#include "dxva_syntax.h" +#include "h264d_syntax.h" + +#include "h264d_log.h" +#include "hal_h264d_fifo.h" + + + +typedef struct h264d_hal_ctx_t { + MppHalApi hal_api; + void *regs; + void *pkts; + void *dump; + RK_U8 spt_BitstrmRaw; + RK_U8 set_BitstrmRaw; + + DXVA_PicParams_H264_MVC *pp; + DXVA_Qmatrix_H264 *qm; + RK_U32 slice_num; + DXVA_Slice_H264_Short *slice_short; //!< MAX_SLICES + DXVA_Slice_H264_Long *slice_long; //!< MAX_SLICES + RK_U8 *bitstream; + RK_U32 strm_len; + H264dLogCtx_t logctx; //!< debug log file + LogCtx_t logctxbuf[LOG_MAX]; + void *priv; //!< resert data for extent + //!< add + HalDecTask *in_task; + MppBufSlots frame_slots; + MppBufSlots packet_slots; + MppBufferGroup buf_group; + MppBuffer cabac_buf; + RK_S32 vpu_socket; + RK_U64 total_time; + RK_U64 iDecodedNum; + IOInterruptCB init_cb; +} H264dHalCtx_t; + + + +#endif /*__HAL_H264D_REG_H__*/ diff --git a/mpp/hal/rkdec/h264d/hal_h264d_rkv_pkt.c b/mpp/hal/rkdec/h264d/hal_h264d_rkv_pkt.c index 7c0c5e89..d8a1f1c8 100644 --- a/mpp/hal/rkdec/h264d/hal_h264d_rkv_pkt.c +++ b/mpp/hal/rkdec/h264d/hal_h264d_rkv_pkt.c @@ -1,527 +1,527 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define MODULE_TAG "hal_h264d_rkv_pkt" - -#include -#include - -#include "vpu.h" -#include "mpp_mem.h" -#include "mpp_buffer.h" -#include "hal_task.h" - -#include "dxva_syntax.h" -#include "h264d_log.h" -#include "h264d_syntax.h" -#include "hal_h264d_fifo.h" -#include "hal_h264d_api.h" -#include "hal_h264d_global.h" -#include "hal_h264d_rkv_pkt.h" -#include "hal_h264d_rkv_reg.h" - -//!< Header -#define H264dREG_HEADER 0x48474552 -#define H264dPPS_HEADER 0x48535050 -#define H264dSCL_HEADER 0x534c4353 -#define H264dRPS_HEADER 0x48535052 -#define H264dCRC_HEADER 0x48435243 -#define H264dSTM_HEADER 0x4d525453 -#define H264dERR_HEADER 0x524f5245 - - -#define FPGA_TEST 0 - -const enum -{ - H264ScalingList4x4Length = 16, - H264ScalingList8x8Length = 64, -} ScalingListLength; - - - -static void rkv_write_sps_to_fifo(H264dHalCtx_t *p_hal, FifoCtx_t *pkt) -{ - FunctionIn(p_hal->logctx.parr[RUN_HAL]); - - fifo_write_bits(pkt, -1, 4, "seq_parameter_set_id"); //!< not used in hard - fifo_write_bits(pkt, -1, 8, "profile_idc"); //!< not used in hard - fifo_write_bits(pkt, -1, 1, "constraint_set3_flag"); //!< not used in hard - fifo_write_bits(pkt, p_hal->pp->chroma_format_idc, 2, "chroma_format_idc"); - fifo_write_bits(pkt, (p_hal->pp->bit_depth_luma_minus8 + 8), 3, "bit_depth_luma"); - fifo_write_bits(pkt, (p_hal->pp->bit_depth_chroma_minus8 + 8), 3, "bit_depth_chroma"); - fifo_write_bits(pkt, 0, 1, "qpprime_y_zero_transform_bypass_flag"); //!< not supported in hard - fifo_write_bits(pkt, p_hal->pp->log2_max_frame_num_minus4, 4, "log2_max_frame_num_minus4"); - fifo_write_bits(pkt, p_hal->pp->num_ref_frames, 5, "max_num_ref_frames"); - fifo_write_bits(pkt, p_hal->pp->pic_order_cnt_type, 2, "pic_order_cnt_type"); - fifo_write_bits(pkt, p_hal->pp->log2_max_pic_order_cnt_lsb_minus4, 4, "log2_max_pic_order_cnt_lsb_minus4"); - fifo_write_bits(pkt, p_hal->pp->delta_pic_order_always_zero_flag, 1, "delta_pic_order_always_zero_flag"); - fifo_write_bits(pkt, (p_hal->pp->wFrameWidthInMbsMinus1 + 1), 9, "pic_width_in_mbs"); - fifo_write_bits(pkt, (p_hal->pp->wFrameHeightInMbsMinus1 + 1), 9, "pic_height_in_mbs"); - fifo_write_bits(pkt, p_hal->pp->frame_mbs_only_flag, 1, "frame_mbs_only_flag"); - fifo_write_bits(pkt, p_hal->pp->MbaffFrameFlag, 1, "mb_adaptive_frame_field_flag"); - fifo_write_bits(pkt, p_hal->pp->direct_8x8_inference_flag, 1, "direct_8x8_inference_flag"); - - fifo_write_bits(pkt, 1, 1, "mvc_extension_enable"); - fifo_write_bits(pkt, (p_hal->pp->num_views_minus1 + 1), 2, "num_views"); - fifo_write_bits(pkt, p_hal->pp->view_id[0], 10, "view_id[2]"); - fifo_write_bits(pkt, p_hal->pp->view_id[1], 10, "view_id[2]"); - fifo_write_bits(pkt, p_hal->pp->num_anchor_refs_l0[0], 1, "num_anchor_refs_l0"); - if (p_hal->pp->num_anchor_refs_l0[0]) { - fifo_write_bits(pkt, p_hal->pp->anchor_ref_l0[0][0], 10, "anchor_ref_l0"); - } else { - fifo_write_bits(pkt, 0, 10, "anchor_ref_l0"); - } - fifo_write_bits(pkt, p_hal->pp->num_anchor_refs_l1[0], 1, "num_anchor_refs_l1"); - if (p_hal->pp->num_anchor_refs_l1[0]) { - fifo_write_bits(pkt, p_hal->pp->anchor_ref_l1[0][0], 10, "anchor_ref_l1"); - } else { - fifo_write_bits(pkt, 0, 10, "anchor_ref_l1"); - } - fifo_write_bits(pkt, p_hal->pp->num_non_anchor_refs_l0[0], 1, "num_non_anchor_refs_l0"); - if (p_hal->pp->num_non_anchor_refs_l0[0]) { - fifo_write_bits(pkt, p_hal->pp->non_anchor_ref_l0[0][0], 10, "non_anchor_ref_l0"); - } else { - fifo_write_bits(pkt, 0, 10, "non_anchor_ref_l0"); - } - fifo_write_bits(pkt, p_hal->pp->num_non_anchor_refs_l1[0], 1, "num_non_anchor_refs_l1"); - if (p_hal->pp->num_non_anchor_refs_l1[0]) { - fifo_write_bits(pkt, p_hal->pp->non_anchor_ref_l1[0][0], 10, "non_anchor_ref_l1"); - } else { - fifo_write_bits(pkt, 0, 10, "non_anchor_ref_l1"); - } - fifo_align_bits(pkt, 32); - FunctionOut(p_hal->logctx.parr[RUN_HAL]); -} - -static void rkv_write_pps_to_fifo(H264dHalCtx_t *p_hal, FifoCtx_t *pkt) -{ - RK_U32 Scaleing_list_address = 0; - RK_U32 offset = RKV_CABAC_TAB_SIZE + RKV_SPSPPS_SIZE + RKV_RPS_SIZE; - FunctionIn(p_hal->logctx.parr[RUN_HAL]); - fifo_write_bits(pkt, -1, 8, "pps_pic_parameter_set_id"); - fifo_write_bits(pkt, -1, 5, "pps_seq_parameter_set_id"); - fifo_write_bits(pkt, p_hal->pp->entropy_coding_mode_flag, 1, "entropy_coding_mode_flag"); - fifo_write_bits(pkt, p_hal->pp->pic_order_present_flag, 1, "bottom_field_pic_order_in_frame_present_flag"); - fifo_write_bits(pkt, p_hal->pp->num_ref_idx_l0_active_minus1, 5, "num_ref_idx_l0_default_active_minus1"); - fifo_write_bits(pkt, p_hal->pp->num_ref_idx_l1_active_minus1, 5, "num_ref_idx_l1_default_active_minus1"); - fifo_write_bits(pkt, p_hal->pp->weighted_pred_flag, 1, "weighted_pred_flag"); - fifo_write_bits(pkt, p_hal->pp->weighted_bipred_idc, 2, "weighted_bipred_idc"); - fifo_write_bits(pkt, p_hal->pp->pic_init_qp_minus26, 7, "pic_init_qp_minus26"); - fifo_write_bits(pkt, p_hal->pp->pic_init_qs_minus26, 6, "pic_init_qs_minus26"); - fifo_write_bits(pkt, p_hal->pp->chroma_qp_index_offset, 5, "chroma_qp_index_offset"); - fifo_write_bits(pkt, p_hal->pp->deblocking_filter_control_present_flag, 1, "deblocking_filter_control_present_flag"); - fifo_write_bits(pkt, p_hal->pp->constrained_intra_pred_flag, 1, "constrained_intra_pred_flag"); - fifo_write_bits(pkt, p_hal->pp->redundant_pic_cnt_present_flag, 1, "redundant_pic_cnt_present_flag"); - fifo_write_bits(pkt, p_hal->pp->transform_8x8_mode_flag, 1, "transform_8x8_mode_flag"); - fifo_write_bits(pkt, p_hal->pp->second_chroma_qp_index_offset, 5, "second_chroma_qp_index_offset"); - fifo_write_bits(pkt, p_hal->pp->scaleing_list_enable_flag, 1, "scaleing_list_enable_flag"); - - Scaleing_list_address = mpp_buffer_get_fd(p_hal->cabac_buf); - //mpp_log("fd=%08x, offset=%d", Scaleing_list_address, offset); - if (VPUClientGetIOMMUStatus() > 0) { - Scaleing_list_address |= offset << 10; - } else { - Scaleing_list_address += offset; - } -#if FPGA_TEST - fifo_write_bits(pkt, 0, 32, "Scaleing_list_address"); -#else - fifo_write_bits(pkt, Scaleing_list_address, 32, "Scaleing_list_address"); -#endif - FunctionOut(p_hal->logctx.parr[RUN_HAL]); -} - - -/*! -*********************************************************************** -* \brief -* reset fifo packet -*********************************************************************** -*/ -//extern "C" -void rkv_reset_fifo_packet(H264dRkvPkt_t *pkt) -{ - if (pkt) { - fifo_packet_reset(&pkt->spspps); - fifo_packet_reset(&pkt->rps); - fifo_packet_reset(&pkt->scanlist); - fifo_packet_reset(&pkt->reg); - } -} - -/*! -*********************************************************************** -* \brief -* free fifo pakcket -*********************************************************************** -*/ -//extern "C" -void rkv_free_fifo_packet(H264dRkvPkt_t *pkt) -{ - if (pkt) { - MPP_FREE(pkt->spspps.pbuf); - MPP_FREE(pkt->rps.pbuf); - MPP_FREE(pkt->scanlist.pbuf); - MPP_FREE(pkt->reg.pbuf); - } -} -/*! -*********************************************************************** -* \brief -* alloc fifo packet -*********************************************************************** -*/ -//extern "C" -MPP_RET rkv_alloc_fifo_packet(H264dLogCtx_t *logctx, H264dRkvPkt_t *pkts) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - LogCtx_t *log_driver = NULL; - RK_U32 pps_size = RKV_SPSPPS_SIZE + 64; - RK_U32 rps_size = RKV_RPS_SIZE + 64; - RK_U32 sclst_size = RKV_SCALING_LIST_SIZE + 64; - RK_U32 regs_size = sizeof(H264dRkvRegs_t); - - FunctionIn(logctx->parr[RUN_HAL]); - //!< initial packages header and malloc buffer - FUN_CHECK(ret = fifo_packet_alloc(&pkts->spspps, H264dPPS_HEADER, pps_size)); - FUN_CHECK(ret = fifo_packet_alloc(&pkts->rps, H264dRPS_HEADER, rps_size)); - FUN_CHECK(ret = fifo_packet_alloc(&pkts->scanlist, H264dSCL_HEADER, sclst_size)); - FUN_CHECK(ret = fifo_packet_alloc(&pkts->reg, H264dREG_HEADER, regs_size)); - - //!< set logctx - pkts->spspps.logctx = logctx->parr[LOG_WRITE_SPSPPS]; - pkts->rps.logctx = logctx->parr[LOG_WRITE_RPS]; - pkts->scanlist.logctx = logctx->parr[LOG_WRITE_SCANLIST]; - pkts->reg.logctx = logctx->parr[LOG_WRITE_REG]; - - //!< set bitstream file output - log_driver = logctx->parr[LOG_FPGA]; - if (log_driver && log_driver->flag->write_en) { - pkts->spspps.fp_data = log_driver->fp; - pkts->rps.fp_data = log_driver->fp; - pkts->scanlist.fp_data = log_driver->fp; - pkts->reg.fp_data = log_driver->fp; - } else { - pkts->spspps.fp_data = NULL; - pkts->rps.fp_data = NULL; - pkts->scanlist.fp_data = NULL; - pkts->reg.fp_data = NULL; - } - FunctionOut(logctx->parr[RUN_HAL]); - return ret = MPP_OK; -__FAILED: - rkv_free_fifo_packet(pkts); - - return ret; -} - -/*! -*********************************************************************** -* \brief -* prepare sps_sps packet -*********************************************************************** -*/ -//extern "C" -void rkv_prepare_spspps_packet(void *hal, FifoCtx_t *pkt) -{ - RK_S32 i = 0; - RK_S32 is_long_term = 0, voidx = 0; - H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal; - - FunctionIn(p_hal->logctx.parr[RUN_HAL]); - fifo_packet_reset(pkt); - LogInfo(pkt->logctx, "------------------ Frame SPS_PPS begin ------------------------"); - rkv_write_sps_to_fifo(p_hal, pkt); - rkv_write_pps_to_fifo(p_hal, pkt); - - for (i = 0; i < 16; i++) { - is_long_term = (p_hal->pp->RefFrameList[i].bPicEntry != 0xff) ? p_hal->pp->RefFrameList[i].AssociatedFlag : 0; - fifo_write_bits(pkt, is_long_term, 1, "is_long_term"); - } - for (i = 0; i < 16; i++) { - voidx = (p_hal->pp->RefFrameList[i].bPicEntry != 0xff) ? p_hal->pp->RefPicLayerIdList[i] : 0; - fifo_write_bits(pkt, voidx, 1, "voidx"); - } - fifo_align_bits(pkt, 64); - fifo_fwrite_data(pkt); //!< "PPSH" header 32 bit - FunctionOut(p_hal->logctx.parr[RUN_HAL]); -} -/*! -*********************************************************************** -* \brief -* prepare frame rps packet -*********************************************************************** -*/ -//extern "C" -void rkv_prepare_framerps_packet(void *hal, FifoCtx_t *pkt) -{ - RK_S32 i = 0, j = 0; - RK_S32 dpb_idx = 0, voidx = 0; - RK_S32 dpb_valid = 0, bottom_flag = 0; - RK_U32 max_frame_num = 0; - RK_U16 frame_num_wrap = 0; - H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal; - DXVA_PicParams_H264_MVC *pp = p_hal->pp; - FunctionIn(p_hal->logctx.parr[RUN_HAL]); - fifo_packet_reset(pkt); - LogInfo(pkt->logctx, "------------------ Frame RPS begin ------------------------"); - max_frame_num = 1 << (pp->log2_max_frame_num_minus4 + 4); - //FPRINT(g_debug_file0, "--------\n"); - for (i = 0; i < 16; i++) { - if ((pp->NonExistingFrameFlags >> i) & 0x01) { - frame_num_wrap = 0; - } else { - if (pp->RefFrameList[i].AssociatedFlag) { - frame_num_wrap = pp->FrameNumList[i]; - } else { - frame_num_wrap = (pp->FrameNumList[i] > pp->frame_num) ? (pp->FrameNumList[i] - max_frame_num) : pp->FrameNumList[i]; - } - } - //FPRINT(g_debug_file0, "i=%d, frame_num_wrap=%d \n", i, frame_num_wrap); - fifo_write_bits(pkt, frame_num_wrap, 16, "frame_num_wrap"); - } - for (i = 0; i < 16; i++) { - fifo_write_bits(pkt, 0, 1, "NULL"); - } - for (i = 0; i < 16; i++) { - fifo_write_bits(pkt, pp->RefPicLayerIdList[i], 1, "voidx"); - } - for (i = 0; i < 32; i++) { - dpb_valid = (p_hal->slice_long[0].RefPicList[0][i].bPicEntry == 0xff) ? 0 : 1; - dpb_idx = dpb_valid ? p_hal->slice_long[0].RefPicList[0][i].Index7Bits : 0; - bottom_flag = dpb_valid ? p_hal->slice_long[0].RefPicList[0][i].AssociatedFlag : 0; - voidx = dpb_valid ? pp->RefPicLayerIdList[dpb_idx] : 0; - fifo_write_bits(pkt, dpb_idx | (dpb_valid << 4), 5, "dpb_idx"); - fifo_write_bits(pkt, bottom_flag, 1, "bottom_flag"); - fifo_write_bits(pkt, voidx, 1, "voidx"); - } - for (j = 1; j < 3; j++) { - for (i = 0; i < 32; i++) { - dpb_valid = (p_hal->slice_long[0].RefPicList[j][i].bPicEntry == 0xff) ? 0 : 1; - dpb_idx = dpb_valid ? p_hal->slice_long[0].RefPicList[j][i].Index7Bits : 0; - bottom_flag = dpb_valid ? p_hal->slice_long[0].RefPicList[j][i].AssociatedFlag : 0; - voidx = dpb_valid ? pp->RefPicLayerIdList[dpb_idx] : 0; - fifo_write_bits(pkt, dpb_idx | (dpb_valid << 4), 5, "dpb_idx"); - fifo_write_bits(pkt, bottom_flag, 1, "bottom_flag"); - fifo_write_bits(pkt, voidx, 1, "voidx"); - } - } - fifo_align_bits(pkt, 128); - fifo_flush_bits(pkt); - fifo_fwrite_data(pkt); //!< "RPSH" header 32 bit - FunctionOut(p_hal->logctx.parr[RUN_HAL]); -} -/*! -*********************************************************************** -* \brief -* prepare scanlist packet -*********************************************************************** -*/ -//extern "C" -void rkv_prepare_scanlist_packet(void *hal, FifoCtx_t *pkt) -{ - RK_S32 i = 0; - H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal; - FunctionIn(p_hal->logctx.parr[RUN_HAL]); - if (p_hal->pp->scaleing_list_enable_flag) { - fifo_packet_reset(pkt); - LogInfo(pkt->logctx, "------------------ Scanlist begin ------------------------"); - for (i = 0; i < 6; ++i) { //!< 4x4, 6 lists - fifo_write_bytes(pkt, p_hal->qm->bScalingLists4x4[i], H264ScalingList4x4Length); - } - for (i = 0; i < 2; ++i) { - fifo_write_bytes(pkt, p_hal->qm->bScalingLists8x8[i], H264ScalingList8x8Length); - } - fifo_fwrite_data(pkt); //!< "SCLS" header 32 bit - } - FunctionOut(p_hal->logctx.parr[RUN_HAL]); -} - -/*! -*********************************************************************** -* \brief -* generate register packet -*********************************************************************** -*/ -//extern "C" -void rkv_generate_regs(void *hal, HalTaskInfo *task, FifoCtx_t *pkt) -{ - H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal; - DXVA_PicParams_H264_MVC *pp = p_hal->pp; - H264dRkvRegs_t *p_regs = (H264dRkvRegs_t *)p_hal->regs; - - FunctionIn(p_hal->logctx.parr[RUN_HAL]); - - memset(p_regs, 0, sizeof(H264dRkvRegs_t)); - //!< set dec_mode && rlc_mode && rps_mode && slice_num - { - p_regs->swreg2_sysctrl.sw_dec_mode = 1; //!< h264 - if (p_regs->swreg2_sysctrl.sw_rlc_mode == 1) { - p_regs->swreg5_stream_rlc_len.sw_stream_len = 0; - } else { - p_regs->swreg5_stream_rlc_len.sw_stream_len = (RK_U32)mpp_packet_get_length(task->dec.input_packet); - } - if (p_regs->swreg2_sysctrl.sw_h264_rps_mode) { // rps_mode == 1 - p_regs->swreg43_rps_base.sw_rps_base += 0x8; - } - p_regs->swreg3_picpar.sw_slice_num_lowbits = 0x7ff; // p_Vid->iNumOfSlicesDecoded & 0x7ff - p_regs->swreg3_picpar.sw_slice_num_highbit = 1; // (p_Vid->iNumOfSlicesDecoded >> 11) & 1 - } - //!< caculate the yuv_frame_size - { - MppFrame cur_frame = NULL; - RK_U32 hor_virstride = 0; - RK_U32 ver_virstride = 0; - RK_U32 y_virstride = 0; - RK_U32 yuv_virstride = 0; - - mpp_buf_slot_get_prop(p_hal->frame_slots, pp->CurrPic.Index7Bits, SLOT_FRAME_PTR, &cur_frame); - hor_virstride = mpp_frame_get_hor_stride(cur_frame); - ver_virstride = mpp_frame_get_ver_stride(cur_frame); - y_virstride = hor_virstride * ver_virstride; - - if (pp->chroma_format_idc == 0) { //!< Y400 - yuv_virstride = y_virstride; - } else if (pp->chroma_format_idc == 1) { //!< Y420 - yuv_virstride = y_virstride + y_virstride / 2; - } else if (pp->chroma_format_idc == 2) { //!< Y422 - yuv_virstride = 2 * y_virstride; - } - p_regs->swreg3_picpar.sw_y_hor_virstride = hor_virstride / 16; - p_regs->swreg3_picpar.sw_uv_hor_virstride = hor_virstride / 16; - p_regs->swreg8_y_virstride.sw_y_virstride = y_virstride / 16; - p_regs->swreg9_yuv_virstride.sw_yuv_virstride = yuv_virstride / 16; - } - //!< caculate mv_size - { - RK_U32 mb_width = 0, mb_height = 0, mv_size = 0; - mb_width = pp->wFrameWidthInMbsMinus1 + 1; - mb_height = (2 - pp->frame_mbs_only_flag) * (pp->wFrameHeightInMbsMinus1 + 1); - mv_size = mb_width * mb_height * 8; // 64bit per 4x4 - p_regs->compare_len = (p_regs->swreg9_yuv_virstride.sw_yuv_virstride + mv_size) * 2; - } - //!< set current - { - MppBuffer frame_buf = NULL; - p_regs->swreg40_cur_poc.sw_cur_poc = pp->CurrFieldOrderCnt[0]; - p_regs->swreg74_h264_cur_poc1.sw_h264_cur_poc1 = pp->CurrFieldOrderCnt[1]; - mpp_buf_slot_get_prop(p_hal->frame_slots, pp->CurrPic.Index7Bits, SLOT_BUFFER, &frame_buf); //!< current out phy addr -#if FPGA_TEST - p_regs->swreg7_decout_base.sw_decout_base = pp->CurrPic.Index7Bits + 1; -#else - p_regs->swreg7_decout_base.sw_decout_base = mpp_buffer_get_fd(frame_buf); -#endif - } - //!< set reference - { - RK_S32 i = 0; - RK_S32 ref_index = -1; - RK_S32 near_index = -1; - MppBuffer frame_buf = NULL; - - for (i = 0; i < 15; i++) { - p_regs->swreg25_39_refer0_14_poc[i] = (i & 1) ? pp->FieldOrderCntList[i / 2][1] : pp->FieldOrderCntList[i / 2][0]; - p_regs->swreg49_63_refer15_29_poc[i] = (i & 1) ? pp->FieldOrderCntList[(i + 15) / 2][0] : pp->FieldOrderCntList[(i + 15) / 2][1]; - p_regs->swreg10_24_refer0_14_base[i].sw_ref_field = (pp->RefPicFiledFlags >> i) & 0x01; - p_regs->swreg10_24_refer0_14_base[i].sw_ref_topfield_used = (pp->UsedForReferenceFlags >> (2 * i + 0)) & 0x01; - p_regs->swreg10_24_refer0_14_base[i].sw_ref_botfield_used = (pp->UsedForReferenceFlags >> (2 * i + 1)) & 0x01; - p_regs->swreg10_24_refer0_14_base[i].sw_ref_colmv_use_flag = (pp->RefPicColmvUsedFlags >> i) & 0x01; -#if FPGA_TEST - p_regs->swreg10_24_refer0_14_base[i].sw_refer_base = pp->RefFrameList[i].Index7Bits + 1; -#else - if (pp->RefFrameList[i].bPicEntry != 0xff) { - ref_index = pp->RefFrameList[i].Index7Bits; - near_index = pp->RefFrameList[i].Index7Bits; - } else { - ref_index = (near_index < 0) ? pp->CurrPic.Index7Bits : near_index; - } - mpp_buf_slot_get_prop(p_hal->frame_slots, ref_index, SLOT_BUFFER, &frame_buf); //!< reference phy addr - p_regs->swreg10_24_refer0_14_base[i].sw_refer_base = mpp_buffer_get_fd(frame_buf); -#endif - } - p_regs->swreg72_refer30_poc = pp->FieldOrderCntList[15][0]; - p_regs->swreg73_refer31_poc = pp->FieldOrderCntList[15][1]; - p_regs->swreg48_refer15_base.sw_ref_field = (pp->RefPicFiledFlags >> 15) & 0x01; - p_regs->swreg48_refer15_base.sw_ref_topfield_used = (pp->UsedForReferenceFlags >> 30) & 0x01; - p_regs->swreg48_refer15_base.sw_ref_botfield_used = (pp->UsedForReferenceFlags >> 31) & 0x01; - p_regs->swreg48_refer15_base.sw_ref_colmv_use_flag = (pp->RefPicColmvUsedFlags >> 15) & 0x01; -#if FPGA_TEST - p_regs->swreg48_refer15_base.sw_refer_base = pp->RefFrameList[15].Index7Bits + 1; -#else - if (pp->RefFrameList[15].bPicEntry != 0xff) { - ref_index = pp->RefFrameList[15].Index7Bits; - } else { - ref_index = (near_index < 0) ? pp->CurrPic.Index7Bits : near_index; - } - mpp_buf_slot_get_prop(p_hal->frame_slots, ref_index, SLOT_BUFFER, &frame_buf); //!< reference phy addr - p_regs->swreg48_refer15_base.sw_refer_base = mpp_buffer_get_fd(frame_buf); -#endif - } - -#if FPGA_TEST - p_regs->swreg4_strm_rlc_base.sw_strm_rlc_base = 0; - p_regs->swreg6_cabactbl_prob_base.sw_cabactbl_base = 0; - p_regs->swreg41_rlcwrite_base.sw_rlcwrite_base = 0; -#else - { - MppBuffer bitstream_buf = NULL; - mpp_buf_slot_get_prop(p_hal->packet_slots, task->dec.input, SLOT_BUFFER, &bitstream_buf); - p_regs->swreg4_strm_rlc_base.sw_strm_rlc_base = mpp_buffer_get_fd(bitstream_buf); - p_regs->swreg6_cabactbl_prob_base.sw_cabactbl_base = mpp_buffer_get_fd(p_hal->cabac_buf); - p_regs->swreg41_rlcwrite_base.sw_rlcwrite_base = p_regs->swreg4_strm_rlc_base.sw_strm_rlc_base; - } -#endif - fifo_packet_reset(pkt); - fifo_write_bytes(pkt, (void *)p_hal->regs, 80 * sizeof(RK_U32)); - { - RK_U32 i = 0; - RK_U32 *ptr = (RK_U32*)p_hal->regs; - LogInfo(pkt->logctx, "------------------ Frame REG begin ------------------------"); - for (i = 0; i < 80; i++) { - LogInfo(pkt->logctx, " reg[%3d] = %08x \n", i, ptr[i]); - } - } - fifo_align_bits(pkt, 64); - fifo_flush_bits(pkt); - fifo_fwrite_data(pkt); //!< "REGH" header 32 bit - - FunctionOut(p_hal->logctx.parr[RUN_HAL]); -} - -/*! -*********************************************************************** -* \brief -* for debug -*********************************************************************** -*/ -void rkv_fprint_fifo_data(FILE *fp, FifoCtx_t *pkt) -{ - RK_U32 i = 0, pkt_size = 0; - RK_U8 *ptr = (RK_U8 *)pkt->pbuf; - if (fp) { - pkt_size = pkt->index * sizeof(RK_U64); - fprintf(fp, "------ Header=%08x, size=%d ------ \n", pkt->header, pkt_size); - for (i = 0; i < pkt_size;) { - fprintf(fp, "0x%02x, ", ptr[i]); - i++; - if ((i % 16) == 0) { - fprintf(fp, "\n"); - } - } - fprintf(fp, "\n\n"); - } -} +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define MODULE_TAG "hal_h264d_rkv_pkt" + +#include +#include + +#include "vpu.h" +#include "mpp_mem.h" +#include "mpp_buffer.h" +#include "hal_task.h" + +#include "dxva_syntax.h" +#include "h264d_log.h" +#include "h264d_syntax.h" +#include "hal_h264d_fifo.h" +#include "hal_h264d_api.h" +#include "hal_h264d_global.h" +#include "hal_h264d_rkv_pkt.h" +#include "hal_h264d_rkv_reg.h" + +//!< Header +#define H264dREG_HEADER 0x48474552 +#define H264dPPS_HEADER 0x48535050 +#define H264dSCL_HEADER 0x534c4353 +#define H264dRPS_HEADER 0x48535052 +#define H264dCRC_HEADER 0x48435243 +#define H264dSTM_HEADER 0x4d525453 +#define H264dERR_HEADER 0x524f5245 + + +#define FPGA_TEST 0 + +const enum +{ + H264ScalingList4x4Length = 16, + H264ScalingList8x8Length = 64, +} ScalingListLength; + + + +static void rkv_write_sps_to_fifo(H264dHalCtx_t *p_hal, FifoCtx_t *pkt) +{ + FunctionIn(p_hal->logctx.parr[RUN_HAL]); + + fifo_write_bits(pkt, -1, 4, "seq_parameter_set_id"); //!< not used in hard + fifo_write_bits(pkt, -1, 8, "profile_idc"); //!< not used in hard + fifo_write_bits(pkt, -1, 1, "constraint_set3_flag"); //!< not used in hard + fifo_write_bits(pkt, p_hal->pp->chroma_format_idc, 2, "chroma_format_idc"); + fifo_write_bits(pkt, (p_hal->pp->bit_depth_luma_minus8 + 8), 3, "bit_depth_luma"); + fifo_write_bits(pkt, (p_hal->pp->bit_depth_chroma_minus8 + 8), 3, "bit_depth_chroma"); + fifo_write_bits(pkt, 0, 1, "qpprime_y_zero_transform_bypass_flag"); //!< not supported in hard + fifo_write_bits(pkt, p_hal->pp->log2_max_frame_num_minus4, 4, "log2_max_frame_num_minus4"); + fifo_write_bits(pkt, p_hal->pp->num_ref_frames, 5, "max_num_ref_frames"); + fifo_write_bits(pkt, p_hal->pp->pic_order_cnt_type, 2, "pic_order_cnt_type"); + fifo_write_bits(pkt, p_hal->pp->log2_max_pic_order_cnt_lsb_minus4, 4, "log2_max_pic_order_cnt_lsb_minus4"); + fifo_write_bits(pkt, p_hal->pp->delta_pic_order_always_zero_flag, 1, "delta_pic_order_always_zero_flag"); + fifo_write_bits(pkt, (p_hal->pp->wFrameWidthInMbsMinus1 + 1), 9, "pic_width_in_mbs"); + fifo_write_bits(pkt, (p_hal->pp->wFrameHeightInMbsMinus1 + 1), 9, "pic_height_in_mbs"); + fifo_write_bits(pkt, p_hal->pp->frame_mbs_only_flag, 1, "frame_mbs_only_flag"); + fifo_write_bits(pkt, p_hal->pp->MbaffFrameFlag, 1, "mb_adaptive_frame_field_flag"); + fifo_write_bits(pkt, p_hal->pp->direct_8x8_inference_flag, 1, "direct_8x8_inference_flag"); + + fifo_write_bits(pkt, 1, 1, "mvc_extension_enable"); + fifo_write_bits(pkt, (p_hal->pp->num_views_minus1 + 1), 2, "num_views"); + fifo_write_bits(pkt, p_hal->pp->view_id[0], 10, "view_id[2]"); + fifo_write_bits(pkt, p_hal->pp->view_id[1], 10, "view_id[2]"); + fifo_write_bits(pkt, p_hal->pp->num_anchor_refs_l0[0], 1, "num_anchor_refs_l0"); + if (p_hal->pp->num_anchor_refs_l0[0]) { + fifo_write_bits(pkt, p_hal->pp->anchor_ref_l0[0][0], 10, "anchor_ref_l0"); + } else { + fifo_write_bits(pkt, 0, 10, "anchor_ref_l0"); + } + fifo_write_bits(pkt, p_hal->pp->num_anchor_refs_l1[0], 1, "num_anchor_refs_l1"); + if (p_hal->pp->num_anchor_refs_l1[0]) { + fifo_write_bits(pkt, p_hal->pp->anchor_ref_l1[0][0], 10, "anchor_ref_l1"); + } else { + fifo_write_bits(pkt, 0, 10, "anchor_ref_l1"); + } + fifo_write_bits(pkt, p_hal->pp->num_non_anchor_refs_l0[0], 1, "num_non_anchor_refs_l0"); + if (p_hal->pp->num_non_anchor_refs_l0[0]) { + fifo_write_bits(pkt, p_hal->pp->non_anchor_ref_l0[0][0], 10, "non_anchor_ref_l0"); + } else { + fifo_write_bits(pkt, 0, 10, "non_anchor_ref_l0"); + } + fifo_write_bits(pkt, p_hal->pp->num_non_anchor_refs_l1[0], 1, "num_non_anchor_refs_l1"); + if (p_hal->pp->num_non_anchor_refs_l1[0]) { + fifo_write_bits(pkt, p_hal->pp->non_anchor_ref_l1[0][0], 10, "non_anchor_ref_l1"); + } else { + fifo_write_bits(pkt, 0, 10, "non_anchor_ref_l1"); + } + fifo_align_bits(pkt, 32); + FunctionOut(p_hal->logctx.parr[RUN_HAL]); +} + +static void rkv_write_pps_to_fifo(H264dHalCtx_t *p_hal, FifoCtx_t *pkt) +{ + RK_U32 Scaleing_list_address = 0; + RK_U32 offset = RKV_CABAC_TAB_SIZE + RKV_SPSPPS_SIZE + RKV_RPS_SIZE; + FunctionIn(p_hal->logctx.parr[RUN_HAL]); + fifo_write_bits(pkt, -1, 8, "pps_pic_parameter_set_id"); + fifo_write_bits(pkt, -1, 5, "pps_seq_parameter_set_id"); + fifo_write_bits(pkt, p_hal->pp->entropy_coding_mode_flag, 1, "entropy_coding_mode_flag"); + fifo_write_bits(pkt, p_hal->pp->pic_order_present_flag, 1, "bottom_field_pic_order_in_frame_present_flag"); + fifo_write_bits(pkt, p_hal->pp->num_ref_idx_l0_active_minus1, 5, "num_ref_idx_l0_default_active_minus1"); + fifo_write_bits(pkt, p_hal->pp->num_ref_idx_l1_active_minus1, 5, "num_ref_idx_l1_default_active_minus1"); + fifo_write_bits(pkt, p_hal->pp->weighted_pred_flag, 1, "weighted_pred_flag"); + fifo_write_bits(pkt, p_hal->pp->weighted_bipred_idc, 2, "weighted_bipred_idc"); + fifo_write_bits(pkt, p_hal->pp->pic_init_qp_minus26, 7, "pic_init_qp_minus26"); + fifo_write_bits(pkt, p_hal->pp->pic_init_qs_minus26, 6, "pic_init_qs_minus26"); + fifo_write_bits(pkt, p_hal->pp->chroma_qp_index_offset, 5, "chroma_qp_index_offset"); + fifo_write_bits(pkt, p_hal->pp->deblocking_filter_control_present_flag, 1, "deblocking_filter_control_present_flag"); + fifo_write_bits(pkt, p_hal->pp->constrained_intra_pred_flag, 1, "constrained_intra_pred_flag"); + fifo_write_bits(pkt, p_hal->pp->redundant_pic_cnt_present_flag, 1, "redundant_pic_cnt_present_flag"); + fifo_write_bits(pkt, p_hal->pp->transform_8x8_mode_flag, 1, "transform_8x8_mode_flag"); + fifo_write_bits(pkt, p_hal->pp->second_chroma_qp_index_offset, 5, "second_chroma_qp_index_offset"); + fifo_write_bits(pkt, p_hal->pp->scaleing_list_enable_flag, 1, "scaleing_list_enable_flag"); + + Scaleing_list_address = mpp_buffer_get_fd(p_hal->cabac_buf); + //mpp_log("fd=%08x, offset=%d", Scaleing_list_address, offset); + if (VPUClientGetIOMMUStatus() > 0) { + Scaleing_list_address |= offset << 10; + } else { + Scaleing_list_address += offset; + } +#if FPGA_TEST + fifo_write_bits(pkt, 0, 32, "Scaleing_list_address"); +#else + fifo_write_bits(pkt, Scaleing_list_address, 32, "Scaleing_list_address"); +#endif + FunctionOut(p_hal->logctx.parr[RUN_HAL]); +} + + +/*! +*********************************************************************** +* \brief +* reset fifo packet +*********************************************************************** +*/ +//extern "C" +void rkv_reset_fifo_packet(H264dRkvPkt_t *pkt) +{ + if (pkt) { + fifo_packet_reset(&pkt->spspps); + fifo_packet_reset(&pkt->rps); + fifo_packet_reset(&pkt->scanlist); + fifo_packet_reset(&pkt->reg); + } +} + +/*! +*********************************************************************** +* \brief +* free fifo pakcket +*********************************************************************** +*/ +//extern "C" +void rkv_free_fifo_packet(H264dRkvPkt_t *pkt) +{ + if (pkt) { + MPP_FREE(pkt->spspps.pbuf); + MPP_FREE(pkt->rps.pbuf); + MPP_FREE(pkt->scanlist.pbuf); + MPP_FREE(pkt->reg.pbuf); + } +} +/*! +*********************************************************************** +* \brief +* alloc fifo packet +*********************************************************************** +*/ +//extern "C" +MPP_RET rkv_alloc_fifo_packet(H264dLogCtx_t *logctx, H264dRkvPkt_t *pkts) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + LogCtx_t *log_driver = NULL; + RK_U32 pps_size = RKV_SPSPPS_SIZE + 64; + RK_U32 rps_size = RKV_RPS_SIZE + 64; + RK_U32 sclst_size = RKV_SCALING_LIST_SIZE + 64; + RK_U32 regs_size = sizeof(H264dRkvRegs_t); + + FunctionIn(logctx->parr[RUN_HAL]); + //!< initial packages header and malloc buffer + FUN_CHECK(ret = fifo_packet_alloc(&pkts->spspps, H264dPPS_HEADER, pps_size)); + FUN_CHECK(ret = fifo_packet_alloc(&pkts->rps, H264dRPS_HEADER, rps_size)); + FUN_CHECK(ret = fifo_packet_alloc(&pkts->scanlist, H264dSCL_HEADER, sclst_size)); + FUN_CHECK(ret = fifo_packet_alloc(&pkts->reg, H264dREG_HEADER, regs_size)); + + //!< set logctx + pkts->spspps.logctx = logctx->parr[LOG_WRITE_SPSPPS]; + pkts->rps.logctx = logctx->parr[LOG_WRITE_RPS]; + pkts->scanlist.logctx = logctx->parr[LOG_WRITE_SCANLIST]; + pkts->reg.logctx = logctx->parr[LOG_WRITE_REG]; + + //!< set bitstream file output + log_driver = logctx->parr[LOG_FPGA]; + if (log_driver && log_driver->flag->write_en) { + pkts->spspps.fp_data = log_driver->fp; + pkts->rps.fp_data = log_driver->fp; + pkts->scanlist.fp_data = log_driver->fp; + pkts->reg.fp_data = log_driver->fp; + } else { + pkts->spspps.fp_data = NULL; + pkts->rps.fp_data = NULL; + pkts->scanlist.fp_data = NULL; + pkts->reg.fp_data = NULL; + } + FunctionOut(logctx->parr[RUN_HAL]); + return ret = MPP_OK; +__FAILED: + rkv_free_fifo_packet(pkts); + + return ret; +} + +/*! +*********************************************************************** +* \brief +* prepare sps_sps packet +*********************************************************************** +*/ +//extern "C" +void rkv_prepare_spspps_packet(void *hal, FifoCtx_t *pkt) +{ + RK_S32 i = 0; + RK_S32 is_long_term = 0, voidx = 0; + H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal; + + FunctionIn(p_hal->logctx.parr[RUN_HAL]); + fifo_packet_reset(pkt); + LogInfo(pkt->logctx, "------------------ Frame SPS_PPS begin ------------------------"); + rkv_write_sps_to_fifo(p_hal, pkt); + rkv_write_pps_to_fifo(p_hal, pkt); + + for (i = 0; i < 16; i++) { + is_long_term = (p_hal->pp->RefFrameList[i].bPicEntry != 0xff) ? p_hal->pp->RefFrameList[i].AssociatedFlag : 0; + fifo_write_bits(pkt, is_long_term, 1, "is_long_term"); + } + for (i = 0; i < 16; i++) { + voidx = (p_hal->pp->RefFrameList[i].bPicEntry != 0xff) ? p_hal->pp->RefPicLayerIdList[i] : 0; + fifo_write_bits(pkt, voidx, 1, "voidx"); + } + fifo_align_bits(pkt, 64); + fifo_fwrite_data(pkt); //!< "PPSH" header 32 bit + FunctionOut(p_hal->logctx.parr[RUN_HAL]); +} +/*! +*********************************************************************** +* \brief +* prepare frame rps packet +*********************************************************************** +*/ +//extern "C" +void rkv_prepare_framerps_packet(void *hal, FifoCtx_t *pkt) +{ + RK_S32 i = 0, j = 0; + RK_S32 dpb_idx = 0, voidx = 0; + RK_S32 dpb_valid = 0, bottom_flag = 0; + RK_U32 max_frame_num = 0; + RK_U16 frame_num_wrap = 0; + H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal; + DXVA_PicParams_H264_MVC *pp = p_hal->pp; + FunctionIn(p_hal->logctx.parr[RUN_HAL]); + fifo_packet_reset(pkt); + LogInfo(pkt->logctx, "------------------ Frame RPS begin ------------------------"); + max_frame_num = 1 << (pp->log2_max_frame_num_minus4 + 4); + //FPRINT(g_debug_file0, "--------\n"); + for (i = 0; i < 16; i++) { + if ((pp->NonExistingFrameFlags >> i) & 0x01) { + frame_num_wrap = 0; + } else { + if (pp->RefFrameList[i].AssociatedFlag) { + frame_num_wrap = pp->FrameNumList[i]; + } else { + frame_num_wrap = (pp->FrameNumList[i] > pp->frame_num) ? (pp->FrameNumList[i] - max_frame_num) : pp->FrameNumList[i]; + } + } + //FPRINT(g_debug_file0, "i=%d, frame_num_wrap=%d \n", i, frame_num_wrap); + fifo_write_bits(pkt, frame_num_wrap, 16, "frame_num_wrap"); + } + for (i = 0; i < 16; i++) { + fifo_write_bits(pkt, 0, 1, "NULL"); + } + for (i = 0; i < 16; i++) { + fifo_write_bits(pkt, pp->RefPicLayerIdList[i], 1, "voidx"); + } + for (i = 0; i < 32; i++) { + dpb_valid = (p_hal->slice_long[0].RefPicList[0][i].bPicEntry == 0xff) ? 0 : 1; + dpb_idx = dpb_valid ? p_hal->slice_long[0].RefPicList[0][i].Index7Bits : 0; + bottom_flag = dpb_valid ? p_hal->slice_long[0].RefPicList[0][i].AssociatedFlag : 0; + voidx = dpb_valid ? pp->RefPicLayerIdList[dpb_idx] : 0; + fifo_write_bits(pkt, dpb_idx | (dpb_valid << 4), 5, "dpb_idx"); + fifo_write_bits(pkt, bottom_flag, 1, "bottom_flag"); + fifo_write_bits(pkt, voidx, 1, "voidx"); + } + for (j = 1; j < 3; j++) { + for (i = 0; i < 32; i++) { + dpb_valid = (p_hal->slice_long[0].RefPicList[j][i].bPicEntry == 0xff) ? 0 : 1; + dpb_idx = dpb_valid ? p_hal->slice_long[0].RefPicList[j][i].Index7Bits : 0; + bottom_flag = dpb_valid ? p_hal->slice_long[0].RefPicList[j][i].AssociatedFlag : 0; + voidx = dpb_valid ? pp->RefPicLayerIdList[dpb_idx] : 0; + fifo_write_bits(pkt, dpb_idx | (dpb_valid << 4), 5, "dpb_idx"); + fifo_write_bits(pkt, bottom_flag, 1, "bottom_flag"); + fifo_write_bits(pkt, voidx, 1, "voidx"); + } + } + fifo_align_bits(pkt, 128); + fifo_flush_bits(pkt); + fifo_fwrite_data(pkt); //!< "RPSH" header 32 bit + FunctionOut(p_hal->logctx.parr[RUN_HAL]); +} +/*! +*********************************************************************** +* \brief +* prepare scanlist packet +*********************************************************************** +*/ +//extern "C" +void rkv_prepare_scanlist_packet(void *hal, FifoCtx_t *pkt) +{ + RK_S32 i = 0; + H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal; + FunctionIn(p_hal->logctx.parr[RUN_HAL]); + if (p_hal->pp->scaleing_list_enable_flag) { + fifo_packet_reset(pkt); + LogInfo(pkt->logctx, "------------------ Scanlist begin ------------------------"); + for (i = 0; i < 6; ++i) { //!< 4x4, 6 lists + fifo_write_bytes(pkt, p_hal->qm->bScalingLists4x4[i], H264ScalingList4x4Length); + } + for (i = 0; i < 2; ++i) { + fifo_write_bytes(pkt, p_hal->qm->bScalingLists8x8[i], H264ScalingList8x8Length); + } + fifo_fwrite_data(pkt); //!< "SCLS" header 32 bit + } + FunctionOut(p_hal->logctx.parr[RUN_HAL]); +} + +/*! +*********************************************************************** +* \brief +* generate register packet +*********************************************************************** +*/ +//extern "C" +void rkv_generate_regs(void *hal, HalTaskInfo *task, FifoCtx_t *pkt) +{ + H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal; + DXVA_PicParams_H264_MVC *pp = p_hal->pp; + H264dRkvRegs_t *p_regs = (H264dRkvRegs_t *)p_hal->regs; + + FunctionIn(p_hal->logctx.parr[RUN_HAL]); + + memset(p_regs, 0, sizeof(H264dRkvRegs_t)); + //!< set dec_mode && rlc_mode && rps_mode && slice_num + { + p_regs->swreg2_sysctrl.sw_dec_mode = 1; //!< h264 + if (p_regs->swreg2_sysctrl.sw_rlc_mode == 1) { + p_regs->swreg5_stream_rlc_len.sw_stream_len = 0; + } else { + p_regs->swreg5_stream_rlc_len.sw_stream_len = (RK_U32)mpp_packet_get_length(task->dec.input_packet); + } + if (p_regs->swreg2_sysctrl.sw_h264_rps_mode) { // rps_mode == 1 + p_regs->swreg43_rps_base.sw_rps_base += 0x8; + } + p_regs->swreg3_picpar.sw_slice_num_lowbits = 0x7ff; // p_Vid->iNumOfSlicesDecoded & 0x7ff + p_regs->swreg3_picpar.sw_slice_num_highbit = 1; // (p_Vid->iNumOfSlicesDecoded >> 11) & 1 + } + //!< caculate the yuv_frame_size + { + MppFrame cur_frame = NULL; + RK_U32 hor_virstride = 0; + RK_U32 ver_virstride = 0; + RK_U32 y_virstride = 0; + RK_U32 yuv_virstride = 0; + + mpp_buf_slot_get_prop(p_hal->frame_slots, pp->CurrPic.Index7Bits, SLOT_FRAME_PTR, &cur_frame); + hor_virstride = mpp_frame_get_hor_stride(cur_frame); + ver_virstride = mpp_frame_get_ver_stride(cur_frame); + y_virstride = hor_virstride * ver_virstride; + + if (pp->chroma_format_idc == 0) { //!< Y400 + yuv_virstride = y_virstride; + } else if (pp->chroma_format_idc == 1) { //!< Y420 + yuv_virstride = y_virstride + y_virstride / 2; + } else if (pp->chroma_format_idc == 2) { //!< Y422 + yuv_virstride = 2 * y_virstride; + } + p_regs->swreg3_picpar.sw_y_hor_virstride = hor_virstride / 16; + p_regs->swreg3_picpar.sw_uv_hor_virstride = hor_virstride / 16; + p_regs->swreg8_y_virstride.sw_y_virstride = y_virstride / 16; + p_regs->swreg9_yuv_virstride.sw_yuv_virstride = yuv_virstride / 16; + } + //!< caculate mv_size + { + RK_U32 mb_width = 0, mb_height = 0, mv_size = 0; + mb_width = pp->wFrameWidthInMbsMinus1 + 1; + mb_height = (2 - pp->frame_mbs_only_flag) * (pp->wFrameHeightInMbsMinus1 + 1); + mv_size = mb_width * mb_height * 8; // 64bit per 4x4 + p_regs->compare_len = (p_regs->swreg9_yuv_virstride.sw_yuv_virstride + mv_size) * 2; + } + //!< set current + { + MppBuffer frame_buf = NULL; + p_regs->swreg40_cur_poc.sw_cur_poc = pp->CurrFieldOrderCnt[0]; + p_regs->swreg74_h264_cur_poc1.sw_h264_cur_poc1 = pp->CurrFieldOrderCnt[1]; + mpp_buf_slot_get_prop(p_hal->frame_slots, pp->CurrPic.Index7Bits, SLOT_BUFFER, &frame_buf); //!< current out phy addr +#if FPGA_TEST + p_regs->swreg7_decout_base.sw_decout_base = pp->CurrPic.Index7Bits + 1; +#else + p_regs->swreg7_decout_base.sw_decout_base = mpp_buffer_get_fd(frame_buf); +#endif + } + //!< set reference + { + RK_S32 i = 0; + RK_S32 ref_index = -1; + RK_S32 near_index = -1; + MppBuffer frame_buf = NULL; + + for (i = 0; i < 15; i++) { + p_regs->swreg25_39_refer0_14_poc[i] = (i & 1) ? pp->FieldOrderCntList[i / 2][1] : pp->FieldOrderCntList[i / 2][0]; + p_regs->swreg49_63_refer15_29_poc[i] = (i & 1) ? pp->FieldOrderCntList[(i + 15) / 2][0] : pp->FieldOrderCntList[(i + 15) / 2][1]; + p_regs->swreg10_24_refer0_14_base[i].sw_ref_field = (pp->RefPicFiledFlags >> i) & 0x01; + p_regs->swreg10_24_refer0_14_base[i].sw_ref_topfield_used = (pp->UsedForReferenceFlags >> (2 * i + 0)) & 0x01; + p_regs->swreg10_24_refer0_14_base[i].sw_ref_botfield_used = (pp->UsedForReferenceFlags >> (2 * i + 1)) & 0x01; + p_regs->swreg10_24_refer0_14_base[i].sw_ref_colmv_use_flag = (pp->RefPicColmvUsedFlags >> i) & 0x01; +#if FPGA_TEST + p_regs->swreg10_24_refer0_14_base[i].sw_refer_base = pp->RefFrameList[i].Index7Bits + 1; +#else + if (pp->RefFrameList[i].bPicEntry != 0xff) { + ref_index = pp->RefFrameList[i].Index7Bits; + near_index = pp->RefFrameList[i].Index7Bits; + } else { + ref_index = (near_index < 0) ? pp->CurrPic.Index7Bits : near_index; + } + mpp_buf_slot_get_prop(p_hal->frame_slots, ref_index, SLOT_BUFFER, &frame_buf); //!< reference phy addr + p_regs->swreg10_24_refer0_14_base[i].sw_refer_base = mpp_buffer_get_fd(frame_buf); +#endif + } + p_regs->swreg72_refer30_poc = pp->FieldOrderCntList[15][0]; + p_regs->swreg73_refer31_poc = pp->FieldOrderCntList[15][1]; + p_regs->swreg48_refer15_base.sw_ref_field = (pp->RefPicFiledFlags >> 15) & 0x01; + p_regs->swreg48_refer15_base.sw_ref_topfield_used = (pp->UsedForReferenceFlags >> 30) & 0x01; + p_regs->swreg48_refer15_base.sw_ref_botfield_used = (pp->UsedForReferenceFlags >> 31) & 0x01; + p_regs->swreg48_refer15_base.sw_ref_colmv_use_flag = (pp->RefPicColmvUsedFlags >> 15) & 0x01; +#if FPGA_TEST + p_regs->swreg48_refer15_base.sw_refer_base = pp->RefFrameList[15].Index7Bits + 1; +#else + if (pp->RefFrameList[15].bPicEntry != 0xff) { + ref_index = pp->RefFrameList[15].Index7Bits; + } else { + ref_index = (near_index < 0) ? pp->CurrPic.Index7Bits : near_index; + } + mpp_buf_slot_get_prop(p_hal->frame_slots, ref_index, SLOT_BUFFER, &frame_buf); //!< reference phy addr + p_regs->swreg48_refer15_base.sw_refer_base = mpp_buffer_get_fd(frame_buf); +#endif + } + +#if FPGA_TEST + p_regs->swreg4_strm_rlc_base.sw_strm_rlc_base = 0; + p_regs->swreg6_cabactbl_prob_base.sw_cabactbl_base = 0; + p_regs->swreg41_rlcwrite_base.sw_rlcwrite_base = 0; +#else + { + MppBuffer bitstream_buf = NULL; + mpp_buf_slot_get_prop(p_hal->packet_slots, task->dec.input, SLOT_BUFFER, &bitstream_buf); + p_regs->swreg4_strm_rlc_base.sw_strm_rlc_base = mpp_buffer_get_fd(bitstream_buf); + p_regs->swreg6_cabactbl_prob_base.sw_cabactbl_base = mpp_buffer_get_fd(p_hal->cabac_buf); + p_regs->swreg41_rlcwrite_base.sw_rlcwrite_base = p_regs->swreg4_strm_rlc_base.sw_strm_rlc_base; + } +#endif + fifo_packet_reset(pkt); + fifo_write_bytes(pkt, (void *)p_hal->regs, 80 * sizeof(RK_U32)); + { + RK_U32 i = 0; + RK_U32 *ptr = (RK_U32*)p_hal->regs; + LogInfo(pkt->logctx, "------------------ Frame REG begin ------------------------"); + for (i = 0; i < 80; i++) { + LogInfo(pkt->logctx, " reg[%3d] = %08x \n", i, ptr[i]); + } + } + fifo_align_bits(pkt, 64); + fifo_flush_bits(pkt); + fifo_fwrite_data(pkt); //!< "REGH" header 32 bit + + FunctionOut(p_hal->logctx.parr[RUN_HAL]); +} + +/*! +*********************************************************************** +* \brief +* for debug +*********************************************************************** +*/ +void rkv_fprint_fifo_data(FILE *fp, FifoCtx_t *pkt) +{ + RK_U32 i = 0, pkt_size = 0; + RK_U8 *ptr = (RK_U8 *)pkt->pbuf; + if (fp) { + pkt_size = pkt->index * sizeof(RK_U64); + fprintf(fp, "------ Header=%08x, size=%d ------ \n", pkt->header, pkt_size); + for (i = 0; i < pkt_size;) { + fprintf(fp, "0x%02x, ", ptr[i]); + i++; + if ((i % 16) == 0) { + fprintf(fp, "\n"); + } + } + fprintf(fp, "\n\n"); + } +} diff --git a/mpp/hal/rkdec/h264d/hal_h264d_rkv_pkt.h b/mpp/hal/rkdec/h264d/hal_h264d_rkv_pkt.h index 6c5a6b23..341f45be 100644 --- a/mpp/hal/rkdec/h264d/hal_h264d_rkv_pkt.h +++ b/mpp/hal/rkdec/h264d/hal_h264d_rkv_pkt.h @@ -1,67 +1,67 @@ -/* -* -* Copyright 2015 Rockchip Electronics Co. LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#ifndef __HAL_H264D_RKV_PKT_H__ -#define __HAL_H264D_RKV_PKT_H__ - -#include "rk_type.h" -#include "mpp_err.h" -#include "hal_task.h" - -#include "h264d_log.h" -#include "hal_h264d_fifo.h" - - -#define RKV_CABAC_TAB_SIZE (3680 + 128) /* bytes */ -#define RKV_SPSPPS_SIZE (256*32 + 128) /* bytes */ -#define RKV_RPS_SIZE (128 + 128) /* bytes */ -#define RKV_SCALING_LIST_SIZE (6*16+2*64 + 128) /* bytes */ -#define RKV_ERROR_INFO_SIZE (256*144*4) /* bytes */ -typedef struct h264d_rkv_packet_t { - FifoCtx_t spspps; - FifoCtx_t rps; - FifoCtx_t scanlist; - FifoCtx_t reg; -} H264dRkvPkt_t; - - -#ifdef __cplusplus -extern "C" { -#endif -void rkv_reset_fifo_packet(H264dRkvPkt_t *pkt); -void rkv_free_fifo_packet (H264dRkvPkt_t *pkt); -MPP_RET rkv_alloc_fifo_packet(H264dLogCtx_t *logctx, H264dRkvPkt_t *pkts); - -void rkv_prepare_spspps_packet (void *hal, FifoCtx_t *pkt); -void rkv_prepare_framerps_packet(void *hal, FifoCtx_t *pkt); -void rkv_prepare_scanlist_packet(void *hal, FifoCtx_t *pkt); -void rkv_prepare_stream_packet (void *hal, FifoCtx_t *pkt); -void rkv_generate_regs (void *hal, HalTaskInfo *task, FifoCtx_t *pkt); -void rkv_fprint_fifo_data (FILE *fp, FifoCtx_t *pkt); - - -#ifdef __cplusplus -} -#endif - - - -//!<============================ -#endif /* __HAL_H264D_RKV_PKT_H__ */ - - - +/* +* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef __HAL_H264D_RKV_PKT_H__ +#define __HAL_H264D_RKV_PKT_H__ + +#include "rk_type.h" +#include "mpp_err.h" +#include "hal_task.h" + +#include "h264d_log.h" +#include "hal_h264d_fifo.h" + + +#define RKV_CABAC_TAB_SIZE (3680 + 128) /* bytes */ +#define RKV_SPSPPS_SIZE (256*32 + 128) /* bytes */ +#define RKV_RPS_SIZE (128 + 128) /* bytes */ +#define RKV_SCALING_LIST_SIZE (6*16+2*64 + 128) /* bytes */ +#define RKV_ERROR_INFO_SIZE (256*144*4) /* bytes */ +typedef struct h264d_rkv_packet_t { + FifoCtx_t spspps; + FifoCtx_t rps; + FifoCtx_t scanlist; + FifoCtx_t reg; +} H264dRkvPkt_t; + + +#ifdef __cplusplus +extern "C" { +#endif +void rkv_reset_fifo_packet(H264dRkvPkt_t *pkt); +void rkv_free_fifo_packet (H264dRkvPkt_t *pkt); +MPP_RET rkv_alloc_fifo_packet(H264dLogCtx_t *logctx, H264dRkvPkt_t *pkts); + +void rkv_prepare_spspps_packet (void *hal, FifoCtx_t *pkt); +void rkv_prepare_framerps_packet(void *hal, FifoCtx_t *pkt); +void rkv_prepare_scanlist_packet(void *hal, FifoCtx_t *pkt); +void rkv_prepare_stream_packet (void *hal, FifoCtx_t *pkt); +void rkv_generate_regs (void *hal, HalTaskInfo *task, FifoCtx_t *pkt); +void rkv_fprint_fifo_data (FILE *fp, FifoCtx_t *pkt); + + +#ifdef __cplusplus +} +#endif + + + +//!<============================ +#endif /* __HAL_H264D_RKV_PKT_H__ */ + + + diff --git a/mpp/hal/rkdec/h264d/hal_h264d_rkv_reg.c b/mpp/hal/rkdec/h264d/hal_h264d_rkv_reg.c index 10682ca5..89f01b21 100644 --- a/mpp/hal/rkdec/h264d/hal_h264d_rkv_reg.c +++ b/mpp/hal/rkdec/h264d/hal_h264d_rkv_reg.c @@ -1,561 +1,561 @@ -/* -* -* Copyright 2015 Rockchip Electronics Co. LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#define MODULE_TAG "hal_h264d_rkv_reg" - -#include -#include -#include - -#include "vpu_api.h" -#include "rk_type.h" -#include "mpp_err.h" -#include "mpp_mem.h" -#include "vpu.h" -#include "mpp_time.h" - - -#include "h264d_log.h" -#include "hal_h264d_global.h" -#include "hal_h264d_rkv_pkt.h" -#include "hal_h264d_rkv_reg.h" - -const RK_U32 H264_RKV_Cabac_table[926 * 4] = { - 0x3602f114, 0xf1144a03, 0x4a033602, 0x68e97fe4, 0x36ff35fa, 0x21173307, - 0x00150217, 0x31000901, 0x390576db, 0x41f54ef3, 0x310c3e01, 0x321149fc, - 0x2b094012, 0x431a001d, 0x68095a10, 0x68ec7fd2, 0x4ef34301, 0x3e0141f5, - 0x5fef56fa, 0x2d093dfa, 0x51fa45fd, 0x370660f5, 0x56fb4307, 0x3a005802, - 0x5ef64cfd, 0x45043605, 0x580051fd, 0x4afb43f9, 0x50fb4afc, 0x3a0148f9, - 0x3f002900, 0x3f003f00, 0x560453f7, 0x48f96100, 0x3e03290d, 0x4efc2d00, - 0x7ee560fd, 0x65e762e4, 0x52e443e9, 0x53f05eec, 0x5beb6eea, 0x5df366ee, - 0x5cf97fe3, 0x60f959fb, 0x2efd6cf3, 0x39ff41ff, 0x4afd5df7, 0x57f85cf7, - 0x36057ee9, 0x3b063c06, 0x30ff4506, 0x45fc4400, 0x55fe58f8, 0x4bff4efa, - 0x36024df9, 0x44fd3205, 0x2a063201, 0x3f0151fc, 0x430046fc, 0x4cfe3902, - 0x4004230b, 0x230b3d01, 0x180c1912, 0x240d1d0d, 0x49f95df6, 0x2e0d49fe, - 0x64f93109, 0x35023509, 0x3dfe3505, 0x38003800, 0x3cfb3ff3, 0x39043eff, - 0x390445fa, 0x3304270e, 0x4003440d, 0x3f093d01, 0x27103207, 0x34042c05, - 0x3cfb300b, 0x3b003bff, 0x2c052116, 0x4eff2b0e, 0x45093c00, 0x28021c0b, - 0x31002c03, 0x2c022e00, 0x2f003302, 0x3e022704, 0x36002e06, 0x3a023603, - 0x33063f04, 0x35073906, 0x37063406, 0x240e2d0b, 0x52ff3508, 0x4efd3707, - 0x1f162e0f, 0x071954ff, 0x031cf91e, 0x0020041c, 0x061eff22, 0x0920061e, - 0x1b1a131f, 0x14251e1a, 0x4611221c, 0x3b054301, 0x1e104309, 0x23122012, - 0x1f181d16, 0x2b122617, 0x3f0b2914, 0x40093b09, 0x59fe5eff, 0x4cfa6cf7, - 0x2d002cfe, 0x40fd3400, 0x46fc3bfe, 0x52f84bfc, 0x4df766ef, 0x2a001803, - 0x37003000, 0x47f93bfa, 0x57f553f4, 0x3a0177e2, 0x24ff1dfd, 0x2b022601, - 0x3a0037fa, 0x4afd4000, 0x46005af6, 0x1f051dfc, 0x3b012a07, 0x48fd3afe, - 0x61f551fd, 0x05083a00, 0x120e0e0a, 0x28021b0d, 0x46fd3a00, 0x55f84ffa, - 0x6af30000, 0x57f66af0, 0x6eee72eb, 0x6eea62f2, 0x67ee6aeb, 0x6ce96beb, - 0x60f670e6, 0x5bfb5ff4, 0x5eea5df7, 0x430956fb, 0x55f650fc, 0x3c0746ff, - 0x3d053a09, 0x320f320c, 0x36113112, 0x2e07290a, 0x310733ff, 0x29093408, - 0x37022f06, 0x2c0a290d, 0x35053206, 0x3f04310d, 0x45fe4006, 0x46063bfe, - 0x1f092c0a, 0x35032b0c, 0x260a220e, 0x280d34fd, 0x2c072011, 0x320d2607, - 0x2b1a390a, 0x0e0b0b0e, 0x0b120b09, 0xfe170915, 0xf120f120, 0xe927eb22, - 0xe129df2a, 0xf426e42e, 0xe82d1d15, 0xe630d335, 0xed2bd541, 0x091ef627, - 0x1b141a12, 0x52f23900, 0x61ed4bfb, 0x001b7ddd, 0xfc1f001c, 0x0822061b, - 0x16180a1e, 0x20161321, 0x29151f1a, 0x2f172c1a, 0x470e4110, 0x3f063c08, - 0x18154111, 0x171a1417, 0x171c201b, 0x2817181c, 0x1d1c2018, 0x39132a17, - 0x3d163516, 0x280c560b, 0x3b0e330b, 0x47f94ffc, 0x46f745fb, 0x44f642f8, - 0x45f449ed, 0x43f146f0, 0x46ed3eec, 0x41ea42f0, 0xfe093fec, 0xf721f71a, - 0xfe29f927, 0x0931032d, 0x3b241b2d, 0x23f942fa, 0x2df82af9, 0x38f430fb, - 0x3efb3cfa, 0x4cf842f8, 0x51fa55fb, 0x51f94df6, 0x49ee50ef, 0x53f64afc, - 0x43f747f7, 0x42f83dff, 0x3b0042f2, 0xf3153b02, 0xf927f221, 0x0233fe2e, - 0x113d063c, 0x3e2a2237, 0x00000000, 0x00000000, 0x3602f114, 0xf1144a03, - 0x4a033602, 0x68e97fe4, 0x36ff35fa, 0x19163307, 0x00100022, 0x290409fe, - 0x410276e3, 0x4ff347fa, 0x32093405, 0x360a46fd, 0x1613221a, 0x02390028, - 0x451a2429, 0x65f17fd3, 0x47fa4cfc, 0x34054ff3, 0x5af34506, 0x2b083400, - 0x52fb45fe, 0x3b0260f6, 0x57fd4b02, 0x380164fd, 0x55fa4afd, 0x51fd3b00, - 0x5ffb56f9, 0x4dff42ff, 0x56fe4601, 0x3d0048fb, 0x3f002900, 0x3f003f00, - 0x560453f7, 0x48f96100, 0x3e03290d, 0x33070f0d, 0x7fd95002, 0x60ef5bee, - 0x62dd51e6, 0x61e966e8, 0x63e877e5, 0x66ee6eeb, 0x50007fdc, 0x5ef959fb, - 0x27005cfc, 0x54f14100, 0x49fe7fdd, 0x5bf768f4, 0x37037fe1, 0x37073807, - 0x35fd3d08, 0x4af94400, 0x67f358f7, 0x59f75bf3, 0x4cf85cf2, 0x6ee957f4, - 0x4ef669e8, 0x63ef70ec, 0x7fba7fb2, 0x7fd27fce, 0x4efb42fc, 0x48f847fc, - 0x37ff3b02, 0x4bfa46f9, 0x77de59f8, 0x14204bfd, 0x7fd4161e, 0x3dfb3600, - 0x3cff3a00, 0x43f83dfd, 0x4af254e7, 0x340541fb, 0x3d003902, 0x46f545f7, - 0x47fc3712, 0x3d073a00, 0x19122909, 0x2b052009, 0x2c002f09, 0x2e023300, - 0x42fc2613, 0x2a0c260f, 0x59002209, 0x1c0a2d04, 0xf5211f0a, 0x0f12d534, - 0xea23001c, 0x0022e726, 0xf420ee27, 0x0000a266, 0xfc21f138, 0xfb250a1d, - 0xf727e333, 0xc645de34, 0xfb2cc143, 0xe3370720, 0x00000120, 0xe721241b, - 0xe424e222, 0xe526e426, 0xf023ee22, 0xf820f222, 0x0023fa25, 0x121c0a1e, - 0x291d191a, 0x48024b00, 0x230e4d08, 0x23111f12, 0x2d111e15, 0x2d122a14, - 0x36101a1b, 0x38104207, 0x430a490b, 0x70e974f6, 0x3df947f1, 0x42fb3500, - 0x50f74df5, 0x57f654f7, 0x65eb7fde, 0x35fb27fd, 0x4bf53df9, 0x5bef4df1, - 0x6fe76be7, 0x4cf57ae4, 0x34f62cf6, 0x3af739f6, 0x45f948f0, 0x4afb45fc, - 0x420256f7, 0x200122f7, 0x34051f0b, 0x43fe37fe, 0x59f84900, 0x04073403, - 0x0811080a, 0x25031310, 0x49fb3dff, 0x4efc46ff, 0x7eeb0000, 0x6eec7ce9, - 0x7ce77ee6, 0x79e569ef, 0x66ef75e5, 0x74e575e6, 0x5ff67adf, 0x5ff864f2, - 0x72e46fef, 0x50fe59fa, 0x55f752fc, 0x48ff51f8, 0x43014005, 0x45003809, - 0x45074501, 0x43fa45f9, 0x40fe4df0, 0x43fa3d02, 0x390240fd, 0x42fd41fd, - 0x33093e00, 0x47fe42ff, 0x46ff4bfe, 0x3c0e48f7, 0x2f002510, 0x250b2312, - 0x290a290c, 0x290c3002, 0x3b00290d, 0x28133203, 0x32124203, 0xfa12fa13, - 0xf41a000e, 0xe721f01f, 0xe425ea21, 0xe22ae227, 0xdc2dd62f, 0xef29de31, - 0xb9450920, 0xc042c13f, 0xd936b64d, 0xf629dd34, 0xff280024, 0x1a1c0e1e, - 0x370c2517, 0xdf25410b, 0xdb28dc27, 0xdf2ee226, 0xe828e22a, 0xf426e331, - 0xfd26f628, 0x141ffb2e, 0x2c191e1d, 0x310b300c, 0x16162d1a, 0x151b1617, - 0x1c1a1421, 0x221b181e, 0x27192a12, 0x460c3212, 0x470e3615, 0x2019530b, - 0x36153115, 0x51fa55fb, 0x51f94df6, 0x49ee50ef, 0x53f64afc, 0x43f747f7, - 0x42f83dff, 0x3b0042f2, 0xf6113b02, 0xf72af320, 0x0035fb31, 0x0a440340, - 0x392f1b42, 0x180047fb, 0x2afe24ff, 0x39f734fe, 0x41fc3ffa, 0x52f943fc, - 0x4cfd51fd, 0x4efa48f9, 0x44f248f4, 0x4cfa46fd, 0x3efb42fb, 0x3dfc3900, - 0x36013cf7, 0xf6113a02, 0xf72af320, 0x0035fb31, 0x0a440340, 0x392f1b42, - 0x00000000, 0x00000000, 0x3602f114, 0xf1144a03, 0x4a033602, 0x68e97fe4, - 0x36ff35fa, 0x101d3307, 0x000e0019, 0x3efd33f6, 0x101a63e5, 0x66e855fc, - 0x39063905, 0x390e49ef, 0x0a142814, 0x0036001d, 0x610c2a25, 0x75ea7fe0, - 0x55fc4afe, 0x390566e8, 0x58f25dfa, 0x37042cfa, 0x67f159f5, 0x391374eb, - 0x54043a14, 0x3f016006, 0x6af355fb, 0x4b063f05, 0x65ff5afd, 0x4ffc3703, - 0x61f44bfe, 0x3c0132f9, 0x3f002900, 0x3f003f00, 0x560453f7, 0x48f96100, - 0x3e03290d, 0x58f72207, 0x7fdc7fec, 0x5ff25bef, 0x56e754e7, 0x5bef59f4, - 0x4cf27fe1, 0x5af367ee, 0x500b7fdb, 0x54024c05, 0x37fa4e05, 0x53f23d04, - 0x4ffb7fdb, 0x5bf568f5, 0x41007fe2, 0x48004ffe, 0x38fa5cfc, 0x47f84403, - 0x56fc62f3, 0x52fb58f4, 0x43fc48fd, 0x59f048f8, 0x3bff45f7, 0x39044205, - 0x47fe47fc, 0x4aff3a02, 0x45ff2cfc, 0x33f93e00, 0x2afa2ffc, 0x35fa29fd, - 0x4ef74c08, 0x340953f5, 0x5afb4300, 0x48f14301, 0x50f84bfb, 0x40eb53eb, - 0x40e71ff3, 0x4b095ee3, 0x4af83f11, 0x1bfe23fb, 0x41035b0d, 0x4d0845f9, - 0x3e0342f6, 0x51ec44fd, 0x07011e00, 0x4aeb17fd, 0x7ce94210, 0xee2c2511, - 0x7feade32, 0x2a002704, 0x1d0b2207, 0x25061f08, 0x28032a07, 0x2b0d2108, - 0x2f04240d, 0x3a023703, 0x2c083c06, 0x2a0e2c0b, 0x38043007, 0x250d3404, - 0x3a133109, 0x2d0c300a, 0x21144500, 0xee233f08, 0xfd1ce721, 0x001b0a18, - 0xd434f222, 0x1113e827, 0x1d24191f, 0x0f222118, 0x4916141e, 0x1f132214, - 0x10132c1b, 0x240f240f, 0x15191c15, 0x0c1f141e, 0x2a18101b, 0x380e5d00, - 0x261a390f, 0x73e87fe8, 0x3ef752ea, 0x3b003500, 0x59f355f2, 0x5cf55ef3, - 0x64eb7fe3, 0x43f439f2, 0x4df647f5, 0x58f055eb, 0x62f168e9, 0x52f67fdb, - 0x3df830f8, 0x46f942f8, 0x4ff64bf2, 0x5cf453f7, 0x4ffc6cee, 0x4bf045ea, - 0x3a013afe, 0x53f74ef3, 0x63f351fc, 0x26fa51f3, 0x3afa3ef3, 0x49f03bfe, - 0x56f34cf6, 0x57f653f7, 0x7fea0000, 0x78e77fe7, 0x72ed7fe5, 0x76e775e9, - 0x71e875e6, 0x78e176e4, 0x5ef67cdb, 0x63f666f1, 0x7fce6af3, 0x39115cfb, - 0x5ef356fb, 0x4dfe5bf4, 0x49ff4700, 0x51f94004, 0x390f4005, 0x44004301, - 0x440143f6, 0x40024d00, 0x4efb4400, 0x3b053707, 0x360e4102, 0x3c052c0f, - 0x4cfe4602, 0x460c56ee, 0x46f44005, 0x3805370b, 0x41024500, 0x36054afa, - 0x4cfa3607, 0x4dfe52f5, 0x2a194dfe, 0xf710f311, 0xeb1bf411, 0xd829e225, - 0xd130d72a, 0xd82ee027, 0xd72ecd34, 0xed2bd934, 0xc93d0b20, 0xce3ed238, - 0xec2dbd51, 0x0f1cfe23, 0x01270122, 0x2614111e, 0x360f2d12, 0xf0244f00, - 0xef25f225, 0x0f220120, 0x19180f1d, 0x101f1622, 0x1c1f1223, 0x1c242921, - 0x3e152f1b, 0x1a131f12, 0x17181824, 0x1e18101b, 0x29161d1f, 0x3c102a16, - 0x3c0e340f, 0x7bf04e03, 0x38163515, 0x21153d19, 0x3d113213, 0x4af84efd, - 0x48f648f7, 0x47f44bee, 0x46fb3ff5, 0x48f24bef, 0x35f843f0, 0x34f73bf2, - 0xfe0944f5, 0xfc1ff61e, 0x0721ff21, 0x17250c1f, 0x4014261f, 0x25f947f7, - 0x31f52cf8, 0x3bf438f6, 0x43f73ff8, 0x4ff644fa, 0x4af84efd, 0x48f648f7, - 0x47f44bee, 0x46fb3ff5, 0x48f24bef, 0x35f843f0, 0x34f73bf2, 0xfe0944f5, - 0xfc1ff61e, 0x0721ff21, 0x17250c1f, 0x4014261f, 0x00000000, 0x00000000, - 0x3602f114, 0xf1144a03, 0x4a033602, 0x68e97fe4, 0x36ff35fa, 0x00003307, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x3f002900, 0x3f003f00, 0x560453f7, 0x48f96100, 0x3e03290d, 0x37010b00, - 0x7fef4500, 0x520066f3, 0x6beb4af9, 0x7fe17fe5, 0x5fee7fe8, 0x72eb7fe5, - 0x7bef7fe2, 0x7af073f4, 0x3ff473f5, 0x54f144fe, 0x46fd68f3, 0x5af65df8, - 0x4aff7fe2, 0x5bf961fa, 0x38fc7fec, 0x4cf952fb, 0x5df97dea, 0x4dfd57f5, - 0x3ffc47fb, 0x54f444fc, 0x41f93ef9, 0x38053d08, 0x400142fe, 0x4efe3d00, - 0x34073201, 0x2c00230a, 0x2d01260b, 0x2c052e00, 0x3301111f, 0x131c3207, - 0x3e0e2110, 0x64f16cf3, 0x5bf365f3, 0x58f65ef4, 0x56f654f0, 0x57f353f9, - 0x46015eed, 0x4afb4800, 0x66f83b12, 0x5f0064f1, 0x48024bfc, 0x47fd4bf5, - 0x45f32e0f, 0x41003e00, 0x48f12515, 0x36103909, 0x480c3e00, 0x090f0018, - 0x120d1908, 0x130d090f, 0x120c250a, 0x21141d06, 0x2d041e0f, 0x3e003a01, - 0x260c3d07, 0x270f2d0b, 0x2c0d2a0b, 0x290c2d10, 0x221e310a, 0x370a2a12, - 0x2e113311, 0xed1a5900, 0xef1aef16, 0xec1ce71e, 0xe525e921, 0xe428e921, - 0xf521ef26, 0xfa29f128, 0x11290126, 0x031bfa1e, 0xf025161a, 0xf826fc23, - 0x0325fd26, 0x002a0526, 0x16271023, 0x251b300e, 0x440c3c15, 0x47fd6102, - 0x32fb2afa, 0x3efe36fd, 0x3f013a00, 0x4aff48fe, 0x43fb5bf7, 0x27fd1bfb, - 0x2e002cfe, 0x44f840f0, 0x4dfa4ef6, 0x5cf456f6, 0x3cf637f1, 0x41fc3efa, - 0x4cf849f4, 0x58f750f9, 0x61f56eef, 0x4ff554ec, 0x4afc49fa, 0x60f356f3, - 0x75ed61f5, 0x21fb4ef8, 0x35fe30fc, 0x47f33efd, 0x56f44ff6, 0x61f25af3, - 0x5dfa0000, 0x4ff854fa, 0x47ff4200, 0x3cfe3e00, 0x4bfb3bfe, 0x3afc3efd, - 0x4fff42f7, 0x44034700, 0x3ef92c0a, 0x280e240f, 0x1d0c1b10, 0x24142c01, - 0x2a052012, 0x3e0a3001, 0x40092e11, 0x61f568f4, 0x58f960f0, 0x55f955f8, - 0x58f355f7, 0x4dfd4204, 0x4cfa4cfd, 0x4cff3a0a, 0x63f953ff, 0x5f025ff2, - 0x4afb4c00, 0x4bf54600, 0x41004401, 0x3e0349f2, 0x44ff3e04, 0x370b4bf3, - 0x460c4005, 0x1306060f, 0x0e0c1007, 0x0b0d0d12, 0x100f0f0d, 0x170d170c, - 0x1a0e140f, 0x28112c0e, 0x11182f11, 0x16191515, 0x1d161b1f, 0x320e2313, - 0x3f07390a, 0x52fc4dfe, 0x45095efd, 0xdd246df4, 0xe620de24, 0xe02ce225, - 0xf122ee22, 0xf921f128, 0x0021fb23, 0x0d210226, 0x3a0d2317, 0x001afd1d, - 0xf91f1e16, 0xfd22f123, 0xff240322, 0x0b200522, 0x0c220523, 0x1d1e0b27, - 0x271d1a22, 0x151f4213, 0x32191f1f, 0x70ec78ef, 0x55f572ee, 0x59f25cf1, - 0x51f147e6, 0x440050f2, 0x38e846f2, 0x32e844e9, 0xf3174af5, 0xf128f31a, - 0x032cf231, 0x222c062d, 0x52133621, 0x17ff4bfd, 0x2b012201, 0x37fe3600, - 0x40013d00, 0x5cf74400, 0x61f36af2, 0x5af45af1, 0x49f658ee, 0x56f24ff7, - 0x46f649f6, 0x42fb45f6, 0x3afb40f7, 0xf6153b02, 0xf81cf518, 0x031dff1c, - 0x1423091d, 0x430e241d, -}; - - - -static RK_U32 rkv_ver_align(RK_U32 val) -{ - return MPP_ALIGN(val, 16); -} - -static RK_U32 rkv_hor_align(RK_U32 val) -{ - return MPP_ALIGN(val, 16); -} - -static RK_U32 rkv_len_align(RK_U32 val) -{ - return (2 * MPP_ALIGN(val, 16)); -} - -static RK_U32 rkv_len_align_422(RK_U32 val) -{ - return ((5 * MPP_ALIGN(val, 16)) / 2); -} - - -static void rkv_h264d_hal_dump(H264dHalCtx_t *p_hal, RK_U32 dump_type) -{ - if (rkv_h264d_hal_debug & H264D_DBG_ERR_DUMP) { - RK_U32 i = 0; - RK_U32 *p_hal_regs = NULL; - H264dRkvErrDump_t *p_dump = (H264dRkvErrDump_t *)p_hal->dump; - switch (dump_type) { - case H264D_DBG_GEN_REGS: - p_hal_regs = (RK_U32 *)p_dump->in_regs; - mpp_log("------- register input ------ \n"); - for (i = 0; i < DEC_RKV_REGISTERS; i++) { - mpp_log("reg[%d]=%08x", i, p_hal_regs[i]); - } - break; - case H264D_DBG_RET_REGS: - p_hal_regs = (RK_U32 *)p_dump->out_regs; - mpp_log("------- register output ------ \n"); - for (i = 0; i < DEC_RKV_REGISTERS; i++) { - mpp_log("reg[%d]=%08x", i, p_hal_regs[i]); - } - break; - - default: - break; - } - } -} - -/*! -*********************************************************************** -* \brief -* init -*********************************************************************** -*/ -//extern "C" -MPP_RET rkv_h264d_init(void *hal, MppHalCfg *cfg) -{ - RK_U32 cabac_size = 0; - MPP_RET ret = MPP_ERR_UNKNOW; - H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal; - - INP_CHECK(ret, NULL == p_hal); - FunctionIn(p_hal->logctx.parr[RUN_HAL]); - p_hal->iDecodedNum = 0; - MEM_CHECK(ret, p_hal->pkts = mpp_calloc_size(void, sizeof(H264dRkvPkt_t))); - MEM_CHECK(ret, p_hal->dump = mpp_malloc_size(void, sizeof(H264dRkvErrDump_t))); - //!< malloc cabac+scanlis + packets + poc_buf - cabac_size = RKV_CABAC_TAB_SIZE + RKV_SPSPPS_SIZE + RKV_RPS_SIZE + RKV_SCALING_LIST_SIZE + RKV_ERROR_INFO_SIZE; - FUN_CHECK(ret = mpp_buffer_get(p_hal->buf_group, &p_hal->cabac_buf, cabac_size)); - //!< copy cabac table bytes - FUN_CHECK(ret = mpp_buffer_write(p_hal->cabac_buf, 0, (void *)H264_RKV_Cabac_table, sizeof(H264_RKV_Cabac_table))); - FUN_CHECK(ret = rkv_alloc_fifo_packet(&p_hal->logctx, (H264dRkvPkt_t *)p_hal->pkts)); - p_hal->regs = (void *)((H264dRkvPkt_t *)p_hal->pkts)->reg.pbuf; - - mpp_slots_set_prop(p_hal->frame_slots, SLOTS_HOR_ALIGN, rkv_hor_align); - mpp_slots_set_prop(p_hal->frame_slots, SLOTS_VER_ALIGN, rkv_ver_align); - mpp_slots_set_prop(p_hal->frame_slots, SLOTS_LEN_ALIGN, rkv_len_align); - - FunctionOut(p_hal->logctx.parr[RUN_HAL]); - (void)cfg; -__RETURN: - return MPP_OK; -__FAILED: - rkv_h264d_deinit(hal); - - return ret; -} -/*! -*********************************************************************** -* \brief -* deinit -*********************************************************************** -*/ -//extern "C" -MPP_RET rkv_h264d_deinit(void *hal) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal; - - INP_CHECK(ret, NULL == p_hal); - FunctionIn(p_hal->logctx.parr[RUN_HAL]); - - rkv_free_fifo_packet((H264dRkvPkt_t *)p_hal->pkts); - MPP_FREE(p_hal->dump); - MPP_FREE(p_hal->pkts); - if (p_hal->cabac_buf) { - FUN_CHECK(ret = mpp_buffer_put(p_hal->cabac_buf)); - } - - FunctionOut(p_hal->logctx.parr[RUN_HAL]); -__RETURN: - return ret = MPP_OK; -__FAILED: - return ret; -} -/*! -*********************************************************************** -* \brief -* generate register -*********************************************************************** -*/ -//extern "C" -MPP_RET rkv_h264d_gen_regs(void *hal, HalTaskInfo *task) -{ - RK_U32 i = 0; - RK_U32 hw_base = 0; - RK_U32 strm_offset = 0; - MPP_RET ret = MPP_ERR_UNKNOW; - H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal; - H264dRkvPkt_t *pkts = (H264dRkvPkt_t *)p_hal->pkts; - H264dRkvRegs_t *p_regs = (H264dRkvRegs_t *)p_hal->regs; - - INP_CHECK(ret, NULL == p_hal); - FunctionIn(p_hal->logctx.parr[RUN_HAL]); - if (task->dec.flags.had_error) { - goto __RETURN; - } - rkv_prepare_spspps_packet(hal, &pkts->spspps); - rkv_prepare_framerps_packet(hal, &pkts->rps); - rkv_prepare_scanlist_packet(hal, &pkts->scanlist); - rkv_generate_regs(p_hal, task, &pkts->reg); - - hw_base = mpp_buffer_get_fd(p_hal->cabac_buf); - //!< copy datas - strm_offset = RKV_CABAC_TAB_SIZE; - for (i = 0; i < 256; i++) { - mpp_buffer_write(p_hal->cabac_buf, (strm_offset + 32 * i), (void *)pkts->spspps.pbuf, RKV_SPSPPS_SIZE); - } - p_regs->swreg42_pps_base.sw_pps_base = hw_base + (strm_offset << 10); - strm_offset += RKV_SPSPPS_SIZE; - - mpp_buffer_write(p_hal->cabac_buf, strm_offset, (void *)pkts->rps.pbuf, RKV_RPS_SIZE); - p_regs->swreg43_rps_base.sw_rps_base = hw_base + (strm_offset << 10); - - strm_offset += RKV_RPS_SIZE; - mpp_buffer_write(p_hal->cabac_buf, strm_offset, (void *)pkts->scanlist.pbuf, RKV_SCALING_LIST_SIZE); - - strm_offset += RKV_SCALING_LIST_SIZE; - p_regs->swreg75_h264_errorinfo_base.sw_errorinfo_base = hw_base + (strm_offset << 10); - - - ((HalDecTask*)&task->dec)->valid = 0; - FunctionOut(p_hal->logctx.parr[RUN_HAL]); - -__RETURN: - return ret = MPP_OK; -} -/*! -*********************************************************************** -* \brief h -* start hard -*********************************************************************** -*/ -//extern "C" -MPP_RET rkv_h264d_start(void *hal, HalTaskInfo *task) -{ - RK_U32 *p_regs = NULL; - MPP_RET ret = MPP_ERR_UNKNOW; - H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal; - - INP_CHECK(ret, NULL == p_hal); - FunctionIn(p_hal->logctx.parr[RUN_HAL]); - if (task->dec.flags.had_error) { - goto __RETURN; - } - p_regs = (RK_U32 *)p_hal->regs; - - p_regs[64] = 0; - p_regs[65] = 0; - p_regs[66] = 0; - p_regs[67] = 0x000000ff; // disable fpga reset - p_regs[44] = 0xffffffff; // 0xffff_ffff, debug enable - p_regs[77] = 0xffffffff; // 0xffff_dfff, debug enable - - p_regs[1] |= 0x00000061; // run hardware, enable buf_empty_en - //!< dump input register - { - H264dRkvErrDump_t *p_dump = (H264dRkvErrDump_t *)p_hal->dump; - memcpy(p_dump->in_regs, p_regs, DEC_RKV_REGISTERS); - if (rkv_h264d_hal_debug & H264D_DBG_GEN_REGS) { - rkv_h264d_hal_dump(p_hal, H264D_DBG_GEN_REGS); - } - } - //!< current buffer slot fd - H264D_DBG(H264D_DBG_DECOUT_INFO, "[DECOUT_INFO] decout_fd=0x%02x", p_regs[7]); -#ifdef RKPLATFORM - if (VPUClientSendReg(p_hal->vpu_socket, (RK_U32 *)p_regs, DEC_RKV_REGISTERS)) { - ret = MPP_ERR_VPUHW; - H264D_ERR("H264 RKV FlushRegs fail. \n"); - } -#endif - FunctionOut(p_hal->logctx.parr[RUN_HAL]); - (void)task; -__RETURN: - return ret = MPP_OK; -} -/*! -*********************************************************************** -* \brief -* wait hard -*********************************************************************** -*/ -//extern "C" -MPP_RET rkv_h264d_wait(void *hal, HalTaskInfo *task) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - H264dRkvRegs_t *p_regs = NULL; - H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal; - - INP_CHECK(ret, NULL == p_hal); - FunctionIn(p_hal->logctx.parr[RUN_HAL]); - - p_regs = (H264dRkvRegs_t *)p_hal->regs; - if (task->dec.flags.had_error) { - goto __SKIP_HARD; - } -#ifdef RKPLATFORM - RK_S32 wait_ret = -1; - RK_S32 ret_len = 0, cur_deat = 0; - VPU_CMD_TYPE ret_cmd = VPU_CMD_BUTT; - RK_S64 p_s, p_e; - p_s = mpp_time(); - wait_ret = VPUClientWaitResult(p_hal->vpu_socket, (RK_U32 *)p_hal->regs, DEC_RKV_REGISTERS, &ret_cmd, &ret_len); - p_e = mpp_time(); - cur_deat = (p_e - p_s) / 1000; - p_hal->total_time += cur_deat; - p_hal->iDecodedNum++; - (void)wait_ret; -#endif - //!< dump registers - { - H264dRkvErrDump_t *p_dump = (H264dRkvErrDump_t *)p_hal->dump; - p_dump->out_regs = (RK_U32 *)p_regs; - if (rkv_h264d_hal_debug & H264D_DBG_RET_REGS) { - rkv_h264d_hal_dump(p_hal, H264D_DBG_RET_REGS); - } - if (p_regs->swreg1_int.sw_dec_error_sta) { - rkv_h264d_hal_dump(p_hal, H264D_DBG_GEN_REGS); - rkv_h264d_hal_dump(p_hal, H264D_DBG_RET_REGS); - } - } -__SKIP_HARD: - if (p_hal->init_cb.callBack) { - IOCallbackCtx m_ctx = { 0 }; - m_ctx.device_id = HAL_RKVDEC; - if (p_regs->swreg1_int.sw_dec_error_sta - || (!p_regs->swreg1_int.sw_dec_rdy_sta) - || p_regs->swreg1_int.sw_dec_empty_sta - || p_regs->swreg45_strmd_error_status.sw_strmd_error_status - || p_regs->swreg45_strmd_error_status.sw_colmv_error_ref_picidx - || p_regs->swreg76_h264_errorinfo_num.sw_strmd_detect_error_flag) { - m_ctx.hard_err = 1; - } - m_ctx.task = (void *)&task->dec; - m_ctx.regs = (RK_U32 *)p_hal->regs; - p_hal->init_cb.callBack(p_hal->init_cb.opaque, &m_ctx); - } - memset(&p_regs->swreg1_int, 0, sizeof(RK_U32)); - - FunctionOut(p_hal->logctx.parr[RUN_HAL]); - (void)task; -__RETURN: - return ret = MPP_OK; -} -/*! -*********************************************************************** -* \brief -* reset -*********************************************************************** -*/ -//extern "C" -MPP_RET rkv_h264d_reset(void *hal) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal; - - INP_CHECK(ret, NULL == p_hal); - FunctionIn(p_hal->logctx.parr[RUN_HAL]); - - memset(p_hal->regs, 0, sizeof(H264dRkvRegs_t)); - rkv_reset_fifo_packet((H264dRkvPkt_t *)p_hal->pkts); - - FunctionOut(p_hal->logctx.parr[RUN_HAL]); -__RETURN: - return ret = MPP_OK; -} -/*! -*********************************************************************** -* \brief -* flush -*********************************************************************** -*/ -//extern "C" -MPP_RET rkv_h264d_flush(void *hal) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal; - - INP_CHECK(ret, NULL == p_hal); - FunctionIn(p_hal->logctx.parr[RUN_HAL]); - - - - - - FunctionOut(p_hal->logctx.parr[RUN_HAL]); -__RETURN: - return ret = MPP_OK; -} -/*! -*********************************************************************** -* \brief -* control -*********************************************************************** -*/ -//extern "C" -MPP_RET rkv_h264d_control(void *hal, RK_S32 cmd_type, void *param) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal; - - INP_CHECK(ret, NULL == p_hal); - FunctionIn(p_hal->logctx.parr[RUN_HAL]); - switch ((MpiCmd)cmd_type) { - case MPP_DEC_SET_FRAME_INFO: { - VPU_GENERIC *p = (VPU_GENERIC *)param; - if (p->CodecType == MPP_FMT_YUV422SP) { - mpp_slots_set_prop(p_hal->frame_slots, SLOTS_LEN_ALIGN, rkv_len_align_422); - mpp_log_f("control format YUV422SP \n"); - } - break; - } - - default: - break; - } - - FunctionOut(p_hal->logctx.parr[RUN_HAL]); - (void)hal; - (void)cmd_type; - (void)param; -__RETURN: - return ret = MPP_OK; -} +/* +* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#define MODULE_TAG "hal_h264d_rkv_reg" + +#include +#include +#include + +#include "vpu_api.h" +#include "rk_type.h" +#include "mpp_err.h" +#include "mpp_mem.h" +#include "vpu.h" +#include "mpp_time.h" + + +#include "h264d_log.h" +#include "hal_h264d_global.h" +#include "hal_h264d_rkv_pkt.h" +#include "hal_h264d_rkv_reg.h" + +const RK_U32 H264_RKV_Cabac_table[926 * 4] = { + 0x3602f114, 0xf1144a03, 0x4a033602, 0x68e97fe4, 0x36ff35fa, 0x21173307, + 0x00150217, 0x31000901, 0x390576db, 0x41f54ef3, 0x310c3e01, 0x321149fc, + 0x2b094012, 0x431a001d, 0x68095a10, 0x68ec7fd2, 0x4ef34301, 0x3e0141f5, + 0x5fef56fa, 0x2d093dfa, 0x51fa45fd, 0x370660f5, 0x56fb4307, 0x3a005802, + 0x5ef64cfd, 0x45043605, 0x580051fd, 0x4afb43f9, 0x50fb4afc, 0x3a0148f9, + 0x3f002900, 0x3f003f00, 0x560453f7, 0x48f96100, 0x3e03290d, 0x4efc2d00, + 0x7ee560fd, 0x65e762e4, 0x52e443e9, 0x53f05eec, 0x5beb6eea, 0x5df366ee, + 0x5cf97fe3, 0x60f959fb, 0x2efd6cf3, 0x39ff41ff, 0x4afd5df7, 0x57f85cf7, + 0x36057ee9, 0x3b063c06, 0x30ff4506, 0x45fc4400, 0x55fe58f8, 0x4bff4efa, + 0x36024df9, 0x44fd3205, 0x2a063201, 0x3f0151fc, 0x430046fc, 0x4cfe3902, + 0x4004230b, 0x230b3d01, 0x180c1912, 0x240d1d0d, 0x49f95df6, 0x2e0d49fe, + 0x64f93109, 0x35023509, 0x3dfe3505, 0x38003800, 0x3cfb3ff3, 0x39043eff, + 0x390445fa, 0x3304270e, 0x4003440d, 0x3f093d01, 0x27103207, 0x34042c05, + 0x3cfb300b, 0x3b003bff, 0x2c052116, 0x4eff2b0e, 0x45093c00, 0x28021c0b, + 0x31002c03, 0x2c022e00, 0x2f003302, 0x3e022704, 0x36002e06, 0x3a023603, + 0x33063f04, 0x35073906, 0x37063406, 0x240e2d0b, 0x52ff3508, 0x4efd3707, + 0x1f162e0f, 0x071954ff, 0x031cf91e, 0x0020041c, 0x061eff22, 0x0920061e, + 0x1b1a131f, 0x14251e1a, 0x4611221c, 0x3b054301, 0x1e104309, 0x23122012, + 0x1f181d16, 0x2b122617, 0x3f0b2914, 0x40093b09, 0x59fe5eff, 0x4cfa6cf7, + 0x2d002cfe, 0x40fd3400, 0x46fc3bfe, 0x52f84bfc, 0x4df766ef, 0x2a001803, + 0x37003000, 0x47f93bfa, 0x57f553f4, 0x3a0177e2, 0x24ff1dfd, 0x2b022601, + 0x3a0037fa, 0x4afd4000, 0x46005af6, 0x1f051dfc, 0x3b012a07, 0x48fd3afe, + 0x61f551fd, 0x05083a00, 0x120e0e0a, 0x28021b0d, 0x46fd3a00, 0x55f84ffa, + 0x6af30000, 0x57f66af0, 0x6eee72eb, 0x6eea62f2, 0x67ee6aeb, 0x6ce96beb, + 0x60f670e6, 0x5bfb5ff4, 0x5eea5df7, 0x430956fb, 0x55f650fc, 0x3c0746ff, + 0x3d053a09, 0x320f320c, 0x36113112, 0x2e07290a, 0x310733ff, 0x29093408, + 0x37022f06, 0x2c0a290d, 0x35053206, 0x3f04310d, 0x45fe4006, 0x46063bfe, + 0x1f092c0a, 0x35032b0c, 0x260a220e, 0x280d34fd, 0x2c072011, 0x320d2607, + 0x2b1a390a, 0x0e0b0b0e, 0x0b120b09, 0xfe170915, 0xf120f120, 0xe927eb22, + 0xe129df2a, 0xf426e42e, 0xe82d1d15, 0xe630d335, 0xed2bd541, 0x091ef627, + 0x1b141a12, 0x52f23900, 0x61ed4bfb, 0x001b7ddd, 0xfc1f001c, 0x0822061b, + 0x16180a1e, 0x20161321, 0x29151f1a, 0x2f172c1a, 0x470e4110, 0x3f063c08, + 0x18154111, 0x171a1417, 0x171c201b, 0x2817181c, 0x1d1c2018, 0x39132a17, + 0x3d163516, 0x280c560b, 0x3b0e330b, 0x47f94ffc, 0x46f745fb, 0x44f642f8, + 0x45f449ed, 0x43f146f0, 0x46ed3eec, 0x41ea42f0, 0xfe093fec, 0xf721f71a, + 0xfe29f927, 0x0931032d, 0x3b241b2d, 0x23f942fa, 0x2df82af9, 0x38f430fb, + 0x3efb3cfa, 0x4cf842f8, 0x51fa55fb, 0x51f94df6, 0x49ee50ef, 0x53f64afc, + 0x43f747f7, 0x42f83dff, 0x3b0042f2, 0xf3153b02, 0xf927f221, 0x0233fe2e, + 0x113d063c, 0x3e2a2237, 0x00000000, 0x00000000, 0x3602f114, 0xf1144a03, + 0x4a033602, 0x68e97fe4, 0x36ff35fa, 0x19163307, 0x00100022, 0x290409fe, + 0x410276e3, 0x4ff347fa, 0x32093405, 0x360a46fd, 0x1613221a, 0x02390028, + 0x451a2429, 0x65f17fd3, 0x47fa4cfc, 0x34054ff3, 0x5af34506, 0x2b083400, + 0x52fb45fe, 0x3b0260f6, 0x57fd4b02, 0x380164fd, 0x55fa4afd, 0x51fd3b00, + 0x5ffb56f9, 0x4dff42ff, 0x56fe4601, 0x3d0048fb, 0x3f002900, 0x3f003f00, + 0x560453f7, 0x48f96100, 0x3e03290d, 0x33070f0d, 0x7fd95002, 0x60ef5bee, + 0x62dd51e6, 0x61e966e8, 0x63e877e5, 0x66ee6eeb, 0x50007fdc, 0x5ef959fb, + 0x27005cfc, 0x54f14100, 0x49fe7fdd, 0x5bf768f4, 0x37037fe1, 0x37073807, + 0x35fd3d08, 0x4af94400, 0x67f358f7, 0x59f75bf3, 0x4cf85cf2, 0x6ee957f4, + 0x4ef669e8, 0x63ef70ec, 0x7fba7fb2, 0x7fd27fce, 0x4efb42fc, 0x48f847fc, + 0x37ff3b02, 0x4bfa46f9, 0x77de59f8, 0x14204bfd, 0x7fd4161e, 0x3dfb3600, + 0x3cff3a00, 0x43f83dfd, 0x4af254e7, 0x340541fb, 0x3d003902, 0x46f545f7, + 0x47fc3712, 0x3d073a00, 0x19122909, 0x2b052009, 0x2c002f09, 0x2e023300, + 0x42fc2613, 0x2a0c260f, 0x59002209, 0x1c0a2d04, 0xf5211f0a, 0x0f12d534, + 0xea23001c, 0x0022e726, 0xf420ee27, 0x0000a266, 0xfc21f138, 0xfb250a1d, + 0xf727e333, 0xc645de34, 0xfb2cc143, 0xe3370720, 0x00000120, 0xe721241b, + 0xe424e222, 0xe526e426, 0xf023ee22, 0xf820f222, 0x0023fa25, 0x121c0a1e, + 0x291d191a, 0x48024b00, 0x230e4d08, 0x23111f12, 0x2d111e15, 0x2d122a14, + 0x36101a1b, 0x38104207, 0x430a490b, 0x70e974f6, 0x3df947f1, 0x42fb3500, + 0x50f74df5, 0x57f654f7, 0x65eb7fde, 0x35fb27fd, 0x4bf53df9, 0x5bef4df1, + 0x6fe76be7, 0x4cf57ae4, 0x34f62cf6, 0x3af739f6, 0x45f948f0, 0x4afb45fc, + 0x420256f7, 0x200122f7, 0x34051f0b, 0x43fe37fe, 0x59f84900, 0x04073403, + 0x0811080a, 0x25031310, 0x49fb3dff, 0x4efc46ff, 0x7eeb0000, 0x6eec7ce9, + 0x7ce77ee6, 0x79e569ef, 0x66ef75e5, 0x74e575e6, 0x5ff67adf, 0x5ff864f2, + 0x72e46fef, 0x50fe59fa, 0x55f752fc, 0x48ff51f8, 0x43014005, 0x45003809, + 0x45074501, 0x43fa45f9, 0x40fe4df0, 0x43fa3d02, 0x390240fd, 0x42fd41fd, + 0x33093e00, 0x47fe42ff, 0x46ff4bfe, 0x3c0e48f7, 0x2f002510, 0x250b2312, + 0x290a290c, 0x290c3002, 0x3b00290d, 0x28133203, 0x32124203, 0xfa12fa13, + 0xf41a000e, 0xe721f01f, 0xe425ea21, 0xe22ae227, 0xdc2dd62f, 0xef29de31, + 0xb9450920, 0xc042c13f, 0xd936b64d, 0xf629dd34, 0xff280024, 0x1a1c0e1e, + 0x370c2517, 0xdf25410b, 0xdb28dc27, 0xdf2ee226, 0xe828e22a, 0xf426e331, + 0xfd26f628, 0x141ffb2e, 0x2c191e1d, 0x310b300c, 0x16162d1a, 0x151b1617, + 0x1c1a1421, 0x221b181e, 0x27192a12, 0x460c3212, 0x470e3615, 0x2019530b, + 0x36153115, 0x51fa55fb, 0x51f94df6, 0x49ee50ef, 0x53f64afc, 0x43f747f7, + 0x42f83dff, 0x3b0042f2, 0xf6113b02, 0xf72af320, 0x0035fb31, 0x0a440340, + 0x392f1b42, 0x180047fb, 0x2afe24ff, 0x39f734fe, 0x41fc3ffa, 0x52f943fc, + 0x4cfd51fd, 0x4efa48f9, 0x44f248f4, 0x4cfa46fd, 0x3efb42fb, 0x3dfc3900, + 0x36013cf7, 0xf6113a02, 0xf72af320, 0x0035fb31, 0x0a440340, 0x392f1b42, + 0x00000000, 0x00000000, 0x3602f114, 0xf1144a03, 0x4a033602, 0x68e97fe4, + 0x36ff35fa, 0x101d3307, 0x000e0019, 0x3efd33f6, 0x101a63e5, 0x66e855fc, + 0x39063905, 0x390e49ef, 0x0a142814, 0x0036001d, 0x610c2a25, 0x75ea7fe0, + 0x55fc4afe, 0x390566e8, 0x58f25dfa, 0x37042cfa, 0x67f159f5, 0x391374eb, + 0x54043a14, 0x3f016006, 0x6af355fb, 0x4b063f05, 0x65ff5afd, 0x4ffc3703, + 0x61f44bfe, 0x3c0132f9, 0x3f002900, 0x3f003f00, 0x560453f7, 0x48f96100, + 0x3e03290d, 0x58f72207, 0x7fdc7fec, 0x5ff25bef, 0x56e754e7, 0x5bef59f4, + 0x4cf27fe1, 0x5af367ee, 0x500b7fdb, 0x54024c05, 0x37fa4e05, 0x53f23d04, + 0x4ffb7fdb, 0x5bf568f5, 0x41007fe2, 0x48004ffe, 0x38fa5cfc, 0x47f84403, + 0x56fc62f3, 0x52fb58f4, 0x43fc48fd, 0x59f048f8, 0x3bff45f7, 0x39044205, + 0x47fe47fc, 0x4aff3a02, 0x45ff2cfc, 0x33f93e00, 0x2afa2ffc, 0x35fa29fd, + 0x4ef74c08, 0x340953f5, 0x5afb4300, 0x48f14301, 0x50f84bfb, 0x40eb53eb, + 0x40e71ff3, 0x4b095ee3, 0x4af83f11, 0x1bfe23fb, 0x41035b0d, 0x4d0845f9, + 0x3e0342f6, 0x51ec44fd, 0x07011e00, 0x4aeb17fd, 0x7ce94210, 0xee2c2511, + 0x7feade32, 0x2a002704, 0x1d0b2207, 0x25061f08, 0x28032a07, 0x2b0d2108, + 0x2f04240d, 0x3a023703, 0x2c083c06, 0x2a0e2c0b, 0x38043007, 0x250d3404, + 0x3a133109, 0x2d0c300a, 0x21144500, 0xee233f08, 0xfd1ce721, 0x001b0a18, + 0xd434f222, 0x1113e827, 0x1d24191f, 0x0f222118, 0x4916141e, 0x1f132214, + 0x10132c1b, 0x240f240f, 0x15191c15, 0x0c1f141e, 0x2a18101b, 0x380e5d00, + 0x261a390f, 0x73e87fe8, 0x3ef752ea, 0x3b003500, 0x59f355f2, 0x5cf55ef3, + 0x64eb7fe3, 0x43f439f2, 0x4df647f5, 0x58f055eb, 0x62f168e9, 0x52f67fdb, + 0x3df830f8, 0x46f942f8, 0x4ff64bf2, 0x5cf453f7, 0x4ffc6cee, 0x4bf045ea, + 0x3a013afe, 0x53f74ef3, 0x63f351fc, 0x26fa51f3, 0x3afa3ef3, 0x49f03bfe, + 0x56f34cf6, 0x57f653f7, 0x7fea0000, 0x78e77fe7, 0x72ed7fe5, 0x76e775e9, + 0x71e875e6, 0x78e176e4, 0x5ef67cdb, 0x63f666f1, 0x7fce6af3, 0x39115cfb, + 0x5ef356fb, 0x4dfe5bf4, 0x49ff4700, 0x51f94004, 0x390f4005, 0x44004301, + 0x440143f6, 0x40024d00, 0x4efb4400, 0x3b053707, 0x360e4102, 0x3c052c0f, + 0x4cfe4602, 0x460c56ee, 0x46f44005, 0x3805370b, 0x41024500, 0x36054afa, + 0x4cfa3607, 0x4dfe52f5, 0x2a194dfe, 0xf710f311, 0xeb1bf411, 0xd829e225, + 0xd130d72a, 0xd82ee027, 0xd72ecd34, 0xed2bd934, 0xc93d0b20, 0xce3ed238, + 0xec2dbd51, 0x0f1cfe23, 0x01270122, 0x2614111e, 0x360f2d12, 0xf0244f00, + 0xef25f225, 0x0f220120, 0x19180f1d, 0x101f1622, 0x1c1f1223, 0x1c242921, + 0x3e152f1b, 0x1a131f12, 0x17181824, 0x1e18101b, 0x29161d1f, 0x3c102a16, + 0x3c0e340f, 0x7bf04e03, 0x38163515, 0x21153d19, 0x3d113213, 0x4af84efd, + 0x48f648f7, 0x47f44bee, 0x46fb3ff5, 0x48f24bef, 0x35f843f0, 0x34f73bf2, + 0xfe0944f5, 0xfc1ff61e, 0x0721ff21, 0x17250c1f, 0x4014261f, 0x25f947f7, + 0x31f52cf8, 0x3bf438f6, 0x43f73ff8, 0x4ff644fa, 0x4af84efd, 0x48f648f7, + 0x47f44bee, 0x46fb3ff5, 0x48f24bef, 0x35f843f0, 0x34f73bf2, 0xfe0944f5, + 0xfc1ff61e, 0x0721ff21, 0x17250c1f, 0x4014261f, 0x00000000, 0x00000000, + 0x3602f114, 0xf1144a03, 0x4a033602, 0x68e97fe4, 0x36ff35fa, 0x00003307, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x3f002900, 0x3f003f00, 0x560453f7, 0x48f96100, 0x3e03290d, 0x37010b00, + 0x7fef4500, 0x520066f3, 0x6beb4af9, 0x7fe17fe5, 0x5fee7fe8, 0x72eb7fe5, + 0x7bef7fe2, 0x7af073f4, 0x3ff473f5, 0x54f144fe, 0x46fd68f3, 0x5af65df8, + 0x4aff7fe2, 0x5bf961fa, 0x38fc7fec, 0x4cf952fb, 0x5df97dea, 0x4dfd57f5, + 0x3ffc47fb, 0x54f444fc, 0x41f93ef9, 0x38053d08, 0x400142fe, 0x4efe3d00, + 0x34073201, 0x2c00230a, 0x2d01260b, 0x2c052e00, 0x3301111f, 0x131c3207, + 0x3e0e2110, 0x64f16cf3, 0x5bf365f3, 0x58f65ef4, 0x56f654f0, 0x57f353f9, + 0x46015eed, 0x4afb4800, 0x66f83b12, 0x5f0064f1, 0x48024bfc, 0x47fd4bf5, + 0x45f32e0f, 0x41003e00, 0x48f12515, 0x36103909, 0x480c3e00, 0x090f0018, + 0x120d1908, 0x130d090f, 0x120c250a, 0x21141d06, 0x2d041e0f, 0x3e003a01, + 0x260c3d07, 0x270f2d0b, 0x2c0d2a0b, 0x290c2d10, 0x221e310a, 0x370a2a12, + 0x2e113311, 0xed1a5900, 0xef1aef16, 0xec1ce71e, 0xe525e921, 0xe428e921, + 0xf521ef26, 0xfa29f128, 0x11290126, 0x031bfa1e, 0xf025161a, 0xf826fc23, + 0x0325fd26, 0x002a0526, 0x16271023, 0x251b300e, 0x440c3c15, 0x47fd6102, + 0x32fb2afa, 0x3efe36fd, 0x3f013a00, 0x4aff48fe, 0x43fb5bf7, 0x27fd1bfb, + 0x2e002cfe, 0x44f840f0, 0x4dfa4ef6, 0x5cf456f6, 0x3cf637f1, 0x41fc3efa, + 0x4cf849f4, 0x58f750f9, 0x61f56eef, 0x4ff554ec, 0x4afc49fa, 0x60f356f3, + 0x75ed61f5, 0x21fb4ef8, 0x35fe30fc, 0x47f33efd, 0x56f44ff6, 0x61f25af3, + 0x5dfa0000, 0x4ff854fa, 0x47ff4200, 0x3cfe3e00, 0x4bfb3bfe, 0x3afc3efd, + 0x4fff42f7, 0x44034700, 0x3ef92c0a, 0x280e240f, 0x1d0c1b10, 0x24142c01, + 0x2a052012, 0x3e0a3001, 0x40092e11, 0x61f568f4, 0x58f960f0, 0x55f955f8, + 0x58f355f7, 0x4dfd4204, 0x4cfa4cfd, 0x4cff3a0a, 0x63f953ff, 0x5f025ff2, + 0x4afb4c00, 0x4bf54600, 0x41004401, 0x3e0349f2, 0x44ff3e04, 0x370b4bf3, + 0x460c4005, 0x1306060f, 0x0e0c1007, 0x0b0d0d12, 0x100f0f0d, 0x170d170c, + 0x1a0e140f, 0x28112c0e, 0x11182f11, 0x16191515, 0x1d161b1f, 0x320e2313, + 0x3f07390a, 0x52fc4dfe, 0x45095efd, 0xdd246df4, 0xe620de24, 0xe02ce225, + 0xf122ee22, 0xf921f128, 0x0021fb23, 0x0d210226, 0x3a0d2317, 0x001afd1d, + 0xf91f1e16, 0xfd22f123, 0xff240322, 0x0b200522, 0x0c220523, 0x1d1e0b27, + 0x271d1a22, 0x151f4213, 0x32191f1f, 0x70ec78ef, 0x55f572ee, 0x59f25cf1, + 0x51f147e6, 0x440050f2, 0x38e846f2, 0x32e844e9, 0xf3174af5, 0xf128f31a, + 0x032cf231, 0x222c062d, 0x52133621, 0x17ff4bfd, 0x2b012201, 0x37fe3600, + 0x40013d00, 0x5cf74400, 0x61f36af2, 0x5af45af1, 0x49f658ee, 0x56f24ff7, + 0x46f649f6, 0x42fb45f6, 0x3afb40f7, 0xf6153b02, 0xf81cf518, 0x031dff1c, + 0x1423091d, 0x430e241d, +}; + + + +static RK_U32 rkv_ver_align(RK_U32 val) +{ + return MPP_ALIGN(val, 16); +} + +static RK_U32 rkv_hor_align(RK_U32 val) +{ + return MPP_ALIGN(val, 16); +} + +static RK_U32 rkv_len_align(RK_U32 val) +{ + return (2 * MPP_ALIGN(val, 16)); +} + +static RK_U32 rkv_len_align_422(RK_U32 val) +{ + return ((5 * MPP_ALIGN(val, 16)) / 2); +} + + +static void rkv_h264d_hal_dump(H264dHalCtx_t *p_hal, RK_U32 dump_type) +{ + if (rkv_h264d_hal_debug & H264D_DBG_ERR_DUMP) { + RK_U32 i = 0; + RK_U32 *p_hal_regs = NULL; + H264dRkvErrDump_t *p_dump = (H264dRkvErrDump_t *)p_hal->dump; + switch (dump_type) { + case H264D_DBG_GEN_REGS: + p_hal_regs = (RK_U32 *)p_dump->in_regs; + mpp_log("------- register input ------ \n"); + for (i = 0; i < DEC_RKV_REGISTERS; i++) { + mpp_log("reg[%d]=%08x", i, p_hal_regs[i]); + } + break; + case H264D_DBG_RET_REGS: + p_hal_regs = (RK_U32 *)p_dump->out_regs; + mpp_log("------- register output ------ \n"); + for (i = 0; i < DEC_RKV_REGISTERS; i++) { + mpp_log("reg[%d]=%08x", i, p_hal_regs[i]); + } + break; + + default: + break; + } + } +} + +/*! +*********************************************************************** +* \brief +* init +*********************************************************************** +*/ +//extern "C" +MPP_RET rkv_h264d_init(void *hal, MppHalCfg *cfg) +{ + RK_U32 cabac_size = 0; + MPP_RET ret = MPP_ERR_UNKNOW; + H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal; + + INP_CHECK(ret, NULL == p_hal); + FunctionIn(p_hal->logctx.parr[RUN_HAL]); + p_hal->iDecodedNum = 0; + MEM_CHECK(ret, p_hal->pkts = mpp_calloc_size(void, sizeof(H264dRkvPkt_t))); + MEM_CHECK(ret, p_hal->dump = mpp_malloc_size(void, sizeof(H264dRkvErrDump_t))); + //!< malloc cabac+scanlis + packets + poc_buf + cabac_size = RKV_CABAC_TAB_SIZE + RKV_SPSPPS_SIZE + RKV_RPS_SIZE + RKV_SCALING_LIST_SIZE + RKV_ERROR_INFO_SIZE; + FUN_CHECK(ret = mpp_buffer_get(p_hal->buf_group, &p_hal->cabac_buf, cabac_size)); + //!< copy cabac table bytes + FUN_CHECK(ret = mpp_buffer_write(p_hal->cabac_buf, 0, (void *)H264_RKV_Cabac_table, sizeof(H264_RKV_Cabac_table))); + FUN_CHECK(ret = rkv_alloc_fifo_packet(&p_hal->logctx, (H264dRkvPkt_t *)p_hal->pkts)); + p_hal->regs = (void *)((H264dRkvPkt_t *)p_hal->pkts)->reg.pbuf; + + mpp_slots_set_prop(p_hal->frame_slots, SLOTS_HOR_ALIGN, rkv_hor_align); + mpp_slots_set_prop(p_hal->frame_slots, SLOTS_VER_ALIGN, rkv_ver_align); + mpp_slots_set_prop(p_hal->frame_slots, SLOTS_LEN_ALIGN, rkv_len_align); + + FunctionOut(p_hal->logctx.parr[RUN_HAL]); + (void)cfg; +__RETURN: + return MPP_OK; +__FAILED: + rkv_h264d_deinit(hal); + + return ret; +} +/*! +*********************************************************************** +* \brief +* deinit +*********************************************************************** +*/ +//extern "C" +MPP_RET rkv_h264d_deinit(void *hal) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal; + + INP_CHECK(ret, NULL == p_hal); + FunctionIn(p_hal->logctx.parr[RUN_HAL]); + + rkv_free_fifo_packet((H264dRkvPkt_t *)p_hal->pkts); + MPP_FREE(p_hal->dump); + MPP_FREE(p_hal->pkts); + if (p_hal->cabac_buf) { + FUN_CHECK(ret = mpp_buffer_put(p_hal->cabac_buf)); + } + + FunctionOut(p_hal->logctx.parr[RUN_HAL]); +__RETURN: + return ret = MPP_OK; +__FAILED: + return ret; +} +/*! +*********************************************************************** +* \brief +* generate register +*********************************************************************** +*/ +//extern "C" +MPP_RET rkv_h264d_gen_regs(void *hal, HalTaskInfo *task) +{ + RK_U32 i = 0; + RK_U32 hw_base = 0; + RK_U32 strm_offset = 0; + MPP_RET ret = MPP_ERR_UNKNOW; + H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal; + H264dRkvPkt_t *pkts = (H264dRkvPkt_t *)p_hal->pkts; + H264dRkvRegs_t *p_regs = (H264dRkvRegs_t *)p_hal->regs; + + INP_CHECK(ret, NULL == p_hal); + FunctionIn(p_hal->logctx.parr[RUN_HAL]); + if (task->dec.flags.had_error) { + goto __RETURN; + } + rkv_prepare_spspps_packet(hal, &pkts->spspps); + rkv_prepare_framerps_packet(hal, &pkts->rps); + rkv_prepare_scanlist_packet(hal, &pkts->scanlist); + rkv_generate_regs(p_hal, task, &pkts->reg); + + hw_base = mpp_buffer_get_fd(p_hal->cabac_buf); + //!< copy datas + strm_offset = RKV_CABAC_TAB_SIZE; + for (i = 0; i < 256; i++) { + mpp_buffer_write(p_hal->cabac_buf, (strm_offset + 32 * i), (void *)pkts->spspps.pbuf, RKV_SPSPPS_SIZE); + } + p_regs->swreg42_pps_base.sw_pps_base = hw_base + (strm_offset << 10); + strm_offset += RKV_SPSPPS_SIZE; + + mpp_buffer_write(p_hal->cabac_buf, strm_offset, (void *)pkts->rps.pbuf, RKV_RPS_SIZE); + p_regs->swreg43_rps_base.sw_rps_base = hw_base + (strm_offset << 10); + + strm_offset += RKV_RPS_SIZE; + mpp_buffer_write(p_hal->cabac_buf, strm_offset, (void *)pkts->scanlist.pbuf, RKV_SCALING_LIST_SIZE); + + strm_offset += RKV_SCALING_LIST_SIZE; + p_regs->swreg75_h264_errorinfo_base.sw_errorinfo_base = hw_base + (strm_offset << 10); + + + ((HalDecTask*)&task->dec)->valid = 0; + FunctionOut(p_hal->logctx.parr[RUN_HAL]); + +__RETURN: + return ret = MPP_OK; +} +/*! +*********************************************************************** +* \brief h +* start hard +*********************************************************************** +*/ +//extern "C" +MPP_RET rkv_h264d_start(void *hal, HalTaskInfo *task) +{ + RK_U32 *p_regs = NULL; + MPP_RET ret = MPP_ERR_UNKNOW; + H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal; + + INP_CHECK(ret, NULL == p_hal); + FunctionIn(p_hal->logctx.parr[RUN_HAL]); + if (task->dec.flags.had_error) { + goto __RETURN; + } + p_regs = (RK_U32 *)p_hal->regs; + + p_regs[64] = 0; + p_regs[65] = 0; + p_regs[66] = 0; + p_regs[67] = 0x000000ff; // disable fpga reset + p_regs[44] = 0xffffffff; // 0xffff_ffff, debug enable + p_regs[77] = 0xffffffff; // 0xffff_dfff, debug enable + + p_regs[1] |= 0x00000061; // run hardware, enable buf_empty_en + //!< dump input register + { + H264dRkvErrDump_t *p_dump = (H264dRkvErrDump_t *)p_hal->dump; + memcpy(p_dump->in_regs, p_regs, DEC_RKV_REGISTERS); + if (rkv_h264d_hal_debug & H264D_DBG_GEN_REGS) { + rkv_h264d_hal_dump(p_hal, H264D_DBG_GEN_REGS); + } + } + //!< current buffer slot fd + H264D_DBG(H264D_DBG_DECOUT_INFO, "[DECOUT_INFO] decout_fd=0x%02x", p_regs[7]); +#ifdef RKPLATFORM + if (VPUClientSendReg(p_hal->vpu_socket, (RK_U32 *)p_regs, DEC_RKV_REGISTERS)) { + ret = MPP_ERR_VPUHW; + H264D_ERR("H264 RKV FlushRegs fail. \n"); + } +#endif + FunctionOut(p_hal->logctx.parr[RUN_HAL]); + (void)task; +__RETURN: + return ret = MPP_OK; +} +/*! +*********************************************************************** +* \brief +* wait hard +*********************************************************************** +*/ +//extern "C" +MPP_RET rkv_h264d_wait(void *hal, HalTaskInfo *task) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + H264dRkvRegs_t *p_regs = NULL; + H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal; + + INP_CHECK(ret, NULL == p_hal); + FunctionIn(p_hal->logctx.parr[RUN_HAL]); + + p_regs = (H264dRkvRegs_t *)p_hal->regs; + if (task->dec.flags.had_error) { + goto __SKIP_HARD; + } +#ifdef RKPLATFORM + RK_S32 wait_ret = -1; + RK_S32 ret_len = 0, cur_deat = 0; + VPU_CMD_TYPE ret_cmd = VPU_CMD_BUTT; + RK_S64 p_s, p_e; + p_s = mpp_time(); + wait_ret = VPUClientWaitResult(p_hal->vpu_socket, (RK_U32 *)p_hal->regs, DEC_RKV_REGISTERS, &ret_cmd, &ret_len); + p_e = mpp_time(); + cur_deat = (p_e - p_s) / 1000; + p_hal->total_time += cur_deat; + p_hal->iDecodedNum++; + (void)wait_ret; +#endif + //!< dump registers + { + H264dRkvErrDump_t *p_dump = (H264dRkvErrDump_t *)p_hal->dump; + p_dump->out_regs = (RK_U32 *)p_regs; + if (rkv_h264d_hal_debug & H264D_DBG_RET_REGS) { + rkv_h264d_hal_dump(p_hal, H264D_DBG_RET_REGS); + } + if (p_regs->swreg1_int.sw_dec_error_sta) { + rkv_h264d_hal_dump(p_hal, H264D_DBG_GEN_REGS); + rkv_h264d_hal_dump(p_hal, H264D_DBG_RET_REGS); + } + } +__SKIP_HARD: + if (p_hal->init_cb.callBack) { + IOCallbackCtx m_ctx = { 0 }; + m_ctx.device_id = HAL_RKVDEC; + if (p_regs->swreg1_int.sw_dec_error_sta + || (!p_regs->swreg1_int.sw_dec_rdy_sta) + || p_regs->swreg1_int.sw_dec_empty_sta + || p_regs->swreg45_strmd_error_status.sw_strmd_error_status + || p_regs->swreg45_strmd_error_status.sw_colmv_error_ref_picidx + || p_regs->swreg76_h264_errorinfo_num.sw_strmd_detect_error_flag) { + m_ctx.hard_err = 1; + } + m_ctx.task = (void *)&task->dec; + m_ctx.regs = (RK_U32 *)p_hal->regs; + p_hal->init_cb.callBack(p_hal->init_cb.opaque, &m_ctx); + } + memset(&p_regs->swreg1_int, 0, sizeof(RK_U32)); + + FunctionOut(p_hal->logctx.parr[RUN_HAL]); + (void)task; +__RETURN: + return ret = MPP_OK; +} +/*! +*********************************************************************** +* \brief +* reset +*********************************************************************** +*/ +//extern "C" +MPP_RET rkv_h264d_reset(void *hal) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal; + + INP_CHECK(ret, NULL == p_hal); + FunctionIn(p_hal->logctx.parr[RUN_HAL]); + + memset(p_hal->regs, 0, sizeof(H264dRkvRegs_t)); + rkv_reset_fifo_packet((H264dRkvPkt_t *)p_hal->pkts); + + FunctionOut(p_hal->logctx.parr[RUN_HAL]); +__RETURN: + return ret = MPP_OK; +} +/*! +*********************************************************************** +* \brief +* flush +*********************************************************************** +*/ +//extern "C" +MPP_RET rkv_h264d_flush(void *hal) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal; + + INP_CHECK(ret, NULL == p_hal); + FunctionIn(p_hal->logctx.parr[RUN_HAL]); + + + + + + FunctionOut(p_hal->logctx.parr[RUN_HAL]); +__RETURN: + return ret = MPP_OK; +} +/*! +*********************************************************************** +* \brief +* control +*********************************************************************** +*/ +//extern "C" +MPP_RET rkv_h264d_control(void *hal, RK_S32 cmd_type, void *param) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal; + + INP_CHECK(ret, NULL == p_hal); + FunctionIn(p_hal->logctx.parr[RUN_HAL]); + switch ((MpiCmd)cmd_type) { + case MPP_DEC_SET_FRAME_INFO: { + VPU_GENERIC *p = (VPU_GENERIC *)param; + if (p->CodecType == MPP_FMT_YUV422SP) { + mpp_slots_set_prop(p_hal->frame_slots, SLOTS_LEN_ALIGN, rkv_len_align_422); + mpp_log_f("control format YUV422SP \n"); + } + break; + } + + default: + break; + } + + FunctionOut(p_hal->logctx.parr[RUN_HAL]); + (void)hal; + (void)cmd_type; + (void)param; +__RETURN: + return ret = MPP_OK; +} diff --git a/mpp/hal/rkdec/h264d/hal_h264d_rkv_reg.h b/mpp/hal/rkdec/h264d/hal_h264d_rkv_reg.h index 0b4a0672..7f0b7577 100644 --- a/mpp/hal/rkdec/h264d/hal_h264d_rkv_reg.h +++ b/mpp/hal/rkdec/h264d/hal_h264d_rkv_reg.h @@ -1,251 +1,251 @@ -/* -* -* Copyright 2015 Rockchip Electronics Co. LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - - -#ifndef __HAL_H264D_RKV_REG_H__ -#define __HAL_H264D_RKV_REG_H__ - -#include "mpp_hal.h" - -typedef struct h264d_rkv_regs_t { - struct { - RK_U32 minor_ver : 8; - RK_U32 level : 1; - RK_U32 dec_support : 3; - RK_U32 profile : 1; - RK_U32 reserve0 : 1; - RK_U32 codec_flag : 1; - RK_U32 reserve1 : 1; - RK_U32 prod_num : 16; - } swreg0_id; - struct { - RK_U32 sw_dec_e : 1;//0 - RK_U32 sw_dec_clkgate_e : 1; // 1 - RK_U32 reserve0 : 1;// 2 - RK_U32 sw_timeout_mode : 1; // 3 - RK_U32 sw_dec_irq_dis : 1;//4 // 4 - RK_U32 sw_dec_timeout_e : 1; //5 - RK_U32 sw_buf_empty_en : 1; // 6 - RK_U32 sw_stmerror_waitdecfifo_empty : 1; // 7 - RK_U32 sw_dec_irq : 1; // 8 - RK_U32 sw_dec_irq_raw : 1; // 9 - RK_U32 reserve2 : 2; - RK_U32 sw_dec_rdy_sta : 1; //12 - RK_U32 sw_dec_bus_sta : 1; //13 - RK_U32 sw_dec_error_sta : 1; // 14 - RK_U32 sw_dec_timeout_sta : 1; //15 - RK_U32 sw_dec_empty_sta : 1; // 16 - RK_U32 sw_colmv_ref_error_sta : 1; // 17 - RK_U32 sw_cabu_end_sta : 1; // 18 - RK_U32 sw_h264orvp9_error_mode : 1; //19 - RK_U32 sw_softrst_en_p : 1; //20 - RK_U32 sw_force_softreset_valid : 1; //21 - RK_U32 sw_softreset_rdy : 1; // 22 - } swreg1_int; - struct { - RK_U32 sw_in_endian : 1; - RK_U32 sw_in_swap32_e : 1; - RK_U32 sw_in_swap64_e : 1; - RK_U32 sw_str_endian : 1; - RK_U32 sw_str_swap32_e : 1; - RK_U32 sw_str_swap64_e : 1; - RK_U32 sw_out_endian : 1; - RK_U32 sw_out_swap32_e : 1; - RK_U32 sw_out_cbcr_swap : 1; - RK_U32 reserve0 : 1; - RK_U32 sw_rlc_mode_direct_write : 1; - RK_U32 sw_rlc_mode : 1; - RK_U32 sw_strm_start_bit : 7; - RK_U32 reserve1 : 1; - RK_U32 sw_dec_mode : 2; - RK_U32 reserve2 : 2; - RK_U32 sw_h264_rps_mode : 1; - RK_U32 sw_h264_stream_mode : 1; - RK_U32 sw_h264_stream_lastpacket : 1; - RK_U32 sw_h264_firstslice_flag : 1; - RK_U32 sw_h264_frame_orslice : 1; - RK_U32 sw_buspr_slot_disable : 1; - } swreg2_sysctrl; - struct { - RK_U32 sw_y_hor_virstride : 9; - RK_U32 reserve : 2; - RK_U32 sw_slice_num_highbit : 1; - RK_U32 sw_uv_hor_virstride : 9; - RK_U32 sw_slice_num_lowbits : 11; - } swreg3_picpar; - struct { - RK_U32 sw_strm_rlc_base; - } swreg4_strm_rlc_base; - struct { - RK_U32 sw_stream_len : 27; - } swreg5_stream_rlc_len; - struct { - RK_U32 sw_cabactbl_base; - } swreg6_cabactbl_prob_base; - struct { - RK_U32 sw_decout_base; - } swreg7_decout_base; - struct { - RK_U32 sw_y_virstride : 20; - } swreg8_y_virstride; - struct { - RK_U32 sw_yuv_virstride : 21; - } swreg9_yuv_virstride; - struct { - RK_U32 sw_refer_base : 10; - RK_U32 sw_ref_field : 1; - RK_U32 sw_ref_topfield_used : 1; - RK_U32 sw_ref_botfield_used : 1; - RK_U32 sw_ref_colmv_use_flag : 1; - - } swreg10_24_refer0_14_base[15]; - RK_U32 swreg25_39_refer0_14_poc[15]; - struct { - RK_U32 sw_cur_poc : 32; - } swreg40_cur_poc; - struct { - RK_U32 sw_rlcwrite_base; - } swreg41_rlcwrite_base; - struct { - RK_U32 sw_pps_base; - } swreg42_pps_base; - struct swreg_sw_rps_base { - RK_U32 sw_rps_base; - } swreg43_rps_base; - struct swreg_strmd_error_e { - RK_U32 sw_strmd_error_e : 28; - RK_U32 reserve : 4; - } swreg44_strmd_error_en; - struct { - RK_U32 sw_strmd_error_status : 28; - RK_U32 sw_colmv_error_ref_picidx : 4; - } swreg45_strmd_error_status; - struct { - RK_U32 sw_strmd_error_ctu_xoffset : 8; - RK_U32 sw_strmd_error_ctu_yoffset : 8; - RK_U32 sw_streamfifo_space2full : 7; - RK_U32 reserve : 1; - RK_U32 sw_vp9_error_ctu0_en : 1; - } swreg46_strmd_error_ctu; - struct { - RK_U32 sw_saowr_xoffet : 9; - RK_U32 reserve : 7; - RK_U32 sw_saowr_yoffset : 10; - } swreg47_sao_ctu_position; - struct { - RK_U32 sw_refer_base : 10; - RK_U32 sw_ref_field : 1; - RK_U32 sw_ref_topfield_used : 1; - RK_U32 sw_ref_botfield_used : 1; - RK_U32 sw_ref_colmv_use_flag : 1; - - } swreg48_refer15_base; - RK_U32 swreg49_63_refer15_29_poc[15]; - struct { - RK_U32 sw_performance_cycle : 32; - } swreg64_performance_cycle; - struct { - RK_U32 sw_axi_ddr_rdata : 32; - } swreg65_axi_ddr_rdata; - struct { - RK_U32 sw_axi_ddr_rdata : 32; - } swreg66_axi_ddr_wdata; - struct { - RK_U32 sw_busifd_resetn : 1; - RK_U32 sw_cabac_resetn : 1; - RK_U32 sw_dec_ctrl_resetn : 1; - RK_U32 sw_transd_resetn : 1; - RK_U32 sw_intra_resetn : 1; - RK_U32 sw_inter_resetn : 1; - RK_U32 sw_recon_resetn : 1; - RK_U32 sw_filer_resetn : 1; - } swreg67_fpgadebug_reset; - struct { - RK_U32 perf_cnt0_sel : 6; - RK_U32 reserve0 : 2; - RK_U32 perf_cnt1_sel : 6; - RK_U32 reserve1 : 2; - RK_U32 perf_cnt2_sel : 6; - } swreg68_performance_sel; - struct { - RK_U32 perf_cnt0 : 32; - } swreg69_performance_cnt0; - struct { - RK_U32 perf_cnt1 : 32; - } swreg70_performance_cnt1; - struct { - RK_U32 perf_cnt2 : 32; - } swreg71_performance_cnt2; - RK_U32 swreg72_refer30_poc; - RK_U32 swreg73_refer31_poc; - struct { - RK_U32 sw_h264_cur_poc1 : 32; - } swreg74_h264_cur_poc1; - struct { - //RK_U32 reserve : 4; - //RK_U32 sw_errorinfo_base : 28; - RK_U32 sw_errorinfo_base : 32; - } swreg75_h264_errorinfo_base; - struct { - RK_U32 sw_slicedec_num : 14; - RK_U32 reserve : 1; - RK_U32 sw_strmd_detect_error_flag : 1; - RK_U32 sw_error_packet_num : 14; - } swreg76_h264_errorinfo_num; - struct { - RK_U32 sw_h264_error_en_highbits : 30; - RK_U32 reserve : 2; - } swreg77_h264_error_e; - RK_U32 slot_idx; - RK_U32 had_err_flag; - RK_U32 used_for_ref; - RK_U32 compare_len; - RK_U32 reverse[100]; -} H264dRkvRegs_t; - - -/* Number registers for the decoder */ -#define DEC_RKV_REGISTERS 78 - -typedef struct h264d_rkv_err_dump_t { - RK_U32 in_regs[DEC_RKV_REGISTERS]; - RK_U32 *out_regs; - -} H264dRkvErrDump_t; - - - -#ifdef __cplusplus -extern "C" { -#endif - -extern const RK_U32 H264_RKV_Cabac_table[926 * 4]; - -MPP_RET rkv_h264d_init (void *hal, MppHalCfg *cfg); -MPP_RET rkv_h264d_deinit (void *hal); -MPP_RET rkv_h264d_gen_regs(void *hal, HalTaskInfo *task); -MPP_RET rkv_h264d_start (void *hal, HalTaskInfo *task); -MPP_RET rkv_h264d_wait (void *hal, HalTaskInfo *task); -MPP_RET rkv_h264d_reset (void *hal); -MPP_RET rkv_h264d_flush (void *hal); -MPP_RET rkv_h264d_control (void *hal, RK_S32 cmd_type, void *param); - -#ifdef __cplusplus -} -#endif - -#endif /* __HAL_H264D_RKV_REG_H__ */ +/* +* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +#ifndef __HAL_H264D_RKV_REG_H__ +#define __HAL_H264D_RKV_REG_H__ + +#include "mpp_hal.h" + +typedef struct h264d_rkv_regs_t { + struct { + RK_U32 minor_ver : 8; + RK_U32 level : 1; + RK_U32 dec_support : 3; + RK_U32 profile : 1; + RK_U32 reserve0 : 1; + RK_U32 codec_flag : 1; + RK_U32 reserve1 : 1; + RK_U32 prod_num : 16; + } swreg0_id; + struct { + RK_U32 sw_dec_e : 1;//0 + RK_U32 sw_dec_clkgate_e : 1; // 1 + RK_U32 reserve0 : 1;// 2 + RK_U32 sw_timeout_mode : 1; // 3 + RK_U32 sw_dec_irq_dis : 1;//4 // 4 + RK_U32 sw_dec_timeout_e : 1; //5 + RK_U32 sw_buf_empty_en : 1; // 6 + RK_U32 sw_stmerror_waitdecfifo_empty : 1; // 7 + RK_U32 sw_dec_irq : 1; // 8 + RK_U32 sw_dec_irq_raw : 1; // 9 + RK_U32 reserve2 : 2; + RK_U32 sw_dec_rdy_sta : 1; //12 + RK_U32 sw_dec_bus_sta : 1; //13 + RK_U32 sw_dec_error_sta : 1; // 14 + RK_U32 sw_dec_timeout_sta : 1; //15 + RK_U32 sw_dec_empty_sta : 1; // 16 + RK_U32 sw_colmv_ref_error_sta : 1; // 17 + RK_U32 sw_cabu_end_sta : 1; // 18 + RK_U32 sw_h264orvp9_error_mode : 1; //19 + RK_U32 sw_softrst_en_p : 1; //20 + RK_U32 sw_force_softreset_valid : 1; //21 + RK_U32 sw_softreset_rdy : 1; // 22 + } swreg1_int; + struct { + RK_U32 sw_in_endian : 1; + RK_U32 sw_in_swap32_e : 1; + RK_U32 sw_in_swap64_e : 1; + RK_U32 sw_str_endian : 1; + RK_U32 sw_str_swap32_e : 1; + RK_U32 sw_str_swap64_e : 1; + RK_U32 sw_out_endian : 1; + RK_U32 sw_out_swap32_e : 1; + RK_U32 sw_out_cbcr_swap : 1; + RK_U32 reserve0 : 1; + RK_U32 sw_rlc_mode_direct_write : 1; + RK_U32 sw_rlc_mode : 1; + RK_U32 sw_strm_start_bit : 7; + RK_U32 reserve1 : 1; + RK_U32 sw_dec_mode : 2; + RK_U32 reserve2 : 2; + RK_U32 sw_h264_rps_mode : 1; + RK_U32 sw_h264_stream_mode : 1; + RK_U32 sw_h264_stream_lastpacket : 1; + RK_U32 sw_h264_firstslice_flag : 1; + RK_U32 sw_h264_frame_orslice : 1; + RK_U32 sw_buspr_slot_disable : 1; + } swreg2_sysctrl; + struct { + RK_U32 sw_y_hor_virstride : 9; + RK_U32 reserve : 2; + RK_U32 sw_slice_num_highbit : 1; + RK_U32 sw_uv_hor_virstride : 9; + RK_U32 sw_slice_num_lowbits : 11; + } swreg3_picpar; + struct { + RK_U32 sw_strm_rlc_base; + } swreg4_strm_rlc_base; + struct { + RK_U32 sw_stream_len : 27; + } swreg5_stream_rlc_len; + struct { + RK_U32 sw_cabactbl_base; + } swreg6_cabactbl_prob_base; + struct { + RK_U32 sw_decout_base; + } swreg7_decout_base; + struct { + RK_U32 sw_y_virstride : 20; + } swreg8_y_virstride; + struct { + RK_U32 sw_yuv_virstride : 21; + } swreg9_yuv_virstride; + struct { + RK_U32 sw_refer_base : 10; + RK_U32 sw_ref_field : 1; + RK_U32 sw_ref_topfield_used : 1; + RK_U32 sw_ref_botfield_used : 1; + RK_U32 sw_ref_colmv_use_flag : 1; + + } swreg10_24_refer0_14_base[15]; + RK_U32 swreg25_39_refer0_14_poc[15]; + struct { + RK_U32 sw_cur_poc : 32; + } swreg40_cur_poc; + struct { + RK_U32 sw_rlcwrite_base; + } swreg41_rlcwrite_base; + struct { + RK_U32 sw_pps_base; + } swreg42_pps_base; + struct swreg_sw_rps_base { + RK_U32 sw_rps_base; + } swreg43_rps_base; + struct swreg_strmd_error_e { + RK_U32 sw_strmd_error_e : 28; + RK_U32 reserve : 4; + } swreg44_strmd_error_en; + struct { + RK_U32 sw_strmd_error_status : 28; + RK_U32 sw_colmv_error_ref_picidx : 4; + } swreg45_strmd_error_status; + struct { + RK_U32 sw_strmd_error_ctu_xoffset : 8; + RK_U32 sw_strmd_error_ctu_yoffset : 8; + RK_U32 sw_streamfifo_space2full : 7; + RK_U32 reserve : 1; + RK_U32 sw_vp9_error_ctu0_en : 1; + } swreg46_strmd_error_ctu; + struct { + RK_U32 sw_saowr_xoffet : 9; + RK_U32 reserve : 7; + RK_U32 sw_saowr_yoffset : 10; + } swreg47_sao_ctu_position; + struct { + RK_U32 sw_refer_base : 10; + RK_U32 sw_ref_field : 1; + RK_U32 sw_ref_topfield_used : 1; + RK_U32 sw_ref_botfield_used : 1; + RK_U32 sw_ref_colmv_use_flag : 1; + + } swreg48_refer15_base; + RK_U32 swreg49_63_refer15_29_poc[15]; + struct { + RK_U32 sw_performance_cycle : 32; + } swreg64_performance_cycle; + struct { + RK_U32 sw_axi_ddr_rdata : 32; + } swreg65_axi_ddr_rdata; + struct { + RK_U32 sw_axi_ddr_rdata : 32; + } swreg66_axi_ddr_wdata; + struct { + RK_U32 sw_busifd_resetn : 1; + RK_U32 sw_cabac_resetn : 1; + RK_U32 sw_dec_ctrl_resetn : 1; + RK_U32 sw_transd_resetn : 1; + RK_U32 sw_intra_resetn : 1; + RK_U32 sw_inter_resetn : 1; + RK_U32 sw_recon_resetn : 1; + RK_U32 sw_filer_resetn : 1; + } swreg67_fpgadebug_reset; + struct { + RK_U32 perf_cnt0_sel : 6; + RK_U32 reserve0 : 2; + RK_U32 perf_cnt1_sel : 6; + RK_U32 reserve1 : 2; + RK_U32 perf_cnt2_sel : 6; + } swreg68_performance_sel; + struct { + RK_U32 perf_cnt0 : 32; + } swreg69_performance_cnt0; + struct { + RK_U32 perf_cnt1 : 32; + } swreg70_performance_cnt1; + struct { + RK_U32 perf_cnt2 : 32; + } swreg71_performance_cnt2; + RK_U32 swreg72_refer30_poc; + RK_U32 swreg73_refer31_poc; + struct { + RK_U32 sw_h264_cur_poc1 : 32; + } swreg74_h264_cur_poc1; + struct { + //RK_U32 reserve : 4; + //RK_U32 sw_errorinfo_base : 28; + RK_U32 sw_errorinfo_base : 32; + } swreg75_h264_errorinfo_base; + struct { + RK_U32 sw_slicedec_num : 14; + RK_U32 reserve : 1; + RK_U32 sw_strmd_detect_error_flag : 1; + RK_U32 sw_error_packet_num : 14; + } swreg76_h264_errorinfo_num; + struct { + RK_U32 sw_h264_error_en_highbits : 30; + RK_U32 reserve : 2; + } swreg77_h264_error_e; + RK_U32 slot_idx; + RK_U32 had_err_flag; + RK_U32 used_for_ref; + RK_U32 compare_len; + RK_U32 reverse[100]; +} H264dRkvRegs_t; + + +/* Number registers for the decoder */ +#define DEC_RKV_REGISTERS 78 + +typedef struct h264d_rkv_err_dump_t { + RK_U32 in_regs[DEC_RKV_REGISTERS]; + RK_U32 *out_regs; + +} H264dRkvErrDump_t; + + + +#ifdef __cplusplus +extern "C" { +#endif + +extern const RK_U32 H264_RKV_Cabac_table[926 * 4]; + +MPP_RET rkv_h264d_init (void *hal, MppHalCfg *cfg); +MPP_RET rkv_h264d_deinit (void *hal); +MPP_RET rkv_h264d_gen_regs(void *hal, HalTaskInfo *task); +MPP_RET rkv_h264d_start (void *hal, HalTaskInfo *task); +MPP_RET rkv_h264d_wait (void *hal, HalTaskInfo *task); +MPP_RET rkv_h264d_reset (void *hal); +MPP_RET rkv_h264d_flush (void *hal); +MPP_RET rkv_h264d_control (void *hal, RK_S32 cmd_type, void *param); + +#ifdef __cplusplus +} +#endif + +#endif /* __HAL_H264D_RKV_REG_H__ */ diff --git a/mpp/hal/rkdec/h264d/hal_h264d_vdpu_pkt.c b/mpp/hal/rkdec/h264d/hal_h264d_vdpu_pkt.c index ce2a9208..9abfbc1f 100644 --- a/mpp/hal/rkdec/h264d/hal_h264d_vdpu_pkt.c +++ b/mpp/hal/rkdec/h264d/hal_h264d_vdpu_pkt.c @@ -1,823 +1,823 @@ - -/* - * Copyright 2010 Rockchip Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define MODULE_TAG "hal_h264d_vdpu_pkt" - -#include -#include - -#include "mpp_mem.h" -#include "hal_task.h" - -#include "dxva_syntax.h" -#include "vpu.h" - -#include "h264d_log.h" -#include "h264d_syntax.h" -#include "hal_h264d_fifo.h" -#include "hal_h264d_api.h" -#include "hal_h264d_global.h" -#include "hal_h264d_vdpu_pkt.h" -#include "hal_h264d_vdpu_reg.h" - - -const RK_U32 H264_VDPU_Cabac_table[VDPU_CABAC_TAB_SIZE / 4] = { - 0x14f10236, 0x034a14f1, 0x0236034a, 0xe47fe968, 0xfa35ff36, 0x07330000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x0029003f, 0x003f003f, 0xf7530456, 0x0061f948, 0x0d29033e, 0x000b0137, - 0x0045ef7f, 0xf3660052, 0xf94aeb6b, 0xe57fe17f, 0xe87fee5f, 0xe57feb72, - 0xe27fef7b, 0xf473f07a, 0xf573f43f, 0xfe44f154, 0xf368fd46, 0xf85df65a, - 0xe27fff4a, 0xfa61f95b, 0xec7ffc38, 0xfb52f94c, 0xea7df95d, 0xf557fd4d, - 0xfb47fc3f, 0xfc44f454, 0xf93ef941, 0x083d0538, 0xfe420140, 0x003dfe4e, - 0x01320734, 0x0a23002c, 0x0b26012d, 0x002e052c, 0x1f110133, 0x07321c13, - 0x10210e3e, 0xf36cf164, 0xf365f35b, 0xf45ef658, 0xf054f656, 0xf953f357, - 0xed5e0146, 0x0048fb4a, 0x123bf866, 0xf164005f, 0xfc4b0248, 0xf54bfd47, - 0x0f2ef345, 0x003e0041, 0x1525f148, 0x09391036, 0x003e0c48, 0x18000f09, - 0x08190d12, 0x0f090d13, 0x0a250c12, 0x061d1421, 0x0f1e042d, 0x013a003e, - 0x073d0c26, 0x0b2d0f27, 0x0b2a0d2c, 0x102d0c29, 0x0a311e22, 0x122a0a37, - 0x1133112e, 0x00591aed, 0x16ef1aef, 0x1ee71cec, 0x21e925e5, 0x21e928e4, - 0x26ef21f5, 0x28f129fa, 0x26012911, 0x1efa1b03, 0x1a1625f0, 0x23fc26f8, - 0x26fd2503, 0x26052a00, 0x23102716, 0x0e301b25, 0x153c0c44, 0x0261fd47, - 0xfa2afb32, 0xfd36fe3e, 0x003a013f, 0xfe48ff4a, 0xf75bfb43, 0xfb1bfd27, - 0xfe2c002e, 0xf040f844, 0xf64efa4d, 0xf656f45c, 0xf137f63c, 0xfa3efc41, - 0xf449f84c, 0xf950f758, 0xef6ef561, 0xec54f54f, 0xfa49fc4a, 0xf356f360, - 0xf561ed75, 0xf84efb21, 0xfc30fe35, 0xfd3ef347, 0xf64ff456, 0xf35af261, - 0x0000fa5d, 0xfa54f84f, 0x0042ff47, 0x003efe3c, 0xfe3bfb4b, 0xfd3efc3a, - 0xf742ff4f, 0x00470344, 0x0a2cf93e, 0x0f240e28, 0x101b0c1d, 0x012c1424, - 0x1220052a, 0x01300a3e, 0x112e0940, 0xf468f561, 0xf060f958, 0xf855f955, - 0xf755f358, 0x0442fd4d, 0xfd4cfa4c, 0x0a3aff4c, 0xff53f963, 0xf25f025f, - 0x004cfb4a, 0x0046f54b, 0x01440041, 0xf249033e, 0x043eff44, 0xf34b0b37, - 0x05400c46, 0x0f060613, 0x07100c0e, 0x120d0d0b, 0x0d0f0f10, 0x0c170d17, - 0x0f140e1a, 0x0e2c1128, 0x112f1811, 0x15151916, 0x1f1b161d, 0x13230e32, - 0x0a39073f, 0xfe4dfc52, 0xfd5e0945, 0xf46d24dd, 0x24de20e6, 0x25e22ce0, - 0x22ee22f1, 0x28f121f9, 0x23fb2100, 0x2602210d, 0x17230d3a, 0x1dfd1a00, - 0x161e1ff9, 0x23f122fd, 0x220324ff, 0x2205200b, 0x2305220c, 0x270b1e1d, - 0x221a1d27, 0x13421f15, 0x1f1f1932, 0xef78ec70, 0xee72f555, 0xf15cf259, - 0xe647f151, 0xf2500044, 0xf246e838, 0xe944e832, 0xf54a17f3, 0x1af328f1, - 0x31f22c03, 0x2d062c22, 0x21361352, 0xfd4bff17, 0x0122012b, 0x0036fe37, - 0x003d0140, 0x0044f75c, 0xf26af361, 0xf15af45a, 0xee58f649, 0xf74ff256, - 0xf649f646, 0xf645fb42, 0xf740fb3a, 0x023b15f6, 0x18f51cf8, 0x1cff1d03, - 0x1d092314, 0x1d240e43, 0x14f10236, 0x034a14f1, 0x0236034a, 0xe47fe968, - 0xfa35ff36, 0x07331721, 0x17021500, 0x01090031, 0xdb760539, 0xf34ef541, - 0x013e0c31, 0xfc491132, 0x1240092b, 0x1d001a43, 0x105a0968, 0xd27fec68, - 0x0143f34e, 0xf541013e, 0xfa56ef5f, 0xfa3d092d, 0xfd45fa51, 0xf5600637, - 0x0743fb56, 0x0258003a, 0xfd4cf65e, 0x05360445, 0xfd510058, 0xf943fb4a, - 0xfc4afb50, 0xf948013a, 0x0029003f, 0x003f003f, 0xf7530456, 0x0061f948, - 0x0d29033e, 0x002dfc4e, 0xfd60e57e, 0xe462e765, 0xe943e452, 0xec5ef053, - 0xea6eeb5b, 0xee66f35d, 0xe37ff95c, 0xfb59f960, 0xf36cfd2e, 0xff41ff39, - 0xf75dfd4a, 0xf75cf857, 0xe97e0536, 0x063c063b, 0x0645ff30, 0x0044fc45, - 0xf858fe55, 0xfa4eff4b, 0xf94d0236, 0x0532fd44, 0x0132062a, 0xfc51013f, - 0xfc460043, 0x0239fe4c, 0x0b230440, 0x013d0b23, 0x12190c18, 0x0d1d0d24, - 0xf65df949, 0xfe490d2e, 0x0931f964, 0x09350235, 0x0535fe3d, 0x00380038, - 0xf33ffb3c, 0xff3e0439, 0xfa450439, 0x0e270433, 0x0d440340, 0x013d093f, - 0x07321027, 0x052c0434, 0x0b30fb3c, 0xff3b003b, 0x1621052c, 0x0e2bff4e, - 0x003c0945, 0x0b1c0228, 0x032c0031, 0x002e022c, 0x0233002f, 0x0427023e, - 0x062e0036, 0x0336023a, 0x043f0633, 0x06390735, 0x06340637, 0x0b2d0e24, - 0x0835ff52, 0x0737fd4e, 0x0f2e161f, 0xff541907, 0x1ef91c03, 0x1c042000, - 0x22ff1e06, 0x1e062009, 0x1f131a1b, 0x1a1e2514, 0x1c221146, 0x0143053b, - 0x0943101e, 0x12201223, 0x161d181f, 0x1726122b, 0x14290b3f, 0x093b0940, - 0xff5efe59, 0xf76cfa4c, 0xfe2c002d, 0x0034fd40, 0xfe3bfc46, 0xfc4bf852, - 0xef66f74d, 0x0318002a, 0x00300037, 0xfa3bf947, 0xf453f557, 0xe277013a, - 0xfd1dff24, 0x0126022b, 0xfa37003a, 0x0040fd4a, 0xf65a0046, 0xfc1d051f, - 0x072a013b, 0xfe3afd48, 0xfd51f561, 0x003a0805, 0x0a0e0e12, 0x0d1b0228, - 0x003afd46, 0xfa4ff855, 0x0000f36a, 0xf06af657, 0xeb72ee6e, 0xf262ea6e, - 0xeb6aee67, 0xeb6be96c, 0xe670f660, 0xf45ffb5b, 0xf75dea5e, 0xfb560943, - 0xfc50f655, 0xff46073c, 0x093a053d, 0x0c320f32, 0x12311136, 0x0a29072e, - 0xff330731, 0x08340929, 0x062f0237, 0x0d290a2c, 0x06320535, 0x0d31043f, - 0x0640fe45, 0xfe3b0646, 0x0a2c091f, 0x0c2b0335, 0x0e220a26, 0xfd340d28, - 0x1120072c, 0x07260d32, 0x0a391a2b, 0x0e0b0b0e, 0x090b120b, 0x150917fe, - 0x20f120f1, 0x22eb27e9, 0x2adf29e1, 0x2ee426f4, 0x151d2de8, 0x35d330e6, - 0x41d52bed, 0x27f61e09, 0x121a141b, 0x0039f252, 0xfb4bed61, 0xdd7d1b00, - 0x1c001ffc, 0x1b062208, 0x1e0a1816, 0x21131620, 0x1a1f1529, 0x1a2c172f, - 0x10410e47, 0x083c063f, 0x11411518, 0x17141a17, 0x1b201c17, 0x1c181728, - 0x18201c1d, 0x172a1339, 0x1635163d, 0x0b560c28, 0x0b330e3b, 0xfc4ff947, - 0xfb45f746, 0xf842f644, 0xed49f445, 0xf046f143, 0xec3eed46, 0xf042ea41, - 0xec3f09fe, 0x1af721f7, 0x27f929fe, 0x2d033109, 0x2d1b243b, 0xfa42f923, - 0xf92af82d, 0xfb30f438, 0xfa3cfb3e, 0xf842f84c, 0xfb55fa51, 0xf64df951, - 0xef50ee49, 0xfc4af653, 0xf747f743, 0xff3df842, 0xf242003b, 0x023b15f3, - 0x21f227f9, 0x2efe3302, 0x3c063d11, 0x37222a3e, 0x14f10236, 0x034a14f1, - 0x0236034a, 0xe47fe968, 0xfa35ff36, 0x07331619, 0x22001000, 0xfe090429, - 0xe3760241, 0xfa47f34f, 0x05340932, 0xfd460a36, 0x1a221316, 0x28003902, - 0x29241a45, 0xd37ff165, 0xfc4cfa47, 0xf34f0534, 0x0645f35a, 0x0034082b, - 0xfe45fb52, 0xf660023b, 0x024bfd57, 0xfd640138, 0xfd4afa55, 0x003bfd51, - 0xf956fb5f, 0xff42ff4d, 0x0146fe56, 0xfb48003d, 0x0029003f, 0x003f003f, - 0xf7530456, 0x0061f948, 0x0d29033e, 0x0d0f0733, 0x0250d97f, 0xee5bef60, - 0xe651dd62, 0xe866e961, 0xe577e863, 0xeb6eee66, 0xdc7f0050, 0xfb59f95e, - 0xfc5c0027, 0x0041f154, 0xdd7ffe49, 0xf468f75b, 0xe17f0337, 0x07380737, - 0x083dfd35, 0x0044f94a, 0xf758f367, 0xf35bf759, 0xf25cf84c, 0xf457e96e, - 0xe869f64e, 0xec70ef63, 0xb27fba7f, 0xce7fd27f, 0xfc42fb4e, 0xfc47f848, - 0x023bff37, 0xf946fa4b, 0xf859de77, 0xfd4b2014, 0x1e16d47f, 0x0036fb3d, - 0x003aff3c, 0xfd3df843, 0xe754f24a, 0xfb410534, 0x0239003d, 0xf745f546, - 0x1237fc47, 0x003a073d, 0x09291219, 0x0920052b, 0x092f002c, 0x0033022e, - 0x1326fc42, 0x0f260c2a, 0x09220059, 0x042d0a1c, 0x0a1f21f5, 0x34d5120f, - 0x1c0023ea, 0x26e72200, 0x27ee20f4, 0x66a20000, 0x38f121fc, 0x1d0a25fb, - 0x33e327f7, 0x34de45c6, 0x43c12cfb, 0x200737e3, 0x20010000, 0x1b2421e7, - 0x22e224e4, 0x26e426e5, 0x22ee23f0, 0x22f220f8, 0x25fa2300, 0x1e0a1c12, - 0x1a191d29, 0x004b0248, 0x084d0e23, 0x121f1123, 0x151e112d, 0x142a122d, - 0x1b1a1036, 0x07421038, 0x0b490a43, 0xf674e970, 0xf147f93d, 0x0035fb42, - 0xf54df750, 0xf754f657, 0xde7feb65, 0xfd27fb35, 0xf93df54b, 0xf14def5b, - 0xe76be76f, 0xe47af54c, 0xf62cf634, 0xf639f73a, 0xf048f945, 0xfc45fb4a, - 0xf7560242, 0xf7220120, 0x0b1f0534, 0xfe37fe43, 0x0049f859, 0x03340704, - 0x0a081108, 0x10130325, 0xff3dfb49, 0xff46fc4e, 0x0000eb7e, 0xe97cec6e, - 0xe67ee77c, 0xef69e579, 0xe575ef66, 0xe675e574, 0xdf7af65f, 0xf264f85f, - 0xef6fe472, 0xfa59fe50, 0xfc52f755, 0xf851ff48, 0x05400143, 0x09380045, - 0x01450745, 0xf945fa43, 0xf04dfe40, 0x023dfa43, 0xfd400239, 0xfd41fd42, - 0x003e0933, 0xff42fe47, 0xfe4bff46, 0xf7480e3c, 0x1025002f, 0x12230b25, - 0x0c290a29, 0x02300c29, 0x0d29003b, 0x03321328, 0x03421232, 0x13fa12fa, - 0x0e001af4, 0x1ff021e7, 0x21ea25e4, 0x27e22ae2, 0x2fd62ddc, 0x31de29ef, - 0x200945b9, 0x3fc142c0, 0x4db636d9, 0x34dd29f6, 0x240028ff, 0x1e0e1c1a, - 0x17250c37, 0x0b4125df, 0x27dc28db, 0x26e22edf, 0x2ae228e8, 0x31e326f4, - 0x28f626fd, 0x2efb1f14, 0x1d1e192c, 0x0c300b31, 0x1a2d1616, 0x17161b15, - 0x21141a1c, 0x1e181b22, 0x122a1927, 0x12320c46, 0x15360e47, 0x0b531920, - 0x15311536, 0xfb55fa51, 0xf64df951, 0xef50ee49, 0xfc4af653, 0xf747f743, - 0xff3df842, 0xf242003b, 0x023b11f6, 0x20f32af7, 0x31fb3500, 0x4003440a, - 0x421b2f39, 0xfb470018, 0xff24fe2a, 0xfe34f739, 0xfa3ffc41, 0xfc43f952, - 0xfd51fd4c, 0xf948fa4e, 0xf448f244, 0xfd46fa4c, 0xfb42fb3e, 0x0039fc3d, - 0xf73c0136, 0x023a11f6, 0x20f32af7, 0x31fb3500, 0x4003440a, 0x421b2f39, - 0x14f10236, 0x034a14f1, 0x0236034a, 0xe47fe968, 0xfa35ff36, 0x07331d10, - 0x19000e00, 0xf633fd3e, 0xe5631a10, 0xfc55e866, 0x05390639, 0xef490e39, - 0x1428140a, 0x1d003600, 0x252a0c61, 0xe07fea75, 0xfe4afc55, 0xe8660539, - 0xfa5df258, 0xfa2c0437, 0xf559f167, 0xeb741339, 0x143a0454, 0x0660013f, - 0xfb55f36a, 0x053f064b, 0xfd5aff65, 0x0337fc4f, 0xfe4bf461, 0xf932013c, - 0x0029003f, 0x003f003f, 0xf7530456, 0x0061f948, 0x0d29033e, 0x0722f758, - 0xec7fdc7f, 0xef5bf25f, 0xe754e756, 0xf459ef5b, 0xe17ff24c, 0xee67f35a, - 0xdb7f0b50, 0x054c0254, 0x054efa37, 0x043df253, 0xdb7ffb4f, 0xf568f55b, - 0xe27f0041, 0xfe4f0048, 0xfc5cfa38, 0x0344f847, 0xf362fc56, 0xf458fb52, - 0xfd48fc43, 0xf848f059, 0xf745ff3b, 0x05420439, 0xfc47fe47, 0x023aff4a, - 0xfc2cff45, 0x003ef933, 0xfc2ffa2a, 0xfd29fa35, 0x084cf74e, 0xf5530934, - 0x0043fb5a, 0x0143f148, 0xfb4bf850, 0xeb53eb40, 0xf31fe740, 0xe35e094b, - 0x113ff84a, 0xfb23fe1b, 0x0d5b0341, 0xf945084d, 0xf642033e, 0xfd44ec51, - 0x001e0107, 0xfd17eb4a, 0x1042e97c, 0x11252cee, 0x32deea7f, 0x0427002a, - 0x07220b1d, 0x081f0625, 0x072a0328, 0x08210d2b, 0x0d24042f, 0x0337023a, - 0x063c082c, 0x0b2c0e2a, 0x07300438, 0x04340d25, 0x0931133a, 0x0a300c2d, - 0x00451421, 0x083f23ee, 0x21e71cfd, 0x180a1b00, 0x22f234d4, 0x27e81311, - 0x1f19241d, 0x1821220f, 0x1e141649, 0x1422131f, 0x1b2c1310, 0x0f240f24, - 0x151c1915, 0x1e141f0c, 0x1b10182a, 0x005d0e38, 0x0f391a26, 0xe87fe873, - 0xea52f73e, 0x0035003b, 0xf255f359, 0xf35ef55c, 0xe37feb64, 0xf239f443, - 0xf547f64d, 0xeb55f058, 0xe968f162, 0xdb7ff652, 0xf830f83d, 0xf842f946, - 0xf24bf64f, 0xf753f45c, 0xee6cfc4f, 0xea45f04b, 0xfe3a013a, 0xf34ef753, - 0xfc51f363, 0xf351fa26, 0xf33efa3a, 0xfe3bf049, 0xf64cf356, 0xf753f657, - 0x0000ea7f, 0xe77fe778, 0xe57fed72, 0xe975e776, 0xe675e871, 0xe476e178, - 0xdb7cf65e, 0xf166f663, 0xf36ace7f, 0xfb5c1139, 0xfb56f35e, 0xf45bfe4d, - 0x0047ff49, 0x0440f951, 0x05400f39, 0x01430044, 0xf6430144, 0x004d0240, - 0x0044fb4e, 0x0737053b, 0x02410e36, 0x0f2c053c, 0x0246fe4c, 0xee560c46, - 0x0540f446, 0x0b370538, 0x00450241, 0xfa4a0536, 0x0736fa4c, 0xf552fe4d, - 0xfe4d192a, 0x11f310f7, 0x11f41beb, 0x25e229d8, 0x2ad730d1, 0x27e02ed8, - 0x34cd2ed7, 0x34d92bed, 0x200b3dc9, 0x38d23ece, 0x51bd2dec, 0x23fe1c0f, - 0x22012701, 0x1e111426, 0x122d0f36, 0x004f24f0, 0x25f225ef, 0x2001220f, - 0x1d0f1819, 0x22161f10, 0x23121f1c, 0x2129241c, 0x1b2f153e, 0x121f131a, - 0x24181817, 0x1b10181e, 0x1f1d1629, 0x162a103c, 0x0f340e3c, 0x034ef07b, - 0x15351638, 0x193d1521, 0x1332113d, 0xfd4ef84a, 0xf748f648, 0xee4bf447, - 0xf53ffb46, 0xef4bf248, 0xf043f835, 0xf23bf734, 0xf54409fe, 0x1ef61ffc, - 0x21ff2107, 0x1f0c2517, 0x1f261440, 0xf747f925, 0xf82cf531, 0xf638f43b, - 0xf83ff743, 0xfa44f64f, 0xfd4ef84a, 0xf748f648, 0xee4bf447, 0xf53ffb46, - 0xef4bf248, 0xf043f835, 0xf23bf734, 0xf54409fe, 0x1ef61ffc, 0x21ff2107, - 0x1f0c2517, 0x1f261440, -}; - -const RK_U32 g_ValueList[34] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33 -}; - - -static RK_U32 check_dpb_buffer_is_valid(H264dHalCtx_t *p_hal, RK_U32 dpb_idx) -{ - - (void)p_hal; - (void)dpb_idx; - - return 1; -} -static MPP_RET vdpu_set_refer_pic_idx(H264dVdpuRegs_t *p_regs, RK_U32 i, RK_U16 val) -{ - switch (i) { - case 0: - p_regs->sw76.num_ref_idx0 = val; - break; - case 1: - p_regs->sw76.num_ref_idx1 = val; - break; - case 2: - p_regs->sw77.num_ref_idx2 = val; - break; - case 3: - p_regs->sw77.num_ref_idx3 = val; - break; - case 4: - p_regs->sw78.num_ref_idx4 = val; - break; - case 5: - p_regs->sw78.num_ref_idx5 = val; - break; - case 6: - p_regs->sw79.num_ref_idx6 = val; - break; - case 7: - p_regs->sw79.num_ref_idx7 = val; - break; - case 8: - p_regs->sw80.num_ref_idx8 = val; - break; - case 9: - p_regs->sw80.num_ref_idx9 = val; - break; - case 10: - p_regs->sw81.num_ref_idx10 = val; - break; - case 11: - p_regs->sw81.num_ref_idx11 = val; - break; - case 12: - p_regs->sw82.num_ref_idx12 = val; - break; - case 13: - p_regs->sw82.num_ref_idx13 = val; - break; - case 14: - p_regs->sw83.num_ref_idx14 = val; - break; - case 15: - p_regs->sw83.num_ref_idx15 = val; - break; - default: - break; - } - - return MPP_OK; -} -static MPP_RET vdpu_set_refer_pic_list_p(H264dVdpuRegs_t *p_regs, RK_U32 i, RK_U16 val) -{ - switch (i) { - case 0: - p_regs->sw106.init_reflist_pf0 = val; - break; - case 1: - p_regs->sw106.init_reflist_pf1 = val; - break; - case 2: - p_regs->sw106.init_reflist_pf2 = val; - break; - case 3: - p_regs->sw106.init_reflist_pf3 = val; - break; - case 4: - p_regs->sw74.init_reflist_pf4 = val; - break; - case 5: - p_regs->sw74.init_reflist_pf5 = val; - break; - case 6: - p_regs->sw74.init_reflist_pf6 = val; - break; - case 7: - p_regs->sw74.init_reflist_pf7 = val; - break; - case 8: - p_regs->sw74.init_reflist_pf8 = val; - break; - case 9: - p_regs->sw74.init_reflist_pf9 = val; - break; - case 10: - p_regs->sw75.init_reflist_pf10 = val; - break; - case 11: - p_regs->sw75.init_reflist_pf11 = val; - break; - case 12: - p_regs->sw75.init_reflist_pf12 = val; - break; - case 13: - p_regs->sw75.init_reflist_pf13 = val; - break; - case 14: - p_regs->sw75.init_reflist_pf14 = val; - break; - case 15: - p_regs->sw75.init_reflist_pf15 = val; - break; - default: - break; - } - - return MPP_OK; -} -static MPP_RET vdpu_set_refer_pic_list_b0(H264dVdpuRegs_t *p_regs, RK_U32 i, RK_U16 val) -{ - switch (i) { - case 0: - p_regs->sw100.init_reflist_df0 = val; - break; - case 1: - p_regs->sw100.init_reflist_df1 = val; - break; - case 2: - p_regs->sw100.init_reflist_df2 = val; - break; - case 3: - p_regs->sw100.init_reflist_df3 = val; - break; - case 4: - p_regs->sw100.init_reflist_df4 = val; - break; - case 5: - p_regs->sw100.init_reflist_df5 = val; - break; - case 6: - p_regs->sw101.init_reflist_df6 = val; - break; - case 7: - p_regs->sw101.init_reflist_df7 = val; - break; - case 8: - p_regs->sw101.init_reflist_df8 = val; - break; - case 9: - p_regs->sw101.init_reflist_df9 = val; - break; - case 10: - p_regs->sw101.init_reflist_df10 = val; - break; - case 11: - p_regs->sw101.init_reflist_df11 = val; - break; - case 12: - p_regs->sw102.init_reflist_df12 = val; - break; - case 13: - p_regs->sw102.init_reflist_df13 = val; - break; - case 14: - p_regs->sw102.init_reflist_df14 = val; - break; - case 15: - p_regs->sw102.init_reflist_df15 = val; - break; - default: - break; - } - - return MPP_OK; -} -static MPP_RET vdpu_set_refer_pic_list_b1(H264dVdpuRegs_t *p_regs, RK_U32 i, RK_U16 val) -{ - switch (i) { - case 0: - p_regs->sw103.init_reflist_db0 = val; - break; - case 1: - p_regs->sw103.init_reflist_db1 = val; - break; - case 2: - p_regs->sw103.init_reflist_db2 = val; - break; - case 3: - p_regs->sw103.init_reflist_db3 = val; - break; - case 4: - p_regs->sw103.init_reflist_db4 = val; - break; - case 5: - p_regs->sw103.init_reflist_db5 = val; - break; - case 6: - p_regs->sw104.init_reflist_db6 = val; - break; - case 7: - p_regs->sw104.init_reflist_db7 = val; - break; - case 8: - p_regs->sw104.init_reflist_db8 = val; - break; - case 9: - p_regs->sw104.init_reflist_db9 = val; - break; - case 10: - p_regs->sw104.init_reflist_db10 = val; - break; - case 11: - p_regs->sw104.init_reflist_db11 = val; - break; - case 12: - p_regs->sw105.init_reflist_db12 = val; - break; - case 13: - p_regs->sw105.init_reflist_db13 = val; - break; - case 14: - p_regs->sw105.init_reflist_db14 = val; - break; - case 15: - p_regs->sw105.init_reflist_db15 = val; - break; - default: - break; - } - - return MPP_OK; -} - -static MPP_RET vdpu_set_refer_pic_base_addr(H264dVdpuRegs_t *p_regs, RK_U32 i, RK_U32 val) -{ - switch (i) { - case 0: - p_regs->sw84.ref0_st_addr = val; - break; - case 1: - p_regs->sw85.ref1_st_addr = val; - break; - case 2: - p_regs->sw86.ref2_st_addr = val; - break; - case 3: - p_regs->sw87.ref3_st_addr = val; - break; - case 4: - p_regs->sw88.ref4_st_addr = val; - break; - case 5: - p_regs->sw89.ref5_st_addr = val; - break; - case 6: - p_regs->sw90.ref6_st_addr = val; - break; - case 7: - p_regs->sw91.ref7_st_addr = val; - break; - case 8: - p_regs->sw92.ref8_st_addr = val; - break; - case 9: - p_regs->sw93.ref9_st_addr = val; - break; - case 10: - p_regs->sw94.ref10_st_addr = val; - break; - case 11: - p_regs->sw95.ref11_st_addr = val; - break; - case 12: - p_regs->sw96.ref12_st_addr = val; - break; - case 13: - p_regs->sw97.ref13_st_addr = val; - break; - case 14: - p_regs->sw98.ref14_st_addr = val; - break; - case 15: - p_regs->sw99.ref15_st_addr = val; - break; - default: - break; - } - return MPP_OK; -} -/*! -*********************************************************************** -* \brief -* set picture parameter and set register -*********************************************************************** -*/ -//extern "C" -MPP_RET vdpu_set_pic_regs(H264dHalCtx_t *p_hal, H264dVdpuRegs_t *p_regs) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - - p_regs->sw110.pic_mb_w = p_hal->pp->wFrameWidthInMbsMinus1 + 1; - p_regs->sw110.pic_mb_h = (2 - p_hal->pp->frame_mbs_only_flag) * (p_hal->pp->wFrameHeightInMbsMinus1 + 1); - - return ret = MPP_OK; -} -/*! -*********************************************************************** -* \brief -* set vlc register -*********************************************************************** -*/ -//extern "C" -MPP_RET vdpu_set_vlc_regs(H264dHalCtx_t *p_hal, H264dVdpuRegs_t *p_regs) -{ - RK_U32 i = 0; - MPP_RET ret = MPP_ERR_UNKNOW; - DXVA_PicParams_H264_MVC *pp = p_hal->pp; - - FunctionIn(p_hal->logctx.parr[RUN_HAL]); - - p_regs->sw57.dec_wr_extmen_dis = 0; - p_regs->sw57.rlc_mode_en = 0; - p_regs->sw51.qp_init_val = pp->pic_init_qp_minus26 + 26; - p_regs->sw114.max_refidx0 = pp->num_ref_idx_l0_active_minus1 + 1; - p_regs->sw111.max_refnum = pp->num_ref_frames; - p_regs->sw112.cur_frm_len = pp->log2_max_frame_num_minus4 + 4; - p_regs->sw112.curfrm_num = pp->frame_num; - p_regs->sw115.const_intra_en = pp->constrained_intra_pred_flag; - p_regs->sw112.dblk_ctrl_flag = pp->deblocking_filter_control_present_flag; - p_regs->sw112.rpcp_flag = pp->redundant_pic_cnt_present_flag; - p_regs->sw113.refpic_mk_len = p_hal->slice_long[0].drpm_used_bitlen; - p_regs->sw115.idr_pic_flag = p_hal->slice_long[0].idr_flag; - p_regs->sw113.idr_pic_id = p_hal->slice_long[0].idr_pic_id; - p_regs->sw114.pps_id = p_hal->slice_long[0].active_pps_id; - p_regs->sw114.poc_field_len = p_hal->slice_long[0].poc_used_bitlen; - /* reference picture flags, TODO separate fields */ - if (pp->field_pic_flag) { - RK_U32 validTmp = 0, validFlags = 0; - RK_U32 longTermTmp = 0, longTermflags = 0; - for (i = 0; i < 32; i++) { - if (pp->RefFrameList[i / 2].bPicEntry == 0xff) { //!< invalid - longTermflags <<= 1; - validFlags <<= 1; - } else { - longTermTmp = pp->RefFrameList[i / 2].AssociatedFlag; //!< get long term flag - longTermflags = (longTermflags << 1) | longTermTmp; - - validTmp = check_dpb_buffer_is_valid(p_hal, pp->RefFrameList[i / 2].Index7Bits); - validTmp = validTmp && ((pp->UsedForReferenceFlags >> i) & 0x01); - validFlags = (validFlags << 1) | validTmp; - } - } - p_regs->sw107.refpic_term_flag = longTermflags; - p_regs->sw108.refpic_valid_flag = validFlags; - } else { - RK_U32 validTmp = 0, validFlags = 0; - RK_U32 longTermTmp = 0, longTermflags = 0; - for (i = 0; i < 16; i++) { - if (pp->RefFrameList[i].bPicEntry == 0xff) { //!< invalid - longTermflags <<= 1; - validFlags <<= 1; - } else { - longTermTmp = pp->RefFrameList[i].AssociatedFlag; - longTermflags = (longTermflags << 1) | longTermTmp; - validTmp = check_dpb_buffer_is_valid(p_hal, pp->RefFrameList[i].Index7Bits); - validTmp = validTmp && ((pp->UsedForReferenceFlags >> (2 * i)) & 0x03); - validFlags = (validFlags << 1) | validTmp; - } - } - p_regs->sw107.refpic_term_flag = (longTermflags << 16); - p_regs->sw108.refpic_valid_flag = (validFlags << 16); - } - - for (i = 0; i < 16; i++) { - if (pp->RefFrameList[i].bPicEntry != 0xff) { //!< valid - if (pp->RefFrameList[i].AssociatedFlag) { //!< longterm flag - vdpu_set_refer_pic_idx(p_regs, i, pp->LongTermPicNumList[i]); //!< pic_num - } else { - vdpu_set_refer_pic_idx(p_regs, i, pp->FrameNumList[i]); //< frame_num - } - } - } - p_regs->sw57.rd_cnt_tab_en = 1; - //!< set poc to buffer - { - RK_U32 *pocBase = NULL; - pocBase = (RK_U32 *)((RK_U8 *)mpp_buffer_get_ptr(p_hal->cabac_buf) + VDPU_CABAC_TAB_SIZE); - //!< set reference reorder poc - for (i = 0; i < 32; i++) { - if (pp->RefFrameList[i / 2].bPicEntry != 0xff) { - *pocBase++ = pp->FieldOrderCntList[i / 2][i & 0x1]; - } else { - *pocBase++ = 0; - } - } - //!< set current poc - if (pp->field_pic_flag || !pp->MbaffFrameFlag) { - *pocBase++ = pp->CurrFieldOrderCnt[0]; - *pocBase++ = pp->CurrFieldOrderCnt[1]; - } else { - *pocBase++ = pp->CurrFieldOrderCnt[0]; - *pocBase++ = pp->CurrFieldOrderCnt[1]; - } - } - p_regs->sw115.cabac_en = pp->entropy_coding_mode_flag; - //!< stream position update - { - MppBuffer bitstream_buf = NULL; - p_regs->sw57.st_code_exit = 1; - mpp_buf_slot_get_prop(p_hal->packet_slots, p_hal->in_task->input, SLOT_BUFFER, &bitstream_buf); - p_regs->sw109.strm_start_bit = 0; //!< sodb stream start bit - if (VPUClientGetIOMMUStatus() > 0) { - p_regs->sw64.rlc_vlc_st_adr = mpp_buffer_get_fd(bitstream_buf); - } - p_regs->sw51.stream_len = p_hal->strm_len; - } - FunctionOut(p_hal->logctx.parr[RUN_HAL]); - - return ret = MPP_OK; -} -/*! -*********************************************************************** -* \brief -* set vlc reference -*********************************************************************** -*/ -//extern "C" -MPP_RET vdpu_set_ref_regs(H264dHalCtx_t *p_hal, H264dVdpuRegs_t *p_regs) -{ - RK_U32 i = 0, j = 0; - MPP_RET ret = MPP_ERR_UNKNOW; - DXVA_Slice_H264_Long *p_long = &p_hal->slice_long[0]; - - FunctionIn(p_hal->logctx.parr[RUN_HAL]); - //!< list0 list1 listP - for (j = 0; j < 3; j++) { - for (i = 0; i < 16; i++) { - RK_U16 val = 0; - if (p_hal->pp->field_pic_flag) { //!< field - RK_U32 nn = 0; - nn = p_hal->pp->CurrPic.AssociatedFlag ? (2 * i + 1) : (2 * i); - if (p_long->RefPicList[j][nn].bPicEntry == 0xff) { - val = g_ValueList[i]; - } else { - val = p_long->RefPicList[j][nn].Index7Bits; - } - } else { //!< frame - if (p_long->RefPicList[j][i].bPicEntry == 0xff) { - val = g_ValueList[i]; - } else { - val = p_long->RefPicList[j][i].Index7Bits; - } - } - switch (j) { - case 0: - vdpu_set_refer_pic_list_p(p_regs, i, val); - break; - case 1: - vdpu_set_refer_pic_list_b0(p_regs, i, val); - - break; - case 2: - vdpu_set_refer_pic_list_b1(p_regs, i, val); - - break; - default: - break; - } - } - } - FunctionOut(p_hal->logctx.parr[RUN_HAL]); - - return ret = MPP_OK; -} -/*! -*********************************************************************** -* \brief -* run Asic -*********************************************************************** -*/ -//extern "C" -MPP_RET vdpu_set_asic_regs(H264dHalCtx_t *p_hal, H264dVdpuRegs_t *p_regs) -{ - RK_U32 i = 0, j = 0; - RK_U32 outPhyAddr = 0; - MppBuffer frame_buf = NULL; - MPP_RET ret = MPP_ERR_UNKNOW; - DXVA_PicParams_H264_MVC *pp = p_hal->pp; - DXVA_Slice_H264_Long *p_long = &p_hal->slice_long[0]; - - FunctionIn(p_hal->logctx.parr[RUN_HAL]); - /* reference picture physic address */ - for (i = 0, j = 0xff; i < MPP_ARRAY_ELEMS(pp->RefFrameList); i++) { - RK_U32 val = 0; - RK_U32 top_closer = 0; - RK_U32 field_flag = 0; - if (pp->RefFrameList[i].bPicEntry != 0xff) { - mpp_buf_slot_get_prop(p_hal->frame_slots, pp->RefFrameList[i].Index7Bits, SLOT_BUFFER, &frame_buf); //!< reference phy addr - j = i; - } else { - mpp_buf_slot_get_prop(p_hal->frame_slots, pp->CurrPic.Index7Bits, SLOT_BUFFER, &frame_buf); //!< current out phy addr - } - - field_flag = ((pp->RefPicFiledFlags >> i) & 0x1) ? 0x2 : 0; - if (field_flag) { - RK_U32 used_flag = 0; - RK_S32 cur_poc = 0; - RK_S32 ref_poc = 0; - - cur_poc = pp->CurrPic.AssociatedFlag ? pp->CurrFieldOrderCnt[1] : pp->CurrFieldOrderCnt[0]; - used_flag = ((pp->UsedForReferenceFlags >> (2 * i)) & 0x3); - if (used_flag & 0x3) { - ref_poc = MPP_MIN(pp->FieldOrderCntList[i][0], pp->FieldOrderCntList[i][1]); - } else if (used_flag & 0x2) { - ref_poc = pp->FieldOrderCntList[i][1]; - } else if (used_flag & 0x1) { - ref_poc = pp->FieldOrderCntList[i][0]; - } - top_closer = (cur_poc < ref_poc) ? 0x1 : 0; - } - val = top_closer | field_flag; - - if (VPUClientGetIOMMUStatus() > 0) { - val = mpp_buffer_get_fd(frame_buf) | (val << 10); - } - vdpu_set_refer_pic_base_addr(p_regs, i, val); - } - /* inter-view reference picture */ - { - H264dVdpuPriv_t *priv = (H264dVdpuPriv_t *)p_hal->priv; - if (pp->curr_layer_id && priv->ilt_dpb && priv->ilt_dpb->valid /*pp->inter_view_flag*/) { - mpp_buf_slot_get_prop(p_hal->frame_slots, priv->ilt_dpb->slot_index, SLOT_BUFFER, &frame_buf); - - if (VPUClientGetIOMMUStatus() > 0) { - p_regs->sw99.ref15_st_addr = mpp_buffer_get_fd(frame_buf); //!< inter-view base, ref15 - } - p_regs->sw108.refpic_valid_flag |= (pp->field_pic_flag ? 0x3 : 0x10000); - } - } - p_regs->sw50.dec_fixed_quant = pp->curr_layer_id; //!< VDPU_MVC_E - p_regs->sw50.dblk_flt_dis = 0; //!< filterDisable = 0; - mpp_buf_slot_get_prop(p_hal->frame_slots, pp->CurrPic.Index7Bits, SLOT_BUFFER, &frame_buf); //!< current out phy addr - - if (VPUClientGetIOMMUStatus() > 0) { - outPhyAddr = mpp_buffer_get_fd(frame_buf); - } - if (pp->field_pic_flag && pp->CurrPic.AssociatedFlag) { - if (VPUClientGetIOMMUStatus() > 0) { - outPhyAddr |= ((pp->wFrameWidthInMbsMinus1 + 1) * 16) << 10; - } else { - outPhyAddr += (pp->wFrameWidthInMbsMinus1 + 1) * 16; - } - } - p_regs->sw63.dec_out_st_adr = outPhyAddr; //!< outPhyAddr, pp->CurrPic.Index7Bits - p_regs->sw110.flt_offset_cb_qp = pp->chroma_qp_index_offset; - p_regs->sw110.flt_offset_cr_qp = pp->second_chroma_qp_index_offset; - /* set default value for register[41] to avoid illegal translation fd */ - { - RK_U32 dirMvOffset = 0; - RK_U32 picSizeInMbs = 0; - - picSizeInMbs = p_hal->pp->wFrameWidthInMbsMinus1 + 1; - picSizeInMbs = picSizeInMbs * (2 - pp->frame_mbs_only_flag) * (pp->wFrameHeightInMbsMinus1 + 1); - dirMvOffset = picSizeInMbs * ((p_hal->pp->chroma_format_idc == 0) ? 256 : 384); - dirMvOffset += (pp->field_pic_flag && pp->CurrPic.AssociatedFlag) ? (picSizeInMbs * 32) : 0; - if (VPUClientGetIOMMUStatus() > 0) { - p_regs->sw62.dmmv_st_adr = (mpp_buffer_get_fd(frame_buf) | (dirMvOffset << 6)); - } - } - p_regs->sw57.dmmv_wr_en = (p_long->nal_ref_idc != 0) ? 1 : 0; //!< defalut set 1 - p_regs->sw115.dlmv_method_en = pp->direct_8x8_inference_flag; - p_regs->sw115.weight_pred_en = pp->weighted_pred_flag; - p_regs->sw111.wp_bslice_sel = pp->weighted_bipred_idc; - p_regs->sw114.max_refidx1 = (pp->num_ref_idx_l1_active_minus1 + 1); - p_regs->sw115.fieldpic_flag_exist = (!pp->frame_mbs_only_flag) ? 1 : 0; - p_regs->sw57.curpic_code_sel = (!pp->frame_mbs_only_flag && (pp->MbaffFrameFlag || pp->field_pic_flag)) ? 1 : 0; - p_regs->sw57.curpic_stru_sel = pp->field_pic_flag; - p_regs->sw57.pic_decfield_sel = (!pp->CurrPic.AssociatedFlag) ? 1 : 0; //!< bottomFieldFlag - p_regs->sw57.sequ_mbaff_en = pp->MbaffFrameFlag; - p_regs->sw115.tranf_8x8_flag_en = pp->transform_8x8_mode_flag; - p_regs->sw115.monochr_en = (p_long->profileIdc >= 100 && pp->chroma_format_idc == 0) ? 1 : 0; - p_regs->sw115.scl_matrix_en = pp->scaleing_list_enable_flag; - { - RK_U32 offset = VDPU_CABAC_TAB_SIZE + VDPU_POC_BUF_SIZE; - if (p_hal->pp->scaleing_list_enable_flag) { - RK_U32 temp = 0; - RK_U32 *ptr = NULL; - ptr = (RK_U32 *)((RK_U8 *)mpp_buffer_get_ptr(p_hal->cabac_buf) + offset); - for (i = 0; i < 6; i++) { - for (j = 0; j < 4; j++) { - temp = (p_hal->qm->bScalingLists4x4[i][4 * j + 0] << 24) | - (p_hal->qm->bScalingLists4x4[i][4 * j + 1] << 16) | - (p_hal->qm->bScalingLists4x4[i][4 * j + 2] << 8) | - (p_hal->qm->bScalingLists4x4[i][4 * j + 3]); - *ptr++ = temp; - } - } - for (i = 0; i < 2; i++) { - for (j = 0; j < 16; j++) { - temp = (p_hal->qm->bScalingLists8x8[i][4 * j + 0] << 24) | - (p_hal->qm->bScalingLists8x8[i][4 * j + 1] << 16) | - (p_hal->qm->bScalingLists8x8[i][4 * j + 2] << 8) | - (p_hal->qm->bScalingLists8x8[i][4 * j + 3]); - *ptr++ = temp; - } - } - } - if (VPUClientGetIOMMUStatus() > 0) { - p_regs->sw61.qtable_st_adr = mpp_buffer_get_fd(p_hal->cabac_buf); - } - } - p_regs->sw57.dec_wr_extmen_dis = 0; //!< set defalut 0 - p_regs->sw57.addit_ch_fmt_wen = 0; - p_regs->sw57.dec_st_work = 1; - FunctionOut(p_hal->logctx.parr[RUN_HAL]); - return ret = MPP_OK; -} - - + +/* + * Copyright 2010 Rockchip Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define MODULE_TAG "hal_h264d_vdpu_pkt" + +#include +#include + +#include "mpp_mem.h" +#include "hal_task.h" + +#include "dxva_syntax.h" +#include "vpu.h" + +#include "h264d_log.h" +#include "h264d_syntax.h" +#include "hal_h264d_fifo.h" +#include "hal_h264d_api.h" +#include "hal_h264d_global.h" +#include "hal_h264d_vdpu_pkt.h" +#include "hal_h264d_vdpu_reg.h" + + +const RK_U32 H264_VDPU_Cabac_table[VDPU_CABAC_TAB_SIZE / 4] = { + 0x14f10236, 0x034a14f1, 0x0236034a, 0xe47fe968, 0xfa35ff36, 0x07330000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x0029003f, 0x003f003f, 0xf7530456, 0x0061f948, 0x0d29033e, 0x000b0137, + 0x0045ef7f, 0xf3660052, 0xf94aeb6b, 0xe57fe17f, 0xe87fee5f, 0xe57feb72, + 0xe27fef7b, 0xf473f07a, 0xf573f43f, 0xfe44f154, 0xf368fd46, 0xf85df65a, + 0xe27fff4a, 0xfa61f95b, 0xec7ffc38, 0xfb52f94c, 0xea7df95d, 0xf557fd4d, + 0xfb47fc3f, 0xfc44f454, 0xf93ef941, 0x083d0538, 0xfe420140, 0x003dfe4e, + 0x01320734, 0x0a23002c, 0x0b26012d, 0x002e052c, 0x1f110133, 0x07321c13, + 0x10210e3e, 0xf36cf164, 0xf365f35b, 0xf45ef658, 0xf054f656, 0xf953f357, + 0xed5e0146, 0x0048fb4a, 0x123bf866, 0xf164005f, 0xfc4b0248, 0xf54bfd47, + 0x0f2ef345, 0x003e0041, 0x1525f148, 0x09391036, 0x003e0c48, 0x18000f09, + 0x08190d12, 0x0f090d13, 0x0a250c12, 0x061d1421, 0x0f1e042d, 0x013a003e, + 0x073d0c26, 0x0b2d0f27, 0x0b2a0d2c, 0x102d0c29, 0x0a311e22, 0x122a0a37, + 0x1133112e, 0x00591aed, 0x16ef1aef, 0x1ee71cec, 0x21e925e5, 0x21e928e4, + 0x26ef21f5, 0x28f129fa, 0x26012911, 0x1efa1b03, 0x1a1625f0, 0x23fc26f8, + 0x26fd2503, 0x26052a00, 0x23102716, 0x0e301b25, 0x153c0c44, 0x0261fd47, + 0xfa2afb32, 0xfd36fe3e, 0x003a013f, 0xfe48ff4a, 0xf75bfb43, 0xfb1bfd27, + 0xfe2c002e, 0xf040f844, 0xf64efa4d, 0xf656f45c, 0xf137f63c, 0xfa3efc41, + 0xf449f84c, 0xf950f758, 0xef6ef561, 0xec54f54f, 0xfa49fc4a, 0xf356f360, + 0xf561ed75, 0xf84efb21, 0xfc30fe35, 0xfd3ef347, 0xf64ff456, 0xf35af261, + 0x0000fa5d, 0xfa54f84f, 0x0042ff47, 0x003efe3c, 0xfe3bfb4b, 0xfd3efc3a, + 0xf742ff4f, 0x00470344, 0x0a2cf93e, 0x0f240e28, 0x101b0c1d, 0x012c1424, + 0x1220052a, 0x01300a3e, 0x112e0940, 0xf468f561, 0xf060f958, 0xf855f955, + 0xf755f358, 0x0442fd4d, 0xfd4cfa4c, 0x0a3aff4c, 0xff53f963, 0xf25f025f, + 0x004cfb4a, 0x0046f54b, 0x01440041, 0xf249033e, 0x043eff44, 0xf34b0b37, + 0x05400c46, 0x0f060613, 0x07100c0e, 0x120d0d0b, 0x0d0f0f10, 0x0c170d17, + 0x0f140e1a, 0x0e2c1128, 0x112f1811, 0x15151916, 0x1f1b161d, 0x13230e32, + 0x0a39073f, 0xfe4dfc52, 0xfd5e0945, 0xf46d24dd, 0x24de20e6, 0x25e22ce0, + 0x22ee22f1, 0x28f121f9, 0x23fb2100, 0x2602210d, 0x17230d3a, 0x1dfd1a00, + 0x161e1ff9, 0x23f122fd, 0x220324ff, 0x2205200b, 0x2305220c, 0x270b1e1d, + 0x221a1d27, 0x13421f15, 0x1f1f1932, 0xef78ec70, 0xee72f555, 0xf15cf259, + 0xe647f151, 0xf2500044, 0xf246e838, 0xe944e832, 0xf54a17f3, 0x1af328f1, + 0x31f22c03, 0x2d062c22, 0x21361352, 0xfd4bff17, 0x0122012b, 0x0036fe37, + 0x003d0140, 0x0044f75c, 0xf26af361, 0xf15af45a, 0xee58f649, 0xf74ff256, + 0xf649f646, 0xf645fb42, 0xf740fb3a, 0x023b15f6, 0x18f51cf8, 0x1cff1d03, + 0x1d092314, 0x1d240e43, 0x14f10236, 0x034a14f1, 0x0236034a, 0xe47fe968, + 0xfa35ff36, 0x07331721, 0x17021500, 0x01090031, 0xdb760539, 0xf34ef541, + 0x013e0c31, 0xfc491132, 0x1240092b, 0x1d001a43, 0x105a0968, 0xd27fec68, + 0x0143f34e, 0xf541013e, 0xfa56ef5f, 0xfa3d092d, 0xfd45fa51, 0xf5600637, + 0x0743fb56, 0x0258003a, 0xfd4cf65e, 0x05360445, 0xfd510058, 0xf943fb4a, + 0xfc4afb50, 0xf948013a, 0x0029003f, 0x003f003f, 0xf7530456, 0x0061f948, + 0x0d29033e, 0x002dfc4e, 0xfd60e57e, 0xe462e765, 0xe943e452, 0xec5ef053, + 0xea6eeb5b, 0xee66f35d, 0xe37ff95c, 0xfb59f960, 0xf36cfd2e, 0xff41ff39, + 0xf75dfd4a, 0xf75cf857, 0xe97e0536, 0x063c063b, 0x0645ff30, 0x0044fc45, + 0xf858fe55, 0xfa4eff4b, 0xf94d0236, 0x0532fd44, 0x0132062a, 0xfc51013f, + 0xfc460043, 0x0239fe4c, 0x0b230440, 0x013d0b23, 0x12190c18, 0x0d1d0d24, + 0xf65df949, 0xfe490d2e, 0x0931f964, 0x09350235, 0x0535fe3d, 0x00380038, + 0xf33ffb3c, 0xff3e0439, 0xfa450439, 0x0e270433, 0x0d440340, 0x013d093f, + 0x07321027, 0x052c0434, 0x0b30fb3c, 0xff3b003b, 0x1621052c, 0x0e2bff4e, + 0x003c0945, 0x0b1c0228, 0x032c0031, 0x002e022c, 0x0233002f, 0x0427023e, + 0x062e0036, 0x0336023a, 0x043f0633, 0x06390735, 0x06340637, 0x0b2d0e24, + 0x0835ff52, 0x0737fd4e, 0x0f2e161f, 0xff541907, 0x1ef91c03, 0x1c042000, + 0x22ff1e06, 0x1e062009, 0x1f131a1b, 0x1a1e2514, 0x1c221146, 0x0143053b, + 0x0943101e, 0x12201223, 0x161d181f, 0x1726122b, 0x14290b3f, 0x093b0940, + 0xff5efe59, 0xf76cfa4c, 0xfe2c002d, 0x0034fd40, 0xfe3bfc46, 0xfc4bf852, + 0xef66f74d, 0x0318002a, 0x00300037, 0xfa3bf947, 0xf453f557, 0xe277013a, + 0xfd1dff24, 0x0126022b, 0xfa37003a, 0x0040fd4a, 0xf65a0046, 0xfc1d051f, + 0x072a013b, 0xfe3afd48, 0xfd51f561, 0x003a0805, 0x0a0e0e12, 0x0d1b0228, + 0x003afd46, 0xfa4ff855, 0x0000f36a, 0xf06af657, 0xeb72ee6e, 0xf262ea6e, + 0xeb6aee67, 0xeb6be96c, 0xe670f660, 0xf45ffb5b, 0xf75dea5e, 0xfb560943, + 0xfc50f655, 0xff46073c, 0x093a053d, 0x0c320f32, 0x12311136, 0x0a29072e, + 0xff330731, 0x08340929, 0x062f0237, 0x0d290a2c, 0x06320535, 0x0d31043f, + 0x0640fe45, 0xfe3b0646, 0x0a2c091f, 0x0c2b0335, 0x0e220a26, 0xfd340d28, + 0x1120072c, 0x07260d32, 0x0a391a2b, 0x0e0b0b0e, 0x090b120b, 0x150917fe, + 0x20f120f1, 0x22eb27e9, 0x2adf29e1, 0x2ee426f4, 0x151d2de8, 0x35d330e6, + 0x41d52bed, 0x27f61e09, 0x121a141b, 0x0039f252, 0xfb4bed61, 0xdd7d1b00, + 0x1c001ffc, 0x1b062208, 0x1e0a1816, 0x21131620, 0x1a1f1529, 0x1a2c172f, + 0x10410e47, 0x083c063f, 0x11411518, 0x17141a17, 0x1b201c17, 0x1c181728, + 0x18201c1d, 0x172a1339, 0x1635163d, 0x0b560c28, 0x0b330e3b, 0xfc4ff947, + 0xfb45f746, 0xf842f644, 0xed49f445, 0xf046f143, 0xec3eed46, 0xf042ea41, + 0xec3f09fe, 0x1af721f7, 0x27f929fe, 0x2d033109, 0x2d1b243b, 0xfa42f923, + 0xf92af82d, 0xfb30f438, 0xfa3cfb3e, 0xf842f84c, 0xfb55fa51, 0xf64df951, + 0xef50ee49, 0xfc4af653, 0xf747f743, 0xff3df842, 0xf242003b, 0x023b15f3, + 0x21f227f9, 0x2efe3302, 0x3c063d11, 0x37222a3e, 0x14f10236, 0x034a14f1, + 0x0236034a, 0xe47fe968, 0xfa35ff36, 0x07331619, 0x22001000, 0xfe090429, + 0xe3760241, 0xfa47f34f, 0x05340932, 0xfd460a36, 0x1a221316, 0x28003902, + 0x29241a45, 0xd37ff165, 0xfc4cfa47, 0xf34f0534, 0x0645f35a, 0x0034082b, + 0xfe45fb52, 0xf660023b, 0x024bfd57, 0xfd640138, 0xfd4afa55, 0x003bfd51, + 0xf956fb5f, 0xff42ff4d, 0x0146fe56, 0xfb48003d, 0x0029003f, 0x003f003f, + 0xf7530456, 0x0061f948, 0x0d29033e, 0x0d0f0733, 0x0250d97f, 0xee5bef60, + 0xe651dd62, 0xe866e961, 0xe577e863, 0xeb6eee66, 0xdc7f0050, 0xfb59f95e, + 0xfc5c0027, 0x0041f154, 0xdd7ffe49, 0xf468f75b, 0xe17f0337, 0x07380737, + 0x083dfd35, 0x0044f94a, 0xf758f367, 0xf35bf759, 0xf25cf84c, 0xf457e96e, + 0xe869f64e, 0xec70ef63, 0xb27fba7f, 0xce7fd27f, 0xfc42fb4e, 0xfc47f848, + 0x023bff37, 0xf946fa4b, 0xf859de77, 0xfd4b2014, 0x1e16d47f, 0x0036fb3d, + 0x003aff3c, 0xfd3df843, 0xe754f24a, 0xfb410534, 0x0239003d, 0xf745f546, + 0x1237fc47, 0x003a073d, 0x09291219, 0x0920052b, 0x092f002c, 0x0033022e, + 0x1326fc42, 0x0f260c2a, 0x09220059, 0x042d0a1c, 0x0a1f21f5, 0x34d5120f, + 0x1c0023ea, 0x26e72200, 0x27ee20f4, 0x66a20000, 0x38f121fc, 0x1d0a25fb, + 0x33e327f7, 0x34de45c6, 0x43c12cfb, 0x200737e3, 0x20010000, 0x1b2421e7, + 0x22e224e4, 0x26e426e5, 0x22ee23f0, 0x22f220f8, 0x25fa2300, 0x1e0a1c12, + 0x1a191d29, 0x004b0248, 0x084d0e23, 0x121f1123, 0x151e112d, 0x142a122d, + 0x1b1a1036, 0x07421038, 0x0b490a43, 0xf674e970, 0xf147f93d, 0x0035fb42, + 0xf54df750, 0xf754f657, 0xde7feb65, 0xfd27fb35, 0xf93df54b, 0xf14def5b, + 0xe76be76f, 0xe47af54c, 0xf62cf634, 0xf639f73a, 0xf048f945, 0xfc45fb4a, + 0xf7560242, 0xf7220120, 0x0b1f0534, 0xfe37fe43, 0x0049f859, 0x03340704, + 0x0a081108, 0x10130325, 0xff3dfb49, 0xff46fc4e, 0x0000eb7e, 0xe97cec6e, + 0xe67ee77c, 0xef69e579, 0xe575ef66, 0xe675e574, 0xdf7af65f, 0xf264f85f, + 0xef6fe472, 0xfa59fe50, 0xfc52f755, 0xf851ff48, 0x05400143, 0x09380045, + 0x01450745, 0xf945fa43, 0xf04dfe40, 0x023dfa43, 0xfd400239, 0xfd41fd42, + 0x003e0933, 0xff42fe47, 0xfe4bff46, 0xf7480e3c, 0x1025002f, 0x12230b25, + 0x0c290a29, 0x02300c29, 0x0d29003b, 0x03321328, 0x03421232, 0x13fa12fa, + 0x0e001af4, 0x1ff021e7, 0x21ea25e4, 0x27e22ae2, 0x2fd62ddc, 0x31de29ef, + 0x200945b9, 0x3fc142c0, 0x4db636d9, 0x34dd29f6, 0x240028ff, 0x1e0e1c1a, + 0x17250c37, 0x0b4125df, 0x27dc28db, 0x26e22edf, 0x2ae228e8, 0x31e326f4, + 0x28f626fd, 0x2efb1f14, 0x1d1e192c, 0x0c300b31, 0x1a2d1616, 0x17161b15, + 0x21141a1c, 0x1e181b22, 0x122a1927, 0x12320c46, 0x15360e47, 0x0b531920, + 0x15311536, 0xfb55fa51, 0xf64df951, 0xef50ee49, 0xfc4af653, 0xf747f743, + 0xff3df842, 0xf242003b, 0x023b11f6, 0x20f32af7, 0x31fb3500, 0x4003440a, + 0x421b2f39, 0xfb470018, 0xff24fe2a, 0xfe34f739, 0xfa3ffc41, 0xfc43f952, + 0xfd51fd4c, 0xf948fa4e, 0xf448f244, 0xfd46fa4c, 0xfb42fb3e, 0x0039fc3d, + 0xf73c0136, 0x023a11f6, 0x20f32af7, 0x31fb3500, 0x4003440a, 0x421b2f39, + 0x14f10236, 0x034a14f1, 0x0236034a, 0xe47fe968, 0xfa35ff36, 0x07331d10, + 0x19000e00, 0xf633fd3e, 0xe5631a10, 0xfc55e866, 0x05390639, 0xef490e39, + 0x1428140a, 0x1d003600, 0x252a0c61, 0xe07fea75, 0xfe4afc55, 0xe8660539, + 0xfa5df258, 0xfa2c0437, 0xf559f167, 0xeb741339, 0x143a0454, 0x0660013f, + 0xfb55f36a, 0x053f064b, 0xfd5aff65, 0x0337fc4f, 0xfe4bf461, 0xf932013c, + 0x0029003f, 0x003f003f, 0xf7530456, 0x0061f948, 0x0d29033e, 0x0722f758, + 0xec7fdc7f, 0xef5bf25f, 0xe754e756, 0xf459ef5b, 0xe17ff24c, 0xee67f35a, + 0xdb7f0b50, 0x054c0254, 0x054efa37, 0x043df253, 0xdb7ffb4f, 0xf568f55b, + 0xe27f0041, 0xfe4f0048, 0xfc5cfa38, 0x0344f847, 0xf362fc56, 0xf458fb52, + 0xfd48fc43, 0xf848f059, 0xf745ff3b, 0x05420439, 0xfc47fe47, 0x023aff4a, + 0xfc2cff45, 0x003ef933, 0xfc2ffa2a, 0xfd29fa35, 0x084cf74e, 0xf5530934, + 0x0043fb5a, 0x0143f148, 0xfb4bf850, 0xeb53eb40, 0xf31fe740, 0xe35e094b, + 0x113ff84a, 0xfb23fe1b, 0x0d5b0341, 0xf945084d, 0xf642033e, 0xfd44ec51, + 0x001e0107, 0xfd17eb4a, 0x1042e97c, 0x11252cee, 0x32deea7f, 0x0427002a, + 0x07220b1d, 0x081f0625, 0x072a0328, 0x08210d2b, 0x0d24042f, 0x0337023a, + 0x063c082c, 0x0b2c0e2a, 0x07300438, 0x04340d25, 0x0931133a, 0x0a300c2d, + 0x00451421, 0x083f23ee, 0x21e71cfd, 0x180a1b00, 0x22f234d4, 0x27e81311, + 0x1f19241d, 0x1821220f, 0x1e141649, 0x1422131f, 0x1b2c1310, 0x0f240f24, + 0x151c1915, 0x1e141f0c, 0x1b10182a, 0x005d0e38, 0x0f391a26, 0xe87fe873, + 0xea52f73e, 0x0035003b, 0xf255f359, 0xf35ef55c, 0xe37feb64, 0xf239f443, + 0xf547f64d, 0xeb55f058, 0xe968f162, 0xdb7ff652, 0xf830f83d, 0xf842f946, + 0xf24bf64f, 0xf753f45c, 0xee6cfc4f, 0xea45f04b, 0xfe3a013a, 0xf34ef753, + 0xfc51f363, 0xf351fa26, 0xf33efa3a, 0xfe3bf049, 0xf64cf356, 0xf753f657, + 0x0000ea7f, 0xe77fe778, 0xe57fed72, 0xe975e776, 0xe675e871, 0xe476e178, + 0xdb7cf65e, 0xf166f663, 0xf36ace7f, 0xfb5c1139, 0xfb56f35e, 0xf45bfe4d, + 0x0047ff49, 0x0440f951, 0x05400f39, 0x01430044, 0xf6430144, 0x004d0240, + 0x0044fb4e, 0x0737053b, 0x02410e36, 0x0f2c053c, 0x0246fe4c, 0xee560c46, + 0x0540f446, 0x0b370538, 0x00450241, 0xfa4a0536, 0x0736fa4c, 0xf552fe4d, + 0xfe4d192a, 0x11f310f7, 0x11f41beb, 0x25e229d8, 0x2ad730d1, 0x27e02ed8, + 0x34cd2ed7, 0x34d92bed, 0x200b3dc9, 0x38d23ece, 0x51bd2dec, 0x23fe1c0f, + 0x22012701, 0x1e111426, 0x122d0f36, 0x004f24f0, 0x25f225ef, 0x2001220f, + 0x1d0f1819, 0x22161f10, 0x23121f1c, 0x2129241c, 0x1b2f153e, 0x121f131a, + 0x24181817, 0x1b10181e, 0x1f1d1629, 0x162a103c, 0x0f340e3c, 0x034ef07b, + 0x15351638, 0x193d1521, 0x1332113d, 0xfd4ef84a, 0xf748f648, 0xee4bf447, + 0xf53ffb46, 0xef4bf248, 0xf043f835, 0xf23bf734, 0xf54409fe, 0x1ef61ffc, + 0x21ff2107, 0x1f0c2517, 0x1f261440, 0xf747f925, 0xf82cf531, 0xf638f43b, + 0xf83ff743, 0xfa44f64f, 0xfd4ef84a, 0xf748f648, 0xee4bf447, 0xf53ffb46, + 0xef4bf248, 0xf043f835, 0xf23bf734, 0xf54409fe, 0x1ef61ffc, 0x21ff2107, + 0x1f0c2517, 0x1f261440, +}; + +const RK_U32 g_ValueList[34] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33 +}; + + +static RK_U32 check_dpb_buffer_is_valid(H264dHalCtx_t *p_hal, RK_U32 dpb_idx) +{ + + (void)p_hal; + (void)dpb_idx; + + return 1; +} +static MPP_RET vdpu_set_refer_pic_idx(H264dVdpuRegs_t *p_regs, RK_U32 i, RK_U16 val) +{ + switch (i) { + case 0: + p_regs->sw76.num_ref_idx0 = val; + break; + case 1: + p_regs->sw76.num_ref_idx1 = val; + break; + case 2: + p_regs->sw77.num_ref_idx2 = val; + break; + case 3: + p_regs->sw77.num_ref_idx3 = val; + break; + case 4: + p_regs->sw78.num_ref_idx4 = val; + break; + case 5: + p_regs->sw78.num_ref_idx5 = val; + break; + case 6: + p_regs->sw79.num_ref_idx6 = val; + break; + case 7: + p_regs->sw79.num_ref_idx7 = val; + break; + case 8: + p_regs->sw80.num_ref_idx8 = val; + break; + case 9: + p_regs->sw80.num_ref_idx9 = val; + break; + case 10: + p_regs->sw81.num_ref_idx10 = val; + break; + case 11: + p_regs->sw81.num_ref_idx11 = val; + break; + case 12: + p_regs->sw82.num_ref_idx12 = val; + break; + case 13: + p_regs->sw82.num_ref_idx13 = val; + break; + case 14: + p_regs->sw83.num_ref_idx14 = val; + break; + case 15: + p_regs->sw83.num_ref_idx15 = val; + break; + default: + break; + } + + return MPP_OK; +} +static MPP_RET vdpu_set_refer_pic_list_p(H264dVdpuRegs_t *p_regs, RK_U32 i, RK_U16 val) +{ + switch (i) { + case 0: + p_regs->sw106.init_reflist_pf0 = val; + break; + case 1: + p_regs->sw106.init_reflist_pf1 = val; + break; + case 2: + p_regs->sw106.init_reflist_pf2 = val; + break; + case 3: + p_regs->sw106.init_reflist_pf3 = val; + break; + case 4: + p_regs->sw74.init_reflist_pf4 = val; + break; + case 5: + p_regs->sw74.init_reflist_pf5 = val; + break; + case 6: + p_regs->sw74.init_reflist_pf6 = val; + break; + case 7: + p_regs->sw74.init_reflist_pf7 = val; + break; + case 8: + p_regs->sw74.init_reflist_pf8 = val; + break; + case 9: + p_regs->sw74.init_reflist_pf9 = val; + break; + case 10: + p_regs->sw75.init_reflist_pf10 = val; + break; + case 11: + p_regs->sw75.init_reflist_pf11 = val; + break; + case 12: + p_regs->sw75.init_reflist_pf12 = val; + break; + case 13: + p_regs->sw75.init_reflist_pf13 = val; + break; + case 14: + p_regs->sw75.init_reflist_pf14 = val; + break; + case 15: + p_regs->sw75.init_reflist_pf15 = val; + break; + default: + break; + } + + return MPP_OK; +} +static MPP_RET vdpu_set_refer_pic_list_b0(H264dVdpuRegs_t *p_regs, RK_U32 i, RK_U16 val) +{ + switch (i) { + case 0: + p_regs->sw100.init_reflist_df0 = val; + break; + case 1: + p_regs->sw100.init_reflist_df1 = val; + break; + case 2: + p_regs->sw100.init_reflist_df2 = val; + break; + case 3: + p_regs->sw100.init_reflist_df3 = val; + break; + case 4: + p_regs->sw100.init_reflist_df4 = val; + break; + case 5: + p_regs->sw100.init_reflist_df5 = val; + break; + case 6: + p_regs->sw101.init_reflist_df6 = val; + break; + case 7: + p_regs->sw101.init_reflist_df7 = val; + break; + case 8: + p_regs->sw101.init_reflist_df8 = val; + break; + case 9: + p_regs->sw101.init_reflist_df9 = val; + break; + case 10: + p_regs->sw101.init_reflist_df10 = val; + break; + case 11: + p_regs->sw101.init_reflist_df11 = val; + break; + case 12: + p_regs->sw102.init_reflist_df12 = val; + break; + case 13: + p_regs->sw102.init_reflist_df13 = val; + break; + case 14: + p_regs->sw102.init_reflist_df14 = val; + break; + case 15: + p_regs->sw102.init_reflist_df15 = val; + break; + default: + break; + } + + return MPP_OK; +} +static MPP_RET vdpu_set_refer_pic_list_b1(H264dVdpuRegs_t *p_regs, RK_U32 i, RK_U16 val) +{ + switch (i) { + case 0: + p_regs->sw103.init_reflist_db0 = val; + break; + case 1: + p_regs->sw103.init_reflist_db1 = val; + break; + case 2: + p_regs->sw103.init_reflist_db2 = val; + break; + case 3: + p_regs->sw103.init_reflist_db3 = val; + break; + case 4: + p_regs->sw103.init_reflist_db4 = val; + break; + case 5: + p_regs->sw103.init_reflist_db5 = val; + break; + case 6: + p_regs->sw104.init_reflist_db6 = val; + break; + case 7: + p_regs->sw104.init_reflist_db7 = val; + break; + case 8: + p_regs->sw104.init_reflist_db8 = val; + break; + case 9: + p_regs->sw104.init_reflist_db9 = val; + break; + case 10: + p_regs->sw104.init_reflist_db10 = val; + break; + case 11: + p_regs->sw104.init_reflist_db11 = val; + break; + case 12: + p_regs->sw105.init_reflist_db12 = val; + break; + case 13: + p_regs->sw105.init_reflist_db13 = val; + break; + case 14: + p_regs->sw105.init_reflist_db14 = val; + break; + case 15: + p_regs->sw105.init_reflist_db15 = val; + break; + default: + break; + } + + return MPP_OK; +} + +static MPP_RET vdpu_set_refer_pic_base_addr(H264dVdpuRegs_t *p_regs, RK_U32 i, RK_U32 val) +{ + switch (i) { + case 0: + p_regs->sw84.ref0_st_addr = val; + break; + case 1: + p_regs->sw85.ref1_st_addr = val; + break; + case 2: + p_regs->sw86.ref2_st_addr = val; + break; + case 3: + p_regs->sw87.ref3_st_addr = val; + break; + case 4: + p_regs->sw88.ref4_st_addr = val; + break; + case 5: + p_regs->sw89.ref5_st_addr = val; + break; + case 6: + p_regs->sw90.ref6_st_addr = val; + break; + case 7: + p_regs->sw91.ref7_st_addr = val; + break; + case 8: + p_regs->sw92.ref8_st_addr = val; + break; + case 9: + p_regs->sw93.ref9_st_addr = val; + break; + case 10: + p_regs->sw94.ref10_st_addr = val; + break; + case 11: + p_regs->sw95.ref11_st_addr = val; + break; + case 12: + p_regs->sw96.ref12_st_addr = val; + break; + case 13: + p_regs->sw97.ref13_st_addr = val; + break; + case 14: + p_regs->sw98.ref14_st_addr = val; + break; + case 15: + p_regs->sw99.ref15_st_addr = val; + break; + default: + break; + } + return MPP_OK; +} +/*! +*********************************************************************** +* \brief +* set picture parameter and set register +*********************************************************************** +*/ +//extern "C" +MPP_RET vdpu_set_pic_regs(H264dHalCtx_t *p_hal, H264dVdpuRegs_t *p_regs) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + + p_regs->sw110.pic_mb_w = p_hal->pp->wFrameWidthInMbsMinus1 + 1; + p_regs->sw110.pic_mb_h = (2 - p_hal->pp->frame_mbs_only_flag) * (p_hal->pp->wFrameHeightInMbsMinus1 + 1); + + return ret = MPP_OK; +} +/*! +*********************************************************************** +* \brief +* set vlc register +*********************************************************************** +*/ +//extern "C" +MPP_RET vdpu_set_vlc_regs(H264dHalCtx_t *p_hal, H264dVdpuRegs_t *p_regs) +{ + RK_U32 i = 0; + MPP_RET ret = MPP_ERR_UNKNOW; + DXVA_PicParams_H264_MVC *pp = p_hal->pp; + + FunctionIn(p_hal->logctx.parr[RUN_HAL]); + + p_regs->sw57.dec_wr_extmen_dis = 0; + p_regs->sw57.rlc_mode_en = 0; + p_regs->sw51.qp_init_val = pp->pic_init_qp_minus26 + 26; + p_regs->sw114.max_refidx0 = pp->num_ref_idx_l0_active_minus1 + 1; + p_regs->sw111.max_refnum = pp->num_ref_frames; + p_regs->sw112.cur_frm_len = pp->log2_max_frame_num_minus4 + 4; + p_regs->sw112.curfrm_num = pp->frame_num; + p_regs->sw115.const_intra_en = pp->constrained_intra_pred_flag; + p_regs->sw112.dblk_ctrl_flag = pp->deblocking_filter_control_present_flag; + p_regs->sw112.rpcp_flag = pp->redundant_pic_cnt_present_flag; + p_regs->sw113.refpic_mk_len = p_hal->slice_long[0].drpm_used_bitlen; + p_regs->sw115.idr_pic_flag = p_hal->slice_long[0].idr_flag; + p_regs->sw113.idr_pic_id = p_hal->slice_long[0].idr_pic_id; + p_regs->sw114.pps_id = p_hal->slice_long[0].active_pps_id; + p_regs->sw114.poc_field_len = p_hal->slice_long[0].poc_used_bitlen; + /* reference picture flags, TODO separate fields */ + if (pp->field_pic_flag) { + RK_U32 validTmp = 0, validFlags = 0; + RK_U32 longTermTmp = 0, longTermflags = 0; + for (i = 0; i < 32; i++) { + if (pp->RefFrameList[i / 2].bPicEntry == 0xff) { //!< invalid + longTermflags <<= 1; + validFlags <<= 1; + } else { + longTermTmp = pp->RefFrameList[i / 2].AssociatedFlag; //!< get long term flag + longTermflags = (longTermflags << 1) | longTermTmp; + + validTmp = check_dpb_buffer_is_valid(p_hal, pp->RefFrameList[i / 2].Index7Bits); + validTmp = validTmp && ((pp->UsedForReferenceFlags >> i) & 0x01); + validFlags = (validFlags << 1) | validTmp; + } + } + p_regs->sw107.refpic_term_flag = longTermflags; + p_regs->sw108.refpic_valid_flag = validFlags; + } else { + RK_U32 validTmp = 0, validFlags = 0; + RK_U32 longTermTmp = 0, longTermflags = 0; + for (i = 0; i < 16; i++) { + if (pp->RefFrameList[i].bPicEntry == 0xff) { //!< invalid + longTermflags <<= 1; + validFlags <<= 1; + } else { + longTermTmp = pp->RefFrameList[i].AssociatedFlag; + longTermflags = (longTermflags << 1) | longTermTmp; + validTmp = check_dpb_buffer_is_valid(p_hal, pp->RefFrameList[i].Index7Bits); + validTmp = validTmp && ((pp->UsedForReferenceFlags >> (2 * i)) & 0x03); + validFlags = (validFlags << 1) | validTmp; + } + } + p_regs->sw107.refpic_term_flag = (longTermflags << 16); + p_regs->sw108.refpic_valid_flag = (validFlags << 16); + } + + for (i = 0; i < 16; i++) { + if (pp->RefFrameList[i].bPicEntry != 0xff) { //!< valid + if (pp->RefFrameList[i].AssociatedFlag) { //!< longterm flag + vdpu_set_refer_pic_idx(p_regs, i, pp->LongTermPicNumList[i]); //!< pic_num + } else { + vdpu_set_refer_pic_idx(p_regs, i, pp->FrameNumList[i]); //< frame_num + } + } + } + p_regs->sw57.rd_cnt_tab_en = 1; + //!< set poc to buffer + { + RK_U32 *pocBase = NULL; + pocBase = (RK_U32 *)((RK_U8 *)mpp_buffer_get_ptr(p_hal->cabac_buf) + VDPU_CABAC_TAB_SIZE); + //!< set reference reorder poc + for (i = 0; i < 32; i++) { + if (pp->RefFrameList[i / 2].bPicEntry != 0xff) { + *pocBase++ = pp->FieldOrderCntList[i / 2][i & 0x1]; + } else { + *pocBase++ = 0; + } + } + //!< set current poc + if (pp->field_pic_flag || !pp->MbaffFrameFlag) { + *pocBase++ = pp->CurrFieldOrderCnt[0]; + *pocBase++ = pp->CurrFieldOrderCnt[1]; + } else { + *pocBase++ = pp->CurrFieldOrderCnt[0]; + *pocBase++ = pp->CurrFieldOrderCnt[1]; + } + } + p_regs->sw115.cabac_en = pp->entropy_coding_mode_flag; + //!< stream position update + { + MppBuffer bitstream_buf = NULL; + p_regs->sw57.st_code_exit = 1; + mpp_buf_slot_get_prop(p_hal->packet_slots, p_hal->in_task->input, SLOT_BUFFER, &bitstream_buf); + p_regs->sw109.strm_start_bit = 0; //!< sodb stream start bit + if (VPUClientGetIOMMUStatus() > 0) { + p_regs->sw64.rlc_vlc_st_adr = mpp_buffer_get_fd(bitstream_buf); + } + p_regs->sw51.stream_len = p_hal->strm_len; + } + FunctionOut(p_hal->logctx.parr[RUN_HAL]); + + return ret = MPP_OK; +} +/*! +*********************************************************************** +* \brief +* set vlc reference +*********************************************************************** +*/ +//extern "C" +MPP_RET vdpu_set_ref_regs(H264dHalCtx_t *p_hal, H264dVdpuRegs_t *p_regs) +{ + RK_U32 i = 0, j = 0; + MPP_RET ret = MPP_ERR_UNKNOW; + DXVA_Slice_H264_Long *p_long = &p_hal->slice_long[0]; + + FunctionIn(p_hal->logctx.parr[RUN_HAL]); + //!< list0 list1 listP + for (j = 0; j < 3; j++) { + for (i = 0; i < 16; i++) { + RK_U16 val = 0; + if (p_hal->pp->field_pic_flag) { //!< field + RK_U32 nn = 0; + nn = p_hal->pp->CurrPic.AssociatedFlag ? (2 * i + 1) : (2 * i); + if (p_long->RefPicList[j][nn].bPicEntry == 0xff) { + val = g_ValueList[i]; + } else { + val = p_long->RefPicList[j][nn].Index7Bits; + } + } else { //!< frame + if (p_long->RefPicList[j][i].bPicEntry == 0xff) { + val = g_ValueList[i]; + } else { + val = p_long->RefPicList[j][i].Index7Bits; + } + } + switch (j) { + case 0: + vdpu_set_refer_pic_list_p(p_regs, i, val); + break; + case 1: + vdpu_set_refer_pic_list_b0(p_regs, i, val); + + break; + case 2: + vdpu_set_refer_pic_list_b1(p_regs, i, val); + + break; + default: + break; + } + } + } + FunctionOut(p_hal->logctx.parr[RUN_HAL]); + + return ret = MPP_OK; +} +/*! +*********************************************************************** +* \brief +* run Asic +*********************************************************************** +*/ +//extern "C" +MPP_RET vdpu_set_asic_regs(H264dHalCtx_t *p_hal, H264dVdpuRegs_t *p_regs) +{ + RK_U32 i = 0, j = 0; + RK_U32 outPhyAddr = 0; + MppBuffer frame_buf = NULL; + MPP_RET ret = MPP_ERR_UNKNOW; + DXVA_PicParams_H264_MVC *pp = p_hal->pp; + DXVA_Slice_H264_Long *p_long = &p_hal->slice_long[0]; + + FunctionIn(p_hal->logctx.parr[RUN_HAL]); + /* reference picture physic address */ + for (i = 0, j = 0xff; i < MPP_ARRAY_ELEMS(pp->RefFrameList); i++) { + RK_U32 val = 0; + RK_U32 top_closer = 0; + RK_U32 field_flag = 0; + if (pp->RefFrameList[i].bPicEntry != 0xff) { + mpp_buf_slot_get_prop(p_hal->frame_slots, pp->RefFrameList[i].Index7Bits, SLOT_BUFFER, &frame_buf); //!< reference phy addr + j = i; + } else { + mpp_buf_slot_get_prop(p_hal->frame_slots, pp->CurrPic.Index7Bits, SLOT_BUFFER, &frame_buf); //!< current out phy addr + } + + field_flag = ((pp->RefPicFiledFlags >> i) & 0x1) ? 0x2 : 0; + if (field_flag) { + RK_U32 used_flag = 0; + RK_S32 cur_poc = 0; + RK_S32 ref_poc = 0; + + cur_poc = pp->CurrPic.AssociatedFlag ? pp->CurrFieldOrderCnt[1] : pp->CurrFieldOrderCnt[0]; + used_flag = ((pp->UsedForReferenceFlags >> (2 * i)) & 0x3); + if (used_flag & 0x3) { + ref_poc = MPP_MIN(pp->FieldOrderCntList[i][0], pp->FieldOrderCntList[i][1]); + } else if (used_flag & 0x2) { + ref_poc = pp->FieldOrderCntList[i][1]; + } else if (used_flag & 0x1) { + ref_poc = pp->FieldOrderCntList[i][0]; + } + top_closer = (cur_poc < ref_poc) ? 0x1 : 0; + } + val = top_closer | field_flag; + + if (VPUClientGetIOMMUStatus() > 0) { + val = mpp_buffer_get_fd(frame_buf) | (val << 10); + } + vdpu_set_refer_pic_base_addr(p_regs, i, val); + } + /* inter-view reference picture */ + { + H264dVdpuPriv_t *priv = (H264dVdpuPriv_t *)p_hal->priv; + if (pp->curr_layer_id && priv->ilt_dpb && priv->ilt_dpb->valid /*pp->inter_view_flag*/) { + mpp_buf_slot_get_prop(p_hal->frame_slots, priv->ilt_dpb->slot_index, SLOT_BUFFER, &frame_buf); + + if (VPUClientGetIOMMUStatus() > 0) { + p_regs->sw99.ref15_st_addr = mpp_buffer_get_fd(frame_buf); //!< inter-view base, ref15 + } + p_regs->sw108.refpic_valid_flag |= (pp->field_pic_flag ? 0x3 : 0x10000); + } + } + p_regs->sw50.dec_fixed_quant = pp->curr_layer_id; //!< VDPU_MVC_E + p_regs->sw50.dblk_flt_dis = 0; //!< filterDisable = 0; + mpp_buf_slot_get_prop(p_hal->frame_slots, pp->CurrPic.Index7Bits, SLOT_BUFFER, &frame_buf); //!< current out phy addr + + if (VPUClientGetIOMMUStatus() > 0) { + outPhyAddr = mpp_buffer_get_fd(frame_buf); + } + if (pp->field_pic_flag && pp->CurrPic.AssociatedFlag) { + if (VPUClientGetIOMMUStatus() > 0) { + outPhyAddr |= ((pp->wFrameWidthInMbsMinus1 + 1) * 16) << 10; + } else { + outPhyAddr += (pp->wFrameWidthInMbsMinus1 + 1) * 16; + } + } + p_regs->sw63.dec_out_st_adr = outPhyAddr; //!< outPhyAddr, pp->CurrPic.Index7Bits + p_regs->sw110.flt_offset_cb_qp = pp->chroma_qp_index_offset; + p_regs->sw110.flt_offset_cr_qp = pp->second_chroma_qp_index_offset; + /* set default value for register[41] to avoid illegal translation fd */ + { + RK_U32 dirMvOffset = 0; + RK_U32 picSizeInMbs = 0; + + picSizeInMbs = p_hal->pp->wFrameWidthInMbsMinus1 + 1; + picSizeInMbs = picSizeInMbs * (2 - pp->frame_mbs_only_flag) * (pp->wFrameHeightInMbsMinus1 + 1); + dirMvOffset = picSizeInMbs * ((p_hal->pp->chroma_format_idc == 0) ? 256 : 384); + dirMvOffset += (pp->field_pic_flag && pp->CurrPic.AssociatedFlag) ? (picSizeInMbs * 32) : 0; + if (VPUClientGetIOMMUStatus() > 0) { + p_regs->sw62.dmmv_st_adr = (mpp_buffer_get_fd(frame_buf) | (dirMvOffset << 6)); + } + } + p_regs->sw57.dmmv_wr_en = (p_long->nal_ref_idc != 0) ? 1 : 0; //!< defalut set 1 + p_regs->sw115.dlmv_method_en = pp->direct_8x8_inference_flag; + p_regs->sw115.weight_pred_en = pp->weighted_pred_flag; + p_regs->sw111.wp_bslice_sel = pp->weighted_bipred_idc; + p_regs->sw114.max_refidx1 = (pp->num_ref_idx_l1_active_minus1 + 1); + p_regs->sw115.fieldpic_flag_exist = (!pp->frame_mbs_only_flag) ? 1 : 0; + p_regs->sw57.curpic_code_sel = (!pp->frame_mbs_only_flag && (pp->MbaffFrameFlag || pp->field_pic_flag)) ? 1 : 0; + p_regs->sw57.curpic_stru_sel = pp->field_pic_flag; + p_regs->sw57.pic_decfield_sel = (!pp->CurrPic.AssociatedFlag) ? 1 : 0; //!< bottomFieldFlag + p_regs->sw57.sequ_mbaff_en = pp->MbaffFrameFlag; + p_regs->sw115.tranf_8x8_flag_en = pp->transform_8x8_mode_flag; + p_regs->sw115.monochr_en = (p_long->profileIdc >= 100 && pp->chroma_format_idc == 0) ? 1 : 0; + p_regs->sw115.scl_matrix_en = pp->scaleing_list_enable_flag; + { + RK_U32 offset = VDPU_CABAC_TAB_SIZE + VDPU_POC_BUF_SIZE; + if (p_hal->pp->scaleing_list_enable_flag) { + RK_U32 temp = 0; + RK_U32 *ptr = NULL; + ptr = (RK_U32 *)((RK_U8 *)mpp_buffer_get_ptr(p_hal->cabac_buf) + offset); + for (i = 0; i < 6; i++) { + for (j = 0; j < 4; j++) { + temp = (p_hal->qm->bScalingLists4x4[i][4 * j + 0] << 24) | + (p_hal->qm->bScalingLists4x4[i][4 * j + 1] << 16) | + (p_hal->qm->bScalingLists4x4[i][4 * j + 2] << 8) | + (p_hal->qm->bScalingLists4x4[i][4 * j + 3]); + *ptr++ = temp; + } + } + for (i = 0; i < 2; i++) { + for (j = 0; j < 16; j++) { + temp = (p_hal->qm->bScalingLists8x8[i][4 * j + 0] << 24) | + (p_hal->qm->bScalingLists8x8[i][4 * j + 1] << 16) | + (p_hal->qm->bScalingLists8x8[i][4 * j + 2] << 8) | + (p_hal->qm->bScalingLists8x8[i][4 * j + 3]); + *ptr++ = temp; + } + } + } + if (VPUClientGetIOMMUStatus() > 0) { + p_regs->sw61.qtable_st_adr = mpp_buffer_get_fd(p_hal->cabac_buf); + } + } + p_regs->sw57.dec_wr_extmen_dis = 0; //!< set defalut 0 + p_regs->sw57.addit_ch_fmt_wen = 0; + p_regs->sw57.dec_st_work = 1; + FunctionOut(p_hal->logctx.parr[RUN_HAL]); + return ret = MPP_OK; +} + + diff --git a/mpp/hal/rkdec/h264d/hal_h264d_vdpu_pkt.h b/mpp/hal/rkdec/h264d/hal_h264d_vdpu_pkt.h index 3c96ed11..92ce2416 100644 --- a/mpp/hal/rkdec/h264d/hal_h264d_vdpu_pkt.h +++ b/mpp/hal/rkdec/h264d/hal_h264d_vdpu_pkt.h @@ -1,540 +1,540 @@ -/* -* -* Copyright 2015 Rockchip Electronics Co. LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#ifndef __HAL_H264D_VDPU_PKT_H__ -#define __HAL_H264D_VDPU_PKT_H__ - -#include "rk_type.h" -#include "mpp_err.h" -#include "hal_task.h" -#include "h264d_log.h" -#include "hal_h264d_fifo.h" -#include "hal_h264d_global.h" - -typedef struct { - RK_U32 sw00_49[50]; - struct { - RK_U32 dec_tiled_msb : 1; - RK_U32 adtion_latency : 6; - RK_U32 dec_fixed_quant : 1; - RK_U32 dblk_flt_dis : 1; - RK_U32 skip_sel : 1; - RK_U32 dec_ascmd0_dis : 1; - RK_U32 adv_pref_dis : 1; - RK_U32 dec_tiled_lsb : 1; - RK_U32 refbuf_thrd : 12; - RK_U32 refbuf_pid : 5; - RK_U32 reverse0 : 2; - } sw50; - struct { - RK_U32 stream_len : 24; - RK_U32 stream_len_ext : 1; - RK_U32 qp_init_val : 6; - RK_U32 reverse0 : 1; - } sw51; - struct { - RK_U32 ydim_mbst : 8; - RK_U32 xdim_mbst : 9; - RK_U32 adv_pref_thrd : 14; - RK_U32 reverse0 : 1; - } sw52; - struct { - RK_U32 dec_fmt_sel : 4; - RK_U32 reverse0 : 28; - } sw53; - struct { - RK_U32 dec_in_endian : 1; - RK_U32 dec_out_endian : 1; - RK_U32 dec_in_wordsp : 1; - RK_U32 dec_out_wordsp : 1; - RK_U32 dec_strm_wordsp : 1; - RK_U32 dec_strendian_e : 1; - RK_U32 reverse0 : 26; - } sw54; - struct { - RK_U32 dec_irq : 1; - RK_U32 dec_irq_dis : 1; - RK_U32 reverse0 : 2; - RK_U32 dec_rdy_sts : 1; - RK_U32 pp_bus_sts : 1; - RK_U32 buf_emt_sts : 1; - RK_U32 reverse1 : 1; - RK_U32 aso_det_sts : 1; - RK_U32 slice_det_sts : 1; - RK_U32 bslice_det_sts : 1; - RK_U32 reverse2 : 1; - RK_U32 error_det_sts : 1; - RK_U32 timeout_det_sts : 1; - RK_U32 reverse3 : 18; - } sw55; - struct { - RK_U32 dec_axi_id_rd : 8; - RK_U32 dec_axi_id_wr : 8; - RK_U32 dec_max_burlen : 5; - RK_U32 bus_pos_sel : 1; - RK_U32 dec_data_discd_en : 1; - RK_U32 axi_sel : 1; - RK_U32 reverse0 : 8; - } sw56; - struct { - RK_U32 dec_st_work : 1; - RK_U32 refpic_buf2_en : 1; - RK_U32 dec_wr_extmen_dis : 1; - RK_U32 reverse0 : 1; - RK_U32 dec_clkgate_en : 1; - RK_U32 timeout_sts_en : 1; - RK_U32 rd_cnt_tab_en : 1; - RK_U32 sequ_mbaff_en : 1; - RK_U32 first_reftop_en : 1; - RK_U32 reftop_en : 1; - RK_U32 dmmv_wr_en : 1; - RK_U32 sorspa_en : 1; - RK_U32 fwd_refpic_mode_sel : 1; - RK_U32 pic_decfield_sel : 1; - RK_U32 pic_type_sel0 : 1; - RK_U32 pic_type_sel1 : 1; - RK_U32 curpic_stru_sel : 1; - RK_U32 curpic_code_sel : 1; - RK_U32 prog_jpeg_en : 1; - RK_U32 divx3_en : 1; - RK_U32 rlc_mode_en : 1; - RK_U32 addit_ch_fmt_wen : 1; - RK_U32 st_code_exit : 1; - RK_U32 reverse1 : 2; - RK_U32 inter_dblspeed : 1; - RK_U32 intra_dblspeed : 1; - RK_U32 intra_dbl3t : 1; - RK_U32 pref_sigchan : 1; - RK_U32 cache_en : 1; - RK_U32 reverse2 : 1; - RK_U32 dec_timeout_mode : 1; - } sw57; - struct { - RK_U32 soft_rst : 1; - RK_U32 reverse0 : 31; - } sw58; - struct { - RK_U32 reverse0 : 2; - RK_U32 pflt_set0_tap2 : 10; - RK_U32 pflt_set0_tap1 : 10; - RK_U32 pflt_set0_tap0 : 10; - } sw59; - struct { - RK_U32 addit_ch_st_adr : 32; - } sw60; - struct { - RK_U32 qtable_st_adr : 32; - } sw61; - struct { - RK_U32 dmmv_st_adr : 32; - } sw62; - struct { - RK_U32 dec_out_st_adr : 32; - } sw63; - struct { - RK_U32 rlc_vlc_st_adr : 32; - } sw64; - struct { - RK_U32 refbuf_y_offset : 9; - RK_U32 reserve0 : 3; - RK_U32 refbuf_fildpar_mode_e : 1; - RK_U32 refbuf_idcal_e : 1; - RK_U32 refbuf_picid : 5; - RK_U32 refbuf_thr_level : 12; - RK_U32 refbuf_e : 1; - } sw65; - RK_U32 sw66; - RK_U32 sw67; - struct { - RK_U32 refbuf_sum_bot : 16; - RK_U32 refbuf_sum_top : 16; - } sw68; - struct { - RK_U32 luma_sum_intra : 16; - RK_U32 refbuf_sum_hit : 16; - } sw69; - struct { - RK_U32 ycomp_mv_sum : 22; - RK_U32 reserve0 : 10; - } sw70; - RK_U32 sw71; - RK_U32 sw72; - RK_U32 sw73; - struct { - RK_U32 init_reflist_pf4 : 5; - RK_U32 init_reflist_pf5 : 5; - RK_U32 init_reflist_pf6 : 5; - RK_U32 init_reflist_pf7 : 5; - RK_U32 init_reflist_pf8 : 5; - RK_U32 init_reflist_pf9 : 5; - RK_U32 reverse0 : 2; - } sw74; - struct { - RK_U32 init_reflist_pf10 : 5; - RK_U32 init_reflist_pf11 : 5; - RK_U32 init_reflist_pf12 : 5; - RK_U32 init_reflist_pf13 : 5; - RK_U32 init_reflist_pf14 : 5; - RK_U32 init_reflist_pf15 : 5; - RK_U32 reverse0 : 2; - } sw75; - struct { - RK_U32 num_ref_idx0 : 16; - RK_U32 num_ref_idx1 : 16; - } sw76; - struct { - RK_U32 num_ref_idx2 : 16; - RK_U32 num_ref_idx3 : 16; - } sw77; - struct { - RK_U32 num_ref_idx4 : 16; - RK_U32 num_ref_idx5 : 16; - } sw78; - struct { - RK_U32 num_ref_idx6 : 16; - RK_U32 num_ref_idx7 : 16; - } sw79; - struct { - RK_U32 num_ref_idx8 : 16; - RK_U32 num_ref_idx9 : 16; - } sw80; - struct { - RK_U32 num_ref_idx10 : 16; - RK_U32 num_ref_idx11 : 16; - } sw81; - struct { - RK_U32 num_ref_idx12 : 16; - RK_U32 num_ref_idx13 : 16; - } sw82; - struct { - RK_U32 num_ref_idx14 : 16; - RK_U32 num_ref_idx15 : 16; - } sw83; - union { - RK_U32 ref0_st_addr; - struct { - RK_U32 ref0_closer_sel : 1; - RK_U32 ref0_field_en : 1; - RK_U32 reverse0 : 30; - }; - } sw84; - union { - RK_U32 ref1_st_addr; - struct { - RK_U32 ref1_closer_sel : 1; - RK_U32 ref1_field_en : 1; - RK_U32 reverse0 : 30; - }; - } sw85; - union { - RK_U32 ref2_st_addr; - struct { - RK_U32 ref2_closer_sel : 1; - RK_U32 ref2_field_en : 1; - RK_U32 reverse0 : 30; - }; - } sw86; - union { - RK_U32 ref3_st_addr; - struct { - RK_U32 ref3_closer_sel : 1; - RK_U32 ref3_field_en : 1; - RK_U32 reverse0 : 30; - }; - } sw87; - union { - RK_U32 ref4_st_addr; - struct { - RK_U32 ref4_closer_sel : 1; - RK_U32 ref4_field_en : 1; - RK_U32 reverse0 : 30; - }; - } sw88; - union { - RK_U32 ref5_st_addr; - struct { - RK_U32 ref5_closer_sel : 1; - RK_U32 ref5_field_en : 1; - RK_U32 reverse0 : 30; - }; - } sw89; - union { - RK_U32 ref6_st_addr; - struct { - RK_U32 ref6_closer_sel : 1; - RK_U32 ref6_field_en : 1; - RK_U32 reverse0 : 30; - }; - } sw90; - union { - RK_U32 ref7_st_addr; - struct { - RK_U32 ref7_closer_sel : 1; - RK_U32 ref7_field_en : 1; - RK_U32 reverse0 : 30; - }; - } sw91; - union { - RK_U32 ref8_st_addr; - struct { - RK_U32 ref8_closer_sel : 1; - RK_U32 ref8_field_en : 1; - RK_U32 reverse0 : 30; - }; - } sw92; - union { - RK_U32 ref9_st_addr; - struct { - RK_U32 ref9_closer_sel : 1; - RK_U32 ref9_field_en : 1; - RK_U32 reverse0 : 30; - }; - } sw93; - union { - RK_U32 ref10_st_addr; - struct { - RK_U32 ref10_closer_sel : 1; - RK_U32 ref10_field_en : 1; - RK_U32 reverse0 : 30; - }; - } sw94; - union { - RK_U32 ref11_st_addr; - struct { - RK_U32 ref11_closer_sel : 1; - RK_U32 ref11_field_en : 1; - RK_U32 reverse0 : 30; - }; - } sw95; - union { - RK_U32 ref12_st_addr; - struct { - RK_U32 ref12_closer_sel : 1; - RK_U32 ref12_field_en : 1; - RK_U32 reverse0 : 30; - }; - } sw96; - union { - RK_U32 ref13_st_addr; - struct { - RK_U32 ref13_closer_sel : 1; - RK_U32 ref13_field_en : 1; - RK_U32 reverse0 : 30; - }; - } sw97; - union { - RK_U32 ref14_st_addr; - struct { - RK_U32 ref14_closer_sel : 1; - RK_U32 ref14_field_en : 1; - RK_U32 reverse0 : 30; - }; - } sw98; - union { - RK_U32 ref15_st_addr; - struct { - RK_U32 ref15_closer_sel : 1; - RK_U32 ref15_field_en : 1; - RK_U32 reverse0 : 30; - }; - } sw99; - struct { - RK_U32 init_reflist_df0 : 5; - RK_U32 init_reflist_df1 : 5; - RK_U32 init_reflist_df2 : 5; - RK_U32 init_reflist_df3 : 5; - RK_U32 init_reflist_df4 : 5; - RK_U32 init_reflist_df5 : 5; - RK_U32 reverse0 : 2; - } sw100; - struct { - RK_U32 init_reflist_df6 : 5; - RK_U32 init_reflist_df7 : 5; - RK_U32 init_reflist_df8 : 5; - RK_U32 init_reflist_df9 : 5; - RK_U32 init_reflist_df10 : 5; - RK_U32 init_reflist_df11 : 5; - RK_U32 reverse0 : 2; - } sw101; - struct { - RK_U32 init_reflist_df12 : 5; - RK_U32 init_reflist_df13 : 5; - RK_U32 init_reflist_df14 : 5; - RK_U32 init_reflist_df15 : 5; - RK_U32 reverse0 : 12; - } sw102; - struct { - RK_U32 init_reflist_db0 : 5; - RK_U32 init_reflist_db1 : 5; - RK_U32 init_reflist_db2 : 5; - RK_U32 init_reflist_db3 : 5; - RK_U32 init_reflist_db4 : 5; - RK_U32 init_reflist_db5 : 5; - RK_U32 reverse0 : 2; - } sw103; - struct { - RK_U32 init_reflist_db6 : 5; - RK_U32 init_reflist_db7 : 5; - RK_U32 init_reflist_db8 : 5; - RK_U32 init_reflist_db9 : 5; - RK_U32 init_reflist_db10 : 5; - RK_U32 init_reflist_db11 : 5; - RK_U32 reverse0 : 2; - } sw104; - struct { - RK_U32 init_reflist_db12 : 5; - RK_U32 init_reflist_db13 : 5; - RK_U32 init_reflist_db14 : 5; - RK_U32 init_reflist_db15 : 5; - RK_U32 reverse0 : 12; - } sw105; - struct { - RK_U32 init_reflist_pf0 : 5; - RK_U32 init_reflist_pf1 : 5; - RK_U32 init_reflist_pf2 : 5; - RK_U32 init_reflist_pf3 : 5; - RK_U32 reverse0 : 12; - } sw106; - struct { - RK_U32 refpic_term_flag : 32; - } sw107; - struct { - RK_U32 refpic_valid_flag : 32; - } sw108; - struct { - RK_U32 strm_start_bit : 6; - RK_U32 reverse0 : 26; - } sw109; - struct { - RK_U32 pic_mb_w : 9; - RK_U32 pic_mb_h : 8; - RK_U32 flt_offset_cb_qp : 5; - RK_U32 flt_offset_cr_qp : 5; - RK_U32 reverse0 : 5; - } sw110; - struct { - RK_U32 max_refnum : 5; - RK_U32 reverse0 : 11; - RK_U32 wp_bslice_sel : 2; - RK_U32 reverse1 : 14; - } sw111; - struct { - RK_U32 curfrm_num : 16; - RK_U32 cur_frm_len : 5; - RK_U32 reverse0 : 9; - RK_U32 rpcp_flag : 1; - RK_U32 dblk_ctrl_flag : 1; - } sw112; - struct { - RK_U32 idr_pic_id : 16; - RK_U32 refpic_mk_len : 11; - RK_U32 reverse0 : 5; - } sw113; - struct { - RK_U32 poc_field_len : 8; - RK_U32 reverse0 : 6; - RK_U32 max_refidx0 : 5; - RK_U32 max_refidx1 : 5; - RK_U32 pps_id : 5; - } sw114; - struct { - RK_U32 fieldpic_flag_exist : 1; - RK_U32 scl_matrix_en : 1; - RK_U32 tranf_8x8_flag_en : 1; - RK_U32 const_intra_en : 1; - RK_U32 weight_pred_en : 1; - RK_U32 cabac_en : 1; - RK_U32 monochr_en : 1; - RK_U32 dlmv_method_en : 1; - RK_U32 idr_pic_flag : 1; - RK_U32 reverse0 : 23; - } sw115; - RK_U32 sw116_158[43]; -} H264dVdpuRegs_t; - - -/* Number registers for the decoder */ -#define DEC_VDPU_REGISTERS 159 - - -#define VDPU_CABAC_TAB_SIZE (3680) /* bytes */ -#define VDPU_POC_BUF_SIZE (34*4) /* bytes */ -#define VDPU_SCALING_LIST_SIZE (6*16+2*64) /* bytes */ - -typedef struct h264d_vdpu_dpb_info_t { - RK_U8 valid; - - RK_S32 slot_index; - RK_U32 is_long_term; - RK_S32 TOP_POC; - RK_S32 BOT_POC; - RK_U16 frame_num; - RK_U32 long_term_frame_idx; - RK_U32 long_term_pic_num; - RK_U32 top_used; - RK_U32 bot_used; - RK_U32 view_id; - RK_U32 colmv_is_used; - RK_U32 field_flag; - RK_U32 is_ilt_flag; - RK_U32 voidx; - - RK_U8 have_same; - RK_U32 new_dpb_idx; -} H264dVdpuDpbInfo_t; - -typedef struct h264d_vdpu_ref_pic_info_t { - RK_U32 valid; - - RK_S32 dpb_idx; - RK_S32 bottom_flag; -} H264dVdpuRefPicInfo_t; - -typedef struct h264d_vdpu_priv_t { - RK_U32 layed_id; - - H264dVdpuDpbInfo_t old_dpb[2][16]; - H264dVdpuDpbInfo_t new_dpb[16]; - H264dVdpuDpbInfo_t *ilt_dpb; - H264dVdpuRefPicInfo_t refinfo[3][32]; //!< listP listB0 list1 -} H264dVdpuPriv_t; - - - -#ifdef __cplusplus -extern "C" { -#endif - -extern const RK_U32 H264_VDPU_Cabac_table[VDPU_CABAC_TAB_SIZE / 4]; - -MPP_RET vdpu_set_pic_regs(H264dHalCtx_t *p_hal, H264dVdpuRegs_t *p_regs); -MPP_RET vdpu_set_vlc_regs(H264dHalCtx_t *p_hal, H264dVdpuRegs_t *p_regs); -MPP_RET vdpu_set_ref_regs(H264dHalCtx_t *p_hal, H264dVdpuRegs_t *p_regs); -MPP_RET vdpu_set_asic_regs(H264dHalCtx_t *p_hal, H264dVdpuRegs_t *p_regs); - - -#ifdef __cplusplus -} -#endif - - - -//!<============================ -#endif /* __HAL_H264D_VDPU_PKT_H__ */ - - - +/* +* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef __HAL_H264D_VDPU_PKT_H__ +#define __HAL_H264D_VDPU_PKT_H__ + +#include "rk_type.h" +#include "mpp_err.h" +#include "hal_task.h" +#include "h264d_log.h" +#include "hal_h264d_fifo.h" +#include "hal_h264d_global.h" + +typedef struct { + RK_U32 sw00_49[50]; + struct { + RK_U32 dec_tiled_msb : 1; + RK_U32 adtion_latency : 6; + RK_U32 dec_fixed_quant : 1; + RK_U32 dblk_flt_dis : 1; + RK_U32 skip_sel : 1; + RK_U32 dec_ascmd0_dis : 1; + RK_U32 adv_pref_dis : 1; + RK_U32 dec_tiled_lsb : 1; + RK_U32 refbuf_thrd : 12; + RK_U32 refbuf_pid : 5; + RK_U32 reverse0 : 2; + } sw50; + struct { + RK_U32 stream_len : 24; + RK_U32 stream_len_ext : 1; + RK_U32 qp_init_val : 6; + RK_U32 reverse0 : 1; + } sw51; + struct { + RK_U32 ydim_mbst : 8; + RK_U32 xdim_mbst : 9; + RK_U32 adv_pref_thrd : 14; + RK_U32 reverse0 : 1; + } sw52; + struct { + RK_U32 dec_fmt_sel : 4; + RK_U32 reverse0 : 28; + } sw53; + struct { + RK_U32 dec_in_endian : 1; + RK_U32 dec_out_endian : 1; + RK_U32 dec_in_wordsp : 1; + RK_U32 dec_out_wordsp : 1; + RK_U32 dec_strm_wordsp : 1; + RK_U32 dec_strendian_e : 1; + RK_U32 reverse0 : 26; + } sw54; + struct { + RK_U32 dec_irq : 1; + RK_U32 dec_irq_dis : 1; + RK_U32 reverse0 : 2; + RK_U32 dec_rdy_sts : 1; + RK_U32 pp_bus_sts : 1; + RK_U32 buf_emt_sts : 1; + RK_U32 reverse1 : 1; + RK_U32 aso_det_sts : 1; + RK_U32 slice_det_sts : 1; + RK_U32 bslice_det_sts : 1; + RK_U32 reverse2 : 1; + RK_U32 error_det_sts : 1; + RK_U32 timeout_det_sts : 1; + RK_U32 reverse3 : 18; + } sw55; + struct { + RK_U32 dec_axi_id_rd : 8; + RK_U32 dec_axi_id_wr : 8; + RK_U32 dec_max_burlen : 5; + RK_U32 bus_pos_sel : 1; + RK_U32 dec_data_discd_en : 1; + RK_U32 axi_sel : 1; + RK_U32 reverse0 : 8; + } sw56; + struct { + RK_U32 dec_st_work : 1; + RK_U32 refpic_buf2_en : 1; + RK_U32 dec_wr_extmen_dis : 1; + RK_U32 reverse0 : 1; + RK_U32 dec_clkgate_en : 1; + RK_U32 timeout_sts_en : 1; + RK_U32 rd_cnt_tab_en : 1; + RK_U32 sequ_mbaff_en : 1; + RK_U32 first_reftop_en : 1; + RK_U32 reftop_en : 1; + RK_U32 dmmv_wr_en : 1; + RK_U32 sorspa_en : 1; + RK_U32 fwd_refpic_mode_sel : 1; + RK_U32 pic_decfield_sel : 1; + RK_U32 pic_type_sel0 : 1; + RK_U32 pic_type_sel1 : 1; + RK_U32 curpic_stru_sel : 1; + RK_U32 curpic_code_sel : 1; + RK_U32 prog_jpeg_en : 1; + RK_U32 divx3_en : 1; + RK_U32 rlc_mode_en : 1; + RK_U32 addit_ch_fmt_wen : 1; + RK_U32 st_code_exit : 1; + RK_U32 reverse1 : 2; + RK_U32 inter_dblspeed : 1; + RK_U32 intra_dblspeed : 1; + RK_U32 intra_dbl3t : 1; + RK_U32 pref_sigchan : 1; + RK_U32 cache_en : 1; + RK_U32 reverse2 : 1; + RK_U32 dec_timeout_mode : 1; + } sw57; + struct { + RK_U32 soft_rst : 1; + RK_U32 reverse0 : 31; + } sw58; + struct { + RK_U32 reverse0 : 2; + RK_U32 pflt_set0_tap2 : 10; + RK_U32 pflt_set0_tap1 : 10; + RK_U32 pflt_set0_tap0 : 10; + } sw59; + struct { + RK_U32 addit_ch_st_adr : 32; + } sw60; + struct { + RK_U32 qtable_st_adr : 32; + } sw61; + struct { + RK_U32 dmmv_st_adr : 32; + } sw62; + struct { + RK_U32 dec_out_st_adr : 32; + } sw63; + struct { + RK_U32 rlc_vlc_st_adr : 32; + } sw64; + struct { + RK_U32 refbuf_y_offset : 9; + RK_U32 reserve0 : 3; + RK_U32 refbuf_fildpar_mode_e : 1; + RK_U32 refbuf_idcal_e : 1; + RK_U32 refbuf_picid : 5; + RK_U32 refbuf_thr_level : 12; + RK_U32 refbuf_e : 1; + } sw65; + RK_U32 sw66; + RK_U32 sw67; + struct { + RK_U32 refbuf_sum_bot : 16; + RK_U32 refbuf_sum_top : 16; + } sw68; + struct { + RK_U32 luma_sum_intra : 16; + RK_U32 refbuf_sum_hit : 16; + } sw69; + struct { + RK_U32 ycomp_mv_sum : 22; + RK_U32 reserve0 : 10; + } sw70; + RK_U32 sw71; + RK_U32 sw72; + RK_U32 sw73; + struct { + RK_U32 init_reflist_pf4 : 5; + RK_U32 init_reflist_pf5 : 5; + RK_U32 init_reflist_pf6 : 5; + RK_U32 init_reflist_pf7 : 5; + RK_U32 init_reflist_pf8 : 5; + RK_U32 init_reflist_pf9 : 5; + RK_U32 reverse0 : 2; + } sw74; + struct { + RK_U32 init_reflist_pf10 : 5; + RK_U32 init_reflist_pf11 : 5; + RK_U32 init_reflist_pf12 : 5; + RK_U32 init_reflist_pf13 : 5; + RK_U32 init_reflist_pf14 : 5; + RK_U32 init_reflist_pf15 : 5; + RK_U32 reverse0 : 2; + } sw75; + struct { + RK_U32 num_ref_idx0 : 16; + RK_U32 num_ref_idx1 : 16; + } sw76; + struct { + RK_U32 num_ref_idx2 : 16; + RK_U32 num_ref_idx3 : 16; + } sw77; + struct { + RK_U32 num_ref_idx4 : 16; + RK_U32 num_ref_idx5 : 16; + } sw78; + struct { + RK_U32 num_ref_idx6 : 16; + RK_U32 num_ref_idx7 : 16; + } sw79; + struct { + RK_U32 num_ref_idx8 : 16; + RK_U32 num_ref_idx9 : 16; + } sw80; + struct { + RK_U32 num_ref_idx10 : 16; + RK_U32 num_ref_idx11 : 16; + } sw81; + struct { + RK_U32 num_ref_idx12 : 16; + RK_U32 num_ref_idx13 : 16; + } sw82; + struct { + RK_U32 num_ref_idx14 : 16; + RK_U32 num_ref_idx15 : 16; + } sw83; + union { + RK_U32 ref0_st_addr; + struct { + RK_U32 ref0_closer_sel : 1; + RK_U32 ref0_field_en : 1; + RK_U32 reverse0 : 30; + }; + } sw84; + union { + RK_U32 ref1_st_addr; + struct { + RK_U32 ref1_closer_sel : 1; + RK_U32 ref1_field_en : 1; + RK_U32 reverse0 : 30; + }; + } sw85; + union { + RK_U32 ref2_st_addr; + struct { + RK_U32 ref2_closer_sel : 1; + RK_U32 ref2_field_en : 1; + RK_U32 reverse0 : 30; + }; + } sw86; + union { + RK_U32 ref3_st_addr; + struct { + RK_U32 ref3_closer_sel : 1; + RK_U32 ref3_field_en : 1; + RK_U32 reverse0 : 30; + }; + } sw87; + union { + RK_U32 ref4_st_addr; + struct { + RK_U32 ref4_closer_sel : 1; + RK_U32 ref4_field_en : 1; + RK_U32 reverse0 : 30; + }; + } sw88; + union { + RK_U32 ref5_st_addr; + struct { + RK_U32 ref5_closer_sel : 1; + RK_U32 ref5_field_en : 1; + RK_U32 reverse0 : 30; + }; + } sw89; + union { + RK_U32 ref6_st_addr; + struct { + RK_U32 ref6_closer_sel : 1; + RK_U32 ref6_field_en : 1; + RK_U32 reverse0 : 30; + }; + } sw90; + union { + RK_U32 ref7_st_addr; + struct { + RK_U32 ref7_closer_sel : 1; + RK_U32 ref7_field_en : 1; + RK_U32 reverse0 : 30; + }; + } sw91; + union { + RK_U32 ref8_st_addr; + struct { + RK_U32 ref8_closer_sel : 1; + RK_U32 ref8_field_en : 1; + RK_U32 reverse0 : 30; + }; + } sw92; + union { + RK_U32 ref9_st_addr; + struct { + RK_U32 ref9_closer_sel : 1; + RK_U32 ref9_field_en : 1; + RK_U32 reverse0 : 30; + }; + } sw93; + union { + RK_U32 ref10_st_addr; + struct { + RK_U32 ref10_closer_sel : 1; + RK_U32 ref10_field_en : 1; + RK_U32 reverse0 : 30; + }; + } sw94; + union { + RK_U32 ref11_st_addr; + struct { + RK_U32 ref11_closer_sel : 1; + RK_U32 ref11_field_en : 1; + RK_U32 reverse0 : 30; + }; + } sw95; + union { + RK_U32 ref12_st_addr; + struct { + RK_U32 ref12_closer_sel : 1; + RK_U32 ref12_field_en : 1; + RK_U32 reverse0 : 30; + }; + } sw96; + union { + RK_U32 ref13_st_addr; + struct { + RK_U32 ref13_closer_sel : 1; + RK_U32 ref13_field_en : 1; + RK_U32 reverse0 : 30; + }; + } sw97; + union { + RK_U32 ref14_st_addr; + struct { + RK_U32 ref14_closer_sel : 1; + RK_U32 ref14_field_en : 1; + RK_U32 reverse0 : 30; + }; + } sw98; + union { + RK_U32 ref15_st_addr; + struct { + RK_U32 ref15_closer_sel : 1; + RK_U32 ref15_field_en : 1; + RK_U32 reverse0 : 30; + }; + } sw99; + struct { + RK_U32 init_reflist_df0 : 5; + RK_U32 init_reflist_df1 : 5; + RK_U32 init_reflist_df2 : 5; + RK_U32 init_reflist_df3 : 5; + RK_U32 init_reflist_df4 : 5; + RK_U32 init_reflist_df5 : 5; + RK_U32 reverse0 : 2; + } sw100; + struct { + RK_U32 init_reflist_df6 : 5; + RK_U32 init_reflist_df7 : 5; + RK_U32 init_reflist_df8 : 5; + RK_U32 init_reflist_df9 : 5; + RK_U32 init_reflist_df10 : 5; + RK_U32 init_reflist_df11 : 5; + RK_U32 reverse0 : 2; + } sw101; + struct { + RK_U32 init_reflist_df12 : 5; + RK_U32 init_reflist_df13 : 5; + RK_U32 init_reflist_df14 : 5; + RK_U32 init_reflist_df15 : 5; + RK_U32 reverse0 : 12; + } sw102; + struct { + RK_U32 init_reflist_db0 : 5; + RK_U32 init_reflist_db1 : 5; + RK_U32 init_reflist_db2 : 5; + RK_U32 init_reflist_db3 : 5; + RK_U32 init_reflist_db4 : 5; + RK_U32 init_reflist_db5 : 5; + RK_U32 reverse0 : 2; + } sw103; + struct { + RK_U32 init_reflist_db6 : 5; + RK_U32 init_reflist_db7 : 5; + RK_U32 init_reflist_db8 : 5; + RK_U32 init_reflist_db9 : 5; + RK_U32 init_reflist_db10 : 5; + RK_U32 init_reflist_db11 : 5; + RK_U32 reverse0 : 2; + } sw104; + struct { + RK_U32 init_reflist_db12 : 5; + RK_U32 init_reflist_db13 : 5; + RK_U32 init_reflist_db14 : 5; + RK_U32 init_reflist_db15 : 5; + RK_U32 reverse0 : 12; + } sw105; + struct { + RK_U32 init_reflist_pf0 : 5; + RK_U32 init_reflist_pf1 : 5; + RK_U32 init_reflist_pf2 : 5; + RK_U32 init_reflist_pf3 : 5; + RK_U32 reverse0 : 12; + } sw106; + struct { + RK_U32 refpic_term_flag : 32; + } sw107; + struct { + RK_U32 refpic_valid_flag : 32; + } sw108; + struct { + RK_U32 strm_start_bit : 6; + RK_U32 reverse0 : 26; + } sw109; + struct { + RK_U32 pic_mb_w : 9; + RK_U32 pic_mb_h : 8; + RK_U32 flt_offset_cb_qp : 5; + RK_U32 flt_offset_cr_qp : 5; + RK_U32 reverse0 : 5; + } sw110; + struct { + RK_U32 max_refnum : 5; + RK_U32 reverse0 : 11; + RK_U32 wp_bslice_sel : 2; + RK_U32 reverse1 : 14; + } sw111; + struct { + RK_U32 curfrm_num : 16; + RK_U32 cur_frm_len : 5; + RK_U32 reverse0 : 9; + RK_U32 rpcp_flag : 1; + RK_U32 dblk_ctrl_flag : 1; + } sw112; + struct { + RK_U32 idr_pic_id : 16; + RK_U32 refpic_mk_len : 11; + RK_U32 reverse0 : 5; + } sw113; + struct { + RK_U32 poc_field_len : 8; + RK_U32 reverse0 : 6; + RK_U32 max_refidx0 : 5; + RK_U32 max_refidx1 : 5; + RK_U32 pps_id : 5; + } sw114; + struct { + RK_U32 fieldpic_flag_exist : 1; + RK_U32 scl_matrix_en : 1; + RK_U32 tranf_8x8_flag_en : 1; + RK_U32 const_intra_en : 1; + RK_U32 weight_pred_en : 1; + RK_U32 cabac_en : 1; + RK_U32 monochr_en : 1; + RK_U32 dlmv_method_en : 1; + RK_U32 idr_pic_flag : 1; + RK_U32 reverse0 : 23; + } sw115; + RK_U32 sw116_158[43]; +} H264dVdpuRegs_t; + + +/* Number registers for the decoder */ +#define DEC_VDPU_REGISTERS 159 + + +#define VDPU_CABAC_TAB_SIZE (3680) /* bytes */ +#define VDPU_POC_BUF_SIZE (34*4) /* bytes */ +#define VDPU_SCALING_LIST_SIZE (6*16+2*64) /* bytes */ + +typedef struct h264d_vdpu_dpb_info_t { + RK_U8 valid; + + RK_S32 slot_index; + RK_U32 is_long_term; + RK_S32 TOP_POC; + RK_S32 BOT_POC; + RK_U16 frame_num; + RK_U32 long_term_frame_idx; + RK_U32 long_term_pic_num; + RK_U32 top_used; + RK_U32 bot_used; + RK_U32 view_id; + RK_U32 colmv_is_used; + RK_U32 field_flag; + RK_U32 is_ilt_flag; + RK_U32 voidx; + + RK_U8 have_same; + RK_U32 new_dpb_idx; +} H264dVdpuDpbInfo_t; + +typedef struct h264d_vdpu_ref_pic_info_t { + RK_U32 valid; + + RK_S32 dpb_idx; + RK_S32 bottom_flag; +} H264dVdpuRefPicInfo_t; + +typedef struct h264d_vdpu_priv_t { + RK_U32 layed_id; + + H264dVdpuDpbInfo_t old_dpb[2][16]; + H264dVdpuDpbInfo_t new_dpb[16]; + H264dVdpuDpbInfo_t *ilt_dpb; + H264dVdpuRefPicInfo_t refinfo[3][32]; //!< listP listB0 list1 +} H264dVdpuPriv_t; + + + +#ifdef __cplusplus +extern "C" { +#endif + +extern const RK_U32 H264_VDPU_Cabac_table[VDPU_CABAC_TAB_SIZE / 4]; + +MPP_RET vdpu_set_pic_regs(H264dHalCtx_t *p_hal, H264dVdpuRegs_t *p_regs); +MPP_RET vdpu_set_vlc_regs(H264dHalCtx_t *p_hal, H264dVdpuRegs_t *p_regs); +MPP_RET vdpu_set_ref_regs(H264dHalCtx_t *p_hal, H264dVdpuRegs_t *p_regs); +MPP_RET vdpu_set_asic_regs(H264dHalCtx_t *p_hal, H264dVdpuRegs_t *p_regs); + + +#ifdef __cplusplus +} +#endif + + + +//!<============================ +#endif /* __HAL_H264D_VDPU_PKT_H__ */ + + + diff --git a/mpp/hal/rkdec/h264d/hal_h264d_vdpu_reg.c b/mpp/hal/rkdec/h264d/hal_h264d_vdpu_reg.c index 918a7321..a3b957c3 100644 --- a/mpp/hal/rkdec/h264d/hal_h264d_vdpu_reg.c +++ b/mpp/hal/rkdec/h264d/hal_h264d_vdpu_reg.c @@ -1,554 +1,554 @@ -/* -* -* Copyright 2015 Rockchip Electronics Co. LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#define MODULE_TAG "hal_h264d_vdpu_reg" - -#include -#include -#include - -#include "rk_type.h" -#include "mpp_err.h" -#include "mpp_mem.h" -#include "vpu.h" -#include "mpp_time.h" - -#include "h264d_log.h" -#include "hal_regdrv.h" -#include "hal_h264d_global.h" -#include "hal_h264d_api.h" -#include "hal_h264d_vdpu_pkt.h" -#include "hal_h264d_vdpu_reg.h" - - -static RK_U32 vdpu_ver_align(RK_U32 val) -{ - return MPP_ALIGN(val, 16); -} - -static RK_U32 vdpu_hor_align(RK_U32 val) -{ - return MPP_ALIGN(val, 16); -} - -static MPP_RET vdpu_set_device_regs(H264dHalCtx_t *p_hal, H264dVdpuRegs_t *p_reg) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - - p_reg->sw53.dec_fmt_sel = 0; //!< set H264 mode - p_reg->sw54.dec_out_endian = 1; //!< little endian - p_reg->sw54.dec_in_endian = 0; //!< big endian - p_reg->sw54.dec_strendian_e = 1; //!< little endian - p_reg->sw50.dec_tiled_msb = 0; //!< 0: raster scan 1: tiled - p_reg->sw56.dec_max_burlen = 16; //!< (0, 4, 8, 16) choice one - p_reg->sw50.dec_ascmd0_dis = 0; //!< disable - p_reg->sw50.adv_pref_dis = 0; //!< disable - p_reg->sw52.adv_pref_thrd = 8; - p_reg->sw50.adtion_latency = 0; //!< compensation for bus latency; values up to 63 - p_reg->sw56.dec_data_discd_en = 0; - p_reg->sw54.dec_out_wordsp = 1;//!< little endian - p_reg->sw54.dec_in_wordsp = 1;//!< little endian - p_reg->sw54.dec_strm_wordsp = 1;//!< little endian - p_reg->sw57.timeout_sts_en = 1; - p_reg->sw57.dec_clkgate_en = 1; - p_reg->sw55.dec_irq_dis = 0; - //!< set AXI RW IDs - p_reg->sw56.dec_axi_id_rd = (0xFF & 0xFFU); //!< 0-255 - p_reg->sw56.dec_axi_id_wr = (0x0 & 0xFFU); //!< 0-255 - ///!< Set prediction filter taps - { - RK_U32 val = 0; - p_reg->sw59.pflt_set0_tap0 = 1; - val = (RK_U32)(-5); - p_reg->sw59.pflt_set0_tap1 = val; - p_reg->sw59.pflt_set0_tap2 = 20; - } - p_reg->sw50.adtion_latency = 0; - //!< clock_gating 0:clock always on, 1: clock gating module control the key(turn off when decoder free) - p_reg->sw57.dec_clkgate_en = 1; - p_reg->sw50.dec_tiled_msb = 0; //!< 0: raster scan 1: tiled - //!< bus_burst_length = 16, bus burst - p_reg->sw56.dec_max_burlen = 16; - p_reg->sw56.dec_data_discd_en = 0; - (void)p_hal; - - return ret = MPP_OK; -} - -static MPP_RET vdpu_get_info_input(H264dHalCtx_t *p_hal, H264dVdpuPriv_t *priv) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - DXVA_PicParams_H264_MVC *pp = p_hal->pp; - - memset(priv->new_dpb, 0, sizeof(priv->new_dpb)); - memset(priv->refinfo, 0, sizeof(priv->refinfo)); - //!< change dpb_info syntax - { - RK_U32 i = 0; - for (i = 0; i < MPP_ARRAY_ELEMS(pp->RefFrameList); i++) { - if (pp->RefFrameList[i].bPicEntry != 0xff) { - priv->new_dpb[i].valid = 1; - priv->new_dpb[i].is_long_term = pp->RefFrameList[i].AssociatedFlag; - priv->new_dpb[i].slot_index = pp->RefFrameList[i].Index7Bits; - priv->new_dpb[i].TOP_POC = pp->FieldOrderCntList[i][0]; - priv->new_dpb[i].BOT_POC = pp->FieldOrderCntList[i][1]; - if (priv->new_dpb[i].is_long_term) { - priv->new_dpb[i].long_term_frame_idx = pp->FrameNumList[i]; - } else { - priv->new_dpb[i].frame_num = pp->FrameNumList[i]; - } - priv->new_dpb[i].long_term_pic_num = pp->LongTermPicNumList[i]; - priv->new_dpb[i].top_used = ((pp->UsedForReferenceFlags >> (2 * i + 0)) & 0x1) ? 1 : 0; - priv->new_dpb[i].bot_used = ((pp->UsedForReferenceFlags >> (2 * i + 1)) & 0x1) ? 1 : 0; - } - } - for (i = 0; i < MPP_ARRAY_ELEMS(pp->ViewIDList); i++) { - priv->new_dpb[i].view_id = pp->ViewIDList[i]; - } - for (i = 0; i < MPP_ARRAY_ELEMS(pp->RefFrameList); i++) { - priv->new_dpb[i].colmv_is_used = ((pp->RefPicColmvUsedFlags >> i) & 0x1) ? 1 : 0; - priv->new_dpb[i].field_flag = ((pp->RefPicFiledFlags >> i) & 0x1) ? 1 : 0; - priv->new_dpb[i].is_ilt_flag = ((pp->UsedForInTerviewflags >> i) & 0x1) ? 1 : 0; - } - for (i = 0; i < MPP_ARRAY_ELEMS(pp->RefPicLayerIdList); i++) { - priv->new_dpb[i].voidx = pp->RefPicLayerIdList[i]; - } - } - //!< change ref_pic_info syntax - { - RK_U32 i = 0, j = 0; - DXVA_Slice_H264_Long *p_long = &p_hal->slice_long[0]; - //!< list P B0 B1 - for (j = 0; j < 3; j++) { - for (i = 0; i < MPP_ARRAY_ELEMS(p_long->RefPicList[j]); i++) { - if (p_long->RefPicList[j][i].bPicEntry != 0xff) { - priv->refinfo[j][i].valid = 1; - priv->refinfo[j][i].dpb_idx = p_long->RefPicList[j][i].Index7Bits; - priv->refinfo[j][i].bottom_flag = p_long->RefPicList[j][i].AssociatedFlag; - } - } - } - } - return ret = MPP_OK; -} - -static void fill_picture_entry(DXVA_PicEntry_H264 *pic, RK_U32 index, RK_U32 flag) -{ - ASSERT((index & 0x7f) == index && (flag & 0x01) == flag); - pic->bPicEntry = index | (flag << 7); -} - -static MPP_RET vdpu_refill_info_input(H264dHalCtx_t *p_hal, H264dVdpuPriv_t *priv) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - DXVA_PicParams_H264_MVC *pp = p_hal->pp; - { - RK_U32 i = 0; - H264dVdpuDpbInfo_t *old_dpb = priv->old_dpb[priv->layed_id]; - //!< re-fill dpb_info - pp->UsedForReferenceFlags = 0; - for (i = 0; i < MPP_ARRAY_ELEMS(pp->RefFrameList); i++) { - if (old_dpb[i].valid) { - fill_picture_entry(&pp->RefFrameList[i], old_dpb[i].slot_index, old_dpb[i].is_long_term); - pp->FieldOrderCntList[i][0] = old_dpb[i].TOP_POC; - pp->FieldOrderCntList[i][1] = old_dpb[i].BOT_POC; - pp->FrameNumList[i] = old_dpb[i].is_long_term ? old_dpb[i].long_term_frame_idx : old_dpb[i].frame_num; - pp->LongTermPicNumList[i] = old_dpb[i].long_term_pic_num; - if (old_dpb[i].top_used) { //!< top_field - pp->UsedForReferenceFlags |= 1 << (2 * i + 0); - } - if (old_dpb[i].bot_used) { //!< bot_field - pp->UsedForReferenceFlags |= 1 << (2 * i + 1); - } - } else { - pp->RefFrameList[i].bPicEntry = 0xff; - pp->FieldOrderCntList[i][0] = 0; - pp->FieldOrderCntList[i][1] = 0; - pp->FrameNumList[i] = 0; - pp->LongTermPicNumList[i] = 0; - } - } - for (i = 0; i < MPP_ARRAY_ELEMS(pp->ViewIDList); i++) { - pp->ViewIDList[i] = old_dpb[i].view_id; - } - pp->RefPicColmvUsedFlags = 0; - pp->RefPicFiledFlags = 0; - pp->UsedForInTerviewflags = 0; - for (i = 0; i < MPP_ARRAY_ELEMS(pp->RefFrameList); i++) { - if (old_dpb[i].colmv_is_used) { - pp->RefPicColmvUsedFlags |= 1 << i; - } - if (old_dpb[i].field_flag) { - pp->RefPicFiledFlags |= 1 << i; - } - if (old_dpb[i].is_ilt_flag) { - pp->UsedForInTerviewflags |= 1 << i; - } - } - for (i = 0; i < MPP_ARRAY_ELEMS(pp->RefPicLayerIdList); i++) { - pp->RefPicLayerIdList[i] = old_dpb[i].voidx; - } - } - //!< re-fill ref_info - { - RK_U32 i = 0, j = 0; - DXVA_Slice_H264_Long *p_long = &p_hal->slice_long[0]; - for (j = 0; j < 3; j++) { - H264dVdpuRefPicInfo_t *p = priv->refinfo[j]; - for (i = 0; i < MPP_ARRAY_ELEMS(p_long->RefPicList[j]); i++) { - if (p[i].valid) { - fill_picture_entry(&p_long->RefPicList[j][i], p[i].dpb_idx, p[i].bottom_flag); - } else { - p_long->RefPicList[j][i].bPicEntry = 0xff; - } - } - } - } - return ret = MPP_OK; -} -static MPP_RET vdpu_adjust_input(H264dHalCtx_t *p_hal, H264dVdpuPriv_t *priv) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - - priv->layed_id = p_hal->pp->curr_layer_id; - vdpu_get_info_input(p_hal, priv); - //!< dpb mapping to new order - { - RK_U32 i = 0, j = 0; - RK_U32 find_flag = 0; - H264dVdpuDpbInfo_t *new_dpb = priv->new_dpb; - H264dVdpuDpbInfo_t *old_dpb = priv->old_dpb[priv->layed_id]; - //!< delete old dpb - for (i = 0; i < MPP_ARRAY_ELEMS(priv->old_dpb[priv->layed_id]); i++) { - find_flag = 0; - if (old_dpb[i].valid) { - for (j = 0; j < MPP_ARRAY_ELEMS(priv->new_dpb); j++) { - if (new_dpb[j].valid) { - find_flag = ((old_dpb[i].frame_num == new_dpb[j].frame_num) ? 1 : 0); - find_flag = ((old_dpb[i].slot_index == new_dpb[j].slot_index) ? find_flag : 0); - if (new_dpb[j].top_used) { - find_flag = ((old_dpb[i].TOP_POC == new_dpb[j].TOP_POC) ? find_flag : 0); - } - if (new_dpb[j].bot_used) { - find_flag = ((old_dpb[i].BOT_POC == new_dpb[j].BOT_POC) ? find_flag : 0); - } - if (find_flag) { //!< found - new_dpb[j].have_same = 1; - new_dpb[j].new_dpb_idx = i; - break; - } - } - } - } - //!< not found - if (find_flag == 0) { - memset(&old_dpb[i], 0, sizeof(old_dpb[i])); - } - } - //!< add new dpb - for (j = 0; j < MPP_ARRAY_ELEMS(priv->new_dpb); j++) { - if ((new_dpb[j].valid == 0) || new_dpb[j].have_same) { - continue; - } - for (i = 0; i < MPP_ARRAY_ELEMS(priv->old_dpb[priv->layed_id]); i++) { - if (old_dpb[i].valid == 0) { - old_dpb[i] = new_dpb[j]; - new_dpb[j].new_dpb_idx = i; - break; - } - } - } - //!< inter-layer reference - priv->ilt_dpb = NULL; - if (priv->layed_id) { - for (i = 0; i < MPP_ARRAY_ELEMS(priv->old_dpb[1]); i++) { - if ((old_dpb[i].valid == 0) && old_dpb[i].is_ilt_flag) { - priv->ilt_dpb = &old_dpb[i]; - break; - } - } - } - } - //!< addjust ref_dpb - { - RK_U32 i = 0, j = 0; - H264dVdpuDpbInfo_t *new_dpb = priv->new_dpb; - - for (j = 0; j < 3; j++) { - H264dVdpuRefPicInfo_t *p = priv->refinfo[j]; - for (i = 0; i < MPP_ARRAY_ELEMS(priv->refinfo[j]); i++) { - if (p[i].valid) { - p[i].dpb_idx = new_dpb[p[i].dpb_idx].new_dpb_idx; - } - } - } - } - vdpu_refill_info_input(p_hal, priv); - - return ret = MPP_OK; -} -/*! -*********************************************************************** -* \brief -* init VDPU granite decoder -*********************************************************************** -*/ -//extern "C" -MPP_RET vdpu_h264d_init(void *hal, MppHalCfg *cfg) -{ - RK_U32 cabac_size = 0; - MPP_RET ret = MPP_ERR_UNKNOW; - H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal; - INP_CHECK(ret, NULL == hal); - - //!< malloc init registers - MEM_CHECK(ret, p_hal->regs = mpp_calloc_size(void, sizeof(H264dVdpuRegs_t))); - MEM_CHECK(ret, p_hal->priv = mpp_calloc_size(void, sizeof(H264dVdpuPriv_t))); - //!< malloc cabac+scanlis + packets + poc_buf - cabac_size = VDPU_CABAC_TAB_SIZE + VDPU_SCALING_LIST_SIZE + VDPU_POC_BUF_SIZE; - FUN_CHECK(ret = mpp_buffer_get(p_hal->buf_group, &p_hal->cabac_buf, cabac_size)); - //!< copy cabac table bytes - FUN_CHECK(ret = mpp_buffer_write(p_hal->cabac_buf, 0, (void *)H264_VDPU_Cabac_table, sizeof(H264_VDPU_Cabac_table))); - FUN_CHECK(ret = vdpu_set_device_regs(p_hal, (H264dVdpuRegs_t *)p_hal->regs)); - mpp_slots_set_prop(p_hal->frame_slots, SLOTS_HOR_ALIGN, vdpu_hor_align); - mpp_slots_set_prop(p_hal->frame_slots, SLOTS_VER_ALIGN, vdpu_ver_align); - mpp_slots_set_prop(p_hal->frame_slots, SLOTS_LEN_ALIGN, NULL); - p_hal->iDecodedNum = 0; - - (void)cfg; -__RETURN: - return MPP_OK; -__FAILED: - vdpu_h264d_deinit(hal); - - return ret; -} - - -/*! -*********************************************************************** -* \brief -* deinit -*********************************************************************** -*/ -//extern "C" -MPP_RET vdpu_h264d_deinit(void *hal) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal; - - INP_CHECK(ret, NULL == p_hal); - - FunctionIn(p_hal->logctx.parr[RUN_HAL]); - - MPP_FREE(p_hal->regs); - MPP_FREE(p_hal->priv); - if (p_hal->cabac_buf) { - FUN_CHECK(ret = mpp_buffer_put(p_hal->cabac_buf)); - } - - FunctionOut(p_hal->logctx.parr[RUN_HAL]); -__RETURN: - return ret = MPP_OK; -__FAILED: - return ret; -} -/*! -*********************************************************************** -* \brief -* generate register -*********************************************************************** -*/ -//extern "C" -MPP_RET vdpu_h264d_gen_regs(void *hal, HalTaskInfo *task) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - - H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal; - INP_CHECK(ret, NULL == p_hal); - FunctionIn(p_hal->logctx.parr[RUN_HAL]); - p_hal->in_task = &task->dec; - if (task->dec.flags.had_error) { - goto __RETURN; - } - LogTrace(p_hal->logctx.parr[RUN_HAL], "[Generate register begin]"); - FUN_CHECK(ret = vdpu_adjust_input(p_hal, (H264dVdpuPriv_t *)p_hal->priv)); - FUN_CHECK(ret = vdpu_set_pic_regs(p_hal, (H264dVdpuRegs_t *)p_hal->regs)); - FUN_CHECK(ret = vdpu_set_vlc_regs(p_hal, (H264dVdpuRegs_t *)p_hal->regs)); - FUN_CHECK(ret = vdpu_set_ref_regs(p_hal, (H264dVdpuRegs_t *)p_hal->regs)); - FUN_CHECK(ret = vdpu_set_asic_regs(p_hal, (H264dVdpuRegs_t *)p_hal->regs)); - LogTrace(p_hal->logctx.parr[RUN_HAL], "[Generate register end]"); - p_hal->in_task->valid = 0; - FunctionOut(p_hal->logctx.parr[RUN_HAL]); -__RETURN: - return ret = MPP_OK; -__FAILED: - return ret; -} -/*! -*********************************************************************** -* \brief h -* start hard -*********************************************************************** -*/ -//extern "C" -MPP_RET vdpu_h264d_start(void *hal, HalTaskInfo *task) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal; - H264dVdpuRegs_t *p_regs = (H264dVdpuRegs_t *)p_hal->regs; - - FunctionIn(p_hal->logctx.parr[RUN_HAL]); - if (task->dec.flags.had_error) { - goto __RETURN; - } - p_regs->sw57.cache_en = 1; - p_regs->sw57.pref_sigchan = 1; - p_regs->sw56.bus_pos_sel = 1; - p_regs->sw57.intra_dbl3t = 1; - p_regs->sw57.inter_dblspeed = 1; - p_regs->sw57.intra_dblspeed = 1; -#ifdef RKPLATFORM - if (VPUClientSendReg(p_hal->vpu_socket, (RK_U32 *)p_hal->regs, DEC_VDPU_REGISTERS)) { - ret = MPP_ERR_VPUHW; - mpp_err_f("H264 VDPU FlushRegs fail, pid=%d, hal_frame_no=%d. \n", getpid(), p_hal->iDecodedNum); - } else { - H264D_LOG("H264 VDPU FlushRegs success, pid=%d, hal_frame_no=%d. \n", getpid(), p_hal->iDecodedNum); - } -#endif -__RETURN: - FunctionOut(p_hal->logctx.parr[RUN_HAL]); - (void)task; - return ret = MPP_OK; -} -/*! -*********************************************************************** -* \brief -* wait hard -*********************************************************************** -*/ -//extern "C" -MPP_RET vdpu_h264d_wait(void *hal, HalTaskInfo *task) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal; - H264dVdpuRegs_t *p_regs = (H264dVdpuRegs_t *)p_hal->regs; - - FunctionIn(p_hal->logctx.parr[RUN_HAL]); - - if (task->dec.flags.had_error) { - goto __SKIP_HARD; - } -#ifdef RKPLATFORM - { - RK_S32 wait_ret = -1; - RK_S32 ret_len = 0, cur_deat = 0; - VPU_CMD_TYPE ret_cmd = VPU_CMD_BUTT; - RK_S64 p_s, p_e; - p_s = mpp_time(); - wait_ret = VPUClientWaitResult(p_hal->vpu_socket, (RK_U32 *)p_hal->regs, DEC_VDPU_REGISTERS, &ret_cmd, &ret_len); - p_e = mpp_time(); - cur_deat = (p_e - p_s) / 1000; - p_hal->total_time += cur_deat; - p_hal->iDecodedNum++; - (void)wait_ret; - } -#endif - -__SKIP_HARD: - if (p_hal->init_cb.callBack) { - IOCallbackCtx m_ctx = { 0 }; - m_ctx.device_id = HAL_VDPU; - if (!p_regs->sw55.dec_rdy_sts) { - m_ctx.hard_err = 1; - } - m_ctx.task = (void *)&task->dec; - m_ctx.regs = (RK_U32 *)p_hal->regs; - p_hal->init_cb.callBack(p_hal->init_cb.opaque, &m_ctx); - } - memset(&p_regs->sw55, 0, sizeof(RK_U32)); - FunctionOut(p_hal->logctx.parr[RUN_HAL]); - (void)task; - - return ret = MPP_OK; -} -/*! -*********************************************************************** -* \brief -* reset -*********************************************************************** -*/ -//extern "C" -MPP_RET vdpu_h264d_reset(void *hal) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal; - - INP_CHECK(ret, NULL == p_hal); - FunctionIn(p_hal->logctx.parr[RUN_HAL]); - - memset(p_hal->priv, 0, sizeof(H264dVdpuPriv_t)); - - FunctionOut(p_hal->logctx.parr[RUN_HAL]); -__RETURN: - return ret = MPP_OK; -} -/*! -*********************************************************************** -* \brief -* flush -*********************************************************************** -*/ -//extern "C" -MPP_RET vdpu_h264d_flush(void *hal) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal; - - INP_CHECK(ret, NULL == p_hal); - FunctionIn(p_hal->logctx.parr[RUN_HAL]); - - - - FunctionOut(p_hal->logctx.parr[RUN_HAL]); -__RETURN: - return ret = MPP_OK; -} -/*! -*********************************************************************** -* \brief -* control -*********************************************************************** -*/ -//extern "C" -MPP_RET vdpu_h264d_control(void *hal, RK_S32 cmd_type, void *param) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal; - - INP_CHECK(ret, NULL == p_hal); - FunctionIn(p_hal->logctx.parr[RUN_HAL]); - - - - FunctionOut(p_hal->logctx.parr[RUN_HAL]); - (void)hal; - (void)cmd_type; - (void)param; -__RETURN: - return ret = MPP_OK; -} +/* +* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#define MODULE_TAG "hal_h264d_vdpu_reg" + +#include +#include +#include + +#include "rk_type.h" +#include "mpp_err.h" +#include "mpp_mem.h" +#include "vpu.h" +#include "mpp_time.h" + +#include "h264d_log.h" +#include "hal_regdrv.h" +#include "hal_h264d_global.h" +#include "hal_h264d_api.h" +#include "hal_h264d_vdpu_pkt.h" +#include "hal_h264d_vdpu_reg.h" + + +static RK_U32 vdpu_ver_align(RK_U32 val) +{ + return MPP_ALIGN(val, 16); +} + +static RK_U32 vdpu_hor_align(RK_U32 val) +{ + return MPP_ALIGN(val, 16); +} + +static MPP_RET vdpu_set_device_regs(H264dHalCtx_t *p_hal, H264dVdpuRegs_t *p_reg) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + + p_reg->sw53.dec_fmt_sel = 0; //!< set H264 mode + p_reg->sw54.dec_out_endian = 1; //!< little endian + p_reg->sw54.dec_in_endian = 0; //!< big endian + p_reg->sw54.dec_strendian_e = 1; //!< little endian + p_reg->sw50.dec_tiled_msb = 0; //!< 0: raster scan 1: tiled + p_reg->sw56.dec_max_burlen = 16; //!< (0, 4, 8, 16) choice one + p_reg->sw50.dec_ascmd0_dis = 0; //!< disable + p_reg->sw50.adv_pref_dis = 0; //!< disable + p_reg->sw52.adv_pref_thrd = 8; + p_reg->sw50.adtion_latency = 0; //!< compensation for bus latency; values up to 63 + p_reg->sw56.dec_data_discd_en = 0; + p_reg->sw54.dec_out_wordsp = 1;//!< little endian + p_reg->sw54.dec_in_wordsp = 1;//!< little endian + p_reg->sw54.dec_strm_wordsp = 1;//!< little endian + p_reg->sw57.timeout_sts_en = 1; + p_reg->sw57.dec_clkgate_en = 1; + p_reg->sw55.dec_irq_dis = 0; + //!< set AXI RW IDs + p_reg->sw56.dec_axi_id_rd = (0xFF & 0xFFU); //!< 0-255 + p_reg->sw56.dec_axi_id_wr = (0x0 & 0xFFU); //!< 0-255 + ///!< Set prediction filter taps + { + RK_U32 val = 0; + p_reg->sw59.pflt_set0_tap0 = 1; + val = (RK_U32)(-5); + p_reg->sw59.pflt_set0_tap1 = val; + p_reg->sw59.pflt_set0_tap2 = 20; + } + p_reg->sw50.adtion_latency = 0; + //!< clock_gating 0:clock always on, 1: clock gating module control the key(turn off when decoder free) + p_reg->sw57.dec_clkgate_en = 1; + p_reg->sw50.dec_tiled_msb = 0; //!< 0: raster scan 1: tiled + //!< bus_burst_length = 16, bus burst + p_reg->sw56.dec_max_burlen = 16; + p_reg->sw56.dec_data_discd_en = 0; + (void)p_hal; + + return ret = MPP_OK; +} + +static MPP_RET vdpu_get_info_input(H264dHalCtx_t *p_hal, H264dVdpuPriv_t *priv) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + DXVA_PicParams_H264_MVC *pp = p_hal->pp; + + memset(priv->new_dpb, 0, sizeof(priv->new_dpb)); + memset(priv->refinfo, 0, sizeof(priv->refinfo)); + //!< change dpb_info syntax + { + RK_U32 i = 0; + for (i = 0; i < MPP_ARRAY_ELEMS(pp->RefFrameList); i++) { + if (pp->RefFrameList[i].bPicEntry != 0xff) { + priv->new_dpb[i].valid = 1; + priv->new_dpb[i].is_long_term = pp->RefFrameList[i].AssociatedFlag; + priv->new_dpb[i].slot_index = pp->RefFrameList[i].Index7Bits; + priv->new_dpb[i].TOP_POC = pp->FieldOrderCntList[i][0]; + priv->new_dpb[i].BOT_POC = pp->FieldOrderCntList[i][1]; + if (priv->new_dpb[i].is_long_term) { + priv->new_dpb[i].long_term_frame_idx = pp->FrameNumList[i]; + } else { + priv->new_dpb[i].frame_num = pp->FrameNumList[i]; + } + priv->new_dpb[i].long_term_pic_num = pp->LongTermPicNumList[i]; + priv->new_dpb[i].top_used = ((pp->UsedForReferenceFlags >> (2 * i + 0)) & 0x1) ? 1 : 0; + priv->new_dpb[i].bot_used = ((pp->UsedForReferenceFlags >> (2 * i + 1)) & 0x1) ? 1 : 0; + } + } + for (i = 0; i < MPP_ARRAY_ELEMS(pp->ViewIDList); i++) { + priv->new_dpb[i].view_id = pp->ViewIDList[i]; + } + for (i = 0; i < MPP_ARRAY_ELEMS(pp->RefFrameList); i++) { + priv->new_dpb[i].colmv_is_used = ((pp->RefPicColmvUsedFlags >> i) & 0x1) ? 1 : 0; + priv->new_dpb[i].field_flag = ((pp->RefPicFiledFlags >> i) & 0x1) ? 1 : 0; + priv->new_dpb[i].is_ilt_flag = ((pp->UsedForInTerviewflags >> i) & 0x1) ? 1 : 0; + } + for (i = 0; i < MPP_ARRAY_ELEMS(pp->RefPicLayerIdList); i++) { + priv->new_dpb[i].voidx = pp->RefPicLayerIdList[i]; + } + } + //!< change ref_pic_info syntax + { + RK_U32 i = 0, j = 0; + DXVA_Slice_H264_Long *p_long = &p_hal->slice_long[0]; + //!< list P B0 B1 + for (j = 0; j < 3; j++) { + for (i = 0; i < MPP_ARRAY_ELEMS(p_long->RefPicList[j]); i++) { + if (p_long->RefPicList[j][i].bPicEntry != 0xff) { + priv->refinfo[j][i].valid = 1; + priv->refinfo[j][i].dpb_idx = p_long->RefPicList[j][i].Index7Bits; + priv->refinfo[j][i].bottom_flag = p_long->RefPicList[j][i].AssociatedFlag; + } + } + } + } + return ret = MPP_OK; +} + +static void fill_picture_entry(DXVA_PicEntry_H264 *pic, RK_U32 index, RK_U32 flag) +{ + ASSERT((index & 0x7f) == index && (flag & 0x01) == flag); + pic->bPicEntry = index | (flag << 7); +} + +static MPP_RET vdpu_refill_info_input(H264dHalCtx_t *p_hal, H264dVdpuPriv_t *priv) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + DXVA_PicParams_H264_MVC *pp = p_hal->pp; + { + RK_U32 i = 0; + H264dVdpuDpbInfo_t *old_dpb = priv->old_dpb[priv->layed_id]; + //!< re-fill dpb_info + pp->UsedForReferenceFlags = 0; + for (i = 0; i < MPP_ARRAY_ELEMS(pp->RefFrameList); i++) { + if (old_dpb[i].valid) { + fill_picture_entry(&pp->RefFrameList[i], old_dpb[i].slot_index, old_dpb[i].is_long_term); + pp->FieldOrderCntList[i][0] = old_dpb[i].TOP_POC; + pp->FieldOrderCntList[i][1] = old_dpb[i].BOT_POC; + pp->FrameNumList[i] = old_dpb[i].is_long_term ? old_dpb[i].long_term_frame_idx : old_dpb[i].frame_num; + pp->LongTermPicNumList[i] = old_dpb[i].long_term_pic_num; + if (old_dpb[i].top_used) { //!< top_field + pp->UsedForReferenceFlags |= 1 << (2 * i + 0); + } + if (old_dpb[i].bot_used) { //!< bot_field + pp->UsedForReferenceFlags |= 1 << (2 * i + 1); + } + } else { + pp->RefFrameList[i].bPicEntry = 0xff; + pp->FieldOrderCntList[i][0] = 0; + pp->FieldOrderCntList[i][1] = 0; + pp->FrameNumList[i] = 0; + pp->LongTermPicNumList[i] = 0; + } + } + for (i = 0; i < MPP_ARRAY_ELEMS(pp->ViewIDList); i++) { + pp->ViewIDList[i] = old_dpb[i].view_id; + } + pp->RefPicColmvUsedFlags = 0; + pp->RefPicFiledFlags = 0; + pp->UsedForInTerviewflags = 0; + for (i = 0; i < MPP_ARRAY_ELEMS(pp->RefFrameList); i++) { + if (old_dpb[i].colmv_is_used) { + pp->RefPicColmvUsedFlags |= 1 << i; + } + if (old_dpb[i].field_flag) { + pp->RefPicFiledFlags |= 1 << i; + } + if (old_dpb[i].is_ilt_flag) { + pp->UsedForInTerviewflags |= 1 << i; + } + } + for (i = 0; i < MPP_ARRAY_ELEMS(pp->RefPicLayerIdList); i++) { + pp->RefPicLayerIdList[i] = old_dpb[i].voidx; + } + } + //!< re-fill ref_info + { + RK_U32 i = 0, j = 0; + DXVA_Slice_H264_Long *p_long = &p_hal->slice_long[0]; + for (j = 0; j < 3; j++) { + H264dVdpuRefPicInfo_t *p = priv->refinfo[j]; + for (i = 0; i < MPP_ARRAY_ELEMS(p_long->RefPicList[j]); i++) { + if (p[i].valid) { + fill_picture_entry(&p_long->RefPicList[j][i], p[i].dpb_idx, p[i].bottom_flag); + } else { + p_long->RefPicList[j][i].bPicEntry = 0xff; + } + } + } + } + return ret = MPP_OK; +} +static MPP_RET vdpu_adjust_input(H264dHalCtx_t *p_hal, H264dVdpuPriv_t *priv) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + + priv->layed_id = p_hal->pp->curr_layer_id; + vdpu_get_info_input(p_hal, priv); + //!< dpb mapping to new order + { + RK_U32 i = 0, j = 0; + RK_U32 find_flag = 0; + H264dVdpuDpbInfo_t *new_dpb = priv->new_dpb; + H264dVdpuDpbInfo_t *old_dpb = priv->old_dpb[priv->layed_id]; + //!< delete old dpb + for (i = 0; i < MPP_ARRAY_ELEMS(priv->old_dpb[priv->layed_id]); i++) { + find_flag = 0; + if (old_dpb[i].valid) { + for (j = 0; j < MPP_ARRAY_ELEMS(priv->new_dpb); j++) { + if (new_dpb[j].valid) { + find_flag = ((old_dpb[i].frame_num == new_dpb[j].frame_num) ? 1 : 0); + find_flag = ((old_dpb[i].slot_index == new_dpb[j].slot_index) ? find_flag : 0); + if (new_dpb[j].top_used) { + find_flag = ((old_dpb[i].TOP_POC == new_dpb[j].TOP_POC) ? find_flag : 0); + } + if (new_dpb[j].bot_used) { + find_flag = ((old_dpb[i].BOT_POC == new_dpb[j].BOT_POC) ? find_flag : 0); + } + if (find_flag) { //!< found + new_dpb[j].have_same = 1; + new_dpb[j].new_dpb_idx = i; + break; + } + } + } + } + //!< not found + if (find_flag == 0) { + memset(&old_dpb[i], 0, sizeof(old_dpb[i])); + } + } + //!< add new dpb + for (j = 0; j < MPP_ARRAY_ELEMS(priv->new_dpb); j++) { + if ((new_dpb[j].valid == 0) || new_dpb[j].have_same) { + continue; + } + for (i = 0; i < MPP_ARRAY_ELEMS(priv->old_dpb[priv->layed_id]); i++) { + if (old_dpb[i].valid == 0) { + old_dpb[i] = new_dpb[j]; + new_dpb[j].new_dpb_idx = i; + break; + } + } + } + //!< inter-layer reference + priv->ilt_dpb = NULL; + if (priv->layed_id) { + for (i = 0; i < MPP_ARRAY_ELEMS(priv->old_dpb[1]); i++) { + if ((old_dpb[i].valid == 0) && old_dpb[i].is_ilt_flag) { + priv->ilt_dpb = &old_dpb[i]; + break; + } + } + } + } + //!< addjust ref_dpb + { + RK_U32 i = 0, j = 0; + H264dVdpuDpbInfo_t *new_dpb = priv->new_dpb; + + for (j = 0; j < 3; j++) { + H264dVdpuRefPicInfo_t *p = priv->refinfo[j]; + for (i = 0; i < MPP_ARRAY_ELEMS(priv->refinfo[j]); i++) { + if (p[i].valid) { + p[i].dpb_idx = new_dpb[p[i].dpb_idx].new_dpb_idx; + } + } + } + } + vdpu_refill_info_input(p_hal, priv); + + return ret = MPP_OK; +} +/*! +*********************************************************************** +* \brief +* init VDPU granite decoder +*********************************************************************** +*/ +//extern "C" +MPP_RET vdpu_h264d_init(void *hal, MppHalCfg *cfg) +{ + RK_U32 cabac_size = 0; + MPP_RET ret = MPP_ERR_UNKNOW; + H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal; + INP_CHECK(ret, NULL == hal); + + //!< malloc init registers + MEM_CHECK(ret, p_hal->regs = mpp_calloc_size(void, sizeof(H264dVdpuRegs_t))); + MEM_CHECK(ret, p_hal->priv = mpp_calloc_size(void, sizeof(H264dVdpuPriv_t))); + //!< malloc cabac+scanlis + packets + poc_buf + cabac_size = VDPU_CABAC_TAB_SIZE + VDPU_SCALING_LIST_SIZE + VDPU_POC_BUF_SIZE; + FUN_CHECK(ret = mpp_buffer_get(p_hal->buf_group, &p_hal->cabac_buf, cabac_size)); + //!< copy cabac table bytes + FUN_CHECK(ret = mpp_buffer_write(p_hal->cabac_buf, 0, (void *)H264_VDPU_Cabac_table, sizeof(H264_VDPU_Cabac_table))); + FUN_CHECK(ret = vdpu_set_device_regs(p_hal, (H264dVdpuRegs_t *)p_hal->regs)); + mpp_slots_set_prop(p_hal->frame_slots, SLOTS_HOR_ALIGN, vdpu_hor_align); + mpp_slots_set_prop(p_hal->frame_slots, SLOTS_VER_ALIGN, vdpu_ver_align); + mpp_slots_set_prop(p_hal->frame_slots, SLOTS_LEN_ALIGN, NULL); + p_hal->iDecodedNum = 0; + + (void)cfg; +__RETURN: + return MPP_OK; +__FAILED: + vdpu_h264d_deinit(hal); + + return ret; +} + + +/*! +*********************************************************************** +* \brief +* deinit +*********************************************************************** +*/ +//extern "C" +MPP_RET vdpu_h264d_deinit(void *hal) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal; + + INP_CHECK(ret, NULL == p_hal); + + FunctionIn(p_hal->logctx.parr[RUN_HAL]); + + MPP_FREE(p_hal->regs); + MPP_FREE(p_hal->priv); + if (p_hal->cabac_buf) { + FUN_CHECK(ret = mpp_buffer_put(p_hal->cabac_buf)); + } + + FunctionOut(p_hal->logctx.parr[RUN_HAL]); +__RETURN: + return ret = MPP_OK; +__FAILED: + return ret; +} +/*! +*********************************************************************** +* \brief +* generate register +*********************************************************************** +*/ +//extern "C" +MPP_RET vdpu_h264d_gen_regs(void *hal, HalTaskInfo *task) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + + H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal; + INP_CHECK(ret, NULL == p_hal); + FunctionIn(p_hal->logctx.parr[RUN_HAL]); + p_hal->in_task = &task->dec; + if (task->dec.flags.had_error) { + goto __RETURN; + } + LogTrace(p_hal->logctx.parr[RUN_HAL], "[Generate register begin]"); + FUN_CHECK(ret = vdpu_adjust_input(p_hal, (H264dVdpuPriv_t *)p_hal->priv)); + FUN_CHECK(ret = vdpu_set_pic_regs(p_hal, (H264dVdpuRegs_t *)p_hal->regs)); + FUN_CHECK(ret = vdpu_set_vlc_regs(p_hal, (H264dVdpuRegs_t *)p_hal->regs)); + FUN_CHECK(ret = vdpu_set_ref_regs(p_hal, (H264dVdpuRegs_t *)p_hal->regs)); + FUN_CHECK(ret = vdpu_set_asic_regs(p_hal, (H264dVdpuRegs_t *)p_hal->regs)); + LogTrace(p_hal->logctx.parr[RUN_HAL], "[Generate register end]"); + p_hal->in_task->valid = 0; + FunctionOut(p_hal->logctx.parr[RUN_HAL]); +__RETURN: + return ret = MPP_OK; +__FAILED: + return ret; +} +/*! +*********************************************************************** +* \brief h +* start hard +*********************************************************************** +*/ +//extern "C" +MPP_RET vdpu_h264d_start(void *hal, HalTaskInfo *task) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal; + H264dVdpuRegs_t *p_regs = (H264dVdpuRegs_t *)p_hal->regs; + + FunctionIn(p_hal->logctx.parr[RUN_HAL]); + if (task->dec.flags.had_error) { + goto __RETURN; + } + p_regs->sw57.cache_en = 1; + p_regs->sw57.pref_sigchan = 1; + p_regs->sw56.bus_pos_sel = 1; + p_regs->sw57.intra_dbl3t = 1; + p_regs->sw57.inter_dblspeed = 1; + p_regs->sw57.intra_dblspeed = 1; +#ifdef RKPLATFORM + if (VPUClientSendReg(p_hal->vpu_socket, (RK_U32 *)p_hal->regs, DEC_VDPU_REGISTERS)) { + ret = MPP_ERR_VPUHW; + mpp_err_f("H264 VDPU FlushRegs fail, pid=%d, hal_frame_no=%d. \n", getpid(), p_hal->iDecodedNum); + } else { + H264D_LOG("H264 VDPU FlushRegs success, pid=%d, hal_frame_no=%d. \n", getpid(), p_hal->iDecodedNum); + } +#endif +__RETURN: + FunctionOut(p_hal->logctx.parr[RUN_HAL]); + (void)task; + return ret = MPP_OK; +} +/*! +*********************************************************************** +* \brief +* wait hard +*********************************************************************** +*/ +//extern "C" +MPP_RET vdpu_h264d_wait(void *hal, HalTaskInfo *task) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal; + H264dVdpuRegs_t *p_regs = (H264dVdpuRegs_t *)p_hal->regs; + + FunctionIn(p_hal->logctx.parr[RUN_HAL]); + + if (task->dec.flags.had_error) { + goto __SKIP_HARD; + } +#ifdef RKPLATFORM + { + RK_S32 wait_ret = -1; + RK_S32 ret_len = 0, cur_deat = 0; + VPU_CMD_TYPE ret_cmd = VPU_CMD_BUTT; + RK_S64 p_s, p_e; + p_s = mpp_time(); + wait_ret = VPUClientWaitResult(p_hal->vpu_socket, (RK_U32 *)p_hal->regs, DEC_VDPU_REGISTERS, &ret_cmd, &ret_len); + p_e = mpp_time(); + cur_deat = (p_e - p_s) / 1000; + p_hal->total_time += cur_deat; + p_hal->iDecodedNum++; + (void)wait_ret; + } +#endif + +__SKIP_HARD: + if (p_hal->init_cb.callBack) { + IOCallbackCtx m_ctx = { 0 }; + m_ctx.device_id = HAL_VDPU; + if (!p_regs->sw55.dec_rdy_sts) { + m_ctx.hard_err = 1; + } + m_ctx.task = (void *)&task->dec; + m_ctx.regs = (RK_U32 *)p_hal->regs; + p_hal->init_cb.callBack(p_hal->init_cb.opaque, &m_ctx); + } + memset(&p_regs->sw55, 0, sizeof(RK_U32)); + FunctionOut(p_hal->logctx.parr[RUN_HAL]); + (void)task; + + return ret = MPP_OK; +} +/*! +*********************************************************************** +* \brief +* reset +*********************************************************************** +*/ +//extern "C" +MPP_RET vdpu_h264d_reset(void *hal) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal; + + INP_CHECK(ret, NULL == p_hal); + FunctionIn(p_hal->logctx.parr[RUN_HAL]); + + memset(p_hal->priv, 0, sizeof(H264dVdpuPriv_t)); + + FunctionOut(p_hal->logctx.parr[RUN_HAL]); +__RETURN: + return ret = MPP_OK; +} +/*! +*********************************************************************** +* \brief +* flush +*********************************************************************** +*/ +//extern "C" +MPP_RET vdpu_h264d_flush(void *hal) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal; + + INP_CHECK(ret, NULL == p_hal); + FunctionIn(p_hal->logctx.parr[RUN_HAL]); + + + + FunctionOut(p_hal->logctx.parr[RUN_HAL]); +__RETURN: + return ret = MPP_OK; +} +/*! +*********************************************************************** +* \brief +* control +*********************************************************************** +*/ +//extern "C" +MPP_RET vdpu_h264d_control(void *hal, RK_S32 cmd_type, void *param) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal; + + INP_CHECK(ret, NULL == p_hal); + FunctionIn(p_hal->logctx.parr[RUN_HAL]); + + + + FunctionOut(p_hal->logctx.parr[RUN_HAL]); + (void)hal; + (void)cmd_type; + (void)param; +__RETURN: + return ret = MPP_OK; +} diff --git a/mpp/hal/rkdec/h264d/hal_h264d_vdpu_reg.h b/mpp/hal/rkdec/h264d/hal_h264d_vdpu_reg.h index dde006f3..8b6c6f89 100644 --- a/mpp/hal/rkdec/h264d/hal_h264d_vdpu_reg.h +++ b/mpp/hal/rkdec/h264d/hal_h264d_vdpu_reg.h @@ -1,50 +1,50 @@ -/* -* -* Copyright 2015 Rockchip Electronics Co. LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - - -#ifndef __HAL_H264D_VDPU_REG_H__ -#define __HAL_H264D_VDPU_REG_H__ - -#include "mpp_hal.h" - - - - - - - -#ifdef __cplusplus -extern "C" { -#endif - - - -MPP_RET vdpu_h264d_init (void *hal, MppHalCfg *cfg); -MPP_RET vdpu_h264d_deinit (void *hal); -MPP_RET vdpu_h264d_gen_regs(void *hal, HalTaskInfo *task); -MPP_RET vdpu_h264d_start (void *hal, HalTaskInfo *task); -MPP_RET vdpu_h264d_wait (void *hal, HalTaskInfo *task); -MPP_RET vdpu_h264d_reset (void *hal); -MPP_RET vdpu_h264d_flush (void *hal); -MPP_RET vdpu_h264d_control (void *hal, RK_S32 cmd_type, void *param); - - -#ifdef __cplusplus -} -#endif - -#endif /*__HAL_H264D_VDPU_REG_H__*/ +/* +* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +#ifndef __HAL_H264D_VDPU_REG_H__ +#define __HAL_H264D_VDPU_REG_H__ + +#include "mpp_hal.h" + + + + + + + +#ifdef __cplusplus +extern "C" { +#endif + + + +MPP_RET vdpu_h264d_init (void *hal, MppHalCfg *cfg); +MPP_RET vdpu_h264d_deinit (void *hal); +MPP_RET vdpu_h264d_gen_regs(void *hal, HalTaskInfo *task); +MPP_RET vdpu_h264d_start (void *hal, HalTaskInfo *task); +MPP_RET vdpu_h264d_wait (void *hal, HalTaskInfo *task); +MPP_RET vdpu_h264d_reset (void *hal); +MPP_RET vdpu_h264d_flush (void *hal); +MPP_RET vdpu_h264d_control (void *hal, RK_S32 cmd_type, void *param); + + +#ifdef __cplusplus +} +#endif + +#endif /*__HAL_H264D_VDPU_REG_H__*/ diff --git a/mpp/hal/rkdec/vp9d/hal_vp9d_api.c b/mpp/hal/rkdec/vp9d/hal_vp9d_api.c index a6a18d39..e82e2eb8 100644 --- a/mpp/hal/rkdec/vp9d/hal_vp9d_api.c +++ b/mpp/hal/rkdec/vp9d/hal_vp9d_api.c @@ -1,983 +1,983 @@ -/* -* -* Copyright 2015 Rockchip Electronics Co. LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - - -#define MODULE_TAG "hal_vp9d_api" - -#include -#include -#include - -#include "rk_type.h" -#include "mpp_log.h" -#include "mpp_err.h" -#include "mpp_mem.h" -#include "mpp_env.h" -#include "mpp_common.h" -#include "mpp_dec.h" - -#include "hal_vp9d_api.h" -#include "hal_vp9d_reg.h" -#include "vpu.h" -#include "mpp_bitput.h" -#include "vp9d_syntax.h" -#include "hal_vp9d_table.h" - -#define PROBE_SIZE 4864 -#define COUNT_SIZE 13208 - -/*nCtuX*nCtuY*8*8/2 - * MaxnCtuX = 4096/64 - * MaxnCtuY = 2304/64 -*/ -#define MAX_SEGMAP_SIZE 73728 -/* - -*/ -#define MAX_INTER_CMD_SIZE 147456 - -RK_U32 vp9h_debug = 0; -//#define dump -#ifdef dump -static FILE *vp9_fp = NULL; -static FILE *vp9_fp1 = NULL; -static FILE *vp9_fp_yuv = NULL; - -static RK_S32 count = 0; -static RK_S32 frame_num = 0; -#endif -typedef struct vp9_dec_last_info { - RK_S32 abs_delta_last; - RK_S8 last_ref_deltas[4]; - RK_S8 last_mode_deltas[2]; - RK_U8 segmentation_enable_flag_last; - RK_U8 last_show_frame; - RK_U8 last_intra_only; - RK_U32 last_width; - RK_U32 last_height; - SHORT feature_data[8][4]; - UCHAR feature_mask[8]; -} vp9_dec_last_info_t; - -typedef struct hal_vp9_context { - RK_S32 vpu_socket; - MppBufSlots slots; - MppBufSlots packet_slots; - MppBufferGroup group; - MppBuffer probe_base; - MppBuffer count_base; - MppBuffer segid_cur_base; - MppBuffer segid_last_base; - void* hw_regs; - IOInterruptCB int_cb; - RK_U32 mv_base_addr; - RK_U32 pre_mv_base_addr; - vp9_dec_last_info_t ls_info; - /*swap between segid_cur_base & segid_last_base - 0 used segid_cur_base as last - 1 used segid_last_base as - */ - RK_U32 last_segid_flag; -} hal_vp9_context_t; - -static RK_U32 vp9_ver_align(RK_U32 val) -{ - return MPP_ALIGN(val, 64); -} - -static RK_U32 vp9_hor_align(RK_U32 val) -{ - return MPP_ALIGN(val, 128); -} -/*! -*********************************************************************** -* \brief -* init -*********************************************************************** -*/ -//extern "C" -MPP_RET hal_vp9d_init(void *hal, MppHalCfg *cfg) -{ - MPP_RET ret = MPP_OK; - hal_vp9_context_t *reg_cxt = (hal_vp9_context_t *)hal; - - if (NULL == reg_cxt) { - mpp_err("hal instant no alloc"); - return MPP_ERR_UNKNOW; - } - mpp_log("hal_vp9d_init in"); - reg_cxt->slots = cfg->frame_slots; - reg_cxt->int_cb = cfg->hal_int_cb; - reg_cxt->mv_base_addr = 0; - reg_cxt->pre_mv_base_addr = 0; - mpp_slots_set_prop(reg_cxt->slots, SLOTS_HOR_ALIGN, vp9_hor_align); - mpp_slots_set_prop(reg_cxt->slots, SLOTS_VER_ALIGN, vp9_ver_align); - - reg_cxt->packet_slots = cfg->packet_slots; - ///<- VPUClientInit -#ifdef RKPLATFORM - if (reg_cxt->vpu_socket <= 0) { - reg_cxt->vpu_socket = VPUClientInit(VPU_DEC_RKV); - if (reg_cxt->vpu_socket <= 0) { - mpp_err("vp9 reg_cxt->vpu_socket <= 0\n"); - return MPP_ERR_UNKNOW; - } - } -#endif - if (reg_cxt->group == NULL) { - -#ifdef RKPLATFORM - mpp_err("mpp_buffer_group_get_internal used ion in"); - ret = mpp_buffer_group_get_internal(®_cxt->group, MPP_BUFFER_TYPE_ION); -#else - ret = mpp_buffer_group_get_internal(®_cxt->group, MPP_BUFFER_TYPE_NORMAL); -#endif - if (MPP_OK != ret) { - mpp_err("vp9 mpp_buffer_group_get failed\n"); - return ret; - } - } - ret = mpp_buffer_get(reg_cxt->group, ®_cxt->probe_base, PROBE_SIZE); - if (MPP_OK != ret) { - mpp_err("vp9 probe_base get buffer failed\n"); - return ret; - } - - ret = mpp_buffer_get(reg_cxt->group, ®_cxt->count_base, COUNT_SIZE); - if (MPP_OK != ret) { - mpp_err("vp9 count_base get buffer failed\n"); - return ret; - } - - ret = mpp_buffer_get(reg_cxt->group, ®_cxt->segid_cur_base, MAX_SEGMAP_SIZE); - if (MPP_OK != ret) { - mpp_err("vp9 segid_cur_base get buffer failed\n"); - return ret; - } - - ret = mpp_buffer_get(reg_cxt->group, ®_cxt->segid_last_base, MAX_SEGMAP_SIZE); - if (MPP_OK != ret) { - mpp_err("vp9 segid_last_base get buffer failed\n"); - return ret; - } - - mpp_env_get_u32("vp9h_debug", &vp9h_debug, 0); - - reg_cxt->hw_regs = mpp_calloc_size(void, sizeof(VP9_REGS)); - - reg_cxt->last_segid_flag = 1; -#ifdef dump - if (vp9_fp_yuv != NULL) { - fclose(vp9_fp_yuv); - } - - frame_num = 0; - vp9_fp_yuv = fopen("data/vp9_out.yuv", "wb"); - count = 0; -#endif - return ret = MPP_OK; - -} -/*! -*********************************************************************** -* \brief -* deinit -*********************************************************************** -*/ -//extern "C" -MPP_RET hal_vp9d_deinit(void *hal) -{ - MPP_RET ret = MPP_OK; - hal_vp9_context_t *reg_cxt = (hal_vp9_context_t *)hal; - - if (reg_cxt->probe_base) { - ret = mpp_buffer_put(reg_cxt->probe_base); - if (MPP_OK != ret) { - mpp_err("vp9 probe_base get buffer failed\n"); - return ret; - } - } - - if (reg_cxt->count_base) { - ret = mpp_buffer_put(reg_cxt->count_base); - if (MPP_OK != ret) { - mpp_err("vp9 count_base put buffer failed\n"); - return ret; - } - } - - if (reg_cxt->segid_cur_base) { - ret = mpp_buffer_put(reg_cxt->segid_cur_base); - if (MPP_OK != ret) { - mpp_err("vp9 segid_cur_base put buffer failed\n"); - return ret; - } - } - - if (reg_cxt->segid_last_base) { - ret = mpp_buffer_put(reg_cxt->segid_last_base); - if (MPP_OK != ret) { - mpp_err("vp9 segid_last_base put buffer failed\n"); - return ret; - } - } - - if (reg_cxt->group) { - ret = mpp_buffer_group_put(reg_cxt->group); - if (MPP_OK != ret) { - mpp_err("vp9d group free buffer failed\n"); - return ret; - } - } - return ret = MPP_OK; -} - -MPP_RET hal_vp9d_output_probe(void *hal, void *dxva) -{ - RK_S32 i, j, k, m, n; - RK_S32 fifo_len = 304; - RK_U64 *probe_packet = NULL; - BitputCtx_t bp; - DXVA_PicParams_VP9 *pic_param = (DXVA_PicParams_VP9*)dxva; - RK_S32 intraFlag = (!pic_param->frame_type || pic_param->intra_only); - vp9_prob partition_probs[PARTITION_CONTEXTS][PARTITION_TYPES - 1]; - vp9_prob uv_mode_prob[INTRA_MODES][INTRA_MODES - 1]; -#ifdef RKPLATFORM - hal_vp9_context_t *reg_cxt = (hal_vp9_context_t*)hal; - void *probe_ptr = mpp_buffer_get_ptr(reg_cxt->probe_base); - if (NULL == probe_ptr) { - - mpp_err("probe_ptr get ptr error"); - return MPP_ERR_NOMEM; - } - memset(probe_ptr, 0, 304 * 8); -#else - (void)hal; -#endif - - if (intraFlag) { - memcpy(partition_probs, vp9_kf_partition_probs, sizeof(partition_probs)); - memcpy(uv_mode_prob, vp9_kf_uv_mode_prob, sizeof(uv_mode_prob)); - } else { - memcpy(partition_probs, pic_param->prob.partition, sizeof(partition_probs)); - memcpy(uv_mode_prob, pic_param->prob.uv_mode, sizeof(uv_mode_prob)); - } - - probe_packet = mpp_calloc(RK_U64, fifo_len + 1); - mpp_set_bitput_ctx(&bp, probe_packet, fifo_len); - //sb info 5 x 128 bit - for (i = 0; i < PARTITION_CONTEXTS; i++) //kf_partition_prob - for (j = 0; j < PARTITION_TYPES - 1; j++) - mpp_put_bits(&bp, partition_probs[i][j], 8); //48 - - for (i = 0; i < PREDICTION_PROBS; i++) //Segment_id_pred_prob //3 - mpp_put_bits(&bp, pic_param->stVP9Segments.pred_probs[i], 8); - - for (i = 0; i < SEG_TREE_PROBS; i++) //Segment_id_probs - mpp_put_bits(&bp, pic_param->stVP9Segments.tree_probs[i], 8); //7 - - for (i = 0; i < SKIP_CONTEXTS; i++) //Skip_flag_probs //3 - mpp_put_bits(&bp, pic_param->prob.skip[i], 8); - - for (i = 0; i < TX_SIZE_CONTEXTS; i++) //Tx_size_probs //6 - for (j = 0; j < TX_SIZES - 1; j++) - mpp_put_bits(&bp, pic_param->prob.tx32p[i][j], 8); - - for (i = 0; i < TX_SIZE_CONTEXTS; i++) //Tx_size_probs //4 - for (j = 0; j < TX_SIZES - 2; j++) - mpp_put_bits(&bp, pic_param->prob.tx16p[i][j], 8); - - for (i = 0; i < TX_SIZE_CONTEXTS; i++) //Tx_size_probs //2 - mpp_put_bits(&bp, pic_param->prob.tx8p[i], 8); - - for (i = 0; i < INTRA_INTER_CONTEXTS; i++) //Tx_size_probs //4 - mpp_put_bits(&bp, pic_param->prob.intra[i], 8); - - mpp_put_align(&bp, 128, 0); - if (intraFlag) { //intra probs - //intra only //149 x 128 bit ,aligned to 152 x 128 bit - //coeff releated prob 64 x 128 bit - for (i = 0; i < TX_SIZES; i++) - for (j = 0; j < PLANE_TYPES; j++) { - RK_S32 byte_count = 0; - for (k = 0; k < COEF_BANDS; k++) { - for (m = 0; m < COEFF_CONTEXTS; m++) - for (n = 0; n < UNCONSTRAINED_NODES; n++) { - mpp_put_bits(&bp, pic_param->prob.coef[i][j][0][k][m][n], 8); - - byte_count++; - if (byte_count == 27) { - mpp_put_align(&bp, 128, 0); - byte_count = 0; - } - } - } - mpp_put_align(&bp, 128, 0); - } - - //intra mode prob 80 x 128 bit - for (i = 0; i < INTRA_MODES; i++) { //vp9_kf_y_mode_prob - RK_S32 byte_count = 0; - for (j = 0; j < INTRA_MODES; j++) - for (k = 0; k < INTRA_MODES - 1; k++) { - mpp_put_bits(&bp, vp9_kf_y_mode_prob[i][j][k], 8); - byte_count++; - if (byte_count == 27) { - byte_count = 0; - mpp_put_align(&bp, 128, 0); - } - - } - if (i < 4) { - for (m = 0; m < (i < 3 ? 23 : 21); m++) - mpp_put_bits(&bp, ((vp9_prob *)(&vp9_kf_uv_mode_prob[0][0]))[i * 23 + m], 8); - for (; m < 23; m++) - mpp_put_bits(&bp, 0, 8); - } else { - for (m = 0; m < 23; m++) - mpp_put_bits(&bp, 0, 8); - } - mpp_put_align(&bp, 128, 0); - } - //align to 152 x 128 bit - for (i = 0; i < INTER_PROB_SIZE_ALIGN_TO_128 - INTRA_PROB_SIZE_ALIGN_TO_128; i++) { //aligned to 153 x 256 bit - mpp_put_bits(&bp, 0, 8); - mpp_put_align(&bp, 128, 0); - } - } else { - //inter probs - //151 x 128 bit ,aligned to 152 x 128 bit - //inter only - - //intra_y_mode & inter_block info 6 x 128 bit - for (i = 0; i < BLOCK_SIZE_GROUPS; i++) //intra_y_mode - for (j = 0; j < INTRA_MODES - 1; j++) - mpp_put_bits(&bp, pic_param->prob.y_mode[i][j], 8); - - for (i = 0; i < COMP_INTER_CONTEXTS; i++) //reference_mode prob - mpp_put_bits(&bp, pic_param->prob.comp[i], 8); - - for (i = 0; i < REF_CONTEXTS; i++) //comp ref bit - mpp_put_bits(&bp, pic_param->prob.comp_ref[i], 8); - - for (i = 0; i < REF_CONTEXTS; i++) //single ref bit - for (j = 0; j < 2; j++) - mpp_put_bits(&bp, pic_param->prob.single_ref[i][j], 8); - - for (i = 0; i < INTER_MODE_CONTEXTS; i++) //mv mode bit - for (j = 0; j < INTER_MODES - 1; j++) - mpp_put_bits(&bp, pic_param->prob.mv_mode[i][j], 8); - - - for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) //comp ref bit - for (j = 0; j < SWITCHABLE_FILTERS - 1; j++) - mpp_put_bits(&bp, pic_param->prob.filter[i][j], 8); - - mpp_put_align(&bp, 128, 0); - - //128 x 128bit - //coeff releated - for (i = 0; i < TX_SIZES; i++) - for (j = 0; j < PLANE_TYPES; j++) { - RK_S32 byte_count = 0; - for (k = 0; k < COEF_BANDS; k++) { - for (m = 0; m < COEFF_CONTEXTS; m++) - for (n = 0; n < UNCONSTRAINED_NODES; n++) { - mpp_put_bits(&bp, pic_param->prob.coef[i][j][0][k][m][n], 8); - byte_count++; - if (byte_count == 27) { - mpp_put_align(&bp, 128, 0); - byte_count = 0; - } - } - } - mpp_put_align(&bp, 128, 0); - } - for (i = 0; i < TX_SIZES; i++) - for (j = 0; j < PLANE_TYPES; j++) { - RK_S32 byte_count = 0; - for (k = 0; k < COEF_BANDS; k++) { - for (m = 0; m < COEFF_CONTEXTS; m++) { - for (n = 0; n < UNCONSTRAINED_NODES; n++) { - mpp_put_bits(&bp, pic_param->prob.coef[i][j][1][k][m][n], 8); - byte_count++; - if (byte_count == 27) { - mpp_put_align(&bp, 128, 0); - byte_count = 0; - } - } - - } - } - mpp_put_align(&bp, 128, 0); - } - - //intra uv mode 6 x 128 - for (i = 0; i < 3; i++) //intra_uv_mode - for (j = 0; j < INTRA_MODES - 1; j++) - mpp_put_bits(&bp, uv_mode_prob[i][j], 8); - mpp_put_align(&bp, 128, 0); - - for (; i < 6; i++) //intra_uv_mode - for (j = 0; j < INTRA_MODES - 1; j++) - mpp_put_bits(&bp, uv_mode_prob[i][j], 8); - mpp_put_align(&bp, 128, 0); - - for (; i < 9; i++) //intra_uv_mode - for (j = 0; j < INTRA_MODES - 1; j++) - mpp_put_bits(&bp, uv_mode_prob[i][j], 8); - mpp_put_align(&bp, 128, 0); - for (; i < INTRA_MODES; i++) //intra_uv_mode - for (j = 0; j < INTRA_MODES - 1; j++) - mpp_put_bits(&bp, uv_mode_prob[i][j], 8); - - mpp_put_align(&bp, 128, 0); - mpp_put_bits(&bp, 0, 8); - mpp_put_align(&bp, 128, 0); - - //mv releated 6 x 128 - for (i = 0; i < MV_JOINTS - 1; i++) //mv_joint_type - mpp_put_bits(&bp, pic_param->prob.mv_joint[i], 8); - - for (i = 0; i < 2; i++) { //sign bit - mpp_put_bits(&bp, pic_param->prob.mv_comp[i].sign, 8); - } - for (i = 0; i < 2; i++) { //classes bit - for (j = 0; j < MV_CLASSES - 1; j++) - mpp_put_bits(&bp, pic_param->prob.mv_comp[i].classes[j], 8); - } - for (i = 0; i < 2; i++) { //classe0 bit - mpp_put_bits(&bp, pic_param->prob.mv_comp[i].class0, 8); - } - for (i = 0; i < 2; i++) { // bits - for (j = 0; j < MV_OFFSET_BITS; j++) - mpp_put_bits(&bp, pic_param->prob.mv_comp[i].bits[j], 8); - } - for (i = 0; i < 2; i++) { //class0_fp bit - for (j = 0; j < CLASS0_SIZE; j++) - for (k = 0; k < MV_FP_SIZE - 1; k++) - mpp_put_bits(&bp, pic_param->prob.mv_comp[i].class0_fp[j][k], 8); - } - for (i = 0; i < 2; i++) { //comp ref bit - for (j = 0; j < MV_FP_SIZE - 1; j++) - mpp_put_bits(&bp, pic_param->prob.mv_comp[i].fp[j], 8); - } - for (i = 0; i < 2; i++) { //class0_hp bit - - mpp_put_bits(&bp, pic_param->prob.mv_comp[i].class0_hp, 8); - } - for (i = 0; i < 2; i++) { //hp bit - mpp_put_bits(&bp, pic_param->prob.mv_comp[i].hp, 8); - } - mpp_put_align(&bp, 128, 0); - } -#ifdef RKPLATFORM - memcpy(probe_ptr, probe_packet, 304 * 8); -#endif -#ifdef dump - if (intraFlag) { - fwrite(probe_packet, 1, 302 * 8, vp9_fp); - } else { - fwrite(probe_packet, 1, 304 * 8, vp9_fp); - } - fflush(vp9_fp); -#endif - if (probe_packet != NULL) - mpp_free(probe_packet); - - return 0; -} -void hal_vp9d_update_counts(void *hal, void *dxva) -{ - hal_vp9_context_t *reg_cxt = (hal_vp9_context_t*)hal; - DXVA_PicParams_VP9 *s = (DXVA_PicParams_VP9*)dxva; - RK_S32 i, j, m, n, k; - RK_U32 *eob_coef; - RK_S32 ref_type; -#ifdef dump - RK_U32 count_length; -#endif - RK_U32 com_len = 0; - - RK_U8 *counts_ptr = mpp_buffer_get_ptr(reg_cxt->count_base); - if (NULL == counts_ptr) { - mpp_err("counts_ptr get ptr error"); - return; - } - -#ifdef dump - if (!(s->frame_type == 0 || s->intra_only)) //inter - count_length = (213 * 64 + 576 * 5 * 32) / 8; - else //intra - count_length = (49 * 64 + 288 * 5 * 32) / 8; - - fwrite(counts_ptr, 1, count_length, vp9_fp1); - fflush(vp9_fp1); -#endif - if ((s->frame_type == 0 || s->intra_only)) { - com_len = sizeof(s->counts.partition) + sizeof(s->counts.skip) + sizeof(s->counts.intra) - + sizeof(s->counts.tx32p) + sizeof(s->counts.tx16p) + sizeof(s->counts.tx8p); - } else { - com_len = sizeof(s->counts) - sizeof(s->counts.coef) - sizeof(s->counts.eob); - } - eob_coef = (RK_U32 *)(counts_ptr + com_len); - memcpy(&s->counts, counts_ptr, com_len); - ref_type = (!(s->frame_type == 0 || s->intra_only)) ? 2 : 1; - if (ref_type == 1) { - memset(s->counts.eob, 0, sizeof(s->counts.eob)); - memset(s->counts.coef, 0, sizeof(s->counts.coef)); - } - for (i = 0; i < ref_type; i++) { - for (j = 0; j < 4; j++) { - for (m = 0; m < 2; m++) { - for (n = 0; n < 6; n++) { - for (k = 0; k < 6; k++) { - s->counts.eob[j][m][i][n][k][0] = eob_coef[1]; - s->counts.eob[j][m][i][n][k][1] = eob_coef[0] - eob_coef[1]; //ffmpeg need do branch_ct[UNCONSTRAINED_NODES][2] = { neob, eob_counts[i][j][k][l] - neob }, - s->counts.coef[j][m][i][n][k][0] = eob_coef[2]; - s->counts.coef[j][m][i][n][k][1] = eob_coef[3]; - s->counts.coef[j][m][i][n][k][2] = eob_coef[4]; - eob_coef += 5; - } - } - } - } - } -} - -/*! -*********************************************************************** -* \brief -* generate register -*********************************************************************** -*/ -//extern "C" -MPP_RET hal_vp9d_gen_regs(void *hal, HalTaskInfo *task) -{ - RK_S32 i; - RK_U8 bit_depth = 0; - RK_U32 pic_h[3] = { 0 }; - RK_U32 ref_frame_width_y; - RK_U32 ref_frame_height_y; - RK_S32 stream_len = 0, aglin_offset = 0; - RK_U32 y_hor_virstride, uv_hor_virstride, y_virstride, uv_virstride, yuv_virstride; - RK_U8 *bitstream = NULL; - MppBuffer streambuf = NULL; - RK_U32 sw_y_hor_virstride; - RK_U32 sw_uv_hor_virstride; - RK_U32 sw_y_virstride; - RK_U32 sw_uv_virstride; - RK_U32 sw_yuv_virstride ; - RK_U8 ref_idx = 0; - RK_U32 *reg_ref_base = 0; -#ifdef dump - char filename[20] = "data/probe"; - char filename1[20] = "data/count"; -#endif - RK_S32 intraFlag = 0; - -#ifdef RKPLATFORM - MppBuffer framebuf = NULL; -#endif -#ifdef dump - if (vp9_fp != NULL) { - fclose(vp9_fp); - - } - if (vp9_fp1 != NULL) { - fclose(vp9_fp1); - } - sprintf(&filename[10], "%d.bin", count); - sprintf(&filename1[10], "%d.bin", count); - mpp_log("filename %s", filename); - mpp_log("filename %s", filename1); - vp9_fp = fopen(filename, "wb"); - vp9_fp1 = fopen(filename1, "wb"); - count++; -#endif - - hal_vp9_context_t *reg_cxt = (hal_vp9_context_t*)hal; - DXVA_PicParams_VP9 *pic_param = (DXVA_PicParams_VP9*)task->dec.syntax.data; - VP9_REGS *vp9_hw_regs = (VP9_REGS*)reg_cxt->hw_regs; - intraFlag = (!pic_param->frame_type || pic_param->intra_only); - hal_vp9d_output_probe(hal, task->dec.syntax.data); - stream_len = (RK_S32)mpp_packet_get_length(task->dec.input_packet); - memset(reg_cxt->hw_regs, 0, sizeof(VP9_REGS)); - vp9_hw_regs->swreg2_sysctrl.sw_dec_mode = 2; //set as vp9 dec - vp9_hw_regs->swreg5_stream_len = ((stream_len + 15) & (~15)) + 0x80; - - mpp_buf_slot_get_prop(reg_cxt->packet_slots, task->dec.input, SLOT_BUFFER, &streambuf); - bitstream = mpp_buffer_get_ptr(streambuf); - aglin_offset = vp9_hw_regs->swreg5_stream_len - stream_len; - if (aglin_offset > 0) { - memset((void *)(bitstream + stream_len), 0, aglin_offset); - } - - //--- caculate the yuv_frame_size and mv_size - bit_depth = pic_param->BitDepthMinus8Luma + 8; - pic_h[0] = vp9_ver_align(pic_param->height); //p_cm->height; - pic_h[1] = vp9_ver_align(pic_param->height) / 2; //(p_cm->height + 1) / 2; - pic_h[2] = pic_h[1]; - - sw_y_hor_virstride = (vp9_hor_align((pic_param->width * bit_depth) >> 3) >> 4); - sw_uv_hor_virstride = (vp9_hor_align((pic_param->width * bit_depth) >> 3) >> 4); - sw_y_virstride = pic_h[0] * sw_y_hor_virstride; - - sw_uv_virstride = pic_h[1] * sw_uv_hor_virstride; - sw_yuv_virstride = sw_y_virstride + sw_uv_virstride; - - vp9_hw_regs->swreg3_picpar.sw_y_hor_virstride = sw_y_hor_virstride; - vp9_hw_regs->swreg3_picpar.sw_uv_hor_virstride = sw_uv_hor_virstride; - vp9_hw_regs->swreg8_y_virstride.sw_y_virstride = sw_y_virstride; - vp9_hw_regs->swreg9_yuv_virstride.sw_yuv_virstride = sw_yuv_virstride; - -#ifdef RKPLATFORM - if (!pic_param->intra_only && pic_param->frame_type && !pic_param->error_resilient_mode) { - reg_cxt->pre_mv_base_addr = reg_cxt->mv_base_addr; - } - - if (!(pic_param->stVP9Segments.enabled && !pic_param->stVP9Segments.update_map)) { - if (!pic_param->intra_only && pic_param->frame_type && !pic_param->error_resilient_mode) { - if (reg_cxt->last_segid_flag) { - reg_cxt->last_segid_flag = 0; - } else { - reg_cxt->last_segid_flag = 1; - } - } - } - mpp_buf_slot_get_prop(reg_cxt->slots, task->dec.output, SLOT_BUFFER, &framebuf); - vp9_hw_regs->swreg7_decout_base = mpp_buffer_get_fd(framebuf); - vp9_hw_regs->swreg4_strm_rlc_base = mpp_buffer_get_fd(streambuf); - vp9_hw_regs->swreg6_cabactbl_prob_base = mpp_buffer_get_fd(reg_cxt->probe_base); - vp9_hw_regs->swreg14_vp9_count_base = mpp_buffer_get_fd(reg_cxt->count_base); - - if (reg_cxt->last_segid_flag) { - vp9_hw_regs->swreg15_vp9_segidlast_base = mpp_buffer_get_fd(reg_cxt->segid_last_base); - vp9_hw_regs->swreg16_vp9_segidcur_base = mpp_buffer_get_fd(reg_cxt->segid_cur_base); - } else { - vp9_hw_regs->swreg15_vp9_segidlast_base = mpp_buffer_get_fd(reg_cxt->segid_cur_base); - vp9_hw_regs->swreg16_vp9_segidcur_base = mpp_buffer_get_fd(reg_cxt->segid_last_base); - } - - if (VPUClientGetIOMMUStatus() > 0) { - reg_cxt->mv_base_addr = vp9_hw_regs->swreg7_decout_base | ((sw_yuv_virstride << 4) << 6); - } else { - reg_cxt->mv_base_addr = vp9_hw_regs->swreg7_decout_base + (sw_yuv_virstride << 4); - } - - if (!reg_cxt->pre_mv_base_addr) { - reg_cxt->pre_mv_base_addr = reg_cxt->mv_base_addr; - } - vp9_hw_regs->swreg52_vp9_refcolmv_base = reg_cxt->pre_mv_base_addr; -#endif - - vp9_hw_regs->swreg10_vp9_cprheader_offset.sw_vp9_cprheader_offset = 0; //no use now. - reg_ref_base = &vp9_hw_regs->swreg11_vp9_referlast_base; - for (i = 0; i < 3; i++) { - ref_idx = pic_param->frame_refs[i].Index7Bits; - ref_frame_width_y = pic_param->ref_frame_coded_width[ref_idx]; - ref_frame_height_y = pic_param->ref_frame_coded_height[ref_idx]; - pic_h[0] = vp9_ver_align(ref_frame_height_y); - pic_h[1] = vp9_ver_align(ref_frame_height_y) / 2; - y_hor_virstride = (vp9_hor_align((ref_frame_width_y * bit_depth) >> 3) >> 4); - uv_hor_virstride = (vp9_hor_align((ref_frame_width_y * bit_depth) >> 3) >> 4); - y_virstride = y_hor_virstride * pic_h[0]; - uv_virstride = uv_hor_virstride * pic_h[1]; - yuv_virstride = y_virstride + uv_virstride; -#ifdef RKPLATFORM - if (pic_param->ref_frame_map[ref_idx].Index7Bits < 0x7f) { - mpp_buf_slot_get_prop(reg_cxt->slots, pic_param->ref_frame_map[ref_idx].Index7Bits, SLOT_BUFFER, &framebuf); - } -#endif - if (pic_param->ref_frame_map[ref_idx].Index7Bits < 0x7f) { - switch (i) { - case 0: { - - vp9_hw_regs->swreg17_vp9_frame_size_last.sw_framewidth_last = ref_frame_width_y; - vp9_hw_regs->swreg17_vp9_frame_size_last.sw_frameheight_last = ref_frame_height_y; - vp9_hw_regs->swreg37_vp9_lastf_hor_virstride.sw_vp9_lastfy_hor_virstride = y_hor_virstride; - vp9_hw_regs->swreg37_vp9_lastf_hor_virstride.sw_vp9_lastfuv_hor_virstride = uv_hor_virstride; - vp9_hw_regs->swreg48_vp9_last_ystride.sw_vp9_lastfy_virstride = y_virstride; - vp9_hw_regs->swreg51_vp9_lastref_yuvstride.sw_vp9_lastref_yuv_virstride = yuv_virstride; - break; - } - case 1: { - vp9_hw_regs->swreg18_vp9_frame_size_golden.sw_framewidth_golden = ref_frame_width_y; - vp9_hw_regs->swreg18_vp9_frame_size_golden.sw_frameheight_golden = ref_frame_height_y; - vp9_hw_regs->swreg38_vp9_goldenf_hor_virstride.sw_vp9_goldenfy_hor_virstride = y_hor_virstride; - vp9_hw_regs->swreg38_vp9_goldenf_hor_virstride.sw_vp9_goldenuv_hor_virstride = uv_hor_virstride; - vp9_hw_regs->swreg49_vp9_golden_ystride.sw_vp9_goldeny_virstride = y_virstride; - break; - } - case 2: { - vp9_hw_regs->swreg19_vp9_frame_size_altref.sw_framewidth_alfter = ref_frame_width_y; - vp9_hw_regs->swreg19_vp9_frame_size_altref.sw_frameheight_alfter = ref_frame_height_y; - vp9_hw_regs->swreg39_vp9_altreff_hor_virstride.sw_vp9_altreffy_hor_virstride = y_hor_virstride; - vp9_hw_regs->swreg39_vp9_altreff_hor_virstride.sw_vp9_altreffuv_hor_virstride = uv_hor_virstride; - vp9_hw_regs->swreg50_vp9_altrefy_ystride.sw_vp9_altrefy_virstride = y_virstride; - break; - } - default: - break; - - } -#ifdef RKPLATFORM - /*0 map to 11*/ - /*1 map to 12*/ - /*2 map to 13*/ - if (framebuf != NULL) { - reg_ref_base[i] = mpp_buffer_get_fd(framebuf); - } else { - mpp_log("ref buff address is no valid used out as base slot index 0x%x", pic_param->ref_frame_map[ref_idx].Index7Bits); - reg_ref_base[i] = vp9_hw_regs->swreg7_decout_base; //set - } -#endif - } else { - reg_ref_base[i] = vp9_hw_regs->swreg7_decout_base; //set - } - } - - for (i = 0; i < 8; i++) { - vp9_hw_regs->swreg20_27_vp9_segid_grp[i].sw_vp9segid_frame_qp_delta_en = (reg_cxt->ls_info.feature_mask[i]) & 0x1; - vp9_hw_regs->swreg20_27_vp9_segid_grp[i].sw_vp9segid_frame_qp_delta = reg_cxt->ls_info.feature_data[i][0]; - vp9_hw_regs->swreg20_27_vp9_segid_grp[i].sw_vp9segid_frame_loopfitler_value_en = (reg_cxt->ls_info.feature_mask[i] >> 1) & 0x1; - vp9_hw_regs->swreg20_27_vp9_segid_grp[i].sw_vp9segid_frame_loopfilter_value = reg_cxt->ls_info.feature_data[i][1]; - vp9_hw_regs->swreg20_27_vp9_segid_grp[i].sw_vp9segid_referinfo_en = (reg_cxt->ls_info.feature_mask[i] >> 2) & 0x1; - vp9_hw_regs->swreg20_27_vp9_segid_grp[i].sw_vp9segid_referinfo = reg_cxt->ls_info.feature_data[i][2]; - vp9_hw_regs->swreg20_27_vp9_segid_grp[i].sw_vp9segid_frame_skip_en = (reg_cxt->ls_info.feature_mask[i] >> 3) & 0x1; - } - - - vp9_hw_regs->swreg20_27_vp9_segid_grp[0].sw_vp9segid_abs_delta = reg_cxt->ls_info.abs_delta_last; - - vp9_hw_regs->swreg28_vp9_cprheader_config.sw_vp9_tx_mode = pic_param->txmode; - - vp9_hw_regs->swreg28_vp9_cprheader_config.sw_vp9_frame_reference_mode = pic_param->refmode; - - vp9_hw_regs->swreg32_vp9_ref_deltas_lastframe.sw_vp9_ref_deltas_lastframe = 0; - - if (!intraFlag) { - for (i = 0; i < 4; i++) - vp9_hw_regs->swreg32_vp9_ref_deltas_lastframe.sw_vp9_ref_deltas_lastframe |= (reg_cxt->ls_info.last_ref_deltas[i] & 0x7f) << (7 * i); - - for (i = 0; i < 2; i++) - vp9_hw_regs->swreg33_vp9_info_lastframe.sw_vp9_mode_deltas_lastframe |= (reg_cxt->ls_info.last_mode_deltas[i] & 0x7f) << (7 * i); - - - } else { - reg_cxt->ls_info.segmentation_enable_flag_last = 0; - reg_cxt->ls_info.last_intra_only = 1; - } - - vp9_hw_regs->swreg33_vp9_info_lastframe.sw_vp9_mode_deltas_lastframe = 0; - - vp9_hw_regs->swreg33_vp9_info_lastframe.sw_segmentation_enable_lstframe = reg_cxt->ls_info.segmentation_enable_flag_last; - vp9_hw_regs->swreg33_vp9_info_lastframe.sw_vp9_last_show_frame = reg_cxt->ls_info.last_show_frame; - vp9_hw_regs->swreg33_vp9_info_lastframe.sw_vp9_last_intra_only = reg_cxt->ls_info.last_intra_only; - vp9_hw_regs->swreg33_vp9_info_lastframe.sw_vp9_last_widthheight_eqcur = (pic_param->width == reg_cxt->ls_info.last_width) && (pic_param->height == reg_cxt->ls_info.last_height); - - vp9_hw_regs->swreg36_vp9_lasttile_size.sw_vp9_lasttile_size = stream_len - pic_param->first_partition_size; - - - if (!intraFlag) { - vp9_hw_regs->swreg29_vp9_lref_scale.sw_vp9_lref_hor_scale = pic_param->mvscale[0][0]; - vp9_hw_regs->swreg29_vp9_lref_scale.sw_vp9_lref_ver_scale = pic_param->mvscale[0][1]; - vp9_hw_regs->swreg30_vp9_gref_scale.sw_vp9_gref_hor_scale = pic_param->mvscale[1][0]; - vp9_hw_regs->swreg30_vp9_gref_scale.sw_vp9_gref_ver_scale = pic_param->mvscale[1][1]; - vp9_hw_regs->swreg31_vp9_aref_scale.sw_vp9_aref_hor_scale = pic_param->mvscale[2][0]; - vp9_hw_regs->swreg31_vp9_aref_scale.sw_vp9_aref_ver_scale = pic_param->mvscale[2][1]; - // vp9_hw_regs.swreg33_vp9_info_lastframe.sw_vp9_color_space_lastkeyframe = p_cm->color_space_last; - } - - - //reuse reg64, and it will be written by hardware to show performance. - vp9_hw_regs->swreg64_performance_cycle.sw_performance_cycle = 0; - vp9_hw_regs->swreg64_performance_cycle.sw_performance_cycle |= pic_param->width; - vp9_hw_regs->swreg64_performance_cycle.sw_performance_cycle |= pic_param->height << 16; - - vp9_hw_regs->swreg1_int.sw_dec_e = 1; - vp9_hw_regs->swreg1_int.sw_dec_timeout_e = 1; - - return MPP_OK; -} -/*! -*********************************************************************** -* \brief h -* start hard -*********************************************************************** -*/ -//extern "C" -MPP_RET hal_vp9d_start(void *hal, HalTaskInfo *task) -{ - RK_U32 i = 0; - MPP_RET ret = MPP_OK; - hal_vp9_context_t *reg_cxt = (hal_vp9_context_t *)hal; - VP9_REGS *hw_regs = ( VP9_REGS *)reg_cxt->hw_regs; - RK_U8 *p = (RK_U8*)reg_cxt->hw_regs; - - if (hw_regs == NULL) { - mpp_err("hal_vp9d_start hw_regs is NULL"); - return MPP_ERR_NULL_PTR; - } - for (i = 0; i < sizeof(VP9_REGS) / 4; i++) { - //vp9h_dbg(VP9H_DBG_REG, "RK_VP9_DEC: regs[%02d]=%08X\n", i, *((RK_U32*)p)); - //mpp_log("RK_VP9_DEC: regs[%02d]=%08X\n", i, *((RK_U32*)p)); - p += 4; - } -#ifdef RKPLATFORM -#if 1 - ret = VPUClientSendReg(reg_cxt->vpu_socket, (RK_U32*)hw_regs, sizeof(VP9_REGS) / 4); // 68 is the nb of uint32_t - if (ret != 0) { - mpp_err("VP9H_DBG_REG: ERROR: VPUClientSendReg Failed!!!\n"); - return MPP_ERR_VPUHW; - } -#endif -#endif - - (void)task; - return ret; -} -/*! -*********************************************************************** -* \brief -* wait hard -*********************************************************************** -*/ -//extern "C" -MPP_RET hal_vp9d_wait(void *hal, HalTaskInfo *task) -{ - MPP_RET ret = MPP_OK; -#ifdef RKPLATFORM - hal_vp9_context_t *reg_cxt = (hal_vp9_context_t *)hal; - DXVA_PicParams_VP9 *pic_param = (DXVA_PicParams_VP9*)task->dec.syntax.data; - RK_U32 i; - VPU_CMD_TYPE cmd; - RK_S32 len; - VP9_REGS *hw_regs = (VP9_REGS*)reg_cxt->hw_regs; - RK_U8* p = (RK_U8*)hw_regs; - MppBuffer framebuf = NULL; - mpp_buf_slot_get_prop(reg_cxt->slots, task->dec.output, SLOT_BUFFER, &framebuf); - - ret = VPUClientWaitResult(reg_cxt->vpu_socket, (RK_U32*)hw_regs, sizeof(VP9_REGS) / 4, &cmd, &len); - - for (i = 0; i < sizeof(VP9_REGS) / 4; i++) { - if (i == 1) { - vp9h_dbg(VP9H_DBG_REG, "RK_VP9_DEC: regs[%02d]=%08X\n", i, *((RK_U32*)p)); - // mpp_log("RK_VP9_DEC: regs[%02d]=%08X\n", i, *((RK_U32*)p)); - } - p += 4; - } - - reg_cxt->ls_info.abs_delta_last = pic_param->stVP9Segments.abs_delta; - for (i = 0 ; i < 4; i ++) { - reg_cxt->ls_info.last_ref_deltas[i] = pic_param->ref_deltas[i]; - } - - for (i = 0 ; i < 2; i ++) { - reg_cxt->ls_info.last_mode_deltas[i] = pic_param->mode_deltas[i]; - } - - for (i = 0; i < 8; i++) { - reg_cxt->ls_info.feature_data[i][0] = pic_param->stVP9Segments.feature_data[i][0]; - reg_cxt->ls_info.feature_data[i][1] = pic_param->stVP9Segments.feature_data[i][1]; - reg_cxt->ls_info.feature_data[i][2] = pic_param->stVP9Segments.feature_data[i][2]; - reg_cxt->ls_info.feature_data[i][3] = pic_param->stVP9Segments.feature_data[i][3]; - reg_cxt->ls_info.feature_mask[i] = pic_param->stVP9Segments.feature_mask[i]; - } - reg_cxt->ls_info.segmentation_enable_flag_last = pic_param->stVP9Segments.enabled; - reg_cxt->ls_info.last_show_frame = pic_param->show_frame; - reg_cxt->ls_info.last_width = pic_param->width; - reg_cxt->ls_info.last_height = pic_param->height; - reg_cxt->ls_info.last_intra_only = (!pic_param->frame_type || pic_param->intra_only); - vp9h_dbg(VP9H_DBG_PAR, "stVP9Segments.enabled = %d show_frame %d width %d height = %d last_intra_only = %d", pic_param->stVP9Segments.enabled, - pic_param->show_frame, pic_param->width, pic_param->height, reg_cxt->ls_info.last_intra_only); - if (reg_cxt->int_cb.callBack) { - if (pic_param->refresh_frame_context && !pic_param->parallelmode) { - hal_vp9d_update_counts(hal, task->dec.syntax.data); - reg_cxt->int_cb.callBack(reg_cxt->int_cb.opaque, (void*)&pic_param->counts); - } - } -#else - (void)hal; -#endif - (void)task; - return ret; -} -/*! -*********************************************************************** -* \brief -* reset -*********************************************************************** -*/ -//extern "C" -MPP_RET hal_vp9d_reset(void *hal) -{ - hal_vp9_context_t *reg_cxt = (hal_vp9_context_t *)hal; - mpp_log("hal_vp9d_reset in"); - memset(®_cxt->ls_info, 0, sizeof(reg_cxt->ls_info)); - reg_cxt->mv_base_addr = 0; - reg_cxt->pre_mv_base_addr = 0; - reg_cxt->last_segid_flag = 1; - return MPP_OK; -} -/*! -*********************************************************************** -* \brief -* flush -*********************************************************************** -*/ -//extern "C" -MPP_RET hal_vp9d_flush(void *hal) -{ - (void)hal; - - - return MPP_OK; -} -/*! -*********************************************************************** -* \brief -* control -*********************************************************************** -*/ -//extern "C" -MPP_RET hal_vp9d_control(void *hal, RK_S32 cmd_type, void *param) -{ - (void)hal; - (void)cmd_type; - (void)param; - - return MPP_OK; -} - - -const MppHalApi hal_api_vp9d = { - "vp9d_rkdec", - MPP_CTX_DEC, - MPP_VIDEO_CodingVP9, - sizeof(hal_vp9_context_t), - 0, - hal_vp9d_init, - hal_vp9d_deinit, - hal_vp9d_gen_regs, - hal_vp9d_start, - hal_vp9d_wait, - hal_vp9d_reset, - hal_vp9d_flush, - hal_vp9d_control, -}; - +/* +* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +#define MODULE_TAG "hal_vp9d_api" + +#include +#include +#include + +#include "rk_type.h" +#include "mpp_log.h" +#include "mpp_err.h" +#include "mpp_mem.h" +#include "mpp_env.h" +#include "mpp_common.h" +#include "mpp_dec.h" + +#include "hal_vp9d_api.h" +#include "hal_vp9d_reg.h" +#include "vpu.h" +#include "mpp_bitput.h" +#include "vp9d_syntax.h" +#include "hal_vp9d_table.h" + +#define PROBE_SIZE 4864 +#define COUNT_SIZE 13208 + +/*nCtuX*nCtuY*8*8/2 + * MaxnCtuX = 4096/64 + * MaxnCtuY = 2304/64 +*/ +#define MAX_SEGMAP_SIZE 73728 +/* + +*/ +#define MAX_INTER_CMD_SIZE 147456 + +RK_U32 vp9h_debug = 0; +//#define dump +#ifdef dump +static FILE *vp9_fp = NULL; +static FILE *vp9_fp1 = NULL; +static FILE *vp9_fp_yuv = NULL; + +static RK_S32 count = 0; +static RK_S32 frame_num = 0; +#endif +typedef struct vp9_dec_last_info { + RK_S32 abs_delta_last; + RK_S8 last_ref_deltas[4]; + RK_S8 last_mode_deltas[2]; + RK_U8 segmentation_enable_flag_last; + RK_U8 last_show_frame; + RK_U8 last_intra_only; + RK_U32 last_width; + RK_U32 last_height; + SHORT feature_data[8][4]; + UCHAR feature_mask[8]; +} vp9_dec_last_info_t; + +typedef struct hal_vp9_context { + RK_S32 vpu_socket; + MppBufSlots slots; + MppBufSlots packet_slots; + MppBufferGroup group; + MppBuffer probe_base; + MppBuffer count_base; + MppBuffer segid_cur_base; + MppBuffer segid_last_base; + void* hw_regs; + IOInterruptCB int_cb; + RK_U32 mv_base_addr; + RK_U32 pre_mv_base_addr; + vp9_dec_last_info_t ls_info; + /*swap between segid_cur_base & segid_last_base + 0 used segid_cur_base as last + 1 used segid_last_base as + */ + RK_U32 last_segid_flag; +} hal_vp9_context_t; + +static RK_U32 vp9_ver_align(RK_U32 val) +{ + return MPP_ALIGN(val, 64); +} + +static RK_U32 vp9_hor_align(RK_U32 val) +{ + return MPP_ALIGN(val, 128); +} +/*! +*********************************************************************** +* \brief +* init +*********************************************************************** +*/ +//extern "C" +MPP_RET hal_vp9d_init(void *hal, MppHalCfg *cfg) +{ + MPP_RET ret = MPP_OK; + hal_vp9_context_t *reg_cxt = (hal_vp9_context_t *)hal; + + if (NULL == reg_cxt) { + mpp_err("hal instant no alloc"); + return MPP_ERR_UNKNOW; + } + mpp_log("hal_vp9d_init in"); + reg_cxt->slots = cfg->frame_slots; + reg_cxt->int_cb = cfg->hal_int_cb; + reg_cxt->mv_base_addr = 0; + reg_cxt->pre_mv_base_addr = 0; + mpp_slots_set_prop(reg_cxt->slots, SLOTS_HOR_ALIGN, vp9_hor_align); + mpp_slots_set_prop(reg_cxt->slots, SLOTS_VER_ALIGN, vp9_ver_align); + + reg_cxt->packet_slots = cfg->packet_slots; + ///<- VPUClientInit +#ifdef RKPLATFORM + if (reg_cxt->vpu_socket <= 0) { + reg_cxt->vpu_socket = VPUClientInit(VPU_DEC_RKV); + if (reg_cxt->vpu_socket <= 0) { + mpp_err("vp9 reg_cxt->vpu_socket <= 0\n"); + return MPP_ERR_UNKNOW; + } + } +#endif + if (reg_cxt->group == NULL) { + +#ifdef RKPLATFORM + mpp_err("mpp_buffer_group_get_internal used ion in"); + ret = mpp_buffer_group_get_internal(®_cxt->group, MPP_BUFFER_TYPE_ION); +#else + ret = mpp_buffer_group_get_internal(®_cxt->group, MPP_BUFFER_TYPE_NORMAL); +#endif + if (MPP_OK != ret) { + mpp_err("vp9 mpp_buffer_group_get failed\n"); + return ret; + } + } + ret = mpp_buffer_get(reg_cxt->group, ®_cxt->probe_base, PROBE_SIZE); + if (MPP_OK != ret) { + mpp_err("vp9 probe_base get buffer failed\n"); + return ret; + } + + ret = mpp_buffer_get(reg_cxt->group, ®_cxt->count_base, COUNT_SIZE); + if (MPP_OK != ret) { + mpp_err("vp9 count_base get buffer failed\n"); + return ret; + } + + ret = mpp_buffer_get(reg_cxt->group, ®_cxt->segid_cur_base, MAX_SEGMAP_SIZE); + if (MPP_OK != ret) { + mpp_err("vp9 segid_cur_base get buffer failed\n"); + return ret; + } + + ret = mpp_buffer_get(reg_cxt->group, ®_cxt->segid_last_base, MAX_SEGMAP_SIZE); + if (MPP_OK != ret) { + mpp_err("vp9 segid_last_base get buffer failed\n"); + return ret; + } + + mpp_env_get_u32("vp9h_debug", &vp9h_debug, 0); + + reg_cxt->hw_regs = mpp_calloc_size(void, sizeof(VP9_REGS)); + + reg_cxt->last_segid_flag = 1; +#ifdef dump + if (vp9_fp_yuv != NULL) { + fclose(vp9_fp_yuv); + } + + frame_num = 0; + vp9_fp_yuv = fopen("data/vp9_out.yuv", "wb"); + count = 0; +#endif + return ret = MPP_OK; + +} +/*! +*********************************************************************** +* \brief +* deinit +*********************************************************************** +*/ +//extern "C" +MPP_RET hal_vp9d_deinit(void *hal) +{ + MPP_RET ret = MPP_OK; + hal_vp9_context_t *reg_cxt = (hal_vp9_context_t *)hal; + + if (reg_cxt->probe_base) { + ret = mpp_buffer_put(reg_cxt->probe_base); + if (MPP_OK != ret) { + mpp_err("vp9 probe_base get buffer failed\n"); + return ret; + } + } + + if (reg_cxt->count_base) { + ret = mpp_buffer_put(reg_cxt->count_base); + if (MPP_OK != ret) { + mpp_err("vp9 count_base put buffer failed\n"); + return ret; + } + } + + if (reg_cxt->segid_cur_base) { + ret = mpp_buffer_put(reg_cxt->segid_cur_base); + if (MPP_OK != ret) { + mpp_err("vp9 segid_cur_base put buffer failed\n"); + return ret; + } + } + + if (reg_cxt->segid_last_base) { + ret = mpp_buffer_put(reg_cxt->segid_last_base); + if (MPP_OK != ret) { + mpp_err("vp9 segid_last_base put buffer failed\n"); + return ret; + } + } + + if (reg_cxt->group) { + ret = mpp_buffer_group_put(reg_cxt->group); + if (MPP_OK != ret) { + mpp_err("vp9d group free buffer failed\n"); + return ret; + } + } + return ret = MPP_OK; +} + +MPP_RET hal_vp9d_output_probe(void *hal, void *dxva) +{ + RK_S32 i, j, k, m, n; + RK_S32 fifo_len = 304; + RK_U64 *probe_packet = NULL; + BitputCtx_t bp; + DXVA_PicParams_VP9 *pic_param = (DXVA_PicParams_VP9*)dxva; + RK_S32 intraFlag = (!pic_param->frame_type || pic_param->intra_only); + vp9_prob partition_probs[PARTITION_CONTEXTS][PARTITION_TYPES - 1]; + vp9_prob uv_mode_prob[INTRA_MODES][INTRA_MODES - 1]; +#ifdef RKPLATFORM + hal_vp9_context_t *reg_cxt = (hal_vp9_context_t*)hal; + void *probe_ptr = mpp_buffer_get_ptr(reg_cxt->probe_base); + if (NULL == probe_ptr) { + + mpp_err("probe_ptr get ptr error"); + return MPP_ERR_NOMEM; + } + memset(probe_ptr, 0, 304 * 8); +#else + (void)hal; +#endif + + if (intraFlag) { + memcpy(partition_probs, vp9_kf_partition_probs, sizeof(partition_probs)); + memcpy(uv_mode_prob, vp9_kf_uv_mode_prob, sizeof(uv_mode_prob)); + } else { + memcpy(partition_probs, pic_param->prob.partition, sizeof(partition_probs)); + memcpy(uv_mode_prob, pic_param->prob.uv_mode, sizeof(uv_mode_prob)); + } + + probe_packet = mpp_calloc(RK_U64, fifo_len + 1); + mpp_set_bitput_ctx(&bp, probe_packet, fifo_len); + //sb info 5 x 128 bit + for (i = 0; i < PARTITION_CONTEXTS; i++) //kf_partition_prob + for (j = 0; j < PARTITION_TYPES - 1; j++) + mpp_put_bits(&bp, partition_probs[i][j], 8); //48 + + for (i = 0; i < PREDICTION_PROBS; i++) //Segment_id_pred_prob //3 + mpp_put_bits(&bp, pic_param->stVP9Segments.pred_probs[i], 8); + + for (i = 0; i < SEG_TREE_PROBS; i++) //Segment_id_probs + mpp_put_bits(&bp, pic_param->stVP9Segments.tree_probs[i], 8); //7 + + for (i = 0; i < SKIP_CONTEXTS; i++) //Skip_flag_probs //3 + mpp_put_bits(&bp, pic_param->prob.skip[i], 8); + + for (i = 0; i < TX_SIZE_CONTEXTS; i++) //Tx_size_probs //6 + for (j = 0; j < TX_SIZES - 1; j++) + mpp_put_bits(&bp, pic_param->prob.tx32p[i][j], 8); + + for (i = 0; i < TX_SIZE_CONTEXTS; i++) //Tx_size_probs //4 + for (j = 0; j < TX_SIZES - 2; j++) + mpp_put_bits(&bp, pic_param->prob.tx16p[i][j], 8); + + for (i = 0; i < TX_SIZE_CONTEXTS; i++) //Tx_size_probs //2 + mpp_put_bits(&bp, pic_param->prob.tx8p[i], 8); + + for (i = 0; i < INTRA_INTER_CONTEXTS; i++) //Tx_size_probs //4 + mpp_put_bits(&bp, pic_param->prob.intra[i], 8); + + mpp_put_align(&bp, 128, 0); + if (intraFlag) { //intra probs + //intra only //149 x 128 bit ,aligned to 152 x 128 bit + //coeff releated prob 64 x 128 bit + for (i = 0; i < TX_SIZES; i++) + for (j = 0; j < PLANE_TYPES; j++) { + RK_S32 byte_count = 0; + for (k = 0; k < COEF_BANDS; k++) { + for (m = 0; m < COEFF_CONTEXTS; m++) + for (n = 0; n < UNCONSTRAINED_NODES; n++) { + mpp_put_bits(&bp, pic_param->prob.coef[i][j][0][k][m][n], 8); + + byte_count++; + if (byte_count == 27) { + mpp_put_align(&bp, 128, 0); + byte_count = 0; + } + } + } + mpp_put_align(&bp, 128, 0); + } + + //intra mode prob 80 x 128 bit + for (i = 0; i < INTRA_MODES; i++) { //vp9_kf_y_mode_prob + RK_S32 byte_count = 0; + for (j = 0; j < INTRA_MODES; j++) + for (k = 0; k < INTRA_MODES - 1; k++) { + mpp_put_bits(&bp, vp9_kf_y_mode_prob[i][j][k], 8); + byte_count++; + if (byte_count == 27) { + byte_count = 0; + mpp_put_align(&bp, 128, 0); + } + + } + if (i < 4) { + for (m = 0; m < (i < 3 ? 23 : 21); m++) + mpp_put_bits(&bp, ((vp9_prob *)(&vp9_kf_uv_mode_prob[0][0]))[i * 23 + m], 8); + for (; m < 23; m++) + mpp_put_bits(&bp, 0, 8); + } else { + for (m = 0; m < 23; m++) + mpp_put_bits(&bp, 0, 8); + } + mpp_put_align(&bp, 128, 0); + } + //align to 152 x 128 bit + for (i = 0; i < INTER_PROB_SIZE_ALIGN_TO_128 - INTRA_PROB_SIZE_ALIGN_TO_128; i++) { //aligned to 153 x 256 bit + mpp_put_bits(&bp, 0, 8); + mpp_put_align(&bp, 128, 0); + } + } else { + //inter probs + //151 x 128 bit ,aligned to 152 x 128 bit + //inter only + + //intra_y_mode & inter_block info 6 x 128 bit + for (i = 0; i < BLOCK_SIZE_GROUPS; i++) //intra_y_mode + for (j = 0; j < INTRA_MODES - 1; j++) + mpp_put_bits(&bp, pic_param->prob.y_mode[i][j], 8); + + for (i = 0; i < COMP_INTER_CONTEXTS; i++) //reference_mode prob + mpp_put_bits(&bp, pic_param->prob.comp[i], 8); + + for (i = 0; i < REF_CONTEXTS; i++) //comp ref bit + mpp_put_bits(&bp, pic_param->prob.comp_ref[i], 8); + + for (i = 0; i < REF_CONTEXTS; i++) //single ref bit + for (j = 0; j < 2; j++) + mpp_put_bits(&bp, pic_param->prob.single_ref[i][j], 8); + + for (i = 0; i < INTER_MODE_CONTEXTS; i++) //mv mode bit + for (j = 0; j < INTER_MODES - 1; j++) + mpp_put_bits(&bp, pic_param->prob.mv_mode[i][j], 8); + + + for (i = 0; i < SWITCHABLE_FILTER_CONTEXTS; i++) //comp ref bit + for (j = 0; j < SWITCHABLE_FILTERS - 1; j++) + mpp_put_bits(&bp, pic_param->prob.filter[i][j], 8); + + mpp_put_align(&bp, 128, 0); + + //128 x 128bit + //coeff releated + for (i = 0; i < TX_SIZES; i++) + for (j = 0; j < PLANE_TYPES; j++) { + RK_S32 byte_count = 0; + for (k = 0; k < COEF_BANDS; k++) { + for (m = 0; m < COEFF_CONTEXTS; m++) + for (n = 0; n < UNCONSTRAINED_NODES; n++) { + mpp_put_bits(&bp, pic_param->prob.coef[i][j][0][k][m][n], 8); + byte_count++; + if (byte_count == 27) { + mpp_put_align(&bp, 128, 0); + byte_count = 0; + } + } + } + mpp_put_align(&bp, 128, 0); + } + for (i = 0; i < TX_SIZES; i++) + for (j = 0; j < PLANE_TYPES; j++) { + RK_S32 byte_count = 0; + for (k = 0; k < COEF_BANDS; k++) { + for (m = 0; m < COEFF_CONTEXTS; m++) { + for (n = 0; n < UNCONSTRAINED_NODES; n++) { + mpp_put_bits(&bp, pic_param->prob.coef[i][j][1][k][m][n], 8); + byte_count++; + if (byte_count == 27) { + mpp_put_align(&bp, 128, 0); + byte_count = 0; + } + } + + } + } + mpp_put_align(&bp, 128, 0); + } + + //intra uv mode 6 x 128 + for (i = 0; i < 3; i++) //intra_uv_mode + for (j = 0; j < INTRA_MODES - 1; j++) + mpp_put_bits(&bp, uv_mode_prob[i][j], 8); + mpp_put_align(&bp, 128, 0); + + for (; i < 6; i++) //intra_uv_mode + for (j = 0; j < INTRA_MODES - 1; j++) + mpp_put_bits(&bp, uv_mode_prob[i][j], 8); + mpp_put_align(&bp, 128, 0); + + for (; i < 9; i++) //intra_uv_mode + for (j = 0; j < INTRA_MODES - 1; j++) + mpp_put_bits(&bp, uv_mode_prob[i][j], 8); + mpp_put_align(&bp, 128, 0); + for (; i < INTRA_MODES; i++) //intra_uv_mode + for (j = 0; j < INTRA_MODES - 1; j++) + mpp_put_bits(&bp, uv_mode_prob[i][j], 8); + + mpp_put_align(&bp, 128, 0); + mpp_put_bits(&bp, 0, 8); + mpp_put_align(&bp, 128, 0); + + //mv releated 6 x 128 + for (i = 0; i < MV_JOINTS - 1; i++) //mv_joint_type + mpp_put_bits(&bp, pic_param->prob.mv_joint[i], 8); + + for (i = 0; i < 2; i++) { //sign bit + mpp_put_bits(&bp, pic_param->prob.mv_comp[i].sign, 8); + } + for (i = 0; i < 2; i++) { //classes bit + for (j = 0; j < MV_CLASSES - 1; j++) + mpp_put_bits(&bp, pic_param->prob.mv_comp[i].classes[j], 8); + } + for (i = 0; i < 2; i++) { //classe0 bit + mpp_put_bits(&bp, pic_param->prob.mv_comp[i].class0, 8); + } + for (i = 0; i < 2; i++) { // bits + for (j = 0; j < MV_OFFSET_BITS; j++) + mpp_put_bits(&bp, pic_param->prob.mv_comp[i].bits[j], 8); + } + for (i = 0; i < 2; i++) { //class0_fp bit + for (j = 0; j < CLASS0_SIZE; j++) + for (k = 0; k < MV_FP_SIZE - 1; k++) + mpp_put_bits(&bp, pic_param->prob.mv_comp[i].class0_fp[j][k], 8); + } + for (i = 0; i < 2; i++) { //comp ref bit + for (j = 0; j < MV_FP_SIZE - 1; j++) + mpp_put_bits(&bp, pic_param->prob.mv_comp[i].fp[j], 8); + } + for (i = 0; i < 2; i++) { //class0_hp bit + + mpp_put_bits(&bp, pic_param->prob.mv_comp[i].class0_hp, 8); + } + for (i = 0; i < 2; i++) { //hp bit + mpp_put_bits(&bp, pic_param->prob.mv_comp[i].hp, 8); + } + mpp_put_align(&bp, 128, 0); + } +#ifdef RKPLATFORM + memcpy(probe_ptr, probe_packet, 304 * 8); +#endif +#ifdef dump + if (intraFlag) { + fwrite(probe_packet, 1, 302 * 8, vp9_fp); + } else { + fwrite(probe_packet, 1, 304 * 8, vp9_fp); + } + fflush(vp9_fp); +#endif + if (probe_packet != NULL) + mpp_free(probe_packet); + + return 0; +} +void hal_vp9d_update_counts(void *hal, void *dxva) +{ + hal_vp9_context_t *reg_cxt = (hal_vp9_context_t*)hal; + DXVA_PicParams_VP9 *s = (DXVA_PicParams_VP9*)dxva; + RK_S32 i, j, m, n, k; + RK_U32 *eob_coef; + RK_S32 ref_type; +#ifdef dump + RK_U32 count_length; +#endif + RK_U32 com_len = 0; + + RK_U8 *counts_ptr = mpp_buffer_get_ptr(reg_cxt->count_base); + if (NULL == counts_ptr) { + mpp_err("counts_ptr get ptr error"); + return; + } + +#ifdef dump + if (!(s->frame_type == 0 || s->intra_only)) //inter + count_length = (213 * 64 + 576 * 5 * 32) / 8; + else //intra + count_length = (49 * 64 + 288 * 5 * 32) / 8; + + fwrite(counts_ptr, 1, count_length, vp9_fp1); + fflush(vp9_fp1); +#endif + if ((s->frame_type == 0 || s->intra_only)) { + com_len = sizeof(s->counts.partition) + sizeof(s->counts.skip) + sizeof(s->counts.intra) + + sizeof(s->counts.tx32p) + sizeof(s->counts.tx16p) + sizeof(s->counts.tx8p); + } else { + com_len = sizeof(s->counts) - sizeof(s->counts.coef) - sizeof(s->counts.eob); + } + eob_coef = (RK_U32 *)(counts_ptr + com_len); + memcpy(&s->counts, counts_ptr, com_len); + ref_type = (!(s->frame_type == 0 || s->intra_only)) ? 2 : 1; + if (ref_type == 1) { + memset(s->counts.eob, 0, sizeof(s->counts.eob)); + memset(s->counts.coef, 0, sizeof(s->counts.coef)); + } + for (i = 0; i < ref_type; i++) { + for (j = 0; j < 4; j++) { + for (m = 0; m < 2; m++) { + for (n = 0; n < 6; n++) { + for (k = 0; k < 6; k++) { + s->counts.eob[j][m][i][n][k][0] = eob_coef[1]; + s->counts.eob[j][m][i][n][k][1] = eob_coef[0] - eob_coef[1]; //ffmpeg need do branch_ct[UNCONSTRAINED_NODES][2] = { neob, eob_counts[i][j][k][l] - neob }, + s->counts.coef[j][m][i][n][k][0] = eob_coef[2]; + s->counts.coef[j][m][i][n][k][1] = eob_coef[3]; + s->counts.coef[j][m][i][n][k][2] = eob_coef[4]; + eob_coef += 5; + } + } + } + } + } +} + +/*! +*********************************************************************** +* \brief +* generate register +*********************************************************************** +*/ +//extern "C" +MPP_RET hal_vp9d_gen_regs(void *hal, HalTaskInfo *task) +{ + RK_S32 i; + RK_U8 bit_depth = 0; + RK_U32 pic_h[3] = { 0 }; + RK_U32 ref_frame_width_y; + RK_U32 ref_frame_height_y; + RK_S32 stream_len = 0, aglin_offset = 0; + RK_U32 y_hor_virstride, uv_hor_virstride, y_virstride, uv_virstride, yuv_virstride; + RK_U8 *bitstream = NULL; + MppBuffer streambuf = NULL; + RK_U32 sw_y_hor_virstride; + RK_U32 sw_uv_hor_virstride; + RK_U32 sw_y_virstride; + RK_U32 sw_uv_virstride; + RK_U32 sw_yuv_virstride ; + RK_U8 ref_idx = 0; + RK_U32 *reg_ref_base = 0; +#ifdef dump + char filename[20] = "data/probe"; + char filename1[20] = "data/count"; +#endif + RK_S32 intraFlag = 0; + +#ifdef RKPLATFORM + MppBuffer framebuf = NULL; +#endif +#ifdef dump + if (vp9_fp != NULL) { + fclose(vp9_fp); + + } + if (vp9_fp1 != NULL) { + fclose(vp9_fp1); + } + sprintf(&filename[10], "%d.bin", count); + sprintf(&filename1[10], "%d.bin", count); + mpp_log("filename %s", filename); + mpp_log("filename %s", filename1); + vp9_fp = fopen(filename, "wb"); + vp9_fp1 = fopen(filename1, "wb"); + count++; +#endif + + hal_vp9_context_t *reg_cxt = (hal_vp9_context_t*)hal; + DXVA_PicParams_VP9 *pic_param = (DXVA_PicParams_VP9*)task->dec.syntax.data; + VP9_REGS *vp9_hw_regs = (VP9_REGS*)reg_cxt->hw_regs; + intraFlag = (!pic_param->frame_type || pic_param->intra_only); + hal_vp9d_output_probe(hal, task->dec.syntax.data); + stream_len = (RK_S32)mpp_packet_get_length(task->dec.input_packet); + memset(reg_cxt->hw_regs, 0, sizeof(VP9_REGS)); + vp9_hw_regs->swreg2_sysctrl.sw_dec_mode = 2; //set as vp9 dec + vp9_hw_regs->swreg5_stream_len = ((stream_len + 15) & (~15)) + 0x80; + + mpp_buf_slot_get_prop(reg_cxt->packet_slots, task->dec.input, SLOT_BUFFER, &streambuf); + bitstream = mpp_buffer_get_ptr(streambuf); + aglin_offset = vp9_hw_regs->swreg5_stream_len - stream_len; + if (aglin_offset > 0) { + memset((void *)(bitstream + stream_len), 0, aglin_offset); + } + + //--- caculate the yuv_frame_size and mv_size + bit_depth = pic_param->BitDepthMinus8Luma + 8; + pic_h[0] = vp9_ver_align(pic_param->height); //p_cm->height; + pic_h[1] = vp9_ver_align(pic_param->height) / 2; //(p_cm->height + 1) / 2; + pic_h[2] = pic_h[1]; + + sw_y_hor_virstride = (vp9_hor_align((pic_param->width * bit_depth) >> 3) >> 4); + sw_uv_hor_virstride = (vp9_hor_align((pic_param->width * bit_depth) >> 3) >> 4); + sw_y_virstride = pic_h[0] * sw_y_hor_virstride; + + sw_uv_virstride = pic_h[1] * sw_uv_hor_virstride; + sw_yuv_virstride = sw_y_virstride + sw_uv_virstride; + + vp9_hw_regs->swreg3_picpar.sw_y_hor_virstride = sw_y_hor_virstride; + vp9_hw_regs->swreg3_picpar.sw_uv_hor_virstride = sw_uv_hor_virstride; + vp9_hw_regs->swreg8_y_virstride.sw_y_virstride = sw_y_virstride; + vp9_hw_regs->swreg9_yuv_virstride.sw_yuv_virstride = sw_yuv_virstride; + +#ifdef RKPLATFORM + if (!pic_param->intra_only && pic_param->frame_type && !pic_param->error_resilient_mode) { + reg_cxt->pre_mv_base_addr = reg_cxt->mv_base_addr; + } + + if (!(pic_param->stVP9Segments.enabled && !pic_param->stVP9Segments.update_map)) { + if (!pic_param->intra_only && pic_param->frame_type && !pic_param->error_resilient_mode) { + if (reg_cxt->last_segid_flag) { + reg_cxt->last_segid_flag = 0; + } else { + reg_cxt->last_segid_flag = 1; + } + } + } + mpp_buf_slot_get_prop(reg_cxt->slots, task->dec.output, SLOT_BUFFER, &framebuf); + vp9_hw_regs->swreg7_decout_base = mpp_buffer_get_fd(framebuf); + vp9_hw_regs->swreg4_strm_rlc_base = mpp_buffer_get_fd(streambuf); + vp9_hw_regs->swreg6_cabactbl_prob_base = mpp_buffer_get_fd(reg_cxt->probe_base); + vp9_hw_regs->swreg14_vp9_count_base = mpp_buffer_get_fd(reg_cxt->count_base); + + if (reg_cxt->last_segid_flag) { + vp9_hw_regs->swreg15_vp9_segidlast_base = mpp_buffer_get_fd(reg_cxt->segid_last_base); + vp9_hw_regs->swreg16_vp9_segidcur_base = mpp_buffer_get_fd(reg_cxt->segid_cur_base); + } else { + vp9_hw_regs->swreg15_vp9_segidlast_base = mpp_buffer_get_fd(reg_cxt->segid_cur_base); + vp9_hw_regs->swreg16_vp9_segidcur_base = mpp_buffer_get_fd(reg_cxt->segid_last_base); + } + + if (VPUClientGetIOMMUStatus() > 0) { + reg_cxt->mv_base_addr = vp9_hw_regs->swreg7_decout_base | ((sw_yuv_virstride << 4) << 6); + } else { + reg_cxt->mv_base_addr = vp9_hw_regs->swreg7_decout_base + (sw_yuv_virstride << 4); + } + + if (!reg_cxt->pre_mv_base_addr) { + reg_cxt->pre_mv_base_addr = reg_cxt->mv_base_addr; + } + vp9_hw_regs->swreg52_vp9_refcolmv_base = reg_cxt->pre_mv_base_addr; +#endif + + vp9_hw_regs->swreg10_vp9_cprheader_offset.sw_vp9_cprheader_offset = 0; //no use now. + reg_ref_base = &vp9_hw_regs->swreg11_vp9_referlast_base; + for (i = 0; i < 3; i++) { + ref_idx = pic_param->frame_refs[i].Index7Bits; + ref_frame_width_y = pic_param->ref_frame_coded_width[ref_idx]; + ref_frame_height_y = pic_param->ref_frame_coded_height[ref_idx]; + pic_h[0] = vp9_ver_align(ref_frame_height_y); + pic_h[1] = vp9_ver_align(ref_frame_height_y) / 2; + y_hor_virstride = (vp9_hor_align((ref_frame_width_y * bit_depth) >> 3) >> 4); + uv_hor_virstride = (vp9_hor_align((ref_frame_width_y * bit_depth) >> 3) >> 4); + y_virstride = y_hor_virstride * pic_h[0]; + uv_virstride = uv_hor_virstride * pic_h[1]; + yuv_virstride = y_virstride + uv_virstride; +#ifdef RKPLATFORM + if (pic_param->ref_frame_map[ref_idx].Index7Bits < 0x7f) { + mpp_buf_slot_get_prop(reg_cxt->slots, pic_param->ref_frame_map[ref_idx].Index7Bits, SLOT_BUFFER, &framebuf); + } +#endif + if (pic_param->ref_frame_map[ref_idx].Index7Bits < 0x7f) { + switch (i) { + case 0: { + + vp9_hw_regs->swreg17_vp9_frame_size_last.sw_framewidth_last = ref_frame_width_y; + vp9_hw_regs->swreg17_vp9_frame_size_last.sw_frameheight_last = ref_frame_height_y; + vp9_hw_regs->swreg37_vp9_lastf_hor_virstride.sw_vp9_lastfy_hor_virstride = y_hor_virstride; + vp9_hw_regs->swreg37_vp9_lastf_hor_virstride.sw_vp9_lastfuv_hor_virstride = uv_hor_virstride; + vp9_hw_regs->swreg48_vp9_last_ystride.sw_vp9_lastfy_virstride = y_virstride; + vp9_hw_regs->swreg51_vp9_lastref_yuvstride.sw_vp9_lastref_yuv_virstride = yuv_virstride; + break; + } + case 1: { + vp9_hw_regs->swreg18_vp9_frame_size_golden.sw_framewidth_golden = ref_frame_width_y; + vp9_hw_regs->swreg18_vp9_frame_size_golden.sw_frameheight_golden = ref_frame_height_y; + vp9_hw_regs->swreg38_vp9_goldenf_hor_virstride.sw_vp9_goldenfy_hor_virstride = y_hor_virstride; + vp9_hw_regs->swreg38_vp9_goldenf_hor_virstride.sw_vp9_goldenuv_hor_virstride = uv_hor_virstride; + vp9_hw_regs->swreg49_vp9_golden_ystride.sw_vp9_goldeny_virstride = y_virstride; + break; + } + case 2: { + vp9_hw_regs->swreg19_vp9_frame_size_altref.sw_framewidth_alfter = ref_frame_width_y; + vp9_hw_regs->swreg19_vp9_frame_size_altref.sw_frameheight_alfter = ref_frame_height_y; + vp9_hw_regs->swreg39_vp9_altreff_hor_virstride.sw_vp9_altreffy_hor_virstride = y_hor_virstride; + vp9_hw_regs->swreg39_vp9_altreff_hor_virstride.sw_vp9_altreffuv_hor_virstride = uv_hor_virstride; + vp9_hw_regs->swreg50_vp9_altrefy_ystride.sw_vp9_altrefy_virstride = y_virstride; + break; + } + default: + break; + + } +#ifdef RKPLATFORM + /*0 map to 11*/ + /*1 map to 12*/ + /*2 map to 13*/ + if (framebuf != NULL) { + reg_ref_base[i] = mpp_buffer_get_fd(framebuf); + } else { + mpp_log("ref buff address is no valid used out as base slot index 0x%x", pic_param->ref_frame_map[ref_idx].Index7Bits); + reg_ref_base[i] = vp9_hw_regs->swreg7_decout_base; //set + } +#endif + } else { + reg_ref_base[i] = vp9_hw_regs->swreg7_decout_base; //set + } + } + + for (i = 0; i < 8; i++) { + vp9_hw_regs->swreg20_27_vp9_segid_grp[i].sw_vp9segid_frame_qp_delta_en = (reg_cxt->ls_info.feature_mask[i]) & 0x1; + vp9_hw_regs->swreg20_27_vp9_segid_grp[i].sw_vp9segid_frame_qp_delta = reg_cxt->ls_info.feature_data[i][0]; + vp9_hw_regs->swreg20_27_vp9_segid_grp[i].sw_vp9segid_frame_loopfitler_value_en = (reg_cxt->ls_info.feature_mask[i] >> 1) & 0x1; + vp9_hw_regs->swreg20_27_vp9_segid_grp[i].sw_vp9segid_frame_loopfilter_value = reg_cxt->ls_info.feature_data[i][1]; + vp9_hw_regs->swreg20_27_vp9_segid_grp[i].sw_vp9segid_referinfo_en = (reg_cxt->ls_info.feature_mask[i] >> 2) & 0x1; + vp9_hw_regs->swreg20_27_vp9_segid_grp[i].sw_vp9segid_referinfo = reg_cxt->ls_info.feature_data[i][2]; + vp9_hw_regs->swreg20_27_vp9_segid_grp[i].sw_vp9segid_frame_skip_en = (reg_cxt->ls_info.feature_mask[i] >> 3) & 0x1; + } + + + vp9_hw_regs->swreg20_27_vp9_segid_grp[0].sw_vp9segid_abs_delta = reg_cxt->ls_info.abs_delta_last; + + vp9_hw_regs->swreg28_vp9_cprheader_config.sw_vp9_tx_mode = pic_param->txmode; + + vp9_hw_regs->swreg28_vp9_cprheader_config.sw_vp9_frame_reference_mode = pic_param->refmode; + + vp9_hw_regs->swreg32_vp9_ref_deltas_lastframe.sw_vp9_ref_deltas_lastframe = 0; + + if (!intraFlag) { + for (i = 0; i < 4; i++) + vp9_hw_regs->swreg32_vp9_ref_deltas_lastframe.sw_vp9_ref_deltas_lastframe |= (reg_cxt->ls_info.last_ref_deltas[i] & 0x7f) << (7 * i); + + for (i = 0; i < 2; i++) + vp9_hw_regs->swreg33_vp9_info_lastframe.sw_vp9_mode_deltas_lastframe |= (reg_cxt->ls_info.last_mode_deltas[i] & 0x7f) << (7 * i); + + + } else { + reg_cxt->ls_info.segmentation_enable_flag_last = 0; + reg_cxt->ls_info.last_intra_only = 1; + } + + vp9_hw_regs->swreg33_vp9_info_lastframe.sw_vp9_mode_deltas_lastframe = 0; + + vp9_hw_regs->swreg33_vp9_info_lastframe.sw_segmentation_enable_lstframe = reg_cxt->ls_info.segmentation_enable_flag_last; + vp9_hw_regs->swreg33_vp9_info_lastframe.sw_vp9_last_show_frame = reg_cxt->ls_info.last_show_frame; + vp9_hw_regs->swreg33_vp9_info_lastframe.sw_vp9_last_intra_only = reg_cxt->ls_info.last_intra_only; + vp9_hw_regs->swreg33_vp9_info_lastframe.sw_vp9_last_widthheight_eqcur = (pic_param->width == reg_cxt->ls_info.last_width) && (pic_param->height == reg_cxt->ls_info.last_height); + + vp9_hw_regs->swreg36_vp9_lasttile_size.sw_vp9_lasttile_size = stream_len - pic_param->first_partition_size; + + + if (!intraFlag) { + vp9_hw_regs->swreg29_vp9_lref_scale.sw_vp9_lref_hor_scale = pic_param->mvscale[0][0]; + vp9_hw_regs->swreg29_vp9_lref_scale.sw_vp9_lref_ver_scale = pic_param->mvscale[0][1]; + vp9_hw_regs->swreg30_vp9_gref_scale.sw_vp9_gref_hor_scale = pic_param->mvscale[1][0]; + vp9_hw_regs->swreg30_vp9_gref_scale.sw_vp9_gref_ver_scale = pic_param->mvscale[1][1]; + vp9_hw_regs->swreg31_vp9_aref_scale.sw_vp9_aref_hor_scale = pic_param->mvscale[2][0]; + vp9_hw_regs->swreg31_vp9_aref_scale.sw_vp9_aref_ver_scale = pic_param->mvscale[2][1]; + // vp9_hw_regs.swreg33_vp9_info_lastframe.sw_vp9_color_space_lastkeyframe = p_cm->color_space_last; + } + + + //reuse reg64, and it will be written by hardware to show performance. + vp9_hw_regs->swreg64_performance_cycle.sw_performance_cycle = 0; + vp9_hw_regs->swreg64_performance_cycle.sw_performance_cycle |= pic_param->width; + vp9_hw_regs->swreg64_performance_cycle.sw_performance_cycle |= pic_param->height << 16; + + vp9_hw_regs->swreg1_int.sw_dec_e = 1; + vp9_hw_regs->swreg1_int.sw_dec_timeout_e = 1; + + return MPP_OK; +} +/*! +*********************************************************************** +* \brief h +* start hard +*********************************************************************** +*/ +//extern "C" +MPP_RET hal_vp9d_start(void *hal, HalTaskInfo *task) +{ + RK_U32 i = 0; + MPP_RET ret = MPP_OK; + hal_vp9_context_t *reg_cxt = (hal_vp9_context_t *)hal; + VP9_REGS *hw_regs = ( VP9_REGS *)reg_cxt->hw_regs; + RK_U8 *p = (RK_U8*)reg_cxt->hw_regs; + + if (hw_regs == NULL) { + mpp_err("hal_vp9d_start hw_regs is NULL"); + return MPP_ERR_NULL_PTR; + } + for (i = 0; i < sizeof(VP9_REGS) / 4; i++) { + //vp9h_dbg(VP9H_DBG_REG, "RK_VP9_DEC: regs[%02d]=%08X\n", i, *((RK_U32*)p)); + //mpp_log("RK_VP9_DEC: regs[%02d]=%08X\n", i, *((RK_U32*)p)); + p += 4; + } +#ifdef RKPLATFORM +#if 1 + ret = VPUClientSendReg(reg_cxt->vpu_socket, (RK_U32*)hw_regs, sizeof(VP9_REGS) / 4); // 68 is the nb of uint32_t + if (ret != 0) { + mpp_err("VP9H_DBG_REG: ERROR: VPUClientSendReg Failed!!!\n"); + return MPP_ERR_VPUHW; + } +#endif +#endif + + (void)task; + return ret; +} +/*! +*********************************************************************** +* \brief +* wait hard +*********************************************************************** +*/ +//extern "C" +MPP_RET hal_vp9d_wait(void *hal, HalTaskInfo *task) +{ + MPP_RET ret = MPP_OK; +#ifdef RKPLATFORM + hal_vp9_context_t *reg_cxt = (hal_vp9_context_t *)hal; + DXVA_PicParams_VP9 *pic_param = (DXVA_PicParams_VP9*)task->dec.syntax.data; + RK_U32 i; + VPU_CMD_TYPE cmd; + RK_S32 len; + VP9_REGS *hw_regs = (VP9_REGS*)reg_cxt->hw_regs; + RK_U8* p = (RK_U8*)hw_regs; + MppBuffer framebuf = NULL; + mpp_buf_slot_get_prop(reg_cxt->slots, task->dec.output, SLOT_BUFFER, &framebuf); + + ret = VPUClientWaitResult(reg_cxt->vpu_socket, (RK_U32*)hw_regs, sizeof(VP9_REGS) / 4, &cmd, &len); + + for (i = 0; i < sizeof(VP9_REGS) / 4; i++) { + if (i == 1) { + vp9h_dbg(VP9H_DBG_REG, "RK_VP9_DEC: regs[%02d]=%08X\n", i, *((RK_U32*)p)); + // mpp_log("RK_VP9_DEC: regs[%02d]=%08X\n", i, *((RK_U32*)p)); + } + p += 4; + } + + reg_cxt->ls_info.abs_delta_last = pic_param->stVP9Segments.abs_delta; + for (i = 0 ; i < 4; i ++) { + reg_cxt->ls_info.last_ref_deltas[i] = pic_param->ref_deltas[i]; + } + + for (i = 0 ; i < 2; i ++) { + reg_cxt->ls_info.last_mode_deltas[i] = pic_param->mode_deltas[i]; + } + + for (i = 0; i < 8; i++) { + reg_cxt->ls_info.feature_data[i][0] = pic_param->stVP9Segments.feature_data[i][0]; + reg_cxt->ls_info.feature_data[i][1] = pic_param->stVP9Segments.feature_data[i][1]; + reg_cxt->ls_info.feature_data[i][2] = pic_param->stVP9Segments.feature_data[i][2]; + reg_cxt->ls_info.feature_data[i][3] = pic_param->stVP9Segments.feature_data[i][3]; + reg_cxt->ls_info.feature_mask[i] = pic_param->stVP9Segments.feature_mask[i]; + } + reg_cxt->ls_info.segmentation_enable_flag_last = pic_param->stVP9Segments.enabled; + reg_cxt->ls_info.last_show_frame = pic_param->show_frame; + reg_cxt->ls_info.last_width = pic_param->width; + reg_cxt->ls_info.last_height = pic_param->height; + reg_cxt->ls_info.last_intra_only = (!pic_param->frame_type || pic_param->intra_only); + vp9h_dbg(VP9H_DBG_PAR, "stVP9Segments.enabled = %d show_frame %d width %d height = %d last_intra_only = %d", pic_param->stVP9Segments.enabled, + pic_param->show_frame, pic_param->width, pic_param->height, reg_cxt->ls_info.last_intra_only); + if (reg_cxt->int_cb.callBack) { + if (pic_param->refresh_frame_context && !pic_param->parallelmode) { + hal_vp9d_update_counts(hal, task->dec.syntax.data); + reg_cxt->int_cb.callBack(reg_cxt->int_cb.opaque, (void*)&pic_param->counts); + } + } +#else + (void)hal; +#endif + (void)task; + return ret; +} +/*! +*********************************************************************** +* \brief +* reset +*********************************************************************** +*/ +//extern "C" +MPP_RET hal_vp9d_reset(void *hal) +{ + hal_vp9_context_t *reg_cxt = (hal_vp9_context_t *)hal; + mpp_log("hal_vp9d_reset in"); + memset(®_cxt->ls_info, 0, sizeof(reg_cxt->ls_info)); + reg_cxt->mv_base_addr = 0; + reg_cxt->pre_mv_base_addr = 0; + reg_cxt->last_segid_flag = 1; + return MPP_OK; +} +/*! +*********************************************************************** +* \brief +* flush +*********************************************************************** +*/ +//extern "C" +MPP_RET hal_vp9d_flush(void *hal) +{ + (void)hal; + + + return MPP_OK; +} +/*! +*********************************************************************** +* \brief +* control +*********************************************************************** +*/ +//extern "C" +MPP_RET hal_vp9d_control(void *hal, RK_S32 cmd_type, void *param) +{ + (void)hal; + (void)cmd_type; + (void)param; + + return MPP_OK; +} + + +const MppHalApi hal_api_vp9d = { + "vp9d_rkdec", + MPP_CTX_DEC, + MPP_VIDEO_CodingVP9, + sizeof(hal_vp9_context_t), + 0, + hal_vp9d_init, + hal_vp9d_deinit, + hal_vp9d_gen_regs, + hal_vp9d_start, + hal_vp9d_wait, + hal_vp9d_reset, + hal_vp9d_flush, + hal_vp9d_control, +}; + diff --git a/mpp/hal/rkdec/vp9d/hal_vp9d_reg.h b/mpp/hal/rkdec/vp9d/hal_vp9d_reg.h index 572ec933..33c7b081 100644 --- a/mpp/hal/rkdec/vp9d/hal_vp9d_reg.h +++ b/mpp/hal/rkdec/vp9d/hal_vp9d_reg.h @@ -1,371 +1,371 @@ -/* - * - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * @file hal_vp9_reg.h - * @brief - * @author csy(csy@rock-chips.com) - - * @version 1.0.0 - * @history - * 2015.7.15 : Create - */ - -#ifndef __HAL_VP9D_REG_H__ -#define __HAL_VP9D_REG_H__ -#include "rk_type.h" -#include "mpp_log.h" - -extern RK_U32 vp9h_debug; -#define VP9H_DBG_FUNCTION (0x00000001) -#define VP9H_DBG_PAR (0x00000002) -#define VP9H_DBG_REG (0x00000004) - - -#define vp9h_dbg(flag, fmt, ...) _mpp_dbg(vp9h_debug, flag, fmt, ## __VA_ARGS__) - -typedef struct { - struct { - RK_U32 minor_ver : 8; - RK_U32 level : 1; - RK_U32 dec_support : 3; - RK_U32 profile : 1; - RK_U32 reserve0 : 1; - RK_U32 codec_flag : 1; - RK_U32 reserve1 : 1; - RK_U32 prod_num : 16; - } swreg0_id; - - struct { - RK_U32 sw_dec_e : 1;//0 - RK_U32 sw_dec_clkgate_e : 1; // 1 - RK_U32 reserve0 : 1;// 2 - RK_U32 sw_timeout_mode : 1; // 3 - RK_U32 sw_dec_irq_dis : 1;//4 // 4 - RK_U32 sw_dec_timeout_e : 1; //5 - RK_U32 sw_buf_empty_en : 1; // 6 - RK_U32 sw_stmerror_waitdecfifo_empty : 1; // 7 - RK_U32 sw_dec_irq : 1; // 8 - RK_U32 sw_dec_irq_raw : 1; // 9 - RK_U32 reserve2 : 2; - RK_U32 sw_dec_rdy_sta : 1; //12 - RK_U32 sw_dec_bus_sta : 1; //13 - RK_U32 sw_dec_error_sta : 1; // 14 - RK_U32 sw_dec_timeout_sta : 1; //15 - RK_U32 sw_dec_empty_sta : 1; // 16 - RK_U32 sw_colmv_ref_error_sta : 1; // 17 - RK_U32 sw_cabu_end_sta : 1; // 18 - RK_U32 sw_h264orvp9_error_mode : 1; //19 - RK_U32 sw_softrst_en_p : 1; //20 - RK_U32 sw_force_softreset_valid : 1; //21 - RK_U32 sw_softreset_rdy : 1; // 22 - } swreg1_int; - - struct { - RK_U32 sw_in_endian : 1; - RK_U32 sw_in_swap32_e : 1; - RK_U32 sw_in_swap64_e : 1; - RK_U32 sw_str_endian : 1; - RK_U32 sw_str_swap32_e : 1; - RK_U32 sw_str_swap64_e : 1; - RK_U32 sw_out_endian : 1; - RK_U32 sw_out_swap32_e : 1; - RK_U32 sw_out_cbcr_swap : 1; - RK_U32 reserve0 : 1; - RK_U32 sw_rlc_mode_direct_write : 1; - RK_U32 sw_rlc_mode : 1; - RK_U32 sw_strm_start_bit : 7; - RK_U32 reserve1 : 1; - RK_U32 sw_dec_mode : 2; - RK_U32 reserve2 : 2; - RK_U32 sw_h264_rps_mode : 1; - RK_U32 sw_h264_stream_mode : 1; - RK_U32 sw_h264_stream_lastpacket : 1; - RK_U32 sw_h264_firstslice_flag : 1; - RK_U32 sw_h264_frame_orslice : 1; - RK_U32 sw_buspr_slot_disable : 1; - RK_U32 reserve3 : 2; - } swreg2_sysctrl; - - struct { - RK_U32 sw_y_hor_virstride : 9; - RK_U32 reserve : 2; - RK_U32 sw_slice_num_highbit : 1; - RK_U32 sw_uv_hor_virstride : 9; - RK_U32 sw_slice_num_lowbits : 11; - } swreg3_picpar; - - RK_U32 swreg4_strm_rlc_base; - RK_U32 swreg5_stream_len; - RK_U32 swreg6_cabactbl_prob_base; - RK_U32 swreg7_decout_base; - - struct { - RK_U32 sw_y_virstride : 20; - RK_U32 reverse0 : 12; - } swreg8_y_virstride; - - struct { - RK_U32 sw_yuv_virstride : 21; - RK_U32 reverse : 11; - } swreg9_yuv_virstride; - - - //only for vp9 - struct { - RK_U32 sw_vp9_cprheader_offset : 16; - RK_U32 reverse : 16; - } swreg10_vp9_cprheader_offset; - - RK_U32 swreg11_vp9_referlast_base; - RK_U32 swreg12_vp9_refergolden_base; - RK_U32 swreg13_vp9_referalfter_base; - RK_U32 swreg14_vp9_count_base; - RK_U32 swreg15_vp9_segidlast_base; - RK_U32 swreg16_vp9_segidcur_base; - - struct { - RK_U32 sw_framewidth_last : 16; - RK_U32 sw_frameheight_last : 16; - } swreg17_vp9_frame_size_last; - - struct { - RK_U32 sw_framewidth_golden : 16; - RK_U32 sw_frameheight_golden : 16; - } swreg18_vp9_frame_size_golden; - - - struct { - RK_U32 sw_framewidth_alfter : 16; - RK_U32 sw_frameheight_alfter : 16; - } swreg19_vp9_frame_size_altref; - - - struct { - RK_U32 sw_vp9segid_abs_delta : 1; //NOTE: only in reg#20, this bit is valid. - RK_U32 sw_vp9segid_frame_qp_delta_en : 1; - RK_U32 sw_vp9segid_frame_qp_delta : 9; - RK_U32 sw_vp9segid_frame_loopfitler_value_en : 1; - RK_U32 sw_vp9segid_frame_loopfilter_value : 7; - RK_U32 sw_vp9segid_referinfo_en : 1; - RK_U32 sw_vp9segid_referinfo : 2; - RK_U32 sw_vp9segid_frame_skip_en : 1; - RK_U32 reverse : 9; - } swreg20_27_vp9_segid_grp[8]; - - - struct { - RK_U32 sw_vp9_tx_mode : 3; - RK_U32 sw_vp9_frame_reference_mode : 2; - RK_U32 reserved : 27; - } swreg28_vp9_cprheader_config; - - - struct { - RK_U32 sw_vp9_lref_hor_scale : 16; - RK_U32 sw_vp9_lref_ver_scale : 16; - } swreg29_vp9_lref_scale; - - struct { - RK_U32 sw_vp9_gref_hor_scale : 16; - RK_U32 sw_vp9_gref_ver_scale : 16; - } swreg30_vp9_gref_scale; - - struct { - RK_U32 sw_vp9_aref_hor_scale : 16; - RK_U32 sw_vp9_aref_ver_scale : 16; - } swreg31_vp9_aref_scale; - - struct { - RK_U32 sw_vp9_ref_deltas_lastframe : 28; - RK_U32 reserve : 4; - } swreg32_vp9_ref_deltas_lastframe; - - struct { - RK_U32 sw_vp9_mode_deltas_lastframe : 14; - RK_U32 reserve0 : 2; - RK_U32 sw_segmentation_enable_lstframe : 1; - RK_U32 sw_vp9_last_show_frame : 1; - RK_U32 sw_vp9_last_intra_only : 1; - RK_U32 sw_vp9_last_widthheight_eqcur : 1; - RK_U32 sw_vp9_color_space_lastkeyframe : 3; - RK_U32 reserve1 : 9; - } swreg33_vp9_info_lastframe; - - RK_U32 swreg34_vp9_intercmd_base; - - struct { - RK_U32 sw_vp9_intercmd_num : 24; - RK_U32 reserve : 8; - } swreg35_vp9_intercmd_num; - - struct { - RK_U32 sw_vp9_lasttile_size : 24; - RK_U32 reserve : 8; - } swreg36_vp9_lasttile_size; - - struct { - RK_U32 sw_vp9_lastfy_hor_virstride : 9; - RK_U32 reserve0 : 7; - RK_U32 sw_vp9_lastfuv_hor_virstride : 9; - RK_U32 reserve1 : 7; - } swreg37_vp9_lastf_hor_virstride; - - struct { - RK_U32 sw_vp9_goldenfy_hor_virstride : 9; - RK_U32 reserve0 : 7; - RK_U32 sw_vp9_goldenuv_hor_virstride : 9; - RK_U32 reserve1 : 7; - } swreg38_vp9_goldenf_hor_virstride; - - struct { - RK_U32 sw_vp9_altreffy_hor_virstride : 9; - RK_U32 reserve0 : 7; - RK_U32 sw_vp9_altreffuv_hor_virstride : 9; - RK_U32 reserve1 : 7; - } swreg39_vp9_altreff_hor_virstride; - - struct { - RK_U32 sw_cur_poc : 32; - } swreg40_cur_poc; - - struct { - RK_U32 reserve : 3; - RK_U32 sw_rlcwrite_base : 29; - } swreg41_rlcwrite_base; - - struct { - RK_U32 reserve : 4; - RK_U32 sw_pps_base : 28; - } swreg42_pps_base; - - struct { - RK_U32 reserve : 4; - RK_U32 sw_rps_base : 28; - } swreg43_rps_base; - - struct { - RK_U32 sw_strmd_error_e : 28; - RK_U32 reserve : 4; - } swreg44_strmd_error_en; - - struct { - RK_U32 vp9_error_info0 : 32; - } swreg45_vp9_error_info0; - - struct { - RK_U32 sw_strmd_error_ctu_xoffset : 8; - RK_U32 sw_strmd_error_ctu_yoffset : 8; - RK_U32 sw_streamfifo_space2full : 7; - RK_U32 reserve : 1; - RK_U32 sw_vp9_error_ctu0_en : 1; - } swreg46_strmd_error_ctu; - - struct { - RK_U32 sw_saowr_xoffet : 9; - RK_U32 reserve : 7; - RK_U32 sw_saowr_yoffset : 10; - } swreg47_sao_ctu_position; - - struct { - RK_U32 sw_vp9_lastfy_virstride : 20; - RK_U32 reserve : 12; - } swreg48_vp9_last_ystride; - - struct { - RK_U32 sw_vp9_goldeny_virstride : 20; - RK_U32 reserve : 12; - } swreg49_vp9_golden_ystride; - - struct { - RK_U32 sw_vp9_altrefy_virstride : 20; - RK_U32 reserve : 12; - } swreg50_vp9_altrefy_ystride; - - struct { - RK_U32 sw_vp9_lastref_yuv_virstride : 21; - RK_U32 reserve : 11; - } swreg51_vp9_lastref_yuvstride; - - - RK_U32 swreg52_vp9_refcolmv_base; - - RK_U32 reg_not_use0[64 - 52 - 1]; - - struct { - RK_U32 sw_performance_cycle : 32; - } swreg64_performance_cycle; - - struct { - RK_U32 sw_axi_ddr_rdata : 32; - } swreg65_axi_ddr_rdata; - - struct { - RK_U32 sw_axi_ddr_wdata : 32; - } swreg66_axi_ddr_wdata; - - struct { - RK_U32 sw_busifd_resetn : 1; - RK_U32 sw_cabac_resetn : 1; - RK_U32 sw_dec_ctrl_resetn : 1; - RK_U32 sw_transd_resetn : 1; - RK_U32 sw_intra_resetn : 1; - RK_U32 sw_inter_resetn : 1; - RK_U32 sw_recon_resetn : 1; - RK_U32 sw_filer_resetn : 1; - } swreg67_fpgadebug_reset; - - struct { - RK_U32 perf_cnt0_sel : 6; - RK_U32 reserve0 : 2; - RK_U32 perf_cnt1_sel : 6; - RK_U32 reserve1 : 2; - RK_U32 perf_cnt2_sel : 6; - } swreg68_performance_sel; - - struct { - RK_U32 perf_cnt0 : 32; - } swreg69_performance_cnt0; - - struct { - RK_U32 perf_cnt1 : 32; - } swreg70_performance_cnt1; - - struct { - RK_U32 perf_cnt2 : 32; - } swreg71_performance_cnt2; - - RK_U32 reg_not_use1[74 - 71 - 1]; - - struct { - RK_U32 sw_h264_cur_poc1 : 32; - } swreg74_h264_cur_poc1; - - struct { - RK_U32 vp9_error_info1 : 32; - } swreg75_vp9_error_info1; - - struct { - RK_U32 vp9_error_ctu1_x : 6; - RK_U32 reserve0 : 2; - RK_U32 vp9_error_ctu1_y : 6; - RK_U32 reserve1 : 1; - RK_U32 vp9_error_ctu1_en : 1; - RK_U32 reserve2 : 16; - } swreg76_vp9_error_ctu1; -} VP9_REGS; -#endif +/* + * + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * @file hal_vp9_reg.h + * @brief + * @author csy(csy@rock-chips.com) + + * @version 1.0.0 + * @history + * 2015.7.15 : Create + */ + +#ifndef __HAL_VP9D_REG_H__ +#define __HAL_VP9D_REG_H__ +#include "rk_type.h" +#include "mpp_log.h" + +extern RK_U32 vp9h_debug; +#define VP9H_DBG_FUNCTION (0x00000001) +#define VP9H_DBG_PAR (0x00000002) +#define VP9H_DBG_REG (0x00000004) + + +#define vp9h_dbg(flag, fmt, ...) _mpp_dbg(vp9h_debug, flag, fmt, ## __VA_ARGS__) + +typedef struct { + struct { + RK_U32 minor_ver : 8; + RK_U32 level : 1; + RK_U32 dec_support : 3; + RK_U32 profile : 1; + RK_U32 reserve0 : 1; + RK_U32 codec_flag : 1; + RK_U32 reserve1 : 1; + RK_U32 prod_num : 16; + } swreg0_id; + + struct { + RK_U32 sw_dec_e : 1;//0 + RK_U32 sw_dec_clkgate_e : 1; // 1 + RK_U32 reserve0 : 1;// 2 + RK_U32 sw_timeout_mode : 1; // 3 + RK_U32 sw_dec_irq_dis : 1;//4 // 4 + RK_U32 sw_dec_timeout_e : 1; //5 + RK_U32 sw_buf_empty_en : 1; // 6 + RK_U32 sw_stmerror_waitdecfifo_empty : 1; // 7 + RK_U32 sw_dec_irq : 1; // 8 + RK_U32 sw_dec_irq_raw : 1; // 9 + RK_U32 reserve2 : 2; + RK_U32 sw_dec_rdy_sta : 1; //12 + RK_U32 sw_dec_bus_sta : 1; //13 + RK_U32 sw_dec_error_sta : 1; // 14 + RK_U32 sw_dec_timeout_sta : 1; //15 + RK_U32 sw_dec_empty_sta : 1; // 16 + RK_U32 sw_colmv_ref_error_sta : 1; // 17 + RK_U32 sw_cabu_end_sta : 1; // 18 + RK_U32 sw_h264orvp9_error_mode : 1; //19 + RK_U32 sw_softrst_en_p : 1; //20 + RK_U32 sw_force_softreset_valid : 1; //21 + RK_U32 sw_softreset_rdy : 1; // 22 + } swreg1_int; + + struct { + RK_U32 sw_in_endian : 1; + RK_U32 sw_in_swap32_e : 1; + RK_U32 sw_in_swap64_e : 1; + RK_U32 sw_str_endian : 1; + RK_U32 sw_str_swap32_e : 1; + RK_U32 sw_str_swap64_e : 1; + RK_U32 sw_out_endian : 1; + RK_U32 sw_out_swap32_e : 1; + RK_U32 sw_out_cbcr_swap : 1; + RK_U32 reserve0 : 1; + RK_U32 sw_rlc_mode_direct_write : 1; + RK_U32 sw_rlc_mode : 1; + RK_U32 sw_strm_start_bit : 7; + RK_U32 reserve1 : 1; + RK_U32 sw_dec_mode : 2; + RK_U32 reserve2 : 2; + RK_U32 sw_h264_rps_mode : 1; + RK_U32 sw_h264_stream_mode : 1; + RK_U32 sw_h264_stream_lastpacket : 1; + RK_U32 sw_h264_firstslice_flag : 1; + RK_U32 sw_h264_frame_orslice : 1; + RK_U32 sw_buspr_slot_disable : 1; + RK_U32 reserve3 : 2; + } swreg2_sysctrl; + + struct { + RK_U32 sw_y_hor_virstride : 9; + RK_U32 reserve : 2; + RK_U32 sw_slice_num_highbit : 1; + RK_U32 sw_uv_hor_virstride : 9; + RK_U32 sw_slice_num_lowbits : 11; + } swreg3_picpar; + + RK_U32 swreg4_strm_rlc_base; + RK_U32 swreg5_stream_len; + RK_U32 swreg6_cabactbl_prob_base; + RK_U32 swreg7_decout_base; + + struct { + RK_U32 sw_y_virstride : 20; + RK_U32 reverse0 : 12; + } swreg8_y_virstride; + + struct { + RK_U32 sw_yuv_virstride : 21; + RK_U32 reverse : 11; + } swreg9_yuv_virstride; + + + //only for vp9 + struct { + RK_U32 sw_vp9_cprheader_offset : 16; + RK_U32 reverse : 16; + } swreg10_vp9_cprheader_offset; + + RK_U32 swreg11_vp9_referlast_base; + RK_U32 swreg12_vp9_refergolden_base; + RK_U32 swreg13_vp9_referalfter_base; + RK_U32 swreg14_vp9_count_base; + RK_U32 swreg15_vp9_segidlast_base; + RK_U32 swreg16_vp9_segidcur_base; + + struct { + RK_U32 sw_framewidth_last : 16; + RK_U32 sw_frameheight_last : 16; + } swreg17_vp9_frame_size_last; + + struct { + RK_U32 sw_framewidth_golden : 16; + RK_U32 sw_frameheight_golden : 16; + } swreg18_vp9_frame_size_golden; + + + struct { + RK_U32 sw_framewidth_alfter : 16; + RK_U32 sw_frameheight_alfter : 16; + } swreg19_vp9_frame_size_altref; + + + struct { + RK_U32 sw_vp9segid_abs_delta : 1; //NOTE: only in reg#20, this bit is valid. + RK_U32 sw_vp9segid_frame_qp_delta_en : 1; + RK_U32 sw_vp9segid_frame_qp_delta : 9; + RK_U32 sw_vp9segid_frame_loopfitler_value_en : 1; + RK_U32 sw_vp9segid_frame_loopfilter_value : 7; + RK_U32 sw_vp9segid_referinfo_en : 1; + RK_U32 sw_vp9segid_referinfo : 2; + RK_U32 sw_vp9segid_frame_skip_en : 1; + RK_U32 reverse : 9; + } swreg20_27_vp9_segid_grp[8]; + + + struct { + RK_U32 sw_vp9_tx_mode : 3; + RK_U32 sw_vp9_frame_reference_mode : 2; + RK_U32 reserved : 27; + } swreg28_vp9_cprheader_config; + + + struct { + RK_U32 sw_vp9_lref_hor_scale : 16; + RK_U32 sw_vp9_lref_ver_scale : 16; + } swreg29_vp9_lref_scale; + + struct { + RK_U32 sw_vp9_gref_hor_scale : 16; + RK_U32 sw_vp9_gref_ver_scale : 16; + } swreg30_vp9_gref_scale; + + struct { + RK_U32 sw_vp9_aref_hor_scale : 16; + RK_U32 sw_vp9_aref_ver_scale : 16; + } swreg31_vp9_aref_scale; + + struct { + RK_U32 sw_vp9_ref_deltas_lastframe : 28; + RK_U32 reserve : 4; + } swreg32_vp9_ref_deltas_lastframe; + + struct { + RK_U32 sw_vp9_mode_deltas_lastframe : 14; + RK_U32 reserve0 : 2; + RK_U32 sw_segmentation_enable_lstframe : 1; + RK_U32 sw_vp9_last_show_frame : 1; + RK_U32 sw_vp9_last_intra_only : 1; + RK_U32 sw_vp9_last_widthheight_eqcur : 1; + RK_U32 sw_vp9_color_space_lastkeyframe : 3; + RK_U32 reserve1 : 9; + } swreg33_vp9_info_lastframe; + + RK_U32 swreg34_vp9_intercmd_base; + + struct { + RK_U32 sw_vp9_intercmd_num : 24; + RK_U32 reserve : 8; + } swreg35_vp9_intercmd_num; + + struct { + RK_U32 sw_vp9_lasttile_size : 24; + RK_U32 reserve : 8; + } swreg36_vp9_lasttile_size; + + struct { + RK_U32 sw_vp9_lastfy_hor_virstride : 9; + RK_U32 reserve0 : 7; + RK_U32 sw_vp9_lastfuv_hor_virstride : 9; + RK_U32 reserve1 : 7; + } swreg37_vp9_lastf_hor_virstride; + + struct { + RK_U32 sw_vp9_goldenfy_hor_virstride : 9; + RK_U32 reserve0 : 7; + RK_U32 sw_vp9_goldenuv_hor_virstride : 9; + RK_U32 reserve1 : 7; + } swreg38_vp9_goldenf_hor_virstride; + + struct { + RK_U32 sw_vp9_altreffy_hor_virstride : 9; + RK_U32 reserve0 : 7; + RK_U32 sw_vp9_altreffuv_hor_virstride : 9; + RK_U32 reserve1 : 7; + } swreg39_vp9_altreff_hor_virstride; + + struct { + RK_U32 sw_cur_poc : 32; + } swreg40_cur_poc; + + struct { + RK_U32 reserve : 3; + RK_U32 sw_rlcwrite_base : 29; + } swreg41_rlcwrite_base; + + struct { + RK_U32 reserve : 4; + RK_U32 sw_pps_base : 28; + } swreg42_pps_base; + + struct { + RK_U32 reserve : 4; + RK_U32 sw_rps_base : 28; + } swreg43_rps_base; + + struct { + RK_U32 sw_strmd_error_e : 28; + RK_U32 reserve : 4; + } swreg44_strmd_error_en; + + struct { + RK_U32 vp9_error_info0 : 32; + } swreg45_vp9_error_info0; + + struct { + RK_U32 sw_strmd_error_ctu_xoffset : 8; + RK_U32 sw_strmd_error_ctu_yoffset : 8; + RK_U32 sw_streamfifo_space2full : 7; + RK_U32 reserve : 1; + RK_U32 sw_vp9_error_ctu0_en : 1; + } swreg46_strmd_error_ctu; + + struct { + RK_U32 sw_saowr_xoffet : 9; + RK_U32 reserve : 7; + RK_U32 sw_saowr_yoffset : 10; + } swreg47_sao_ctu_position; + + struct { + RK_U32 sw_vp9_lastfy_virstride : 20; + RK_U32 reserve : 12; + } swreg48_vp9_last_ystride; + + struct { + RK_U32 sw_vp9_goldeny_virstride : 20; + RK_U32 reserve : 12; + } swreg49_vp9_golden_ystride; + + struct { + RK_U32 sw_vp9_altrefy_virstride : 20; + RK_U32 reserve : 12; + } swreg50_vp9_altrefy_ystride; + + struct { + RK_U32 sw_vp9_lastref_yuv_virstride : 21; + RK_U32 reserve : 11; + } swreg51_vp9_lastref_yuvstride; + + + RK_U32 swreg52_vp9_refcolmv_base; + + RK_U32 reg_not_use0[64 - 52 - 1]; + + struct { + RK_U32 sw_performance_cycle : 32; + } swreg64_performance_cycle; + + struct { + RK_U32 sw_axi_ddr_rdata : 32; + } swreg65_axi_ddr_rdata; + + struct { + RK_U32 sw_axi_ddr_wdata : 32; + } swreg66_axi_ddr_wdata; + + struct { + RK_U32 sw_busifd_resetn : 1; + RK_U32 sw_cabac_resetn : 1; + RK_U32 sw_dec_ctrl_resetn : 1; + RK_U32 sw_transd_resetn : 1; + RK_U32 sw_intra_resetn : 1; + RK_U32 sw_inter_resetn : 1; + RK_U32 sw_recon_resetn : 1; + RK_U32 sw_filer_resetn : 1; + } swreg67_fpgadebug_reset; + + struct { + RK_U32 perf_cnt0_sel : 6; + RK_U32 reserve0 : 2; + RK_U32 perf_cnt1_sel : 6; + RK_U32 reserve1 : 2; + RK_U32 perf_cnt2_sel : 6; + } swreg68_performance_sel; + + struct { + RK_U32 perf_cnt0 : 32; + } swreg69_performance_cnt0; + + struct { + RK_U32 perf_cnt1 : 32; + } swreg70_performance_cnt1; + + struct { + RK_U32 perf_cnt2 : 32; + } swreg71_performance_cnt2; + + RK_U32 reg_not_use1[74 - 71 - 1]; + + struct { + RK_U32 sw_h264_cur_poc1 : 32; + } swreg74_h264_cur_poc1; + + struct { + RK_U32 vp9_error_info1 : 32; + } swreg75_vp9_error_info1; + + struct { + RK_U32 vp9_error_ctu1_x : 6; + RK_U32 reserve0 : 2; + RK_U32 vp9_error_ctu1_y : 6; + RK_U32 reserve1 : 1; + RK_U32 vp9_error_ctu1_en : 1; + RK_U32 reserve2 : 16; + } swreg76_vp9_error_ctu1; +} VP9_REGS; +#endif diff --git a/mpp/hal/rkdec/vp9d/hal_vp9d_table.h b/mpp/hal/rkdec/vp9d/hal_vp9d_table.h index 0c8b4d57..eacb0af1 100644 --- a/mpp/hal/rkdec/vp9d/hal_vp9d_table.h +++ b/mpp/hal/rkdec/vp9d/hal_vp9d_table.h @@ -1,205 +1,205 @@ -/* - * - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef _HAL_VP9D_TABLE_H_ -#define _HAL_VP9D_TABLE_H_ -#include "rk_type.h" - -typedef RK_U8 vp9_prob; - -#define PARTITION_CONTEXTS 16 -#define PARTITION_TYPES 4 -#define MAX_SEGMENTS 8 -#define SEG_TREE_PROBS (MAX_SEGMENTS-1) -#define PREDICTION_PROBS 3 -#define SKIP_CONTEXTS 3 -#define TX_SIZE_CONTEXTS 2 -#define TX_SIZES 4 -#define INTRA_INTER_CONTEXTS 4 -#define PLANE_TYPES 2 -#define COEF_BANDS 6 -#define COEFF_CONTEXTS 6 -#define UNCONSTRAINED_NODES 3 -#define INTRA_MODES 10 -#define INTER_PROB_SIZE_ALIGN_TO_128 151 -#define INTRA_PROB_SIZE_ALIGN_TO_128 149 -#define BLOCK_SIZE_GROUPS 4 -#define COMP_INTER_CONTEXTS 5 -#define REF_CONTEXTS 5 -#define INTER_MODE_CONTEXTS 7 -#define SWITCHABLE_FILTERS 3 // number of switchable filters -#define SWITCHABLE_FILTER_CONTEXTS (SWITCHABLE_FILTERS + 1) -#define INTER_MODES 4 -#define MV_JOINTS 4 -#define MV_CLASSES 11 -#define CLASS0_BITS 1 /* bits at integer precision for class 0 */ -#define CLASS0_SIZE (1 << CLASS0_BITS) -#define MV_OFFSET_BITS (MV_CLASSES + CLASS0_BITS - 2) -#define MV_FP_SIZE 4 - - -const vp9_prob vp9_kf_y_mode_prob[INTRA_MODES][INTRA_MODES][INTRA_MODES - 1] = { - { - // above = dc - { 137, 30, 42, 148, 151, 207, 70, 52, 91 }, // left = dc - { 92, 45, 102, 136, 116, 180, 74, 90, 100 }, // left = v - { 73, 32, 19, 187, 222, 215, 46, 34, 100 }, // left = h - { 91, 30, 32, 116, 121, 186, 93, 86, 94 }, // left = d45 - { 72, 35, 36, 149, 68, 206, 68, 63, 105 }, // left = d135 - { 73, 31, 28, 138, 57, 124, 55, 122, 151 }, // left = d117 - { 67, 23, 21, 140, 126, 197, 40, 37, 171 }, // left = d153 - { 86, 27, 28, 128, 154, 212, 45, 43, 53 }, // left = d207 - { 74, 32, 27, 107, 86, 160, 63, 134, 102 }, // left = d63 - { 59, 67, 44, 140, 161, 202, 78, 67, 119 } // left = tm - }, { // above = v - { 63, 36, 126, 146, 123, 158, 60, 90, 96 }, // left = dc - { 43, 46, 168, 134, 107, 128, 69, 142, 92 }, // left = v - { 44, 29, 68, 159, 201, 177, 50, 57, 77 }, // left = h - { 58, 38, 76, 114, 97, 172, 78, 133, 92 }, // left = d45 - { 46, 41, 76, 140, 63, 184, 69, 112, 57 }, // left = d135 - { 38, 32, 85, 140, 46, 112, 54, 151, 133 }, // left = d117 - { 39, 27, 61, 131, 110, 175, 44, 75, 136 }, // left = d153 - { 52, 30, 74, 113, 130, 175, 51, 64, 58 }, // left = d207 - { 47, 35, 80, 100, 74, 143, 64, 163, 74 }, // left = d63 - { 36, 61, 116, 114, 128, 162, 80, 125, 82 } // left = tm - }, { // above = h - { 82, 26, 26, 171, 208, 204, 44, 32, 105 }, // left = dc - { 55, 44, 68, 166, 179, 192, 57, 57, 108 }, // left = v - { 42, 26, 11, 199, 241, 228, 23, 15, 85 }, // left = h - { 68, 42, 19, 131, 160, 199, 55, 52, 83 }, // left = d45 - { 58, 50, 25, 139, 115, 232, 39, 52, 118 }, // left = d135 - { 50, 35, 33, 153, 104, 162, 64, 59, 131 }, // left = d117 - { 44, 24, 16, 150, 177, 202, 33, 19, 156 }, // left = d153 - { 55, 27, 12, 153, 203, 218, 26, 27, 49 }, // left = d207 - { 53, 49, 21, 110, 116, 168, 59, 80, 76 }, // left = d63 - { 38, 72, 19, 168, 203, 212, 50, 50, 107 } // left = tm - }, { // above = d45 - { 103, 26, 36, 129, 132, 201, 83, 80, 93 }, // left = dc - { 59, 38, 83, 112, 103, 162, 98, 136, 90 }, // left = v - { 62, 30, 23, 158, 200, 207, 59, 57, 50 }, // left = h - { 67, 30, 29, 84, 86, 191, 102, 91, 59 }, // left = d45 - { 60, 32, 33, 112, 71, 220, 64, 89, 104 }, // left = d135 - { 53, 26, 34, 130, 56, 149, 84, 120, 103 }, // left = d117 - { 53, 21, 23, 133, 109, 210, 56, 77, 172 }, // left = d153 - { 77, 19, 29, 112, 142, 228, 55, 66, 36 }, // left = d207 - { 61, 29, 29, 93, 97, 165, 83, 175, 162 }, // left = d63 - { 47, 47, 43, 114, 137, 181, 100, 99, 95 } // left = tm - }, { // above = d135 - { 69, 23, 29, 128, 83, 199, 46, 44, 101 }, // left = dc - { 53, 40, 55, 139, 69, 183, 61, 80, 110 }, // left = v - { 40, 29, 19, 161, 180, 207, 43, 24, 91 }, // left = h - { 60, 34, 19, 105, 61, 198, 53, 64, 89 }, // left = d45 - { 52, 31, 22, 158, 40, 209, 58, 62, 89 }, // left = d135 - { 44, 31, 29, 147, 46, 158, 56, 102, 198 }, // left = d117 - { 35, 19, 12, 135, 87, 209, 41, 45, 167 }, // left = d153 - { 55, 25, 21, 118, 95, 215, 38, 39, 66 }, // left = d207 - { 51, 38, 25, 113, 58, 164, 70, 93, 97 }, // left = d63 - { 47, 54, 34, 146, 108, 203, 72, 103, 151 } // left = tm - }, { // above = d117 - { 64, 19, 37, 156, 66, 138, 49, 95, 133 }, // left = dc - { 46, 27, 80, 150, 55, 124, 55, 121, 135 }, // left = v - { 36, 23, 27, 165, 149, 166, 54, 64, 118 }, // left = h - { 53, 21, 36, 131, 63, 163, 60, 109, 81 }, // left = d45 - { 40, 26, 35, 154, 40, 185, 51, 97, 123 }, // left = d135 - { 35, 19, 34, 179, 19, 97, 48, 129, 124 }, // left = d117 - { 36, 20, 26, 136, 62, 164, 33, 77, 154 }, // left = d153 - { 45, 18, 32, 130, 90, 157, 40, 79, 91 }, // left = d207 - { 45, 26, 28, 129, 45, 129, 49, 147, 123 }, // left = d63 - { 38, 44, 51, 136, 74, 162, 57, 97, 121 } // left = tm - }, { // above = d153 - { 75, 17, 22, 136, 138, 185, 32, 34, 166 }, // left = dc - { 56, 39, 58, 133, 117, 173, 48, 53, 187 }, // left = v - { 35, 21, 12, 161, 212, 207, 20, 23, 145 }, // left = h - { 56, 29, 19, 117, 109, 181, 55, 68, 112 }, // left = d45 - { 47, 29, 17, 153, 64, 220, 59, 51, 114 }, // left = d135 - { 46, 16, 24, 136, 76, 147, 41, 64, 172 }, // left = d117 - { 34, 17, 11, 108, 152, 187, 13, 15, 209 }, // left = d153 - { 51, 24, 14, 115, 133, 209, 32, 26, 104 }, // left = d207 - { 55, 30, 18, 122, 79, 179, 44, 88, 116 }, // left = d63 - { 37, 49, 25, 129, 168, 164, 41, 54, 148 } // left = tm - }, { // above = d207 - { 82, 22, 32, 127, 143, 213, 39, 41, 70 }, // left = dc - { 62, 44, 61, 123, 105, 189, 48, 57, 64 }, // left = v - { 47, 25, 17, 175, 222, 220, 24, 30, 86 }, // left = h - { 68, 36, 17, 106, 102, 206, 59, 74, 74 }, // left = d45 - { 57, 39, 23, 151, 68, 216, 55, 63, 58 }, // left = d135 - { 49, 30, 35, 141, 70, 168, 82, 40, 115 }, // left = d117 - { 51, 25, 15, 136, 129, 202, 38, 35, 139 }, // left = d153 - { 68, 26, 16, 111, 141, 215, 29, 28, 28 }, // left = d207 - { 59, 39, 19, 114, 75, 180, 77, 104, 42 }, // left = d63 - { 40, 61, 26, 126, 152, 206, 61, 59, 93 } // left = tm - }, { // above = d63 - { 78, 23, 39, 111, 117, 170, 74, 124, 94 }, // left = dc - { 48, 34, 86, 101, 92, 146, 78, 179, 134 }, // left = v - { 47, 22, 24, 138, 187, 178, 68, 69, 59 }, // left = h - { 56, 25, 33, 105, 112, 187, 95, 177, 129 }, // left = d45 - { 48, 31, 27, 114, 63, 183, 82, 116, 56 }, // left = d135 - { 43, 28, 37, 121, 63, 123, 61, 192, 169 }, // left = d117 - { 42, 17, 24, 109, 97, 177, 56, 76, 122 }, // left = d153 - { 58, 18, 28, 105, 139, 182, 70, 92, 63 }, // left = d207 - { 46, 23, 32, 74, 86, 150, 67, 183, 88 }, // left = d63 - { 36, 38, 48, 92, 122, 165, 88, 137, 91 } // left = tm - }, { // above = tm - { 65, 70, 60, 155, 159, 199, 61, 60, 81 }, // left = dc - { 44, 78, 115, 132, 119, 173, 71, 112, 93 }, // left = v - { 39, 38, 21, 184, 227, 206, 42, 32, 64 }, // left = h - { 58, 47, 36, 124, 137, 193, 80, 82, 78 }, // left = d45 - { 49, 50, 35, 144, 95, 205, 63, 78, 59 }, // left = d135 - { 41, 53, 52, 148, 71, 142, 65, 128, 51 }, // left = d117 - { 40, 36, 28, 143, 143, 202, 40, 55, 137 }, // left = d153 - { 52, 34, 29, 129, 183, 227, 42, 35, 43 }, // left = d207 - { 42, 44, 44, 104, 105, 164, 64, 130, 80 }, // left = d63 - { 43, 81, 53, 140, 169, 204, 68, 84, 72 } // left = tm - } -}; - -const vp9_prob vp9_kf_uv_mode_prob[INTRA_MODES][INTRA_MODES - 1] = { - { 144, 11, 54, 157, 195, 130, 46, 58, 108 }, // y = dc - { 118, 15, 123, 148, 131, 101, 44, 93, 131 }, // y = v - { 113, 12, 23, 188, 226, 142, 26, 32, 125 }, // y = h - { 120, 11, 50, 123, 163, 135, 64, 77, 103 }, // y = d45 - { 113, 9, 36, 155, 111, 157, 32, 44, 161 }, // y = d135 - { 116, 9, 55, 176, 76, 96, 37, 61, 149 }, // y = d117 - { 115, 9, 28, 141, 161, 167, 21, 25, 193 }, // y = d153 - { 120, 12, 32, 145, 195, 142, 32, 38, 86 }, // y = d207 - { 116, 12, 64, 120, 140, 125, 49, 115, 121 }, // y = d63 - { 102, 19, 66, 162, 182, 122, 35, 59, 128 } // y = tm -}; - -const vp9_prob vp9_kf_partition_probs[PARTITION_CONTEXTS] -[PARTITION_TYPES - 1] = { - // 8x8 -> 4x4 - { 158, 97, 94 }, // a/l both not split - { 93, 24, 99 }, // a split, l not split - { 85, 119, 44 }, // l split, a not split - { 62, 59, 67 }, // a/l both split - // 16x16 -> 8x8 - { 149, 53, 53 }, // a/l both not split - { 94, 20, 48 }, // a split, l not split - { 83, 53, 24 }, // l split, a not split - { 52, 18, 18 }, // a/l both split - // 32x32 -> 16x16 - { 150, 40, 39 }, // a/l both not split - { 78, 12, 26 }, // a split, l not split - { 67, 33, 11 }, // l split, a not split - { 24, 7, 5 }, // a/l both split - // 64x64 -> 32x32 - { 174, 35, 49 }, // a/l both not split - { 68, 11, 27 }, // a split, l not split - { 57, 15, 9 }, // l split, a not split - { 12, 3, 3 }, // a/l both split -}; -#endif +/* + * + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _HAL_VP9D_TABLE_H_ +#define _HAL_VP9D_TABLE_H_ +#include "rk_type.h" + +typedef RK_U8 vp9_prob; + +#define PARTITION_CONTEXTS 16 +#define PARTITION_TYPES 4 +#define MAX_SEGMENTS 8 +#define SEG_TREE_PROBS (MAX_SEGMENTS-1) +#define PREDICTION_PROBS 3 +#define SKIP_CONTEXTS 3 +#define TX_SIZE_CONTEXTS 2 +#define TX_SIZES 4 +#define INTRA_INTER_CONTEXTS 4 +#define PLANE_TYPES 2 +#define COEF_BANDS 6 +#define COEFF_CONTEXTS 6 +#define UNCONSTRAINED_NODES 3 +#define INTRA_MODES 10 +#define INTER_PROB_SIZE_ALIGN_TO_128 151 +#define INTRA_PROB_SIZE_ALIGN_TO_128 149 +#define BLOCK_SIZE_GROUPS 4 +#define COMP_INTER_CONTEXTS 5 +#define REF_CONTEXTS 5 +#define INTER_MODE_CONTEXTS 7 +#define SWITCHABLE_FILTERS 3 // number of switchable filters +#define SWITCHABLE_FILTER_CONTEXTS (SWITCHABLE_FILTERS + 1) +#define INTER_MODES 4 +#define MV_JOINTS 4 +#define MV_CLASSES 11 +#define CLASS0_BITS 1 /* bits at integer precision for class 0 */ +#define CLASS0_SIZE (1 << CLASS0_BITS) +#define MV_OFFSET_BITS (MV_CLASSES + CLASS0_BITS - 2) +#define MV_FP_SIZE 4 + + +const vp9_prob vp9_kf_y_mode_prob[INTRA_MODES][INTRA_MODES][INTRA_MODES - 1] = { + { + // above = dc + { 137, 30, 42, 148, 151, 207, 70, 52, 91 }, // left = dc + { 92, 45, 102, 136, 116, 180, 74, 90, 100 }, // left = v + { 73, 32, 19, 187, 222, 215, 46, 34, 100 }, // left = h + { 91, 30, 32, 116, 121, 186, 93, 86, 94 }, // left = d45 + { 72, 35, 36, 149, 68, 206, 68, 63, 105 }, // left = d135 + { 73, 31, 28, 138, 57, 124, 55, 122, 151 }, // left = d117 + { 67, 23, 21, 140, 126, 197, 40, 37, 171 }, // left = d153 + { 86, 27, 28, 128, 154, 212, 45, 43, 53 }, // left = d207 + { 74, 32, 27, 107, 86, 160, 63, 134, 102 }, // left = d63 + { 59, 67, 44, 140, 161, 202, 78, 67, 119 } // left = tm + }, { // above = v + { 63, 36, 126, 146, 123, 158, 60, 90, 96 }, // left = dc + { 43, 46, 168, 134, 107, 128, 69, 142, 92 }, // left = v + { 44, 29, 68, 159, 201, 177, 50, 57, 77 }, // left = h + { 58, 38, 76, 114, 97, 172, 78, 133, 92 }, // left = d45 + { 46, 41, 76, 140, 63, 184, 69, 112, 57 }, // left = d135 + { 38, 32, 85, 140, 46, 112, 54, 151, 133 }, // left = d117 + { 39, 27, 61, 131, 110, 175, 44, 75, 136 }, // left = d153 + { 52, 30, 74, 113, 130, 175, 51, 64, 58 }, // left = d207 + { 47, 35, 80, 100, 74, 143, 64, 163, 74 }, // left = d63 + { 36, 61, 116, 114, 128, 162, 80, 125, 82 } // left = tm + }, { // above = h + { 82, 26, 26, 171, 208, 204, 44, 32, 105 }, // left = dc + { 55, 44, 68, 166, 179, 192, 57, 57, 108 }, // left = v + { 42, 26, 11, 199, 241, 228, 23, 15, 85 }, // left = h + { 68, 42, 19, 131, 160, 199, 55, 52, 83 }, // left = d45 + { 58, 50, 25, 139, 115, 232, 39, 52, 118 }, // left = d135 + { 50, 35, 33, 153, 104, 162, 64, 59, 131 }, // left = d117 + { 44, 24, 16, 150, 177, 202, 33, 19, 156 }, // left = d153 + { 55, 27, 12, 153, 203, 218, 26, 27, 49 }, // left = d207 + { 53, 49, 21, 110, 116, 168, 59, 80, 76 }, // left = d63 + { 38, 72, 19, 168, 203, 212, 50, 50, 107 } // left = tm + }, { // above = d45 + { 103, 26, 36, 129, 132, 201, 83, 80, 93 }, // left = dc + { 59, 38, 83, 112, 103, 162, 98, 136, 90 }, // left = v + { 62, 30, 23, 158, 200, 207, 59, 57, 50 }, // left = h + { 67, 30, 29, 84, 86, 191, 102, 91, 59 }, // left = d45 + { 60, 32, 33, 112, 71, 220, 64, 89, 104 }, // left = d135 + { 53, 26, 34, 130, 56, 149, 84, 120, 103 }, // left = d117 + { 53, 21, 23, 133, 109, 210, 56, 77, 172 }, // left = d153 + { 77, 19, 29, 112, 142, 228, 55, 66, 36 }, // left = d207 + { 61, 29, 29, 93, 97, 165, 83, 175, 162 }, // left = d63 + { 47, 47, 43, 114, 137, 181, 100, 99, 95 } // left = tm + }, { // above = d135 + { 69, 23, 29, 128, 83, 199, 46, 44, 101 }, // left = dc + { 53, 40, 55, 139, 69, 183, 61, 80, 110 }, // left = v + { 40, 29, 19, 161, 180, 207, 43, 24, 91 }, // left = h + { 60, 34, 19, 105, 61, 198, 53, 64, 89 }, // left = d45 + { 52, 31, 22, 158, 40, 209, 58, 62, 89 }, // left = d135 + { 44, 31, 29, 147, 46, 158, 56, 102, 198 }, // left = d117 + { 35, 19, 12, 135, 87, 209, 41, 45, 167 }, // left = d153 + { 55, 25, 21, 118, 95, 215, 38, 39, 66 }, // left = d207 + { 51, 38, 25, 113, 58, 164, 70, 93, 97 }, // left = d63 + { 47, 54, 34, 146, 108, 203, 72, 103, 151 } // left = tm + }, { // above = d117 + { 64, 19, 37, 156, 66, 138, 49, 95, 133 }, // left = dc + { 46, 27, 80, 150, 55, 124, 55, 121, 135 }, // left = v + { 36, 23, 27, 165, 149, 166, 54, 64, 118 }, // left = h + { 53, 21, 36, 131, 63, 163, 60, 109, 81 }, // left = d45 + { 40, 26, 35, 154, 40, 185, 51, 97, 123 }, // left = d135 + { 35, 19, 34, 179, 19, 97, 48, 129, 124 }, // left = d117 + { 36, 20, 26, 136, 62, 164, 33, 77, 154 }, // left = d153 + { 45, 18, 32, 130, 90, 157, 40, 79, 91 }, // left = d207 + { 45, 26, 28, 129, 45, 129, 49, 147, 123 }, // left = d63 + { 38, 44, 51, 136, 74, 162, 57, 97, 121 } // left = tm + }, { // above = d153 + { 75, 17, 22, 136, 138, 185, 32, 34, 166 }, // left = dc + { 56, 39, 58, 133, 117, 173, 48, 53, 187 }, // left = v + { 35, 21, 12, 161, 212, 207, 20, 23, 145 }, // left = h + { 56, 29, 19, 117, 109, 181, 55, 68, 112 }, // left = d45 + { 47, 29, 17, 153, 64, 220, 59, 51, 114 }, // left = d135 + { 46, 16, 24, 136, 76, 147, 41, 64, 172 }, // left = d117 + { 34, 17, 11, 108, 152, 187, 13, 15, 209 }, // left = d153 + { 51, 24, 14, 115, 133, 209, 32, 26, 104 }, // left = d207 + { 55, 30, 18, 122, 79, 179, 44, 88, 116 }, // left = d63 + { 37, 49, 25, 129, 168, 164, 41, 54, 148 } // left = tm + }, { // above = d207 + { 82, 22, 32, 127, 143, 213, 39, 41, 70 }, // left = dc + { 62, 44, 61, 123, 105, 189, 48, 57, 64 }, // left = v + { 47, 25, 17, 175, 222, 220, 24, 30, 86 }, // left = h + { 68, 36, 17, 106, 102, 206, 59, 74, 74 }, // left = d45 + { 57, 39, 23, 151, 68, 216, 55, 63, 58 }, // left = d135 + { 49, 30, 35, 141, 70, 168, 82, 40, 115 }, // left = d117 + { 51, 25, 15, 136, 129, 202, 38, 35, 139 }, // left = d153 + { 68, 26, 16, 111, 141, 215, 29, 28, 28 }, // left = d207 + { 59, 39, 19, 114, 75, 180, 77, 104, 42 }, // left = d63 + { 40, 61, 26, 126, 152, 206, 61, 59, 93 } // left = tm + }, { // above = d63 + { 78, 23, 39, 111, 117, 170, 74, 124, 94 }, // left = dc + { 48, 34, 86, 101, 92, 146, 78, 179, 134 }, // left = v + { 47, 22, 24, 138, 187, 178, 68, 69, 59 }, // left = h + { 56, 25, 33, 105, 112, 187, 95, 177, 129 }, // left = d45 + { 48, 31, 27, 114, 63, 183, 82, 116, 56 }, // left = d135 + { 43, 28, 37, 121, 63, 123, 61, 192, 169 }, // left = d117 + { 42, 17, 24, 109, 97, 177, 56, 76, 122 }, // left = d153 + { 58, 18, 28, 105, 139, 182, 70, 92, 63 }, // left = d207 + { 46, 23, 32, 74, 86, 150, 67, 183, 88 }, // left = d63 + { 36, 38, 48, 92, 122, 165, 88, 137, 91 } // left = tm + }, { // above = tm + { 65, 70, 60, 155, 159, 199, 61, 60, 81 }, // left = dc + { 44, 78, 115, 132, 119, 173, 71, 112, 93 }, // left = v + { 39, 38, 21, 184, 227, 206, 42, 32, 64 }, // left = h + { 58, 47, 36, 124, 137, 193, 80, 82, 78 }, // left = d45 + { 49, 50, 35, 144, 95, 205, 63, 78, 59 }, // left = d135 + { 41, 53, 52, 148, 71, 142, 65, 128, 51 }, // left = d117 + { 40, 36, 28, 143, 143, 202, 40, 55, 137 }, // left = d153 + { 52, 34, 29, 129, 183, 227, 42, 35, 43 }, // left = d207 + { 42, 44, 44, 104, 105, 164, 64, 130, 80 }, // left = d63 + { 43, 81, 53, 140, 169, 204, 68, 84, 72 } // left = tm + } +}; + +const vp9_prob vp9_kf_uv_mode_prob[INTRA_MODES][INTRA_MODES - 1] = { + { 144, 11, 54, 157, 195, 130, 46, 58, 108 }, // y = dc + { 118, 15, 123, 148, 131, 101, 44, 93, 131 }, // y = v + { 113, 12, 23, 188, 226, 142, 26, 32, 125 }, // y = h + { 120, 11, 50, 123, 163, 135, 64, 77, 103 }, // y = d45 + { 113, 9, 36, 155, 111, 157, 32, 44, 161 }, // y = d135 + { 116, 9, 55, 176, 76, 96, 37, 61, 149 }, // y = d117 + { 115, 9, 28, 141, 161, 167, 21, 25, 193 }, // y = d153 + { 120, 12, 32, 145, 195, 142, 32, 38, 86 }, // y = d207 + { 116, 12, 64, 120, 140, 125, 49, 115, 121 }, // y = d63 + { 102, 19, 66, 162, 182, 122, 35, 59, 128 } // y = tm +}; + +const vp9_prob vp9_kf_partition_probs[PARTITION_CONTEXTS] +[PARTITION_TYPES - 1] = { + // 8x8 -> 4x4 + { 158, 97, 94 }, // a/l both not split + { 93, 24, 99 }, // a split, l not split + { 85, 119, 44 }, // l split, a not split + { 62, 59, 67 }, // a/l both split + // 16x16 -> 8x8 + { 149, 53, 53 }, // a/l both not split + { 94, 20, 48 }, // a split, l not split + { 83, 53, 24 }, // l split, a not split + { 52, 18, 18 }, // a/l both split + // 32x32 -> 16x16 + { 150, 40, 39 }, // a/l both not split + { 78, 12, 26 }, // a split, l not split + { 67, 33, 11 }, // l split, a not split + { 24, 7, 5 }, // a/l both split + // 64x64 -> 32x32 + { 174, 35, 49 }, // a/l both not split + { 68, 11, 27 }, // a split, l not split + { 57, 15, 9 }, // l split, a not split + { 12, 3, 3 }, // a/l both split +}; +#endif diff --git a/mpp/hal/rkenc/h264e/hal_h264e.h b/mpp/hal/rkenc/h264e/hal_h264e.h index 7519e351..d01725a3 100644 --- a/mpp/hal/rkenc/h264e/hal_h264e.h +++ b/mpp/hal/rkenc/h264e/hal_h264e.h @@ -1,366 +1,366 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __HAL_H264E_H__ -#define __HAL_H264E_H__ - -#include "vpu.h" -#include "mpp_log.h" -#include "mpp_hal.h" - -#include "mpp_packet.h" -#include "h264e_syntax.h" - -extern RK_U32 h264e_hal_log_mode; - -#define H264E_HAL_LOG_ERROR 0x00000001 - -#define H264E_HAL_LOG_SIMPLE 0x00000010 - -#define H264E_HAL_LOG_FLOW 0x00000100 - -#define H264E_HAL_LOG_DPB 0x00001000 -#define H264E_HAL_LOG_HEADER 0x00002000 - -#define H264E_HAL_LOG_DETAIL 0x00010000 - -#define H264E_HAL_LOG_FILE 0x00100000 - - - -#define H264E_HAL_MASK_2b (RK_U32)0x00000003 -#define H264E_HAL_MASK_3b (RK_U32)0x00000007 -#define H264E_HAL_MASK_4b (RK_U32)0x0000000F -#define H264E_HAL_MASK_5b (RK_U32)0x0000001F -#define H264E_HAL_MASK_6b (RK_U32)0x0000003F -#define H264E_HAL_MASK_11b (RK_U32)0x000007FF -#define H264E_HAL_MASK_14b (RK_U32)0x00003FFF -#define H264E_HAL_MASK_16b (RK_U32)0x0000FFFF - - -#define h264e_hal_debug_enter() \ - do {\ - if (h264e_hal_log_mode & H264E_HAL_LOG_FLOW)\ - { mpp_log("line(%d), func(%s), enter", __LINE__, __FUNCTION__); }\ - } while (0) - -#define h264e_hal_debug_leave() \ - do {\ - if (h264e_hal_log_mode & H264E_HAL_LOG_FLOW)\ - { mpp_log("line(%d), func(%s), leave", __LINE__, __FUNCTION__); }\ - } while (0) - -#define h264e_hal_log_err(fmt, ...) \ - do {\ - if (h264e_hal_log_mode & H264E_HAL_LOG_ERROR)\ - { mpp_err(fmt, ## __VA_ARGS__); }\ - } while (0) - -#define h264e_hal_log_detail(fmt, ...) \ - do {\ - if (h264e_hal_log_mode & H264E_HAL_LOG_DETAIL)\ - { mpp_log(fmt, ## __VA_ARGS__); }\ - } while (0) - -#define h264e_hal_log_dpb(fmt, ...) \ - do {\ - if (h264e_hal_log_mode & H264E_HAL_LOG_DPB)\ - { mpp_log(fmt, ## __VA_ARGS__); }\ - } while (0) - -#define h264e_hal_log_header(fmt, ...) \ - do {\ - if (h264e_hal_log_mode & H264E_HAL_LOG_HEADER)\ - { mpp_log(fmt, ## __VA_ARGS__); }\ - } while (0) - -#define h264e_hal_log_simple(fmt, ...) \ - do {\ - if (h264e_hal_log_mode & H264E_HAL_LOG_SIMPLE)\ - { mpp_log(fmt, ## __VA_ARGS__); }\ - } while (0) - -#define h264e_hal_log_file(fmt, ...) \ - do {\ - if (h264e_hal_log_mode & H264E_HAL_LOG_FILE)\ - { mpp_log(fmt, ## __VA_ARGS__); }\ - } while (0) - -#define H264E_HAL_MIN(a,b) ( (a)<(b) ? (a) : (b) ) -#define H264E_HAL_MAX(a,b) ( (a)>(b) ? (a) : (b) ) -#define H264E_HAL_MIN3(a,b,c) H264E_HAL_MIN((a),H264E_HAL_MIN((b),(c))) -#define H264E_HAL_MAX3(a,b,c) H264E_HAL_MAX((a),H264E_HAL_MAX((b),(c))) -#define H264E_HAL_MIN4(a,b,c,d) H264E_HAL_MIN((a),H264E_HAL_MIN3((b),(c),(d))) -#define H264E_HAL_MAX4(a,b,c,d) H264E_HAL_MAX((a),H264E_HAL_MAX3((b),(c),(d))) -#define H264E_HAL_CLIP3(v, min, max) ((v) < (min) ? (min) : ((v) > (max) ? (max) : (v))) - -#define H264E_HAL_FCLOSE(fp) do{ if(fp) fclose(fp); fp = NULL; } while (0) - -#define H264E_HAL_SET_REG(reg, addr, val) \ - do { \ - reg[(addr)>>2] = (RK_U32)(val); \ - if(h264e_hal_log_mode & 0/*H264E_HAL_LOG_INFO*/) \ - mpp_log("line(%d) set reg[%03d/%03x]: %08x", __LINE__, (addr)>>2, addr, val); \ - } while (0) - - -#define H264E_HAL_VALIDATE_GT(val, name, limit) \ - do { \ - if((val)<=(limit)) { \ - mpp_err("%s(%d) should > %d", name, val, limit); \ - return MPP_NOK; \ - } \ - } while (0) - -#define H264E_HAL_VALIDATE_NEQ(val, name, limit) \ - do { \ - if((val)==(limit)) { \ - mpp_err("%s(%d) should not = %d", name, val, limit); \ - return MPP_NOK; \ - } \ - } while (0) - - -#define H264E_REF_MAX 16 -#define H264E_MAX_PACKETED_PARAM_SIZE 256 //sps + pps - -typedef enum h264e_hal_slice_type_t { - H264E_HAL_SLICE_TYPE_P = 0, - H264E_HAL_SLICE_TYPE_B = 1, - H264E_HAL_SLICE_TYPE_I = 2, -} h264e_hal_slice_type; - -typedef struct h264e_hal_sps_t { - RK_S32 i_id; - - RK_S32 i_profile_idc; - RK_S32 i_level_idc; - - RK_S32 b_constraint_set0; - RK_S32 b_constraint_set1; - RK_S32 b_constraint_set2; - RK_S32 b_constraint_set3; - - RK_S32 i_log2_max_frame_num; - - RK_S32 i_poc_type; - /* poc 0 */ - RK_S32 i_log2_max_poc_lsb; - - RK_S32 i_num_ref_frames; - RK_S32 b_gaps_in_frame_num_value_allowed; - RK_S32 i_mb_width; - RK_S32 i_mb_height; - RK_S32 b_frame_mbs_only; - RK_S32 b_mb_adaptive_frame_field; - RK_S32 b_direct8x8_inference; - - RK_S32 b_crop; - struct { - RK_S32 i_left; - RK_S32 i_right; - RK_S32 i_top; - RK_S32 i_bottom; - } crop; - - RK_S32 b_vui; - struct { - RK_S32 b_aspect_ratio_info_present; - RK_S32 i_sar_width; - RK_S32 i_sar_height; - - RK_S32 b_overscan_info_present; - RK_S32 b_overscan_info; - - RK_S32 b_signal_type_present; - RK_S32 i_vidformat; - RK_S32 b_fullrange; - RK_S32 b_color_description_present; - RK_S32 i_colorprim; - RK_S32 i_transfer; - RK_S32 i_colmatrix; - - RK_S32 b_chroma_loc_info_present; - RK_S32 i_chroma_loc_top; - RK_S32 i_chroma_loc_bottom; - - RK_S32 b_timing_info_present; - RK_U32 i_num_units_in_tick; - RK_U32 i_time_scale; - RK_S32 b_fixed_frame_rate; - - RK_S32 b_nal_hrd_parameters_present; - RK_S32 b_vcl_hrd_parameters_present; - - struct { - RK_S32 i_cpb_cnt; - RK_S32 i_bit_rate_scale; - RK_S32 i_cpb_size_scale; - RK_S32 i_bit_rate_value; - RK_S32 i_cpb_size_value; - RK_S32 i_bit_rate_unscaled; - RK_S32 i_cpb_size_unscaled; - RK_S32 b_cbr_hrd; - - RK_S32 i_initial_cpb_removal_delay_length; - RK_S32 i_cpb_removal_delay_length; - RK_S32 i_dpb_output_delay_length; - RK_S32 i_time_offset_length; - } hrd; - - RK_S32 b_pic_struct_present; - RK_S32 b_bitstream_restriction; - RK_S32 b_motion_vectors_over_pic_boundaries; - RK_S32 i_max_bytes_per_pic_denom; - RK_S32 i_max_bits_per_mb_denom; - RK_S32 i_log2_max_mv_length_horizontal; - RK_S32 i_log2_max_mv_length_vertical; - RK_S32 i_num_reorder_frames; - RK_S32 i_max_dec_frame_buffering; - - /* FIXME to complete */ - } vui; - - RK_S32 b_qpprime_y_zero_transform_bypass; - RK_S32 i_chroma_format_idc; - - /* only for backup, excluded in read SPS*/ - RK_S32 keyframe_max_interval; -} h264e_hal_sps; - -typedef struct h264e_hal_pps_t { - RK_S32 i_id; - RK_S32 i_sps_id; - - RK_S32 b_cabac; - - RK_S32 b_pic_order; - RK_S32 i_num_slice_groups; - - RK_S32 i_num_ref_idx_l0_default_active; - RK_S32 i_num_ref_idx_l1_default_active; - - RK_S32 b_weighted_pred; - RK_S32 i_weighted_bipred_idc; - - RK_S32 i_pic_init_qp; - RK_S32 i_pic_init_qs; - - RK_S32 i_chroma_qp_index_offset; - RK_S32 i_second_chroma_qp_index_offset; - - RK_S32 b_deblocking_filter_control; - RK_S32 b_constrained_intra_pred; - RK_S32 b_redundant_pic_cnt; - - RK_S32 b_transform_8x8_mode; - - RK_S32 b_cqm_preset; //pic_scaling_list_present_flag - const RK_U8 *scaling_list[8]; /* could be 12, but we don't allow separate Cb/Cr lists */ -} h264e_hal_pps; - -typedef enum h264e_rkv_nal_idx_t { - RKV_H264E_RKV_NAL_IDX_SPS, - RKV_H264E_RKV_NAL_IDX_PPS, - RKV_H264E_RKV_NAL_IDX_BUTT, -} h264e_rkv_nal_idx; - -typedef enum rkvenc_nal_unit_type_t { - RKVENC_NAL_UNKNOWN = 0, - RKVENC_NAL_SLICE = 1, - RKVENC_NAL_SLICE_DPA = 2, - RKVENC_NAL_SLICE_DPB = 3, - RKVENC_NAL_SLICE_DPC = 4, - RKVENC_NAL_SLICE_IDR = 5, /* ref_idc != 0 */ - RKVENC_NAL_SEI = 6, /* ref_idc == 0 */ - RKVENC_NAL_SPS = 7, - RKVENC_NAL_PPS = 8, - RKVENC_NAL_AUD = 9, - RKVENC_NAL_FILLER = 12, - /* ref_idc == 0 for 6,9,10,11,12 */ -} rkvenc_nal_unit_type; - -typedef enum rkvencnal_priority_t { - RKVENC_NAL_PRIORITY_DISPOSABLE = 0, - RKVENC_NAL_PRIORITY_LOW = 1, - RKVENC_NAL_PRIORITY_HIGH = 2, - RKVENC_NAL_PRIORITY_HIGHEST = 3, -} rkvenc_nal_priority; - -typedef struct h264e_hal_vui_param_t { - /* they will be reduced to be 0 < x <= 65535 and prime */ - RK_S32 i_sar_height; - RK_S32 i_sar_width; - - RK_S32 i_overscan; /* 0=undef, 1=no overscan, 2=overscan */ - - /* see h264 annex E for the values of the following */ - RK_S32 i_vidformat; - RK_S32 b_fullrange; - RK_S32 i_colorprim; - RK_S32 i_transfer; - RK_S32 i_colmatrix; - RK_S32 i_chroma_loc; /* both top & bottom */ -} h264e_hal_vui_param; - -typedef struct h264e_hal_ref_param_t { - RK_S32 i_frame_reference; /* Maximum number of reference frames */ - RK_S32 i_ref_pos; - RK_S32 i_long_term_en; - RK_S32 i_long_term_internal; - RK_S32 hw_longterm_mode; - RK_S32 i_dpb_size; /* Force a DPB size larger than that implied by B-frames and reference frames. - * Useful in combination with interactive error resilience. */ - RK_S32 i_frame_packing; -} h264e_hal_ref_param; - - -typedef struct h264e_hal_param_t { - RK_S32 constrained_intra; - - h264e_hal_vui_param vui; - h264e_hal_ref_param ref; - -} h264e_hal_param; - -typedef struct h264e_hal_context_t { - MppHalApi api; - VPU_CLIENT_TYPE vpu_client; - RK_S32 vpu_socket; - IOInterruptCB int_cb; - h264e_feedback feedback; - void *regs; - void *ioctl_input; - void *ioctl_output; - void *buffers; - void *extra_info; - void *dpb_ctx; - RK_U32 frame_cnt_gen_ready; - RK_U32 frame_cnt_send_ready; - RK_U32 num_frames_to_send; - RK_U32 frame_cnt; - h264e_hal_param param; - RK_U32 enc_mode; - HalEncTask enc_task; - void *dump_files; - - void *param_buf; - size_t param_size; - MppPacket packeted_param; - void *test_cfg; -} h264e_hal_context; - -#endif +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __HAL_H264E_H__ +#define __HAL_H264E_H__ + +#include "vpu.h" +#include "mpp_log.h" +#include "mpp_hal.h" + +#include "mpp_packet.h" +#include "h264e_syntax.h" + +extern RK_U32 h264e_hal_log_mode; + +#define H264E_HAL_LOG_ERROR 0x00000001 + +#define H264E_HAL_LOG_SIMPLE 0x00000010 + +#define H264E_HAL_LOG_FLOW 0x00000100 + +#define H264E_HAL_LOG_DPB 0x00001000 +#define H264E_HAL_LOG_HEADER 0x00002000 + +#define H264E_HAL_LOG_DETAIL 0x00010000 + +#define H264E_HAL_LOG_FILE 0x00100000 + + + +#define H264E_HAL_MASK_2b (RK_U32)0x00000003 +#define H264E_HAL_MASK_3b (RK_U32)0x00000007 +#define H264E_HAL_MASK_4b (RK_U32)0x0000000F +#define H264E_HAL_MASK_5b (RK_U32)0x0000001F +#define H264E_HAL_MASK_6b (RK_U32)0x0000003F +#define H264E_HAL_MASK_11b (RK_U32)0x000007FF +#define H264E_HAL_MASK_14b (RK_U32)0x00003FFF +#define H264E_HAL_MASK_16b (RK_U32)0x0000FFFF + + +#define h264e_hal_debug_enter() \ + do {\ + if (h264e_hal_log_mode & H264E_HAL_LOG_FLOW)\ + { mpp_log("line(%d), func(%s), enter", __LINE__, __FUNCTION__); }\ + } while (0) + +#define h264e_hal_debug_leave() \ + do {\ + if (h264e_hal_log_mode & H264E_HAL_LOG_FLOW)\ + { mpp_log("line(%d), func(%s), leave", __LINE__, __FUNCTION__); }\ + } while (0) + +#define h264e_hal_log_err(fmt, ...) \ + do {\ + if (h264e_hal_log_mode & H264E_HAL_LOG_ERROR)\ + { mpp_err(fmt, ## __VA_ARGS__); }\ + } while (0) + +#define h264e_hal_log_detail(fmt, ...) \ + do {\ + if (h264e_hal_log_mode & H264E_HAL_LOG_DETAIL)\ + { mpp_log(fmt, ## __VA_ARGS__); }\ + } while (0) + +#define h264e_hal_log_dpb(fmt, ...) \ + do {\ + if (h264e_hal_log_mode & H264E_HAL_LOG_DPB)\ + { mpp_log(fmt, ## __VA_ARGS__); }\ + } while (0) + +#define h264e_hal_log_header(fmt, ...) \ + do {\ + if (h264e_hal_log_mode & H264E_HAL_LOG_HEADER)\ + { mpp_log(fmt, ## __VA_ARGS__); }\ + } while (0) + +#define h264e_hal_log_simple(fmt, ...) \ + do {\ + if (h264e_hal_log_mode & H264E_HAL_LOG_SIMPLE)\ + { mpp_log(fmt, ## __VA_ARGS__); }\ + } while (0) + +#define h264e_hal_log_file(fmt, ...) \ + do {\ + if (h264e_hal_log_mode & H264E_HAL_LOG_FILE)\ + { mpp_log(fmt, ## __VA_ARGS__); }\ + } while (0) + +#define H264E_HAL_MIN(a,b) ( (a)<(b) ? (a) : (b) ) +#define H264E_HAL_MAX(a,b) ( (a)>(b) ? (a) : (b) ) +#define H264E_HAL_MIN3(a,b,c) H264E_HAL_MIN((a),H264E_HAL_MIN((b),(c))) +#define H264E_HAL_MAX3(a,b,c) H264E_HAL_MAX((a),H264E_HAL_MAX((b),(c))) +#define H264E_HAL_MIN4(a,b,c,d) H264E_HAL_MIN((a),H264E_HAL_MIN3((b),(c),(d))) +#define H264E_HAL_MAX4(a,b,c,d) H264E_HAL_MAX((a),H264E_HAL_MAX3((b),(c),(d))) +#define H264E_HAL_CLIP3(v, min, max) ((v) < (min) ? (min) : ((v) > (max) ? (max) : (v))) + +#define H264E_HAL_FCLOSE(fp) do{ if(fp) fclose(fp); fp = NULL; } while (0) + +#define H264E_HAL_SET_REG(reg, addr, val) \ + do { \ + reg[(addr)>>2] = (RK_U32)(val); \ + if(h264e_hal_log_mode & 0/*H264E_HAL_LOG_INFO*/) \ + mpp_log("line(%d) set reg[%03d/%03x]: %08x", __LINE__, (addr)>>2, addr, val); \ + } while (0) + + +#define H264E_HAL_VALIDATE_GT(val, name, limit) \ + do { \ + if((val)<=(limit)) { \ + mpp_err("%s(%d) should > %d", name, val, limit); \ + return MPP_NOK; \ + } \ + } while (0) + +#define H264E_HAL_VALIDATE_NEQ(val, name, limit) \ + do { \ + if((val)==(limit)) { \ + mpp_err("%s(%d) should not = %d", name, val, limit); \ + return MPP_NOK; \ + } \ + } while (0) + + +#define H264E_REF_MAX 16 +#define H264E_MAX_PACKETED_PARAM_SIZE 256 //sps + pps + +typedef enum h264e_hal_slice_type_t { + H264E_HAL_SLICE_TYPE_P = 0, + H264E_HAL_SLICE_TYPE_B = 1, + H264E_HAL_SLICE_TYPE_I = 2, +} h264e_hal_slice_type; + +typedef struct h264e_hal_sps_t { + RK_S32 i_id; + + RK_S32 i_profile_idc; + RK_S32 i_level_idc; + + RK_S32 b_constraint_set0; + RK_S32 b_constraint_set1; + RK_S32 b_constraint_set2; + RK_S32 b_constraint_set3; + + RK_S32 i_log2_max_frame_num; + + RK_S32 i_poc_type; + /* poc 0 */ + RK_S32 i_log2_max_poc_lsb; + + RK_S32 i_num_ref_frames; + RK_S32 b_gaps_in_frame_num_value_allowed; + RK_S32 i_mb_width; + RK_S32 i_mb_height; + RK_S32 b_frame_mbs_only; + RK_S32 b_mb_adaptive_frame_field; + RK_S32 b_direct8x8_inference; + + RK_S32 b_crop; + struct { + RK_S32 i_left; + RK_S32 i_right; + RK_S32 i_top; + RK_S32 i_bottom; + } crop; + + RK_S32 b_vui; + struct { + RK_S32 b_aspect_ratio_info_present; + RK_S32 i_sar_width; + RK_S32 i_sar_height; + + RK_S32 b_overscan_info_present; + RK_S32 b_overscan_info; + + RK_S32 b_signal_type_present; + RK_S32 i_vidformat; + RK_S32 b_fullrange; + RK_S32 b_color_description_present; + RK_S32 i_colorprim; + RK_S32 i_transfer; + RK_S32 i_colmatrix; + + RK_S32 b_chroma_loc_info_present; + RK_S32 i_chroma_loc_top; + RK_S32 i_chroma_loc_bottom; + + RK_S32 b_timing_info_present; + RK_U32 i_num_units_in_tick; + RK_U32 i_time_scale; + RK_S32 b_fixed_frame_rate; + + RK_S32 b_nal_hrd_parameters_present; + RK_S32 b_vcl_hrd_parameters_present; + + struct { + RK_S32 i_cpb_cnt; + RK_S32 i_bit_rate_scale; + RK_S32 i_cpb_size_scale; + RK_S32 i_bit_rate_value; + RK_S32 i_cpb_size_value; + RK_S32 i_bit_rate_unscaled; + RK_S32 i_cpb_size_unscaled; + RK_S32 b_cbr_hrd; + + RK_S32 i_initial_cpb_removal_delay_length; + RK_S32 i_cpb_removal_delay_length; + RK_S32 i_dpb_output_delay_length; + RK_S32 i_time_offset_length; + } hrd; + + RK_S32 b_pic_struct_present; + RK_S32 b_bitstream_restriction; + RK_S32 b_motion_vectors_over_pic_boundaries; + RK_S32 i_max_bytes_per_pic_denom; + RK_S32 i_max_bits_per_mb_denom; + RK_S32 i_log2_max_mv_length_horizontal; + RK_S32 i_log2_max_mv_length_vertical; + RK_S32 i_num_reorder_frames; + RK_S32 i_max_dec_frame_buffering; + + /* FIXME to complete */ + } vui; + + RK_S32 b_qpprime_y_zero_transform_bypass; + RK_S32 i_chroma_format_idc; + + /* only for backup, excluded in read SPS*/ + RK_S32 keyframe_max_interval; +} h264e_hal_sps; + +typedef struct h264e_hal_pps_t { + RK_S32 i_id; + RK_S32 i_sps_id; + + RK_S32 b_cabac; + + RK_S32 b_pic_order; + RK_S32 i_num_slice_groups; + + RK_S32 i_num_ref_idx_l0_default_active; + RK_S32 i_num_ref_idx_l1_default_active; + + RK_S32 b_weighted_pred; + RK_S32 i_weighted_bipred_idc; + + RK_S32 i_pic_init_qp; + RK_S32 i_pic_init_qs; + + RK_S32 i_chroma_qp_index_offset; + RK_S32 i_second_chroma_qp_index_offset; + + RK_S32 b_deblocking_filter_control; + RK_S32 b_constrained_intra_pred; + RK_S32 b_redundant_pic_cnt; + + RK_S32 b_transform_8x8_mode; + + RK_S32 b_cqm_preset; //pic_scaling_list_present_flag + const RK_U8 *scaling_list[8]; /* could be 12, but we don't allow separate Cb/Cr lists */ +} h264e_hal_pps; + +typedef enum h264e_rkv_nal_idx_t { + RKV_H264E_RKV_NAL_IDX_SPS, + RKV_H264E_RKV_NAL_IDX_PPS, + RKV_H264E_RKV_NAL_IDX_BUTT, +} h264e_rkv_nal_idx; + +typedef enum rkvenc_nal_unit_type_t { + RKVENC_NAL_UNKNOWN = 0, + RKVENC_NAL_SLICE = 1, + RKVENC_NAL_SLICE_DPA = 2, + RKVENC_NAL_SLICE_DPB = 3, + RKVENC_NAL_SLICE_DPC = 4, + RKVENC_NAL_SLICE_IDR = 5, /* ref_idc != 0 */ + RKVENC_NAL_SEI = 6, /* ref_idc == 0 */ + RKVENC_NAL_SPS = 7, + RKVENC_NAL_PPS = 8, + RKVENC_NAL_AUD = 9, + RKVENC_NAL_FILLER = 12, + /* ref_idc == 0 for 6,9,10,11,12 */ +} rkvenc_nal_unit_type; + +typedef enum rkvencnal_priority_t { + RKVENC_NAL_PRIORITY_DISPOSABLE = 0, + RKVENC_NAL_PRIORITY_LOW = 1, + RKVENC_NAL_PRIORITY_HIGH = 2, + RKVENC_NAL_PRIORITY_HIGHEST = 3, +} rkvenc_nal_priority; + +typedef struct h264e_hal_vui_param_t { + /* they will be reduced to be 0 < x <= 65535 and prime */ + RK_S32 i_sar_height; + RK_S32 i_sar_width; + + RK_S32 i_overscan; /* 0=undef, 1=no overscan, 2=overscan */ + + /* see h264 annex E for the values of the following */ + RK_S32 i_vidformat; + RK_S32 b_fullrange; + RK_S32 i_colorprim; + RK_S32 i_transfer; + RK_S32 i_colmatrix; + RK_S32 i_chroma_loc; /* both top & bottom */ +} h264e_hal_vui_param; + +typedef struct h264e_hal_ref_param_t { + RK_S32 i_frame_reference; /* Maximum number of reference frames */ + RK_S32 i_ref_pos; + RK_S32 i_long_term_en; + RK_S32 i_long_term_internal; + RK_S32 hw_longterm_mode; + RK_S32 i_dpb_size; /* Force a DPB size larger than that implied by B-frames and reference frames. + * Useful in combination with interactive error resilience. */ + RK_S32 i_frame_packing; +} h264e_hal_ref_param; + + +typedef struct h264e_hal_param_t { + RK_S32 constrained_intra; + + h264e_hal_vui_param vui; + h264e_hal_ref_param ref; + +} h264e_hal_param; + +typedef struct h264e_hal_context_t { + MppHalApi api; + VPU_CLIENT_TYPE vpu_client; + RK_S32 vpu_socket; + IOInterruptCB int_cb; + h264e_feedback feedback; + void *regs; + void *ioctl_input; + void *ioctl_output; + void *buffers; + void *extra_info; + void *dpb_ctx; + RK_U32 frame_cnt_gen_ready; + RK_U32 frame_cnt_send_ready; + RK_U32 num_frames_to_send; + RK_U32 frame_cnt; + h264e_hal_param param; + RK_U32 enc_mode; + HalEncTask enc_task; + void *dump_files; + + void *param_buf; + size_t param_size; + MppPacket packeted_param; + void *test_cfg; +} h264e_hal_context; + +#endif diff --git a/mpp/hal/rkenc/h264e/hal_h264e_api.c b/mpp/hal/rkenc/h264e/hal_h264e_api.c index 1df3eabc..a1a04ec5 100644 --- a/mpp/hal/rkenc/h264e/hal_h264e_api.c +++ b/mpp/hal/rkenc/h264e/hal_h264e_api.c @@ -1,149 +1,149 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define MODULE_TAG "hal_h264e_api" - -#include -#include -#ifdef RKPLATFORM -#include -#endif - -#include "mpp_common.h" -#include "vpu.h" -#include "mpp_hal.h" -#include "mpp_env.h" -#include "hal_h264e_api.h" -#include "hal_h264e.h" -#include "hal_h264e_vpu.h" -#include "hal_h264e_rkv.h" - -RK_U32 h264e_hal_log_mode = 0; - -MPP_RET hal_h264e_init(void *hal, MppHalCfg *cfg) -{ - h264e_hal_context *ctx = (h264e_hal_context *)hal; - MppHalApi *api = &ctx->api; - - mpp_env_get_u32("h264e_hal_debug", &h264e_hal_log_mode, 0x00000001); - if (!access("/dev/rkvenc", F_OK)) - cfg->device_id = HAL_RKVENC; - else - cfg->device_id = HAL_VEPU; - - switch (cfg->device_id) { - case HAL_VEPU: - api->init = hal_h264e_vpu_init; - api->deinit = hal_h264e_vpu_deinit; - api->reg_gen = hal_h264e_vpu_gen_regs; - api->start = hal_h264e_vpu_start; - api->wait = hal_h264e_vpu_wait; - api->reset = hal_h264e_vpu_reset; - api->flush = hal_h264e_vpu_flush; - api->control = hal_h264e_vpu_control; - break; - case HAL_RKVENC: - api->init = hal_h264e_rkv_init; - api->deinit = hal_h264e_rkv_deinit; - api->reg_gen = hal_h264e_rkv_gen_regs; - api->start = hal_h264e_rkv_start; - api->wait = hal_h264e_rkv_wait; - api->reset = hal_h264e_rkv_reset; - api->flush = hal_h264e_rkv_flush; - api->control = hal_h264e_rkv_control; - break; - default: - mpp_err("invalid device_id: %d", cfg->device_id); - return MPP_NOK; - } - - return api->init(hal, cfg); -} - -MPP_RET hal_h264e_deinit(void *hal) -{ - h264e_hal_context *ctx = (h264e_hal_context *)hal; - MppHalApi *api = &ctx->api; - - return api->deinit(hal); -} - -MPP_RET hal_h264e_gen_regs(void *hal, HalTaskInfo *task) -{ - h264e_hal_context *ctx = (h264e_hal_context *)hal; - MppHalApi *api = &ctx->api; - - return api->reg_gen(hal, task); -} - -MPP_RET hal_h264e_start(void *hal, HalTaskInfo *task) -{ - h264e_hal_context *ctx = (h264e_hal_context *)hal; - MppHalApi *api = &ctx->api; - - return api->start(hal, task); -} - -MPP_RET hal_h264e_wait(void *hal, HalTaskInfo *task) -{ - h264e_hal_context *ctx = (h264e_hal_context *)hal; - MppHalApi *api = &ctx->api; - - return api->wait(hal, task); -} - -MPP_RET hal_h264e_reset(void *hal) -{ - h264e_hal_context *ctx = (h264e_hal_context *)hal; - MppHalApi *api = &ctx->api; - - return api->reset(hal); -} - -MPP_RET hal_h264e_flush(void *hal) -{ - h264e_hal_context *ctx = (h264e_hal_context *)hal; - MppHalApi *api = &ctx->api; - - return api->flush(hal); -} - -MPP_RET hal_h264e_control(void *hal, RK_S32 cmd_type, void *param) -{ - h264e_hal_context *ctx = (h264e_hal_context *)hal; - MppHalApi *api = &ctx->api; - - return api->control(hal, cmd_type, param); -} - - -const MppHalApi hal_api_h264e = { - "h264e_rkvenc", - MPP_CTX_ENC, - MPP_VIDEO_CodingAVC, - sizeof(h264e_hal_context), - 0, - hal_h264e_init, - hal_h264e_deinit, - hal_h264e_gen_regs, - hal_h264e_start, - hal_h264e_wait, - hal_h264e_reset, - hal_h264e_flush, - hal_h264e_control, -}; - - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define MODULE_TAG "hal_h264e_api" + +#include +#include +#ifdef RKPLATFORM +#include +#endif + +#include "mpp_common.h" +#include "vpu.h" +#include "mpp_hal.h" +#include "mpp_env.h" +#include "hal_h264e_api.h" +#include "hal_h264e.h" +#include "hal_h264e_vpu.h" +#include "hal_h264e_rkv.h" + +RK_U32 h264e_hal_log_mode = 0; + +MPP_RET hal_h264e_init(void *hal, MppHalCfg *cfg) +{ + h264e_hal_context *ctx = (h264e_hal_context *)hal; + MppHalApi *api = &ctx->api; + + mpp_env_get_u32("h264e_hal_debug", &h264e_hal_log_mode, 0x00000001); + if (!access("/dev/rkvenc", F_OK)) + cfg->device_id = HAL_RKVENC; + else + cfg->device_id = HAL_VEPU; + + switch (cfg->device_id) { + case HAL_VEPU: + api->init = hal_h264e_vpu_init; + api->deinit = hal_h264e_vpu_deinit; + api->reg_gen = hal_h264e_vpu_gen_regs; + api->start = hal_h264e_vpu_start; + api->wait = hal_h264e_vpu_wait; + api->reset = hal_h264e_vpu_reset; + api->flush = hal_h264e_vpu_flush; + api->control = hal_h264e_vpu_control; + break; + case HAL_RKVENC: + api->init = hal_h264e_rkv_init; + api->deinit = hal_h264e_rkv_deinit; + api->reg_gen = hal_h264e_rkv_gen_regs; + api->start = hal_h264e_rkv_start; + api->wait = hal_h264e_rkv_wait; + api->reset = hal_h264e_rkv_reset; + api->flush = hal_h264e_rkv_flush; + api->control = hal_h264e_rkv_control; + break; + default: + mpp_err("invalid device_id: %d", cfg->device_id); + return MPP_NOK; + } + + return api->init(hal, cfg); +} + +MPP_RET hal_h264e_deinit(void *hal) +{ + h264e_hal_context *ctx = (h264e_hal_context *)hal; + MppHalApi *api = &ctx->api; + + return api->deinit(hal); +} + +MPP_RET hal_h264e_gen_regs(void *hal, HalTaskInfo *task) +{ + h264e_hal_context *ctx = (h264e_hal_context *)hal; + MppHalApi *api = &ctx->api; + + return api->reg_gen(hal, task); +} + +MPP_RET hal_h264e_start(void *hal, HalTaskInfo *task) +{ + h264e_hal_context *ctx = (h264e_hal_context *)hal; + MppHalApi *api = &ctx->api; + + return api->start(hal, task); +} + +MPP_RET hal_h264e_wait(void *hal, HalTaskInfo *task) +{ + h264e_hal_context *ctx = (h264e_hal_context *)hal; + MppHalApi *api = &ctx->api; + + return api->wait(hal, task); +} + +MPP_RET hal_h264e_reset(void *hal) +{ + h264e_hal_context *ctx = (h264e_hal_context *)hal; + MppHalApi *api = &ctx->api; + + return api->reset(hal); +} + +MPP_RET hal_h264e_flush(void *hal) +{ + h264e_hal_context *ctx = (h264e_hal_context *)hal; + MppHalApi *api = &ctx->api; + + return api->flush(hal); +} + +MPP_RET hal_h264e_control(void *hal, RK_S32 cmd_type, void *param) +{ + h264e_hal_context *ctx = (h264e_hal_context *)hal; + MppHalApi *api = &ctx->api; + + return api->control(hal, cmd_type, param); +} + + +const MppHalApi hal_api_h264e = { + "h264e_rkvenc", + MPP_CTX_ENC, + MPP_VIDEO_CodingAVC, + sizeof(h264e_hal_context), + 0, + hal_h264e_init, + hal_h264e_deinit, + hal_h264e_gen_regs, + hal_h264e_start, + hal_h264e_wait, + hal_h264e_reset, + hal_h264e_flush, + hal_h264e_control, +}; + + diff --git a/mpp/hal/rkenc/h264e/hal_h264e_rkv.c b/mpp/hal/rkenc/h264e/hal_h264e_rkv.c index dfb8ac89..5373bbbc 100644 --- a/mpp/hal/rkenc/h264e/hal_h264e_rkv.c +++ b/mpp/hal/rkenc/h264e/hal_h264e_rkv.c @@ -1,3647 +1,3647 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define MODULE_TAG "hal_h264e_rk" - -#include -#include - -#include "vpu.h" -#include "mpp_common.h" -#include "mpp_mem.h" - -#include "h264_syntax.h" -#include "hal_h264e.h" -#include "hal_h264e_rkv.h" - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define MODULE_TAG "hal_h264e_rk" + +#include +#include + +#include "vpu.h" +#include "mpp_common.h" +#include "mpp_mem.h" + +#include "h264_syntax.h" +#include "hal_h264e.h" +#include "hal_h264e_rkv.h" + #define RKVENC_DUMP_INFO 0 - -#define RKVENC_FRAME_TYPE_AUTO 0x0000 /* Let x264 choose the right type */ -#define RKVENC_FRAME_TYPE_IDR 0x0001 -#define RKVENC_FRAME_TYPE_I 0x0002 -#define RKVENC_FRAME_TYPE_P 0x0003 -#define RKVENC_FRAME_TYPE_BREF 0x0004 /* Non-disposable B-frame */ -#define RKVENC_FRAME_TYPE_B 0x0005 -#define RKVENC_FRAME_TYPE_KEYFRAME 0x0006 /* IDR or I depending on b_open_gop option */ -#define RKVENC_IS_TYPE_I(x) ((x)==RKVENC_FRAME_TYPE_I || (x)==RKVENC_FRAME_TYPE_IDR) -#define RKVENC_IS_TYPE_B(x) ((x)==RKVENC_FRAME_TYPE_B || (x)==RKVENC_FRAME_TYPE_BREF) -#define RKVENC_IS_DISPOSABLE(type) ( type == RKVENC_FRAME_TYPE_B ) - -const RK_S32 h264e_csp_idx_map[H264E_RKV_CSP_BUTT] = {RKV_H264E_CSP2_BGRA, RKV_H264E_CSP2_BGR, RKV_H264E_CSP2_RGB, 0, RKV_H264E_CSP2_NV16, RKV_H264E_CSP2_I422, RKV_H264E_CSP2_NV12, - RKV_H264E_CSP2_I420, RKV_H264E_CSP2_RGB, RKV_H264E_CSP2_RGB - }; - -static const RK_U32 h264e_h3d_tbl[40] = { - 0x0b080400, 0x1815120f, 0x23201e1b, 0x2c2a2725, - 0x33312f2d, 0x38373634, 0x3d3c3b39, 0x403f3e3d, - 0x42414140, 0x43434342, 0x44444444, 0x44444444, - 0x44444444, 0x43434344, 0x42424343, 0x40414142, - 0x3d3e3f40, 0x393a3b3c, 0x35363738, 0x30313334, - 0x2c2d2e2f, 0x28292a2b, 0x23242526, 0x20202122, - 0x191b1d1f, 0x14151618, 0x0f101112, 0x0b0c0d0e, - 0x08090a0a, 0x06070708, 0x05050506, 0x03040404, - 0x02020303, 0x01010102, 0x00010101, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000 -}; - -static const RK_U8 h264e_ue_size_tab[256] = { - 1, 1, 3, 3, 5, 5, 5, 5, 7, 7, 7, 7, 7, 7, 7, 7, - 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, -}; - -/* default quant matrices */ -static const RK_U8 h264e_rkv_cqm_jvt4i[16] = { - 6, 13, 20, 28, - 13, 20, 28, 32, - 20, 28, 32, 37, - 28, 32, 37, 42 -}; -static const RK_U8 h264e_rkv_cqm_jvt4p[16] = { - 10, 14, 20, 24, - 14, 20, 24, 27, - 20, 24, 27, 30, - 24, 27, 30, 34 -}; -static const RK_U8 h264e_rkv_cqm_jvt8i[64] = { - 6, 10, 13, 16, 18, 23, 25, 27, - 10, 11, 16, 18, 23, 25, 27, 29, - 13, 16, 18, 23, 25, 27, 29, 31, - 16, 18, 23, 25, 27, 29, 31, 33, - 18, 23, 25, 27, 29, 31, 33, 36, - 23, 25, 27, 29, 31, 33, 36, 38, - 25, 27, 29, 31, 33, 36, 38, 40, - 27, 29, 31, 33, 36, 38, 40, 42 -}; -static const RK_U8 h264e_rkv_cqm_jvt8p[64] = { - 9, 13, 15, 17, 19, 21, 22, 24, - 13, 13, 17, 19, 21, 22, 24, 25, - 15, 17, 19, 21, 22, 24, 25, 27, - 17, 19, 21, 22, 24, 25, 27, 28, - 19, 21, 22, 24, 25, 27, 28, 30, - 21, 22, 24, 25, 27, 28, 30, 32, - 22, 24, 25, 27, 28, 30, 32, 33, - 24, 25, 27, 28, 30, 32, 33, 35 -}; - -static const RK_U8 h264e_rkv_cqm_flat16[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 const RK_U8 * const h264e_rkv_cqm_jvt[8] = { - h264e_rkv_cqm_jvt4i, h264e_rkv_cqm_jvt4p, - h264e_rkv_cqm_jvt4i, h264e_rkv_cqm_jvt4p, - h264e_rkv_cqm_jvt8i, h264e_rkv_cqm_jvt8p, - h264e_rkv_cqm_jvt8i, h264e_rkv_cqm_jvt8p -}; - -/* zigzags are transposed with respect to the tables in the standard */ -static const RK_U8 h264e_rkv_zigzag_scan4[2][16] = { - { - // frame - 0, 4, 1, 2, 5, 8, 12, 9, 6, 3, 7, 10, 13, 14, 11, 15 - }, - { - // field - 0, 1, 4, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 - } -}; -static const RK_U8 h264e_rkv_zigzag_scan8[2][64] = { - { - 0, 8, 1, 2, 9, 16, 24, 17, 10, 3, 4, 11, 18, 25, 32, 40, - 33, 26, 19, 12, 5, 6, 13, 20, 27, 34, 41, 48, 56, 49, 42, 35, - 28, 21, 14, 7, 15, 22, 29, 36, 43, 50, 57, 58, 51, 44, 37, 30, - 23, 31, 38, 45, 52, 59, 60, 53, 46, 39, 47, 54, 61, 62, 55, 63 - }, - { - 0, 1, 2, 8, 9, 3, 4, 10, 16, 11, 5, 6, 7, 12, 17, 24, - 18, 13, 14, 15, 19, 25, 32, 26, 20, 21, 22, 23, 27, 33, 40, 34, - 28, 29, 30, 31, 35, 41, 48, 42, 36, 37, 38, 39, 43, 49, 50, 44, - 45, 46, 47, 51, 56, 57, 52, 53, 54, 55, 58, 59, 60, 61, 62, 63 - } -}; - -#if RKVENC_DUMP_INFO -static RK_U32 reg_idx2addr_map[132] = { - 0xffff, //0, unvalid. - 0x0000, //1 - 0x0004, //2 - 0x0008, //3 - 0x000c, //4 - 0x0010, //5 - 0x0014, //6 - 0x0018, //7 - 0x001C, //8 - 0x0030, //9 - 0x0034, //10 - 0x0038, //11 - 0x003c, //12 - 0x0040, //13 - 0x0044, //14 - 0x0048, //15 - 0x004c, //16 - 0x0050, //17 - 0x0054, //18 - 0x0058, //19 - 0x005c, //20 - 0x0060, //21.0~21.4 - 0x0074, //22.0~22.39 - 0x0114, //23 - 0x0118, //24 - 0x011c, //25 - 0x0120, //26 - 0x0124, //27 - 0x0128, //28 - 0x012c, //29 - 0x0130, //30 - 0x0134, //31 - 0x0138, //32 - 0x013c, //33 - 0x0140, //34 - 0x0144, //35 - 0x0148, //36 - 0x014c, //36 - 0x0150, //38 - 0x0154, //39 - 0x0158, //40 - 0x015c, //41 - 0x0160, //42 - 0x0164, //43 - 0x0168, //44 - 0x016c, //45 - 0x0170, //46 - 0x0174, //47 - 0x0178, //48 - 0x017c, //49 - 0x0180, //50 - 0x0184, //51 - 0x0188, //52 - 0x018c, //53 - 0x0190, //54 - 0x0194, //55 - 0x0198, //56 - 0x019c, //57 - 0x01a0, //58 - 0x01a4, //59 - 0x01a8, //60 - 0x01ac, //61 - 0x01b0, //62 - 0x01b4, //63 - 0x01b8, //64 - 0x01c0, //65 - 0x01c4, //66 - 0x01d0, //67.0~67.7 - 0x01f0, //68.0~68.7 - 0x0210, //69 - 0x0214, //70 - 0x0218, //71 - 0x021c, //72 - 0x0220, //73 - 0x0224, //74 - 0x0228, //75 - 0x022c, //76 - 0x0230, //77 - 0x0234, //78 - 0x0238, //79 - 0x0400, //80.0~80.255 - 0x0800, //81 - 0x0804, //82 - 0x0808, //83 - 0x0810, //84 - 0x0814, //85 - 0x0818, //86 - 0x0820, //87 - 0x0824, //88 - 0x0828, //89 - 0x082c, //90 - 0x0830, //91 - 0x0834, //92 - 0x0840, //93 - 0x0844, //94 - 0x0848, //95 - 0x084c, //96 - 0x0850, //97 - 0x0854, //98 - 0x0860, //99( 33 regs below are not present in c-model, included) - 0x0864, //100 - 0x0868, //101 - 0x086c, //102 - 0x0870, //103 - 0x0874, //104 - 0x0880, //105 - 0x0884, //106 - 0x0888, //107 - 0x088c, //108 - 0x0890, //109 - 0x0894, //110 - 0x0898, //111 - 0x089c, //112 - 0x08a0, //113 - 0x08a4, //114 - 0x08a8, //115 - 0x08ac, //116 - 0x08b0, //117 - 0x08b4, //118 - 0x08b8, //119 - 0x08bc, //120 - 0x08c0, //121 - 0x08c4, //122 - 0x08c8, //123 - 0x08cc, //124 - 0x08d0, //125 - 0x08d4, //126 - 0x08d8, //127 - 0x08dc, //128 - 0x08e0, //129 - 0x08e4, //130 - 0x08e8, //131 -}; -#endif - -static h264e_hal_rkv_csp_info hal_h264e_rkv_convert_csp(RK_S32 src_type) -{ - MppFrameFormat src_fmt = (MppFrameFormat)src_type; - h264e_hal_rkv_csp_info dst_info; - switch (src_fmt) { - case MPP_FMT_YUV420P: { - dst_info.fmt = (RK_U32)H264E_RKV_CSP_YUV420P; - dst_info.cswap = 0; - dst_info.aswap = 0; - break; - } - case MPP_FMT_YUV420SP: { - dst_info.fmt = (RK_U32)H264E_RKV_CSP_YUV420SP; - dst_info.cswap = 0; - dst_info.aswap = 0; - break; - } - case MPP_FMT_YUV420SP_10BIT: { - dst_info.fmt = (RK_U32)H264E_RKV_CSP_NONE; - dst_info.cswap = 0; - dst_info.aswap = 0; - break; - } - case MPP_FMT_YUV420SP_VU: { //TODO: to be confirmed - dst_info.fmt = (RK_U32)H264E_RKV_CSP_YUV420SP; - dst_info.cswap = 1; - dst_info.aswap = 0; - break; - } - case MPP_FMT_YUV422P: { - dst_info.fmt = (RK_U32)H264E_RKV_CSP_YUV422P; - dst_info.cswap = 0; - dst_info.aswap = 0; - break; - } - case MPP_FMT_YUV422SP: { - dst_info.fmt = (RK_U32)H264E_RKV_CSP_YUV422SP; - dst_info.cswap = 0; - dst_info.aswap = 0; - break; - } - case MPP_FMT_YUV422SP_10BIT: { - dst_info.fmt = (RK_U32)H264E_RKV_CSP_NONE; - dst_info.cswap = 0; - dst_info.aswap = 0; - break; - } - case MPP_FMT_YUV422SP_VU: { - dst_info.fmt = (RK_U32)H264E_RKV_CSP_YUV422SP; - dst_info.cswap = 1; - dst_info.aswap = 0; - break; - } - case MPP_FMT_YUV422_YUYV: { - dst_info.fmt = (RK_U32)H264E_RKV_CSP_YUYV422; - dst_info.cswap = 0; - dst_info.aswap = 0; - break; - } - case MPP_FMT_YUV422_UYVY: { - dst_info.fmt = (RK_U32)H264E_RKV_CSP_UYVY422; - dst_info.cswap = 0; - dst_info.aswap = 0; - break; - } - case MPP_FMT_RGB565: { - dst_info.fmt = (RK_U32)H264E_RKV_CSP_BGR565; - dst_info.cswap = 1; - dst_info.aswap = 0; - break; - } - case MPP_FMT_BGR565: { - dst_info.fmt = (RK_U32)H264E_RKV_CSP_BGR565; - dst_info.cswap = 0; - dst_info.aswap = 0; - break; - } - case MPP_FMT_RGB555: { - dst_info.fmt = (RK_U32)H264E_RKV_CSP_NONE; - dst_info.cswap = 0; - dst_info.aswap = 0; - break; - } - case MPP_FMT_BGR555: { - dst_info.fmt = (RK_U32)H264E_RKV_CSP_NONE; - dst_info.cswap = 0; - dst_info.aswap = 0; - break; - } - case MPP_FMT_RGB444: { - dst_info.fmt = (RK_U32)H264E_RKV_CSP_NONE; - dst_info.cswap = 0; - dst_info.aswap = 0; - break; - } - case MPP_FMT_BGR444: { - dst_info.fmt = (RK_U32)H264E_RKV_CSP_NONE; - dst_info.cswap = 0; - dst_info.aswap = 0; - break; - } - case MPP_FMT_RGB888: { - dst_info.fmt = (RK_U32)H264E_RKV_CSP_BGR888; - dst_info.cswap = 1; - dst_info.aswap = 0; - break; - } - case MPP_FMT_BGR888: { - dst_info.fmt = (RK_U32)H264E_RKV_CSP_BGR888; - dst_info.cswap = 0; - dst_info.aswap = 0; - break; - } - case MPP_FMT_RGB101010: { - dst_info.fmt = (RK_U32)H264E_RKV_CSP_NONE; - dst_info.cswap = 0; - dst_info.aswap = 0; - break; - } - case MPP_FMT_BGR101010: { - dst_info.fmt = (RK_U32)H264E_RKV_CSP_NONE; - dst_info.cswap = 0; - dst_info.aswap = 0; - break; - } - case MPP_FMT_ARGB8888: { - dst_info.fmt = (RK_U32)H264E_RKV_CSP_BGRA8888; - dst_info.cswap = 1; - dst_info.aswap = 1; - break; - } - case MPP_FMT_ABGR8888: { - dst_info.fmt = (RK_U32)H264E_RKV_CSP_BGRA8888; - dst_info.cswap = 0; - dst_info.aswap = 1; - break; - } - default: { - h264e_hal_log_err("unvalid src color space: %d", src_type); - dst_info.fmt = (RK_U32)H264E_RKV_CSP_NONE; - dst_info.cswap = 0; - dst_info.aswap = 0; - } - } - - return dst_info; -} - - - -static MPP_RET hal_h264e_rkv_close_dump_files(void *dump_files) -{ - h264e_hal_rkv_dump_files *files = (h264e_hal_rkv_dump_files *)dump_files; - H264E_HAL_FCLOSE(files->fp_mpp_syntax_in); - H264E_HAL_FCLOSE(files->fp_mpp_reg_in); - H264E_HAL_FCLOSE(files->fp_mpp_reg_out); - H264E_HAL_FCLOSE(files->fp_mpp_strm_out); - H264E_HAL_FCLOSE(files->fp_mpp_feedback); - H264E_HAL_FCLOSE(files->fp_mpp_extra_ino_cfg); - return MPP_OK; -} - - -static MPP_RET hal_h264e_rkv_open_dump_files(void *dump_files) -{ - if (h264e_hal_log_mode & H264E_HAL_LOG_FILE) { - char base_path[512]; - char full_path[512]; - h264e_hal_rkv_dump_files *files = (h264e_hal_rkv_dump_files *)dump_files; - strcpy(base_path, "/tmp/"); - - sprintf(full_path, "%s%s", base_path, "mpp_syntax_in.txt"); - files->fp_mpp_syntax_in = fopen(full_path, "wb"); - if (!files->fp_mpp_syntax_in) { - h264e_hal_log_err("%s open error", full_path); - return MPP_ERR_OPEN_FILE; - } - - - sprintf(full_path, "%s%s", base_path, "mpp_reg_in.txt"); - files->fp_mpp_reg_in = fopen(full_path, "wb"); - if (!files->fp_mpp_reg_in) { - h264e_hal_log_err("%s open error", full_path); - return MPP_ERR_OPEN_FILE; - } - - sprintf(full_path, "%s%s", base_path, "mpp_reg_out.txt"); - files->fp_mpp_reg_out = fopen(full_path, "wb"); - if (!files->fp_mpp_reg_out) { - h264e_hal_log_err("%s open error", full_path); - return MPP_ERR_OPEN_FILE; - } - - sprintf(full_path, "%s%s", base_path, "mpp_feedback.txt"); - files->fp_mpp_feedback = fopen(full_path, "wb"); - if (!files->fp_mpp_feedback) { - h264e_hal_log_err("%s open error", full_path); - return MPP_ERR_OPEN_FILE; - } - - sprintf(full_path, "%s%s", base_path, "mpp_strm_out.bin"); - files->fp_mpp_strm_out = fopen(full_path, "wb"); - if (!files->fp_mpp_strm_out) { - h264e_hal_log_err("%s open error", full_path); - return MPP_ERR_OPEN_FILE; - } - - sprintf(full_path, "%s%s", base_path, "mpp_extra_info_cfg.txt"); - files->fp_mpp_extra_ino_cfg = fopen(full_path, "wb"); - if (!files->fp_mpp_extra_ino_cfg) { - h264e_hal_log_err("%s open error", full_path); - return MPP_ERR_OPEN_FILE; - } - } - return MPP_OK; -} - -static void hal_h264e_rkv_dump_mpp_syntax_in(h264e_syntax *syn, h264e_hal_context *ctx) -{ -#if RKVENC_DUMP_INFO - h264e_hal_rkv_dump_files *dump_files = (h264e_hal_rkv_dump_files *)ctx->dump_files; - FILE *fp = dump_files->fp_mpp_syntax_in; - if (fp) { - //RK_S32 k = 0; - fprintf(fp, "#FRAME %d\n", ctx->frame_cnt); - - fprintf(fp, "%-16d %s\n", syn->pic_luma_width, "pic_luma_width"); - fprintf(fp, "%-16d %s\n", syn->pic_luma_height, "pic_luma_height"); - fprintf(fp, "%-16d %s\n", syn->level_idc, "level_idc"); - fprintf(fp, "%-16d %s\n", syn->profile_idc, "profile_idc"); - fprintf(fp, "%-16d %s\n", syn->frame_coding_type, "frame_coding_type"); - fprintf(fp, "%-16d %s\n", syn->qp, "swreg10.pic_qp"); - fprintf(fp, "%-16d %s\n", syn->input_image_format, "swreg14.src_cfmt"); - - fprintf(fp, "%-16d %s\n", syn->enable_cabac, "swreg59.etpy_mode"); - fprintf(fp, "%-16d %s\n", syn->pic_init_qp, "swreg59.pic_init_qp"); - fprintf(fp, "%-16d %s\n", syn->chroma_qp_index_offset, "swreg59.cb_ofst"); - fprintf(fp, "%-16d %s\n", syn->second_chroma_qp_index_offset, "swreg59.cr_ofst"); - - fprintf(fp, "%-16d %s\n", syn->slice_type, "swreg60.sli_type"); - fprintf(fp, "%-16d %s\n", syn->pps_id, "swreg60.pps_id"); - fprintf(fp, "%-16d %s\n", syn->frame_num, "swreg60.frm_num"); - fprintf(fp, "%-16d %s\n", syn->cabac_init_idc, "swreg60.cbc_init_idc"); - - fprintf(fp, "%-16d %s\n", syn->idr_pic_id, "swreg61.idr_pid"); - fprintf(fp, "%-16d %s\n", syn->pic_order_cnt_lsb, "swreg61.poc_lsb"); - - fprintf(fp, "%-16d %s\n", syn->keyframe_max_interval, "keyframe_max_interval"); - - fprintf(fp, "\n"); - fflush(fp); - } else { - h264e_hal_log_file("try to dump data to mpp_syntax_in.txt, but file is not opened"); - } -#else - (void)ctx; - (void)syn; -#endif -} - -static void hal_h264e_rkv_dump_mpp_reg_in(h264e_hal_context *ctx) -{ -#if RKVENC_DUMP_INFO - RK_S32 k = 0; - h264e_hal_rkv_dump_files *dump_files = (h264e_hal_rkv_dump_files *)ctx->dump_files; - FILE *fp = dump_files->fp_mpp_reg_in; - h264e_rkv_reg_set *reg_list = (h264e_rkv_reg_set *)ctx->regs; - RK_U32 *regs = (RK_U32 *)®_list[ctx->frame_cnt_gen_ready]; - -#if RKV_H264E_ADD_RESERVE_REGS - h264e_rkv_reg_set * r = (h264e_rkv_reg_set *)regs; -#endif - h264e_hal_log_file("dump_rkv_mpp_reg_in enter, %d regs are dumped", RK_H264E_NUM_REGS); - if (fp) { - fprintf(fp, "#FRAME %d:\n", ctx->frame_cnt); - - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 1, 1, reg_idx2addr_map[ 1], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 2, 2, reg_idx2addr_map[ 2], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 3, 3, reg_idx2addr_map[ 3], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 4, 4, reg_idx2addr_map[ 4], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 5, 5, reg_idx2addr_map[ 5], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 6, 6, reg_idx2addr_map[ 6], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 7, 7, reg_idx2addr_map[ 7], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 8, 8, reg_idx2addr_map[ 8], *regs++); -#if RKV_H264E_ADD_RESERVE_REGS - regs += MPP_ARRAY_ELEMS(r->reserve_08_09); -#endif - - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 9, 9, reg_idx2addr_map[ 9], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 10, 10, reg_idx2addr_map[10], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 11, 11, reg_idx2addr_map[11], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 12, 12, reg_idx2addr_map[12], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 13, 13, reg_idx2addr_map[13], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 14, 14, reg_idx2addr_map[14], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 15, 15, reg_idx2addr_map[15], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 16, 16, reg_idx2addr_map[16], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 17, 17, reg_idx2addr_map[17], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 18, 18, reg_idx2addr_map[18], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 19, 19, reg_idx2addr_map[19], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 20, 20, reg_idx2addr_map[20], *regs++); - for (k = 0; k < 5; k++) - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 21, 21, reg_idx2addr_map[21], *regs++); - for (k = 0; k < 40; k++) - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 22, 22, reg_idx2addr_map[22], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 23, 23, reg_idx2addr_map[23], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 24, 24, reg_idx2addr_map[24], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 25, 25, reg_idx2addr_map[25], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 26, 26, reg_idx2addr_map[26], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 27, 27, reg_idx2addr_map[27], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 28, 28, reg_idx2addr_map[28], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 29, 29, reg_idx2addr_map[29], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 30, 30, reg_idx2addr_map[30], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 31, 31, reg_idx2addr_map[31], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 32, 32, reg_idx2addr_map[32], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 33, 33, reg_idx2addr_map[33], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 34, 34, reg_idx2addr_map[34], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 35, 35, reg_idx2addr_map[35], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 36, 36, reg_idx2addr_map[36], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 37, 37, reg_idx2addr_map[37], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 38, 38, reg_idx2addr_map[38], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 39, 39, reg_idx2addr_map[39], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 40, 40, reg_idx2addr_map[40], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 41, 41, reg_idx2addr_map[41], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 42, 42, reg_idx2addr_map[42], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 43, 43, reg_idx2addr_map[43], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 44, 44, reg_idx2addr_map[44], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 45, 45, reg_idx2addr_map[45], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 46, 46, reg_idx2addr_map[46], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 47, 47, reg_idx2addr_map[47], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 48, 48, reg_idx2addr_map[48], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 49, 49, reg_idx2addr_map[49], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 50, 50, reg_idx2addr_map[50], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 51, 51, reg_idx2addr_map[51], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 52, 52, reg_idx2addr_map[52], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 53, 53, reg_idx2addr_map[53], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 54, 54, reg_idx2addr_map[54], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 55, 55, reg_idx2addr_map[55], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 56, 56, reg_idx2addr_map[56], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 57, 57, reg_idx2addr_map[57], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 58, 58, reg_idx2addr_map[58], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 59, 59, reg_idx2addr_map[59], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 60, 60, reg_idx2addr_map[60], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 61, 61, reg_idx2addr_map[61], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 62, 62, reg_idx2addr_map[62], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 63, 63, reg_idx2addr_map[63], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 64, 64, reg_idx2addr_map[64], *regs++); -#if RKV_H264E_ADD_RESERVE_REGS - regs += MPP_ARRAY_ELEMS(r->reserve_64_65); -#endif - - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 65, 65, reg_idx2addr_map[65], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 66, 66, reg_idx2addr_map[66], *regs++); -#if RKV_H264E_ADD_RESERVE_REGS - regs += MPP_ARRAY_ELEMS(r->reserve_66_67); -#endif - - for (k = 0; k < 8; k++) - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 67, 67, reg_idx2addr_map[67], *regs++); - for (k = 0; k < 8; k++) - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 68, 68, reg_idx2addr_map[68], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 69, 69, reg_idx2addr_map[69], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 70, 70, reg_idx2addr_map[70], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 71, 71, reg_idx2addr_map[71], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 72, 72, reg_idx2addr_map[72], *regs++); - - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 74, 73, reg_idx2addr_map[73], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 75, 74, reg_idx2addr_map[74], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 76, 75, reg_idx2addr_map[75], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 77, 76, reg_idx2addr_map[76], *regs++); -#if !RKV_H264E_REMOVE_UNNECESSARY_REGS - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 78, 77, reg_idx2addr_map[77], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 79, 78, reg_idx2addr_map[78], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 80, 79, reg_idx2addr_map[79], *regs++); -#if RKV_H264E_ADD_RESERVE_REGS - regs += MPP_ARRAY_ELEMS(r->reserve_79_80); -#endif - - for (k = 0; k < 256; k++) - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 73, 80, reg_idx2addr_map[80], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 81, 81, reg_idx2addr_map[81], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 82, 82, reg_idx2addr_map[82], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 83, 83, reg_idx2addr_map[83], *regs++); -#if RKV_H264E_ADD_RESERVE_REGS - regs += MPP_ARRAY_ELEMS(r->reserve_83_84); -#endif - - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 84, 84, reg_idx2addr_map[84], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 85, 85, reg_idx2addr_map[85], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 86, 86, reg_idx2addr_map[86], *regs++); -#if RKV_H264E_ADD_RESERVE_REGS - regs += MPP_ARRAY_ELEMS(r->reserve_86_87); -#endif - - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 87, 87, reg_idx2addr_map[87], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 88, 88, reg_idx2addr_map[88], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 89, 89, reg_idx2addr_map[89], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 90, 90, reg_idx2addr_map[90], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 91, 91, reg_idx2addr_map[91], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 92, 92, reg_idx2addr_map[92], *regs++); -#if RKV_H264E_ADD_RESERVE_REGS - regs += MPP_ARRAY_ELEMS(r->reserve_92_93); -#endif - - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 93, 93, reg_idx2addr_map[93], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 94, 94, reg_idx2addr_map[94], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 95, 95, reg_idx2addr_map[95], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 96, 96, reg_idx2addr_map[96], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 97, 97, reg_idx2addr_map[97], *regs++); - fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 98, 98, reg_idx2addr_map[98], *regs ); -#endif //#if !RKV_H264E_REMOVE_UNNECESSARY_REGS - - - fprintf(fp, "\n"); - fflush(fp); - } else { - h264e_hal_log_file("try to dump data to mpp_reg_in.txt, but file is not opened"); - } -#else - (void)ctx; -#endif -} - -static void hal_h264e_rkv_dump_mpp_extra_info_cfg(h264e_hal_context *ctx, h264e_control_extra_info_cfg *cfg) -{ -#if RKVENC_DUMP_INFO - h264e_hal_rkv_dump_files *dump_files = (h264e_hal_rkv_dump_files *)ctx->dump_files; - FILE *fp = dump_files->fp_mpp_extra_ino_cfg; - if (fp) { - /* common cfg */ - fprintf(fp, "%-16d %s\n", cfg->pic_luma_width, "pic_luma_width"); - fprintf(fp, "%-16d %s\n", cfg->pic_luma_height, "pic_luma_height"); - fprintf(fp, "%-16d %s\n", cfg->enable_cabac, "enable_cabac"); - fprintf(fp, "%-16d %s\n", cfg->transform8x8_mode, "transform8x8_mode"); - fprintf(fp, "%-16d %s\n", cfg->chroma_qp_index_offset, "chroma_qp_index_offset"); - fprintf(fp, "%-16d %s\n", cfg->pic_init_qp, "pic_init_qp"); - //RK_S32 rotation_enable; //0: 0/180 degrees, 1: 90/270 degrees //TODO: add rotation - - /* additional cfg only for rkv */ - fprintf(fp, "%-16d %s\n", cfg->input_image_format, "input_image_format"); - fprintf(fp, "%-16d %s\n", cfg->profile_idc, "profile_idc"); - fprintf(fp, "%-16d %s\n", cfg->level_idc, "level_idc"); //TODO: may be removed later, get from sps/pps instead - fprintf(fp, "%-16d %s\n", cfg->keyframe_max_interval, "keyframe_max_interval"); - fprintf(fp, "%-16d %s\n", cfg->second_chroma_qp_index_offset, "second_chroma_qp_index_offset"); - fprintf(fp, "%-16d %s\n", cfg->pps_id, "pps_id"); //TODO: may be removed later, get from sps/pps instead - - fprintf(fp, "\n"); - fflush(fp); - } -#else - (void)ctx; - (void)cfg; -#endif -} - -static void hal_h264e_rkv_dump_mpp_reg_out(h264e_hal_context *ctx) -{ -#if RKVENC_DUMP_INFO - RK_U32 k = 0; - h264e_hal_rkv_dump_files *dump_files = (h264e_hal_rkv_dump_files *)ctx->dump_files; - FILE *fp = dump_files->fp_mpp_reg_out; - h264e_rkv_ioctl_output *reg_out = (h264e_rkv_ioctl_output *)ctx->ioctl_output; - RK_U32 *p_reg = (RK_U32 *)reg_out + sizeof(reg_out->frame_num) / 4; - if (fp) { - fprintf(fp, "%d frames out\n", reg_out->frame_num); - for (k = 0; k < ctx->num_frames_to_send; k++) { - fprintf(fp, "#FRAME %d:\n", (ctx->frame_cnt - 1) - (ctx->num_frames_to_send - 1 - k)); - for (k = 0; k < 12; k++) { - fprintf(fp, "reg[%03d/%03x]: %08x\n", k, k * 4, p_reg[k]); - } - fprintf(fp, "\n"); - p_reg += sizeof(reg_out->elem[0]) / 4; - } - fflush(fp); - } else { - h264e_hal_log_file("try to dump data to mpp_reg_out.txt, but file is not opened"); - } -#else - (void)ctx; -#endif -} - -static void hal_h264e_rkv_dump_mpp_feedback(h264e_hal_context *ctx) -{ -#if RKVENC_DUMP_INFO - h264e_hal_rkv_dump_files *dump_files = (h264e_hal_rkv_dump_files *)ctx->dump_files; - FILE *fp = dump_files->fp_mpp_feedback; - if (fp) { - h264e_feedback *fb = &ctx->feedback; - (void)fb; - } else { - h264e_hal_log_file("try to dump data to mpp_feedback.txt, but file is not opened"); - } -#else - (void)ctx; -#endif -} - -static void hal_h264e_rkv_dump_mpp_strm_out_header(h264e_hal_context *ctx, MppPacket packet) -{ -#if RKVENC_DUMP_INFO - h264e_hal_rkv_dump_files *dump_files = (h264e_hal_rkv_dump_files *)ctx->dump_files; - void *ptr = mpp_packet_get_data(packet); - size_t len = mpp_packet_get_length(packet); - FILE *fp = dump_files->fp_mpp_strm_out; - - if (fp) { - fwrite(ptr, 1, len, fp); - fflush(fp); - } else { - h264e_hal_log_file("try to dump strm header to mpp_strm_out.txt, but file is not opened"); - } -#else - (void)ctx; - (void)packet; -#endif -} - - + +#define RKVENC_FRAME_TYPE_AUTO 0x0000 /* Let x264 choose the right type */ +#define RKVENC_FRAME_TYPE_IDR 0x0001 +#define RKVENC_FRAME_TYPE_I 0x0002 +#define RKVENC_FRAME_TYPE_P 0x0003 +#define RKVENC_FRAME_TYPE_BREF 0x0004 /* Non-disposable B-frame */ +#define RKVENC_FRAME_TYPE_B 0x0005 +#define RKVENC_FRAME_TYPE_KEYFRAME 0x0006 /* IDR or I depending on b_open_gop option */ +#define RKVENC_IS_TYPE_I(x) ((x)==RKVENC_FRAME_TYPE_I || (x)==RKVENC_FRAME_TYPE_IDR) +#define RKVENC_IS_TYPE_B(x) ((x)==RKVENC_FRAME_TYPE_B || (x)==RKVENC_FRAME_TYPE_BREF) +#define RKVENC_IS_DISPOSABLE(type) ( type == RKVENC_FRAME_TYPE_B ) + +const RK_S32 h264e_csp_idx_map[H264E_RKV_CSP_BUTT] = {RKV_H264E_CSP2_BGRA, RKV_H264E_CSP2_BGR, RKV_H264E_CSP2_RGB, 0, RKV_H264E_CSP2_NV16, RKV_H264E_CSP2_I422, RKV_H264E_CSP2_NV12, + RKV_H264E_CSP2_I420, RKV_H264E_CSP2_RGB, RKV_H264E_CSP2_RGB + }; + +static const RK_U32 h264e_h3d_tbl[40] = { + 0x0b080400, 0x1815120f, 0x23201e1b, 0x2c2a2725, + 0x33312f2d, 0x38373634, 0x3d3c3b39, 0x403f3e3d, + 0x42414140, 0x43434342, 0x44444444, 0x44444444, + 0x44444444, 0x43434344, 0x42424343, 0x40414142, + 0x3d3e3f40, 0x393a3b3c, 0x35363738, 0x30313334, + 0x2c2d2e2f, 0x28292a2b, 0x23242526, 0x20202122, + 0x191b1d1f, 0x14151618, 0x0f101112, 0x0b0c0d0e, + 0x08090a0a, 0x06070708, 0x05050506, 0x03040404, + 0x02020303, 0x01010102, 0x00010101, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000 +}; + +static const RK_U8 h264e_ue_size_tab[256] = { + 1, 1, 3, 3, 5, 5, 5, 5, 7, 7, 7, 7, 7, 7, 7, 7, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +}; + +/* default quant matrices */ +static const RK_U8 h264e_rkv_cqm_jvt4i[16] = { + 6, 13, 20, 28, + 13, 20, 28, 32, + 20, 28, 32, 37, + 28, 32, 37, 42 +}; +static const RK_U8 h264e_rkv_cqm_jvt4p[16] = { + 10, 14, 20, 24, + 14, 20, 24, 27, + 20, 24, 27, 30, + 24, 27, 30, 34 +}; +static const RK_U8 h264e_rkv_cqm_jvt8i[64] = { + 6, 10, 13, 16, 18, 23, 25, 27, + 10, 11, 16, 18, 23, 25, 27, 29, + 13, 16, 18, 23, 25, 27, 29, 31, + 16, 18, 23, 25, 27, 29, 31, 33, + 18, 23, 25, 27, 29, 31, 33, 36, + 23, 25, 27, 29, 31, 33, 36, 38, + 25, 27, 29, 31, 33, 36, 38, 40, + 27, 29, 31, 33, 36, 38, 40, 42 +}; +static const RK_U8 h264e_rkv_cqm_jvt8p[64] = { + 9, 13, 15, 17, 19, 21, 22, 24, + 13, 13, 17, 19, 21, 22, 24, 25, + 15, 17, 19, 21, 22, 24, 25, 27, + 17, 19, 21, 22, 24, 25, 27, 28, + 19, 21, 22, 24, 25, 27, 28, 30, + 21, 22, 24, 25, 27, 28, 30, 32, + 22, 24, 25, 27, 28, 30, 32, 33, + 24, 25, 27, 28, 30, 32, 33, 35 +}; + +static const RK_U8 h264e_rkv_cqm_flat16[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 const RK_U8 * const h264e_rkv_cqm_jvt[8] = { + h264e_rkv_cqm_jvt4i, h264e_rkv_cqm_jvt4p, + h264e_rkv_cqm_jvt4i, h264e_rkv_cqm_jvt4p, + h264e_rkv_cqm_jvt8i, h264e_rkv_cqm_jvt8p, + h264e_rkv_cqm_jvt8i, h264e_rkv_cqm_jvt8p +}; + +/* zigzags are transposed with respect to the tables in the standard */ +static const RK_U8 h264e_rkv_zigzag_scan4[2][16] = { + { + // frame + 0, 4, 1, 2, 5, 8, 12, 9, 6, 3, 7, 10, 13, 14, 11, 15 + }, + { + // field + 0, 1, 4, 2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 + } +}; +static const RK_U8 h264e_rkv_zigzag_scan8[2][64] = { + { + 0, 8, 1, 2, 9, 16, 24, 17, 10, 3, 4, 11, 18, 25, 32, 40, + 33, 26, 19, 12, 5, 6, 13, 20, 27, 34, 41, 48, 56, 49, 42, 35, + 28, 21, 14, 7, 15, 22, 29, 36, 43, 50, 57, 58, 51, 44, 37, 30, + 23, 31, 38, 45, 52, 59, 60, 53, 46, 39, 47, 54, 61, 62, 55, 63 + }, + { + 0, 1, 2, 8, 9, 3, 4, 10, 16, 11, 5, 6, 7, 12, 17, 24, + 18, 13, 14, 15, 19, 25, 32, 26, 20, 21, 22, 23, 27, 33, 40, 34, + 28, 29, 30, 31, 35, 41, 48, 42, 36, 37, 38, 39, 43, 49, 50, 44, + 45, 46, 47, 51, 56, 57, 52, 53, 54, 55, 58, 59, 60, 61, 62, 63 + } +}; + +#if RKVENC_DUMP_INFO +static RK_U32 reg_idx2addr_map[132] = { + 0xffff, //0, unvalid. + 0x0000, //1 + 0x0004, //2 + 0x0008, //3 + 0x000c, //4 + 0x0010, //5 + 0x0014, //6 + 0x0018, //7 + 0x001C, //8 + 0x0030, //9 + 0x0034, //10 + 0x0038, //11 + 0x003c, //12 + 0x0040, //13 + 0x0044, //14 + 0x0048, //15 + 0x004c, //16 + 0x0050, //17 + 0x0054, //18 + 0x0058, //19 + 0x005c, //20 + 0x0060, //21.0~21.4 + 0x0074, //22.0~22.39 + 0x0114, //23 + 0x0118, //24 + 0x011c, //25 + 0x0120, //26 + 0x0124, //27 + 0x0128, //28 + 0x012c, //29 + 0x0130, //30 + 0x0134, //31 + 0x0138, //32 + 0x013c, //33 + 0x0140, //34 + 0x0144, //35 + 0x0148, //36 + 0x014c, //36 + 0x0150, //38 + 0x0154, //39 + 0x0158, //40 + 0x015c, //41 + 0x0160, //42 + 0x0164, //43 + 0x0168, //44 + 0x016c, //45 + 0x0170, //46 + 0x0174, //47 + 0x0178, //48 + 0x017c, //49 + 0x0180, //50 + 0x0184, //51 + 0x0188, //52 + 0x018c, //53 + 0x0190, //54 + 0x0194, //55 + 0x0198, //56 + 0x019c, //57 + 0x01a0, //58 + 0x01a4, //59 + 0x01a8, //60 + 0x01ac, //61 + 0x01b0, //62 + 0x01b4, //63 + 0x01b8, //64 + 0x01c0, //65 + 0x01c4, //66 + 0x01d0, //67.0~67.7 + 0x01f0, //68.0~68.7 + 0x0210, //69 + 0x0214, //70 + 0x0218, //71 + 0x021c, //72 + 0x0220, //73 + 0x0224, //74 + 0x0228, //75 + 0x022c, //76 + 0x0230, //77 + 0x0234, //78 + 0x0238, //79 + 0x0400, //80.0~80.255 + 0x0800, //81 + 0x0804, //82 + 0x0808, //83 + 0x0810, //84 + 0x0814, //85 + 0x0818, //86 + 0x0820, //87 + 0x0824, //88 + 0x0828, //89 + 0x082c, //90 + 0x0830, //91 + 0x0834, //92 + 0x0840, //93 + 0x0844, //94 + 0x0848, //95 + 0x084c, //96 + 0x0850, //97 + 0x0854, //98 + 0x0860, //99( 33 regs below are not present in c-model, included) + 0x0864, //100 + 0x0868, //101 + 0x086c, //102 + 0x0870, //103 + 0x0874, //104 + 0x0880, //105 + 0x0884, //106 + 0x0888, //107 + 0x088c, //108 + 0x0890, //109 + 0x0894, //110 + 0x0898, //111 + 0x089c, //112 + 0x08a0, //113 + 0x08a4, //114 + 0x08a8, //115 + 0x08ac, //116 + 0x08b0, //117 + 0x08b4, //118 + 0x08b8, //119 + 0x08bc, //120 + 0x08c0, //121 + 0x08c4, //122 + 0x08c8, //123 + 0x08cc, //124 + 0x08d0, //125 + 0x08d4, //126 + 0x08d8, //127 + 0x08dc, //128 + 0x08e0, //129 + 0x08e4, //130 + 0x08e8, //131 +}; +#endif + +static h264e_hal_rkv_csp_info hal_h264e_rkv_convert_csp(RK_S32 src_type) +{ + MppFrameFormat src_fmt = (MppFrameFormat)src_type; + h264e_hal_rkv_csp_info dst_info; + switch (src_fmt) { + case MPP_FMT_YUV420P: { + dst_info.fmt = (RK_U32)H264E_RKV_CSP_YUV420P; + dst_info.cswap = 0; + dst_info.aswap = 0; + break; + } + case MPP_FMT_YUV420SP: { + dst_info.fmt = (RK_U32)H264E_RKV_CSP_YUV420SP; + dst_info.cswap = 0; + dst_info.aswap = 0; + break; + } + case MPP_FMT_YUV420SP_10BIT: { + dst_info.fmt = (RK_U32)H264E_RKV_CSP_NONE; + dst_info.cswap = 0; + dst_info.aswap = 0; + break; + } + case MPP_FMT_YUV420SP_VU: { //TODO: to be confirmed + dst_info.fmt = (RK_U32)H264E_RKV_CSP_YUV420SP; + dst_info.cswap = 1; + dst_info.aswap = 0; + break; + } + case MPP_FMT_YUV422P: { + dst_info.fmt = (RK_U32)H264E_RKV_CSP_YUV422P; + dst_info.cswap = 0; + dst_info.aswap = 0; + break; + } + case MPP_FMT_YUV422SP: { + dst_info.fmt = (RK_U32)H264E_RKV_CSP_YUV422SP; + dst_info.cswap = 0; + dst_info.aswap = 0; + break; + } + case MPP_FMT_YUV422SP_10BIT: { + dst_info.fmt = (RK_U32)H264E_RKV_CSP_NONE; + dst_info.cswap = 0; + dst_info.aswap = 0; + break; + } + case MPP_FMT_YUV422SP_VU: { + dst_info.fmt = (RK_U32)H264E_RKV_CSP_YUV422SP; + dst_info.cswap = 1; + dst_info.aswap = 0; + break; + } + case MPP_FMT_YUV422_YUYV: { + dst_info.fmt = (RK_U32)H264E_RKV_CSP_YUYV422; + dst_info.cswap = 0; + dst_info.aswap = 0; + break; + } + case MPP_FMT_YUV422_UYVY: { + dst_info.fmt = (RK_U32)H264E_RKV_CSP_UYVY422; + dst_info.cswap = 0; + dst_info.aswap = 0; + break; + } + case MPP_FMT_RGB565: { + dst_info.fmt = (RK_U32)H264E_RKV_CSP_BGR565; + dst_info.cswap = 1; + dst_info.aswap = 0; + break; + } + case MPP_FMT_BGR565: { + dst_info.fmt = (RK_U32)H264E_RKV_CSP_BGR565; + dst_info.cswap = 0; + dst_info.aswap = 0; + break; + } + case MPP_FMT_RGB555: { + dst_info.fmt = (RK_U32)H264E_RKV_CSP_NONE; + dst_info.cswap = 0; + dst_info.aswap = 0; + break; + } + case MPP_FMT_BGR555: { + dst_info.fmt = (RK_U32)H264E_RKV_CSP_NONE; + dst_info.cswap = 0; + dst_info.aswap = 0; + break; + } + case MPP_FMT_RGB444: { + dst_info.fmt = (RK_U32)H264E_RKV_CSP_NONE; + dst_info.cswap = 0; + dst_info.aswap = 0; + break; + } + case MPP_FMT_BGR444: { + dst_info.fmt = (RK_U32)H264E_RKV_CSP_NONE; + dst_info.cswap = 0; + dst_info.aswap = 0; + break; + } + case MPP_FMT_RGB888: { + dst_info.fmt = (RK_U32)H264E_RKV_CSP_BGR888; + dst_info.cswap = 1; + dst_info.aswap = 0; + break; + } + case MPP_FMT_BGR888: { + dst_info.fmt = (RK_U32)H264E_RKV_CSP_BGR888; + dst_info.cswap = 0; + dst_info.aswap = 0; + break; + } + case MPP_FMT_RGB101010: { + dst_info.fmt = (RK_U32)H264E_RKV_CSP_NONE; + dst_info.cswap = 0; + dst_info.aswap = 0; + break; + } + case MPP_FMT_BGR101010: { + dst_info.fmt = (RK_U32)H264E_RKV_CSP_NONE; + dst_info.cswap = 0; + dst_info.aswap = 0; + break; + } + case MPP_FMT_ARGB8888: { + dst_info.fmt = (RK_U32)H264E_RKV_CSP_BGRA8888; + dst_info.cswap = 1; + dst_info.aswap = 1; + break; + } + case MPP_FMT_ABGR8888: { + dst_info.fmt = (RK_U32)H264E_RKV_CSP_BGRA8888; + dst_info.cswap = 0; + dst_info.aswap = 1; + break; + } + default: { + h264e_hal_log_err("unvalid src color space: %d", src_type); + dst_info.fmt = (RK_U32)H264E_RKV_CSP_NONE; + dst_info.cswap = 0; + dst_info.aswap = 0; + } + } + + return dst_info; +} + + + +static MPP_RET hal_h264e_rkv_close_dump_files(void *dump_files) +{ + h264e_hal_rkv_dump_files *files = (h264e_hal_rkv_dump_files *)dump_files; + H264E_HAL_FCLOSE(files->fp_mpp_syntax_in); + H264E_HAL_FCLOSE(files->fp_mpp_reg_in); + H264E_HAL_FCLOSE(files->fp_mpp_reg_out); + H264E_HAL_FCLOSE(files->fp_mpp_strm_out); + H264E_HAL_FCLOSE(files->fp_mpp_feedback); + H264E_HAL_FCLOSE(files->fp_mpp_extra_ino_cfg); + return MPP_OK; +} + + +static MPP_RET hal_h264e_rkv_open_dump_files(void *dump_files) +{ + if (h264e_hal_log_mode & H264E_HAL_LOG_FILE) { + char base_path[512]; + char full_path[512]; + h264e_hal_rkv_dump_files *files = (h264e_hal_rkv_dump_files *)dump_files; + strcpy(base_path, "/tmp/"); + + sprintf(full_path, "%s%s", base_path, "mpp_syntax_in.txt"); + files->fp_mpp_syntax_in = fopen(full_path, "wb"); + if (!files->fp_mpp_syntax_in) { + h264e_hal_log_err("%s open error", full_path); + return MPP_ERR_OPEN_FILE; + } + + + sprintf(full_path, "%s%s", base_path, "mpp_reg_in.txt"); + files->fp_mpp_reg_in = fopen(full_path, "wb"); + if (!files->fp_mpp_reg_in) { + h264e_hal_log_err("%s open error", full_path); + return MPP_ERR_OPEN_FILE; + } + + sprintf(full_path, "%s%s", base_path, "mpp_reg_out.txt"); + files->fp_mpp_reg_out = fopen(full_path, "wb"); + if (!files->fp_mpp_reg_out) { + h264e_hal_log_err("%s open error", full_path); + return MPP_ERR_OPEN_FILE; + } + + sprintf(full_path, "%s%s", base_path, "mpp_feedback.txt"); + files->fp_mpp_feedback = fopen(full_path, "wb"); + if (!files->fp_mpp_feedback) { + h264e_hal_log_err("%s open error", full_path); + return MPP_ERR_OPEN_FILE; + } + + sprintf(full_path, "%s%s", base_path, "mpp_strm_out.bin"); + files->fp_mpp_strm_out = fopen(full_path, "wb"); + if (!files->fp_mpp_strm_out) { + h264e_hal_log_err("%s open error", full_path); + return MPP_ERR_OPEN_FILE; + } + + sprintf(full_path, "%s%s", base_path, "mpp_extra_info_cfg.txt"); + files->fp_mpp_extra_ino_cfg = fopen(full_path, "wb"); + if (!files->fp_mpp_extra_ino_cfg) { + h264e_hal_log_err("%s open error", full_path); + return MPP_ERR_OPEN_FILE; + } + } + return MPP_OK; +} + +static void hal_h264e_rkv_dump_mpp_syntax_in(h264e_syntax *syn, h264e_hal_context *ctx) +{ +#if RKVENC_DUMP_INFO + h264e_hal_rkv_dump_files *dump_files = (h264e_hal_rkv_dump_files *)ctx->dump_files; + FILE *fp = dump_files->fp_mpp_syntax_in; + if (fp) { + //RK_S32 k = 0; + fprintf(fp, "#FRAME %d\n", ctx->frame_cnt); + + fprintf(fp, "%-16d %s\n", syn->pic_luma_width, "pic_luma_width"); + fprintf(fp, "%-16d %s\n", syn->pic_luma_height, "pic_luma_height"); + fprintf(fp, "%-16d %s\n", syn->level_idc, "level_idc"); + fprintf(fp, "%-16d %s\n", syn->profile_idc, "profile_idc"); + fprintf(fp, "%-16d %s\n", syn->frame_coding_type, "frame_coding_type"); + fprintf(fp, "%-16d %s\n", syn->qp, "swreg10.pic_qp"); + fprintf(fp, "%-16d %s\n", syn->input_image_format, "swreg14.src_cfmt"); + + fprintf(fp, "%-16d %s\n", syn->enable_cabac, "swreg59.etpy_mode"); + fprintf(fp, "%-16d %s\n", syn->pic_init_qp, "swreg59.pic_init_qp"); + fprintf(fp, "%-16d %s\n", syn->chroma_qp_index_offset, "swreg59.cb_ofst"); + fprintf(fp, "%-16d %s\n", syn->second_chroma_qp_index_offset, "swreg59.cr_ofst"); + + fprintf(fp, "%-16d %s\n", syn->slice_type, "swreg60.sli_type"); + fprintf(fp, "%-16d %s\n", syn->pps_id, "swreg60.pps_id"); + fprintf(fp, "%-16d %s\n", syn->frame_num, "swreg60.frm_num"); + fprintf(fp, "%-16d %s\n", syn->cabac_init_idc, "swreg60.cbc_init_idc"); + + fprintf(fp, "%-16d %s\n", syn->idr_pic_id, "swreg61.idr_pid"); + fprintf(fp, "%-16d %s\n", syn->pic_order_cnt_lsb, "swreg61.poc_lsb"); + + fprintf(fp, "%-16d %s\n", syn->keyframe_max_interval, "keyframe_max_interval"); + + fprintf(fp, "\n"); + fflush(fp); + } else { + h264e_hal_log_file("try to dump data to mpp_syntax_in.txt, but file is not opened"); + } +#else + (void)ctx; + (void)syn; +#endif +} + +static void hal_h264e_rkv_dump_mpp_reg_in(h264e_hal_context *ctx) +{ +#if RKVENC_DUMP_INFO + RK_S32 k = 0; + h264e_hal_rkv_dump_files *dump_files = (h264e_hal_rkv_dump_files *)ctx->dump_files; + FILE *fp = dump_files->fp_mpp_reg_in; + h264e_rkv_reg_set *reg_list = (h264e_rkv_reg_set *)ctx->regs; + RK_U32 *regs = (RK_U32 *)®_list[ctx->frame_cnt_gen_ready]; + +#if RKV_H264E_ADD_RESERVE_REGS + h264e_rkv_reg_set * r = (h264e_rkv_reg_set *)regs; +#endif + h264e_hal_log_file("dump_rkv_mpp_reg_in enter, %d regs are dumped", RK_H264E_NUM_REGS); + if (fp) { + fprintf(fp, "#FRAME %d:\n", ctx->frame_cnt); + + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 1, 1, reg_idx2addr_map[ 1], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 2, 2, reg_idx2addr_map[ 2], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 3, 3, reg_idx2addr_map[ 3], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 4, 4, reg_idx2addr_map[ 4], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 5, 5, reg_idx2addr_map[ 5], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 6, 6, reg_idx2addr_map[ 6], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 7, 7, reg_idx2addr_map[ 7], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 8, 8, reg_idx2addr_map[ 8], *regs++); +#if RKV_H264E_ADD_RESERVE_REGS + regs += MPP_ARRAY_ELEMS(r->reserve_08_09); +#endif + + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 9, 9, reg_idx2addr_map[ 9], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 10, 10, reg_idx2addr_map[10], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 11, 11, reg_idx2addr_map[11], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 12, 12, reg_idx2addr_map[12], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 13, 13, reg_idx2addr_map[13], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 14, 14, reg_idx2addr_map[14], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 15, 15, reg_idx2addr_map[15], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 16, 16, reg_idx2addr_map[16], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 17, 17, reg_idx2addr_map[17], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 18, 18, reg_idx2addr_map[18], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 19, 19, reg_idx2addr_map[19], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 20, 20, reg_idx2addr_map[20], *regs++); + for (k = 0; k < 5; k++) + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 21, 21, reg_idx2addr_map[21], *regs++); + for (k = 0; k < 40; k++) + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 22, 22, reg_idx2addr_map[22], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 23, 23, reg_idx2addr_map[23], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 24, 24, reg_idx2addr_map[24], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 25, 25, reg_idx2addr_map[25], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 26, 26, reg_idx2addr_map[26], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 27, 27, reg_idx2addr_map[27], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 28, 28, reg_idx2addr_map[28], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 29, 29, reg_idx2addr_map[29], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 30, 30, reg_idx2addr_map[30], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 31, 31, reg_idx2addr_map[31], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 32, 32, reg_idx2addr_map[32], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 33, 33, reg_idx2addr_map[33], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 34, 34, reg_idx2addr_map[34], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 35, 35, reg_idx2addr_map[35], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 36, 36, reg_idx2addr_map[36], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 37, 37, reg_idx2addr_map[37], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 38, 38, reg_idx2addr_map[38], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 39, 39, reg_idx2addr_map[39], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 40, 40, reg_idx2addr_map[40], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 41, 41, reg_idx2addr_map[41], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 42, 42, reg_idx2addr_map[42], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 43, 43, reg_idx2addr_map[43], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 44, 44, reg_idx2addr_map[44], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 45, 45, reg_idx2addr_map[45], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 46, 46, reg_idx2addr_map[46], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 47, 47, reg_idx2addr_map[47], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 48, 48, reg_idx2addr_map[48], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 49, 49, reg_idx2addr_map[49], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 50, 50, reg_idx2addr_map[50], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 51, 51, reg_idx2addr_map[51], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 52, 52, reg_idx2addr_map[52], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 53, 53, reg_idx2addr_map[53], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 54, 54, reg_idx2addr_map[54], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 55, 55, reg_idx2addr_map[55], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 56, 56, reg_idx2addr_map[56], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 57, 57, reg_idx2addr_map[57], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 58, 58, reg_idx2addr_map[58], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 59, 59, reg_idx2addr_map[59], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 60, 60, reg_idx2addr_map[60], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 61, 61, reg_idx2addr_map[61], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 62, 62, reg_idx2addr_map[62], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 63, 63, reg_idx2addr_map[63], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 64, 64, reg_idx2addr_map[64], *regs++); +#if RKV_H264E_ADD_RESERVE_REGS + regs += MPP_ARRAY_ELEMS(r->reserve_64_65); +#endif + + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 65, 65, reg_idx2addr_map[65], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 66, 66, reg_idx2addr_map[66], *regs++); +#if RKV_H264E_ADD_RESERVE_REGS + regs += MPP_ARRAY_ELEMS(r->reserve_66_67); +#endif + + for (k = 0; k < 8; k++) + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 67, 67, reg_idx2addr_map[67], *regs++); + for (k = 0; k < 8; k++) + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 68, 68, reg_idx2addr_map[68], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 69, 69, reg_idx2addr_map[69], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 70, 70, reg_idx2addr_map[70], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 71, 71, reg_idx2addr_map[71], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 72, 72, reg_idx2addr_map[72], *regs++); + + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 74, 73, reg_idx2addr_map[73], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 75, 74, reg_idx2addr_map[74], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 76, 75, reg_idx2addr_map[75], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 77, 76, reg_idx2addr_map[76], *regs++); +#if !RKV_H264E_REMOVE_UNNECESSARY_REGS + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 78, 77, reg_idx2addr_map[77], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 79, 78, reg_idx2addr_map[78], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 80, 79, reg_idx2addr_map[79], *regs++); +#if RKV_H264E_ADD_RESERVE_REGS + regs += MPP_ARRAY_ELEMS(r->reserve_79_80); +#endif + + for (k = 0; k < 256; k++) + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 73, 80, reg_idx2addr_map[80], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 81, 81, reg_idx2addr_map[81], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 82, 82, reg_idx2addr_map[82], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 83, 83, reg_idx2addr_map[83], *regs++); +#if RKV_H264E_ADD_RESERVE_REGS + regs += MPP_ARRAY_ELEMS(r->reserve_83_84); +#endif + + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 84, 84, reg_idx2addr_map[84], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 85, 85, reg_idx2addr_map[85], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 86, 86, reg_idx2addr_map[86], *regs++); +#if RKV_H264E_ADD_RESERVE_REGS + regs += MPP_ARRAY_ELEMS(r->reserve_86_87); +#endif + + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 87, 87, reg_idx2addr_map[87], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 88, 88, reg_idx2addr_map[88], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 89, 89, reg_idx2addr_map[89], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 90, 90, reg_idx2addr_map[90], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 91, 91, reg_idx2addr_map[91], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 92, 92, reg_idx2addr_map[92], *regs++); +#if RKV_H264E_ADD_RESERVE_REGS + regs += MPP_ARRAY_ELEMS(r->reserve_92_93); +#endif + + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 93, 93, reg_idx2addr_map[93], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 94, 94, reg_idx2addr_map[94], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 95, 95, reg_idx2addr_map[95], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 96, 96, reg_idx2addr_map[96], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 97, 97, reg_idx2addr_map[97], *regs++); + fprintf(fp, "reg[%03d/%03d/%04x]: %08x\n", 98, 98, reg_idx2addr_map[98], *regs ); +#endif //#if !RKV_H264E_REMOVE_UNNECESSARY_REGS + + + fprintf(fp, "\n"); + fflush(fp); + } else { + h264e_hal_log_file("try to dump data to mpp_reg_in.txt, but file is not opened"); + } +#else + (void)ctx; +#endif +} + +static void hal_h264e_rkv_dump_mpp_extra_info_cfg(h264e_hal_context *ctx, h264e_control_extra_info_cfg *cfg) +{ +#if RKVENC_DUMP_INFO + h264e_hal_rkv_dump_files *dump_files = (h264e_hal_rkv_dump_files *)ctx->dump_files; + FILE *fp = dump_files->fp_mpp_extra_ino_cfg; + if (fp) { + /* common cfg */ + fprintf(fp, "%-16d %s\n", cfg->pic_luma_width, "pic_luma_width"); + fprintf(fp, "%-16d %s\n", cfg->pic_luma_height, "pic_luma_height"); + fprintf(fp, "%-16d %s\n", cfg->enable_cabac, "enable_cabac"); + fprintf(fp, "%-16d %s\n", cfg->transform8x8_mode, "transform8x8_mode"); + fprintf(fp, "%-16d %s\n", cfg->chroma_qp_index_offset, "chroma_qp_index_offset"); + fprintf(fp, "%-16d %s\n", cfg->pic_init_qp, "pic_init_qp"); + //RK_S32 rotation_enable; //0: 0/180 degrees, 1: 90/270 degrees //TODO: add rotation + + /* additional cfg only for rkv */ + fprintf(fp, "%-16d %s\n", cfg->input_image_format, "input_image_format"); + fprintf(fp, "%-16d %s\n", cfg->profile_idc, "profile_idc"); + fprintf(fp, "%-16d %s\n", cfg->level_idc, "level_idc"); //TODO: may be removed later, get from sps/pps instead + fprintf(fp, "%-16d %s\n", cfg->keyframe_max_interval, "keyframe_max_interval"); + fprintf(fp, "%-16d %s\n", cfg->second_chroma_qp_index_offset, "second_chroma_qp_index_offset"); + fprintf(fp, "%-16d %s\n", cfg->pps_id, "pps_id"); //TODO: may be removed later, get from sps/pps instead + + fprintf(fp, "\n"); + fflush(fp); + } +#else + (void)ctx; + (void)cfg; +#endif +} + +static void hal_h264e_rkv_dump_mpp_reg_out(h264e_hal_context *ctx) +{ +#if RKVENC_DUMP_INFO + RK_U32 k = 0; + h264e_hal_rkv_dump_files *dump_files = (h264e_hal_rkv_dump_files *)ctx->dump_files; + FILE *fp = dump_files->fp_mpp_reg_out; + h264e_rkv_ioctl_output *reg_out = (h264e_rkv_ioctl_output *)ctx->ioctl_output; + RK_U32 *p_reg = (RK_U32 *)reg_out + sizeof(reg_out->frame_num) / 4; + if (fp) { + fprintf(fp, "%d frames out\n", reg_out->frame_num); + for (k = 0; k < ctx->num_frames_to_send; k++) { + fprintf(fp, "#FRAME %d:\n", (ctx->frame_cnt - 1) - (ctx->num_frames_to_send - 1 - k)); + for (k = 0; k < 12; k++) { + fprintf(fp, "reg[%03d/%03x]: %08x\n", k, k * 4, p_reg[k]); + } + fprintf(fp, "\n"); + p_reg += sizeof(reg_out->elem[0]) / 4; + } + fflush(fp); + } else { + h264e_hal_log_file("try to dump data to mpp_reg_out.txt, but file is not opened"); + } +#else + (void)ctx; +#endif +} + +static void hal_h264e_rkv_dump_mpp_feedback(h264e_hal_context *ctx) +{ +#if RKVENC_DUMP_INFO + h264e_hal_rkv_dump_files *dump_files = (h264e_hal_rkv_dump_files *)ctx->dump_files; + FILE *fp = dump_files->fp_mpp_feedback; + if (fp) { + h264e_feedback *fb = &ctx->feedback; + (void)fb; + } else { + h264e_hal_log_file("try to dump data to mpp_feedback.txt, but file is not opened"); + } +#else + (void)ctx; +#endif +} + +static void hal_h264e_rkv_dump_mpp_strm_out_header(h264e_hal_context *ctx, MppPacket packet) +{ +#if RKVENC_DUMP_INFO + h264e_hal_rkv_dump_files *dump_files = (h264e_hal_rkv_dump_files *)ctx->dump_files; + void *ptr = mpp_packet_get_data(packet); + size_t len = mpp_packet_get_length(packet); + FILE *fp = dump_files->fp_mpp_strm_out; + + if (fp) { + fwrite(ptr, 1, len, fp); + fflush(fp); + } else { + h264e_hal_log_file("try to dump strm header to mpp_strm_out.txt, but file is not opened"); + } +#else + (void)ctx; + (void)packet; +#endif +} + + void hal_h264e_rkv_dump_mpp_strm_out(h264e_hal_context *ctx, MppBuffer hw_buf) -{ -#if RKVENC_DUMP_INFO - h264e_hal_rkv_dump_files *dump_files = (h264e_hal_rkv_dump_files *)ctx->dump_files; - FILE *fp = dump_files->fp_mpp_strm_out; - if (fp) { - RK_U32 k = 0; - RK_U32 strm_size = 0; - RK_U8 *sw_buf = NULL; - RK_U8 *hw_buf_vir_addr = NULL; - h264e_rkv_ioctl_output *ioctl_output = (h264e_rkv_ioctl_output *)ctx->ioctl_output; - h264e_rkv_ioctl_output_elem *out_elem = ioctl_output->elem; - RK_U32 frame_num = ioctl_output->frame_num; - +{ +#if RKVENC_DUMP_INFO + h264e_hal_rkv_dump_files *dump_files = (h264e_hal_rkv_dump_files *)ctx->dump_files; + FILE *fp = dump_files->fp_mpp_strm_out; + if (fp) { + RK_U32 k = 0; + RK_U32 strm_size = 0; + RK_U8 *sw_buf = NULL; + RK_U8 *hw_buf_vir_addr = NULL; + h264e_rkv_ioctl_output *ioctl_output = (h264e_rkv_ioctl_output *)ctx->ioctl_output; + h264e_rkv_ioctl_output_elem *out_elem = ioctl_output->elem; + RK_U32 frame_num = ioctl_output->frame_num; + h264e_hal_log_file("dump %d frames strm out below", frame_num); - for (k = 0; k < frame_num; k++) { - strm_size = (RK_U32)out_elem[k].swreg69.bs_lgth; + for (k = 0; k < frame_num; k++) { + strm_size = (RK_U32)out_elem[k].swreg69.bs_lgth; hw_buf_vir_addr = (RK_U8 *)mpp_buffer_get_ptr(hw_buf); - sw_buf = mpp_malloc(RK_U8, strm_size); - + sw_buf = mpp_malloc(RK_U8, strm_size); + h264e_hal_log_file("dump frame %d, fd %d, strm_size: %d", k, mpp_buffer_get_fd(hw_buf), strm_size); - - memcpy(sw_buf, hw_buf_vir_addr, strm_size); - - fwrite(sw_buf, 1, strm_size, fp); - - if (sw_buf) - mpp_free(sw_buf); - } - fflush(fp); - } else { - h264e_hal_log_file("try to dump data to mpp_strm_out.txt, but file is not opened"); - } -#else - (void)ctx; - (void)hw_buf; -#endif -} - -void hal_h264e_rkv_frame_push( h264e_hal_rkv_frame **list, h264e_hal_rkv_frame *frame ) -{ - RK_S32 i = 0; - while ( list[i] ) i++; - list[i] = frame; - h264e_hal_log_dpb("frame push list[%d] %p", i, frame); - -} - -static h264e_hal_rkv_frame *hal_h264e_rkv_frame_new(h264e_hal_rkv_dpb_ctx *dpb_ctx) -{ - RK_S32 k = 0; - h264e_hal_rkv_frame *frame_buf = dpb_ctx->frame_buf; - RK_S32 num_buf = MPP_ARRAY_ELEMS(dpb_ctx->frame_buf); - h264e_hal_rkv_frame *new_frame = NULL; - h264e_hal_debug_enter(); - for (k = 0; k < num_buf; k++) { - if (!frame_buf[k].hw_buf_used) { - new_frame = &frame_buf[k]; - frame_buf[k].hw_buf_used = 1; - break; - } - } - - if (!new_frame) { - h264e_hal_log_err("!new_frame, new_frame get failed"); - return NULL; - } - - h264e_hal_debug_leave(); - return new_frame; -} - -h264e_hal_rkv_frame *hal_h264e_rkv_frame_pop( h264e_hal_rkv_frame **list ) -{ - h264e_hal_rkv_frame *frame; - RK_S32 i = 0; - mpp_assert( list[0] ); - while ( list[i + 1] ) i++; - frame = list[i]; - list[i] = NULL; - h264e_hal_log_dpb("frame pop list[%d] %p", i, frame); - return frame; -} - -void hal_h264e_rkv_frame_unshift( h264e_hal_rkv_frame **list, h264e_hal_rkv_frame *frame ) -{ - RK_S32 i = 0; - while ( list[i] ) i++; - while ( i-- ) - list[i + 1] = list[i]; - list[0] = frame; - h264e_hal_log_dpb("frame unshift list[0] %p", frame); -} - -h264e_hal_rkv_frame *hal_h264e_rkv_frame_shift( h264e_hal_rkv_frame **list ) -{ - h264e_hal_rkv_frame *frame = list[0]; - RK_S32 i; - for ( i = 0; list[i]; i++ ) - list[i] = list[i + 1]; - mpp_assert(frame); - h264e_hal_log_dpb("frame shift list[0] %p", frame); - return frame; -} - - -void hal_h264e_rkv_frame_push_unused( h264e_hal_rkv_dpb_ctx *dpb_ctx, h264e_hal_rkv_frame *frame ) -{ - h264e_hal_debug_enter(); - mpp_assert( frame->i_reference_count > 0 ); - frame->i_reference_count--; - if ( frame->i_reference_count == 0 ) - hal_h264e_rkv_frame_push( dpb_ctx->frames.unused, frame ); - h264e_hal_debug_leave(); -} - -h264e_hal_rkv_frame *hal_h264e_rkv_frame_pop_unused( h264e_hal_context *ctx) -{ - h264e_hal_rkv_frame *frame = NULL; - - h264e_hal_rkv_dpb_ctx *dpb_ctx = (h264e_hal_rkv_dpb_ctx *)ctx->dpb_ctx; - - h264e_hal_debug_enter(); - if ( dpb_ctx->frames.unused[0] ) - frame = hal_h264e_rkv_frame_pop( dpb_ctx->frames.unused ); - else { - frame = hal_h264e_rkv_frame_new( dpb_ctx ); - } - - if ( !frame ) { - h264e_hal_log_err("!frame, return NULL"); - return NULL; - } - frame->i_reference_count = 1; - frame->b_keyframe = 0; - frame->b_corrupt = 0; - frame->long_term_flag = 0; - frame->reorder_longterm_flag = 0; - - h264e_hal_debug_leave(); - - return frame; -} - -static void hal_h264e_rkv_reference_reset( h264e_hal_rkv_dpb_ctx *dpb_ctx ) -{ - h264e_hal_debug_enter(); - while ( dpb_ctx->frames.reference[0] ) - hal_h264e_rkv_frame_push_unused( dpb_ctx, hal_h264e_rkv_frame_pop( dpb_ctx->frames.reference ) ); - dpb_ctx->fdec->i_poc = 0; - h264e_hal_debug_leave(); -} - -#if 0 -static void hal_h264e_rkv_reference_hierarchy_reset( h264e_hal_context *ctx) -{ - RK_S32 ref; - RK_S32 i = 0; - RK_S32 b_hasdelayframe = 0; - h264e_hal_rkv_dpb_ctx *dpb_ctx = (h264e_hal_rkv_dpb_ctx *)ctx->dpb_ctx; - h264e_hal_rkv_extra_info *extra_info = (h264e_hal_rkv_extra_info *)ctx->extra_info; - h264e_hal_sps *sps = &extra_info->sps; - RK_S32 i_num_reorder_frames = sps->vui.i_num_reorder_frames; - - /* look for delay frames -- chain must only contain frames that are disposable */ - for ( i = 0; dpb_ctx->frames.current[i] && RKVENC_IS_DISPOSABLE( dpb_ctx->frames.current[i]->i_type ); i++ ) - b_hasdelayframe |= dpb_ctx->frames.current[i]->i_coded - != dpb_ctx->frames.current[i]->i_frame + i_num_reorder_frames; - - /* This function must handle b-pyramid and clear frames for open-gop */ - if (!b_hasdelayframe && dpb_ctx->frames.i_poc_last_open_gop == -1 ) - return; - - /* Remove last BREF. There will never be old BREFs in the - * dpb during a BREF decode when pyramid == STRICT */ - for ( ref = 0; dpb_ctx->frames.reference[ref]; ref++ ) { - if (dpb_ctx->frames.reference[ref]->i_poc < dpb_ctx->frames.i_poc_last_open_gop && - dpb_ctx->i_type != H264E_HAL_SLICE_TYPE_B ) { - RK_S32 diff = dpb_ctx->i_frame_num - dpb_ctx->frames.reference[ref]->i_frame_num; - dpb_ctx->mmco[dpb_ctx->i_mmco_command_count].i_difference_of_pic_nums = diff; - dpb_ctx->mmco[dpb_ctx->i_mmco_command_count++].i_poc = dpb_ctx->frames.reference[ref]->i_poc; - hal_h264e_rkv_frame_push_unused( dpb_ctx, hal_h264e_rkv_frame_shift( &dpb_ctx->frames.reference[ref] ) ); - dpb_ctx->b_ref_reorder[0] = 1; - ref--; - } - } -} -#endif - -static RK_S32 hal_h264e_rkv_reference_distance( h264e_hal_ref_param *ref_cfg, h264e_hal_rkv_dpb_ctx *dpb_ctx, h264e_hal_rkv_frame *frame ) -{ - if ( ref_cfg->i_frame_packing == 5 ) - return abs((dpb_ctx->fdec->i_frame_cnt & ~1) - (frame->i_frame_cnt & ~1)) + - ((dpb_ctx->fdec->i_frame_cnt & 1) != (frame->i_frame_cnt & 1)); - else - return abs(dpb_ctx->fdec->i_frame_cnt - frame->i_frame_cnt); -} - - -static void hal_h264e_rkv_reference_build_list(h264e_hal_context *ctx) -{ - RK_S32 b_ok = 1, i = 0, list = 0, j = 0; - h264e_hal_rkv_extra_info *extra_info = (h264e_hal_rkv_extra_info *)ctx->extra_info; - h264e_hal_sps *sps = &extra_info->sps; - h264e_hal_rkv_dpb_ctx *dpb_ctx = (h264e_hal_rkv_dpb_ctx *)ctx->dpb_ctx; - h264e_hal_param *par = &ctx->param; - h264e_hal_ref_param *ref_cfg = &par->ref; - h264e_hal_rkv_frame *fdec = dpb_ctx->fdec; - RK_S32 i_poc = fdec->i_poc; - - h264e_hal_debug_enter(); - /* build ref list 0/1 */ - dpb_ctx->i_ref[0] = 0; - dpb_ctx->i_ref[1] = 0; - - if ( dpb_ctx->i_slice_type == H264E_HAL_SLICE_TYPE_I ) { - if ( ref_cfg->i_long_term_en && ref_cfg->i_frame_reference > 1 ) - ref_cfg->hw_longterm_mode ^= 1; //0 and 1, circle; If ref==1 , longterm mode only 1; - - if ( ref_cfg->i_long_term_en && ref_cfg->hw_longterm_mode && ((dpb_ctx->fdec->i_frame_cnt % ref_cfg->i_long_term_internal) == 0)) - fdec->long_term_flag = 1; - h264e_hal_log_dpb("dpb_ctx->i_slice_type == SLICE_TYPE_I, return"); - return; - } - - h264e_hal_log_dpb("fdec->i_poc: %d", fdec->i_poc); - for ( i = 0; dpb_ctx->frames.reference[i]; i++ ) { - if ( dpb_ctx->frames.reference[i]->b_corrupt ) - continue; - if ( dpb_ctx->frames.reference[i]->i_poc < i_poc ) - dpb_ctx->fref[0][dpb_ctx->i_ref[0]++] = dpb_ctx->frames.reference[i]; - else if ( dpb_ctx->frames.reference[i]->i_poc > i_poc ) - dpb_ctx->fref[1][dpb_ctx->i_ref[1]++] = dpb_ctx->frames.reference[i]; - } - - h264e_hal_log_dpb("dpb_ctx->i_ref[0]: %d", dpb_ctx->i_ref[0]); - h264e_hal_log_dpb("dpb_ctx->i_ref[1]: %d", dpb_ctx->i_ref[1]); - - if ( dpb_ctx->i_mmco_remove_from_end ) { - /* Order ref0 for MMCO remove */ - do { - b_ok = 1; - for (i = 0; i < dpb_ctx->i_ref[0] - 1; i++ ) { - if ( dpb_ctx->fref[0][i]->i_frame_cnt < dpb_ctx->fref[0][i + 1]->i_frame_cnt ) { - MPP_SWAP( h264e_hal_rkv_frame *, dpb_ctx->fref[0][i], dpb_ctx->fref[0][i + 1] ); - b_ok = 0; - break; - } - } - } while ( !b_ok ); - - for ( i = dpb_ctx->i_ref[0] - 1; i >= dpb_ctx->i_ref[0] - dpb_ctx->i_mmco_remove_from_end; i-- ) { - RK_S32 diff = dpb_ctx->fdec->i_frame_num - dpb_ctx->fref[0][i]->i_frame_num; - dpb_ctx->mmco[dpb_ctx->i_mmco_command_count].i_poc = dpb_ctx->fref[0][i]->i_poc; - dpb_ctx->mmco[dpb_ctx->i_mmco_command_count++].i_difference_of_pic_nums = diff; - } - } - - /* Order reference lists by distance from the current frame. */ - for ( list = 0; list < 1; list++ ) { //only one list - dpb_ctx->fref_nearest[list] = dpb_ctx->fref[list][0]; - do { - b_ok = 1; - for ( i = 0; i < dpb_ctx->i_ref[list] - 1; i++ ) { - if ( list ? dpb_ctx->fref[list][i + 1]->i_poc < dpb_ctx->fref_nearest[list]->i_poc - : dpb_ctx->fref[list][i + 1]->i_poc > dpb_ctx->fref_nearest[list]->i_poc ) - dpb_ctx->fref_nearest[list] = dpb_ctx->fref[list][i + 1]; - if ( hal_h264e_rkv_reference_distance( ref_cfg, dpb_ctx, dpb_ctx->fref[list][i] ) > - hal_h264e_rkv_reference_distance( ref_cfg, dpb_ctx, dpb_ctx->fref[list][i + 1] ) ) { - MPP_SWAP( h264e_hal_rkv_frame *, dpb_ctx->fref[list][i], dpb_ctx->fref[list][i + 1] ); - b_ok = 0; - break; - } - } - } while ( !b_ok ); - } - //Order long_term frame to last lists , only one long_term frame - if (ref_cfg->i_long_term_en) { - for (i = 0; i < dpb_ctx->i_ref[0]; i++) { - if (dpb_ctx->fref[0][i]->long_term_flag == 1) { - for (j = i; j < dpb_ctx->i_ref[0] - 1; j++) { - MPP_SWAP(h264e_hal_rkv_frame *, dpb_ctx->fref[0][j], dpb_ctx->fref[0][j + 1]); - } - break; - } - } - } - - //reorder, when in longterm_mode "1", don't reorder; - if (ref_cfg->i_frame_reference > 1 && ref_cfg->i_ref_pos && ref_cfg->i_ref_pos < dpb_ctx->i_ref[0]) - dpb_ctx->b_ref_pic_list_reordering[0] = 1; - else - dpb_ctx->b_ref_pic_list_reordering[0] = 0; - if (dpb_ctx->b_ref_pic_list_reordering[0]) { - for (list = 0; list < 1; list++) { - if (dpb_ctx->fref[0][ref_cfg->i_ref_pos]->long_term_flag) { - fdec->reorder_longterm_flag = 1; - } - for (i = ref_cfg->i_ref_pos; i >= 1; i--) { - MPP_SWAP(h264e_hal_rkv_frame *, dpb_ctx->fref[list][i], dpb_ctx->fref[list][i - 1]); - } - } - } - - //first P frame mark max_long_term_frame_idx_plus1 - if ( ref_cfg->i_long_term_en && dpb_ctx->fdec->i_frame_num == 1 ) { - dpb_ctx->i_mmco_command_count = 0; - - dpb_ctx->mmco[dpb_ctx->i_mmco_command_count].i_poc = 0; - dpb_ctx->mmco[dpb_ctx->i_mmco_command_count].memory_management_control_operation = 4; - dpb_ctx->mmco[dpb_ctx->i_mmco_command_count++].i_difference_of_pic_nums = 2; // max_long_term_frame_idx_plus1 , slice will plus 1, is 0; - } else - dpb_ctx->i_mmco_command_count = 0; - - //longterm marking - if ( ref_cfg->i_long_term_en && ((dpb_ctx->fdec->i_frame_cnt % ref_cfg->i_long_term_internal) == 0)) { - RK_S32 reflist_longterm = 0; - RK_S32 reflist_longidx = 0; - RK_S32 reflist_short_to_long = 0; - RK_S32 reflist_short_to_long_idx = 0; - - //search frame for transferring short to long; - if (ref_cfg->hw_longterm_mode == 0 || dpb_ctx->fdec->i_frame_num == 1) { - for (i = 0; i < dpb_ctx->i_ref[0]; i++) { - if (!dpb_ctx->fref[0][i]->long_term_flag && (ref_cfg->i_ref_pos + 1) == i) { - reflist_short_to_long++; - reflist_short_to_long_idx = i; - break; - } - } - //clear ref longterm flag - for (i = 0; i < dpb_ctx->i_ref[0]; i++) { - if (dpb_ctx->fref[0][i]->long_term_flag) { - reflist_longterm++; - reflist_longidx = i; - dpb_ctx->fref[0][i]->long_term_flag = 0; - } - } - } - - mpp_assert(reflist_longterm <= 1); - - //marking ref longterm to unused; - if ( reflist_longterm == 1 ) { - i = reflist_longidx; - - dpb_ctx->mmco[dpb_ctx->i_mmco_command_count].i_poc = dpb_ctx->fref[0][i]->i_poc; - dpb_ctx->mmco[dpb_ctx->i_mmco_command_count].memory_management_control_operation = 2; //long_term_pic_num - dpb_ctx->mmco[dpb_ctx->i_mmco_command_count++].i_difference_of_pic_nums = 1; - } else if ( dpb_ctx->i_ref[0] >= sps->i_num_ref_frames && dpb_ctx->i_ref[0] > 1 ) { //if dpb is full, so it need release a short term ref frame; - //if longterm marking is same with release short term, change release short term; - RK_S32 pos = ((reflist_short_to_long && reflist_short_to_long_idx == (dpb_ctx->i_ref[0] - 1)) || dpb_ctx->fref[0][dpb_ctx->i_ref[0] - 1]->long_term_flag) + 1; - RK_S32 diff = dpb_ctx->fdec->i_frame_num - dpb_ctx->fref[0][dpb_ctx->i_ref[0] - pos]->i_frame_num; - - dpb_ctx->mmco[dpb_ctx->i_mmco_command_count].i_poc = dpb_ctx->fref[0][dpb_ctx->i_ref[0] - pos]->i_poc; - dpb_ctx->mmco[dpb_ctx->i_mmco_command_count].memory_management_control_operation = 1; - dpb_ctx->mmco[dpb_ctx->i_mmco_command_count++].i_difference_of_pic_nums = diff; // difference_of_pic_nums_minus1 - } - - //marking curr pic to longterm; - if ( ref_cfg->hw_longterm_mode && dpb_ctx->fdec->i_frame_num == 1) { - fdec->long_term_flag = 1; - dpb_ctx->mmco[dpb_ctx->i_mmco_command_count].i_poc = 0; - dpb_ctx->mmco[dpb_ctx->i_mmco_command_count].memory_management_control_operation = 6; - dpb_ctx->mmco[dpb_ctx->i_mmco_command_count++].i_difference_of_pic_nums = 1; // long_term_frame_idx ; - } else if ( reflist_short_to_long ) { //Assign a long-term frame index to a short-term picture - i = reflist_short_to_long_idx; - RK_S32 diff = dpb_ctx->fdec->i_frame_num - dpb_ctx->fref[0][i]->i_frame_num; - - dpb_ctx->fref[0][i]->long_term_flag = 1; - dpb_ctx->mmco[dpb_ctx->i_mmco_command_count].i_poc = dpb_ctx->fref[0][i]->i_poc; - dpb_ctx->mmco[dpb_ctx->i_mmco_command_count].memory_management_control_operation = 3; //short term to long term; - dpb_ctx->mmco[dpb_ctx->i_mmco_command_count++].i_difference_of_pic_nums = diff; // difference_of_pic_nums_minus1 , slice will minus 1, is 0; - } - } else { - if (!(ref_cfg->i_long_term_en && dpb_ctx->fdec->i_frame_num == 1)) - dpb_ctx->i_mmco_command_count = 0; - } - - dpb_ctx->i_ref[1] = H264E_HAL_MIN( dpb_ctx->i_ref[1], dpb_ctx->i_max_ref1 ); - dpb_ctx->i_ref[0] = H264E_HAL_MIN( dpb_ctx->i_ref[0], dpb_ctx->i_max_ref0 ); - dpb_ctx->i_ref[0] = H264E_HAL_MIN( dpb_ctx->i_ref[0], ref_cfg->i_frame_reference ); // if reconfig() has lowered the limit - - /* EXP: add duplicates */ - mpp_assert( dpb_ctx->i_ref[0] + dpb_ctx->i_ref[1] <= H264E_REF_MAX ); - - h264e_hal_debug_leave(); -} - -static MPP_RET hal_h264e_rkv_reference_update( h264e_hal_context *ctx) -{ - RK_S32 i = 0, j = 0; - h264e_hal_rkv_extra_info *extra_info = (h264e_hal_rkv_extra_info *)ctx->extra_info; - h264e_hal_sps *sps = &extra_info->sps; - h264e_hal_rkv_dpb_ctx *dpb_ctx = (h264e_hal_rkv_dpb_ctx *)ctx->dpb_ctx; - h264e_hal_ref_param *ref_cfg = &ctx->param.ref; - - h264e_hal_debug_enter(); - if ( !dpb_ctx->fdec->b_kept_as_ref ) { - h264e_hal_log_err("!dpb_ctx->fdec->b_kept_as_ref, return early"); - return MPP_OK; - } - - /* apply mmco from previous frame. */ - for ( i = 0; i < dpb_ctx->i_mmco_command_count; i++ ) { - RK_S32 mmco = dpb_ctx->mmco[i].memory_management_control_operation; - for ( j = 0; dpb_ctx->frames.reference[j]; j++ ) { - if ( dpb_ctx->frames.reference[j]->i_poc == dpb_ctx->mmco[i].i_poc && (mmco == 1 || mmco == 2) ) - hal_h264e_rkv_frame_push_unused( dpb_ctx, hal_h264e_rkv_frame_shift( &dpb_ctx->frames.reference[j] ) ); - } - } - - /* move frame in the buffer */ - h264e_hal_log_dpb("try to push dpb_ctx->fdec %p, poc %d", dpb_ctx->fdec, dpb_ctx->fdec->i_poc); - hal_h264e_rkv_frame_push( dpb_ctx->frames.reference, dpb_ctx->fdec ); - if ( ref_cfg->i_long_term_en ) { - if ( dpb_ctx->frames.reference[sps->i_num_ref_frames] ) { - for (i = 0; i < 17; i++) { - if (dpb_ctx->frames.reference[i]->long_term_flag == 0) { //if longterm , don't remove; - hal_h264e_rkv_frame_push_unused(dpb_ctx, hal_h264e_rkv_frame_shift(&dpb_ctx->frames.reference[i])); - break; - } - mpp_assert(i != 16); - } - } - } else { - if ( dpb_ctx->frames.reference[sps->i_num_ref_frames] ) - hal_h264e_rkv_frame_push_unused( dpb_ctx, hal_h264e_rkv_frame_shift( dpb_ctx->frames.reference ) ); - } - - h264e_hal_debug_leave(); - return MPP_OK; -} - - - -static MPP_RET hal_h264e_rkv_reference_frame_set( h264e_hal_context *ctx, h264e_syntax *syn) -{ - RK_U32 i_nal_type = 0, i_nal_ref_idc = 0; - RK_S32 list = 0, k = 0; - h264e_hal_rkv_dpb_ctx *dpb_ctx = (h264e_hal_rkv_dpb_ctx *)ctx->dpb_ctx; - h264e_hal_rkv_extra_info *extra_info = (h264e_hal_rkv_extra_info *)ctx->extra_info; - h264e_hal_sps *sps = &extra_info->sps; - h264e_hal_ref_param *ref_cfg = &ctx->param.ref; - - h264e_hal_debug_enter(); - - dpb_ctx->fdec = hal_h264e_rkv_frame_pop_unused(ctx); - if ( !dpb_ctx->fdec ) { - h264e_hal_log_err("!dpb_ctx->fdec, current recon buf get failed"); - return MPP_NOK; - } - - dpb_ctx->i_max_ref0 = ref_cfg->i_frame_reference; - dpb_ctx->i_max_ref1 = H264E_HAL_MIN( sps->vui.i_num_reorder_frames, ref_cfg->i_frame_reference ); - - if (syn->frame_coding_type == RKVENC_FRAME_TYPE_IDR) { - dpb_ctx->i_frame_num = 0; - dpb_ctx->frames.i_last_idr = dpb_ctx->i_frame_cnt; - } - - dpb_ctx->fdec->i_frame_cnt = dpb_ctx->i_frame_cnt; - dpb_ctx->fdec->i_frame_num = dpb_ctx->i_frame_num; - dpb_ctx->fdec->i_frame_type = syn->frame_coding_type; - dpb_ctx->fdec->i_poc = 2 * ( dpb_ctx->fdec->i_frame_cnt - H264E_HAL_MAX( dpb_ctx->frames.i_last_idr, 0 ) ); - - - if ( !RKVENC_IS_TYPE_I( dpb_ctx->fdec->i_frame_type ) ) { - RK_S32 valid_refs_left = 0; - for ( k = 0; dpb_ctx->frames.reference[k]; k++ ) - if ( !dpb_ctx->frames.reference[k]->b_corrupt ) - valid_refs_left++; - /* No valid reference frames left: force an IDR. */ - if ( !valid_refs_left ) { - dpb_ctx->fdec->b_keyframe = 1; - dpb_ctx->fdec->i_frame_type = RKVENC_FRAME_TYPE_IDR; - } - } - if ( dpb_ctx->fdec->b_keyframe ) - dpb_ctx->frames.i_last_keyframe = dpb_ctx->fdec->i_frame_cnt; - - - dpb_ctx->i_mmco_command_count = - dpb_ctx->i_mmco_remove_from_end = 0; - dpb_ctx->b_ref_pic_list_reordering[0] = 0; - dpb_ctx->b_ref_pic_list_reordering[1] = 0; - - /* calculate nal type and nal ref idc */ - if (syn->frame_coding_type == RKVENC_FRAME_TYPE_IDR) { //TODO: extend syn->frame_coding_type definition - /* reset ref pictures */ - i_nal_type = RKVENC_NAL_SLICE_IDR; - i_nal_ref_idc = RKVENC_NAL_PRIORITY_HIGHEST; - dpb_ctx->i_slice_type = H264E_HAL_SLICE_TYPE_I; - hal_h264e_rkv_reference_reset(dpb_ctx); - } else if ( syn->frame_coding_type == RKVENC_FRAME_TYPE_I ) { - i_nal_type = RKVENC_NAL_SLICE; - i_nal_ref_idc = RKVENC_NAL_PRIORITY_HIGH; /* Not completely true but for now it is (as all I/P are kept as ref)*/ - dpb_ctx->i_slice_type = H264E_HAL_SLICE_TYPE_I; - } else if ( syn->frame_coding_type == RKVENC_FRAME_TYPE_P ) { - i_nal_type = RKVENC_NAL_SLICE; - i_nal_ref_idc = RKVENC_NAL_PRIORITY_HIGH; /* Not completely true but for now it is (as all I/P are kept as ref)*/ - dpb_ctx->i_slice_type = H264E_HAL_SLICE_TYPE_P; - } else if ( syn->frame_coding_type == RKVENC_FRAME_TYPE_BREF ) { - i_nal_type = RKVENC_NAL_SLICE; - i_nal_ref_idc = RKVENC_NAL_PRIORITY_HIGH; - dpb_ctx->i_slice_type = H264E_HAL_SLICE_TYPE_B; - } else { /* B frame */ - i_nal_type = RKVENC_NAL_SLICE; - i_nal_ref_idc = RKVENC_NAL_PRIORITY_DISPOSABLE; - dpb_ctx->i_slice_type = H264E_HAL_SLICE_TYPE_B; - } - - dpb_ctx->fdec->b_kept_as_ref = i_nal_ref_idc != RKVENC_NAL_PRIORITY_DISPOSABLE;// && h->param.i_keyint_max > 1; - - - if (sps->keyframe_max_interval == 1) - i_nal_ref_idc = RKVENC_NAL_PRIORITY_LOW; - - dpb_ctx->i_nal_ref_idc = i_nal_ref_idc; - dpb_ctx->i_nal_type = i_nal_type; - - - dpb_ctx->fdec->i_pts = dpb_ctx->fdec->i_pts; - - - /* build list */ - hal_h264e_rkv_reference_build_list(ctx); - - /* set syntax (slice header) */ - - /* If the ref list isn't in the default order, construct reordering header */ - for (list = 0; list < 2; list++ ) { - if ( dpb_ctx->b_ref_pic_list_reordering[list] ) { - RK_S32 pred_frame_num = dpb_ctx->fdec->i_frame_num & ((1 << sps->i_log2_max_frame_num) - 1); - for ( k = 0; k < dpb_ctx->i_ref[list]; k++ ) { - if ( dpb_ctx->fdec->reorder_longterm_flag ) { // - dpb_ctx->fdec->reorder_longterm_flag = 0; //clear reorder_longterm_flag - dpb_ctx->ref_pic_list_order[list][k].idc = 2; //reorder long_term_pic_num; - dpb_ctx->ref_pic_list_order[list][k].arg = 0; //long_term_pic_num - break; //NOTE: RK feature: only reorder one time - } else { - RK_S32 lx_frame_num = dpb_ctx->fref[list][k]->i_frame_num & ((1 << sps->i_log2_max_frame_num) - 1); - RK_S32 diff = lx_frame_num - pred_frame_num; - dpb_ctx->ref_pic_list_order[list][k].idc = ( diff > 0 ); - dpb_ctx->ref_pic_list_order[list][k].arg = (abs(diff) - 1) & ((1 << sps->i_log2_max_frame_num) - 1); - pred_frame_num = dpb_ctx->fref[list][k]->i_frame_num; - break; //NOTE: RK feature: only reorder one time - } - } - } - } - - if (dpb_ctx->i_nal_type == RKVENC_NAL_SLICE_IDR) { - if (ref_cfg->i_long_term_en && ref_cfg->hw_longterm_mode && ((dpb_ctx->fdec->i_frame_cnt % ref_cfg->i_long_term_internal) == 0) ) - dpb_ctx->i_long_term_reference_flag = 1; - dpb_ctx->i_idr_pic_id = dpb_ctx->i_tmp_idr_pic_id; - dpb_ctx->i_tmp_idr_pic_id ^= 1; - } else { - dpb_ctx->i_long_term_reference_flag = 0; - dpb_ctx->i_idr_pic_id = -1; - } - - - h264e_hal_debug_leave(); - - return MPP_OK; -} - - -static MPP_RET hal_h264e_rkv_reference_frame_update( h264e_hal_context *ctx) -{ - //h264e_hal_rkv_dpb_ctx *dpb_ctx = (h264e_hal_rkv_dpb_ctx *)ctx->dpb_ctx; - - h264e_hal_debug_enter(); - if (MPP_OK != hal_h264e_rkv_reference_update(ctx)) { - h264e_hal_log_err("reference update failed, return now"); - return MPP_NOK; - } - - h264e_hal_debug_leave(); - return MPP_OK; -} - -static MPP_RET hal_h264e_rkv_free_buffers(h264e_hal_context *ctx) -{ - RK_S32 k = 0; - h264e_hal_rkv_buffers *buffers = (h264e_hal_rkv_buffers *)ctx->buffers; - h264e_hal_debug_enter(); - for (k = 0; k < 2; k++) { - if (buffers->hw_pp_buf[k]) { - if (MPP_OK != mpp_buffer_put(buffers->hw_pp_buf[k])) { - h264e_hal_log_err("hw_pp_buf[%d] put failed", k); - return MPP_NOK; - } - } - } - for (k = 0; k < 2; k++) { - if (buffers->hw_dsp_buf[k]) { - if (MPP_OK != mpp_buffer_put(buffers->hw_dsp_buf[k])) { - h264e_hal_log_err("hw_dsp_buf[%d] put failed", k); - return MPP_NOK; - } - } - } - for (k = 0; k < RKV_H264E_LINKTABLE_FRAME_NUM; k++) { - if (buffers->hw_mei_buf[k]) { - if (MPP_OK != mpp_buffer_put(buffers->hw_mei_buf[k])) { - h264e_hal_log_err("hw_mei_buf[%d] put failed", k); - return MPP_NOK; - } - } - } - - for (k = 0; k < RKV_H264E_LINKTABLE_FRAME_NUM; k++) { - if (buffers->hw_roi_buf[k]) { - if (MPP_OK != mpp_buffer_put(buffers->hw_roi_buf[k])) { - h264e_hal_log_err("hw_roi_buf[%d] put failed", k); - return MPP_NOK; - } - } - if (buffers->hw_osd_buf[k]) { - if (MPP_OK != mpp_buffer_put(buffers->hw_osd_buf[k])) { - h264e_hal_log_err("hw_osd_buf[%d] put failed", k); - return MPP_NOK; - } - } - } - - { - RK_S32 num_buf = MPP_ARRAY_ELEMS(buffers->hw_rec_buf); - for (k = 0; k < num_buf; k++) { - if (buffers->hw_rec_buf[k]) { - if (MPP_OK != mpp_buffer_put(buffers->hw_rec_buf[k])) { - h264e_hal_log_err("hw_rec_buf[%d] put failed", k); - return MPP_NOK; - } - } - } - } - - - - for (k = 0; k < H264E_HAL_RKV_BUF_GRP_BUTT; k++) { - if (buffers->hw_buf_grp[k]) { - if (MPP_OK != mpp_buffer_group_put(buffers->hw_buf_grp[k])) { - h264e_hal_log_err("buf group[%d] put failed", k); - return MPP_NOK; - } - } - } - - h264e_hal_debug_leave(); - - return MPP_OK; -} - -static MPP_RET hal_h264e_rkv_allocate_buffers(h264e_hal_context *ctx, h264e_syntax *syn, h264e_hal_sps *sps, h264e_hal_rkv_coveragetest_cfg *test_cfg) -{ - RK_S32 k = 0; - h264e_hal_rkv_buffers *buffers = (h264e_hal_rkv_buffers *)ctx->buffers; - RK_U32 num_mbs_oneframe = (syn->pic_luma_width + 15) / 16 * ((syn->pic_luma_height + 15) / 16); - RK_U32 frame_size = ((syn->pic_luma_width + 15) & (~15)) * ((syn->pic_luma_height + 15) & (~15)) * 3 / 2; - h264e_hal_rkv_dpb_ctx *dpb_ctx = (h264e_hal_rkv_dpb_ctx *)ctx->dpb_ctx; - h264e_hal_rkv_frame *frame_buf = dpb_ctx->frame_buf; - RK_U32 all_intra_mode = sps->keyframe_max_interval == 1; - h264e_hal_debug_enter(); - //TODO: reduce buf size - for (k = 0; k < H264E_HAL_RKV_BUF_GRP_BUTT; k++) { - if (MPP_OK != mpp_buffer_group_get_internal(&buffers->hw_buf_grp[k], MPP_BUFFER_TYPE_ION)) { - h264e_hal_log_err("buf group[%d] get failed", k); - return MPP_ERR_MALLOC; - } - } - - if (syn->preproc_en || (test_cfg && test_cfg->preproc)) { - for (k = 0; k < 2; k++) { - if (MPP_OK != mpp_buffer_get(buffers->hw_buf_grp[H264E_HAL_RKV_BUF_GRP_PP], &buffers->hw_pp_buf[k], frame_size)) { - h264e_hal_log_err("hw_pp_buf[%d] get failed", k); - return MPP_ERR_MALLOC; - } else { - h264e_hal_log_dpb("hw_pp_buf[%d] %p done, fd %d", k, buffers->hw_pp_buf[k], mpp_buffer_get_fd(buffers->hw_pp_buf[k])); - } - } - } - - if (!all_intra_mode) { - for (k = 0; k < 2; k++) { - if (MPP_OK != mpp_buffer_get(buffers->hw_buf_grp[H264E_HAL_RKV_BUF_GRP_DSP], &buffers->hw_dsp_buf[k], frame_size / 16)) { - h264e_hal_log_err("hw_dsp_buf[%d] get failed", k); - return MPP_ERR_MALLOC; - } else { - h264e_hal_log_dpb("hw_dsp_buf[%d] %p done, fd %d", k, buffers->hw_dsp_buf[k], mpp_buffer_get_fd(buffers->hw_dsp_buf[k])); - } - } - } - - #if 0 //default setting - RK_U32 num_mei_oneframe = (syn->pic_luma_width + 255) / 256 * ((syn->pic_luma_height + 15) / 16); - for (k = 0; k < RKV_H264E_LINKTABLE_FRAME_NUM; k++) { - if (MPP_OK != mpp_buffer_get(buffers->hw_buf_grp[H264E_HAL_RKV_BUF_GRP_MEI], &buffers->hw_mei_buf[k], num_mei_oneframe * 16 * 4)) { - h264e_hal_log_err("hw_mei_buf[%d] get failed", k); - return MPP_ERR_MALLOC; - } else { - h264e_hal_log_dpb("hw_mei_buf[%d] %p done, fd %d", k, buffers->hw_mei_buf[k], mpp_buffer_get_fd(buffers->hw_mei_buf[k])); - } - } - #endif - - if (syn->roi_en || (test_cfg && test_cfg->roi)) { - for (k = 0; k < RKV_H264E_LINKTABLE_FRAME_NUM; k++) { - if (MPP_OK != mpp_buffer_get(buffers->hw_buf_grp[H264E_HAL_RKV_BUF_GRP_ROI], &buffers->hw_roi_buf[k], num_mbs_oneframe * 1)) { - h264e_hal_log_err("hw_roi_buf[%d] get failed", k); - return MPP_ERR_MALLOC; - } else { - h264e_hal_log_dpb("hw_roi_buf[%d] %p done, fd %d", k, buffers->hw_roi_buf[k], mpp_buffer_get_fd(buffers->hw_roi_buf[k])); - } - } - } - - { - RK_S32 num_buf = MPP_ARRAY_ELEMS(buffers->hw_rec_buf); - for (k = 0; k < num_buf; k++) { - if (MPP_OK != mpp_buffer_get(buffers->hw_buf_grp[H264E_HAL_RKV_BUF_GRP_REC], &buffers->hw_rec_buf[k], frame_size)) { - h264e_hal_log_err("hw_rec_buf[%d] get failed", k); - return MPP_ERR_MALLOC; - } else { - h264e_hal_log_dpb("hw_rec_buf[%d] %p done, fd %d", k, buffers->hw_rec_buf[k], mpp_buffer_get_fd(buffers->hw_rec_buf[k])); - } - frame_buf[k].hw_buf = buffers->hw_rec_buf[k]; - } - } - - if (syn->osd_mode || (test_cfg && test_cfg->osd)) { - for (k = 0; k < RKV_H264E_LINKTABLE_FRAME_NUM; k++) { - if (MPP_OK != mpp_buffer_get(buffers->hw_buf_grp[H264E_HAL_RKV_BUF_GRP_REC], &buffers->hw_osd_buf[k], num_mbs_oneframe * 256)) { - h264e_hal_log_err("hw_osd_buf[%d] get failed", buffers->hw_osd_buf[k]); - return MPP_ERR_MALLOC; - } else { - h264e_hal_log_dpb("hw_osd_buf[%d] %p done, fd %d", k, buffers->hw_osd_buf[k], mpp_buffer_get_fd(buffers->hw_osd_buf[k])); - } - } - } - - h264e_hal_debug_leave(); - return MPP_OK; -} - -static void hal_h264e_rkv_set_param(h264e_hal_param *p) -{ - h264e_hal_vui_param *vui = &p->vui; - h264e_hal_ref_param *ref = &p->ref; - - p->constrained_intra = 0; - - vui->i_sar_height = 0; - vui->i_sar_width = 0; - vui->i_overscan = 0; - vui->i_vidformat = 5; - vui->b_fullrange = 0; - vui->i_colorprim = 2; - vui->i_transfer = 2; - vui->i_colmatrix = -1; - vui->i_chroma_loc = 0; - - ref->i_frame_reference = RKV_H264E_NUM_REFS; - ref->i_dpb_size = RKV_H264E_NUM_REFS; - ref->i_ref_pos = 1; - ref->i_long_term_en = RKV_H264E_LONGTERM_REF_EN; - ref->hw_longterm_mode = 0; - ref->i_long_term_internal = 0; - ref->i_frame_packing = -1; -} - -static void hal_h264e_rkv_adjust_param(h264e_hal_context *ctx) -{ - h264e_hal_param *par = &ctx->param; - (void)par; -} - -MPP_RET hal_h264e_rkv_set_sps(h264e_hal_sps *sps, h264e_hal_param *par, h264e_control_extra_info_cfg *cfg) -{ - h264e_hal_vui_param vui = par->vui; - h264e_hal_ref_param ref_cfg = par->ref; - RK_S32 max_frame_num = 0; - - //default settings - RK_S32 i_bframe_pyramid = 0; - RK_S32 i_bframe = 0; - RK_S32 b_intra_refresh = 0; - RK_S32 Log2MaxFrameNum = 16; - RK_S32 Sw_log2_max_pic_order_cnt_lsb_minus4 = 12; - RK_S32 b_interlaced = 0; - RK_S32 b_fake_interlaced = 0; - RK_S32 crop_rect_left = 0; - RK_S32 crop_rect_right = 0; - RK_S32 crop_rect_top = 0; - RK_S32 crop_rect_bottom = 0; - RK_S32 i_timebase_num = 1; - RK_S32 i_timebase_den = 25; - RK_S32 b_vfr_input = 0; - RK_S32 i_nal_hrd = 0; - RK_S32 b_pic_struct = 0; - RK_S32 analyse_mv_range = 128; //TODO: relative to level_idc, transplant x264_validate_levels. - h264e_hal_rkv_csp_info csp_info = hal_h264e_rkv_convert_csp(cfg->input_image_format); - RK_S32 csp = h264e_csp_idx_map[csp_info.fmt] & RKV_H264E_CSP2_MASK; - RK_S32 i_dpb_size = ref_cfg.i_dpb_size; - RK_S32 i_frame_reference = ref_cfg.i_frame_reference; - - sps->i_id = 0; - sps->i_mb_width = ( cfg->pic_luma_width + 15 ) / 16; - sps->i_mb_height = ( cfg->pic_luma_height + 15 ) / 16; - sps->i_chroma_format_idc = csp >= RKV_H264E_CSP2_I444 ? RKV_H264E_CHROMA_444 : - csp >= RKV_H264E_CSP2_I422 ? RKV_H264E_CHROMA_422 : RKV_H264E_CHROMA_420; - - sps->b_qpprime_y_zero_transform_bypass = 0; //param->rc.i_rc_method == X264_RC_CQP && param->rc.i_qp_constant == 0; - sps->i_profile_idc = cfg->profile_idc; - - sps->b_constraint_set0 = 0; //sps->i_profile_idc == H264_PROFILE_BASELINE; - /* x264 doesn't support the features that are in Baseline and not in Main, - * namely arbitrary_slice_order and slice_groups. */ - sps->b_constraint_set1 = 0; //sps->i_profile_idc <= H264_PROFILE_MAIN; - /* Never set constraint_set2, it is not necessary and not used in real world. */ - sps->b_constraint_set2 = 0; - sps->b_constraint_set3 = 0; - - sps->i_level_idc = cfg->level_idc; - if ( cfg->level_idc == 9 && ( sps->i_profile_idc == H264_PROFILE_BASELINE || sps->i_profile_idc == H264_PROFILE_MAIN ) ) { - sps->b_constraint_set3 = 1; /* level 1b with Baseline or Main profile is signalled via constraint_set3 */ - sps->i_level_idc = 11; - } - /* Intra profiles */ - if ( cfg->keyframe_max_interval == 1 && sps->i_profile_idc > H264_PROFILE_HIGH ) - sps->b_constraint_set3 = 1; - - sps->vui.i_num_reorder_frames = i_bframe_pyramid ? 2 : i_bframe ? 1 : 0; - /* extra slot with pyramid so that we don't have to override the - * order of forgetting old pictures */ - sps->vui.i_max_dec_frame_buffering = - sps->i_num_ref_frames = H264E_HAL_MIN(H264E_REF_MAX, H264E_HAL_MAX4(i_frame_reference, 1 + sps->vui.i_num_reorder_frames, - i_bframe_pyramid ? 4 : 1, i_dpb_size)); //TODO: multi refs - sps->i_num_ref_frames -= i_bframe_pyramid == RKV_H264E_B_PYRAMID_STRICT; //TODO: multi refs - if ( cfg->keyframe_max_interval == 1 ) { - sps->i_num_ref_frames = 0; - sps->vui.i_max_dec_frame_buffering = 0; - } - - /* number of refs + current frame */ - max_frame_num = sps->vui.i_max_dec_frame_buffering * (!!i_bframe_pyramid + 1) + 1; - /* Intra refresh cannot write a recovery time greater than max frame num-1 */ - if (b_intra_refresh ) { - RK_S32 time_to_recovery = H264E_HAL_MIN( sps->i_mb_width - 1, cfg->keyframe_max_interval) + i_bframe - 1; - max_frame_num = H264E_HAL_MAX( max_frame_num, time_to_recovery + 1 ); - } - - sps->i_log2_max_frame_num = Log2MaxFrameNum;//fix by gsl org 16, at least 4 - while ( (1 << sps->i_log2_max_frame_num) <= max_frame_num ) - sps->i_log2_max_frame_num++; - - sps->i_poc_type = 0; - - if ( sps->i_poc_type == 0 ) { - RK_S32 max_delta_poc = (i_bframe + 2) * (!!i_bframe_pyramid + 1) * 2; - sps->i_log2_max_poc_lsb = Sw_log2_max_pic_order_cnt_lsb_minus4 + 4; - while ( (1 << sps->i_log2_max_poc_lsb) <= max_delta_poc * 2 ) - sps->i_log2_max_poc_lsb++; - } - - sps->b_vui = 1; - - sps->b_gaps_in_frame_num_value_allowed = 0; - sps->b_frame_mbs_only = !(b_interlaced || b_fake_interlaced); - if ( !sps->b_frame_mbs_only ) - sps->i_mb_height = ( sps->i_mb_height + 1 ) & ~1; - sps->b_mb_adaptive_frame_field = b_interlaced; - sps->b_direct8x8_inference = 1; - - sps->crop.i_left = crop_rect_left; - sps->crop.i_top = crop_rect_top; - sps->crop.i_right = crop_rect_right + sps->i_mb_width * 16 - cfg->pic_luma_width; - sps->crop.i_bottom = (crop_rect_bottom + sps->i_mb_height * 16 - cfg->pic_luma_height) >> !sps->b_frame_mbs_only; - sps->b_crop = sps->crop.i_left || sps->crop.i_top || - sps->crop.i_right || sps->crop.i_bottom; - - sps->vui.b_aspect_ratio_info_present = 0; - if (vui.i_sar_width > 0 && vui.i_sar_height > 0 ) { - sps->vui.b_aspect_ratio_info_present = 1; - sps->vui.i_sar_width = vui.i_sar_width; - sps->vui.i_sar_height = vui.i_sar_height; - } - - sps->vui.b_overscan_info_present = vui.i_overscan > 0 && vui.i_overscan <= 2; - if ( sps->vui.b_overscan_info_present ) - sps->vui.b_overscan_info = ( vui.i_overscan == 2 ? 1 : 0 ); - - sps->vui.b_signal_type_present = 0; - sps->vui.i_vidformat = ( vui.i_vidformat >= 0 && vui.i_vidformat <= 5 ? vui.i_vidformat : 5 ); - sps->vui.b_fullrange = ( vui.b_fullrange >= 0 && vui.b_fullrange <= 1 ? vui.b_fullrange : - ( csp >= RKV_H264E_CSP2_BGR ? 1 : 0 ) ); - sps->vui.b_color_description_present = 0; - - sps->vui.i_colorprim = ( vui.i_colorprim >= 0 && vui.i_colorprim <= 9 ? vui.i_colorprim : 2 ); - sps->vui.i_transfer = ( vui.i_transfer >= 0 && vui.i_transfer <= 15 ? vui.i_transfer : 2 ); - sps->vui.i_colmatrix = ( vui.i_colmatrix >= 0 && vui.i_colmatrix <= 10 ? vui.i_colmatrix : - ( csp >= RKV_H264E_CSP2_BGR ? 0 : 2 ) ); - if ( sps->vui.i_colorprim != 2 || - sps->vui.i_transfer != 2 || - sps->vui.i_colmatrix != 2 ) { - sps->vui.b_color_description_present = 1; - } - - if ( sps->vui.i_vidformat != 5 || - sps->vui.b_fullrange || - sps->vui.b_color_description_present ) { - sps->vui.b_signal_type_present = 1; - } - - /* FIXME: not sufficient for interlaced video */ - sps->vui.b_chroma_loc_info_present = vui.i_chroma_loc > 0 && vui.i_chroma_loc <= 5 && - sps->i_chroma_format_idc == RKV_H264E_CHROMA_420; - if ( sps->vui.b_chroma_loc_info_present ) { - sps->vui.i_chroma_loc_top = vui.i_chroma_loc; - sps->vui.i_chroma_loc_bottom = vui.i_chroma_loc; - } - - sps->vui.b_timing_info_present = i_timebase_num > 0 && i_timebase_den > 0; - - if ( sps->vui.b_timing_info_present ) { - sps->vui.i_num_units_in_tick = i_timebase_num; - sps->vui.i_time_scale = i_timebase_den * 2; - sps->vui.b_fixed_frame_rate = !b_vfr_input; - } - - sps->vui.b_vcl_hrd_parameters_present = 0; // we don't support VCL HRD - sps->vui.b_nal_hrd_parameters_present = !!i_nal_hrd; - sps->vui.b_pic_struct_present = b_pic_struct; - - // NOTE: HRD related parts of the SPS are initialised in x264_ratecontrol_init_reconfigurable - - sps->vui.b_bitstream_restriction = cfg->keyframe_max_interval > 1; - if ( sps->vui.b_bitstream_restriction ) { - sps->vui.b_motion_vectors_over_pic_boundaries = 1; - sps->vui.i_max_bytes_per_pic_denom = 0; - sps->vui.i_max_bits_per_mb_denom = 0; - sps->vui.i_log2_max_mv_length_horizontal = - sps->vui.i_log2_max_mv_length_vertical = (RK_S32)log2f((float)H264E_HAL_MAX( 1, analyse_mv_range * 4 - 1 ) ) + 1; - } - - /* only for backup, excluded in read SPS */ - sps->keyframe_max_interval = cfg->keyframe_max_interval; - return MPP_OK; -} - - -RK_S32 hal_h264e_rkv_stream_get_pos(h264e_hal_rkv_stream *s) -{ - return (RK_S32)(8 * (s->p - s->p_start) + (4 * 8) - s->i_left); -} - - -MPP_RET hal_h264e_rkv_stream_init(h264e_hal_rkv_stream *s) -{ - RK_S32 offset = 0; - RK_U8 *p_buf = NULL; - s->buf = mpp_calloc(RK_U8, 512); //SPS+PPS - p_buf = s->buf + 8; //NOTE - - offset = (size_t)(p_buf) & 3; - s->p = s->p_start = p_buf - offset; - //s->p_end = (RK_U8*)s->buf + i_data; - s->i_left = (4 - offset) * 8; - //s->cur_bits = endian_fix32(M32(s->p)); - s->cur_bits = (*(s->p) << 24) + (*(s->p + 1) << 16) + (*(s->p + 2) << 8) + (*(s->p + 3) << 0); - s->cur_bits >>= (4 - offset) * 8; - s->count_bit = 0; - - return MPP_OK; -} - - -MPP_RET hal_h264e_rkv_stream_reset(h264e_hal_rkv_stream *s) -{ - RK_S32 offset = 0; - RK_U8 *p_buf = NULL; - p_buf = s->buf + 8; //NOTE - h264e_hal_debug_enter(); - - offset = (size_t)(p_buf) & 3; - s->p = s->p_start = p_buf - offset; - //s->p_end = (RK_U8*)s->buf + i_data; - s->i_left = (4 - offset) * 8; - //s->cur_bits = endian_fix32(M32(s->p)); - s->cur_bits = (*(s->p) << 24) + (*(s->p + 1) << 16) + (*(s->p + 2) << 8) + (*(s->p + 3) << 0); - s->cur_bits >>= (4 - offset) * 8; - s->count_bit = 0; - h264e_hal_debug_leave(); - return MPP_OK; -} - -MPP_RET hal_h264e_rkv_stream_deinit(h264e_hal_rkv_stream *s) -{ - MPP_FREE(s->buf); - - s->p = NULL; - s->p_start = NULL; - //s->p_end = NULL; - - s->i_left = 0; - s->cur_bits = 0; - s->count_bit = 0; - - return MPP_OK; -} - -MPP_RET hal_h264e_rkv_stream_realign(h264e_hal_rkv_stream *s) -{ - RK_S32 offset = (size_t)(s->p) & 3; //used to judge alignment - if (offset) { - s->p = s->p - offset; //move pointer to 32bit aligned pos - s->i_left = (4 - offset) * 8; //init - //s->cur_bits = endian_fix32(M32(s->p)); - s->cur_bits = (*(s->p) << 24) + (*(s->p + 1) << 16) + (*(s->p + 2) << 8) + (*(s->p + 3) << 0); - s->cur_bits >>= (4 - offset) * 8; //shift right the invalid bit - } - - return MPP_OK; -} - -MPP_RET hal_h264e_rkv_stream_write_with_log(h264e_hal_rkv_stream *s, RK_S32 i_count, RK_U32 val, char *name) -{ - RK_U32 i_bits = val; - - h264e_hal_log_header("write bits name %s, count %d, val %d", name, i_count, val); - - s->count_bit += i_count; - if (i_count < s->i_left) { - s->cur_bits = (s->cur_bits << i_count) | i_bits; - s->i_left -= i_count; - } else { - i_count -= s->i_left; - s->cur_bits = (s->cur_bits << s->i_left) | (i_bits >> i_count); - //M32(s->p) = endian_fix32(s->cur_bits); - *(s->p) = 0; - *(s->p) = (s->cur_bits >> 24) & 0xff; - *(s->p + 1) = (s->cur_bits >> 16) & 0xff; - *(s->p + 2) = (s->cur_bits >> 8) & 0xff; - *(s->p + 3) = (s->cur_bits >> 0) & 0xff; - s->p += 4; - s->cur_bits = i_bits; - s->i_left = 32 - i_count; - } - return MPP_OK; -} - -MPP_RET hal_h264e_rkv_stream_write1_with_log(h264e_hal_rkv_stream *s, RK_U32 val, char *name) -{ - RK_U32 i_bit = val; - - h264e_hal_log_header("write 1 bit name %s, val %d", name, val); - - s->count_bit += 1; - s->cur_bits <<= 1; - s->cur_bits |= i_bit; - s->i_left--; - if (s->i_left == 4 * 8 - 32) { - //M32(s->p) = endian_fix32(s->cur_bits); - *(s->p) = (s->cur_bits >> 24) & 0xff; - *(s->p + 1) = (s->cur_bits >> 16) & 0xff; - *(s->p + 2) = (s->cur_bits >> 8) & 0xff; - *(s->p + 3) = (s->cur_bits >> 0) & 0xff; - s->p += 4; - s->i_left = 4 * 8; - } - return MPP_OK; -} - -MPP_RET hal_h264e_rkv_stream_write_ue_with_log(h264e_hal_rkv_stream *s, RK_U32 val, char *name) -{ - RK_S32 size = 0; - RK_S32 tmp = ++val; - - h264e_hal_log_header("write UE bits name %s, val %d (2 steps below are real writting)", name, val); - if (tmp >= 0x10000) { - size = 32; - tmp >>= 16; - } - if (tmp >= 0x100) { - size += 16; - tmp >>= 8; - } - size += h264e_ue_size_tab[tmp]; - - hal_h264e_rkv_stream_write_with_log(s, size >> 1, 0, name); - hal_h264e_rkv_stream_write_with_log(s, (size >> 1) + 1, val, name); - - return MPP_OK; -} - -MPP_RET hal_h264e_rkv_stream_write_se_with_log(h264e_hal_rkv_stream *s, RK_S32 val, char *name) -{ - RK_S32 size = 0; - RK_S32 tmp = 1 - val * 2; - if (tmp < 0) - tmp = val * 2; - - val = tmp; - if (tmp >= 0x100) { - size = 16; - tmp >>= 8; - } - size += h264e_ue_size_tab[tmp]; - - return hal_h264e_rkv_stream_write_with_log(s, size, val, name); -} - -MPP_RET hal_h264e_rkv_stream_write32(h264e_hal_rkv_stream *s, RK_U32 i_bits, char *name) -{ - hal_h264e_rkv_stream_write_with_log(s, 16, i_bits >> 16, name); - hal_h264e_rkv_stream_write_with_log(s, 16, i_bits , name); - - return MPP_OK; -} - -static RK_S32 hal_h264e_rkv_stream_size_se( RK_S32 val ) -{ - RK_S32 tmp = 1 - val * 2; - if ( tmp < 0 ) tmp = val * 2; - if ( tmp < 256 ) - return h264e_ue_size_tab[tmp]; - else - return h264e_ue_size_tab[tmp >> 8] + 16; -} - - -MPP_RET hal_h264e_rkv_stream_rbsp_trailing(h264e_hal_rkv_stream *s) -{ - //align bits, 1+N zeros. - hal_h264e_rkv_stream_write1_with_log(s, 1, "align_1_bit"); - hal_h264e_rkv_stream_write_with_log(s, s->i_left & 7, 0, "align_N_bits"); - - return MPP_OK; -} - -/* Write the rest of cur_bits to the bitstream; results in a bitstream no longer 32-bit aligned. */ -MPP_RET hal_h264e_rkv_stream_flush(h264e_hal_rkv_stream *s) -{ - //do 4 bytes aligned - //M32(s->p) = endian_fix32(s->cur_bits << (s->i_left & 31)); - RK_U32 tmp_bit = s->cur_bits << (s->i_left & 31); - *(s->p) = (tmp_bit >> 24) & 0xff; - *(s->p + 1) = (tmp_bit >> 16) & 0xff; - *(s->p + 2) = (tmp_bit >> 8) & 0xff; - *(s->p + 3) = (tmp_bit >> 0) & 0xff; - s->p += 4 - (s->i_left >> 3);//p point to bit which aligned, rather than the pos next to 4-byte alinged - s->i_left = 4 * 8; - - return MPP_OK; -} - -void hal_h264e_rkv_nals_init(h264e_hal_rkv_extra_info *out) -{ - out->nal_buf = mpp_calloc(RK_U8, 512); - out->nal_num = 0; -} - -void hal_h264e_rkv_nals_deinit(h264e_hal_rkv_extra_info *out) -{ - MPP_FREE(out->nal_buf); - - out->nal_num = 0; -} - -void hal_h264e_rkv_nal_start(h264e_hal_rkv_extra_info *out, RK_S32 i_type, RK_S32 i_ref_idc) -{ - h264e_hal_rkv_stream *s = &out->stream; - RK_U8 *stream_buf = s->p_start; - out->nal[out->nal_num].i_ref_idc = i_ref_idc; - out->nal[out->nal_num].i_type = i_type; - out->nal[out->nal_num].b_long_startcode = 1; - - out->nal[out->nal_num].i_payload = 0; - out->nal[out->nal_num].p_payload = &stream_buf[hal_h264e_rkv_stream_get_pos(s) / 8]; - out->nal[out->nal_num].i_padding = 0; -} - -void hal_h264e_rkv_nal_end(h264e_hal_rkv_extra_info *out) -{ - h264e_hal_rkv_nal *nal = &(out->nal[out->nal_num]); - h264e_hal_rkv_stream *s = &out->stream; - RK_U8 *stream_buf = s->p_start; - RK_U8 *end = &stream_buf[hal_h264e_rkv_stream_get_pos(s) / 8]; - nal->i_payload = (RK_S32)(end - nal->p_payload); - /* Assembly implementation of nal_escape reads past the end of the input. - * While undefined padding wouldn't actually affect the output, it makes valgrind unhappy. */ - memset(end, 0xff, 64); - //if (h->param.nalu_process) - // h->param.nalu_process(h, nal, h->fenc->opaque); - out->nal_num++; - //return x264_nal_check_buffer(h); -} - -RK_U8 *hal_h264e_rkv_nal_escape_c(RK_U8 *dst, RK_U8 *src, RK_U8 *end) -{ - if (src < end) *dst++ = *src++; - if (src < end) *dst++ = *src++; - while (src < end) { - if (src[0] <= 0x03 && !dst[-2] && !dst[-1]) - *dst++ = 0x03; - *dst++ = *src++; - } - return dst; -} - -void hal_h264e_rkv_nal_encode(RK_U8 *dst, h264e_hal_rkv_nal *nal) -{ - RK_S32 b_annexb = 1; - RK_S32 size = 0; - RK_U8 *src = nal->p_payload; - RK_U8 *end = nal->p_payload + nal->i_payload; - RK_U8 *orig_dst = dst; - - if (b_annexb) { - //if (nal->b_long_startcode)//fix by gsl - //*dst++ = 0x00;//fix by gsl - *dst++ = 0x00; - *dst++ = 0x00; - *dst++ = 0x01; - } else /* save room for size later */ - dst += 4; - - /* nal header */ - *dst++ = (0x00 << 7) | (nal->i_ref_idc << 5) | nal->i_type; - - dst = hal_h264e_rkv_nal_escape_c(dst, src, end); - size = (RK_S32)((dst - orig_dst) - 4); - - /* Write the size header for mp4/etc */ - if (!b_annexb) { - /* Size doesn't include the size of the header we're writing now. */ - orig_dst[0] = size >> 24; - orig_dst[1] = size >> 16; - orig_dst[2] = size >> 8; - orig_dst[3] = size >> 0; - } - - nal->i_payload = size + 4; - nal->p_payload = orig_dst; -} - - - -MPP_RET hal_h264e_rkv_encapsulate_nals(h264e_hal_rkv_extra_info *out) -{ - RK_S32 i = 0; - RK_S32 i_avcintra_class = 0; - RK_S32 nal_size = 0; - RK_S32 necessary_size = 0; - RK_U8 *nal_buffer = out->nal_buf; - RK_S32 nal_num = out->nal_num; - h264e_hal_rkv_nal *nal = out->nal; - - h264e_hal_debug_enter(); - - for (i = 0; i < nal_num; i++) - nal_size += nal[i].i_payload; - - /* Worst-case NAL unit escaping: reallocate the buffer if it's too small. */ - necessary_size = nal_size * 3 / 2 + nal_num * 4 + 4 + 64; - for (i = 0; i < nal_num; i++) - necessary_size += nal[i].i_padding; - - for (i = 0; i < nal_num; i++) { - nal[i].b_long_startcode = !i || - nal[i].i_type == RKVENC_NAL_SPS || - nal[i].i_type == RKVENC_NAL_PPS || - i_avcintra_class; - hal_h264e_rkv_nal_encode(nal_buffer, &nal[i]); - nal_buffer += nal[i].i_payload; - } - - h264e_hal_log_header("nals total size: %d bytes", nal_buffer - out->nal_buf); - - h264e_hal_debug_leave(); - - return MPP_OK; -} - - - -MPP_RET hal_h264e_rkv_sps_write(h264e_hal_sps *sps, h264e_hal_rkv_stream *s) -{ - h264e_hal_debug_enter(); - - s->count_bit = 0; - hal_h264e_rkv_stream_realign(s); - hal_h264e_rkv_stream_write_with_log(s, 8, sps->i_profile_idc, "profile_idc"); - hal_h264e_rkv_stream_write1_with_log(s, sps->b_constraint_set0, "constraint_set0_flag"); - hal_h264e_rkv_stream_write1_with_log(s, sps->b_constraint_set1, "constraint_set1_flag"); - hal_h264e_rkv_stream_write1_with_log(s, sps->b_constraint_set2, "constraint_set2_flag"); - hal_h264e_rkv_stream_write1_with_log(s, sps->b_constraint_set3, "constraint_set3_flag"); - - hal_h264e_rkv_stream_write_with_log(s, 4, 0, "reserved_zero_4bits"); - - hal_h264e_rkv_stream_write_with_log(s, 8, sps->i_level_idc, "level_idc"); - - hal_h264e_rkv_stream_write_ue_with_log(s, sps->i_id, "seq_parameter_set_id"); - - if (sps->i_profile_idc >= H264_PROFILE_HIGH) { - hal_h264e_rkv_stream_write_ue_with_log(s, sps->i_chroma_format_idc, "chroma_format_idc"); - if (sps->i_chroma_format_idc == RKV_H264E_CHROMA_444) - hal_h264e_rkv_stream_write1_with_log(s, 0, "separate_colour_plane_flag"); - hal_h264e_rkv_stream_write_ue_with_log(s, H264_BIT_DEPTH - 8, "bit_depth_luma_minus8"); - hal_h264e_rkv_stream_write_ue_with_log(s, H264_BIT_DEPTH - 8, "bit_depth_chroma_minus8"); - hal_h264e_rkv_stream_write1_with_log(s, sps->b_qpprime_y_zero_transform_bypass, "qpprime_y_zero_transform_bypass_flag"); - hal_h264e_rkv_stream_write1_with_log(s, 0, "seq_scaling_matrix_present_flag"); - } - - hal_h264e_rkv_stream_write_ue_with_log(s, sps->i_log2_max_frame_num - 4, "log2_max_frame_num_minus4"); - hal_h264e_rkv_stream_write_ue_with_log(s, sps->i_poc_type, "delta_pic_order_always_zero_flag"); - if (sps->i_poc_type == 0) - hal_h264e_rkv_stream_write_ue_with_log(s, sps->i_log2_max_poc_lsb - 4, "log2_max_pic_order_cnt_lsb_minus4"); - hal_h264e_rkv_stream_write_ue_with_log(s, sps->i_num_ref_frames, "max_num_ref_frames"); - hal_h264e_rkv_stream_write1_with_log(s, sps->b_gaps_in_frame_num_value_allowed, "gaps_in_frame_num_value_allowed_flag"); - hal_h264e_rkv_stream_write_ue_with_log(s, sps->i_mb_width - 1, "pic_width_in_mbs_minus1"); - hal_h264e_rkv_stream_write_ue_with_log(s, (sps->i_mb_height >> !sps->b_frame_mbs_only) - 1, "pic_height_in_map_units_minus1"); - hal_h264e_rkv_stream_write1_with_log(s, sps->b_frame_mbs_only, "frame_mbs_only_flag"); - if (!sps->b_frame_mbs_only) - hal_h264e_rkv_stream_write1_with_log(s, sps->b_mb_adaptive_frame_field, "mb_adaptive_frame_field_flag"); - hal_h264e_rkv_stream_write1_with_log(s, sps->b_direct8x8_inference, "direct_8x8_inference_flag"); - - hal_h264e_rkv_stream_write1_with_log(s, sps->b_crop, "frame_cropping_flag"); - if (sps->b_crop) { - RK_S32 h_shift = sps->i_chroma_format_idc == RKV_H264E_CHROMA_420 || sps->i_chroma_format_idc == RKV_H264E_CHROMA_422; - RK_S32 v_shift = sps->i_chroma_format_idc == RKV_H264E_CHROMA_420; - hal_h264e_rkv_stream_write_ue_with_log(s, sps->crop.i_left >> h_shift, "frame_crop_left_offset"); - hal_h264e_rkv_stream_write_ue_with_log(s, sps->crop.i_right >> h_shift, "frame_crop_right_offset"); - hal_h264e_rkv_stream_write_ue_with_log(s, sps->crop.i_top >> v_shift, "frame_crop_top_offset"); - hal_h264e_rkv_stream_write_ue_with_log(s, sps->crop.i_bottom >> v_shift, "frame_crop_bottom_offset"); - } - - hal_h264e_rkv_stream_write1_with_log(s, sps->b_vui, "vui_parameters_present_flag"); - if (sps->b_vui) { - hal_h264e_rkv_stream_write1_with_log(s, sps->vui.b_aspect_ratio_info_present, "aspect_ratio_info_present_flag"); - if (sps->vui.b_aspect_ratio_info_present) { - RK_S32 i = 0; - static const struct { RK_U8 w, h, sar; } sar[] = { - // aspect_ratio_idc = 0 -> unspecified - { 1, 1, 1 }, { 12, 11, 2 }, { 10, 11, 3 }, { 16, 11, 4 }, - { 40, 33, 5 }, { 24, 11, 6 }, { 20, 11, 7 }, { 32, 11, 8 }, - { 80, 33, 9 }, { 18, 11, 10 }, { 15, 11, 11 }, { 64, 33, 12 }, - { 160, 99, 13 }, { 4, 3, 14 }, { 3, 2, 15 }, { 2, 1, 16 }, - // aspect_ratio_idc = [17..254] -> reserved - { 0, 0, 255 } - }; - for (i = 0; sar[i].sar != 255; i++) { - if (sar[i].w == sps->vui.i_sar_width && - sar[i].h == sps->vui.i_sar_height) - break; - } - hal_h264e_rkv_stream_write_with_log(s, 8, sar[i].sar, "aspect_ratio_idc"); - if (sar[i].sar == 255) { /* aspect_ratio_idc (extended) */ - hal_h264e_rkv_stream_write_with_log(s, 16, sps->vui.i_sar_width, "sar_width"); - hal_h264e_rkv_stream_write_with_log(s, 16, sps->vui.i_sar_height, "sar_height"); - } - } - - hal_h264e_rkv_stream_write1_with_log(s, sps->vui.b_overscan_info_present, "overscan_info_present_flag"); - if (sps->vui.b_overscan_info_present) - hal_h264e_rkv_stream_write1_with_log(s, sps->vui.b_overscan_info, "overscan_appropriate_flag"); - - hal_h264e_rkv_stream_write1_with_log(s, sps->vui.b_signal_type_present, "video_signal_type_present_flag"); - if (sps->vui.b_signal_type_present) { - hal_h264e_rkv_stream_write_with_log(s, 3, sps->vui.i_vidformat, "video_format"); - hal_h264e_rkv_stream_write1_with_log(s, sps->vui.b_fullrange, "video_full_range_flag"); - hal_h264e_rkv_stream_write1_with_log(s, sps->vui.b_color_description_present, "colour_description_present_flag"); - if (sps->vui.b_color_description_present) { - hal_h264e_rkv_stream_write_with_log(s, 8, sps->vui.i_colorprim, "colour_primaries"); - hal_h264e_rkv_stream_write_with_log(s, 8, sps->vui.i_transfer, "transfer_characteristics"); - hal_h264e_rkv_stream_write_with_log(s, 8, sps->vui.i_colmatrix, "matrix_coefficients"); - } - } - - hal_h264e_rkv_stream_write1_with_log(s, sps->vui.b_chroma_loc_info_present, "chroma_loc_info_present_flag"); - if (sps->vui.b_chroma_loc_info_present) { - hal_h264e_rkv_stream_write_ue_with_log(s, sps->vui.i_chroma_loc_top, "chroma_loc_info_present_flag"); - hal_h264e_rkv_stream_write_ue_with_log(s, sps->vui.i_chroma_loc_bottom, "chroma_sample_loc_type_bottom_field"); - } - - hal_h264e_rkv_stream_write1_with_log(s, sps->vui.b_timing_info_present, "chroma_sample_loc_type_bottom_field"); - if (sps->vui.b_timing_info_present) { - hal_h264e_rkv_stream_write32(s, sps->vui.i_num_units_in_tick, "num_units_in_tick"); - hal_h264e_rkv_stream_write32(s, sps->vui.i_time_scale, "time_scale"); - hal_h264e_rkv_stream_write1_with_log(s, sps->vui.b_fixed_frame_rate, "fixed_frame_rate_flag"); - } - - hal_h264e_rkv_stream_write1_with_log(s, sps->vui.b_nal_hrd_parameters_present, "time_scale"); - if (sps->vui.b_nal_hrd_parameters_present) { - hal_h264e_rkv_stream_write_ue_with_log(s, sps->vui.hrd.i_cpb_cnt - 1, "cpb_cnt_minus1"); - hal_h264e_rkv_stream_write_with_log(s, 4, sps->vui.hrd.i_bit_rate_scale, "bit_rate_scale"); - hal_h264e_rkv_stream_write_with_log(s, 4, sps->vui.hrd.i_cpb_size_scale, "cpb_size_scale"); - - hal_h264e_rkv_stream_write_ue_with_log(s, sps->vui.hrd.i_bit_rate_value - 1, "bit_rate_value_minus1"); - hal_h264e_rkv_stream_write_ue_with_log(s, sps->vui.hrd.i_cpb_size_value - 1, "cpb_size_value_minus1"); - - hal_h264e_rkv_stream_write1_with_log(s, sps->vui.hrd.b_cbr_hrd, "cbr_flag"); - - hal_h264e_rkv_stream_write_with_log(s, 5, sps->vui.hrd.i_initial_cpb_removal_delay_length - 1, "initial_cpb_removal_delay_length_minus1"); - hal_h264e_rkv_stream_write_with_log(s, 5, sps->vui.hrd.i_cpb_removal_delay_length - 1, "cpb_removal_delay_length_minus1"); - hal_h264e_rkv_stream_write_with_log(s, 5, sps->vui.hrd.i_dpb_output_delay_length - 1, "dpb_output_delay_length_minus1"); - hal_h264e_rkv_stream_write_with_log(s, 5, sps->vui.hrd.i_time_offset_length, "time_offset_length"); - } - - hal_h264e_rkv_stream_write1_with_log(s, sps->vui.b_vcl_hrd_parameters_present, "vcl_hrd_parameters_present_flag"); - - if (sps->vui.b_nal_hrd_parameters_present || sps->vui.b_vcl_hrd_parameters_present) - hal_h264e_rkv_stream_write1_with_log(s, 0, "low_delay_hrd_flag"); /* low_delay_hrd_flag */ - - hal_h264e_rkv_stream_write1_with_log(s, sps->vui.b_pic_struct_present, "pic_struct_present_flag"); - hal_h264e_rkv_stream_write1_with_log(s, sps->vui.b_bitstream_restriction, "bitstream_restriction_flag"); - if (sps->vui.b_bitstream_restriction) { - hal_h264e_rkv_stream_write1_with_log(s, sps->vui.b_motion_vectors_over_pic_boundaries, "motion_vectors_over_pic_boundaries_flag"); - hal_h264e_rkv_stream_write_ue_with_log(s, sps->vui.i_max_bytes_per_pic_denom, "max_bytes_per_pic_denom"); - hal_h264e_rkv_stream_write_ue_with_log(s, sps->vui.i_max_bits_per_mb_denom, "max_bits_per_mb_denom"); - hal_h264e_rkv_stream_write_ue_with_log(s, sps->vui.i_log2_max_mv_length_horizontal, "log2_max_mv_length_horizontal"); - hal_h264e_rkv_stream_write_ue_with_log(s, sps->vui.i_log2_max_mv_length_vertical, "log2_max_mv_length_vertical"); - hal_h264e_rkv_stream_write_ue_with_log(s, sps->vui.i_num_reorder_frames, "max_num_reorder_frames"); - hal_h264e_rkv_stream_write_ue_with_log(s, sps->vui.i_max_dec_frame_buffering, "max_num_reorder_frames"); - } - } - hal_h264e_rkv_stream_rbsp_trailing(s); - hal_h264e_rkv_stream_flush(s); - - h264e_hal_log_header("write pure sps head size: %d bits", s->count_bit); - - h264e_hal_debug_leave(); - - return MPP_OK; -} - - -/* -static void transpose( RK_U8 *buf, RK_S32 w ) -{ - RK_S32 i=0, j=0; - for(i = 0; i < w; i++ ) - for(j = 0; j < i; j++ ) - MPP_SWAP( RK_U8, buf[w*i+j], buf[w*j+i] ); -} -*/ - -MPP_RET hal_h264e_rkv_set_pps(h264e_hal_pps *pps, h264e_hal_param *par, h264e_control_extra_info_cfg *cfg, h264e_hal_sps *sps) -{ - RK_S32 k = 0; - RK_S32 i_avcintra_class = 0; - RK_S32 b_interlaced = 0; - RK_S32 analyse_weighted_pred = 0; - RK_S32 analyse_b_weighted_bipred = 0; - RK_S32 pps_init_qp = -1; //TODO: merge with syn - RK_S32 Sw_deblock_filter_ctrl_present_flag = 1; - RK_S32 b_cqm_preset = 0; - - pps->i_id = cfg->pps_id; - pps->i_sps_id = sps->i_id; - pps->b_cabac = cfg->enable_cabac; - - pps->b_pic_order = !i_avcintra_class && b_interlaced; - pps->i_num_slice_groups = 1; - - pps->i_num_ref_idx_l0_default_active = 1; - pps->i_num_ref_idx_l1_default_active = 1; - - pps->b_weighted_pred = analyse_weighted_pred > 0; - pps->i_weighted_bipred_idc = analyse_b_weighted_bipred ? 2 : 0; - - pps->i_pic_init_qp = cfg->pic_init_qp; - if (pps_init_qp >= 0 && pps_init_qp <= 51) { - pps->i_pic_init_qp = pps_init_qp; - } - pps->i_pic_init_qs = 26 + H264_QP_BD_OFFSET; - - pps->i_chroma_qp_index_offset = 0; //TODO: cfg->chroma_qp_index_offset; - pps->i_second_chroma_qp_index_offset = 0; //TODO: cfg->second_chroma_qp_index_offset; - pps->b_deblocking_filter_control = Sw_deblock_filter_ctrl_present_flag; - pps->b_constrained_intra_pred = par->constrained_intra; - pps->b_redundant_pic_cnt = 0; - - pps->b_transform_8x8_mode = sps->i_profile_idc >= H264_PROFILE_HIGH; //TODO: cfg->transform8x8_mode ? 1 : 0; - - pps->b_cqm_preset = b_cqm_preset; - - switch ( pps->b_cqm_preset ) { - case RKV_H264E_CQM_FLAT: - for (k = 0; k < 8; k++ ) - pps->scaling_list[k] = h264e_rkv_cqm_flat16; - break; - case RKV_H264E_CQM_JVT: - for (k = 0; k < 8; k++ ) - pps->scaling_list[k] = h264e_rkv_cqm_jvt[k]; - break; - case RKV_H264E_CQM_CUSTOM: - /* match the transposed DCT & zigzag */ - h264e_hal_log_err("CQM_CUSTOM mode is not supported now"); - return MPP_NOK; - //break; - default: - h264e_hal_log_err("invalid cqm_preset mode"); - return MPP_NOK; - //break; - } - - return MPP_OK; -} - -static void hal_h264e_rkv_scaling_list_write( h264e_hal_rkv_stream *s, h264e_hal_pps *pps, RK_S32 idx ) -{ - RK_S32 k = 0; - const RK_S32 len = idx < 4 ? 16 : 64; - const RK_U8 *zigzag = idx < 4 ? h264e_rkv_zigzag_scan4[0] : h264e_rkv_zigzag_scan8[0]; - const RK_U8 *list = pps->scaling_list[idx]; - const RK_U8 *def_list = (idx == RKV_H264E_CQM_4IC) ? pps->scaling_list[RKV_H264E_CQM_4IY] - : (idx == RKV_H264E_CQM_4PC) ? pps->scaling_list[RKV_H264E_CQM_4PY] - : (idx == RKV_H264E_CQM_8IC + 4) ? pps->scaling_list[RKV_H264E_CQM_8IY + 4] - : (idx == RKV_H264E_CQM_8PC + 4) ? pps->scaling_list[RKV_H264E_CQM_8PY + 4] - : h264e_rkv_cqm_jvt[idx]; - if ( !memcmp( list, def_list, len ) ) - hal_h264e_rkv_stream_write1_with_log( s, 0, "scaling_list_present_flag"); // scaling_list_present_flag - else if ( !memcmp( list, h264e_rkv_cqm_jvt[idx], len ) ) { - hal_h264e_rkv_stream_write1_with_log( s, 1, "scaling_list_present_flag"); // scaling_list_present_flag - hal_h264e_rkv_stream_write_se_with_log( s, -8, "use_jvt_list"); // use jvt list - } else { - RK_S32 run; - hal_h264e_rkv_stream_write1_with_log( s, 1, "scaling_list_present_flag"); // scaling_list_present_flag - - // try run-length compression of trailing values - for ( run = len; run > 1; run-- ) - if ( list[zigzag[run - 1]] != list[zigzag[run - 2]] ) - break; - if ( run < len && len - run < hal_h264e_rkv_stream_size_se( (RK_S8) - list[zigzag[run]] ) ) - run = len; - - for ( k = 0; k < run; k++ ) - hal_h264e_rkv_stream_write_se_with_log( s, (RK_S8)(list[zigzag[k]] - (k > 0 ? list[zigzag[k - 1]] : 8)), "delta_scale"); // delta - - if ( run < len ) - hal_h264e_rkv_stream_write_se_with_log( s, (RK_S8) - list[zigzag[run]], "-scale"); - } -} - -MPP_RET hal_h264e_rkv_pps_write(h264e_hal_pps *pps, h264e_hal_sps *sps, h264e_hal_rkv_stream *s) -{ - h264e_hal_debug_enter(); - - s->count_bit = 0; - hal_h264e_rkv_stream_realign( s ); - - hal_h264e_rkv_stream_write_ue_with_log( s, pps->i_id, "pic_parameter_set_id"); - hal_h264e_rkv_stream_write_ue_with_log( s, pps->i_sps_id, "seq_parameter_set_id"); - - hal_h264e_rkv_stream_write1_with_log( s, pps->b_cabac, "entropy_coding_mode_flag"); - hal_h264e_rkv_stream_write1_with_log( s, pps->b_pic_order, "bottom_field_pic_order_in_frame_present_flag"); - hal_h264e_rkv_stream_write_ue_with_log( s, pps->i_num_slice_groups - 1, "num_slice_groups_minus1"); - - hal_h264e_rkv_stream_write_ue_with_log( s, pps->i_num_ref_idx_l0_default_active - 1, "num_ref_idx_l0_default_active_minus1"); - hal_h264e_rkv_stream_write_ue_with_log( s, pps->i_num_ref_idx_l1_default_active - 1, "num_ref_idx_l1_default_active_minus1"); - hal_h264e_rkv_stream_write1_with_log( s, pps->b_weighted_pred, "weighted_pred_flag"); - hal_h264e_rkv_stream_write_with_log( s, 2, pps->i_weighted_bipred_idc, "weighted_bipred_idc"); - - hal_h264e_rkv_stream_write_se_with_log( s, pps->i_pic_init_qp - 26 - H264_QP_BD_OFFSET, "pic_init_qp_minus26"); - hal_h264e_rkv_stream_write_se_with_log( s, pps->i_pic_init_qs - 26 - H264_QP_BD_OFFSET, "pic_init_qs_minus26"); - hal_h264e_rkv_stream_write_se_with_log( s, pps->i_chroma_qp_index_offset, "chroma_qp_index_offset"); - - hal_h264e_rkv_stream_write1_with_log( s, pps->b_deblocking_filter_control, "deblocking_filter_control_present_flag"); - hal_h264e_rkv_stream_write1_with_log( s, pps->b_constrained_intra_pred, "constrained_intra_pred_flag"); - hal_h264e_rkv_stream_write1_with_log( s, pps->b_redundant_pic_cnt, "redundant_pic_cnt_present_flag"); - - if ( pps->b_transform_8x8_mode || pps->b_cqm_preset != RKV_H264E_CQM_FLAT ) { - hal_h264e_rkv_stream_write1_with_log( s, pps->b_transform_8x8_mode, "transform_8x8_mode_flag"); - hal_h264e_rkv_stream_write1_with_log( s, (pps->b_cqm_preset != RKV_H264E_CQM_FLAT), "pic_scaling_matrix_present_flag"); - if ( pps->b_cqm_preset != RKV_H264E_CQM_FLAT ) { - hal_h264e_rkv_scaling_list_write( s, pps, RKV_H264E_CQM_4IY); - hal_h264e_rkv_scaling_list_write( s, pps, RKV_H264E_CQM_4IC ); - hal_h264e_rkv_stream_write1_with_log( s, 0, "scaling_list_end_flag"); // Cr = Cb TODO:replaced with real name - hal_h264e_rkv_scaling_list_write( s, pps, RKV_H264E_CQM_4PY ); - hal_h264e_rkv_scaling_list_write( s, pps, RKV_H264E_CQM_4PC ); - hal_h264e_rkv_stream_write1_with_log( s, 0, "scaling_list_end_flag"); // Cr = Cb TODO:replaced with real name - if ( pps->b_transform_8x8_mode ) { - if ( sps->i_chroma_format_idc == RKV_H264E_CHROMA_444 ) { - hal_h264e_rkv_scaling_list_write( s, pps, RKV_H264E_CQM_8IY + 4 ); - hal_h264e_rkv_scaling_list_write( s, pps, RKV_H264E_CQM_8IC + 4 ); - hal_h264e_rkv_stream_write1_with_log( s, 0, "scaling_list_end_flag" ); // Cr = Cb TODO:replaced with real name - hal_h264e_rkv_scaling_list_write( s, pps, RKV_H264E_CQM_8PY + 4 ); - hal_h264e_rkv_scaling_list_write( s, pps, RKV_H264E_CQM_8PC + 4 ); - hal_h264e_rkv_stream_write1_with_log( s, 0, "scaling_list_end_flag" ); // Cr = Cb TODO:replaced with real name - } else { - hal_h264e_rkv_scaling_list_write( s, pps, RKV_H264E_CQM_8IY + 4 ); - hal_h264e_rkv_scaling_list_write( s, pps, RKV_H264E_CQM_8PY + 4 ); - } - } - } - hal_h264e_rkv_stream_write_se_with_log( s, pps->i_second_chroma_qp_index_offset, "second_chroma_qp_index_offset"); - } - - hal_h264e_rkv_stream_rbsp_trailing( s ); - hal_h264e_rkv_stream_flush( s ); - - h264e_hal_log_header("write pure pps size: %d bits", s->count_bit); - - h264e_hal_debug_leave(); - - return MPP_OK; -} - -static MPP_RET hal_h264e_rkv_init_extra_info(h264e_hal_rkv_extra_info *extra_info) -{ - hal_h264e_rkv_nals_init(extra_info); - hal_h264e_rkv_stream_init(&extra_info->stream); - - return MPP_OK; -} - -static MPP_RET hal_h264e_rkv_deinit_extra_info(void *extra_info) -{ - h264e_hal_rkv_extra_info *info = (h264e_hal_rkv_extra_info *)extra_info; - hal_h264e_rkv_stream_deinit(&info->stream); - hal_h264e_rkv_nals_deinit(info); - - return MPP_OK; -} - -static MPP_RET hal_h264e_rkv_set_extra_info(h264e_hal_context *ctx, void *param) -{ - h264e_control_extra_info_cfg *cfg = (h264e_control_extra_info_cfg *)param; - h264e_hal_param *par = &ctx->param; - h264e_hal_rkv_extra_info *info = (h264e_hal_rkv_extra_info *)ctx->extra_info; - h264e_hal_sps *sps_info = &info->sps; - h264e_hal_pps *pps_info = &info->pps; - - h264e_hal_debug_enter(); - hal_h264e_rkv_dump_mpp_extra_info_cfg(ctx, cfg); - - info->nal_num = 0; - hal_h264e_rkv_stream_reset(&info->stream); - - hal_h264e_rkv_nal_start(info, RKVENC_NAL_SPS, RKVENC_NAL_PRIORITY_HIGHEST); - hal_h264e_rkv_set_sps(sps_info, par, cfg); - hal_h264e_rkv_sps_write(sps_info, &info->stream); - hal_h264e_rkv_nal_end(info); - - hal_h264e_rkv_nal_start(info, RKVENC_NAL_PPS, RKVENC_NAL_PRIORITY_HIGHEST); - hal_h264e_rkv_set_pps(pps_info, par, cfg, sps_info); - hal_h264e_rkv_pps_write(pps_info, sps_info, &info->stream); - hal_h264e_rkv_nal_end(info); - - hal_h264e_rkv_encapsulate_nals(info); - - h264e_hal_debug_leave(); - - return MPP_OK; -} - - -static void hal_h264e_rkv_reference_deinit( h264e_hal_rkv_dpb_ctx *dpb_ctx) -{ - h264e_hal_rkv_dpb_ctx *d_ctx = (h264e_hal_rkv_dpb_ctx *)dpb_ctx; - - h264e_hal_debug_enter(); - - MPP_FREE(d_ctx->frames.unused); - - h264e_hal_debug_leave(); -} - - -static void hal_h264e_rkv_reference_init( void *dpb, h264e_hal_param *par) -{ - //RK_S32 k = 0; - h264e_hal_rkv_dpb_ctx *dpb_ctx = (h264e_hal_rkv_dpb_ctx *)dpb; - h264e_hal_ref_param *ref_cfg = &par->ref; - - h264e_hal_debug_enter(); - memset(dpb_ctx, 0, sizeof(h264e_hal_rkv_dpb_ctx)); - - dpb_ctx->frames.unused = mpp_calloc(h264e_hal_rkv_frame *, H264E_REF_MAX + 1); - //for(k=0; kframes.reference[k] = &dpb_ctx->frame_buf[k]; - // h264e_hal_log_dpb("dpb_ctx->frames.reference[%d]: %p", k, dpb_ctx->frames.reference[k]); - //} - dpb_ctx->i_long_term_reference_flag = ref_cfg->i_long_term_en; - dpb_ctx->i_tmp_idr_pic_id = 0; - - h264e_hal_debug_leave(); -} - -MPP_RET hal_h264e_rkv_init(void *hal, MppHalCfg *cfg) -{ - h264e_hal_context *ctx = (h264e_hal_context *)hal; - h264e_hal_rkv_dpb_ctx *dpb_ctx = NULL; - h264e_hal_debug_enter(); - - hal_h264e_rkv_set_param(&ctx->param); - - ctx->ioctl_input = mpp_calloc(h264e_rkv_ioctl_input, 1); - ctx->ioctl_output = mpp_calloc(h264e_rkv_ioctl_output, 1); - ctx->regs = mpp_calloc(h264e_rkv_reg_set, RKV_H264E_LINKTABLE_FRAME_NUM); - ctx->buffers = mpp_calloc(h264e_hal_rkv_buffers, 1); - ctx->extra_info = mpp_calloc(h264e_hal_rkv_extra_info, 1); - ctx->dpb_ctx = mpp_calloc(h264e_hal_rkv_dpb_ctx, 1); - ctx->dump_files = mpp_calloc(h264e_hal_rkv_dump_files, 1); - ctx->param_size = H264E_MAX_PACKETED_PARAM_SIZE; - ctx->param_buf = mpp_calloc_size(void, ctx->param_size); - mpp_packet_init(&ctx->packeted_param, ctx->param_buf, ctx->param_size); - hal_h264e_rkv_open_dump_files(ctx->dump_files); - hal_h264e_rkv_init_extra_info(ctx->extra_info); - hal_h264e_rkv_reference_init(ctx->dpb_ctx, &ctx->param); - - ctx->int_cb = cfg->hal_int_cb; - ctx->frame_cnt = 0; - ctx->frame_cnt_gen_ready = 0; - ctx->frame_cnt_send_ready = 0; - ctx->num_frames_to_send = 1; - - /* support multi-refs */ - dpb_ctx = (h264e_hal_rkv_dpb_ctx *)ctx->dpb_ctx; - dpb_ctx->i_frame_cnt = 0; - dpb_ctx->i_frame_num = 0; - - ctx->vpu_socket = -1; - ctx->vpu_client = VPU_ENC_RKV; - h264e_hal_log_detail("vpu client: %d", ctx->vpu_client); -#ifdef RKPLATFORM - if (ctx->vpu_socket <= 0) { - ctx->vpu_socket = VPUClientInit(ctx->vpu_client); - if (ctx->vpu_socket <= 0) { - h264e_hal_log_err("get vpu_socket(%d) <=0, failed. \n", ctx->vpu_socket); - return MPP_ERR_UNKNOW; - } else { - VPUHwEncConfig_t hwCfg; - h264e_hal_log_detail("get vpu_socket(%d), success. \n", ctx->vpu_socket); - memset(&hwCfg, 0, sizeof(VPUHwEncConfig_t)); - if (VPUClientGetHwCfg(ctx->vpu_socket, (RK_U32*)&hwCfg, sizeof(hwCfg))) { - h264e_hal_log_err("h264enc # Get HwCfg failed, release vpu\n"); - VPUClientRelease(ctx->vpu_socket); - return MPP_NOK; - } - } - } -#endif - - h264e_hal_debug_leave(); - return MPP_OK; -} - -MPP_RET hal_h264e_rkv_deinit(void *hal) -{ - h264e_hal_context *ctx = (h264e_hal_context *)hal; - h264e_hal_debug_enter(); - - MPP_FREE(ctx->regs); - MPP_FREE(ctx->ioctl_input); - MPP_FREE(ctx->ioctl_output); - - if (ctx->buffers) { - hal_h264e_rkv_free_buffers(ctx); - MPP_FREE(ctx->buffers); - } - - if (ctx->extra_info) { - hal_h264e_rkv_deinit_extra_info(ctx->extra_info); - MPP_FREE(ctx->extra_info); - } - - if (ctx->packeted_param) { - mpp_packet_deinit(&ctx->packeted_param); - ctx->packeted_param = NULL; - } - - if (ctx->param_buf) { - mpp_free(ctx->param_buf); - ctx->param_buf = NULL; - } - - ctx->param_size = 0; - - if (ctx->dpb_ctx) { - hal_h264e_rkv_reference_deinit(ctx->dpb_ctx); - MPP_FREE(ctx->dpb_ctx); - } - - if (ctx->dump_files) { - hal_h264e_rkv_close_dump_files(ctx->dump_files); - MPP_FREE(ctx->dump_files); - } - -#ifdef RKPLATFORM - if (ctx->vpu_socket <= 0) { - h264e_hal_log_err("invalid vpu socket: %d", ctx->vpu_socket); - return MPP_NOK; - } - - if (VPU_SUCCESS != VPUClientRelease(ctx->vpu_socket)) { - h264e_hal_log_err("VPUClientRelease failed"); - return MPP_ERR_VPUHW; - } -#endif - - - h264e_hal_debug_leave(); - return MPP_OK; -} - - -MPP_RET hal_h264e_rkv_set_ioctl_extra_info(h264e_rkv_ioctl_extra_info *extra_info, h264e_syntax *syn) -{ - h264e_rkv_ioctl_extra_info_elem *info = NULL; - RK_U32 frame_size = syn->pic_luma_width * syn->pic_luma_height; // TODO: according to yuv format - - extra_info->magic = 0; - extra_info->cnt = 2; - - /* input cb addr */ - info = &extra_info->elem[0]; - info->reg_idx = 71; - info->offset = frame_size; - - /* input cr addr */ - info = &extra_info->elem[1]; - info->reg_idx = 72; - info->offset = frame_size * 5 / 4; //TODO: relevant with YUV format - return MPP_OK; -} - -static MPP_RET hal_h264e_rkv_validate_syntax(h264e_syntax *syn, h264e_hal_rkv_csp_info *src_fmt, RK_U32 gop_start) -{ - RK_U32 input_image_format = syn->input_image_format; - h264e_hal_debug_enter(); - - /* validate */ - H264E_HAL_VALIDATE_GT(syn->output_strm_limit_size, "output_strm_limit_size", 0); - - /* adjust */ - *src_fmt = hal_h264e_rkv_convert_csp(input_image_format); - syn->input_image_format = src_fmt->fmt; - - syn->input_cb_addr = syn->input_luma_addr; - syn->input_cr_addr = syn->input_luma_addr; - - H264E_HAL_VALIDATE_NEQ(syn->input_image_format, "input_image_format", H264E_RKV_CSP_NONE); - if (syn->frame_coding_type == 1) { /* ASIC_INTRA */ - if (gop_start) - syn->frame_coding_type = RKVENC_FRAME_TYPE_IDR; - else - syn->frame_coding_type = RKVENC_FRAME_TYPE_I; - } else { /* ASIC_INTER */ - syn->frame_coding_type = RKVENC_FRAME_TYPE_P; - } - - h264e_hal_debug_leave(); - return MPP_OK; -} - -MPP_RET hal_h264e_rkv_set_rc_regs(h264e_rkv_reg_set *regs, h264e_syntax *syn, - h264e_hal_rkv_coveragetest_cfg *test) -{ - if (test && test->mbrc) { - RK_U32 num_mbs_oneframe = (syn->pic_luma_width + 15) / 16 * ((syn->pic_luma_height + 15) / 16); - RK_U32 frame_target_bitrate = (syn->pic_luma_width * syn->pic_luma_height / 1920 / 1080) * 10000000 / 8; //Bytes - RK_U32 frame_target_size = frame_target_bitrate / syn->keyframe_max_interval; - RK_U32 mb_target_size = frame_target_size / num_mbs_oneframe; - RK_U32 aq_strength = 2; - - h264e_hal_log_detail("---- test-mbrc ----"); - regs->swreg46.rc_en = 1; - regs->swreg46.rc_mode = 1; //0:frame/slice rc; 1:mbrc - regs->swreg46.aqmode_en = 1; - regs->swreg46.aq_strg = (RK_U32)(aq_strength * 1.0397 * 256); - regs->swreg46.Reserved = 0x0; - regs->swreg46.rc_ctu_num = (syn->pic_luma_width + 15) / 16; - - regs->swreg47.bits_error0 = ((mb_target_size >> 4) * num_mbs_oneframe / 2) * -192; //sw_bits_error[0]; - regs->swreg47.bits_error1 = ((mb_target_size >> 4) * num_mbs_oneframe / 2) * -144; //sw_bits_error[1]; - regs->swreg48.bits_error2 = ((mb_target_size >> 4) * num_mbs_oneframe / 2) * -96; //sw_bits_error[2]; - regs->swreg48.bits_error3 = ((mb_target_size >> 4) * num_mbs_oneframe / 2) * -16; //sw_bits_error[3]; - regs->swreg49.bits_error4 = ((mb_target_size >> 4) * num_mbs_oneframe / 2) * 16; //sw_bits_error[4]; - regs->swreg49.bits_error5 = ((mb_target_size >> 4) * num_mbs_oneframe / 2) * 96; //sw_bits_error[5]; - regs->swreg50.bits_error6 = ((mb_target_size >> 4) * num_mbs_oneframe / 2) * 144; //sw_bits_error[6]; - regs->swreg50.bits_error7 = ((mb_target_size >> 4) * num_mbs_oneframe / 2) * 192; //sw_bits_error[7]; - regs->swreg51.bits_error8 = ((mb_target_size >> 4) * num_mbs_oneframe / 2) * 256; //sw_bits_error[8]; - - regs->swreg52.qp_adjuest0 = -4; //sw_qp_adjuest[0]; - regs->swreg52.qp_adjuest1 = -3; //sw_qp_adjuest[1]; - regs->swreg52.qp_adjuest2 = -2; //sw_qp_adjuest[2]; - regs->swreg52.qp_adjuest3 = -1; //sw_qp_adjuest[3]; - regs->swreg52.qp_adjuest4 = 0; //sw_qp_adjuest[4]; - regs->swreg52.qp_adjuest5 = 1; //sw_qp_adjuest[5]; - regs->swreg53.qp_adjuest6 = 2; //sw_qp_adjuest[6]; - regs->swreg53.qp_adjuest7 = 3; //sw_qp_adjuest[7]; - regs->swreg53.qp_adjuest8 = 4; //sw_qp_adjuest[8]; - - regs->swreg54.rc_qp_mod = 2; //sw_quality_flag; - regs->swreg54.rc_fact0 = 8; //sw_quality_factor_0; - regs->swreg54.rc_fact1 = 8; //sw_quality_factor_1; - regs->swreg54.Reserved = 0x0; - regs->swreg54.rc_qp_range = 4; //sw_rc_clip_qp_range; + + memcpy(sw_buf, hw_buf_vir_addr, strm_size); + + fwrite(sw_buf, 1, strm_size, fp); + + if (sw_buf) + mpp_free(sw_buf); + } + fflush(fp); + } else { + h264e_hal_log_file("try to dump data to mpp_strm_out.txt, but file is not opened"); + } +#else + (void)ctx; + (void)hw_buf; +#endif +} + +void hal_h264e_rkv_frame_push( h264e_hal_rkv_frame **list, h264e_hal_rkv_frame *frame ) +{ + RK_S32 i = 0; + while ( list[i] ) i++; + list[i] = frame; + h264e_hal_log_dpb("frame push list[%d] %p", i, frame); + +} + +static h264e_hal_rkv_frame *hal_h264e_rkv_frame_new(h264e_hal_rkv_dpb_ctx *dpb_ctx) +{ + RK_S32 k = 0; + h264e_hal_rkv_frame *frame_buf = dpb_ctx->frame_buf; + RK_S32 num_buf = MPP_ARRAY_ELEMS(dpb_ctx->frame_buf); + h264e_hal_rkv_frame *new_frame = NULL; + h264e_hal_debug_enter(); + for (k = 0; k < num_buf; k++) { + if (!frame_buf[k].hw_buf_used) { + new_frame = &frame_buf[k]; + frame_buf[k].hw_buf_used = 1; + break; + } + } + + if (!new_frame) { + h264e_hal_log_err("!new_frame, new_frame get failed"); + return NULL; + } + + h264e_hal_debug_leave(); + return new_frame; +} + +h264e_hal_rkv_frame *hal_h264e_rkv_frame_pop( h264e_hal_rkv_frame **list ) +{ + h264e_hal_rkv_frame *frame; + RK_S32 i = 0; + mpp_assert( list[0] ); + while ( list[i + 1] ) i++; + frame = list[i]; + list[i] = NULL; + h264e_hal_log_dpb("frame pop list[%d] %p", i, frame); + return frame; +} + +void hal_h264e_rkv_frame_unshift( h264e_hal_rkv_frame **list, h264e_hal_rkv_frame *frame ) +{ + RK_S32 i = 0; + while ( list[i] ) i++; + while ( i-- ) + list[i + 1] = list[i]; + list[0] = frame; + h264e_hal_log_dpb("frame unshift list[0] %p", frame); +} + +h264e_hal_rkv_frame *hal_h264e_rkv_frame_shift( h264e_hal_rkv_frame **list ) +{ + h264e_hal_rkv_frame *frame = list[0]; + RK_S32 i; + for ( i = 0; list[i]; i++ ) + list[i] = list[i + 1]; + mpp_assert(frame); + h264e_hal_log_dpb("frame shift list[0] %p", frame); + return frame; +} + + +void hal_h264e_rkv_frame_push_unused( h264e_hal_rkv_dpb_ctx *dpb_ctx, h264e_hal_rkv_frame *frame ) +{ + h264e_hal_debug_enter(); + mpp_assert( frame->i_reference_count > 0 ); + frame->i_reference_count--; + if ( frame->i_reference_count == 0 ) + hal_h264e_rkv_frame_push( dpb_ctx->frames.unused, frame ); + h264e_hal_debug_leave(); +} + +h264e_hal_rkv_frame *hal_h264e_rkv_frame_pop_unused( h264e_hal_context *ctx) +{ + h264e_hal_rkv_frame *frame = NULL; + + h264e_hal_rkv_dpb_ctx *dpb_ctx = (h264e_hal_rkv_dpb_ctx *)ctx->dpb_ctx; + + h264e_hal_debug_enter(); + if ( dpb_ctx->frames.unused[0] ) + frame = hal_h264e_rkv_frame_pop( dpb_ctx->frames.unused ); + else { + frame = hal_h264e_rkv_frame_new( dpb_ctx ); + } + + if ( !frame ) { + h264e_hal_log_err("!frame, return NULL"); + return NULL; + } + frame->i_reference_count = 1; + frame->b_keyframe = 0; + frame->b_corrupt = 0; + frame->long_term_flag = 0; + frame->reorder_longterm_flag = 0; + + h264e_hal_debug_leave(); + + return frame; +} + +static void hal_h264e_rkv_reference_reset( h264e_hal_rkv_dpb_ctx *dpb_ctx ) +{ + h264e_hal_debug_enter(); + while ( dpb_ctx->frames.reference[0] ) + hal_h264e_rkv_frame_push_unused( dpb_ctx, hal_h264e_rkv_frame_pop( dpb_ctx->frames.reference ) ); + dpb_ctx->fdec->i_poc = 0; + h264e_hal_debug_leave(); +} + +#if 0 +static void hal_h264e_rkv_reference_hierarchy_reset( h264e_hal_context *ctx) +{ + RK_S32 ref; + RK_S32 i = 0; + RK_S32 b_hasdelayframe = 0; + h264e_hal_rkv_dpb_ctx *dpb_ctx = (h264e_hal_rkv_dpb_ctx *)ctx->dpb_ctx; + h264e_hal_rkv_extra_info *extra_info = (h264e_hal_rkv_extra_info *)ctx->extra_info; + h264e_hal_sps *sps = &extra_info->sps; + RK_S32 i_num_reorder_frames = sps->vui.i_num_reorder_frames; + + /* look for delay frames -- chain must only contain frames that are disposable */ + for ( i = 0; dpb_ctx->frames.current[i] && RKVENC_IS_DISPOSABLE( dpb_ctx->frames.current[i]->i_type ); i++ ) + b_hasdelayframe |= dpb_ctx->frames.current[i]->i_coded + != dpb_ctx->frames.current[i]->i_frame + i_num_reorder_frames; + + /* This function must handle b-pyramid and clear frames for open-gop */ + if (!b_hasdelayframe && dpb_ctx->frames.i_poc_last_open_gop == -1 ) + return; + + /* Remove last BREF. There will never be old BREFs in the + * dpb during a BREF decode when pyramid == STRICT */ + for ( ref = 0; dpb_ctx->frames.reference[ref]; ref++ ) { + if (dpb_ctx->frames.reference[ref]->i_poc < dpb_ctx->frames.i_poc_last_open_gop && + dpb_ctx->i_type != H264E_HAL_SLICE_TYPE_B ) { + RK_S32 diff = dpb_ctx->i_frame_num - dpb_ctx->frames.reference[ref]->i_frame_num; + dpb_ctx->mmco[dpb_ctx->i_mmco_command_count].i_difference_of_pic_nums = diff; + dpb_ctx->mmco[dpb_ctx->i_mmco_command_count++].i_poc = dpb_ctx->frames.reference[ref]->i_poc; + hal_h264e_rkv_frame_push_unused( dpb_ctx, hal_h264e_rkv_frame_shift( &dpb_ctx->frames.reference[ref] ) ); + dpb_ctx->b_ref_reorder[0] = 1; + ref--; + } + } +} +#endif + +static RK_S32 hal_h264e_rkv_reference_distance( h264e_hal_ref_param *ref_cfg, h264e_hal_rkv_dpb_ctx *dpb_ctx, h264e_hal_rkv_frame *frame ) +{ + if ( ref_cfg->i_frame_packing == 5 ) + return abs((dpb_ctx->fdec->i_frame_cnt & ~1) - (frame->i_frame_cnt & ~1)) + + ((dpb_ctx->fdec->i_frame_cnt & 1) != (frame->i_frame_cnt & 1)); + else + return abs(dpb_ctx->fdec->i_frame_cnt - frame->i_frame_cnt); +} + + +static void hal_h264e_rkv_reference_build_list(h264e_hal_context *ctx) +{ + RK_S32 b_ok = 1, i = 0, list = 0, j = 0; + h264e_hal_rkv_extra_info *extra_info = (h264e_hal_rkv_extra_info *)ctx->extra_info; + h264e_hal_sps *sps = &extra_info->sps; + h264e_hal_rkv_dpb_ctx *dpb_ctx = (h264e_hal_rkv_dpb_ctx *)ctx->dpb_ctx; + h264e_hal_param *par = &ctx->param; + h264e_hal_ref_param *ref_cfg = &par->ref; + h264e_hal_rkv_frame *fdec = dpb_ctx->fdec; + RK_S32 i_poc = fdec->i_poc; + + h264e_hal_debug_enter(); + /* build ref list 0/1 */ + dpb_ctx->i_ref[0] = 0; + dpb_ctx->i_ref[1] = 0; + + if ( dpb_ctx->i_slice_type == H264E_HAL_SLICE_TYPE_I ) { + if ( ref_cfg->i_long_term_en && ref_cfg->i_frame_reference > 1 ) + ref_cfg->hw_longterm_mode ^= 1; //0 and 1, circle; If ref==1 , longterm mode only 1; + + if ( ref_cfg->i_long_term_en && ref_cfg->hw_longterm_mode && ((dpb_ctx->fdec->i_frame_cnt % ref_cfg->i_long_term_internal) == 0)) + fdec->long_term_flag = 1; + h264e_hal_log_dpb("dpb_ctx->i_slice_type == SLICE_TYPE_I, return"); + return; + } + + h264e_hal_log_dpb("fdec->i_poc: %d", fdec->i_poc); + for ( i = 0; dpb_ctx->frames.reference[i]; i++ ) { + if ( dpb_ctx->frames.reference[i]->b_corrupt ) + continue; + if ( dpb_ctx->frames.reference[i]->i_poc < i_poc ) + dpb_ctx->fref[0][dpb_ctx->i_ref[0]++] = dpb_ctx->frames.reference[i]; + else if ( dpb_ctx->frames.reference[i]->i_poc > i_poc ) + dpb_ctx->fref[1][dpb_ctx->i_ref[1]++] = dpb_ctx->frames.reference[i]; + } + + h264e_hal_log_dpb("dpb_ctx->i_ref[0]: %d", dpb_ctx->i_ref[0]); + h264e_hal_log_dpb("dpb_ctx->i_ref[1]: %d", dpb_ctx->i_ref[1]); + + if ( dpb_ctx->i_mmco_remove_from_end ) { + /* Order ref0 for MMCO remove */ + do { + b_ok = 1; + for (i = 0; i < dpb_ctx->i_ref[0] - 1; i++ ) { + if ( dpb_ctx->fref[0][i]->i_frame_cnt < dpb_ctx->fref[0][i + 1]->i_frame_cnt ) { + MPP_SWAP( h264e_hal_rkv_frame *, dpb_ctx->fref[0][i], dpb_ctx->fref[0][i + 1] ); + b_ok = 0; + break; + } + } + } while ( !b_ok ); + + for ( i = dpb_ctx->i_ref[0] - 1; i >= dpb_ctx->i_ref[0] - dpb_ctx->i_mmco_remove_from_end; i-- ) { + RK_S32 diff = dpb_ctx->fdec->i_frame_num - dpb_ctx->fref[0][i]->i_frame_num; + dpb_ctx->mmco[dpb_ctx->i_mmco_command_count].i_poc = dpb_ctx->fref[0][i]->i_poc; + dpb_ctx->mmco[dpb_ctx->i_mmco_command_count++].i_difference_of_pic_nums = diff; + } + } + + /* Order reference lists by distance from the current frame. */ + for ( list = 0; list < 1; list++ ) { //only one list + dpb_ctx->fref_nearest[list] = dpb_ctx->fref[list][0]; + do { + b_ok = 1; + for ( i = 0; i < dpb_ctx->i_ref[list] - 1; i++ ) { + if ( list ? dpb_ctx->fref[list][i + 1]->i_poc < dpb_ctx->fref_nearest[list]->i_poc + : dpb_ctx->fref[list][i + 1]->i_poc > dpb_ctx->fref_nearest[list]->i_poc ) + dpb_ctx->fref_nearest[list] = dpb_ctx->fref[list][i + 1]; + if ( hal_h264e_rkv_reference_distance( ref_cfg, dpb_ctx, dpb_ctx->fref[list][i] ) > + hal_h264e_rkv_reference_distance( ref_cfg, dpb_ctx, dpb_ctx->fref[list][i + 1] ) ) { + MPP_SWAP( h264e_hal_rkv_frame *, dpb_ctx->fref[list][i], dpb_ctx->fref[list][i + 1] ); + b_ok = 0; + break; + } + } + } while ( !b_ok ); + } + //Order long_term frame to last lists , only one long_term frame + if (ref_cfg->i_long_term_en) { + for (i = 0; i < dpb_ctx->i_ref[0]; i++) { + if (dpb_ctx->fref[0][i]->long_term_flag == 1) { + for (j = i; j < dpb_ctx->i_ref[0] - 1; j++) { + MPP_SWAP(h264e_hal_rkv_frame *, dpb_ctx->fref[0][j], dpb_ctx->fref[0][j + 1]); + } + break; + } + } + } + + //reorder, when in longterm_mode "1", don't reorder; + if (ref_cfg->i_frame_reference > 1 && ref_cfg->i_ref_pos && ref_cfg->i_ref_pos < dpb_ctx->i_ref[0]) + dpb_ctx->b_ref_pic_list_reordering[0] = 1; + else + dpb_ctx->b_ref_pic_list_reordering[0] = 0; + if (dpb_ctx->b_ref_pic_list_reordering[0]) { + for (list = 0; list < 1; list++) { + if (dpb_ctx->fref[0][ref_cfg->i_ref_pos]->long_term_flag) { + fdec->reorder_longterm_flag = 1; + } + for (i = ref_cfg->i_ref_pos; i >= 1; i--) { + MPP_SWAP(h264e_hal_rkv_frame *, dpb_ctx->fref[list][i], dpb_ctx->fref[list][i - 1]); + } + } + } + + //first P frame mark max_long_term_frame_idx_plus1 + if ( ref_cfg->i_long_term_en && dpb_ctx->fdec->i_frame_num == 1 ) { + dpb_ctx->i_mmco_command_count = 0; + + dpb_ctx->mmco[dpb_ctx->i_mmco_command_count].i_poc = 0; + dpb_ctx->mmco[dpb_ctx->i_mmco_command_count].memory_management_control_operation = 4; + dpb_ctx->mmco[dpb_ctx->i_mmco_command_count++].i_difference_of_pic_nums = 2; // max_long_term_frame_idx_plus1 , slice will plus 1, is 0; + } else + dpb_ctx->i_mmco_command_count = 0; + + //longterm marking + if ( ref_cfg->i_long_term_en && ((dpb_ctx->fdec->i_frame_cnt % ref_cfg->i_long_term_internal) == 0)) { + RK_S32 reflist_longterm = 0; + RK_S32 reflist_longidx = 0; + RK_S32 reflist_short_to_long = 0; + RK_S32 reflist_short_to_long_idx = 0; + + //search frame for transferring short to long; + if (ref_cfg->hw_longterm_mode == 0 || dpb_ctx->fdec->i_frame_num == 1) { + for (i = 0; i < dpb_ctx->i_ref[0]; i++) { + if (!dpb_ctx->fref[0][i]->long_term_flag && (ref_cfg->i_ref_pos + 1) == i) { + reflist_short_to_long++; + reflist_short_to_long_idx = i; + break; + } + } + //clear ref longterm flag + for (i = 0; i < dpb_ctx->i_ref[0]; i++) { + if (dpb_ctx->fref[0][i]->long_term_flag) { + reflist_longterm++; + reflist_longidx = i; + dpb_ctx->fref[0][i]->long_term_flag = 0; + } + } + } + + mpp_assert(reflist_longterm <= 1); + + //marking ref longterm to unused; + if ( reflist_longterm == 1 ) { + i = reflist_longidx; + + dpb_ctx->mmco[dpb_ctx->i_mmco_command_count].i_poc = dpb_ctx->fref[0][i]->i_poc; + dpb_ctx->mmco[dpb_ctx->i_mmco_command_count].memory_management_control_operation = 2; //long_term_pic_num + dpb_ctx->mmco[dpb_ctx->i_mmco_command_count++].i_difference_of_pic_nums = 1; + } else if ( dpb_ctx->i_ref[0] >= sps->i_num_ref_frames && dpb_ctx->i_ref[0] > 1 ) { //if dpb is full, so it need release a short term ref frame; + //if longterm marking is same with release short term, change release short term; + RK_S32 pos = ((reflist_short_to_long && reflist_short_to_long_idx == (dpb_ctx->i_ref[0] - 1)) || dpb_ctx->fref[0][dpb_ctx->i_ref[0] - 1]->long_term_flag) + 1; + RK_S32 diff = dpb_ctx->fdec->i_frame_num - dpb_ctx->fref[0][dpb_ctx->i_ref[0] - pos]->i_frame_num; + + dpb_ctx->mmco[dpb_ctx->i_mmco_command_count].i_poc = dpb_ctx->fref[0][dpb_ctx->i_ref[0] - pos]->i_poc; + dpb_ctx->mmco[dpb_ctx->i_mmco_command_count].memory_management_control_operation = 1; + dpb_ctx->mmco[dpb_ctx->i_mmco_command_count++].i_difference_of_pic_nums = diff; // difference_of_pic_nums_minus1 + } + + //marking curr pic to longterm; + if ( ref_cfg->hw_longterm_mode && dpb_ctx->fdec->i_frame_num == 1) { + fdec->long_term_flag = 1; + dpb_ctx->mmco[dpb_ctx->i_mmco_command_count].i_poc = 0; + dpb_ctx->mmco[dpb_ctx->i_mmco_command_count].memory_management_control_operation = 6; + dpb_ctx->mmco[dpb_ctx->i_mmco_command_count++].i_difference_of_pic_nums = 1; // long_term_frame_idx ; + } else if ( reflist_short_to_long ) { //Assign a long-term frame index to a short-term picture + i = reflist_short_to_long_idx; + RK_S32 diff = dpb_ctx->fdec->i_frame_num - dpb_ctx->fref[0][i]->i_frame_num; + + dpb_ctx->fref[0][i]->long_term_flag = 1; + dpb_ctx->mmco[dpb_ctx->i_mmco_command_count].i_poc = dpb_ctx->fref[0][i]->i_poc; + dpb_ctx->mmco[dpb_ctx->i_mmco_command_count].memory_management_control_operation = 3; //short term to long term; + dpb_ctx->mmco[dpb_ctx->i_mmco_command_count++].i_difference_of_pic_nums = diff; // difference_of_pic_nums_minus1 , slice will minus 1, is 0; + } + } else { + if (!(ref_cfg->i_long_term_en && dpb_ctx->fdec->i_frame_num == 1)) + dpb_ctx->i_mmco_command_count = 0; + } + + dpb_ctx->i_ref[1] = H264E_HAL_MIN( dpb_ctx->i_ref[1], dpb_ctx->i_max_ref1 ); + dpb_ctx->i_ref[0] = H264E_HAL_MIN( dpb_ctx->i_ref[0], dpb_ctx->i_max_ref0 ); + dpb_ctx->i_ref[0] = H264E_HAL_MIN( dpb_ctx->i_ref[0], ref_cfg->i_frame_reference ); // if reconfig() has lowered the limit + + /* EXP: add duplicates */ + mpp_assert( dpb_ctx->i_ref[0] + dpb_ctx->i_ref[1] <= H264E_REF_MAX ); + + h264e_hal_debug_leave(); +} + +static MPP_RET hal_h264e_rkv_reference_update( h264e_hal_context *ctx) +{ + RK_S32 i = 0, j = 0; + h264e_hal_rkv_extra_info *extra_info = (h264e_hal_rkv_extra_info *)ctx->extra_info; + h264e_hal_sps *sps = &extra_info->sps; + h264e_hal_rkv_dpb_ctx *dpb_ctx = (h264e_hal_rkv_dpb_ctx *)ctx->dpb_ctx; + h264e_hal_ref_param *ref_cfg = &ctx->param.ref; + + h264e_hal_debug_enter(); + if ( !dpb_ctx->fdec->b_kept_as_ref ) { + h264e_hal_log_err("!dpb_ctx->fdec->b_kept_as_ref, return early"); + return MPP_OK; + } + + /* apply mmco from previous frame. */ + for ( i = 0; i < dpb_ctx->i_mmco_command_count; i++ ) { + RK_S32 mmco = dpb_ctx->mmco[i].memory_management_control_operation; + for ( j = 0; dpb_ctx->frames.reference[j]; j++ ) { + if ( dpb_ctx->frames.reference[j]->i_poc == dpb_ctx->mmco[i].i_poc && (mmco == 1 || mmco == 2) ) + hal_h264e_rkv_frame_push_unused( dpb_ctx, hal_h264e_rkv_frame_shift( &dpb_ctx->frames.reference[j] ) ); + } + } + + /* move frame in the buffer */ + h264e_hal_log_dpb("try to push dpb_ctx->fdec %p, poc %d", dpb_ctx->fdec, dpb_ctx->fdec->i_poc); + hal_h264e_rkv_frame_push( dpb_ctx->frames.reference, dpb_ctx->fdec ); + if ( ref_cfg->i_long_term_en ) { + if ( dpb_ctx->frames.reference[sps->i_num_ref_frames] ) { + for (i = 0; i < 17; i++) { + if (dpb_ctx->frames.reference[i]->long_term_flag == 0) { //if longterm , don't remove; + hal_h264e_rkv_frame_push_unused(dpb_ctx, hal_h264e_rkv_frame_shift(&dpb_ctx->frames.reference[i])); + break; + } + mpp_assert(i != 16); + } + } + } else { + if ( dpb_ctx->frames.reference[sps->i_num_ref_frames] ) + hal_h264e_rkv_frame_push_unused( dpb_ctx, hal_h264e_rkv_frame_shift( dpb_ctx->frames.reference ) ); + } + + h264e_hal_debug_leave(); + return MPP_OK; +} + + + +static MPP_RET hal_h264e_rkv_reference_frame_set( h264e_hal_context *ctx, h264e_syntax *syn) +{ + RK_U32 i_nal_type = 0, i_nal_ref_idc = 0; + RK_S32 list = 0, k = 0; + h264e_hal_rkv_dpb_ctx *dpb_ctx = (h264e_hal_rkv_dpb_ctx *)ctx->dpb_ctx; + h264e_hal_rkv_extra_info *extra_info = (h264e_hal_rkv_extra_info *)ctx->extra_info; + h264e_hal_sps *sps = &extra_info->sps; + h264e_hal_ref_param *ref_cfg = &ctx->param.ref; + + h264e_hal_debug_enter(); + + dpb_ctx->fdec = hal_h264e_rkv_frame_pop_unused(ctx); + if ( !dpb_ctx->fdec ) { + h264e_hal_log_err("!dpb_ctx->fdec, current recon buf get failed"); + return MPP_NOK; + } + + dpb_ctx->i_max_ref0 = ref_cfg->i_frame_reference; + dpb_ctx->i_max_ref1 = H264E_HAL_MIN( sps->vui.i_num_reorder_frames, ref_cfg->i_frame_reference ); + + if (syn->frame_coding_type == RKVENC_FRAME_TYPE_IDR) { + dpb_ctx->i_frame_num = 0; + dpb_ctx->frames.i_last_idr = dpb_ctx->i_frame_cnt; + } + + dpb_ctx->fdec->i_frame_cnt = dpb_ctx->i_frame_cnt; + dpb_ctx->fdec->i_frame_num = dpb_ctx->i_frame_num; + dpb_ctx->fdec->i_frame_type = syn->frame_coding_type; + dpb_ctx->fdec->i_poc = 2 * ( dpb_ctx->fdec->i_frame_cnt - H264E_HAL_MAX( dpb_ctx->frames.i_last_idr, 0 ) ); + + + if ( !RKVENC_IS_TYPE_I( dpb_ctx->fdec->i_frame_type ) ) { + RK_S32 valid_refs_left = 0; + for ( k = 0; dpb_ctx->frames.reference[k]; k++ ) + if ( !dpb_ctx->frames.reference[k]->b_corrupt ) + valid_refs_left++; + /* No valid reference frames left: force an IDR. */ + if ( !valid_refs_left ) { + dpb_ctx->fdec->b_keyframe = 1; + dpb_ctx->fdec->i_frame_type = RKVENC_FRAME_TYPE_IDR; + } + } + if ( dpb_ctx->fdec->b_keyframe ) + dpb_ctx->frames.i_last_keyframe = dpb_ctx->fdec->i_frame_cnt; + + + dpb_ctx->i_mmco_command_count = + dpb_ctx->i_mmco_remove_from_end = 0; + dpb_ctx->b_ref_pic_list_reordering[0] = 0; + dpb_ctx->b_ref_pic_list_reordering[1] = 0; + + /* calculate nal type and nal ref idc */ + if (syn->frame_coding_type == RKVENC_FRAME_TYPE_IDR) { //TODO: extend syn->frame_coding_type definition + /* reset ref pictures */ + i_nal_type = RKVENC_NAL_SLICE_IDR; + i_nal_ref_idc = RKVENC_NAL_PRIORITY_HIGHEST; + dpb_ctx->i_slice_type = H264E_HAL_SLICE_TYPE_I; + hal_h264e_rkv_reference_reset(dpb_ctx); + } else if ( syn->frame_coding_type == RKVENC_FRAME_TYPE_I ) { + i_nal_type = RKVENC_NAL_SLICE; + i_nal_ref_idc = RKVENC_NAL_PRIORITY_HIGH; /* Not completely true but for now it is (as all I/P are kept as ref)*/ + dpb_ctx->i_slice_type = H264E_HAL_SLICE_TYPE_I; + } else if ( syn->frame_coding_type == RKVENC_FRAME_TYPE_P ) { + i_nal_type = RKVENC_NAL_SLICE; + i_nal_ref_idc = RKVENC_NAL_PRIORITY_HIGH; /* Not completely true but for now it is (as all I/P are kept as ref)*/ + dpb_ctx->i_slice_type = H264E_HAL_SLICE_TYPE_P; + } else if ( syn->frame_coding_type == RKVENC_FRAME_TYPE_BREF ) { + i_nal_type = RKVENC_NAL_SLICE; + i_nal_ref_idc = RKVENC_NAL_PRIORITY_HIGH; + dpb_ctx->i_slice_type = H264E_HAL_SLICE_TYPE_B; + } else { /* B frame */ + i_nal_type = RKVENC_NAL_SLICE; + i_nal_ref_idc = RKVENC_NAL_PRIORITY_DISPOSABLE; + dpb_ctx->i_slice_type = H264E_HAL_SLICE_TYPE_B; + } + + dpb_ctx->fdec->b_kept_as_ref = i_nal_ref_idc != RKVENC_NAL_PRIORITY_DISPOSABLE;// && h->param.i_keyint_max > 1; + + + if (sps->keyframe_max_interval == 1) + i_nal_ref_idc = RKVENC_NAL_PRIORITY_LOW; + + dpb_ctx->i_nal_ref_idc = i_nal_ref_idc; + dpb_ctx->i_nal_type = i_nal_type; + + + dpb_ctx->fdec->i_pts = dpb_ctx->fdec->i_pts; + + + /* build list */ + hal_h264e_rkv_reference_build_list(ctx); + + /* set syntax (slice header) */ + + /* If the ref list isn't in the default order, construct reordering header */ + for (list = 0; list < 2; list++ ) { + if ( dpb_ctx->b_ref_pic_list_reordering[list] ) { + RK_S32 pred_frame_num = dpb_ctx->fdec->i_frame_num & ((1 << sps->i_log2_max_frame_num) - 1); + for ( k = 0; k < dpb_ctx->i_ref[list]; k++ ) { + if ( dpb_ctx->fdec->reorder_longterm_flag ) { // + dpb_ctx->fdec->reorder_longterm_flag = 0; //clear reorder_longterm_flag + dpb_ctx->ref_pic_list_order[list][k].idc = 2; //reorder long_term_pic_num; + dpb_ctx->ref_pic_list_order[list][k].arg = 0; //long_term_pic_num + break; //NOTE: RK feature: only reorder one time + } else { + RK_S32 lx_frame_num = dpb_ctx->fref[list][k]->i_frame_num & ((1 << sps->i_log2_max_frame_num) - 1); + RK_S32 diff = lx_frame_num - pred_frame_num; + dpb_ctx->ref_pic_list_order[list][k].idc = ( diff > 0 ); + dpb_ctx->ref_pic_list_order[list][k].arg = (abs(diff) - 1) & ((1 << sps->i_log2_max_frame_num) - 1); + pred_frame_num = dpb_ctx->fref[list][k]->i_frame_num; + break; //NOTE: RK feature: only reorder one time + } + } + } + } + + if (dpb_ctx->i_nal_type == RKVENC_NAL_SLICE_IDR) { + if (ref_cfg->i_long_term_en && ref_cfg->hw_longterm_mode && ((dpb_ctx->fdec->i_frame_cnt % ref_cfg->i_long_term_internal) == 0) ) + dpb_ctx->i_long_term_reference_flag = 1; + dpb_ctx->i_idr_pic_id = dpb_ctx->i_tmp_idr_pic_id; + dpb_ctx->i_tmp_idr_pic_id ^= 1; + } else { + dpb_ctx->i_long_term_reference_flag = 0; + dpb_ctx->i_idr_pic_id = -1; + } + + + h264e_hal_debug_leave(); + + return MPP_OK; +} + + +static MPP_RET hal_h264e_rkv_reference_frame_update( h264e_hal_context *ctx) +{ + //h264e_hal_rkv_dpb_ctx *dpb_ctx = (h264e_hal_rkv_dpb_ctx *)ctx->dpb_ctx; + + h264e_hal_debug_enter(); + if (MPP_OK != hal_h264e_rkv_reference_update(ctx)) { + h264e_hal_log_err("reference update failed, return now"); + return MPP_NOK; + } + + h264e_hal_debug_leave(); + return MPP_OK; +} + +static MPP_RET hal_h264e_rkv_free_buffers(h264e_hal_context *ctx) +{ + RK_S32 k = 0; + h264e_hal_rkv_buffers *buffers = (h264e_hal_rkv_buffers *)ctx->buffers; + h264e_hal_debug_enter(); + for (k = 0; k < 2; k++) { + if (buffers->hw_pp_buf[k]) { + if (MPP_OK != mpp_buffer_put(buffers->hw_pp_buf[k])) { + h264e_hal_log_err("hw_pp_buf[%d] put failed", k); + return MPP_NOK; + } + } + } + for (k = 0; k < 2; k++) { + if (buffers->hw_dsp_buf[k]) { + if (MPP_OK != mpp_buffer_put(buffers->hw_dsp_buf[k])) { + h264e_hal_log_err("hw_dsp_buf[%d] put failed", k); + return MPP_NOK; + } + } + } + for (k = 0; k < RKV_H264E_LINKTABLE_FRAME_NUM; k++) { + if (buffers->hw_mei_buf[k]) { + if (MPP_OK != mpp_buffer_put(buffers->hw_mei_buf[k])) { + h264e_hal_log_err("hw_mei_buf[%d] put failed", k); + return MPP_NOK; + } + } + } + + for (k = 0; k < RKV_H264E_LINKTABLE_FRAME_NUM; k++) { + if (buffers->hw_roi_buf[k]) { + if (MPP_OK != mpp_buffer_put(buffers->hw_roi_buf[k])) { + h264e_hal_log_err("hw_roi_buf[%d] put failed", k); + return MPP_NOK; + } + } + if (buffers->hw_osd_buf[k]) { + if (MPP_OK != mpp_buffer_put(buffers->hw_osd_buf[k])) { + h264e_hal_log_err("hw_osd_buf[%d] put failed", k); + return MPP_NOK; + } + } + } + + { + RK_S32 num_buf = MPP_ARRAY_ELEMS(buffers->hw_rec_buf); + for (k = 0; k < num_buf; k++) { + if (buffers->hw_rec_buf[k]) { + if (MPP_OK != mpp_buffer_put(buffers->hw_rec_buf[k])) { + h264e_hal_log_err("hw_rec_buf[%d] put failed", k); + return MPP_NOK; + } + } + } + } + + + + for (k = 0; k < H264E_HAL_RKV_BUF_GRP_BUTT; k++) { + if (buffers->hw_buf_grp[k]) { + if (MPP_OK != mpp_buffer_group_put(buffers->hw_buf_grp[k])) { + h264e_hal_log_err("buf group[%d] put failed", k); + return MPP_NOK; + } + } + } + + h264e_hal_debug_leave(); + + return MPP_OK; +} + +static MPP_RET hal_h264e_rkv_allocate_buffers(h264e_hal_context *ctx, h264e_syntax *syn, h264e_hal_sps *sps, h264e_hal_rkv_coveragetest_cfg *test_cfg) +{ + RK_S32 k = 0; + h264e_hal_rkv_buffers *buffers = (h264e_hal_rkv_buffers *)ctx->buffers; + RK_U32 num_mbs_oneframe = (syn->pic_luma_width + 15) / 16 * ((syn->pic_luma_height + 15) / 16); + RK_U32 frame_size = ((syn->pic_luma_width + 15) & (~15)) * ((syn->pic_luma_height + 15) & (~15)) * 3 / 2; + h264e_hal_rkv_dpb_ctx *dpb_ctx = (h264e_hal_rkv_dpb_ctx *)ctx->dpb_ctx; + h264e_hal_rkv_frame *frame_buf = dpb_ctx->frame_buf; + RK_U32 all_intra_mode = sps->keyframe_max_interval == 1; + h264e_hal_debug_enter(); + //TODO: reduce buf size + for (k = 0; k < H264E_HAL_RKV_BUF_GRP_BUTT; k++) { + if (MPP_OK != mpp_buffer_group_get_internal(&buffers->hw_buf_grp[k], MPP_BUFFER_TYPE_ION)) { + h264e_hal_log_err("buf group[%d] get failed", k); + return MPP_ERR_MALLOC; + } + } + + if (syn->preproc_en || (test_cfg && test_cfg->preproc)) { + for (k = 0; k < 2; k++) { + if (MPP_OK != mpp_buffer_get(buffers->hw_buf_grp[H264E_HAL_RKV_BUF_GRP_PP], &buffers->hw_pp_buf[k], frame_size)) { + h264e_hal_log_err("hw_pp_buf[%d] get failed", k); + return MPP_ERR_MALLOC; + } else { + h264e_hal_log_dpb("hw_pp_buf[%d] %p done, fd %d", k, buffers->hw_pp_buf[k], mpp_buffer_get_fd(buffers->hw_pp_buf[k])); + } + } + } + + if (!all_intra_mode) { + for (k = 0; k < 2; k++) { + if (MPP_OK != mpp_buffer_get(buffers->hw_buf_grp[H264E_HAL_RKV_BUF_GRP_DSP], &buffers->hw_dsp_buf[k], frame_size / 16)) { + h264e_hal_log_err("hw_dsp_buf[%d] get failed", k); + return MPP_ERR_MALLOC; + } else { + h264e_hal_log_dpb("hw_dsp_buf[%d] %p done, fd %d", k, buffers->hw_dsp_buf[k], mpp_buffer_get_fd(buffers->hw_dsp_buf[k])); + } + } + } + + #if 0 //default setting + RK_U32 num_mei_oneframe = (syn->pic_luma_width + 255) / 256 * ((syn->pic_luma_height + 15) / 16); + for (k = 0; k < RKV_H264E_LINKTABLE_FRAME_NUM; k++) { + if (MPP_OK != mpp_buffer_get(buffers->hw_buf_grp[H264E_HAL_RKV_BUF_GRP_MEI], &buffers->hw_mei_buf[k], num_mei_oneframe * 16 * 4)) { + h264e_hal_log_err("hw_mei_buf[%d] get failed", k); + return MPP_ERR_MALLOC; + } else { + h264e_hal_log_dpb("hw_mei_buf[%d] %p done, fd %d", k, buffers->hw_mei_buf[k], mpp_buffer_get_fd(buffers->hw_mei_buf[k])); + } + } + #endif + + if (syn->roi_en || (test_cfg && test_cfg->roi)) { + for (k = 0; k < RKV_H264E_LINKTABLE_FRAME_NUM; k++) { + if (MPP_OK != mpp_buffer_get(buffers->hw_buf_grp[H264E_HAL_RKV_BUF_GRP_ROI], &buffers->hw_roi_buf[k], num_mbs_oneframe * 1)) { + h264e_hal_log_err("hw_roi_buf[%d] get failed", k); + return MPP_ERR_MALLOC; + } else { + h264e_hal_log_dpb("hw_roi_buf[%d] %p done, fd %d", k, buffers->hw_roi_buf[k], mpp_buffer_get_fd(buffers->hw_roi_buf[k])); + } + } + } + + { + RK_S32 num_buf = MPP_ARRAY_ELEMS(buffers->hw_rec_buf); + for (k = 0; k < num_buf; k++) { + if (MPP_OK != mpp_buffer_get(buffers->hw_buf_grp[H264E_HAL_RKV_BUF_GRP_REC], &buffers->hw_rec_buf[k], frame_size)) { + h264e_hal_log_err("hw_rec_buf[%d] get failed", k); + return MPP_ERR_MALLOC; + } else { + h264e_hal_log_dpb("hw_rec_buf[%d] %p done, fd %d", k, buffers->hw_rec_buf[k], mpp_buffer_get_fd(buffers->hw_rec_buf[k])); + } + frame_buf[k].hw_buf = buffers->hw_rec_buf[k]; + } + } + + if (syn->osd_mode || (test_cfg && test_cfg->osd)) { + for (k = 0; k < RKV_H264E_LINKTABLE_FRAME_NUM; k++) { + if (MPP_OK != mpp_buffer_get(buffers->hw_buf_grp[H264E_HAL_RKV_BUF_GRP_REC], &buffers->hw_osd_buf[k], num_mbs_oneframe * 256)) { + h264e_hal_log_err("hw_osd_buf[%d] get failed", buffers->hw_osd_buf[k]); + return MPP_ERR_MALLOC; + } else { + h264e_hal_log_dpb("hw_osd_buf[%d] %p done, fd %d", k, buffers->hw_osd_buf[k], mpp_buffer_get_fd(buffers->hw_osd_buf[k])); + } + } + } + + h264e_hal_debug_leave(); + return MPP_OK; +} + +static void hal_h264e_rkv_set_param(h264e_hal_param *p) +{ + h264e_hal_vui_param *vui = &p->vui; + h264e_hal_ref_param *ref = &p->ref; + + p->constrained_intra = 0; + + vui->i_sar_height = 0; + vui->i_sar_width = 0; + vui->i_overscan = 0; + vui->i_vidformat = 5; + vui->b_fullrange = 0; + vui->i_colorprim = 2; + vui->i_transfer = 2; + vui->i_colmatrix = -1; + vui->i_chroma_loc = 0; + + ref->i_frame_reference = RKV_H264E_NUM_REFS; + ref->i_dpb_size = RKV_H264E_NUM_REFS; + ref->i_ref_pos = 1; + ref->i_long_term_en = RKV_H264E_LONGTERM_REF_EN; + ref->hw_longterm_mode = 0; + ref->i_long_term_internal = 0; + ref->i_frame_packing = -1; +} + +static void hal_h264e_rkv_adjust_param(h264e_hal_context *ctx) +{ + h264e_hal_param *par = &ctx->param; + (void)par; +} + +MPP_RET hal_h264e_rkv_set_sps(h264e_hal_sps *sps, h264e_hal_param *par, h264e_control_extra_info_cfg *cfg) +{ + h264e_hal_vui_param vui = par->vui; + h264e_hal_ref_param ref_cfg = par->ref; + RK_S32 max_frame_num = 0; + + //default settings + RK_S32 i_bframe_pyramid = 0; + RK_S32 i_bframe = 0; + RK_S32 b_intra_refresh = 0; + RK_S32 Log2MaxFrameNum = 16; + RK_S32 Sw_log2_max_pic_order_cnt_lsb_minus4 = 12; + RK_S32 b_interlaced = 0; + RK_S32 b_fake_interlaced = 0; + RK_S32 crop_rect_left = 0; + RK_S32 crop_rect_right = 0; + RK_S32 crop_rect_top = 0; + RK_S32 crop_rect_bottom = 0; + RK_S32 i_timebase_num = 1; + RK_S32 i_timebase_den = 25; + RK_S32 b_vfr_input = 0; + RK_S32 i_nal_hrd = 0; + RK_S32 b_pic_struct = 0; + RK_S32 analyse_mv_range = 128; //TODO: relative to level_idc, transplant x264_validate_levels. + h264e_hal_rkv_csp_info csp_info = hal_h264e_rkv_convert_csp(cfg->input_image_format); + RK_S32 csp = h264e_csp_idx_map[csp_info.fmt] & RKV_H264E_CSP2_MASK; + RK_S32 i_dpb_size = ref_cfg.i_dpb_size; + RK_S32 i_frame_reference = ref_cfg.i_frame_reference; + + sps->i_id = 0; + sps->i_mb_width = ( cfg->pic_luma_width + 15 ) / 16; + sps->i_mb_height = ( cfg->pic_luma_height + 15 ) / 16; + sps->i_chroma_format_idc = csp >= RKV_H264E_CSP2_I444 ? RKV_H264E_CHROMA_444 : + csp >= RKV_H264E_CSP2_I422 ? RKV_H264E_CHROMA_422 : RKV_H264E_CHROMA_420; + + sps->b_qpprime_y_zero_transform_bypass = 0; //param->rc.i_rc_method == X264_RC_CQP && param->rc.i_qp_constant == 0; + sps->i_profile_idc = cfg->profile_idc; + + sps->b_constraint_set0 = 0; //sps->i_profile_idc == H264_PROFILE_BASELINE; + /* x264 doesn't support the features that are in Baseline and not in Main, + * namely arbitrary_slice_order and slice_groups. */ + sps->b_constraint_set1 = 0; //sps->i_profile_idc <= H264_PROFILE_MAIN; + /* Never set constraint_set2, it is not necessary and not used in real world. */ + sps->b_constraint_set2 = 0; + sps->b_constraint_set3 = 0; + + sps->i_level_idc = cfg->level_idc; + if ( cfg->level_idc == 9 && ( sps->i_profile_idc == H264_PROFILE_BASELINE || sps->i_profile_idc == H264_PROFILE_MAIN ) ) { + sps->b_constraint_set3 = 1; /* level 1b with Baseline or Main profile is signalled via constraint_set3 */ + sps->i_level_idc = 11; + } + /* Intra profiles */ + if ( cfg->keyframe_max_interval == 1 && sps->i_profile_idc > H264_PROFILE_HIGH ) + sps->b_constraint_set3 = 1; + + sps->vui.i_num_reorder_frames = i_bframe_pyramid ? 2 : i_bframe ? 1 : 0; + /* extra slot with pyramid so that we don't have to override the + * order of forgetting old pictures */ + sps->vui.i_max_dec_frame_buffering = + sps->i_num_ref_frames = H264E_HAL_MIN(H264E_REF_MAX, H264E_HAL_MAX4(i_frame_reference, 1 + sps->vui.i_num_reorder_frames, + i_bframe_pyramid ? 4 : 1, i_dpb_size)); //TODO: multi refs + sps->i_num_ref_frames -= i_bframe_pyramid == RKV_H264E_B_PYRAMID_STRICT; //TODO: multi refs + if ( cfg->keyframe_max_interval == 1 ) { + sps->i_num_ref_frames = 0; + sps->vui.i_max_dec_frame_buffering = 0; + } + + /* number of refs + current frame */ + max_frame_num = sps->vui.i_max_dec_frame_buffering * (!!i_bframe_pyramid + 1) + 1; + /* Intra refresh cannot write a recovery time greater than max frame num-1 */ + if (b_intra_refresh ) { + RK_S32 time_to_recovery = H264E_HAL_MIN( sps->i_mb_width - 1, cfg->keyframe_max_interval) + i_bframe - 1; + max_frame_num = H264E_HAL_MAX( max_frame_num, time_to_recovery + 1 ); + } + + sps->i_log2_max_frame_num = Log2MaxFrameNum;//fix by gsl org 16, at least 4 + while ( (1 << sps->i_log2_max_frame_num) <= max_frame_num ) + sps->i_log2_max_frame_num++; + + sps->i_poc_type = 0; + + if ( sps->i_poc_type == 0 ) { + RK_S32 max_delta_poc = (i_bframe + 2) * (!!i_bframe_pyramid + 1) * 2; + sps->i_log2_max_poc_lsb = Sw_log2_max_pic_order_cnt_lsb_minus4 + 4; + while ( (1 << sps->i_log2_max_poc_lsb) <= max_delta_poc * 2 ) + sps->i_log2_max_poc_lsb++; + } + + sps->b_vui = 1; + + sps->b_gaps_in_frame_num_value_allowed = 0; + sps->b_frame_mbs_only = !(b_interlaced || b_fake_interlaced); + if ( !sps->b_frame_mbs_only ) + sps->i_mb_height = ( sps->i_mb_height + 1 ) & ~1; + sps->b_mb_adaptive_frame_field = b_interlaced; + sps->b_direct8x8_inference = 1; + + sps->crop.i_left = crop_rect_left; + sps->crop.i_top = crop_rect_top; + sps->crop.i_right = crop_rect_right + sps->i_mb_width * 16 - cfg->pic_luma_width; + sps->crop.i_bottom = (crop_rect_bottom + sps->i_mb_height * 16 - cfg->pic_luma_height) >> !sps->b_frame_mbs_only; + sps->b_crop = sps->crop.i_left || sps->crop.i_top || + sps->crop.i_right || sps->crop.i_bottom; + + sps->vui.b_aspect_ratio_info_present = 0; + if (vui.i_sar_width > 0 && vui.i_sar_height > 0 ) { + sps->vui.b_aspect_ratio_info_present = 1; + sps->vui.i_sar_width = vui.i_sar_width; + sps->vui.i_sar_height = vui.i_sar_height; + } + + sps->vui.b_overscan_info_present = vui.i_overscan > 0 && vui.i_overscan <= 2; + if ( sps->vui.b_overscan_info_present ) + sps->vui.b_overscan_info = ( vui.i_overscan == 2 ? 1 : 0 ); + + sps->vui.b_signal_type_present = 0; + sps->vui.i_vidformat = ( vui.i_vidformat >= 0 && vui.i_vidformat <= 5 ? vui.i_vidformat : 5 ); + sps->vui.b_fullrange = ( vui.b_fullrange >= 0 && vui.b_fullrange <= 1 ? vui.b_fullrange : + ( csp >= RKV_H264E_CSP2_BGR ? 1 : 0 ) ); + sps->vui.b_color_description_present = 0; + + sps->vui.i_colorprim = ( vui.i_colorprim >= 0 && vui.i_colorprim <= 9 ? vui.i_colorprim : 2 ); + sps->vui.i_transfer = ( vui.i_transfer >= 0 && vui.i_transfer <= 15 ? vui.i_transfer : 2 ); + sps->vui.i_colmatrix = ( vui.i_colmatrix >= 0 && vui.i_colmatrix <= 10 ? vui.i_colmatrix : + ( csp >= RKV_H264E_CSP2_BGR ? 0 : 2 ) ); + if ( sps->vui.i_colorprim != 2 || + sps->vui.i_transfer != 2 || + sps->vui.i_colmatrix != 2 ) { + sps->vui.b_color_description_present = 1; + } + + if ( sps->vui.i_vidformat != 5 || + sps->vui.b_fullrange || + sps->vui.b_color_description_present ) { + sps->vui.b_signal_type_present = 1; + } + + /* FIXME: not sufficient for interlaced video */ + sps->vui.b_chroma_loc_info_present = vui.i_chroma_loc > 0 && vui.i_chroma_loc <= 5 && + sps->i_chroma_format_idc == RKV_H264E_CHROMA_420; + if ( sps->vui.b_chroma_loc_info_present ) { + sps->vui.i_chroma_loc_top = vui.i_chroma_loc; + sps->vui.i_chroma_loc_bottom = vui.i_chroma_loc; + } + + sps->vui.b_timing_info_present = i_timebase_num > 0 && i_timebase_den > 0; + + if ( sps->vui.b_timing_info_present ) { + sps->vui.i_num_units_in_tick = i_timebase_num; + sps->vui.i_time_scale = i_timebase_den * 2; + sps->vui.b_fixed_frame_rate = !b_vfr_input; + } + + sps->vui.b_vcl_hrd_parameters_present = 0; // we don't support VCL HRD + sps->vui.b_nal_hrd_parameters_present = !!i_nal_hrd; + sps->vui.b_pic_struct_present = b_pic_struct; + + // NOTE: HRD related parts of the SPS are initialised in x264_ratecontrol_init_reconfigurable + + sps->vui.b_bitstream_restriction = cfg->keyframe_max_interval > 1; + if ( sps->vui.b_bitstream_restriction ) { + sps->vui.b_motion_vectors_over_pic_boundaries = 1; + sps->vui.i_max_bytes_per_pic_denom = 0; + sps->vui.i_max_bits_per_mb_denom = 0; + sps->vui.i_log2_max_mv_length_horizontal = + sps->vui.i_log2_max_mv_length_vertical = (RK_S32)log2f((float)H264E_HAL_MAX( 1, analyse_mv_range * 4 - 1 ) ) + 1; + } + + /* only for backup, excluded in read SPS */ + sps->keyframe_max_interval = cfg->keyframe_max_interval; + return MPP_OK; +} + + +RK_S32 hal_h264e_rkv_stream_get_pos(h264e_hal_rkv_stream *s) +{ + return (RK_S32)(8 * (s->p - s->p_start) + (4 * 8) - s->i_left); +} + + +MPP_RET hal_h264e_rkv_stream_init(h264e_hal_rkv_stream *s) +{ + RK_S32 offset = 0; + RK_U8 *p_buf = NULL; + s->buf = mpp_calloc(RK_U8, 512); //SPS+PPS + p_buf = s->buf + 8; //NOTE + + offset = (size_t)(p_buf) & 3; + s->p = s->p_start = p_buf - offset; + //s->p_end = (RK_U8*)s->buf + i_data; + s->i_left = (4 - offset) * 8; + //s->cur_bits = endian_fix32(M32(s->p)); + s->cur_bits = (*(s->p) << 24) + (*(s->p + 1) << 16) + (*(s->p + 2) << 8) + (*(s->p + 3) << 0); + s->cur_bits >>= (4 - offset) * 8; + s->count_bit = 0; + + return MPP_OK; +} + + +MPP_RET hal_h264e_rkv_stream_reset(h264e_hal_rkv_stream *s) +{ + RK_S32 offset = 0; + RK_U8 *p_buf = NULL; + p_buf = s->buf + 8; //NOTE + h264e_hal_debug_enter(); + + offset = (size_t)(p_buf) & 3; + s->p = s->p_start = p_buf - offset; + //s->p_end = (RK_U8*)s->buf + i_data; + s->i_left = (4 - offset) * 8; + //s->cur_bits = endian_fix32(M32(s->p)); + s->cur_bits = (*(s->p) << 24) + (*(s->p + 1) << 16) + (*(s->p + 2) << 8) + (*(s->p + 3) << 0); + s->cur_bits >>= (4 - offset) * 8; + s->count_bit = 0; + h264e_hal_debug_leave(); + return MPP_OK; +} + +MPP_RET hal_h264e_rkv_stream_deinit(h264e_hal_rkv_stream *s) +{ + MPP_FREE(s->buf); + + s->p = NULL; + s->p_start = NULL; + //s->p_end = NULL; + + s->i_left = 0; + s->cur_bits = 0; + s->count_bit = 0; + + return MPP_OK; +} + +MPP_RET hal_h264e_rkv_stream_realign(h264e_hal_rkv_stream *s) +{ + RK_S32 offset = (size_t)(s->p) & 3; //used to judge alignment + if (offset) { + s->p = s->p - offset; //move pointer to 32bit aligned pos + s->i_left = (4 - offset) * 8; //init + //s->cur_bits = endian_fix32(M32(s->p)); + s->cur_bits = (*(s->p) << 24) + (*(s->p + 1) << 16) + (*(s->p + 2) << 8) + (*(s->p + 3) << 0); + s->cur_bits >>= (4 - offset) * 8; //shift right the invalid bit + } + + return MPP_OK; +} + +MPP_RET hal_h264e_rkv_stream_write_with_log(h264e_hal_rkv_stream *s, RK_S32 i_count, RK_U32 val, char *name) +{ + RK_U32 i_bits = val; + + h264e_hal_log_header("write bits name %s, count %d, val %d", name, i_count, val); + + s->count_bit += i_count; + if (i_count < s->i_left) { + s->cur_bits = (s->cur_bits << i_count) | i_bits; + s->i_left -= i_count; + } else { + i_count -= s->i_left; + s->cur_bits = (s->cur_bits << s->i_left) | (i_bits >> i_count); + //M32(s->p) = endian_fix32(s->cur_bits); + *(s->p) = 0; + *(s->p) = (s->cur_bits >> 24) & 0xff; + *(s->p + 1) = (s->cur_bits >> 16) & 0xff; + *(s->p + 2) = (s->cur_bits >> 8) & 0xff; + *(s->p + 3) = (s->cur_bits >> 0) & 0xff; + s->p += 4; + s->cur_bits = i_bits; + s->i_left = 32 - i_count; + } + return MPP_OK; +} + +MPP_RET hal_h264e_rkv_stream_write1_with_log(h264e_hal_rkv_stream *s, RK_U32 val, char *name) +{ + RK_U32 i_bit = val; + + h264e_hal_log_header("write 1 bit name %s, val %d", name, val); + + s->count_bit += 1; + s->cur_bits <<= 1; + s->cur_bits |= i_bit; + s->i_left--; + if (s->i_left == 4 * 8 - 32) { + //M32(s->p) = endian_fix32(s->cur_bits); + *(s->p) = (s->cur_bits >> 24) & 0xff; + *(s->p + 1) = (s->cur_bits >> 16) & 0xff; + *(s->p + 2) = (s->cur_bits >> 8) & 0xff; + *(s->p + 3) = (s->cur_bits >> 0) & 0xff; + s->p += 4; + s->i_left = 4 * 8; + } + return MPP_OK; +} + +MPP_RET hal_h264e_rkv_stream_write_ue_with_log(h264e_hal_rkv_stream *s, RK_U32 val, char *name) +{ + RK_S32 size = 0; + RK_S32 tmp = ++val; + + h264e_hal_log_header("write UE bits name %s, val %d (2 steps below are real writting)", name, val); + if (tmp >= 0x10000) { + size = 32; + tmp >>= 16; + } + if (tmp >= 0x100) { + size += 16; + tmp >>= 8; + } + size += h264e_ue_size_tab[tmp]; + + hal_h264e_rkv_stream_write_with_log(s, size >> 1, 0, name); + hal_h264e_rkv_stream_write_with_log(s, (size >> 1) + 1, val, name); + + return MPP_OK; +} + +MPP_RET hal_h264e_rkv_stream_write_se_with_log(h264e_hal_rkv_stream *s, RK_S32 val, char *name) +{ + RK_S32 size = 0; + RK_S32 tmp = 1 - val * 2; + if (tmp < 0) + tmp = val * 2; + + val = tmp; + if (tmp >= 0x100) { + size = 16; + tmp >>= 8; + } + size += h264e_ue_size_tab[tmp]; + + return hal_h264e_rkv_stream_write_with_log(s, size, val, name); +} + +MPP_RET hal_h264e_rkv_stream_write32(h264e_hal_rkv_stream *s, RK_U32 i_bits, char *name) +{ + hal_h264e_rkv_stream_write_with_log(s, 16, i_bits >> 16, name); + hal_h264e_rkv_stream_write_with_log(s, 16, i_bits , name); + + return MPP_OK; +} + +static RK_S32 hal_h264e_rkv_stream_size_se( RK_S32 val ) +{ + RK_S32 tmp = 1 - val * 2; + if ( tmp < 0 ) tmp = val * 2; + if ( tmp < 256 ) + return h264e_ue_size_tab[tmp]; + else + return h264e_ue_size_tab[tmp >> 8] + 16; +} + + +MPP_RET hal_h264e_rkv_stream_rbsp_trailing(h264e_hal_rkv_stream *s) +{ + //align bits, 1+N zeros. + hal_h264e_rkv_stream_write1_with_log(s, 1, "align_1_bit"); + hal_h264e_rkv_stream_write_with_log(s, s->i_left & 7, 0, "align_N_bits"); + + return MPP_OK; +} + +/* Write the rest of cur_bits to the bitstream; results in a bitstream no longer 32-bit aligned. */ +MPP_RET hal_h264e_rkv_stream_flush(h264e_hal_rkv_stream *s) +{ + //do 4 bytes aligned + //M32(s->p) = endian_fix32(s->cur_bits << (s->i_left & 31)); + RK_U32 tmp_bit = s->cur_bits << (s->i_left & 31); + *(s->p) = (tmp_bit >> 24) & 0xff; + *(s->p + 1) = (tmp_bit >> 16) & 0xff; + *(s->p + 2) = (tmp_bit >> 8) & 0xff; + *(s->p + 3) = (tmp_bit >> 0) & 0xff; + s->p += 4 - (s->i_left >> 3);//p point to bit which aligned, rather than the pos next to 4-byte alinged + s->i_left = 4 * 8; + + return MPP_OK; +} + +void hal_h264e_rkv_nals_init(h264e_hal_rkv_extra_info *out) +{ + out->nal_buf = mpp_calloc(RK_U8, 512); + out->nal_num = 0; +} + +void hal_h264e_rkv_nals_deinit(h264e_hal_rkv_extra_info *out) +{ + MPP_FREE(out->nal_buf); + + out->nal_num = 0; +} + +void hal_h264e_rkv_nal_start(h264e_hal_rkv_extra_info *out, RK_S32 i_type, RK_S32 i_ref_idc) +{ + h264e_hal_rkv_stream *s = &out->stream; + RK_U8 *stream_buf = s->p_start; + out->nal[out->nal_num].i_ref_idc = i_ref_idc; + out->nal[out->nal_num].i_type = i_type; + out->nal[out->nal_num].b_long_startcode = 1; + + out->nal[out->nal_num].i_payload = 0; + out->nal[out->nal_num].p_payload = &stream_buf[hal_h264e_rkv_stream_get_pos(s) / 8]; + out->nal[out->nal_num].i_padding = 0; +} + +void hal_h264e_rkv_nal_end(h264e_hal_rkv_extra_info *out) +{ + h264e_hal_rkv_nal *nal = &(out->nal[out->nal_num]); + h264e_hal_rkv_stream *s = &out->stream; + RK_U8 *stream_buf = s->p_start; + RK_U8 *end = &stream_buf[hal_h264e_rkv_stream_get_pos(s) / 8]; + nal->i_payload = (RK_S32)(end - nal->p_payload); + /* Assembly implementation of nal_escape reads past the end of the input. + * While undefined padding wouldn't actually affect the output, it makes valgrind unhappy. */ + memset(end, 0xff, 64); + //if (h->param.nalu_process) + // h->param.nalu_process(h, nal, h->fenc->opaque); + out->nal_num++; + //return x264_nal_check_buffer(h); +} + +RK_U8 *hal_h264e_rkv_nal_escape_c(RK_U8 *dst, RK_U8 *src, RK_U8 *end) +{ + if (src < end) *dst++ = *src++; + if (src < end) *dst++ = *src++; + while (src < end) { + if (src[0] <= 0x03 && !dst[-2] && !dst[-1]) + *dst++ = 0x03; + *dst++ = *src++; + } + return dst; +} + +void hal_h264e_rkv_nal_encode(RK_U8 *dst, h264e_hal_rkv_nal *nal) +{ + RK_S32 b_annexb = 1; + RK_S32 size = 0; + RK_U8 *src = nal->p_payload; + RK_U8 *end = nal->p_payload + nal->i_payload; + RK_U8 *orig_dst = dst; + + if (b_annexb) { + //if (nal->b_long_startcode)//fix by gsl + //*dst++ = 0x00;//fix by gsl + *dst++ = 0x00; + *dst++ = 0x00; + *dst++ = 0x01; + } else /* save room for size later */ + dst += 4; + + /* nal header */ + *dst++ = (0x00 << 7) | (nal->i_ref_idc << 5) | nal->i_type; + + dst = hal_h264e_rkv_nal_escape_c(dst, src, end); + size = (RK_S32)((dst - orig_dst) - 4); + + /* Write the size header for mp4/etc */ + if (!b_annexb) { + /* Size doesn't include the size of the header we're writing now. */ + orig_dst[0] = size >> 24; + orig_dst[1] = size >> 16; + orig_dst[2] = size >> 8; + orig_dst[3] = size >> 0; + } + + nal->i_payload = size + 4; + nal->p_payload = orig_dst; +} + + + +MPP_RET hal_h264e_rkv_encapsulate_nals(h264e_hal_rkv_extra_info *out) +{ + RK_S32 i = 0; + RK_S32 i_avcintra_class = 0; + RK_S32 nal_size = 0; + RK_S32 necessary_size = 0; + RK_U8 *nal_buffer = out->nal_buf; + RK_S32 nal_num = out->nal_num; + h264e_hal_rkv_nal *nal = out->nal; + + h264e_hal_debug_enter(); + + for (i = 0; i < nal_num; i++) + nal_size += nal[i].i_payload; + + /* Worst-case NAL unit escaping: reallocate the buffer if it's too small. */ + necessary_size = nal_size * 3 / 2 + nal_num * 4 + 4 + 64; + for (i = 0; i < nal_num; i++) + necessary_size += nal[i].i_padding; + + for (i = 0; i < nal_num; i++) { + nal[i].b_long_startcode = !i || + nal[i].i_type == RKVENC_NAL_SPS || + nal[i].i_type == RKVENC_NAL_PPS || + i_avcintra_class; + hal_h264e_rkv_nal_encode(nal_buffer, &nal[i]); + nal_buffer += nal[i].i_payload; + } + + h264e_hal_log_header("nals total size: %d bytes", nal_buffer - out->nal_buf); + + h264e_hal_debug_leave(); + + return MPP_OK; +} + + + +MPP_RET hal_h264e_rkv_sps_write(h264e_hal_sps *sps, h264e_hal_rkv_stream *s) +{ + h264e_hal_debug_enter(); + + s->count_bit = 0; + hal_h264e_rkv_stream_realign(s); + hal_h264e_rkv_stream_write_with_log(s, 8, sps->i_profile_idc, "profile_idc"); + hal_h264e_rkv_stream_write1_with_log(s, sps->b_constraint_set0, "constraint_set0_flag"); + hal_h264e_rkv_stream_write1_with_log(s, sps->b_constraint_set1, "constraint_set1_flag"); + hal_h264e_rkv_stream_write1_with_log(s, sps->b_constraint_set2, "constraint_set2_flag"); + hal_h264e_rkv_stream_write1_with_log(s, sps->b_constraint_set3, "constraint_set3_flag"); + + hal_h264e_rkv_stream_write_with_log(s, 4, 0, "reserved_zero_4bits"); + + hal_h264e_rkv_stream_write_with_log(s, 8, sps->i_level_idc, "level_idc"); + + hal_h264e_rkv_stream_write_ue_with_log(s, sps->i_id, "seq_parameter_set_id"); + + if (sps->i_profile_idc >= H264_PROFILE_HIGH) { + hal_h264e_rkv_stream_write_ue_with_log(s, sps->i_chroma_format_idc, "chroma_format_idc"); + if (sps->i_chroma_format_idc == RKV_H264E_CHROMA_444) + hal_h264e_rkv_stream_write1_with_log(s, 0, "separate_colour_plane_flag"); + hal_h264e_rkv_stream_write_ue_with_log(s, H264_BIT_DEPTH - 8, "bit_depth_luma_minus8"); + hal_h264e_rkv_stream_write_ue_with_log(s, H264_BIT_DEPTH - 8, "bit_depth_chroma_minus8"); + hal_h264e_rkv_stream_write1_with_log(s, sps->b_qpprime_y_zero_transform_bypass, "qpprime_y_zero_transform_bypass_flag"); + hal_h264e_rkv_stream_write1_with_log(s, 0, "seq_scaling_matrix_present_flag"); + } + + hal_h264e_rkv_stream_write_ue_with_log(s, sps->i_log2_max_frame_num - 4, "log2_max_frame_num_minus4"); + hal_h264e_rkv_stream_write_ue_with_log(s, sps->i_poc_type, "delta_pic_order_always_zero_flag"); + if (sps->i_poc_type == 0) + hal_h264e_rkv_stream_write_ue_with_log(s, sps->i_log2_max_poc_lsb - 4, "log2_max_pic_order_cnt_lsb_minus4"); + hal_h264e_rkv_stream_write_ue_with_log(s, sps->i_num_ref_frames, "max_num_ref_frames"); + hal_h264e_rkv_stream_write1_with_log(s, sps->b_gaps_in_frame_num_value_allowed, "gaps_in_frame_num_value_allowed_flag"); + hal_h264e_rkv_stream_write_ue_with_log(s, sps->i_mb_width - 1, "pic_width_in_mbs_minus1"); + hal_h264e_rkv_stream_write_ue_with_log(s, (sps->i_mb_height >> !sps->b_frame_mbs_only) - 1, "pic_height_in_map_units_minus1"); + hal_h264e_rkv_stream_write1_with_log(s, sps->b_frame_mbs_only, "frame_mbs_only_flag"); + if (!sps->b_frame_mbs_only) + hal_h264e_rkv_stream_write1_with_log(s, sps->b_mb_adaptive_frame_field, "mb_adaptive_frame_field_flag"); + hal_h264e_rkv_stream_write1_with_log(s, sps->b_direct8x8_inference, "direct_8x8_inference_flag"); + + hal_h264e_rkv_stream_write1_with_log(s, sps->b_crop, "frame_cropping_flag"); + if (sps->b_crop) { + RK_S32 h_shift = sps->i_chroma_format_idc == RKV_H264E_CHROMA_420 || sps->i_chroma_format_idc == RKV_H264E_CHROMA_422; + RK_S32 v_shift = sps->i_chroma_format_idc == RKV_H264E_CHROMA_420; + hal_h264e_rkv_stream_write_ue_with_log(s, sps->crop.i_left >> h_shift, "frame_crop_left_offset"); + hal_h264e_rkv_stream_write_ue_with_log(s, sps->crop.i_right >> h_shift, "frame_crop_right_offset"); + hal_h264e_rkv_stream_write_ue_with_log(s, sps->crop.i_top >> v_shift, "frame_crop_top_offset"); + hal_h264e_rkv_stream_write_ue_with_log(s, sps->crop.i_bottom >> v_shift, "frame_crop_bottom_offset"); + } + + hal_h264e_rkv_stream_write1_with_log(s, sps->b_vui, "vui_parameters_present_flag"); + if (sps->b_vui) { + hal_h264e_rkv_stream_write1_with_log(s, sps->vui.b_aspect_ratio_info_present, "aspect_ratio_info_present_flag"); + if (sps->vui.b_aspect_ratio_info_present) { + RK_S32 i = 0; + static const struct { RK_U8 w, h, sar; } sar[] = { + // aspect_ratio_idc = 0 -> unspecified + { 1, 1, 1 }, { 12, 11, 2 }, { 10, 11, 3 }, { 16, 11, 4 }, + { 40, 33, 5 }, { 24, 11, 6 }, { 20, 11, 7 }, { 32, 11, 8 }, + { 80, 33, 9 }, { 18, 11, 10 }, { 15, 11, 11 }, { 64, 33, 12 }, + { 160, 99, 13 }, { 4, 3, 14 }, { 3, 2, 15 }, { 2, 1, 16 }, + // aspect_ratio_idc = [17..254] -> reserved + { 0, 0, 255 } + }; + for (i = 0; sar[i].sar != 255; i++) { + if (sar[i].w == sps->vui.i_sar_width && + sar[i].h == sps->vui.i_sar_height) + break; + } + hal_h264e_rkv_stream_write_with_log(s, 8, sar[i].sar, "aspect_ratio_idc"); + if (sar[i].sar == 255) { /* aspect_ratio_idc (extended) */ + hal_h264e_rkv_stream_write_with_log(s, 16, sps->vui.i_sar_width, "sar_width"); + hal_h264e_rkv_stream_write_with_log(s, 16, sps->vui.i_sar_height, "sar_height"); + } + } + + hal_h264e_rkv_stream_write1_with_log(s, sps->vui.b_overscan_info_present, "overscan_info_present_flag"); + if (sps->vui.b_overscan_info_present) + hal_h264e_rkv_stream_write1_with_log(s, sps->vui.b_overscan_info, "overscan_appropriate_flag"); + + hal_h264e_rkv_stream_write1_with_log(s, sps->vui.b_signal_type_present, "video_signal_type_present_flag"); + if (sps->vui.b_signal_type_present) { + hal_h264e_rkv_stream_write_with_log(s, 3, sps->vui.i_vidformat, "video_format"); + hal_h264e_rkv_stream_write1_with_log(s, sps->vui.b_fullrange, "video_full_range_flag"); + hal_h264e_rkv_stream_write1_with_log(s, sps->vui.b_color_description_present, "colour_description_present_flag"); + if (sps->vui.b_color_description_present) { + hal_h264e_rkv_stream_write_with_log(s, 8, sps->vui.i_colorprim, "colour_primaries"); + hal_h264e_rkv_stream_write_with_log(s, 8, sps->vui.i_transfer, "transfer_characteristics"); + hal_h264e_rkv_stream_write_with_log(s, 8, sps->vui.i_colmatrix, "matrix_coefficients"); + } + } + + hal_h264e_rkv_stream_write1_with_log(s, sps->vui.b_chroma_loc_info_present, "chroma_loc_info_present_flag"); + if (sps->vui.b_chroma_loc_info_present) { + hal_h264e_rkv_stream_write_ue_with_log(s, sps->vui.i_chroma_loc_top, "chroma_loc_info_present_flag"); + hal_h264e_rkv_stream_write_ue_with_log(s, sps->vui.i_chroma_loc_bottom, "chroma_sample_loc_type_bottom_field"); + } + + hal_h264e_rkv_stream_write1_with_log(s, sps->vui.b_timing_info_present, "chroma_sample_loc_type_bottom_field"); + if (sps->vui.b_timing_info_present) { + hal_h264e_rkv_stream_write32(s, sps->vui.i_num_units_in_tick, "num_units_in_tick"); + hal_h264e_rkv_stream_write32(s, sps->vui.i_time_scale, "time_scale"); + hal_h264e_rkv_stream_write1_with_log(s, sps->vui.b_fixed_frame_rate, "fixed_frame_rate_flag"); + } + + hal_h264e_rkv_stream_write1_with_log(s, sps->vui.b_nal_hrd_parameters_present, "time_scale"); + if (sps->vui.b_nal_hrd_parameters_present) { + hal_h264e_rkv_stream_write_ue_with_log(s, sps->vui.hrd.i_cpb_cnt - 1, "cpb_cnt_minus1"); + hal_h264e_rkv_stream_write_with_log(s, 4, sps->vui.hrd.i_bit_rate_scale, "bit_rate_scale"); + hal_h264e_rkv_stream_write_with_log(s, 4, sps->vui.hrd.i_cpb_size_scale, "cpb_size_scale"); + + hal_h264e_rkv_stream_write_ue_with_log(s, sps->vui.hrd.i_bit_rate_value - 1, "bit_rate_value_minus1"); + hal_h264e_rkv_stream_write_ue_with_log(s, sps->vui.hrd.i_cpb_size_value - 1, "cpb_size_value_minus1"); + + hal_h264e_rkv_stream_write1_with_log(s, sps->vui.hrd.b_cbr_hrd, "cbr_flag"); + + hal_h264e_rkv_stream_write_with_log(s, 5, sps->vui.hrd.i_initial_cpb_removal_delay_length - 1, "initial_cpb_removal_delay_length_minus1"); + hal_h264e_rkv_stream_write_with_log(s, 5, sps->vui.hrd.i_cpb_removal_delay_length - 1, "cpb_removal_delay_length_minus1"); + hal_h264e_rkv_stream_write_with_log(s, 5, sps->vui.hrd.i_dpb_output_delay_length - 1, "dpb_output_delay_length_minus1"); + hal_h264e_rkv_stream_write_with_log(s, 5, sps->vui.hrd.i_time_offset_length, "time_offset_length"); + } + + hal_h264e_rkv_stream_write1_with_log(s, sps->vui.b_vcl_hrd_parameters_present, "vcl_hrd_parameters_present_flag"); + + if (sps->vui.b_nal_hrd_parameters_present || sps->vui.b_vcl_hrd_parameters_present) + hal_h264e_rkv_stream_write1_with_log(s, 0, "low_delay_hrd_flag"); /* low_delay_hrd_flag */ + + hal_h264e_rkv_stream_write1_with_log(s, sps->vui.b_pic_struct_present, "pic_struct_present_flag"); + hal_h264e_rkv_stream_write1_with_log(s, sps->vui.b_bitstream_restriction, "bitstream_restriction_flag"); + if (sps->vui.b_bitstream_restriction) { + hal_h264e_rkv_stream_write1_with_log(s, sps->vui.b_motion_vectors_over_pic_boundaries, "motion_vectors_over_pic_boundaries_flag"); + hal_h264e_rkv_stream_write_ue_with_log(s, sps->vui.i_max_bytes_per_pic_denom, "max_bytes_per_pic_denom"); + hal_h264e_rkv_stream_write_ue_with_log(s, sps->vui.i_max_bits_per_mb_denom, "max_bits_per_mb_denom"); + hal_h264e_rkv_stream_write_ue_with_log(s, sps->vui.i_log2_max_mv_length_horizontal, "log2_max_mv_length_horizontal"); + hal_h264e_rkv_stream_write_ue_with_log(s, sps->vui.i_log2_max_mv_length_vertical, "log2_max_mv_length_vertical"); + hal_h264e_rkv_stream_write_ue_with_log(s, sps->vui.i_num_reorder_frames, "max_num_reorder_frames"); + hal_h264e_rkv_stream_write_ue_with_log(s, sps->vui.i_max_dec_frame_buffering, "max_num_reorder_frames"); + } + } + hal_h264e_rkv_stream_rbsp_trailing(s); + hal_h264e_rkv_stream_flush(s); + + h264e_hal_log_header("write pure sps head size: %d bits", s->count_bit); + + h264e_hal_debug_leave(); + + return MPP_OK; +} + + +/* +static void transpose( RK_U8 *buf, RK_S32 w ) +{ + RK_S32 i=0, j=0; + for(i = 0; i < w; i++ ) + for(j = 0; j < i; j++ ) + MPP_SWAP( RK_U8, buf[w*i+j], buf[w*j+i] ); +} +*/ + +MPP_RET hal_h264e_rkv_set_pps(h264e_hal_pps *pps, h264e_hal_param *par, h264e_control_extra_info_cfg *cfg, h264e_hal_sps *sps) +{ + RK_S32 k = 0; + RK_S32 i_avcintra_class = 0; + RK_S32 b_interlaced = 0; + RK_S32 analyse_weighted_pred = 0; + RK_S32 analyse_b_weighted_bipred = 0; + RK_S32 pps_init_qp = -1; //TODO: merge with syn + RK_S32 Sw_deblock_filter_ctrl_present_flag = 1; + RK_S32 b_cqm_preset = 0; + + pps->i_id = cfg->pps_id; + pps->i_sps_id = sps->i_id; + pps->b_cabac = cfg->enable_cabac; + + pps->b_pic_order = !i_avcintra_class && b_interlaced; + pps->i_num_slice_groups = 1; + + pps->i_num_ref_idx_l0_default_active = 1; + pps->i_num_ref_idx_l1_default_active = 1; + + pps->b_weighted_pred = analyse_weighted_pred > 0; + pps->i_weighted_bipred_idc = analyse_b_weighted_bipred ? 2 : 0; + + pps->i_pic_init_qp = cfg->pic_init_qp; + if (pps_init_qp >= 0 && pps_init_qp <= 51) { + pps->i_pic_init_qp = pps_init_qp; + } + pps->i_pic_init_qs = 26 + H264_QP_BD_OFFSET; + + pps->i_chroma_qp_index_offset = 0; //TODO: cfg->chroma_qp_index_offset; + pps->i_second_chroma_qp_index_offset = 0; //TODO: cfg->second_chroma_qp_index_offset; + pps->b_deblocking_filter_control = Sw_deblock_filter_ctrl_present_flag; + pps->b_constrained_intra_pred = par->constrained_intra; + pps->b_redundant_pic_cnt = 0; + + pps->b_transform_8x8_mode = sps->i_profile_idc >= H264_PROFILE_HIGH; //TODO: cfg->transform8x8_mode ? 1 : 0; + + pps->b_cqm_preset = b_cqm_preset; + + switch ( pps->b_cqm_preset ) { + case RKV_H264E_CQM_FLAT: + for (k = 0; k < 8; k++ ) + pps->scaling_list[k] = h264e_rkv_cqm_flat16; + break; + case RKV_H264E_CQM_JVT: + for (k = 0; k < 8; k++ ) + pps->scaling_list[k] = h264e_rkv_cqm_jvt[k]; + break; + case RKV_H264E_CQM_CUSTOM: + /* match the transposed DCT & zigzag */ + h264e_hal_log_err("CQM_CUSTOM mode is not supported now"); + return MPP_NOK; + //break; + default: + h264e_hal_log_err("invalid cqm_preset mode"); + return MPP_NOK; + //break; + } + + return MPP_OK; +} + +static void hal_h264e_rkv_scaling_list_write( h264e_hal_rkv_stream *s, h264e_hal_pps *pps, RK_S32 idx ) +{ + RK_S32 k = 0; + const RK_S32 len = idx < 4 ? 16 : 64; + const RK_U8 *zigzag = idx < 4 ? h264e_rkv_zigzag_scan4[0] : h264e_rkv_zigzag_scan8[0]; + const RK_U8 *list = pps->scaling_list[idx]; + const RK_U8 *def_list = (idx == RKV_H264E_CQM_4IC) ? pps->scaling_list[RKV_H264E_CQM_4IY] + : (idx == RKV_H264E_CQM_4PC) ? pps->scaling_list[RKV_H264E_CQM_4PY] + : (idx == RKV_H264E_CQM_8IC + 4) ? pps->scaling_list[RKV_H264E_CQM_8IY + 4] + : (idx == RKV_H264E_CQM_8PC + 4) ? pps->scaling_list[RKV_H264E_CQM_8PY + 4] + : h264e_rkv_cqm_jvt[idx]; + if ( !memcmp( list, def_list, len ) ) + hal_h264e_rkv_stream_write1_with_log( s, 0, "scaling_list_present_flag"); // scaling_list_present_flag + else if ( !memcmp( list, h264e_rkv_cqm_jvt[idx], len ) ) { + hal_h264e_rkv_stream_write1_with_log( s, 1, "scaling_list_present_flag"); // scaling_list_present_flag + hal_h264e_rkv_stream_write_se_with_log( s, -8, "use_jvt_list"); // use jvt list + } else { + RK_S32 run; + hal_h264e_rkv_stream_write1_with_log( s, 1, "scaling_list_present_flag"); // scaling_list_present_flag + + // try run-length compression of trailing values + for ( run = len; run > 1; run-- ) + if ( list[zigzag[run - 1]] != list[zigzag[run - 2]] ) + break; + if ( run < len && len - run < hal_h264e_rkv_stream_size_se( (RK_S8) - list[zigzag[run]] ) ) + run = len; + + for ( k = 0; k < run; k++ ) + hal_h264e_rkv_stream_write_se_with_log( s, (RK_S8)(list[zigzag[k]] - (k > 0 ? list[zigzag[k - 1]] : 8)), "delta_scale"); // delta + + if ( run < len ) + hal_h264e_rkv_stream_write_se_with_log( s, (RK_S8) - list[zigzag[run]], "-scale"); + } +} + +MPP_RET hal_h264e_rkv_pps_write(h264e_hal_pps *pps, h264e_hal_sps *sps, h264e_hal_rkv_stream *s) +{ + h264e_hal_debug_enter(); + + s->count_bit = 0; + hal_h264e_rkv_stream_realign( s ); + + hal_h264e_rkv_stream_write_ue_with_log( s, pps->i_id, "pic_parameter_set_id"); + hal_h264e_rkv_stream_write_ue_with_log( s, pps->i_sps_id, "seq_parameter_set_id"); + + hal_h264e_rkv_stream_write1_with_log( s, pps->b_cabac, "entropy_coding_mode_flag"); + hal_h264e_rkv_stream_write1_with_log( s, pps->b_pic_order, "bottom_field_pic_order_in_frame_present_flag"); + hal_h264e_rkv_stream_write_ue_with_log( s, pps->i_num_slice_groups - 1, "num_slice_groups_minus1"); + + hal_h264e_rkv_stream_write_ue_with_log( s, pps->i_num_ref_idx_l0_default_active - 1, "num_ref_idx_l0_default_active_minus1"); + hal_h264e_rkv_stream_write_ue_with_log( s, pps->i_num_ref_idx_l1_default_active - 1, "num_ref_idx_l1_default_active_minus1"); + hal_h264e_rkv_stream_write1_with_log( s, pps->b_weighted_pred, "weighted_pred_flag"); + hal_h264e_rkv_stream_write_with_log( s, 2, pps->i_weighted_bipred_idc, "weighted_bipred_idc"); + + hal_h264e_rkv_stream_write_se_with_log( s, pps->i_pic_init_qp - 26 - H264_QP_BD_OFFSET, "pic_init_qp_minus26"); + hal_h264e_rkv_stream_write_se_with_log( s, pps->i_pic_init_qs - 26 - H264_QP_BD_OFFSET, "pic_init_qs_minus26"); + hal_h264e_rkv_stream_write_se_with_log( s, pps->i_chroma_qp_index_offset, "chroma_qp_index_offset"); + + hal_h264e_rkv_stream_write1_with_log( s, pps->b_deblocking_filter_control, "deblocking_filter_control_present_flag"); + hal_h264e_rkv_stream_write1_with_log( s, pps->b_constrained_intra_pred, "constrained_intra_pred_flag"); + hal_h264e_rkv_stream_write1_with_log( s, pps->b_redundant_pic_cnt, "redundant_pic_cnt_present_flag"); + + if ( pps->b_transform_8x8_mode || pps->b_cqm_preset != RKV_H264E_CQM_FLAT ) { + hal_h264e_rkv_stream_write1_with_log( s, pps->b_transform_8x8_mode, "transform_8x8_mode_flag"); + hal_h264e_rkv_stream_write1_with_log( s, (pps->b_cqm_preset != RKV_H264E_CQM_FLAT), "pic_scaling_matrix_present_flag"); + if ( pps->b_cqm_preset != RKV_H264E_CQM_FLAT ) { + hal_h264e_rkv_scaling_list_write( s, pps, RKV_H264E_CQM_4IY); + hal_h264e_rkv_scaling_list_write( s, pps, RKV_H264E_CQM_4IC ); + hal_h264e_rkv_stream_write1_with_log( s, 0, "scaling_list_end_flag"); // Cr = Cb TODO:replaced with real name + hal_h264e_rkv_scaling_list_write( s, pps, RKV_H264E_CQM_4PY ); + hal_h264e_rkv_scaling_list_write( s, pps, RKV_H264E_CQM_4PC ); + hal_h264e_rkv_stream_write1_with_log( s, 0, "scaling_list_end_flag"); // Cr = Cb TODO:replaced with real name + if ( pps->b_transform_8x8_mode ) { + if ( sps->i_chroma_format_idc == RKV_H264E_CHROMA_444 ) { + hal_h264e_rkv_scaling_list_write( s, pps, RKV_H264E_CQM_8IY + 4 ); + hal_h264e_rkv_scaling_list_write( s, pps, RKV_H264E_CQM_8IC + 4 ); + hal_h264e_rkv_stream_write1_with_log( s, 0, "scaling_list_end_flag" ); // Cr = Cb TODO:replaced with real name + hal_h264e_rkv_scaling_list_write( s, pps, RKV_H264E_CQM_8PY + 4 ); + hal_h264e_rkv_scaling_list_write( s, pps, RKV_H264E_CQM_8PC + 4 ); + hal_h264e_rkv_stream_write1_with_log( s, 0, "scaling_list_end_flag" ); // Cr = Cb TODO:replaced with real name + } else { + hal_h264e_rkv_scaling_list_write( s, pps, RKV_H264E_CQM_8IY + 4 ); + hal_h264e_rkv_scaling_list_write( s, pps, RKV_H264E_CQM_8PY + 4 ); + } + } + } + hal_h264e_rkv_stream_write_se_with_log( s, pps->i_second_chroma_qp_index_offset, "second_chroma_qp_index_offset"); + } + + hal_h264e_rkv_stream_rbsp_trailing( s ); + hal_h264e_rkv_stream_flush( s ); + + h264e_hal_log_header("write pure pps size: %d bits", s->count_bit); + + h264e_hal_debug_leave(); + + return MPP_OK; +} + +static MPP_RET hal_h264e_rkv_init_extra_info(h264e_hal_rkv_extra_info *extra_info) +{ + hal_h264e_rkv_nals_init(extra_info); + hal_h264e_rkv_stream_init(&extra_info->stream); + + return MPP_OK; +} + +static MPP_RET hal_h264e_rkv_deinit_extra_info(void *extra_info) +{ + h264e_hal_rkv_extra_info *info = (h264e_hal_rkv_extra_info *)extra_info; + hal_h264e_rkv_stream_deinit(&info->stream); + hal_h264e_rkv_nals_deinit(info); + + return MPP_OK; +} + +static MPP_RET hal_h264e_rkv_set_extra_info(h264e_hal_context *ctx, void *param) +{ + h264e_control_extra_info_cfg *cfg = (h264e_control_extra_info_cfg *)param; + h264e_hal_param *par = &ctx->param; + h264e_hal_rkv_extra_info *info = (h264e_hal_rkv_extra_info *)ctx->extra_info; + h264e_hal_sps *sps_info = &info->sps; + h264e_hal_pps *pps_info = &info->pps; + + h264e_hal_debug_enter(); + hal_h264e_rkv_dump_mpp_extra_info_cfg(ctx, cfg); + + info->nal_num = 0; + hal_h264e_rkv_stream_reset(&info->stream); + + hal_h264e_rkv_nal_start(info, RKVENC_NAL_SPS, RKVENC_NAL_PRIORITY_HIGHEST); + hal_h264e_rkv_set_sps(sps_info, par, cfg); + hal_h264e_rkv_sps_write(sps_info, &info->stream); + hal_h264e_rkv_nal_end(info); + + hal_h264e_rkv_nal_start(info, RKVENC_NAL_PPS, RKVENC_NAL_PRIORITY_HIGHEST); + hal_h264e_rkv_set_pps(pps_info, par, cfg, sps_info); + hal_h264e_rkv_pps_write(pps_info, sps_info, &info->stream); + hal_h264e_rkv_nal_end(info); + + hal_h264e_rkv_encapsulate_nals(info); + + h264e_hal_debug_leave(); + + return MPP_OK; +} + + +static void hal_h264e_rkv_reference_deinit( h264e_hal_rkv_dpb_ctx *dpb_ctx) +{ + h264e_hal_rkv_dpb_ctx *d_ctx = (h264e_hal_rkv_dpb_ctx *)dpb_ctx; + + h264e_hal_debug_enter(); + + MPP_FREE(d_ctx->frames.unused); + + h264e_hal_debug_leave(); +} + + +static void hal_h264e_rkv_reference_init( void *dpb, h264e_hal_param *par) +{ + //RK_S32 k = 0; + h264e_hal_rkv_dpb_ctx *dpb_ctx = (h264e_hal_rkv_dpb_ctx *)dpb; + h264e_hal_ref_param *ref_cfg = &par->ref; + + h264e_hal_debug_enter(); + memset(dpb_ctx, 0, sizeof(h264e_hal_rkv_dpb_ctx)); + + dpb_ctx->frames.unused = mpp_calloc(h264e_hal_rkv_frame *, H264E_REF_MAX + 1); + //for(k=0; kframes.reference[k] = &dpb_ctx->frame_buf[k]; + // h264e_hal_log_dpb("dpb_ctx->frames.reference[%d]: %p", k, dpb_ctx->frames.reference[k]); + //} + dpb_ctx->i_long_term_reference_flag = ref_cfg->i_long_term_en; + dpb_ctx->i_tmp_idr_pic_id = 0; + + h264e_hal_debug_leave(); +} + +MPP_RET hal_h264e_rkv_init(void *hal, MppHalCfg *cfg) +{ + h264e_hal_context *ctx = (h264e_hal_context *)hal; + h264e_hal_rkv_dpb_ctx *dpb_ctx = NULL; + h264e_hal_debug_enter(); + + hal_h264e_rkv_set_param(&ctx->param); + + ctx->ioctl_input = mpp_calloc(h264e_rkv_ioctl_input, 1); + ctx->ioctl_output = mpp_calloc(h264e_rkv_ioctl_output, 1); + ctx->regs = mpp_calloc(h264e_rkv_reg_set, RKV_H264E_LINKTABLE_FRAME_NUM); + ctx->buffers = mpp_calloc(h264e_hal_rkv_buffers, 1); + ctx->extra_info = mpp_calloc(h264e_hal_rkv_extra_info, 1); + ctx->dpb_ctx = mpp_calloc(h264e_hal_rkv_dpb_ctx, 1); + ctx->dump_files = mpp_calloc(h264e_hal_rkv_dump_files, 1); + ctx->param_size = H264E_MAX_PACKETED_PARAM_SIZE; + ctx->param_buf = mpp_calloc_size(void, ctx->param_size); + mpp_packet_init(&ctx->packeted_param, ctx->param_buf, ctx->param_size); + hal_h264e_rkv_open_dump_files(ctx->dump_files); + hal_h264e_rkv_init_extra_info(ctx->extra_info); + hal_h264e_rkv_reference_init(ctx->dpb_ctx, &ctx->param); + + ctx->int_cb = cfg->hal_int_cb; + ctx->frame_cnt = 0; + ctx->frame_cnt_gen_ready = 0; + ctx->frame_cnt_send_ready = 0; + ctx->num_frames_to_send = 1; + + /* support multi-refs */ + dpb_ctx = (h264e_hal_rkv_dpb_ctx *)ctx->dpb_ctx; + dpb_ctx->i_frame_cnt = 0; + dpb_ctx->i_frame_num = 0; + + ctx->vpu_socket = -1; + ctx->vpu_client = VPU_ENC_RKV; + h264e_hal_log_detail("vpu client: %d", ctx->vpu_client); +#ifdef RKPLATFORM + if (ctx->vpu_socket <= 0) { + ctx->vpu_socket = VPUClientInit(ctx->vpu_client); + if (ctx->vpu_socket <= 0) { + h264e_hal_log_err("get vpu_socket(%d) <=0, failed. \n", ctx->vpu_socket); + return MPP_ERR_UNKNOW; + } else { + VPUHwEncConfig_t hwCfg; + h264e_hal_log_detail("get vpu_socket(%d), success. \n", ctx->vpu_socket); + memset(&hwCfg, 0, sizeof(VPUHwEncConfig_t)); + if (VPUClientGetHwCfg(ctx->vpu_socket, (RK_U32*)&hwCfg, sizeof(hwCfg))) { + h264e_hal_log_err("h264enc # Get HwCfg failed, release vpu\n"); + VPUClientRelease(ctx->vpu_socket); + return MPP_NOK; + } + } + } +#endif + + h264e_hal_debug_leave(); + return MPP_OK; +} + +MPP_RET hal_h264e_rkv_deinit(void *hal) +{ + h264e_hal_context *ctx = (h264e_hal_context *)hal; + h264e_hal_debug_enter(); + + MPP_FREE(ctx->regs); + MPP_FREE(ctx->ioctl_input); + MPP_FREE(ctx->ioctl_output); + + if (ctx->buffers) { + hal_h264e_rkv_free_buffers(ctx); + MPP_FREE(ctx->buffers); + } + + if (ctx->extra_info) { + hal_h264e_rkv_deinit_extra_info(ctx->extra_info); + MPP_FREE(ctx->extra_info); + } + + if (ctx->packeted_param) { + mpp_packet_deinit(&ctx->packeted_param); + ctx->packeted_param = NULL; + } + + if (ctx->param_buf) { + mpp_free(ctx->param_buf); + ctx->param_buf = NULL; + } + + ctx->param_size = 0; + + if (ctx->dpb_ctx) { + hal_h264e_rkv_reference_deinit(ctx->dpb_ctx); + MPP_FREE(ctx->dpb_ctx); + } + + if (ctx->dump_files) { + hal_h264e_rkv_close_dump_files(ctx->dump_files); + MPP_FREE(ctx->dump_files); + } + +#ifdef RKPLATFORM + if (ctx->vpu_socket <= 0) { + h264e_hal_log_err("invalid vpu socket: %d", ctx->vpu_socket); + return MPP_NOK; + } + + if (VPU_SUCCESS != VPUClientRelease(ctx->vpu_socket)) { + h264e_hal_log_err("VPUClientRelease failed"); + return MPP_ERR_VPUHW; + } +#endif + + + h264e_hal_debug_leave(); + return MPP_OK; +} + + +MPP_RET hal_h264e_rkv_set_ioctl_extra_info(h264e_rkv_ioctl_extra_info *extra_info, h264e_syntax *syn) +{ + h264e_rkv_ioctl_extra_info_elem *info = NULL; + RK_U32 frame_size = syn->pic_luma_width * syn->pic_luma_height; // TODO: according to yuv format + + extra_info->magic = 0; + extra_info->cnt = 2; + + /* input cb addr */ + info = &extra_info->elem[0]; + info->reg_idx = 71; + info->offset = frame_size; + + /* input cr addr */ + info = &extra_info->elem[1]; + info->reg_idx = 72; + info->offset = frame_size * 5 / 4; //TODO: relevant with YUV format + return MPP_OK; +} + +static MPP_RET hal_h264e_rkv_validate_syntax(h264e_syntax *syn, h264e_hal_rkv_csp_info *src_fmt, RK_U32 gop_start) +{ + RK_U32 input_image_format = syn->input_image_format; + h264e_hal_debug_enter(); + + /* validate */ + H264E_HAL_VALIDATE_GT(syn->output_strm_limit_size, "output_strm_limit_size", 0); + + /* adjust */ + *src_fmt = hal_h264e_rkv_convert_csp(input_image_format); + syn->input_image_format = src_fmt->fmt; + + syn->input_cb_addr = syn->input_luma_addr; + syn->input_cr_addr = syn->input_luma_addr; + + H264E_HAL_VALIDATE_NEQ(syn->input_image_format, "input_image_format", H264E_RKV_CSP_NONE); + if (syn->frame_coding_type == 1) { /* ASIC_INTRA */ + if (gop_start) + syn->frame_coding_type = RKVENC_FRAME_TYPE_IDR; + else + syn->frame_coding_type = RKVENC_FRAME_TYPE_I; + } else { /* ASIC_INTER */ + syn->frame_coding_type = RKVENC_FRAME_TYPE_P; + } + + h264e_hal_debug_leave(); + return MPP_OK; +} + +MPP_RET hal_h264e_rkv_set_rc_regs(h264e_rkv_reg_set *regs, h264e_syntax *syn, + h264e_hal_rkv_coveragetest_cfg *test) +{ + if (test && test->mbrc) { + RK_U32 num_mbs_oneframe = (syn->pic_luma_width + 15) / 16 * ((syn->pic_luma_height + 15) / 16); + RK_U32 frame_target_bitrate = (syn->pic_luma_width * syn->pic_luma_height / 1920 / 1080) * 10000000 / 8; //Bytes + RK_U32 frame_target_size = frame_target_bitrate / syn->keyframe_max_interval; + RK_U32 mb_target_size = frame_target_size / num_mbs_oneframe; + RK_U32 aq_strength = 2; + + h264e_hal_log_detail("---- test-mbrc ----"); + regs->swreg46.rc_en = 1; + regs->swreg46.rc_mode = 1; //0:frame/slice rc; 1:mbrc + regs->swreg46.aqmode_en = 1; + regs->swreg46.aq_strg = (RK_U32)(aq_strength * 1.0397 * 256); + regs->swreg46.Reserved = 0x0; + regs->swreg46.rc_ctu_num = (syn->pic_luma_width + 15) / 16; + + regs->swreg47.bits_error0 = ((mb_target_size >> 4) * num_mbs_oneframe / 2) * -192; //sw_bits_error[0]; + regs->swreg47.bits_error1 = ((mb_target_size >> 4) * num_mbs_oneframe / 2) * -144; //sw_bits_error[1]; + regs->swreg48.bits_error2 = ((mb_target_size >> 4) * num_mbs_oneframe / 2) * -96; //sw_bits_error[2]; + regs->swreg48.bits_error3 = ((mb_target_size >> 4) * num_mbs_oneframe / 2) * -16; //sw_bits_error[3]; + regs->swreg49.bits_error4 = ((mb_target_size >> 4) * num_mbs_oneframe / 2) * 16; //sw_bits_error[4]; + regs->swreg49.bits_error5 = ((mb_target_size >> 4) * num_mbs_oneframe / 2) * 96; //sw_bits_error[5]; + regs->swreg50.bits_error6 = ((mb_target_size >> 4) * num_mbs_oneframe / 2) * 144; //sw_bits_error[6]; + regs->swreg50.bits_error7 = ((mb_target_size >> 4) * num_mbs_oneframe / 2) * 192; //sw_bits_error[7]; + regs->swreg51.bits_error8 = ((mb_target_size >> 4) * num_mbs_oneframe / 2) * 256; //sw_bits_error[8]; + + regs->swreg52.qp_adjuest0 = -4; //sw_qp_adjuest[0]; + regs->swreg52.qp_adjuest1 = -3; //sw_qp_adjuest[1]; + regs->swreg52.qp_adjuest2 = -2; //sw_qp_adjuest[2]; + regs->swreg52.qp_adjuest3 = -1; //sw_qp_adjuest[3]; + regs->swreg52.qp_adjuest4 = 0; //sw_qp_adjuest[4]; + regs->swreg52.qp_adjuest5 = 1; //sw_qp_adjuest[5]; + regs->swreg53.qp_adjuest6 = 2; //sw_qp_adjuest[6]; + regs->swreg53.qp_adjuest7 = 3; //sw_qp_adjuest[7]; + regs->swreg53.qp_adjuest8 = 4; //sw_qp_adjuest[8]; + + regs->swreg54.rc_qp_mod = 2; //sw_quality_flag; + regs->swreg54.rc_fact0 = 8; //sw_quality_factor_0; + regs->swreg54.rc_fact1 = 8; //sw_quality_factor_1; + regs->swreg54.Reserved = 0x0; + regs->swreg54.rc_qp_range = 4; //sw_rc_clip_qp_range; regs->swreg54.rc_max_qp = 40; regs->swreg54.rc_min_qp = 20; - - regs->swreg55.ctu_ebits = mb_target_size; //sw_ctu_target_bits; - } else { - regs->swreg46.rc_mode = 0; //0:frame/slice rc; 1:mbrc - regs->swreg54.rc_qp_range = 4; //yn->swreg54.rc_qp_range; - regs->swreg54.rc_max_qp = 51; //syn->swreg54.rc_max_qp; - regs->swreg54.rc_min_qp = 1; //syn->swreg54.rc_min_qp; - - regs->swreg55.ctu_ebits = 0; //syn->swreg55.ctu_ebits; - - (void)test; - } - - return MPP_OK; -} - -MPP_RET hal_h264e_rkv_set_roi_regs(h264e_rkv_reg_set *regs, h264e_syntax *syn, MppBuffer roi_idx_buf, RK_U32 frame_cnt, - h264e_hal_rkv_coveragetest_cfg *test) -{ - if (test && test->roi) { - RK_U32 k = 0; - RK_U32 num_mbs_oneframe = (syn->pic_luma_width + 15) / 16 * ((syn->pic_luma_height + 15) / 16); - h264e_hal_rkv_roi_cfg *roi_cfg = mpp_calloc(h264e_hal_rkv_roi_cfg, num_mbs_oneframe); - h264e_hal_log_detail("---- test-roi ----"); - regs->swreg10.roi_enc = 1; - regs->swreg29_ctuc_addr = mpp_buffer_get_fd(roi_idx_buf); - if (frame_cnt % 3 == 0) { - for (k = 0; k < 4 * ((syn->pic_luma_width + 15) / 16); k++) { - roi_cfg[k].set_qp_y_en = 1; - roi_cfg[k].qp_y = 20; - } - } else if (frame_cnt % 3 == 1) { - for (k = 0; k < 4 * ((syn->pic_luma_width + 15) / 16); k++) { - roi_cfg[k].forbit_inter = 1; - } - } else { // frame_cnt%3==2 - for (k = 0; k < 4 * ((syn->pic_luma_width + 15) / 16); k++) { - roi_cfg[k].set_qp_y_en = 1; - roi_cfg[k].qp_y = 20; - roi_cfg[k].forbit_inter = 1; - } - } - mpp_buffer_write(roi_idx_buf, 0, (void *)roi_cfg, num_mbs_oneframe); - MPP_FREE(roi_cfg); - } else { - regs->swreg10.roi_enc = 0; //syn->swreg10.roi_enc; - (void)test; - } - - return MPP_OK; -} - -MPP_RET hal_h264e_rkv_set_osd_regs(h264e_rkv_reg_set *regs, h264e_syntax *syn, MppBuffer osd_idx_buf, - h264e_hal_rkv_coveragetest_cfg *test) -{ - if (test && test->osd) { -#define OSD_SIZE_MBS 4 //size of osd in mb - RK_S32 k = 0; - RK_U32 osd_r0_en = 1; - RK_U32 osd_r1_en = 1; - RK_U32 osd_r2_en = 1; - RK_U32 osd_r3_en = 1; - RK_U32 osd_r4_en = 1; - RK_U32 osd_r5_en = 1; - RK_U32 osd_r6_en = 1; - RK_U32 osd_r7_en = 1; - - RK_U32 osd_r0_inv_en = 0; - RK_U32 osd_r1_inv_en = 0; - RK_U32 osd_r2_inv_en = 0; - RK_U32 osd_r3_inv_en = 0; - RK_U32 osd_r4_inv_en = 0; - RK_U32 osd_r5_inv_en = 0; - RK_U32 osd_r6_inv_en = 0; - RK_U32 osd_r7_inv_en = 0; - - RK_U32 osd_size_pixels = 16 * OSD_SIZE_MBS * 16 * OSD_SIZE_MBS; - h264e_hal_log_detail("---- test-osd ----"); - - - regs->swreg65.osd_en = (osd_r0_en << 0) + (osd_r1_en << 1) + (osd_r2_en << 2) + (osd_r3_en << 3) + (osd_r4_en << 4) + (osd_r5_en << 5) + (osd_r6_en << 6) + (osd_r7_en << 7); - regs->swreg65.osd_inv = (osd_r0_inv_en << 0) + (osd_r1_inv_en << 1) + (osd_r2_inv_en << 2) + (osd_r3_inv_en << 3) + - (osd_r4_inv_en << 4) + (osd_r5_inv_en << 5) + (osd_r6_inv_en << 6) + (osd_r7_inv_en << 7); - - regs->swreg65.osd_clk_sel = 1; - regs->swreg65.osd_plt_type = 0; //OSD_plt_type; - - regs->swreg66.osd_inv_r1 = 0; //OSD_r1_inv_range; - regs->swreg66.osd_inv_r2 = 0; //OSD_r2_inv_range; - regs->swreg66.osd_inv_r3 = 0; //OSD_r3_inv_range; - regs->swreg66.osd_inv_r4 = 0; //OSD_r4_inv_range; - regs->swreg66.osd_inv_r5 = 0; //OSD_r5_inv_range; - regs->swreg66.osd_inv_r6 = 0; //OSD_r6_inv_range; - regs->swreg66.osd_inv_r7 = 0; //OSD_r7_inv_range; - - regs->swreg67_osd_pos[0].lt_pos_x = 0 * OSD_SIZE_MBS; //OSD_r0_x_lt_pos; - regs->swreg67_osd_pos[0].lt_pos_y = 0 * OSD_SIZE_MBS; //OSD_r0_y_lt_pos; - regs->swreg67_osd_pos[0].rd_pos_x = 0 * OSD_SIZE_MBS + OSD_SIZE_MBS - 1; //OSD_r0_x_rd_pos; - regs->swreg67_osd_pos[0].rd_pos_y = 0 * OSD_SIZE_MBS + OSD_SIZE_MBS - 1; //OSD_r0_y_rd_pos; - - regs->swreg67_osd_pos[1].lt_pos_x = 1 * OSD_SIZE_MBS; //OSD_r1_x_lt_pos; - regs->swreg67_osd_pos[1].lt_pos_y = 0 * OSD_SIZE_MBS; //OSD_r1_y_lt_pos; - regs->swreg67_osd_pos[1].rd_pos_x = 1 * OSD_SIZE_MBS + OSD_SIZE_MBS - 1; //OSD_r1_x_rd_pos; - regs->swreg67_osd_pos[1].rd_pos_y = 0 * OSD_SIZE_MBS + OSD_SIZE_MBS - 1; //OSD_r1_y_rd_pos; - - regs->swreg67_osd_pos[2].lt_pos_x = 2 * OSD_SIZE_MBS; //OSD_r2_x_lt_pos; - regs->swreg67_osd_pos[2].lt_pos_y = 0 * OSD_SIZE_MBS; //OSD_r2_y_lt_pos; - regs->swreg67_osd_pos[2].rd_pos_x = 2 * OSD_SIZE_MBS + OSD_SIZE_MBS - 1; //OSD_r2_x_rd_pos; - regs->swreg67_osd_pos[2].rd_pos_y = 0 * OSD_SIZE_MBS + OSD_SIZE_MBS - 1; //OSD_r2_y_rd_pos; - - regs->swreg67_osd_pos[3].lt_pos_x = 3 * OSD_SIZE_MBS; //OSD_r3_x_lt_pos; - regs->swreg67_osd_pos[3].lt_pos_y = 0 * OSD_SIZE_MBS; //OSD_r3_y_lt_pos; - regs->swreg67_osd_pos[3].rd_pos_x = 3 * OSD_SIZE_MBS + OSD_SIZE_MBS - 1; //OSD_r3_x_rd_pos; - regs->swreg67_osd_pos[3].rd_pos_y = 0 * OSD_SIZE_MBS + OSD_SIZE_MBS - 1; //OSD_r3_y_rd_pos; - - regs->swreg67_osd_pos[4].lt_pos_x = 0 * OSD_SIZE_MBS; //OSD_r4_x_lt_pos; - regs->swreg67_osd_pos[4].lt_pos_y = 1 * OSD_SIZE_MBS; //OSD_r4_y_lt_pos; - regs->swreg67_osd_pos[4].rd_pos_x = 0 * OSD_SIZE_MBS + OSD_SIZE_MBS - 1; //OSD_r4_x_rd_pos; - regs->swreg67_osd_pos[4].rd_pos_y = 1 * OSD_SIZE_MBS + OSD_SIZE_MBS - 1; //OSD_r4_x_rd_pos; - - regs->swreg67_osd_pos[5].lt_pos_x = 1 * OSD_SIZE_MBS; //OSD_r5_x_lt_pos; - regs->swreg67_osd_pos[5].lt_pos_y = 1 * OSD_SIZE_MBS; //OSD_r5_y_lt_pos; - regs->swreg67_osd_pos[5].rd_pos_x = 1 * OSD_SIZE_MBS + OSD_SIZE_MBS - 1; //OSD_r5_x_rd_pos; - regs->swreg67_osd_pos[5].rd_pos_y = 1 * OSD_SIZE_MBS + OSD_SIZE_MBS - 1; //OSD_r5_y_rd_pos; - - regs->swreg67_osd_pos[6].lt_pos_x = 2 * OSD_SIZE_MBS; //OSD_r6_x_lt_pos; - regs->swreg67_osd_pos[6].lt_pos_y = 1 * OSD_SIZE_MBS; //OSD_r6_y_lt_pos; - regs->swreg67_osd_pos[6].rd_pos_x = 2 * OSD_SIZE_MBS + OSD_SIZE_MBS - 1; //OSD_r6_x_rd_pos; - regs->swreg67_osd_pos[6].rd_pos_y = 1 * OSD_SIZE_MBS + OSD_SIZE_MBS - 1; //OSD_r6_y_rd_pos; - - regs->swreg67_osd_pos[7].lt_pos_x = 3 * OSD_SIZE_MBS; //OSD_r7_x_lt_pos; - regs->swreg67_osd_pos[7].lt_pos_y = 1 * OSD_SIZE_MBS; //OSD_r7_y_lt_pos; - regs->swreg67_osd_pos[7].rd_pos_x = 3 * OSD_SIZE_MBS + OSD_SIZE_MBS - 1; //OSD_r7_x_rd_pos; - regs->swreg67_osd_pos[7].rd_pos_y = 1 * OSD_SIZE_MBS + OSD_SIZE_MBS - 1; //OSD_r7_y_rd_pos; - - for (k = 0; k < 8; k++) { - if (regs->swreg65.osd_plt_type == 0) //configurable - memset((RK_U8 *)mpp_buffer_get_ptr(osd_idx_buf) + k * osd_size_pixels, 32 * k, osd_size_pixels); - else //fixed mode: only support idx 0~7 - memset((RK_U8 *)mpp_buffer_get_ptr(osd_idx_buf) + k * osd_size_pixels, k, osd_size_pixels); - - regs->swreg68_indx_addr_i[k] = mpp_buffer_get_fd(osd_idx_buf) | ((k * osd_size_pixels) << 10); //h->param.indx_addr_i[i]; - } -#if 0 //written in kernel - for (k = 0; k < 256; k++) { - regs->swreg73_osd_indx_tab_i[k] = k | (0x80 << 8) | (0x80 << 16) | (k << 24); - } -#endif - - } else { - - (void)test; - } - (void)syn; - - return MPP_OK; -} - -MPP_RET hal_h264e_rkv_set_pp_regs(h264e_rkv_reg_set *regs, h264e_syntax *syn, MppBuffer hw_buf_w, MppBuffer hw_buf_r, RK_U32 frame_cnt, - h264e_hal_rkv_coveragetest_cfg *test) -{ - RK_S32 k = 0; - RK_S32 stridey, stridec; - if (test && test->preproc) { - - RK_U32 h3d_tbl[40] = { - 0x0b080400, 0x1815120f, 0x23201e1b, 0x2c2a2725, - 0x33312f2d, 0x38373634, 0x3d3c3b39, 0x403f3e3d, - 0x42414140, 0x43434342, 0x44444444, 0x44444444, - 0x44444444, 0x43434344, 0x42424343, 0x40414142, - 0x3d3e3f40, 0x393a3b3c, 0x35363738, 0x30313334, - 0x2c2d2e2f, 0x28292a2b, 0x23242526, 0x20202122, - 0x191b1d1f, 0x14151618, 0x0f101112, 0x0b0c0d0e, - 0x08090a0a, 0x06070708, 0x05050506, 0x03040404, - 0x02020303, 0x01010102, 0x00010101, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000 - }; - - h264e_hal_log_detail("---- test-preproc ----"); - //regs->swreg14.src_aswap = 0; //h->param.swap_a; - //regs->swreg14.src_cswap = 0; //h->param.swap_c; - regs->swreg14.src_cfmt = syn->input_image_format; //(h->param.prep_cfg_val&0xf000) ? h->param.format : 0x7; //src_cfmt - regs->swreg14.src_clip_dis = 0; //csc_clip_range; - - regs->swreg15.wght_b2y = 0;// csc_par_lu_b; - regs->swreg15.wght_g2y = 0;// csc_par_lu_g; - regs->swreg15.wght_r2y = 0;// csc_par_lu_r; - - regs->swreg16.wght_b2u = 0; //csc_par_cb_b; - regs->swreg16.wght_g2u = 0; //csc_par_cb_g; - regs->swreg16.wght_r2u = 0; //csc_par_cb_r; - - regs->swreg17.wght_b2v = 0; //csc_par_cr_b; - regs->swreg17.wght_g2v = 0; //csc_par_cr_g; - regs->swreg17.wght_r2v = 0; //csc_par_cr_r; - - regs->swreg18.ofst_rgb2v = 0; //csc_par_cr_offset; - regs->swreg18.ofst_rgb2u = 0; //csc_par_cb_offset; - regs->swreg18.ofst_rgb2y = 0; //csc_par_lu_offset; - - regs->swreg19.src_tfltr = (frame_cnt == 0) ? 0 : 1; //temporal_en; - regs->swreg19.src_tfltr_we = 1; //temporal_wr_en; - regs->swreg19.src_tfltr_bw = 0; //temporal_bw; - - regs->swreg19.src_sfltr = 1; //spatial_en; - regs->swreg19.src_mfltr_thrd = 7; //median_threshold; - regs->swreg19.src_mfltr_y = 1; //median_en; - regs->swreg19.src_mfltr_c = 0; //median_chroma_en; - regs->swreg19.src_bfltr_strg = 0; //sw_bilater_flag != 0; //be check - regs->swreg19.src_bfltr = 1; //bilater_en; - regs->swreg19.src_mbflt_odr = 0; //filter_order; - regs->swreg19.src_matf_y = 1; //matf_lu_en; - regs->swreg19.src_matf_c = 1; //matf_ch_en; - regs->swreg19.src_shp_y = 1; //sharp_lu_en; - regs->swreg19.src_shp_c = 0; //sharp_ch_en; - regs->swreg19.src_shp_div = 5; //sharp_div; - regs->swreg19.src_shp_thld = 5; //sharp_threshold; - regs->swreg19.src_mirr = 0; //mirr_mode; - regs->swreg19.src_rot = 0; //rot_mode; - regs->swreg19.src_matf_itsy = 0; //matf_lu_flag; - - regs->swreg20.tfltr_thld_y = 60; //matf_lu_threshold; - regs->swreg20.reserve = 0x0; - regs->swreg20.tfltr_thld_c = 80; //matf_ch_threshold; - regs->swreg20.reserve1 = 0x0; - - regs->swreg21_scr_stbl[0] = (RK_U32)1073741823; //sharp_matrix[0]; - regs->swreg21_scr_stbl[1] = (RK_U32)1073741823; //sharp_matrix[1]; - regs->swreg21_scr_stbl[2] = (RK_U32)0xfff38fff;// 4294152191; //sharp_matrix[2]; - regs->swreg21_scr_stbl[3] = (RK_U32)1073741823; //sharp_matrix[3]; - regs->swreg21_scr_stbl[4] = (RK_U32)1073741823; //sharp_matrix[4]; - - for (k = 0; k < 40; k++) - regs->swreg22_h3d_tbl[k] = h3d_tbl[k]; - - - stridey = (syn->pic_luma_width + 15) & (~15); - stridec = stridey; - - regs->swreg23.src_ystrid = stridey; - regs->swreg23.reserve = 0x0; - regs->swreg23.src_cstrid = stridec; ////YUV420 planar; - - regs->swreg27_fltw_addr = mpp_buffer_get_fd(hw_buf_w); - regs->swreg28_fltr_addr = mpp_buffer_get_fd(hw_buf_r); - } else { - regs->swreg14.src_cfmt = syn->input_image_format; //syn->swreg14.src_cfmt; //src_cfmt - - for (k = 0; k < 5; k++) - regs->swreg21_scr_stbl[k] = 0; //syn->swreg21_scr_stbl[k]; - - for (k = 0; k < 40; k++) - regs->swreg22_h3d_tbl[k] = h264e_h3d_tbl[k]; - - stridey = (regs->swreg19.src_rot == 1 || regs->swreg19.src_rot == 3) ? (syn->pic_luma_height - 1) : (syn->pic_luma_width - 1); - if (regs->swreg14.src_cfmt == 0 ) - stridey = (stridey + 1) * 4 - 1; - else if (regs->swreg14.src_cfmt == 1 ) - stridey = (stridey + 1) * 3 - 1; - else if ( regs->swreg14.src_cfmt == 2 || regs->swreg14.src_cfmt == 8 || regs->swreg14.src_cfmt == 9 ) - stridey = (stridey + 1) * 2 - 1; - stridec = (regs->swreg14.src_cfmt == 4 || regs->swreg14.src_cfmt == 6) ? stridey : ((stridey + 1) / 2 - 1); - regs->swreg23.src_ystrid = stridey; //syn->swreg23.src_ystrid; - regs->swreg23.src_cstrid = stridec; //syn->swreg23.src_cstrid; ////YUV420 planar; - - (void)test; - } - - return MPP_OK; -} - -MPP_RET hal_h264e_rkv_gen_regs(void *hal, HalTaskInfo *task) -{ - h264e_hal_context *ctx = (h264e_hal_context *)hal; - h264e_hal_param *par = &ctx->param; - h264e_rkv_reg_set *regs = NULL; - h264e_hal_rkv_csp_info src_fmt; - h264e_syntax *syn = (h264e_syntax *)task->enc.syntax.data; - h264e_rkv_ioctl_input *ioctl_info = (h264e_rkv_ioctl_input *)ctx->ioctl_input; - h264e_rkv_reg_set *reg_list = (h264e_rkv_reg_set *)ctx->regs; - h264e_hal_rkv_dpb_ctx *dpb_ctx = (h264e_hal_rkv_dpb_ctx *)ctx->dpb_ctx; - h264e_hal_rkv_extra_info *extra_info = (h264e_hal_rkv_extra_info *)ctx->extra_info; - h264e_hal_rkv_coveragetest_cfg *test_cfg = (h264e_hal_rkv_coveragetest_cfg *)ctx->test_cfg; - h264e_hal_sps *sps = &extra_info->sps; - h264e_hal_pps *pps = &extra_info->pps; - - RK_S32 pic_width_align16 = (syn->pic_luma_width + 15) & (~15); - RK_S32 pic_height_align16 = (syn->pic_luma_height + 15) & (~15); - RK_S32 pic_width_in_blk64 = (syn->pic_luma_width + 63) / 64; - h264e_hal_rkv_buffers *bufs = (h264e_hal_rkv_buffers *)ctx->buffers; - RK_U32 mul_buf_idx = ctx->frame_cnt % RKV_H264E_LINKTABLE_FRAME_NUM; - RK_U32 buf2_idx = ctx->frame_cnt % 2; - //RK_S32 pic_height_align64 = (syn->pic_luma_height + 63) & (~63); - ctx->enc_mode = RKV_H264E_ENC_MODE; - - h264e_hal_debug_enter(); - hal_h264e_rkv_dump_mpp_syntax_in(syn, ctx); - - if (MPP_OK != hal_h264e_rkv_validate_syntax(syn, &src_fmt, ctx->frame_cnt % sps->keyframe_max_interval == 0)) { - h264e_hal_log_err("hal_h264e_rkv_validate_syntax failed"); - } - - ctx->enc_task = task->enc; - - hal_h264e_rkv_adjust_param(ctx); //TODO: future expansion - - h264e_hal_log_simple("frame %d | type %d | start gen regs", ctx->frame_cnt, syn->slice_type); - - if (ctx->frame_cnt == 0) { - if (MPP_OK != hal_h264e_rkv_allocate_buffers(ctx, syn, sps, test_cfg)) { - h264e_hal_log_err("hal_h264e_rkv_allocate_buffers failed, free now"); - hal_h264e_rkv_free_buffers(ctx); - } - } - - if (ctx->enc_mode == 2 || ctx->enc_mode == 3) { //link table mode - RK_U32 idx = ctx->frame_cnt_gen_ready; - ctx->num_frames_to_send = RKV_H264E_LINKTABLE_EACH_NUM; - if (idx == 0) { - ioctl_info->enc_mode = ctx->enc_mode; - ioctl_info->frame_num = ctx->num_frames_to_send; - } - regs = ®_list[idx]; - ioctl_info->reg_info[idx].reg_num = sizeof(h264e_rkv_reg_set) / 4; - hal_h264e_rkv_set_ioctl_extra_info(&ioctl_info->reg_info[idx].extra_info, syn); - } else { - ctx->num_frames_to_send = 1; - ioctl_info->frame_num = ctx->num_frames_to_send; - ioctl_info->enc_mode = ctx->enc_mode; - regs = ®_list[0]; - ioctl_info->reg_info[0].reg_num = sizeof(h264e_rkv_reg_set) / 4; - hal_h264e_rkv_set_ioctl_extra_info(&ioctl_info->reg_info[0].extra_info, syn); - } - - if (MPP_OK != hal_h264e_rkv_reference_frame_set(ctx, syn)) { - h264e_hal_log_err("hal_h264e_rkv_reference_frame_set failed, multi-ref error"); - } - - h264e_hal_log_detail("generate regs when frame_cnt_gen_ready/(num_frames_to_send-1): %d/%d", - ctx->frame_cnt_gen_ready, ctx->num_frames_to_send - 1); - - memset(regs, 0, sizeof(h264e_rkv_reg_set)); - - regs->swreg01.rkvenc_ver = 0x1; - - regs->swreg02.lkt_num = 0; //syn->link_table_en? h->param.i_frame_total : 0; - regs->swreg02.rkvenc_cmd = ctx->enc_mode; - //regs->swreg02.rkvenc_cmd = syn->link_table_en ? 0x2 : 0x1; - regs->swreg02.enc_cke = 0; //syn->swreg02.enc_cke; - - regs->swreg03.safe_clr = 0x0; - - regs->swreg04.lkt_addr = 0x10000000;//syn->swreg04.lkt_addr; - - regs->swreg05.ofe_fnsh = 1; //syn->swreg05.ofe_fnsh; - regs->swreg05.lkt_fnsh = 1; //syn->swreg05.lkt_fnsh; - regs->swreg05.clr_fnsh = 1; //syn->swreg05.clr_fnsh; - regs->swreg05.ose_fnsh = 1; //syn->swreg05.ose_fnsh; - regs->swreg05.bs_ovflr = 1; //syn->swreg05.bs_ovflr; - regs->swreg05.brsp_ful = 1; //syn->swreg05.brsp_ful; - regs->swreg05.brsp_err = 1; //syn->swreg05.brsp_err; - regs->swreg05.rrsp_err = 1; //syn->swreg05.rrsp_err; - regs->swreg05.tmt_err = 1; //syn->swreg05.tmt_err ; - - regs->swreg09.pic_wd8_m1 = pic_width_align16 / 8 - 1; - regs->swreg09.pic_wfill = (syn->pic_luma_width & 0xf) ? (16 - (syn->pic_luma_width & 0xf)) : 0; - regs->swreg09.pic_hd8_m1 = pic_height_align16 / 8 - 1; - regs->swreg09.pic_hfill = (syn->pic_luma_height & 0xf) ? (16 - (syn->pic_luma_height & 0xf)) : 0; - - regs->swreg10.enc_stnd = 0; //H264 - regs->swreg10.cur_frm_ref = ((ctx->frame_cnt + 1) % sps->keyframe_max_interval) != 0; //syn->swreg10.cur_frm_ref; //Current frame should be refered in future - regs->swreg10.mei_stor = 0; //syn->swreg10.mei_stor; - regs->swreg10.bs_scp = 1; //syn->swreg10.bs_scp; - regs->swreg10.pic_qp = syn->qp;//syn->swreg10.pic_qp; //if CQP, pic_qp=qp constant. - regs->swreg10.slice_int = 0; //syn->swreg10.slice_int; - regs->swreg10.node_int = 0; //syn->swreg10.node_int;//node_int_frame_pos - - regs->swreg11.ppln_enc_lmt = 2; //syn->swreg11.ppln_enc_lmt; - regs->swreg11.rfp_load_thrd = 0; //syn->swreg11.rfp_load_thrd; - - regs->swreg12.src_bus_ordr = 0x0; - regs->swreg12.cmvw_bus_ordr = 0x0; - regs->swreg12.dspw_bus_ordr = 0x0; - regs->swreg12.rfpw_bus_ordr = 0x0; - regs->swreg12.src_bus_edin = 0x0;//syn->swreg12.src_bus_edin; - regs->swreg12.meiw_bus_edin = 0x0; - regs->swreg12.bsw_bus_edin = 0x7; - regs->swreg12.lktr_bus_edin = 0x0; - regs->swreg12.ctur_bus_edin = 0x0; - regs->swreg12.lktw_bus_edin = 0x0; - regs->swreg12.rfp_map_dcol = 0x0; - regs->swreg12.rfp_map_sctr = 0x0; - - regs->swreg13.axi_brsp_cke = 0x7f; //syn->swreg13.axi_brsp_cke; - regs->swreg13.cime_dspw_orsd = 0x0; - - hal_h264e_rkv_set_pp_regs(regs, syn, bufs->hw_pp_buf[buf2_idx], bufs->hw_pp_buf[1 - buf2_idx], ctx->frame_cnt, test_cfg); - - regs->swreg24_adr_srcy = syn->input_luma_addr; //syn->addr_cfg.adr_srcy; - regs->swreg25_adr_srcu = syn->input_cb_addr; //syn->addr_cfg.adr_srcu; - regs->swreg26_adr_srcv = syn->input_cr_addr; //syn->addr_cfg.adr_srcv; - hal_h264e_rkv_set_roi_regs(regs, syn, bufs->hw_roi_buf[mul_buf_idx], ctx->frame_cnt, test_cfg); - - regs->swreg30_rfpw_addr = mpp_buffer_get_fd(dpb_ctx->fdec->hw_buf);//syn->addr_cfg.rfpw_addr; //TODO: extend recon luma buf - if (dpb_ctx->fref[0][0]) - regs->swreg31_rfpr_addr = mpp_buffer_get_fd(dpb_ctx->fref[0][0]->hw_buf); //syn->addr_cfg.rfpr_addr; - //regs->swreg32_cmvw_addr = mpp_buffer_get_fd(bufs->hw_cmv_buf[buf2_idx]); - - if (bufs->hw_dsp_buf[buf2_idx]) - regs->swreg34_dspw_addr = mpp_buffer_get_fd(bufs->hw_dsp_buf[buf2_idx]); //syn->addr_cfg.dspw_addr; - if (bufs->hw_dsp_buf[1 - buf2_idx]) - regs->swreg35_dspr_addr = mpp_buffer_get_fd(bufs->hw_dsp_buf[1 - buf2_idx]); //syn->addr_cfg.dspr_addr; - - regs->swreg36_meiw_addr = 0; //mpp_buffer_get_fd(bufs->hw_mei_buf[mul_buf_idx]); - regs->swreg38_bsbb_addr = syn->output_strm_addr; - if (VPUClientGetIOMMUStatus() > 0) - regs->swreg37_bsbt_addr = regs->swreg38_bsbb_addr | (syn->output_strm_limit_size << 10); // TODO: stream size relative with syntax - else - regs->swreg37_bsbt_addr = regs->swreg38_bsbb_addr + (syn->output_strm_limit_size); - regs->swreg39_bsbr_addr = regs->swreg38_bsbb_addr; - regs->swreg40_bsbw_addr = regs->swreg38_bsbb_addr; //syn->addr_cfg.bsbw_addr; - - h264e_hal_log_dpb("regs->swreg37_bsbt_addr: %08x", regs->swreg37_bsbt_addr); - h264e_hal_log_dpb("regs->swreg38_bsbb_addr: %08x", regs->swreg38_bsbb_addr); - h264e_hal_log_dpb("regs->swreg39_bsbr_addr: %08x", regs->swreg39_bsbr_addr); - h264e_hal_log_dpb("regs->swreg40_bsbw_addr: %08x", regs->swreg40_bsbw_addr); - - regs->swreg41.sli_cut = 0; //syn->swreg41.sli_cut; - regs->swreg41.sli_cut_mode = 0; //syn->swreg41.sli_cut_mode; - regs->swreg41.sli_cut_bmod = 1; //syn->swreg41.sli_cut_bmod; - regs->swreg41.sli_max_num = 0; //syn->swreg41.sli_max_num; - regs->swreg41.sli_out_mode = 0; //syn->swreg41.sli_out_mode; - regs->swreg41.sli_cut_cnum = 0; //syn->swreg41.sli_cut_cnum; - - regs->swreg42.sli_cut_byte = 0; //syn->swreg42.sli_cut_byte; - - { - RK_U32 cime_wid_4p = 0, cime_hei_4p = 0; - if ( sps->i_level_idc == 10 || sps->i_level_idc == 9 ) { //9 is level 1b; - cime_wid_4p = 44; - cime_hei_4p = 12; - } else if ( sps->i_level_idc == 11 || sps->i_level_idc == 12 || sps->i_level_idc == 13 || sps->i_level_idc == 20 ) { - cime_wid_4p = 44; - cime_hei_4p = 28; - } else { - cime_wid_4p = 44; - cime_hei_4p = 28; - } - - if (176 < cime_wid_4p * 4) - cime_wid_4p = 176 / 4; - - if (112 < cime_hei_4p * 4) - cime_hei_4p = 112 / 4; - - if (cime_hei_4p / 4 * 2 > (RK_U32)(regs->swreg09.pic_hd8_m1 + 2) / 2) - cime_hei_4p = (regs->swreg09.pic_hd8_m1 + 2) / 2 / 2 * 4; - - if (cime_wid_4p / 4 > (RK_U32)(((regs->swreg09.pic_wd8_m1 + 1) * 8 + 63) / 64 * 64 / 128 * 4)) - cime_wid_4p = ((regs->swreg09.pic_wd8_m1 + 1) * 8 + 63) / 64 * 64 / 128 * 4 * 4; - - regs->swreg43.cime_srch_h = cime_wid_4p / 4; //syn->swreg43.cime_srch_h; - regs->swreg43.cime_srch_v = cime_hei_4p / 4; //syn->swreg43.cime_srch_v; - } - - regs->swreg43.rime_srch_h = 7; //syn->swreg43.rime_srch_h; - regs->swreg43.rime_srch_v = 5; //syn->swreg43.rime_srch_v; - regs->swreg43.dlt_frm_num = 0x0; - - regs->swreg44.pmv_mdst_h = 5; //syn->swreg44.pmv_mdst_h; - regs->swreg44.pmv_mdst_v = 5; //syn->swreg44.pmv_mdst_v; - regs->swreg44.mv_limit = (sps->i_level_idc > 20) ? 2 : ((sps->i_level_idc >= 11) ? 1 : 0); //syn->swreg44.mv_limit; - regs->swreg44.mv_num = 3; //syn->swreg44.mv_num; - - - if (pic_width_align16 > 3584) - regs->swreg45.cime_rama_h = 8; - else if (pic_width_align16 > 3136) - regs->swreg45.cime_rama_h = 9; - else if (pic_width_align16 > 2816) - regs->swreg45.cime_rama_h = 10; - else if (pic_width_align16 > 2560) - regs->swreg45.cime_rama_h = 11; - else if (pic_width_align16 > 2368) - regs->swreg45.cime_rama_h = 12; - else if (pic_width_align16 > 2176) - regs->swreg45.cime_rama_h = 13; - else if (pic_width_align16 > 2048) - regs->swreg45.cime_rama_h = 14; - else if (pic_width_align16 > 1856) - regs->swreg45.cime_rama_h = 15; - else if (pic_width_align16 > 1792) - regs->swreg45.cime_rama_h = 16; - else - regs->swreg45.cime_rama_h = 17; - - { - RK_U32 i_swin_all_4_h = (2 * regs->swreg43.cime_srch_v + 1); - RK_U32 i_swin_all_16_w = ((regs->swreg43.cime_srch_h * 4 + 15) / 16 * 2 + 1); - if (i_swin_all_4_h < regs->swreg45.cime_rama_h) - regs->swreg45.cime_rama_max = (i_swin_all_4_h - 1) * pic_width_in_blk64 + i_swin_all_16_w; - else - regs->swreg45.cime_rama_max = (regs->swreg45.cime_rama_h - 1) * pic_width_in_blk64 + i_swin_all_16_w; - } - - regs->swreg45.cach_l1_dtmr = 0x3; //syn->swreg45.cach_l1_dtmr; - regs->swreg45.cach_l2_tag = 0x0; - if (pic_width_align16 <= 512) - regs->swreg45.cach_l2_tag = 0x0; - else if (pic_width_align16 <= 1024) - regs->swreg45.cach_l2_tag = 0x1; - else if (pic_width_align16 <= 2048) - regs->swreg45.cach_l2_tag = 0x2; - else if (pic_width_align16 <= 4096) - regs->swreg45.cach_l2_tag = 0x3; - - hal_h264e_rkv_set_rc_regs(regs, syn, test_cfg); - - regs->swreg56.rect_size = (sps->i_profile_idc == H264_PROFILE_BASELINE && sps->i_level_idc <= 30); - regs->swreg56.inter_4x4 = 1; - regs->swreg56.arb_sel = 0; //syn->swreg56.arb_sel; - regs->swreg56.vlc_lmt = (sps->i_profile_idc < H264_PROFILE_HIGH && !syn->enable_cabac); - regs->swreg56.rdo_mark = 0; //syn->swreg56.rdo_mark; - /*if (syn->transform8x8_mode == 0 && (syn->swreg56.rdo_mark & 0xb5) == 0xb5) //NOTE: bug may exist here - { - h264e_hal_log_err("RdoMark and trans8x8 conflict!"); - mpp_assert(0); - return MPP_NOK; - }*/ - - { - RK_U32 i_nal_type = 0, i_nal_ref_idc = 0; - - if (syn->frame_coding_type == RKVENC_FRAME_TYPE_IDR ) { //TODO: extend syn->frame_coding_type definition - /* reset ref pictures */ - i_nal_type = RKVENC_NAL_SLICE_IDR; - i_nal_ref_idc = RKVENC_NAL_PRIORITY_HIGHEST; - } else if (syn->frame_coding_type == RKVENC_FRAME_TYPE_I ) { - i_nal_type = RKVENC_NAL_SLICE; - i_nal_ref_idc = RKVENC_NAL_PRIORITY_HIGH; /* Not completely true but for now it is (as all I/P are kept as ref)*/ - } else if (syn->frame_coding_type == RKVENC_FRAME_TYPE_P ) { - i_nal_type = RKVENC_NAL_SLICE; - i_nal_ref_idc = RKVENC_NAL_PRIORITY_HIGH; /* Not completely true but for now it is (as all I/P are kept as ref)*/ - } else if (syn->frame_coding_type == RKVENC_FRAME_TYPE_BREF ) { - i_nal_type = RKVENC_NAL_SLICE; - i_nal_ref_idc = RKVENC_NAL_PRIORITY_HIGH; - } else { /* B frame */ - i_nal_type = RKVENC_NAL_SLICE; - i_nal_ref_idc = RKVENC_NAL_PRIORITY_DISPOSABLE; - } - if (sps->keyframe_max_interval == 1) - i_nal_ref_idc = RKVENC_NAL_PRIORITY_LOW; - - regs->swreg57.nal_ref_idc = i_nal_ref_idc; //syn->swreg57.nal_ref_idc; - regs->swreg57.nal_unit_type = i_nal_type; //syn->swreg57.nal_unit_type; - } - - - regs->swreg58.max_fnum = sps->i_log2_max_frame_num - 4; //syn->swreg58.max_fnum; - regs->swreg58.drct_8x8 = 1; //syn->swreg58.drct_8x8; - regs->swreg58.mpoc_lm4 = sps->i_log2_max_poc_lsb - 4; //syn->swreg58.mpoc_lm4; - - regs->swreg59.etpy_mode = syn->enable_cabac; - regs->swreg59.trns_8x8 = pps->b_transform_8x8_mode; //syn->swreg59.trns_8x8; - regs->swreg59.csip_flg = par->constrained_intra; //syn->swreg59.csip_flg; - regs->swreg59.num_ref0_idx = pps->i_num_ref_idx_l0_default_active - 1; //syn->swreg59.num_ref0_idx; - regs->swreg59.num_ref1_idx = pps->i_num_ref_idx_l1_default_active - 1; //syn->swreg59.num_ref1_idx; - regs->swreg59.pic_init_qp = syn->pic_init_qp - H264_QP_BD_OFFSET; - regs->swreg59.cb_ofst = pps->i_chroma_qp_index_offset; //syn->chroma_qp_index_offset; - regs->swreg59.cr_ofst = pps->i_second_chroma_qp_index_offset; //syn->second_chroma_qp_index_offset; - regs->swreg59.wght_pred = 0x0; - regs->swreg59.dbf_cp_flg = 1; //syn->deblocking_filter_control; - - regs->swreg60.sli_type = syn->slice_type; //syn->swreg60.sli_type; - regs->swreg60.pps_id = syn->pps_id; - regs->swreg60.drct_smvp = 0x0; - regs->swreg60.num_ref_ovrd = 0; - regs->swreg60.cbc_init_idc = syn->cabac_init_idc; - - regs->swreg60.frm_num = dpb_ctx->i_frame_num; - - regs->swreg61.idr_pid = dpb_ctx->i_idr_pic_id; - regs->swreg61.poc_lsb = dpb_ctx->fdec->i_poc & ((1 << sps->i_log2_max_poc_lsb) - 1); - - regs->swreg62.rodr_pic_idx = dpb_ctx->ref_pic_list_order[0][0].idc; //syn->swreg62.rodr_pic_idx; - regs->swreg62.ref_list0_rodr = dpb_ctx->b_ref_pic_list_reordering[0]; //syn->swreg62.ref_list0_rodr; - regs->swreg62.sli_beta_ofst = 0; //syn->slice_beta_offset; - regs->swreg62.sli_alph_ofst = 0; //syn->slice_alpha_offset; - regs->swreg62.dis_dblk_idc = 0; //syn->disable_deblocking_filter_idc; - regs->swreg62.rodr_pic_num = dpb_ctx->ref_pic_list_order[0][0].arg; //syn->swreg62.rodr_pic_num; - - { - RK_S32 mmco4_pre = dpb_ctx->i_mmco_command_count > 0 && (dpb_ctx->mmco[0].memory_management_control_operation == 4); - regs->swreg63.nopp_flg = 0x0; - regs->swreg63.ltrf_flg = dpb_ctx->i_long_term_reference_flag; //syn->swreg63.ltrf_flg; - regs->swreg63.arpm_flg = dpb_ctx->i_mmco_command_count; //syn->swreg63.arpm_flg; - regs->swreg63.mmco4_pre = mmco4_pre; - regs->swreg63.mmco_0 = dpb_ctx->i_mmco_command_count > mmco4_pre ? dpb_ctx->mmco[mmco4_pre].memory_management_control_operation : 0; - regs->swreg63.dopn_m1_0 = dpb_ctx->i_mmco_command_count > mmco4_pre ? dpb_ctx->mmco[mmco4_pre].i_difference_of_pic_nums - 1 : 0;; //syn->swreg63.dopn_m1_0; - - regs->swreg64.mmco_1 = dpb_ctx->i_mmco_command_count > (mmco4_pre + 1) ? dpb_ctx->mmco[(mmco4_pre + 1)].memory_management_control_operation : 0; //syn->swreg64.mmco_1; - regs->swreg64.dopn_m1_1 = dpb_ctx->i_mmco_command_count > (mmco4_pre + 1) ? dpb_ctx->mmco[(mmco4_pre + 1)].i_difference_of_pic_nums - 1 : 0; //syn->swreg64.dopn_m1_1; - } - - hal_h264e_rkv_set_osd_regs(regs, syn, bufs->hw_osd_buf[mul_buf_idx], test_cfg); - - regs->swreg69.bs_lgth = 0x0; - - regs->swreg70.sse_l32 = 0x0; - - regs->swreg71.qp_sum = 0x0; - regs->swreg71.sse_h8 = 0x0; - - regs->swreg72.slice_scnum = 0x0; - regs->swreg72.slice_slnum = 0x0; - - regs->swreg73.st_enc = 0x0; - regs->swreg73.axiw_cln = 0x0; - regs->swreg73.axir_cln = 0x0; - - regs->swreg74.fnum_enc = 0x0; - regs->swreg74.fnum_cfg = 0x0; - regs->swreg74.fnum_int = 0x0; - - regs->swreg75.node_addr = 0x0; - - regs->swreg76.bsbw_addr = 0x0; //syn->swreg77.bsbw_addr; read only - regs->swreg76.Bsbw_ovfl = 0x0; - -#if !RKV_H264E_REMOVE_UNNECESSARY_REGS - regs->swreg77.axib_idl = 0x0; - regs->swreg77.axib_ful = 0x0; - regs->swreg77.axib_err = 0x0; - regs->swreg77.axir_err = 0x0; - - regs->swreg78.slice_num = 0x0; - - regs->swreg79.slice_len = 0x0; - - for (k = 0; k < 256; k++) - regs->swreg80_osd_indx_tab_i[k] = 0; //syn->swreg73_osd_indx_tab_i[k]; - - regs->swreg81.axip0_work = 0x0; - regs->swreg81.axip0_clr = 0x0; - - regs->swreg82.axip0_ltcy_id = 0x0; - regs->swreg82.axip0_ltcy_thr = 0x0; - - regs->swreg83.axip0_cnt_type = 0x0; - regs->swreg83.axip0_cnt_ddr = 0x0; - regs->swreg83.axip0_cnt_rid = 0x0; - regs->swreg83.axip0_cnt_wid = 0x0; - - regs->swreg84.axip1_work = 0x0; - regs->swreg84.axip1_clr = 0x0; - - regs->swreg85.axip1_ltcy_id = 0x0; - regs->swreg85.axip1_ltcy_thr = 0x0; - - regs->swreg86.axip1_cnt_type = 0x0; - regs->swreg86.axip1_cnt_ddr = 0x0; - regs->swreg86.axip1_cnt_rid = 0x0; - regs->swreg86.axip1_cnt_wid = 0x0; - - regs->swreg87.axip0_cnt_type = 0x0; - - regs->swreg88.axip0_num_ltcy = 0x0; - - regs->swreg89.axip0_sum_ltcy = 0x0; - - regs->swreg90.axip0_byte_rd = 0x0; - - regs->swreg91.axip0_byte_wr = 0x0; - - regs->swreg92.axip0_wrk_cyc = 0x0; - - regs->swreg93.axip1_cnt_type = 0x0; - - regs->swreg94.axip1_num_ltcy = 0x0; - - regs->swreg95.axip1_sum_ltcy = 0x0; - - regs->swreg96.axip1_byte_rd = 0x0; - - regs->swreg97.axip1_byte_wr = 0x0; - - regs->swreg98.axip1_wrk_cyc = 0x0; -#endif //#if !RKV_H264E_REMOVE_UNNECESSARY_REGS - - hal_h264e_rkv_dump_mpp_reg_in(ctx); - - hal_h264e_rkv_reference_frame_update(ctx); - dpb_ctx->i_frame_cnt++; - if (dpb_ctx->i_nal_ref_idc != RKVENC_NAL_PRIORITY_DISPOSABLE) - dpb_ctx->i_frame_num ++; - - ctx->frame_cnt_gen_ready++; - ctx->frame_cnt++; - - h264e_hal_debug_leave(); - - return MPP_OK; -} - -MPP_RET hal_h264e_rkv_start(void *hal, HalTaskInfo *task) -{ - MPP_RET ret = MPP_OK; - h264e_hal_context *ctx = (h264e_hal_context *)hal; - h264e_rkv_reg_set *reg_list = (h264e_rkv_reg_set *)ctx->regs; - RK_U32 length = 0, k = 0; - h264e_rkv_ioctl_input *ioctl_info = (h264e_rkv_ioctl_input *)ctx->ioctl_input; - - h264e_hal_debug_enter(); - if (ctx->frame_cnt_gen_ready != ctx->num_frames_to_send) { - h264e_hal_log_detail("frame_cnt_gen_ready(%d) != num_frames_to_send(%d), start hardware later", - ctx->frame_cnt_gen_ready, ctx->num_frames_to_send); - return MPP_OK; - } - - h264e_hal_log_detail("memcpy %d frames' regs from reg list to reg info", ioctl_info->frame_num); - for (k = 0; k < ioctl_info->frame_num; k++) - memcpy(&ioctl_info->reg_info[k].regs, ®_list[k], sizeof(h264e_rkv_reg_set)); - - length = (sizeof(ioctl_info->enc_mode) + sizeof(ioctl_info->frame_num) + - sizeof(ioctl_info->reg_info[0]) * ioctl_info->frame_num) >> 2; - - ctx->frame_cnt_send_ready ++; - - (void)task; - -#ifdef RKPLATFORM - if (ctx->vpu_socket <= 0) { - h264e_hal_log_err("invalid vpu socket: %d", ctx->vpu_socket); - return MPP_NOK; - } - - h264e_hal_log_detail("vpu client is sending %d regs", length); - if (MPP_OK != VPUClientSendReg(ctx->vpu_socket, (RK_U32 *)ioctl_info, length)) { - h264e_hal_log_err("VPUClientSendReg Failed!!!"); - return MPP_ERR_VPUHW; - } else { - h264e_hal_log_detail("VPUClientSendReg successfully!"); - } -#else - (void)length; -#endif - - h264e_hal_debug_leave(); - - return ret; -} - -static MPP_RET hal_h264e_rkv_set_feedback(h264e_feedback *fb, h264e_rkv_ioctl_output *out) -{ - RK_U32 k = 0; - h264e_rkv_ioctl_output_elem *elem = NULL; - h264e_hal_debug_enter(); - for (k = 0; k < out->frame_num; k++) { - elem = &out->elem[k]; - fb->qp_sum = elem->swreg71.qp_sum; - fb->out_strm_size = elem->swreg69.bs_lgth; - - fb->hw_status = 0; - h264e_hal_log_detail("hw_status: 0x%08x", elem->hw_status); - if (elem->hw_status & RKV_H264E_INT_LINKTABLE_FINISH) { - h264e_hal_log_err("RKV_H264E_INT_LINKTABLE_FINISH"); - } - if (elem->hw_status & RKV_H264E_INT_ONE_FRAME_FINISH) { - h264e_hal_log_detail("RKV_H264E_INT_ONE_FRAME_FINISH"); - } - if (elem->hw_status & RKV_H264E_INT_ONE_SLICE_FINISH) { - h264e_hal_log_err("RKV_H264E_INT_ONE_SLICE_FINISH"); - } - - if (elem->hw_status & RKV_H264E_INT_SAFE_CLEAR_FINISH) { - h264e_hal_log_err("RKV_H264E_INT_SAFE_CLEAR_FINISH"); - } - - if (elem->hw_status & RKV_H264E_INT_BIT_STREAM_OVERFLOW) { - h264e_hal_log_err("RKV_H264E_INT_BIT_STREAM_OVERFLOW"); - fb->hw_status = 1; - } - if (elem->hw_status & RKV_H264E_INT_BUS_WRITE_FULL) { - h264e_hal_log_err("RKV_H264E_INT_BUS_WRITE_FULL"); - fb->hw_status = 1; - } - if (elem->hw_status & RKV_H264E_INT_BUS_WRITE_ERROR) { - h264e_hal_log_err("RKV_H264E_INT_BUS_WRITE_ERROR"); - fb->hw_status = 1; - } - if (elem->hw_status & RKV_H264E_INT_BUS_READ_ERROR) { - h264e_hal_log_err("RKV_H264E_INT_BUS_READ_ERROR"); - fb->hw_status = 1; - } - if (elem->hw_status & RKV_H264E_INT_TIMEOUT_ERROR) { - h264e_hal_log_err("RKV_H264E_INT_TIMEOUT_ERROR"); - fb->hw_status = 1; - } - - fb->hw_status = elem->hw_status; - } - - h264e_hal_debug_leave(); - return MPP_OK; -} - -MPP_RET hal_h264e_rkv_wait(void *hal, HalTaskInfo *task) -{ - VPU_CMD_TYPE cmd = 0; - RK_S32 hw_ret = 0; - h264e_hal_context *ctx = (h264e_hal_context *)hal; - h264e_rkv_ioctl_output *reg_out = (h264e_rkv_ioctl_output *)ctx->ioctl_output; - RK_S32 length = (sizeof(reg_out->frame_num) + sizeof(reg_out->elem[0]) * ctx->num_frames_to_send) >> 2; - IOInterruptCB int_cb = ctx->int_cb; - h264e_feedback *fb = &ctx->feedback; - (void)task; - h264e_hal_debug_enter(); - - if (ctx->frame_cnt_gen_ready != ctx->num_frames_to_send) { - h264e_hal_log_detail("frame_cnt_gen_ready(%d) != num_frames_to_send(%d), wait hardware later", - ctx->frame_cnt_gen_ready, ctx->num_frames_to_send); - return MPP_OK; - } else { - ctx->frame_cnt_gen_ready = 0; - if (ctx->enc_mode == 3) { - h264e_hal_log_detail("only for test enc_mode 3 ..."); //TODO: remove later - if (ctx->frame_cnt_send_ready != RKV_H264E_LINKTABLE_FRAME_NUM) { - h264e_hal_log_detail("frame_cnt_send_ready(%d) != RKV_H264E_LINKTABLE_FRAME_NUM(%d), wait hardware later", - ctx->frame_cnt_send_ready, RKV_H264E_LINKTABLE_FRAME_NUM); - return MPP_OK; - } else { - ctx->frame_cnt_send_ready = 0; - } - } - } - -#ifdef RKPLATFORM - if (ctx->vpu_socket <= 0) { - h264e_hal_log_err("invalid vpu socket: %d", ctx->vpu_socket); - return MPP_NOK; - } - - h264e_hal_log_detail("VPUClientWaitResult expect length %d\n", length); - - hw_ret = VPUClientWaitResult(ctx->vpu_socket, (RK_U32 *)reg_out, - length, &cmd, NULL); - - h264e_hal_log_detail("VPUClientWaitResult: ret %d, cmd %d, len %d\n", hw_ret, cmd, length); - - - if ((VPU_SUCCESS != hw_ret) || (cmd != VPU_SEND_CONFIG_ACK_OK)) - h264e_hal_log_err("hardware wait error"); - - if (hw_ret != MPP_OK) { - h264e_hal_log_err("hardware returns error:%d", hw_ret); - return MPP_ERR_VPUHW; - } -#else - (void)hw_ret; - (void)length; - (void)cmd; -#endif - - if (int_cb.callBack) { - hal_h264e_rkv_set_feedback(fb, reg_out); - int_cb.callBack(int_cb.opaque, fb); - } - - hal_h264e_rkv_dump_mpp_reg_out(ctx); - hal_h264e_rkv_dump_mpp_feedback(ctx); - hal_h264e_rkv_dump_mpp_strm_out(ctx, ctx->enc_task.output); - h264e_hal_debug_leave(); - - return MPP_OK; -} - -MPP_RET hal_h264e_rkv_reset(void *hal) -{ - (void)hal; - h264e_hal_debug_enter(); - - h264e_hal_debug_leave(); - return MPP_OK; -} - -MPP_RET hal_h264e_rkv_flush(void *hal) -{ - (void)hal; - h264e_hal_debug_enter(); - - h264e_hal_debug_leave(); - return MPP_OK; -} - -MPP_RET hal_h264e_rkv_control(void *hal, RK_S32 cmd_type, void *param) -{ - h264e_hal_context *ctx = (h264e_hal_context *)hal; - h264e_hal_debug_enter(); - - h264e_hal_log_detail("hal_h264e_rkv_control cmd 0x%x, info %p", cmd_type, param); - switch (cmd_type) { - case MPP_ENC_SET_EXTRA_INFO: { - hal_h264e_rkv_set_extra_info(ctx, param); - break; - } - case MPP_ENC_GET_EXTRA_INFO: { - RK_S32 k = 0; - size_t offset = 0; - MppPacket pkt = ctx->packeted_param; - MppPacket *pkt_out = (MppPacket *)param; - h264e_hal_rkv_extra_info *src = (h264e_hal_rkv_extra_info *)ctx->extra_info; - - for (k = 0; k < src->nal_num; k++) { - h264e_hal_log_header("get extra info nal type %d, size %d bytes", src->nal[k].i_type, src->nal[k].i_payload); - mpp_packet_write(pkt, offset, src->nal[k].p_payload, src->nal[k].i_payload); - offset += src->nal[k].i_payload; - } - mpp_packet_set_length(pkt, offset); - *pkt_out = pkt; - - hal_h264e_rkv_dump_mpp_strm_out_header(ctx, pkt); - break; - } - default : { - h264e_hal_log_err("unrecognizable cmd type %d", cmd_type); - } break; - } - - h264e_hal_debug_leave(); - return MPP_OK; -} - + regs->swreg55.ctu_ebits = mb_target_size; //sw_ctu_target_bits; + } else { + regs->swreg46.rc_mode = 0; //0:frame/slice rc; 1:mbrc + regs->swreg54.rc_qp_range = 4; //yn->swreg54.rc_qp_range; + regs->swreg54.rc_max_qp = 51; //syn->swreg54.rc_max_qp; + regs->swreg54.rc_min_qp = 1; //syn->swreg54.rc_min_qp; + + regs->swreg55.ctu_ebits = 0; //syn->swreg55.ctu_ebits; + + (void)test; + } + + return MPP_OK; +} + +MPP_RET hal_h264e_rkv_set_roi_regs(h264e_rkv_reg_set *regs, h264e_syntax *syn, MppBuffer roi_idx_buf, RK_U32 frame_cnt, + h264e_hal_rkv_coveragetest_cfg *test) +{ + if (test && test->roi) { + RK_U32 k = 0; + RK_U32 num_mbs_oneframe = (syn->pic_luma_width + 15) / 16 * ((syn->pic_luma_height + 15) / 16); + h264e_hal_rkv_roi_cfg *roi_cfg = mpp_calloc(h264e_hal_rkv_roi_cfg, num_mbs_oneframe); + h264e_hal_log_detail("---- test-roi ----"); + regs->swreg10.roi_enc = 1; + regs->swreg29_ctuc_addr = mpp_buffer_get_fd(roi_idx_buf); + if (frame_cnt % 3 == 0) { + for (k = 0; k < 4 * ((syn->pic_luma_width + 15) / 16); k++) { + roi_cfg[k].set_qp_y_en = 1; + roi_cfg[k].qp_y = 20; + } + } else if (frame_cnt % 3 == 1) { + for (k = 0; k < 4 * ((syn->pic_luma_width + 15) / 16); k++) { + roi_cfg[k].forbit_inter = 1; + } + } else { // frame_cnt%3==2 + for (k = 0; k < 4 * ((syn->pic_luma_width + 15) / 16); k++) { + roi_cfg[k].set_qp_y_en = 1; + roi_cfg[k].qp_y = 20; + roi_cfg[k].forbit_inter = 1; + } + } + mpp_buffer_write(roi_idx_buf, 0, (void *)roi_cfg, num_mbs_oneframe); + MPP_FREE(roi_cfg); + } else { + regs->swreg10.roi_enc = 0; //syn->swreg10.roi_enc; + (void)test; + } + + return MPP_OK; +} + +MPP_RET hal_h264e_rkv_set_osd_regs(h264e_rkv_reg_set *regs, h264e_syntax *syn, MppBuffer osd_idx_buf, + h264e_hal_rkv_coveragetest_cfg *test) +{ + if (test && test->osd) { +#define OSD_SIZE_MBS 4 //size of osd in mb + RK_S32 k = 0; + RK_U32 osd_r0_en = 1; + RK_U32 osd_r1_en = 1; + RK_U32 osd_r2_en = 1; + RK_U32 osd_r3_en = 1; + RK_U32 osd_r4_en = 1; + RK_U32 osd_r5_en = 1; + RK_U32 osd_r6_en = 1; + RK_U32 osd_r7_en = 1; + + RK_U32 osd_r0_inv_en = 0; + RK_U32 osd_r1_inv_en = 0; + RK_U32 osd_r2_inv_en = 0; + RK_U32 osd_r3_inv_en = 0; + RK_U32 osd_r4_inv_en = 0; + RK_U32 osd_r5_inv_en = 0; + RK_U32 osd_r6_inv_en = 0; + RK_U32 osd_r7_inv_en = 0; + + RK_U32 osd_size_pixels = 16 * OSD_SIZE_MBS * 16 * OSD_SIZE_MBS; + h264e_hal_log_detail("---- test-osd ----"); + + + regs->swreg65.osd_en = (osd_r0_en << 0) + (osd_r1_en << 1) + (osd_r2_en << 2) + (osd_r3_en << 3) + (osd_r4_en << 4) + (osd_r5_en << 5) + (osd_r6_en << 6) + (osd_r7_en << 7); + regs->swreg65.osd_inv = (osd_r0_inv_en << 0) + (osd_r1_inv_en << 1) + (osd_r2_inv_en << 2) + (osd_r3_inv_en << 3) + + (osd_r4_inv_en << 4) + (osd_r5_inv_en << 5) + (osd_r6_inv_en << 6) + (osd_r7_inv_en << 7); + + regs->swreg65.osd_clk_sel = 1; + regs->swreg65.osd_plt_type = 0; //OSD_plt_type; + + regs->swreg66.osd_inv_r1 = 0; //OSD_r1_inv_range; + regs->swreg66.osd_inv_r2 = 0; //OSD_r2_inv_range; + regs->swreg66.osd_inv_r3 = 0; //OSD_r3_inv_range; + regs->swreg66.osd_inv_r4 = 0; //OSD_r4_inv_range; + regs->swreg66.osd_inv_r5 = 0; //OSD_r5_inv_range; + regs->swreg66.osd_inv_r6 = 0; //OSD_r6_inv_range; + regs->swreg66.osd_inv_r7 = 0; //OSD_r7_inv_range; + + regs->swreg67_osd_pos[0].lt_pos_x = 0 * OSD_SIZE_MBS; //OSD_r0_x_lt_pos; + regs->swreg67_osd_pos[0].lt_pos_y = 0 * OSD_SIZE_MBS; //OSD_r0_y_lt_pos; + regs->swreg67_osd_pos[0].rd_pos_x = 0 * OSD_SIZE_MBS + OSD_SIZE_MBS - 1; //OSD_r0_x_rd_pos; + regs->swreg67_osd_pos[0].rd_pos_y = 0 * OSD_SIZE_MBS + OSD_SIZE_MBS - 1; //OSD_r0_y_rd_pos; + + regs->swreg67_osd_pos[1].lt_pos_x = 1 * OSD_SIZE_MBS; //OSD_r1_x_lt_pos; + regs->swreg67_osd_pos[1].lt_pos_y = 0 * OSD_SIZE_MBS; //OSD_r1_y_lt_pos; + regs->swreg67_osd_pos[1].rd_pos_x = 1 * OSD_SIZE_MBS + OSD_SIZE_MBS - 1; //OSD_r1_x_rd_pos; + regs->swreg67_osd_pos[1].rd_pos_y = 0 * OSD_SIZE_MBS + OSD_SIZE_MBS - 1; //OSD_r1_y_rd_pos; + + regs->swreg67_osd_pos[2].lt_pos_x = 2 * OSD_SIZE_MBS; //OSD_r2_x_lt_pos; + regs->swreg67_osd_pos[2].lt_pos_y = 0 * OSD_SIZE_MBS; //OSD_r2_y_lt_pos; + regs->swreg67_osd_pos[2].rd_pos_x = 2 * OSD_SIZE_MBS + OSD_SIZE_MBS - 1; //OSD_r2_x_rd_pos; + regs->swreg67_osd_pos[2].rd_pos_y = 0 * OSD_SIZE_MBS + OSD_SIZE_MBS - 1; //OSD_r2_y_rd_pos; + + regs->swreg67_osd_pos[3].lt_pos_x = 3 * OSD_SIZE_MBS; //OSD_r3_x_lt_pos; + regs->swreg67_osd_pos[3].lt_pos_y = 0 * OSD_SIZE_MBS; //OSD_r3_y_lt_pos; + regs->swreg67_osd_pos[3].rd_pos_x = 3 * OSD_SIZE_MBS + OSD_SIZE_MBS - 1; //OSD_r3_x_rd_pos; + regs->swreg67_osd_pos[3].rd_pos_y = 0 * OSD_SIZE_MBS + OSD_SIZE_MBS - 1; //OSD_r3_y_rd_pos; + + regs->swreg67_osd_pos[4].lt_pos_x = 0 * OSD_SIZE_MBS; //OSD_r4_x_lt_pos; + regs->swreg67_osd_pos[4].lt_pos_y = 1 * OSD_SIZE_MBS; //OSD_r4_y_lt_pos; + regs->swreg67_osd_pos[4].rd_pos_x = 0 * OSD_SIZE_MBS + OSD_SIZE_MBS - 1; //OSD_r4_x_rd_pos; + regs->swreg67_osd_pos[4].rd_pos_y = 1 * OSD_SIZE_MBS + OSD_SIZE_MBS - 1; //OSD_r4_x_rd_pos; + + regs->swreg67_osd_pos[5].lt_pos_x = 1 * OSD_SIZE_MBS; //OSD_r5_x_lt_pos; + regs->swreg67_osd_pos[5].lt_pos_y = 1 * OSD_SIZE_MBS; //OSD_r5_y_lt_pos; + regs->swreg67_osd_pos[5].rd_pos_x = 1 * OSD_SIZE_MBS + OSD_SIZE_MBS - 1; //OSD_r5_x_rd_pos; + regs->swreg67_osd_pos[5].rd_pos_y = 1 * OSD_SIZE_MBS + OSD_SIZE_MBS - 1; //OSD_r5_y_rd_pos; + + regs->swreg67_osd_pos[6].lt_pos_x = 2 * OSD_SIZE_MBS; //OSD_r6_x_lt_pos; + regs->swreg67_osd_pos[6].lt_pos_y = 1 * OSD_SIZE_MBS; //OSD_r6_y_lt_pos; + regs->swreg67_osd_pos[6].rd_pos_x = 2 * OSD_SIZE_MBS + OSD_SIZE_MBS - 1; //OSD_r6_x_rd_pos; + regs->swreg67_osd_pos[6].rd_pos_y = 1 * OSD_SIZE_MBS + OSD_SIZE_MBS - 1; //OSD_r6_y_rd_pos; + + regs->swreg67_osd_pos[7].lt_pos_x = 3 * OSD_SIZE_MBS; //OSD_r7_x_lt_pos; + regs->swreg67_osd_pos[7].lt_pos_y = 1 * OSD_SIZE_MBS; //OSD_r7_y_lt_pos; + regs->swreg67_osd_pos[7].rd_pos_x = 3 * OSD_SIZE_MBS + OSD_SIZE_MBS - 1; //OSD_r7_x_rd_pos; + regs->swreg67_osd_pos[7].rd_pos_y = 1 * OSD_SIZE_MBS + OSD_SIZE_MBS - 1; //OSD_r7_y_rd_pos; + + for (k = 0; k < 8; k++) { + if (regs->swreg65.osd_plt_type == 0) //configurable + memset((RK_U8 *)mpp_buffer_get_ptr(osd_idx_buf) + k * osd_size_pixels, 32 * k, osd_size_pixels); + else //fixed mode: only support idx 0~7 + memset((RK_U8 *)mpp_buffer_get_ptr(osd_idx_buf) + k * osd_size_pixels, k, osd_size_pixels); + + regs->swreg68_indx_addr_i[k] = mpp_buffer_get_fd(osd_idx_buf) | ((k * osd_size_pixels) << 10); //h->param.indx_addr_i[i]; + } +#if 0 //written in kernel + for (k = 0; k < 256; k++) { + regs->swreg73_osd_indx_tab_i[k] = k | (0x80 << 8) | (0x80 << 16) | (k << 24); + } +#endif + + } else { + + (void)test; + } + (void)syn; + + return MPP_OK; +} + +MPP_RET hal_h264e_rkv_set_pp_regs(h264e_rkv_reg_set *regs, h264e_syntax *syn, MppBuffer hw_buf_w, MppBuffer hw_buf_r, RK_U32 frame_cnt, + h264e_hal_rkv_coveragetest_cfg *test) +{ + RK_S32 k = 0; + RK_S32 stridey, stridec; + if (test && test->preproc) { + + RK_U32 h3d_tbl[40] = { + 0x0b080400, 0x1815120f, 0x23201e1b, 0x2c2a2725, + 0x33312f2d, 0x38373634, 0x3d3c3b39, 0x403f3e3d, + 0x42414140, 0x43434342, 0x44444444, 0x44444444, + 0x44444444, 0x43434344, 0x42424343, 0x40414142, + 0x3d3e3f40, 0x393a3b3c, 0x35363738, 0x30313334, + 0x2c2d2e2f, 0x28292a2b, 0x23242526, 0x20202122, + 0x191b1d1f, 0x14151618, 0x0f101112, 0x0b0c0d0e, + 0x08090a0a, 0x06070708, 0x05050506, 0x03040404, + 0x02020303, 0x01010102, 0x00010101, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000 + }; + + h264e_hal_log_detail("---- test-preproc ----"); + //regs->swreg14.src_aswap = 0; //h->param.swap_a; + //regs->swreg14.src_cswap = 0; //h->param.swap_c; + regs->swreg14.src_cfmt = syn->input_image_format; //(h->param.prep_cfg_val&0xf000) ? h->param.format : 0x7; //src_cfmt + regs->swreg14.src_clip_dis = 0; //csc_clip_range; + + regs->swreg15.wght_b2y = 0;// csc_par_lu_b; + regs->swreg15.wght_g2y = 0;// csc_par_lu_g; + regs->swreg15.wght_r2y = 0;// csc_par_lu_r; + + regs->swreg16.wght_b2u = 0; //csc_par_cb_b; + regs->swreg16.wght_g2u = 0; //csc_par_cb_g; + regs->swreg16.wght_r2u = 0; //csc_par_cb_r; + + regs->swreg17.wght_b2v = 0; //csc_par_cr_b; + regs->swreg17.wght_g2v = 0; //csc_par_cr_g; + regs->swreg17.wght_r2v = 0; //csc_par_cr_r; + + regs->swreg18.ofst_rgb2v = 0; //csc_par_cr_offset; + regs->swreg18.ofst_rgb2u = 0; //csc_par_cb_offset; + regs->swreg18.ofst_rgb2y = 0; //csc_par_lu_offset; + + regs->swreg19.src_tfltr = (frame_cnt == 0) ? 0 : 1; //temporal_en; + regs->swreg19.src_tfltr_we = 1; //temporal_wr_en; + regs->swreg19.src_tfltr_bw = 0; //temporal_bw; + + regs->swreg19.src_sfltr = 1; //spatial_en; + regs->swreg19.src_mfltr_thrd = 7; //median_threshold; + regs->swreg19.src_mfltr_y = 1; //median_en; + regs->swreg19.src_mfltr_c = 0; //median_chroma_en; + regs->swreg19.src_bfltr_strg = 0; //sw_bilater_flag != 0; //be check + regs->swreg19.src_bfltr = 1; //bilater_en; + regs->swreg19.src_mbflt_odr = 0; //filter_order; + regs->swreg19.src_matf_y = 1; //matf_lu_en; + regs->swreg19.src_matf_c = 1; //matf_ch_en; + regs->swreg19.src_shp_y = 1; //sharp_lu_en; + regs->swreg19.src_shp_c = 0; //sharp_ch_en; + regs->swreg19.src_shp_div = 5; //sharp_div; + regs->swreg19.src_shp_thld = 5; //sharp_threshold; + regs->swreg19.src_mirr = 0; //mirr_mode; + regs->swreg19.src_rot = 0; //rot_mode; + regs->swreg19.src_matf_itsy = 0; //matf_lu_flag; + + regs->swreg20.tfltr_thld_y = 60; //matf_lu_threshold; + regs->swreg20.reserve = 0x0; + regs->swreg20.tfltr_thld_c = 80; //matf_ch_threshold; + regs->swreg20.reserve1 = 0x0; + + regs->swreg21_scr_stbl[0] = (RK_U32)1073741823; //sharp_matrix[0]; + regs->swreg21_scr_stbl[1] = (RK_U32)1073741823; //sharp_matrix[1]; + regs->swreg21_scr_stbl[2] = (RK_U32)0xfff38fff;// 4294152191; //sharp_matrix[2]; + regs->swreg21_scr_stbl[3] = (RK_U32)1073741823; //sharp_matrix[3]; + regs->swreg21_scr_stbl[4] = (RK_U32)1073741823; //sharp_matrix[4]; + + for (k = 0; k < 40; k++) + regs->swreg22_h3d_tbl[k] = h3d_tbl[k]; + + + stridey = (syn->pic_luma_width + 15) & (~15); + stridec = stridey; + + regs->swreg23.src_ystrid = stridey; + regs->swreg23.reserve = 0x0; + regs->swreg23.src_cstrid = stridec; ////YUV420 planar; + + regs->swreg27_fltw_addr = mpp_buffer_get_fd(hw_buf_w); + regs->swreg28_fltr_addr = mpp_buffer_get_fd(hw_buf_r); + } else { + regs->swreg14.src_cfmt = syn->input_image_format; //syn->swreg14.src_cfmt; //src_cfmt + + for (k = 0; k < 5; k++) + regs->swreg21_scr_stbl[k] = 0; //syn->swreg21_scr_stbl[k]; + + for (k = 0; k < 40; k++) + regs->swreg22_h3d_tbl[k] = h264e_h3d_tbl[k]; + + stridey = (regs->swreg19.src_rot == 1 || regs->swreg19.src_rot == 3) ? (syn->pic_luma_height - 1) : (syn->pic_luma_width - 1); + if (regs->swreg14.src_cfmt == 0 ) + stridey = (stridey + 1) * 4 - 1; + else if (regs->swreg14.src_cfmt == 1 ) + stridey = (stridey + 1) * 3 - 1; + else if ( regs->swreg14.src_cfmt == 2 || regs->swreg14.src_cfmt == 8 || regs->swreg14.src_cfmt == 9 ) + stridey = (stridey + 1) * 2 - 1; + stridec = (regs->swreg14.src_cfmt == 4 || regs->swreg14.src_cfmt == 6) ? stridey : ((stridey + 1) / 2 - 1); + regs->swreg23.src_ystrid = stridey; //syn->swreg23.src_ystrid; + regs->swreg23.src_cstrid = stridec; //syn->swreg23.src_cstrid; ////YUV420 planar; + + (void)test; + } + + return MPP_OK; +} + +MPP_RET hal_h264e_rkv_gen_regs(void *hal, HalTaskInfo *task) +{ + h264e_hal_context *ctx = (h264e_hal_context *)hal; + h264e_hal_param *par = &ctx->param; + h264e_rkv_reg_set *regs = NULL; + h264e_hal_rkv_csp_info src_fmt; + h264e_syntax *syn = (h264e_syntax *)task->enc.syntax.data; + h264e_rkv_ioctl_input *ioctl_info = (h264e_rkv_ioctl_input *)ctx->ioctl_input; + h264e_rkv_reg_set *reg_list = (h264e_rkv_reg_set *)ctx->regs; + h264e_hal_rkv_dpb_ctx *dpb_ctx = (h264e_hal_rkv_dpb_ctx *)ctx->dpb_ctx; + h264e_hal_rkv_extra_info *extra_info = (h264e_hal_rkv_extra_info *)ctx->extra_info; + h264e_hal_rkv_coveragetest_cfg *test_cfg = (h264e_hal_rkv_coveragetest_cfg *)ctx->test_cfg; + h264e_hal_sps *sps = &extra_info->sps; + h264e_hal_pps *pps = &extra_info->pps; + + RK_S32 pic_width_align16 = (syn->pic_luma_width + 15) & (~15); + RK_S32 pic_height_align16 = (syn->pic_luma_height + 15) & (~15); + RK_S32 pic_width_in_blk64 = (syn->pic_luma_width + 63) / 64; + h264e_hal_rkv_buffers *bufs = (h264e_hal_rkv_buffers *)ctx->buffers; + RK_U32 mul_buf_idx = ctx->frame_cnt % RKV_H264E_LINKTABLE_FRAME_NUM; + RK_U32 buf2_idx = ctx->frame_cnt % 2; + //RK_S32 pic_height_align64 = (syn->pic_luma_height + 63) & (~63); + ctx->enc_mode = RKV_H264E_ENC_MODE; + + h264e_hal_debug_enter(); + hal_h264e_rkv_dump_mpp_syntax_in(syn, ctx); + + if (MPP_OK != hal_h264e_rkv_validate_syntax(syn, &src_fmt, ctx->frame_cnt % sps->keyframe_max_interval == 0)) { + h264e_hal_log_err("hal_h264e_rkv_validate_syntax failed"); + } + + ctx->enc_task = task->enc; + + hal_h264e_rkv_adjust_param(ctx); //TODO: future expansion + + h264e_hal_log_simple("frame %d | type %d | start gen regs", ctx->frame_cnt, syn->slice_type); + + if (ctx->frame_cnt == 0) { + if (MPP_OK != hal_h264e_rkv_allocate_buffers(ctx, syn, sps, test_cfg)) { + h264e_hal_log_err("hal_h264e_rkv_allocate_buffers failed, free now"); + hal_h264e_rkv_free_buffers(ctx); + } + } + + if (ctx->enc_mode == 2 || ctx->enc_mode == 3) { //link table mode + RK_U32 idx = ctx->frame_cnt_gen_ready; + ctx->num_frames_to_send = RKV_H264E_LINKTABLE_EACH_NUM; + if (idx == 0) { + ioctl_info->enc_mode = ctx->enc_mode; + ioctl_info->frame_num = ctx->num_frames_to_send; + } + regs = ®_list[idx]; + ioctl_info->reg_info[idx].reg_num = sizeof(h264e_rkv_reg_set) / 4; + hal_h264e_rkv_set_ioctl_extra_info(&ioctl_info->reg_info[idx].extra_info, syn); + } else { + ctx->num_frames_to_send = 1; + ioctl_info->frame_num = ctx->num_frames_to_send; + ioctl_info->enc_mode = ctx->enc_mode; + regs = ®_list[0]; + ioctl_info->reg_info[0].reg_num = sizeof(h264e_rkv_reg_set) / 4; + hal_h264e_rkv_set_ioctl_extra_info(&ioctl_info->reg_info[0].extra_info, syn); + } + + if (MPP_OK != hal_h264e_rkv_reference_frame_set(ctx, syn)) { + h264e_hal_log_err("hal_h264e_rkv_reference_frame_set failed, multi-ref error"); + } + + h264e_hal_log_detail("generate regs when frame_cnt_gen_ready/(num_frames_to_send-1): %d/%d", + ctx->frame_cnt_gen_ready, ctx->num_frames_to_send - 1); + + memset(regs, 0, sizeof(h264e_rkv_reg_set)); + + regs->swreg01.rkvenc_ver = 0x1; + + regs->swreg02.lkt_num = 0; //syn->link_table_en? h->param.i_frame_total : 0; + regs->swreg02.rkvenc_cmd = ctx->enc_mode; + //regs->swreg02.rkvenc_cmd = syn->link_table_en ? 0x2 : 0x1; + regs->swreg02.enc_cke = 0; //syn->swreg02.enc_cke; + + regs->swreg03.safe_clr = 0x0; + + regs->swreg04.lkt_addr = 0x10000000;//syn->swreg04.lkt_addr; + + regs->swreg05.ofe_fnsh = 1; //syn->swreg05.ofe_fnsh; + regs->swreg05.lkt_fnsh = 1; //syn->swreg05.lkt_fnsh; + regs->swreg05.clr_fnsh = 1; //syn->swreg05.clr_fnsh; + regs->swreg05.ose_fnsh = 1; //syn->swreg05.ose_fnsh; + regs->swreg05.bs_ovflr = 1; //syn->swreg05.bs_ovflr; + regs->swreg05.brsp_ful = 1; //syn->swreg05.brsp_ful; + regs->swreg05.brsp_err = 1; //syn->swreg05.brsp_err; + regs->swreg05.rrsp_err = 1; //syn->swreg05.rrsp_err; + regs->swreg05.tmt_err = 1; //syn->swreg05.tmt_err ; + + regs->swreg09.pic_wd8_m1 = pic_width_align16 / 8 - 1; + regs->swreg09.pic_wfill = (syn->pic_luma_width & 0xf) ? (16 - (syn->pic_luma_width & 0xf)) : 0; + regs->swreg09.pic_hd8_m1 = pic_height_align16 / 8 - 1; + regs->swreg09.pic_hfill = (syn->pic_luma_height & 0xf) ? (16 - (syn->pic_luma_height & 0xf)) : 0; + + regs->swreg10.enc_stnd = 0; //H264 + regs->swreg10.cur_frm_ref = ((ctx->frame_cnt + 1) % sps->keyframe_max_interval) != 0; //syn->swreg10.cur_frm_ref; //Current frame should be refered in future + regs->swreg10.mei_stor = 0; //syn->swreg10.mei_stor; + regs->swreg10.bs_scp = 1; //syn->swreg10.bs_scp; + regs->swreg10.pic_qp = syn->qp;//syn->swreg10.pic_qp; //if CQP, pic_qp=qp constant. + regs->swreg10.slice_int = 0; //syn->swreg10.slice_int; + regs->swreg10.node_int = 0; //syn->swreg10.node_int;//node_int_frame_pos + + regs->swreg11.ppln_enc_lmt = 2; //syn->swreg11.ppln_enc_lmt; + regs->swreg11.rfp_load_thrd = 0; //syn->swreg11.rfp_load_thrd; + + regs->swreg12.src_bus_ordr = 0x0; + regs->swreg12.cmvw_bus_ordr = 0x0; + regs->swreg12.dspw_bus_ordr = 0x0; + regs->swreg12.rfpw_bus_ordr = 0x0; + regs->swreg12.src_bus_edin = 0x0;//syn->swreg12.src_bus_edin; + regs->swreg12.meiw_bus_edin = 0x0; + regs->swreg12.bsw_bus_edin = 0x7; + regs->swreg12.lktr_bus_edin = 0x0; + regs->swreg12.ctur_bus_edin = 0x0; + regs->swreg12.lktw_bus_edin = 0x0; + regs->swreg12.rfp_map_dcol = 0x0; + regs->swreg12.rfp_map_sctr = 0x0; + + regs->swreg13.axi_brsp_cke = 0x7f; //syn->swreg13.axi_brsp_cke; + regs->swreg13.cime_dspw_orsd = 0x0; + + hal_h264e_rkv_set_pp_regs(regs, syn, bufs->hw_pp_buf[buf2_idx], bufs->hw_pp_buf[1 - buf2_idx], ctx->frame_cnt, test_cfg); + + regs->swreg24_adr_srcy = syn->input_luma_addr; //syn->addr_cfg.adr_srcy; + regs->swreg25_adr_srcu = syn->input_cb_addr; //syn->addr_cfg.adr_srcu; + regs->swreg26_adr_srcv = syn->input_cr_addr; //syn->addr_cfg.adr_srcv; + + hal_h264e_rkv_set_roi_regs(regs, syn, bufs->hw_roi_buf[mul_buf_idx], ctx->frame_cnt, test_cfg); + + regs->swreg30_rfpw_addr = mpp_buffer_get_fd(dpb_ctx->fdec->hw_buf);//syn->addr_cfg.rfpw_addr; //TODO: extend recon luma buf + if (dpb_ctx->fref[0][0]) + regs->swreg31_rfpr_addr = mpp_buffer_get_fd(dpb_ctx->fref[0][0]->hw_buf); //syn->addr_cfg.rfpr_addr; + //regs->swreg32_cmvw_addr = mpp_buffer_get_fd(bufs->hw_cmv_buf[buf2_idx]); + + if (bufs->hw_dsp_buf[buf2_idx]) + regs->swreg34_dspw_addr = mpp_buffer_get_fd(bufs->hw_dsp_buf[buf2_idx]); //syn->addr_cfg.dspw_addr; + if (bufs->hw_dsp_buf[1 - buf2_idx]) + regs->swreg35_dspr_addr = mpp_buffer_get_fd(bufs->hw_dsp_buf[1 - buf2_idx]); //syn->addr_cfg.dspr_addr; + + regs->swreg36_meiw_addr = 0; //mpp_buffer_get_fd(bufs->hw_mei_buf[mul_buf_idx]); + regs->swreg38_bsbb_addr = syn->output_strm_addr; + if (VPUClientGetIOMMUStatus() > 0) + regs->swreg37_bsbt_addr = regs->swreg38_bsbb_addr | (syn->output_strm_limit_size << 10); // TODO: stream size relative with syntax + else + regs->swreg37_bsbt_addr = regs->swreg38_bsbb_addr + (syn->output_strm_limit_size); + regs->swreg39_bsbr_addr = regs->swreg38_bsbb_addr; + regs->swreg40_bsbw_addr = regs->swreg38_bsbb_addr; //syn->addr_cfg.bsbw_addr; + + h264e_hal_log_dpb("regs->swreg37_bsbt_addr: %08x", regs->swreg37_bsbt_addr); + h264e_hal_log_dpb("regs->swreg38_bsbb_addr: %08x", regs->swreg38_bsbb_addr); + h264e_hal_log_dpb("regs->swreg39_bsbr_addr: %08x", regs->swreg39_bsbr_addr); + h264e_hal_log_dpb("regs->swreg40_bsbw_addr: %08x", regs->swreg40_bsbw_addr); + + regs->swreg41.sli_cut = 0; //syn->swreg41.sli_cut; + regs->swreg41.sli_cut_mode = 0; //syn->swreg41.sli_cut_mode; + regs->swreg41.sli_cut_bmod = 1; //syn->swreg41.sli_cut_bmod; + regs->swreg41.sli_max_num = 0; //syn->swreg41.sli_max_num; + regs->swreg41.sli_out_mode = 0; //syn->swreg41.sli_out_mode; + regs->swreg41.sli_cut_cnum = 0; //syn->swreg41.sli_cut_cnum; + + regs->swreg42.sli_cut_byte = 0; //syn->swreg42.sli_cut_byte; + + { + RK_U32 cime_wid_4p = 0, cime_hei_4p = 0; + if ( sps->i_level_idc == 10 || sps->i_level_idc == 9 ) { //9 is level 1b; + cime_wid_4p = 44; + cime_hei_4p = 12; + } else if ( sps->i_level_idc == 11 || sps->i_level_idc == 12 || sps->i_level_idc == 13 || sps->i_level_idc == 20 ) { + cime_wid_4p = 44; + cime_hei_4p = 28; + } else { + cime_wid_4p = 44; + cime_hei_4p = 28; + } + + if (176 < cime_wid_4p * 4) + cime_wid_4p = 176 / 4; + + if (112 < cime_hei_4p * 4) + cime_hei_4p = 112 / 4; + + if (cime_hei_4p / 4 * 2 > (RK_U32)(regs->swreg09.pic_hd8_m1 + 2) / 2) + cime_hei_4p = (regs->swreg09.pic_hd8_m1 + 2) / 2 / 2 * 4; + + if (cime_wid_4p / 4 > (RK_U32)(((regs->swreg09.pic_wd8_m1 + 1) * 8 + 63) / 64 * 64 / 128 * 4)) + cime_wid_4p = ((regs->swreg09.pic_wd8_m1 + 1) * 8 + 63) / 64 * 64 / 128 * 4 * 4; + + regs->swreg43.cime_srch_h = cime_wid_4p / 4; //syn->swreg43.cime_srch_h; + regs->swreg43.cime_srch_v = cime_hei_4p / 4; //syn->swreg43.cime_srch_v; + } + + regs->swreg43.rime_srch_h = 7; //syn->swreg43.rime_srch_h; + regs->swreg43.rime_srch_v = 5; //syn->swreg43.rime_srch_v; + regs->swreg43.dlt_frm_num = 0x0; + + regs->swreg44.pmv_mdst_h = 5; //syn->swreg44.pmv_mdst_h; + regs->swreg44.pmv_mdst_v = 5; //syn->swreg44.pmv_mdst_v; + regs->swreg44.mv_limit = (sps->i_level_idc > 20) ? 2 : ((sps->i_level_idc >= 11) ? 1 : 0); //syn->swreg44.mv_limit; + regs->swreg44.mv_num = 3; //syn->swreg44.mv_num; + + + if (pic_width_align16 > 3584) + regs->swreg45.cime_rama_h = 8; + else if (pic_width_align16 > 3136) + regs->swreg45.cime_rama_h = 9; + else if (pic_width_align16 > 2816) + regs->swreg45.cime_rama_h = 10; + else if (pic_width_align16 > 2560) + regs->swreg45.cime_rama_h = 11; + else if (pic_width_align16 > 2368) + regs->swreg45.cime_rama_h = 12; + else if (pic_width_align16 > 2176) + regs->swreg45.cime_rama_h = 13; + else if (pic_width_align16 > 2048) + regs->swreg45.cime_rama_h = 14; + else if (pic_width_align16 > 1856) + regs->swreg45.cime_rama_h = 15; + else if (pic_width_align16 > 1792) + regs->swreg45.cime_rama_h = 16; + else + regs->swreg45.cime_rama_h = 17; + + { + RK_U32 i_swin_all_4_h = (2 * regs->swreg43.cime_srch_v + 1); + RK_U32 i_swin_all_16_w = ((regs->swreg43.cime_srch_h * 4 + 15) / 16 * 2 + 1); + if (i_swin_all_4_h < regs->swreg45.cime_rama_h) + regs->swreg45.cime_rama_max = (i_swin_all_4_h - 1) * pic_width_in_blk64 + i_swin_all_16_w; + else + regs->swreg45.cime_rama_max = (regs->swreg45.cime_rama_h - 1) * pic_width_in_blk64 + i_swin_all_16_w; + } + + regs->swreg45.cach_l1_dtmr = 0x3; //syn->swreg45.cach_l1_dtmr; + regs->swreg45.cach_l2_tag = 0x0; + if (pic_width_align16 <= 512) + regs->swreg45.cach_l2_tag = 0x0; + else if (pic_width_align16 <= 1024) + regs->swreg45.cach_l2_tag = 0x1; + else if (pic_width_align16 <= 2048) + regs->swreg45.cach_l2_tag = 0x2; + else if (pic_width_align16 <= 4096) + regs->swreg45.cach_l2_tag = 0x3; + + hal_h264e_rkv_set_rc_regs(regs, syn, test_cfg); + + regs->swreg56.rect_size = (sps->i_profile_idc == H264_PROFILE_BASELINE && sps->i_level_idc <= 30); + regs->swreg56.inter_4x4 = 1; + regs->swreg56.arb_sel = 0; //syn->swreg56.arb_sel; + regs->swreg56.vlc_lmt = (sps->i_profile_idc < H264_PROFILE_HIGH && !syn->enable_cabac); + regs->swreg56.rdo_mark = 0; //syn->swreg56.rdo_mark; + /*if (syn->transform8x8_mode == 0 && (syn->swreg56.rdo_mark & 0xb5) == 0xb5) //NOTE: bug may exist here + { + h264e_hal_log_err("RdoMark and trans8x8 conflict!"); + mpp_assert(0); + return MPP_NOK; + }*/ + + { + RK_U32 i_nal_type = 0, i_nal_ref_idc = 0; + + if (syn->frame_coding_type == RKVENC_FRAME_TYPE_IDR ) { //TODO: extend syn->frame_coding_type definition + /* reset ref pictures */ + i_nal_type = RKVENC_NAL_SLICE_IDR; + i_nal_ref_idc = RKVENC_NAL_PRIORITY_HIGHEST; + } else if (syn->frame_coding_type == RKVENC_FRAME_TYPE_I ) { + i_nal_type = RKVENC_NAL_SLICE; + i_nal_ref_idc = RKVENC_NAL_PRIORITY_HIGH; /* Not completely true but for now it is (as all I/P are kept as ref)*/ + } else if (syn->frame_coding_type == RKVENC_FRAME_TYPE_P ) { + i_nal_type = RKVENC_NAL_SLICE; + i_nal_ref_idc = RKVENC_NAL_PRIORITY_HIGH; /* Not completely true but for now it is (as all I/P are kept as ref)*/ + } else if (syn->frame_coding_type == RKVENC_FRAME_TYPE_BREF ) { + i_nal_type = RKVENC_NAL_SLICE; + i_nal_ref_idc = RKVENC_NAL_PRIORITY_HIGH; + } else { /* B frame */ + i_nal_type = RKVENC_NAL_SLICE; + i_nal_ref_idc = RKVENC_NAL_PRIORITY_DISPOSABLE; + } + if (sps->keyframe_max_interval == 1) + i_nal_ref_idc = RKVENC_NAL_PRIORITY_LOW; + + regs->swreg57.nal_ref_idc = i_nal_ref_idc; //syn->swreg57.nal_ref_idc; + regs->swreg57.nal_unit_type = i_nal_type; //syn->swreg57.nal_unit_type; + } + + + regs->swreg58.max_fnum = sps->i_log2_max_frame_num - 4; //syn->swreg58.max_fnum; + regs->swreg58.drct_8x8 = 1; //syn->swreg58.drct_8x8; + regs->swreg58.mpoc_lm4 = sps->i_log2_max_poc_lsb - 4; //syn->swreg58.mpoc_lm4; + + regs->swreg59.etpy_mode = syn->enable_cabac; + regs->swreg59.trns_8x8 = pps->b_transform_8x8_mode; //syn->swreg59.trns_8x8; + regs->swreg59.csip_flg = par->constrained_intra; //syn->swreg59.csip_flg; + regs->swreg59.num_ref0_idx = pps->i_num_ref_idx_l0_default_active - 1; //syn->swreg59.num_ref0_idx; + regs->swreg59.num_ref1_idx = pps->i_num_ref_idx_l1_default_active - 1; //syn->swreg59.num_ref1_idx; + regs->swreg59.pic_init_qp = syn->pic_init_qp - H264_QP_BD_OFFSET; + regs->swreg59.cb_ofst = pps->i_chroma_qp_index_offset; //syn->chroma_qp_index_offset; + regs->swreg59.cr_ofst = pps->i_second_chroma_qp_index_offset; //syn->second_chroma_qp_index_offset; + regs->swreg59.wght_pred = 0x0; + regs->swreg59.dbf_cp_flg = 1; //syn->deblocking_filter_control; + + regs->swreg60.sli_type = syn->slice_type; //syn->swreg60.sli_type; + regs->swreg60.pps_id = syn->pps_id; + regs->swreg60.drct_smvp = 0x0; + regs->swreg60.num_ref_ovrd = 0; + regs->swreg60.cbc_init_idc = syn->cabac_init_idc; + + regs->swreg60.frm_num = dpb_ctx->i_frame_num; + + regs->swreg61.idr_pid = dpb_ctx->i_idr_pic_id; + regs->swreg61.poc_lsb = dpb_ctx->fdec->i_poc & ((1 << sps->i_log2_max_poc_lsb) - 1); + + regs->swreg62.rodr_pic_idx = dpb_ctx->ref_pic_list_order[0][0].idc; //syn->swreg62.rodr_pic_idx; + regs->swreg62.ref_list0_rodr = dpb_ctx->b_ref_pic_list_reordering[0]; //syn->swreg62.ref_list0_rodr; + regs->swreg62.sli_beta_ofst = 0; //syn->slice_beta_offset; + regs->swreg62.sli_alph_ofst = 0; //syn->slice_alpha_offset; + regs->swreg62.dis_dblk_idc = 0; //syn->disable_deblocking_filter_idc; + regs->swreg62.rodr_pic_num = dpb_ctx->ref_pic_list_order[0][0].arg; //syn->swreg62.rodr_pic_num; + + { + RK_S32 mmco4_pre = dpb_ctx->i_mmco_command_count > 0 && (dpb_ctx->mmco[0].memory_management_control_operation == 4); + regs->swreg63.nopp_flg = 0x0; + regs->swreg63.ltrf_flg = dpb_ctx->i_long_term_reference_flag; //syn->swreg63.ltrf_flg; + regs->swreg63.arpm_flg = dpb_ctx->i_mmco_command_count; //syn->swreg63.arpm_flg; + regs->swreg63.mmco4_pre = mmco4_pre; + regs->swreg63.mmco_0 = dpb_ctx->i_mmco_command_count > mmco4_pre ? dpb_ctx->mmco[mmco4_pre].memory_management_control_operation : 0; + regs->swreg63.dopn_m1_0 = dpb_ctx->i_mmco_command_count > mmco4_pre ? dpb_ctx->mmco[mmco4_pre].i_difference_of_pic_nums - 1 : 0;; //syn->swreg63.dopn_m1_0; + + regs->swreg64.mmco_1 = dpb_ctx->i_mmco_command_count > (mmco4_pre + 1) ? dpb_ctx->mmco[(mmco4_pre + 1)].memory_management_control_operation : 0; //syn->swreg64.mmco_1; + regs->swreg64.dopn_m1_1 = dpb_ctx->i_mmco_command_count > (mmco4_pre + 1) ? dpb_ctx->mmco[(mmco4_pre + 1)].i_difference_of_pic_nums - 1 : 0; //syn->swreg64.dopn_m1_1; + } + + hal_h264e_rkv_set_osd_regs(regs, syn, bufs->hw_osd_buf[mul_buf_idx], test_cfg); + + regs->swreg69.bs_lgth = 0x0; + + regs->swreg70.sse_l32 = 0x0; + + regs->swreg71.qp_sum = 0x0; + regs->swreg71.sse_h8 = 0x0; + + regs->swreg72.slice_scnum = 0x0; + regs->swreg72.slice_slnum = 0x0; + + regs->swreg73.st_enc = 0x0; + regs->swreg73.axiw_cln = 0x0; + regs->swreg73.axir_cln = 0x0; + + regs->swreg74.fnum_enc = 0x0; + regs->swreg74.fnum_cfg = 0x0; + regs->swreg74.fnum_int = 0x0; + + regs->swreg75.node_addr = 0x0; + + regs->swreg76.bsbw_addr = 0x0; //syn->swreg77.bsbw_addr; read only + regs->swreg76.Bsbw_ovfl = 0x0; + +#if !RKV_H264E_REMOVE_UNNECESSARY_REGS + regs->swreg77.axib_idl = 0x0; + regs->swreg77.axib_ful = 0x0; + regs->swreg77.axib_err = 0x0; + regs->swreg77.axir_err = 0x0; + + regs->swreg78.slice_num = 0x0; + + regs->swreg79.slice_len = 0x0; + + for (k = 0; k < 256; k++) + regs->swreg80_osd_indx_tab_i[k] = 0; //syn->swreg73_osd_indx_tab_i[k]; + + regs->swreg81.axip0_work = 0x0; + regs->swreg81.axip0_clr = 0x0; + + regs->swreg82.axip0_ltcy_id = 0x0; + regs->swreg82.axip0_ltcy_thr = 0x0; + + regs->swreg83.axip0_cnt_type = 0x0; + regs->swreg83.axip0_cnt_ddr = 0x0; + regs->swreg83.axip0_cnt_rid = 0x0; + regs->swreg83.axip0_cnt_wid = 0x0; + + regs->swreg84.axip1_work = 0x0; + regs->swreg84.axip1_clr = 0x0; + + regs->swreg85.axip1_ltcy_id = 0x0; + regs->swreg85.axip1_ltcy_thr = 0x0; + + regs->swreg86.axip1_cnt_type = 0x0; + regs->swreg86.axip1_cnt_ddr = 0x0; + regs->swreg86.axip1_cnt_rid = 0x0; + regs->swreg86.axip1_cnt_wid = 0x0; + + regs->swreg87.axip0_cnt_type = 0x0; + + regs->swreg88.axip0_num_ltcy = 0x0; + + regs->swreg89.axip0_sum_ltcy = 0x0; + + regs->swreg90.axip0_byte_rd = 0x0; + + regs->swreg91.axip0_byte_wr = 0x0; + + regs->swreg92.axip0_wrk_cyc = 0x0; + + regs->swreg93.axip1_cnt_type = 0x0; + + regs->swreg94.axip1_num_ltcy = 0x0; + + regs->swreg95.axip1_sum_ltcy = 0x0; + + regs->swreg96.axip1_byte_rd = 0x0; + + regs->swreg97.axip1_byte_wr = 0x0; + + regs->swreg98.axip1_wrk_cyc = 0x0; +#endif //#if !RKV_H264E_REMOVE_UNNECESSARY_REGS + + hal_h264e_rkv_dump_mpp_reg_in(ctx); + + hal_h264e_rkv_reference_frame_update(ctx); + dpb_ctx->i_frame_cnt++; + if (dpb_ctx->i_nal_ref_idc != RKVENC_NAL_PRIORITY_DISPOSABLE) + dpb_ctx->i_frame_num ++; + + ctx->frame_cnt_gen_ready++; + ctx->frame_cnt++; + + h264e_hal_debug_leave(); + + return MPP_OK; +} + +MPP_RET hal_h264e_rkv_start(void *hal, HalTaskInfo *task) +{ + MPP_RET ret = MPP_OK; + h264e_hal_context *ctx = (h264e_hal_context *)hal; + h264e_rkv_reg_set *reg_list = (h264e_rkv_reg_set *)ctx->regs; + RK_U32 length = 0, k = 0; + h264e_rkv_ioctl_input *ioctl_info = (h264e_rkv_ioctl_input *)ctx->ioctl_input; + + h264e_hal_debug_enter(); + if (ctx->frame_cnt_gen_ready != ctx->num_frames_to_send) { + h264e_hal_log_detail("frame_cnt_gen_ready(%d) != num_frames_to_send(%d), start hardware later", + ctx->frame_cnt_gen_ready, ctx->num_frames_to_send); + return MPP_OK; + } + + h264e_hal_log_detail("memcpy %d frames' regs from reg list to reg info", ioctl_info->frame_num); + for (k = 0; k < ioctl_info->frame_num; k++) + memcpy(&ioctl_info->reg_info[k].regs, ®_list[k], sizeof(h264e_rkv_reg_set)); + + length = (sizeof(ioctl_info->enc_mode) + sizeof(ioctl_info->frame_num) + + sizeof(ioctl_info->reg_info[0]) * ioctl_info->frame_num) >> 2; + + ctx->frame_cnt_send_ready ++; + + (void)task; + +#ifdef RKPLATFORM + if (ctx->vpu_socket <= 0) { + h264e_hal_log_err("invalid vpu socket: %d", ctx->vpu_socket); + return MPP_NOK; + } + + h264e_hal_log_detail("vpu client is sending %d regs", length); + if (MPP_OK != VPUClientSendReg(ctx->vpu_socket, (RK_U32 *)ioctl_info, length)) { + h264e_hal_log_err("VPUClientSendReg Failed!!!"); + return MPP_ERR_VPUHW; + } else { + h264e_hal_log_detail("VPUClientSendReg successfully!"); + } +#else + (void)length; +#endif + + h264e_hal_debug_leave(); + + return ret; +} + +static MPP_RET hal_h264e_rkv_set_feedback(h264e_feedback *fb, h264e_rkv_ioctl_output *out) +{ + RK_U32 k = 0; + h264e_rkv_ioctl_output_elem *elem = NULL; + h264e_hal_debug_enter(); + for (k = 0; k < out->frame_num; k++) { + elem = &out->elem[k]; + fb->qp_sum = elem->swreg71.qp_sum; + fb->out_strm_size = elem->swreg69.bs_lgth; + + fb->hw_status = 0; + h264e_hal_log_detail("hw_status: 0x%08x", elem->hw_status); + if (elem->hw_status & RKV_H264E_INT_LINKTABLE_FINISH) { + h264e_hal_log_err("RKV_H264E_INT_LINKTABLE_FINISH"); + } + if (elem->hw_status & RKV_H264E_INT_ONE_FRAME_FINISH) { + h264e_hal_log_detail("RKV_H264E_INT_ONE_FRAME_FINISH"); + } + if (elem->hw_status & RKV_H264E_INT_ONE_SLICE_FINISH) { + h264e_hal_log_err("RKV_H264E_INT_ONE_SLICE_FINISH"); + } + + if (elem->hw_status & RKV_H264E_INT_SAFE_CLEAR_FINISH) { + h264e_hal_log_err("RKV_H264E_INT_SAFE_CLEAR_FINISH"); + } + + if (elem->hw_status & RKV_H264E_INT_BIT_STREAM_OVERFLOW) { + h264e_hal_log_err("RKV_H264E_INT_BIT_STREAM_OVERFLOW"); + fb->hw_status = 1; + } + if (elem->hw_status & RKV_H264E_INT_BUS_WRITE_FULL) { + h264e_hal_log_err("RKV_H264E_INT_BUS_WRITE_FULL"); + fb->hw_status = 1; + } + if (elem->hw_status & RKV_H264E_INT_BUS_WRITE_ERROR) { + h264e_hal_log_err("RKV_H264E_INT_BUS_WRITE_ERROR"); + fb->hw_status = 1; + } + if (elem->hw_status & RKV_H264E_INT_BUS_READ_ERROR) { + h264e_hal_log_err("RKV_H264E_INT_BUS_READ_ERROR"); + fb->hw_status = 1; + } + if (elem->hw_status & RKV_H264E_INT_TIMEOUT_ERROR) { + h264e_hal_log_err("RKV_H264E_INT_TIMEOUT_ERROR"); + fb->hw_status = 1; + } + + fb->hw_status = elem->hw_status; + } + + h264e_hal_debug_leave(); + return MPP_OK; +} + +MPP_RET hal_h264e_rkv_wait(void *hal, HalTaskInfo *task) +{ + VPU_CMD_TYPE cmd = 0; + RK_S32 hw_ret = 0; + h264e_hal_context *ctx = (h264e_hal_context *)hal; + h264e_rkv_ioctl_output *reg_out = (h264e_rkv_ioctl_output *)ctx->ioctl_output; + RK_S32 length = (sizeof(reg_out->frame_num) + sizeof(reg_out->elem[0]) * ctx->num_frames_to_send) >> 2; + IOInterruptCB int_cb = ctx->int_cb; + h264e_feedback *fb = &ctx->feedback; + (void)task; + h264e_hal_debug_enter(); + + if (ctx->frame_cnt_gen_ready != ctx->num_frames_to_send) { + h264e_hal_log_detail("frame_cnt_gen_ready(%d) != num_frames_to_send(%d), wait hardware later", + ctx->frame_cnt_gen_ready, ctx->num_frames_to_send); + return MPP_OK; + } else { + ctx->frame_cnt_gen_ready = 0; + if (ctx->enc_mode == 3) { + h264e_hal_log_detail("only for test enc_mode 3 ..."); //TODO: remove later + if (ctx->frame_cnt_send_ready != RKV_H264E_LINKTABLE_FRAME_NUM) { + h264e_hal_log_detail("frame_cnt_send_ready(%d) != RKV_H264E_LINKTABLE_FRAME_NUM(%d), wait hardware later", + ctx->frame_cnt_send_ready, RKV_H264E_LINKTABLE_FRAME_NUM); + return MPP_OK; + } else { + ctx->frame_cnt_send_ready = 0; + } + } + } + +#ifdef RKPLATFORM + if (ctx->vpu_socket <= 0) { + h264e_hal_log_err("invalid vpu socket: %d", ctx->vpu_socket); + return MPP_NOK; + } + + h264e_hal_log_detail("VPUClientWaitResult expect length %d\n", length); + + hw_ret = VPUClientWaitResult(ctx->vpu_socket, (RK_U32 *)reg_out, + length, &cmd, NULL); + + h264e_hal_log_detail("VPUClientWaitResult: ret %d, cmd %d, len %d\n", hw_ret, cmd, length); + + + if ((VPU_SUCCESS != hw_ret) || (cmd != VPU_SEND_CONFIG_ACK_OK)) + h264e_hal_log_err("hardware wait error"); + + if (hw_ret != MPP_OK) { + h264e_hal_log_err("hardware returns error:%d", hw_ret); + return MPP_ERR_VPUHW; + } +#else + (void)hw_ret; + (void)length; + (void)cmd; +#endif + + if (int_cb.callBack) { + hal_h264e_rkv_set_feedback(fb, reg_out); + int_cb.callBack(int_cb.opaque, fb); + } + + hal_h264e_rkv_dump_mpp_reg_out(ctx); + hal_h264e_rkv_dump_mpp_feedback(ctx); + hal_h264e_rkv_dump_mpp_strm_out(ctx, ctx->enc_task.output); + h264e_hal_debug_leave(); + + return MPP_OK; +} + +MPP_RET hal_h264e_rkv_reset(void *hal) +{ + (void)hal; + h264e_hal_debug_enter(); + + h264e_hal_debug_leave(); + return MPP_OK; +} + +MPP_RET hal_h264e_rkv_flush(void *hal) +{ + (void)hal; + h264e_hal_debug_enter(); + + h264e_hal_debug_leave(); + return MPP_OK; +} + +MPP_RET hal_h264e_rkv_control(void *hal, RK_S32 cmd_type, void *param) +{ + h264e_hal_context *ctx = (h264e_hal_context *)hal; + h264e_hal_debug_enter(); + + h264e_hal_log_detail("hal_h264e_rkv_control cmd 0x%x, info %p", cmd_type, param); + switch (cmd_type) { + case MPP_ENC_SET_EXTRA_INFO: { + hal_h264e_rkv_set_extra_info(ctx, param); + break; + } + case MPP_ENC_GET_EXTRA_INFO: { + RK_S32 k = 0; + size_t offset = 0; + MppPacket pkt = ctx->packeted_param; + MppPacket *pkt_out = (MppPacket *)param; + h264e_hal_rkv_extra_info *src = (h264e_hal_rkv_extra_info *)ctx->extra_info; + + for (k = 0; k < src->nal_num; k++) { + h264e_hal_log_header("get extra info nal type %d, size %d bytes", src->nal[k].i_type, src->nal[k].i_payload); + mpp_packet_write(pkt, offset, src->nal[k].p_payload, src->nal[k].i_payload); + offset += src->nal[k].i_payload; + } + mpp_packet_set_length(pkt, offset); + *pkt_out = pkt; + + hal_h264e_rkv_dump_mpp_strm_out_header(ctx, pkt); + break; + } + default : { + h264e_hal_log_err("unrecognizable cmd type %d", cmd_type); + } break; + } + + h264e_hal_debug_leave(); + return MPP_OK; +} + diff --git a/mpp/hal/rkenc/h264e/hal_h264e_rkv.h b/mpp/hal/rkenc/h264e/hal_h264e_rkv.h index 69b4169b..c624f7b9 100644 --- a/mpp/hal/rkenc/h264e/hal_h264e_rkv.h +++ b/mpp/hal/rkenc/h264e/hal_h264e_rkv.h @@ -1,1575 +1,1575 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __HAL_H264E_RK_H__ -#define __HAL_H264E_RK_H__ - -#include "mpp_buffer.h" -#include "mpp_hal.h" -#include "hal_task.h" -/* -enc_mode - 0: N/A - 1: one frame encode by register configuration - 2: multi-frame encode start with link table - 3: multi-frame encode link table update -*/ -#define RKV_H264E_SDK_TEST 1 - - -#define RKV_H264E_ENC_MODE 1 //2/3 -#define RKV_H264E_LINKTABLE_FRAME_NUM 1 //2 - -#if RKV_H264E_ENC_MODE == 2 -#define RKV_H264E_LINKTABLE_EACH_NUM RKV_H264E_LINKTABLE_FRAME_NUM -#else -#define RKV_H264E_LINKTABLE_EACH_NUM 1 -#endif - -#define RKV_H264E_NUM_REFS 1 -#define RKV_H264E_LONGTERM_REF_EN 0 -//------------------------------------------------------------------------------- - -#define RKV_H264E_LINKTABLE_MAX_SIZE 256 -#define RKV_H264E_ADD_RESERVE_REGS 1 -#define RKV_H264E_REMOVE_UNNECESSARY_REGS 1 - -#define RKV_H264E_CSP2_MASK 0x00ff /* */ -#define RKV_H264E_CSP2_NONE 0x0000 /* Invalid mode */ -#define RKV_H264E_CSP2_I420 0x0001 /* yuv 4:2:0 planar */ -#define RKV_H264E_CSP2_YV12 0x0002 /* yvu 4:2:0 planar */ -#define RKV_H264E_CSP2_NV12 0x0003 /* yuv 4:2:0, with one y plane and one packed u+v */ -#define RKV_H264E_CSP2_I422 0x0004 /* yuv 4:2:2 planar */ -#define RKV_H264E_CSP2_YV16 0x0005 /* yvu 4:2:2 planar */ -#define RKV_H264E_CSP2_NV16 0x0006 /* yuv 4:2:2, with one y plane and one packed u+v */ -#define RKV_H264E_CSP2_V210 0x0007 /* 10-bit yuv 4:2:2 packed in 32 */ -#define RKV_H264E_CSP2_I444 0x0008 /* yuv 4:4:4 planar */ -#define RKV_H264E_CSP2_YV24 0x0009 /* yvu 4:4:4 planar */ -#define RKV_H264E_CSP2_BGR 0x000a /* packed bgr 24bits */ -#define RKV_H264E_CSP2_BGRA 0x000b /* packed bgr 32bits */ -#define RKV_H264E_CSP2_RGB 0x000c /* packed rgb 24bits */ -#define RKV_H264E_CSP2_MAX 0x000d /* end of list */ -#define RKV_H264E_CSP2_VFLIP 0x1000 /* the csp is vertically flipped */ -#define RKV_H264E_CSP2_HIGH_DEPTH 0x2000 /* the csp has a depth of 16 bits per pixel component */ - -#define RKV_H264E_B_PYRAMID_NONE 0 -#define RKV_H264E_B_PYRAMID_STRICT 1 -#define RKV_H264E_B_PYRAMID_NORMAL 2 - -#define RKV_H264E_CQM_FLAT 0 -#define RKV_H264E_CQM_JVT 1 -#define RKV_H264E_CQM_CUSTOM 2 - - -#define RKV_H264E_INT_ONE_FRAME_FINISH 0x00000001 -#define RKV_H264E_INT_LINKTABLE_FINISH 0x00000002 -#define RKV_H264E_INT_SAFE_CLEAR_FINISH 0x00000004 -#define RKV_H264E_INT_ONE_SLICE_FINISH 0x00000008 -#define RKV_H264E_INT_BIT_STREAM_OVERFLOW 0x00000010 -#define RKV_H264E_INT_BUS_WRITE_FULL 0x00000020 -#define RKV_H264E_INT_BUS_WRITE_ERROR 0x00000040 -#define RKV_H264E_INT_BUS_READ_ERROR 0x00000080 -#define RKV_H264E_INT_TIMEOUT_ERROR 0x00000100 - -#if RKV_H264E_SDK_TEST -typedef struct h264e_hal_rkv_coveragetest_cfg_t { - RK_U32 qp; - RK_U32 preproc; - RK_U32 osd; - RK_U32 mbrc; - RK_U32 roi; -} h264e_hal_rkv_coveragetest_cfg; -#endif - - -typedef enum h264e_rkv_csp_t { - H264E_RKV_CSP_BGRA8888, // 0 - H264E_RKV_CSP_BGR888, // 1 - H264E_RKV_CSP_BGR565, // 2 - H264E_RKV_CSP_NONE, // 3 - H264E_RKV_CSP_YUV422SP, // 4 - H264E_RKV_CSP_YUV422P, // 5 - H264E_RKV_CSP_YUV420SP, // 6 - H264E_RKV_CSP_YUV420P, // 7 - H264E_RKV_CSP_YUYV422, // 8 - H264E_RKV_CSP_UYVY422, // 9 - H264E_RKV_CSP_BUTT, // 10 -} h264e_hal_rkv_csp; - - -typedef enum h264e_rkv_chroma_fmt_t { - RKV_H264E_CHROMA_400 = 0, - RKV_H264E_CHROMA_420 = 1, - RKV_H264E_CHROMA_422 = 2, - RKV_H264E_CHROMA_444 = 3, -} h264e_rkv_chroma_fmt; - -typedef struct h264e_hal_rkv_csp_info_t { - RK_U32 fmt; - RK_U32 cswap; // U/V swap for YUV420SP/YUV422SP/YUYV422/UYUV422; R/B swap for BGRA88/RGB888/RGB565. - RK_U32 aswap; // 0: BGRA, 1:ABGR. -} h264e_hal_rkv_csp_info; - -typedef enum h264e_rkv_cqm4_t { - RKV_H264E_CQM_4IY = 0, - RKV_H264E_CQM_4PY = 1, - RKV_H264E_CQM_4IC = 2, - RKV_H264E_CQM_4PC = 3 -} h264e_rkv_cqm4; - -typedef enum h264e_rkv_cqm8_t { - RKV_H264E_CQM_8IY = 0, - RKV_H264E_CQM_8PY = 1, - RKV_H264E_CQM_8IC = 2, - RKV_H264E_CQM_8PC = 3, -} h264e_rkv_cqm8; - -typedef enum h264e_hal_rkv_buf_grp_t { - H264E_HAL_RKV_BUF_GRP_PP, - H264E_HAL_RKV_BUF_GRP_DSP, - H264E_HAL_RKV_BUF_GRP_MEI, - H264E_HAL_RKV_BUF_GRP_CMV, - H264E_HAL_RKV_BUF_GRP_ROI, - H264E_HAL_RKV_BUF_GRP_REC, - H264E_HAL_RKV_BUF_GRP_BUTT -} h264e_hal_rkv_buf_grp; - -typedef struct h264e_hal_rkv_roi_cfg_t { - RK_U8 qp_y : 6; - RK_U8 set_qp_y_en : 1; - RK_U8 forbit_inter : 1; -} h264e_hal_rkv_roi_cfg; - - -typedef struct h264e_hal_rkv_buffers_t { - MppBufferGroup hw_buf_grp[H264E_HAL_RKV_BUF_GRP_BUTT]; - - //MppBuffer hw_input_buf[RKV_H264E_LINKTABLE_FRAME_NUM]; - //MppBuffer hw_output_buf[RKV_H264E_LINKTABLE_FRAME_NUM]; - MppBuffer hw_pp_buf[2]; - MppBuffer hw_dsp_buf[2]; //down scale picture - MppBuffer hw_mei_buf[RKV_H264E_LINKTABLE_FRAME_NUM]; - //MppBuffer hw_cmv_buf[2]; - MppBuffer hw_roi_buf[RKV_H264E_LINKTABLE_FRAME_NUM]; - MppBuffer hw_rec_buf[RKV_H264E_NUM_REFS + 1]; //extra 1 frame for current recon - MppBuffer hw_osd_buf[RKV_H264E_LINKTABLE_FRAME_NUM]; -} h264e_hal_rkv_buffers; - -typedef struct h264e_hal_rkv_nal_t { - RK_S32 i_ref_idc; /* nal_priority_e */ - RK_S32 i_type; /* nal_unit_type_e */ - RK_S32 b_long_startcode; - RK_S32 i_first_mb; /* If this NAL is a slice, the index of the first MB in the slice. */ - RK_S32 i_last_mb; /* If this NAL is a slice, the index of the last MB in the slice. */ - - /* Size of payload (including any padding) in bytes. */ - RK_S32 i_payload; - /* If param->b_annexb is set, Annex-B bytestream with startcode. - * Otherwise, startcode is replaced with a 4-byte size. - * This size is the size used in mp4/similar muxing; it is equal to i_payload-4 */ - RK_U8 *p_payload; - - /* Size of padding in bytes. */ - RK_S32 i_padding; - RK_S32 sh_head_len; -} h264e_hal_rkv_nal; - -typedef struct h264e_hal_rkv_dump_files_t { - FILE *fp_mpp_syntax_in; - FILE *fp_mpp_reg_in; - FILE *fp_mpp_reg_out; - FILE *fp_mpp_strm_out; - FILE *fp_mpp_feedback; - FILE *fp_mpp_extra_ino_cfg; -} h264e_hal_rkv_dump_files; - -typedef struct h264e_hal_rkv_stream_t { - RK_U8 *p_start; - RK_U8 *p; - //RK_U8 *p_end; - - RK_U32 cur_bits; - RK_S32 i_left; /* i_count number of available bits */ - - //add buf pointer - RK_U8 *buf; - RK_U32 count_bit; -} h264e_hal_rkv_stream; - - -typedef struct h264e_hal_rkv_extra_info_t { - RK_S32 nal_num; - h264e_hal_rkv_nal nal[RKV_H264E_RKV_NAL_IDX_BUTT]; - RK_U8 *nal_buf; - h264e_hal_rkv_stream stream; - h264e_hal_sps sps; - h264e_hal_pps pps; -} h264e_hal_rkv_extra_info; -#define RKV_H264E_REF_MAX 16 -typedef RK_U8 pixel; -struct h264e_hal_rkv_weight_t; -typedef void (* weight_fn_t)( pixel *, intptr_t, pixel *, intptr_t, const struct h264e_hal_rkv_weight_t *, int ); -typedef struct h264e_hal_rkv_weight_t { - /* aligning the first member is a gcc hack to force the struct to be - * 16 byte aligned, as well as force sizeof(struct) to be a multiple of 16 */ - RK_S16 cachea[8]; - RK_S16 cacheb[8]; - RK_S32 i_denom; - RK_S32 i_scale; - RK_S32 i_offset; - weight_fn_t *weightfn; -} h264e_hal_rkv_weight; -typedef struct h264e_hal_rkv_hrd_t { - double cpb_initial_arrival_time; - double cpb_final_arrival_time; - double cpb_removal_time; - - double dpb_output_time; -} h264e_hal_rkv_hrd; - -struct h264e_hal_rkv_frame_t; -typedef struct h264e_hal_rkv_frame_t { - MppBuffer hw_buf; - RK_S32 hw_buf_used; - RK_S32 i_frame_cnt; /* Presentation frame number */ - RK_S32 i_frame_num; /* 7.4.3 frame_num */ - RK_S32 long_term_flag; - RK_S32 reorder_longterm_flag; - RK_S32 i_poc; - RK_S32 i_delta_poc[2]; - RK_S32 i_frame_type; - RK_S64 i_pts; - RK_S64 i_dts; - RK_S32 b_kept_as_ref; - RK_S32 b_keyframe; - RK_S32 b_corrupt; - RK_S32 i_reference_count; -} h264e_hal_rkv_frame; - - -typedef struct h264e_hal_rkv_dpb_ctx_t { - //h264e_hal_rkv_frame *fenc; - h264e_hal_rkv_frame *fdec; - h264e_hal_rkv_frame *fref[2][RKV_H264E_REF_MAX + 1]; - h264e_hal_rkv_frame *fref_nearest[2]; //Used for RC - struct { - /* Unused frames: 0 = fenc, 1 = fdec */ - h264e_hal_rkv_frame **unused; - - /* frames used for reference + sentinels */ - h264e_hal_rkv_frame *reference[RKV_H264E_REF_MAX + 1]; //TODO: remove later - - - RK_S32 i_last_keyframe; /* Frame number of the last keyframe */ - RK_S32 i_last_idr; /* Frame number of the last IDR (not RP)*/ - //RK_S64 i_largest_pts; - //RK_S64 i_second_largest_pts; - } frames; - - h264e_hal_rkv_frame frame_buf[RKV_H264E_REF_MAX + 1]; - - RK_S32 i_ref[2]; - RK_U32 i_nal_type; - RK_U32 i_nal_ref_idc; - - RK_S32 i_frame_cnt; /* Presentation frame number */ - RK_S32 i_frame_num; /* 7.4.3 frame_num */ - - //move from slice header below - RK_S32 i_slice_type; - RK_S32 i_idr_pic_id; /* -1 if nal_type != 5 */ - RK_S32 i_tmp_idr_pic_id; - //RK_S32 i_poc; - //RK_S32 i_delta_poc[2]; - //RK_S32 i_redundant_pic_cnt; - RK_S32 i_max_ref0; - RK_S32 i_max_ref1; - RK_S32 b_ref_pic_list_reordering[2]; - struct { - RK_S32 idc; - RK_S32 arg; - } ref_pic_list_order[2][RKV_H264E_REF_MAX]; - - RK_S32 i_mmco_remove_from_end; - RK_S32 i_mmco_command_count; - struct { /* struct for future expansion */ - RK_S32 i_difference_of_pic_nums; - RK_S32 i_poc; - RK_S32 memory_management_control_operation; - } mmco[RKV_H264E_REF_MAX]; - - RK_S32 i_long_term_reference_flag; -} h264e_hal_rkv_dpb_ctx; - -typedef struct h264e_hal_rkv_dbg_info_t { - struct { - RK_U32 lkt_num : 8; - RK_U32 rkvenc_cmd : 2; //MAY - RK_U32 reserve : 6; - RK_U32 enc_cke : 1; - RK_U32 Reserve : 15; - } swreg02; //ENC_STRT - - struct { - RK_U32 lkt_addr : 32; - } swreg04; //LKT_ADDR - struct { - RK_U32 ofe_fnsh : 1; - RK_U32 lkt_fnsh : 1; - RK_U32 clr_fnsh : 1; - RK_U32 ose_fnsh : 1; - RK_U32 bs_ovflr : 1; - RK_U32 brsp_ful : 1; - RK_U32 brsp_err : 1; - RK_U32 rrsp_err : 1; - RK_U32 tmt_err : 1; - RK_U32 reserve : 23; - } swreg05; //INT_EN - - struct { - RK_U32 enc_stnd : 1; - RK_U32 roi_enc : 1; - RK_U32 cur_frm_ref : 1; - RK_U32 mei_stor : 1; - RK_U32 bs_scp : 1; - RK_U32 reserve : 3; - RK_U32 pic_qp : 6; - RK_U32 reserve1 : 16; - RK_U32 slice_int : 1; - RK_U32 node_int : 1; - } swreg10; //ENC_PIC - - struct { - RK_U32 ppln_enc_lmt : 4; - RK_U32 reserve : 4; - RK_U32 rfp_load_thrd : 8; - RK_U32 reserve1 : 16; - } swreg11; //ENC_WDG - - struct { - RK_U32 src_bus_ordr : 1; - RK_U32 cmvw_bus_ordr : 1; - RK_U32 dspw_bus_ordr : 1; - RK_U32 rfpw_bus_ordr : 1; - RK_U32 src_bus_edin : 4; - RK_U32 meiw_bus_edin : 4; - RK_U32 bsw_bus_edin : 3; - RK_U32 lktr_bus_edin : 4; - RK_U32 ctur_bus_edin : 4; - RK_U32 lktw_bus_edin : 4; - RK_U32 rfp_map_dcol : 2; - RK_U32 rfp_map_sctr : 1; - RK_U32 reserve : 2; - } swreg12; //DTRNS_MAP - - struct { - RK_U32 axi_brsp_cke : 7; - RK_U32 cime_dspw_orsd : 1; - RK_U32 reserve : 24; - } swreg13; // DTRNS_CFG - - struct { - RK_U32 src_aswap : 1; - RK_U32 src_cswap : 1; - RK_U32 src_cfmt : 4; - RK_U32 src_clip_dis : 1; - RK_U32 reserve : 25; - } swreg14; //SRC_FMT - - struct { - RK_U32 wght_b2y : 9; - RK_U32 wght_g2y : 9; - RK_U32 wght_r2y : 9; - RK_U32 reserve : 5; - } swreg15; //SRC_UDFY - - struct { - RK_U32 wght_b2u : 9; - RK_U32 wght_g2u : 9; - RK_U32 wght_r2u : 9; - RK_U32 reserve : 5; - } swreg16; //SRC_UDFU - - struct { - RK_U32 wght_b2v : 9; - RK_U32 wght_g2v : 9; - RK_U32 wght_r2v : 9; - RK_U32 reserve : 5; - } swreg17; //SRC_UDFV - - - struct { - RK_U32 ofst_rgb2v : 8; - RK_U32 ofst_rgb2u : 8; - RK_U32 ofst_rgb2y : 5; - RK_U32 reserve : 11; - } swreg18; //SRC_UDFO - - struct { - RK_U32 src_tfltr : 1; - RK_U32 src_tfltr_we : 1; - RK_U32 src_tfltr_bw : 1; - RK_U32 src_sfltr : 1; - RK_U32 src_mfltr_thrd : 5; - RK_U32 src_mfltr_y : 1; - RK_U32 src_mfltr_c : 1; - RK_U32 src_bfltr_strg : 1; - RK_U32 src_bfltr : 1; - RK_U32 src_mbflt_odr : 1; - RK_U32 src_matf_y : 1; - RK_U32 src_matf_c : 1; - RK_U32 src_shp_y : 1; - RK_U32 src_shp_c : 1; - RK_U32 src_shp_div : 3; - RK_U32 src_shp_thld : 5; - RK_U32 src_mirr : 1; - RK_U32 src_rot : 2; - RK_U32 src_matf_itsy : 1; - RK_U32 reserve : 2; - } swreg19; // SRC_PROC - - struct { - RK_U32 tfltr_thld_y : 15; - RK_U32 reserve : 1; - RK_U32 tfltr_thld_c : 15; - RK_U32 reserve1 : 1; - } swreg20; // SRC_TTHLD - - RK_U32 swreg21_scr_stbl[5]; //4.22. H3D_TBL0~39 - RK_U32 swreg22_h3d_tbl[40]; //4.22. H3D_TBL0~39 - - struct { - RK_U32 src_ystrid : 14; - RK_U32 reserve : 2; - RK_U32 src_cstrid : 14; - RK_U32 reserve1 : 2; - } swreg23; //SRC_STRID - - struct { - RK_U32 adr_srcy; //swreg24 - RK_U32 adr_srcu; - RK_U32 adr_srcv; - RK_U32 fltw_addr; - RK_U32 fltr_addr; - RK_U32 ctuc_addr; - RK_U32 rfpw_addr; - RK_U32 rfpr_addr; - RK_U32 cmvw_addr; - RK_U32 cmvr_addr; - RK_U32 dspw_addr; - RK_U32 dspr_addr; - RK_U32 meiw_addr; - RK_U32 bsbt_addr; - RK_U32 bsbb_addr; - RK_U32 bsbr_addr; - RK_U32 bsbw_addr; - } addr_cfg; - - struct { - RK_U32 sli_cut : 1; - RK_U32 sli_cut_mode : 1; - RK_U32 sli_cut_bmod : 1; - RK_U32 sli_max_num : 10; - RK_U32 sli_out_mode : 1; - RK_U32 reserve : 2; - RK_U32 sli_cut_cnum : 16; - } swreg41; // SLI_SPL - - struct { - RK_U32 sli_cut_byte : 18; - RK_U32 reserve : 14; - } swreg42; // SLI_SPL_BYTE - - struct { - RK_U32 cime_srch_h : 4; - RK_U32 cime_srch_v : 4; - RK_U32 rime_srch_h : 3; - RK_U32 rime_srch_v : 3; - RK_U32 reserved : 2; - RK_U32 dlt_frm_num : 16; - } swreg43; //ME_RNGE - - struct { - RK_U32 pmv_mdst_h : 8; - RK_U32 pmv_mdst_v : 8; - RK_U32 mv_limit : 2; - RK_U32 mv_num : 2; - RK_U32 reserve : 12; - } swreg44; // ME_CNST - - struct { - RK_U32 cime_rama_max : 11; - RK_U32 cime_rama_h : 5; - RK_U32 cach_l2_tag : 2; - RK_U32 cach_l1_dtmr : 5; - RK_U32 reserve : 9; - } swreg45; //ME_RAM - - struct { - RK_U32 rc_en : 1; - RK_U32 rc_mode : 1; - RK_U32 aqmode_en : 1; - RK_U32 aq_strg : 10; - RK_U32 Reserved : 3; - RK_U32 rc_ctu_num : 16; - } swreg46; //RC_CFG - - struct { - RK_U32 bits_error0 : 16; - RK_U32 bits_error1 : 16; - } swreg47; //RC_ERP0 //TODO: merge with reg 48~51, in arrays bit_error[5] - - struct { - RK_U32 bits_error2 : 16; - RK_U32 bits_error3 : 16; - } swreg48; //RC_ERP1 - - struct { - RK_U32 bits_error4 : 16; - RK_U32 bits_error5 : 16; - } swreg49; //RC_ERP2 - - struct { - RK_U32 bits_error6 : 16; - RK_U32 bits_error7 : 16; - } swreg50; //RC_ERP3 - - struct { - RK_U32 bits_error8 : 16; - RK_U32 reserve : 16; - } swreg51; //RC_ERP4 - - struct { - RK_U32 qp_adjuest0 : 5; - RK_U32 qp_adjuest1 : 5; - RK_U32 qp_adjuest2 : 5; - RK_U32 qp_adjuest3 : 5; - RK_U32 qp_adjuest4 : 5; - RK_U32 qp_adjuest5 : 5; - RK_U32 reserve : 2; - } swreg52; // RC_ADJ0 - - struct { - RK_U32 qp_adjuest6 : 5; - RK_U32 qp_adjuest7 : 5; - RK_U32 qp_adjuest8 : 5; - RK_U32 reserve : 17; - } swreg53; // RC_ADJ1 - - struct { - RK_U32 rc_qp_mod : 2; - RK_U32 rc_fact0 : 6; - RK_U32 rc_fact1 : 6; - RK_U32 Reserved : 2; - RK_U32 rc_qp_range : 4; - RK_U32 rc_max_qp : 6; - RK_U32 rc_min_qp : 6; - } swreg54; //RC_QP - - struct { - RK_U32 ctu_ebits : 20; - RK_U32 reserve : 12; - } swreg55; //RC_TGT - - struct { - RK_U32 rect_size : 1; - RK_U32 inter_4x4 : 1; - RK_U32 arb_sel : 1; - RK_U32 vlc_lmt : 1; - RK_U32 reserve : 1; - RK_U32 rdo_mark : 8; - RK_U32 reserve1 : 19; - } swreg56; //RDO_CFG - - struct { - RK_U32 nal_ref_idc : 2; - RK_U32 nal_unit_type : 5; - RK_U32 reserve : 25; - } swreg57; // SYNT_NAL - - struct { - RK_U32 max_fnum : 4; - RK_U32 drct_8x8 : 1; - RK_U32 mpoc_lm4 : 4; - RK_U32 reserve : 23; - } swreg58; // SYNT_SPS - - struct { - RK_U32 etpy_mode : 1; - RK_U32 trns_8x8 : 1; - RK_U32 csip_flg : 1; - RK_U32 num_ref0_idx : 2; - RK_U32 num_ref1_idx : 2; - RK_U32 pic_init_qp : 6; - int cb_ofst : 5; - int cr_ofst : 5; - RK_U32 wght_pred : 1; - RK_U32 dbf_cp_flg : 1; - RK_U32 reserve : 7; - } swreg59; // SYNT_PPS - - struct { - RK_U32 sli_type : 2; - RK_U32 pps_id : 8; - RK_U32 drct_smvp : 1; - RK_U32 num_ref_ovrd : 1; - RK_U32 cbc_init_idc : 2; - RK_U32 reserve : 2; - RK_U32 frm_num : 16; - } swreg60; // SYNT_SLI0 - - struct { - RK_U32 idr_pid : 16; - RK_U32 poc_lsb : 16; - } swreg61; // SYNT_SLI1 - - struct { - RK_U32 rodr_pic_idx : 2; - RK_U32 ref_list0_rodr : 1; - RK_S32 sli_beta_ofst : 4; - RK_S32 sli_alph_ofst : 4; - RK_U32 dis_dblk_idc : 2; - RK_U32 reserve : 3; - RK_U32 rodr_pic_num : 16; - } swreg62; // SYNT_SLI2_RODR - - struct { - RK_U32 nopp_flg : 1; - RK_U32 ltrf_flg : 1; - RK_U32 arpm_flg : 1; - RK_U32 mmco4_pre : 1; - RK_U32 mmco_0 : 3; - RK_U32 dopn_m1_0 : 16; - RK_U32 reserve : 9; - } swreg63; // SYNT_REF_MARK0 - - struct { - RK_U32 mmco_1 : 3; - RK_U32 dopn_m1_1 : 16; - RK_U32 reserve : 13; - } swreg64; // SYNT_REF_MARK1 - - struct { - RK_U32 osd_en : 8; - RK_U32 osd_inv : 8; - RK_U32 osd_clk_sel : 1; - RK_U32 osd_plt_type : 1; - RK_U32 reserve : 14; - } swreg65; //OSD_CFG - - struct { - RK_U32 osd_inv_r0 : 4; - RK_U32 osd_inv_r1 : 4; - RK_U32 osd_inv_r2 : 4; - RK_U32 osd_inv_r3 : 4; - RK_U32 osd_inv_r4 : 4; - RK_U32 osd_inv_r5 : 4; - RK_U32 osd_inv_r6 : 4; - RK_U32 osd_inv_r7 : 4; - } swreg66; //OSD_INV - - h264e_osd_pos swreg67_osd_pos[8]; - - RK_U32 swreg68_indx_addr_i[8]; //4.68. OSD_ADDR0-7 - - struct { - RK_U32 bs_lgth : 32; - } swreg69; //ST_BSL - - struct { - RK_U32 sse_l32 : 32; - } swreg70; // ST_SSE_L32 - - struct { - RK_U32 qp_sum : 22; - RK_U32 reserve : 2; - RK_U32 sse_h8 : 8; - } swreg71; // ST_SSE_QP - - struct { - RK_U32 slice_scnum : 12; - RK_U32 slice_slnum : 12; - RK_U32 reserve : 8; - } swreg72; //ST_SAO - - RK_U32 swreg73_osd_indx_tab_i[256]; //4.73. OSD_PLT0~255 - - struct { - RK_U32 st_enc : 2; - RK_U32 axiw_cln : 2; - RK_U32 axir_cln : 2; - RK_U32 reserve : 26; - } swreg74; // ST_ENC - - struct { - RK_U32 fnum_enc : 8; - RK_U32 fnum_cfg : 8; - RK_U32 fnum_int : 8; - RK_U32 reserve : 8; - } swreg75; // ST_LKT - - struct { - RK_U32 node_addr : 32; - } swreg76; //ST_NOD - - struct { - RK_U32 Bsbw_ovfl : 1; - RK_U32 reserve : 2; - RK_U32 bsbw_addr : 29; - } swreg77; //ST_BSB - -#if 0 - struct { - RK_U32 axib_idl : 7; - RK_U32 axib_ful : 7; - RK_U32 axib_err : 7; - RK_U32 axir_err : 6; - RK_U32 reserve : 5; - } swreg78; //ST_DTRNS - - struct { - RK_U32 slice_num : 6; - RK_U32 reserve : 26; - } swreg79; //ST_SNUM - - struct { - RK_U32 slice_len : 23; - RK_U32 reserve : 9; - } swreg80; //ST_SLEN - - struct { - RK_U32 axip0_work : 1; - RK_U32 axip0_clr : 1; - RK_U32 axip0_frm : 1; - RK_U32 reserve : 29; - } swreg81; // AXIP0_CMD - - struct { - RK_U32 axip0_ltcy_id : 4; - RK_U32 axip0_ltcy_thr : 12; - RK_U32 reserve : 16; - } swreg82; // AXIP0_LTCY - - struct { - RK_U32 axip0_cnt_type : 1; - RK_U32 axip0_cnt_ddr : 2; - RK_U32 axip0_cnt_rid : 5; - RK_U32 axip0_cnt_wid : 5; - RK_U32 reserve : 19; - } swreg83; // AXIP0_CNT - - struct { - RK_U32 axip1_work : 1; - RK_U32 axip1_clr : 1; - RK_U32 reserve : 30; - } swreg84; // AXIP1_CMD - - struct { - RK_U32 axip1_ltcy_id : 4; - RK_U32 axip1_ltcy_thr : 12; - RK_U32 reserve : 16; - } swreg85; // AXIP1_LTCY - - struct { - RK_U32 axip1_cnt_type : 1; - RK_U32 axip1_cnt_ddr : 2; - RK_U32 axip1_cnt_rid : 5; - RK_U32 axip1_cnt_wid : 5; - RK_U32 reserve : 19; - } swreg86; // AXIP1_CNT - - struct { - RK_U32 axip0_cnt_type : 16; - RK_U32 reserve : 16; - } swreg87; // ST_AXIP0_MAXL - - - struct { - RK_U32 axip0_num_ltcy : 32; - } swreg88; // ST_AXIP0_NUML - - struct { - RK_U32 axip0_sum_ltcy : 32; - } swreg89; // ST_AXIP0_SUML - - struct { - RK_U32 axip0_byte_rd : 32; - } swreg90; // ST_AXIP0_RDB - - struct { - RK_U32 axip0_byte_wr : 32; - } swreg91; // ST_AXIP0_WRB - - struct { - RK_U32 axip0_wrk_cyc : 32; - } swreg92; //ST_AXIP0_CYCL - - struct { - RK_U32 axip1_cnt_type : 16; - RK_U32 reserve : 16; - } swreg93; // ST_AXIP1_MAXL - - struct { - RK_U32 axip1_num_ltcy : 32; - } swreg94; // ST_AXIP1_NUML - - struct { - RK_U32 axip1_sum_ltcy : 32; - } swreg95; // ST_AXIP1_SUML - - struct { - RK_U32 axip1_byte_rd : 32; - } swreg96; // ST_AXIP1_RDB - - struct { - RK_U32 axip1_byte_wr : 32; - } swreg97; // ST_AXIP1_WRB - - struct { - RK_U32 axip1_wrk_cyc : 32; - } swreg98; // ST_AXIP1_CYCL -#endif //#if 0 -} h264e_hal_rkv_dbg_info; - - -/* cmodel version r2893 */ - -typedef struct h264e_osd_cfg_t { - RK_U32 lt_pos_x : 8; - RK_U32 lt_pos_y : 8; - RK_U32 rd_pos_x : 8; - RK_U32 rd_pos_y : 8; -} h264e_osd_cfg; //OSD_POS0-7 - -typedef struct h264e_rkv_reg_set_t { - - struct { - RK_U32 rkvenc_ver : 32; //default : 0x0000_0001 - } swreg01; //VERSION - - struct { - RK_U32 lkt_num : 8; - RK_U32 rkvenc_cmd : 2; - RK_U32 reserve : 6; - RK_U32 enc_cke : 1; - RK_U32 Reserve : 15; - } swreg02; //ENC_STRT - - struct { - RK_U32 safe_clr : 1; - RK_U32 reserve : 31; - } swreg03; //ENC_CLR - - struct { - RK_U32 lkt_addr : 32; - } swreg04; //LKT_ADDR - - struct { - RK_U32 ofe_fnsh : 1; - RK_U32 lkt_fnsh : 1; - RK_U32 clr_fnsh : 1; - RK_U32 ose_fnsh : 1; - RK_U32 bs_ovflr : 1; - RK_U32 brsp_ful : 1; - RK_U32 brsp_err : 1; - RK_U32 rrsp_err : 1; - RK_U32 tmt_err : 1; - RK_U32 reserve : 23; - } swreg05; //INT_EN - - struct { - RK_U32 reserve : 32; - } swreg06; //4.5. INT_MSK - - struct { - RK_U32 clr_ofe_fnsh : 1; - RK_U32 clr_lkt_fnsh : 1; - RK_U32 clr_clr_fnsh : 1; - RK_U32 clr_ose_fnsh : 1; - RK_U32 clr_bs_ovflr : 1; - RK_U32 clr_brsp_ful : 1; - RK_U32 clr_brsp_err : 1; - RK_U32 clr_rrsp_err : 1; - RK_U32 clr_tmt_err : 1; - RK_U32 reserve : 23; - } swreg07; //4.6. INT_CLR - - struct { - RK_U32 reserve : 32; - } swreg08; //4.7. INT_STUS - -#if RKV_H264E_ADD_RESERVE_REGS - RK_U32 reserve_08_09[4]; -#endif - - struct { - RK_U32 pic_wd8_m1 : 9; - RK_U32 reserve0 : 1; - RK_U32 pic_wfill : 6; - RK_U32 pic_hd8_m1 : 9; - RK_U32 reserve1 : 1; - RK_U32 pic_hfill : 6; - } swreg09; // ENC_RSL - - - struct { - RK_U32 enc_stnd : 1; - RK_U32 roi_enc : 1; - RK_U32 cur_frm_ref : 1; - RK_U32 mei_stor : 1; - RK_U32 bs_scp : 1; - RK_U32 reserve : 3; - RK_U32 pic_qp : 6; - RK_U32 reserve1 : 16; - RK_U32 slice_int : 1; - RK_U32 node_int : 1; - } swreg10; //ENC_PIC - - struct { - RK_U32 ppln_enc_lmt : 4; - RK_U32 reserve : 4; - RK_U32 rfp_load_thrd : 8; - RK_U32 reserve1 : 16; - } swreg11; //ENC_WDG - - struct { - RK_U32 src_bus_ordr : 1; - RK_U32 cmvw_bus_ordr : 1; - RK_U32 dspw_bus_ordr : 1; - RK_U32 rfpw_bus_ordr : 1; - RK_U32 src_bus_edin : 4; - RK_U32 meiw_bus_edin : 4; - RK_U32 bsw_bus_edin : 3; - RK_U32 lktr_bus_edin : 4; - RK_U32 ctur_bus_edin : 4; - RK_U32 lktw_bus_edin : 4; - RK_U32 rfp_map_dcol : 2; - RK_U32 rfp_map_sctr : 1; - RK_U32 reserve : 2; - } swreg12; //DTRNS_MAP - - struct { - RK_U32 axi_brsp_cke : 7; - RK_U32 cime_dspw_orsd : 1; - RK_U32 reserve : 24; - } swreg13; // DTRNS_CFG - - struct { - RK_U32 src_aswap : 1; - RK_U32 src_cswap : 1; - RK_U32 src_cfmt : 4; - RK_U32 src_clip_dis : 1; - RK_U32 reserve : 25; - } swreg14; //SRC_FMT - - struct { - RK_U32 wght_b2y : 9; - RK_U32 wght_g2y : 9; - RK_U32 wght_r2y : 9; - RK_U32 reserve : 5; - } swreg15; //SRC_UDFY - - struct { - RK_U32 wght_b2u : 9; - RK_U32 wght_g2u : 9; - RK_U32 wght_r2u : 9; - RK_U32 reserve : 5; - } swreg16; //SRC_UDFU - - struct { - RK_U32 wght_b2v : 9; - RK_U32 wght_g2v : 9; - RK_U32 wght_r2v : 9; - RK_U32 reserve : 5; - } swreg17; //SRC_UDFV - - struct { - RK_U32 ofst_rgb2v : 8; - RK_U32 ofst_rgb2u : 8; - RK_U32 ofst_rgb2y : 5; - RK_U32 reserve : 11; - } swreg18; //SRC_UDFO - - struct { - RK_U32 src_tfltr : 1; - RK_U32 src_tfltr_we : 1; - RK_U32 src_tfltr_bw : 1; - RK_U32 src_sfltr : 1; - RK_U32 src_mfltr_thrd : 5; - RK_U32 src_mfltr_y : 1; - RK_U32 src_mfltr_c : 1; - RK_U32 src_bfltr_strg : 1; - RK_U32 src_bfltr : 1; - RK_U32 src_mbflt_odr : 1; - RK_U32 src_matf_y : 1; - RK_U32 src_matf_c : 1; - RK_U32 src_shp_y : 1; - RK_U32 src_shp_c : 1; - RK_U32 src_shp_div : 3; - RK_U32 src_shp_thld : 5; - RK_U32 src_mirr : 1; - RK_U32 src_rot : 2; - RK_U32 src_matf_itsy : 1; - RK_U32 reserve : 2; - } swreg19; // SRC_PROC - - struct { - RK_U32 tfltr_thld_y : 15; - RK_U32 reserve : 1; - RK_U32 tfltr_thld_c : 15; - RK_U32 reserve1 : 1; - } swreg20; // SRC_TTHLD - - RK_U32 swreg21_scr_stbl[5]; //4.22. H3D_TBL0~39 - - RK_U32 swreg22_h3d_tbl[40]; //4.22. H3D_TBL0~39 - - struct { - RK_U32 src_ystrid : 14; - RK_U32 reserve : 2; - RK_U32 src_cstrid : 14; - RK_U32 reserve1 : 2; - } swreg23; //SRC_STRID - - RK_U32 swreg24_adr_srcy; //swreg24 - RK_U32 swreg25_adr_srcu; //swreg25 - RK_U32 swreg26_adr_srcv; //swreg26 - RK_U32 swreg27_fltw_addr; //swreg27 - RK_U32 swreg28_fltr_addr; //swreg28 - RK_U32 swreg29_ctuc_addr; //swreg29 - RK_U32 swreg30_rfpw_addr; //swreg30 - RK_U32 swreg31_rfpr_addr; //swreg31 - RK_U32 swreg32_cmvw_addr; //swreg32 - RK_U32 swreg33_cmvr_addr; //swreg33 - RK_U32 swreg34_dspw_addr; //swreg34 - RK_U32 swreg35_dspr_addr; //swreg35 - RK_U32 swreg36_meiw_addr; //swreg36 - RK_U32 swreg37_bsbt_addr; //swreg37 - RK_U32 swreg38_bsbb_addr; //swreg38 - RK_U32 swreg39_bsbr_addr; //swreg39 - RK_U32 swreg40_bsbw_addr; //swreg40 - - struct { - RK_U32 sli_cut : 1; - RK_U32 sli_cut_mode : 1; - RK_U32 sli_cut_bmod : 1; - RK_U32 sli_max_num : 10; - RK_U32 sli_out_mode : 1; - RK_U32 reserve : 2; - RK_U32 sli_cut_cnum : 16; - } swreg41; // SLI_SPL - - struct { - RK_U32 sli_cut_byte : 18; - RK_U32 reserve : 14; - } swreg42; // SLI_SPL_BYTE - - struct { - RK_U32 cime_srch_h : 4; - RK_U32 cime_srch_v : 4; - RK_U32 rime_srch_h : 3; - RK_U32 rime_srch_v : 3; - RK_U32 reserved : 2; - RK_U32 dlt_frm_num : 16; - } swreg43; //ME_RNGE - - - struct { - RK_U32 pmv_mdst_h : 8; - RK_U32 pmv_mdst_v : 8; - RK_U32 mv_limit : 2; - RK_U32 mv_num : 2; - RK_U32 reserve : 12; - } swreg44; // ME_CNST - - struct { - RK_U32 cime_rama_max : 11; - RK_U32 cime_rama_h : 5; - RK_U32 cach_l2_tag : 2; - RK_U32 cach_l1_dtmr : 5; - RK_U32 reserve : 9; - } swreg45; //ME_RAM - - struct { - RK_U32 rc_en : 1; - RK_U32 rc_mode : 1; - RK_U32 aqmode_en : 1; - RK_U32 aq_strg : 10; - RK_U32 Reserved : 3; - RK_U32 rc_ctu_num : 16; - } swreg46; //RC_CFG - - struct { - RK_U32 bits_error0 : 16; - RK_U32 bits_error1 : 16; - } swreg47; //RC_ERP0 - - struct { - RK_U32 bits_error2 : 16; - RK_U32 bits_error3 : 16; - } swreg48; //RC_ERP1 - - struct { - RK_U32 bits_error4 : 16; - RK_U32 bits_error5 : 16; - } swreg49; //RC_ERP2 - - struct { - RK_U32 bits_error6 : 16; - RK_U32 bits_error7 : 16; - } swreg50; //RC_ERP3 - - struct { - RK_U32 bits_error8 : 16; - RK_U32 reserve : 16; - } swreg51; //RC_ERP4 - - struct { - RK_U32 qp_adjuest0 : 5; - RK_U32 qp_adjuest1 : 5; - RK_U32 qp_adjuest2 : 5; - RK_U32 qp_adjuest3 : 5; - RK_U32 qp_adjuest4 : 5; - RK_U32 qp_adjuest5 : 5; - RK_U32 reserve : 2; - } swreg52; // RC_ADJ0 - - struct { - RK_U32 qp_adjuest6 : 5; - RK_U32 qp_adjuest7 : 5; - RK_U32 qp_adjuest8 : 5; - RK_U32 reserve : 17; - } swreg53; // RC_ADJ1 - - struct { - RK_U32 rc_qp_mod : 2; - RK_U32 rc_fact0 : 6; - RK_U32 rc_fact1 : 6; - RK_U32 Reserved : 2; - RK_U32 rc_qp_range : 4; - RK_U32 rc_max_qp : 6; - RK_U32 rc_min_qp : 6; - } swreg54; //RC_QP - - struct { - RK_U32 ctu_ebits : 20; - RK_U32 reserve : 12; - } swreg55; //RC_TGT - - - struct { - RK_U32 rect_size : 1; - RK_U32 inter_4x4 : 1; - RK_U32 arb_sel : 1; - RK_U32 vlc_lmt : 1; - RK_U32 reserve : 1; - RK_U32 rdo_mark : 8; - RK_U32 reserve1 : 19; - } swreg56; //RDO_CFG - - struct { - RK_U32 nal_ref_idc : 2; - RK_U32 nal_unit_type : 5; - RK_U32 reserve : 25; - } swreg57; // SYNT_NAL - - struct { - RK_U32 max_fnum : 4; - RK_U32 drct_8x8 : 1; - RK_U32 mpoc_lm4 : 4; - RK_U32 reserve : 23; - } swreg58; // SYNT_SPS - - struct { - RK_U32 etpy_mode : 1; - RK_U32 trns_8x8 : 1; - RK_U32 csip_flg : 1; - RK_U32 num_ref0_idx : 2; - RK_U32 num_ref1_idx : 2; - RK_U32 pic_init_qp : 6; - RK_S32 cb_ofst : 5; - RK_S32 cr_ofst : 5; - RK_U32 wght_pred : 1; - RK_U32 dbf_cp_flg : 1; - RK_U32 reserve : 7; - } swreg59; // SYNT_PPS - - struct { - RK_U32 sli_type : 2; - RK_U32 pps_id : 8; - RK_U32 drct_smvp : 1; - RK_U32 num_ref_ovrd : 1; - RK_U32 cbc_init_idc : 2; - RK_U32 reserve : 2; - RK_U32 frm_num : 16; - } swreg60; // SYNT_SLI0 - - struct { - RK_U32 idr_pid : 16; - RK_U32 poc_lsb : 16; - } swreg61; // SYNT_SLI1 - - struct { - RK_U32 rodr_pic_idx : 2; - RK_U32 ref_list0_rodr : 1; - RK_S32 sli_beta_ofst : 4; - RK_S32 sli_alph_ofst : 4; - RK_U32 dis_dblk_idc : 2; - RK_U32 reserve : 3; - RK_U32 rodr_pic_num : 16; - } swreg62; // SYNT_SLI2_RODR - - struct { - RK_U32 nopp_flg : 1; - RK_U32 ltrf_flg : 1; - RK_U32 arpm_flg : 1; - RK_U32 mmco4_pre : 1; - RK_U32 mmco_0 : 3; - RK_U32 dopn_m1_0 : 16; - RK_U32 reserve : 9; - } swreg63; // SYNT_REF_MARK0 - - struct { - RK_U32 mmco_1 : 3; - RK_U32 dopn_m1_1 : 16; - RK_U32 reserve : 13; - } swreg64; // SYNT_REF_MARK1 - -#if RKV_H264E_ADD_RESERVE_REGS - RK_U32 reserve_64_65[1]; -#endif - struct { - RK_U32 osd_en : 8; - RK_U32 osd_inv : 8; - RK_U32 osd_clk_sel : 1; - RK_U32 osd_plt_type : 1; - RK_U32 reserve : 14; - } swreg65; //OSD_CFG - - struct { - RK_U32 osd_inv_r0 : 4; - RK_U32 osd_inv_r1 : 4; - RK_U32 osd_inv_r2 : 4; - RK_U32 osd_inv_r3 : 4; - RK_U32 osd_inv_r4 : 4; - RK_U32 osd_inv_r5 : 4; - RK_U32 osd_inv_r6 : 4; - RK_U32 osd_inv_r7 : 4; - } swreg66; //OSD_INV - -#if RKV_H264E_ADD_RESERVE_REGS - RK_U32 reserve_66_67[2]; -#endif - - h264e_osd_cfg swreg67_osd_pos[8]; - - RK_U32 swreg68_indx_addr_i[8]; //4.68. OSD_ADDR0-7 - - struct { - RK_U32 bs_lgth : 32; - } swreg69; //ST_BSL - - struct { - RK_U32 sse_l32 : 32; - } swreg70; // ST_SSE_L32 - - struct { - RK_U32 qp_sum : 22; - RK_U32 reserve : 2; - RK_U32 sse_h8 : 8; - } swreg71; // ST_SSE_QP - - struct { - RK_U32 slice_scnum : 12; - RK_U32 slice_slnum : 12; - RK_U32 reserve : 8; - } swreg72; //ST_SAO - - - struct { - RK_U32 st_enc : 2; - RK_U32 axiw_cln : 2; - RK_U32 axir_cln : 2; - RK_U32 reserve : 26; - } swreg73; // ST_ENC - - struct { - RK_U32 fnum_enc : 8; - RK_U32 fnum_cfg : 8; - RK_U32 fnum_int : 8; - RK_U32 reserve : 8; - } swreg74; // ST_LKT - - struct { - RK_U32 node_addr : 32; - } swreg75; //ST_NOD - - struct { - RK_U32 Bsbw_ovfl : 1; - RK_U32 reserve : 2; - RK_U32 bsbw_addr : 29; - } swreg76; //ST_BSB - -#if !RKV_H264E_REMOVE_UNNECESSARY_REGS - - struct { - RK_U32 axib_idl : 7; - RK_U32 axib_ful : 7; - RK_U32 axib_err : 7; - RK_U32 axir_err : 6; - RK_U32 reserve : 5; - } swreg77; //ST_DTRNS - - struct { - RK_U32 slice_num : 6; - RK_U32 reserve : 26; - } swreg78; //ST_SNUM - - struct { - RK_U32 slice_len : 23; - RK_U32 reserve : 9; - } swreg79; //ST_SLEN - -#if RKV_H264E_ADD_RESERVE_REGS - RK_U32 reserve_79_80[113]; -#endif - - RK_U32 swreg80_osd_indx_tab_i[256]; //4.73. OSD_PLT0~255 - - struct { - RK_U32 axip0_work : 1; - RK_U32 axip0_clr : 1; - RK_U32 axip0_frm : 1; - RK_U32 reserve : 29; - } swreg81; // AXIP0_CMD - - struct { - RK_U32 axip0_ltcy_id : 4; - RK_U32 axip0_ltcy_thr : 12; - RK_U32 reserve : 16; - } swreg82; // AXIP0_LTCY - - struct { - RK_U32 axip0_cnt_type : 1; - RK_U32 axip0_cnt_ddr : 2; - RK_U32 axip0_cnt_rid : 5; - RK_U32 axip0_cnt_wid : 5; - RK_U32 reserve : 19; - } swreg83; // AXIP0_CNT - -#if RKV_H264E_ADD_RESERVE_REGS - RK_U32 reserve_83_84[1]; -#endif - - struct { - RK_U32 axip1_work : 1; - RK_U32 axip1_clr : 1; - RK_U32 reserve : 30; - } swreg84; // AXIP1_CMD - - struct { - RK_U32 axip1_ltcy_id : 4; - RK_U32 axip1_ltcy_thr : 12; - RK_U32 reserve : 16; - } swreg85; // AXIP1_LTCY - - struct { - RK_U32 axip1_cnt_type : 1; - RK_U32 axip1_cnt_ddr : 2; - RK_U32 axip1_cnt_rid : 5; - RK_U32 axip1_cnt_wid : 5; - RK_U32 reserve : 19; - } swreg86; // AXIP1_CNT - -#if RKV_H264E_ADD_RESERVE_REGS - RK_U32 reserve_86_87[1]; -#endif - - struct { - RK_U32 axip0_cnt_type : 16; - RK_U32 reserve : 16; - } swreg87; // ST_AXIP0_MAXL - - - struct { - RK_U32 axip0_num_ltcy : 32; - } swreg88; // ST_AXIP0_NUML - - struct { - RK_U32 axip0_sum_ltcy : 32; - } swreg89; // ST_AXIP0_SUML - - struct { - RK_U32 axip0_byte_rd : 32; - } swreg90; // ST_AXIP0_RDB - - struct { - RK_U32 axip0_byte_wr : 32; - } swreg91; // ST_AXIP0_WRB - - struct { - RK_U32 axip0_wrk_cyc : 32; - } swreg92; //ST_AXIP0_CYCL - -#if RKV_H264E_ADD_RESERVE_REGS - RK_U32 reserve_92_93[2]; -#endif - - struct { - RK_U32 axip1_cnt_type : 16; - RK_U32 reserve : 16; - } swreg93; // ST_AXIP1_MAXL - - struct { - RK_U32 axip1_num_ltcy : 32; - } swreg94; // ST_AXIP1_NUML - - struct { - RK_U32 axip1_sum_ltcy : 32; - } swreg95; // ST_AXIP1_SUML - - struct { - RK_U32 axip1_byte_rd : 32; - } swreg96; // ST_AXIP1_RDB - - struct { - RK_U32 axip1_byte_wr : 32; - } swreg97; // ST_AXIP1_WRB - - struct { - RK_U32 axip1_wrk_cyc : 32; - } swreg98; // ST_AXIP1_CYCL - -#endif //#if !RKV_H264E_REMOVE_UNNECESSARY_REGS -} h264e_rkv_reg_set; - -typedef struct h264e_rkv_ioctl_extra_info_elem_t { - RK_U32 reg_idx; - RK_U32 offset; -} h264e_rkv_ioctl_extra_info_elem; - -typedef struct h264e_rkv_ioctl_extra_info_t { - RK_U32 magic; - RK_U32 cnt; - h264e_rkv_ioctl_extra_info_elem elem[20]; -} h264e_rkv_ioctl_extra_info; - -typedef struct h264e_rkv_ioctl_reg_info_t { - RK_U32 reg_num; - h264e_rkv_reg_set regs; - h264e_rkv_ioctl_extra_info extra_info; -} h264e_rkv_ioctl_reg_info; - -/* -enc_mode - 0: N/A - 1: one frame encode by register configuration - 2: multi-frame encode start with link table - 3: multi_frame_encode link table update -*/ -typedef struct h264e_rkv_ioctl_input_t { - RK_U32 enc_mode; - RK_U32 frame_num; - - h264e_rkv_ioctl_reg_info reg_info[RKV_H264E_LINKTABLE_MAX_SIZE]; -} h264e_rkv_ioctl_input; - - -typedef struct h264e_rkv_ioctl_output_elem_t { - RK_U32 hw_status; - - struct { - RK_U32 bs_lgth : 32; - } swreg69; //ST_BSL - - struct { - RK_U32 sse_l32 : 32; - } swreg70; // ST_SSE_L32 - - struct { - RK_U32 qp_sum : 22; - RK_U32 reserve : 2; - RK_U32 sse_h8 : 8; - } swreg71; // ST_SSE_QP - - struct { - RK_U32 slice_scnum : 12; - RK_U32 slice_slnum : 12; - RK_U32 reserve : 8; - } swreg72; //ST_SAO - - - struct { - RK_U32 st_enc : 2; - RK_U32 axiw_cln : 2; - RK_U32 axir_cln : 2; - RK_U32 reserve : 26; - } swreg73; // ST_ENC - - struct { - RK_U32 fnum_enc : 8; - RK_U32 fnum_cfg : 8; - RK_U32 fnum_int : 8; - RK_U32 reserve : 8; - } swreg74; // ST_LKT - - struct { - RK_U32 node_addr : 32; - } swreg75; //ST_NOD - - struct { - RK_U32 Bsbw_ovfl : 1; - RK_U32 reserve : 2; - RK_U32 bsbw_addr : 29; - } swreg76; //ST_BSB - - struct { - RK_U32 axib_idl : 7; - RK_U32 axib_ful : 7; - RK_U32 axib_err : 7; - RK_U32 axir_err : 6; - RK_U32 reserve : 5; - } swreg77; //ST_DTRNS - - struct { - RK_U32 slice_num : 6; - RK_U32 reserve : 26; - } swreg78; //ST_SNUM - - struct { - RK_U32 slice_len : 23; - RK_U32 reserve : 9; - } swreg79; //ST_SLEN -} h264e_rkv_ioctl_output_elem; - -typedef struct h264e_rkv_ioctl_output_t { - RK_U32 frame_num; - h264e_rkv_ioctl_output_elem elem[RKV_H264E_LINKTABLE_MAX_SIZE]; -} h264e_rkv_ioctl_output; - - -#define RK_H264E_NUM_REGS ((RK_S32)(sizeof(h264e_rkv_reg_set)/4)) - -MPP_RET hal_h264e_rkv_init (void *hal, MppHalCfg *cfg); -MPP_RET hal_h264e_rkv_deinit (void *hal); -MPP_RET hal_h264e_rkv_gen_regs(void *hal, HalTaskInfo *task); -MPP_RET hal_h264e_rkv_start (void *hal, HalTaskInfo *task); -MPP_RET hal_h264e_rkv_wait (void *hal, HalTaskInfo *task); -MPP_RET hal_h264e_rkv_reset (void *hal); -MPP_RET hal_h264e_rkv_flush (void *hal); -MPP_RET hal_h264e_rkv_control (void *hal, RK_S32 cmd_type, void *param); - -#endif +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __HAL_H264E_RK_H__ +#define __HAL_H264E_RK_H__ + +#include "mpp_buffer.h" +#include "mpp_hal.h" +#include "hal_task.h" +/* +enc_mode + 0: N/A + 1: one frame encode by register configuration + 2: multi-frame encode start with link table + 3: multi-frame encode link table update +*/ +#define RKV_H264E_SDK_TEST 1 + + +#define RKV_H264E_ENC_MODE 1 //2/3 +#define RKV_H264E_LINKTABLE_FRAME_NUM 1 //2 + +#if RKV_H264E_ENC_MODE == 2 +#define RKV_H264E_LINKTABLE_EACH_NUM RKV_H264E_LINKTABLE_FRAME_NUM +#else +#define RKV_H264E_LINKTABLE_EACH_NUM 1 +#endif + +#define RKV_H264E_NUM_REFS 1 +#define RKV_H264E_LONGTERM_REF_EN 0 +//------------------------------------------------------------------------------- + +#define RKV_H264E_LINKTABLE_MAX_SIZE 256 +#define RKV_H264E_ADD_RESERVE_REGS 1 +#define RKV_H264E_REMOVE_UNNECESSARY_REGS 1 + +#define RKV_H264E_CSP2_MASK 0x00ff /* */ +#define RKV_H264E_CSP2_NONE 0x0000 /* Invalid mode */ +#define RKV_H264E_CSP2_I420 0x0001 /* yuv 4:2:0 planar */ +#define RKV_H264E_CSP2_YV12 0x0002 /* yvu 4:2:0 planar */ +#define RKV_H264E_CSP2_NV12 0x0003 /* yuv 4:2:0, with one y plane and one packed u+v */ +#define RKV_H264E_CSP2_I422 0x0004 /* yuv 4:2:2 planar */ +#define RKV_H264E_CSP2_YV16 0x0005 /* yvu 4:2:2 planar */ +#define RKV_H264E_CSP2_NV16 0x0006 /* yuv 4:2:2, with one y plane and one packed u+v */ +#define RKV_H264E_CSP2_V210 0x0007 /* 10-bit yuv 4:2:2 packed in 32 */ +#define RKV_H264E_CSP2_I444 0x0008 /* yuv 4:4:4 planar */ +#define RKV_H264E_CSP2_YV24 0x0009 /* yvu 4:4:4 planar */ +#define RKV_H264E_CSP2_BGR 0x000a /* packed bgr 24bits */ +#define RKV_H264E_CSP2_BGRA 0x000b /* packed bgr 32bits */ +#define RKV_H264E_CSP2_RGB 0x000c /* packed rgb 24bits */ +#define RKV_H264E_CSP2_MAX 0x000d /* end of list */ +#define RKV_H264E_CSP2_VFLIP 0x1000 /* the csp is vertically flipped */ +#define RKV_H264E_CSP2_HIGH_DEPTH 0x2000 /* the csp has a depth of 16 bits per pixel component */ + +#define RKV_H264E_B_PYRAMID_NONE 0 +#define RKV_H264E_B_PYRAMID_STRICT 1 +#define RKV_H264E_B_PYRAMID_NORMAL 2 + +#define RKV_H264E_CQM_FLAT 0 +#define RKV_H264E_CQM_JVT 1 +#define RKV_H264E_CQM_CUSTOM 2 + + +#define RKV_H264E_INT_ONE_FRAME_FINISH 0x00000001 +#define RKV_H264E_INT_LINKTABLE_FINISH 0x00000002 +#define RKV_H264E_INT_SAFE_CLEAR_FINISH 0x00000004 +#define RKV_H264E_INT_ONE_SLICE_FINISH 0x00000008 +#define RKV_H264E_INT_BIT_STREAM_OVERFLOW 0x00000010 +#define RKV_H264E_INT_BUS_WRITE_FULL 0x00000020 +#define RKV_H264E_INT_BUS_WRITE_ERROR 0x00000040 +#define RKV_H264E_INT_BUS_READ_ERROR 0x00000080 +#define RKV_H264E_INT_TIMEOUT_ERROR 0x00000100 + +#if RKV_H264E_SDK_TEST +typedef struct h264e_hal_rkv_coveragetest_cfg_t { + RK_U32 qp; + RK_U32 preproc; + RK_U32 osd; + RK_U32 mbrc; + RK_U32 roi; +} h264e_hal_rkv_coveragetest_cfg; +#endif + + +typedef enum h264e_rkv_csp_t { + H264E_RKV_CSP_BGRA8888, // 0 + H264E_RKV_CSP_BGR888, // 1 + H264E_RKV_CSP_BGR565, // 2 + H264E_RKV_CSP_NONE, // 3 + H264E_RKV_CSP_YUV422SP, // 4 + H264E_RKV_CSP_YUV422P, // 5 + H264E_RKV_CSP_YUV420SP, // 6 + H264E_RKV_CSP_YUV420P, // 7 + H264E_RKV_CSP_YUYV422, // 8 + H264E_RKV_CSP_UYVY422, // 9 + H264E_RKV_CSP_BUTT, // 10 +} h264e_hal_rkv_csp; + + +typedef enum h264e_rkv_chroma_fmt_t { + RKV_H264E_CHROMA_400 = 0, + RKV_H264E_CHROMA_420 = 1, + RKV_H264E_CHROMA_422 = 2, + RKV_H264E_CHROMA_444 = 3, +} h264e_rkv_chroma_fmt; + +typedef struct h264e_hal_rkv_csp_info_t { + RK_U32 fmt; + RK_U32 cswap; // U/V swap for YUV420SP/YUV422SP/YUYV422/UYUV422; R/B swap for BGRA88/RGB888/RGB565. + RK_U32 aswap; // 0: BGRA, 1:ABGR. +} h264e_hal_rkv_csp_info; + +typedef enum h264e_rkv_cqm4_t { + RKV_H264E_CQM_4IY = 0, + RKV_H264E_CQM_4PY = 1, + RKV_H264E_CQM_4IC = 2, + RKV_H264E_CQM_4PC = 3 +} h264e_rkv_cqm4; + +typedef enum h264e_rkv_cqm8_t { + RKV_H264E_CQM_8IY = 0, + RKV_H264E_CQM_8PY = 1, + RKV_H264E_CQM_8IC = 2, + RKV_H264E_CQM_8PC = 3, +} h264e_rkv_cqm8; + +typedef enum h264e_hal_rkv_buf_grp_t { + H264E_HAL_RKV_BUF_GRP_PP, + H264E_HAL_RKV_BUF_GRP_DSP, + H264E_HAL_RKV_BUF_GRP_MEI, + H264E_HAL_RKV_BUF_GRP_CMV, + H264E_HAL_RKV_BUF_GRP_ROI, + H264E_HAL_RKV_BUF_GRP_REC, + H264E_HAL_RKV_BUF_GRP_BUTT +} h264e_hal_rkv_buf_grp; + +typedef struct h264e_hal_rkv_roi_cfg_t { + RK_U8 qp_y : 6; + RK_U8 set_qp_y_en : 1; + RK_U8 forbit_inter : 1; +} h264e_hal_rkv_roi_cfg; + + +typedef struct h264e_hal_rkv_buffers_t { + MppBufferGroup hw_buf_grp[H264E_HAL_RKV_BUF_GRP_BUTT]; + + //MppBuffer hw_input_buf[RKV_H264E_LINKTABLE_FRAME_NUM]; + //MppBuffer hw_output_buf[RKV_H264E_LINKTABLE_FRAME_NUM]; + MppBuffer hw_pp_buf[2]; + MppBuffer hw_dsp_buf[2]; //down scale picture + MppBuffer hw_mei_buf[RKV_H264E_LINKTABLE_FRAME_NUM]; + //MppBuffer hw_cmv_buf[2]; + MppBuffer hw_roi_buf[RKV_H264E_LINKTABLE_FRAME_NUM]; + MppBuffer hw_rec_buf[RKV_H264E_NUM_REFS + 1]; //extra 1 frame for current recon + MppBuffer hw_osd_buf[RKV_H264E_LINKTABLE_FRAME_NUM]; +} h264e_hal_rkv_buffers; + +typedef struct h264e_hal_rkv_nal_t { + RK_S32 i_ref_idc; /* nal_priority_e */ + RK_S32 i_type; /* nal_unit_type_e */ + RK_S32 b_long_startcode; + RK_S32 i_first_mb; /* If this NAL is a slice, the index of the first MB in the slice. */ + RK_S32 i_last_mb; /* If this NAL is a slice, the index of the last MB in the slice. */ + + /* Size of payload (including any padding) in bytes. */ + RK_S32 i_payload; + /* If param->b_annexb is set, Annex-B bytestream with startcode. + * Otherwise, startcode is replaced with a 4-byte size. + * This size is the size used in mp4/similar muxing; it is equal to i_payload-4 */ + RK_U8 *p_payload; + + /* Size of padding in bytes. */ + RK_S32 i_padding; + RK_S32 sh_head_len; +} h264e_hal_rkv_nal; + +typedef struct h264e_hal_rkv_dump_files_t { + FILE *fp_mpp_syntax_in; + FILE *fp_mpp_reg_in; + FILE *fp_mpp_reg_out; + FILE *fp_mpp_strm_out; + FILE *fp_mpp_feedback; + FILE *fp_mpp_extra_ino_cfg; +} h264e_hal_rkv_dump_files; + +typedef struct h264e_hal_rkv_stream_t { + RK_U8 *p_start; + RK_U8 *p; + //RK_U8 *p_end; + + RK_U32 cur_bits; + RK_S32 i_left; /* i_count number of available bits */ + + //add buf pointer + RK_U8 *buf; + RK_U32 count_bit; +} h264e_hal_rkv_stream; + + +typedef struct h264e_hal_rkv_extra_info_t { + RK_S32 nal_num; + h264e_hal_rkv_nal nal[RKV_H264E_RKV_NAL_IDX_BUTT]; + RK_U8 *nal_buf; + h264e_hal_rkv_stream stream; + h264e_hal_sps sps; + h264e_hal_pps pps; +} h264e_hal_rkv_extra_info; +#define RKV_H264E_REF_MAX 16 +typedef RK_U8 pixel; +struct h264e_hal_rkv_weight_t; +typedef void (* weight_fn_t)( pixel *, intptr_t, pixel *, intptr_t, const struct h264e_hal_rkv_weight_t *, int ); +typedef struct h264e_hal_rkv_weight_t { + /* aligning the first member is a gcc hack to force the struct to be + * 16 byte aligned, as well as force sizeof(struct) to be a multiple of 16 */ + RK_S16 cachea[8]; + RK_S16 cacheb[8]; + RK_S32 i_denom; + RK_S32 i_scale; + RK_S32 i_offset; + weight_fn_t *weightfn; +} h264e_hal_rkv_weight; +typedef struct h264e_hal_rkv_hrd_t { + double cpb_initial_arrival_time; + double cpb_final_arrival_time; + double cpb_removal_time; + + double dpb_output_time; +} h264e_hal_rkv_hrd; + +struct h264e_hal_rkv_frame_t; +typedef struct h264e_hal_rkv_frame_t { + MppBuffer hw_buf; + RK_S32 hw_buf_used; + RK_S32 i_frame_cnt; /* Presentation frame number */ + RK_S32 i_frame_num; /* 7.4.3 frame_num */ + RK_S32 long_term_flag; + RK_S32 reorder_longterm_flag; + RK_S32 i_poc; + RK_S32 i_delta_poc[2]; + RK_S32 i_frame_type; + RK_S64 i_pts; + RK_S64 i_dts; + RK_S32 b_kept_as_ref; + RK_S32 b_keyframe; + RK_S32 b_corrupt; + RK_S32 i_reference_count; +} h264e_hal_rkv_frame; + + +typedef struct h264e_hal_rkv_dpb_ctx_t { + //h264e_hal_rkv_frame *fenc; + h264e_hal_rkv_frame *fdec; + h264e_hal_rkv_frame *fref[2][RKV_H264E_REF_MAX + 1]; + h264e_hal_rkv_frame *fref_nearest[2]; //Used for RC + struct { + /* Unused frames: 0 = fenc, 1 = fdec */ + h264e_hal_rkv_frame **unused; + + /* frames used for reference + sentinels */ + h264e_hal_rkv_frame *reference[RKV_H264E_REF_MAX + 1]; //TODO: remove later + + + RK_S32 i_last_keyframe; /* Frame number of the last keyframe */ + RK_S32 i_last_idr; /* Frame number of the last IDR (not RP)*/ + //RK_S64 i_largest_pts; + //RK_S64 i_second_largest_pts; + } frames; + + h264e_hal_rkv_frame frame_buf[RKV_H264E_REF_MAX + 1]; + + RK_S32 i_ref[2]; + RK_U32 i_nal_type; + RK_U32 i_nal_ref_idc; + + RK_S32 i_frame_cnt; /* Presentation frame number */ + RK_S32 i_frame_num; /* 7.4.3 frame_num */ + + //move from slice header below + RK_S32 i_slice_type; + RK_S32 i_idr_pic_id; /* -1 if nal_type != 5 */ + RK_S32 i_tmp_idr_pic_id; + //RK_S32 i_poc; + //RK_S32 i_delta_poc[2]; + //RK_S32 i_redundant_pic_cnt; + RK_S32 i_max_ref0; + RK_S32 i_max_ref1; + RK_S32 b_ref_pic_list_reordering[2]; + struct { + RK_S32 idc; + RK_S32 arg; + } ref_pic_list_order[2][RKV_H264E_REF_MAX]; + + RK_S32 i_mmco_remove_from_end; + RK_S32 i_mmco_command_count; + struct { /* struct for future expansion */ + RK_S32 i_difference_of_pic_nums; + RK_S32 i_poc; + RK_S32 memory_management_control_operation; + } mmco[RKV_H264E_REF_MAX]; + + RK_S32 i_long_term_reference_flag; +} h264e_hal_rkv_dpb_ctx; + +typedef struct h264e_hal_rkv_dbg_info_t { + struct { + RK_U32 lkt_num : 8; + RK_U32 rkvenc_cmd : 2; //MAY + RK_U32 reserve : 6; + RK_U32 enc_cke : 1; + RK_U32 Reserve : 15; + } swreg02; //ENC_STRT + + struct { + RK_U32 lkt_addr : 32; + } swreg04; //LKT_ADDR + struct { + RK_U32 ofe_fnsh : 1; + RK_U32 lkt_fnsh : 1; + RK_U32 clr_fnsh : 1; + RK_U32 ose_fnsh : 1; + RK_U32 bs_ovflr : 1; + RK_U32 brsp_ful : 1; + RK_U32 brsp_err : 1; + RK_U32 rrsp_err : 1; + RK_U32 tmt_err : 1; + RK_U32 reserve : 23; + } swreg05; //INT_EN + + struct { + RK_U32 enc_stnd : 1; + RK_U32 roi_enc : 1; + RK_U32 cur_frm_ref : 1; + RK_U32 mei_stor : 1; + RK_U32 bs_scp : 1; + RK_U32 reserve : 3; + RK_U32 pic_qp : 6; + RK_U32 reserve1 : 16; + RK_U32 slice_int : 1; + RK_U32 node_int : 1; + } swreg10; //ENC_PIC + + struct { + RK_U32 ppln_enc_lmt : 4; + RK_U32 reserve : 4; + RK_U32 rfp_load_thrd : 8; + RK_U32 reserve1 : 16; + } swreg11; //ENC_WDG + + struct { + RK_U32 src_bus_ordr : 1; + RK_U32 cmvw_bus_ordr : 1; + RK_U32 dspw_bus_ordr : 1; + RK_U32 rfpw_bus_ordr : 1; + RK_U32 src_bus_edin : 4; + RK_U32 meiw_bus_edin : 4; + RK_U32 bsw_bus_edin : 3; + RK_U32 lktr_bus_edin : 4; + RK_U32 ctur_bus_edin : 4; + RK_U32 lktw_bus_edin : 4; + RK_U32 rfp_map_dcol : 2; + RK_U32 rfp_map_sctr : 1; + RK_U32 reserve : 2; + } swreg12; //DTRNS_MAP + + struct { + RK_U32 axi_brsp_cke : 7; + RK_U32 cime_dspw_orsd : 1; + RK_U32 reserve : 24; + } swreg13; // DTRNS_CFG + + struct { + RK_U32 src_aswap : 1; + RK_U32 src_cswap : 1; + RK_U32 src_cfmt : 4; + RK_U32 src_clip_dis : 1; + RK_U32 reserve : 25; + } swreg14; //SRC_FMT + + struct { + RK_U32 wght_b2y : 9; + RK_U32 wght_g2y : 9; + RK_U32 wght_r2y : 9; + RK_U32 reserve : 5; + } swreg15; //SRC_UDFY + + struct { + RK_U32 wght_b2u : 9; + RK_U32 wght_g2u : 9; + RK_U32 wght_r2u : 9; + RK_U32 reserve : 5; + } swreg16; //SRC_UDFU + + struct { + RK_U32 wght_b2v : 9; + RK_U32 wght_g2v : 9; + RK_U32 wght_r2v : 9; + RK_U32 reserve : 5; + } swreg17; //SRC_UDFV + + + struct { + RK_U32 ofst_rgb2v : 8; + RK_U32 ofst_rgb2u : 8; + RK_U32 ofst_rgb2y : 5; + RK_U32 reserve : 11; + } swreg18; //SRC_UDFO + + struct { + RK_U32 src_tfltr : 1; + RK_U32 src_tfltr_we : 1; + RK_U32 src_tfltr_bw : 1; + RK_U32 src_sfltr : 1; + RK_U32 src_mfltr_thrd : 5; + RK_U32 src_mfltr_y : 1; + RK_U32 src_mfltr_c : 1; + RK_U32 src_bfltr_strg : 1; + RK_U32 src_bfltr : 1; + RK_U32 src_mbflt_odr : 1; + RK_U32 src_matf_y : 1; + RK_U32 src_matf_c : 1; + RK_U32 src_shp_y : 1; + RK_U32 src_shp_c : 1; + RK_U32 src_shp_div : 3; + RK_U32 src_shp_thld : 5; + RK_U32 src_mirr : 1; + RK_U32 src_rot : 2; + RK_U32 src_matf_itsy : 1; + RK_U32 reserve : 2; + } swreg19; // SRC_PROC + + struct { + RK_U32 tfltr_thld_y : 15; + RK_U32 reserve : 1; + RK_U32 tfltr_thld_c : 15; + RK_U32 reserve1 : 1; + } swreg20; // SRC_TTHLD + + RK_U32 swreg21_scr_stbl[5]; //4.22. H3D_TBL0~39 + RK_U32 swreg22_h3d_tbl[40]; //4.22. H3D_TBL0~39 + + struct { + RK_U32 src_ystrid : 14; + RK_U32 reserve : 2; + RK_U32 src_cstrid : 14; + RK_U32 reserve1 : 2; + } swreg23; //SRC_STRID + + struct { + RK_U32 adr_srcy; //swreg24 + RK_U32 adr_srcu; + RK_U32 adr_srcv; + RK_U32 fltw_addr; + RK_U32 fltr_addr; + RK_U32 ctuc_addr; + RK_U32 rfpw_addr; + RK_U32 rfpr_addr; + RK_U32 cmvw_addr; + RK_U32 cmvr_addr; + RK_U32 dspw_addr; + RK_U32 dspr_addr; + RK_U32 meiw_addr; + RK_U32 bsbt_addr; + RK_U32 bsbb_addr; + RK_U32 bsbr_addr; + RK_U32 bsbw_addr; + } addr_cfg; + + struct { + RK_U32 sli_cut : 1; + RK_U32 sli_cut_mode : 1; + RK_U32 sli_cut_bmod : 1; + RK_U32 sli_max_num : 10; + RK_U32 sli_out_mode : 1; + RK_U32 reserve : 2; + RK_U32 sli_cut_cnum : 16; + } swreg41; // SLI_SPL + + struct { + RK_U32 sli_cut_byte : 18; + RK_U32 reserve : 14; + } swreg42; // SLI_SPL_BYTE + + struct { + RK_U32 cime_srch_h : 4; + RK_U32 cime_srch_v : 4; + RK_U32 rime_srch_h : 3; + RK_U32 rime_srch_v : 3; + RK_U32 reserved : 2; + RK_U32 dlt_frm_num : 16; + } swreg43; //ME_RNGE + + struct { + RK_U32 pmv_mdst_h : 8; + RK_U32 pmv_mdst_v : 8; + RK_U32 mv_limit : 2; + RK_U32 mv_num : 2; + RK_U32 reserve : 12; + } swreg44; // ME_CNST + + struct { + RK_U32 cime_rama_max : 11; + RK_U32 cime_rama_h : 5; + RK_U32 cach_l2_tag : 2; + RK_U32 cach_l1_dtmr : 5; + RK_U32 reserve : 9; + } swreg45; //ME_RAM + + struct { + RK_U32 rc_en : 1; + RK_U32 rc_mode : 1; + RK_U32 aqmode_en : 1; + RK_U32 aq_strg : 10; + RK_U32 Reserved : 3; + RK_U32 rc_ctu_num : 16; + } swreg46; //RC_CFG + + struct { + RK_U32 bits_error0 : 16; + RK_U32 bits_error1 : 16; + } swreg47; //RC_ERP0 //TODO: merge with reg 48~51, in arrays bit_error[5] + + struct { + RK_U32 bits_error2 : 16; + RK_U32 bits_error3 : 16; + } swreg48; //RC_ERP1 + + struct { + RK_U32 bits_error4 : 16; + RK_U32 bits_error5 : 16; + } swreg49; //RC_ERP2 + + struct { + RK_U32 bits_error6 : 16; + RK_U32 bits_error7 : 16; + } swreg50; //RC_ERP3 + + struct { + RK_U32 bits_error8 : 16; + RK_U32 reserve : 16; + } swreg51; //RC_ERP4 + + struct { + RK_U32 qp_adjuest0 : 5; + RK_U32 qp_adjuest1 : 5; + RK_U32 qp_adjuest2 : 5; + RK_U32 qp_adjuest3 : 5; + RK_U32 qp_adjuest4 : 5; + RK_U32 qp_adjuest5 : 5; + RK_U32 reserve : 2; + } swreg52; // RC_ADJ0 + + struct { + RK_U32 qp_adjuest6 : 5; + RK_U32 qp_adjuest7 : 5; + RK_U32 qp_adjuest8 : 5; + RK_U32 reserve : 17; + } swreg53; // RC_ADJ1 + + struct { + RK_U32 rc_qp_mod : 2; + RK_U32 rc_fact0 : 6; + RK_U32 rc_fact1 : 6; + RK_U32 Reserved : 2; + RK_U32 rc_qp_range : 4; + RK_U32 rc_max_qp : 6; + RK_U32 rc_min_qp : 6; + } swreg54; //RC_QP + + struct { + RK_U32 ctu_ebits : 20; + RK_U32 reserve : 12; + } swreg55; //RC_TGT + + struct { + RK_U32 rect_size : 1; + RK_U32 inter_4x4 : 1; + RK_U32 arb_sel : 1; + RK_U32 vlc_lmt : 1; + RK_U32 reserve : 1; + RK_U32 rdo_mark : 8; + RK_U32 reserve1 : 19; + } swreg56; //RDO_CFG + + struct { + RK_U32 nal_ref_idc : 2; + RK_U32 nal_unit_type : 5; + RK_U32 reserve : 25; + } swreg57; // SYNT_NAL + + struct { + RK_U32 max_fnum : 4; + RK_U32 drct_8x8 : 1; + RK_U32 mpoc_lm4 : 4; + RK_U32 reserve : 23; + } swreg58; // SYNT_SPS + + struct { + RK_U32 etpy_mode : 1; + RK_U32 trns_8x8 : 1; + RK_U32 csip_flg : 1; + RK_U32 num_ref0_idx : 2; + RK_U32 num_ref1_idx : 2; + RK_U32 pic_init_qp : 6; + int cb_ofst : 5; + int cr_ofst : 5; + RK_U32 wght_pred : 1; + RK_U32 dbf_cp_flg : 1; + RK_U32 reserve : 7; + } swreg59; // SYNT_PPS + + struct { + RK_U32 sli_type : 2; + RK_U32 pps_id : 8; + RK_U32 drct_smvp : 1; + RK_U32 num_ref_ovrd : 1; + RK_U32 cbc_init_idc : 2; + RK_U32 reserve : 2; + RK_U32 frm_num : 16; + } swreg60; // SYNT_SLI0 + + struct { + RK_U32 idr_pid : 16; + RK_U32 poc_lsb : 16; + } swreg61; // SYNT_SLI1 + + struct { + RK_U32 rodr_pic_idx : 2; + RK_U32 ref_list0_rodr : 1; + RK_S32 sli_beta_ofst : 4; + RK_S32 sli_alph_ofst : 4; + RK_U32 dis_dblk_idc : 2; + RK_U32 reserve : 3; + RK_U32 rodr_pic_num : 16; + } swreg62; // SYNT_SLI2_RODR + + struct { + RK_U32 nopp_flg : 1; + RK_U32 ltrf_flg : 1; + RK_U32 arpm_flg : 1; + RK_U32 mmco4_pre : 1; + RK_U32 mmco_0 : 3; + RK_U32 dopn_m1_0 : 16; + RK_U32 reserve : 9; + } swreg63; // SYNT_REF_MARK0 + + struct { + RK_U32 mmco_1 : 3; + RK_U32 dopn_m1_1 : 16; + RK_U32 reserve : 13; + } swreg64; // SYNT_REF_MARK1 + + struct { + RK_U32 osd_en : 8; + RK_U32 osd_inv : 8; + RK_U32 osd_clk_sel : 1; + RK_U32 osd_plt_type : 1; + RK_U32 reserve : 14; + } swreg65; //OSD_CFG + + struct { + RK_U32 osd_inv_r0 : 4; + RK_U32 osd_inv_r1 : 4; + RK_U32 osd_inv_r2 : 4; + RK_U32 osd_inv_r3 : 4; + RK_U32 osd_inv_r4 : 4; + RK_U32 osd_inv_r5 : 4; + RK_U32 osd_inv_r6 : 4; + RK_U32 osd_inv_r7 : 4; + } swreg66; //OSD_INV + + h264e_osd_pos swreg67_osd_pos[8]; + + RK_U32 swreg68_indx_addr_i[8]; //4.68. OSD_ADDR0-7 + + struct { + RK_U32 bs_lgth : 32; + } swreg69; //ST_BSL + + struct { + RK_U32 sse_l32 : 32; + } swreg70; // ST_SSE_L32 + + struct { + RK_U32 qp_sum : 22; + RK_U32 reserve : 2; + RK_U32 sse_h8 : 8; + } swreg71; // ST_SSE_QP + + struct { + RK_U32 slice_scnum : 12; + RK_U32 slice_slnum : 12; + RK_U32 reserve : 8; + } swreg72; //ST_SAO + + RK_U32 swreg73_osd_indx_tab_i[256]; //4.73. OSD_PLT0~255 + + struct { + RK_U32 st_enc : 2; + RK_U32 axiw_cln : 2; + RK_U32 axir_cln : 2; + RK_U32 reserve : 26; + } swreg74; // ST_ENC + + struct { + RK_U32 fnum_enc : 8; + RK_U32 fnum_cfg : 8; + RK_U32 fnum_int : 8; + RK_U32 reserve : 8; + } swreg75; // ST_LKT + + struct { + RK_U32 node_addr : 32; + } swreg76; //ST_NOD + + struct { + RK_U32 Bsbw_ovfl : 1; + RK_U32 reserve : 2; + RK_U32 bsbw_addr : 29; + } swreg77; //ST_BSB + +#if 0 + struct { + RK_U32 axib_idl : 7; + RK_U32 axib_ful : 7; + RK_U32 axib_err : 7; + RK_U32 axir_err : 6; + RK_U32 reserve : 5; + } swreg78; //ST_DTRNS + + struct { + RK_U32 slice_num : 6; + RK_U32 reserve : 26; + } swreg79; //ST_SNUM + + struct { + RK_U32 slice_len : 23; + RK_U32 reserve : 9; + } swreg80; //ST_SLEN + + struct { + RK_U32 axip0_work : 1; + RK_U32 axip0_clr : 1; + RK_U32 axip0_frm : 1; + RK_U32 reserve : 29; + } swreg81; // AXIP0_CMD + + struct { + RK_U32 axip0_ltcy_id : 4; + RK_U32 axip0_ltcy_thr : 12; + RK_U32 reserve : 16; + } swreg82; // AXIP0_LTCY + + struct { + RK_U32 axip0_cnt_type : 1; + RK_U32 axip0_cnt_ddr : 2; + RK_U32 axip0_cnt_rid : 5; + RK_U32 axip0_cnt_wid : 5; + RK_U32 reserve : 19; + } swreg83; // AXIP0_CNT + + struct { + RK_U32 axip1_work : 1; + RK_U32 axip1_clr : 1; + RK_U32 reserve : 30; + } swreg84; // AXIP1_CMD + + struct { + RK_U32 axip1_ltcy_id : 4; + RK_U32 axip1_ltcy_thr : 12; + RK_U32 reserve : 16; + } swreg85; // AXIP1_LTCY + + struct { + RK_U32 axip1_cnt_type : 1; + RK_U32 axip1_cnt_ddr : 2; + RK_U32 axip1_cnt_rid : 5; + RK_U32 axip1_cnt_wid : 5; + RK_U32 reserve : 19; + } swreg86; // AXIP1_CNT + + struct { + RK_U32 axip0_cnt_type : 16; + RK_U32 reserve : 16; + } swreg87; // ST_AXIP0_MAXL + + + struct { + RK_U32 axip0_num_ltcy : 32; + } swreg88; // ST_AXIP0_NUML + + struct { + RK_U32 axip0_sum_ltcy : 32; + } swreg89; // ST_AXIP0_SUML + + struct { + RK_U32 axip0_byte_rd : 32; + } swreg90; // ST_AXIP0_RDB + + struct { + RK_U32 axip0_byte_wr : 32; + } swreg91; // ST_AXIP0_WRB + + struct { + RK_U32 axip0_wrk_cyc : 32; + } swreg92; //ST_AXIP0_CYCL + + struct { + RK_U32 axip1_cnt_type : 16; + RK_U32 reserve : 16; + } swreg93; // ST_AXIP1_MAXL + + struct { + RK_U32 axip1_num_ltcy : 32; + } swreg94; // ST_AXIP1_NUML + + struct { + RK_U32 axip1_sum_ltcy : 32; + } swreg95; // ST_AXIP1_SUML + + struct { + RK_U32 axip1_byte_rd : 32; + } swreg96; // ST_AXIP1_RDB + + struct { + RK_U32 axip1_byte_wr : 32; + } swreg97; // ST_AXIP1_WRB + + struct { + RK_U32 axip1_wrk_cyc : 32; + } swreg98; // ST_AXIP1_CYCL +#endif //#if 0 +} h264e_hal_rkv_dbg_info; + + +/* cmodel version r2893 */ + +typedef struct h264e_osd_cfg_t { + RK_U32 lt_pos_x : 8; + RK_U32 lt_pos_y : 8; + RK_U32 rd_pos_x : 8; + RK_U32 rd_pos_y : 8; +} h264e_osd_cfg; //OSD_POS0-7 + +typedef struct h264e_rkv_reg_set_t { + + struct { + RK_U32 rkvenc_ver : 32; //default : 0x0000_0001 + } swreg01; //VERSION + + struct { + RK_U32 lkt_num : 8; + RK_U32 rkvenc_cmd : 2; + RK_U32 reserve : 6; + RK_U32 enc_cke : 1; + RK_U32 Reserve : 15; + } swreg02; //ENC_STRT + + struct { + RK_U32 safe_clr : 1; + RK_U32 reserve : 31; + } swreg03; //ENC_CLR + + struct { + RK_U32 lkt_addr : 32; + } swreg04; //LKT_ADDR + + struct { + RK_U32 ofe_fnsh : 1; + RK_U32 lkt_fnsh : 1; + RK_U32 clr_fnsh : 1; + RK_U32 ose_fnsh : 1; + RK_U32 bs_ovflr : 1; + RK_U32 brsp_ful : 1; + RK_U32 brsp_err : 1; + RK_U32 rrsp_err : 1; + RK_U32 tmt_err : 1; + RK_U32 reserve : 23; + } swreg05; //INT_EN + + struct { + RK_U32 reserve : 32; + } swreg06; //4.5. INT_MSK + + struct { + RK_U32 clr_ofe_fnsh : 1; + RK_U32 clr_lkt_fnsh : 1; + RK_U32 clr_clr_fnsh : 1; + RK_U32 clr_ose_fnsh : 1; + RK_U32 clr_bs_ovflr : 1; + RK_U32 clr_brsp_ful : 1; + RK_U32 clr_brsp_err : 1; + RK_U32 clr_rrsp_err : 1; + RK_U32 clr_tmt_err : 1; + RK_U32 reserve : 23; + } swreg07; //4.6. INT_CLR + + struct { + RK_U32 reserve : 32; + } swreg08; //4.7. INT_STUS + +#if RKV_H264E_ADD_RESERVE_REGS + RK_U32 reserve_08_09[4]; +#endif + + struct { + RK_U32 pic_wd8_m1 : 9; + RK_U32 reserve0 : 1; + RK_U32 pic_wfill : 6; + RK_U32 pic_hd8_m1 : 9; + RK_U32 reserve1 : 1; + RK_U32 pic_hfill : 6; + } swreg09; // ENC_RSL + + + struct { + RK_U32 enc_stnd : 1; + RK_U32 roi_enc : 1; + RK_U32 cur_frm_ref : 1; + RK_U32 mei_stor : 1; + RK_U32 bs_scp : 1; + RK_U32 reserve : 3; + RK_U32 pic_qp : 6; + RK_U32 reserve1 : 16; + RK_U32 slice_int : 1; + RK_U32 node_int : 1; + } swreg10; //ENC_PIC + + struct { + RK_U32 ppln_enc_lmt : 4; + RK_U32 reserve : 4; + RK_U32 rfp_load_thrd : 8; + RK_U32 reserve1 : 16; + } swreg11; //ENC_WDG + + struct { + RK_U32 src_bus_ordr : 1; + RK_U32 cmvw_bus_ordr : 1; + RK_U32 dspw_bus_ordr : 1; + RK_U32 rfpw_bus_ordr : 1; + RK_U32 src_bus_edin : 4; + RK_U32 meiw_bus_edin : 4; + RK_U32 bsw_bus_edin : 3; + RK_U32 lktr_bus_edin : 4; + RK_U32 ctur_bus_edin : 4; + RK_U32 lktw_bus_edin : 4; + RK_U32 rfp_map_dcol : 2; + RK_U32 rfp_map_sctr : 1; + RK_U32 reserve : 2; + } swreg12; //DTRNS_MAP + + struct { + RK_U32 axi_brsp_cke : 7; + RK_U32 cime_dspw_orsd : 1; + RK_U32 reserve : 24; + } swreg13; // DTRNS_CFG + + struct { + RK_U32 src_aswap : 1; + RK_U32 src_cswap : 1; + RK_U32 src_cfmt : 4; + RK_U32 src_clip_dis : 1; + RK_U32 reserve : 25; + } swreg14; //SRC_FMT + + struct { + RK_U32 wght_b2y : 9; + RK_U32 wght_g2y : 9; + RK_U32 wght_r2y : 9; + RK_U32 reserve : 5; + } swreg15; //SRC_UDFY + + struct { + RK_U32 wght_b2u : 9; + RK_U32 wght_g2u : 9; + RK_U32 wght_r2u : 9; + RK_U32 reserve : 5; + } swreg16; //SRC_UDFU + + struct { + RK_U32 wght_b2v : 9; + RK_U32 wght_g2v : 9; + RK_U32 wght_r2v : 9; + RK_U32 reserve : 5; + } swreg17; //SRC_UDFV + + struct { + RK_U32 ofst_rgb2v : 8; + RK_U32 ofst_rgb2u : 8; + RK_U32 ofst_rgb2y : 5; + RK_U32 reserve : 11; + } swreg18; //SRC_UDFO + + struct { + RK_U32 src_tfltr : 1; + RK_U32 src_tfltr_we : 1; + RK_U32 src_tfltr_bw : 1; + RK_U32 src_sfltr : 1; + RK_U32 src_mfltr_thrd : 5; + RK_U32 src_mfltr_y : 1; + RK_U32 src_mfltr_c : 1; + RK_U32 src_bfltr_strg : 1; + RK_U32 src_bfltr : 1; + RK_U32 src_mbflt_odr : 1; + RK_U32 src_matf_y : 1; + RK_U32 src_matf_c : 1; + RK_U32 src_shp_y : 1; + RK_U32 src_shp_c : 1; + RK_U32 src_shp_div : 3; + RK_U32 src_shp_thld : 5; + RK_U32 src_mirr : 1; + RK_U32 src_rot : 2; + RK_U32 src_matf_itsy : 1; + RK_U32 reserve : 2; + } swreg19; // SRC_PROC + + struct { + RK_U32 tfltr_thld_y : 15; + RK_U32 reserve : 1; + RK_U32 tfltr_thld_c : 15; + RK_U32 reserve1 : 1; + } swreg20; // SRC_TTHLD + + RK_U32 swreg21_scr_stbl[5]; //4.22. H3D_TBL0~39 + + RK_U32 swreg22_h3d_tbl[40]; //4.22. H3D_TBL0~39 + + struct { + RK_U32 src_ystrid : 14; + RK_U32 reserve : 2; + RK_U32 src_cstrid : 14; + RK_U32 reserve1 : 2; + } swreg23; //SRC_STRID + + RK_U32 swreg24_adr_srcy; //swreg24 + RK_U32 swreg25_adr_srcu; //swreg25 + RK_U32 swreg26_adr_srcv; //swreg26 + RK_U32 swreg27_fltw_addr; //swreg27 + RK_U32 swreg28_fltr_addr; //swreg28 + RK_U32 swreg29_ctuc_addr; //swreg29 + RK_U32 swreg30_rfpw_addr; //swreg30 + RK_U32 swreg31_rfpr_addr; //swreg31 + RK_U32 swreg32_cmvw_addr; //swreg32 + RK_U32 swreg33_cmvr_addr; //swreg33 + RK_U32 swreg34_dspw_addr; //swreg34 + RK_U32 swreg35_dspr_addr; //swreg35 + RK_U32 swreg36_meiw_addr; //swreg36 + RK_U32 swreg37_bsbt_addr; //swreg37 + RK_U32 swreg38_bsbb_addr; //swreg38 + RK_U32 swreg39_bsbr_addr; //swreg39 + RK_U32 swreg40_bsbw_addr; //swreg40 + + struct { + RK_U32 sli_cut : 1; + RK_U32 sli_cut_mode : 1; + RK_U32 sli_cut_bmod : 1; + RK_U32 sli_max_num : 10; + RK_U32 sli_out_mode : 1; + RK_U32 reserve : 2; + RK_U32 sli_cut_cnum : 16; + } swreg41; // SLI_SPL + + struct { + RK_U32 sli_cut_byte : 18; + RK_U32 reserve : 14; + } swreg42; // SLI_SPL_BYTE + + struct { + RK_U32 cime_srch_h : 4; + RK_U32 cime_srch_v : 4; + RK_U32 rime_srch_h : 3; + RK_U32 rime_srch_v : 3; + RK_U32 reserved : 2; + RK_U32 dlt_frm_num : 16; + } swreg43; //ME_RNGE + + + struct { + RK_U32 pmv_mdst_h : 8; + RK_U32 pmv_mdst_v : 8; + RK_U32 mv_limit : 2; + RK_U32 mv_num : 2; + RK_U32 reserve : 12; + } swreg44; // ME_CNST + + struct { + RK_U32 cime_rama_max : 11; + RK_U32 cime_rama_h : 5; + RK_U32 cach_l2_tag : 2; + RK_U32 cach_l1_dtmr : 5; + RK_U32 reserve : 9; + } swreg45; //ME_RAM + + struct { + RK_U32 rc_en : 1; + RK_U32 rc_mode : 1; + RK_U32 aqmode_en : 1; + RK_U32 aq_strg : 10; + RK_U32 Reserved : 3; + RK_U32 rc_ctu_num : 16; + } swreg46; //RC_CFG + + struct { + RK_U32 bits_error0 : 16; + RK_U32 bits_error1 : 16; + } swreg47; //RC_ERP0 + + struct { + RK_U32 bits_error2 : 16; + RK_U32 bits_error3 : 16; + } swreg48; //RC_ERP1 + + struct { + RK_U32 bits_error4 : 16; + RK_U32 bits_error5 : 16; + } swreg49; //RC_ERP2 + + struct { + RK_U32 bits_error6 : 16; + RK_U32 bits_error7 : 16; + } swreg50; //RC_ERP3 + + struct { + RK_U32 bits_error8 : 16; + RK_U32 reserve : 16; + } swreg51; //RC_ERP4 + + struct { + RK_U32 qp_adjuest0 : 5; + RK_U32 qp_adjuest1 : 5; + RK_U32 qp_adjuest2 : 5; + RK_U32 qp_adjuest3 : 5; + RK_U32 qp_adjuest4 : 5; + RK_U32 qp_adjuest5 : 5; + RK_U32 reserve : 2; + } swreg52; // RC_ADJ0 + + struct { + RK_U32 qp_adjuest6 : 5; + RK_U32 qp_adjuest7 : 5; + RK_U32 qp_adjuest8 : 5; + RK_U32 reserve : 17; + } swreg53; // RC_ADJ1 + + struct { + RK_U32 rc_qp_mod : 2; + RK_U32 rc_fact0 : 6; + RK_U32 rc_fact1 : 6; + RK_U32 Reserved : 2; + RK_U32 rc_qp_range : 4; + RK_U32 rc_max_qp : 6; + RK_U32 rc_min_qp : 6; + } swreg54; //RC_QP + + struct { + RK_U32 ctu_ebits : 20; + RK_U32 reserve : 12; + } swreg55; //RC_TGT + + + struct { + RK_U32 rect_size : 1; + RK_U32 inter_4x4 : 1; + RK_U32 arb_sel : 1; + RK_U32 vlc_lmt : 1; + RK_U32 reserve : 1; + RK_U32 rdo_mark : 8; + RK_U32 reserve1 : 19; + } swreg56; //RDO_CFG + + struct { + RK_U32 nal_ref_idc : 2; + RK_U32 nal_unit_type : 5; + RK_U32 reserve : 25; + } swreg57; // SYNT_NAL + + struct { + RK_U32 max_fnum : 4; + RK_U32 drct_8x8 : 1; + RK_U32 mpoc_lm4 : 4; + RK_U32 reserve : 23; + } swreg58; // SYNT_SPS + + struct { + RK_U32 etpy_mode : 1; + RK_U32 trns_8x8 : 1; + RK_U32 csip_flg : 1; + RK_U32 num_ref0_idx : 2; + RK_U32 num_ref1_idx : 2; + RK_U32 pic_init_qp : 6; + RK_S32 cb_ofst : 5; + RK_S32 cr_ofst : 5; + RK_U32 wght_pred : 1; + RK_U32 dbf_cp_flg : 1; + RK_U32 reserve : 7; + } swreg59; // SYNT_PPS + + struct { + RK_U32 sli_type : 2; + RK_U32 pps_id : 8; + RK_U32 drct_smvp : 1; + RK_U32 num_ref_ovrd : 1; + RK_U32 cbc_init_idc : 2; + RK_U32 reserve : 2; + RK_U32 frm_num : 16; + } swreg60; // SYNT_SLI0 + + struct { + RK_U32 idr_pid : 16; + RK_U32 poc_lsb : 16; + } swreg61; // SYNT_SLI1 + + struct { + RK_U32 rodr_pic_idx : 2; + RK_U32 ref_list0_rodr : 1; + RK_S32 sli_beta_ofst : 4; + RK_S32 sli_alph_ofst : 4; + RK_U32 dis_dblk_idc : 2; + RK_U32 reserve : 3; + RK_U32 rodr_pic_num : 16; + } swreg62; // SYNT_SLI2_RODR + + struct { + RK_U32 nopp_flg : 1; + RK_U32 ltrf_flg : 1; + RK_U32 arpm_flg : 1; + RK_U32 mmco4_pre : 1; + RK_U32 mmco_0 : 3; + RK_U32 dopn_m1_0 : 16; + RK_U32 reserve : 9; + } swreg63; // SYNT_REF_MARK0 + + struct { + RK_U32 mmco_1 : 3; + RK_U32 dopn_m1_1 : 16; + RK_U32 reserve : 13; + } swreg64; // SYNT_REF_MARK1 + +#if RKV_H264E_ADD_RESERVE_REGS + RK_U32 reserve_64_65[1]; +#endif + struct { + RK_U32 osd_en : 8; + RK_U32 osd_inv : 8; + RK_U32 osd_clk_sel : 1; + RK_U32 osd_plt_type : 1; + RK_U32 reserve : 14; + } swreg65; //OSD_CFG + + struct { + RK_U32 osd_inv_r0 : 4; + RK_U32 osd_inv_r1 : 4; + RK_U32 osd_inv_r2 : 4; + RK_U32 osd_inv_r3 : 4; + RK_U32 osd_inv_r4 : 4; + RK_U32 osd_inv_r5 : 4; + RK_U32 osd_inv_r6 : 4; + RK_U32 osd_inv_r7 : 4; + } swreg66; //OSD_INV + +#if RKV_H264E_ADD_RESERVE_REGS + RK_U32 reserve_66_67[2]; +#endif + + h264e_osd_cfg swreg67_osd_pos[8]; + + RK_U32 swreg68_indx_addr_i[8]; //4.68. OSD_ADDR0-7 + + struct { + RK_U32 bs_lgth : 32; + } swreg69; //ST_BSL + + struct { + RK_U32 sse_l32 : 32; + } swreg70; // ST_SSE_L32 + + struct { + RK_U32 qp_sum : 22; + RK_U32 reserve : 2; + RK_U32 sse_h8 : 8; + } swreg71; // ST_SSE_QP + + struct { + RK_U32 slice_scnum : 12; + RK_U32 slice_slnum : 12; + RK_U32 reserve : 8; + } swreg72; //ST_SAO + + + struct { + RK_U32 st_enc : 2; + RK_U32 axiw_cln : 2; + RK_U32 axir_cln : 2; + RK_U32 reserve : 26; + } swreg73; // ST_ENC + + struct { + RK_U32 fnum_enc : 8; + RK_U32 fnum_cfg : 8; + RK_U32 fnum_int : 8; + RK_U32 reserve : 8; + } swreg74; // ST_LKT + + struct { + RK_U32 node_addr : 32; + } swreg75; //ST_NOD + + struct { + RK_U32 Bsbw_ovfl : 1; + RK_U32 reserve : 2; + RK_U32 bsbw_addr : 29; + } swreg76; //ST_BSB + +#if !RKV_H264E_REMOVE_UNNECESSARY_REGS + + struct { + RK_U32 axib_idl : 7; + RK_U32 axib_ful : 7; + RK_U32 axib_err : 7; + RK_U32 axir_err : 6; + RK_U32 reserve : 5; + } swreg77; //ST_DTRNS + + struct { + RK_U32 slice_num : 6; + RK_U32 reserve : 26; + } swreg78; //ST_SNUM + + struct { + RK_U32 slice_len : 23; + RK_U32 reserve : 9; + } swreg79; //ST_SLEN + +#if RKV_H264E_ADD_RESERVE_REGS + RK_U32 reserve_79_80[113]; +#endif + + RK_U32 swreg80_osd_indx_tab_i[256]; //4.73. OSD_PLT0~255 + + struct { + RK_U32 axip0_work : 1; + RK_U32 axip0_clr : 1; + RK_U32 axip0_frm : 1; + RK_U32 reserve : 29; + } swreg81; // AXIP0_CMD + + struct { + RK_U32 axip0_ltcy_id : 4; + RK_U32 axip0_ltcy_thr : 12; + RK_U32 reserve : 16; + } swreg82; // AXIP0_LTCY + + struct { + RK_U32 axip0_cnt_type : 1; + RK_U32 axip0_cnt_ddr : 2; + RK_U32 axip0_cnt_rid : 5; + RK_U32 axip0_cnt_wid : 5; + RK_U32 reserve : 19; + } swreg83; // AXIP0_CNT + +#if RKV_H264E_ADD_RESERVE_REGS + RK_U32 reserve_83_84[1]; +#endif + + struct { + RK_U32 axip1_work : 1; + RK_U32 axip1_clr : 1; + RK_U32 reserve : 30; + } swreg84; // AXIP1_CMD + + struct { + RK_U32 axip1_ltcy_id : 4; + RK_U32 axip1_ltcy_thr : 12; + RK_U32 reserve : 16; + } swreg85; // AXIP1_LTCY + + struct { + RK_U32 axip1_cnt_type : 1; + RK_U32 axip1_cnt_ddr : 2; + RK_U32 axip1_cnt_rid : 5; + RK_U32 axip1_cnt_wid : 5; + RK_U32 reserve : 19; + } swreg86; // AXIP1_CNT + +#if RKV_H264E_ADD_RESERVE_REGS + RK_U32 reserve_86_87[1]; +#endif + + struct { + RK_U32 axip0_cnt_type : 16; + RK_U32 reserve : 16; + } swreg87; // ST_AXIP0_MAXL + + + struct { + RK_U32 axip0_num_ltcy : 32; + } swreg88; // ST_AXIP0_NUML + + struct { + RK_U32 axip0_sum_ltcy : 32; + } swreg89; // ST_AXIP0_SUML + + struct { + RK_U32 axip0_byte_rd : 32; + } swreg90; // ST_AXIP0_RDB + + struct { + RK_U32 axip0_byte_wr : 32; + } swreg91; // ST_AXIP0_WRB + + struct { + RK_U32 axip0_wrk_cyc : 32; + } swreg92; //ST_AXIP0_CYCL + +#if RKV_H264E_ADD_RESERVE_REGS + RK_U32 reserve_92_93[2]; +#endif + + struct { + RK_U32 axip1_cnt_type : 16; + RK_U32 reserve : 16; + } swreg93; // ST_AXIP1_MAXL + + struct { + RK_U32 axip1_num_ltcy : 32; + } swreg94; // ST_AXIP1_NUML + + struct { + RK_U32 axip1_sum_ltcy : 32; + } swreg95; // ST_AXIP1_SUML + + struct { + RK_U32 axip1_byte_rd : 32; + } swreg96; // ST_AXIP1_RDB + + struct { + RK_U32 axip1_byte_wr : 32; + } swreg97; // ST_AXIP1_WRB + + struct { + RK_U32 axip1_wrk_cyc : 32; + } swreg98; // ST_AXIP1_CYCL + +#endif //#if !RKV_H264E_REMOVE_UNNECESSARY_REGS +} h264e_rkv_reg_set; + +typedef struct h264e_rkv_ioctl_extra_info_elem_t { + RK_U32 reg_idx; + RK_U32 offset; +} h264e_rkv_ioctl_extra_info_elem; + +typedef struct h264e_rkv_ioctl_extra_info_t { + RK_U32 magic; + RK_U32 cnt; + h264e_rkv_ioctl_extra_info_elem elem[20]; +} h264e_rkv_ioctl_extra_info; + +typedef struct h264e_rkv_ioctl_reg_info_t { + RK_U32 reg_num; + h264e_rkv_reg_set regs; + h264e_rkv_ioctl_extra_info extra_info; +} h264e_rkv_ioctl_reg_info; + +/* +enc_mode + 0: N/A + 1: one frame encode by register configuration + 2: multi-frame encode start with link table + 3: multi_frame_encode link table update +*/ +typedef struct h264e_rkv_ioctl_input_t { + RK_U32 enc_mode; + RK_U32 frame_num; + + h264e_rkv_ioctl_reg_info reg_info[RKV_H264E_LINKTABLE_MAX_SIZE]; +} h264e_rkv_ioctl_input; + + +typedef struct h264e_rkv_ioctl_output_elem_t { + RK_U32 hw_status; + + struct { + RK_U32 bs_lgth : 32; + } swreg69; //ST_BSL + + struct { + RK_U32 sse_l32 : 32; + } swreg70; // ST_SSE_L32 + + struct { + RK_U32 qp_sum : 22; + RK_U32 reserve : 2; + RK_U32 sse_h8 : 8; + } swreg71; // ST_SSE_QP + + struct { + RK_U32 slice_scnum : 12; + RK_U32 slice_slnum : 12; + RK_U32 reserve : 8; + } swreg72; //ST_SAO + + + struct { + RK_U32 st_enc : 2; + RK_U32 axiw_cln : 2; + RK_U32 axir_cln : 2; + RK_U32 reserve : 26; + } swreg73; // ST_ENC + + struct { + RK_U32 fnum_enc : 8; + RK_U32 fnum_cfg : 8; + RK_U32 fnum_int : 8; + RK_U32 reserve : 8; + } swreg74; // ST_LKT + + struct { + RK_U32 node_addr : 32; + } swreg75; //ST_NOD + + struct { + RK_U32 Bsbw_ovfl : 1; + RK_U32 reserve : 2; + RK_U32 bsbw_addr : 29; + } swreg76; //ST_BSB + + struct { + RK_U32 axib_idl : 7; + RK_U32 axib_ful : 7; + RK_U32 axib_err : 7; + RK_U32 axir_err : 6; + RK_U32 reserve : 5; + } swreg77; //ST_DTRNS + + struct { + RK_U32 slice_num : 6; + RK_U32 reserve : 26; + } swreg78; //ST_SNUM + + struct { + RK_U32 slice_len : 23; + RK_U32 reserve : 9; + } swreg79; //ST_SLEN +} h264e_rkv_ioctl_output_elem; + +typedef struct h264e_rkv_ioctl_output_t { + RK_U32 frame_num; + h264e_rkv_ioctl_output_elem elem[RKV_H264E_LINKTABLE_MAX_SIZE]; +} h264e_rkv_ioctl_output; + + +#define RK_H264E_NUM_REGS ((RK_S32)(sizeof(h264e_rkv_reg_set)/4)) + +MPP_RET hal_h264e_rkv_init (void *hal, MppHalCfg *cfg); +MPP_RET hal_h264e_rkv_deinit (void *hal); +MPP_RET hal_h264e_rkv_gen_regs(void *hal, HalTaskInfo *task); +MPP_RET hal_h264e_rkv_start (void *hal, HalTaskInfo *task); +MPP_RET hal_h264e_rkv_wait (void *hal, HalTaskInfo *task); +MPP_RET hal_h264e_rkv_reset (void *hal); +MPP_RET hal_h264e_rkv_flush (void *hal); +MPP_RET hal_h264e_rkv_control (void *hal, RK_S32 cmd_type, void *param); + +#endif diff --git a/mpp/hal/rkenc/h264e/hal_h264e_vpu.c b/mpp/hal/rkenc/h264e/hal_h264e_vpu.c index 57f3c43e..611a5944 100644 --- a/mpp/hal/rkenc/h264e/hal_h264e_vpu.c +++ b/mpp/hal/rkenc/h264e/hal_h264e_vpu.c @@ -1,2257 +1,2257 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define MODULE_TAG "hal_h264e_vpu" -#include -#include "vpu.h" -#include "rk_mpi.h" -#include "mpp_mem.h" -#include "mpp_frame.h" -#include "hal_h264e.h" -#include "hal_h264e_vpu.h" - - -/* H.264 motion estimation parameters */ -static const RK_U32 h264_prev_mode_favor[52] = { - 7, 7, 8, 8, 9, 9, 10, 10, 11, 12, 12, 13, 14, 15, 16, 17, 18, - 19, 20, 21, 22, 24, 25, 27, 29, 30, 32, 34, 36, 38, 41, 43, 46, - 49, 51, 55, 58, 61, 65, 69, 73, 78, 82, 87, 93, 98, 104, 110, - 117, 124, 132, 140 -}; - -/* sqrt(2^((qp-12)/3))*8 */ -static const RK_U32 h264_diff_mv_penalty[52] = { - 2, 2, 3, 3, 3, 4, 4, 4, 5, 6, - 6, 7, 8, 9, 10, 11, 13, 14, 16, 18, - 20, 23, 26, 29, 32, 36, 40, 45, 51, 57, - 64, 72, 81, 91, 102, 114, 128, 144, 161, 181, - 203, 228, 256, 287, 323, 362, 406, 456, 512, 575, - 645, 724 -}; - -/* 31*sqrt(2^((qp-12)/3))/4 */ -static const RK_U32 h264_diff_mv_penalty4p[52] = { - 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, - 6, 7, 8, 9, 10, 11, 12, 14, 16, 17, - 20, 22, 25, 28, 31, 35, 39, 44, 49, 55, - 62, 70, 78, 88, 98, 110, 124, 139, 156, 175, - 197, 221, 248, 278, 312, 351, 394, 442, 496, 557, - 625, 701 -}; - -static const RK_U32 h264_intra16_favor[52] = { - 24, 24, 24, 26, 27, 30, 32, 35, 39, 43, 48, 53, 58, 64, 71, 78, - 85, 93, 102, 111, 121, 131, 142, 154, 167, 180, 195, 211, 229, - 248, 271, 296, 326, 361, 404, 457, 523, 607, 714, 852, 1034, - 1272, 1588, 2008, 2568, 3318, 4323, 5672, 7486, 9928, 13216, - 17648 -}; - -static const RK_U32 h264_inter_favor[52] = { - 40, 40, 41, 42, 43, 44, 45, 48, 51, 53, 55, 60, 62, 67, 69, 72, - 78, 84, 90, 96, 110, 120, 135, 152, 170, 189, 210, 235, 265, - 297, 335, 376, 420, 470, 522, 572, 620, 670, 724, 770, 820, - 867, 915, 970, 1020, 1076, 1132, 1180, 1230, 1275, 1320, 1370 -}; - -static RK_U32 h264_skip_sad_penalty[52] = { - 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 233, 205, 182, 163, - 146, 132, 120, 109, 100, 92, 84, 78, 71, 66, 61, 56, 52, 48, - 44, 41, 38, 35, 32, 30, 27, 25, 23, 21, 19, 17, 15, 14, - 12, 11, 9, 8, 7, 5, 4, 3, 2, 1 -}; - -const RK_S32 h264_context_init_intra[460][2] = { - /* 0 -> 10 */ - { 20, -15 }, { 2, 54 }, { 3, 74 }, { 20, -15 }, - { 2, 54 }, { 3, 74 }, { -28, 127 }, { -23, 104 }, - { -6, 53 }, { -1, 54 }, { 7, 51 }, - - /* 11 -> 23 unsused for I */ - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, - - /* 24 -> 39 */ - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - - /* 40 -> 53 */ - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, - - /* 54 -> 59 */ - { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, - - /* 60 -> 69 */ - { 0, 41 }, { 0, 63 }, { 0, 63 }, { 0, 63 }, - { -9, 83 }, { 4, 86 }, { 0, 97 }, { -7, 72 }, - { 13, 41 }, { 3, 62 }, - - /* 70 -> 87 */ - { 0, 11 }, { 1, 55 }, { 0, 69 }, { -17, 127 }, - { -13, 102 }, { 0, 82 }, { -7, 74 }, { -21, 107 }, - { -27, 127 }, { -31, 127 }, { -24, 127 }, { -18, 95 }, - { -27, 127 }, { -21, 114 }, { -30, 127 }, { -17, 123 }, - { -12, 115 }, { -16, 122 }, - - /* 88 -> 104 */ - { -11, 115 }, { -12, 63 }, { -2, 68 }, { -15, 84 }, - { -13, 104 }, { -3, 70 }, { -8, 93 }, { -10, 90 }, - { -30, 127 }, { -1, 74 }, { -6, 97 }, { -7, 91 }, - { -20, 127 }, { -4, 56 }, { -5, 82 }, { -7, 76 }, - { -22, 125 }, - - /* 105 -> 135 */ - { -7, 93 }, { -11, 87 }, { -3, 77 }, { -5, 71 }, - { -4, 63 }, { -4, 68 }, { -12, 84 }, { -7, 62 }, - { -7, 65 }, { 8, 61 }, { 5, 56 }, { -2, 66 }, - { 1, 64 }, { 0, 61 }, { -2, 78 }, { 1, 50 }, - { 7, 52 }, { 10, 35 }, { 0, 44 }, { 11, 38 }, - { 1, 45 }, { 0, 46 }, { 5, 44 }, { 31, 17 }, - { 1, 51 }, { 7, 50 }, { 28, 19 }, { 16, 33 }, - { 14, 62 }, { -13, 108 }, { -15, 100 }, - - /* 136 -> 165 */ - { -13, 101 }, { -13, 91 }, { -12, 94 }, { -10, 88 }, - { -16, 84 }, { -10, 86 }, { -7, 83 }, { -13, 87 }, - { -19, 94 }, { 1, 70 }, { 0, 72 }, { -5, 74 }, - { 18, 59 }, { -8, 102 }, { -15, 100 }, { 0, 95 }, - { -4, 75 }, { 2, 72 }, { -11, 75 }, { -3, 71 }, - { 15, 46 }, { -13, 69 }, { 0, 62 }, { 0, 65 }, - { 21, 37 }, { -15, 72 }, { 9, 57 }, { 16, 54 }, - { 0, 62 }, { 12, 72 }, - - /* 166 -> 196 */ - { 24, 0 }, { 15, 9 }, { 8, 25 }, { 13, 18 }, - { 15, 9 }, { 13, 19 }, { 10, 37 }, { 12, 18 }, - { 6, 29 }, { 20, 33 }, { 15, 30 }, { 4, 45 }, - { 1, 58 }, { 0, 62 }, { 7, 61 }, { 12, 38 }, - { 11, 45 }, { 15, 39 }, { 11, 42 }, { 13, 44 }, - { 16, 45 }, { 12, 41 }, { 10, 49 }, { 30, 34 }, - { 18, 42 }, { 10, 55 }, { 17, 51 }, { 17, 46 }, - { 0, 89 }, { 26, -19 }, { 22, -17 }, - - /* 197 -> 226 */ - { 26, -17 }, { 30, -25 }, { 28, -20 }, { 33, -23 }, - { 37, -27 }, { 33, -23 }, { 40, -28 }, { 38, -17 }, - { 33, -11 }, { 40, -15 }, { 41, -6 }, { 38, 1 }, - { 41, 17 }, { 30, -6 }, { 27, 3 }, { 26, 22 }, - { 37, -16 }, { 35, -4 }, { 38, -8 }, { 38, -3 }, - { 37, 3 }, { 38, 5 }, { 42, 0 }, { 35, 16 }, - { 39, 22 }, { 14, 48 }, { 27, 37 }, { 21, 60 }, - { 12, 68 }, { 2, 97 }, - - /* 227 -> 251 */ - { -3, 71 }, { -6, 42 }, { -5, 50 }, { -3, 54 }, - { -2, 62 }, { 0, 58 }, { 1, 63 }, { -2, 72 }, - { -1, 74 }, { -9, 91 }, { -5, 67 }, { -5, 27 }, - { -3, 39 }, { -2, 44 }, { 0, 46 }, { -16, 64 }, - { -8, 68 }, { -10, 78 }, { -6, 77 }, { -10, 86 }, - { -12, 92 }, { -15, 55 }, { -10, 60 }, { -6, 62 }, - { -4, 65 }, - - /* 252 -> 275 */ - { -12, 73 }, { -8, 76 }, { -7, 80 }, { -9, 88 }, - { -17, 110 }, { -11, 97 }, { -20, 84 }, { -11, 79 }, - { -6, 73 }, { -4, 74 }, { -13, 86 }, { -13, 96 }, - { -11, 97 }, { -19, 117 }, { -8, 78 }, { -5, 33 }, - { -4, 48 }, { -2, 53 }, { -3, 62 }, { -13, 71 }, - { -10, 79 }, { -12, 86 }, { -13, 90 }, { -14, 97 }, - - /* 276 special case, bypass used */ - { 0, 0 }, - - /* 277 -> 307 */ - { -6, 93 }, { -6, 84 }, { -8, 79 }, { 0, 66 }, - { -1, 71 }, { 0, 62 }, { -2, 60 }, { -2, 59 }, - { -5, 75 }, { -3, 62 }, { -4, 58 }, { -9, 66 }, - { -1, 79 }, { 0, 71 }, { 3, 68 }, { 10, 44 }, - { -7, 62 }, { 15, 36 }, { 14, 40 }, { 16, 27 }, - { 12, 29 }, { 1, 44 }, { 20, 36 }, { 18, 32 }, - { 5, 42 }, { 1, 48 }, { 10, 62 }, { 17, 46 }, - { 9, 64 }, { -12, 104 }, { -11, 97 }, - - /* 308 -> 337 */ - { -16, 96 }, { -7, 88 }, { -8, 85 }, { -7, 85 }, - { -9, 85 }, { -13, 88 }, { 4, 66 }, { -3, 77 }, - { -3, 76 }, { -6, 76 }, { 10, 58 }, { -1, 76 }, - { -1, 83 }, { -7, 99 }, { -14, 95 }, { 2, 95 }, - { 0, 76 }, { -5, 74 }, { 0, 70 }, { -11, 75 }, - { 1, 68 }, { 0, 65 }, { -14, 73 }, { 3, 62 }, - { 4, 62 }, { -1, 68 }, { -13, 75 }, { 11, 55 }, - { 5, 64 }, { 12, 70 }, - - /* 338 -> 368 */ - { 15, 6 }, { 6, 19 }, { 7, 16 }, { 12, 14 }, - { 18, 13 }, { 13, 11 }, { 13, 15 }, { 15, 16 }, - { 12, 23 }, { 13, 23 }, { 15, 20 }, { 14, 26 }, - { 14, 44 }, { 17, 40 }, { 17, 47 }, { 24, 17 }, - { 21, 21 }, { 25, 22 }, { 31, 27 }, { 22, 29 }, - { 19, 35 }, { 14, 50 }, { 10, 57 }, { 7, 63 }, - { -2, 77 }, { -4, 82 }, { -3, 94 }, { 9, 69 }, - { -12, 109 }, { 36, -35 }, { 36, -34 }, - - /* 369 -> 398 */ - { 32, -26 }, { 37, -30 }, { 44, -32 }, { 34, -18 }, - { 34, -15 }, { 40, -15 }, { 33, -7 }, { 35, -5 }, - { 33, 0 }, { 38, 2 }, { 33, 13 }, { 23, 35 }, - { 13, 58 }, { 29, -3 }, { 26, 0 }, { 22, 30 }, - { 31, -7 }, { 35, -15 }, { 34, -3 }, { 34, 3 }, - { 36, -1 }, { 34, 5 }, { 32, 11 }, { 35, 5 }, - { 34, 12 }, { 39, 11 }, { 30, 29 }, { 34, 26 }, - { 29, 39 }, { 19, 66 }, - - /* 399 -> 435 */ - { 31, 21 }, { 31, 31 }, { 25, 50 }, - { -17, 120 }, { -20, 112 }, { -18, 114 }, { -11, 85 }, - { -15, 92 }, { -14, 89 }, { -26, 71 }, { -15, 81 }, - { -14, 80 }, { 0, 68 }, { -14, 70 }, { -24, 56 }, - { -23, 68 }, { -24, 50 }, { -11, 74 }, { 23, -13 }, - { 26, -13 }, { 40, -15 }, { 49, -14 }, { 44, 3 }, - { 45, 6 }, { 44, 34 }, { 33, 54 }, { 19, 82 }, - { -3, 75 }, { -1, 23 }, { 1, 34 }, { 1, 43 }, - { 0, 54 }, { -2, 55 }, { 0, 61 }, { 1, 64 }, - { 0, 68 }, { -9, 92 }, - - /* 436 -> 459 */ - { -14, 106 }, { -13, 97 }, { -15, 90 }, { -12, 90 }, - { -18, 88 }, { -10, 73 }, { -9, 79 }, { -14, 86 }, - { -10, 73 }, { -10, 70 }, { -10, 69 }, { -5, 66 }, - { -9, 64 }, { -5, 58 }, { 2, 59 }, { 21, -10 }, - { 24, -11 }, { 28, -8 }, { 28, -1 }, { 29, 3 }, - { 29, 9 }, { 35, 20 }, { 29, 36 }, { 14, 67 } -}; - -const RK_S32 h264_context_init[3][460][2] = { - /* cabac_init_idc == 0 */ - { - /* 0 -> 10 */ - { 20, -15 }, { 2, 54 }, { 3, 74 }, { 20, -15 }, - { 2, 54 }, { 3, 74 }, { -28, 127 }, { -23, 104 }, - { -6, 53 }, { -1, 54 }, { 7, 51 }, - - /* 11 -> 23 */ - { 23, 33 }, { 23, 2 }, { 21, 0 }, { 1, 9 }, - { 0, 49 }, { -37, 118 }, { 5, 57 }, { -13, 78 }, - { -11, 65 }, { 1, 62 }, { 12, 49 }, { -4, 73 }, - { 17, 50 }, - - /* 24 -> 39 */ - { 18, 64 }, { 9, 43 }, { 29, 0 }, { 26, 67 }, - { 16, 90 }, { 9, 104 }, { -46, 127 }, { -20, 104 }, - { 1, 67 }, { -13, 78 }, { -11, 65 }, { 1, 62 }, - { -6, 86 }, { -17, 95 }, { -6, 61 }, { 9, 45 }, - - /* 40 -> 53 */ - { -3, 69 }, { -6, 81 }, { -11, 96 }, { 6, 55 }, - { 7, 67 }, { -5, 86 }, { 2, 88 }, { 0, 58 }, - { -3, 76 }, { -10, 94 }, { 5, 54 }, { 4, 69 }, - { -3, 81 }, { 0, 88 }, - - /* 54 -> 59 */ - { -7, 67 }, { -5, 74 }, { -4, 74 }, { -5, 80 }, - { -7, 72 }, { 1, 58 }, - - /* 60 -> 69 */ - { 0, 41 }, { 0, 63 }, { 0, 63 }, { 0, 63 }, - { -9, 83 }, { 4, 86 }, { 0, 97 }, { -7, 72 }, - { 13, 41 }, { 3, 62 }, - - /* 70 -> 87 */ - { 0, 45 }, { -4, 78 }, { -3, 96 }, { -27, 126 }, - { -28, 98 }, { -25, 101 }, { -23, 67 }, { -28, 82 }, - { -20, 94 }, { -16, 83 }, { -22, 110 }, { -21, 91 }, - { -18, 102 }, { -13, 93 }, { -29, 127 }, { -7, 92 }, - { -5, 89 }, { -7, 96 }, { -13, 108 }, { -3, 46 }, - { -1, 65 }, { -1, 57 }, { -9, 93 }, { -3, 74 }, - { -9, 92 }, { -8, 87 }, { -23, 126 }, { 5, 54 }, - { 6, 60 }, { 6, 59 }, { 6, 69 }, { -1, 48 }, - { 0, 68 }, { -4, 69 }, { -8, 88 }, - - /* 105 -> 165 */ - { -2, 85 }, { -6, 78 }, { -1, 75 }, { -7, 77 }, - { 2, 54 }, { 5, 50 }, { -3, 68 }, { 1, 50 }, - { 6, 42 }, { -4, 81 }, { 1, 63 }, { -4, 70 }, - { 0, 67 }, { 2, 57 }, { -2, 76 }, { 11, 35 }, - { 4, 64 }, { 1, 61 }, { 11, 35 }, { 18, 25 }, - { 12, 24 }, { 13, 29 }, { 13, 36 }, { -10, 93 }, - { -7, 73 }, { -2, 73 }, { 13, 46 }, { 9, 49 }, - { -7, 100 }, { 9, 53 }, { 2, 53 }, { 5, 53 }, - { -2, 61 }, { 0, 56 }, { 0, 56 }, { -13, 63 }, - { -5, 60 }, { -1, 62 }, { 4, 57 }, { -6, 69 }, - { 4, 57 }, { 14, 39 }, { 4, 51 }, { 13, 68 }, - { 3, 64 }, { 1, 61 }, { 9, 63 }, { 7, 50 }, - { 16, 39 }, { 5, 44 }, { 4, 52 }, { 11, 48 }, - { -5, 60 }, { -1, 59 }, { 0, 59 }, { 22, 33 }, - { 5, 44 }, { 14, 43 }, { -1, 78 }, { 0, 60 }, - { 9, 69 }, - - /* 166 -> 226 */ - { 11, 28 }, { 2, 40 }, { 3, 44 }, { 0, 49 }, - { 0, 46 }, { 2, 44 }, { 2, 51 }, { 0, 47 }, - { 4, 39 }, { 2, 62 }, { 6, 46 }, { 0, 54 }, - { 3, 54 }, { 2, 58 }, { 4, 63 }, { 6, 51 }, - { 6, 57 }, { 7, 53 }, { 6, 52 }, { 6, 55 }, - { 11, 45 }, { 14, 36 }, { 8, 53 }, { -1, 82 }, - { 7, 55 }, { -3, 78 }, { 15, 46 }, { 22, 31 }, - { -1, 84 }, { 25, 7 }, { 30, -7 }, { 28, 3 }, - { 28, 4 }, { 32, 0 }, { 34, -1 }, { 30, 6 }, - { 30, 6 }, { 32, 9 }, { 31, 19 }, { 26, 27 }, - { 26, 30 }, { 37, 20 }, { 28, 34 }, { 17, 70 }, - { 1, 67 }, { 5, 59 }, { 9, 67 }, { 16, 30 }, - { 18, 32 }, { 18, 35 }, { 22, 29 }, { 24, 31 }, - { 23, 38 }, { 18, 43 }, { 20, 41 }, { 11, 63 }, - { 9, 59 }, { 9, 64 }, { -1, 94 }, { -2, 89 }, - { -9, 108 }, - - /* 227 -> 275 */ - { -6, 76 }, { -2, 44 }, { 0, 45 }, { 0, 52 }, - { -3, 64 }, { -2, 59 }, { -4, 70 }, { -4, 75 }, - { -8, 82 }, { -17, 102 }, { -9, 77 }, { 3, 24 }, - { 0, 42 }, { 0, 48 }, { 0, 55 }, { -6, 59 }, - { -7, 71 }, { -12, 83 }, { -11, 87 }, { -30, 119 }, - { 1, 58 }, { -3, 29 }, { -1, 36 }, { 1, 38 }, - { 2, 43 }, { -6, 55 }, { 0, 58 }, { 0, 64 }, - { -3, 74 }, { -10, 90 }, { 0, 70 }, { -4, 29 }, - { 5, 31 }, { 7, 42 }, { 1, 59 }, { -2, 58 }, - { -3, 72 }, { -3, 81 }, { -11, 97 }, { 0, 58 }, - { 8, 5 }, { 10, 14 }, { 14, 18 }, { 13, 27 }, - { 2, 40 }, { 0, 58 }, { -3, 70 }, { -6, 79 }, - { -8, 85 }, - - /* 276 special case, bypass used */ - { 0, 0 }, - - /* 277 -> 337 */ - { -13, 106 }, { -16, 106 }, { -10, 87 }, { -21, 114 }, - { -18, 110 }, { -14, 98 }, { -22, 110 }, { -21, 106 }, - { -18, 103 }, { -21, 107 }, { -23, 108 }, { -26, 112 }, - { -10, 96 }, { -12, 95 }, { -5, 91 }, { -9, 93 }, - { -22, 94 }, { -5, 86 }, { 9, 67 }, { -4, 80 }, - { -10, 85 }, { -1, 70 }, { 7, 60 }, { 9, 58 }, - { 5, 61 }, { 12, 50 }, { 15, 50 }, { 18, 49 }, - { 17, 54 }, { 10, 41 }, { 7, 46 }, { -1, 51 }, - { 7, 49 }, { 8, 52 }, { 9, 41 }, { 6, 47 }, - { 2, 55 }, { 13, 41 }, { 10, 44 }, { 6, 50 }, - { 5, 53 }, { 13, 49 }, { 4, 63 }, { 6, 64 }, - { -2, 69 }, { -2, 59 }, { 6, 70 }, { 10, 44 }, - { 9, 31 }, { 12, 43 }, { 3, 53 }, { 14, 34 }, - { 10, 38 }, { -3, 52 }, { 13, 40 }, { 17, 32 }, - { 7, 44 }, { 7, 38 }, { 13, 50 }, { 10, 57 }, - { 26, 43 }, - - /* 338 -> 398 */ - { 14, 11 }, { 11, 14 }, { 9, 11 }, { 18, 11 }, - { 21, 9 }, { 23, -2 }, { 32, -15 }, { 32, -15 }, - { 34, -21 }, { 39, -23 }, { 42, -33 }, { 41, -31 }, - { 46, -28 }, { 38, -12 }, { 21, 29 }, { 45, -24 }, - { 53, -45 }, { 48, -26 }, { 65, -43 }, { 43, -19 }, - { 39, -10 }, { 30, 9 }, { 18, 26 }, { 20, 27 }, - { 0, 57 }, { -14, 82 }, { -5, 75 }, { -19, 97 }, - { -35, 125 }, { 27, 0 }, { 28, 0 }, { 31, -4 }, - { 27, 6 }, { 34, 8 }, { 30, 10 }, { 24, 22 }, - { 33, 19 }, { 22, 32 }, { 26, 31 }, { 21, 41 }, - { 26, 44 }, { 23, 47 }, { 16, 65 }, { 14, 71 }, - { 8, 60 }, { 6, 63 }, { 17, 65 }, { 21, 24 }, - { 23, 20 }, { 26, 23 }, { 27, 32 }, { 28, 23 }, - { 28, 24 }, { 23, 40 }, { 24, 32 }, { 28, 29 }, - { 23, 42 }, { 19, 57 }, { 22, 53 }, { 22, 61 }, - { 11, 86 }, - - /* 399 -> 435 */ - { 12, 40 }, { 11, 51 }, { 14, 59 }, - { -4, 79 }, { -7, 71 }, { -5, 69 }, { -9, 70 }, - { -8, 66 }, { -10, 68 }, { -19, 73 }, { -12, 69 }, - { -16, 70 }, { -15, 67 }, { -20, 62 }, { -19, 70 }, - { -16, 66 }, { -22, 65 }, { -20, 63 }, { 9, -2 }, - { 26, -9 }, { 33, -9 }, { 39, -7 }, { 41, -2 }, - { 45, 3 }, { 49, 9 }, { 45, 27 }, { 36, 59 }, - { -6, 66 }, { -7, 35 }, { -7, 42 }, { -8, 45 }, - { -5, 48 }, { -12, 56 }, { -6, 60 }, { -5, 62 }, - { -8, 66 }, { -8, 76 }, - - /* 436 -> 459 */ - { -5, 85 }, { -6, 81 }, { -10, 77 }, { -7, 81 }, - { -17, 80 }, { -18, 73 }, { -4, 74 }, { -10, 83 }, - { -9, 71 }, { -9, 67 }, { -1, 61 }, { -8, 66 }, - { -14, 66 }, { 0, 59 }, { 2, 59 }, { 21, -13 }, - { 33, -14 }, { 39, -7 }, { 46, -2 }, { 51, 2 }, - { 60, 6 }, { 61, 17 }, { 55, 34 }, { 42, 62 }, - }, - - /* cabac_init_idc == 1 */ - { - /* 0 -> 10 */ - { 20, -15 }, { 2, 54 }, { 3, 74 }, { 20, -15 }, - { 2, 54 }, { 3, 74 }, { -28, 127 }, { -23, 104 }, - { -6, 53 }, { -1, 54 }, { 7, 51 }, - - /* 11 -> 23 */ - { 22, 25 }, { 34, 0 }, { 16, 0 }, { -2, 9 }, - { 4, 41 }, { -29, 118 }, { 2, 65 }, { -6, 71 }, - { -13, 79 }, { 5, 52 }, { 9, 50 }, { -3, 70 }, - { 10, 54 }, - - /* 24 -> 39 */ - { 26, 34 }, { 19, 22 }, { 40, 0 }, { 57, 2 }, - { 41, 36 }, { 26, 69 }, { -45, 127 }, { -15, 101 }, - { -4, 76 }, { -6, 71 }, { -13, 79 }, { 5, 52 }, - { 6, 69 }, { -13, 90 }, { 0, 52 }, { 8, 43 }, - - /* 40 -> 53 */ - { -2, 69 }, { -5, 82 }, { -10, 96 }, { 2, 59 }, - { 2, 75 }, { -3, 87 }, { -3, 100 }, { 1, 56 }, - { -3, 74 }, { -6, 85 }, { 0, 59 }, { -3, 81 }, - { -7, 86 }, { -5, 95 }, - - /* 54 -> 59 */ - { -1, 66 }, { -1, 77 }, { 1, 70 }, { -2, 86 }, - { -5, 72 }, { 0, 61 }, - - /* 60 -> 69 */ - { 0, 41 }, { 0, 63 }, { 0, 63 }, { 0, 63 }, - { -9, 83 }, { 4, 86 }, { 0, 97 }, { -7, 72 }, - { 13, 41 }, { 3, 62 }, - - /* 70 -> 104 */ - { 13, 15 }, { 7, 51 }, { 2, 80 }, { -39, 127 }, - { -18, 91 }, { -17, 96 }, { -26, 81 }, { -35, 98 }, - { -24, 102 }, { -23, 97 }, { -27, 119 }, { -24, 99 }, - { -21, 110 }, { -18, 102 }, { -36, 127 }, { 0, 80 }, - { -5, 89 }, { -7, 94 }, { -4, 92 }, { 0, 39 }, - { 0, 65 }, { -15, 84 }, { -35, 127 }, { -2, 73 }, - { -12, 104 }, { -9, 91 }, { -31, 127 }, { 3, 55 }, - { 7, 56 }, { 7, 55 }, { 8, 61 }, { -3, 53 }, - { 0, 68 }, { -7, 74 }, { -9, 88 }, - - /* 105 -> 165 */ - { -13, 103 }, { -13, 91 }, { -9, 89 }, { -14, 92 }, - { -8, 76 }, { -12, 87 }, { -23, 110 }, { -24, 105 }, - { -10, 78 }, { -20, 112 }, { -17, 99 }, { -78, 127 }, - { -70, 127 }, { -50, 127 }, { -46, 127 }, { -4, 66 }, - { -5, 78 }, { -4, 71 }, { -8, 72 }, { 2, 59 }, - { -1, 55 }, { -7, 70 }, { -6, 75 }, { -8, 89 }, - { -34, 119 }, { -3, 75 }, { 32, 20 }, { 30, 22 }, - { -44, 127 }, { 0, 54 }, { -5, 61 }, { 0, 58 }, - { -1, 60 }, { -3, 61 }, { -8, 67 }, { -25, 84 }, - { -14, 74 }, { -5, 65 }, { 5, 52 }, { 2, 57 }, - { 0, 61 }, { -9, 69 }, { -11, 70 }, { 18, 55 }, - { -4, 71 }, { 0, 58 }, { 7, 61 }, { 9, 41 }, - { 18, 25 }, { 9, 32 }, { 5, 43 }, { 9, 47 }, - { 0, 44 }, { 0, 51 }, { 2, 46 }, { 19, 38 }, - { -4, 66 }, { 15, 38 }, { 12, 42 }, { 9, 34 }, - { 0, 89 }, - - /* 166 -> 226 */ - { 4, 45 }, { 10, 28 }, { 10, 31 }, { 33, -11 }, - { 52, -43 }, { 18, 15 }, { 28, 0 }, { 35, -22 }, - { 38, -25 }, { 34, 0 }, { 39, -18 }, { 32, -12 }, - { 102, -94 }, { 0, 0 }, { 56, -15 }, { 33, -4 }, - { 29, 10 }, { 37, -5 }, { 51, -29 }, { 39, -9 }, - { 52, -34 }, { 69, -58 }, { 67, -63 }, { 44, -5 }, - { 32, 7 }, { 55, -29 }, { 32, 1 }, { 0, 0 }, - { 27, 36 }, { 33, -25 }, { 34, -30 }, { 36, -28 }, - { 38, -28 }, { 38, -27 }, { 34, -18 }, { 35, -16 }, - { 34, -14 }, { 32, -8 }, { 37, -6 }, { 35, 0 }, - { 30, 10 }, { 28, 18 }, { 26, 25 }, { 29, 41 }, - { 0, 75 }, { 2, 72 }, { 8, 77 }, { 14, 35 }, - { 18, 31 }, { 17, 35 }, { 21, 30 }, { 17, 45 }, - { 20, 42 }, { 18, 45 }, { 27, 26 }, { 16, 54 }, - { 7, 66 }, { 16, 56 }, { 11, 73 }, { 10, 67 }, - { -10, 116 }, - - /* 227 -> 275 */ - { -23, 112 }, { -15, 71 }, { -7, 61 }, { 0, 53 }, - { -5, 66 }, { -11, 77 }, { -9, 80 }, { -9, 84 }, - { -10, 87 }, { -34, 127 }, { -21, 101 }, { -3, 39 }, - { -5, 53 }, { -7, 61 }, { -11, 75 }, { -15, 77 }, - { -17, 91 }, { -25, 107 }, { -25, 111 }, { -28, 122 }, - { -11, 76 }, { -10, 44 }, { -10, 52 }, { -10, 57 }, - { -9, 58 }, { -16, 72 }, { -7, 69 }, { -4, 69 }, - { -5, 74 }, { -9, 86 }, { 2, 66 }, { -9, 34 }, - { 1, 32 }, { 11, 31 }, { 5, 52 }, { -2, 55 }, - { -2, 67 }, { 0, 73 }, { -8, 89 }, { 3, 52 }, - { 7, 4 }, { 10, 8 }, { 17, 8 }, { 16, 19 }, - { 3, 37 }, { -1, 61 }, { -5, 73 }, { -1, 70 }, - { -4, 78 }, - - /* 276 special case, bypass used */ - { 0, 0 }, - - /* 277 -> 337 */ - { -21, 126 }, { -23, 124 }, { -20, 110 }, { -26, 126 }, - { -25, 124 }, { -17, 105 }, { -27, 121 }, { -27, 117 }, - { -17, 102 }, { -26, 117 }, { -27, 116 }, { -33, 122 }, - { -10, 95 }, { -14, 100 }, { -8, 95 }, { -17, 111 }, - { -28, 114 }, { -6, 89 }, { -2, 80 }, { -4, 82 }, - { -9, 85 }, { -8, 81 }, { -1, 72 }, { 5, 64 }, - { 1, 67 }, { 9, 56 }, { 0, 69 }, { 1, 69 }, - { 7, 69 }, { -7, 69 }, { -6, 67 }, { -16, 77 }, - { -2, 64 }, { 2, 61 }, { -6, 67 }, { -3, 64 }, - { 2, 57 }, { -3, 65 }, { -3, 66 }, { 0, 62 }, - { 9, 51 }, { -1, 66 }, { -2, 71 }, { -2, 75 }, - { -1, 70 }, { -9, 72 }, { 14, 60 }, { 16, 37 }, - { 0, 47 }, { 18, 35 }, { 11, 37 }, { 12, 41 }, - { 10, 41 }, { 2, 48 }, { 12, 41 }, { 13, 41 }, - { 0, 59 }, { 3, 50 }, { 19, 40 }, { 3, 66 }, - { 18, 50 }, - - /* 338 -> 398 */ - { 19, -6 }, { 18, -6 }, { 14, 0 }, { 26, -12 }, - { 31, -16 }, { 33, -25 }, { 33, -22 }, { 37, -28 }, - { 39, -30 }, { 42, -30 }, { 47, -42 }, { 45, -36 }, - { 49, -34 }, { 41, -17 }, { 32, 9 }, { 69, -71 }, - { 63, -63 }, { 66, -64 }, { 77, -74 }, { 54, -39 }, - { 52, -35 }, { 41, -10 }, { 36, 0 }, { 40, -1 }, - { 30, 14 }, { 28, 26 }, { 23, 37 }, { 12, 55 }, - { 11, 65 }, { 37, -33 }, { 39, -36 }, { 40, -37 }, - { 38, -30 }, { 46, -33 }, { 42, -30 }, { 40, -24 }, - { 49, -29 }, { 38, -12 }, { 40, -10 }, { 38, -3 }, - { 46, -5 }, { 31, 20 }, { 29, 30 }, { 25, 44 }, - { 12, 48 }, { 11, 49 }, { 26, 45 }, { 22, 22 }, - { 23, 22 }, { 27, 21 }, { 33, 20 }, { 26, 28 }, - { 30, 24 }, { 27, 34 }, { 18, 42 }, { 25, 39 }, - { 18, 50 }, { 12, 70 }, { 21, 54 }, { 14, 71 }, - { 11, 83 }, - - /* 399 -> 435 */ - { 25, 32 }, { 21, 49 }, { 21, 54 }, - { -5, 85 }, { -6, 81 }, { -10, 77 }, { -7, 81 }, - { -17, 80 }, { -18, 73 }, { -4, 74 }, { -10, 83 }, - { -9, 71 }, { -9, 67 }, { -1, 61 }, { -8, 66 }, - { -14, 66 }, { 0, 59 }, { 2, 59 }, { 17, -10 }, - { 32, -13 }, { 42, -9 }, { 49, -5 }, { 53, 0 }, - { 64, 3 }, { 68, 10 }, { 66, 27 }, { 47, 57 }, - { -5, 71 }, { 0, 24 }, { -1, 36 }, { -2, 42 }, - { -2, 52 }, { -9, 57 }, { -6, 63 }, { -4, 65 }, - { -4, 67 }, { -7, 82 }, - - /* 436 -> 459 */ - { -3, 81 }, { -3, 76 }, { -7, 72 }, { -6, 78 }, - { -12, 72 }, { -14, 68 }, { -3, 70 }, { -6, 76 }, - { -5, 66 }, { -5, 62 }, { 0, 57 }, { -4, 61 }, - { -9, 60 }, { 1, 54 }, { 2, 58 }, { 17, -10 }, - { 32, -13 }, { 42, -9 }, { 49, -5 }, { 53, 0 }, - { 64, 3 }, { 68, 10 }, { 66, 27 }, { 47, 57 }, - }, - - /* cabac_init_idc == 2 */ - { - /* 0 -> 10 */ - { 20, -15 }, { 2, 54 }, { 3, 74 }, { 20, -15 }, - { 2, 54 }, { 3, 74 }, { -28, 127 }, { -23, 104 }, - { -6, 53 }, { -1, 54 }, { 7, 51 }, - - /* 11 -> 23 */ - { 29, 16 }, { 25, 0 }, { 14, 0 }, { -10, 51 }, - { -3, 62 }, { -27, 99 }, { 26, 16 }, { -4, 85 }, - { -24, 102 }, { 5, 57 }, { 6, 57 }, { -17, 73 }, - { 14, 57 }, - - /* 24 -> 39 */ - { 20, 40 }, { 20, 10 }, { 29, 0 }, { 54, 0 }, - { 37, 42 }, { 12, 97 }, { -32, 127 }, { -22, 117 }, - { -2, 74 }, { -4, 85 }, { -24, 102 }, { 5, 57 }, - { -6, 93 }, { -14, 88 }, { -6, 44 }, { 4, 55 }, - - /* 40 -> 53 */ - { -11, 89 }, { -15, 103 }, { -21, 116 }, { 19, 57 }, - { 20, 58 }, { 4, 84 }, { 6, 96 }, { 1, 63 }, - { -5, 85 }, { -13, 106 }, { 5, 63 }, { 6, 75 }, - { -3, 90 }, { -1, 101 }, - - /* 54 -> 59 */ - { 3, 55 }, { -4, 79 }, { -2, 75 }, { -12, 97 }, - { -7, 50 }, { 1, 60 }, - - /* 60 -> 69 */ - { 0, 41 }, { 0, 63 }, { 0, 63 }, { 0, 63 }, - { -9, 83 }, { 4, 86 }, { 0, 97 }, { -7, 72 }, - { 13, 41 }, { 3, 62 }, - - /* 70 -> 104 */ - { 7, 34 }, { -9, 88 }, { -20, 127 }, { -36, 127 }, - { -17, 91 }, { -14, 95 }, { -25, 84 }, { -25, 86 }, - { -12, 89 }, { -17, 91 }, { -31, 127 }, { -14, 76 }, - { -18, 103 }, { -13, 90 }, { -37, 127 }, { 11, 80 }, - { 5, 76 }, { 2, 84 }, { 5, 78 }, { -6, 55 }, - { 4, 61 }, { -14, 83 }, { -37, 127 }, { -5, 79 }, - { -11, 104 }, { -11, 91 }, { -30, 127 }, { 0, 65 }, - { -2, 79 }, { 0, 72 }, { -4, 92 }, { -6, 56 }, - { 3, 68 }, { -8, 71 }, { -13, 98 }, - - /* 105 -> 165 */ - { -4, 86 }, { -12, 88 }, { -5, 82 }, { -3, 72 }, - { -4, 67 }, { -8, 72 }, { -16, 89 }, { -9, 69 }, - { -1, 59 }, { 5, 66 }, { 4, 57 }, { -4, 71 }, - { -2, 71 }, { 2, 58 }, { -1, 74 }, { -4, 44 }, - { -1, 69 }, { 0, 62 }, { -7, 51 }, { -4, 47 }, - { -6, 42 }, { -3, 41 }, { -6, 53 }, { 8, 76 }, - { -9, 78 }, { -11, 83 }, { 9, 52 }, { 0, 67 }, - { -5, 90 }, { 1, 67 }, { -15, 72 }, { -5, 75 }, - { -8, 80 }, { -21, 83 }, { -21, 64 }, { -13, 31 }, - { -25, 64 }, { -29, 94 }, { 9, 75 }, { 17, 63 }, - { -8, 74 }, { -5, 35 }, { -2, 27 }, { 13, 91 }, - { 3, 65 }, { -7, 69 }, { 8, 77 }, { -10, 66 }, - { 3, 62 }, { -3, 68 }, { -20, 81 }, { 0, 30 }, - { 1, 7 }, { -3, 23 }, { -21, 74 }, { 16, 66 }, - { -23, 124 }, { 17, 37 }, { 44, -18 }, { 50, -34 }, - { -22, 127 }, - - /* 166 -> 226 */ - { 4, 39 }, { 0, 42 }, { 7, 34 }, { 11, 29 }, - { 8, 31 }, { 6, 37 }, { 7, 42 }, { 3, 40 }, - { 8, 33 }, { 13, 43 }, { 13, 36 }, { 4, 47 }, - { 3, 55 }, { 2, 58 }, { 6, 60 }, { 8, 44 }, - { 11, 44 }, { 14, 42 }, { 7, 48 }, { 4, 56 }, - { 4, 52 }, { 13, 37 }, { 9, 49 }, { 19, 58 }, - { 10, 48 }, { 12, 45 }, { 0, 69 }, { 20, 33 }, - { 8, 63 }, { 35, -18 }, { 33, -25 }, { 28, -3 }, - { 24, 10 }, { 27, 0 }, { 34, -14 }, { 52, -44 }, - { 39, -24 }, { 19, 17 }, { 31, 25 }, { 36, 29 }, - { 24, 33 }, { 34, 15 }, { 30, 20 }, { 22, 73 }, - { 20, 34 }, { 19, 31 }, { 27, 44 }, { 19, 16 }, - { 15, 36 }, { 15, 36 }, { 21, 28 }, { 25, 21 }, - { 30, 20 }, { 31, 12 }, { 27, 16 }, { 24, 42 }, - { 0, 93 }, { 14, 56 }, { 15, 57 }, { 26, 38 }, - { -24, 127 }, - - /* 227 -> 275 */ - { -24, 115 }, { -22, 82 }, { -9, 62 }, { 0, 53 }, - { 0, 59 }, { -14, 85 }, { -13, 89 }, { -13, 94 }, - { -11, 92 }, { -29, 127 }, { -21, 100 }, { -14, 57 }, - { -12, 67 }, { -11, 71 }, { -10, 77 }, { -21, 85 }, - { -16, 88 }, { -23, 104 }, { -15, 98 }, { -37, 127 }, - { -10, 82 }, { -8, 48 }, { -8, 61 }, { -8, 66 }, - { -7, 70 }, { -14, 75 }, { -10, 79 }, { -9, 83 }, - { -12, 92 }, { -18, 108 }, { -4, 79 }, { -22, 69 }, - { -16, 75 }, { -2, 58 }, { 1, 58 }, { -13, 78 }, - { -9, 83 }, { -4, 81 }, { -13, 99 }, { -13, 81 }, - { -6, 38 }, { -13, 62 }, { -6, 58 }, { -2, 59 }, - { -16, 73 }, { -10, 76 }, { -13, 86 }, { -9, 83 }, - { -10, 87 }, - - /* 276 special case, bypass used */ - { 0, 0 }, - - /* 277 -> 337 */ - { -22, 127 }, { -25, 127 }, { -25, 120 }, { -27, 127 }, - { -19, 114 }, { -23, 117 }, { -25, 118 }, { -26, 117 }, - { -24, 113 }, { -28, 118 }, { -31, 120 }, { -37, 124 }, - { -10, 94 }, { -15, 102 }, { -10, 99 }, { -13, 106 }, - { -50, 127 }, { -5, 92 }, { 17, 57 }, { -5, 86 }, - { -13, 94 }, { -12, 91 }, { -2, 77 }, { 0, 71 }, - { -1, 73 }, { 4, 64 }, { -7, 81 }, { 5, 64 }, - { 15, 57 }, { 1, 67 }, { 0, 68 }, { -10, 67 }, - { 1, 68 }, { 0, 77 }, { 2, 64 }, { 0, 68 }, - { -5, 78 }, { 7, 55 }, { 5, 59 }, { 2, 65 }, - { 14, 54 }, { 15, 44 }, { 5, 60 }, { 2, 70 }, - { -2, 76 }, { -18, 86 }, { 12, 70 }, { 5, 64 }, - { -12, 70 }, { 11, 55 }, { 5, 56 }, { 0, 69 }, - { 2, 65 }, { -6, 74 }, { 5, 54 }, { 7, 54 }, - { -6, 76 }, { -11, 82 }, { -2, 77 }, { -2, 77 }, - { 25, 42 }, - - /* 338 -> 398 */ - { 17, -13 }, { 16, -9 }, { 17, -12 }, { 27, -21 }, - { 37, -30 }, { 41, -40 }, { 42, -41 }, { 48, -47 }, - { 39, -32 }, { 46, -40 }, { 52, -51 }, { 46, -41 }, - { 52, -39 }, { 43, -19 }, { 32, 11 }, { 61, -55 }, - { 56, -46 }, { 62, -50 }, { 81, -67 }, { 45, -20 }, - { 35, -2 }, { 28, 15 }, { 34, 1 }, { 39, 1 }, - { 30, 17 }, { 20, 38 }, { 18, 45 }, { 15, 54 }, - { 0, 79 }, { 36, -16 }, { 37, -14 }, { 37, -17 }, - { 32, 1 }, { 34, 15 }, { 29, 15 }, { 24, 25 }, - { 34, 22 }, { 31, 16 }, { 35, 18 }, { 31, 28 }, - { 33, 41 }, { 36, 28 }, { 27, 47 }, { 21, 62 }, - { 18, 31 }, { 19, 26 }, { 36, 24 }, { 24, 23 }, - { 27, 16 }, { 24, 30 }, { 31, 29 }, { 22, 41 }, - { 22, 42 }, { 16, 60 }, { 15, 52 }, { 14, 60 }, - { 3, 78 }, { -16, 123 }, { 21, 53 }, { 22, 56 }, - { 25, 61 }, - - /* 399 -> 435 */ - { 21, 33 }, { 19, 50 }, { 17, 61 }, - { -3, 78 }, { -8, 74 }, { -9, 72 }, { -10, 72 }, - { -18, 75 }, { -12, 71 }, { -11, 63 }, { -5, 70 }, - { -17, 75 }, { -14, 72 }, { -16, 67 }, { -8, 53 }, - { -14, 59 }, { -9, 52 }, { -11, 68 }, { 9, -2 }, - { 30, -10 }, { 31, -4 }, { 33, -1 }, { 33, 7 }, - { 31, 12 }, { 37, 23 }, { 31, 38 }, { 20, 64 }, - { -9, 71 }, { -7, 37 }, { -8, 44 }, { -11, 49 }, - { -10, 56 }, { -12, 59 }, { -8, 63 }, { -9, 67 }, - { -6, 68 }, { -10, 79 }, - - /* 436 -> 459 */ - { -3, 78 }, { -8, 74 }, { -9, 72 }, { -10, 72 }, - { -18, 75 }, { -12, 71 }, { -11, 63 }, { -5, 70 }, - { -17, 75 }, { -14, 72 }, { -16, 67 }, { -8, 53 }, - { -14, 59 }, { -9, 52 }, { -11, 68 }, { 9, -2 }, - { 30, -10 }, { 31, -4 }, { 33, -1 }, { 33, 7 }, - { 31, 12 }, { 37, 23 }, { 31, 38 }, { 20, 64 }, - } -}; - -#ifdef H264E_DUMP_DATA_TO_FILE -static MPP_RET hal_h264e_vpu_open_dump_files(void *dump_files) -{ - if (h264e_hal_log_mode & H264E_HAL_LOG_FILE) { - char base_path[512]; - char full_path[512]; - h264e_hal_vpu_dump_files *files = (h264e_hal_vpu_dump_files *)dump_files; - strcpy(base_path, "/sdcard/h264e_data/"); - - sprintf(full_path, "%s%s", base_path, "mpp_syntax_in.txt"); - files->fp_mpp_syntax_in = fopen(full_path, "wb"); - if (!files->fp_mpp_syntax_in) { - mpp_err("%s open error", full_path); - return MPP_ERR_OPEN_FILE; - } - - - sprintf(full_path, "%s%s", base_path, "mpp_reg_in.txt"); - files->fp_mpp_reg_in = fopen(full_path, "wb"); - if (!files->fp_mpp_reg_in) { - mpp_err("%s open error", full_path); - return MPP_ERR_OPEN_FILE; - } - - sprintf(full_path, "%s%s", base_path, "mpp_reg_out.txt"); - files->fp_mpp_reg_out = fopen(full_path, "wb"); - if (!files->fp_mpp_reg_out) { - mpp_err("%s open error", full_path); - return MPP_ERR_OPEN_FILE; - } - - sprintf(full_path, "%s%s", base_path, "mpp_feedback.txt"); - files->fp_mpp_feedback = fopen(full_path, "wb"); - if (!files->fp_mpp_feedback) { - mpp_err("%s open error", full_path); - return MPP_ERR_OPEN_FILE; - } - - sprintf(full_path, "%s%s", base_path, "mpp_strm_out.bin"); - files->fp_mpp_strm_out = fopen(full_path, "wb"); - if (!files->fp_mpp_strm_out) { - mpp_err("%s open error", full_path); - return MPP_ERR_OPEN_FILE; - } - } - return MPP_OK; -} - - -static MPP_RET hal_h264e_vpu_close_dump_files(void *dump_files) -{ - h264e_hal_vpu_dump_files *files = (h264e_hal_vpu_dump_files *)dump_files; - H264E_HAL_FCLOSE(files->fp_mpp_syntax_in); - H264E_HAL_FCLOSE(files->fp_mpp_reg_in); - H264E_HAL_FCLOSE(files->fp_mpp_reg_out); - H264E_HAL_FCLOSE(files->fp_mpp_strm_out); - H264E_HAL_FCLOSE(files->fp_mpp_feedback); - return MPP_OK; -} - -static void hal_h264e_vpu_dump_mpp_syntax_in(h264e_syntax *syn, h264e_hal_context *ctx) -{ - h264e_hal_vpu_dump_files *dump_files = (h264e_hal_vpu_dump_files *)ctx->dump_files; - FILE *fp = dump_files->fp_mpp_syntax_in; - if (fp) { - RK_S32 k = 0; - fprintf(fp, "#FRAME %d:\n", ctx->frame_cnt); - fprintf(fp, "%-16d %s\n", syn->frame_coding_type, "frame_coding_type"); - fprintf(fp, "%-16d %s\n", syn->pic_init_qp, "pic_init_qp"); - fprintf(fp, "%-16d %s\n", syn->slice_alpha_offset, "slice_alpha_offset"); - fprintf(fp, "%-16d %s\n", syn->slice_beta_offset, "slice_beta_offset"); - fprintf(fp, "%-16d %s\n", syn->chroma_qp_index_offset, "chroma_qp_index_offset"); - fprintf(fp, "%-16d %s\n", syn->filter_disable, "filter_disable"); - fprintf(fp, "%-16d %s\n", syn->idr_pic_id, "idr_pic_id"); - fprintf(fp, "%-16d %s\n", syn->pps_id, "pps_id"); - fprintf(fp, "%-16d %s\n", syn->frame_num, "frame_num"); - fprintf(fp, "%-16d %s\n", syn->slice_size_mb_rows, "slice_size_mb_rows"); - fprintf(fp, "%-16d %s\n", syn->h264_inter4x4_disabled, "h264_inter4x4_disabled"); - fprintf(fp, "%-16d %s\n", syn->enable_cabac, "enable_cabac"); - fprintf(fp, "%-16d %s\n", syn->transform8x8_mode, "transform8x8_mode"); - fprintf(fp, "%-16d %s\n", syn->cabac_init_idc, "cabac_init_idc"); - fprintf(fp, "%-16d %s\n", syn->qp, "qp"); - fprintf(fp, "%-16d %s\n", syn->mad_qp_delta, "mad_qp_delta"); - fprintf(fp, "%-16d %s\n", syn->mad_threshold, "mad_threshold"); - fprintf(fp, "%-16d %s\n", syn->qp_min, "qp_min"); - fprintf(fp, "%-16d %s\n", syn->qp_max, "qp_max"); - fprintf(fp, "%-16d %s\n", syn->cp_distance_mbs, "cp_distance_mbs"); - for (k = 0; k < 10; k++) - fprintf(fp, "%-16d cp_target[%d]\n", syn->cp_target[k], k); - for (k = 0; k < 7; k++) - fprintf(fp, "%-16d target_error[%d]\n", syn->target_error[k], k); - for (k = 0; k < 7; k++) - fprintf(fp, "%-16d delta_qp[%d]\n", syn->delta_qp[k], k); - fprintf(fp, "%-16d %s\n", syn->output_strm_limit_size, "output_strm_limit_size"); - fprintf(fp, "%-16d %s\n", syn->pic_luma_width, "pic_luma_width"); - fprintf(fp, "%-16d %s\n", syn->pic_luma_height, "pic_luma_height"); - fprintf(fp, "%-16d %s\n", syn->input_image_format, "input_image_format"); - - fprintf(fp, "%-16d %s\n", syn->color_conversion_coeff_a, "color_conversion_coeff_a"); - fprintf(fp, "%-16d %s\n", syn->color_conversion_coeff_b, "color_conversion_coeff_b"); - fprintf(fp, "%-16d %s\n", syn->color_conversion_coeff_c, "color_conversion_coeff_c"); - fprintf(fp, "%-16d %s\n", syn->color_conversion_coeff_e, "color_conversion_coeff_e"); - fprintf(fp, "%-16d %s\n", syn->color_conversion_coeff_f, "color_conversion_coeff_f"); - fprintf(fp, "%-16d %s\n", syn->color_conversion_r_mask_msb, "color_conversion_r_mask_msb"); - fprintf(fp, "%-16d %s\n", syn->color_conversion_g_mask_msb, "color_conversion_g_mask_msb"); - fprintf(fp, "%-16d %s\n", syn->color_conversion_b_mask_msb, "color_conversion_b_mask_msb"); - - fprintf(fp, "\n"); - fflush(fp); - } else { - mpp_log("try to dump data to mpp_syntax_in.txt, but file is not opened"); - } -} - -static void hal_h264e_vpu_dump_mpp_reg_in(h264e_hal_context *ctx) -{ - h264e_hal_vpu_dump_files *dump_files = (h264e_hal_vpu_dump_files *)ctx->dump_files; - FILE *fp = dump_files->fp_mpp_reg_in; - if (fp) { - RK_S32 k = 0; - RK_U32 *reg = (RK_U32 *)ctx->regs; - fprintf(fp, "#FRAME %d:\n", ctx->frame_cnt); - for (k = 0; k < VEPU_H264E_NUM_REGS; k++) { - fprintf(fp, "reg[%03d/%03x]: %08x\n", k, k * 4, reg[k]); - //mpp_log("reg[%03d/%03x]: %08x", k, k*4, reg[k]); - } - fprintf(fp, "\n"); - } else { - mpp_log("try to dump data to mpp_reg_in.txt, but file is not opened"); - } -} - -static void hal_h264e_vpu_dump_mpp_reg_out(h264e_hal_context *ctx) -{ - h264e_hal_vpu_dump_files *dump_files = (h264e_hal_vpu_dump_files *)ctx->dump_files; - FILE *fp = dump_files->fp_mpp_reg_out; - if (fp) { - RK_S32 k = 0; - RK_U32 *reg = (RK_U32 *)ctx->regs; - fprintf(fp, "#FRAME %d:\n", ctx->frame_cnt - 1); - for (k = 0; k < VEPU_H264E_NUM_REGS; k++) { - fprintf(fp, "reg[%03d/%03x]: %08x\n", k, k * 4, reg[k]); - //mpp_log("reg[%03d/%03x]: %08x", k, k*4, reg[k]); - } - fprintf(fp, "\n"); - } else { - mpp_log("try to dump data to mpp_reg_in.txt, but file is not opened"); - } -} - -static void hal_h264e_vpu_dump_mpp_feedback(h264e_hal_context *ctx) -{ - h264e_hal_vpu_dump_files *dump_files = (h264e_hal_vpu_dump_files *)ctx->dump_files; - FILE *fp = dump_files->fp_mpp_feedback; - if (fp) { - RK_S32 k = 0; - h264e_feedback *fb = &ctx->feedback; - fprintf(fp, "#FRAME %d:\n", ctx->frame_cnt - 1); - fprintf(fp, "%-16d %s\n", fb->hw_status, "hw_status"); - fprintf(fp, "%-16d %s\n", fb->out_strm_size, "out_strm_size"); - fprintf(fp, "%-16d %s\n", fb->qp_sum, "qp_sum"); - for (k = 0; k < 10; k++) - fprintf(fp, "%-16d cp[%d]\n", fb->cp[k], k); - fprintf(fp, "%-16d %s\n", fb->mad_count, "mad_count"); - fprintf(fp, "%-16d %s\n", fb->rlc_count, "rlc_count"); - - fprintf(fp, "\n"); - fflush(fp); - } else { - mpp_log("try to dump data to mpp_feedback.txt, but file is not opened"); - } -} - -static void hal_h264e_vpu_dump_mpp_strm_out_header(h264e_hal_context *ctx, MppPacket packet) -{ - h264e_hal_vpu_dump_files *dump_files = (h264e_hal_vpu_dump_files *)ctx->dump_files; - void *ptr = mpp_packet_get_data(packet); - size_t len = mpp_packet_get_length(packet); - FILE *fp = dump_files->fp_mpp_strm_out; - - if (fp) { - fwrite(ptr, 1, len, fp); - fflush(fp); - } else { - mpp_log("try to dump strm header to mpp_strm_out.txt, but file is not opened"); - } -} - -void hal_h264e_vpu_dump_mpp_strm_out(h264e_hal_context *ctx, MppBuffer hw_buf) -{ - h264e_hal_vpu_dump_files *dump_files = (h264e_hal_vpu_dump_files *)ctx->dump_files; - FILE *fp = dump_files->fp_mpp_strm_out; - if (fp && hw_buf) { - RK_U32 *reg_val = (RK_U32 *)ctx->regs; - RK_U32 strm_size = reg_val[VEPU_REG_STR_BUF_LIMIT / 4] / 8; - - RK_U8 *hw_buf_vir_addr = (RK_U8 *)mpp_buffer_get_ptr(hw_buf); - - mpp_log("strm_size: %d", strm_size); - - fwrite(hw_buf_vir_addr, 1, strm_size, fp); - fflush(fp); - } else { - mpp_log("try to dump data to mpp_strm_out.txt, but file is not opened"); - } -} -#endif - -static h264e_hal_vpu_csp_info hal_h264e_vpu_convert_csp(RK_S32 src_type) -{ - MppFrameFormat src_fmt = (MppFrameFormat)src_type; - h264e_hal_vpu_csp_info dst_info; - dst_info.fmt = 0; - dst_info.r_mask_msb = 0; - dst_info.g_mask_msb = 0; - dst_info.b_mask_msb = 0; - - switch (src_fmt) { - case MPP_FMT_YUV420P: { - dst_info.fmt = H264E_VPU_CSP_YUV420P; - break; - } - case MPP_FMT_YUV420SP: { - dst_info.fmt = H264E_VPU_CSP_YUV420SP; - break; - } - case MPP_FMT_YUV420SP_10BIT: { - dst_info.fmt = H264E_VPU_CSP_NONE; - break; - } - case MPP_FMT_YUV420SP_VU: { //TODO: to be confirmed - dst_info.fmt = H264E_VPU_CSP_NONE; - break; - } - case MPP_FMT_YUV422P: { - dst_info.fmt = H264E_VPU_CSP_NONE; - break; - } - case MPP_FMT_YUV422SP: { - dst_info.fmt = H264E_VPU_CSP_NONE; - break; - } - case MPP_FMT_YUV422SP_10BIT: { - dst_info.fmt = H264E_VPU_CSP_NONE; - break; - } - case MPP_FMT_YUV422SP_VU: { - dst_info.fmt = H264E_VPU_CSP_NONE; - break; - } - case MPP_FMT_YUV422_YUYV: { - dst_info.fmt = H264E_VPU_CSP_YUYV422; - break; - } - case MPP_FMT_YUV422_UYVY: { - dst_info.fmt = H264E_VPU_CSP_UYVY422; - break; - } - case MPP_FMT_RGB565: { - dst_info.fmt = H264E_VPU_CSP_RGB565; - dst_info.r_mask_msb = 15; - dst_info.g_mask_msb = 10; - dst_info.b_mask_msb = 4; - break; - } - case MPP_FMT_BGR565: { - dst_info.fmt = H264E_VPU_CSP_RGB565; - dst_info.r_mask_msb = 4; - dst_info.g_mask_msb = 10; +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define MODULE_TAG "hal_h264e_vpu" +#include +#include "vpu.h" +#include "rk_mpi.h" +#include "mpp_mem.h" +#include "mpp_frame.h" +#include "hal_h264e.h" +#include "hal_h264e_vpu.h" + + +/* H.264 motion estimation parameters */ +static const RK_U32 h264_prev_mode_favor[52] = { + 7, 7, 8, 8, 9, 9, 10, 10, 11, 12, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 24, 25, 27, 29, 30, 32, 34, 36, 38, 41, 43, 46, + 49, 51, 55, 58, 61, 65, 69, 73, 78, 82, 87, 93, 98, 104, 110, + 117, 124, 132, 140 +}; + +/* sqrt(2^((qp-12)/3))*8 */ +static const RK_U32 h264_diff_mv_penalty[52] = { + 2, 2, 3, 3, 3, 4, 4, 4, 5, 6, + 6, 7, 8, 9, 10, 11, 13, 14, 16, 18, + 20, 23, 26, 29, 32, 36, 40, 45, 51, 57, + 64, 72, 81, 91, 102, 114, 128, 144, 161, 181, + 203, 228, 256, 287, 323, 362, 406, 456, 512, 575, + 645, 724 +}; + +/* 31*sqrt(2^((qp-12)/3))/4 */ +static const RK_U32 h264_diff_mv_penalty4p[52] = { + 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, + 6, 7, 8, 9, 10, 11, 12, 14, 16, 17, + 20, 22, 25, 28, 31, 35, 39, 44, 49, 55, + 62, 70, 78, 88, 98, 110, 124, 139, 156, 175, + 197, 221, 248, 278, 312, 351, 394, 442, 496, 557, + 625, 701 +}; + +static const RK_U32 h264_intra16_favor[52] = { + 24, 24, 24, 26, 27, 30, 32, 35, 39, 43, 48, 53, 58, 64, 71, 78, + 85, 93, 102, 111, 121, 131, 142, 154, 167, 180, 195, 211, 229, + 248, 271, 296, 326, 361, 404, 457, 523, 607, 714, 852, 1034, + 1272, 1588, 2008, 2568, 3318, 4323, 5672, 7486, 9928, 13216, + 17648 +}; + +static const RK_U32 h264_inter_favor[52] = { + 40, 40, 41, 42, 43, 44, 45, 48, 51, 53, 55, 60, 62, 67, 69, 72, + 78, 84, 90, 96, 110, 120, 135, 152, 170, 189, 210, 235, 265, + 297, 335, 376, 420, 470, 522, 572, 620, 670, 724, 770, 820, + 867, 915, 970, 1020, 1076, 1132, 1180, 1230, 1275, 1320, 1370 +}; + +static RK_U32 h264_skip_sad_penalty[52] = { + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 233, 205, 182, 163, + 146, 132, 120, 109, 100, 92, 84, 78, 71, 66, 61, 56, 52, 48, + 44, 41, 38, 35, 32, 30, 27, 25, 23, 21, 19, 17, 15, 14, + 12, 11, 9, 8, 7, 5, 4, 3, 2, 1 +}; + +const RK_S32 h264_context_init_intra[460][2] = { + /* 0 -> 10 */ + { 20, -15 }, { 2, 54 }, { 3, 74 }, { 20, -15 }, + { 2, 54 }, { 3, 74 }, { -28, 127 }, { -23, 104 }, + { -6, 53 }, { -1, 54 }, { 7, 51 }, + + /* 11 -> 23 unsused for I */ + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, + + /* 24 -> 39 */ + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + + /* 40 -> 53 */ + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, + + /* 54 -> 59 */ + { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, + + /* 60 -> 69 */ + { 0, 41 }, { 0, 63 }, { 0, 63 }, { 0, 63 }, + { -9, 83 }, { 4, 86 }, { 0, 97 }, { -7, 72 }, + { 13, 41 }, { 3, 62 }, + + /* 70 -> 87 */ + { 0, 11 }, { 1, 55 }, { 0, 69 }, { -17, 127 }, + { -13, 102 }, { 0, 82 }, { -7, 74 }, { -21, 107 }, + { -27, 127 }, { -31, 127 }, { -24, 127 }, { -18, 95 }, + { -27, 127 }, { -21, 114 }, { -30, 127 }, { -17, 123 }, + { -12, 115 }, { -16, 122 }, + + /* 88 -> 104 */ + { -11, 115 }, { -12, 63 }, { -2, 68 }, { -15, 84 }, + { -13, 104 }, { -3, 70 }, { -8, 93 }, { -10, 90 }, + { -30, 127 }, { -1, 74 }, { -6, 97 }, { -7, 91 }, + { -20, 127 }, { -4, 56 }, { -5, 82 }, { -7, 76 }, + { -22, 125 }, + + /* 105 -> 135 */ + { -7, 93 }, { -11, 87 }, { -3, 77 }, { -5, 71 }, + { -4, 63 }, { -4, 68 }, { -12, 84 }, { -7, 62 }, + { -7, 65 }, { 8, 61 }, { 5, 56 }, { -2, 66 }, + { 1, 64 }, { 0, 61 }, { -2, 78 }, { 1, 50 }, + { 7, 52 }, { 10, 35 }, { 0, 44 }, { 11, 38 }, + { 1, 45 }, { 0, 46 }, { 5, 44 }, { 31, 17 }, + { 1, 51 }, { 7, 50 }, { 28, 19 }, { 16, 33 }, + { 14, 62 }, { -13, 108 }, { -15, 100 }, + + /* 136 -> 165 */ + { -13, 101 }, { -13, 91 }, { -12, 94 }, { -10, 88 }, + { -16, 84 }, { -10, 86 }, { -7, 83 }, { -13, 87 }, + { -19, 94 }, { 1, 70 }, { 0, 72 }, { -5, 74 }, + { 18, 59 }, { -8, 102 }, { -15, 100 }, { 0, 95 }, + { -4, 75 }, { 2, 72 }, { -11, 75 }, { -3, 71 }, + { 15, 46 }, { -13, 69 }, { 0, 62 }, { 0, 65 }, + { 21, 37 }, { -15, 72 }, { 9, 57 }, { 16, 54 }, + { 0, 62 }, { 12, 72 }, + + /* 166 -> 196 */ + { 24, 0 }, { 15, 9 }, { 8, 25 }, { 13, 18 }, + { 15, 9 }, { 13, 19 }, { 10, 37 }, { 12, 18 }, + { 6, 29 }, { 20, 33 }, { 15, 30 }, { 4, 45 }, + { 1, 58 }, { 0, 62 }, { 7, 61 }, { 12, 38 }, + { 11, 45 }, { 15, 39 }, { 11, 42 }, { 13, 44 }, + { 16, 45 }, { 12, 41 }, { 10, 49 }, { 30, 34 }, + { 18, 42 }, { 10, 55 }, { 17, 51 }, { 17, 46 }, + { 0, 89 }, { 26, -19 }, { 22, -17 }, + + /* 197 -> 226 */ + { 26, -17 }, { 30, -25 }, { 28, -20 }, { 33, -23 }, + { 37, -27 }, { 33, -23 }, { 40, -28 }, { 38, -17 }, + { 33, -11 }, { 40, -15 }, { 41, -6 }, { 38, 1 }, + { 41, 17 }, { 30, -6 }, { 27, 3 }, { 26, 22 }, + { 37, -16 }, { 35, -4 }, { 38, -8 }, { 38, -3 }, + { 37, 3 }, { 38, 5 }, { 42, 0 }, { 35, 16 }, + { 39, 22 }, { 14, 48 }, { 27, 37 }, { 21, 60 }, + { 12, 68 }, { 2, 97 }, + + /* 227 -> 251 */ + { -3, 71 }, { -6, 42 }, { -5, 50 }, { -3, 54 }, + { -2, 62 }, { 0, 58 }, { 1, 63 }, { -2, 72 }, + { -1, 74 }, { -9, 91 }, { -5, 67 }, { -5, 27 }, + { -3, 39 }, { -2, 44 }, { 0, 46 }, { -16, 64 }, + { -8, 68 }, { -10, 78 }, { -6, 77 }, { -10, 86 }, + { -12, 92 }, { -15, 55 }, { -10, 60 }, { -6, 62 }, + { -4, 65 }, + + /* 252 -> 275 */ + { -12, 73 }, { -8, 76 }, { -7, 80 }, { -9, 88 }, + { -17, 110 }, { -11, 97 }, { -20, 84 }, { -11, 79 }, + { -6, 73 }, { -4, 74 }, { -13, 86 }, { -13, 96 }, + { -11, 97 }, { -19, 117 }, { -8, 78 }, { -5, 33 }, + { -4, 48 }, { -2, 53 }, { -3, 62 }, { -13, 71 }, + { -10, 79 }, { -12, 86 }, { -13, 90 }, { -14, 97 }, + + /* 276 special case, bypass used */ + { 0, 0 }, + + /* 277 -> 307 */ + { -6, 93 }, { -6, 84 }, { -8, 79 }, { 0, 66 }, + { -1, 71 }, { 0, 62 }, { -2, 60 }, { -2, 59 }, + { -5, 75 }, { -3, 62 }, { -4, 58 }, { -9, 66 }, + { -1, 79 }, { 0, 71 }, { 3, 68 }, { 10, 44 }, + { -7, 62 }, { 15, 36 }, { 14, 40 }, { 16, 27 }, + { 12, 29 }, { 1, 44 }, { 20, 36 }, { 18, 32 }, + { 5, 42 }, { 1, 48 }, { 10, 62 }, { 17, 46 }, + { 9, 64 }, { -12, 104 }, { -11, 97 }, + + /* 308 -> 337 */ + { -16, 96 }, { -7, 88 }, { -8, 85 }, { -7, 85 }, + { -9, 85 }, { -13, 88 }, { 4, 66 }, { -3, 77 }, + { -3, 76 }, { -6, 76 }, { 10, 58 }, { -1, 76 }, + { -1, 83 }, { -7, 99 }, { -14, 95 }, { 2, 95 }, + { 0, 76 }, { -5, 74 }, { 0, 70 }, { -11, 75 }, + { 1, 68 }, { 0, 65 }, { -14, 73 }, { 3, 62 }, + { 4, 62 }, { -1, 68 }, { -13, 75 }, { 11, 55 }, + { 5, 64 }, { 12, 70 }, + + /* 338 -> 368 */ + { 15, 6 }, { 6, 19 }, { 7, 16 }, { 12, 14 }, + { 18, 13 }, { 13, 11 }, { 13, 15 }, { 15, 16 }, + { 12, 23 }, { 13, 23 }, { 15, 20 }, { 14, 26 }, + { 14, 44 }, { 17, 40 }, { 17, 47 }, { 24, 17 }, + { 21, 21 }, { 25, 22 }, { 31, 27 }, { 22, 29 }, + { 19, 35 }, { 14, 50 }, { 10, 57 }, { 7, 63 }, + { -2, 77 }, { -4, 82 }, { -3, 94 }, { 9, 69 }, + { -12, 109 }, { 36, -35 }, { 36, -34 }, + + /* 369 -> 398 */ + { 32, -26 }, { 37, -30 }, { 44, -32 }, { 34, -18 }, + { 34, -15 }, { 40, -15 }, { 33, -7 }, { 35, -5 }, + { 33, 0 }, { 38, 2 }, { 33, 13 }, { 23, 35 }, + { 13, 58 }, { 29, -3 }, { 26, 0 }, { 22, 30 }, + { 31, -7 }, { 35, -15 }, { 34, -3 }, { 34, 3 }, + { 36, -1 }, { 34, 5 }, { 32, 11 }, { 35, 5 }, + { 34, 12 }, { 39, 11 }, { 30, 29 }, { 34, 26 }, + { 29, 39 }, { 19, 66 }, + + /* 399 -> 435 */ + { 31, 21 }, { 31, 31 }, { 25, 50 }, + { -17, 120 }, { -20, 112 }, { -18, 114 }, { -11, 85 }, + { -15, 92 }, { -14, 89 }, { -26, 71 }, { -15, 81 }, + { -14, 80 }, { 0, 68 }, { -14, 70 }, { -24, 56 }, + { -23, 68 }, { -24, 50 }, { -11, 74 }, { 23, -13 }, + { 26, -13 }, { 40, -15 }, { 49, -14 }, { 44, 3 }, + { 45, 6 }, { 44, 34 }, { 33, 54 }, { 19, 82 }, + { -3, 75 }, { -1, 23 }, { 1, 34 }, { 1, 43 }, + { 0, 54 }, { -2, 55 }, { 0, 61 }, { 1, 64 }, + { 0, 68 }, { -9, 92 }, + + /* 436 -> 459 */ + { -14, 106 }, { -13, 97 }, { -15, 90 }, { -12, 90 }, + { -18, 88 }, { -10, 73 }, { -9, 79 }, { -14, 86 }, + { -10, 73 }, { -10, 70 }, { -10, 69 }, { -5, 66 }, + { -9, 64 }, { -5, 58 }, { 2, 59 }, { 21, -10 }, + { 24, -11 }, { 28, -8 }, { 28, -1 }, { 29, 3 }, + { 29, 9 }, { 35, 20 }, { 29, 36 }, { 14, 67 } +}; + +const RK_S32 h264_context_init[3][460][2] = { + /* cabac_init_idc == 0 */ + { + /* 0 -> 10 */ + { 20, -15 }, { 2, 54 }, { 3, 74 }, { 20, -15 }, + { 2, 54 }, { 3, 74 }, { -28, 127 }, { -23, 104 }, + { -6, 53 }, { -1, 54 }, { 7, 51 }, + + /* 11 -> 23 */ + { 23, 33 }, { 23, 2 }, { 21, 0 }, { 1, 9 }, + { 0, 49 }, { -37, 118 }, { 5, 57 }, { -13, 78 }, + { -11, 65 }, { 1, 62 }, { 12, 49 }, { -4, 73 }, + { 17, 50 }, + + /* 24 -> 39 */ + { 18, 64 }, { 9, 43 }, { 29, 0 }, { 26, 67 }, + { 16, 90 }, { 9, 104 }, { -46, 127 }, { -20, 104 }, + { 1, 67 }, { -13, 78 }, { -11, 65 }, { 1, 62 }, + { -6, 86 }, { -17, 95 }, { -6, 61 }, { 9, 45 }, + + /* 40 -> 53 */ + { -3, 69 }, { -6, 81 }, { -11, 96 }, { 6, 55 }, + { 7, 67 }, { -5, 86 }, { 2, 88 }, { 0, 58 }, + { -3, 76 }, { -10, 94 }, { 5, 54 }, { 4, 69 }, + { -3, 81 }, { 0, 88 }, + + /* 54 -> 59 */ + { -7, 67 }, { -5, 74 }, { -4, 74 }, { -5, 80 }, + { -7, 72 }, { 1, 58 }, + + /* 60 -> 69 */ + { 0, 41 }, { 0, 63 }, { 0, 63 }, { 0, 63 }, + { -9, 83 }, { 4, 86 }, { 0, 97 }, { -7, 72 }, + { 13, 41 }, { 3, 62 }, + + /* 70 -> 87 */ + { 0, 45 }, { -4, 78 }, { -3, 96 }, { -27, 126 }, + { -28, 98 }, { -25, 101 }, { -23, 67 }, { -28, 82 }, + { -20, 94 }, { -16, 83 }, { -22, 110 }, { -21, 91 }, + { -18, 102 }, { -13, 93 }, { -29, 127 }, { -7, 92 }, + { -5, 89 }, { -7, 96 }, { -13, 108 }, { -3, 46 }, + { -1, 65 }, { -1, 57 }, { -9, 93 }, { -3, 74 }, + { -9, 92 }, { -8, 87 }, { -23, 126 }, { 5, 54 }, + { 6, 60 }, { 6, 59 }, { 6, 69 }, { -1, 48 }, + { 0, 68 }, { -4, 69 }, { -8, 88 }, + + /* 105 -> 165 */ + { -2, 85 }, { -6, 78 }, { -1, 75 }, { -7, 77 }, + { 2, 54 }, { 5, 50 }, { -3, 68 }, { 1, 50 }, + { 6, 42 }, { -4, 81 }, { 1, 63 }, { -4, 70 }, + { 0, 67 }, { 2, 57 }, { -2, 76 }, { 11, 35 }, + { 4, 64 }, { 1, 61 }, { 11, 35 }, { 18, 25 }, + { 12, 24 }, { 13, 29 }, { 13, 36 }, { -10, 93 }, + { -7, 73 }, { -2, 73 }, { 13, 46 }, { 9, 49 }, + { -7, 100 }, { 9, 53 }, { 2, 53 }, { 5, 53 }, + { -2, 61 }, { 0, 56 }, { 0, 56 }, { -13, 63 }, + { -5, 60 }, { -1, 62 }, { 4, 57 }, { -6, 69 }, + { 4, 57 }, { 14, 39 }, { 4, 51 }, { 13, 68 }, + { 3, 64 }, { 1, 61 }, { 9, 63 }, { 7, 50 }, + { 16, 39 }, { 5, 44 }, { 4, 52 }, { 11, 48 }, + { -5, 60 }, { -1, 59 }, { 0, 59 }, { 22, 33 }, + { 5, 44 }, { 14, 43 }, { -1, 78 }, { 0, 60 }, + { 9, 69 }, + + /* 166 -> 226 */ + { 11, 28 }, { 2, 40 }, { 3, 44 }, { 0, 49 }, + { 0, 46 }, { 2, 44 }, { 2, 51 }, { 0, 47 }, + { 4, 39 }, { 2, 62 }, { 6, 46 }, { 0, 54 }, + { 3, 54 }, { 2, 58 }, { 4, 63 }, { 6, 51 }, + { 6, 57 }, { 7, 53 }, { 6, 52 }, { 6, 55 }, + { 11, 45 }, { 14, 36 }, { 8, 53 }, { -1, 82 }, + { 7, 55 }, { -3, 78 }, { 15, 46 }, { 22, 31 }, + { -1, 84 }, { 25, 7 }, { 30, -7 }, { 28, 3 }, + { 28, 4 }, { 32, 0 }, { 34, -1 }, { 30, 6 }, + { 30, 6 }, { 32, 9 }, { 31, 19 }, { 26, 27 }, + { 26, 30 }, { 37, 20 }, { 28, 34 }, { 17, 70 }, + { 1, 67 }, { 5, 59 }, { 9, 67 }, { 16, 30 }, + { 18, 32 }, { 18, 35 }, { 22, 29 }, { 24, 31 }, + { 23, 38 }, { 18, 43 }, { 20, 41 }, { 11, 63 }, + { 9, 59 }, { 9, 64 }, { -1, 94 }, { -2, 89 }, + { -9, 108 }, + + /* 227 -> 275 */ + { -6, 76 }, { -2, 44 }, { 0, 45 }, { 0, 52 }, + { -3, 64 }, { -2, 59 }, { -4, 70 }, { -4, 75 }, + { -8, 82 }, { -17, 102 }, { -9, 77 }, { 3, 24 }, + { 0, 42 }, { 0, 48 }, { 0, 55 }, { -6, 59 }, + { -7, 71 }, { -12, 83 }, { -11, 87 }, { -30, 119 }, + { 1, 58 }, { -3, 29 }, { -1, 36 }, { 1, 38 }, + { 2, 43 }, { -6, 55 }, { 0, 58 }, { 0, 64 }, + { -3, 74 }, { -10, 90 }, { 0, 70 }, { -4, 29 }, + { 5, 31 }, { 7, 42 }, { 1, 59 }, { -2, 58 }, + { -3, 72 }, { -3, 81 }, { -11, 97 }, { 0, 58 }, + { 8, 5 }, { 10, 14 }, { 14, 18 }, { 13, 27 }, + { 2, 40 }, { 0, 58 }, { -3, 70 }, { -6, 79 }, + { -8, 85 }, + + /* 276 special case, bypass used */ + { 0, 0 }, + + /* 277 -> 337 */ + { -13, 106 }, { -16, 106 }, { -10, 87 }, { -21, 114 }, + { -18, 110 }, { -14, 98 }, { -22, 110 }, { -21, 106 }, + { -18, 103 }, { -21, 107 }, { -23, 108 }, { -26, 112 }, + { -10, 96 }, { -12, 95 }, { -5, 91 }, { -9, 93 }, + { -22, 94 }, { -5, 86 }, { 9, 67 }, { -4, 80 }, + { -10, 85 }, { -1, 70 }, { 7, 60 }, { 9, 58 }, + { 5, 61 }, { 12, 50 }, { 15, 50 }, { 18, 49 }, + { 17, 54 }, { 10, 41 }, { 7, 46 }, { -1, 51 }, + { 7, 49 }, { 8, 52 }, { 9, 41 }, { 6, 47 }, + { 2, 55 }, { 13, 41 }, { 10, 44 }, { 6, 50 }, + { 5, 53 }, { 13, 49 }, { 4, 63 }, { 6, 64 }, + { -2, 69 }, { -2, 59 }, { 6, 70 }, { 10, 44 }, + { 9, 31 }, { 12, 43 }, { 3, 53 }, { 14, 34 }, + { 10, 38 }, { -3, 52 }, { 13, 40 }, { 17, 32 }, + { 7, 44 }, { 7, 38 }, { 13, 50 }, { 10, 57 }, + { 26, 43 }, + + /* 338 -> 398 */ + { 14, 11 }, { 11, 14 }, { 9, 11 }, { 18, 11 }, + { 21, 9 }, { 23, -2 }, { 32, -15 }, { 32, -15 }, + { 34, -21 }, { 39, -23 }, { 42, -33 }, { 41, -31 }, + { 46, -28 }, { 38, -12 }, { 21, 29 }, { 45, -24 }, + { 53, -45 }, { 48, -26 }, { 65, -43 }, { 43, -19 }, + { 39, -10 }, { 30, 9 }, { 18, 26 }, { 20, 27 }, + { 0, 57 }, { -14, 82 }, { -5, 75 }, { -19, 97 }, + { -35, 125 }, { 27, 0 }, { 28, 0 }, { 31, -4 }, + { 27, 6 }, { 34, 8 }, { 30, 10 }, { 24, 22 }, + { 33, 19 }, { 22, 32 }, { 26, 31 }, { 21, 41 }, + { 26, 44 }, { 23, 47 }, { 16, 65 }, { 14, 71 }, + { 8, 60 }, { 6, 63 }, { 17, 65 }, { 21, 24 }, + { 23, 20 }, { 26, 23 }, { 27, 32 }, { 28, 23 }, + { 28, 24 }, { 23, 40 }, { 24, 32 }, { 28, 29 }, + { 23, 42 }, { 19, 57 }, { 22, 53 }, { 22, 61 }, + { 11, 86 }, + + /* 399 -> 435 */ + { 12, 40 }, { 11, 51 }, { 14, 59 }, + { -4, 79 }, { -7, 71 }, { -5, 69 }, { -9, 70 }, + { -8, 66 }, { -10, 68 }, { -19, 73 }, { -12, 69 }, + { -16, 70 }, { -15, 67 }, { -20, 62 }, { -19, 70 }, + { -16, 66 }, { -22, 65 }, { -20, 63 }, { 9, -2 }, + { 26, -9 }, { 33, -9 }, { 39, -7 }, { 41, -2 }, + { 45, 3 }, { 49, 9 }, { 45, 27 }, { 36, 59 }, + { -6, 66 }, { -7, 35 }, { -7, 42 }, { -8, 45 }, + { -5, 48 }, { -12, 56 }, { -6, 60 }, { -5, 62 }, + { -8, 66 }, { -8, 76 }, + + /* 436 -> 459 */ + { -5, 85 }, { -6, 81 }, { -10, 77 }, { -7, 81 }, + { -17, 80 }, { -18, 73 }, { -4, 74 }, { -10, 83 }, + { -9, 71 }, { -9, 67 }, { -1, 61 }, { -8, 66 }, + { -14, 66 }, { 0, 59 }, { 2, 59 }, { 21, -13 }, + { 33, -14 }, { 39, -7 }, { 46, -2 }, { 51, 2 }, + { 60, 6 }, { 61, 17 }, { 55, 34 }, { 42, 62 }, + }, + + /* cabac_init_idc == 1 */ + { + /* 0 -> 10 */ + { 20, -15 }, { 2, 54 }, { 3, 74 }, { 20, -15 }, + { 2, 54 }, { 3, 74 }, { -28, 127 }, { -23, 104 }, + { -6, 53 }, { -1, 54 }, { 7, 51 }, + + /* 11 -> 23 */ + { 22, 25 }, { 34, 0 }, { 16, 0 }, { -2, 9 }, + { 4, 41 }, { -29, 118 }, { 2, 65 }, { -6, 71 }, + { -13, 79 }, { 5, 52 }, { 9, 50 }, { -3, 70 }, + { 10, 54 }, + + /* 24 -> 39 */ + { 26, 34 }, { 19, 22 }, { 40, 0 }, { 57, 2 }, + { 41, 36 }, { 26, 69 }, { -45, 127 }, { -15, 101 }, + { -4, 76 }, { -6, 71 }, { -13, 79 }, { 5, 52 }, + { 6, 69 }, { -13, 90 }, { 0, 52 }, { 8, 43 }, + + /* 40 -> 53 */ + { -2, 69 }, { -5, 82 }, { -10, 96 }, { 2, 59 }, + { 2, 75 }, { -3, 87 }, { -3, 100 }, { 1, 56 }, + { -3, 74 }, { -6, 85 }, { 0, 59 }, { -3, 81 }, + { -7, 86 }, { -5, 95 }, + + /* 54 -> 59 */ + { -1, 66 }, { -1, 77 }, { 1, 70 }, { -2, 86 }, + { -5, 72 }, { 0, 61 }, + + /* 60 -> 69 */ + { 0, 41 }, { 0, 63 }, { 0, 63 }, { 0, 63 }, + { -9, 83 }, { 4, 86 }, { 0, 97 }, { -7, 72 }, + { 13, 41 }, { 3, 62 }, + + /* 70 -> 104 */ + { 13, 15 }, { 7, 51 }, { 2, 80 }, { -39, 127 }, + { -18, 91 }, { -17, 96 }, { -26, 81 }, { -35, 98 }, + { -24, 102 }, { -23, 97 }, { -27, 119 }, { -24, 99 }, + { -21, 110 }, { -18, 102 }, { -36, 127 }, { 0, 80 }, + { -5, 89 }, { -7, 94 }, { -4, 92 }, { 0, 39 }, + { 0, 65 }, { -15, 84 }, { -35, 127 }, { -2, 73 }, + { -12, 104 }, { -9, 91 }, { -31, 127 }, { 3, 55 }, + { 7, 56 }, { 7, 55 }, { 8, 61 }, { -3, 53 }, + { 0, 68 }, { -7, 74 }, { -9, 88 }, + + /* 105 -> 165 */ + { -13, 103 }, { -13, 91 }, { -9, 89 }, { -14, 92 }, + { -8, 76 }, { -12, 87 }, { -23, 110 }, { -24, 105 }, + { -10, 78 }, { -20, 112 }, { -17, 99 }, { -78, 127 }, + { -70, 127 }, { -50, 127 }, { -46, 127 }, { -4, 66 }, + { -5, 78 }, { -4, 71 }, { -8, 72 }, { 2, 59 }, + { -1, 55 }, { -7, 70 }, { -6, 75 }, { -8, 89 }, + { -34, 119 }, { -3, 75 }, { 32, 20 }, { 30, 22 }, + { -44, 127 }, { 0, 54 }, { -5, 61 }, { 0, 58 }, + { -1, 60 }, { -3, 61 }, { -8, 67 }, { -25, 84 }, + { -14, 74 }, { -5, 65 }, { 5, 52 }, { 2, 57 }, + { 0, 61 }, { -9, 69 }, { -11, 70 }, { 18, 55 }, + { -4, 71 }, { 0, 58 }, { 7, 61 }, { 9, 41 }, + { 18, 25 }, { 9, 32 }, { 5, 43 }, { 9, 47 }, + { 0, 44 }, { 0, 51 }, { 2, 46 }, { 19, 38 }, + { -4, 66 }, { 15, 38 }, { 12, 42 }, { 9, 34 }, + { 0, 89 }, + + /* 166 -> 226 */ + { 4, 45 }, { 10, 28 }, { 10, 31 }, { 33, -11 }, + { 52, -43 }, { 18, 15 }, { 28, 0 }, { 35, -22 }, + { 38, -25 }, { 34, 0 }, { 39, -18 }, { 32, -12 }, + { 102, -94 }, { 0, 0 }, { 56, -15 }, { 33, -4 }, + { 29, 10 }, { 37, -5 }, { 51, -29 }, { 39, -9 }, + { 52, -34 }, { 69, -58 }, { 67, -63 }, { 44, -5 }, + { 32, 7 }, { 55, -29 }, { 32, 1 }, { 0, 0 }, + { 27, 36 }, { 33, -25 }, { 34, -30 }, { 36, -28 }, + { 38, -28 }, { 38, -27 }, { 34, -18 }, { 35, -16 }, + { 34, -14 }, { 32, -8 }, { 37, -6 }, { 35, 0 }, + { 30, 10 }, { 28, 18 }, { 26, 25 }, { 29, 41 }, + { 0, 75 }, { 2, 72 }, { 8, 77 }, { 14, 35 }, + { 18, 31 }, { 17, 35 }, { 21, 30 }, { 17, 45 }, + { 20, 42 }, { 18, 45 }, { 27, 26 }, { 16, 54 }, + { 7, 66 }, { 16, 56 }, { 11, 73 }, { 10, 67 }, + { -10, 116 }, + + /* 227 -> 275 */ + { -23, 112 }, { -15, 71 }, { -7, 61 }, { 0, 53 }, + { -5, 66 }, { -11, 77 }, { -9, 80 }, { -9, 84 }, + { -10, 87 }, { -34, 127 }, { -21, 101 }, { -3, 39 }, + { -5, 53 }, { -7, 61 }, { -11, 75 }, { -15, 77 }, + { -17, 91 }, { -25, 107 }, { -25, 111 }, { -28, 122 }, + { -11, 76 }, { -10, 44 }, { -10, 52 }, { -10, 57 }, + { -9, 58 }, { -16, 72 }, { -7, 69 }, { -4, 69 }, + { -5, 74 }, { -9, 86 }, { 2, 66 }, { -9, 34 }, + { 1, 32 }, { 11, 31 }, { 5, 52 }, { -2, 55 }, + { -2, 67 }, { 0, 73 }, { -8, 89 }, { 3, 52 }, + { 7, 4 }, { 10, 8 }, { 17, 8 }, { 16, 19 }, + { 3, 37 }, { -1, 61 }, { -5, 73 }, { -1, 70 }, + { -4, 78 }, + + /* 276 special case, bypass used */ + { 0, 0 }, + + /* 277 -> 337 */ + { -21, 126 }, { -23, 124 }, { -20, 110 }, { -26, 126 }, + { -25, 124 }, { -17, 105 }, { -27, 121 }, { -27, 117 }, + { -17, 102 }, { -26, 117 }, { -27, 116 }, { -33, 122 }, + { -10, 95 }, { -14, 100 }, { -8, 95 }, { -17, 111 }, + { -28, 114 }, { -6, 89 }, { -2, 80 }, { -4, 82 }, + { -9, 85 }, { -8, 81 }, { -1, 72 }, { 5, 64 }, + { 1, 67 }, { 9, 56 }, { 0, 69 }, { 1, 69 }, + { 7, 69 }, { -7, 69 }, { -6, 67 }, { -16, 77 }, + { -2, 64 }, { 2, 61 }, { -6, 67 }, { -3, 64 }, + { 2, 57 }, { -3, 65 }, { -3, 66 }, { 0, 62 }, + { 9, 51 }, { -1, 66 }, { -2, 71 }, { -2, 75 }, + { -1, 70 }, { -9, 72 }, { 14, 60 }, { 16, 37 }, + { 0, 47 }, { 18, 35 }, { 11, 37 }, { 12, 41 }, + { 10, 41 }, { 2, 48 }, { 12, 41 }, { 13, 41 }, + { 0, 59 }, { 3, 50 }, { 19, 40 }, { 3, 66 }, + { 18, 50 }, + + /* 338 -> 398 */ + { 19, -6 }, { 18, -6 }, { 14, 0 }, { 26, -12 }, + { 31, -16 }, { 33, -25 }, { 33, -22 }, { 37, -28 }, + { 39, -30 }, { 42, -30 }, { 47, -42 }, { 45, -36 }, + { 49, -34 }, { 41, -17 }, { 32, 9 }, { 69, -71 }, + { 63, -63 }, { 66, -64 }, { 77, -74 }, { 54, -39 }, + { 52, -35 }, { 41, -10 }, { 36, 0 }, { 40, -1 }, + { 30, 14 }, { 28, 26 }, { 23, 37 }, { 12, 55 }, + { 11, 65 }, { 37, -33 }, { 39, -36 }, { 40, -37 }, + { 38, -30 }, { 46, -33 }, { 42, -30 }, { 40, -24 }, + { 49, -29 }, { 38, -12 }, { 40, -10 }, { 38, -3 }, + { 46, -5 }, { 31, 20 }, { 29, 30 }, { 25, 44 }, + { 12, 48 }, { 11, 49 }, { 26, 45 }, { 22, 22 }, + { 23, 22 }, { 27, 21 }, { 33, 20 }, { 26, 28 }, + { 30, 24 }, { 27, 34 }, { 18, 42 }, { 25, 39 }, + { 18, 50 }, { 12, 70 }, { 21, 54 }, { 14, 71 }, + { 11, 83 }, + + /* 399 -> 435 */ + { 25, 32 }, { 21, 49 }, { 21, 54 }, + { -5, 85 }, { -6, 81 }, { -10, 77 }, { -7, 81 }, + { -17, 80 }, { -18, 73 }, { -4, 74 }, { -10, 83 }, + { -9, 71 }, { -9, 67 }, { -1, 61 }, { -8, 66 }, + { -14, 66 }, { 0, 59 }, { 2, 59 }, { 17, -10 }, + { 32, -13 }, { 42, -9 }, { 49, -5 }, { 53, 0 }, + { 64, 3 }, { 68, 10 }, { 66, 27 }, { 47, 57 }, + { -5, 71 }, { 0, 24 }, { -1, 36 }, { -2, 42 }, + { -2, 52 }, { -9, 57 }, { -6, 63 }, { -4, 65 }, + { -4, 67 }, { -7, 82 }, + + /* 436 -> 459 */ + { -3, 81 }, { -3, 76 }, { -7, 72 }, { -6, 78 }, + { -12, 72 }, { -14, 68 }, { -3, 70 }, { -6, 76 }, + { -5, 66 }, { -5, 62 }, { 0, 57 }, { -4, 61 }, + { -9, 60 }, { 1, 54 }, { 2, 58 }, { 17, -10 }, + { 32, -13 }, { 42, -9 }, { 49, -5 }, { 53, 0 }, + { 64, 3 }, { 68, 10 }, { 66, 27 }, { 47, 57 }, + }, + + /* cabac_init_idc == 2 */ + { + /* 0 -> 10 */ + { 20, -15 }, { 2, 54 }, { 3, 74 }, { 20, -15 }, + { 2, 54 }, { 3, 74 }, { -28, 127 }, { -23, 104 }, + { -6, 53 }, { -1, 54 }, { 7, 51 }, + + /* 11 -> 23 */ + { 29, 16 }, { 25, 0 }, { 14, 0 }, { -10, 51 }, + { -3, 62 }, { -27, 99 }, { 26, 16 }, { -4, 85 }, + { -24, 102 }, { 5, 57 }, { 6, 57 }, { -17, 73 }, + { 14, 57 }, + + /* 24 -> 39 */ + { 20, 40 }, { 20, 10 }, { 29, 0 }, { 54, 0 }, + { 37, 42 }, { 12, 97 }, { -32, 127 }, { -22, 117 }, + { -2, 74 }, { -4, 85 }, { -24, 102 }, { 5, 57 }, + { -6, 93 }, { -14, 88 }, { -6, 44 }, { 4, 55 }, + + /* 40 -> 53 */ + { -11, 89 }, { -15, 103 }, { -21, 116 }, { 19, 57 }, + { 20, 58 }, { 4, 84 }, { 6, 96 }, { 1, 63 }, + { -5, 85 }, { -13, 106 }, { 5, 63 }, { 6, 75 }, + { -3, 90 }, { -1, 101 }, + + /* 54 -> 59 */ + { 3, 55 }, { -4, 79 }, { -2, 75 }, { -12, 97 }, + { -7, 50 }, { 1, 60 }, + + /* 60 -> 69 */ + { 0, 41 }, { 0, 63 }, { 0, 63 }, { 0, 63 }, + { -9, 83 }, { 4, 86 }, { 0, 97 }, { -7, 72 }, + { 13, 41 }, { 3, 62 }, + + /* 70 -> 104 */ + { 7, 34 }, { -9, 88 }, { -20, 127 }, { -36, 127 }, + { -17, 91 }, { -14, 95 }, { -25, 84 }, { -25, 86 }, + { -12, 89 }, { -17, 91 }, { -31, 127 }, { -14, 76 }, + { -18, 103 }, { -13, 90 }, { -37, 127 }, { 11, 80 }, + { 5, 76 }, { 2, 84 }, { 5, 78 }, { -6, 55 }, + { 4, 61 }, { -14, 83 }, { -37, 127 }, { -5, 79 }, + { -11, 104 }, { -11, 91 }, { -30, 127 }, { 0, 65 }, + { -2, 79 }, { 0, 72 }, { -4, 92 }, { -6, 56 }, + { 3, 68 }, { -8, 71 }, { -13, 98 }, + + /* 105 -> 165 */ + { -4, 86 }, { -12, 88 }, { -5, 82 }, { -3, 72 }, + { -4, 67 }, { -8, 72 }, { -16, 89 }, { -9, 69 }, + { -1, 59 }, { 5, 66 }, { 4, 57 }, { -4, 71 }, + { -2, 71 }, { 2, 58 }, { -1, 74 }, { -4, 44 }, + { -1, 69 }, { 0, 62 }, { -7, 51 }, { -4, 47 }, + { -6, 42 }, { -3, 41 }, { -6, 53 }, { 8, 76 }, + { -9, 78 }, { -11, 83 }, { 9, 52 }, { 0, 67 }, + { -5, 90 }, { 1, 67 }, { -15, 72 }, { -5, 75 }, + { -8, 80 }, { -21, 83 }, { -21, 64 }, { -13, 31 }, + { -25, 64 }, { -29, 94 }, { 9, 75 }, { 17, 63 }, + { -8, 74 }, { -5, 35 }, { -2, 27 }, { 13, 91 }, + { 3, 65 }, { -7, 69 }, { 8, 77 }, { -10, 66 }, + { 3, 62 }, { -3, 68 }, { -20, 81 }, { 0, 30 }, + { 1, 7 }, { -3, 23 }, { -21, 74 }, { 16, 66 }, + { -23, 124 }, { 17, 37 }, { 44, -18 }, { 50, -34 }, + { -22, 127 }, + + /* 166 -> 226 */ + { 4, 39 }, { 0, 42 }, { 7, 34 }, { 11, 29 }, + { 8, 31 }, { 6, 37 }, { 7, 42 }, { 3, 40 }, + { 8, 33 }, { 13, 43 }, { 13, 36 }, { 4, 47 }, + { 3, 55 }, { 2, 58 }, { 6, 60 }, { 8, 44 }, + { 11, 44 }, { 14, 42 }, { 7, 48 }, { 4, 56 }, + { 4, 52 }, { 13, 37 }, { 9, 49 }, { 19, 58 }, + { 10, 48 }, { 12, 45 }, { 0, 69 }, { 20, 33 }, + { 8, 63 }, { 35, -18 }, { 33, -25 }, { 28, -3 }, + { 24, 10 }, { 27, 0 }, { 34, -14 }, { 52, -44 }, + { 39, -24 }, { 19, 17 }, { 31, 25 }, { 36, 29 }, + { 24, 33 }, { 34, 15 }, { 30, 20 }, { 22, 73 }, + { 20, 34 }, { 19, 31 }, { 27, 44 }, { 19, 16 }, + { 15, 36 }, { 15, 36 }, { 21, 28 }, { 25, 21 }, + { 30, 20 }, { 31, 12 }, { 27, 16 }, { 24, 42 }, + { 0, 93 }, { 14, 56 }, { 15, 57 }, { 26, 38 }, + { -24, 127 }, + + /* 227 -> 275 */ + { -24, 115 }, { -22, 82 }, { -9, 62 }, { 0, 53 }, + { 0, 59 }, { -14, 85 }, { -13, 89 }, { -13, 94 }, + { -11, 92 }, { -29, 127 }, { -21, 100 }, { -14, 57 }, + { -12, 67 }, { -11, 71 }, { -10, 77 }, { -21, 85 }, + { -16, 88 }, { -23, 104 }, { -15, 98 }, { -37, 127 }, + { -10, 82 }, { -8, 48 }, { -8, 61 }, { -8, 66 }, + { -7, 70 }, { -14, 75 }, { -10, 79 }, { -9, 83 }, + { -12, 92 }, { -18, 108 }, { -4, 79 }, { -22, 69 }, + { -16, 75 }, { -2, 58 }, { 1, 58 }, { -13, 78 }, + { -9, 83 }, { -4, 81 }, { -13, 99 }, { -13, 81 }, + { -6, 38 }, { -13, 62 }, { -6, 58 }, { -2, 59 }, + { -16, 73 }, { -10, 76 }, { -13, 86 }, { -9, 83 }, + { -10, 87 }, + + /* 276 special case, bypass used */ + { 0, 0 }, + + /* 277 -> 337 */ + { -22, 127 }, { -25, 127 }, { -25, 120 }, { -27, 127 }, + { -19, 114 }, { -23, 117 }, { -25, 118 }, { -26, 117 }, + { -24, 113 }, { -28, 118 }, { -31, 120 }, { -37, 124 }, + { -10, 94 }, { -15, 102 }, { -10, 99 }, { -13, 106 }, + { -50, 127 }, { -5, 92 }, { 17, 57 }, { -5, 86 }, + { -13, 94 }, { -12, 91 }, { -2, 77 }, { 0, 71 }, + { -1, 73 }, { 4, 64 }, { -7, 81 }, { 5, 64 }, + { 15, 57 }, { 1, 67 }, { 0, 68 }, { -10, 67 }, + { 1, 68 }, { 0, 77 }, { 2, 64 }, { 0, 68 }, + { -5, 78 }, { 7, 55 }, { 5, 59 }, { 2, 65 }, + { 14, 54 }, { 15, 44 }, { 5, 60 }, { 2, 70 }, + { -2, 76 }, { -18, 86 }, { 12, 70 }, { 5, 64 }, + { -12, 70 }, { 11, 55 }, { 5, 56 }, { 0, 69 }, + { 2, 65 }, { -6, 74 }, { 5, 54 }, { 7, 54 }, + { -6, 76 }, { -11, 82 }, { -2, 77 }, { -2, 77 }, + { 25, 42 }, + + /* 338 -> 398 */ + { 17, -13 }, { 16, -9 }, { 17, -12 }, { 27, -21 }, + { 37, -30 }, { 41, -40 }, { 42, -41 }, { 48, -47 }, + { 39, -32 }, { 46, -40 }, { 52, -51 }, { 46, -41 }, + { 52, -39 }, { 43, -19 }, { 32, 11 }, { 61, -55 }, + { 56, -46 }, { 62, -50 }, { 81, -67 }, { 45, -20 }, + { 35, -2 }, { 28, 15 }, { 34, 1 }, { 39, 1 }, + { 30, 17 }, { 20, 38 }, { 18, 45 }, { 15, 54 }, + { 0, 79 }, { 36, -16 }, { 37, -14 }, { 37, -17 }, + { 32, 1 }, { 34, 15 }, { 29, 15 }, { 24, 25 }, + { 34, 22 }, { 31, 16 }, { 35, 18 }, { 31, 28 }, + { 33, 41 }, { 36, 28 }, { 27, 47 }, { 21, 62 }, + { 18, 31 }, { 19, 26 }, { 36, 24 }, { 24, 23 }, + { 27, 16 }, { 24, 30 }, { 31, 29 }, { 22, 41 }, + { 22, 42 }, { 16, 60 }, { 15, 52 }, { 14, 60 }, + { 3, 78 }, { -16, 123 }, { 21, 53 }, { 22, 56 }, + { 25, 61 }, + + /* 399 -> 435 */ + { 21, 33 }, { 19, 50 }, { 17, 61 }, + { -3, 78 }, { -8, 74 }, { -9, 72 }, { -10, 72 }, + { -18, 75 }, { -12, 71 }, { -11, 63 }, { -5, 70 }, + { -17, 75 }, { -14, 72 }, { -16, 67 }, { -8, 53 }, + { -14, 59 }, { -9, 52 }, { -11, 68 }, { 9, -2 }, + { 30, -10 }, { 31, -4 }, { 33, -1 }, { 33, 7 }, + { 31, 12 }, { 37, 23 }, { 31, 38 }, { 20, 64 }, + { -9, 71 }, { -7, 37 }, { -8, 44 }, { -11, 49 }, + { -10, 56 }, { -12, 59 }, { -8, 63 }, { -9, 67 }, + { -6, 68 }, { -10, 79 }, + + /* 436 -> 459 */ + { -3, 78 }, { -8, 74 }, { -9, 72 }, { -10, 72 }, + { -18, 75 }, { -12, 71 }, { -11, 63 }, { -5, 70 }, + { -17, 75 }, { -14, 72 }, { -16, 67 }, { -8, 53 }, + { -14, 59 }, { -9, 52 }, { -11, 68 }, { 9, -2 }, + { 30, -10 }, { 31, -4 }, { 33, -1 }, { 33, 7 }, + { 31, 12 }, { 37, 23 }, { 31, 38 }, { 20, 64 }, + } +}; + +#ifdef H264E_DUMP_DATA_TO_FILE +static MPP_RET hal_h264e_vpu_open_dump_files(void *dump_files) +{ + if (h264e_hal_log_mode & H264E_HAL_LOG_FILE) { + char base_path[512]; + char full_path[512]; + h264e_hal_vpu_dump_files *files = (h264e_hal_vpu_dump_files *)dump_files; + strcpy(base_path, "/sdcard/h264e_data/"); + + sprintf(full_path, "%s%s", base_path, "mpp_syntax_in.txt"); + files->fp_mpp_syntax_in = fopen(full_path, "wb"); + if (!files->fp_mpp_syntax_in) { + mpp_err("%s open error", full_path); + return MPP_ERR_OPEN_FILE; + } + + + sprintf(full_path, "%s%s", base_path, "mpp_reg_in.txt"); + files->fp_mpp_reg_in = fopen(full_path, "wb"); + if (!files->fp_mpp_reg_in) { + mpp_err("%s open error", full_path); + return MPP_ERR_OPEN_FILE; + } + + sprintf(full_path, "%s%s", base_path, "mpp_reg_out.txt"); + files->fp_mpp_reg_out = fopen(full_path, "wb"); + if (!files->fp_mpp_reg_out) { + mpp_err("%s open error", full_path); + return MPP_ERR_OPEN_FILE; + } + + sprintf(full_path, "%s%s", base_path, "mpp_feedback.txt"); + files->fp_mpp_feedback = fopen(full_path, "wb"); + if (!files->fp_mpp_feedback) { + mpp_err("%s open error", full_path); + return MPP_ERR_OPEN_FILE; + } + + sprintf(full_path, "%s%s", base_path, "mpp_strm_out.bin"); + files->fp_mpp_strm_out = fopen(full_path, "wb"); + if (!files->fp_mpp_strm_out) { + mpp_err("%s open error", full_path); + return MPP_ERR_OPEN_FILE; + } + } + return MPP_OK; +} + + +static MPP_RET hal_h264e_vpu_close_dump_files(void *dump_files) +{ + h264e_hal_vpu_dump_files *files = (h264e_hal_vpu_dump_files *)dump_files; + H264E_HAL_FCLOSE(files->fp_mpp_syntax_in); + H264E_HAL_FCLOSE(files->fp_mpp_reg_in); + H264E_HAL_FCLOSE(files->fp_mpp_reg_out); + H264E_HAL_FCLOSE(files->fp_mpp_strm_out); + H264E_HAL_FCLOSE(files->fp_mpp_feedback); + return MPP_OK; +} + +static void hal_h264e_vpu_dump_mpp_syntax_in(h264e_syntax *syn, h264e_hal_context *ctx) +{ + h264e_hal_vpu_dump_files *dump_files = (h264e_hal_vpu_dump_files *)ctx->dump_files; + FILE *fp = dump_files->fp_mpp_syntax_in; + if (fp) { + RK_S32 k = 0; + fprintf(fp, "#FRAME %d:\n", ctx->frame_cnt); + fprintf(fp, "%-16d %s\n", syn->frame_coding_type, "frame_coding_type"); + fprintf(fp, "%-16d %s\n", syn->pic_init_qp, "pic_init_qp"); + fprintf(fp, "%-16d %s\n", syn->slice_alpha_offset, "slice_alpha_offset"); + fprintf(fp, "%-16d %s\n", syn->slice_beta_offset, "slice_beta_offset"); + fprintf(fp, "%-16d %s\n", syn->chroma_qp_index_offset, "chroma_qp_index_offset"); + fprintf(fp, "%-16d %s\n", syn->filter_disable, "filter_disable"); + fprintf(fp, "%-16d %s\n", syn->idr_pic_id, "idr_pic_id"); + fprintf(fp, "%-16d %s\n", syn->pps_id, "pps_id"); + fprintf(fp, "%-16d %s\n", syn->frame_num, "frame_num"); + fprintf(fp, "%-16d %s\n", syn->slice_size_mb_rows, "slice_size_mb_rows"); + fprintf(fp, "%-16d %s\n", syn->h264_inter4x4_disabled, "h264_inter4x4_disabled"); + fprintf(fp, "%-16d %s\n", syn->enable_cabac, "enable_cabac"); + fprintf(fp, "%-16d %s\n", syn->transform8x8_mode, "transform8x8_mode"); + fprintf(fp, "%-16d %s\n", syn->cabac_init_idc, "cabac_init_idc"); + fprintf(fp, "%-16d %s\n", syn->qp, "qp"); + fprintf(fp, "%-16d %s\n", syn->mad_qp_delta, "mad_qp_delta"); + fprintf(fp, "%-16d %s\n", syn->mad_threshold, "mad_threshold"); + fprintf(fp, "%-16d %s\n", syn->qp_min, "qp_min"); + fprintf(fp, "%-16d %s\n", syn->qp_max, "qp_max"); + fprintf(fp, "%-16d %s\n", syn->cp_distance_mbs, "cp_distance_mbs"); + for (k = 0; k < 10; k++) + fprintf(fp, "%-16d cp_target[%d]\n", syn->cp_target[k], k); + for (k = 0; k < 7; k++) + fprintf(fp, "%-16d target_error[%d]\n", syn->target_error[k], k); + for (k = 0; k < 7; k++) + fprintf(fp, "%-16d delta_qp[%d]\n", syn->delta_qp[k], k); + fprintf(fp, "%-16d %s\n", syn->output_strm_limit_size, "output_strm_limit_size"); + fprintf(fp, "%-16d %s\n", syn->pic_luma_width, "pic_luma_width"); + fprintf(fp, "%-16d %s\n", syn->pic_luma_height, "pic_luma_height"); + fprintf(fp, "%-16d %s\n", syn->input_image_format, "input_image_format"); + + fprintf(fp, "%-16d %s\n", syn->color_conversion_coeff_a, "color_conversion_coeff_a"); + fprintf(fp, "%-16d %s\n", syn->color_conversion_coeff_b, "color_conversion_coeff_b"); + fprintf(fp, "%-16d %s\n", syn->color_conversion_coeff_c, "color_conversion_coeff_c"); + fprintf(fp, "%-16d %s\n", syn->color_conversion_coeff_e, "color_conversion_coeff_e"); + fprintf(fp, "%-16d %s\n", syn->color_conversion_coeff_f, "color_conversion_coeff_f"); + fprintf(fp, "%-16d %s\n", syn->color_conversion_r_mask_msb, "color_conversion_r_mask_msb"); + fprintf(fp, "%-16d %s\n", syn->color_conversion_g_mask_msb, "color_conversion_g_mask_msb"); + fprintf(fp, "%-16d %s\n", syn->color_conversion_b_mask_msb, "color_conversion_b_mask_msb"); + + fprintf(fp, "\n"); + fflush(fp); + } else { + mpp_log("try to dump data to mpp_syntax_in.txt, but file is not opened"); + } +} + +static void hal_h264e_vpu_dump_mpp_reg_in(h264e_hal_context *ctx) +{ + h264e_hal_vpu_dump_files *dump_files = (h264e_hal_vpu_dump_files *)ctx->dump_files; + FILE *fp = dump_files->fp_mpp_reg_in; + if (fp) { + RK_S32 k = 0; + RK_U32 *reg = (RK_U32 *)ctx->regs; + fprintf(fp, "#FRAME %d:\n", ctx->frame_cnt); + for (k = 0; k < VEPU_H264E_NUM_REGS; k++) { + fprintf(fp, "reg[%03d/%03x]: %08x\n", k, k * 4, reg[k]); + //mpp_log("reg[%03d/%03x]: %08x", k, k*4, reg[k]); + } + fprintf(fp, "\n"); + } else { + mpp_log("try to dump data to mpp_reg_in.txt, but file is not opened"); + } +} + +static void hal_h264e_vpu_dump_mpp_reg_out(h264e_hal_context *ctx) +{ + h264e_hal_vpu_dump_files *dump_files = (h264e_hal_vpu_dump_files *)ctx->dump_files; + FILE *fp = dump_files->fp_mpp_reg_out; + if (fp) { + RK_S32 k = 0; + RK_U32 *reg = (RK_U32 *)ctx->regs; + fprintf(fp, "#FRAME %d:\n", ctx->frame_cnt - 1); + for (k = 0; k < VEPU_H264E_NUM_REGS; k++) { + fprintf(fp, "reg[%03d/%03x]: %08x\n", k, k * 4, reg[k]); + //mpp_log("reg[%03d/%03x]: %08x", k, k*4, reg[k]); + } + fprintf(fp, "\n"); + } else { + mpp_log("try to dump data to mpp_reg_in.txt, but file is not opened"); + } +} + +static void hal_h264e_vpu_dump_mpp_feedback(h264e_hal_context *ctx) +{ + h264e_hal_vpu_dump_files *dump_files = (h264e_hal_vpu_dump_files *)ctx->dump_files; + FILE *fp = dump_files->fp_mpp_feedback; + if (fp) { + RK_S32 k = 0; + h264e_feedback *fb = &ctx->feedback; + fprintf(fp, "#FRAME %d:\n", ctx->frame_cnt - 1); + fprintf(fp, "%-16d %s\n", fb->hw_status, "hw_status"); + fprintf(fp, "%-16d %s\n", fb->out_strm_size, "out_strm_size"); + fprintf(fp, "%-16d %s\n", fb->qp_sum, "qp_sum"); + for (k = 0; k < 10; k++) + fprintf(fp, "%-16d cp[%d]\n", fb->cp[k], k); + fprintf(fp, "%-16d %s\n", fb->mad_count, "mad_count"); + fprintf(fp, "%-16d %s\n", fb->rlc_count, "rlc_count"); + + fprintf(fp, "\n"); + fflush(fp); + } else { + mpp_log("try to dump data to mpp_feedback.txt, but file is not opened"); + } +} + +static void hal_h264e_vpu_dump_mpp_strm_out_header(h264e_hal_context *ctx, MppPacket packet) +{ + h264e_hal_vpu_dump_files *dump_files = (h264e_hal_vpu_dump_files *)ctx->dump_files; + void *ptr = mpp_packet_get_data(packet); + size_t len = mpp_packet_get_length(packet); + FILE *fp = dump_files->fp_mpp_strm_out; + + if (fp) { + fwrite(ptr, 1, len, fp); + fflush(fp); + } else { + mpp_log("try to dump strm header to mpp_strm_out.txt, but file is not opened"); + } +} + +void hal_h264e_vpu_dump_mpp_strm_out(h264e_hal_context *ctx, MppBuffer hw_buf) +{ + h264e_hal_vpu_dump_files *dump_files = (h264e_hal_vpu_dump_files *)ctx->dump_files; + FILE *fp = dump_files->fp_mpp_strm_out; + if (fp && hw_buf) { + RK_U32 *reg_val = (RK_U32 *)ctx->regs; + RK_U32 strm_size = reg_val[VEPU_REG_STR_BUF_LIMIT / 4] / 8; + + RK_U8 *hw_buf_vir_addr = (RK_U8 *)mpp_buffer_get_ptr(hw_buf); + + mpp_log("strm_size: %d", strm_size); + + fwrite(hw_buf_vir_addr, 1, strm_size, fp); + fflush(fp); + } else { + mpp_log("try to dump data to mpp_strm_out.txt, but file is not opened"); + } +} +#endif + +static h264e_hal_vpu_csp_info hal_h264e_vpu_convert_csp(RK_S32 src_type) +{ + MppFrameFormat src_fmt = (MppFrameFormat)src_type; + h264e_hal_vpu_csp_info dst_info; + dst_info.fmt = 0; + dst_info.r_mask_msb = 0; + dst_info.g_mask_msb = 0; + dst_info.b_mask_msb = 0; + + switch (src_fmt) { + case MPP_FMT_YUV420P: { + dst_info.fmt = H264E_VPU_CSP_YUV420P; + break; + } + case MPP_FMT_YUV420SP: { + dst_info.fmt = H264E_VPU_CSP_YUV420SP; + break; + } + case MPP_FMT_YUV420SP_10BIT: { + dst_info.fmt = H264E_VPU_CSP_NONE; + break; + } + case MPP_FMT_YUV420SP_VU: { //TODO: to be confirmed + dst_info.fmt = H264E_VPU_CSP_NONE; + break; + } + case MPP_FMT_YUV422P: { + dst_info.fmt = H264E_VPU_CSP_NONE; + break; + } + case MPP_FMT_YUV422SP: { + dst_info.fmt = H264E_VPU_CSP_NONE; + break; + } + case MPP_FMT_YUV422SP_10BIT: { + dst_info.fmt = H264E_VPU_CSP_NONE; + break; + } + case MPP_FMT_YUV422SP_VU: { + dst_info.fmt = H264E_VPU_CSP_NONE; + break; + } + case MPP_FMT_YUV422_YUYV: { + dst_info.fmt = H264E_VPU_CSP_YUYV422; + break; + } + case MPP_FMT_YUV422_UYVY: { + dst_info.fmt = H264E_VPU_CSP_UYVY422; + break; + } + case MPP_FMT_RGB565: { + dst_info.fmt = H264E_VPU_CSP_RGB565; + dst_info.r_mask_msb = 15; + dst_info.g_mask_msb = 10; + dst_info.b_mask_msb = 4; + break; + } + case MPP_FMT_BGR565: { + dst_info.fmt = H264E_VPU_CSP_RGB565; + dst_info.r_mask_msb = 4; + dst_info.g_mask_msb = 10; dst_info.b_mask_msb = 15; - break; - } - case MPP_FMT_RGB555: { - dst_info.fmt = H264E_VPU_CSP_RGB555; - dst_info.r_mask_msb = 14; - dst_info.g_mask_msb = 9; + break; + } + case MPP_FMT_RGB555: { + dst_info.fmt = H264E_VPU_CSP_RGB555; + dst_info.r_mask_msb = 14; + dst_info.g_mask_msb = 9; dst_info.b_mask_msb = 4; - break; - } - case MPP_FMT_BGR555: { - dst_info.fmt = H264E_VPU_CSP_RGB555; - dst_info.r_mask_msb = 14; - dst_info.g_mask_msb = 9; + break; + } + case MPP_FMT_BGR555: { + dst_info.fmt = H264E_VPU_CSP_RGB555; + dst_info.r_mask_msb = 14; + dst_info.g_mask_msb = 9; dst_info.b_mask_msb = 4; - break; - } - case MPP_FMT_RGB444: { - dst_info.fmt = H264E_VPU_CSP_RGB444; - dst_info.r_mask_msb = 11; - dst_info.g_mask_msb = 7; + break; + } + case MPP_FMT_RGB444: { + dst_info.fmt = H264E_VPU_CSP_RGB444; + dst_info.r_mask_msb = 11; + dst_info.g_mask_msb = 7; dst_info.b_mask_msb = 3; - break; - } - case MPP_FMT_BGR444: { - dst_info.fmt = H264E_VPU_CSP_RGB444; - dst_info.r_mask_msb = 11; - dst_info.g_mask_msb = 7; + break; + } + case MPP_FMT_BGR444: { + dst_info.fmt = H264E_VPU_CSP_RGB444; + dst_info.r_mask_msb = 11; + dst_info.g_mask_msb = 7; dst_info.b_mask_msb = 3; - break; - } - case MPP_FMT_RGB888: { - dst_info.fmt = H264E_VPU_CSP_RGB888; - dst_info.r_mask_msb = 23; - dst_info.g_mask_msb = 15; - dst_info.b_mask_msb = 7; - break; - } - case MPP_FMT_BGR888: { - dst_info.fmt = H264E_VPU_CSP_RGB888; - dst_info.r_mask_msb = 23; - dst_info.g_mask_msb = 15; + break; + } + case MPP_FMT_RGB888: { + dst_info.fmt = H264E_VPU_CSP_RGB888; + dst_info.r_mask_msb = 23; + dst_info.g_mask_msb = 15; dst_info.b_mask_msb = 7; - break; - } - case MPP_FMT_RGB101010: { - dst_info.fmt = H264E_VPU_CSP_RGB101010; - dst_info.r_mask_msb = 29; - dst_info.g_mask_msb = 19; + break; + } + case MPP_FMT_BGR888: { + dst_info.fmt = H264E_VPU_CSP_RGB888; + dst_info.r_mask_msb = 23; + dst_info.g_mask_msb = 15; + dst_info.b_mask_msb = 7; + break; + } + case MPP_FMT_RGB101010: { + dst_info.fmt = H264E_VPU_CSP_RGB101010; + dst_info.r_mask_msb = 29; + dst_info.g_mask_msb = 19; dst_info.b_mask_msb = 9; - break; - } - case MPP_FMT_BGR101010: { - dst_info.fmt = H264E_VPU_CSP_RGB101010; - dst_info.r_mask_msb = 29; - dst_info.g_mask_msb = 19; + break; + } + case MPP_FMT_BGR101010: { + dst_info.fmt = H264E_VPU_CSP_RGB101010; + dst_info.r_mask_msb = 29; + dst_info.g_mask_msb = 19; dst_info.b_mask_msb = 9; - break; - } - case MPP_FMT_ARGB8888: { - dst_info.fmt = H264E_VPU_CSP_NONE; - break; - } - case MPP_FMT_ABGR8888: { - dst_info.fmt = H264E_VPU_CSP_NONE; - break; - } - default: { - h264e_hal_log_err("unvalid src color space: %d", src_type); - dst_info.fmt = H264E_VPU_CSP_NONE; - } - } - - return dst_info; -} - - -static MPP_RET hal_h264e_vpu_free_buffers(h264e_hal_context *ctx) -{ - RK_S32 k = 0; - h264e_hal_vpu_buffers *buffers = (h264e_hal_vpu_buffers *)ctx->buffers; - h264e_hal_debug_enter(); - - if (buffers->hw_cabac_table_buf) { - if (MPP_OK != mpp_buffer_put(buffers->hw_cabac_table_buf)) { - mpp_err("hw_cabac_table_buf put failed"); - return MPP_NOK; - } - } - - if (buffers->hw_nal_size_table_buf) { - if (MPP_OK != mpp_buffer_put(buffers->hw_nal_size_table_buf)) { - mpp_err("hw_nal_size_table_buf put failed"); - return MPP_NOK; - } - } - - - for (k = 0; k < 2; k++) { - if (buffers->hw_rec_buf[k]) { - if (MPP_OK != mpp_buffer_put(buffers->hw_rec_buf[k])) { - mpp_err("hw_rec_buf[%d] put failed", k); - return MPP_NOK; - } - } - } - - if (buffers->hw_buf_grp) { - if (MPP_OK != mpp_buffer_group_put(buffers->hw_buf_grp)) { - mpp_err("buf group[%d] put failed", k); - return MPP_NOK; - } - buffers->hw_buf_grp = NULL; - } - - h264e_hal_debug_leave(); - return MPP_OK; -} - -static void hal_h264e_vpu_write_cabac_table(h264e_syntax *syn, MppBuffer hw_cabac_tab_buf) -{ - const RK_S32(*context)[460][2]; - RK_S32 i, j, qp; - - RK_U8 table[H264E_CABAC_TABLE_BUF_SIZE] = {0}; - RK_U32 cabac_init_idc = syn->cabac_init_idc; - - h264e_hal_debug_enter(); - - for (qp = 0; qp < 52; qp++) { /* All QP values */ - for (j = 0; j < 2; j++) { /* Intra/Inter */ - if (j == 0) - /*lint -e(545) */ - context = &h264_context_init_intra; - else - /*lint -e(545) */ - context = &h264_context_init[cabac_init_idc]; - - for (i = 0; i < 460; i++) { - RK_S32 m = (RK_S32)(*context)[i][0]; - RK_S32 n = (RK_S32)(*context)[i][1]; - - RK_S32 pre_ctx_state = - H264E_HAL_CLIP3(1, 126, - ((m * (RK_S32)qp) >> 4) + n); - - if (pre_ctx_state <= 63) { - table[qp * 464 * 2 + j * 464 + i] = - (RK_U8)((63 - - pre_ctx_state) << 1); - } else { - table[qp * 464 * 2 + j * 464 + i] = - (RK_U8)(((pre_ctx_state - 64) - << 1) | 1); - } - } - } - } - - mpp_buffer_write(hw_cabac_tab_buf, 0, table, H264E_CABAC_TABLE_BUF_SIZE); - - h264e_hal_debug_leave(); -} - -static MPP_RET hal_h264e_vpu_allocate_buffers(h264e_hal_context *ctx, h264e_syntax *syn) -{ - MPP_RET ret = MPP_OK; - RK_S32 k = 0; - h264e_hal_vpu_buffers *buffers = (h264e_hal_vpu_buffers *)ctx->buffers; - RK_U32 frame_size = ((syn->pic_luma_width + 15) & (~15)) * ((syn->pic_luma_height + 15) & (~15)) * 3 / 2; - - h264e_hal_debug_enter(); - ret = mpp_buffer_group_get_internal(&buffers->hw_buf_grp, MPP_BUFFER_TYPE_ION); - if (ret) { - mpp_err("buf group get failed ret %d\n", ret); - return ret; - } - - ret = mpp_buffer_get(buffers->hw_buf_grp, &buffers->hw_cabac_table_buf, H264E_CABAC_TABLE_BUF_SIZE); - if (ret) { - mpp_err("hw_cabac_table_buf get failed\n"); - return ret; - } - - ret = mpp_buffer_get(buffers->hw_buf_grp, &buffers->hw_nal_size_table_buf, (sizeof(RK_U32) * (syn->pic_luma_height + 1) + 7) & (~7)); - if (ret) { - mpp_err("hw_nal_size_table_buf get failed\n"); - return ret; - } - - for (k = 0; k < 2; k++) { - ret = mpp_buffer_get(buffers->hw_buf_grp, &buffers->hw_rec_buf[k], frame_size + 4096); - if (ret) { - mpp_err("hw_rec_buf[%d] get failed\n", k); - return ret; - } - } - - hal_h264e_vpu_write_cabac_table(syn, buffers->hw_cabac_table_buf); - - h264e_hal_debug_leave(); - return MPP_OK; -} - - -static MPP_RET hal_h264e_vpu_stream_buffer_status(h264e_hal_vpu_stream *stream) -{ - if (stream->byte_cnt + 5 > stream->size) { - stream->overflow = 1; - return MPP_NOK; - } - - return MPP_OK; -} - -static MPP_RET hal_h264e_vpu_stream_buffer_reset(h264e_hal_vpu_stream *strmbuf) -{ - strmbuf->stream = strmbuf->buffer; - strmbuf->byte_cnt = 0; - strmbuf->overflow = 0; - strmbuf->byte_buffer = 0; - strmbuf->buffered_bits = 0; - strmbuf->zero_bytes = 0; - strmbuf->emul_cnt = 0; - - return MPP_OK; -} - -static MPP_RET hal_h264e_vpu_stream_buffer_init(h264e_hal_vpu_stream *strmbuf, RK_S32 size) -{ - strmbuf->buffer = mpp_calloc(RK_U8, size); - - if (strmbuf->buffer == NULL) { - mpp_err("allocate stream buffer failed\n"); - return MPP_NOK; - } - strmbuf->stream = strmbuf->buffer; - strmbuf->size = size; - strmbuf->byte_cnt = 0; - strmbuf->overflow = 0; - strmbuf->byte_buffer = 0; - strmbuf->buffered_bits = 0; - strmbuf->zero_bytes = 0; - strmbuf->emul_cnt = 0; - - if (MPP_OK != hal_h264e_vpu_stream_buffer_status(strmbuf)) { - mpp_err("stream buffer is overflow, while init"); - return MPP_NOK; - } - - return MPP_OK; -} - - -void hal_h264e_vpu_stream_put_bits(h264e_hal_vpu_stream *buffer, RK_S32 value, RK_S32 number, - const char *name) -{ - RK_S32 bits; - RK_U32 byte_buffer = buffer->byte_buffer; - RK_U8*stream = buffer->stream; - - if (hal_h264e_vpu_stream_buffer_status(buffer) != 0) - return; - - h264e_hal_log_detail("assemble %s value %x, bits %d\n", name, value, number); - - mpp_assert(value < (1 << number)); //opposite to 'BUG_ON' in kernel - mpp_assert(number < 25); - - bits = number + buffer->buffered_bits; - value <<= (32 - bits); - byte_buffer = byte_buffer | value; - - while (bits > 7) { - *stream = (RK_U8)(byte_buffer >> 24); - - bits -= 8; - byte_buffer <<= 8; - stream++; - buffer->byte_cnt++; - } - - buffer->byte_buffer = byte_buffer; - buffer->buffered_bits = (RK_U8)bits; - buffer->stream = stream; - - return; -} - -void hal_h264e_vpu_stream_put_bits_with_detect(h264e_hal_vpu_stream * buffer, RK_S32 value, RK_S32 number, const char *name) -{ - RK_S32 bits; - RK_U8 *stream = buffer->stream; - RK_U32 byte_buffer = buffer->byte_buffer; - - mpp_assert(value < (1 << number)); - mpp_assert(number < 25); - - h264e_hal_log_detail("assemble %s value %x, bits %d\n", name, value, number); - - bits = number + buffer->buffered_bits; - byte_buffer = byte_buffer | ((RK_U32) value << (32 - bits)); - - while (bits > 7) { - RK_S32 zeroBytes = buffer->zero_bytes; - RK_S32 byteCnt = buffer->byte_cnt; - - if (hal_h264e_vpu_stream_buffer_status(buffer) != MPP_OK) - return; - - *stream = (RK_U8) (byte_buffer >> 24); - byteCnt++; - - if ((zeroBytes == 2) && (*stream < 4)) { - *stream++ = 3; - *stream = (RK_U8) (byte_buffer >> 24); - byteCnt++; - zeroBytes = 0; - buffer->emul_cnt++; - } - - if (*stream == 0) - zeroBytes++; - else - zeroBytes = 0; - - bits -= 8; - byte_buffer <<= 8; - stream++; - buffer->zero_bytes = zeroBytes; - buffer->byte_cnt = byteCnt; - buffer->stream = stream; - } - - buffer->buffered_bits = (RK_U8) bits; - buffer->byte_buffer = byte_buffer; -} - - -void hal_h264e_vpu_rbsp_trailing_bits(h264e_hal_vpu_stream * stream) -{ - hal_h264e_vpu_stream_put_bits_with_detect(stream, 1, 1, "rbsp_stop_one_bit"); - if (stream->buffered_bits > 0) { - hal_h264e_vpu_stream_put_bits_with_detect(stream, 0, 8 - stream->buffered_bits, "bsp_alignment_zero_bit(s)"); - } -} - -static void hal_h264e_vpu_write_ue(h264e_hal_vpu_stream *fifo, RK_U32 val, - const char *name) -{ - RK_U32 num_bits = 0; - - val++; - while (val >> ++num_bits); - - if (num_bits > 12) { - RK_U32 tmp; - - tmp = num_bits - 1; - - if (tmp > 24) { - tmp -= 24; - hal_h264e_vpu_stream_put_bits_with_detect(fifo, 0, 24, name); - } - - hal_h264e_vpu_stream_put_bits_with_detect(fifo, 0, tmp, name); - - if (num_bits > 24) { - num_bits -= 24; - hal_h264e_vpu_stream_put_bits_with_detect(fifo, val >> num_bits, 24, name); - val = val >> num_bits; - } - - hal_h264e_vpu_stream_put_bits_with_detect(fifo, val, num_bits, name); - } else { - hal_h264e_vpu_stream_put_bits_with_detect(fifo, val, 2 * num_bits - 1, name); - } -} - -static void hal_h264e_vpu_write_se(h264e_hal_vpu_stream *fifo, RK_S32 val, const char *name) -{ - RK_U32 tmp; - - if (val > 0) - tmp = (RK_U32)(2 * val - 1); - else - tmp = (RK_U32)(-2 * val); - - hal_h264e_vpu_write_ue(fifo, tmp, name); -} - -static MPP_RET hal_h264e_vpu_nal_start(h264e_hal_vpu_stream * stream, RK_S32 nalRefIdc, rkvenc_nal_unit_type nalUnitType) -{ - hal_h264e_vpu_stream_put_bits(stream, 0, 8, "leadin_zero_8bits"); - hal_h264e_vpu_stream_put_bits(stream, 0, 8, "start_code_prefix"); - hal_h264e_vpu_stream_put_bits(stream, 0, 8, "start_code_prefix"); - hal_h264e_vpu_stream_put_bits(stream, 1, 8, "start_code_prefix"); - hal_h264e_vpu_stream_put_bits(stream, 0, 1, "forbidden_zero_bit"); - hal_h264e_vpu_stream_put_bits(stream, nalRefIdc, 2, "nal_ref_idc"); - hal_h264e_vpu_stream_put_bits(stream, (RK_S32)nalUnitType, 5, "nal_unit_type"); - stream->zero_bytes = 0; /* we start new counter for zero bytes */ - - return MPP_OK; -} - - - -static MPP_RET hal_h264e_vpu_write_sps(h264e_hal_vpu_stream *stream, h264e_hal_sps *sps) -{ - h264e_hal_debug_enter(); - - hal_h264e_vpu_nal_start(stream, 1, RKVENC_NAL_SPS); - - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->i_profile_idc, 8, "profile_idc"); //FIXED: 77, 42 - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->b_constraint_set0, 1, "constraint_set0_flag"); //E0 - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->b_constraint_set1, 1, "constraint_set1_flag"); - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->b_constraint_set2, 1, "constraint_set2_flag"); - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->b_constraint_set3, 1, "constraint_set3_flag"); - - hal_h264e_vpu_stream_put_bits_with_detect(stream, 0, 4, "reserved_zero_4bits"); - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->i_level_idc, 8, "level_idc"); //28 - - hal_h264e_vpu_write_ue(stream, sps->i_id, "seq_parameter_set_id"); //8D - - if (sps->i_profile_idc >= 100) { //High profile - hal_h264e_vpu_write_ue(stream, sps->i_chroma_format_idc, "chroma_format_idc"); - hal_h264e_vpu_write_ue(stream, H264_BIT_DEPTH - 8, "bit_depth_luma_minus8"); - hal_h264e_vpu_write_ue(stream, H264_BIT_DEPTH - 8, "bit_depth_chroma_minus8"); - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->b_qpprime_y_zero_transform_bypass, 1, "qpprime_y_zero_transform_bypass_flag"); - hal_h264e_vpu_stream_put_bits_with_detect(stream, 0, 1, "seq_scaling_matrix_present_flag"); - } - - hal_h264e_vpu_write_ue(stream, sps->i_log2_max_frame_num - 4, "log2_max_frame_num_minus4"); - - hal_h264e_vpu_write_ue(stream, sps->i_poc_type, "pic_order_cnt_type"); //68 16 - - hal_h264e_vpu_write_ue(stream, sps->i_num_ref_frames, "num_ref_frames"); - - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->b_gaps_in_frame_num_value_allowed, 1, "gaps_in_frame_num_value_allowed_flag"); - - hal_h264e_vpu_write_ue(stream, sps->i_mb_width - 1, "pic_width_in_mbs_minus1"); - - hal_h264e_vpu_write_ue(stream, sps->i_mb_height - 1, "pic_height_in_map_units_minus1"); //09 64 - - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->b_frame_mbs_only, 1, "frame_mbs_only_flag"); - - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->b_direct8x8_inference, 1, "direct_8x8_inference_flag"); - - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->b_crop, 1, "frame_cropping_flag"); - if (sps->b_crop) { - hal_h264e_vpu_write_ue(stream, sps->crop.i_left / 2, "frame_crop_left_offset"); - hal_h264e_vpu_write_ue(stream, sps->crop.i_right / 2, "frame_crop_right_offset"); - hal_h264e_vpu_write_ue(stream, sps->crop.i_top / 2, "frame_crop_top_offset"); - hal_h264e_vpu_write_ue(stream, sps->crop.i_bottom / 2, "frame_crop_bottom_offset"); - } - - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->b_vui, 1, "vui_parameters_present_flag"); - if (sps->b_vui) { - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.b_aspect_ratio_info_present, 1, "aspect_ratio_info_present_flag"); - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.b_overscan_info_present, 1, "overscan_info_present_flag"); - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.b_signal_type_present, 1, "video_signal_type_present_flag"); - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.b_chroma_loc_info_present, 1, "chroma_loc_info_present_flag"); - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.b_timing_info_present, 1, "timing_info_present_flag"); - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.i_num_units_in_tick >> 16, 16, "num_units_in_tick msb"); - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.i_num_units_in_tick & 0xffff, 16, "num_units_in_tick lsb"); - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.i_time_scale >> 16, 16, "time_scale msb"); - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.i_time_scale & 0xffff, 16, "time_scale lsb"); - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.b_fixed_frame_rate, 1, "fixed_frame_rate_flag"); - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.b_nal_hrd_parameters_present, 1, "nal_hrd_parameters_present_flag"); - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.b_vcl_hrd_parameters_present, 1, "vcl_hrd_parameters_present_flag"); - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.b_pic_struct_present, 1, "pic_struct_present_flag"); - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.b_bitstream_restriction, 1, "bit_stream_restriction_flag"); - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.b_motion_vectors_over_pic_boundaries, 1, "motion_vectors_over_pic_boundaries"); - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.i_max_bytes_per_pic_denom, 1, "max_bytes_per_pic_denom"); - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.i_max_bits_per_mb_denom, 1, "max_bits_per_mb_denom"); - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.i_log2_max_mv_length_horizontal, 7, "log2_mv_length_horizontal"); - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.i_log2_max_mv_length_vertical, 5, "log2_mv_length_vertical"); - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.i_num_reorder_frames, 1, "num_reorder_frames"); - hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.i_max_dec_frame_buffering, 3, "max_dec_frame_buffering"); - } - - hal_h264e_vpu_rbsp_trailing_bits(stream); - - h264e_hal_log_detail("sps write size: %d bytes", stream->byte_cnt); - - h264e_hal_debug_leave(); - - return MPP_OK; -} - -static MPP_RET hal_h264e_vpu_write_pps(h264e_hal_vpu_stream *stream, h264e_hal_pps *pps) -{ - h264e_hal_debug_enter(); - - hal_h264e_vpu_nal_start(stream, 1, RKVENC_NAL_PPS); - - hal_h264e_vpu_write_ue(stream, pps->i_id, "pic_parameter_set_id"); - hal_h264e_vpu_write_ue(stream, pps->i_sps_id, "seq_parameter_set_id"); - - hal_h264e_vpu_stream_put_bits_with_detect(stream, pps->b_cabac, 1, "entropy_coding_mode_flag"); - hal_h264e_vpu_stream_put_bits_with_detect(stream, pps->b_pic_order, 1, "pic_order_present_flag"); - - hal_h264e_vpu_write_ue(stream, pps->i_num_slice_groups - 1, "num_slice_groups_minus1"); - hal_h264e_vpu_write_ue(stream, pps->i_num_ref_idx_l0_default_active - 1, "num_ref_idx_l0_active_minus1"); - hal_h264e_vpu_write_ue(stream, pps->i_num_ref_idx_l1_default_active - 1, "num_ref_idx_l1_active_minus1"); - - hal_h264e_vpu_stream_put_bits_with_detect(stream, pps->b_weighted_pred, 1, "weighted_pred_flag"); - hal_h264e_vpu_stream_put_bits_with_detect(stream, pps->i_weighted_bipred_idc, 2, "weighted_bipred_idc"); - - hal_h264e_vpu_write_se(stream, pps->i_pic_init_qp - 26, "pic_init_qp_minus26"); - hal_h264e_vpu_write_se(stream, pps->i_pic_init_qs - 26, "pic_init_qs_minus26"); - hal_h264e_vpu_write_se(stream, pps->i_chroma_qp_index_offset, "chroma_qp_index_offset"); - - hal_h264e_vpu_stream_put_bits_with_detect(stream, pps->b_deblocking_filter_control, 1, "deblocking_filter_control_present_flag"); - hal_h264e_vpu_stream_put_bits_with_detect(stream, pps->b_constrained_intra_pred, 1, "constrained_intra_pred_flag"); - - hal_h264e_vpu_stream_put_bits_with_detect(stream, pps->b_redundant_pic_cnt, 1, "redundant_pic_cnt_present_flag"); - - if (pps->b_transform_8x8_mode) { - hal_h264e_vpu_stream_put_bits_with_detect(stream, pps->b_transform_8x8_mode, 1, "transform_8x8_mode_flag"); - hal_h264e_vpu_stream_put_bits_with_detect(stream, pps->b_cqm_preset, 1, "pic_scaling_matrix_present_flag"); - hal_h264e_vpu_write_se(stream, pps->i_chroma_qp_index_offset, "chroma_qp_index_offset"); - } - - hal_h264e_vpu_rbsp_trailing_bits(stream); - - h264e_hal_log_detail("pps write size: %d bytes", stream->byte_cnt); - - h264e_hal_debug_leave(); - - return MPP_OK; -} - -static void hal_h264e_vpu_set_sps(h264e_hal_sps *sps, h264e_control_extra_info_cfg *cfg) -{ - sps->i_profile_idc = cfg->profile_idc; /* 66 = baseline, 77 = main, 100 = high */ - sps->b_constraint_set0 = 1; - sps->b_constraint_set1 = 1; - sps->b_constraint_set2 = 1; - sps->b_constraint_set3 = 0; - - sps->i_level_idc = cfg->level_idc; - sps->i_id = 0; - sps->i_log2_max_frame_num = 16; - sps->i_poc_type = 2; - - sps->i_num_ref_frames = 1; - sps->b_gaps_in_frame_num_value_allowed = 0; - sps->i_mb_width = ( cfg->pic_luma_width + 15 ) / 16; - sps->i_mb_height = ( cfg->pic_luma_height + 15 ) / 16; - sps->b_frame_mbs_only = 1; - sps->b_direct8x8_inference = 1; - sps->i_chroma_format_idc = 1; //YUV420 - - sps->b_vui = 1; - - sps->vui.b_fullrange = 0; - sps->vui.i_sar_width = 0; - sps->vui.i_sar_height = 0; - sps->vui.b_aspect_ratio_info_present = 0; - sps->vui.b_overscan_info_present = 0; - sps->vui.b_signal_type_present = 0; - sps->vui.b_chroma_loc_info_present = 0; - - sps->vui.b_timing_info_present = 1; - sps->vui.i_num_units_in_tick = 1; - sps->vui.i_time_scale = 0x19; - sps->vui.b_fixed_frame_rate = 0; - - sps->vui.b_nal_hrd_parameters_present = 0; - sps->vui.b_vcl_hrd_parameters_present = 0; - sps->vui.b_pic_struct_present = 0; - - sps->vui.b_bitstream_restriction = 1; - sps->vui.b_motion_vectors_over_pic_boundaries = 1; - sps->vui.i_max_bytes_per_pic_denom = 1; - sps->vui.i_max_bits_per_mb_denom = 1; - sps->vui.i_log2_max_mv_length_horizontal = 8; - sps->vui.i_log2_max_mv_length_vertical = 7; - sps->vui.i_num_reorder_frames = 1; - sps->vui.i_max_dec_frame_buffering = 2; - - if (cfg->pic_luma_width % 16 || cfg->pic_luma_height % 16 ) { - RK_U32 fill_right = sps->i_mb_width * 16 - cfg->pic_luma_width; - RK_U32 fill_bottom = sps->i_mb_height * 16 - cfg->pic_luma_height; - sps->b_crop = 1; - sps->crop.i_right = fill_right; - sps->crop.i_bottom = fill_bottom; - sps->crop.i_left = 0; - sps->crop.i_top = 0; - } else { - sps->b_crop = 0; - sps->crop.i_right = 0; - sps->crop.i_bottom = 0; - sps->crop.i_left = 0; - sps->crop.i_top = 0; - } - - /* only for backup, exclued in read SPS */ - sps->keyframe_max_interval = cfg->keyframe_max_interval; -} - -static void hal_h264e_vpu_set_pps(h264e_hal_pps *pps, h264e_control_extra_info_cfg *cfg) -{ - pps->i_id = 0; - pps->i_sps_id = 0; - pps->b_cabac = 0; - pps->b_pic_order = 0; - pps->i_num_slice_groups = 1; - pps->i_num_ref_idx_l0_default_active = 1; - pps->i_num_ref_idx_l1_default_active = 1; - pps->b_weighted_pred = 0; - pps->i_weighted_bipred_idc = 0; - pps->i_pic_init_qp = cfg->pic_init_qp; - pps->i_pic_init_qs = cfg->pic_init_qp; - pps->i_chroma_qp_index_offset = cfg->chroma_qp_index_offset; - pps->b_deblocking_filter_control = 1; - pps->b_constrained_intra_pred = 0; - pps->b_redundant_pic_cnt = 0; - pps->b_transform_8x8_mode = cfg->transform8x8_mode; - - (void)cfg; -} - -static MPP_RET hal_h264e_vpu_init_extra_info(void *extra_info) -{ - h264e_hal_vpu_extra_info *info = (h264e_hal_vpu_extra_info *)extra_info; - h264e_hal_vpu_stream *sps_stream = &info->sps_stream; - h264e_hal_vpu_stream *pps_stream = &info->pps_stream; - - if (MPP_OK != hal_h264e_vpu_stream_buffer_init(sps_stream, 128)) { - mpp_err("sps stream sw buf init failed"); - return MPP_NOK; - } - if (MPP_OK != hal_h264e_vpu_stream_buffer_init(pps_stream, 128)) { - mpp_err("pps stream sw buf init failed"); - return MPP_NOK; - } - - return MPP_OK; -} - -static MPP_RET hal_h264e_vpu_deinit_extra_info(void *extra_info) -{ - h264e_hal_vpu_extra_info *info = (h264e_hal_vpu_extra_info *)extra_info; - h264e_hal_vpu_stream *sps_stream = &info->sps_stream; - h264e_hal_vpu_stream *pps_stream = &info->pps_stream; - - MPP_FREE(sps_stream->buffer); - MPP_FREE(pps_stream->buffer); - - return MPP_OK; -} - -static MPP_RET hal_h264e_vpu_set_extra_info(void *extra_info, void *param) -{ - h264e_control_extra_info_cfg *cfg = (h264e_control_extra_info_cfg *)param; - h264e_hal_vpu_extra_info *info = (h264e_hal_vpu_extra_info *)extra_info; - h264e_hal_vpu_stream *sps_stream = &info->sps_stream; - h264e_hal_vpu_stream *pps_stream = &info->pps_stream; - h264e_hal_sps *sps = &info->sps; - h264e_hal_pps *pps = &info->pps; - h264e_hal_debug_enter(); - - hal_h264e_vpu_stream_buffer_reset(sps_stream); - hal_h264e_vpu_stream_buffer_reset(pps_stream); - - hal_h264e_vpu_set_sps(sps, cfg); - hal_h264e_vpu_set_pps(pps, cfg); - - hal_h264e_vpu_write_sps(sps_stream, sps); - hal_h264e_vpu_write_pps(pps_stream, pps); - - h264e_hal_debug_leave(); - - return MPP_OK; -} - -static RK_S32 exp_golomb_signed(RK_S32 val) -{ - RK_S32 tmp = 0; - - if (val > 0) - val = 2 * val; - else - val = -2 * val + 1; - - while (val >> ++tmp) - ; - - return tmp * 2 - 1; -} - - -MPP_RET hal_h264e_vpu_init(void *hal, MppHalCfg *cfg) -{ - h264e_hal_context *ctx = (h264e_hal_context *)hal; - h264e_hal_debug_enter(); - - ctx->int_cb = cfg->hal_int_cb; - ctx->regs = mpp_calloc(h264e_vpu_reg_set, 1); - ctx->buffers = mpp_calloc(h264e_hal_vpu_buffers, 1); - ctx->extra_info = mpp_calloc(h264e_hal_vpu_extra_info, 1); - ctx->dump_files = mpp_calloc(h264e_hal_vpu_dump_files, 1); - ctx->param_size = H264E_MAX_PACKETED_PARAM_SIZE; - ctx->param_buf = mpp_calloc_size(void, ctx->param_size); - mpp_packet_init(&ctx->packeted_param, ctx->param_buf, ctx->param_size); - - hal_h264e_vpu_init_extra_info(ctx->extra_info); -#ifdef H264E_DUMP_DATA_TO_FILE - hal_h264e_vpu_open_dump_files(ctx->dump_files); -#endif - - ctx->vpu_socket = -1; - ctx->vpu_client = VPU_ENC; - h264e_hal_log_detail("vpu client: %d", ctx->vpu_client); -#ifdef RKPLATFORM - if (ctx->vpu_socket <= 0) { - ctx->vpu_socket = VPUClientInit(ctx->vpu_client); - if (ctx->vpu_socket <= 0) { - mpp_err("get vpu_socket(%d) <=0, failed. \n", ctx->vpu_socket); - return MPP_ERR_UNKNOW; - } else { - VPUHwEncConfig_t hwCfg; - h264e_hal_log_detail("get vpu_socket(%d), success. \n", ctx->vpu_socket); - memset(&hwCfg, 0, sizeof(VPUHwEncConfig_t)); - if (VPUClientGetHwCfg(ctx->vpu_socket, (RK_U32*)&hwCfg, sizeof(hwCfg))) { - mpp_err("h264enc # Get HwCfg failed, release vpu\n"); - VPUClientRelease(ctx->vpu_socket); - return MPP_NOK; - } - } - } -#endif - - h264e_hal_debug_leave(); - return MPP_OK; -} - -MPP_RET hal_h264e_vpu_deinit(void *hal) -{ - h264e_hal_context *ctx = (h264e_hal_context *)hal; - h264e_hal_debug_enter(); - - MPP_FREE(ctx->regs); - - if (ctx->extra_info) { - hal_h264e_vpu_deinit_extra_info(ctx->extra_info); - MPP_FREE(ctx->extra_info); - } - - if (ctx->packeted_param) { - mpp_packet_deinit(&ctx->packeted_param); - ctx->packeted_param = NULL; - } - - if (ctx->param_buf) { - mpp_free(ctx->param_buf); - ctx->param_buf = NULL; - } - - ctx->param_size = 0; - - if (ctx->buffers) { - hal_h264e_vpu_free_buffers(ctx); - MPP_FREE(ctx->buffers); - } - -#ifdef H264E_DUMP_DATA_TO_FILE - if (ctx->dump_files) { - hal_h264e_vpu_close_dump_files(ctx->dump_files); - MPP_FREE(ctx->dump_files); - } -#endif - -#ifdef RKPLATFORM - if (ctx->vpu_socket <= 0) { - mpp_err("invalid vpu socket: %d", ctx->vpu_socket); - return MPP_NOK; - } - - if (VPU_SUCCESS != VPUClientRelease(ctx->vpu_socket)) { - mpp_err("VPUClientRelease failed"); - return MPP_ERR_VPUHW; - } -#endif - - h264e_hal_debug_leave(); - return MPP_OK; -} - -static MPP_RET hal_h264e_vpu_validate_syntax(h264e_syntax *syn, h264e_hal_vpu_csp_info *src_fmt) -{ - h264e_hal_debug_enter(); - - /* validate */ - H264E_HAL_VALIDATE_GT(syn->output_strm_limit_size, "output_strm_limit_size", 0); - - /* adjust */ - syn->output_strm_limit_size /= 8; /* 64-bit addresses */ - syn->output_strm_limit_size &= (~0x07); /* 8 multiple size */ - *src_fmt = hal_h264e_vpu_convert_csp(syn->input_image_format); - syn->input_image_format = src_fmt->fmt; + break; + } + case MPP_FMT_ARGB8888: { + dst_info.fmt = H264E_VPU_CSP_NONE; + break; + } + case MPP_FMT_ABGR8888: { + dst_info.fmt = H264E_VPU_CSP_NONE; + break; + } + default: { + h264e_hal_log_err("unvalid src color space: %d", src_type); + dst_info.fmt = H264E_VPU_CSP_NONE; + } + } - H264E_HAL_VALIDATE_NEQ(syn->input_image_format, "input_image_format", H264E_VPU_CSP_NONE); - - h264e_hal_debug_leave(); - return MPP_OK; -} - - -MPP_RET hal_h264e_vpu_gen_regs(void *hal, HalTaskInfo *task) -{ - RK_S32 scaler = 0, i = 0; - RK_U32 val = 0, skip_penalty = 0; - RK_U32 overfill_r = 0, overfill_b = 0; - RK_U32 first_free_bit = 0, constrained_intra_prediction = 0; - RK_U8 dmv_penalty[128] = {0}; - RK_U8 dmv_qpel_penalty[128] = {0}; - RK_U32 diff_mv_penalty[3] = {0}; - h264e_hal_vpu_csp_info src_fmt; + return dst_info; +} + + +static MPP_RET hal_h264e_vpu_free_buffers(h264e_hal_context *ctx) +{ + RK_S32 k = 0; + h264e_hal_vpu_buffers *buffers = (h264e_hal_vpu_buffers *)ctx->buffers; + h264e_hal_debug_enter(); + + if (buffers->hw_cabac_table_buf) { + if (MPP_OK != mpp_buffer_put(buffers->hw_cabac_table_buf)) { + mpp_err("hw_cabac_table_buf put failed"); + return MPP_NOK; + } + } + + if (buffers->hw_nal_size_table_buf) { + if (MPP_OK != mpp_buffer_put(buffers->hw_nal_size_table_buf)) { + mpp_err("hw_nal_size_table_buf put failed"); + return MPP_NOK; + } + } + + + for (k = 0; k < 2; k++) { + if (buffers->hw_rec_buf[k]) { + if (MPP_OK != mpp_buffer_put(buffers->hw_rec_buf[k])) { + mpp_err("hw_rec_buf[%d] put failed", k); + return MPP_NOK; + } + } + } + + if (buffers->hw_buf_grp) { + if (MPP_OK != mpp_buffer_group_put(buffers->hw_buf_grp)) { + mpp_err("buf group[%d] put failed", k); + return MPP_NOK; + } + buffers->hw_buf_grp = NULL; + } + + h264e_hal_debug_leave(); + return MPP_OK; +} + +static void hal_h264e_vpu_write_cabac_table(h264e_syntax *syn, MppBuffer hw_cabac_tab_buf) +{ + const RK_S32(*context)[460][2]; + RK_S32 i, j, qp; + + RK_U8 table[H264E_CABAC_TABLE_BUF_SIZE] = {0}; + RK_U32 cabac_init_idc = syn->cabac_init_idc; + + h264e_hal_debug_enter(); + + for (qp = 0; qp < 52; qp++) { /* All QP values */ + for (j = 0; j < 2; j++) { /* Intra/Inter */ + if (j == 0) + /*lint -e(545) */ + context = &h264_context_init_intra; + else + /*lint -e(545) */ + context = &h264_context_init[cabac_init_idc]; + + for (i = 0; i < 460; i++) { + RK_S32 m = (RK_S32)(*context)[i][0]; + RK_S32 n = (RK_S32)(*context)[i][1]; + + RK_S32 pre_ctx_state = + H264E_HAL_CLIP3(1, 126, + ((m * (RK_S32)qp) >> 4) + n); + + if (pre_ctx_state <= 63) { + table[qp * 464 * 2 + j * 464 + i] = + (RK_U8)((63 + - pre_ctx_state) << 1); + } else { + table[qp * 464 * 2 + j * 464 + i] = + (RK_U8)(((pre_ctx_state - 64) + << 1) | 1); + } + } + } + } + + mpp_buffer_write(hw_cabac_tab_buf, 0, table, H264E_CABAC_TABLE_BUF_SIZE); + + h264e_hal_debug_leave(); +} + +static MPP_RET hal_h264e_vpu_allocate_buffers(h264e_hal_context *ctx, h264e_syntax *syn) +{ + MPP_RET ret = MPP_OK; + RK_S32 k = 0; + h264e_hal_vpu_buffers *buffers = (h264e_hal_vpu_buffers *)ctx->buffers; + RK_U32 frame_size = ((syn->pic_luma_width + 15) & (~15)) * ((syn->pic_luma_height + 15) & (~15)) * 3 / 2; + + h264e_hal_debug_enter(); + ret = mpp_buffer_group_get_internal(&buffers->hw_buf_grp, MPP_BUFFER_TYPE_ION); + if (ret) { + mpp_err("buf group get failed ret %d\n", ret); + return ret; + } + + ret = mpp_buffer_get(buffers->hw_buf_grp, &buffers->hw_cabac_table_buf, H264E_CABAC_TABLE_BUF_SIZE); + if (ret) { + mpp_err("hw_cabac_table_buf get failed\n"); + return ret; + } + + ret = mpp_buffer_get(buffers->hw_buf_grp, &buffers->hw_nal_size_table_buf, (sizeof(RK_U32) * (syn->pic_luma_height + 1) + 7) & (~7)); + if (ret) { + mpp_err("hw_nal_size_table_buf get failed\n"); + return ret; + } + + for (k = 0; k < 2; k++) { + ret = mpp_buffer_get(buffers->hw_buf_grp, &buffers->hw_rec_buf[k], frame_size + 4096); + if (ret) { + mpp_err("hw_rec_buf[%d] get failed\n", k); + return ret; + } + } + + hal_h264e_vpu_write_cabac_table(syn, buffers->hw_cabac_table_buf); + + h264e_hal_debug_leave(); + return MPP_OK; +} + + +static MPP_RET hal_h264e_vpu_stream_buffer_status(h264e_hal_vpu_stream *stream) +{ + if (stream->byte_cnt + 5 > stream->size) { + stream->overflow = 1; + return MPP_NOK; + } + + return MPP_OK; +} + +static MPP_RET hal_h264e_vpu_stream_buffer_reset(h264e_hal_vpu_stream *strmbuf) +{ + strmbuf->stream = strmbuf->buffer; + strmbuf->byte_cnt = 0; + strmbuf->overflow = 0; + strmbuf->byte_buffer = 0; + strmbuf->buffered_bits = 0; + strmbuf->zero_bytes = 0; + strmbuf->emul_cnt = 0; + + return MPP_OK; +} + +static MPP_RET hal_h264e_vpu_stream_buffer_init(h264e_hal_vpu_stream *strmbuf, RK_S32 size) +{ + strmbuf->buffer = mpp_calloc(RK_U8, size); + + if (strmbuf->buffer == NULL) { + mpp_err("allocate stream buffer failed\n"); + return MPP_NOK; + } + strmbuf->stream = strmbuf->buffer; + strmbuf->size = size; + strmbuf->byte_cnt = 0; + strmbuf->overflow = 0; + strmbuf->byte_buffer = 0; + strmbuf->buffered_bits = 0; + strmbuf->zero_bytes = 0; + strmbuf->emul_cnt = 0; + + if (MPP_OK != hal_h264e_vpu_stream_buffer_status(strmbuf)) { + mpp_err("stream buffer is overflow, while init"); + return MPP_NOK; + } + + return MPP_OK; +} + + +void hal_h264e_vpu_stream_put_bits(h264e_hal_vpu_stream *buffer, RK_S32 value, RK_S32 number, + const char *name) +{ + RK_S32 bits; + RK_U32 byte_buffer = buffer->byte_buffer; + RK_U8*stream = buffer->stream; + + if (hal_h264e_vpu_stream_buffer_status(buffer) != 0) + return; + + h264e_hal_log_detail("assemble %s value %x, bits %d\n", name, value, number); + + mpp_assert(value < (1 << number)); //opposite to 'BUG_ON' in kernel + mpp_assert(number < 25); + + bits = number + buffer->buffered_bits; + value <<= (32 - bits); + byte_buffer = byte_buffer | value; + + while (bits > 7) { + *stream = (RK_U8)(byte_buffer >> 24); + + bits -= 8; + byte_buffer <<= 8; + stream++; + buffer->byte_cnt++; + } + + buffer->byte_buffer = byte_buffer; + buffer->buffered_bits = (RK_U8)bits; + buffer->stream = stream; + + return; +} + +void hal_h264e_vpu_stream_put_bits_with_detect(h264e_hal_vpu_stream * buffer, RK_S32 value, RK_S32 number, const char *name) +{ + RK_S32 bits; + RK_U8 *stream = buffer->stream; + RK_U32 byte_buffer = buffer->byte_buffer; + + mpp_assert(value < (1 << number)); + mpp_assert(number < 25); + + h264e_hal_log_detail("assemble %s value %x, bits %d\n", name, value, number); + + bits = number + buffer->buffered_bits; + byte_buffer = byte_buffer | ((RK_U32) value << (32 - bits)); + + while (bits > 7) { + RK_S32 zeroBytes = buffer->zero_bytes; + RK_S32 byteCnt = buffer->byte_cnt; + + if (hal_h264e_vpu_stream_buffer_status(buffer) != MPP_OK) + return; + + *stream = (RK_U8) (byte_buffer >> 24); + byteCnt++; + + if ((zeroBytes == 2) && (*stream < 4)) { + *stream++ = 3; + *stream = (RK_U8) (byte_buffer >> 24); + byteCnt++; + zeroBytes = 0; + buffer->emul_cnt++; + } + + if (*stream == 0) + zeroBytes++; + else + zeroBytes = 0; + + bits -= 8; + byte_buffer <<= 8; + stream++; + buffer->zero_bytes = zeroBytes; + buffer->byte_cnt = byteCnt; + buffer->stream = stream; + } + + buffer->buffered_bits = (RK_U8) bits; + buffer->byte_buffer = byte_buffer; +} + + +void hal_h264e_vpu_rbsp_trailing_bits(h264e_hal_vpu_stream * stream) +{ + hal_h264e_vpu_stream_put_bits_with_detect(stream, 1, 1, "rbsp_stop_one_bit"); + if (stream->buffered_bits > 0) { + hal_h264e_vpu_stream_put_bits_with_detect(stream, 0, 8 - stream->buffered_bits, "bsp_alignment_zero_bit(s)"); + } +} + +static void hal_h264e_vpu_write_ue(h264e_hal_vpu_stream *fifo, RK_U32 val, + const char *name) +{ + RK_U32 num_bits = 0; + + val++; + while (val >> ++num_bits); + + if (num_bits > 12) { + RK_U32 tmp; + + tmp = num_bits - 1; + + if (tmp > 24) { + tmp -= 24; + hal_h264e_vpu_stream_put_bits_with_detect(fifo, 0, 24, name); + } + + hal_h264e_vpu_stream_put_bits_with_detect(fifo, 0, tmp, name); + + if (num_bits > 24) { + num_bits -= 24; + hal_h264e_vpu_stream_put_bits_with_detect(fifo, val >> num_bits, 24, name); + val = val >> num_bits; + } + + hal_h264e_vpu_stream_put_bits_with_detect(fifo, val, num_bits, name); + } else { + hal_h264e_vpu_stream_put_bits_with_detect(fifo, val, 2 * num_bits - 1, name); + } +} + +static void hal_h264e_vpu_write_se(h264e_hal_vpu_stream *fifo, RK_S32 val, const char *name) +{ + RK_U32 tmp; + + if (val > 0) + tmp = (RK_U32)(2 * val - 1); + else + tmp = (RK_U32)(-2 * val); + + hal_h264e_vpu_write_ue(fifo, tmp, name); +} + +static MPP_RET hal_h264e_vpu_nal_start(h264e_hal_vpu_stream * stream, RK_S32 nalRefIdc, rkvenc_nal_unit_type nalUnitType) +{ + hal_h264e_vpu_stream_put_bits(stream, 0, 8, "leadin_zero_8bits"); + hal_h264e_vpu_stream_put_bits(stream, 0, 8, "start_code_prefix"); + hal_h264e_vpu_stream_put_bits(stream, 0, 8, "start_code_prefix"); + hal_h264e_vpu_stream_put_bits(stream, 1, 8, "start_code_prefix"); + hal_h264e_vpu_stream_put_bits(stream, 0, 1, "forbidden_zero_bit"); + hal_h264e_vpu_stream_put_bits(stream, nalRefIdc, 2, "nal_ref_idc"); + hal_h264e_vpu_stream_put_bits(stream, (RK_S32)nalUnitType, 5, "nal_unit_type"); + stream->zero_bytes = 0; /* we start new counter for zero bytes */ + + return MPP_OK; +} + + + +static MPP_RET hal_h264e_vpu_write_sps(h264e_hal_vpu_stream *stream, h264e_hal_sps *sps) +{ + h264e_hal_debug_enter(); + + hal_h264e_vpu_nal_start(stream, 1, RKVENC_NAL_SPS); + + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->i_profile_idc, 8, "profile_idc"); //FIXED: 77, 42 + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->b_constraint_set0, 1, "constraint_set0_flag"); //E0 + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->b_constraint_set1, 1, "constraint_set1_flag"); + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->b_constraint_set2, 1, "constraint_set2_flag"); + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->b_constraint_set3, 1, "constraint_set3_flag"); + + hal_h264e_vpu_stream_put_bits_with_detect(stream, 0, 4, "reserved_zero_4bits"); + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->i_level_idc, 8, "level_idc"); //28 + + hal_h264e_vpu_write_ue(stream, sps->i_id, "seq_parameter_set_id"); //8D + + if (sps->i_profile_idc >= 100) { //High profile + hal_h264e_vpu_write_ue(stream, sps->i_chroma_format_idc, "chroma_format_idc"); + hal_h264e_vpu_write_ue(stream, H264_BIT_DEPTH - 8, "bit_depth_luma_minus8"); + hal_h264e_vpu_write_ue(stream, H264_BIT_DEPTH - 8, "bit_depth_chroma_minus8"); + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->b_qpprime_y_zero_transform_bypass, 1, "qpprime_y_zero_transform_bypass_flag"); + hal_h264e_vpu_stream_put_bits_with_detect(stream, 0, 1, "seq_scaling_matrix_present_flag"); + } + + hal_h264e_vpu_write_ue(stream, sps->i_log2_max_frame_num - 4, "log2_max_frame_num_minus4"); + + hal_h264e_vpu_write_ue(stream, sps->i_poc_type, "pic_order_cnt_type"); //68 16 + + hal_h264e_vpu_write_ue(stream, sps->i_num_ref_frames, "num_ref_frames"); + + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->b_gaps_in_frame_num_value_allowed, 1, "gaps_in_frame_num_value_allowed_flag"); + + hal_h264e_vpu_write_ue(stream, sps->i_mb_width - 1, "pic_width_in_mbs_minus1"); + + hal_h264e_vpu_write_ue(stream, sps->i_mb_height - 1, "pic_height_in_map_units_minus1"); //09 64 + + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->b_frame_mbs_only, 1, "frame_mbs_only_flag"); + + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->b_direct8x8_inference, 1, "direct_8x8_inference_flag"); + + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->b_crop, 1, "frame_cropping_flag"); + if (sps->b_crop) { + hal_h264e_vpu_write_ue(stream, sps->crop.i_left / 2, "frame_crop_left_offset"); + hal_h264e_vpu_write_ue(stream, sps->crop.i_right / 2, "frame_crop_right_offset"); + hal_h264e_vpu_write_ue(stream, sps->crop.i_top / 2, "frame_crop_top_offset"); + hal_h264e_vpu_write_ue(stream, sps->crop.i_bottom / 2, "frame_crop_bottom_offset"); + } + + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->b_vui, 1, "vui_parameters_present_flag"); + if (sps->b_vui) { + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.b_aspect_ratio_info_present, 1, "aspect_ratio_info_present_flag"); + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.b_overscan_info_present, 1, "overscan_info_present_flag"); + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.b_signal_type_present, 1, "video_signal_type_present_flag"); + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.b_chroma_loc_info_present, 1, "chroma_loc_info_present_flag"); + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.b_timing_info_present, 1, "timing_info_present_flag"); + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.i_num_units_in_tick >> 16, 16, "num_units_in_tick msb"); + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.i_num_units_in_tick & 0xffff, 16, "num_units_in_tick lsb"); + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.i_time_scale >> 16, 16, "time_scale msb"); + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.i_time_scale & 0xffff, 16, "time_scale lsb"); + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.b_fixed_frame_rate, 1, "fixed_frame_rate_flag"); + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.b_nal_hrd_parameters_present, 1, "nal_hrd_parameters_present_flag"); + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.b_vcl_hrd_parameters_present, 1, "vcl_hrd_parameters_present_flag"); + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.b_pic_struct_present, 1, "pic_struct_present_flag"); + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.b_bitstream_restriction, 1, "bit_stream_restriction_flag"); + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.b_motion_vectors_over_pic_boundaries, 1, "motion_vectors_over_pic_boundaries"); + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.i_max_bytes_per_pic_denom, 1, "max_bytes_per_pic_denom"); + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.i_max_bits_per_mb_denom, 1, "max_bits_per_mb_denom"); + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.i_log2_max_mv_length_horizontal, 7, "log2_mv_length_horizontal"); + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.i_log2_max_mv_length_vertical, 5, "log2_mv_length_vertical"); + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.i_num_reorder_frames, 1, "num_reorder_frames"); + hal_h264e_vpu_stream_put_bits_with_detect(stream, sps->vui.i_max_dec_frame_buffering, 3, "max_dec_frame_buffering"); + } + + hal_h264e_vpu_rbsp_trailing_bits(stream); + + h264e_hal_log_detail("sps write size: %d bytes", stream->byte_cnt); + + h264e_hal_debug_leave(); + + return MPP_OK; +} + +static MPP_RET hal_h264e_vpu_write_pps(h264e_hal_vpu_stream *stream, h264e_hal_pps *pps) +{ + h264e_hal_debug_enter(); + + hal_h264e_vpu_nal_start(stream, 1, RKVENC_NAL_PPS); + + hal_h264e_vpu_write_ue(stream, pps->i_id, "pic_parameter_set_id"); + hal_h264e_vpu_write_ue(stream, pps->i_sps_id, "seq_parameter_set_id"); + + hal_h264e_vpu_stream_put_bits_with_detect(stream, pps->b_cabac, 1, "entropy_coding_mode_flag"); + hal_h264e_vpu_stream_put_bits_with_detect(stream, pps->b_pic_order, 1, "pic_order_present_flag"); + + hal_h264e_vpu_write_ue(stream, pps->i_num_slice_groups - 1, "num_slice_groups_minus1"); + hal_h264e_vpu_write_ue(stream, pps->i_num_ref_idx_l0_default_active - 1, "num_ref_idx_l0_active_minus1"); + hal_h264e_vpu_write_ue(stream, pps->i_num_ref_idx_l1_default_active - 1, "num_ref_idx_l1_active_minus1"); + + hal_h264e_vpu_stream_put_bits_with_detect(stream, pps->b_weighted_pred, 1, "weighted_pred_flag"); + hal_h264e_vpu_stream_put_bits_with_detect(stream, pps->i_weighted_bipred_idc, 2, "weighted_bipred_idc"); + + hal_h264e_vpu_write_se(stream, pps->i_pic_init_qp - 26, "pic_init_qp_minus26"); + hal_h264e_vpu_write_se(stream, pps->i_pic_init_qs - 26, "pic_init_qs_minus26"); + hal_h264e_vpu_write_se(stream, pps->i_chroma_qp_index_offset, "chroma_qp_index_offset"); + + hal_h264e_vpu_stream_put_bits_with_detect(stream, pps->b_deblocking_filter_control, 1, "deblocking_filter_control_present_flag"); + hal_h264e_vpu_stream_put_bits_with_detect(stream, pps->b_constrained_intra_pred, 1, "constrained_intra_pred_flag"); + + hal_h264e_vpu_stream_put_bits_with_detect(stream, pps->b_redundant_pic_cnt, 1, "redundant_pic_cnt_present_flag"); + + if (pps->b_transform_8x8_mode) { + hal_h264e_vpu_stream_put_bits_with_detect(stream, pps->b_transform_8x8_mode, 1, "transform_8x8_mode_flag"); + hal_h264e_vpu_stream_put_bits_with_detect(stream, pps->b_cqm_preset, 1, "pic_scaling_matrix_present_flag"); + hal_h264e_vpu_write_se(stream, pps->i_chroma_qp_index_offset, "chroma_qp_index_offset"); + } + + hal_h264e_vpu_rbsp_trailing_bits(stream); + + h264e_hal_log_detail("pps write size: %d bytes", stream->byte_cnt); + + h264e_hal_debug_leave(); + + return MPP_OK; +} + +static void hal_h264e_vpu_set_sps(h264e_hal_sps *sps, h264e_control_extra_info_cfg *cfg) +{ + sps->i_profile_idc = cfg->profile_idc; /* 66 = baseline, 77 = main, 100 = high */ + sps->b_constraint_set0 = 1; + sps->b_constraint_set1 = 1; + sps->b_constraint_set2 = 1; + sps->b_constraint_set3 = 0; + + sps->i_level_idc = cfg->level_idc; + sps->i_id = 0; + sps->i_log2_max_frame_num = 16; + sps->i_poc_type = 2; + + sps->i_num_ref_frames = 1; + sps->b_gaps_in_frame_num_value_allowed = 0; + sps->i_mb_width = ( cfg->pic_luma_width + 15 ) / 16; + sps->i_mb_height = ( cfg->pic_luma_height + 15 ) / 16; + sps->b_frame_mbs_only = 1; + sps->b_direct8x8_inference = 1; + sps->i_chroma_format_idc = 1; //YUV420 + + sps->b_vui = 1; + + sps->vui.b_fullrange = 0; + sps->vui.i_sar_width = 0; + sps->vui.i_sar_height = 0; + sps->vui.b_aspect_ratio_info_present = 0; + sps->vui.b_overscan_info_present = 0; + sps->vui.b_signal_type_present = 0; + sps->vui.b_chroma_loc_info_present = 0; + + sps->vui.b_timing_info_present = 1; + sps->vui.i_num_units_in_tick = 1; + sps->vui.i_time_scale = 0x19; + sps->vui.b_fixed_frame_rate = 0; + + sps->vui.b_nal_hrd_parameters_present = 0; + sps->vui.b_vcl_hrd_parameters_present = 0; + sps->vui.b_pic_struct_present = 0; + + sps->vui.b_bitstream_restriction = 1; + sps->vui.b_motion_vectors_over_pic_boundaries = 1; + sps->vui.i_max_bytes_per_pic_denom = 1; + sps->vui.i_max_bits_per_mb_denom = 1; + sps->vui.i_log2_max_mv_length_horizontal = 8; + sps->vui.i_log2_max_mv_length_vertical = 7; + sps->vui.i_num_reorder_frames = 1; + sps->vui.i_max_dec_frame_buffering = 2; + + if (cfg->pic_luma_width % 16 || cfg->pic_luma_height % 16 ) { + RK_U32 fill_right = sps->i_mb_width * 16 - cfg->pic_luma_width; + RK_U32 fill_bottom = sps->i_mb_height * 16 - cfg->pic_luma_height; + sps->b_crop = 1; + sps->crop.i_right = fill_right; + sps->crop.i_bottom = fill_bottom; + sps->crop.i_left = 0; + sps->crop.i_top = 0; + } else { + sps->b_crop = 0; + sps->crop.i_right = 0; + sps->crop.i_bottom = 0; + sps->crop.i_left = 0; + sps->crop.i_top = 0; + } + + /* only for backup, exclued in read SPS */ + sps->keyframe_max_interval = cfg->keyframe_max_interval; +} + +static void hal_h264e_vpu_set_pps(h264e_hal_pps *pps, h264e_control_extra_info_cfg *cfg) +{ + pps->i_id = 0; + pps->i_sps_id = 0; + pps->b_cabac = 0; + pps->b_pic_order = 0; + pps->i_num_slice_groups = 1; + pps->i_num_ref_idx_l0_default_active = 1; + pps->i_num_ref_idx_l1_default_active = 1; + pps->b_weighted_pred = 0; + pps->i_weighted_bipred_idc = 0; + pps->i_pic_init_qp = cfg->pic_init_qp; + pps->i_pic_init_qs = cfg->pic_init_qp; + pps->i_chroma_qp_index_offset = cfg->chroma_qp_index_offset; + pps->b_deblocking_filter_control = 1; + pps->b_constrained_intra_pred = 0; + pps->b_redundant_pic_cnt = 0; + pps->b_transform_8x8_mode = cfg->transform8x8_mode; + + (void)cfg; +} + +static MPP_RET hal_h264e_vpu_init_extra_info(void *extra_info) +{ + h264e_hal_vpu_extra_info *info = (h264e_hal_vpu_extra_info *)extra_info; + h264e_hal_vpu_stream *sps_stream = &info->sps_stream; + h264e_hal_vpu_stream *pps_stream = &info->pps_stream; + + if (MPP_OK != hal_h264e_vpu_stream_buffer_init(sps_stream, 128)) { + mpp_err("sps stream sw buf init failed"); + return MPP_NOK; + } + if (MPP_OK != hal_h264e_vpu_stream_buffer_init(pps_stream, 128)) { + mpp_err("pps stream sw buf init failed"); + return MPP_NOK; + } + + return MPP_OK; +} + +static MPP_RET hal_h264e_vpu_deinit_extra_info(void *extra_info) +{ + h264e_hal_vpu_extra_info *info = (h264e_hal_vpu_extra_info *)extra_info; + h264e_hal_vpu_stream *sps_stream = &info->sps_stream; + h264e_hal_vpu_stream *pps_stream = &info->pps_stream; + + MPP_FREE(sps_stream->buffer); + MPP_FREE(pps_stream->buffer); + + return MPP_OK; +} + +static MPP_RET hal_h264e_vpu_set_extra_info(void *extra_info, void *param) +{ + h264e_control_extra_info_cfg *cfg = (h264e_control_extra_info_cfg *)param; + h264e_hal_vpu_extra_info *info = (h264e_hal_vpu_extra_info *)extra_info; + h264e_hal_vpu_stream *sps_stream = &info->sps_stream; + h264e_hal_vpu_stream *pps_stream = &info->pps_stream; + h264e_hal_sps *sps = &info->sps; + h264e_hal_pps *pps = &info->pps; + h264e_hal_debug_enter(); + + hal_h264e_vpu_stream_buffer_reset(sps_stream); + hal_h264e_vpu_stream_buffer_reset(pps_stream); + + hal_h264e_vpu_set_sps(sps, cfg); + hal_h264e_vpu_set_pps(pps, cfg); + + hal_h264e_vpu_write_sps(sps_stream, sps); + hal_h264e_vpu_write_pps(pps_stream, pps); + + h264e_hal_debug_leave(); + + return MPP_OK; +} + +static RK_S32 exp_golomb_signed(RK_S32 val) +{ + RK_S32 tmp = 0; + + if (val > 0) + val = 2 * val; + else + val = -2 * val + 1; + + while (val >> ++tmp) + ; + + return tmp * 2 - 1; +} + + +MPP_RET hal_h264e_vpu_init(void *hal, MppHalCfg *cfg) +{ + h264e_hal_context *ctx = (h264e_hal_context *)hal; + h264e_hal_debug_enter(); + + ctx->int_cb = cfg->hal_int_cb; + ctx->regs = mpp_calloc(h264e_vpu_reg_set, 1); + ctx->buffers = mpp_calloc(h264e_hal_vpu_buffers, 1); + ctx->extra_info = mpp_calloc(h264e_hal_vpu_extra_info, 1); + ctx->dump_files = mpp_calloc(h264e_hal_vpu_dump_files, 1); + ctx->param_size = H264E_MAX_PACKETED_PARAM_SIZE; + ctx->param_buf = mpp_calloc_size(void, ctx->param_size); + mpp_packet_init(&ctx->packeted_param, ctx->param_buf, ctx->param_size); + + hal_h264e_vpu_init_extra_info(ctx->extra_info); +#ifdef H264E_DUMP_DATA_TO_FILE + hal_h264e_vpu_open_dump_files(ctx->dump_files); +#endif + + ctx->vpu_socket = -1; + ctx->vpu_client = VPU_ENC; + h264e_hal_log_detail("vpu client: %d", ctx->vpu_client); +#ifdef RKPLATFORM + if (ctx->vpu_socket <= 0) { + ctx->vpu_socket = VPUClientInit(ctx->vpu_client); + if (ctx->vpu_socket <= 0) { + mpp_err("get vpu_socket(%d) <=0, failed. \n", ctx->vpu_socket); + return MPP_ERR_UNKNOW; + } else { + VPUHwEncConfig_t hwCfg; + h264e_hal_log_detail("get vpu_socket(%d), success. \n", ctx->vpu_socket); + memset(&hwCfg, 0, sizeof(VPUHwEncConfig_t)); + if (VPUClientGetHwCfg(ctx->vpu_socket, (RK_U32*)&hwCfg, sizeof(hwCfg))) { + mpp_err("h264enc # Get HwCfg failed, release vpu\n"); + VPUClientRelease(ctx->vpu_socket); + return MPP_NOK; + } + } + } +#endif + + h264e_hal_debug_leave(); + return MPP_OK; +} + +MPP_RET hal_h264e_vpu_deinit(void *hal) +{ + h264e_hal_context *ctx = (h264e_hal_context *)hal; + h264e_hal_debug_enter(); + + MPP_FREE(ctx->regs); + + if (ctx->extra_info) { + hal_h264e_vpu_deinit_extra_info(ctx->extra_info); + MPP_FREE(ctx->extra_info); + } + + if (ctx->packeted_param) { + mpp_packet_deinit(&ctx->packeted_param); + ctx->packeted_param = NULL; + } + + if (ctx->param_buf) { + mpp_free(ctx->param_buf); + ctx->param_buf = NULL; + } + + ctx->param_size = 0; + + if (ctx->buffers) { + hal_h264e_vpu_free_buffers(ctx); + MPP_FREE(ctx->buffers); + } + +#ifdef H264E_DUMP_DATA_TO_FILE + if (ctx->dump_files) { + hal_h264e_vpu_close_dump_files(ctx->dump_files); + MPP_FREE(ctx->dump_files); + } +#endif + +#ifdef RKPLATFORM + if (ctx->vpu_socket <= 0) { + mpp_err("invalid vpu socket: %d", ctx->vpu_socket); + return MPP_NOK; + } + + if (VPU_SUCCESS != VPUClientRelease(ctx->vpu_socket)) { + mpp_err("VPUClientRelease failed"); + return MPP_ERR_VPUHW; + } +#endif + + h264e_hal_debug_leave(); + return MPP_OK; +} + +static MPP_RET hal_h264e_vpu_validate_syntax(h264e_syntax *syn, h264e_hal_vpu_csp_info *src_fmt) +{ + h264e_hal_debug_enter(); + + /* validate */ + H264E_HAL_VALIDATE_GT(syn->output_strm_limit_size, "output_strm_limit_size", 0); + + /* adjust */ + syn->output_strm_limit_size /= 8; /* 64-bit addresses */ + syn->output_strm_limit_size &= (~0x07); /* 8 multiple size */ + *src_fmt = hal_h264e_vpu_convert_csp(syn->input_image_format); + syn->input_image_format = src_fmt->fmt; + + H264E_HAL_VALIDATE_NEQ(syn->input_image_format, "input_image_format", H264E_VPU_CSP_NONE); + + h264e_hal_debug_leave(); + return MPP_OK; +} + + +MPP_RET hal_h264e_vpu_gen_regs(void *hal, HalTaskInfo *task) +{ + RK_S32 scaler = 0, i = 0; + RK_U32 val = 0, skip_penalty = 0; + RK_U32 overfill_r = 0, overfill_b = 0; + RK_U32 first_free_bit = 0, constrained_intra_prediction = 0; + RK_U8 dmv_penalty[128] = {0}; + RK_U8 dmv_qpel_penalty[128] = {0}; + RK_U32 diff_mv_penalty[3] = {0}; + h264e_hal_vpu_csp_info src_fmt; + + h264e_hal_context *ctx = (h264e_hal_context *)hal; + RK_U32 *reg = (RK_U32 *)ctx->regs; + h264e_syntax *syn = (h264e_syntax *)task->enc.syntax.data; + + RK_U32 mbs_in_row = (syn->pic_luma_width + 15) / 16; + RK_U32 mbs_in_col = (syn->pic_luma_height + 15) / 16; + RK_U32 prev_mode_favor = h264_prev_mode_favor[syn->qp]; + h264e_hal_vpu_buffers *bufs = (h264e_hal_vpu_buffers *)ctx->buffers; + RK_U32 buf2_idx = ctx->frame_cnt % 2; + h264e_hal_vpu_extra_info *extra_info = (h264e_hal_vpu_extra_info *)ctx->extra_info; + h264e_hal_pps *pps = &extra_info->pps; + h264e_hal_debug_enter(); + + if (ctx->frame_cnt == 0) { + if (MPP_OK != hal_h264e_vpu_allocate_buffers(ctx, syn)) { + h264e_hal_log_err("hal_h264e_vpu_allocate_buffers failed, free now"); + hal_h264e_vpu_free_buffers(ctx); + } + } + +#ifdef H264E_DUMP_DATA_TO_FILE + hal_h264e_vpu_dump_mpp_syntax_in(syn, ctx); +#endif + if (MPP_OK != hal_h264e_vpu_validate_syntax(syn, &src_fmt)) { + h264e_hal_log_err("hal_h264e_vpu_validate_syntax failed"); + } + ctx->enc_task = task->enc; + memset(reg, 0, sizeof(h264e_vpu_reg_set)); + + h264e_hal_log_detail("frame %d generate regs now", ctx->frame_cnt); + + /* If frame encode type for current frame is intra, write sps pps to + the output buffer */ + H264E_HAL_SET_REG(reg, VEPU_REG_STR_BUF_LIMIT, syn->output_strm_limit_size); + + /* + * The hardware needs only the value for luma plane, because + * values of other planes are calculated internally based on + * format setting. + */ + val = VEPU_REG_INTRA_AREA_TOP(mbs_in_col) + | VEPU_REG_INTRA_AREA_BOTTOM(mbs_in_col) + | VEPU_REG_INTRA_AREA_LEFT(mbs_in_row) + | VEPU_REG_INTRA_AREA_RIGHT(mbs_in_row); + H264E_HAL_SET_REG(reg, VEPU_REG_INTRA_AREA_CTRL, val); //FIXED + H264E_HAL_SET_REG(reg, VEPU_REG_STR_HDR_REM_MSB, 0); + H264E_HAL_SET_REG(reg, VEPU_REG_STR_HDR_REM_LSB, 0); + + + val = VEPU_REG_AXI_CTRL_READ_ID(0); + val |= VEPU_REG_AXI_CTRL_WRITE_ID(0); + val |= VEPU_REG_AXI_CTRL_BURST_LEN(16); + val |= VEPU_REG_AXI_CTRL_INCREMENT_MODE(0); + val |= VEPU_REG_AXI_CTRL_BIRST_DISCARD(0); + H264E_HAL_SET_REG(reg, VEPU_REG_AXI_CTRL, val); + + H264E_HAL_SET_REG(reg, VEPU_QP_ADJUST_MAD_DELTA_ROI, syn->mad_qp_delta); + + val = 0; + if (mbs_in_row * mbs_in_col > 3600) + val = VEPU_REG_DISABLE_QUARTER_PIXEL_MV; + val |= VEPU_REG_CABAC_INIT_IDC(syn->cabac_init_idc); + if (syn->enable_cabac) + val |= VEPU_REG_ENTROPY_CODING_MODE; + if (pps->b_transform_8x8_mode) + val |= VEPU_REG_H264_TRANS8X8_MODE; + if (syn->h264_inter4x4_disabled) + val |= VEPU_REG_H264_INTER4X4_MODE; + /*reg |= VEPU_REG_H264_STREAM_MODE;*/ + val |= VEPU_REG_H264_SLICE_SIZE(syn->slice_size_mb_rows); + H264E_HAL_SET_REG(reg, VEPU_REG_ENC_CTRL0, val); + + scaler = H264E_HAL_MAX(1, 200 / (mbs_in_row + mbs_in_col)); + skip_penalty = H264E_HAL_MIN(255, h264_skip_sad_penalty[syn->qp] * scaler); + if (syn->pic_luma_width & 0x0f) + overfill_r = (16 - (syn->pic_luma_width & 0x0f) ) / 4; + if (syn->pic_luma_height & 0x0f) + overfill_b = 16 - (syn->pic_luma_height & 0x0f); + val = VEPU_REG_STREAM_START_OFFSET(first_free_bit) | + VEPU_REG_SKIP_MACROBLOCK_PENALTY(skip_penalty) | + VEPU_REG_IN_IMG_CTRL_OVRFLR_D4(overfill_r) | + VEPU_REG_IN_IMG_CTRL_OVRFLB(overfill_b); + H264E_HAL_SET_REG(reg, VEPU_REG_ENC_OVER_FILL_STRM_OFFSET, val); + + + val = VEPU_REG_IN_IMG_CHROMA_OFFSET(0) + | VEPU_REG_IN_IMG_LUMA_OFFSET(0) + | VEPU_REG_IN_IMG_CTRL_ROW_LEN(syn->pic_luma_width); + H264E_HAL_SET_REG(reg, VEPU_REG_INPUT_LUMA_INFO, val); + + val = VEPU_REG_CHECKPOINT_CHECK1(syn->cp_target[0]) + | VEPU_REG_CHECKPOINT_CHECK0(syn->cp_target[1]); + H264E_HAL_SET_REG(reg, VEPU_REG_CHECKPOINT(0), val); + + val = VEPU_REG_CHECKPOINT_CHECK1(syn->cp_target[2]) + | VEPU_REG_CHECKPOINT_CHECK0(syn->cp_target[3]); + H264E_HAL_SET_REG(reg, VEPU_REG_CHECKPOINT(1), val); + + val = VEPU_REG_CHECKPOINT_CHECK1(syn->cp_target[4]) + | VEPU_REG_CHECKPOINT_CHECK0(syn->cp_target[5]); + H264E_HAL_SET_REG(reg, VEPU_REG_CHECKPOINT(2), val); + + val = VEPU_REG_CHECKPOINT_CHECK1(syn->cp_target[6]) + | VEPU_REG_CHECKPOINT_CHECK0(syn->cp_target[7]); + H264E_HAL_SET_REG(reg, VEPU_REG_CHECKPOINT(3), val); + + val = VEPU_REG_CHECKPOINT_CHECK1(syn->cp_target[8]) + | VEPU_REG_CHECKPOINT_CHECK0(syn->cp_target[9]); + H264E_HAL_SET_REG(reg, VEPU_REG_CHECKPOINT(4), val); + + val = VEPU_REG_CHKPT_WORD_ERR_CHK1(syn->target_error[0]) + | VEPU_REG_CHKPT_WORD_ERR_CHK0(syn->target_error[1]); + H264E_HAL_SET_REG(reg, VEPU_REG_CHKPT_WORD_ERR(0), val); + + val = VEPU_REG_CHKPT_WORD_ERR_CHK1(syn->target_error[2]) + | VEPU_REG_CHKPT_WORD_ERR_CHK0(syn->target_error[3]); + H264E_HAL_SET_REG(reg, VEPU_REG_CHKPT_WORD_ERR(1), val); + + val = VEPU_REG_CHKPT_WORD_ERR_CHK1(syn->target_error[4]) + | VEPU_REG_CHKPT_WORD_ERR_CHK0(syn->target_error[5]); + H264E_HAL_SET_REG(reg, VEPU_REG_CHKPT_WORD_ERR(2), val); + + val = VEPU_REG_CHKPT_DELTA_QP_CHK6(syn->delta_qp[6]) + | VEPU_REG_CHKPT_DELTA_QP_CHK5(syn->delta_qp[5]) + | VEPU_REG_CHKPT_DELTA_QP_CHK4(syn->delta_qp[4]) + | VEPU_REG_CHKPT_DELTA_QP_CHK3(syn->delta_qp[3]) + | VEPU_REG_CHKPT_DELTA_QP_CHK2(syn->delta_qp[2]) + | VEPU_REG_CHKPT_DELTA_QP_CHK1(syn->delta_qp[1]) + | VEPU_REG_CHKPT_DELTA_QP_CHK0(syn->delta_qp[0]); + H264E_HAL_SET_REG(reg, VEPU_REG_CHKPT_DELTA_QP, val); + + val = VEPU_REG_MAD_THRESHOLD(syn->mad_threshold) + | VEPU_REG_IN_IMG_CTRL_FMT(src_fmt.fmt) + | VEPU_REG_IN_IMG_ROTATE_MODE(0) + | VEPU_REG_SIZE_TABLE_PRESENT; //FIXED + H264E_HAL_SET_REG(reg, VEPU_REG_ENC_CTRL1, val); + + val = VEPU_REG_INTRA16X16_MODE(h264_intra16_favor[syn->qp]) + | VEPU_REG_INTER_MODE(h264_inter_favor[syn->qp]); + H264E_HAL_SET_REG(reg, VEPU_REG_INTRA_INTER_MODE, val); + + val = VEPU_REG_PPS_INIT_QP(syn->pic_init_qp) + | VEPU_REG_SLICE_FILTER_ALPHA(syn->slice_alpha_offset) + | VEPU_REG_SLICE_FILTER_BETA(syn->slice_beta_offset) + | VEPU_REG_CHROMA_QP_OFFSET(syn->chroma_qp_index_offset) + | VEPU_REG_IDR_PIC_ID(syn->idr_pic_id); + + if (syn->filter_disable) + val |= VEPU_REG_FILTER_DISABLE; + + if (constrained_intra_prediction) + val |= VEPU_REG_CONSTRAINED_INTRA_PREDICTION; + H264E_HAL_SET_REG(reg, VEPU_REG_ENC_CTRL2, val); + + H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_NEXT_PIC, 0); + H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_MV_OUT, 0); + H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_CABAC_TBL, mpp_buffer_get_fd(bufs->hw_cabac_table_buf)); + + val = VEPU_REG_ROI1_TOP_MB(mbs_in_col) + | VEPU_REG_ROI1_BOTTOM_MB(mbs_in_col) + | VEPU_REG_ROI1_LEFT_MB(mbs_in_row) + | VEPU_REG_ROI1_RIGHT_MB(mbs_in_row); + H264E_HAL_SET_REG(reg, VEPU_REG_ROI1, val); //FIXED + + val = VEPU_REG_ROI2_TOP_MB(mbs_in_col) + | VEPU_REG_ROI2_BOTTOM_MB(mbs_in_col) + | VEPU_REG_ROI2_LEFT_MB(mbs_in_row) + | VEPU_REG_ROI2_RIGHT_MB(mbs_in_row); + H264E_HAL_SET_REG(reg, VEPU_REG_ROI2, val); //FIXED + H264E_HAL_SET_REG(reg, VEPU_REG_STABLILIZATION_OUTPUT, 0); + + val = VEPU_REG_RGB2YUV_CONVERSION_COEFB(syn->color_conversion_coeff_b) + | VEPU_REG_RGB2YUV_CONVERSION_COEFA(syn->color_conversion_coeff_a); + H264E_HAL_SET_REG(reg, VEPU_REG_RGB2YUV_CONVERSION_COEF1, val); //FIXED + + val = VEPU_REG_RGB2YUV_CONVERSION_COEFE(syn->color_conversion_coeff_e) + | VEPU_REG_RGB2YUV_CONVERSION_COEFC(syn->color_conversion_coeff_c); + H264E_HAL_SET_REG(reg, VEPU_REG_RGB2YUV_CONVERSION_COEF2, val); //FIXED + + val = VEPU_REG_RGB2YUV_CONVERSION_COEFF(syn->color_conversion_coeff_f); + H264E_HAL_SET_REG(reg, VEPU_REG_RGB2YUV_CONVERSION_COEF3, val); //FIXED + + val = VEPU_REG_RGB_MASK_B_MSB(src_fmt.b_mask_msb) + | VEPU_REG_RGB_MASK_G_MSB(src_fmt.g_mask_msb) + | VEPU_REG_RGB_MASK_R_MSB(src_fmt.r_mask_msb); + H264E_HAL_SET_REG(reg, VEPU_REG_RGB_MASK_MSB, val); //FIXED + + diff_mv_penalty[0] = h264_diff_mv_penalty4p[syn->qp]; + diff_mv_penalty[1] = h264_diff_mv_penalty[syn->qp]; + diff_mv_penalty[2] = h264_diff_mv_penalty[syn->qp]; + + val = VEPU_REG_1MV_PENALTY(diff_mv_penalty[1]) + | VEPU_REG_QMV_PENALTY(diff_mv_penalty[2]) + | VEPU_REG_4MV_PENALTY(diff_mv_penalty[0]); + + val |= VEPU_REG_SPLIT_MV_MODE_EN; + H264E_HAL_SET_REG(reg, VEPU_REG_MV_PENALTY, val); + + val = VEPU_REG_H264_LUMA_INIT_QP(syn->qp) + | VEPU_REG_H264_QP_MAX(syn->qp_max) + | VEPU_REG_H264_QP_MIN(syn->qp_min) + | VEPU_REG_H264_CHKPT_DISTANCE(syn->cp_distance_mbs); + H264E_HAL_SET_REG(reg, VEPU_REG_QP_VAL, val); + + val = VEPU_REG_ZERO_MV_FAVOR_D2(10); + H264E_HAL_SET_REG(reg, VEPU_REG_MVC_RELATE, val); + + val = VEPU_REG_OUTPUT_SWAP32 + | VEPU_REG_OUTPUT_SWAP16 + | VEPU_REG_OUTPUT_SWAP8 + | VEPU_REG_INPUT_SWAP8 + | VEPU_REG_INPUT_SWAP16 + | VEPU_REG_INPUT_SWAP32; + H264E_HAL_SET_REG(reg, VEPU_REG_DATA_ENDIAN, val); + + val = VEPU_REG_PPS_ID(syn->pps_id) + | VEPU_REG_INTRA_PRED_MODE(prev_mode_favor) + | VEPU_REG_FRAME_NUM(syn->frame_num); + H264E_HAL_SET_REG(reg, VEPU_REG_ENC_CTRL3, val); + + val = VEPU_REG_INTERRUPT_TIMEOUT_EN; + H264E_HAL_SET_REG(reg, VEPU_REG_INTERRUPT, val); + + for (i = 0; i < 128; i++) { + dmv_penalty[i] = i; + dmv_qpel_penalty[i] = H264E_HAL_MIN(255, exp_golomb_signed(i)); + } + + for (i = 0; i < 128; i += 4) { + val = VEPU_REG_DMV_PENALTY_TABLE_BIT(dmv_penalty[i], 3); + val |= VEPU_REG_DMV_PENALTY_TABLE_BIT(dmv_penalty[i + 1], 2); + val |= VEPU_REG_DMV_PENALTY_TABLE_BIT(dmv_penalty[i + 2], 1); + val |= VEPU_REG_DMV_PENALTY_TABLE_BIT(dmv_penalty[i + 3], 0); + H264E_HAL_SET_REG(reg, VEPU_REG_DMV_PENALTY_TBL(i / 4), val); + + val = VEPU_REG_DMV_Q_PIXEL_PENALTY_TABLE_BIT( + dmv_qpel_penalty[i], 3); + val |= VEPU_REG_DMV_Q_PIXEL_PENALTY_TABLE_BIT( + dmv_qpel_penalty[i + 1], 2); + val |= VEPU_REG_DMV_Q_PIXEL_PENALTY_TABLE_BIT( + dmv_qpel_penalty[i + 2], 1); + val |= VEPU_REG_DMV_Q_PIXEL_PENALTY_TABLE_BIT( + dmv_qpel_penalty[i + 3], 0); + H264E_HAL_SET_REG(reg, VEPU_REG_DMV_Q_PIXEL_PENALTY_TBL(i / 4), val); + } + + /* set buffers addr */ + H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_IN_LUMA, syn->input_luma_addr); + H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_IN_CB, syn->input_cb_addr); + H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_IN_CR, syn->input_cr_addr); + + H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_OUTPUT_STREAM, syn->output_strm_addr); + H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_OUTPUT_CTRL, mpp_buffer_get_fd(bufs->hw_nal_size_table_buf)); + + { + RK_S32 recon_chroma_addr = 0, ref_chroma_addr = 0; + RK_U32 frame_luma_size = mbs_in_col * mbs_in_row * 256; + RK_S32 recon_luma_addr = mpp_buffer_get_fd(bufs->hw_rec_buf[buf2_idx]); + RK_S32 ref_luma_addr = mpp_buffer_get_fd(bufs->hw_rec_buf[1 - buf2_idx]); + if (VPUClientGetIOMMUStatus() > 0) { + recon_chroma_addr = recon_luma_addr | (frame_luma_size << 10); + ref_chroma_addr = ref_luma_addr | (frame_luma_size << 10); + } else { + recon_chroma_addr = recon_luma_addr + frame_luma_size; + ref_chroma_addr = ref_luma_addr + frame_luma_size ; + } + H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_REC_LUMA, recon_luma_addr); + H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_REC_CHROMA, recon_chroma_addr); + H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_REF_LUMA, ref_luma_addr); + H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_REF_CHROMA , ref_chroma_addr); + } + + + /* set important encode mode info */ + val = VEPU_REG_MB_HEIGHT(mbs_in_col) + | VEPU_REG_MB_WIDTH(mbs_in_row) + | VEPU_REG_PIC_TYPE(syn->frame_coding_type) + | VEPU_REG_ENCODE_FORMAT(3) + | VEPU_REG_ENCODE_ENABLE; + H264E_HAL_SET_REG(reg, VEPU_REG_ENCODE_START, val); + + +#ifdef H264E_DUMP_DATA_TO_FILE + hal_h264e_vpu_dump_mpp_reg_in(ctx); +#endif + + ctx->frame_cnt++; + h264e_hal_debug_leave(); + return MPP_OK; +} + +MPP_RET hal_h264e_vpu_start(void *hal, HalTaskInfo *task) +{ + h264e_hal_context *ctx = (h264e_hal_context *)hal; + (void)task; + h264e_hal_debug_enter(); +#ifdef RKPLATFORM + if (ctx->vpu_socket > 0) { + RK_U32 *p_regs = (RK_U32 *)ctx->regs; + h264e_hal_log_detail("vpu client is sending %d regs", VEPU_H264E_NUM_REGS); + if (MPP_OK != VPUClientSendReg(ctx->vpu_socket, p_regs, VEPU_H264E_NUM_REGS)) { + mpp_err("VPUClientSendReg Failed!!!"); + return MPP_ERR_VPUHW; + } else { + h264e_hal_log_detail("VPUClientSendReg successfully!"); + } + } else { + mpp_err("invalid vpu socket: %d", ctx->vpu_socket); + return MPP_NOK; + } +#endif + (void)ctx; + h264e_hal_debug_leave(); + + return MPP_OK; +} + +static MPP_RET hal_h264e_vpu_set_feedback(h264e_feedback *fb, h264e_vpu_reg_set *reg) +{ + RK_S32 i = 0; + RK_U32 cpt_prev = 0, overflow = 0; + RK_U32 cpt_idx = VEPU_REG_CHECKPOINT(0) / 4; + RK_U32 *reg_val = (RK_U32 *)reg; + fb->hw_status = reg_val[VEPU_REG_INTERRUPT / 4]; + fb->qp_sum = VEPU_REG_QP_SUM(reg_val[VEPU_REG_QP_SUM_DIV2 / 4]); + fb->mad_count = VEPU_REG_MB_CNT_SET(reg_val[VEPU_REG_MB_CTRL / 4]); + fb->rlc_count = VEPU_REG_RLC_SUM_OUT(reg_val[VEPU_REG_RLC_SUM / 4]); + fb->out_strm_size = reg_val[VEPU_REG_STR_BUF_LIMIT / 4] / 8; + for (i = 0; i < 10; i++) { + RK_U32 cpt = VEPU_REG_CHECKPOINT_RESULT(reg_val[cpt_idx]); + if (cpt < cpt_prev) + overflow += (1 << 21); + fb->cp[i] = cpt + overflow; + cpt_idx += (i & 1); + } + + return MPP_OK; +} + +MPP_RET hal_h264e_vpu_wait(void *hal, HalTaskInfo *task) +{ + h264e_hal_context *ctx = (h264e_hal_context *)hal; + h264e_vpu_reg_set *reg_out = (h264e_vpu_reg_set *)ctx->regs; + IOInterruptCB int_cb = ctx->int_cb; + h264e_feedback *fb = &ctx->feedback; + (void)task; + h264e_hal_debug_enter(); + +#ifdef RKPLATFORM + if (ctx->vpu_socket > 0) { + VPU_CMD_TYPE cmd = 0; + RK_S32 length = 0; + RK_S32 hw_ret = VPUClientWaitResult(ctx->vpu_socket, (RK_U32 *)reg_out, + VEPU_H264E_NUM_REGS, &cmd, &length); + + h264e_hal_log_detail("VPUClientWaitResult: ret %d, cmd %d, len %d\n", hw_ret, cmd, length); + + + if ((VPU_SUCCESS != hw_ret) || (cmd != VPU_SEND_CONFIG_ACK_OK)) + mpp_err("hardware wait error"); + + if (hw_ret != MPP_OK) { + mpp_err("hardware returns error:%d", hw_ret); + return MPP_ERR_VPUHW; + } + } else { + mpp_err("invalid vpu socket: %d", ctx->vpu_socket); + return MPP_NOK; + } +#endif + + if (int_cb.callBack) { + hal_h264e_vpu_set_feedback(fb, reg_out); +#ifdef H264E_DUMP_DATA_TO_FILE + hal_h264e_vpu_dump_mpp_feedback(ctx); +#endif + int_cb.callBack(int_cb.opaque, fb); + } + +#ifdef H264E_DUMP_DATA_TO_FILE + hal_h264e_vpu_dump_mpp_reg_out(ctx); + hal_h264e_vpu_dump_mpp_strm_out(ctx, ctx->enc_task.output); +#endif + //hal_h264e_vpu_dump_mpp_strm_out(ctx, NULL); + + h264e_hal_debug_leave(); + + return MPP_OK; +} + +MPP_RET hal_h264e_vpu_reset(void *hal) +{ + (void)hal; + h264e_hal_debug_enter(); + + h264e_hal_debug_leave(); + return MPP_OK; +} + +MPP_RET hal_h264e_vpu_flush(void *hal) +{ + (void)hal; + h264e_hal_debug_enter(); + + h264e_hal_debug_leave(); + return MPP_OK; +} + +MPP_RET hal_h264e_vpu_control(void *hal, RK_S32 cmd_type, void *param) +{ + h264e_hal_context *ctx = (h264e_hal_context *)hal; + h264e_hal_debug_enter(); + + h264e_hal_log_detail("hal_h264e_vpu_control cmd 0x%x, info %p", cmd_type, param); + switch (cmd_type) { + case MPP_ENC_SET_EXTRA_INFO: { + hal_h264e_vpu_set_extra_info(ctx->extra_info, param); + break; + } + case MPP_ENC_GET_EXTRA_INFO: { + MppPacket pkt = ctx->packeted_param; + MppPacket *pkt_out = (MppPacket *)param; + + h264e_hal_vpu_extra_info *src = (h264e_hal_vpu_extra_info *)ctx->extra_info; + h264e_hal_vpu_stream *sps_stream = &src->sps_stream; + h264e_hal_vpu_stream *pps_stream = &src->pps_stream; + + size_t offset = 0; + + mpp_packet_write(pkt, offset, sps_stream->buffer, sps_stream->byte_cnt); + offset += sps_stream->byte_cnt; + + mpp_packet_write(pkt, offset, pps_stream->buffer, pps_stream->byte_cnt); + offset += pps_stream->byte_cnt; + + mpp_packet_set_length(pkt, offset); + + *pkt_out = pkt; +#ifdef H264E_DUMP_DATA_TO_FILE + hal_h264e_vpu_dump_mpp_strm_out_header(ctx, pkt); +#endif + break; + } + default : { + mpp_err("unrecognizable cmd type %d", cmd_type); + } break; + } + + h264e_hal_debug_leave(); + return MPP_OK; +} - h264e_hal_context *ctx = (h264e_hal_context *)hal; - RK_U32 *reg = (RK_U32 *)ctx->regs; - h264e_syntax *syn = (h264e_syntax *)task->enc.syntax.data; - - RK_U32 mbs_in_row = (syn->pic_luma_width + 15) / 16; - RK_U32 mbs_in_col = (syn->pic_luma_height + 15) / 16; - RK_U32 prev_mode_favor = h264_prev_mode_favor[syn->qp]; - h264e_hal_vpu_buffers *bufs = (h264e_hal_vpu_buffers *)ctx->buffers; - RK_U32 buf2_idx = ctx->frame_cnt % 2; - h264e_hal_vpu_extra_info *extra_info = (h264e_hal_vpu_extra_info *)ctx->extra_info; - h264e_hal_pps *pps = &extra_info->pps; - h264e_hal_debug_enter(); - - if (ctx->frame_cnt == 0) { - if (MPP_OK != hal_h264e_vpu_allocate_buffers(ctx, syn)) { - h264e_hal_log_err("hal_h264e_vpu_allocate_buffers failed, free now"); - hal_h264e_vpu_free_buffers(ctx); - } - } - -#ifdef H264E_DUMP_DATA_TO_FILE - hal_h264e_vpu_dump_mpp_syntax_in(syn, ctx); -#endif - if (MPP_OK != hal_h264e_vpu_validate_syntax(syn, &src_fmt)) { - h264e_hal_log_err("hal_h264e_vpu_validate_syntax failed"); - } - ctx->enc_task = task->enc; - memset(reg, 0, sizeof(h264e_vpu_reg_set)); - - h264e_hal_log_detail("frame %d generate regs now", ctx->frame_cnt); - - /* If frame encode type for current frame is intra, write sps pps to - the output buffer */ - H264E_HAL_SET_REG(reg, VEPU_REG_STR_BUF_LIMIT, syn->output_strm_limit_size); - - /* - * The hardware needs only the value for luma plane, because - * values of other planes are calculated internally based on - * format setting. - */ - val = VEPU_REG_INTRA_AREA_TOP(mbs_in_col) - | VEPU_REG_INTRA_AREA_BOTTOM(mbs_in_col) - | VEPU_REG_INTRA_AREA_LEFT(mbs_in_row) - | VEPU_REG_INTRA_AREA_RIGHT(mbs_in_row); - H264E_HAL_SET_REG(reg, VEPU_REG_INTRA_AREA_CTRL, val); //FIXED - H264E_HAL_SET_REG(reg, VEPU_REG_STR_HDR_REM_MSB, 0); - H264E_HAL_SET_REG(reg, VEPU_REG_STR_HDR_REM_LSB, 0); - - - val = VEPU_REG_AXI_CTRL_READ_ID(0); - val |= VEPU_REG_AXI_CTRL_WRITE_ID(0); - val |= VEPU_REG_AXI_CTRL_BURST_LEN(16); - val |= VEPU_REG_AXI_CTRL_INCREMENT_MODE(0); - val |= VEPU_REG_AXI_CTRL_BIRST_DISCARD(0); - H264E_HAL_SET_REG(reg, VEPU_REG_AXI_CTRL, val); - - H264E_HAL_SET_REG(reg, VEPU_QP_ADJUST_MAD_DELTA_ROI, syn->mad_qp_delta); - - val = 0; - if (mbs_in_row * mbs_in_col > 3600) - val = VEPU_REG_DISABLE_QUARTER_PIXEL_MV; - val |= VEPU_REG_CABAC_INIT_IDC(syn->cabac_init_idc); - if (syn->enable_cabac) - val |= VEPU_REG_ENTROPY_CODING_MODE; - if (pps->b_transform_8x8_mode) - val |= VEPU_REG_H264_TRANS8X8_MODE; - if (syn->h264_inter4x4_disabled) - val |= VEPU_REG_H264_INTER4X4_MODE; - /*reg |= VEPU_REG_H264_STREAM_MODE;*/ - val |= VEPU_REG_H264_SLICE_SIZE(syn->slice_size_mb_rows); - H264E_HAL_SET_REG(reg, VEPU_REG_ENC_CTRL0, val); - - scaler = H264E_HAL_MAX(1, 200 / (mbs_in_row + mbs_in_col)); - skip_penalty = H264E_HAL_MIN(255, h264_skip_sad_penalty[syn->qp] * scaler); - if (syn->pic_luma_width & 0x0f) - overfill_r = (16 - (syn->pic_luma_width & 0x0f) ) / 4; - if (syn->pic_luma_height & 0x0f) - overfill_b = 16 - (syn->pic_luma_height & 0x0f); - val = VEPU_REG_STREAM_START_OFFSET(first_free_bit) | - VEPU_REG_SKIP_MACROBLOCK_PENALTY(skip_penalty) | - VEPU_REG_IN_IMG_CTRL_OVRFLR_D4(overfill_r) | - VEPU_REG_IN_IMG_CTRL_OVRFLB(overfill_b); - H264E_HAL_SET_REG(reg, VEPU_REG_ENC_OVER_FILL_STRM_OFFSET, val); - - - val = VEPU_REG_IN_IMG_CHROMA_OFFSET(0) - | VEPU_REG_IN_IMG_LUMA_OFFSET(0) - | VEPU_REG_IN_IMG_CTRL_ROW_LEN(syn->pic_luma_width); - H264E_HAL_SET_REG(reg, VEPU_REG_INPUT_LUMA_INFO, val); - - val = VEPU_REG_CHECKPOINT_CHECK1(syn->cp_target[0]) - | VEPU_REG_CHECKPOINT_CHECK0(syn->cp_target[1]); - H264E_HAL_SET_REG(reg, VEPU_REG_CHECKPOINT(0), val); - - val = VEPU_REG_CHECKPOINT_CHECK1(syn->cp_target[2]) - | VEPU_REG_CHECKPOINT_CHECK0(syn->cp_target[3]); - H264E_HAL_SET_REG(reg, VEPU_REG_CHECKPOINT(1), val); - - val = VEPU_REG_CHECKPOINT_CHECK1(syn->cp_target[4]) - | VEPU_REG_CHECKPOINT_CHECK0(syn->cp_target[5]); - H264E_HAL_SET_REG(reg, VEPU_REG_CHECKPOINT(2), val); - - val = VEPU_REG_CHECKPOINT_CHECK1(syn->cp_target[6]) - | VEPU_REG_CHECKPOINT_CHECK0(syn->cp_target[7]); - H264E_HAL_SET_REG(reg, VEPU_REG_CHECKPOINT(3), val); - - val = VEPU_REG_CHECKPOINT_CHECK1(syn->cp_target[8]) - | VEPU_REG_CHECKPOINT_CHECK0(syn->cp_target[9]); - H264E_HAL_SET_REG(reg, VEPU_REG_CHECKPOINT(4), val); - - val = VEPU_REG_CHKPT_WORD_ERR_CHK1(syn->target_error[0]) - | VEPU_REG_CHKPT_WORD_ERR_CHK0(syn->target_error[1]); - H264E_HAL_SET_REG(reg, VEPU_REG_CHKPT_WORD_ERR(0), val); - - val = VEPU_REG_CHKPT_WORD_ERR_CHK1(syn->target_error[2]) - | VEPU_REG_CHKPT_WORD_ERR_CHK0(syn->target_error[3]); - H264E_HAL_SET_REG(reg, VEPU_REG_CHKPT_WORD_ERR(1), val); - - val = VEPU_REG_CHKPT_WORD_ERR_CHK1(syn->target_error[4]) - | VEPU_REG_CHKPT_WORD_ERR_CHK0(syn->target_error[5]); - H264E_HAL_SET_REG(reg, VEPU_REG_CHKPT_WORD_ERR(2), val); - - val = VEPU_REG_CHKPT_DELTA_QP_CHK6(syn->delta_qp[6]) - | VEPU_REG_CHKPT_DELTA_QP_CHK5(syn->delta_qp[5]) - | VEPU_REG_CHKPT_DELTA_QP_CHK4(syn->delta_qp[4]) - | VEPU_REG_CHKPT_DELTA_QP_CHK3(syn->delta_qp[3]) - | VEPU_REG_CHKPT_DELTA_QP_CHK2(syn->delta_qp[2]) - | VEPU_REG_CHKPT_DELTA_QP_CHK1(syn->delta_qp[1]) - | VEPU_REG_CHKPT_DELTA_QP_CHK0(syn->delta_qp[0]); - H264E_HAL_SET_REG(reg, VEPU_REG_CHKPT_DELTA_QP, val); - - val = VEPU_REG_MAD_THRESHOLD(syn->mad_threshold) - | VEPU_REG_IN_IMG_CTRL_FMT(src_fmt.fmt) - | VEPU_REG_IN_IMG_ROTATE_MODE(0) - | VEPU_REG_SIZE_TABLE_PRESENT; //FIXED - H264E_HAL_SET_REG(reg, VEPU_REG_ENC_CTRL1, val); - - val = VEPU_REG_INTRA16X16_MODE(h264_intra16_favor[syn->qp]) - | VEPU_REG_INTER_MODE(h264_inter_favor[syn->qp]); - H264E_HAL_SET_REG(reg, VEPU_REG_INTRA_INTER_MODE, val); - - val = VEPU_REG_PPS_INIT_QP(syn->pic_init_qp) - | VEPU_REG_SLICE_FILTER_ALPHA(syn->slice_alpha_offset) - | VEPU_REG_SLICE_FILTER_BETA(syn->slice_beta_offset) - | VEPU_REG_CHROMA_QP_OFFSET(syn->chroma_qp_index_offset) - | VEPU_REG_IDR_PIC_ID(syn->idr_pic_id); - - if (syn->filter_disable) - val |= VEPU_REG_FILTER_DISABLE; - - if (constrained_intra_prediction) - val |= VEPU_REG_CONSTRAINED_INTRA_PREDICTION; - H264E_HAL_SET_REG(reg, VEPU_REG_ENC_CTRL2, val); - - H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_NEXT_PIC, 0); - H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_MV_OUT, 0); - H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_CABAC_TBL, mpp_buffer_get_fd(bufs->hw_cabac_table_buf)); - - val = VEPU_REG_ROI1_TOP_MB(mbs_in_col) - | VEPU_REG_ROI1_BOTTOM_MB(mbs_in_col) - | VEPU_REG_ROI1_LEFT_MB(mbs_in_row) - | VEPU_REG_ROI1_RIGHT_MB(mbs_in_row); - H264E_HAL_SET_REG(reg, VEPU_REG_ROI1, val); //FIXED - - val = VEPU_REG_ROI2_TOP_MB(mbs_in_col) - | VEPU_REG_ROI2_BOTTOM_MB(mbs_in_col) - | VEPU_REG_ROI2_LEFT_MB(mbs_in_row) - | VEPU_REG_ROI2_RIGHT_MB(mbs_in_row); - H264E_HAL_SET_REG(reg, VEPU_REG_ROI2, val); //FIXED - H264E_HAL_SET_REG(reg, VEPU_REG_STABLILIZATION_OUTPUT, 0); - - val = VEPU_REG_RGB2YUV_CONVERSION_COEFB(syn->color_conversion_coeff_b) - | VEPU_REG_RGB2YUV_CONVERSION_COEFA(syn->color_conversion_coeff_a); - H264E_HAL_SET_REG(reg, VEPU_REG_RGB2YUV_CONVERSION_COEF1, val); //FIXED - - val = VEPU_REG_RGB2YUV_CONVERSION_COEFE(syn->color_conversion_coeff_e) - | VEPU_REG_RGB2YUV_CONVERSION_COEFC(syn->color_conversion_coeff_c); - H264E_HAL_SET_REG(reg, VEPU_REG_RGB2YUV_CONVERSION_COEF2, val); //FIXED - - val = VEPU_REG_RGB2YUV_CONVERSION_COEFF(syn->color_conversion_coeff_f); - H264E_HAL_SET_REG(reg, VEPU_REG_RGB2YUV_CONVERSION_COEF3, val); //FIXED - - val = VEPU_REG_RGB_MASK_B_MSB(src_fmt.b_mask_msb) - | VEPU_REG_RGB_MASK_G_MSB(src_fmt.g_mask_msb) - | VEPU_REG_RGB_MASK_R_MSB(src_fmt.r_mask_msb); - H264E_HAL_SET_REG(reg, VEPU_REG_RGB_MASK_MSB, val); //FIXED - - diff_mv_penalty[0] = h264_diff_mv_penalty4p[syn->qp]; - diff_mv_penalty[1] = h264_diff_mv_penalty[syn->qp]; - diff_mv_penalty[2] = h264_diff_mv_penalty[syn->qp]; - - val = VEPU_REG_1MV_PENALTY(diff_mv_penalty[1]) - | VEPU_REG_QMV_PENALTY(diff_mv_penalty[2]) - | VEPU_REG_4MV_PENALTY(diff_mv_penalty[0]); - - val |= VEPU_REG_SPLIT_MV_MODE_EN; - H264E_HAL_SET_REG(reg, VEPU_REG_MV_PENALTY, val); - - val = VEPU_REG_H264_LUMA_INIT_QP(syn->qp) - | VEPU_REG_H264_QP_MAX(syn->qp_max) - | VEPU_REG_H264_QP_MIN(syn->qp_min) - | VEPU_REG_H264_CHKPT_DISTANCE(syn->cp_distance_mbs); - H264E_HAL_SET_REG(reg, VEPU_REG_QP_VAL, val); - - val = VEPU_REG_ZERO_MV_FAVOR_D2(10); - H264E_HAL_SET_REG(reg, VEPU_REG_MVC_RELATE, val); - - val = VEPU_REG_OUTPUT_SWAP32 - | VEPU_REG_OUTPUT_SWAP16 - | VEPU_REG_OUTPUT_SWAP8 - | VEPU_REG_INPUT_SWAP8 - | VEPU_REG_INPUT_SWAP16 - | VEPU_REG_INPUT_SWAP32; - H264E_HAL_SET_REG(reg, VEPU_REG_DATA_ENDIAN, val); - - val = VEPU_REG_PPS_ID(syn->pps_id) - | VEPU_REG_INTRA_PRED_MODE(prev_mode_favor) - | VEPU_REG_FRAME_NUM(syn->frame_num); - H264E_HAL_SET_REG(reg, VEPU_REG_ENC_CTRL3, val); - - val = VEPU_REG_INTERRUPT_TIMEOUT_EN; - H264E_HAL_SET_REG(reg, VEPU_REG_INTERRUPT, val); - - for (i = 0; i < 128; i++) { - dmv_penalty[i] = i; - dmv_qpel_penalty[i] = H264E_HAL_MIN(255, exp_golomb_signed(i)); - } - - for (i = 0; i < 128; i += 4) { - val = VEPU_REG_DMV_PENALTY_TABLE_BIT(dmv_penalty[i], 3); - val |= VEPU_REG_DMV_PENALTY_TABLE_BIT(dmv_penalty[i + 1], 2); - val |= VEPU_REG_DMV_PENALTY_TABLE_BIT(dmv_penalty[i + 2], 1); - val |= VEPU_REG_DMV_PENALTY_TABLE_BIT(dmv_penalty[i + 3], 0); - H264E_HAL_SET_REG(reg, VEPU_REG_DMV_PENALTY_TBL(i / 4), val); - - val = VEPU_REG_DMV_Q_PIXEL_PENALTY_TABLE_BIT( - dmv_qpel_penalty[i], 3); - val |= VEPU_REG_DMV_Q_PIXEL_PENALTY_TABLE_BIT( - dmv_qpel_penalty[i + 1], 2); - val |= VEPU_REG_DMV_Q_PIXEL_PENALTY_TABLE_BIT( - dmv_qpel_penalty[i + 2], 1); - val |= VEPU_REG_DMV_Q_PIXEL_PENALTY_TABLE_BIT( - dmv_qpel_penalty[i + 3], 0); - H264E_HAL_SET_REG(reg, VEPU_REG_DMV_Q_PIXEL_PENALTY_TBL(i / 4), val); - } - - /* set buffers addr */ - H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_IN_LUMA, syn->input_luma_addr); - H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_IN_CB, syn->input_cb_addr); - H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_IN_CR, syn->input_cr_addr); - - H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_OUTPUT_STREAM, syn->output_strm_addr); - H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_OUTPUT_CTRL, mpp_buffer_get_fd(bufs->hw_nal_size_table_buf)); - - { - RK_S32 recon_chroma_addr = 0, ref_chroma_addr = 0; - RK_U32 frame_luma_size = mbs_in_col * mbs_in_row * 256; - RK_S32 recon_luma_addr = mpp_buffer_get_fd(bufs->hw_rec_buf[buf2_idx]); - RK_S32 ref_luma_addr = mpp_buffer_get_fd(bufs->hw_rec_buf[1 - buf2_idx]); - if (VPUClientGetIOMMUStatus() > 0) { - recon_chroma_addr = recon_luma_addr | (frame_luma_size << 10); - ref_chroma_addr = ref_luma_addr | (frame_luma_size << 10); - } else { - recon_chroma_addr = recon_luma_addr + frame_luma_size; - ref_chroma_addr = ref_luma_addr + frame_luma_size ; - } - H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_REC_LUMA, recon_luma_addr); - H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_REC_CHROMA, recon_chroma_addr); - H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_REF_LUMA, ref_luma_addr); - H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_REF_CHROMA , ref_chroma_addr); - } - - - /* set important encode mode info */ - val = VEPU_REG_MB_HEIGHT(mbs_in_col) - | VEPU_REG_MB_WIDTH(mbs_in_row) - | VEPU_REG_PIC_TYPE(syn->frame_coding_type) - | VEPU_REG_ENCODE_FORMAT(3) - | VEPU_REG_ENCODE_ENABLE; - H264E_HAL_SET_REG(reg, VEPU_REG_ENCODE_START, val); - - -#ifdef H264E_DUMP_DATA_TO_FILE - hal_h264e_vpu_dump_mpp_reg_in(ctx); -#endif - - ctx->frame_cnt++; - h264e_hal_debug_leave(); - return MPP_OK; -} - -MPP_RET hal_h264e_vpu_start(void *hal, HalTaskInfo *task) -{ - h264e_hal_context *ctx = (h264e_hal_context *)hal; - (void)task; - h264e_hal_debug_enter(); -#ifdef RKPLATFORM - if (ctx->vpu_socket > 0) { - RK_U32 *p_regs = (RK_U32 *)ctx->regs; - h264e_hal_log_detail("vpu client is sending %d regs", VEPU_H264E_NUM_REGS); - if (MPP_OK != VPUClientSendReg(ctx->vpu_socket, p_regs, VEPU_H264E_NUM_REGS)) { - mpp_err("VPUClientSendReg Failed!!!"); - return MPP_ERR_VPUHW; - } else { - h264e_hal_log_detail("VPUClientSendReg successfully!"); - } - } else { - mpp_err("invalid vpu socket: %d", ctx->vpu_socket); - return MPP_NOK; - } -#endif - (void)ctx; - h264e_hal_debug_leave(); - - return MPP_OK; -} - -static MPP_RET hal_h264e_vpu_set_feedback(h264e_feedback *fb, h264e_vpu_reg_set *reg) -{ - RK_S32 i = 0; - RK_U32 cpt_prev = 0, overflow = 0; - RK_U32 cpt_idx = VEPU_REG_CHECKPOINT(0) / 4; - RK_U32 *reg_val = (RK_U32 *)reg; - fb->hw_status = reg_val[VEPU_REG_INTERRUPT / 4]; - fb->qp_sum = VEPU_REG_QP_SUM(reg_val[VEPU_REG_QP_SUM_DIV2 / 4]); - fb->mad_count = VEPU_REG_MB_CNT_SET(reg_val[VEPU_REG_MB_CTRL / 4]); - fb->rlc_count = VEPU_REG_RLC_SUM_OUT(reg_val[VEPU_REG_RLC_SUM / 4]); - fb->out_strm_size = reg_val[VEPU_REG_STR_BUF_LIMIT / 4] / 8; - for (i = 0; i < 10; i++) { - RK_U32 cpt = VEPU_REG_CHECKPOINT_RESULT(reg_val[cpt_idx]); - if (cpt < cpt_prev) - overflow += (1 << 21); - fb->cp[i] = cpt + overflow; - cpt_idx += (i & 1); - } - - return MPP_OK; -} - -MPP_RET hal_h264e_vpu_wait(void *hal, HalTaskInfo *task) -{ - h264e_hal_context *ctx = (h264e_hal_context *)hal; - h264e_vpu_reg_set *reg_out = (h264e_vpu_reg_set *)ctx->regs; - IOInterruptCB int_cb = ctx->int_cb; - h264e_feedback *fb = &ctx->feedback; - (void)task; - h264e_hal_debug_enter(); - -#ifdef RKPLATFORM - if (ctx->vpu_socket > 0) { - VPU_CMD_TYPE cmd = 0; - RK_S32 length = 0; - RK_S32 hw_ret = VPUClientWaitResult(ctx->vpu_socket, (RK_U32 *)reg_out, - VEPU_H264E_NUM_REGS, &cmd, &length); - - h264e_hal_log_detail("VPUClientWaitResult: ret %d, cmd %d, len %d\n", hw_ret, cmd, length); - - - if ((VPU_SUCCESS != hw_ret) || (cmd != VPU_SEND_CONFIG_ACK_OK)) - mpp_err("hardware wait error"); - - if (hw_ret != MPP_OK) { - mpp_err("hardware returns error:%d", hw_ret); - return MPP_ERR_VPUHW; - } - } else { - mpp_err("invalid vpu socket: %d", ctx->vpu_socket); - return MPP_NOK; - } -#endif - - if (int_cb.callBack) { - hal_h264e_vpu_set_feedback(fb, reg_out); -#ifdef H264E_DUMP_DATA_TO_FILE - hal_h264e_vpu_dump_mpp_feedback(ctx); -#endif - int_cb.callBack(int_cb.opaque, fb); - } - -#ifdef H264E_DUMP_DATA_TO_FILE - hal_h264e_vpu_dump_mpp_reg_out(ctx); - hal_h264e_vpu_dump_mpp_strm_out(ctx, ctx->enc_task.output); -#endif - //hal_h264e_vpu_dump_mpp_strm_out(ctx, NULL); - - h264e_hal_debug_leave(); - - return MPP_OK; -} - -MPP_RET hal_h264e_vpu_reset(void *hal) -{ - (void)hal; - h264e_hal_debug_enter(); - - h264e_hal_debug_leave(); - return MPP_OK; -} - -MPP_RET hal_h264e_vpu_flush(void *hal) -{ - (void)hal; - h264e_hal_debug_enter(); - - h264e_hal_debug_leave(); - return MPP_OK; -} - -MPP_RET hal_h264e_vpu_control(void *hal, RK_S32 cmd_type, void *param) -{ - h264e_hal_context *ctx = (h264e_hal_context *)hal; - h264e_hal_debug_enter(); - - h264e_hal_log_detail("hal_h264e_vpu_control cmd 0x%x, info %p", cmd_type, param); - switch (cmd_type) { - case MPP_ENC_SET_EXTRA_INFO: { - hal_h264e_vpu_set_extra_info(ctx->extra_info, param); - break; - } - case MPP_ENC_GET_EXTRA_INFO: { - MppPacket pkt = ctx->packeted_param; - MppPacket *pkt_out = (MppPacket *)param; - - h264e_hal_vpu_extra_info *src = (h264e_hal_vpu_extra_info *)ctx->extra_info; - h264e_hal_vpu_stream *sps_stream = &src->sps_stream; - h264e_hal_vpu_stream *pps_stream = &src->pps_stream; - - size_t offset = 0; - - mpp_packet_write(pkt, offset, sps_stream->buffer, sps_stream->byte_cnt); - offset += sps_stream->byte_cnt; - - mpp_packet_write(pkt, offset, pps_stream->buffer, pps_stream->byte_cnt); - offset += pps_stream->byte_cnt; - - mpp_packet_set_length(pkt, offset); - - *pkt_out = pkt; -#ifdef H264E_DUMP_DATA_TO_FILE - hal_h264e_vpu_dump_mpp_strm_out_header(ctx, pkt); -#endif - break; - } - default : { - mpp_err("unrecognizable cmd type %d", cmd_type); - } break; - } - - h264e_hal_debug_leave(); - return MPP_OK; -} - diff --git a/mpp/hal/rkenc/h264e/hal_h264e_vpu.h b/mpp/hal/rkenc/h264e/hal_h264e_vpu.h index 7538bbe9..eba514d4 100644 --- a/mpp/hal/rkenc/h264e/hal_h264e_vpu.h +++ b/mpp/hal/rkenc/h264e/hal_h264e_vpu.h @@ -1,696 +1,696 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __HAL_H264E_ON2_H__ -#define __HAL_H264E_ON2_H__ - -#include "mpp_hal.h" -#include "hal_task.h" - -#define BIT(n) (1<<(n)) - -/* RK3228 Encoder registers. */ -#define VEPU_REG_VP8_QUT_1ST(i) (0x000 + ((i) * 0x24)) -#define VEPU_REG_VP8_QUT_DC_Y2(x) (((x) & 0x3fff) << 16) -#define VEPU_REG_VP8_QUT_DC_Y1(x) (((x) & 0x3fff) << 0) -#define VEPU_REG_VP8_QUT_2ND(i) (0x004 + ((i) * 0x24)) -#define VEPU_REG_VP8_QUT_AC_Y1(x) (((x) & 0x3fff) << 16) -#define VEPU_REG_VP8_QUT_DC_CHR(x) (((x) & 0x3fff) << 0) -#define VEPU_REG_VP8_QUT_3RD(i) (0x008 + ((i) * 0x24)) -#define VEPU_REG_VP8_QUT_AC_CHR(x) (((x) & 0x3fff) << 16) -#define VEPU_REG_VP8_QUT_AC_Y2(x) (((x) & 0x3fff) << 0) -#define VEPU_REG_VP8_QUT_4TH(i) (0x00c + ((i) * 0x24)) -#define VEPU_REG_VP8_QUT_ZB_DC_CHR(x) (((x) & 0x1ff) << 18) -#define VEPU_REG_VP8_QUT_ZB_DC_Y2(x) (((x) & 0x1ff) << 9) -#define VEPU_REG_VP8_QUT_ZB_DC_Y1(x) (((x) & 0x1ff) << 0) -#define VEPU_REG_VP8_QUT_5TH(i) (0x010 + ((i) * 0x24)) -#define VEPU_REG_VP8_QUT_ZB_AC_CHR(x) (((x) & 0x1ff) << 18) -#define VEPU_REG_VP8_QUT_ZB_AC_Y2(x) (((x) & 0x1ff) << 9) -#define VEPU_REG_VP8_QUT_ZB_AC_Y1(x) (((x) & 0x1ff) << 0) -#define VEPU_REG_VP8_QUT_6TH(i) (0x014 + ((i) * 0x24)) -#define VEPU_REG_VP8_QUT_RND_DC_CHR(x) (((x) & 0xff) << 16) -#define VEPU_REG_VP8_QUT_RND_DC_Y2(x) (((x) & 0xff) << 8) -#define VEPU_REG_VP8_QUT_RND_DC_Y1(x) (((x) & 0xff) << 0) -#define VEPU_REG_VP8_QUT_7TH(i) (0x018 + ((i) * 0x24)) -#define VEPU_REG_VP8_QUT_RND_AC_CHR(x) (((x) & 0xff) << 16) -#define VEPU_REG_VP8_QUT_RND_AC_Y2(x) (((x) & 0xff) << 8) -#define VEPU_REG_VP8_QUT_RND_AC_Y1(x) (((x) & 0xff) << 0) -#define VEPU_REG_VP8_QUT_8TH(i) (0x01c + ((i) * 0x24)) -#define VEPU_REG_VP8_SEG_FILTER_LEVEL(x) (((x) & 0x3f) << 25) -#define VEPU_REG_VP8_DEQUT_DC_CHR(x) (((x) & 0xff) << 17) -#define VEPU_REG_VP8_DEQUT_DC_Y2(x) (((x) & 0x1ff) << 8) -#define VEPU_REG_VP8_DEQUT_DC_Y1(x) (((x) & 0xff) << 0) -#define VEPU_REG_VP8_QUT_9TH(i) (0x020 + ((i) * 0x24)) -#define VEPU_REG_VP8_DEQUT_AC_CHR(x) (((x) & 0x1ff) << 18) -#define VEPU_REG_VP8_DEQUT_AC_Y2(x) (((x) & 0x1ff) << 9) -#define VEPU_REG_VP8_DEQUT_AC_Y1(x) (((x) & 0x1ff) << 0) -#define VEPU_REG_ADDR_VP8_SEG_MAP 0x06c -#define VEPU_REG_VP8_INTRA_4X4_PENALTY(i) (0x070 + ((i) * 0x4)) -#define VEPU_REG_VP8_INTRA_4X4_PENALTY_0(x) (((x) & 0xfff) << 0) -#define VEPU_REG_VP8_INTRA_4x4_PENALTY_1(x) (((x) & 0xfff) << 16) -#define VEPU_REG_VP8_INTRA_16X16_PENALTY(i) (0x084 + ((i) * 0x4)) -#define VEPU_REG_VP8_INTRA_16X16_PENALTY_0(x) (((x) & 0xfff) << 0) -#define VEPU_REG_VP8_INTRA_16X16_PENALTY_1(x) (((x) & 0xfff) << 16) -#define VEPU_REG_VP8_CONTROL 0x0a0 -#define VEPU_REG_VP8_LF_MODE_DELTA_BPRED(x) (((x) & 0x1f) << 24) -#define VEPU_REG_VP8_LF_REF_DELTA_INTRA_MB(x) (((x) & 0x7f) << 16) -#define VEPU_REG_VP8_INTER_TYPE_BIT_COST(x) (((x) & 0xfff) << 0) -#define VEPU_REG_VP8_REF_FRAME_VAL 0x0a4 -#define VEPU_REG_VP8_COEF_DMV_PENALTY(x) (((x) & 0xfff) << 16) -#define VEPU_REG_VP8_REF_FRAME(x) (((x) & 0xfff) << 0) -#define VEPU_REG_VP8_LOOP_FILTER_REF_DELTA 0x0a8 -#define VEPU_REG_VP8_LF_REF_DELTA_ALT_REF(x) (((x) & 0x7f) << 16) -#define VEPU_REG_VP8_LF_REF_DELTA_LAST_REF(x) (((x) & 0x7f) << 8) -#define VEPU_REG_VP8_LF_REF_DELTA_GOLDEN(x) (((x) & 0x7f) << 0) -#define VEPU_REG_VP8_LOOP_FILTER_MODE_DELTA 0x0ac -#define VEPU_REG_VP8_LF_MODE_DELTA_SPLITMV(x) (((x) & 0x7f) << 16) -#define VEPU_REG_VP8_LF_MODE_DELTA_ZEROMV(x) (((x) & 0x7f) << 8) -#define VEPU_REG_VP8_LF_MODE_DELTA_NEWMV(x) (((x) & 0x7f) << 0) -#define VEPU_REG_INTRA_SLICE_BITMAP(i) (0x0b0 + ((i) * 0x4)) -#define VEPU_REG_ADDR_VP8_DCT_PART(i) (0x0b0 + ((i) * 0x4)) -#define VEPU_REG_INTRA_AREA_CTRL 0x0b8 -#define VEPU_REG_INTRA_AREA_TOP(x) (((x) & 0xff) << 24) -#define VEPU_REG_INTRA_AREA_BOTTOM(x) (((x) & 0xff) << 16) -#define VEPU_REG_INTRA_AREA_LEFT(x) (((x) & 0xff) << 8) -#define VEPU_REG_INTRA_AREA_RIGHT(x) (((x) & 0xff) << 0) -#define VEPU_REG_CIR_INTRA_CTRL 0x0bc -#define VEPU_REG_CIR_INTRA_FIRST_MB(x) (((x) & 0xffff) << 16) -#define VEPU_REG_CIR_INTRA_INTERVAL(x) (((x) & 0xffff) << 0) -#define VEPU_REG_ADDR_IN_LUMA 0x0c0 -#define VEPU_REG_ADDR_IN_CB 0x0c4 -#define VEPU_REG_ADDR_IN_CR 0x0c8 -#define VEPU_REG_STR_HDR_REM_MSB 0x0cc -#define VEPU_REG_STR_HDR_REM_LSB 0x0d0 -#define VEPU_REG_STR_BUF_LIMIT 0x0d4 -#define VEPU_REG_AXI_CTRL 0x0d8 -#define VEPU_REG_AXI_CTRL_READ_ID(x) (((x) & 0xff) << 24) -#define VEPU_REG_AXI_CTRL_WRITE_ID(x) (((x) & 0xff) << 16) -#define VEPU_REG_AXI_CTRL_BURST_LEN(x) (((x) & 0x3f) << 8) -#define VEPU_REG_AXI_CTRL_INCREMENT_MODE(x) (((x) & 0x01) << 2) -#define VEPU_REG_AXI_CTRL_BIRST_DISCARD(x) (((x) & 0x01) << 1) -#define VEPU_REG_AXI_CTRL_BIRST_DISABLE BIT(0) -#define VEPU_QP_ADJUST_MAD_DELTA_ROI 0x0dc -#define VEPU_REG_ROI_QP_DELTA_1 (((x) & 0xf) << 12) -#define VEPU_REG_ROI_QP_DELTA_2 (((x) & 0xf) << 8) -#define VEPU_REG_MAD_QP_ADJUSTMENT (((x) & 0xf) << 0) -#define VEPU_REG_ADDR_REF_LUMA 0x0e0 -#define VEPU_REG_ADDR_REF_CHROMA 0x0e4 -#define VEPU_REG_QP_SUM_DIV2 0x0e8 -#define VEPU_REG_QP_SUM(x) (((x) & 0x001fffff) * 2) -#define VEPU_REG_ENC_CTRL0 0x0ec -#define VEPU_REG_DISABLE_QUARTER_PIXEL_MV BIT(28) -#define VEPU_REG_DEBLOCKING_FILTER_MODE(x) (((x) & 0x3) << 24) -#define VEPU_REG_CABAC_INIT_IDC(x) (((x) & 0x3) << 21) -#define VEPU_REG_ENTROPY_CODING_MODE BIT(20) -#define VEPU_REG_H264_TRANS8X8_MODE BIT(17) -#define VEPU_REG_H264_INTER4X4_MODE BIT(16) -#define VEPU_REG_H264_STREAM_MODE BIT(15) -#define VEPU_REG_H264_SLICE_SIZE(x) (((x) & 0x7f) << 8) -#define VEPU_REG_ENC_OVER_FILL_STRM_OFFSET 0x0f0 -#define VEPU_REG_STREAM_START_OFFSET(x) (((x) & 0x3f) << 16) -#define VEPU_REG_SKIP_MACROBLOCK_PENALTY(x) (((x) & 0xff) << 8) -#define VEPU_REG_IN_IMG_CTRL_OVRFLR_D4(x) (((x) & 0x3) << 4) -#define VEPU_REG_IN_IMG_CTRL_OVRFLB(x) (((x) & 0xf) << 0) -#define VEPU_REG_INPUT_LUMA_INFO 0x0f4 -#define VEPU_REG_IN_IMG_CHROMA_OFFSET(x) (((x) & 0x7) << 20) -#define VEPU_REG_IN_IMG_LUMA_OFFSET(x) (((x) & 0x7) << 16) -#define VEPU_REG_IN_IMG_CTRL_ROW_LEN(x) (((x) & 0x3fff) << 0) -#define VEPU_REG_RLC_SUM 0x0f8 -#define VEPU_REG_RLC_SUM_OUT(x) (((x) & 0x007fffff) * 4) -#define VEPU_REG_SPLIT_PENALTY_4X4 0x0f8 -#define VEPU_REG_VP8_SPLIT_PENALTY_4X4 (((x) & 0x1ff) << 19) -#define VEPU_REG_ADDR_REC_LUMA 0x0fc -#define VEPU_REG_ADDR_REC_CHROMA 0x100 -#define VEPU_REG_CHECKPOINT(i) (0x104 + ((i) * 0x4)) -#define VEPU_REG_CHECKPOINT_CHECK0(x) (((x) & 0xffff)) -#define VEPU_REG_CHECKPOINT_CHECK1(x) (((x) & 0xffff) << 16) -#define VEPU_REG_CHECKPOINT_RESULT(x) ((((x) >> (16 - 16 \ - * (i & 1))) & 0xffff) \ - * 32) -#define VEPU_REG_VP8_SEG0_QUANT_AC_Y1 0x104 -#define VEPU_REG_VP8_SEG0_RND_AC_Y1(x) (((x) & 0xff) << 23) -#define VEPU_REG_VP8_SEG0_ZBIN_AC_Y1(x) (((x) & 0x1ff) << 14) -#define VEPU_REG_VP8_SEG0_QUT_AC_Y1(x) (((x) & 0x3fff) << 0) -#define VEPU_REG_VP8_SEG0_QUANT_DC_Y2 0x108 -#define VEPU_REG_VP8_SEG0_RND_DC_Y2(x) (((x) & 0xff) << 23) -#define VEPU_REG_VP8_SEG0_ZBIN_DC_Y2(x) (((x) & 0x1ff) << 14) -#define VEPU_REG_VP8_SEG0_QUT_DC_Y2(x) (((x) & 0x3fff) << 0) -#define VEPU_REG_VP8_SEG0_QUANT_AC_Y2 0x10c -#define VEPU_REG_VP8_SEG0_RND_AC_Y2(x) (((x) & 0xff) << 23) -#define VEPU_REG_VP8_SEG0_ZBIN_AC_Y2(x) (((x) & 0x1ff) << 14) -#define VEPU_REG_VP8_SEG0_QUT_AC_Y2(x) (((x) & 0x3fff) << 0) -#define VEPU_REG_VP8_SEG0_QUANT_DC_CHR 0x110 -#define VEPU_REG_VP8_SEG0_RND_DC_CHR(x) (((x) & 0xff) << 23) -#define VEPU_REG_VP8_SEG0_ZBIN_DC_CHR(x) (((x) & 0x1ff) << 14) -#define VEPU_REG_VP8_SEG0_QUT_DC_CHR(x) (((x) & 0x3fff) << 0) -#define VEPU_REG_VP8_SEG0_QUANT_AC_CHR 0x114 -#define VEPU_REG_VP8_SEG0_RND_AC_CHR(x) (((x) & 0xff) << 23) -#define VEPU_REG_VP8_SEG0_ZBIN_AC_CHR(x) (((x) & 0x1ff) << 14) -#define VEPU_REG_VP8_SEG0_QUT_AC_CHR(x) (((x) & 0x3fff) << 0) -#define VEPU_REG_VP8_SEG0_QUANT_DQUT 0x118 -#define VEPU_REG_VP8_MV_REF_IDX1(x) (((x) & 0x03) << 26) -#define VEPU_REG_VP8_SEG0_DQUT_DC_Y2(x) (((x) & 0x1ff) << 17) -#define VEPU_REG_VP8_SEG0_DQUT_AC_Y1(x) (((x) & 0x1ff) << 8) -#define VEPU_REG_VP8_SEG0_DQUT_DC_Y1(x) (((x) & 0xff) << 0) -#define VEPU_REG_CHKPT_WORD_ERR(i) (0x118 + ((i) * 0x4)) -#define VEPU_REG_CHKPT_WORD_ERR_CHK0(x) (((x) & 0xffff)) -#define VEPU_REG_CHKPT_WORD_ERR_CHK1(x) (((x) & 0xffff) << 16) -#define VEPU_REG_VP8_SEG0_QUANT_DQUT_1 0x11c -#define VEPU_REG_VP8_SEGMENT_MAP_UPDATE BIT(30) -#define VEPU_REG_VP8_SEGMENT_EN BIT(29) -#define VEPU_REG_VP8_MV_REF_IDX2_EN BIT(28) -#define VEPU_REG_VP8_MV_REF_IDX2(x) (((x) & 0x03) << 26) -#define VEPU_REG_VP8_SEG0_DQUT_AC_CHR(x) (((x) & 0x1ff) << 17) -#define VEPU_REG_VP8_SEG0_DQUT_DC_CHR(x) (((x) & 0xff) << 9) -#define VEPU_REG_VP8_SEG0_DQUT_AC_Y2(x) (((x) & 0x1ff) << 0) -#define VEPU_REG_VP8_BOOL_ENC_VALUE 0x120 -#define VEPU_REG_CHKPT_DELTA_QP 0x124 -#define VEPU_REG_CHKPT_DELTA_QP_CHK0(x) (((x) & 0x0f) << 0) -#define VEPU_REG_CHKPT_DELTA_QP_CHK1(x) (((x) & 0x0f) << 4) -#define VEPU_REG_CHKPT_DELTA_QP_CHK2(x) (((x) & 0x0f) << 8) -#define VEPU_REG_CHKPT_DELTA_QP_CHK3(x) (((x) & 0x0f) << 12) -#define VEPU_REG_CHKPT_DELTA_QP_CHK4(x) (((x) & 0x0f) << 16) -#define VEPU_REG_CHKPT_DELTA_QP_CHK5(x) (((x) & 0x0f) << 20) -#define VEPU_REG_CHKPT_DELTA_QP_CHK6(x) (((x) & 0x0f) << 24) -#define VEPU_REG_VP8_ENC_CTRL2 0x124 -#define VEPU_REG_VP8_ZERO_MV_PENALTY_FOR_REF2(x) (((x) & 0xff) << 24) -#define VEPU_REG_VP8_FILTER_SHARPNESS(x) (((x) & 0x07) << 21) -#define VEPU_REG_VP8_FILTER_LEVEL(x) (((x) & 0x3f) << 15) -#define VEPU_REG_VP8_DCT_PARTITION_CNT(x) (((x) & 0x03) << 13) -#define VEPU_REG_VP8_BOOL_ENC_VALUE_BITS(x) (((x) & 0x1f) << 8) -#define VEPU_REG_VP8_BOOL_ENC_RANGE(x) (((x) & 0xff) << 0) -#define VEPU_REG_ENC_CTRL1 0x128 -#define VEPU_REG_MAD_THRESHOLD(x) (((x) & 0x3f) << 24) -#define VEPU_REG_COMPLETED_SLICES(x) (((x) & 0xff) << 16) -#define VEPU_REG_IN_IMG_CTRL_FMT(x) (((x) & 0xf) << 4) -#define VEPU_REG_IN_IMG_ROTATE_MODE(x) (((x) & 0x3) << 2) -#define VEPU_REG_SIZE_TABLE_PRESENT BIT(0) -#define VEPU_REG_INTRA_INTER_MODE 0x12c -#define VEPU_REG_INTRA16X16_MODE(x) (((x) & 0xffff) << 16) -#define VEPU_REG_INTER_MODE(x) (((x) & 0xffff) << 0) -#define VEPU_REG_ENC_CTRL2 0x130 -#define VEPU_REG_PPS_INIT_QP(x) (((x) & 0x3f) << 26) -#define VEPU_REG_SLICE_FILTER_ALPHA(x) (((x) & 0xf) << 22) -#define VEPU_REG_SLICE_FILTER_BETA(x) (((x) & 0xf) << 18) -#define VEPU_REG_CHROMA_QP_OFFSET(x) (((x) & 0x1f) << 13) -#define VEPU_REG_FILTER_DISABLE BIT(5) -#define VEPU_REG_IDR_PIC_ID(x) (((x) & 0xf) << 1) -#define VEPU_REG_CONSTRAINED_INTRA_PREDICTION BIT(0) -#define VEPU_REG_ADDR_OUTPUT_STREAM 0x134 -#define VEPU_REG_ADDR_OUTPUT_CTRL 0x138 -#define VEPU_REG_ADDR_NEXT_PIC 0x13c -#define VEPU_REG_ADDR_MV_OUT 0x140 -#define VEPU_REG_ADDR_CABAC_TBL 0x144 -#define VEPU_REG_ROI1 0x148 -#define VEPU_REG_ROI1_TOP_MB(x) (((x) & 0xff) << 24) -#define VEPU_REG_ROI1_BOTTOM_MB(x) (((x) & 0xff) << 16) -#define VEPU_REG_ROI1_LEFT_MB(x) (((x) & 0xff) << 8) -#define VEPU_REG_ROI1_RIGHT_MB(x) (((x) & 0xff) << 0) -#define VEPU_REG_ROI2 0x14c -#define VEPU_REG_ROI2_TOP_MB(x) (((x) & 0xff) << 24) -#define VEPU_REG_ROI2_BOTTOM_MB(x) (((x) & 0xff) << 16) -#define VEPU_REG_ROI2_LEFT_MB(x) (((x) & 0xff) << 8) -#define VEPU_REG_ROI2_RIGHT_MB(x) (((x) & 0xff) << 0) -#define VEPU_REG_STABLE_MATRIX(i) (0x150 + ((i) * 0x4)) -#define VEPU_REG_STABLE_MOTION_SUM 0x174 -#define VEPU_REG_STABLILIZATION_OUTPUT 0x178 -#define VEPU_REG_STABLE_MIN_VALUE(x) (((x) & 0xffffff) << 8) -#define VEPU_REG_STABLE_MODE_SEL(x) (((x) & 0x3) << 6) -#define VEPU_REG_STABLE_HOR_GMV(x) (((x) & 0x3f) << 0) -#define VEPU_REG_RGB2YUV_CONVERSION_COEF1 0x17c -#define VEPU_REG_RGB2YUV_CONVERSION_COEFB(x) (((x) & 0xffff) << 16) -#define VEPU_REG_RGB2YUV_CONVERSION_COEFA(x) (((x) & 0xffff) << 0) -#define VEPU_REG_RGB2YUV_CONVERSION_COEF2 0x180 -#define VEPU_REG_RGB2YUV_CONVERSION_COEFE(x) (((x) & 0xffff) << 16) -#define VEPU_REG_RGB2YUV_CONVERSION_COEFC(x) (((x) & 0xffff) << 0) -#define VEPU_REG_RGB2YUV_CONVERSION_COEF3 0x184 -#define VEPU_REG_RGB2YUV_CONVERSION_COEFF(x) (((x) & 0xffff) << 0) -#define VEPU_REG_RGB_MASK_MSB 0x188 -#define VEPU_REG_RGB_MASK_B_MSB(x) (((x) & 0x1f) << 16) -#define VEPU_REG_RGB_MASK_G_MSB(x) (((x) & 0x1f) << 8) -#define VEPU_REG_RGB_MASK_R_MSB(x) (((x) & 0x1f) << 0) -#define VEPU_REG_MV_PENALTY 0x18c -#define VEPU_REG_1MV_PENALTY(x) (((x) & 0x3ff) << 21) -#define VEPU_REG_QMV_PENALTY(x) (((x) & 0x3ff) << 11) -#define VEPU_REG_4MV_PENALTY(x) (((x) & 0x3ff) << 1) -#define VEPU_REG_SPLIT_MV_MODE_EN BIT(0) -#define VEPU_REG_QP_VAL 0x190 -#define VEPU_REG_H264_LUMA_INIT_QP(x) (((x) & 0x3f) << 26) -#define VEPU_REG_H264_QP_MAX(x) (((x) & 0x3f) << 20) -#define VEPU_REG_H264_QP_MIN(x) (((x) & 0x3f) << 14) -#define VEPU_REG_H264_CHKPT_DISTANCE(x) (((x) & 0xfff) << 0) -#define VEPU_REG_VP8_SEG0_QUANT_DC_Y1 0x190 -#define VEPU_REG_VP8_SEG0_RND_DC_Y1(x) (((x) & 0xff) << 23) -#define VEPU_REG_VP8_SEG0_ZBIN_DC_Y1(x) (((x) & 0x1ff) << 14) -#define VEPU_REG_VP8_SEG0_QUT_DC_Y1(x) (((x) & 0x3fff) << 0) -#define VEPU_REG_MVC_RELATE 0x198 -#define VEPU_REG_ZERO_MV_FAVOR_D2(x) (((x) & 0xf) << 20) -#define VEPU_REG_PENALTY_4X4MV(x) (((x) & 0x1ff) << 11) -#define VEPU_REG_MVC_VIEW_ID(x) (((x) & 0x7) << 8) -#define VEPU_REG_MVC_ANCHOR_PIC_FLAG BIT(7) -#define VEPU_REG_MVC_PRIORITY_ID(x) (((x) & 0x7) << 4) -#define VEPU_REG_MVC_TEMPORAL_ID(x) (((x) & 0x7) << 1) -#define VEPU_REG_MVC_INTER_VIEW_FLAG BIT(0) -#define VEPU_REG_ENCODE_START 0x19c -#define VEPU_REG_MB_HEIGHT(x) (((x) & 0x1ff) << 20) -#define VEPU_REG_MB_WIDTH(x) (((x) & 0x1ff) << 8) -#define VEPU_REG_PIC_TYPE(x) (((x) & 0x3) << 6) -#define VEPU_REG_ENCODE_FORMAT(x) (((x) & 0x3) << 4) -#define VEPU_REG_ENCODE_ENABLE BIT(0) -#define VEPU_REG_MB_CTRL 0x1a0 -#define VEPU_REG_MB_CNT_OUT(x) (((x) & 0xffff) << 16) -#define VEPU_REG_MB_CNT_SET(x) (((x) & 0xffff) << 0) -#define VEPU_REG_DATA_ENDIAN 0x1a4 -#define VEPU_REG_INPUT_SWAP8 BIT(31) -#define VEPU_REG_INPUT_SWAP16 BIT(30) -#define VEPU_REG_INPUT_SWAP32 BIT(29) -#define VEPU_REG_OUTPUT_SWAP8 BIT(28) -#define VEPU_REG_OUTPUT_SWAP16 BIT(27) -#define VEPU_REG_OUTPUT_SWAP32 BIT(26) -#define VEPU_REG_TEST_IRQ BIT(24) -#define VEPU_REG_TEST_COUNTER(x) (((x) & 0xf) << 20) -#define VEPU_REG_TEST_REG BIT(19) -#define VEPU_REG_TEST_MEMORY BIT(18) -#define VEPU_REG_TEST_LEN(x) (((x) & 0x3ffff) << 0) -#define VEPU_REG_ENC_CTRL3 0x1a8 -#define VEPU_REG_PPS_ID(x) (((x) & 0xff) << 24) -#define VEPU_REG_INTRA_PRED_MODE(x) (((x) & 0xff) << 16) -#define VEPU_REG_FRAME_NUM(x) (((x) & 0xffff) << 0) -#define VEPU_REG_ENC_CTRL4 0x1ac -#define VEPU_REG_MV_PENALTY_16X8_8X16(x) (((x) & 0x3ff) << 20) -#define VEPU_REG_MV_PENALTY_8X8(x) (((x) & 0x3ff) << 10) -#define VEPU_REG_MV_PENALTY_8X4_4X8(x) (((x) & 0x3ff) << 0) -#define VEPU_REG_ADDR_VP8_PROB_CNT 0x1b0 -#define VEPU_REG_INTERRUPT 0x1b4 -#define VEPU_REG_INTERRUPT_NON BIT(28) -#define VEPU_REG_MV_WRITE_EN BIT(24) -#define VEPU_REG_RECON_WRITE_DIS BIT(20) -#define VEPU_REG_INTERRUPT_SLICE_READY_EN BIT(16) -#define VEPU_REG_CLK_GATING_EN BIT(12) -#define VEPU_REG_INTERRUPT_TIMEOUT_EN BIT(10) -#define VEPU_REG_INTERRUPT_RESET BIT(9) -#define VEPU_REG_INTERRUPT_DIS_BIT BIT(8) -#define VEPU_REG_INTERRUPT_TIMEOUT BIT(6) -#define VEPU_REG_INTERRUPT_BUFFER_FULL BIT(5) -#define VEPU_REG_INTERRUPT_BUS_ERROR BIT(4) -#define VEPU_REG_INTERRUPT_FUSE BIT(3) -#define VEPU_REG_INTERRUPT_SLICE_READY BIT(2) -#define VEPU_REG_INTERRUPT_FRAME_READY BIT(1) -#define VEPU_REG_INTERRUPT_BIT BIT(0) -#define VEPU_REG_DMV_PENALTY_TBL(i) (0x1E0 + ((i) * 0x4)) -#define VEPU_REG_DMV_PENALTY_TABLE_BIT(x, i) (x << i * 8) -#define VEPU_REG_DMV_Q_PIXEL_PENALTY_TBL(i) (0x260 + ((i) * 0x4)) -#define VEPU_REG_DMV_Q_PIXEL_PENALTY_TABLE_BIT(x, i) (x << i * 8) - -/* vpu decoder register */ -#define VDPU_REG_DEC_CTRL0 0x0c8 -#define VDPU_REG_REF_BUF_CTRL2_REFBU2_PICID(x) (((x) & 0x1f) << 25) -#define VDPU_REG_REF_BUF_CTRL2_REFBU2_THR(x) (((x) & 0xfff) << 13) -#define VDPU_REG_CONFIG_TILED_MODE_LSB BIT(12) -#define VDPU_REG_CONFIG_DEC_ADV_PRE_DIS BIT(11) -#define VDPU_REG_CONFIG_DEC_SCMD_DIS BIT(10) -#define VDPU_REG_DEC_CTRL0_SKIP_MODE BIT(9) -#define VDPU_REG_DEC_CTRL0_FILTERING_DIS BIT(8) -#define VDPU_REG_DEC_CTRL0_PIC_FIXED_QUANT BIT(7) -#define VDPU_REG_CONFIG_DEC_LATENCY(x) (((x) & 0x3f) << 1) -#define VDPU_REG_CONFIG_TILED_MODE_MSB(x) BIT(0) -#define VDPU_REG_CONFIG_DEC_OUT_TILED_E BIT(0) -#define VDPU_REG_STREAM_LEN 0x0cc -#define VDPU_REG_DEC_CTRL3_INIT_QP(x) (((x) & 0x3f) << 25) -#define VDPU_REG_DEC_STREAM_LEN_HI BIT(24) -#define VDPU_REG_DEC_CTRL3_STREAM_LEN(x) (((x) & 0xffffff) << 0) -#define VDPU_REG_ERROR_CONCEALMENT 0x0d0 -#define VDPU_REG_REF_BUF_CTRL2_APF_THRESHOLD(x) (((x) & 0x3fff) << 17) -#define VDPU_REG_ERR_CONC_STARTMB_X(x) (((x) & 0x1ff) << 8) -#define VDPU_REG_ERR_CONC_STARTMB_Y(x) (((x) & 0xff) << 0) -#define VDPU_REG_DEC_FORMAT 0x0d4 -#define VDPU_REG_DEC_CTRL0_DEC_MODE(x) (((x) & 0xf) << 0) -#define VDPU_REG_DATA_ENDIAN 0x0d8 -#define VDPU_REG_CONFIG_DEC_STRENDIAN_E BIT(5) -#define VDPU_REG_CONFIG_DEC_STRSWAP32_E BIT(4) -#define VDPU_REG_CONFIG_DEC_OUTSWAP32_E BIT(3) -#define VDPU_REG_CONFIG_DEC_INSWAP32_E BIT(2) -#define VDPU_REG_CONFIG_DEC_OUT_ENDIAN BIT(1) -#define VDPU_REG_CONFIG_DEC_IN_ENDIAN BIT(0) -#define VDPU_REG_INTERRUPT 0x0dc -#define VDPU_REG_INTERRUPT_DEC_TIMEOUT BIT(13) -#define VDPU_REG_INTERRUPT_DEC_ERROR_INT BIT(12) -#define VDPU_REG_INTERRUPT_DEC_PIC_INF BIT(10) -#define VDPU_REG_INTERRUPT_DEC_SLICE_INT BIT(9) -#define VDPU_REG_INTERRUPT_DEC_ASO_INT BIT(8) -#define VDPU_REG_INTERRUPT_DEC_BUFFER_INT BIT(6) -#define VDPU_REG_INTERRUPT_DEC_BUS_INT BIT(5) -#define VDPU_REG_INTERRUPT_DEC_RDY_INT BIT(4) -#define VDPU_REG_INTERRUPT_DEC_IRQ_DIS BIT(1) -#define VDPU_REG_INTERRUPT_DEC_IRQ BIT(0) -#define VDPU_REG_AXI_CTRL 0x0e0 -#define VDPU_REG_AXI_DEC_SEL BIT(23) -#define VDPU_REG_CONFIG_DEC_DATA_DISC_E BIT(22) -#define VDPU_REG_PARAL_BUS_E(x) BIT(21) -#define VDPU_REG_CONFIG_DEC_MAX_BURST(x) (((x) & 0x1f) << 16) -#define VDPU_REG_DEC_CTRL0_DEC_AXI_WR_ID(x) (((x) & 0xff) << 8) -#define VDPU_REG_CONFIG_DEC_AXI_RD_ID(x) (((x) & 0xff) << 0) -#define VDPU_REG_EN_FLAGS 0x0e4 -#define VDPU_REG_AHB_HLOCK_E BIT(31) -#define VDPU_REG_CACHE_E BIT(29) -#define VDPU_REG_PREFETCH_SINGLE_CHANNEL_E BIT(28) -#define VDPU_REG_INTRA_3_CYCLE_ENHANCE BIT(27) -#define VDPU_REG_INTRA_DOUBLE_SPEED BIT(26) -#define VDPU_REG_INTER_DOUBLE_SPEED BIT(25) -#define VDPU_REG_DEC_CTRL3_START_CODE_E BIT(22) -#define VDPU_REG_DEC_CTRL3_CH_8PIX_ILEAV_E BIT(21) -#define VDPU_REG_DEC_CTRL0_RLC_MODE_E BIT(20) -#define VDPU_REG_DEC_CTRL0_DIVX3_E BIT(19) -#define VDPU_REG_DEC_CTRL0_PJPEG_E BIT(18) -#define VDPU_REG_DEC_CTRL0_PIC_INTERLACE_E BIT(17) -#define VDPU_REG_DEC_CTRL0_PIC_FIELDMODE_E BIT(16) -#define VDPU_REG_DEC_CTRL0_PIC_B_E BIT(15) -#define VDPU_REG_DEC_CTRL0_PIC_INTER_E BIT(14) -#define VDPU_REG_DEC_CTRL0_PIC_TOPFIELD_E BIT(13) -#define VDPU_REG_DEC_CTRL0_FWD_INTERLACE_E BIT(12) -#define VDPU_REG_DEC_CTRL0_SORENSON_E BIT(11) -#define VDPU_REG_DEC_CTRL0_WRITE_MVS_E BIT(10) -#define VDPU_REG_DEC_CTRL0_REF_TOPFIELD_E BIT(9) -#define VDPU_REG_DEC_CTRL0_REFTOPFIRST_E BIT(8) -#define VDPU_REG_DEC_CTRL0_SEQ_MBAFF_E BIT(7) -#define VDPU_REG_DEC_CTRL0_PICORD_COUNT_E BIT(6) -#define VDPU_REG_CONFIG_DEC_TIMEOUT_E BIT(5) -#define VDPU_REG_CONFIG_DEC_CLK_GATE_E BIT(4) -#define VDPU_REG_DEC_CTRL0_DEC_OUT_DIS BIT(2) -#define VDPU_REG_REF_BUF_CTRL2_REFBU2_BUF_E BIT(1) -#define VDPU_REG_INTERRUPT_DEC_E BIT(0) -#define VDPU_REG_SOFT_RESET 0x0e8 -#define VDPU_REG_PRED_FLT 0x0ec -#define VDPU_REG_PRED_FLT_PRED_BC_TAP_0_0(x) (((x) & 0x3ff) << 22) -#define VDPU_REG_PRED_FLT_PRED_BC_TAP_0_1(x) (((x) & 0x3ff) << 12) -#define VDPU_REG_PRED_FLT_PRED_BC_TAP_0_2(x) (((x) & 0x3ff) << 2) -#define VDPU_REG_ADDITIONAL_CHROMA_ADDRESS 0x0f0 -#define VDPU_REG_ADDR_QTABLE 0x0f4 -#define VDPU_REG_DIRECT_MV_ADDR 0x0f8 -#define VDPU_REG_ADDR_DST 0x0fc -#define VDPU_REG_ADDR_STR 0x100 -#define VDPU_REG_REFBUF_RELATED 0x104 -#define VDPU_REG_FWD_PIC(i) (0x128 + ((i) * 0x4)) -#define VDPU_REG_FWD_PIC_PINIT_RLIST_F5(x) (((x) & 0x1f) << 25) -#define VDPU_REG_FWD_PIC_PINIT_RLIST_F4(x) (((x) & 0x1f) << 20) -#define VDPU_REG_FWD_PIC_PINIT_RLIST_F3(x) (((x) & 0x1f) << 15) -#define VDPU_REG_FWD_PIC_PINIT_RLIST_F2(x) (((x) & 0x1f) << 10) -#define VDPU_REG_FWD_PIC_PINIT_RLIST_F1(x) (((x) & 0x1f) << 5) -#define VDPU_REG_FWD_PIC_PINIT_RLIST_F0(x) (((x) & 0x1f) << 0) -#define VDPU_REG_REF_PIC(i) (0x130 + ((i) * 0x4)) -#define VDPU_REG_REF_PIC_REFER1_NBR(x) (((x) & 0xffff) << 16) -#define VDPU_REG_REF_PIC_REFER0_NBR(x) (((x) & 0xffff) << 0) -#define VDPU_REG_H264_ADDR_REF(i) (0x150 + ((i) * 0x4)) -#define VDPU_REG_ADDR_REF_FIELD_E BIT(1) -#define VDPU_REG_ADDR_REF_TOPC_E BIT(0) -#define VDPU_REG_INITIAL_REF_PIC_LIST0 0x190 -#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_F5(x) (((x) & 0x1f) << 25) -#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_F4(x) (((x) & 0x1f) << 20) -#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_F3(x) (((x) & 0x1f) << 15) -#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_F2(x) (((x) & 0x1f) << 10) -#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_F1(x) (((x) & 0x1f) << 5) -#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_F0(x) (((x) & 0x1f) << 0) -#define VDPU_REG_INITIAL_REF_PIC_LIST1 0x194 -#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_F11(x) (((x) & 0x1f) << 25) -#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_F10(x) (((x) & 0x1f) << 20) -#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_F9(x) (((x) & 0x1f) << 15) -#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_F8(x) (((x) & 0x1f) << 10) -#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_F7(x) (((x) & 0x1f) << 5) -#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_F6(x) (((x) & 0x1f) << 0) -#define VDPU_REG_INITIAL_REF_PIC_LIST2 0x198 -#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_F15(x) (((x) & 0x1f) << 15) -#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_F14(x) (((x) & 0x1f) << 10) -#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_F13(x) (((x) & 0x1f) << 5) -#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_F12(x) (((x) & 0x1f) << 0) -#define VDPU_REG_INITIAL_REF_PIC_LIST3 0x19c -#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_B5(x) (((x) & 0x1f) << 25) -#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_B4(x) (((x) & 0x1f) << 20) -#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_B3(x) (((x) & 0x1f) << 15) -#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_B2(x) (((x) & 0x1f) << 10) -#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_B1(x) (((x) & 0x1f) << 5) -#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_B0(x) (((x) & 0x1f) << 0) -#define VDPU_REG_INITIAL_REF_PIC_LIST4 0x1a0 -#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_B11(x) (((x) & 0x1f) << 25) -#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_B10(x) (((x) & 0x1f) << 20) -#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_B9(x) (((x) & 0x1f) << 15) -#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_B8(x) (((x) & 0x1f) << 10) -#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_B7(x) (((x) & 0x1f) << 5) -#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_B6(x) (((x) & 0x1f) << 0) -#define VDPU_REG_INITIAL_REF_PIC_LIST5 0x1a4 -#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_B15(x) (((x) & 0x1f) << 15) -#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_B14(x) (((x) & 0x1f) << 10) -#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_B13(x) (((x) & 0x1f) << 5) -#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_B12(x) (((x) & 0x1f) << 0) -#define VDPU_REG_INITIAL_REF_PIC_LIST6 0x1a8 -#define VDPU_REG_BD_P_REF_PIC_PINIT_RLIST_F3(x) (((x) & 0x1f) << 15) -#define VDPU_REG_BD_P_REF_PIC_PINIT_RLIST_F2(x) (((x) & 0x1f) << 10) -#define VDPU_REG_BD_P_REF_PIC_PINIT_RLIST_F1(x) (((x) & 0x1f) << 5) -#define VDPU_REG_BD_P_REF_PIC_PINIT_RLIST_F0(x) (((x) & 0x1f) << 0) -#define VDPU_REG_LT_REF 0x1ac -#define VDPU_REG_VALID_REF 0x1b0 -#define VDPU_REG_H264_PIC_MB_SIZE 0x1b8 -#define VDPU_REG_DEC_CTRL2_CH_QP_OFFSET2(x) (((x) & 0x1f) << 22) -#define VDPU_REG_DEC_CTRL2_CH_QP_OFFSET(x) (((x) & 0x1f) << 17) -#define VDPU_REG_DEC_CTRL1_PIC_MB_HEIGHT_P(x) (((x) & 0xff) << 9) -#define VDPU_REG_DEC_CTRL1_PIC_MB_WIDTH(x) (((x) & 0x1ff) << 0) -#define VDPU_REG_H264_CTRL 0x1bc -#define VDPU_REG_DEC_CTRL4_WEIGHT_BIPR_IDC(x) (((x) & 0x3) << 16) -#define VDPU_REG_DEC_CTRL1_REF_FRAMES(x) (((x) & 0x1f) << 0) -#define VDPU_REG_CURRENT_FRAME 0x1c0 -#define VDPU_REG_DEC_CTRL5_FILT_CTRL_PRES BIT(31) -#define VDPU_REG_DEC_CTRL5_RDPIC_CNT_PRES BIT(30) -#define VDPU_REG_DEC_CTRL4_FRAMENUM_LEN(x) (((x) & 0x1f) << 16) -#define VDPU_REG_DEC_CTRL4_FRAMENUM(x) (((x) & 0xffff) << 0) -#define VDPU_REG_REF_FRAME 0x1c4 -#define VDPU_REG_DEC_CTRL5_REFPIC_MK_LEN(x) (((x) & 0x7ff) << 16) -#define VDPU_REG_DEC_CTRL5_IDR_PIC_ID(x) (((x) & 0xffff) << 0) -#define VDPU_REG_DEC_CTRL6 0x1c8 -#define VDPU_REG_DEC_CTRL6_PPS_ID(x) (((x) & 0xff) << 24) -#define VDPU_REG_DEC_CTRL6_REFIDX1_ACTIVE(x) (((x) & 0x1f) << 19) -#define VDPU_REG_DEC_CTRL6_REFIDX0_ACTIVE(x) (((x) & 0x1f) << 14) -#define VDPU_REG_DEC_CTRL6_POC_LENGTH(x) (((x) & 0xff) << 0) -#define VDPU_REG_ENABLE_FLAG 0x1cc -#define VDPU_REG_DEC_CTRL5_IDR_PIC_E BIT(8) -#define VDPU_REG_DEC_CTRL4_DIR_8X8_INFER_E BIT(7) -#define VDPU_REG_DEC_CTRL4_BLACKWHITE_E BIT(6) -#define VDPU_REG_DEC_CTRL4_CABAC_E BIT(5) -#define VDPU_REG_DEC_CTRL4_WEIGHT_PRED_E BIT(4) -#define VDPU_REG_DEC_CTRL5_CONST_INTRA_E BIT(3) -#define VDPU_REG_DEC_CTRL5_8X8TRANS_FLAG_E BIT(2) -#define VDPU_REG_DEC_CTRL2_TYPE1_QUANT_E BIT(1) -#define VDPU_REG_DEC_CTRL2_FIELDPIC_FLAG_E BIT(0) -#define VDPU_REG_VP8_PIC_MB_SIZE 0x1e0 -#define VDPU_REG_DEC_PIC_MB_WIDTH(x) (((x) & 0x1ff) << 23) -#define VDPU_REG_DEC_MB_WIDTH_OFF(x) (((x) & 0xf) << 19) -#define VDPU_REG_DEC_PIC_MB_HEIGHT_P(x) (((x) & 0xff) << 11) -#define VDPU_REG_DEC_MB_HEIGHT_OFF(x) (((x) & 0xf) << 7) -#define VDPU_REG_DEC_CTRL1_PIC_MB_W_EXT(x) (((x) & 0x7) << 3) -#define VDPU_REG_DEC_CTRL1_PIC_MB_H_EXT(x) (((x) & 0x7) << 0) -#define VDPU_REG_VP8_DCT_START_BIT 0x1e4 -#define VDPU_REG_DEC_CTRL4_DCT1_START_BIT(x) (((x) & 0x3f) << 26) -#define VDPU_REG_DEC_CTRL4_DCT2_START_BIT(x) (((x) & 0x3f) << 20) -#define VDPU_REG_DEC_CTRL4_VC1_HEIGHT_EXT BIT(13) -#define VDPU_REG_DEC_CTRL4_BILIN_MC_E BIT(12) -#define VDPU_REG_VP8_CTRL0 0x1e8 -#define VDPU_REG_DEC_CTRL2_STRM_START_BIT(x) (((x) & 0x3f) << 26) -#define VDPU_REG_DEC_CTRL2_STRM1_START_BIT(x) (((x) & 0x3f) << 18) -#define VDPU_REG_DEC_CTRL2_BOOLEAN_VALUE(x) (((x) & 0xff) << 8) -#define VDPU_REG_DEC_CTRL2_BOOLEAN_RANGE(x) (((x) & 0xff) << 0) -#define VDPU_REG_VP8_DATA_VAL 0x1f0 -#define VDPU_REG_DEC_CTRL6_COEFFS_PART_AM(x) (((x) & 0xf) << 24) -#define VDPU_REG_DEC_CTRL6_STREAM1_LEN(x) (((x) & 0xffffff) << 0) -#define VDPU_REG_PRED_FLT7 0x1f4 -#define VDPU_REG_PRED_FLT_PRED_BC_TAP_5_1(x) (((x) & 0x3ff) << 22) -#define VDPU_REG_PRED_FLT_PRED_BC_TAP_5_2(x) (((x) & 0x3ff) << 12) -#define VDPU_REG_PRED_FLT_PRED_BC_TAP_5_3(x) (((x) & 0x3ff) << 2) -#define VDPU_REG_PRED_FLT8 0x1f8 -#define VDPU_REG_PRED_FLT_PRED_BC_TAP_6_0(x) (((x) & 0x3ff) << 22) -#define VDPU_REG_PRED_FLT_PRED_BC_TAP_6_1(x) (((x) & 0x3ff) << 12) -#define VDPU_REG_PRED_FLT_PRED_BC_TAP_6_2(x) (((x) & 0x3ff) << 2) -#define VDPU_REG_PRED_FLT9 0x1fc -#define VDPU_REG_PRED_FLT_PRED_BC_TAP_6_3(x) (((x) & 0x3ff) << 22) -#define VDPU_REG_PRED_FLT_PRED_BC_TAP_7_0(x) (((x) & 0x3ff) << 12) -#define VDPU_REG_PRED_FLT_PRED_BC_TAP_7_1(x) (((x) & 0x3ff) << 2) -#define VDPU_REG_PRED_FLT10 0x200 -#define VDPU_REG_PRED_FLT_PRED_BC_TAP_7_2(x) (((x) & 0x3ff) << 22) -#define VDPU_REG_PRED_FLT_PRED_BC_TAP_7_3(x) (((x) & 0x3ff) << 12) -#define VDPU_REG_BD_REF_PIC_PRED_TAP_2_M1(x) (((x) & 0x3) << 10) -#define VDPU_REG_BD_REF_PIC_PRED_TAP_2_4(x) (((x) & 0x3) << 8) -#define VDPU_REG_BD_REF_PIC_PRED_TAP_4_M1(x) (((x) & 0x3) << 6) -#define VDPU_REG_BD_REF_PIC_PRED_TAP_4_4(x) (((x) & 0x3) << 4) -#define VDPU_REG_BD_REF_PIC_PRED_TAP_6_M1(x) (((x) & 0x3) << 2) -#define VDPU_REG_BD_REF_PIC_PRED_TAP_6_4(x) (((x) & 0x3) << 0) -#define VDPU_REG_FILTER_LEVEL 0x204 -#define VDPU_REG_REF_PIC_LF_LEVEL_0(x) (((x) & 0x3f) << 18) -#define VDPU_REG_REF_PIC_LF_LEVEL_1(x) (((x) & 0x3f) << 12) -#define VDPU_REG_REF_PIC_LF_LEVEL_2(x) (((x) & 0x3f) << 6) -#define VDPU_REG_REF_PIC_LF_LEVEL_3(x) (((x) & 0x3f) << 0) -#define VDPU_REG_VP8_QUANTER0 0x208 -#define VDPU_REG_REF_PIC_QUANT_DELTA_0(x) (((x) & 0x1f) << 27) -#define VDPU_REG_REF_PIC_QUANT_DELTA_1(x) (((x) & 0x1f) << 22) -#define VDPU_REG_REF_PIC_QUANT_0(x) (((x) & 0x7ff) << 11) -#define VDPU_REG_REF_PIC_QUANT_1(x) (((x) & 0x7ff) << 0) -#define VDPU_REG_VP8_ADDR_REF0 0x20c -#define VDPU_REG_FILTER_MB_ADJ 0x210 -#define VDPU_REG_REF_PIC_FILT_TYPE_E BIT(31) -#define VDPU_REG_REF_PIC_FILT_SHARPNESS(x) (((x) & 0x7) << 28) -#define VDPU_REG_FILT_MB_ADJ_0(x) (((x) & 0x7f) << 21) -#define VDPU_REG_FILT_MB_ADJ_1(x) (((x) & 0x7f) << 14) -#define VDPU_REG_FILT_MB_ADJ_2(x) (((x) & 0x7f) << 7) -#define VDPU_REG_FILT_MB_ADJ_3(x) (((x) & 0x7f) << 0) -#define VDPU_REG_FILTER_REF_ADJ 0x214 -#define VDPU_REG_REF_PIC_ADJ_0(x) (((x) & 0x7f) << 21) -#define VDPU_REG_REF_PIC_ADJ_1(x) (((x) & 0x7f) << 14) -#define VDPU_REG_REF_PIC_ADJ_2(x) (((x) & 0x7f) << 7) -#define VDPU_REG_REF_PIC_ADJ_3(x) (((x) & 0x7f) << 0) -#define VDPU_REG_VP8_ADDR_REF2_5(i) (0x218 + ((i) * 0x4)) -#define VDPU_REG_VP8_GREF_SIGN_BIAS BIT(0) -#define VDPU_REG_VP8_AREF_SIGN_BIAS BIT(0) -#define VDPU_REG_VP8_DCT_BASE(i) (0x230 + ((i) * 0x4)) -#define VDPU_REG_VP8_ADDR_CTRL_PART 0x244 -#define VDPU_REG_VP8_ADDR_REF1 0x250 -#define VDPU_REG_VP8_SEGMENT_VAL 0x254 -#define VDPU_REG_FWD_PIC1_SEGMENT_BASE(x) ((x) << 0) -#define VDPU_REG_FWD_PIC1_SEGMENT_UPD_E BIT(1) -#define VDPU_REG_FWD_PIC1_SEGMENT_E BIT(0) -#define VDPU_REG_VP8_DCT_START_BIT2 0x258 -#define VDPU_REG_DEC_CTRL7_DCT3_START_BIT(x) (((x) & 0x3f) << 24) -#define VDPU_REG_DEC_CTRL7_DCT4_START_BIT(x) (((x) & 0x3f) << 18) -#define VDPU_REG_DEC_CTRL7_DCT5_START_BIT(x) (((x) & 0x3f) << 12) -#define VDPU_REG_DEC_CTRL7_DCT6_START_BIT(x) (((x) & 0x3f) << 6) -#define VDPU_REG_DEC_CTRL7_DCT7_START_BIT(x) (((x) & 0x3f) << 0) -#define VDPU_REG_VP8_QUANTER1 0x25c -#define VDPU_REG_REF_PIC_QUANT_DELTA_2(x) (((x) & 0x1f) << 27) -#define VDPU_REG_REF_PIC_QUANT_DELTA_3(x) (((x) & 0x1f) << 22) -#define VDPU_REG_REF_PIC_QUANT_2(x) (((x) & 0x7ff) << 11) -#define VDPU_REG_REF_PIC_QUANT_3(x) (((x) & 0x7ff) << 0) -#define VDPU_REG_VP8_QUANTER2 0x260 -#define VDPU_REG_REF_PIC_QUANT_DELTA_4(x) (((x) & 0x1f) << 27) -#define VDPU_REG_REF_PIC_QUANT_4(x) (((x) & 0x7ff) << 11) -#define VDPU_REG_REF_PIC_QUANT_5(x) (((x) & 0x7ff) << 0) -#define VDPU_REG_PRED_FLT1 0x264 -#define VDPU_REG_PRED_FLT_PRED_BC_TAP_0_3(x) (((x) & 0x3ff) << 22) -#define VDPU_REG_PRED_FLT_PRED_BC_TAP_1_0(x) (((x) & 0x3ff) << 12) -#define VDPU_REG_PRED_FLT_PRED_BC_TAP_1_1(x) (((x) & 0x3ff) << 2) -#define VDPU_REG_PRED_FLT2 0x268 -#define VDPU_REG_PRED_FLT_PRED_BC_TAP_1_2(x) (((x) & 0x3ff) << 22) -#define VDPU_REG_PRED_FLT_PRED_BC_TAP_1_3(x) (((x) & 0x3ff) << 12) -#define VDPU_REG_PRED_FLT_PRED_BC_TAP_2_0(x) (((x) & 0x3ff) << 2) -#define VDPU_REG_PRED_FLT3 0x26c -#define VDPU_REG_PRED_FLT_PRED_BC_TAP_2_1(x) (((x) & 0x3ff) << 22) -#define VDPU_REG_PRED_FLT_PRED_BC_TAP_2_2(x) (((x) & 0x3ff) << 12) -#define VDPU_REG_PRED_FLT_PRED_BC_TAP_2_3(x) (((x) & 0x3ff) << 2) -#define VDPU_REG_PRED_FLT4 0x270 -#define VDPU_REG_PRED_FLT_PRED_BC_TAP_3_0(x) (((x) & 0x3ff) << 22) -#define VDPU_REG_PRED_FLT_PRED_BC_TAP_3_1(x) (((x) & 0x3ff) << 12) -#define VDPU_REG_PRED_FLT_PRED_BC_TAP_3_2(x) (((x) & 0x3ff) << 2) -#define VDPU_REG_PRED_FLT5 0x274 -#define VDPU_REG_PRED_FLT_PRED_BC_TAP_3_3(x) (((x) & 0x3ff) << 22) -#define VDPU_REG_PRED_FLT_PRED_BC_TAP_4_0(x) (((x) & 0x3ff) << 12) -#define VDPU_REG_PRED_FLT_PRED_BC_TAP_4_1(x) (((x) & 0x3ff) << 2) -#define VDPU_REG_PRED_FLT6 0x278 -#define VDPU_REG_PRED_FLT_PRED_BC_TAP_4_2(x) (((x) & 0x3ff) << 22) -#define VDPU_REG_PRED_FLT_PRED_BC_TAP_4_3(x) (((x) & 0x3ff) << 12) -#define VDPU_REG_PRED_FLT_PRED_BC_TAP_5_0(x) (((x) & 0x3ff) << 2) - -#define VEPU_H264E_NUM_REGS 184 -#define H264E_CABAC_TABLE_BUF_SIZE (52*2*464) - -typedef struct h264e_hal_vpu_dump_files_t { - FILE *fp_mpp_syntax_in; - FILE *fp_mpp_reg_in; - FILE *fp_mpp_reg_out; - FILE *fp_mpp_strm_out; - FILE *fp_mpp_feedback; -} h264e_hal_vpu_dump_files; - -/* transplant from vpu_api.h:EncInputPictureType */ -typedef enum { - H264E_VPU_CSP_YUV420P = 0, // YYYY... UUUU... VVVV - H264E_VPU_CSP_YUV420SP = 1, // YYYY... UVUVUV... - H264E_VPU_CSP_YUYV422 = 2, // YUYVYUYV... - H264E_VPU_CSP_UYVY422 = 3, // UYVYUYVY... - H264E_VPU_CSP_RGB565 = 4, // 16-bit RGB - H264E_VPU_CSP_BGR565 = 5, // 16-bit RGB - H264E_VPU_CSP_RGB555 = 6, // 15-bit RGB - H264E_VPU_CSP_BGR555 = 7, // 15-bit RGB - H264E_VPU_CSP_RGB444 = 8, // 12-bit RGB - H264E_VPU_CSP_BGR444 = 9, // 12-bit RGB - H264E_VPU_CSP_RGB888 = 10, // 24-bit RGB - H264E_VPU_CSP_BGR888 = 11, // 24-bit RGB - H264E_VPU_CSP_RGB101010 = 12, // 30-bit RGB - H264E_VPU_CSP_BGR101010 = 13, // 30-bit RGB - H264E_VPU_CSP_NONE, - H264E_VPU_CSP_BUTT, -} h264e_hal_vpu_csp; - -typedef struct h264e_hal_vpu_csp_info_t { - RK_U32 fmt; - RK_U32 r_mask_msb; - RK_U32 g_mask_msb; - RK_U32 b_mask_msb; -} h264e_hal_vpu_csp_info; - -/* struct for assemble bitstream */ -typedef struct h264e_hal_vpu_stream_t { - RK_U8 *buffer; /* point to first byte of stream */ - RK_U8 *stream; /* Pointer to next byte of stream */ - RK_U32 size; /* Byte size of stream buffer */ - RK_U32 byte_cnt; /* Byte counter */ - RK_U32 bit_cnt; /* Bit counter */ - RK_U32 byte_buffer; /* Byte buffer */ - RK_U32 buffered_bits; /* Amount of bits in byte buffer, [0-7] */ - RK_U32 zero_bytes; /* Amount of consecutive zero bytes */ - RK_S32 overflow; /* This will signal a buffer overflow */ - RK_U32 emul_cnt; /* Counter for emulation_3_byte, needed in SEI */ -} h264e_hal_vpu_stream; - -typedef struct h264e_hal_vpu_extra_info_t { - h264e_hal_vpu_stream sps_stream; - h264e_hal_vpu_stream pps_stream; - h264e_hal_sps sps; - h264e_hal_pps pps; -} h264e_hal_vpu_extra_info; - -typedef enum h264e_hal_vpu_buf_grp_t { - H264E_HAL_VPU_BUF_GRP_REC, - H264E_HAL_VPU_BUF_GRP_CABAC_TBL, - H264E_HAL_VPU_BUF_GRP_NALSIZE_TBL, - H264E_HAL_VPU_BUF_GRP_BUTT, -} h264e_hal_vpu_buf_grp; - -typedef struct h264e_hal_vpu_buffers_t { - MppBufferGroup hw_buf_grp; - - MppBuffer hw_rec_buf[2]; - MppBuffer hw_cabac_table_buf; - MppBuffer hw_nal_size_table_buf; -} h264e_hal_vpu_buffers; - -typedef struct h264e_vpu_reg_set_t { - RK_U32 val[VEPU_H264E_NUM_REGS]; -} h264e_vpu_reg_set; - -MPP_RET hal_h264e_vpu_init (void *hal, MppHalCfg *cfg); -MPP_RET hal_h264e_vpu_deinit (void *hal); -MPP_RET hal_h264e_vpu_gen_regs(void *hal, HalTaskInfo *task); -MPP_RET hal_h264e_vpu_start (void *hal, HalTaskInfo *task); -MPP_RET hal_h264e_vpu_wait (void *hal, HalTaskInfo *task); -MPP_RET hal_h264e_vpu_reset (void *hal); -MPP_RET hal_h264e_vpu_flush (void *hal); -MPP_RET hal_h264e_vpu_control (void *hal, RK_S32 cmd_type, void *param); - -#endif +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __HAL_H264E_ON2_H__ +#define __HAL_H264E_ON2_H__ + +#include "mpp_hal.h" +#include "hal_task.h" + +#define BIT(n) (1<<(n)) + +/* RK3228 Encoder registers. */ +#define VEPU_REG_VP8_QUT_1ST(i) (0x000 + ((i) * 0x24)) +#define VEPU_REG_VP8_QUT_DC_Y2(x) (((x) & 0x3fff) << 16) +#define VEPU_REG_VP8_QUT_DC_Y1(x) (((x) & 0x3fff) << 0) +#define VEPU_REG_VP8_QUT_2ND(i) (0x004 + ((i) * 0x24)) +#define VEPU_REG_VP8_QUT_AC_Y1(x) (((x) & 0x3fff) << 16) +#define VEPU_REG_VP8_QUT_DC_CHR(x) (((x) & 0x3fff) << 0) +#define VEPU_REG_VP8_QUT_3RD(i) (0x008 + ((i) * 0x24)) +#define VEPU_REG_VP8_QUT_AC_CHR(x) (((x) & 0x3fff) << 16) +#define VEPU_REG_VP8_QUT_AC_Y2(x) (((x) & 0x3fff) << 0) +#define VEPU_REG_VP8_QUT_4TH(i) (0x00c + ((i) * 0x24)) +#define VEPU_REG_VP8_QUT_ZB_DC_CHR(x) (((x) & 0x1ff) << 18) +#define VEPU_REG_VP8_QUT_ZB_DC_Y2(x) (((x) & 0x1ff) << 9) +#define VEPU_REG_VP8_QUT_ZB_DC_Y1(x) (((x) & 0x1ff) << 0) +#define VEPU_REG_VP8_QUT_5TH(i) (0x010 + ((i) * 0x24)) +#define VEPU_REG_VP8_QUT_ZB_AC_CHR(x) (((x) & 0x1ff) << 18) +#define VEPU_REG_VP8_QUT_ZB_AC_Y2(x) (((x) & 0x1ff) << 9) +#define VEPU_REG_VP8_QUT_ZB_AC_Y1(x) (((x) & 0x1ff) << 0) +#define VEPU_REG_VP8_QUT_6TH(i) (0x014 + ((i) * 0x24)) +#define VEPU_REG_VP8_QUT_RND_DC_CHR(x) (((x) & 0xff) << 16) +#define VEPU_REG_VP8_QUT_RND_DC_Y2(x) (((x) & 0xff) << 8) +#define VEPU_REG_VP8_QUT_RND_DC_Y1(x) (((x) & 0xff) << 0) +#define VEPU_REG_VP8_QUT_7TH(i) (0x018 + ((i) * 0x24)) +#define VEPU_REG_VP8_QUT_RND_AC_CHR(x) (((x) & 0xff) << 16) +#define VEPU_REG_VP8_QUT_RND_AC_Y2(x) (((x) & 0xff) << 8) +#define VEPU_REG_VP8_QUT_RND_AC_Y1(x) (((x) & 0xff) << 0) +#define VEPU_REG_VP8_QUT_8TH(i) (0x01c + ((i) * 0x24)) +#define VEPU_REG_VP8_SEG_FILTER_LEVEL(x) (((x) & 0x3f) << 25) +#define VEPU_REG_VP8_DEQUT_DC_CHR(x) (((x) & 0xff) << 17) +#define VEPU_REG_VP8_DEQUT_DC_Y2(x) (((x) & 0x1ff) << 8) +#define VEPU_REG_VP8_DEQUT_DC_Y1(x) (((x) & 0xff) << 0) +#define VEPU_REG_VP8_QUT_9TH(i) (0x020 + ((i) * 0x24)) +#define VEPU_REG_VP8_DEQUT_AC_CHR(x) (((x) & 0x1ff) << 18) +#define VEPU_REG_VP8_DEQUT_AC_Y2(x) (((x) & 0x1ff) << 9) +#define VEPU_REG_VP8_DEQUT_AC_Y1(x) (((x) & 0x1ff) << 0) +#define VEPU_REG_ADDR_VP8_SEG_MAP 0x06c +#define VEPU_REG_VP8_INTRA_4X4_PENALTY(i) (0x070 + ((i) * 0x4)) +#define VEPU_REG_VP8_INTRA_4X4_PENALTY_0(x) (((x) & 0xfff) << 0) +#define VEPU_REG_VP8_INTRA_4x4_PENALTY_1(x) (((x) & 0xfff) << 16) +#define VEPU_REG_VP8_INTRA_16X16_PENALTY(i) (0x084 + ((i) * 0x4)) +#define VEPU_REG_VP8_INTRA_16X16_PENALTY_0(x) (((x) & 0xfff) << 0) +#define VEPU_REG_VP8_INTRA_16X16_PENALTY_1(x) (((x) & 0xfff) << 16) +#define VEPU_REG_VP8_CONTROL 0x0a0 +#define VEPU_REG_VP8_LF_MODE_DELTA_BPRED(x) (((x) & 0x1f) << 24) +#define VEPU_REG_VP8_LF_REF_DELTA_INTRA_MB(x) (((x) & 0x7f) << 16) +#define VEPU_REG_VP8_INTER_TYPE_BIT_COST(x) (((x) & 0xfff) << 0) +#define VEPU_REG_VP8_REF_FRAME_VAL 0x0a4 +#define VEPU_REG_VP8_COEF_DMV_PENALTY(x) (((x) & 0xfff) << 16) +#define VEPU_REG_VP8_REF_FRAME(x) (((x) & 0xfff) << 0) +#define VEPU_REG_VP8_LOOP_FILTER_REF_DELTA 0x0a8 +#define VEPU_REG_VP8_LF_REF_DELTA_ALT_REF(x) (((x) & 0x7f) << 16) +#define VEPU_REG_VP8_LF_REF_DELTA_LAST_REF(x) (((x) & 0x7f) << 8) +#define VEPU_REG_VP8_LF_REF_DELTA_GOLDEN(x) (((x) & 0x7f) << 0) +#define VEPU_REG_VP8_LOOP_FILTER_MODE_DELTA 0x0ac +#define VEPU_REG_VP8_LF_MODE_DELTA_SPLITMV(x) (((x) & 0x7f) << 16) +#define VEPU_REG_VP8_LF_MODE_DELTA_ZEROMV(x) (((x) & 0x7f) << 8) +#define VEPU_REG_VP8_LF_MODE_DELTA_NEWMV(x) (((x) & 0x7f) << 0) +#define VEPU_REG_INTRA_SLICE_BITMAP(i) (0x0b0 + ((i) * 0x4)) +#define VEPU_REG_ADDR_VP8_DCT_PART(i) (0x0b0 + ((i) * 0x4)) +#define VEPU_REG_INTRA_AREA_CTRL 0x0b8 +#define VEPU_REG_INTRA_AREA_TOP(x) (((x) & 0xff) << 24) +#define VEPU_REG_INTRA_AREA_BOTTOM(x) (((x) & 0xff) << 16) +#define VEPU_REG_INTRA_AREA_LEFT(x) (((x) & 0xff) << 8) +#define VEPU_REG_INTRA_AREA_RIGHT(x) (((x) & 0xff) << 0) +#define VEPU_REG_CIR_INTRA_CTRL 0x0bc +#define VEPU_REG_CIR_INTRA_FIRST_MB(x) (((x) & 0xffff) << 16) +#define VEPU_REG_CIR_INTRA_INTERVAL(x) (((x) & 0xffff) << 0) +#define VEPU_REG_ADDR_IN_LUMA 0x0c0 +#define VEPU_REG_ADDR_IN_CB 0x0c4 +#define VEPU_REG_ADDR_IN_CR 0x0c8 +#define VEPU_REG_STR_HDR_REM_MSB 0x0cc +#define VEPU_REG_STR_HDR_REM_LSB 0x0d0 +#define VEPU_REG_STR_BUF_LIMIT 0x0d4 +#define VEPU_REG_AXI_CTRL 0x0d8 +#define VEPU_REG_AXI_CTRL_READ_ID(x) (((x) & 0xff) << 24) +#define VEPU_REG_AXI_CTRL_WRITE_ID(x) (((x) & 0xff) << 16) +#define VEPU_REG_AXI_CTRL_BURST_LEN(x) (((x) & 0x3f) << 8) +#define VEPU_REG_AXI_CTRL_INCREMENT_MODE(x) (((x) & 0x01) << 2) +#define VEPU_REG_AXI_CTRL_BIRST_DISCARD(x) (((x) & 0x01) << 1) +#define VEPU_REG_AXI_CTRL_BIRST_DISABLE BIT(0) +#define VEPU_QP_ADJUST_MAD_DELTA_ROI 0x0dc +#define VEPU_REG_ROI_QP_DELTA_1 (((x) & 0xf) << 12) +#define VEPU_REG_ROI_QP_DELTA_2 (((x) & 0xf) << 8) +#define VEPU_REG_MAD_QP_ADJUSTMENT (((x) & 0xf) << 0) +#define VEPU_REG_ADDR_REF_LUMA 0x0e0 +#define VEPU_REG_ADDR_REF_CHROMA 0x0e4 +#define VEPU_REG_QP_SUM_DIV2 0x0e8 +#define VEPU_REG_QP_SUM(x) (((x) & 0x001fffff) * 2) +#define VEPU_REG_ENC_CTRL0 0x0ec +#define VEPU_REG_DISABLE_QUARTER_PIXEL_MV BIT(28) +#define VEPU_REG_DEBLOCKING_FILTER_MODE(x) (((x) & 0x3) << 24) +#define VEPU_REG_CABAC_INIT_IDC(x) (((x) & 0x3) << 21) +#define VEPU_REG_ENTROPY_CODING_MODE BIT(20) +#define VEPU_REG_H264_TRANS8X8_MODE BIT(17) +#define VEPU_REG_H264_INTER4X4_MODE BIT(16) +#define VEPU_REG_H264_STREAM_MODE BIT(15) +#define VEPU_REG_H264_SLICE_SIZE(x) (((x) & 0x7f) << 8) +#define VEPU_REG_ENC_OVER_FILL_STRM_OFFSET 0x0f0 +#define VEPU_REG_STREAM_START_OFFSET(x) (((x) & 0x3f) << 16) +#define VEPU_REG_SKIP_MACROBLOCK_PENALTY(x) (((x) & 0xff) << 8) +#define VEPU_REG_IN_IMG_CTRL_OVRFLR_D4(x) (((x) & 0x3) << 4) +#define VEPU_REG_IN_IMG_CTRL_OVRFLB(x) (((x) & 0xf) << 0) +#define VEPU_REG_INPUT_LUMA_INFO 0x0f4 +#define VEPU_REG_IN_IMG_CHROMA_OFFSET(x) (((x) & 0x7) << 20) +#define VEPU_REG_IN_IMG_LUMA_OFFSET(x) (((x) & 0x7) << 16) +#define VEPU_REG_IN_IMG_CTRL_ROW_LEN(x) (((x) & 0x3fff) << 0) +#define VEPU_REG_RLC_SUM 0x0f8 +#define VEPU_REG_RLC_SUM_OUT(x) (((x) & 0x007fffff) * 4) +#define VEPU_REG_SPLIT_PENALTY_4X4 0x0f8 +#define VEPU_REG_VP8_SPLIT_PENALTY_4X4 (((x) & 0x1ff) << 19) +#define VEPU_REG_ADDR_REC_LUMA 0x0fc +#define VEPU_REG_ADDR_REC_CHROMA 0x100 +#define VEPU_REG_CHECKPOINT(i) (0x104 + ((i) * 0x4)) +#define VEPU_REG_CHECKPOINT_CHECK0(x) (((x) & 0xffff)) +#define VEPU_REG_CHECKPOINT_CHECK1(x) (((x) & 0xffff) << 16) +#define VEPU_REG_CHECKPOINT_RESULT(x) ((((x) >> (16 - 16 \ + * (i & 1))) & 0xffff) \ + * 32) +#define VEPU_REG_VP8_SEG0_QUANT_AC_Y1 0x104 +#define VEPU_REG_VP8_SEG0_RND_AC_Y1(x) (((x) & 0xff) << 23) +#define VEPU_REG_VP8_SEG0_ZBIN_AC_Y1(x) (((x) & 0x1ff) << 14) +#define VEPU_REG_VP8_SEG0_QUT_AC_Y1(x) (((x) & 0x3fff) << 0) +#define VEPU_REG_VP8_SEG0_QUANT_DC_Y2 0x108 +#define VEPU_REG_VP8_SEG0_RND_DC_Y2(x) (((x) & 0xff) << 23) +#define VEPU_REG_VP8_SEG0_ZBIN_DC_Y2(x) (((x) & 0x1ff) << 14) +#define VEPU_REG_VP8_SEG0_QUT_DC_Y2(x) (((x) & 0x3fff) << 0) +#define VEPU_REG_VP8_SEG0_QUANT_AC_Y2 0x10c +#define VEPU_REG_VP8_SEG0_RND_AC_Y2(x) (((x) & 0xff) << 23) +#define VEPU_REG_VP8_SEG0_ZBIN_AC_Y2(x) (((x) & 0x1ff) << 14) +#define VEPU_REG_VP8_SEG0_QUT_AC_Y2(x) (((x) & 0x3fff) << 0) +#define VEPU_REG_VP8_SEG0_QUANT_DC_CHR 0x110 +#define VEPU_REG_VP8_SEG0_RND_DC_CHR(x) (((x) & 0xff) << 23) +#define VEPU_REG_VP8_SEG0_ZBIN_DC_CHR(x) (((x) & 0x1ff) << 14) +#define VEPU_REG_VP8_SEG0_QUT_DC_CHR(x) (((x) & 0x3fff) << 0) +#define VEPU_REG_VP8_SEG0_QUANT_AC_CHR 0x114 +#define VEPU_REG_VP8_SEG0_RND_AC_CHR(x) (((x) & 0xff) << 23) +#define VEPU_REG_VP8_SEG0_ZBIN_AC_CHR(x) (((x) & 0x1ff) << 14) +#define VEPU_REG_VP8_SEG0_QUT_AC_CHR(x) (((x) & 0x3fff) << 0) +#define VEPU_REG_VP8_SEG0_QUANT_DQUT 0x118 +#define VEPU_REG_VP8_MV_REF_IDX1(x) (((x) & 0x03) << 26) +#define VEPU_REG_VP8_SEG0_DQUT_DC_Y2(x) (((x) & 0x1ff) << 17) +#define VEPU_REG_VP8_SEG0_DQUT_AC_Y1(x) (((x) & 0x1ff) << 8) +#define VEPU_REG_VP8_SEG0_DQUT_DC_Y1(x) (((x) & 0xff) << 0) +#define VEPU_REG_CHKPT_WORD_ERR(i) (0x118 + ((i) * 0x4)) +#define VEPU_REG_CHKPT_WORD_ERR_CHK0(x) (((x) & 0xffff)) +#define VEPU_REG_CHKPT_WORD_ERR_CHK1(x) (((x) & 0xffff) << 16) +#define VEPU_REG_VP8_SEG0_QUANT_DQUT_1 0x11c +#define VEPU_REG_VP8_SEGMENT_MAP_UPDATE BIT(30) +#define VEPU_REG_VP8_SEGMENT_EN BIT(29) +#define VEPU_REG_VP8_MV_REF_IDX2_EN BIT(28) +#define VEPU_REG_VP8_MV_REF_IDX2(x) (((x) & 0x03) << 26) +#define VEPU_REG_VP8_SEG0_DQUT_AC_CHR(x) (((x) & 0x1ff) << 17) +#define VEPU_REG_VP8_SEG0_DQUT_DC_CHR(x) (((x) & 0xff) << 9) +#define VEPU_REG_VP8_SEG0_DQUT_AC_Y2(x) (((x) & 0x1ff) << 0) +#define VEPU_REG_VP8_BOOL_ENC_VALUE 0x120 +#define VEPU_REG_CHKPT_DELTA_QP 0x124 +#define VEPU_REG_CHKPT_DELTA_QP_CHK0(x) (((x) & 0x0f) << 0) +#define VEPU_REG_CHKPT_DELTA_QP_CHK1(x) (((x) & 0x0f) << 4) +#define VEPU_REG_CHKPT_DELTA_QP_CHK2(x) (((x) & 0x0f) << 8) +#define VEPU_REG_CHKPT_DELTA_QP_CHK3(x) (((x) & 0x0f) << 12) +#define VEPU_REG_CHKPT_DELTA_QP_CHK4(x) (((x) & 0x0f) << 16) +#define VEPU_REG_CHKPT_DELTA_QP_CHK5(x) (((x) & 0x0f) << 20) +#define VEPU_REG_CHKPT_DELTA_QP_CHK6(x) (((x) & 0x0f) << 24) +#define VEPU_REG_VP8_ENC_CTRL2 0x124 +#define VEPU_REG_VP8_ZERO_MV_PENALTY_FOR_REF2(x) (((x) & 0xff) << 24) +#define VEPU_REG_VP8_FILTER_SHARPNESS(x) (((x) & 0x07) << 21) +#define VEPU_REG_VP8_FILTER_LEVEL(x) (((x) & 0x3f) << 15) +#define VEPU_REG_VP8_DCT_PARTITION_CNT(x) (((x) & 0x03) << 13) +#define VEPU_REG_VP8_BOOL_ENC_VALUE_BITS(x) (((x) & 0x1f) << 8) +#define VEPU_REG_VP8_BOOL_ENC_RANGE(x) (((x) & 0xff) << 0) +#define VEPU_REG_ENC_CTRL1 0x128 +#define VEPU_REG_MAD_THRESHOLD(x) (((x) & 0x3f) << 24) +#define VEPU_REG_COMPLETED_SLICES(x) (((x) & 0xff) << 16) +#define VEPU_REG_IN_IMG_CTRL_FMT(x) (((x) & 0xf) << 4) +#define VEPU_REG_IN_IMG_ROTATE_MODE(x) (((x) & 0x3) << 2) +#define VEPU_REG_SIZE_TABLE_PRESENT BIT(0) +#define VEPU_REG_INTRA_INTER_MODE 0x12c +#define VEPU_REG_INTRA16X16_MODE(x) (((x) & 0xffff) << 16) +#define VEPU_REG_INTER_MODE(x) (((x) & 0xffff) << 0) +#define VEPU_REG_ENC_CTRL2 0x130 +#define VEPU_REG_PPS_INIT_QP(x) (((x) & 0x3f) << 26) +#define VEPU_REG_SLICE_FILTER_ALPHA(x) (((x) & 0xf) << 22) +#define VEPU_REG_SLICE_FILTER_BETA(x) (((x) & 0xf) << 18) +#define VEPU_REG_CHROMA_QP_OFFSET(x) (((x) & 0x1f) << 13) +#define VEPU_REG_FILTER_DISABLE BIT(5) +#define VEPU_REG_IDR_PIC_ID(x) (((x) & 0xf) << 1) +#define VEPU_REG_CONSTRAINED_INTRA_PREDICTION BIT(0) +#define VEPU_REG_ADDR_OUTPUT_STREAM 0x134 +#define VEPU_REG_ADDR_OUTPUT_CTRL 0x138 +#define VEPU_REG_ADDR_NEXT_PIC 0x13c +#define VEPU_REG_ADDR_MV_OUT 0x140 +#define VEPU_REG_ADDR_CABAC_TBL 0x144 +#define VEPU_REG_ROI1 0x148 +#define VEPU_REG_ROI1_TOP_MB(x) (((x) & 0xff) << 24) +#define VEPU_REG_ROI1_BOTTOM_MB(x) (((x) & 0xff) << 16) +#define VEPU_REG_ROI1_LEFT_MB(x) (((x) & 0xff) << 8) +#define VEPU_REG_ROI1_RIGHT_MB(x) (((x) & 0xff) << 0) +#define VEPU_REG_ROI2 0x14c +#define VEPU_REG_ROI2_TOP_MB(x) (((x) & 0xff) << 24) +#define VEPU_REG_ROI2_BOTTOM_MB(x) (((x) & 0xff) << 16) +#define VEPU_REG_ROI2_LEFT_MB(x) (((x) & 0xff) << 8) +#define VEPU_REG_ROI2_RIGHT_MB(x) (((x) & 0xff) << 0) +#define VEPU_REG_STABLE_MATRIX(i) (0x150 + ((i) * 0x4)) +#define VEPU_REG_STABLE_MOTION_SUM 0x174 +#define VEPU_REG_STABLILIZATION_OUTPUT 0x178 +#define VEPU_REG_STABLE_MIN_VALUE(x) (((x) & 0xffffff) << 8) +#define VEPU_REG_STABLE_MODE_SEL(x) (((x) & 0x3) << 6) +#define VEPU_REG_STABLE_HOR_GMV(x) (((x) & 0x3f) << 0) +#define VEPU_REG_RGB2YUV_CONVERSION_COEF1 0x17c +#define VEPU_REG_RGB2YUV_CONVERSION_COEFB(x) (((x) & 0xffff) << 16) +#define VEPU_REG_RGB2YUV_CONVERSION_COEFA(x) (((x) & 0xffff) << 0) +#define VEPU_REG_RGB2YUV_CONVERSION_COEF2 0x180 +#define VEPU_REG_RGB2YUV_CONVERSION_COEFE(x) (((x) & 0xffff) << 16) +#define VEPU_REG_RGB2YUV_CONVERSION_COEFC(x) (((x) & 0xffff) << 0) +#define VEPU_REG_RGB2YUV_CONVERSION_COEF3 0x184 +#define VEPU_REG_RGB2YUV_CONVERSION_COEFF(x) (((x) & 0xffff) << 0) +#define VEPU_REG_RGB_MASK_MSB 0x188 +#define VEPU_REG_RGB_MASK_B_MSB(x) (((x) & 0x1f) << 16) +#define VEPU_REG_RGB_MASK_G_MSB(x) (((x) & 0x1f) << 8) +#define VEPU_REG_RGB_MASK_R_MSB(x) (((x) & 0x1f) << 0) +#define VEPU_REG_MV_PENALTY 0x18c +#define VEPU_REG_1MV_PENALTY(x) (((x) & 0x3ff) << 21) +#define VEPU_REG_QMV_PENALTY(x) (((x) & 0x3ff) << 11) +#define VEPU_REG_4MV_PENALTY(x) (((x) & 0x3ff) << 1) +#define VEPU_REG_SPLIT_MV_MODE_EN BIT(0) +#define VEPU_REG_QP_VAL 0x190 +#define VEPU_REG_H264_LUMA_INIT_QP(x) (((x) & 0x3f) << 26) +#define VEPU_REG_H264_QP_MAX(x) (((x) & 0x3f) << 20) +#define VEPU_REG_H264_QP_MIN(x) (((x) & 0x3f) << 14) +#define VEPU_REG_H264_CHKPT_DISTANCE(x) (((x) & 0xfff) << 0) +#define VEPU_REG_VP8_SEG0_QUANT_DC_Y1 0x190 +#define VEPU_REG_VP8_SEG0_RND_DC_Y1(x) (((x) & 0xff) << 23) +#define VEPU_REG_VP8_SEG0_ZBIN_DC_Y1(x) (((x) & 0x1ff) << 14) +#define VEPU_REG_VP8_SEG0_QUT_DC_Y1(x) (((x) & 0x3fff) << 0) +#define VEPU_REG_MVC_RELATE 0x198 +#define VEPU_REG_ZERO_MV_FAVOR_D2(x) (((x) & 0xf) << 20) +#define VEPU_REG_PENALTY_4X4MV(x) (((x) & 0x1ff) << 11) +#define VEPU_REG_MVC_VIEW_ID(x) (((x) & 0x7) << 8) +#define VEPU_REG_MVC_ANCHOR_PIC_FLAG BIT(7) +#define VEPU_REG_MVC_PRIORITY_ID(x) (((x) & 0x7) << 4) +#define VEPU_REG_MVC_TEMPORAL_ID(x) (((x) & 0x7) << 1) +#define VEPU_REG_MVC_INTER_VIEW_FLAG BIT(0) +#define VEPU_REG_ENCODE_START 0x19c +#define VEPU_REG_MB_HEIGHT(x) (((x) & 0x1ff) << 20) +#define VEPU_REG_MB_WIDTH(x) (((x) & 0x1ff) << 8) +#define VEPU_REG_PIC_TYPE(x) (((x) & 0x3) << 6) +#define VEPU_REG_ENCODE_FORMAT(x) (((x) & 0x3) << 4) +#define VEPU_REG_ENCODE_ENABLE BIT(0) +#define VEPU_REG_MB_CTRL 0x1a0 +#define VEPU_REG_MB_CNT_OUT(x) (((x) & 0xffff) << 16) +#define VEPU_REG_MB_CNT_SET(x) (((x) & 0xffff) << 0) +#define VEPU_REG_DATA_ENDIAN 0x1a4 +#define VEPU_REG_INPUT_SWAP8 BIT(31) +#define VEPU_REG_INPUT_SWAP16 BIT(30) +#define VEPU_REG_INPUT_SWAP32 BIT(29) +#define VEPU_REG_OUTPUT_SWAP8 BIT(28) +#define VEPU_REG_OUTPUT_SWAP16 BIT(27) +#define VEPU_REG_OUTPUT_SWAP32 BIT(26) +#define VEPU_REG_TEST_IRQ BIT(24) +#define VEPU_REG_TEST_COUNTER(x) (((x) & 0xf) << 20) +#define VEPU_REG_TEST_REG BIT(19) +#define VEPU_REG_TEST_MEMORY BIT(18) +#define VEPU_REG_TEST_LEN(x) (((x) & 0x3ffff) << 0) +#define VEPU_REG_ENC_CTRL3 0x1a8 +#define VEPU_REG_PPS_ID(x) (((x) & 0xff) << 24) +#define VEPU_REG_INTRA_PRED_MODE(x) (((x) & 0xff) << 16) +#define VEPU_REG_FRAME_NUM(x) (((x) & 0xffff) << 0) +#define VEPU_REG_ENC_CTRL4 0x1ac +#define VEPU_REG_MV_PENALTY_16X8_8X16(x) (((x) & 0x3ff) << 20) +#define VEPU_REG_MV_PENALTY_8X8(x) (((x) & 0x3ff) << 10) +#define VEPU_REG_MV_PENALTY_8X4_4X8(x) (((x) & 0x3ff) << 0) +#define VEPU_REG_ADDR_VP8_PROB_CNT 0x1b0 +#define VEPU_REG_INTERRUPT 0x1b4 +#define VEPU_REG_INTERRUPT_NON BIT(28) +#define VEPU_REG_MV_WRITE_EN BIT(24) +#define VEPU_REG_RECON_WRITE_DIS BIT(20) +#define VEPU_REG_INTERRUPT_SLICE_READY_EN BIT(16) +#define VEPU_REG_CLK_GATING_EN BIT(12) +#define VEPU_REG_INTERRUPT_TIMEOUT_EN BIT(10) +#define VEPU_REG_INTERRUPT_RESET BIT(9) +#define VEPU_REG_INTERRUPT_DIS_BIT BIT(8) +#define VEPU_REG_INTERRUPT_TIMEOUT BIT(6) +#define VEPU_REG_INTERRUPT_BUFFER_FULL BIT(5) +#define VEPU_REG_INTERRUPT_BUS_ERROR BIT(4) +#define VEPU_REG_INTERRUPT_FUSE BIT(3) +#define VEPU_REG_INTERRUPT_SLICE_READY BIT(2) +#define VEPU_REG_INTERRUPT_FRAME_READY BIT(1) +#define VEPU_REG_INTERRUPT_BIT BIT(0) +#define VEPU_REG_DMV_PENALTY_TBL(i) (0x1E0 + ((i) * 0x4)) +#define VEPU_REG_DMV_PENALTY_TABLE_BIT(x, i) (x << i * 8) +#define VEPU_REG_DMV_Q_PIXEL_PENALTY_TBL(i) (0x260 + ((i) * 0x4)) +#define VEPU_REG_DMV_Q_PIXEL_PENALTY_TABLE_BIT(x, i) (x << i * 8) + +/* vpu decoder register */ +#define VDPU_REG_DEC_CTRL0 0x0c8 +#define VDPU_REG_REF_BUF_CTRL2_REFBU2_PICID(x) (((x) & 0x1f) << 25) +#define VDPU_REG_REF_BUF_CTRL2_REFBU2_THR(x) (((x) & 0xfff) << 13) +#define VDPU_REG_CONFIG_TILED_MODE_LSB BIT(12) +#define VDPU_REG_CONFIG_DEC_ADV_PRE_DIS BIT(11) +#define VDPU_REG_CONFIG_DEC_SCMD_DIS BIT(10) +#define VDPU_REG_DEC_CTRL0_SKIP_MODE BIT(9) +#define VDPU_REG_DEC_CTRL0_FILTERING_DIS BIT(8) +#define VDPU_REG_DEC_CTRL0_PIC_FIXED_QUANT BIT(7) +#define VDPU_REG_CONFIG_DEC_LATENCY(x) (((x) & 0x3f) << 1) +#define VDPU_REG_CONFIG_TILED_MODE_MSB(x) BIT(0) +#define VDPU_REG_CONFIG_DEC_OUT_TILED_E BIT(0) +#define VDPU_REG_STREAM_LEN 0x0cc +#define VDPU_REG_DEC_CTRL3_INIT_QP(x) (((x) & 0x3f) << 25) +#define VDPU_REG_DEC_STREAM_LEN_HI BIT(24) +#define VDPU_REG_DEC_CTRL3_STREAM_LEN(x) (((x) & 0xffffff) << 0) +#define VDPU_REG_ERROR_CONCEALMENT 0x0d0 +#define VDPU_REG_REF_BUF_CTRL2_APF_THRESHOLD(x) (((x) & 0x3fff) << 17) +#define VDPU_REG_ERR_CONC_STARTMB_X(x) (((x) & 0x1ff) << 8) +#define VDPU_REG_ERR_CONC_STARTMB_Y(x) (((x) & 0xff) << 0) +#define VDPU_REG_DEC_FORMAT 0x0d4 +#define VDPU_REG_DEC_CTRL0_DEC_MODE(x) (((x) & 0xf) << 0) +#define VDPU_REG_DATA_ENDIAN 0x0d8 +#define VDPU_REG_CONFIG_DEC_STRENDIAN_E BIT(5) +#define VDPU_REG_CONFIG_DEC_STRSWAP32_E BIT(4) +#define VDPU_REG_CONFIG_DEC_OUTSWAP32_E BIT(3) +#define VDPU_REG_CONFIG_DEC_INSWAP32_E BIT(2) +#define VDPU_REG_CONFIG_DEC_OUT_ENDIAN BIT(1) +#define VDPU_REG_CONFIG_DEC_IN_ENDIAN BIT(0) +#define VDPU_REG_INTERRUPT 0x0dc +#define VDPU_REG_INTERRUPT_DEC_TIMEOUT BIT(13) +#define VDPU_REG_INTERRUPT_DEC_ERROR_INT BIT(12) +#define VDPU_REG_INTERRUPT_DEC_PIC_INF BIT(10) +#define VDPU_REG_INTERRUPT_DEC_SLICE_INT BIT(9) +#define VDPU_REG_INTERRUPT_DEC_ASO_INT BIT(8) +#define VDPU_REG_INTERRUPT_DEC_BUFFER_INT BIT(6) +#define VDPU_REG_INTERRUPT_DEC_BUS_INT BIT(5) +#define VDPU_REG_INTERRUPT_DEC_RDY_INT BIT(4) +#define VDPU_REG_INTERRUPT_DEC_IRQ_DIS BIT(1) +#define VDPU_REG_INTERRUPT_DEC_IRQ BIT(0) +#define VDPU_REG_AXI_CTRL 0x0e0 +#define VDPU_REG_AXI_DEC_SEL BIT(23) +#define VDPU_REG_CONFIG_DEC_DATA_DISC_E BIT(22) +#define VDPU_REG_PARAL_BUS_E(x) BIT(21) +#define VDPU_REG_CONFIG_DEC_MAX_BURST(x) (((x) & 0x1f) << 16) +#define VDPU_REG_DEC_CTRL0_DEC_AXI_WR_ID(x) (((x) & 0xff) << 8) +#define VDPU_REG_CONFIG_DEC_AXI_RD_ID(x) (((x) & 0xff) << 0) +#define VDPU_REG_EN_FLAGS 0x0e4 +#define VDPU_REG_AHB_HLOCK_E BIT(31) +#define VDPU_REG_CACHE_E BIT(29) +#define VDPU_REG_PREFETCH_SINGLE_CHANNEL_E BIT(28) +#define VDPU_REG_INTRA_3_CYCLE_ENHANCE BIT(27) +#define VDPU_REG_INTRA_DOUBLE_SPEED BIT(26) +#define VDPU_REG_INTER_DOUBLE_SPEED BIT(25) +#define VDPU_REG_DEC_CTRL3_START_CODE_E BIT(22) +#define VDPU_REG_DEC_CTRL3_CH_8PIX_ILEAV_E BIT(21) +#define VDPU_REG_DEC_CTRL0_RLC_MODE_E BIT(20) +#define VDPU_REG_DEC_CTRL0_DIVX3_E BIT(19) +#define VDPU_REG_DEC_CTRL0_PJPEG_E BIT(18) +#define VDPU_REG_DEC_CTRL0_PIC_INTERLACE_E BIT(17) +#define VDPU_REG_DEC_CTRL0_PIC_FIELDMODE_E BIT(16) +#define VDPU_REG_DEC_CTRL0_PIC_B_E BIT(15) +#define VDPU_REG_DEC_CTRL0_PIC_INTER_E BIT(14) +#define VDPU_REG_DEC_CTRL0_PIC_TOPFIELD_E BIT(13) +#define VDPU_REG_DEC_CTRL0_FWD_INTERLACE_E BIT(12) +#define VDPU_REG_DEC_CTRL0_SORENSON_E BIT(11) +#define VDPU_REG_DEC_CTRL0_WRITE_MVS_E BIT(10) +#define VDPU_REG_DEC_CTRL0_REF_TOPFIELD_E BIT(9) +#define VDPU_REG_DEC_CTRL0_REFTOPFIRST_E BIT(8) +#define VDPU_REG_DEC_CTRL0_SEQ_MBAFF_E BIT(7) +#define VDPU_REG_DEC_CTRL0_PICORD_COUNT_E BIT(6) +#define VDPU_REG_CONFIG_DEC_TIMEOUT_E BIT(5) +#define VDPU_REG_CONFIG_DEC_CLK_GATE_E BIT(4) +#define VDPU_REG_DEC_CTRL0_DEC_OUT_DIS BIT(2) +#define VDPU_REG_REF_BUF_CTRL2_REFBU2_BUF_E BIT(1) +#define VDPU_REG_INTERRUPT_DEC_E BIT(0) +#define VDPU_REG_SOFT_RESET 0x0e8 +#define VDPU_REG_PRED_FLT 0x0ec +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_0_0(x) (((x) & 0x3ff) << 22) +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_0_1(x) (((x) & 0x3ff) << 12) +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_0_2(x) (((x) & 0x3ff) << 2) +#define VDPU_REG_ADDITIONAL_CHROMA_ADDRESS 0x0f0 +#define VDPU_REG_ADDR_QTABLE 0x0f4 +#define VDPU_REG_DIRECT_MV_ADDR 0x0f8 +#define VDPU_REG_ADDR_DST 0x0fc +#define VDPU_REG_ADDR_STR 0x100 +#define VDPU_REG_REFBUF_RELATED 0x104 +#define VDPU_REG_FWD_PIC(i) (0x128 + ((i) * 0x4)) +#define VDPU_REG_FWD_PIC_PINIT_RLIST_F5(x) (((x) & 0x1f) << 25) +#define VDPU_REG_FWD_PIC_PINIT_RLIST_F4(x) (((x) & 0x1f) << 20) +#define VDPU_REG_FWD_PIC_PINIT_RLIST_F3(x) (((x) & 0x1f) << 15) +#define VDPU_REG_FWD_PIC_PINIT_RLIST_F2(x) (((x) & 0x1f) << 10) +#define VDPU_REG_FWD_PIC_PINIT_RLIST_F1(x) (((x) & 0x1f) << 5) +#define VDPU_REG_FWD_PIC_PINIT_RLIST_F0(x) (((x) & 0x1f) << 0) +#define VDPU_REG_REF_PIC(i) (0x130 + ((i) * 0x4)) +#define VDPU_REG_REF_PIC_REFER1_NBR(x) (((x) & 0xffff) << 16) +#define VDPU_REG_REF_PIC_REFER0_NBR(x) (((x) & 0xffff) << 0) +#define VDPU_REG_H264_ADDR_REF(i) (0x150 + ((i) * 0x4)) +#define VDPU_REG_ADDR_REF_FIELD_E BIT(1) +#define VDPU_REG_ADDR_REF_TOPC_E BIT(0) +#define VDPU_REG_INITIAL_REF_PIC_LIST0 0x190 +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_F5(x) (((x) & 0x1f) << 25) +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_F4(x) (((x) & 0x1f) << 20) +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_F3(x) (((x) & 0x1f) << 15) +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_F2(x) (((x) & 0x1f) << 10) +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_F1(x) (((x) & 0x1f) << 5) +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_F0(x) (((x) & 0x1f) << 0) +#define VDPU_REG_INITIAL_REF_PIC_LIST1 0x194 +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_F11(x) (((x) & 0x1f) << 25) +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_F10(x) (((x) & 0x1f) << 20) +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_F9(x) (((x) & 0x1f) << 15) +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_F8(x) (((x) & 0x1f) << 10) +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_F7(x) (((x) & 0x1f) << 5) +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_F6(x) (((x) & 0x1f) << 0) +#define VDPU_REG_INITIAL_REF_PIC_LIST2 0x198 +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_F15(x) (((x) & 0x1f) << 15) +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_F14(x) (((x) & 0x1f) << 10) +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_F13(x) (((x) & 0x1f) << 5) +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_F12(x) (((x) & 0x1f) << 0) +#define VDPU_REG_INITIAL_REF_PIC_LIST3 0x19c +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_B5(x) (((x) & 0x1f) << 25) +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_B4(x) (((x) & 0x1f) << 20) +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_B3(x) (((x) & 0x1f) << 15) +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_B2(x) (((x) & 0x1f) << 10) +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_B1(x) (((x) & 0x1f) << 5) +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_B0(x) (((x) & 0x1f) << 0) +#define VDPU_REG_INITIAL_REF_PIC_LIST4 0x1a0 +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_B11(x) (((x) & 0x1f) << 25) +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_B10(x) (((x) & 0x1f) << 20) +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_B9(x) (((x) & 0x1f) << 15) +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_B8(x) (((x) & 0x1f) << 10) +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_B7(x) (((x) & 0x1f) << 5) +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_B6(x) (((x) & 0x1f) << 0) +#define VDPU_REG_INITIAL_REF_PIC_LIST5 0x1a4 +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_B15(x) (((x) & 0x1f) << 15) +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_B14(x) (((x) & 0x1f) << 10) +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_B13(x) (((x) & 0x1f) << 5) +#define VDPU_REG_BD_REF_PIC_BINIT_RLIST_B12(x) (((x) & 0x1f) << 0) +#define VDPU_REG_INITIAL_REF_PIC_LIST6 0x1a8 +#define VDPU_REG_BD_P_REF_PIC_PINIT_RLIST_F3(x) (((x) & 0x1f) << 15) +#define VDPU_REG_BD_P_REF_PIC_PINIT_RLIST_F2(x) (((x) & 0x1f) << 10) +#define VDPU_REG_BD_P_REF_PIC_PINIT_RLIST_F1(x) (((x) & 0x1f) << 5) +#define VDPU_REG_BD_P_REF_PIC_PINIT_RLIST_F0(x) (((x) & 0x1f) << 0) +#define VDPU_REG_LT_REF 0x1ac +#define VDPU_REG_VALID_REF 0x1b0 +#define VDPU_REG_H264_PIC_MB_SIZE 0x1b8 +#define VDPU_REG_DEC_CTRL2_CH_QP_OFFSET2(x) (((x) & 0x1f) << 22) +#define VDPU_REG_DEC_CTRL2_CH_QP_OFFSET(x) (((x) & 0x1f) << 17) +#define VDPU_REG_DEC_CTRL1_PIC_MB_HEIGHT_P(x) (((x) & 0xff) << 9) +#define VDPU_REG_DEC_CTRL1_PIC_MB_WIDTH(x) (((x) & 0x1ff) << 0) +#define VDPU_REG_H264_CTRL 0x1bc +#define VDPU_REG_DEC_CTRL4_WEIGHT_BIPR_IDC(x) (((x) & 0x3) << 16) +#define VDPU_REG_DEC_CTRL1_REF_FRAMES(x) (((x) & 0x1f) << 0) +#define VDPU_REG_CURRENT_FRAME 0x1c0 +#define VDPU_REG_DEC_CTRL5_FILT_CTRL_PRES BIT(31) +#define VDPU_REG_DEC_CTRL5_RDPIC_CNT_PRES BIT(30) +#define VDPU_REG_DEC_CTRL4_FRAMENUM_LEN(x) (((x) & 0x1f) << 16) +#define VDPU_REG_DEC_CTRL4_FRAMENUM(x) (((x) & 0xffff) << 0) +#define VDPU_REG_REF_FRAME 0x1c4 +#define VDPU_REG_DEC_CTRL5_REFPIC_MK_LEN(x) (((x) & 0x7ff) << 16) +#define VDPU_REG_DEC_CTRL5_IDR_PIC_ID(x) (((x) & 0xffff) << 0) +#define VDPU_REG_DEC_CTRL6 0x1c8 +#define VDPU_REG_DEC_CTRL6_PPS_ID(x) (((x) & 0xff) << 24) +#define VDPU_REG_DEC_CTRL6_REFIDX1_ACTIVE(x) (((x) & 0x1f) << 19) +#define VDPU_REG_DEC_CTRL6_REFIDX0_ACTIVE(x) (((x) & 0x1f) << 14) +#define VDPU_REG_DEC_CTRL6_POC_LENGTH(x) (((x) & 0xff) << 0) +#define VDPU_REG_ENABLE_FLAG 0x1cc +#define VDPU_REG_DEC_CTRL5_IDR_PIC_E BIT(8) +#define VDPU_REG_DEC_CTRL4_DIR_8X8_INFER_E BIT(7) +#define VDPU_REG_DEC_CTRL4_BLACKWHITE_E BIT(6) +#define VDPU_REG_DEC_CTRL4_CABAC_E BIT(5) +#define VDPU_REG_DEC_CTRL4_WEIGHT_PRED_E BIT(4) +#define VDPU_REG_DEC_CTRL5_CONST_INTRA_E BIT(3) +#define VDPU_REG_DEC_CTRL5_8X8TRANS_FLAG_E BIT(2) +#define VDPU_REG_DEC_CTRL2_TYPE1_QUANT_E BIT(1) +#define VDPU_REG_DEC_CTRL2_FIELDPIC_FLAG_E BIT(0) +#define VDPU_REG_VP8_PIC_MB_SIZE 0x1e0 +#define VDPU_REG_DEC_PIC_MB_WIDTH(x) (((x) & 0x1ff) << 23) +#define VDPU_REG_DEC_MB_WIDTH_OFF(x) (((x) & 0xf) << 19) +#define VDPU_REG_DEC_PIC_MB_HEIGHT_P(x) (((x) & 0xff) << 11) +#define VDPU_REG_DEC_MB_HEIGHT_OFF(x) (((x) & 0xf) << 7) +#define VDPU_REG_DEC_CTRL1_PIC_MB_W_EXT(x) (((x) & 0x7) << 3) +#define VDPU_REG_DEC_CTRL1_PIC_MB_H_EXT(x) (((x) & 0x7) << 0) +#define VDPU_REG_VP8_DCT_START_BIT 0x1e4 +#define VDPU_REG_DEC_CTRL4_DCT1_START_BIT(x) (((x) & 0x3f) << 26) +#define VDPU_REG_DEC_CTRL4_DCT2_START_BIT(x) (((x) & 0x3f) << 20) +#define VDPU_REG_DEC_CTRL4_VC1_HEIGHT_EXT BIT(13) +#define VDPU_REG_DEC_CTRL4_BILIN_MC_E BIT(12) +#define VDPU_REG_VP8_CTRL0 0x1e8 +#define VDPU_REG_DEC_CTRL2_STRM_START_BIT(x) (((x) & 0x3f) << 26) +#define VDPU_REG_DEC_CTRL2_STRM1_START_BIT(x) (((x) & 0x3f) << 18) +#define VDPU_REG_DEC_CTRL2_BOOLEAN_VALUE(x) (((x) & 0xff) << 8) +#define VDPU_REG_DEC_CTRL2_BOOLEAN_RANGE(x) (((x) & 0xff) << 0) +#define VDPU_REG_VP8_DATA_VAL 0x1f0 +#define VDPU_REG_DEC_CTRL6_COEFFS_PART_AM(x) (((x) & 0xf) << 24) +#define VDPU_REG_DEC_CTRL6_STREAM1_LEN(x) (((x) & 0xffffff) << 0) +#define VDPU_REG_PRED_FLT7 0x1f4 +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_5_1(x) (((x) & 0x3ff) << 22) +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_5_2(x) (((x) & 0x3ff) << 12) +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_5_3(x) (((x) & 0x3ff) << 2) +#define VDPU_REG_PRED_FLT8 0x1f8 +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_6_0(x) (((x) & 0x3ff) << 22) +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_6_1(x) (((x) & 0x3ff) << 12) +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_6_2(x) (((x) & 0x3ff) << 2) +#define VDPU_REG_PRED_FLT9 0x1fc +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_6_3(x) (((x) & 0x3ff) << 22) +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_7_0(x) (((x) & 0x3ff) << 12) +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_7_1(x) (((x) & 0x3ff) << 2) +#define VDPU_REG_PRED_FLT10 0x200 +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_7_2(x) (((x) & 0x3ff) << 22) +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_7_3(x) (((x) & 0x3ff) << 12) +#define VDPU_REG_BD_REF_PIC_PRED_TAP_2_M1(x) (((x) & 0x3) << 10) +#define VDPU_REG_BD_REF_PIC_PRED_TAP_2_4(x) (((x) & 0x3) << 8) +#define VDPU_REG_BD_REF_PIC_PRED_TAP_4_M1(x) (((x) & 0x3) << 6) +#define VDPU_REG_BD_REF_PIC_PRED_TAP_4_4(x) (((x) & 0x3) << 4) +#define VDPU_REG_BD_REF_PIC_PRED_TAP_6_M1(x) (((x) & 0x3) << 2) +#define VDPU_REG_BD_REF_PIC_PRED_TAP_6_4(x) (((x) & 0x3) << 0) +#define VDPU_REG_FILTER_LEVEL 0x204 +#define VDPU_REG_REF_PIC_LF_LEVEL_0(x) (((x) & 0x3f) << 18) +#define VDPU_REG_REF_PIC_LF_LEVEL_1(x) (((x) & 0x3f) << 12) +#define VDPU_REG_REF_PIC_LF_LEVEL_2(x) (((x) & 0x3f) << 6) +#define VDPU_REG_REF_PIC_LF_LEVEL_3(x) (((x) & 0x3f) << 0) +#define VDPU_REG_VP8_QUANTER0 0x208 +#define VDPU_REG_REF_PIC_QUANT_DELTA_0(x) (((x) & 0x1f) << 27) +#define VDPU_REG_REF_PIC_QUANT_DELTA_1(x) (((x) & 0x1f) << 22) +#define VDPU_REG_REF_PIC_QUANT_0(x) (((x) & 0x7ff) << 11) +#define VDPU_REG_REF_PIC_QUANT_1(x) (((x) & 0x7ff) << 0) +#define VDPU_REG_VP8_ADDR_REF0 0x20c +#define VDPU_REG_FILTER_MB_ADJ 0x210 +#define VDPU_REG_REF_PIC_FILT_TYPE_E BIT(31) +#define VDPU_REG_REF_PIC_FILT_SHARPNESS(x) (((x) & 0x7) << 28) +#define VDPU_REG_FILT_MB_ADJ_0(x) (((x) & 0x7f) << 21) +#define VDPU_REG_FILT_MB_ADJ_1(x) (((x) & 0x7f) << 14) +#define VDPU_REG_FILT_MB_ADJ_2(x) (((x) & 0x7f) << 7) +#define VDPU_REG_FILT_MB_ADJ_3(x) (((x) & 0x7f) << 0) +#define VDPU_REG_FILTER_REF_ADJ 0x214 +#define VDPU_REG_REF_PIC_ADJ_0(x) (((x) & 0x7f) << 21) +#define VDPU_REG_REF_PIC_ADJ_1(x) (((x) & 0x7f) << 14) +#define VDPU_REG_REF_PIC_ADJ_2(x) (((x) & 0x7f) << 7) +#define VDPU_REG_REF_PIC_ADJ_3(x) (((x) & 0x7f) << 0) +#define VDPU_REG_VP8_ADDR_REF2_5(i) (0x218 + ((i) * 0x4)) +#define VDPU_REG_VP8_GREF_SIGN_BIAS BIT(0) +#define VDPU_REG_VP8_AREF_SIGN_BIAS BIT(0) +#define VDPU_REG_VP8_DCT_BASE(i) (0x230 + ((i) * 0x4)) +#define VDPU_REG_VP8_ADDR_CTRL_PART 0x244 +#define VDPU_REG_VP8_ADDR_REF1 0x250 +#define VDPU_REG_VP8_SEGMENT_VAL 0x254 +#define VDPU_REG_FWD_PIC1_SEGMENT_BASE(x) ((x) << 0) +#define VDPU_REG_FWD_PIC1_SEGMENT_UPD_E BIT(1) +#define VDPU_REG_FWD_PIC1_SEGMENT_E BIT(0) +#define VDPU_REG_VP8_DCT_START_BIT2 0x258 +#define VDPU_REG_DEC_CTRL7_DCT3_START_BIT(x) (((x) & 0x3f) << 24) +#define VDPU_REG_DEC_CTRL7_DCT4_START_BIT(x) (((x) & 0x3f) << 18) +#define VDPU_REG_DEC_CTRL7_DCT5_START_BIT(x) (((x) & 0x3f) << 12) +#define VDPU_REG_DEC_CTRL7_DCT6_START_BIT(x) (((x) & 0x3f) << 6) +#define VDPU_REG_DEC_CTRL7_DCT7_START_BIT(x) (((x) & 0x3f) << 0) +#define VDPU_REG_VP8_QUANTER1 0x25c +#define VDPU_REG_REF_PIC_QUANT_DELTA_2(x) (((x) & 0x1f) << 27) +#define VDPU_REG_REF_PIC_QUANT_DELTA_3(x) (((x) & 0x1f) << 22) +#define VDPU_REG_REF_PIC_QUANT_2(x) (((x) & 0x7ff) << 11) +#define VDPU_REG_REF_PIC_QUANT_3(x) (((x) & 0x7ff) << 0) +#define VDPU_REG_VP8_QUANTER2 0x260 +#define VDPU_REG_REF_PIC_QUANT_DELTA_4(x) (((x) & 0x1f) << 27) +#define VDPU_REG_REF_PIC_QUANT_4(x) (((x) & 0x7ff) << 11) +#define VDPU_REG_REF_PIC_QUANT_5(x) (((x) & 0x7ff) << 0) +#define VDPU_REG_PRED_FLT1 0x264 +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_0_3(x) (((x) & 0x3ff) << 22) +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_1_0(x) (((x) & 0x3ff) << 12) +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_1_1(x) (((x) & 0x3ff) << 2) +#define VDPU_REG_PRED_FLT2 0x268 +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_1_2(x) (((x) & 0x3ff) << 22) +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_1_3(x) (((x) & 0x3ff) << 12) +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_2_0(x) (((x) & 0x3ff) << 2) +#define VDPU_REG_PRED_FLT3 0x26c +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_2_1(x) (((x) & 0x3ff) << 22) +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_2_2(x) (((x) & 0x3ff) << 12) +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_2_3(x) (((x) & 0x3ff) << 2) +#define VDPU_REG_PRED_FLT4 0x270 +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_3_0(x) (((x) & 0x3ff) << 22) +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_3_1(x) (((x) & 0x3ff) << 12) +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_3_2(x) (((x) & 0x3ff) << 2) +#define VDPU_REG_PRED_FLT5 0x274 +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_3_3(x) (((x) & 0x3ff) << 22) +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_4_0(x) (((x) & 0x3ff) << 12) +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_4_1(x) (((x) & 0x3ff) << 2) +#define VDPU_REG_PRED_FLT6 0x278 +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_4_2(x) (((x) & 0x3ff) << 22) +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_4_3(x) (((x) & 0x3ff) << 12) +#define VDPU_REG_PRED_FLT_PRED_BC_TAP_5_0(x) (((x) & 0x3ff) << 2) + +#define VEPU_H264E_NUM_REGS 184 +#define H264E_CABAC_TABLE_BUF_SIZE (52*2*464) + +typedef struct h264e_hal_vpu_dump_files_t { + FILE *fp_mpp_syntax_in; + FILE *fp_mpp_reg_in; + FILE *fp_mpp_reg_out; + FILE *fp_mpp_strm_out; + FILE *fp_mpp_feedback; +} h264e_hal_vpu_dump_files; + +/* transplant from vpu_api.h:EncInputPictureType */ +typedef enum { + H264E_VPU_CSP_YUV420P = 0, // YYYY... UUUU... VVVV + H264E_VPU_CSP_YUV420SP = 1, // YYYY... UVUVUV... + H264E_VPU_CSP_YUYV422 = 2, // YUYVYUYV... + H264E_VPU_CSP_UYVY422 = 3, // UYVYUYVY... + H264E_VPU_CSP_RGB565 = 4, // 16-bit RGB + H264E_VPU_CSP_BGR565 = 5, // 16-bit RGB + H264E_VPU_CSP_RGB555 = 6, // 15-bit RGB + H264E_VPU_CSP_BGR555 = 7, // 15-bit RGB + H264E_VPU_CSP_RGB444 = 8, // 12-bit RGB + H264E_VPU_CSP_BGR444 = 9, // 12-bit RGB + H264E_VPU_CSP_RGB888 = 10, // 24-bit RGB + H264E_VPU_CSP_BGR888 = 11, // 24-bit RGB + H264E_VPU_CSP_RGB101010 = 12, // 30-bit RGB + H264E_VPU_CSP_BGR101010 = 13, // 30-bit RGB + H264E_VPU_CSP_NONE, + H264E_VPU_CSP_BUTT, +} h264e_hal_vpu_csp; + +typedef struct h264e_hal_vpu_csp_info_t { + RK_U32 fmt; + RK_U32 r_mask_msb; + RK_U32 g_mask_msb; + RK_U32 b_mask_msb; +} h264e_hal_vpu_csp_info; + +/* struct for assemble bitstream */ +typedef struct h264e_hal_vpu_stream_t { + RK_U8 *buffer; /* point to first byte of stream */ + RK_U8 *stream; /* Pointer to next byte of stream */ + RK_U32 size; /* Byte size of stream buffer */ + RK_U32 byte_cnt; /* Byte counter */ + RK_U32 bit_cnt; /* Bit counter */ + RK_U32 byte_buffer; /* Byte buffer */ + RK_U32 buffered_bits; /* Amount of bits in byte buffer, [0-7] */ + RK_U32 zero_bytes; /* Amount of consecutive zero bytes */ + RK_S32 overflow; /* This will signal a buffer overflow */ + RK_U32 emul_cnt; /* Counter for emulation_3_byte, needed in SEI */ +} h264e_hal_vpu_stream; + +typedef struct h264e_hal_vpu_extra_info_t { + h264e_hal_vpu_stream sps_stream; + h264e_hal_vpu_stream pps_stream; + h264e_hal_sps sps; + h264e_hal_pps pps; +} h264e_hal_vpu_extra_info; + +typedef enum h264e_hal_vpu_buf_grp_t { + H264E_HAL_VPU_BUF_GRP_REC, + H264E_HAL_VPU_BUF_GRP_CABAC_TBL, + H264E_HAL_VPU_BUF_GRP_NALSIZE_TBL, + H264E_HAL_VPU_BUF_GRP_BUTT, +} h264e_hal_vpu_buf_grp; + +typedef struct h264e_hal_vpu_buffers_t { + MppBufferGroup hw_buf_grp; + + MppBuffer hw_rec_buf[2]; + MppBuffer hw_cabac_table_buf; + MppBuffer hw_nal_size_table_buf; +} h264e_hal_vpu_buffers; + +typedef struct h264e_vpu_reg_set_t { + RK_U32 val[VEPU_H264E_NUM_REGS]; +} h264e_vpu_reg_set; + +MPP_RET hal_h264e_vpu_init (void *hal, MppHalCfg *cfg); +MPP_RET hal_h264e_vpu_deinit (void *hal); +MPP_RET hal_h264e_vpu_gen_regs(void *hal, HalTaskInfo *task); +MPP_RET hal_h264e_vpu_start (void *hal, HalTaskInfo *task); +MPP_RET hal_h264e_vpu_wait (void *hal, HalTaskInfo *task); +MPP_RET hal_h264e_vpu_reset (void *hal); +MPP_RET hal_h264e_vpu_flush (void *hal); +MPP_RET hal_h264e_vpu_control (void *hal, RK_S32 cmd_type, void *param); + +#endif diff --git a/mpp/hal/rkenc/h264e/test/h264e_hal_test.c b/mpp/hal/rkenc/h264e/test/h264e_hal_test.c index 112174ac..062a6dc0 100644 --- a/mpp/hal/rkenc/h264e/test/h264e_hal_test.c +++ b/mpp/hal/rkenc/h264e/test/h264e_hal_test.c @@ -1,1616 +1,1616 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define MODULE_TAG "h264e_hal_test" - -#include -#include -#include -#include - -#ifdef RKPLATFORM -#include -#endif - -#include "mpp_log.h" -#include "mpp_mem.h" -#include "mpp_time.h" -#include "mpp_common.h" -#include "mpp_frame.h" - -#include "hal_h264e_api.h" -#include "hal_h264e.h" -#include "hal_h264e_vpu.h" -#include "hal_h264e_rkv.h" - - -static HalDeviceId test_device_id = HAL_RKVENC; - -#define MAX_FRAME_LUMA_SIZE (4096*2304) -#define MAX_FRAME_TOTAL_SIZE (MAX_FRAME_LUMA_SIZE*3/2) -#define GET_U32(val) ((RK_U32)(*((RK_U32 *)&(val)))) -//#define GET_U32(val) ((RK_U32)(val)) - -#define H264E_HAL_FSCAN(fp, fmt, dst) \ - do { \ - fscanf(fp, fmt, &data); \ - dst = data; \ - fgets(temp, 512, fp); \ - }while(0) - -//golden data from on2 project -FILE *fp_golden_syntax_in = NULL; -FILE *fp_mpp_syntax_in = NULL; -FILE *fp_mpp_reg_in = NULL; -FILE *fp_mpp_reg_out = NULL; -FILE *fp_h264e_yuv_in = NULL; -FILE *fp_mpp_strm_out = NULL; -FILE *fp_mpp_feedback = NULL; -FILE *fp_mpp_yuv_in = NULL; -FILE *fp_mpp_wr2hw_reg_in = NULL; - -RK_U32 g_frame_cnt = 0; -RK_U32 g_frame_read_cnt = 0; -typedef struct h264e_hal_test_cfg_t { - RK_U32 hw_mode; - char input_syntax_file_path[256]; - char input_yuv_file_path[256]; - RK_U32 pic_width; - RK_U32 pic_height; - RK_U32 src_format; - RK_U32 num_frames; - - h264e_hal_rkv_coveragetest_cfg test; -} h264e_hal_test_cfg; - -static RK_U32 h264e_rkv_revert_csp(h264e_hal_rkv_csp_info csp_info) -{ - h264e_hal_rkv_csp fmt = (h264e_hal_rkv_csp)csp_info.fmt; - RK_U32 cswap = csp_info.cswap; - RK_U32 aswap = csp_info.aswap; - MppFrameFormat dst_fmt; - - switch (fmt) { - case H264E_RKV_CSP_YUV420P: { - dst_fmt = MPP_FMT_YUV420P; - break; - } - case H264E_RKV_CSP_YUV420SP: { - dst_fmt = cswap ? MPP_FMT_YUV420SP_VU : MPP_FMT_YUV420SP; - break; - } - case H264E_RKV_CSP_YUV422P: { - dst_fmt = MPP_FMT_YUV422P; - break; - } - case H264E_RKV_CSP_YUV422SP: { - dst_fmt = cswap ? MPP_FMT_YUV422SP_VU : MPP_FMT_YUV422SP; - break; - } - case H264E_RKV_CSP_YUYV422: { - dst_fmt = MPP_FMT_YUV422_YUYV; - break; - } - case H264E_RKV_CSP_UYVY422: { - dst_fmt = MPP_FMT_YUV422_UYVY; - break; - } - case H264E_RKV_CSP_BGR565: { - dst_fmt = cswap ? MPP_FMT_RGB565 : MPP_FMT_BGR565; - break; - } - case H264E_RKV_CSP_BGR888: { - dst_fmt = cswap ? MPP_FMT_RGB888 : MPP_FMT_BGR888; - break; - } - case H264E_RKV_CSP_BGRA8888: { - if (aswap) - dst_fmt = cswap ? MPP_FMT_ABGR8888 : MPP_FMT_ARGB8888; - else - dst_fmt = MPP_FMT_BUTT; - - break; - } - default: { - h264e_hal_log_err("invalid csp_info.fmt %d, csp_info.cswap %d, csp_info.aswap %d", - csp_info.fmt, csp_info.cswap, csp_info.aswap); - dst_fmt = MPP_FMT_BUTT; - } - } - - if (dst_fmt == MPP_FMT_BUTT) { - h264e_hal_log_err("revert_csp error, src_fmt %d, dst_fmt %d", fmt, dst_fmt); - } - - return (RK_U32)dst_fmt; -} - -static RK_U32 h264e_vpu_revert_csp(RK_U32 csp) -{ - h264e_hal_vpu_csp fmt = (h264e_hal_vpu_csp)csp; - MppFrameFormat dst_fmt; - - switch (fmt) { - case H264E_VPU_CSP_YUV420P: { - dst_fmt = MPP_FMT_YUV420P; - break; - } - case H264E_VPU_CSP_YUV420SP: { - dst_fmt = MPP_FMT_YUV420SP; - break; - } - case H264E_VPU_CSP_YUYV422: { - dst_fmt = MPP_FMT_YUV422_YUYV; - break; - } - case H264E_VPU_CSP_UYVY422: { - dst_fmt = MPP_FMT_YUV422_UYVY; - break; - } - case H264E_VPU_CSP_RGB565: { - dst_fmt = MPP_FMT_RGB565; - break; - } - case H264E_VPU_CSP_BGR565: { - dst_fmt = MPP_FMT_BGR565; - break; - } - case H264E_VPU_CSP_RGB555: { - dst_fmt = MPP_FMT_RGB555; - break; - } - case H264E_VPU_CSP_BGR555: { - dst_fmt = MPP_FMT_BGR555; - break; - } - case H264E_VPU_CSP_RGB444: { - dst_fmt = MPP_FMT_RGB444; - break; - } - case H264E_VPU_CSP_BGR444: { - dst_fmt = MPP_FMT_BGR444; - break; - } - case H264E_VPU_CSP_RGB888: { - dst_fmt = MPP_FMT_RGB888; - break; - } - case H264E_VPU_CSP_BGR888: { - dst_fmt = MPP_FMT_BGR888; - break; - } - case H264E_VPU_CSP_RGB101010: { - dst_fmt = MPP_FMT_RGB101010; - break; - } - case H264E_VPU_CSP_BGR101010: { - dst_fmt = MPP_FMT_BGR101010; - break; - } - default: { - h264e_hal_log_err("invalid csp %d", csp); - dst_fmt = MPP_FMT_BUTT; - } - } - - return (RK_U32)dst_fmt; -} - - -static MPP_RET h264e_rkv_test_open_files(h264e_hal_test_cfg test_cfg) -{ - char base_path[512]; - char full_path[512]; - strcpy(base_path, "/sdcard/h264e_data/"); - - sprintf(full_path, "%s", test_cfg.input_yuv_file_path); - fp_h264e_yuv_in = fopen(full_path, "rb"); - if (!fp_h264e_yuv_in) { - mpp_err("%s open error", full_path); - return MPP_ERR_OPEN_FILE; - } - -#if !RKV_H264E_SDK_TEST - sprintf(full_path, "%s", test_cfg.input_syntax_file_path); - fp_golden_syntax_in = fopen(full_path, "rb"); - if (!fp_golden_syntax_in) { - mpp_err("%s open error", full_path); - return MPP_ERR_OPEN_FILE; - } -#endif - -#if 0 - sprintf(full_path, "%s%s", base_path, "mpp_yuv_in.yuv"); - fp_mpp_yuv_in = fopen(full_path, "wb"); - if (!fp_mpp_yuv_in) { - mpp_err("%s open error", full_path); - return MPP_ERR_OPEN_FILE; - } -#endif - - return MPP_OK; -} - - -static MPP_RET h264e_vpu_test_open_files(h264e_hal_test_cfg test_cfg) -{ - char base_path[512]; - char full_path[512]; - strcpy(base_path, "/sdcard/h264e_data/"); - - sprintf(full_path, "%s", test_cfg.input_yuv_file_path); - fp_h264e_yuv_in = fopen(full_path, "rb"); - if (!fp_h264e_yuv_in) { - mpp_err("%s open error", full_path); - return MPP_ERR_OPEN_FILE; - } - - sprintf(full_path, "%s", test_cfg.input_syntax_file_path); - fp_golden_syntax_in = fopen(full_path, "rb"); - if (!fp_golden_syntax_in) { - mpp_err("%s open error", full_path); - return MPP_ERR_OPEN_FILE; - } - - sprintf(full_path, "%s%s", base_path, "mpp_yuv_in.yuv"); - fp_mpp_yuv_in = fopen(full_path, "wb"); - if (!fp_mpp_yuv_in) { - mpp_err("%s open error", full_path); - return MPP_ERR_OPEN_FILE; - } - - return MPP_OK; -} - - - -static MPP_RET h264e_test_close_files() -{ - if (fp_h264e_yuv_in) { - fclose(fp_h264e_yuv_in); - fp_h264e_yuv_in = NULL; - } - - if (fp_golden_syntax_in) { - fclose(fp_golden_syntax_in); - fp_golden_syntax_in = NULL; - } - - if (fp_mpp_syntax_in) { - fclose(fp_mpp_syntax_in); - fp_mpp_syntax_in = NULL; - } - - - if (fp_mpp_yuv_in) { - fclose(fp_mpp_yuv_in); - fp_mpp_yuv_in = NULL; - } - - if (fp_mpp_reg_in) { - fclose(fp_mpp_reg_in); - fp_mpp_reg_in = NULL; - } - - if (fp_mpp_reg_out) { - fclose(fp_mpp_reg_out); - fp_mpp_reg_out = NULL; - } - - if (fp_mpp_strm_out) { - fclose(fp_mpp_strm_out); - fp_mpp_strm_out = NULL; - } - - if (fp_mpp_feedback) { - fclose(fp_mpp_feedback); - fp_mpp_feedback = NULL; - } - - if (fp_mpp_wr2hw_reg_in) { - fclose(fp_mpp_wr2hw_reg_in); - fp_mpp_wr2hw_reg_in = NULL; - } - - return MPP_OK; -} - -static MPP_RET get_rkv_h264e_yuv_in_frame(h264e_syntax *syn, MppBuffer *hw_buf) -{ - RK_U32 read_ret = 0; - RK_U32 frame_luma_size = syn->pic_luma_width * syn->pic_luma_height; - RK_U32 frame_size = frame_luma_size * 3 / 2; - RK_U8 *hw_buf_ptr = (RK_U8 *)mpp_buffer_get_ptr(hw_buf[g_frame_read_cnt % RKV_H264E_LINKTABLE_FRAME_NUM]);; - mpp_assert(fp_h264e_yuv_in); - - read_ret = (RK_U32)fread(hw_buf_ptr, 1, frame_size, fp_h264e_yuv_in); - if (read_ret == 0) { - mpp_log("yuv file end, nothing is read in %d frame", g_frame_read_cnt); - return MPP_EOS_STREAM_REACHED; - } else if (read_ret != frame_size) { - mpp_err("read yuv frame %d error, needed:%d, actual:%d", g_frame_read_cnt, frame_size, read_ret); - return MPP_NOK; - } else { - mpp_log("read frame %d size %d successfully", g_frame_read_cnt, read_ret); - } - - if (fp_mpp_yuv_in) { - fwrite(hw_buf_ptr, 1, frame_size, fp_mpp_yuv_in); - } - - return MPP_OK; -} - -static MPP_RET get_h264e_yuv_in_one_frame(RK_U8 *sw_buf, h264e_syntax *syn, MppBuffer hw_buf) -{ - RK_U32 read_ret = 0; - RK_U32 frame_luma_size = syn->pic_luma_width * syn->pic_luma_height; - RK_U32 frame_size = frame_luma_size * 3 / 2; - mpp_assert(fp_h264e_yuv_in); - - //TODO: remove sw_buf, read & write fd ptr directly - read_ret = (RK_U32)fread(sw_buf, 1, frame_size, fp_h264e_yuv_in); - if (read_ret == 0) { - mpp_log("yuv file end, nothing is read in frame %d", g_frame_cnt); - return MPP_EOS_STREAM_REACHED; - } else if (read_ret != frame_size) { - mpp_err("read yuv one frame error, needed:%d, actual:%d", frame_size, read_ret); - return MPP_NOK; - } else { - mpp_log("read frame %d size %d successfully", g_frame_cnt, frame_size); - } - - - mpp_buffer_write(hw_buf, 0, sw_buf, frame_size); - - if (fp_mpp_yuv_in) { - memcpy(sw_buf, mpp_buffer_get_ptr(hw_buf), frame_size); - fwrite(sw_buf, 1, frame_luma_size, fp_mpp_yuv_in); - } - return MPP_OK; -} - -static MPP_RET get_vpu_syntax_in(h264e_syntax *syn, MppBuffer hw_in_buf, MppBuffer hw_output_strm_buf, RK_U32 frame_luma_size) -{ - RK_S32 k = 0; - mpp_assert(fp_golden_syntax_in); - memset(syn, 0, sizeof(h264e_syntax)); - - if (fp_golden_syntax_in) { - char temp[512] = {0}; - RK_S32 data = 0; - if (!fgets(temp, 512, fp_golden_syntax_in)) - return MPP_EOS_STREAM_REACHED; - - fscanf(fp_golden_syntax_in, "%d", &data); - fgets(temp, 512, fp_golden_syntax_in); - syn->frame_coding_type = data; - - - fscanf(fp_golden_syntax_in, "%d", &data); - fgets(temp, 512, fp_golden_syntax_in); - syn->pic_init_qp = data; - - fscanf(fp_golden_syntax_in, "%d", &data); - fgets(temp, 512, fp_golden_syntax_in); - syn->slice_alpha_offset = data; - - fscanf(fp_golden_syntax_in, "%d", &data); - fgets(temp, 512, fp_golden_syntax_in); - syn->slice_beta_offset = data; - - fscanf(fp_golden_syntax_in, "%d", &data); - fgets(temp, 512, fp_golden_syntax_in); - syn->chroma_qp_index_offset = data; - - fscanf(fp_golden_syntax_in, "%d", &data); - fgets(temp, 512, fp_golden_syntax_in); - syn->filter_disable = data; - - fscanf(fp_golden_syntax_in, "%d", &data); - fgets(temp, 512, fp_golden_syntax_in); - syn->idr_pic_id = data; - - fscanf(fp_golden_syntax_in, "%d", &data); - fgets(temp, 512, fp_golden_syntax_in); - syn->pps_id = data; - - fscanf(fp_golden_syntax_in, "%d", &data); - fgets(temp, 512, fp_golden_syntax_in); - syn->frame_num = data; - - fscanf(fp_golden_syntax_in, "%d", &data); - fgets(temp, 512, fp_golden_syntax_in); - syn->slice_size_mb_rows = data; - - fscanf(fp_golden_syntax_in, "%d", &data); - fgets(temp, 512, fp_golden_syntax_in); - syn->h264_inter4x4_disabled = data; - - fscanf(fp_golden_syntax_in, "%d", &data); - fgets(temp, 512, fp_golden_syntax_in); - syn->enable_cabac = data; - - fscanf(fp_golden_syntax_in, "%d", &data); - fgets(temp, 512, fp_golden_syntax_in); - syn->transform8x8_mode = data; - - fscanf(fp_golden_syntax_in, "%d", &data); - fgets(temp, 512, fp_golden_syntax_in); - syn->cabac_init_idc = data; - - fscanf(fp_golden_syntax_in, "%d", &data); - fgets(temp, 512, fp_golden_syntax_in); - syn->qp = data; - - fscanf(fp_golden_syntax_in, "%d", &data); - fgets(temp, 512, fp_golden_syntax_in); - syn->mad_qp_delta = data; - - fscanf(fp_golden_syntax_in, "%d", &data); - fgets(temp, 512, fp_golden_syntax_in); - syn->mad_threshold = data; - - fscanf(fp_golden_syntax_in, "%d", &data); - fgets(temp, 512, fp_golden_syntax_in); - syn->qp_min = data; - - fscanf(fp_golden_syntax_in, "%d", &data); - fgets(temp, 512, fp_golden_syntax_in); - syn->qp_max = data; - - fscanf(fp_golden_syntax_in, "%d", &data); - fgets(temp, 512, fp_golden_syntax_in); - syn->cp_distance_mbs = data; - - for (k = 0; k < 10; k++) { - fscanf(fp_golden_syntax_in, "%d", &data); - fgets(temp, 512, fp_golden_syntax_in); - syn->cp_target[k] = data; - } - - for (k = 0; k < 7; k++) { - fscanf(fp_golden_syntax_in, "%d", &data); - fgets(temp, 512, fp_golden_syntax_in); - syn->target_error[k] = data; - } - for (k = 0; k < 7; k++) { - fscanf(fp_golden_syntax_in, "%d", &data); - fgets(temp, 512, fp_golden_syntax_in); - syn->delta_qp[k] = data; - } - - fscanf(fp_golden_syntax_in, "%d", &data); - fgets(temp, 512, fp_golden_syntax_in); - syn->output_strm_limit_size = data; - - fscanf(fp_golden_syntax_in, "%d", &data); - fgets(temp, 512, fp_golden_syntax_in); - syn->pic_luma_width = data; - - fscanf(fp_golden_syntax_in, "%d", &data); - fgets(temp, 512, fp_golden_syntax_in); - syn->pic_luma_height = data; - - fscanf(fp_golden_syntax_in, "%d", &data); - fgets(temp, 512, fp_golden_syntax_in); - syn->input_image_format = data; - - fscanf(fp_golden_syntax_in, "%d", &data); - fgets(temp, 512, fp_golden_syntax_in); - syn->color_conversion_coeff_a = data; - - fscanf(fp_golden_syntax_in, "%d", &data); - fgets(temp, 512, fp_golden_syntax_in); - syn->color_conversion_coeff_b = data; - - fscanf(fp_golden_syntax_in, "%d", &data); - fgets(temp, 512, fp_golden_syntax_in); - syn->color_conversion_coeff_c = data; - - fscanf(fp_golden_syntax_in, "%d", &data); - fgets(temp, 512, fp_golden_syntax_in); - syn->color_conversion_coeff_e = data; - - fscanf(fp_golden_syntax_in, "%d", &data); - fgets(temp, 512, fp_golden_syntax_in); - syn->color_conversion_coeff_f = data; - - fscanf(fp_golden_syntax_in, "%d", &data); - fgets(temp, 512, fp_golden_syntax_in); - - fscanf(fp_golden_syntax_in, "%d", &data); - fgets(temp, 512, fp_golden_syntax_in); - - fscanf(fp_golden_syntax_in, "%d", &data); - fgets(temp, 512, fp_golden_syntax_in); - - fgets(temp, 512, fp_golden_syntax_in); - } - - if (hw_in_buf) - syn->input_luma_addr = mpp_buffer_get_fd(hw_in_buf); - syn->input_cb_addr = syn->input_luma_addr | (frame_luma_size << 10); - syn->input_cr_addr = syn->input_cb_addr | ((frame_luma_size/4) << 10); - - if (hw_output_strm_buf) - syn->output_strm_addr = mpp_buffer_get_fd(hw_output_strm_buf); - - /* adjust */ - syn->input_image_format = h264e_vpu_revert_csp(syn->input_image_format); - - return MPP_OK; -} - -#if 0 -static void dump_rkv_mpp_dbg_info(h264e_hal_rkv_dbg_info *info, h264e_syntax *syn) -{ - if (fp_mpp_syntax_in) { - RK_S32 k = 0; - FILE *fp = fp_mpp_syntax_in; - fprintf(fp, "#FRAME %d\n", g_frame_read_cnt); - - fprintf(fp, "%-16d %s\n", syn->pic_luma_width, "pic_luma_width"); - fprintf(fp, "%-16d %s\n", syn->pic_luma_height, "pic_luma_height"); - fprintf(fp, "%-16d %s\n", syn->level_idc, "level_idc"); - fprintf(fp, "%-16d %s\n", syn->profile_idc, "profile_idc"); - fprintf(fp, "%-16d %s\n", syn->frame_coding_type, "frame_coding_type"); - - fprintf(fp, "%-16d %s\n", info->swreg02.lkt_num, "swreg02.lkt_num"); - fprintf(fp, "%-16d %s\n", info->swreg02.rkvenc_cmd, "swreg02.rkvenc_cmd"); - fprintf(fp, "%-16d %s\n", info->swreg02.enc_cke, "swreg02.enc_cke"); - - fprintf(fp, "%-16d %s\n", info->swreg04.lkt_addr, "swreg04.lkt_addr"); - - fprintf(fp, "%-16d %s\n", info->swreg05.ofe_fnsh, "swreg05.ofe_fnsh"); - fprintf(fp, "%-16d %s\n", info->swreg05.lkt_fnsh, "swreg05.lkt_fnsh"); - fprintf(fp, "%-16d %s\n", info->swreg05.clr_fnsh, "swreg05.clr_fnsh"); - fprintf(fp, "%-16d %s\n", info->swreg05.ose_fnsh, "swreg05.ose_fnsh"); - fprintf(fp, "%-16d %s\n", info->swreg05.bs_ovflr, "swreg05.bs_ovflr"); - fprintf(fp, "%-16d %s\n", info->swreg05.brsp_ful, "swreg05.brsp_ful"); - fprintf(fp, "%-16d %s\n", info->swreg05.brsp_err, "swreg05.brsp_err"); - fprintf(fp, "%-16d %s\n", info->swreg05.rrsp_err, "swreg05.rrsp_err"); - fprintf(fp, "%-16d %s\n", info->swreg05.tmt_err, "swreg05.tmt_err"); - - fprintf(fp, "%-16d %s\n", info->swreg10.roi_enc, "swreg10.roi_enc"); - fprintf(fp, "%-16d %s\n", info->swreg10.cur_frm_ref, "swreg10.cur_frm_ref"); - fprintf(fp, "%-16d %s\n", info->swreg10.mei_stor, "swreg10.mei_stor"); - fprintf(fp, "%-16d %s\n", info->swreg10.bs_scp, "swreg10.bs_scp"); - fprintf(fp, "%-16d %s\n", info->swreg10.pic_qp, "swreg10.pic_qp"); - fprintf(fp, "%-16d %s\n", info->swreg10.slice_int, "swreg10.slice_int"); - fprintf(fp, "%-16d %s\n", info->swreg10.node_int, "swreg10.node_int"); - - fprintf(fp, "%-16d %s\n", info->swreg11.ppln_enc_lmt, "swreg11.ppln_enc_lmt"); - fprintf(fp, "%-16d %s\n", info->swreg11.rfp_load_thrd, "swreg11.rfp_load_thrd"); - - fprintf(fp, "%-16d %s\n", info->swreg12.src_bus_edin, "swreg12.src_bus_edin"); - - - fprintf(fp, "%-16d %s\n", info->swreg13.axi_brsp_cke, "swreg13.axi_brsp_cke"); - - fprintf(fp, "%-16d %s\n", info->swreg14.src_aswap, "swreg14.src_aswap"); - fprintf(fp, "%-16d %s\n", info->swreg14.src_cswap, "swreg14.src_cswap"); - fprintf(fp, "%-16d %s\n", info->swreg14.src_cfmt, "swreg14.src_cfmt"); - fprintf(fp, "%-16d %s\n", info->swreg14.src_clip_dis, "swreg14.src_clip_dis"); - - fprintf(fp, "%-16d %s\n", info->swreg15.wght_b2y, "swreg15.wght_b2y"); - fprintf(fp, "%-16d %s\n", info->swreg15.wght_g2y, "swreg15.wght_g2y"); - fprintf(fp, "%-16d %s\n", info->swreg15.wght_r2y, "swreg15.wght_r2y"); - - fprintf(fp, "%-16d %s\n", info->swreg16.wght_b2u, "swreg16.wght_b2u"); - fprintf(fp, "%-16d %s\n", info->swreg16.wght_g2u, "swreg16.wght_g2u"); - fprintf(fp, "%-16d %s\n", info->swreg16.wght_r2u, "swreg16.wght_r2u"); - - fprintf(fp, "%-16d %s\n", info->swreg17.wght_b2v, "swreg17.wght_b2v"); - fprintf(fp, "%-16d %s\n", info->swreg17.wght_g2v, "swreg17.wght_g2v"); - fprintf(fp, "%-16d %s\n", info->swreg17.wght_r2v, "swreg17.wght_r2v"); - - fprintf(fp, "%-16d %s\n", info->swreg18.ofst_rgb2v, "swreg18.ofst_rgb2v"); - fprintf(fp, "%-16d %s\n", info->swreg18.ofst_rgb2u, "swreg18.ofst_rgb2u"); - fprintf(fp, "%-16d %s\n", info->swreg18.ofst_rgb2y, "swreg18.ofst_rgb2y"); - - fprintf(fp, "%-16d %s\n", info->swreg19.src_tfltr, "swreg19.src_tfltr"); - fprintf(fp, "%-16d %s\n", info->swreg19.src_tfltr_we, "swreg19.src_tfltr_we"); - fprintf(fp, "%-16d %s\n", info->swreg19.src_tfltr_bw, "swreg19.src_tfltr_bw"); - fprintf(fp, "%-16d %s\n", info->swreg19.src_sfltr, "swreg19.src_sfltr"); - fprintf(fp, "%-16d %s\n", info->swreg19.src_mfltr_thrd, "swreg19.src_mfltr_thrd"); - fprintf(fp, "%-16d %s\n", info->swreg19.src_mfltr_y, "swreg19.src_mfltr_y"); - fprintf(fp, "%-16d %s\n", info->swreg19.src_mfltr_c, "swreg19.src_mfltr_c"); - fprintf(fp, "%-16d %s\n", info->swreg19.src_bfltr_strg, "swreg19.src_bfltr_strg"); - fprintf(fp, "%-16d %s\n", info->swreg19.src_bfltr, "swreg19.src_bfltr"); - fprintf(fp, "%-16d %s\n", info->swreg19.src_mbflt_odr, "swreg19.src_mbflt_odr"); - fprintf(fp, "%-16d %s\n", info->swreg19.src_matf_y, "swreg19.src_matf_y"); - fprintf(fp, "%-16d %s\n", info->swreg19.src_matf_c, "swreg19.src_matf_c"); - fprintf(fp, "%-16d %s\n", info->swreg19.src_shp_y, "swreg19.src_shp_y"); - fprintf(fp, "%-16d %s\n", info->swreg19.src_shp_c, "swreg19.src_shp_c"); - fprintf(fp, "%-16d %s\n", info->swreg19.src_shp_div, "swreg19.src_shp_div"); - fprintf(fp, "%-16d %s\n", info->swreg19.src_shp_thld, "swreg19.src_shp_thld"); - fprintf(fp, "%-16d %s\n", info->swreg19.src_mirr, "swreg19.src_mirr"); - fprintf(fp, "%-16d %s\n", info->swreg19.src_rot, "swreg19.src_rot"); - fprintf(fp, "%-16d %s\n", info->swreg19.src_matf_itsy, "swreg19.src_matf_itsy"); - - fprintf(fp, "%-16d %s\n", info->swreg20.tfltr_thld_y, "swreg20.tfltr_thld_y"); - fprintf(fp, "%-16d %s\n", info->swreg20.tfltr_thld_c, "swreg20.tfltr_thld_c"); - - for (k = 0; k < 5; k++) - fprintf(fp, "%-16d swreg21_scr_stbl[%d]\n", info->swreg21_scr_stbl[k], k); - - for (k = 0; k < 40; k++) - fprintf(fp, "%-16d swreg22_h3d_tbl[%d]\n", info->swreg22_h3d_tbl[k], k); - - fprintf(fp, "%-16d %s\n", info->swreg23.src_ystrid, "swreg23.src_ystrid"); - fprintf(fp, "%-16d %s\n", info->swreg23.src_cstrid, "swreg23.src_cstrid"); - - fprintf(fp, "%#-16x %s\n", info->addr_cfg.adr_srcy, "addr_cfg.adr_srcy"); - fprintf(fp, "%#-16x %s\n", info->addr_cfg.adr_srcu, "addr_cfg.adr_srcu"); - fprintf(fp, "%#-16x %s\n", info->addr_cfg.adr_srcv, "addr_cfg.adr_srcv"); - fprintf(fp, "%#-16x %s\n", info->addr_cfg.ctuc_addr, "addr_cfg.ctuc_addr"); - fprintf(fp, "%#-16x %s\n", info->addr_cfg.rfpw_addr, "addr_cfg.rfpw_addr"); - fprintf(fp, "%#-16x %s\n", info->addr_cfg.rfpr_addr, "addr_cfg.rfpr_addr"); - fprintf(fp, "%#-16x %s\n", info->addr_cfg.dspw_addr, "addr_cfg.dspw_addr"); - fprintf(fp, "%#-16x %s\n", info->addr_cfg.dspr_addr, "addr_cfg.dspr_addr"); - fprintf(fp, "%#-16x %s\n", info->addr_cfg.bsbw_addr, "addr_cfg.bsbw_addr"); - - fprintf(fp, "%-16d %s\n", info->swreg41.sli_cut, "swreg41.sli_cut"); - fprintf(fp, "%-16d %s\n", info->swreg41.sli_cut_mode, "swreg41.sli_cut_mode"); - fprintf(fp, "%-16d %s\n", info->swreg41.sli_cut_bmod, "swreg41.sli_cut_bmod"); - fprintf(fp, "%-16d %s\n", info->swreg41.sli_max_num, "swreg41.sli_max_num"); - fprintf(fp, "%-16d %s\n", info->swreg41.sli_out_mode, "swreg41.sli_out_mode"); - fprintf(fp, "%-16d %s\n", info->swreg41.sli_cut_cnum, "swreg41.sli_cut_cnum"); - - fprintf(fp, "%-16d %s\n", info->swreg42.sli_cut_byte, "swreg42.sli_cut_byte"); - - fprintf(fp, "%-16d %s\n", info->swreg43.cime_srch_h, "swreg43.cime_srch_h"); - fprintf(fp, "%-16d %s\n", info->swreg43.cime_srch_v, "swreg43.cime_srch_v"); - fprintf(fp, "%-16d %s\n", info->swreg43.rime_srch_h, "swreg43.rime_srch_h"); - fprintf(fp, "%-16d %s\n", info->swreg43.rime_srch_v, "swreg43.rime_srch_v"); - - fprintf(fp, "%-16d %s\n", info->swreg44.pmv_mdst_h, "swreg44.pmv_mdst_h"); - fprintf(fp, "%-16d %s\n", info->swreg44.pmv_mdst_v, "swreg44.pmv_mdst_v"); - fprintf(fp, "%-16d %s\n", info->swreg44.mv_limit, "swreg44.mv_limit"); - fprintf(fp, "%-16d %s\n", info->swreg44.mv_num, "swreg44.mv_num"); - - fprintf(fp, "%-16d %s\n", info->swreg45.cach_l1_dtmr, "swreg45.cach_l1_dtmr"); - - fprintf(fp, "%-16d %s\n", info->swreg46.rc_en, "swreg46.rc_en"); - fprintf(fp, "%-16d %s\n", info->swreg46.rc_mode, "swreg46.rc_mode"); - fprintf(fp, "%-16d %s\n", info->swreg46.aqmode_en, "swreg46.aqmode_en"); - fprintf(fp, "%-16d %s\n", info->swreg46.aq_strg, "swreg46.aq_strg"); - fprintf(fp, "%-16d %s\n", info->swreg46.rc_ctu_num, "swreg46.rc_ctu_num"); - - fprintf(fp, "%-16d %s\n", info->swreg47.bits_error0, "swreg47.bits_error0"); - fprintf(fp, "%-16d %s\n", info->swreg47.bits_error1, "swreg47.bits_error1"); - fprintf(fp, "%-16d %s\n", info->swreg48.bits_error2, "swreg48.bits_error2"); - fprintf(fp, "%-16d %s\n", info->swreg48.bits_error3, "swreg48.bits_error3"); - fprintf(fp, "%-16d %s\n", info->swreg49.bits_error4, "swreg49.bits_error4"); - fprintf(fp, "%-16d %s\n", info->swreg49.bits_error5, "swreg49.bits_error5"); - fprintf(fp, "%-16d %s\n", info->swreg50.bits_error6, "swreg50.bits_error6"); - fprintf(fp, "%-16d %s\n", info->swreg50.bits_error7, "swreg50.bits_error7"); - fprintf(fp, "%-16d %s\n", info->swreg51.bits_error8, "swreg51.bits_error8"); - - fprintf(fp, "%-16d %s\n", info->swreg52.qp_adjuest0, "swreg52.qp_adjuest0"); - fprintf(fp, "%-16d %s\n", info->swreg52.qp_adjuest1, "swreg52.qp_adjuest1"); - fprintf(fp, "%-16d %s\n", info->swreg52.qp_adjuest2, "swreg52.qp_adjuest2"); - fprintf(fp, "%-16d %s\n", info->swreg52.qp_adjuest3, "swreg52.qp_adjuest3"); - fprintf(fp, "%-16d %s\n", info->swreg52.qp_adjuest4, "swreg52.qp_adjuest4"); - fprintf(fp, "%-16d %s\n", info->swreg52.qp_adjuest5, "swreg52.qp_adjuest5"); - fprintf(fp, "%-16d %s\n", info->swreg53.qp_adjuest6, "swreg53.qp_adjuest6"); - fprintf(fp, "%-16d %s\n", info->swreg53.qp_adjuest7, "swreg53.qp_adjuest7"); - fprintf(fp, "%-16d %s\n", info->swreg53.qp_adjuest8, "swreg53.qp_adjuest8"); - - fprintf(fp, "%-16d %s\n", info->swreg54.rc_qp_mod, "swreg54.rc_qp_mod"); - fprintf(fp, "%-16d %s\n", info->swreg54.rc_fact0, "swreg54.rc_fact0"); - fprintf(fp, "%-16d %s\n", info->swreg54.rc_fact1, "swreg54.rc_fact1"); - fprintf(fp, "%-16d %s\n", info->swreg54.rc_qp_range, "swreg54.rc_qp_range"); - fprintf(fp, "%-16d %s\n", info->swreg54.rc_max_qp, "swreg54.rc_max_qp"); - fprintf(fp, "%-16d %s\n", info->swreg54.rc_min_qp, "swreg54.rc_min_qp"); - - fprintf(fp, "%-16d %s\n", info->swreg55.ctu_ebits, "swreg55.ctu_ebits"); - - fprintf(fp, "%-16d %s\n", info->swreg56.arb_sel, "swreg56.arb_sel"); - fprintf(fp, "%-16d %s\n", info->swreg56.rdo_mark, "swreg56.rdo_mark"); - - fprintf(fp, "%-16d %s\n", info->swreg57.nal_ref_idc, "swreg57.nal_ref_idc"); - fprintf(fp, "%-16d %s\n", info->swreg57.nal_unit_type, "swreg57.nal_unit_type"); - - fprintf(fp, "%-16d %s\n", info->swreg58.max_fnum, "swreg58.max_fnum"); - fprintf(fp, "%-16d %s\n", info->swreg58.drct_8x8, "swreg58.drct_8x8"); - fprintf(fp, "%-16d %s\n", info->swreg58.mpoc_lm4, "swreg58.mpoc_lm4"); - - fprintf(fp, "%-16d %s\n", info->swreg59.etpy_mode, "swreg59.etpy_mode"); - fprintf(fp, "%-16d %s\n", info->swreg59.trns_8x8, "swreg59.trns_8x8"); - fprintf(fp, "%-16d %s\n", info->swreg59.csip_flg, "swreg59.csip_flg"); - fprintf(fp, "%-16d %s\n", info->swreg59.num_ref0_idx, "swreg59.num_ref0_idx"); - fprintf(fp, "%-16d %s\n", info->swreg59.num_ref1_idx, "swreg59.num_ref1_idx"); - fprintf(fp, "%-16d %s\n", info->swreg59.pic_init_qp, "swreg59.pic_init_qp"); - fprintf(fp, "%-16d %s\n", info->swreg59.cb_ofst, "swreg59.cb_ofst"); - fprintf(fp, "%-16d %s\n", info->swreg59.cr_ofst, "swreg59.cr_ofst"); - fprintf(fp, "%-16d %s\n", info->swreg59.dbf_cp_flg, "swreg59.dbf_cp_flg"); - - fprintf(fp, "%-16d %s\n", info->swreg60.sli_type, "swreg60.sli_type"); - fprintf(fp, "%-16d %s\n", info->swreg60.pps_id, "swreg60.pps_id"); - fprintf(fp, "%-16d %s\n", info->swreg60.num_ref_ovrd, "swreg60.num_ref_ovrd"); - fprintf(fp, "%-16d %s\n", info->swreg60.cbc_init_idc, "swreg60.cbc_init_idc"); - fprintf(fp, "%-16d %s\n", info->swreg60.frm_num, "swreg60.frm_num"); - - fprintf(fp, "%-16d %s\n", info->swreg61.idr_pid, "swreg61.idr_pid"); - fprintf(fp, "%-16d %s\n", info->swreg61.poc_lsb, "swreg61.poc_lsb"); - - fprintf(fp, "%-16d %s\n", info->swreg62.rodr_pic_idx, "swreg62.rodr_pic_idx"); - fprintf(fp, "%-16d %s\n", info->swreg62.ref_list0_rodr, "swreg62.ref_list0_rodr"); - fprintf(fp, "%-16d %s\n", info->swreg62.sli_beta_ofst, "swreg62.sli_beta_ofst"); - fprintf(fp, "%-16d %s\n", info->swreg62.sli_alph_ofst, "swreg62.sli_alph_ofst"); - fprintf(fp, "%-16d %s\n", info->swreg62.dis_dblk_idc, "swreg62.dis_dblk_idc"); - fprintf(fp, "%-16d %s\n", info->swreg62.rodr_pic_num, "swreg62.rodr_pic_num"); - - fprintf(fp, "%-16d %s\n", info->swreg63.ltrf_flg, "swreg63.ltrf_flg"); - fprintf(fp, "%-16d %s\n", info->swreg63.arpm_flg, "swreg63.arpm_flg"); - fprintf(fp, "%-16d %s\n", info->swreg63.mmco4_pre, "swreg63.mmco4_pre"); - fprintf(fp, "%-16d %s\n", info->swreg63.mmco_0, "swreg63.mmco_0"); - fprintf(fp, "%-16d %s\n", info->swreg63.dopn_m1_0, "swreg63.dopn_m1_0"); - - fprintf(fp, "%-16d %s\n", info->swreg64.mmco_1, "swreg64.mmco_1"); - fprintf(fp, "%-16d %s\n", info->swreg64.dopn_m1_1, "swreg64.dopn_m1_1"); - - fprintf(fp, "%-16d %s\n", info->swreg65.osd_en, "swreg65.osd_en"); - fprintf(fp, "%-16d %s\n", info->swreg65.osd_inv, "swreg65.osd_inv"); - fprintf(fp, "%-16d %s\n", info->swreg65.osd_plt_type, "swreg65.osd_plt_type"); - - fprintf(fp, "%-16d %s\n", info->swreg66.osd_inv_r0, "swreg66.osd_inv_r0"); - fprintf(fp, "%-16d %s\n", info->swreg66.osd_inv_r1, "swreg66.osd_inv_r1"); - fprintf(fp, "%-16d %s\n", info->swreg66.osd_inv_r2, "swreg66.osd_inv_r2"); - fprintf(fp, "%-16d %s\n", info->swreg66.osd_inv_r3, "swreg66.osd_inv_r3"); - fprintf(fp, "%-16d %s\n", info->swreg66.osd_inv_r4, "swreg66.osd_inv_r4"); - fprintf(fp, "%-16d %s\n", info->swreg66.osd_inv_r5, "swreg66.osd_inv_r5"); - fprintf(fp, "%-16d %s\n", info->swreg66.osd_inv_r6, "swreg66.osd_inv_r6"); - fprintf(fp, "%-16d %s\n", info->swreg66.osd_inv_r7, "swreg66.osd_inv_r7"); - - for (k = 0; k < 8; k++) { - fprintf(fp, "%-16d swreg67_osd_pos[%d].lt_pos_x\n", info->swreg67_osd_pos[k].lt_pos_x, k); - fprintf(fp, "%-16d swreg67_osd_pos[%d].lt_pos_y\n", info->swreg67_osd_pos[k].lt_pos_y, k); - fprintf(fp, "%-16d swreg67_osd_pos[%d].rd_pos_x\n", info->swreg67_osd_pos[k].rd_pos_x, k); - fprintf(fp, "%-16d swreg67_osd_pos[%d].rd_pos_y\n", info->swreg67_osd_pos[k].rd_pos_y, k); - } - for (k = 0; k < 8; k++) - fprintf(fp, "%-16d swreg68_indx_addr_i[%d]\n", info->swreg68_indx_addr_i[k], k); - - for (k = 0; k < 256; k++) - fprintf(fp, "%#-16x swreg73_osd_indx_tab_i[%d]\n", info->swreg73_osd_indx_tab_i[k], k); - - fprintf(fp, "%#-16x %s\n", info->swreg77.bsbw_addr, "swreg77.bsbw_addr"); - - fprintf(fp, "\n"); - fflush(fp); - } else { - mpp_log("try to dump data to mpp_syntax_in.txt, but file is not opened"); - } -} -#endif - - -#if 0 -static MPP_RET get_rkv_dbg_info(h264e_hal_rkv_dbg_info *info, h264e_syntax *syn, - MppBuffer *hw_in_buf, MppBuffer *hw_output_strm_buf) - -{ - RK_S32 k = 0; - RK_U32 buf_idx = g_frame_read_cnt % RKV_H264E_LINKTABLE_FRAME_NUM; - h264e_hal_debug_enter(); - mpp_assert(fp_golden_syntax_in); - memset(syn, 0, sizeof(h264e_syntax)); - memset(info, 0, sizeof(h264e_hal_rkv_dbg_info)); - - if (hw_in_buf[buf_idx]) { - syn->input_luma_addr = mpp_buffer_get_fd(hw_in_buf[buf_idx]); - syn->input_cb_addr = syn->input_luma_addr; //NOTE: transfer offset in extra_info - syn->input_cr_addr = syn->input_luma_addr; - } - if (hw_output_strm_buf[buf_idx]) - syn->output_strm_addr = mpp_buffer_get_fd(hw_output_strm_buf[buf_idx]); - - - if (fp_golden_syntax_in) { - FILE *fp = fp_golden_syntax_in; - char temp[512] = {0}; - RK_S32 data = 0; - - if (!fgets(temp, 512, fp)) - return MPP_EOS_STREAM_REACHED; - - H264E_HAL_FSCAN(fp, "%d\n", syn->pic_luma_width); - H264E_HAL_FSCAN(fp, "%d\n", syn->pic_luma_height); - H264E_HAL_FSCAN(fp, "%d\n", syn->level_idc); - H264E_HAL_FSCAN(fp, "%d\n", syn->profile_idc); - H264E_HAL_FSCAN(fp, "%d\n", syn->frame_coding_type); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg02.lkt_num); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg02.rkvenc_cmd); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg02.enc_cke); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg04.lkt_addr); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg05.ofe_fnsh); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg05.lkt_fnsh); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg05.clr_fnsh); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg05.ose_fnsh); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg05.bs_ovflr); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg05.brsp_ful); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg05.brsp_err); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg05.rrsp_err); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg05.tmt_err); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg10.roi_enc); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg10.cur_frm_ref); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg10.mei_stor); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg10.bs_scp); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg10.pic_qp); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg10.slice_int); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg10.node_int); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg11.ppln_enc_lmt); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg11.rfp_load_thrd); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg12.src_bus_edin); - - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg13.axi_brsp_cke); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg14.src_aswap); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg14.src_cswap); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg14.src_cfmt); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg14.src_clip_dis); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg15.wght_b2y); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg15.wght_g2y); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg15.wght_r2y); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg16.wght_b2u); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg16.wght_g2u); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg16.wght_r2u); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg17.wght_b2v); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg17.wght_g2v); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg17.wght_r2v); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg18.ofst_rgb2v); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg18.ofst_rgb2u); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg18.ofst_rgb2y); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg19.src_tfltr); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg19.src_tfltr_we); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg19.src_tfltr_bw); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg19.src_sfltr); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg19.src_mfltr_thrd); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg19.src_mfltr_y); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg19.src_mfltr_c); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg19.src_bfltr_strg); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg19.src_bfltr); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg19.src_mbflt_odr); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg19.src_matf_y); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg19.src_matf_c); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg19.src_shp_y); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg19.src_shp_c); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg19.src_shp_div); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg19.src_shp_thld); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg19.src_mirr); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg19.src_rot); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg19.src_matf_itsy); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg20.tfltr_thld_y); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg20.tfltr_thld_c); - - for (k = 0; k < 5; k++) - H264E_HAL_FSCAN(fp, "%d\n", info->swreg21_scr_stbl[k]); - - for (k = 0; k < 40; k++) - H264E_HAL_FSCAN(fp, "%d\n", info->swreg22_h3d_tbl[k]); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg23.src_ystrid); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg23.src_cstrid); - - H264E_HAL_FSCAN(fp, "%x\n", info->addr_cfg.adr_srcy); - H264E_HAL_FSCAN(fp, "%x\n", info->addr_cfg.adr_srcu); - H264E_HAL_FSCAN(fp, "%x\n", info->addr_cfg.adr_srcv); - H264E_HAL_FSCAN(fp, "%x\n", info->addr_cfg.ctuc_addr); - H264E_HAL_FSCAN(fp, "%x\n", info->addr_cfg.rfpw_addr); - H264E_HAL_FSCAN(fp, "%x\n", info->addr_cfg.rfpr_addr); - H264E_HAL_FSCAN(fp, "%x\n", info->addr_cfg.dspw_addr); - H264E_HAL_FSCAN(fp, "%x\n", info->addr_cfg.dspr_addr); - H264E_HAL_FSCAN(fp, "%x\n", info->addr_cfg.bsbw_addr); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg41.sli_cut); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg41.sli_cut_mode); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg41.sli_cut_bmod); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg41.sli_max_num); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg41.sli_out_mode); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg41.sli_cut_cnum); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg42.sli_cut_byte); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg43.cime_srch_h); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg43.cime_srch_v); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg43.rime_srch_h); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg43.rime_srch_v); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg44.pmv_mdst_h); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg44.pmv_mdst_v); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg44.mv_limit); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg44.mv_num); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg45.cach_l1_dtmr); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg46.rc_en); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg46.rc_mode); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg46.aqmode_en); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg46.aq_strg); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg46.rc_ctu_num); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg47.bits_error0); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg47.bits_error1); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg48.bits_error2); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg48.bits_error3); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg49.bits_error4); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg49.bits_error5); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg50.bits_error6); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg50.bits_error7); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg51.bits_error8); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg52.qp_adjuest0); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg52.qp_adjuest1); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg52.qp_adjuest2); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg52.qp_adjuest3); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg52.qp_adjuest4); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg52.qp_adjuest5); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg53.qp_adjuest6); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg53.qp_adjuest7); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg53.qp_adjuest8); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg54.rc_qp_mod); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg54.rc_fact0); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg54.rc_fact1); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg54.rc_qp_range); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg54.rc_max_qp); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg54.rc_min_qp); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg55.ctu_ebits); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg56.arb_sel); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg56.rdo_mark); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg57.nal_ref_idc); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg57.nal_unit_type); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg58.max_fnum); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg58.drct_8x8); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg58.mpoc_lm4); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg59.etpy_mode); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg59.trns_8x8); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg59.csip_flg); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg59.num_ref0_idx); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg59.num_ref1_idx); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg59.pic_init_qp); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg59.cb_ofst); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg59.cr_ofst); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg59.dbf_cp_flg); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg60.sli_type); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg60.pps_id); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg60.num_ref_ovrd); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg60.cbc_init_idc); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg60.frm_num); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg61.idr_pid); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg61.poc_lsb); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg62.rodr_pic_idx); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg62.ref_list0_rodr); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg62.sli_beta_ofst); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg62.sli_alph_ofst); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg62.dis_dblk_idc); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg62.rodr_pic_num); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg63.ltrf_flg); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg63.arpm_flg); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg63.mmco4_pre); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg63.mmco_0); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg63.dopn_m1_0); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg64.mmco_1); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg64.dopn_m1_1); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg65.osd_en); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg65.osd_inv); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg65.osd_plt_type); - - H264E_HAL_FSCAN(fp, "%d\n", info->swreg66.osd_inv_r0); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg66.osd_inv_r1); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg66.osd_inv_r2); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg66.osd_inv_r3); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg66.osd_inv_r4); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg66.osd_inv_r5); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg66.osd_inv_r6); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg66.osd_inv_r7); - - for (k = 0; k < 8; k++) { - H264E_HAL_FSCAN(fp, "%d\n", info->swreg67_osd_pos[k].lt_pos_x); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg67_osd_pos[k].lt_pos_y); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg67_osd_pos[k].rd_pos_x); - H264E_HAL_FSCAN(fp, "%d\n", info->swreg67_osd_pos[k].rd_pos_y); - } - for (k = 0; k < 8; k++) - H264E_HAL_FSCAN(fp, "%d\n", info->swreg68_indx_addr_i[k]); - - for (k = 0; k < 256; k++) - H264E_HAL_FSCAN(fp, "%x\n", info->swreg73_osd_indx_tab_i[k]); - - H264E_HAL_FSCAN(fp, "%x\n", info->swreg77.bsbw_addr); - - H264E_HAL_FSCAN(fp, "%x\n", syn->keyframe_max_interval); - - fgets(temp, 512, fp); - - //set values actually used - syn->slice_type = info->swreg60.sli_type; - syn->pps_id = info->swreg60.pps_id; - syn->cabac_init_idc = info->swreg60.cbc_init_idc; - syn->pic_order_cnt_lsb = info->swreg61.poc_lsb; - syn->idr_pic_id = info->swreg61.idr_pid; - syn->pic_init_qp = info->swreg59.pic_init_qp; - syn->qp = info->swreg10.pic_qp; - syn->frame_num = info->swreg60.frm_num; - syn->input_image_format = info->swreg14.src_cfmt; - syn->transform8x8_mode = info->swreg59.trns_8x8; - } - - h264e_hal_debug_leave(); - return MPP_OK; -} -#endif - - -static MPP_RET get_rkv_syntax_in( h264e_syntax *syn, MppBuffer *hw_in_buf, MppBuffer *hw_output_strm_buf, h264e_hal_test_cfg *cfg) - -{ - h264e_hal_rkv_csp_info csp_info; - RK_U32 buf_idx = g_frame_read_cnt % RKV_H264E_LINKTABLE_FRAME_NUM; - h264e_hal_debug_enter(); - //mpp_assert(fp_golden_syntax_in); - memset(syn, 0, sizeof(h264e_syntax)); - - if (hw_in_buf[buf_idx]) { - syn->input_luma_addr = mpp_buffer_get_fd(hw_in_buf[buf_idx]); - syn->input_cb_addr = syn->input_luma_addr; //NOTE: transfer offset in extra_info - syn->input_cr_addr = syn->input_luma_addr; - } - if (hw_output_strm_buf[buf_idx]) - syn->output_strm_addr = mpp_buffer_get_fd(hw_output_strm_buf[buf_idx]); - -#if RKV_H264E_SDK_TEST - mpp_log("make syntax begin"); - syn->pic_luma_width = cfg->pic_width; - syn->pic_luma_height = cfg->pic_height; - syn->level_idc = H264_LEVEL_4_1; - syn->profile_idc = H264_PROFILE_HIGH; - mpp_log("syn->level_idc %d", syn->level_idc); - mpp_log("syn->profile_idc %d", syn->profile_idc); - syn->keyframe_max_interval = 30; - if (g_frame_cnt == 0 || g_frame_cnt % syn->keyframe_max_interval == 0) { - syn->frame_coding_type = 1; //intra - syn->slice_type = 2; - } else { - syn->frame_coding_type = 0; //inter - syn->slice_type = 0; - } - syn->qp = 26; - csp_info.fmt = H264E_RKV_CSP_YUV420P; - csp_info.cswap = 0; //TODO: - csp_info.aswap = 0; //TODO: - syn->input_image_format = h264e_rkv_revert_csp(csp_info); - - syn->enable_cabac = 1; - syn->pic_init_qp = 26; - syn->chroma_qp_index_offset = 0; - syn->second_chroma_qp_index_offset = 0; - - syn->pps_id = 0 ; - syn->frame_num = 0; - syn->cabac_init_idc = 0; - - - syn->idr_pic_id = 0; - syn->pic_order_cnt_lsb = 0; - - - mpp_log("make syntax end"); -#else - if (fp_golden_syntax_in) { - FILE *fp = fp_golden_syntax_in; - char temp[512] = {0}; - RK_S32 data = 0; - - if (!fgets(temp, 512, fp)) - return MPP_EOS_STREAM_REACHED; - - H264E_HAL_FSCAN(fp, "%d\n", syn->pic_luma_width); - H264E_HAL_FSCAN(fp, "%d\n", syn->pic_luma_height); - H264E_HAL_FSCAN(fp, "%d\n", syn->level_idc); - H264E_HAL_FSCAN(fp, "%d\n", syn->profile_idc); - H264E_HAL_FSCAN(fp, "%d\n", syn->frame_coding_type); - H264E_HAL_FSCAN(fp, "%d\n", syn->qp); - H264E_HAL_FSCAN(fp, "%d\n", syn->input_image_format); - - H264E_HAL_FSCAN(fp, "%d\n", syn->enable_cabac); - H264E_HAL_FSCAN(fp, "%d\n", syn->pic_init_qp); - H264E_HAL_FSCAN(fp, "%d\n", syn->chroma_qp_index_offset); - H264E_HAL_FSCAN(fp, "%d\n", syn->second_chroma_qp_index_offset); - - H264E_HAL_FSCAN(fp, "%d\n", syn->slice_type); - H264E_HAL_FSCAN(fp, "%d\n", syn->pps_id); - H264E_HAL_FSCAN(fp, "%d\n", syn->frame_num); - H264E_HAL_FSCAN(fp, "%d\n", syn->cabac_init_idc); - - - H264E_HAL_FSCAN(fp, "%d\n", syn->idr_pic_id); - H264E_HAL_FSCAN(fp, "%d\n", syn->pic_order_cnt_lsb); - - H264E_HAL_FSCAN(fp, "%x\n", syn->keyframe_max_interval); - - fgets(temp, 512, fp); - - /* adjust */ - csp_info.fmt = syn->input_image_format; - csp_info.cswap = 0; //TODO: - csp_info.aswap = 0; //TODO: - syn->input_image_format = h264e_rkv_revert_csp(csp_info); - } else { - mpp_err("rkv_syntax_in.txt doesn't exits"); - } -#endif - syn->output_strm_limit_size = (RK_U32)(syn->pic_luma_width * syn->pic_luma_height * 3 / 2); - - h264e_hal_debug_leave(); - return MPP_OK; -} - -static MPP_RET h264e_hal_test_parse_options(int arg_num, char **arg_str, h264e_hal_test_cfg *cfg) -{ - RK_S32 k = 0; - memset(cfg, 0, sizeof(h264e_hal_test_cfg)); - - cfg->num_frames = 30; - for (k = 1; k < arg_num; k++) { - if (!strcmp("-hw", arg_str[k])) { - cfg->hw_mode = atoi(arg_str[k + 1]); - k++; - } - if (!strcmp("-yuv", arg_str[k])) { - strcpy(cfg->input_yuv_file_path, arg_str[k + 1]); - k++; - } - if (!strcmp("-syn", arg_str[k])) { - strcpy(cfg->input_syntax_file_path, arg_str[k + 1]); - k++; - } - - if (!strcmp("-w", arg_str[k])) { - cfg->pic_width = atoi(arg_str[k + 1]); - k++; - } - if (!strcmp("-h", arg_str[k])) { - cfg->pic_height = atoi(arg_str[k + 1]); - k++; - } - if (!strcmp("-fmt", arg_str[k])) { - cfg->src_format = atoi(arg_str[k + 1]); - k++; - } - if (!strcmp("-frame", arg_str[k])) { - cfg->num_frames = atoi(arg_str[k + 1]); - k++; - } - - /* coverage test */ - if (!strcmp("--test-qp", arg_str[k])) { - cfg->test.qp = atoi(arg_str[k + 1]); - k++; - } - if (!strcmp("--test-preproc", arg_str[k])) { - cfg->test.preproc = atoi(arg_str[k + 1]); - k++; - } - if (!strcmp("--test-osd", arg_str[k])) { - cfg->test.osd = atoi(arg_str[k + 1]); - k++; - } - if (!strcmp("--test-mbrc", arg_str[k])) { - cfg->test.mbrc = atoi(arg_str[k + 1]); - k++; - } - if (!strcmp("--test-roi", arg_str[k])) { - cfg->test.roi = atoi(arg_str[k + 1]); - k++; - } - } - - - if (!cfg->input_yuv_file_path) { - mpp_log("test param parse error: input_yuv_file_path is NULL"); - return MPP_NOK; - } -#if RKV_H264E_SDK_TEST - if (!cfg->pic_width) { - mpp_log("test param parse error: pic_width is 0"); - return MPP_NOK; - } - if (!cfg->pic_height) { - mpp_log("test param parse error: pic_height is 0"); - return MPP_NOK; - } -#else - if (!cfg->input_syntax_file_path) { - mpp_log("test param parse error: input_syntax_file_path is NULL"); - return MPP_NOK; - } -#endif - - if (cfg->hw_mode == 0) - test_device_id = HAL_RKVENC; - else if (cfg->hw_mode == 1) - test_device_id = HAL_VEPU; - else { - mpp_log("test param parse error: hw_mode is %d", cfg->hw_mode); - return MPP_NOK; - } - - mpp_log("======== hal converage test cfg (st) ======="); - if (cfg->test.qp) - mpp_log("cfg->test.qp %d", cfg->test.qp); - if (cfg->test.preproc) - mpp_log("cfg->test.preproc %d", cfg->test.preproc); - if (cfg->test.osd) - mpp_log("cfg->test.osd %d", cfg->test.osd); - if (cfg->test.mbrc) - mpp_log("cfg->test.mbrc %d", cfg->test.mbrc); - if (cfg->test.roi) - mpp_log("cfg->test.roi %d", cfg->test.roi); - mpp_log("======== hal converage test cfg (ed) ======="); - - return MPP_OK; -} - -static void h264e_hal_test_init(h264e_hal_context *ctx, HalTaskInfo *task_info) -{ - memset(ctx, 0, sizeof(h264e_hal_context)); - memset(task_info, 0, sizeof(HalTaskInfo)); -} - -static void h264e_hal_test_deinit(h264e_hal_context *ctx, HalTaskInfo *task_info) -{ - (void)ctx; - (void)task_info; -} - -MPP_RET h264_hal_test_call_back(void *control, void *feedback) -{ - (void)control; - h264e_feedback *fb = (h264e_feedback *)feedback; - (void)fb; - - mpp_log("h264_hal_test_call_back, enter"); - mpp_log("h264_hal_test_call_back, leave"); - - return MPP_OK; -} - -static void h264e_hal_set_extra_info_cfg(h264e_control_extra_info_cfg *info, h264e_syntax *syn) -{ - info->chroma_qp_index_offset = syn->chroma_qp_index_offset; - info->enable_cabac = syn->enable_cabac; - info->pic_init_qp = syn->pic_init_qp; - info->pic_luma_height = syn->pic_luma_height; - info->pic_luma_width = syn->pic_luma_width; - info->transform8x8_mode = syn->transform8x8_mode; - - info->input_image_format = syn->input_image_format; - info->profile_idc = syn->profile_idc; - info->level_idc = syn->level_idc; - info->keyframe_max_interval = syn->keyframe_max_interval; - info->second_chroma_qp_index_offset = syn->second_chroma_qp_index_offset; - info->pps_id = syn->pps_id; -} - -MPP_RET h264e_hal_vpu_test() -{ - MPP_RET ret = MPP_OK; - h264e_hal_context ctx; - MppHalCfg hal_cfg; - HalTaskInfo task_info; - h264e_syntax syntax_data; - h264e_control_extra_info_cfg extra_info_cfg; - MppPacket extra_info_pkt; - RK_U8 extra_info_buf[H264E_MAX_PACKETED_PARAM_SIZE] = {0}; - MppBufferGroup hw_input_buf_grp = NULL; - MppBufferGroup hw_output_buf_grp = NULL; - MppBuffer hw_input_buf = NULL; //Y, U, V - MppBuffer hw_output_strm_buf = NULL; - RK_U32 frame_luma_size = 0; - RK_S64 t0; - - RK_U8 *input_sw_buf = mpp_malloc(RK_U8, MAX_FRAME_TOTAL_SIZE); - - mpp_packet_init(&extra_info_pkt, (void *)extra_info_buf, H264E_MAX_PACKETED_PARAM_SIZE); - - get_vpu_syntax_in(&syntax_data, hw_input_buf, hw_output_strm_buf, frame_luma_size); - if (fp_golden_syntax_in) - fseek(fp_golden_syntax_in, 0L, SEEK_SET); - - frame_luma_size = syntax_data.pic_luma_width * syntax_data.pic_luma_height; - - h264e_hal_test_init(&ctx, &task_info); - - if (MPP_OK != mpp_buffer_group_get_internal(&hw_input_buf_grp, MPP_BUFFER_TYPE_ION)) { - mpp_err("hw_input_buf_grp get failed, test is ended early"); - goto __test_end; - } - if (MPP_OK != mpp_buffer_group_get_internal(&hw_output_buf_grp, MPP_BUFFER_TYPE_ION)) { - mpp_err("hw_output_buf_grp get failed, test is ended early"); - goto __test_end; - } - - mpp_buffer_get(hw_input_buf_grp, &hw_input_buf, frame_luma_size*3/2); - mpp_buffer_get(hw_output_buf_grp, &hw_output_strm_buf, 1024 * 1024 * 2); - - task_info.enc.syntax.data = (void *)&syntax_data; - task_info.enc.input = hw_input_buf; - task_info.enc.output = hw_input_buf; - - hal_cfg.hal_int_cb.callBack = h264_hal_test_call_back; - hal_cfg.hal_int_cb.opaque = NULL; //control context - hal_cfg.device_id = test_device_id; - hal_h264e_init(&ctx, &hal_cfg); - - h264e_hal_set_extra_info_cfg(&extra_info_cfg, &syntax_data); - hal_h264e_vpu_control(&ctx, MPP_ENC_SET_EXTRA_INFO, &extra_info_cfg); - hal_h264e_vpu_control(&ctx, MPP_ENC_GET_EXTRA_INFO, &extra_info_pkt); - - do { - /* get golden input */ - if (MPP_EOS_STREAM_REACHED == get_vpu_syntax_in(&syntax_data, hw_input_buf, hw_output_strm_buf, frame_luma_size)) { - mpp_log("syntax input file end, total %d frames are encoded, test is ended", g_frame_cnt); - break; - } - - ret = get_h264e_yuv_in_one_frame(input_sw_buf, &syntax_data, hw_input_buf); - - if (ret == MPP_EOS_STREAM_REACHED) { - mpp_log("yuv file end, total %d frames are encoded, test is ended", g_frame_cnt); - break; - } else if (ret == MPP_NOK) { - mpp_err("read yuv file failed, test is ended early"); - goto __test_end; - } - - - /* generate registers */ - hal_h264e_gen_regs(&ctx, &task_info); - - - /* run hardware */ - t0 = mpp_time(); - mpp_log("hal_h264e_start time : %lld ", (RK_S64)(t0 / 1000)); - - hal_h264e_start(&ctx, &task_info); - hal_h264e_wait(&ctx, &task_info); - - g_frame_cnt ++; - } while (1); - - -__test_end: - hal_h264e_deinit(&ctx); - h264e_hal_test_deinit(&ctx, &task_info); - - mpp_packet_deinit(&extra_info_pkt); - //free sw buf - if (input_sw_buf) { - mpp_free(input_sw_buf); - input_sw_buf = NULL; - } - - //free hw buf - if (hw_input_buf) - mpp_buffer_put(hw_input_buf); - if (hw_output_strm_buf) - mpp_buffer_put(hw_output_strm_buf); - - if (hw_input_buf_grp) - mpp_buffer_group_put(hw_input_buf_grp); - if (hw_output_buf_grp) - mpp_buffer_group_put(hw_output_buf_grp); - - return MPP_OK; -} - - -MPP_RET h264e_hal_rkv_test(h264e_hal_test_cfg *test_cfg) -{ - RK_S32 k = 0; - MPP_RET ret = MPP_OK; - h264e_hal_context ctx; - MppHalCfg hal_cfg; - HalTaskInfo task_info; - h264e_control_extra_info_cfg extra_info_cfg; - MppPacket extra_info_pkt; - RK_U8 extra_info_buf[H264E_MAX_PACKETED_PARAM_SIZE] = {0}; - //h264e_hal_rkv_dbg_info dbg_info; - h264e_syntax syntax_data[RKV_H264E_LINKTABLE_FRAME_NUM]; - MppBufferGroup hw_input_buf_grp = NULL; - MppBufferGroup hw_output_buf_grp = NULL; - MppBuffer hw_input_buf_mul[RKV_H264E_LINKTABLE_FRAME_NUM] = {NULL}; - MppBuffer hw_output_strm_buf_mul[RKV_H264E_LINKTABLE_FRAME_NUM] = {NULL}; - RK_U32 frame_luma_stride = 0; - RK_S64 t0; - - mpp_packet_init(&extra_info_pkt, (void *)extra_info_buf, H264E_MAX_PACKETED_PARAM_SIZE); - - - get_rkv_syntax_in(&syntax_data[0], hw_input_buf_mul, hw_output_strm_buf_mul, test_cfg); - if (fp_golden_syntax_in) - fseek(fp_golden_syntax_in, 0L, SEEK_SET); - - - frame_luma_stride = ((syntax_data[0].pic_luma_width + 15) & (~15)) * ((syntax_data[0].pic_luma_height + 15) & (~15)); - - h264e_hal_test_init(&ctx, &task_info); - - - if (MPP_OK != mpp_buffer_group_get_internal(&hw_input_buf_grp, MPP_BUFFER_TYPE_ION)) { - mpp_err("hw_input_buf_grp get failed, test is ended early"); - goto __test_end; - } - if (MPP_OK != mpp_buffer_group_get_internal(&hw_output_buf_grp, MPP_BUFFER_TYPE_ION)) { - mpp_err("hw_output_buf_grp get failed, test is ended early"); - goto __test_end; - } - - for (k = 0; k < RKV_H264E_LINKTABLE_FRAME_NUM; k++) - mpp_buffer_get(hw_input_buf_grp, &hw_input_buf_mul[k], frame_luma_stride * 3 / 2); - - for (k = 0; k < RKV_H264E_LINKTABLE_FRAME_NUM; k++) - mpp_buffer_get(hw_output_buf_grp, &hw_output_strm_buf_mul[k], syntax_data[0].pic_luma_width * syntax_data[0].pic_luma_height * 3 / 2); - - - hal_cfg.hal_int_cb.callBack = h264_hal_test_call_back; - hal_cfg.hal_int_cb.opaque = NULL; //control context - hal_cfg.device_id = test_device_id; - hal_h264e_init(&ctx, &hal_cfg); - - ctx.test_cfg = (void *)&test_cfg->test; - - h264e_hal_set_extra_info_cfg(&extra_info_cfg, &syntax_data[0]); //TODO: use dbg info for input instead - hal_h264e_rkv_control(&ctx, MPP_ENC_SET_EXTRA_INFO, &extra_info_cfg); - hal_h264e_rkv_control(&ctx, MPP_ENC_GET_EXTRA_INFO, &extra_info_pkt); - - do { - /* get golden input */ - if (g_frame_read_cnt <= g_frame_cnt) { - h264e_syntax *syn = NULL; - RK_S32 frame_num = RKV_H264E_ENC_MODE == 1 ? 1 : RKV_H264E_LINKTABLE_FRAME_NUM; - mpp_log("read %d frames input", frame_num); - for (k = 0; k < frame_num; k++, g_frame_read_cnt++) { - syn = &syntax_data[g_frame_read_cnt % RKV_H264E_LINKTABLE_FRAME_NUM]; - if (MPP_EOS_STREAM_REACHED == get_rkv_syntax_in(syn, hw_input_buf_mul, hw_output_strm_buf_mul, test_cfg)) { - mpp_log("syntax input file end, total %d frames are encoded, test is ended", g_frame_cnt); - goto __test_end; - } - ret = get_rkv_h264e_yuv_in_frame(syn, hw_input_buf_mul); - if (ret == MPP_EOS_STREAM_REACHED) { - if (g_frame_cnt == test_cfg->num_frames) { - mpp_log("total %d frames are encoded, test is ended", g_frame_cnt); - goto __test_end; - } else { - fseek(fp_h264e_yuv_in, 0L, SEEK_SET); - ret = get_rkv_h264e_yuv_in_frame(syn, hw_input_buf_mul); - } - } else if (ret == MPP_NOK) { - mpp_err("read yuv file failed, test is ended early"); - goto __test_end; - } - } - } - - task_info.enc.syntax.data = (void *)&syntax_data[g_frame_cnt % RKV_H264E_LINKTABLE_FRAME_NUM]; - task_info.enc.input = hw_input_buf_mul[g_frame_cnt % RKV_H264E_LINKTABLE_FRAME_NUM]; - task_info.enc.output = hw_output_strm_buf_mul[g_frame_cnt % RKV_H264E_LINKTABLE_FRAME_NUM]; - /* generate registers */ - hal_h264e_gen_regs(&ctx, &task_info); - - - /* run hardware */ - t0 = mpp_time(); - mpp_log("hal_h264e_start time : %lld ", (RK_S64)(t0 / 1000)); - - hal_h264e_start(&ctx, &task_info); - hal_h264e_wait(&ctx, &task_info); - - g_frame_cnt ++; - - if(g_frame_cnt==test_cfg->num_frames) { - mpp_log("test_cfg->num_frames %d reached, end test", test_cfg->num_frames); - goto __test_end; - } - - } while (1); - - -__test_end: - mpp_packet_deinit(&extra_info_pkt); - - hal_h264e_deinit(&ctx); - h264e_hal_test_deinit(&ctx, &task_info); - - //free hw buf - for (k = 0; k < RKV_H264E_LINKTABLE_FRAME_NUM; k++) { - if (hw_input_buf_mul[k]) - mpp_buffer_put(hw_input_buf_mul[k]); - if (hw_output_strm_buf_mul[k]) - mpp_buffer_put(hw_output_strm_buf_mul[k]); - } - - if (hw_input_buf_grp) - mpp_buffer_group_put(hw_input_buf_grp); - if (hw_output_buf_grp) - mpp_buffer_group_put(hw_output_buf_grp); - - return MPP_OK; -} - - -int main(int argc, char **argv) -{ - h264e_hal_test_cfg test_cfg; - - mpp_log("******* h264e hal test start *******"); - - if (MPP_OK != h264e_hal_test_parse_options(argc, argv, &test_cfg)) { - mpp_err("parse opitons failed, test is ended early"); - goto __test_end; - } - - if (test_device_id == HAL_VEPU) { - if (MPP_OK != h264e_vpu_test_open_files(test_cfg)) { - mpp_err("open files error, test is ended early"); - goto __test_end; - } - mpp_log("choose h264e_hal_vpu_test"); - h264e_hal_vpu_test(); - } else { - if (MPP_OK != h264e_rkv_test_open_files(test_cfg)) { - mpp_err("open files error, test is ended early"); - goto __test_end; - } - mpp_log("choose h264e_hal_rkv_test"); - h264e_hal_rkv_test(&test_cfg); - } - -__test_end: - - h264e_test_close_files(); - - mpp_log("******* h264e hal test end *******"); - return 0; -} +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define MODULE_TAG "h264e_hal_test" + +#include +#include +#include +#include + +#ifdef RKPLATFORM +#include +#endif + +#include "mpp_log.h" +#include "mpp_mem.h" +#include "mpp_time.h" +#include "mpp_common.h" +#include "mpp_frame.h" + +#include "hal_h264e_api.h" +#include "hal_h264e.h" +#include "hal_h264e_vpu.h" +#include "hal_h264e_rkv.h" + + +static HalDeviceId test_device_id = HAL_RKVENC; + +#define MAX_FRAME_LUMA_SIZE (4096*2304) +#define MAX_FRAME_TOTAL_SIZE (MAX_FRAME_LUMA_SIZE*3/2) +#define GET_U32(val) ((RK_U32)(*((RK_U32 *)&(val)))) +//#define GET_U32(val) ((RK_U32)(val)) + +#define H264E_HAL_FSCAN(fp, fmt, dst) \ + do { \ + fscanf(fp, fmt, &data); \ + dst = data; \ + fgets(temp, 512, fp); \ + }while(0) + +//golden data from on2 project +FILE *fp_golden_syntax_in = NULL; +FILE *fp_mpp_syntax_in = NULL; +FILE *fp_mpp_reg_in = NULL; +FILE *fp_mpp_reg_out = NULL; +FILE *fp_h264e_yuv_in = NULL; +FILE *fp_mpp_strm_out = NULL; +FILE *fp_mpp_feedback = NULL; +FILE *fp_mpp_yuv_in = NULL; +FILE *fp_mpp_wr2hw_reg_in = NULL; + +RK_U32 g_frame_cnt = 0; +RK_U32 g_frame_read_cnt = 0; +typedef struct h264e_hal_test_cfg_t { + RK_U32 hw_mode; + char input_syntax_file_path[256]; + char input_yuv_file_path[256]; + RK_U32 pic_width; + RK_U32 pic_height; + RK_U32 src_format; + RK_U32 num_frames; + + h264e_hal_rkv_coveragetest_cfg test; +} h264e_hal_test_cfg; + +static RK_U32 h264e_rkv_revert_csp(h264e_hal_rkv_csp_info csp_info) +{ + h264e_hal_rkv_csp fmt = (h264e_hal_rkv_csp)csp_info.fmt; + RK_U32 cswap = csp_info.cswap; + RK_U32 aswap = csp_info.aswap; + MppFrameFormat dst_fmt; + + switch (fmt) { + case H264E_RKV_CSP_YUV420P: { + dst_fmt = MPP_FMT_YUV420P; + break; + } + case H264E_RKV_CSP_YUV420SP: { + dst_fmt = cswap ? MPP_FMT_YUV420SP_VU : MPP_FMT_YUV420SP; + break; + } + case H264E_RKV_CSP_YUV422P: { + dst_fmt = MPP_FMT_YUV422P; + break; + } + case H264E_RKV_CSP_YUV422SP: { + dst_fmt = cswap ? MPP_FMT_YUV422SP_VU : MPP_FMT_YUV422SP; + break; + } + case H264E_RKV_CSP_YUYV422: { + dst_fmt = MPP_FMT_YUV422_YUYV; + break; + } + case H264E_RKV_CSP_UYVY422: { + dst_fmt = MPP_FMT_YUV422_UYVY; + break; + } + case H264E_RKV_CSP_BGR565: { + dst_fmt = cswap ? MPP_FMT_RGB565 : MPP_FMT_BGR565; + break; + } + case H264E_RKV_CSP_BGR888: { + dst_fmt = cswap ? MPP_FMT_RGB888 : MPP_FMT_BGR888; + break; + } + case H264E_RKV_CSP_BGRA8888: { + if (aswap) + dst_fmt = cswap ? MPP_FMT_ABGR8888 : MPP_FMT_ARGB8888; + else + dst_fmt = MPP_FMT_BUTT; + + break; + } + default: { + h264e_hal_log_err("invalid csp_info.fmt %d, csp_info.cswap %d, csp_info.aswap %d", + csp_info.fmt, csp_info.cswap, csp_info.aswap); + dst_fmt = MPP_FMT_BUTT; + } + } + + if (dst_fmt == MPP_FMT_BUTT) { + h264e_hal_log_err("revert_csp error, src_fmt %d, dst_fmt %d", fmt, dst_fmt); + } + + return (RK_U32)dst_fmt; +} + +static RK_U32 h264e_vpu_revert_csp(RK_U32 csp) +{ + h264e_hal_vpu_csp fmt = (h264e_hal_vpu_csp)csp; + MppFrameFormat dst_fmt; + + switch (fmt) { + case H264E_VPU_CSP_YUV420P: { + dst_fmt = MPP_FMT_YUV420P; + break; + } + case H264E_VPU_CSP_YUV420SP: { + dst_fmt = MPP_FMT_YUV420SP; + break; + } + case H264E_VPU_CSP_YUYV422: { + dst_fmt = MPP_FMT_YUV422_YUYV; + break; + } + case H264E_VPU_CSP_UYVY422: { + dst_fmt = MPP_FMT_YUV422_UYVY; + break; + } + case H264E_VPU_CSP_RGB565: { + dst_fmt = MPP_FMT_RGB565; + break; + } + case H264E_VPU_CSP_BGR565: { + dst_fmt = MPP_FMT_BGR565; + break; + } + case H264E_VPU_CSP_RGB555: { + dst_fmt = MPP_FMT_RGB555; + break; + } + case H264E_VPU_CSP_BGR555: { + dst_fmt = MPP_FMT_BGR555; + break; + } + case H264E_VPU_CSP_RGB444: { + dst_fmt = MPP_FMT_RGB444; + break; + } + case H264E_VPU_CSP_BGR444: { + dst_fmt = MPP_FMT_BGR444; + break; + } + case H264E_VPU_CSP_RGB888: { + dst_fmt = MPP_FMT_RGB888; + break; + } + case H264E_VPU_CSP_BGR888: { + dst_fmt = MPP_FMT_BGR888; + break; + } + case H264E_VPU_CSP_RGB101010: { + dst_fmt = MPP_FMT_RGB101010; + break; + } + case H264E_VPU_CSP_BGR101010: { + dst_fmt = MPP_FMT_BGR101010; + break; + } + default: { + h264e_hal_log_err("invalid csp %d", csp); + dst_fmt = MPP_FMT_BUTT; + } + } + + return (RK_U32)dst_fmt; +} + + +static MPP_RET h264e_rkv_test_open_files(h264e_hal_test_cfg test_cfg) +{ + char base_path[512]; + char full_path[512]; + strcpy(base_path, "/sdcard/h264e_data/"); + + sprintf(full_path, "%s", test_cfg.input_yuv_file_path); + fp_h264e_yuv_in = fopen(full_path, "rb"); + if (!fp_h264e_yuv_in) { + mpp_err("%s open error", full_path); + return MPP_ERR_OPEN_FILE; + } + +#if !RKV_H264E_SDK_TEST + sprintf(full_path, "%s", test_cfg.input_syntax_file_path); + fp_golden_syntax_in = fopen(full_path, "rb"); + if (!fp_golden_syntax_in) { + mpp_err("%s open error", full_path); + return MPP_ERR_OPEN_FILE; + } +#endif + +#if 0 + sprintf(full_path, "%s%s", base_path, "mpp_yuv_in.yuv"); + fp_mpp_yuv_in = fopen(full_path, "wb"); + if (!fp_mpp_yuv_in) { + mpp_err("%s open error", full_path); + return MPP_ERR_OPEN_FILE; + } +#endif + + return MPP_OK; +} + + +static MPP_RET h264e_vpu_test_open_files(h264e_hal_test_cfg test_cfg) +{ + char base_path[512]; + char full_path[512]; + strcpy(base_path, "/sdcard/h264e_data/"); + + sprintf(full_path, "%s", test_cfg.input_yuv_file_path); + fp_h264e_yuv_in = fopen(full_path, "rb"); + if (!fp_h264e_yuv_in) { + mpp_err("%s open error", full_path); + return MPP_ERR_OPEN_FILE; + } + + sprintf(full_path, "%s", test_cfg.input_syntax_file_path); + fp_golden_syntax_in = fopen(full_path, "rb"); + if (!fp_golden_syntax_in) { + mpp_err("%s open error", full_path); + return MPP_ERR_OPEN_FILE; + } + + sprintf(full_path, "%s%s", base_path, "mpp_yuv_in.yuv"); + fp_mpp_yuv_in = fopen(full_path, "wb"); + if (!fp_mpp_yuv_in) { + mpp_err("%s open error", full_path); + return MPP_ERR_OPEN_FILE; + } + + return MPP_OK; +} + + + +static MPP_RET h264e_test_close_files() +{ + if (fp_h264e_yuv_in) { + fclose(fp_h264e_yuv_in); + fp_h264e_yuv_in = NULL; + } + + if (fp_golden_syntax_in) { + fclose(fp_golden_syntax_in); + fp_golden_syntax_in = NULL; + } + + if (fp_mpp_syntax_in) { + fclose(fp_mpp_syntax_in); + fp_mpp_syntax_in = NULL; + } + + + if (fp_mpp_yuv_in) { + fclose(fp_mpp_yuv_in); + fp_mpp_yuv_in = NULL; + } + + if (fp_mpp_reg_in) { + fclose(fp_mpp_reg_in); + fp_mpp_reg_in = NULL; + } + + if (fp_mpp_reg_out) { + fclose(fp_mpp_reg_out); + fp_mpp_reg_out = NULL; + } + + if (fp_mpp_strm_out) { + fclose(fp_mpp_strm_out); + fp_mpp_strm_out = NULL; + } + + if (fp_mpp_feedback) { + fclose(fp_mpp_feedback); + fp_mpp_feedback = NULL; + } + + if (fp_mpp_wr2hw_reg_in) { + fclose(fp_mpp_wr2hw_reg_in); + fp_mpp_wr2hw_reg_in = NULL; + } + + return MPP_OK; +} + +static MPP_RET get_rkv_h264e_yuv_in_frame(h264e_syntax *syn, MppBuffer *hw_buf) +{ + RK_U32 read_ret = 0; + RK_U32 frame_luma_size = syn->pic_luma_width * syn->pic_luma_height; + RK_U32 frame_size = frame_luma_size * 3 / 2; + RK_U8 *hw_buf_ptr = (RK_U8 *)mpp_buffer_get_ptr(hw_buf[g_frame_read_cnt % RKV_H264E_LINKTABLE_FRAME_NUM]);; + mpp_assert(fp_h264e_yuv_in); + + read_ret = (RK_U32)fread(hw_buf_ptr, 1, frame_size, fp_h264e_yuv_in); + if (read_ret == 0) { + mpp_log("yuv file end, nothing is read in %d frame", g_frame_read_cnt); + return MPP_EOS_STREAM_REACHED; + } else if (read_ret != frame_size) { + mpp_err("read yuv frame %d error, needed:%d, actual:%d", g_frame_read_cnt, frame_size, read_ret); + return MPP_NOK; + } else { + mpp_log("read frame %d size %d successfully", g_frame_read_cnt, read_ret); + } + + if (fp_mpp_yuv_in) { + fwrite(hw_buf_ptr, 1, frame_size, fp_mpp_yuv_in); + } + + return MPP_OK; +} + +static MPP_RET get_h264e_yuv_in_one_frame(RK_U8 *sw_buf, h264e_syntax *syn, MppBuffer hw_buf) +{ + RK_U32 read_ret = 0; + RK_U32 frame_luma_size = syn->pic_luma_width * syn->pic_luma_height; + RK_U32 frame_size = frame_luma_size * 3 / 2; + mpp_assert(fp_h264e_yuv_in); + + //TODO: remove sw_buf, read & write fd ptr directly + read_ret = (RK_U32)fread(sw_buf, 1, frame_size, fp_h264e_yuv_in); + if (read_ret == 0) { + mpp_log("yuv file end, nothing is read in frame %d", g_frame_cnt); + return MPP_EOS_STREAM_REACHED; + } else if (read_ret != frame_size) { + mpp_err("read yuv one frame error, needed:%d, actual:%d", frame_size, read_ret); + return MPP_NOK; + } else { + mpp_log("read frame %d size %d successfully", g_frame_cnt, frame_size); + } + + + mpp_buffer_write(hw_buf, 0, sw_buf, frame_size); + + if (fp_mpp_yuv_in) { + memcpy(sw_buf, mpp_buffer_get_ptr(hw_buf), frame_size); + fwrite(sw_buf, 1, frame_luma_size, fp_mpp_yuv_in); + } + return MPP_OK; +} + +static MPP_RET get_vpu_syntax_in(h264e_syntax *syn, MppBuffer hw_in_buf, MppBuffer hw_output_strm_buf, RK_U32 frame_luma_size) +{ + RK_S32 k = 0; + mpp_assert(fp_golden_syntax_in); + memset(syn, 0, sizeof(h264e_syntax)); + + if (fp_golden_syntax_in) { + char temp[512] = {0}; + RK_S32 data = 0; + if (!fgets(temp, 512, fp_golden_syntax_in)) + return MPP_EOS_STREAM_REACHED; + + fscanf(fp_golden_syntax_in, "%d", &data); + fgets(temp, 512, fp_golden_syntax_in); + syn->frame_coding_type = data; + + + fscanf(fp_golden_syntax_in, "%d", &data); + fgets(temp, 512, fp_golden_syntax_in); + syn->pic_init_qp = data; + + fscanf(fp_golden_syntax_in, "%d", &data); + fgets(temp, 512, fp_golden_syntax_in); + syn->slice_alpha_offset = data; + + fscanf(fp_golden_syntax_in, "%d", &data); + fgets(temp, 512, fp_golden_syntax_in); + syn->slice_beta_offset = data; + + fscanf(fp_golden_syntax_in, "%d", &data); + fgets(temp, 512, fp_golden_syntax_in); + syn->chroma_qp_index_offset = data; + + fscanf(fp_golden_syntax_in, "%d", &data); + fgets(temp, 512, fp_golden_syntax_in); + syn->filter_disable = data; + + fscanf(fp_golden_syntax_in, "%d", &data); + fgets(temp, 512, fp_golden_syntax_in); + syn->idr_pic_id = data; + + fscanf(fp_golden_syntax_in, "%d", &data); + fgets(temp, 512, fp_golden_syntax_in); + syn->pps_id = data; + + fscanf(fp_golden_syntax_in, "%d", &data); + fgets(temp, 512, fp_golden_syntax_in); + syn->frame_num = data; + + fscanf(fp_golden_syntax_in, "%d", &data); + fgets(temp, 512, fp_golden_syntax_in); + syn->slice_size_mb_rows = data; + + fscanf(fp_golden_syntax_in, "%d", &data); + fgets(temp, 512, fp_golden_syntax_in); + syn->h264_inter4x4_disabled = data; + + fscanf(fp_golden_syntax_in, "%d", &data); + fgets(temp, 512, fp_golden_syntax_in); + syn->enable_cabac = data; + + fscanf(fp_golden_syntax_in, "%d", &data); + fgets(temp, 512, fp_golden_syntax_in); + syn->transform8x8_mode = data; + + fscanf(fp_golden_syntax_in, "%d", &data); + fgets(temp, 512, fp_golden_syntax_in); + syn->cabac_init_idc = data; + + fscanf(fp_golden_syntax_in, "%d", &data); + fgets(temp, 512, fp_golden_syntax_in); + syn->qp = data; + + fscanf(fp_golden_syntax_in, "%d", &data); + fgets(temp, 512, fp_golden_syntax_in); + syn->mad_qp_delta = data; + + fscanf(fp_golden_syntax_in, "%d", &data); + fgets(temp, 512, fp_golden_syntax_in); + syn->mad_threshold = data; + + fscanf(fp_golden_syntax_in, "%d", &data); + fgets(temp, 512, fp_golden_syntax_in); + syn->qp_min = data; + + fscanf(fp_golden_syntax_in, "%d", &data); + fgets(temp, 512, fp_golden_syntax_in); + syn->qp_max = data; + + fscanf(fp_golden_syntax_in, "%d", &data); + fgets(temp, 512, fp_golden_syntax_in); + syn->cp_distance_mbs = data; + + for (k = 0; k < 10; k++) { + fscanf(fp_golden_syntax_in, "%d", &data); + fgets(temp, 512, fp_golden_syntax_in); + syn->cp_target[k] = data; + } + + for (k = 0; k < 7; k++) { + fscanf(fp_golden_syntax_in, "%d", &data); + fgets(temp, 512, fp_golden_syntax_in); + syn->target_error[k] = data; + } + for (k = 0; k < 7; k++) { + fscanf(fp_golden_syntax_in, "%d", &data); + fgets(temp, 512, fp_golden_syntax_in); + syn->delta_qp[k] = data; + } + + fscanf(fp_golden_syntax_in, "%d", &data); + fgets(temp, 512, fp_golden_syntax_in); + syn->output_strm_limit_size = data; + + fscanf(fp_golden_syntax_in, "%d", &data); + fgets(temp, 512, fp_golden_syntax_in); + syn->pic_luma_width = data; + + fscanf(fp_golden_syntax_in, "%d", &data); + fgets(temp, 512, fp_golden_syntax_in); + syn->pic_luma_height = data; + + fscanf(fp_golden_syntax_in, "%d", &data); + fgets(temp, 512, fp_golden_syntax_in); + syn->input_image_format = data; + + fscanf(fp_golden_syntax_in, "%d", &data); + fgets(temp, 512, fp_golden_syntax_in); + syn->color_conversion_coeff_a = data; + + fscanf(fp_golden_syntax_in, "%d", &data); + fgets(temp, 512, fp_golden_syntax_in); + syn->color_conversion_coeff_b = data; + + fscanf(fp_golden_syntax_in, "%d", &data); + fgets(temp, 512, fp_golden_syntax_in); + syn->color_conversion_coeff_c = data; + + fscanf(fp_golden_syntax_in, "%d", &data); + fgets(temp, 512, fp_golden_syntax_in); + syn->color_conversion_coeff_e = data; + + fscanf(fp_golden_syntax_in, "%d", &data); + fgets(temp, 512, fp_golden_syntax_in); + syn->color_conversion_coeff_f = data; + + fscanf(fp_golden_syntax_in, "%d", &data); + fgets(temp, 512, fp_golden_syntax_in); + + fscanf(fp_golden_syntax_in, "%d", &data); + fgets(temp, 512, fp_golden_syntax_in); + + fscanf(fp_golden_syntax_in, "%d", &data); + fgets(temp, 512, fp_golden_syntax_in); + + fgets(temp, 512, fp_golden_syntax_in); + } + + if (hw_in_buf) + syn->input_luma_addr = mpp_buffer_get_fd(hw_in_buf); + syn->input_cb_addr = syn->input_luma_addr | (frame_luma_size << 10); + syn->input_cr_addr = syn->input_cb_addr | ((frame_luma_size/4) << 10); + + if (hw_output_strm_buf) + syn->output_strm_addr = mpp_buffer_get_fd(hw_output_strm_buf); + + /* adjust */ + syn->input_image_format = h264e_vpu_revert_csp(syn->input_image_format); + + return MPP_OK; +} + +#if 0 +static void dump_rkv_mpp_dbg_info(h264e_hal_rkv_dbg_info *info, h264e_syntax *syn) +{ + if (fp_mpp_syntax_in) { + RK_S32 k = 0; + FILE *fp = fp_mpp_syntax_in; + fprintf(fp, "#FRAME %d\n", g_frame_read_cnt); + + fprintf(fp, "%-16d %s\n", syn->pic_luma_width, "pic_luma_width"); + fprintf(fp, "%-16d %s\n", syn->pic_luma_height, "pic_luma_height"); + fprintf(fp, "%-16d %s\n", syn->level_idc, "level_idc"); + fprintf(fp, "%-16d %s\n", syn->profile_idc, "profile_idc"); + fprintf(fp, "%-16d %s\n", syn->frame_coding_type, "frame_coding_type"); + + fprintf(fp, "%-16d %s\n", info->swreg02.lkt_num, "swreg02.lkt_num"); + fprintf(fp, "%-16d %s\n", info->swreg02.rkvenc_cmd, "swreg02.rkvenc_cmd"); + fprintf(fp, "%-16d %s\n", info->swreg02.enc_cke, "swreg02.enc_cke"); + + fprintf(fp, "%-16d %s\n", info->swreg04.lkt_addr, "swreg04.lkt_addr"); + + fprintf(fp, "%-16d %s\n", info->swreg05.ofe_fnsh, "swreg05.ofe_fnsh"); + fprintf(fp, "%-16d %s\n", info->swreg05.lkt_fnsh, "swreg05.lkt_fnsh"); + fprintf(fp, "%-16d %s\n", info->swreg05.clr_fnsh, "swreg05.clr_fnsh"); + fprintf(fp, "%-16d %s\n", info->swreg05.ose_fnsh, "swreg05.ose_fnsh"); + fprintf(fp, "%-16d %s\n", info->swreg05.bs_ovflr, "swreg05.bs_ovflr"); + fprintf(fp, "%-16d %s\n", info->swreg05.brsp_ful, "swreg05.brsp_ful"); + fprintf(fp, "%-16d %s\n", info->swreg05.brsp_err, "swreg05.brsp_err"); + fprintf(fp, "%-16d %s\n", info->swreg05.rrsp_err, "swreg05.rrsp_err"); + fprintf(fp, "%-16d %s\n", info->swreg05.tmt_err, "swreg05.tmt_err"); + + fprintf(fp, "%-16d %s\n", info->swreg10.roi_enc, "swreg10.roi_enc"); + fprintf(fp, "%-16d %s\n", info->swreg10.cur_frm_ref, "swreg10.cur_frm_ref"); + fprintf(fp, "%-16d %s\n", info->swreg10.mei_stor, "swreg10.mei_stor"); + fprintf(fp, "%-16d %s\n", info->swreg10.bs_scp, "swreg10.bs_scp"); + fprintf(fp, "%-16d %s\n", info->swreg10.pic_qp, "swreg10.pic_qp"); + fprintf(fp, "%-16d %s\n", info->swreg10.slice_int, "swreg10.slice_int"); + fprintf(fp, "%-16d %s\n", info->swreg10.node_int, "swreg10.node_int"); + + fprintf(fp, "%-16d %s\n", info->swreg11.ppln_enc_lmt, "swreg11.ppln_enc_lmt"); + fprintf(fp, "%-16d %s\n", info->swreg11.rfp_load_thrd, "swreg11.rfp_load_thrd"); + + fprintf(fp, "%-16d %s\n", info->swreg12.src_bus_edin, "swreg12.src_bus_edin"); + + + fprintf(fp, "%-16d %s\n", info->swreg13.axi_brsp_cke, "swreg13.axi_brsp_cke"); + + fprintf(fp, "%-16d %s\n", info->swreg14.src_aswap, "swreg14.src_aswap"); + fprintf(fp, "%-16d %s\n", info->swreg14.src_cswap, "swreg14.src_cswap"); + fprintf(fp, "%-16d %s\n", info->swreg14.src_cfmt, "swreg14.src_cfmt"); + fprintf(fp, "%-16d %s\n", info->swreg14.src_clip_dis, "swreg14.src_clip_dis"); + + fprintf(fp, "%-16d %s\n", info->swreg15.wght_b2y, "swreg15.wght_b2y"); + fprintf(fp, "%-16d %s\n", info->swreg15.wght_g2y, "swreg15.wght_g2y"); + fprintf(fp, "%-16d %s\n", info->swreg15.wght_r2y, "swreg15.wght_r2y"); + + fprintf(fp, "%-16d %s\n", info->swreg16.wght_b2u, "swreg16.wght_b2u"); + fprintf(fp, "%-16d %s\n", info->swreg16.wght_g2u, "swreg16.wght_g2u"); + fprintf(fp, "%-16d %s\n", info->swreg16.wght_r2u, "swreg16.wght_r2u"); + + fprintf(fp, "%-16d %s\n", info->swreg17.wght_b2v, "swreg17.wght_b2v"); + fprintf(fp, "%-16d %s\n", info->swreg17.wght_g2v, "swreg17.wght_g2v"); + fprintf(fp, "%-16d %s\n", info->swreg17.wght_r2v, "swreg17.wght_r2v"); + + fprintf(fp, "%-16d %s\n", info->swreg18.ofst_rgb2v, "swreg18.ofst_rgb2v"); + fprintf(fp, "%-16d %s\n", info->swreg18.ofst_rgb2u, "swreg18.ofst_rgb2u"); + fprintf(fp, "%-16d %s\n", info->swreg18.ofst_rgb2y, "swreg18.ofst_rgb2y"); + + fprintf(fp, "%-16d %s\n", info->swreg19.src_tfltr, "swreg19.src_tfltr"); + fprintf(fp, "%-16d %s\n", info->swreg19.src_tfltr_we, "swreg19.src_tfltr_we"); + fprintf(fp, "%-16d %s\n", info->swreg19.src_tfltr_bw, "swreg19.src_tfltr_bw"); + fprintf(fp, "%-16d %s\n", info->swreg19.src_sfltr, "swreg19.src_sfltr"); + fprintf(fp, "%-16d %s\n", info->swreg19.src_mfltr_thrd, "swreg19.src_mfltr_thrd"); + fprintf(fp, "%-16d %s\n", info->swreg19.src_mfltr_y, "swreg19.src_mfltr_y"); + fprintf(fp, "%-16d %s\n", info->swreg19.src_mfltr_c, "swreg19.src_mfltr_c"); + fprintf(fp, "%-16d %s\n", info->swreg19.src_bfltr_strg, "swreg19.src_bfltr_strg"); + fprintf(fp, "%-16d %s\n", info->swreg19.src_bfltr, "swreg19.src_bfltr"); + fprintf(fp, "%-16d %s\n", info->swreg19.src_mbflt_odr, "swreg19.src_mbflt_odr"); + fprintf(fp, "%-16d %s\n", info->swreg19.src_matf_y, "swreg19.src_matf_y"); + fprintf(fp, "%-16d %s\n", info->swreg19.src_matf_c, "swreg19.src_matf_c"); + fprintf(fp, "%-16d %s\n", info->swreg19.src_shp_y, "swreg19.src_shp_y"); + fprintf(fp, "%-16d %s\n", info->swreg19.src_shp_c, "swreg19.src_shp_c"); + fprintf(fp, "%-16d %s\n", info->swreg19.src_shp_div, "swreg19.src_shp_div"); + fprintf(fp, "%-16d %s\n", info->swreg19.src_shp_thld, "swreg19.src_shp_thld"); + fprintf(fp, "%-16d %s\n", info->swreg19.src_mirr, "swreg19.src_mirr"); + fprintf(fp, "%-16d %s\n", info->swreg19.src_rot, "swreg19.src_rot"); + fprintf(fp, "%-16d %s\n", info->swreg19.src_matf_itsy, "swreg19.src_matf_itsy"); + + fprintf(fp, "%-16d %s\n", info->swreg20.tfltr_thld_y, "swreg20.tfltr_thld_y"); + fprintf(fp, "%-16d %s\n", info->swreg20.tfltr_thld_c, "swreg20.tfltr_thld_c"); + + for (k = 0; k < 5; k++) + fprintf(fp, "%-16d swreg21_scr_stbl[%d]\n", info->swreg21_scr_stbl[k], k); + + for (k = 0; k < 40; k++) + fprintf(fp, "%-16d swreg22_h3d_tbl[%d]\n", info->swreg22_h3d_tbl[k], k); + + fprintf(fp, "%-16d %s\n", info->swreg23.src_ystrid, "swreg23.src_ystrid"); + fprintf(fp, "%-16d %s\n", info->swreg23.src_cstrid, "swreg23.src_cstrid"); + + fprintf(fp, "%#-16x %s\n", info->addr_cfg.adr_srcy, "addr_cfg.adr_srcy"); + fprintf(fp, "%#-16x %s\n", info->addr_cfg.adr_srcu, "addr_cfg.adr_srcu"); + fprintf(fp, "%#-16x %s\n", info->addr_cfg.adr_srcv, "addr_cfg.adr_srcv"); + fprintf(fp, "%#-16x %s\n", info->addr_cfg.ctuc_addr, "addr_cfg.ctuc_addr"); + fprintf(fp, "%#-16x %s\n", info->addr_cfg.rfpw_addr, "addr_cfg.rfpw_addr"); + fprintf(fp, "%#-16x %s\n", info->addr_cfg.rfpr_addr, "addr_cfg.rfpr_addr"); + fprintf(fp, "%#-16x %s\n", info->addr_cfg.dspw_addr, "addr_cfg.dspw_addr"); + fprintf(fp, "%#-16x %s\n", info->addr_cfg.dspr_addr, "addr_cfg.dspr_addr"); + fprintf(fp, "%#-16x %s\n", info->addr_cfg.bsbw_addr, "addr_cfg.bsbw_addr"); + + fprintf(fp, "%-16d %s\n", info->swreg41.sli_cut, "swreg41.sli_cut"); + fprintf(fp, "%-16d %s\n", info->swreg41.sli_cut_mode, "swreg41.sli_cut_mode"); + fprintf(fp, "%-16d %s\n", info->swreg41.sli_cut_bmod, "swreg41.sli_cut_bmod"); + fprintf(fp, "%-16d %s\n", info->swreg41.sli_max_num, "swreg41.sli_max_num"); + fprintf(fp, "%-16d %s\n", info->swreg41.sli_out_mode, "swreg41.sli_out_mode"); + fprintf(fp, "%-16d %s\n", info->swreg41.sli_cut_cnum, "swreg41.sli_cut_cnum"); + + fprintf(fp, "%-16d %s\n", info->swreg42.sli_cut_byte, "swreg42.sli_cut_byte"); + + fprintf(fp, "%-16d %s\n", info->swreg43.cime_srch_h, "swreg43.cime_srch_h"); + fprintf(fp, "%-16d %s\n", info->swreg43.cime_srch_v, "swreg43.cime_srch_v"); + fprintf(fp, "%-16d %s\n", info->swreg43.rime_srch_h, "swreg43.rime_srch_h"); + fprintf(fp, "%-16d %s\n", info->swreg43.rime_srch_v, "swreg43.rime_srch_v"); + + fprintf(fp, "%-16d %s\n", info->swreg44.pmv_mdst_h, "swreg44.pmv_mdst_h"); + fprintf(fp, "%-16d %s\n", info->swreg44.pmv_mdst_v, "swreg44.pmv_mdst_v"); + fprintf(fp, "%-16d %s\n", info->swreg44.mv_limit, "swreg44.mv_limit"); + fprintf(fp, "%-16d %s\n", info->swreg44.mv_num, "swreg44.mv_num"); + + fprintf(fp, "%-16d %s\n", info->swreg45.cach_l1_dtmr, "swreg45.cach_l1_dtmr"); + + fprintf(fp, "%-16d %s\n", info->swreg46.rc_en, "swreg46.rc_en"); + fprintf(fp, "%-16d %s\n", info->swreg46.rc_mode, "swreg46.rc_mode"); + fprintf(fp, "%-16d %s\n", info->swreg46.aqmode_en, "swreg46.aqmode_en"); + fprintf(fp, "%-16d %s\n", info->swreg46.aq_strg, "swreg46.aq_strg"); + fprintf(fp, "%-16d %s\n", info->swreg46.rc_ctu_num, "swreg46.rc_ctu_num"); + + fprintf(fp, "%-16d %s\n", info->swreg47.bits_error0, "swreg47.bits_error0"); + fprintf(fp, "%-16d %s\n", info->swreg47.bits_error1, "swreg47.bits_error1"); + fprintf(fp, "%-16d %s\n", info->swreg48.bits_error2, "swreg48.bits_error2"); + fprintf(fp, "%-16d %s\n", info->swreg48.bits_error3, "swreg48.bits_error3"); + fprintf(fp, "%-16d %s\n", info->swreg49.bits_error4, "swreg49.bits_error4"); + fprintf(fp, "%-16d %s\n", info->swreg49.bits_error5, "swreg49.bits_error5"); + fprintf(fp, "%-16d %s\n", info->swreg50.bits_error6, "swreg50.bits_error6"); + fprintf(fp, "%-16d %s\n", info->swreg50.bits_error7, "swreg50.bits_error7"); + fprintf(fp, "%-16d %s\n", info->swreg51.bits_error8, "swreg51.bits_error8"); + + fprintf(fp, "%-16d %s\n", info->swreg52.qp_adjuest0, "swreg52.qp_adjuest0"); + fprintf(fp, "%-16d %s\n", info->swreg52.qp_adjuest1, "swreg52.qp_adjuest1"); + fprintf(fp, "%-16d %s\n", info->swreg52.qp_adjuest2, "swreg52.qp_adjuest2"); + fprintf(fp, "%-16d %s\n", info->swreg52.qp_adjuest3, "swreg52.qp_adjuest3"); + fprintf(fp, "%-16d %s\n", info->swreg52.qp_adjuest4, "swreg52.qp_adjuest4"); + fprintf(fp, "%-16d %s\n", info->swreg52.qp_adjuest5, "swreg52.qp_adjuest5"); + fprintf(fp, "%-16d %s\n", info->swreg53.qp_adjuest6, "swreg53.qp_adjuest6"); + fprintf(fp, "%-16d %s\n", info->swreg53.qp_adjuest7, "swreg53.qp_adjuest7"); + fprintf(fp, "%-16d %s\n", info->swreg53.qp_adjuest8, "swreg53.qp_adjuest8"); + + fprintf(fp, "%-16d %s\n", info->swreg54.rc_qp_mod, "swreg54.rc_qp_mod"); + fprintf(fp, "%-16d %s\n", info->swreg54.rc_fact0, "swreg54.rc_fact0"); + fprintf(fp, "%-16d %s\n", info->swreg54.rc_fact1, "swreg54.rc_fact1"); + fprintf(fp, "%-16d %s\n", info->swreg54.rc_qp_range, "swreg54.rc_qp_range"); + fprintf(fp, "%-16d %s\n", info->swreg54.rc_max_qp, "swreg54.rc_max_qp"); + fprintf(fp, "%-16d %s\n", info->swreg54.rc_min_qp, "swreg54.rc_min_qp"); + + fprintf(fp, "%-16d %s\n", info->swreg55.ctu_ebits, "swreg55.ctu_ebits"); + + fprintf(fp, "%-16d %s\n", info->swreg56.arb_sel, "swreg56.arb_sel"); + fprintf(fp, "%-16d %s\n", info->swreg56.rdo_mark, "swreg56.rdo_mark"); + + fprintf(fp, "%-16d %s\n", info->swreg57.nal_ref_idc, "swreg57.nal_ref_idc"); + fprintf(fp, "%-16d %s\n", info->swreg57.nal_unit_type, "swreg57.nal_unit_type"); + + fprintf(fp, "%-16d %s\n", info->swreg58.max_fnum, "swreg58.max_fnum"); + fprintf(fp, "%-16d %s\n", info->swreg58.drct_8x8, "swreg58.drct_8x8"); + fprintf(fp, "%-16d %s\n", info->swreg58.mpoc_lm4, "swreg58.mpoc_lm4"); + + fprintf(fp, "%-16d %s\n", info->swreg59.etpy_mode, "swreg59.etpy_mode"); + fprintf(fp, "%-16d %s\n", info->swreg59.trns_8x8, "swreg59.trns_8x8"); + fprintf(fp, "%-16d %s\n", info->swreg59.csip_flg, "swreg59.csip_flg"); + fprintf(fp, "%-16d %s\n", info->swreg59.num_ref0_idx, "swreg59.num_ref0_idx"); + fprintf(fp, "%-16d %s\n", info->swreg59.num_ref1_idx, "swreg59.num_ref1_idx"); + fprintf(fp, "%-16d %s\n", info->swreg59.pic_init_qp, "swreg59.pic_init_qp"); + fprintf(fp, "%-16d %s\n", info->swreg59.cb_ofst, "swreg59.cb_ofst"); + fprintf(fp, "%-16d %s\n", info->swreg59.cr_ofst, "swreg59.cr_ofst"); + fprintf(fp, "%-16d %s\n", info->swreg59.dbf_cp_flg, "swreg59.dbf_cp_flg"); + + fprintf(fp, "%-16d %s\n", info->swreg60.sli_type, "swreg60.sli_type"); + fprintf(fp, "%-16d %s\n", info->swreg60.pps_id, "swreg60.pps_id"); + fprintf(fp, "%-16d %s\n", info->swreg60.num_ref_ovrd, "swreg60.num_ref_ovrd"); + fprintf(fp, "%-16d %s\n", info->swreg60.cbc_init_idc, "swreg60.cbc_init_idc"); + fprintf(fp, "%-16d %s\n", info->swreg60.frm_num, "swreg60.frm_num"); + + fprintf(fp, "%-16d %s\n", info->swreg61.idr_pid, "swreg61.idr_pid"); + fprintf(fp, "%-16d %s\n", info->swreg61.poc_lsb, "swreg61.poc_lsb"); + + fprintf(fp, "%-16d %s\n", info->swreg62.rodr_pic_idx, "swreg62.rodr_pic_idx"); + fprintf(fp, "%-16d %s\n", info->swreg62.ref_list0_rodr, "swreg62.ref_list0_rodr"); + fprintf(fp, "%-16d %s\n", info->swreg62.sli_beta_ofst, "swreg62.sli_beta_ofst"); + fprintf(fp, "%-16d %s\n", info->swreg62.sli_alph_ofst, "swreg62.sli_alph_ofst"); + fprintf(fp, "%-16d %s\n", info->swreg62.dis_dblk_idc, "swreg62.dis_dblk_idc"); + fprintf(fp, "%-16d %s\n", info->swreg62.rodr_pic_num, "swreg62.rodr_pic_num"); + + fprintf(fp, "%-16d %s\n", info->swreg63.ltrf_flg, "swreg63.ltrf_flg"); + fprintf(fp, "%-16d %s\n", info->swreg63.arpm_flg, "swreg63.arpm_flg"); + fprintf(fp, "%-16d %s\n", info->swreg63.mmco4_pre, "swreg63.mmco4_pre"); + fprintf(fp, "%-16d %s\n", info->swreg63.mmco_0, "swreg63.mmco_0"); + fprintf(fp, "%-16d %s\n", info->swreg63.dopn_m1_0, "swreg63.dopn_m1_0"); + + fprintf(fp, "%-16d %s\n", info->swreg64.mmco_1, "swreg64.mmco_1"); + fprintf(fp, "%-16d %s\n", info->swreg64.dopn_m1_1, "swreg64.dopn_m1_1"); + + fprintf(fp, "%-16d %s\n", info->swreg65.osd_en, "swreg65.osd_en"); + fprintf(fp, "%-16d %s\n", info->swreg65.osd_inv, "swreg65.osd_inv"); + fprintf(fp, "%-16d %s\n", info->swreg65.osd_plt_type, "swreg65.osd_plt_type"); + + fprintf(fp, "%-16d %s\n", info->swreg66.osd_inv_r0, "swreg66.osd_inv_r0"); + fprintf(fp, "%-16d %s\n", info->swreg66.osd_inv_r1, "swreg66.osd_inv_r1"); + fprintf(fp, "%-16d %s\n", info->swreg66.osd_inv_r2, "swreg66.osd_inv_r2"); + fprintf(fp, "%-16d %s\n", info->swreg66.osd_inv_r3, "swreg66.osd_inv_r3"); + fprintf(fp, "%-16d %s\n", info->swreg66.osd_inv_r4, "swreg66.osd_inv_r4"); + fprintf(fp, "%-16d %s\n", info->swreg66.osd_inv_r5, "swreg66.osd_inv_r5"); + fprintf(fp, "%-16d %s\n", info->swreg66.osd_inv_r6, "swreg66.osd_inv_r6"); + fprintf(fp, "%-16d %s\n", info->swreg66.osd_inv_r7, "swreg66.osd_inv_r7"); + + for (k = 0; k < 8; k++) { + fprintf(fp, "%-16d swreg67_osd_pos[%d].lt_pos_x\n", info->swreg67_osd_pos[k].lt_pos_x, k); + fprintf(fp, "%-16d swreg67_osd_pos[%d].lt_pos_y\n", info->swreg67_osd_pos[k].lt_pos_y, k); + fprintf(fp, "%-16d swreg67_osd_pos[%d].rd_pos_x\n", info->swreg67_osd_pos[k].rd_pos_x, k); + fprintf(fp, "%-16d swreg67_osd_pos[%d].rd_pos_y\n", info->swreg67_osd_pos[k].rd_pos_y, k); + } + for (k = 0; k < 8; k++) + fprintf(fp, "%-16d swreg68_indx_addr_i[%d]\n", info->swreg68_indx_addr_i[k], k); + + for (k = 0; k < 256; k++) + fprintf(fp, "%#-16x swreg73_osd_indx_tab_i[%d]\n", info->swreg73_osd_indx_tab_i[k], k); + + fprintf(fp, "%#-16x %s\n", info->swreg77.bsbw_addr, "swreg77.bsbw_addr"); + + fprintf(fp, "\n"); + fflush(fp); + } else { + mpp_log("try to dump data to mpp_syntax_in.txt, but file is not opened"); + } +} +#endif + + +#if 0 +static MPP_RET get_rkv_dbg_info(h264e_hal_rkv_dbg_info *info, h264e_syntax *syn, + MppBuffer *hw_in_buf, MppBuffer *hw_output_strm_buf) + +{ + RK_S32 k = 0; + RK_U32 buf_idx = g_frame_read_cnt % RKV_H264E_LINKTABLE_FRAME_NUM; + h264e_hal_debug_enter(); + mpp_assert(fp_golden_syntax_in); + memset(syn, 0, sizeof(h264e_syntax)); + memset(info, 0, sizeof(h264e_hal_rkv_dbg_info)); + + if (hw_in_buf[buf_idx]) { + syn->input_luma_addr = mpp_buffer_get_fd(hw_in_buf[buf_idx]); + syn->input_cb_addr = syn->input_luma_addr; //NOTE: transfer offset in extra_info + syn->input_cr_addr = syn->input_luma_addr; + } + if (hw_output_strm_buf[buf_idx]) + syn->output_strm_addr = mpp_buffer_get_fd(hw_output_strm_buf[buf_idx]); + + + if (fp_golden_syntax_in) { + FILE *fp = fp_golden_syntax_in; + char temp[512] = {0}; + RK_S32 data = 0; + + if (!fgets(temp, 512, fp)) + return MPP_EOS_STREAM_REACHED; + + H264E_HAL_FSCAN(fp, "%d\n", syn->pic_luma_width); + H264E_HAL_FSCAN(fp, "%d\n", syn->pic_luma_height); + H264E_HAL_FSCAN(fp, "%d\n", syn->level_idc); + H264E_HAL_FSCAN(fp, "%d\n", syn->profile_idc); + H264E_HAL_FSCAN(fp, "%d\n", syn->frame_coding_type); + + H264E_HAL_FSCAN(fp, "%d\n", info->swreg02.lkt_num); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg02.rkvenc_cmd); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg02.enc_cke); + + H264E_HAL_FSCAN(fp, "%d\n", info->swreg04.lkt_addr); + + H264E_HAL_FSCAN(fp, "%d\n", info->swreg05.ofe_fnsh); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg05.lkt_fnsh); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg05.clr_fnsh); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg05.ose_fnsh); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg05.bs_ovflr); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg05.brsp_ful); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg05.brsp_err); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg05.rrsp_err); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg05.tmt_err); + + H264E_HAL_FSCAN(fp, "%d\n", info->swreg10.roi_enc); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg10.cur_frm_ref); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg10.mei_stor); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg10.bs_scp); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg10.pic_qp); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg10.slice_int); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg10.node_int); + + H264E_HAL_FSCAN(fp, "%d\n", info->swreg11.ppln_enc_lmt); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg11.rfp_load_thrd); + + H264E_HAL_FSCAN(fp, "%d\n", info->swreg12.src_bus_edin); + + + H264E_HAL_FSCAN(fp, "%d\n", info->swreg13.axi_brsp_cke); + + H264E_HAL_FSCAN(fp, "%d\n", info->swreg14.src_aswap); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg14.src_cswap); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg14.src_cfmt); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg14.src_clip_dis); + + H264E_HAL_FSCAN(fp, "%d\n", info->swreg15.wght_b2y); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg15.wght_g2y); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg15.wght_r2y); + + H264E_HAL_FSCAN(fp, "%d\n", info->swreg16.wght_b2u); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg16.wght_g2u); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg16.wght_r2u); + + H264E_HAL_FSCAN(fp, "%d\n", info->swreg17.wght_b2v); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg17.wght_g2v); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg17.wght_r2v); + + H264E_HAL_FSCAN(fp, "%d\n", info->swreg18.ofst_rgb2v); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg18.ofst_rgb2u); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg18.ofst_rgb2y); + + H264E_HAL_FSCAN(fp, "%d\n", info->swreg19.src_tfltr); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg19.src_tfltr_we); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg19.src_tfltr_bw); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg19.src_sfltr); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg19.src_mfltr_thrd); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg19.src_mfltr_y); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg19.src_mfltr_c); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg19.src_bfltr_strg); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg19.src_bfltr); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg19.src_mbflt_odr); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg19.src_matf_y); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg19.src_matf_c); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg19.src_shp_y); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg19.src_shp_c); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg19.src_shp_div); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg19.src_shp_thld); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg19.src_mirr); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg19.src_rot); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg19.src_matf_itsy); + + H264E_HAL_FSCAN(fp, "%d\n", info->swreg20.tfltr_thld_y); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg20.tfltr_thld_c); + + for (k = 0; k < 5; k++) + H264E_HAL_FSCAN(fp, "%d\n", info->swreg21_scr_stbl[k]); + + for (k = 0; k < 40; k++) + H264E_HAL_FSCAN(fp, "%d\n", info->swreg22_h3d_tbl[k]); + + H264E_HAL_FSCAN(fp, "%d\n", info->swreg23.src_ystrid); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg23.src_cstrid); + + H264E_HAL_FSCAN(fp, "%x\n", info->addr_cfg.adr_srcy); + H264E_HAL_FSCAN(fp, "%x\n", info->addr_cfg.adr_srcu); + H264E_HAL_FSCAN(fp, "%x\n", info->addr_cfg.adr_srcv); + H264E_HAL_FSCAN(fp, "%x\n", info->addr_cfg.ctuc_addr); + H264E_HAL_FSCAN(fp, "%x\n", info->addr_cfg.rfpw_addr); + H264E_HAL_FSCAN(fp, "%x\n", info->addr_cfg.rfpr_addr); + H264E_HAL_FSCAN(fp, "%x\n", info->addr_cfg.dspw_addr); + H264E_HAL_FSCAN(fp, "%x\n", info->addr_cfg.dspr_addr); + H264E_HAL_FSCAN(fp, "%x\n", info->addr_cfg.bsbw_addr); + + H264E_HAL_FSCAN(fp, "%d\n", info->swreg41.sli_cut); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg41.sli_cut_mode); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg41.sli_cut_bmod); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg41.sli_max_num); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg41.sli_out_mode); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg41.sli_cut_cnum); + + H264E_HAL_FSCAN(fp, "%d\n", info->swreg42.sli_cut_byte); + + H264E_HAL_FSCAN(fp, "%d\n", info->swreg43.cime_srch_h); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg43.cime_srch_v); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg43.rime_srch_h); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg43.rime_srch_v); + + H264E_HAL_FSCAN(fp, "%d\n", info->swreg44.pmv_mdst_h); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg44.pmv_mdst_v); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg44.mv_limit); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg44.mv_num); + + H264E_HAL_FSCAN(fp, "%d\n", info->swreg45.cach_l1_dtmr); + + H264E_HAL_FSCAN(fp, "%d\n", info->swreg46.rc_en); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg46.rc_mode); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg46.aqmode_en); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg46.aq_strg); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg46.rc_ctu_num); + + H264E_HAL_FSCAN(fp, "%d\n", info->swreg47.bits_error0); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg47.bits_error1); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg48.bits_error2); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg48.bits_error3); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg49.bits_error4); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg49.bits_error5); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg50.bits_error6); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg50.bits_error7); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg51.bits_error8); + + H264E_HAL_FSCAN(fp, "%d\n", info->swreg52.qp_adjuest0); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg52.qp_adjuest1); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg52.qp_adjuest2); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg52.qp_adjuest3); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg52.qp_adjuest4); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg52.qp_adjuest5); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg53.qp_adjuest6); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg53.qp_adjuest7); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg53.qp_adjuest8); + + H264E_HAL_FSCAN(fp, "%d\n", info->swreg54.rc_qp_mod); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg54.rc_fact0); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg54.rc_fact1); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg54.rc_qp_range); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg54.rc_max_qp); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg54.rc_min_qp); + + H264E_HAL_FSCAN(fp, "%d\n", info->swreg55.ctu_ebits); + + H264E_HAL_FSCAN(fp, "%d\n", info->swreg56.arb_sel); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg56.rdo_mark); + + H264E_HAL_FSCAN(fp, "%d\n", info->swreg57.nal_ref_idc); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg57.nal_unit_type); + + H264E_HAL_FSCAN(fp, "%d\n", info->swreg58.max_fnum); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg58.drct_8x8); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg58.mpoc_lm4); + + H264E_HAL_FSCAN(fp, "%d\n", info->swreg59.etpy_mode); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg59.trns_8x8); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg59.csip_flg); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg59.num_ref0_idx); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg59.num_ref1_idx); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg59.pic_init_qp); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg59.cb_ofst); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg59.cr_ofst); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg59.dbf_cp_flg); + + H264E_HAL_FSCAN(fp, "%d\n", info->swreg60.sli_type); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg60.pps_id); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg60.num_ref_ovrd); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg60.cbc_init_idc); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg60.frm_num); + + H264E_HAL_FSCAN(fp, "%d\n", info->swreg61.idr_pid); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg61.poc_lsb); + + H264E_HAL_FSCAN(fp, "%d\n", info->swreg62.rodr_pic_idx); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg62.ref_list0_rodr); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg62.sli_beta_ofst); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg62.sli_alph_ofst); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg62.dis_dblk_idc); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg62.rodr_pic_num); + + H264E_HAL_FSCAN(fp, "%d\n", info->swreg63.ltrf_flg); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg63.arpm_flg); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg63.mmco4_pre); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg63.mmco_0); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg63.dopn_m1_0); + + H264E_HAL_FSCAN(fp, "%d\n", info->swreg64.mmco_1); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg64.dopn_m1_1); + + H264E_HAL_FSCAN(fp, "%d\n", info->swreg65.osd_en); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg65.osd_inv); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg65.osd_plt_type); + + H264E_HAL_FSCAN(fp, "%d\n", info->swreg66.osd_inv_r0); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg66.osd_inv_r1); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg66.osd_inv_r2); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg66.osd_inv_r3); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg66.osd_inv_r4); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg66.osd_inv_r5); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg66.osd_inv_r6); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg66.osd_inv_r7); + + for (k = 0; k < 8; k++) { + H264E_HAL_FSCAN(fp, "%d\n", info->swreg67_osd_pos[k].lt_pos_x); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg67_osd_pos[k].lt_pos_y); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg67_osd_pos[k].rd_pos_x); + H264E_HAL_FSCAN(fp, "%d\n", info->swreg67_osd_pos[k].rd_pos_y); + } + for (k = 0; k < 8; k++) + H264E_HAL_FSCAN(fp, "%d\n", info->swreg68_indx_addr_i[k]); + + for (k = 0; k < 256; k++) + H264E_HAL_FSCAN(fp, "%x\n", info->swreg73_osd_indx_tab_i[k]); + + H264E_HAL_FSCAN(fp, "%x\n", info->swreg77.bsbw_addr); + + H264E_HAL_FSCAN(fp, "%x\n", syn->keyframe_max_interval); + + fgets(temp, 512, fp); + + //set values actually used + syn->slice_type = info->swreg60.sli_type; + syn->pps_id = info->swreg60.pps_id; + syn->cabac_init_idc = info->swreg60.cbc_init_idc; + syn->pic_order_cnt_lsb = info->swreg61.poc_lsb; + syn->idr_pic_id = info->swreg61.idr_pid; + syn->pic_init_qp = info->swreg59.pic_init_qp; + syn->qp = info->swreg10.pic_qp; + syn->frame_num = info->swreg60.frm_num; + syn->input_image_format = info->swreg14.src_cfmt; + syn->transform8x8_mode = info->swreg59.trns_8x8; + } + + h264e_hal_debug_leave(); + return MPP_OK; +} +#endif + + +static MPP_RET get_rkv_syntax_in( h264e_syntax *syn, MppBuffer *hw_in_buf, MppBuffer *hw_output_strm_buf, h264e_hal_test_cfg *cfg) + +{ + h264e_hal_rkv_csp_info csp_info; + RK_U32 buf_idx = g_frame_read_cnt % RKV_H264E_LINKTABLE_FRAME_NUM; + h264e_hal_debug_enter(); + //mpp_assert(fp_golden_syntax_in); + memset(syn, 0, sizeof(h264e_syntax)); + + if (hw_in_buf[buf_idx]) { + syn->input_luma_addr = mpp_buffer_get_fd(hw_in_buf[buf_idx]); + syn->input_cb_addr = syn->input_luma_addr; //NOTE: transfer offset in extra_info + syn->input_cr_addr = syn->input_luma_addr; + } + if (hw_output_strm_buf[buf_idx]) + syn->output_strm_addr = mpp_buffer_get_fd(hw_output_strm_buf[buf_idx]); + +#if RKV_H264E_SDK_TEST + mpp_log("make syntax begin"); + syn->pic_luma_width = cfg->pic_width; + syn->pic_luma_height = cfg->pic_height; + syn->level_idc = H264_LEVEL_4_1; + syn->profile_idc = H264_PROFILE_HIGH; + mpp_log("syn->level_idc %d", syn->level_idc); + mpp_log("syn->profile_idc %d", syn->profile_idc); + syn->keyframe_max_interval = 30; + if (g_frame_cnt == 0 || g_frame_cnt % syn->keyframe_max_interval == 0) { + syn->frame_coding_type = 1; //intra + syn->slice_type = 2; + } else { + syn->frame_coding_type = 0; //inter + syn->slice_type = 0; + } + syn->qp = 26; + csp_info.fmt = H264E_RKV_CSP_YUV420P; + csp_info.cswap = 0; //TODO: + csp_info.aswap = 0; //TODO: + syn->input_image_format = h264e_rkv_revert_csp(csp_info); + + syn->enable_cabac = 1; + syn->pic_init_qp = 26; + syn->chroma_qp_index_offset = 0; + syn->second_chroma_qp_index_offset = 0; + + syn->pps_id = 0 ; + syn->frame_num = 0; + syn->cabac_init_idc = 0; + + + syn->idr_pic_id = 0; + syn->pic_order_cnt_lsb = 0; + + + mpp_log("make syntax end"); +#else + if (fp_golden_syntax_in) { + FILE *fp = fp_golden_syntax_in; + char temp[512] = {0}; + RK_S32 data = 0; + + if (!fgets(temp, 512, fp)) + return MPP_EOS_STREAM_REACHED; + + H264E_HAL_FSCAN(fp, "%d\n", syn->pic_luma_width); + H264E_HAL_FSCAN(fp, "%d\n", syn->pic_luma_height); + H264E_HAL_FSCAN(fp, "%d\n", syn->level_idc); + H264E_HAL_FSCAN(fp, "%d\n", syn->profile_idc); + H264E_HAL_FSCAN(fp, "%d\n", syn->frame_coding_type); + H264E_HAL_FSCAN(fp, "%d\n", syn->qp); + H264E_HAL_FSCAN(fp, "%d\n", syn->input_image_format); + + H264E_HAL_FSCAN(fp, "%d\n", syn->enable_cabac); + H264E_HAL_FSCAN(fp, "%d\n", syn->pic_init_qp); + H264E_HAL_FSCAN(fp, "%d\n", syn->chroma_qp_index_offset); + H264E_HAL_FSCAN(fp, "%d\n", syn->second_chroma_qp_index_offset); + + H264E_HAL_FSCAN(fp, "%d\n", syn->slice_type); + H264E_HAL_FSCAN(fp, "%d\n", syn->pps_id); + H264E_HAL_FSCAN(fp, "%d\n", syn->frame_num); + H264E_HAL_FSCAN(fp, "%d\n", syn->cabac_init_idc); + + + H264E_HAL_FSCAN(fp, "%d\n", syn->idr_pic_id); + H264E_HAL_FSCAN(fp, "%d\n", syn->pic_order_cnt_lsb); + + H264E_HAL_FSCAN(fp, "%x\n", syn->keyframe_max_interval); + + fgets(temp, 512, fp); + + /* adjust */ + csp_info.fmt = syn->input_image_format; + csp_info.cswap = 0; //TODO: + csp_info.aswap = 0; //TODO: + syn->input_image_format = h264e_rkv_revert_csp(csp_info); + } else { + mpp_err("rkv_syntax_in.txt doesn't exits"); + } +#endif + syn->output_strm_limit_size = (RK_U32)(syn->pic_luma_width * syn->pic_luma_height * 3 / 2); + + h264e_hal_debug_leave(); + return MPP_OK; +} + +static MPP_RET h264e_hal_test_parse_options(int arg_num, char **arg_str, h264e_hal_test_cfg *cfg) +{ + RK_S32 k = 0; + memset(cfg, 0, sizeof(h264e_hal_test_cfg)); + + cfg->num_frames = 30; + for (k = 1; k < arg_num; k++) { + if (!strcmp("-hw", arg_str[k])) { + cfg->hw_mode = atoi(arg_str[k + 1]); + k++; + } + if (!strcmp("-yuv", arg_str[k])) { + strcpy(cfg->input_yuv_file_path, arg_str[k + 1]); + k++; + } + if (!strcmp("-syn", arg_str[k])) { + strcpy(cfg->input_syntax_file_path, arg_str[k + 1]); + k++; + } + + if (!strcmp("-w", arg_str[k])) { + cfg->pic_width = atoi(arg_str[k + 1]); + k++; + } + if (!strcmp("-h", arg_str[k])) { + cfg->pic_height = atoi(arg_str[k + 1]); + k++; + } + if (!strcmp("-fmt", arg_str[k])) { + cfg->src_format = atoi(arg_str[k + 1]); + k++; + } + if (!strcmp("-frame", arg_str[k])) { + cfg->num_frames = atoi(arg_str[k + 1]); + k++; + } + + /* coverage test */ + if (!strcmp("--test-qp", arg_str[k])) { + cfg->test.qp = atoi(arg_str[k + 1]); + k++; + } + if (!strcmp("--test-preproc", arg_str[k])) { + cfg->test.preproc = atoi(arg_str[k + 1]); + k++; + } + if (!strcmp("--test-osd", arg_str[k])) { + cfg->test.osd = atoi(arg_str[k + 1]); + k++; + } + if (!strcmp("--test-mbrc", arg_str[k])) { + cfg->test.mbrc = atoi(arg_str[k + 1]); + k++; + } + if (!strcmp("--test-roi", arg_str[k])) { + cfg->test.roi = atoi(arg_str[k + 1]); + k++; + } + } + + + if (!cfg->input_yuv_file_path) { + mpp_log("test param parse error: input_yuv_file_path is NULL"); + return MPP_NOK; + } +#if RKV_H264E_SDK_TEST + if (!cfg->pic_width) { + mpp_log("test param parse error: pic_width is 0"); + return MPP_NOK; + } + if (!cfg->pic_height) { + mpp_log("test param parse error: pic_height is 0"); + return MPP_NOK; + } +#else + if (!cfg->input_syntax_file_path) { + mpp_log("test param parse error: input_syntax_file_path is NULL"); + return MPP_NOK; + } +#endif + + if (cfg->hw_mode == 0) + test_device_id = HAL_RKVENC; + else if (cfg->hw_mode == 1) + test_device_id = HAL_VEPU; + else { + mpp_log("test param parse error: hw_mode is %d", cfg->hw_mode); + return MPP_NOK; + } + + mpp_log("======== hal converage test cfg (st) ======="); + if (cfg->test.qp) + mpp_log("cfg->test.qp %d", cfg->test.qp); + if (cfg->test.preproc) + mpp_log("cfg->test.preproc %d", cfg->test.preproc); + if (cfg->test.osd) + mpp_log("cfg->test.osd %d", cfg->test.osd); + if (cfg->test.mbrc) + mpp_log("cfg->test.mbrc %d", cfg->test.mbrc); + if (cfg->test.roi) + mpp_log("cfg->test.roi %d", cfg->test.roi); + mpp_log("======== hal converage test cfg (ed) ======="); + + return MPP_OK; +} + +static void h264e_hal_test_init(h264e_hal_context *ctx, HalTaskInfo *task_info) +{ + memset(ctx, 0, sizeof(h264e_hal_context)); + memset(task_info, 0, sizeof(HalTaskInfo)); +} + +static void h264e_hal_test_deinit(h264e_hal_context *ctx, HalTaskInfo *task_info) +{ + (void)ctx; + (void)task_info; +} + +MPP_RET h264_hal_test_call_back(void *control, void *feedback) +{ + (void)control; + h264e_feedback *fb = (h264e_feedback *)feedback; + (void)fb; + + mpp_log("h264_hal_test_call_back, enter"); + mpp_log("h264_hal_test_call_back, leave"); + + return MPP_OK; +} + +static void h264e_hal_set_extra_info_cfg(h264e_control_extra_info_cfg *info, h264e_syntax *syn) +{ + info->chroma_qp_index_offset = syn->chroma_qp_index_offset; + info->enable_cabac = syn->enable_cabac; + info->pic_init_qp = syn->pic_init_qp; + info->pic_luma_height = syn->pic_luma_height; + info->pic_luma_width = syn->pic_luma_width; + info->transform8x8_mode = syn->transform8x8_mode; + + info->input_image_format = syn->input_image_format; + info->profile_idc = syn->profile_idc; + info->level_idc = syn->level_idc; + info->keyframe_max_interval = syn->keyframe_max_interval; + info->second_chroma_qp_index_offset = syn->second_chroma_qp_index_offset; + info->pps_id = syn->pps_id; +} + +MPP_RET h264e_hal_vpu_test() +{ + MPP_RET ret = MPP_OK; + h264e_hal_context ctx; + MppHalCfg hal_cfg; + HalTaskInfo task_info; + h264e_syntax syntax_data; + h264e_control_extra_info_cfg extra_info_cfg; + MppPacket extra_info_pkt; + RK_U8 extra_info_buf[H264E_MAX_PACKETED_PARAM_SIZE] = {0}; + MppBufferGroup hw_input_buf_grp = NULL; + MppBufferGroup hw_output_buf_grp = NULL; + MppBuffer hw_input_buf = NULL; //Y, U, V + MppBuffer hw_output_strm_buf = NULL; + RK_U32 frame_luma_size = 0; + RK_S64 t0; + + RK_U8 *input_sw_buf = mpp_malloc(RK_U8, MAX_FRAME_TOTAL_SIZE); + + mpp_packet_init(&extra_info_pkt, (void *)extra_info_buf, H264E_MAX_PACKETED_PARAM_SIZE); + + get_vpu_syntax_in(&syntax_data, hw_input_buf, hw_output_strm_buf, frame_luma_size); + if (fp_golden_syntax_in) + fseek(fp_golden_syntax_in, 0L, SEEK_SET); + + frame_luma_size = syntax_data.pic_luma_width * syntax_data.pic_luma_height; + + h264e_hal_test_init(&ctx, &task_info); + + if (MPP_OK != mpp_buffer_group_get_internal(&hw_input_buf_grp, MPP_BUFFER_TYPE_ION)) { + mpp_err("hw_input_buf_grp get failed, test is ended early"); + goto __test_end; + } + if (MPP_OK != mpp_buffer_group_get_internal(&hw_output_buf_grp, MPP_BUFFER_TYPE_ION)) { + mpp_err("hw_output_buf_grp get failed, test is ended early"); + goto __test_end; + } + + mpp_buffer_get(hw_input_buf_grp, &hw_input_buf, frame_luma_size*3/2); + mpp_buffer_get(hw_output_buf_grp, &hw_output_strm_buf, 1024 * 1024 * 2); + + task_info.enc.syntax.data = (void *)&syntax_data; + task_info.enc.input = hw_input_buf; + task_info.enc.output = hw_input_buf; + + hal_cfg.hal_int_cb.callBack = h264_hal_test_call_back; + hal_cfg.hal_int_cb.opaque = NULL; //control context + hal_cfg.device_id = test_device_id; + hal_h264e_init(&ctx, &hal_cfg); + + h264e_hal_set_extra_info_cfg(&extra_info_cfg, &syntax_data); + hal_h264e_vpu_control(&ctx, MPP_ENC_SET_EXTRA_INFO, &extra_info_cfg); + hal_h264e_vpu_control(&ctx, MPP_ENC_GET_EXTRA_INFO, &extra_info_pkt); + + do { + /* get golden input */ + if (MPP_EOS_STREAM_REACHED == get_vpu_syntax_in(&syntax_data, hw_input_buf, hw_output_strm_buf, frame_luma_size)) { + mpp_log("syntax input file end, total %d frames are encoded, test is ended", g_frame_cnt); + break; + } + + ret = get_h264e_yuv_in_one_frame(input_sw_buf, &syntax_data, hw_input_buf); + + if (ret == MPP_EOS_STREAM_REACHED) { + mpp_log("yuv file end, total %d frames are encoded, test is ended", g_frame_cnt); + break; + } else if (ret == MPP_NOK) { + mpp_err("read yuv file failed, test is ended early"); + goto __test_end; + } + + + /* generate registers */ + hal_h264e_gen_regs(&ctx, &task_info); + + + /* run hardware */ + t0 = mpp_time(); + mpp_log("hal_h264e_start time : %lld ", (RK_S64)(t0 / 1000)); + + hal_h264e_start(&ctx, &task_info); + hal_h264e_wait(&ctx, &task_info); + + g_frame_cnt ++; + } while (1); + + +__test_end: + hal_h264e_deinit(&ctx); + h264e_hal_test_deinit(&ctx, &task_info); + + mpp_packet_deinit(&extra_info_pkt); + //free sw buf + if (input_sw_buf) { + mpp_free(input_sw_buf); + input_sw_buf = NULL; + } + + //free hw buf + if (hw_input_buf) + mpp_buffer_put(hw_input_buf); + if (hw_output_strm_buf) + mpp_buffer_put(hw_output_strm_buf); + + if (hw_input_buf_grp) + mpp_buffer_group_put(hw_input_buf_grp); + if (hw_output_buf_grp) + mpp_buffer_group_put(hw_output_buf_grp); + + return MPP_OK; +} + + +MPP_RET h264e_hal_rkv_test(h264e_hal_test_cfg *test_cfg) +{ + RK_S32 k = 0; + MPP_RET ret = MPP_OK; + h264e_hal_context ctx; + MppHalCfg hal_cfg; + HalTaskInfo task_info; + h264e_control_extra_info_cfg extra_info_cfg; + MppPacket extra_info_pkt; + RK_U8 extra_info_buf[H264E_MAX_PACKETED_PARAM_SIZE] = {0}; + //h264e_hal_rkv_dbg_info dbg_info; + h264e_syntax syntax_data[RKV_H264E_LINKTABLE_FRAME_NUM]; + MppBufferGroup hw_input_buf_grp = NULL; + MppBufferGroup hw_output_buf_grp = NULL; + MppBuffer hw_input_buf_mul[RKV_H264E_LINKTABLE_FRAME_NUM] = {NULL}; + MppBuffer hw_output_strm_buf_mul[RKV_H264E_LINKTABLE_FRAME_NUM] = {NULL}; + RK_U32 frame_luma_stride = 0; + RK_S64 t0; + + mpp_packet_init(&extra_info_pkt, (void *)extra_info_buf, H264E_MAX_PACKETED_PARAM_SIZE); + + + get_rkv_syntax_in(&syntax_data[0], hw_input_buf_mul, hw_output_strm_buf_mul, test_cfg); + if (fp_golden_syntax_in) + fseek(fp_golden_syntax_in, 0L, SEEK_SET); + + + frame_luma_stride = ((syntax_data[0].pic_luma_width + 15) & (~15)) * ((syntax_data[0].pic_luma_height + 15) & (~15)); + + h264e_hal_test_init(&ctx, &task_info); + + + if (MPP_OK != mpp_buffer_group_get_internal(&hw_input_buf_grp, MPP_BUFFER_TYPE_ION)) { + mpp_err("hw_input_buf_grp get failed, test is ended early"); + goto __test_end; + } + if (MPP_OK != mpp_buffer_group_get_internal(&hw_output_buf_grp, MPP_BUFFER_TYPE_ION)) { + mpp_err("hw_output_buf_grp get failed, test is ended early"); + goto __test_end; + } + + for (k = 0; k < RKV_H264E_LINKTABLE_FRAME_NUM; k++) + mpp_buffer_get(hw_input_buf_grp, &hw_input_buf_mul[k], frame_luma_stride * 3 / 2); + + for (k = 0; k < RKV_H264E_LINKTABLE_FRAME_NUM; k++) + mpp_buffer_get(hw_output_buf_grp, &hw_output_strm_buf_mul[k], syntax_data[0].pic_luma_width * syntax_data[0].pic_luma_height * 3 / 2); + + + hal_cfg.hal_int_cb.callBack = h264_hal_test_call_back; + hal_cfg.hal_int_cb.opaque = NULL; //control context + hal_cfg.device_id = test_device_id; + hal_h264e_init(&ctx, &hal_cfg); + + ctx.test_cfg = (void *)&test_cfg->test; + + h264e_hal_set_extra_info_cfg(&extra_info_cfg, &syntax_data[0]); //TODO: use dbg info for input instead + hal_h264e_rkv_control(&ctx, MPP_ENC_SET_EXTRA_INFO, &extra_info_cfg); + hal_h264e_rkv_control(&ctx, MPP_ENC_GET_EXTRA_INFO, &extra_info_pkt); + + do { + /* get golden input */ + if (g_frame_read_cnt <= g_frame_cnt) { + h264e_syntax *syn = NULL; + RK_S32 frame_num = RKV_H264E_ENC_MODE == 1 ? 1 : RKV_H264E_LINKTABLE_FRAME_NUM; + mpp_log("read %d frames input", frame_num); + for (k = 0; k < frame_num; k++, g_frame_read_cnt++) { + syn = &syntax_data[g_frame_read_cnt % RKV_H264E_LINKTABLE_FRAME_NUM]; + if (MPP_EOS_STREAM_REACHED == get_rkv_syntax_in(syn, hw_input_buf_mul, hw_output_strm_buf_mul, test_cfg)) { + mpp_log("syntax input file end, total %d frames are encoded, test is ended", g_frame_cnt); + goto __test_end; + } + ret = get_rkv_h264e_yuv_in_frame(syn, hw_input_buf_mul); + if (ret == MPP_EOS_STREAM_REACHED) { + if (g_frame_cnt == test_cfg->num_frames) { + mpp_log("total %d frames are encoded, test is ended", g_frame_cnt); + goto __test_end; + } else { + fseek(fp_h264e_yuv_in, 0L, SEEK_SET); + ret = get_rkv_h264e_yuv_in_frame(syn, hw_input_buf_mul); + } + } else if (ret == MPP_NOK) { + mpp_err("read yuv file failed, test is ended early"); + goto __test_end; + } + } + } + + task_info.enc.syntax.data = (void *)&syntax_data[g_frame_cnt % RKV_H264E_LINKTABLE_FRAME_NUM]; + task_info.enc.input = hw_input_buf_mul[g_frame_cnt % RKV_H264E_LINKTABLE_FRAME_NUM]; + task_info.enc.output = hw_output_strm_buf_mul[g_frame_cnt % RKV_H264E_LINKTABLE_FRAME_NUM]; + /* generate registers */ + hal_h264e_gen_regs(&ctx, &task_info); + + + /* run hardware */ + t0 = mpp_time(); + mpp_log("hal_h264e_start time : %lld ", (RK_S64)(t0 / 1000)); + + hal_h264e_start(&ctx, &task_info); + hal_h264e_wait(&ctx, &task_info); + + g_frame_cnt ++; + + if(g_frame_cnt==test_cfg->num_frames) { + mpp_log("test_cfg->num_frames %d reached, end test", test_cfg->num_frames); + goto __test_end; + } + + } while (1); + + +__test_end: + mpp_packet_deinit(&extra_info_pkt); + + hal_h264e_deinit(&ctx); + h264e_hal_test_deinit(&ctx, &task_info); + + //free hw buf + for (k = 0; k < RKV_H264E_LINKTABLE_FRAME_NUM; k++) { + if (hw_input_buf_mul[k]) + mpp_buffer_put(hw_input_buf_mul[k]); + if (hw_output_strm_buf_mul[k]) + mpp_buffer_put(hw_output_strm_buf_mul[k]); + } + + if (hw_input_buf_grp) + mpp_buffer_group_put(hw_input_buf_grp); + if (hw_output_buf_grp) + mpp_buffer_group_put(hw_output_buf_grp); + + return MPP_OK; +} + + +int main(int argc, char **argv) +{ + h264e_hal_test_cfg test_cfg; + + mpp_log("******* h264e hal test start *******"); + + if (MPP_OK != h264e_hal_test_parse_options(argc, argv, &test_cfg)) { + mpp_err("parse opitons failed, test is ended early"); + goto __test_end; + } + + if (test_device_id == HAL_VEPU) { + if (MPP_OK != h264e_vpu_test_open_files(test_cfg)) { + mpp_err("open files error, test is ended early"); + goto __test_end; + } + mpp_log("choose h264e_hal_vpu_test"); + h264e_hal_vpu_test(); + } else { + if (MPP_OK != h264e_rkv_test_open_files(test_cfg)) { + mpp_err("open files error, test is ended early"); + goto __test_end; + } + mpp_log("choose h264e_hal_rkv_test"); + h264e_hal_rkv_test(&test_cfg); + } + +__test_end: + + h264e_test_close_files(); + + mpp_log("******* h264e hal test end *******"); + return 0; +} diff --git a/mpp/hal/vpu/h263d/hal_h263d_reg.c b/mpp/hal/vpu/h263d/hal_h263d_reg.c index 5106340e..c3ed4ade 100644 --- a/mpp/hal/vpu/h263d/hal_h263d_reg.c +++ b/mpp/hal/vpu/h263d/hal_h263d_reg.c @@ -1,353 +1,353 @@ -/* - * - * Copyright 2016 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define MODULE_TAG "hal_vpu_h263d" - -#include -#include - -#include "mpp_log.h" -#include "mpp_err.h" -#include "mpp_mem.h" -#include "mpp_env.h" -#include "mpp_buffer.h" - -#include "vpu.h" -#include "mpp_dec.h" -#include "h263d_syntax.h" -#include "hal_h263d_api.h" -#include "hal_h263d_reg.h" - -typedef struct h263d_reg_context { - MppBufSlots frm_slots; - MppBufSlots pkt_slots; - IOInterruptCB int_cb; - - // save fd for curr/ref0/ref1 for reg_gen - RK_S32 vpu_fd; - RK_S32 fd_curr; - RK_S32 fd_ref0; - - VpuH263dRegSet_t* regs; -} hal_h263_ctx; - -RK_U32 h263d_hal_debug = 0; - -static void vpu_h263d_get_buffer_by_index(hal_h263_ctx *ctx, RK_S32 index, MppBuffer *buffer) -{ - if (index >= 0) { - mpp_buf_slot_get_prop(ctx->frm_slots, index, SLOT_BUFFER, buffer); - mpp_assert(*buffer); - } -} - -static void vpu_h263d_setup_regs_by_syntax(hal_h263_ctx *ctx, MppSyntax syntax) -{ - VpuH263dRegSet_t *regs = ctx->regs; - DXVA2_DecodeBufferDesc **data = syntax.data; - DXVA_PicParams_H263 *pp = NULL; - RK_U32 stream_length = 0; - RK_U32 stream_used = 0; - RK_U32 i; - - for (i = 0; i < syntax.number; i++) { - DXVA2_DecodeBufferDesc *desc = data[i]; - switch (desc->CompressedBufferType) { - case DXVA2_PictureParametersBufferType : { - pp = (DXVA_PicParams_H263 *)desc->pvPVPState; - } break; - case DXVA2_BitStreamDateBufferType : { - stream_length = desc->DataSize; - stream_used = desc->DataOffset; - } break; - default : { - mpp_err_f("found invalid buffer descriptor type %d\n", desc->CompressedBufferType); - } break; - } - } - - mpp_assert(pp); - mpp_assert(stream_length); - mpp_assert(stream_used); - - regs->reg120.sw_pic_mb_width = (pp->vop_width + 15) >> 4; - regs->reg120.sw_pic_mb_hight_p = (pp->vop_height + 15) >> 4; - regs->reg120.sw_mb_width_off = pp->vop_width & 0xf; - regs->reg120.sw_mb_height_off = pp->vop_height & 0xf; - - regs->reg53_dec_mode = 2; - regs->reg50_dec_ctrl.sw_filtering_dis = 1; - regs->reg136.sw_rounding = 0; - regs->reg51_stream_info.sw_init_qp = pp->vop_quant; - regs->reg122.sw_sync_markers_en = 1; - - { - /* - * update stream base address here according to consumed bit length - * 1. hardware start address has to be 64 bit align - * 2. hardware need to know which is the start bit in - * 2. pass (10bit fd + (offset << 10)) register value to kernel - */ - RK_U32 val = regs->reg64_input_stream_base; - RK_U32 consumed_bytes = stream_used >> 3; - RK_U32 consumed_bytes_align = consumed_bytes & (~0x7); - RK_U32 start_bit_offset = stream_used & 0x3F; - RK_U32 left_bytes = stream_length - consumed_bytes_align; - - val += (consumed_bytes_align << 10); - regs->reg64_input_stream_base = val; - regs->reg122.sw_stream_start_word = start_bit_offset; - regs->reg51_stream_info.sw_stream_len = left_bytes; - } - - regs->reg122.sw_vop_time_incr = pp->vop_time_increment_resolution; - - switch (pp->vop_coding_type) { - case H263_P_VOP : { - regs->reg57_enable_ctrl.sw_pic_inter_e = 1; - - if (ctx->fd_ref0 >= 0) { - regs->reg131_ref0_base = (RK_U32)ctx->fd_ref0; - regs->reg148_ref1_base = (RK_U32)ctx->fd_ref0; - } else { - regs->reg131_ref0_base = (RK_U32)ctx->fd_curr; - regs->reg148_ref1_base = (RK_U32)ctx->fd_curr; - } - } break; - case H263_I_VOP : { - regs->reg57_enable_ctrl.sw_pic_inter_e = 0; - - regs->reg131_ref0_base = (RK_U32)ctx->fd_curr; - regs->reg148_ref1_base = (RK_U32)ctx->fd_curr; - } break; - default : { - /* no nothing */ - } break; - } - - regs->reg136.sw_hrz_bit_of_fwd_mv = 1; - regs->reg136.sw_vrz_bit_of_fwd_mv = 1; - regs->reg136.sw_prev_pic_type = (pp->prev_coding_type == H263_P_VOP); -} - -MPP_RET hal_vpu_h263d_init(void *hal, MppHalCfg *cfg) -{ - MPP_RET ret = MPP_OK; - VpuH263dRegSet_t *regs = NULL; - hal_h263_ctx *ctx = (hal_h263_ctx *)hal; - RK_S32 vpu_fd = -1; - - mpp_assert(hal); - - regs = mpp_calloc(VpuH263dRegSet_t, 1); - if (NULL == regs) { - mpp_err_f("failed to malloc register ret\n"); - ret = MPP_ERR_MALLOC; - goto ERR_RET; - } - -#ifdef RKPLATFORM - vpu_fd = VPUClientInit(VPU_DEC); - if (vpu_fd < 0) { - mpp_err_f("failed to open vpu client\n"); - ret = MPP_ERR_UNKNOW; - goto ERR_RET; - } -#endif - - /* - * basic register configuration setup here - */ - regs->reg54_endian.sw_dec_out_endian = 1; - regs->reg54_endian.sw_dec_in_endian = 1; - regs->reg54_endian.sw_dec_inswap32_e = 1; - regs->reg54_endian.sw_dec_outswap32_e = 1; - regs->reg54_endian.sw_dec_strswap32_e = 1; - regs->reg54_endian.sw_dec_strendian_e = 1; - regs->reg56_axi_ctrl.sw_dec_max_burst = 16; - regs->reg52_error_concealment.sw_apf_threshold = 1; - regs->reg57_enable_ctrl.sw_dec_timeout_e = 1; - regs->reg57_enable_ctrl.sw_dec_clk_gate_e = 1; - regs->reg57_enable_ctrl.sw_dec_e = 1; - regs->reg59.sw_pred_bc_tap_0_0 = -1; - regs->reg59.sw_pred_bc_tap_0_1 = 3; - regs->reg59.sw_pred_bc_tap_0_2 = -6; - regs->reg153.sw_pred_bc_tap_0_3 = 20; - - ctx->frm_slots = cfg->frame_slots; - ctx->pkt_slots = cfg->packet_slots; - ctx->int_cb = cfg->hal_int_cb; - ctx->vpu_fd = vpu_fd; - ctx->regs = regs; - - mpp_env_get_u32("h263d_hal_debug", &h263d_hal_debug, 0); - - return ret; -ERR_RET: - if (regs) { - mpp_free(regs); - regs = NULL; - } - - return ret; -} - -MPP_RET hal_vpu_h263d_deinit(void *hal) -{ - MPP_RET ret = MPP_OK; - hal_h263_ctx *ctx = (hal_h263_ctx *)hal; - - mpp_assert(hal); - - if (ctx->regs) { - mpp_free(ctx->regs); - ctx->regs = NULL; - } - -#ifdef RKPLATFORM - if (ctx->vpu_fd >= 0) { - VPUClientRelease(ctx->vpu_fd); - ctx->vpu_fd = -1; - } -#endif - - return ret; -} - -MPP_RET hal_vpu_h263d_gen_regs(void *hal, HalTaskInfo *syn) -{ - MPP_RET ret = MPP_OK; - hal_h263_ctx *ctx = (hal_h263_ctx *)hal; - HalDecTask *task = &syn->dec; - MppBuffer buf_frm_curr = NULL; - MppBuffer buf_frm_ref0 = NULL; - MppBuffer buf_pkt = NULL; - VpuH263dRegSet_t *regs = ctx->regs; - - mpp_assert(task->valid); - mpp_assert(task->input >= 0); - mpp_assert(task->output >= 0); - - /* setup buffer for input / output / reference */ - mpp_buf_slot_get_prop(ctx->pkt_slots, task->input, SLOT_BUFFER, &buf_pkt); - mpp_assert(buf_pkt); - vpu_h263d_get_buffer_by_index(ctx, task->output, &buf_frm_curr); - vpu_h263d_get_buffer_by_index(ctx, task->refer[0], &buf_frm_ref0); - - /* address registers setup first */ - ctx->fd_curr = mpp_buffer_get_fd(buf_frm_curr); - ctx->fd_ref0 = (buf_frm_ref0) ? (mpp_buffer_get_fd(buf_frm_ref0)) : (-1); - regs->reg63_cur_pic_base = (RK_U32)ctx->fd_curr; - regs->reg64_input_stream_base = mpp_buffer_get_fd(buf_pkt); - - /* setup other registers, here will update packet address */ - vpu_h263d_setup_regs_by_syntax(ctx, task->syntax); - - return ret; -} - -MPP_RET hal_vpu_h263d_start(void *hal, HalTaskInfo *task) -{ - MPP_RET ret = MPP_OK; -#ifdef RKPLATFORM - hal_h263_ctx *ctx = (hal_h263_ctx *)hal; - RK_U32 reg_count = (sizeof(*ctx->regs) / sizeof(RK_U32)); - RK_U32* regs = (RK_U32 *)ctx->regs; - - if (h263d_hal_debug & H263D_HAL_DBG_REG_PUT) { - RK_U32 i = 0; - for (i = 0; i < reg_count; i++) { - mpp_log("reg[%03d]: %08x\n", i, regs[i]); - } - } - - ret = VPUClientSendReg(ctx->vpu_fd, regs, reg_count); -#endif - (void)hal; - (void)task; - return ret; -} - -MPP_RET hal_vpu_h263d_wait(void *hal, HalTaskInfo *task) -{ - MPP_RET ret = MPP_OK; -#ifdef RKPLATFORM - hal_h263_ctx *ctx = (hal_h263_ctx *)hal; - VpuH263dRegSet_t reg_out; - RK_U32* regs = (RK_U32 *)®_out; - RK_U32 reg_count = (sizeof(reg_out) / sizeof(RK_U32)); - VPU_CMD_TYPE cmd = 0; - RK_S32 length = 0; - - ret = VPUClientWaitResult(ctx->vpu_fd, regs, (sizeof(reg_out) / sizeof(RK_U32)), - &cmd, &length); - - if (h263d_hal_debug & H263D_HAL_DBG_REG_GET) { - RK_U32 i = 0; - - for (i = 0; i < reg_count; i++) { - mpp_log("reg[%03d]: %08x\n", i, regs[i]); - } - } -#endif - (void)hal; - (void)task; - return ret; -} - -MPP_RET hal_vpu_h263d_reset(void *hal) -{ - MPP_RET ret = MPP_OK; - - (void)hal; - return ret; -} - -MPP_RET hal_vpu_h263d_flush(void *hal) -{ - MPP_RET ret = MPP_OK; - - (void)hal; - return ret; -} - -MPP_RET hal_vpu_h263d_control(void *hal, RK_S32 cmd_type, void *param) -{ - MPP_RET ret = MPP_OK; - - (void)hal; - (void)cmd_type; - (void)param; - return ret; -} - -const MppHalApi hal_api_h263d = { - "h263d_vpu", - MPP_CTX_DEC, - MPP_VIDEO_CodingH263, - sizeof(hal_h263_ctx), - 0, - hal_vpu_h263d_init, - hal_vpu_h263d_deinit, - hal_vpu_h263d_gen_regs, - hal_vpu_h263d_start, - hal_vpu_h263d_wait, - hal_vpu_h263d_reset, - hal_vpu_h263d_flush, - hal_vpu_h263d_control, -}; - +/* + * + * Copyright 2016 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define MODULE_TAG "hal_vpu_h263d" + +#include +#include + +#include "mpp_log.h" +#include "mpp_err.h" +#include "mpp_mem.h" +#include "mpp_env.h" +#include "mpp_buffer.h" + +#include "vpu.h" +#include "mpp_dec.h" +#include "h263d_syntax.h" +#include "hal_h263d_api.h" +#include "hal_h263d_reg.h" + +typedef struct h263d_reg_context { + MppBufSlots frm_slots; + MppBufSlots pkt_slots; + IOInterruptCB int_cb; + + // save fd for curr/ref0/ref1 for reg_gen + RK_S32 vpu_fd; + RK_S32 fd_curr; + RK_S32 fd_ref0; + + VpuH263dRegSet_t* regs; +} hal_h263_ctx; + +RK_U32 h263d_hal_debug = 0; + +static void vpu_h263d_get_buffer_by_index(hal_h263_ctx *ctx, RK_S32 index, MppBuffer *buffer) +{ + if (index >= 0) { + mpp_buf_slot_get_prop(ctx->frm_slots, index, SLOT_BUFFER, buffer); + mpp_assert(*buffer); + } +} + +static void vpu_h263d_setup_regs_by_syntax(hal_h263_ctx *ctx, MppSyntax syntax) +{ + VpuH263dRegSet_t *regs = ctx->regs; + DXVA2_DecodeBufferDesc **data = syntax.data; + DXVA_PicParams_H263 *pp = NULL; + RK_U32 stream_length = 0; + RK_U32 stream_used = 0; + RK_U32 i; + + for (i = 0; i < syntax.number; i++) { + DXVA2_DecodeBufferDesc *desc = data[i]; + switch (desc->CompressedBufferType) { + case DXVA2_PictureParametersBufferType : { + pp = (DXVA_PicParams_H263 *)desc->pvPVPState; + } break; + case DXVA2_BitStreamDateBufferType : { + stream_length = desc->DataSize; + stream_used = desc->DataOffset; + } break; + default : { + mpp_err_f("found invalid buffer descriptor type %d\n", desc->CompressedBufferType); + } break; + } + } + + mpp_assert(pp); + mpp_assert(stream_length); + mpp_assert(stream_used); + + regs->reg120.sw_pic_mb_width = (pp->vop_width + 15) >> 4; + regs->reg120.sw_pic_mb_hight_p = (pp->vop_height + 15) >> 4; + regs->reg120.sw_mb_width_off = pp->vop_width & 0xf; + regs->reg120.sw_mb_height_off = pp->vop_height & 0xf; + + regs->reg53_dec_mode = 2; + regs->reg50_dec_ctrl.sw_filtering_dis = 1; + regs->reg136.sw_rounding = 0; + regs->reg51_stream_info.sw_init_qp = pp->vop_quant; + regs->reg122.sw_sync_markers_en = 1; + + { + /* + * update stream base address here according to consumed bit length + * 1. hardware start address has to be 64 bit align + * 2. hardware need to know which is the start bit in + * 2. pass (10bit fd + (offset << 10)) register value to kernel + */ + RK_U32 val = regs->reg64_input_stream_base; + RK_U32 consumed_bytes = stream_used >> 3; + RK_U32 consumed_bytes_align = consumed_bytes & (~0x7); + RK_U32 start_bit_offset = stream_used & 0x3F; + RK_U32 left_bytes = stream_length - consumed_bytes_align; + + val += (consumed_bytes_align << 10); + regs->reg64_input_stream_base = val; + regs->reg122.sw_stream_start_word = start_bit_offset; + regs->reg51_stream_info.sw_stream_len = left_bytes; + } + + regs->reg122.sw_vop_time_incr = pp->vop_time_increment_resolution; + + switch (pp->vop_coding_type) { + case H263_P_VOP : { + regs->reg57_enable_ctrl.sw_pic_inter_e = 1; + + if (ctx->fd_ref0 >= 0) { + regs->reg131_ref0_base = (RK_U32)ctx->fd_ref0; + regs->reg148_ref1_base = (RK_U32)ctx->fd_ref0; + } else { + regs->reg131_ref0_base = (RK_U32)ctx->fd_curr; + regs->reg148_ref1_base = (RK_U32)ctx->fd_curr; + } + } break; + case H263_I_VOP : { + regs->reg57_enable_ctrl.sw_pic_inter_e = 0; + + regs->reg131_ref0_base = (RK_U32)ctx->fd_curr; + regs->reg148_ref1_base = (RK_U32)ctx->fd_curr; + } break; + default : { + /* no nothing */ + } break; + } + + regs->reg136.sw_hrz_bit_of_fwd_mv = 1; + regs->reg136.sw_vrz_bit_of_fwd_mv = 1; + regs->reg136.sw_prev_pic_type = (pp->prev_coding_type == H263_P_VOP); +} + +MPP_RET hal_vpu_h263d_init(void *hal, MppHalCfg *cfg) +{ + MPP_RET ret = MPP_OK; + VpuH263dRegSet_t *regs = NULL; + hal_h263_ctx *ctx = (hal_h263_ctx *)hal; + RK_S32 vpu_fd = -1; + + mpp_assert(hal); + + regs = mpp_calloc(VpuH263dRegSet_t, 1); + if (NULL == regs) { + mpp_err_f("failed to malloc register ret\n"); + ret = MPP_ERR_MALLOC; + goto ERR_RET; + } + +#ifdef RKPLATFORM + vpu_fd = VPUClientInit(VPU_DEC); + if (vpu_fd < 0) { + mpp_err_f("failed to open vpu client\n"); + ret = MPP_ERR_UNKNOW; + goto ERR_RET; + } +#endif + + /* + * basic register configuration setup here + */ + regs->reg54_endian.sw_dec_out_endian = 1; + regs->reg54_endian.sw_dec_in_endian = 1; + regs->reg54_endian.sw_dec_inswap32_e = 1; + regs->reg54_endian.sw_dec_outswap32_e = 1; + regs->reg54_endian.sw_dec_strswap32_e = 1; + regs->reg54_endian.sw_dec_strendian_e = 1; + regs->reg56_axi_ctrl.sw_dec_max_burst = 16; + regs->reg52_error_concealment.sw_apf_threshold = 1; + regs->reg57_enable_ctrl.sw_dec_timeout_e = 1; + regs->reg57_enable_ctrl.sw_dec_clk_gate_e = 1; + regs->reg57_enable_ctrl.sw_dec_e = 1; + regs->reg59.sw_pred_bc_tap_0_0 = -1; + regs->reg59.sw_pred_bc_tap_0_1 = 3; + regs->reg59.sw_pred_bc_tap_0_2 = -6; + regs->reg153.sw_pred_bc_tap_0_3 = 20; + + ctx->frm_slots = cfg->frame_slots; + ctx->pkt_slots = cfg->packet_slots; + ctx->int_cb = cfg->hal_int_cb; + ctx->vpu_fd = vpu_fd; + ctx->regs = regs; + + mpp_env_get_u32("h263d_hal_debug", &h263d_hal_debug, 0); + + return ret; +ERR_RET: + if (regs) { + mpp_free(regs); + regs = NULL; + } + + return ret; +} + +MPP_RET hal_vpu_h263d_deinit(void *hal) +{ + MPP_RET ret = MPP_OK; + hal_h263_ctx *ctx = (hal_h263_ctx *)hal; + + mpp_assert(hal); + + if (ctx->regs) { + mpp_free(ctx->regs); + ctx->regs = NULL; + } + +#ifdef RKPLATFORM + if (ctx->vpu_fd >= 0) { + VPUClientRelease(ctx->vpu_fd); + ctx->vpu_fd = -1; + } +#endif + + return ret; +} + +MPP_RET hal_vpu_h263d_gen_regs(void *hal, HalTaskInfo *syn) +{ + MPP_RET ret = MPP_OK; + hal_h263_ctx *ctx = (hal_h263_ctx *)hal; + HalDecTask *task = &syn->dec; + MppBuffer buf_frm_curr = NULL; + MppBuffer buf_frm_ref0 = NULL; + MppBuffer buf_pkt = NULL; + VpuH263dRegSet_t *regs = ctx->regs; + + mpp_assert(task->valid); + mpp_assert(task->input >= 0); + mpp_assert(task->output >= 0); + + /* setup buffer for input / output / reference */ + mpp_buf_slot_get_prop(ctx->pkt_slots, task->input, SLOT_BUFFER, &buf_pkt); + mpp_assert(buf_pkt); + vpu_h263d_get_buffer_by_index(ctx, task->output, &buf_frm_curr); + vpu_h263d_get_buffer_by_index(ctx, task->refer[0], &buf_frm_ref0); + + /* address registers setup first */ + ctx->fd_curr = mpp_buffer_get_fd(buf_frm_curr); + ctx->fd_ref0 = (buf_frm_ref0) ? (mpp_buffer_get_fd(buf_frm_ref0)) : (-1); + regs->reg63_cur_pic_base = (RK_U32)ctx->fd_curr; + regs->reg64_input_stream_base = mpp_buffer_get_fd(buf_pkt); + + /* setup other registers, here will update packet address */ + vpu_h263d_setup_regs_by_syntax(ctx, task->syntax); + + return ret; +} + +MPP_RET hal_vpu_h263d_start(void *hal, HalTaskInfo *task) +{ + MPP_RET ret = MPP_OK; +#ifdef RKPLATFORM + hal_h263_ctx *ctx = (hal_h263_ctx *)hal; + RK_U32 reg_count = (sizeof(*ctx->regs) / sizeof(RK_U32)); + RK_U32* regs = (RK_U32 *)ctx->regs; + + if (h263d_hal_debug & H263D_HAL_DBG_REG_PUT) { + RK_U32 i = 0; + for (i = 0; i < reg_count; i++) { + mpp_log("reg[%03d]: %08x\n", i, regs[i]); + } + } + + ret = VPUClientSendReg(ctx->vpu_fd, regs, reg_count); +#endif + (void)hal; + (void)task; + return ret; +} + +MPP_RET hal_vpu_h263d_wait(void *hal, HalTaskInfo *task) +{ + MPP_RET ret = MPP_OK; +#ifdef RKPLATFORM + hal_h263_ctx *ctx = (hal_h263_ctx *)hal; + VpuH263dRegSet_t reg_out; + RK_U32* regs = (RK_U32 *)®_out; + RK_U32 reg_count = (sizeof(reg_out) / sizeof(RK_U32)); + VPU_CMD_TYPE cmd = 0; + RK_S32 length = 0; + + ret = VPUClientWaitResult(ctx->vpu_fd, regs, (sizeof(reg_out) / sizeof(RK_U32)), + &cmd, &length); + + if (h263d_hal_debug & H263D_HAL_DBG_REG_GET) { + RK_U32 i = 0; + + for (i = 0; i < reg_count; i++) { + mpp_log("reg[%03d]: %08x\n", i, regs[i]); + } + } +#endif + (void)hal; + (void)task; + return ret; +} + +MPP_RET hal_vpu_h263d_reset(void *hal) +{ + MPP_RET ret = MPP_OK; + + (void)hal; + return ret; +} + +MPP_RET hal_vpu_h263d_flush(void *hal) +{ + MPP_RET ret = MPP_OK; + + (void)hal; + return ret; +} + +MPP_RET hal_vpu_h263d_control(void *hal, RK_S32 cmd_type, void *param) +{ + MPP_RET ret = MPP_OK; + + (void)hal; + (void)cmd_type; + (void)param; + return ret; +} + +const MppHalApi hal_api_h263d = { + "h263d_vpu", + MPP_CTX_DEC, + MPP_VIDEO_CodingH263, + sizeof(hal_h263_ctx), + 0, + hal_vpu_h263d_init, + hal_vpu_h263d_deinit, + hal_vpu_h263d_gen_regs, + hal_vpu_h263d_start, + hal_vpu_h263d_wait, + hal_vpu_h263d_reset, + hal_vpu_h263d_flush, + hal_vpu_h263d_control, +}; + diff --git a/mpp/hal/vpu/h263d/hal_h263d_reg.h b/mpp/hal/vpu/h263d/hal_h263d_reg.h index 696cee21..b6825963 100644 --- a/mpp/hal/vpu/h263d/hal_h263d_reg.h +++ b/mpp/hal/vpu/h263d/hal_h263d_reg.h @@ -1,398 +1,398 @@ -/* - * Copyright 2016 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __HAL_H263D_REG_H__ -#define __HAL_H263D_REG_H__ - -#include "rk_type.h" - -typedef struct { - RK_U32 reg00_49[50]; - - struct { - RK_U32 sw_dec_out_tiled_e : 1; - RK_U32 sw_dec_latency : 6; - RK_U32 sw_pic_fixed_quant : 1; - RK_U32 sw_filtering_dis : 1; - RK_U32 sw_divx_enable : 1; - RK_U32 sw_dec_scmd_dis : 1; - RK_U32 sw_dec_adv_pre_dis : 1; - RK_U32 sw_priority_mode : 1; - RK_U32 sw_refbu2_thr : 12; - RK_U32 sw_refbu2_picid : 5; - RK_U32 reserve1 : 2; - } reg50_dec_ctrl; - - struct { - RK_U32 sw_stream_len : 24; - RK_U32 reserve1 : 1; - RK_U32 sw_init_qp : 6; - RK_U32 reserve2 : 1; - } reg51_stream_info; - - struct { - RK_U32 sw_startmb_y : 8; - RK_U32 sw_startmb_x : 9; - RK_U32 sw_apf_threshold : 14; - RK_U32 sw_reserve : 1; - } reg52_error_concealment; - - RK_U32 reg53_dec_mode; - - struct { - RK_U32 sw_dec_in_endian : 1; - RK_U32 sw_dec_out_endian : 1; - RK_U32 sw_dec_inswap32_e : 1; - RK_U32 sw_dec_outswap32_e : 1; - RK_U32 sw_dec_strswap32_e : 1; - RK_U32 sw_dec_strendian_e : 1; - RK_U32 reserve3 : 26; - } reg54_endian; - - struct { - RK_U32 sw_dec_irq : 1; - RK_U32 sw_dec_irq_dis : 1; - RK_U32 reserve0 : 2; - RK_U32 sw_dec_rdy_int : 1; - RK_U32 sw_dec_bus_int : 1; - RK_U32 sw_dec_buf_empty_int: 1; - RK_U32 reserve1 : 1; - RK_U32 sw_dec_aso_int : 1; - RK_U32 sw_dec_slice_int : 1; - RK_U32 sw_dec_b_pic_inf : 1; - RK_U32 reserve2 : 1; - RK_U32 sw_dec_error_int : 1; - RK_U32 sw_dec_timeout : 1; - RK_U32 reserve3 : 18; - } reg55_Interrupt; - - struct { - RK_U32 sw_dec_axi_rn_id : 8; - RK_U32 sw_dec_axi_wr_id : 8; - RK_U32 sw_dec_max_burst : 5; - RK_U32 reserve0 : 1; - RK_U32 sw_dec_data_disc_e : 1; - RK_U32 reserve1 : 9; - } reg56_axi_ctrl; - - struct { - RK_U32 sw_dec_e : 1; - RK_U32 sw_refbu2_buf_e : 1; - RK_U32 sw_dec_out_dis : 1; - RK_U32 reserve : 1; - RK_U32 sw_dec_clk_gate_e : 1; - RK_U32 sw_dec_timeout_e : 1; - RK_U32 sw_picord_count_e : 1; - RK_U32 sw_seq_mbaff_e : 1; - RK_U32 sw_reftopfirst_e : 1; - RK_U32 sw_ref_topfield_e : 1; - RK_U32 sw_write_mvs_e : 1; - RK_U32 sw_sorenson_e : 1; - RK_U32 sw_fwd_interlace_e : 1; - RK_U32 sw_pic_topfield_e : 1; - RK_U32 sw_pic_inter_e : 1; - RK_U32 sw_pic_b_e : 1; - RK_U32 sw_pic_fieldmode_e : 1; - RK_U32 sw_pic_interlace_e : 1; - RK_U32 sw_pjpeg_e : 1; - RK_U32 sw_divx3_e : 1; - RK_U32 sw_rlc_mode_e : 1; - RK_U32 sw_ch_8pix_ileav_e : 1; - RK_U32 sw_start_code_e : 1; - RK_U32 reserve1 : 8; - RK_U32 sw_dec_ahb_hlock_e : 1; - } reg57_enable_ctrl; - - struct { - RK_U32 sw_soft_rst : 1; - RK_U32 reverse0 : 31; - } reg58; - - struct { - RK_U32 reserve : 2; - RK_S32 sw_pred_bc_tap_0_2 : 10; - RK_S32 sw_pred_bc_tap_0_1 : 10; - RK_S32 sw_pred_bc_tap_0_0 : 10; - } reg59; - - RK_U32 reg60_addit_ch_st_base; - RK_U32 reg61_qtable_base; - RK_U32 reg62_directmv_base; - RK_U32 reg63_cur_pic_base; - RK_U32 reg64_input_stream_base; - - struct { - RK_U32 sw_refbu_y_offset : 9; - RK_U32 sw_reserve : 3; - RK_U32 sw_refbu_fparmod_e : 1; - RK_U32 sw_refbu_eval_e : 1; - RK_U32 sw_refbu_picid : 5; - RK_U32 sw_refbu_thr : 12; - RK_U32 sw_refbu_e : 1; - } reg65_refpicbuf_ctrl; - - struct { - RK_U32 build_version : 3; - RK_U32 product_IDen : 1; - RK_U32 minor_version : 8; - RK_U32 major_version : 4; - RK_U32 product_numer : 16; - } reg66_id; - - struct { - RK_U32 sw_reserve : 25; - RK_U32 sw_dec_rtl_rom : 1; - RK_U32 sw_dec_rv_prof : 2; - RK_U32 sw_ref_buff2_exist : 1; - RK_U32 sw_dec_divx_prof : 1; - RK_U32 sw_dec_refbu_ilace : 1; - RK_U32 sw_dec_jpeg_exten : 1; - } reg67_synthesis_cfg; - - struct { - RK_U32 sw_refbu_top_sum : 16; - RK_U32 sw_refbu_bot_sum : 16; - } reg68_sum_of_partitions; - - struct { - RK_U32 sw_refbu_intra_sum : 16; - RK_U32 sw_refbu_hit_sum : 16; - } reg69_sum_inf; - - struct { - RK_U32 sw_refbu_mv_sum : 22; - RK_U32 sw_reserve : 10; - } reg70_sum_mv; - - RK_U32 reg71_119_reserve[49]; - - struct { - RK_U32 sw_reserve0 : 5; - RK_U32 sw_topfieldfirst_e : 1; - RK_U32 sw_alt_scan_e : 1; - RK_U32 sw_mb_height_off : 4; - RK_U32 sw_pic_mb_hight_p : 8; - RK_U32 sw_mb_width_off : 4; - RK_U32 sw_pic_mb_width : 9; - } reg120; - - struct { - RK_U32 sw_reserve : 5; - RK_U32 sw_vp7_version : 1; - RK_U32 sw_dc_match0 : 3; - RK_U32 sw_dc_match1 : 3; - RK_U32 sw_eable_bilinear : 1; - RK_U32 sw_remain_mv : 1; - RK_U32 sw_reserve1 : 6; - RK_U32 sw_dct2_start_bit : 6; - RK_U32 sw_dct1_start_bit : 6; - } reg121; - - struct { - RK_U32 sw_vop_time_incr : 16; - RK_U32 sw_intradc_vlc_thr : 3; - RK_U32 sw_ch_qp_offset : 5; - RK_U32 sw_quant_type_1_en : 1; - RK_U32 sw_sync_markers_en : 1; - RK_U32 sw_stream_start_word: 6; - } reg122; - - struct { - RK_U32 sw_dc_comp1 : 16; - RK_U32 sw_dc_comp0 : 16; - } reg123; - - struct { - RK_U32 sw_stream1_len : 24; - RK_U32 sw_coeffs_part_am : 4; - RK_U32 sw_reserve : 4; - } reg124; - - struct { - RK_U32 reserve : 2; - RK_U32 sw_pred_bc_tap_5_3 : 10; - RK_U32 sw_pred_bc_tap_5_2 : 10; - RK_U32 sw_pred_bc_tap_5_1 : 10; - } reg125; - - struct { - RK_U32 reserve : 2; - RK_U32 sw_pred_bc_tap_6_2 : 10; - RK_U32 sw_pred_bc_tap_6_1 : 10; - RK_U32 sw_pred_bc_tap_6_0 : 10; - } reg126; - - struct { - RK_U32 reserve : 2; - RK_U32 sw_pred_bc_tap_7_1 : 10; - RK_U32 sw_pred_bc_tap_7_0 : 10; - RK_U32 sw_pred_bc_tap_6_3 : 10; - } reg127; - - struct { - RK_U32 sw_pred_tap_6_4 : 2; - RK_U32 sw_pred_tap_6_M1 : 2; - RK_U32 sw_pred_tap_4_4 : 2; - RK_U32 sw_pred_tap_4_M1 : 2; - RK_U32 sw_pred_tap_2_4 : 2; - RK_U32 sw_pred_tap_2_M1 : 2; - RK_U32 sw_pred_bc_tap_7_3 : 10; - RK_U32 sw_pred_bc_tap_7_2 : 10; - } reg128; - - struct { - RK_U32 sw_filt_level_3 : 6; - RK_U32 sw_filt_level_2 : 6; - RK_U32 sw_filt_level_1 : 6; - RK_U32 sw_filt_level_0 : 6; - RK_U32 reserve : 8; - } reg129; - - struct { - RK_U32 sw_quant_1 : 11; - RK_U32 sw_quant_0 : 11; - RK_U32 sw_quant_delta_1 : 5; - RK_U32 sw_quant_delta_0 : 5; - } reg130; - - - RK_U32 reg131_ref0_base; - - struct { - RK_U32 sw_filt_mb_adj_3 : 7; - RK_U32 sw_filt_mb_adj_2 : 7; - RK_U32 sw_filt_mb_adj_1 : 7; - RK_U32 sw_filt_mb_adj_0 : 7; - RK_U32 sw_filt_sharpness : 3; - RK_U32 sw_filt_type : 1; - } reg132; - - - struct { - RK_U32 sw_filt_ref_adj_3 : 7; - RK_U32 sw_filt_ref_adj_2 : 7; - RK_U32 sw_filt_ref_adj_1 : 7; - RK_U32 sw_filt_ref_adj_0 : 7; - RK_U32 sw_reserve : 4; - } reg133; - - RK_U32 reg134_ref2_base; - RK_U32 reg135_ref3_base; - - struct { - RK_U32 sw_prev_pic_type : 1; - RK_U32 sw_rounding : 1; - RK_U32 sw_fwd_mv_y_resolution : 1; - RK_U32 sw_vrz_bit_of_bwd_mv : 4; - RK_U32 sw_hrz_bit_of_bwd_mv : 4; - RK_U32 sw_vrz_bit_of_fwd_mv : 4; - RK_U32 sw_hrz_bit_of_fwd_mv : 4; - RK_U32 sw_alt_scan : 1; - RK_U32 sw_reserve : 12; - } reg136; - - struct { - RK_U32 sw_trb_per_trd_d0 : 27; - RK_U32 sw_reserve : 5; - } reg137; - - struct { - RK_U32 sw_trb_per_trd_dm1 : 27; - RK_U32 sw_reserve : 5; - } reg138; - - struct { - RK_U32 sw_trb_per_trd_d1 : 27; - RK_U32 sw_reserve : 5; - } reg139; - - RK_U32 reg_dct_strm_base[5]; - RK_U32 reg145_bitpl_ctrl_base; - RK_U32 reg_dct_strm1_base[2]; - - RK_U32 reg148_ref1_base; - - RK_U32 reg149_segment_map_base; - - - struct { - RK_U32 sw_dct_start_bit_7 : 6; - RK_U32 sw_dct_start_bit_6 : 6; - RK_U32 sw_dct_start_bit_5 : 6; - RK_U32 sw_dct_start_bit_4 : 6; - RK_U32 sw_dct_start_bit_3 : 6; - RK_U32 sw_reserve : 2; - } reg150; - - struct { - RK_U32 sw_quant_3 : 11; - RK_U32 sw_quant_2 : 11; - RK_U32 sw_quant_delta_3 : 5; - RK_U32 sw_quant_delta_2 : 5; - } reg151; - - struct { - RK_U32 sw_quant_5 : 11; - RK_U32 sw_quant_4 : 11; - RK_U32 sw_quant_delta_4 : 5; - RK_U32 sw_reserve : 5; - } reg152; - - struct { - RK_U32 reserve : 2; - RK_U32 sw_pred_bc_tap_1_1 : 10; - RK_U32 sw_pred_bc_tap_1_0 : 10; - RK_U32 sw_pred_bc_tap_0_3 : 10; - } reg153; - - struct { - RK_U32 reserve : 2; - RK_U32 sw_pred_bc_tap_2_0 : 10; - RK_U32 sw_pred_bc_tap_1_3 : 10; - RK_U32 sw_pred_bc_tap_1_2 : 10; - } reg154; - - struct { - RK_U32 reserve : 2; - RK_U32 sw_pred_bc_tap_2_3 : 10; - RK_U32 sw_pred_bc_tap_2_2 : 10; - RK_U32 sw_pred_bc_tap_2_1 : 10; - } reg155; - - struct { - RK_U32 reserve : 2; - RK_U32 sw_pred_bc_tap_3_2 : 10; - RK_U32 sw_pred_bc_tap_3_1 : 10; - RK_U32 sw_pred_bc_tap_3_0 : 10; - } reg156; - - struct { - RK_U32 reserve : 2; - RK_U32 sw_pred_bc_tap_4_1 : 10; - RK_U32 sw_pred_bc_tap_4_0 : 10; - RK_U32 sw_pred_bc_tap_3_3 : 10; - } reg157; - - struct { - RK_U32 reserve : 2; - RK_U32 sw_pred_bc_tap_5_0 : 10; - RK_U32 sw_pred_bc_tap_4_3 : 10; - RK_U32 sw_pred_bc_tap_4_2 : 10; - } reg158; -} VpuH263dRegSet_t; - -#endif - +/* + * Copyright 2016 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __HAL_H263D_REG_H__ +#define __HAL_H263D_REG_H__ + +#include "rk_type.h" + +typedef struct { + RK_U32 reg00_49[50]; + + struct { + RK_U32 sw_dec_out_tiled_e : 1; + RK_U32 sw_dec_latency : 6; + RK_U32 sw_pic_fixed_quant : 1; + RK_U32 sw_filtering_dis : 1; + RK_U32 sw_divx_enable : 1; + RK_U32 sw_dec_scmd_dis : 1; + RK_U32 sw_dec_adv_pre_dis : 1; + RK_U32 sw_priority_mode : 1; + RK_U32 sw_refbu2_thr : 12; + RK_U32 sw_refbu2_picid : 5; + RK_U32 reserve1 : 2; + } reg50_dec_ctrl; + + struct { + RK_U32 sw_stream_len : 24; + RK_U32 reserve1 : 1; + RK_U32 sw_init_qp : 6; + RK_U32 reserve2 : 1; + } reg51_stream_info; + + struct { + RK_U32 sw_startmb_y : 8; + RK_U32 sw_startmb_x : 9; + RK_U32 sw_apf_threshold : 14; + RK_U32 sw_reserve : 1; + } reg52_error_concealment; + + RK_U32 reg53_dec_mode; + + struct { + RK_U32 sw_dec_in_endian : 1; + RK_U32 sw_dec_out_endian : 1; + RK_U32 sw_dec_inswap32_e : 1; + RK_U32 sw_dec_outswap32_e : 1; + RK_U32 sw_dec_strswap32_e : 1; + RK_U32 sw_dec_strendian_e : 1; + RK_U32 reserve3 : 26; + } reg54_endian; + + struct { + RK_U32 sw_dec_irq : 1; + RK_U32 sw_dec_irq_dis : 1; + RK_U32 reserve0 : 2; + RK_U32 sw_dec_rdy_int : 1; + RK_U32 sw_dec_bus_int : 1; + RK_U32 sw_dec_buf_empty_int: 1; + RK_U32 reserve1 : 1; + RK_U32 sw_dec_aso_int : 1; + RK_U32 sw_dec_slice_int : 1; + RK_U32 sw_dec_b_pic_inf : 1; + RK_U32 reserve2 : 1; + RK_U32 sw_dec_error_int : 1; + RK_U32 sw_dec_timeout : 1; + RK_U32 reserve3 : 18; + } reg55_Interrupt; + + struct { + RK_U32 sw_dec_axi_rn_id : 8; + RK_U32 sw_dec_axi_wr_id : 8; + RK_U32 sw_dec_max_burst : 5; + RK_U32 reserve0 : 1; + RK_U32 sw_dec_data_disc_e : 1; + RK_U32 reserve1 : 9; + } reg56_axi_ctrl; + + struct { + RK_U32 sw_dec_e : 1; + RK_U32 sw_refbu2_buf_e : 1; + RK_U32 sw_dec_out_dis : 1; + RK_U32 reserve : 1; + RK_U32 sw_dec_clk_gate_e : 1; + RK_U32 sw_dec_timeout_e : 1; + RK_U32 sw_picord_count_e : 1; + RK_U32 sw_seq_mbaff_e : 1; + RK_U32 sw_reftopfirst_e : 1; + RK_U32 sw_ref_topfield_e : 1; + RK_U32 sw_write_mvs_e : 1; + RK_U32 sw_sorenson_e : 1; + RK_U32 sw_fwd_interlace_e : 1; + RK_U32 sw_pic_topfield_e : 1; + RK_U32 sw_pic_inter_e : 1; + RK_U32 sw_pic_b_e : 1; + RK_U32 sw_pic_fieldmode_e : 1; + RK_U32 sw_pic_interlace_e : 1; + RK_U32 sw_pjpeg_e : 1; + RK_U32 sw_divx3_e : 1; + RK_U32 sw_rlc_mode_e : 1; + RK_U32 sw_ch_8pix_ileav_e : 1; + RK_U32 sw_start_code_e : 1; + RK_U32 reserve1 : 8; + RK_U32 sw_dec_ahb_hlock_e : 1; + } reg57_enable_ctrl; + + struct { + RK_U32 sw_soft_rst : 1; + RK_U32 reverse0 : 31; + } reg58; + + struct { + RK_U32 reserve : 2; + RK_S32 sw_pred_bc_tap_0_2 : 10; + RK_S32 sw_pred_bc_tap_0_1 : 10; + RK_S32 sw_pred_bc_tap_0_0 : 10; + } reg59; + + RK_U32 reg60_addit_ch_st_base; + RK_U32 reg61_qtable_base; + RK_U32 reg62_directmv_base; + RK_U32 reg63_cur_pic_base; + RK_U32 reg64_input_stream_base; + + struct { + RK_U32 sw_refbu_y_offset : 9; + RK_U32 sw_reserve : 3; + RK_U32 sw_refbu_fparmod_e : 1; + RK_U32 sw_refbu_eval_e : 1; + RK_U32 sw_refbu_picid : 5; + RK_U32 sw_refbu_thr : 12; + RK_U32 sw_refbu_e : 1; + } reg65_refpicbuf_ctrl; + + struct { + RK_U32 build_version : 3; + RK_U32 product_IDen : 1; + RK_U32 minor_version : 8; + RK_U32 major_version : 4; + RK_U32 product_numer : 16; + } reg66_id; + + struct { + RK_U32 sw_reserve : 25; + RK_U32 sw_dec_rtl_rom : 1; + RK_U32 sw_dec_rv_prof : 2; + RK_U32 sw_ref_buff2_exist : 1; + RK_U32 sw_dec_divx_prof : 1; + RK_U32 sw_dec_refbu_ilace : 1; + RK_U32 sw_dec_jpeg_exten : 1; + } reg67_synthesis_cfg; + + struct { + RK_U32 sw_refbu_top_sum : 16; + RK_U32 sw_refbu_bot_sum : 16; + } reg68_sum_of_partitions; + + struct { + RK_U32 sw_refbu_intra_sum : 16; + RK_U32 sw_refbu_hit_sum : 16; + } reg69_sum_inf; + + struct { + RK_U32 sw_refbu_mv_sum : 22; + RK_U32 sw_reserve : 10; + } reg70_sum_mv; + + RK_U32 reg71_119_reserve[49]; + + struct { + RK_U32 sw_reserve0 : 5; + RK_U32 sw_topfieldfirst_e : 1; + RK_U32 sw_alt_scan_e : 1; + RK_U32 sw_mb_height_off : 4; + RK_U32 sw_pic_mb_hight_p : 8; + RK_U32 sw_mb_width_off : 4; + RK_U32 sw_pic_mb_width : 9; + } reg120; + + struct { + RK_U32 sw_reserve : 5; + RK_U32 sw_vp7_version : 1; + RK_U32 sw_dc_match0 : 3; + RK_U32 sw_dc_match1 : 3; + RK_U32 sw_eable_bilinear : 1; + RK_U32 sw_remain_mv : 1; + RK_U32 sw_reserve1 : 6; + RK_U32 sw_dct2_start_bit : 6; + RK_U32 sw_dct1_start_bit : 6; + } reg121; + + struct { + RK_U32 sw_vop_time_incr : 16; + RK_U32 sw_intradc_vlc_thr : 3; + RK_U32 sw_ch_qp_offset : 5; + RK_U32 sw_quant_type_1_en : 1; + RK_U32 sw_sync_markers_en : 1; + RK_U32 sw_stream_start_word: 6; + } reg122; + + struct { + RK_U32 sw_dc_comp1 : 16; + RK_U32 sw_dc_comp0 : 16; + } reg123; + + struct { + RK_U32 sw_stream1_len : 24; + RK_U32 sw_coeffs_part_am : 4; + RK_U32 sw_reserve : 4; + } reg124; + + struct { + RK_U32 reserve : 2; + RK_U32 sw_pred_bc_tap_5_3 : 10; + RK_U32 sw_pred_bc_tap_5_2 : 10; + RK_U32 sw_pred_bc_tap_5_1 : 10; + } reg125; + + struct { + RK_U32 reserve : 2; + RK_U32 sw_pred_bc_tap_6_2 : 10; + RK_U32 sw_pred_bc_tap_6_1 : 10; + RK_U32 sw_pred_bc_tap_6_0 : 10; + } reg126; + + struct { + RK_U32 reserve : 2; + RK_U32 sw_pred_bc_tap_7_1 : 10; + RK_U32 sw_pred_bc_tap_7_0 : 10; + RK_U32 sw_pred_bc_tap_6_3 : 10; + } reg127; + + struct { + RK_U32 sw_pred_tap_6_4 : 2; + RK_U32 sw_pred_tap_6_M1 : 2; + RK_U32 sw_pred_tap_4_4 : 2; + RK_U32 sw_pred_tap_4_M1 : 2; + RK_U32 sw_pred_tap_2_4 : 2; + RK_U32 sw_pred_tap_2_M1 : 2; + RK_U32 sw_pred_bc_tap_7_3 : 10; + RK_U32 sw_pred_bc_tap_7_2 : 10; + } reg128; + + struct { + RK_U32 sw_filt_level_3 : 6; + RK_U32 sw_filt_level_2 : 6; + RK_U32 sw_filt_level_1 : 6; + RK_U32 sw_filt_level_0 : 6; + RK_U32 reserve : 8; + } reg129; + + struct { + RK_U32 sw_quant_1 : 11; + RK_U32 sw_quant_0 : 11; + RK_U32 sw_quant_delta_1 : 5; + RK_U32 sw_quant_delta_0 : 5; + } reg130; + + + RK_U32 reg131_ref0_base; + + struct { + RK_U32 sw_filt_mb_adj_3 : 7; + RK_U32 sw_filt_mb_adj_2 : 7; + RK_U32 sw_filt_mb_adj_1 : 7; + RK_U32 sw_filt_mb_adj_0 : 7; + RK_U32 sw_filt_sharpness : 3; + RK_U32 sw_filt_type : 1; + } reg132; + + + struct { + RK_U32 sw_filt_ref_adj_3 : 7; + RK_U32 sw_filt_ref_adj_2 : 7; + RK_U32 sw_filt_ref_adj_1 : 7; + RK_U32 sw_filt_ref_adj_0 : 7; + RK_U32 sw_reserve : 4; + } reg133; + + RK_U32 reg134_ref2_base; + RK_U32 reg135_ref3_base; + + struct { + RK_U32 sw_prev_pic_type : 1; + RK_U32 sw_rounding : 1; + RK_U32 sw_fwd_mv_y_resolution : 1; + RK_U32 sw_vrz_bit_of_bwd_mv : 4; + RK_U32 sw_hrz_bit_of_bwd_mv : 4; + RK_U32 sw_vrz_bit_of_fwd_mv : 4; + RK_U32 sw_hrz_bit_of_fwd_mv : 4; + RK_U32 sw_alt_scan : 1; + RK_U32 sw_reserve : 12; + } reg136; + + struct { + RK_U32 sw_trb_per_trd_d0 : 27; + RK_U32 sw_reserve : 5; + } reg137; + + struct { + RK_U32 sw_trb_per_trd_dm1 : 27; + RK_U32 sw_reserve : 5; + } reg138; + + struct { + RK_U32 sw_trb_per_trd_d1 : 27; + RK_U32 sw_reserve : 5; + } reg139; + + RK_U32 reg_dct_strm_base[5]; + RK_U32 reg145_bitpl_ctrl_base; + RK_U32 reg_dct_strm1_base[2]; + + RK_U32 reg148_ref1_base; + + RK_U32 reg149_segment_map_base; + + + struct { + RK_U32 sw_dct_start_bit_7 : 6; + RK_U32 sw_dct_start_bit_6 : 6; + RK_U32 sw_dct_start_bit_5 : 6; + RK_U32 sw_dct_start_bit_4 : 6; + RK_U32 sw_dct_start_bit_3 : 6; + RK_U32 sw_reserve : 2; + } reg150; + + struct { + RK_U32 sw_quant_3 : 11; + RK_U32 sw_quant_2 : 11; + RK_U32 sw_quant_delta_3 : 5; + RK_U32 sw_quant_delta_2 : 5; + } reg151; + + struct { + RK_U32 sw_quant_5 : 11; + RK_U32 sw_quant_4 : 11; + RK_U32 sw_quant_delta_4 : 5; + RK_U32 sw_reserve : 5; + } reg152; + + struct { + RK_U32 reserve : 2; + RK_U32 sw_pred_bc_tap_1_1 : 10; + RK_U32 sw_pred_bc_tap_1_0 : 10; + RK_U32 sw_pred_bc_tap_0_3 : 10; + } reg153; + + struct { + RK_U32 reserve : 2; + RK_U32 sw_pred_bc_tap_2_0 : 10; + RK_U32 sw_pred_bc_tap_1_3 : 10; + RK_U32 sw_pred_bc_tap_1_2 : 10; + } reg154; + + struct { + RK_U32 reserve : 2; + RK_U32 sw_pred_bc_tap_2_3 : 10; + RK_U32 sw_pred_bc_tap_2_2 : 10; + RK_U32 sw_pred_bc_tap_2_1 : 10; + } reg155; + + struct { + RK_U32 reserve : 2; + RK_U32 sw_pred_bc_tap_3_2 : 10; + RK_U32 sw_pred_bc_tap_3_1 : 10; + RK_U32 sw_pred_bc_tap_3_0 : 10; + } reg156; + + struct { + RK_U32 reserve : 2; + RK_U32 sw_pred_bc_tap_4_1 : 10; + RK_U32 sw_pred_bc_tap_4_0 : 10; + RK_U32 sw_pred_bc_tap_3_3 : 10; + } reg157; + + struct { + RK_U32 reserve : 2; + RK_U32 sw_pred_bc_tap_5_0 : 10; + RK_U32 sw_pred_bc_tap_4_3 : 10; + RK_U32 sw_pred_bc_tap_4_2 : 10; + } reg158; +} VpuH263dRegSet_t; + +#endif + diff --git a/mpp/hal/vpu/jpegd/CMakeLists.txt b/mpp/hal/vpu/jpegd/CMakeLists.txt index 0f91067d..429aba37 100644 --- a/mpp/hal/vpu/jpegd/CMakeLists.txt +++ b/mpp/hal/vpu/jpegd/CMakeLists.txt @@ -1,20 +1,20 @@ -# vim: syntax=cmake -# hal jpeg reg - -set(HAL_JPEGD_HDR - hal_jpegd_reg.h - ) - -set(HAL_JPEGD_SRC - hal_jpegd_reg.c - ) - -add_library(hal_jpegd STATIC - ${HAL_JPEGD_SRC} ${HAL_JPEGD_HDR} - ) - -set_target_properties(hal_jpegd PROPERTIES FOLDER "mpp/hal") - - target_link_libraries(hal_jpegd mpp_base) - -#add_subdirectory(test) +# vim: syntax=cmake +# hal jpeg reg + +set(HAL_JPEGD_HDR + hal_jpegd_reg.h + ) + +set(HAL_JPEGD_SRC + hal_jpegd_reg.c + ) + +add_library(hal_jpegd STATIC + ${HAL_JPEGD_SRC} ${HAL_JPEGD_HDR} + ) + +set_target_properties(hal_jpegd PROPERTIES FOLDER "mpp/hal") + + target_link_libraries(hal_jpegd mpp_base) + +#add_subdirectory(test) diff --git a/mpp/hal/vpu/jpegd/hal_jpegd_reg.c b/mpp/hal/vpu/jpegd/hal_jpegd_reg.c index 4b8d6292..d627694c 100644 --- a/mpp/hal/vpu/jpegd/hal_jpegd_reg.c +++ b/mpp/hal/vpu/jpegd/hal_jpegd_reg.c @@ -1,2188 +1,2188 @@ -/* - * - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -#define MODULE_TAG "JPEGHAL" - -#include -#include - -#include "mpp_buffer.h" -#include "mpp_log.h" -#include "mpp_err.h" -#include "mpp_mem.h" -#include "mpp_bitread.h" -#include "mpp_dec.h" -#include "vpu.h" -#include "mpp_buffer.h" -#include "mpp_env.h" -#include "mpp_bitput.h" - -#include "jpegd_api.h" -#include "hal_jpegd_reg.h" - -static const RK_U8 zzOrder[64] = { - 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, - 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, - 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51, - 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63 -}; - -void jpegd_input_buff_load_init(JpegSyntaxParam *pSyntax) -{ - FUN_TEST("Enter"); - // TODO: no need so far - (void)pSyntax; - FUN_TEST("Exit"); -} - -static void jpegd_write_len_bits(JpegSyntaxParam *pSyntax, JpegHalContext *pCtx) -{ - FUN_TEST("Enter"); - ScanInfo *JPG_SCN = &pSyntax->scan; - HuffmanTables *JPG_VLC = &pSyntax->vlc; - JpegRegSet *reg = &(pCtx->regs); - - VlcTable *pTable1 = NULL; - VlcTable *pTable2 = NULL; - - /* first select the table we'll use */ - - /* this trick is done because hw always wants luma table as ac hw table 1 */ - if (JPG_SCN->Ta[0] == 0) { - pTable1 = &(JPG_VLC->acTable0); - pTable2 = &(JPG_VLC->acTable1); - } else { - pTable1 = &(JPG_VLC->acTable1); - pTable2 = &(JPG_VLC->acTable0); - } - - JPEGD_ASSERT(pTable1); - JPEGD_ASSERT(pTable2); - - /* write AC table 1 (luma) */ - reg->reg134.sw_ac1_code1_cnt = pTable1->bits[0]; - reg->reg134.sw_ac1_code2_cnt = pTable1->bits[1]; - reg->reg134.sw_ac1_code3_cnt = pTable1->bits[2]; - reg->reg134.sw_ac1_code4_cnt = pTable1->bits[3]; - reg->reg134.sw_ac1_code5_cnt = pTable1->bits[4]; - reg->reg134.sw_ac1_code6_cnt = pTable1->bits[5]; - - reg->reg135.sw_ac1_code7_cnt = pTable1->bits[6]; - reg->reg135.sw_ac1_code8_cnt = pTable1->bits[7]; - reg->reg135.sw_ac1_code9_cnt = pTable1->bits[8]; - reg->reg135.sw_ac1_code10_cnt = pTable1->bits[9]; - - reg->reg136.sw_ac1_code11_cnt = pTable1->bits[10]; - reg->reg136.sw_ac1_code12_cnt = pTable1->bits[11]; - reg->reg136.sw_ac1_code13_cnt = pTable1->bits[12]; - reg->reg136.sw_ac1_code14_cnt = pTable1->bits[13]; - - reg->reg137.sw_ac1_code15_cnt = pTable1->bits[14]; - reg->reg137.sw_ac1_code16_cnt = pTable1->bits[15]; - - /* table AC2 (the not-luma table) */ - reg->reg137.sw_ac2_code1_cnt = pTable2->bits[0]; - reg->reg137.sw_ac2_code2_cnt = pTable2->bits[1]; - reg->reg137.sw_ac2_code3_cnt = pTable2->bits[2]; - reg->reg137.sw_ac2_code4_cnt = pTable2->bits[3]; - - reg->reg138.sw_ac2_code5_cnt = pTable2->bits[4]; - reg->reg138.sw_ac2_code6_cnt = pTable2->bits[5]; - reg->reg138.sw_ac2_code7_cnt = pTable2->bits[6]; - reg->reg138.sw_ac2_code8_cnt = pTable2->bits[7]; - - reg->reg139.sw_ac2_code9_cnt = pTable2->bits[8]; - reg->reg139.sw_ac2_code10_cnt = pTable2->bits[9]; - reg->reg139.sw_ac2_code11_cnt = pTable2->bits[10]; - reg->reg139.sw_ac2_code12_cnt = pTable2->bits[11]; - - reg->reg140.sw_ac2_code13_cnt = pTable2->bits[12]; - reg->reg140.sw_ac2_code14_cnt = pTable2->bits[13]; - reg->reg140.sw_ac2_code15_cnt = pTable2->bits[14]; - reg->reg140.sw_ac2_code16_cnt = pTable2->bits[15]; - - if (JPG_SCN->Td[0] == 0) { - pTable1 = &(JPG_VLC->dcTable0); - pTable2 = &(JPG_VLC->dcTable1); - } else { - pTable1 = &(JPG_VLC->dcTable1); - pTable2 = &(JPG_VLC->dcTable0); - } - - JPEGD_ASSERT(pTable1); - JPEGD_ASSERT(pTable2); - - /* write DC table 1 (luma) */ - reg->reg141.sw_dc1_code1_cnt = pTable1->bits[0]; - reg->reg141.sw_dc1_code2_cnt = pTable1->bits[1]; - reg->reg141.sw_dc1_code3_cnt = pTable1->bits[2]; - reg->reg141.sw_dc1_code4_cnt = pTable1->bits[3]; - reg->reg141.sw_dc1_code5_cnt = pTable1->bits[4]; - reg->reg141.sw_dc1_code6_cnt = pTable1->bits[5]; - reg->reg141.sw_dc1_code7_cnt = pTable1->bits[6]; - reg->reg141.sw_dc1_code8_cnt = pTable1->bits[7]; - - reg->reg142.sw_dc1_code9_cnt = pTable1->bits[8]; - reg->reg142.sw_dc1_code10_cnt = pTable1->bits[9]; - reg->reg142.sw_dc1_code11_cnt = pTable1->bits[10]; - reg->reg142.sw_dc1_code12_cnt = pTable1->bits[11]; - reg->reg142.sw_dc1_code13_cnt = pTable1->bits[12]; - reg->reg142.sw_dc1_code14_cnt = pTable1->bits[13]; - reg->reg142.sw_dc1_code15_cnt = pTable1->bits[14]; - reg->reg142.sw_dc1_code16_cnt = pTable1->bits[15]; - - /* table DC2 (the not-luma table) */ - reg->reg143.sw_dc2_code1_cnt = pTable2->bits[0]; - reg->reg143.sw_dc2_code2_cnt = pTable2->bits[1]; - reg->reg143.sw_dc2_code3_cnt = pTable2->bits[2]; - reg->reg143.sw_dc2_code4_cnt = pTable2->bits[3]; - reg->reg143.sw_dc2_code5_cnt = pTable2->bits[4]; - reg->reg143.sw_dc2_code6_cnt = pTable2->bits[5]; - reg->reg143.sw_dc2_code7_cnt = pTable2->bits[6]; - reg->reg143.sw_dc2_code8_cnt = pTable2->bits[7]; - - reg->reg144.sw_dc2_code9_cnt = pTable2->bits[8]; - reg->reg144.sw_dc2_code10_cnt = pTable2->bits[9]; - reg->reg144.sw_dc2_code11_cnt = pTable2->bits[10]; - reg->reg144.sw_dc2_code12_cnt = pTable2->bits[11]; - reg->reg144.sw_dc2_code13_cnt = pTable2->bits[12]; - reg->reg144.sw_dc2_code14_cnt = pTable2->bits[13]; - reg->reg144.sw_dc2_code15_cnt = pTable2->bits[14]; - reg->reg144.sw_dc2_code16_cnt = pTable2->bits[15]; - - FUN_TEST("Exit"); - return; -} - -static void jpegd_set_stream_params(JpegSyntaxParam *pSyntax, JpegHalContext *pCtx) -{ - FUN_TEST("Enter"); - StreamStorage *JPG_STR = &pSyntax->stream; - JpegRegSet *reg = &(pCtx->regs); - - RK_U32 addrTmp = 0; - RK_U32 amountOfStream = 0; - - JPEGD_INFO_LOG("read %d bits\n", JPG_STR->readBits); - JPEGD_INFO_LOG("read %d bytes\n", JPG_STR->readBits / 8); - JPEGD_INFO_LOG("Stream physical address start: 0x%08x\n", JPG_STR->streamBus); - JPEGD_INFO_LOG("Stream virtual address start: %p\n", JPG_STR->pStartOfStream); - - /* calculate and set stream start address to hw */ - addrTmp = (((RK_U32) JPG_STR->pStartOfStream & 0x3) + - (RK_U32) (JPG_STR->pCurrPos - JPG_STR->pStartOfStream)) & (~7); - - JPEGD_INFO_LOG("pStartOfStream data: 0x%x, 0x%x, 0x%x, 0x%x", JPG_STR->pStartOfStream[JPG_STR->streamLength - 4], - JPG_STR->pStartOfStream[JPG_STR->streamLength - 3], - JPG_STR->pStartOfStream[JPG_STR->streamLength - 2], - JPG_STR->pStartOfStream[JPG_STR->streamLength - 1]); - - if (VPUClientGetIOMMUStatus() <= 0) { - reg->reg64_rlc_vlc_base = JPG_STR->streamBus + addrTmp; - } else { - reg->reg64_rlc_vlc_base = JPG_STR->streamBus | (addrTmp << 10); - } - JPEGD_INFO_LOG("reg64_rlc_vlc_base: 0x%08x\n", reg->reg64_rlc_vlc_base); - - /* calculate and set stream start bit to hw */ - - /* change current pos to bus address style */ - /* remove three lowest bits and add the difference to bitPosInWord */ - /* used as bit pos in word not as bit pos in byte actually... */ - switch ((RK_U32) JPG_STR->pCurrPos & (7)) { - case 0: - break; - case 1: - JPG_STR->bitPosInByte += 8; - break; - case 2: - JPG_STR->bitPosInByte += 16; - break; - case 3: - JPG_STR->bitPosInByte += 24; - break; - case 4: - JPG_STR->bitPosInByte += 32; - break; - case 5: - JPG_STR->bitPosInByte += 40; - break; - case 6: - JPG_STR->bitPosInByte += 48; - break; - case 7: - JPG_STR->bitPosInByte += 56; - break; - default: - JPEGD_ASSERT(0); - break; - } - - reg->reg122.sw_strm_start_bit = JPG_STR->bitPosInByte; - - /* set up stream length for HW. - * length = size of original buffer - stream we already decoded in SW */ - JPG_STR->pCurrPos = (RK_U8 *) ((RK_U32) JPG_STR->pCurrPos & (~7)); - - if (pSyntax->info.inputStreaming) { - JPEGD_VERBOSE_LOG("inputStreaming-1, inputBufferLen:%d", pSyntax->info.inputBufferLen); - amountOfStream = (pSyntax->info.inputBufferLen - - (RK_U32) (JPG_STR->pCurrPos - JPG_STR->pStartOfStream)); - - reg->reg51_stream_info.sw_stream_len = amountOfStream; - pSyntax->info.streamEnd = 1; - } else { - JPEGD_VERBOSE_LOG("inputStreaming-2"); - amountOfStream = (JPG_STR->streamLength - - (RK_U32) (JPG_STR->pCurrPos - JPG_STR->pStartOfStream)); - - reg->reg51_stream_info.sw_stream_len = amountOfStream; - - /* because no input streaming, frame should be ready during decoding this buffer */ - pSyntax->info.streamEnd = 1; - } - - reg->reg122.sw_jpeg_stream_all = pSyntax->info.streamEnd; - - JPEGD_INFO_LOG("streamLength: %d\n", JPG_STR->streamLength); - JPEGD_INFO_LOG("pCurrPos: %p\n", JPG_STR->pCurrPos); - JPEGD_INFO_LOG("pStartOfStream: %p\n", JPG_STR->pStartOfStream); - JPEGD_INFO_LOG("bitPosInByte: 0x%08x\n", JPG_STR->bitPosInByte); - - FUN_TEST("Exit"); - return; -} - -static void jpegd_select_chroma_table(JpegSyntaxParam *pSyntax, JpegHalContext *pCtx) -{ - FUN_TEST("Enter"); - ScanInfo *JPG_SCN = &pSyntax->scan; - JpegRegSet *reg = &(pCtx->regs); - - /* this trick is done because hw always wants luma table as ac hw table 1 */ - if (JPG_SCN->Ta[0] == 0) { - reg->reg122.sw_cr_ac_vlctable = JPG_SCN->Ta[2]; - reg->reg122.sw_cb_ac_vlctable = JPG_SCN->Ta[1]; - } else { - if (JPG_SCN->Ta[0] == JPG_SCN->Ta[1]) - reg->reg122.sw_cb_ac_vlctable = 0; - else - reg->reg122.sw_cb_ac_vlctable = 1; - - if (JPG_SCN->Ta[0] == JPG_SCN->Ta[2]) - reg->reg122.sw_cr_ac_vlctable = 0; - else - reg->reg122.sw_cr_ac_vlctable = 1; - } - - /* Third DC table selectors */ - if (pSyntax->info.operationType != JPEGDEC_PROGRESSIVE) { - JPEGD_INFO_LOG("NON_PROGRESSIVE"); - if (JPG_SCN->Td[0] == 0) { - reg->reg122.sw_cr_dc_vlctable = JPG_SCN->Td[2]; - reg->reg122.sw_cb_dc_vlctable = JPG_SCN->Td[1]; - } else { - if (JPG_SCN->Td[0] == JPG_SCN->Td[1]) - reg->reg122.sw_cb_dc_vlctable = 0; - else - reg->reg122.sw_cb_dc_vlctable = 1; - - if (JPG_SCN->Td[0] == JPG_SCN->Td[2]) - reg->reg122.sw_cr_dc_vlctable = 0; - else - reg->reg122.sw_cr_dc_vlctable = 1; - } - - reg->reg122.sw_cr_dc_vlctable3 = 0; - reg->reg122.sw_cb_dc_vlctable3 = 0; - } else { - JPEGD_INFO_LOG("JPEGDEC_PROGRESSIVE"); - } - - FUN_TEST("Exit"); - return; -} - -MPP_RET jpegd_set_output_format(JpegHalContext *pCtx, JpegSyntaxParam *pSyntax) -{ - FUN_TEST("Enter"); - MPP_RET ret = MPP_OK; - if (NULL == pSyntax || NULL == pCtx) { - JPEGD_ERROR_LOG("NULL pointer"); - return MPP_ERR_NULL_PTR; - } - PostProcessInfo ppInfo; - RK_U32 ppInputFomart = 0; - RK_U32 ppScaleW = 640, ppScaleH = 480; - - if (pCtx->set_output_fmt_flag && (pCtx->output_fmt != pSyntax->imageInfo.outputFormat)) { - /* Using pp to convert all format to yuv420sp */ - switch (pSyntax->imageInfo.outputFormat) { - case JPEGDEC_YCbCr400: - ppInputFomart = PP_IN_FORMAT_YUV400; - break; - case MPP_FMT_YUV420SP: - ppInputFomart = PP_IN_FORMAT_YUV420SEMI; - break; - case MPP_FMT_YUV422SP: - ppInputFomart = PP_IN_FORMAT_YUV422SEMI; - break; - case JPEGDEC_YCbCr440: - ppInputFomart = PP_IN_FORMAT_YUV440SEMI; - break; - case JPEGDEC_YCbCr411_SEMIPLANAR: - ppInputFomart = PP_IN_FORMAT_YUV411_SEMI; - break; - case JPEGDEC_YCbCr444_SEMIPLANAR: - ppInputFomart = PP_IN_FORMAT_YUV444_SEMI; - break; - } - - // set pp info - memset(&ppInfo, 0, sizeof(ppInfo)); - ppInfo.enable = 1; - ppInfo.outFomart = 5; //PP_OUT_FORMAT_YUV420INTERLAVE - ppScaleW = pSyntax->imageInfo.outputWidth; - ppScaleH = pSyntax->imageInfo.outputHeight; - if (ppScaleW > 1920) { // || ppScaleH > 1920) { - ppScaleW = (ppScaleW + 15) & (~15); //(ppScaleW + 15)/16*16; - ppScaleH = (ppScaleH + 15) & (~15); - } else { - ppScaleW = (ppScaleW + 7) & (~7); // pp dest width must be dividable by 8 - ppScaleH = (ppScaleH + 1) & (~1); // must be dividable by 2.in pp downscaling ,the output lines always equal (desire lines - 1); - } - - JPEGD_INFO_LOG("Post Process! ppScaleW:%d, ppScaleH:%d", ppScaleW, ppScaleH); - pSyntax->ppInstance = (void *)1; - } else { - /* keep original output format */ - memset(&ppInfo, 0, sizeof(ppInfo)); - ppInfo.outFomart = 5; //PP_OUT_FORMAT_YUV420INTERLAVE - ppScaleW = pSyntax->imageInfo.outputWidth; - ppScaleH = pSyntax->imageInfo.outputHeight; - - ppScaleW = (ppScaleW + 15) & (~15); - ppScaleH = (ppScaleH + 15) & (~15); - - switch (pSyntax->imageInfo.outputFormat) { - case JPEGDEC_YCbCr400: - ppInputFomart = PP_IN_FORMAT_YUV400; - break; - case MPP_FMT_YUV420SP: - ppInputFomart = PP_IN_FORMAT_YUV420SEMI; - break; - case MPP_FMT_YUV422SP: - ppInputFomart = PP_IN_FORMAT_YUV422SEMI; - break; - case JPEGDEC_YCbCr440: - ppInputFomart = PP_IN_FORMAT_YUV440SEMI; - break; - case JPEGDEC_YCbCr411_SEMIPLANAR: - ppInputFomart = PP_IN_FORMAT_YUV411_SEMI; - break; - case JPEGDEC_YCbCr444_SEMIPLANAR: - ppInputFomart = PP_IN_FORMAT_YUV444_SEMI; - break; - } - - pSyntax->ppInstance = (void *)0; - } - - memcpy(&(pSyntax->ppInfo), &(ppInfo), sizeof(PostProcessInfo)); - pSyntax->ppScaleW = ppScaleW; - pSyntax->ppScaleH = ppScaleH; - pSyntax->ppInputFomart = ppInputFomart; - - FUN_TEST("Exit"); - return ret; -} - -static void jpegd_write_tables(JpegSyntaxParam *pSyntax, JpegHalContext *pCtx) -{ - FUN_TEST("Enter"); - ScanInfo *JPG_SCN = &pSyntax->scan; - HuffmanTables *JPG_VLC = &pSyntax->vlc; - QuantTables *JPG_QTB = &pSyntax->quant; - FrameInfo *JPG_FRM = &pSyntax->frame; - - RK_U32 i, j = 0; - RK_U32 shifter = 32; - RK_U32 tableWord = 0; - RK_U32 tableValue = 0; - RK_U8 tableTmp[64] = { 0 }; - RK_U32 *pTableBase = NULL; - - pTableBase = (RK_U32 *)mpp_buffer_get_ptr(pCtx->pTableBase); - - /* QP tables for all components */ - for (j = 0; j < pSyntax->info.amountOfQTables; j++) { - if ((JPG_FRM->component[j].Tq) == 0) { - for (i = 0; i < 64; i++) { - tableTmp[zzOrder[i]] = (RK_U8) JPG_QTB->table0[i]; - } - - /* update shifter */ - shifter = 32; - - for (i = 0; i < 64; i++) { - shifter -= 8; - - if (shifter == 24) - tableWord = (tableTmp[i] << shifter); - else - tableWord |= (tableTmp[i] << shifter); - - if (shifter == 0) { - *(pTableBase) = tableWord; - pTableBase++; - shifter = 32; - } - } - } else { - for (i = 0; i < 64; i++) { - tableTmp[zzOrder[i]] = (RK_U8) JPG_QTB->table1[i]; - } - - /* update shifter */ - shifter = 32; - - for (i = 0; i < 64; i++) { - shifter -= 8; - - if (shifter == 24) - tableWord = (tableTmp[i] << shifter); - else - tableWord |= (tableTmp[i] << shifter); - - if (shifter == 0) { - *(pTableBase) = tableWord; - pTableBase++; - shifter = 32; - } - } - } - } - - /* update shifter */ - shifter = 32; - - if (pSyntax->info.yCbCrMode != JPEGDEC_YUV400) { - /* this trick is done because hw always wants luma table as ac hw table 1 */ - if (JPG_SCN->Ta[0] == 0) { - /* Write AC Table 1 (as specified in HW regs) - * NOTE: Not the same as actable[1] (as specified in JPEG Spec) */ - JPEGD_VERBOSE_LOG("INTERNAL: Write tables: AC1 (luma)\n"); - if (JPG_VLC->acTable0.vals) { - for (i = 0; i < 162; i++) { - if (i < JPG_VLC->acTable0.tableLength) { - tableValue = (RK_U8) JPG_VLC->acTable0.vals[i]; - } else { - tableValue = 0; - } - - if (shifter == 32) - tableWord = (tableValue << (shifter - 8)); - else - tableWord |= (tableValue << (shifter - 8)); - - shifter -= 8; - - if (shifter == 0) { - *(pTableBase) = tableWord; - pTableBase++; - shifter = 32; - } - } - } else { - for (i = 0; i < 162; i++) { - tableWord = 0; - shifter -= 8; - - if (shifter == 0) { - *(pTableBase) = tableWord; - pTableBase++; - shifter = 32; - } - } - } - - /* Write AC Table 2 */ - JPEGD_VERBOSE_LOG("INTERNAL: Write tables: AC2 (not-luma)\n"); - if (JPG_VLC->acTable1.vals) { - for (i = 0; i < 162; i++) { - if (i < JPG_VLC->acTable1.tableLength) { - tableValue = (RK_U8) JPG_VLC->acTable1.vals[i]; - } else { - tableValue = 0; - } - - if (shifter == 32) - tableWord = (tableValue << (shifter - 8)); - else - tableWord |= (tableValue << (shifter - 8)); - - shifter -= 8; - - if (shifter == 0) { - *(pTableBase) = tableWord; - pTableBase++; - shifter = 32; - } - } - } else { - for (i = 0; i < 162; i++) { - tableWord = 0; - shifter -= 8; - - if (shifter == 0) { - *(pTableBase) = tableWord; - pTableBase++; - shifter = 32; - } - } - } - } else { - /* Write AC Table 1 (as specified in HW regs) - * NOTE: Not the same as actable[1] (as specified in JPEG Spec) */ - if (JPG_VLC->acTable1.vals) { - JPEGD_INFO_LOG("INTERNAL: Write tables: AC1 (luma)\n"); - for (i = 0; i < 162; i++) { - if (i < JPG_VLC->acTable1.tableLength) { - tableValue = (RK_U8) JPG_VLC->acTable1.vals[i]; - } else { - tableValue = 0; - } - - if (shifter == 32) - tableWord = (tableValue << (shifter - 8)); - else - tableWord |= (tableValue << (shifter - 8)); - - shifter -= 8; - - if (shifter == 0) { - *(pTableBase) = tableWord; - pTableBase++; - shifter = 32; - } - } - } else { - for (i = 0; i < 162; i++) { - tableWord = 0; - shifter -= 8; - - if (shifter == 0) { - *(pTableBase) = tableWord; - pTableBase++; - shifter = 32; - } - } - } - - /* Write AC Table 2 */ - if (JPG_VLC->acTable0.vals) { - JPEGD_INFO_LOG("INTERNAL: writeTables: AC2 (not-luma)\n"); - for (i = 0; i < 162; i++) { - if (i < JPG_VLC->acTable0.tableLength) { - tableValue = (RK_U8) JPG_VLC->acTable0.vals[i]; - } else { - tableValue = 0; - } - - if (shifter == 32) - tableWord = (tableValue << (shifter - 8)); - else - tableWord |= (tableValue << (shifter - 8)); - - shifter -= 8; - - if (shifter == 0) { - *(pTableBase) = tableWord; - pTableBase++; - shifter = 32; - } - } - } else { - for (i = 0; i < 162; i++) { - tableWord = 0; - shifter -= 8; - - if (shifter == 0) { - *(pTableBase) = tableWord; - pTableBase++; - shifter = 32; - } - } - } - } - - /* this trick is done because hw always wants luma table as dc hw table 1 */ - if (JPG_SCN->Td[0] == 0) { - if (JPG_VLC->dcTable0.vals) { - for (i = 0; i < 12; i++) { - if (i < JPG_VLC->dcTable0.tableLength) { - tableValue = (RK_U8) JPG_VLC->dcTable0.vals[i]; - } else { - tableValue = 0; - } - - if (shifter == 32) - tableWord = (tableValue << (shifter - 8)); - else - tableWord |= (tableValue << (shifter - 8)); - - shifter -= 8; - - if (shifter == 0) { - *(pTableBase) = tableWord; - pTableBase++; - shifter = 32; - } - } - } else { - for (i = 0; i < 12; i++) { - tableWord = 0; - shifter -= 8; - - if (shifter == 0) { - *(pTableBase) = tableWord; - pTableBase++; - shifter = 32; - } - } - } - - if (JPG_VLC->dcTable1.vals) { - for (i = 0; i < 12; i++) { - if (i < JPG_VLC->dcTable1.tableLength) { - tableValue = (RK_U8) JPG_VLC->dcTable1.vals[i]; - } else { - tableValue = 0; - } - - if (shifter == 32) - tableWord = (tableValue << (shifter - 8)); - else - tableWord |= (tableValue << (shifter - 8)); - - shifter -= 8; - - if (shifter == 0) { - *(pTableBase) = tableWord; - pTableBase++; - shifter = 32; - } - } - } else { - for (i = 0; i < 12; i++) { - tableWord = 0; - shifter -= 8; - - if (shifter == 0) { - *(pTableBase) = tableWord; - pTableBase++; - shifter = 32; - } - } - } - - } else { - if (JPG_VLC->dcTable1.vals) { - for (i = 0; i < 12; i++) { - if (i < JPG_VLC->dcTable1.tableLength) { - tableValue = (RK_U8) JPG_VLC->dcTable1.vals[i]; - } else { - tableValue = 0; - } - - if (shifter == 32) - tableWord = (tableValue << (shifter - 8)); - else - tableWord |= (tableValue << (shifter - 8)); - - shifter -= 8; - - if (shifter == 0) { - *(pTableBase) = tableWord; - pTableBase++; - shifter = 32; - } - } - } else { - for (i = 0; i < 12; i++) { - tableWord = 0; - shifter -= 8; - - if (shifter == 0) { - *(pTableBase) = tableWord; - pTableBase++; - shifter = 32; - } - } - } - - if (JPG_VLC->dcTable0.vals) { - for (i = 0; i < 12; i++) { - if (i < JPG_VLC->dcTable0.tableLength) { - tableValue = (RK_U8) JPG_VLC->dcTable0.vals[i]; - } else { - tableValue = 0; - } - - if (shifter == 32) - tableWord = (tableValue << (shifter - 8)); - else - tableWord |= (tableValue << (shifter - 8)); - - shifter -= 8; - - if (shifter == 0) { - *(pTableBase) = tableWord; - pTableBase++; - shifter = 32; - } - } - } else { - for (i = 0; i < 12; i++) { - tableWord = 0; - shifter -= 8; - - if (shifter == 0) { - *(pTableBase) = tableWord; - pTableBase++; - shifter = 32; - } - } - } - } - } else { /* YUV400 */ - if (!pSyntax->info.nonInterleavedScanReady) { - /* this trick is done because hw always wants luma table as ac hw table 1 */ - if (JPG_SCN->Ta[0] == 0) { - /* Write AC Table 1 (as specified in HW regs) - * NOTE: Not the same as actable[1] (as specified in JPEG Spec) */ - JPEGD_INFO_LOG("INTERNAL: Write tables: AC1 (luma)\n"); - if (JPG_VLC->acTable0.vals) { - for (i = 0; i < 162; i++) { - if (i < JPG_VLC->acTable0.tableLength) { - tableValue = (RK_U8) JPG_VLC->acTable0.vals[i]; - } else { - tableValue = 0; - } - - if (shifter == 32) - tableWord = (tableValue << (shifter - 8)); - else - tableWord |= (tableValue << (shifter - 8)); - - shifter -= 8; - - if (shifter == 0) { - *(pTableBase) = tableWord; - pTableBase++; - shifter = 32; - } - } - } else { - for (i = 0; i < 162; i++) { - tableWord = 0; - shifter -= 8; - - if (shifter == 0) { - *(pTableBase) = tableWord; - pTableBase++; - shifter = 32; - } - } - } - - /* Write AC Table 2 */ - JPEGD_INFO_LOG("INTERNAL: Write zero table (YUV400): \n"); - for (i = 0; i < 162; i++) { - tableValue = 0; - - if (shifter == 32) - tableWord = (tableValue << (shifter - 8)); - else - tableWord |= (tableValue << (shifter - 8)); - - shifter -= 8; - - if (shifter == 0) { - *(pTableBase) = tableWord; - pTableBase++; - shifter = 32; - } - } - } else { - /* Write AC Table 1 (as specified in HW regs) - * NOTE: Not the same as actable[1] (as specified in JPEG Spec) */ - if (JPG_VLC->acTable1.vals) { - JPEGD_INFO_LOG("INTERNAL: Write tables: AC1 (luma)\n"); - for (i = 0; i < 162; i++) { - if (i < JPG_VLC->acTable1.tableLength) { - tableValue = (RK_U8) JPG_VLC->acTable1.vals[i]; - } else { - tableValue = 0; - } - - if (shifter == 32) - tableWord = (tableValue << (shifter - 8)); - else - tableWord |= (tableValue << (shifter - 8)); - - shifter -= 8; - - if (shifter == 0) { - *(pTableBase) = tableWord; - pTableBase++; - shifter = 32; - } - } - } else { - for (i = 0; i < 162; i++) { - tableWord = 0; - - shifter -= 8; - - if (shifter == 0) { - *(pTableBase) = tableWord; - pTableBase++; - shifter = 32; - } - } - } - - /* Write AC Table 2 */ - JPEGD_INFO_LOG("INTERNAL: writeTables: padding zero (YUV400)\n"); - for (i = 0; i < 162; i++) { - tableValue = 0; - - if (shifter == 32) - tableWord = (tableValue << (shifter - 8)); - else - tableWord |= (tableValue << (shifter - 8)); - - shifter -= 8; - - if (shifter == 0) { - *(pTableBase) = tableWord; - pTableBase++; - shifter = 32; - } - } - } - - /* this trick is done because hw always wants luma table as dc hw table 1 */ - if (JPG_SCN->Td[0] == 0) { - if (JPG_VLC->dcTable0.vals) { - for (i = 0; i < 12; i++) { - if (i < JPG_VLC->dcTable0.tableLength) { - tableValue = (RK_U8) JPG_VLC->dcTable0.vals[i]; - } else { - tableValue = 0; - } - - if (shifter == 32) - tableWord = (tableValue << (shifter - 8)); - else - tableWord |= (tableValue << (shifter - 8)); - - shifter -= 8; - - if (shifter == 0) { - *(pTableBase) = tableWord; - pTableBase++; - shifter = 32; - } - } - } else { - for (i = 0; i < 12; i++) { - tableWord = 0; - shifter -= 8; - - if (shifter == 0) { - *(pTableBase) = tableWord; - pTableBase++; - shifter = 32; - } - } - } - - for (i = 0; i < 12; i++) { - tableValue = 0; - - if (shifter == 32) - tableWord = (tableValue << (shifter - 8)); - else - tableWord |= (tableValue << (shifter - 8)); - - shifter -= 8; - - if (shifter == 0) { - *(pTableBase) = tableWord; - pTableBase++; - shifter = 32; - } - } - } else { - if (JPG_VLC->dcTable1.vals) { - for (i = 0; i < 12; i++) { - if (i < JPG_VLC->dcTable1.tableLength) { - tableValue = (RK_U8) JPG_VLC->dcTable1.vals[i]; - } else { - tableValue = 0; - } - - if (shifter == 32) - tableWord = (tableValue << (shifter - 8)); - else - tableWord |= (tableValue << (shifter - 8)); - - shifter -= 8; - - if (shifter == 0) { - *(pTableBase) = tableWord; - pTableBase++; - shifter = 32; - } - } - } else { - for (i = 0; i < 12; i++) { - tableWord = 0; - shifter -= 8; - - if (shifter == 0) { - *(pTableBase) = tableWord; - pTableBase++; - shifter = 32; - } - } - } - - for (i = 0; i < 12; i++) { - tableValue = 0; - - if (shifter == 32) - tableWord = (tableValue << (shifter - 8)); - else - tableWord |= (tableValue << (shifter - 8)); - - shifter -= 8; - - if (shifter == 0) { - *(pTableBase) = tableWord; - pTableBase++; - shifter = 32; - } - } - } - } else { - /* this trick is done because hw always wants luma table as ac hw table 1 */ - if (JPG_SCN->Ta[pSyntax->info.componentId] == 0) { - /* Write AC Table 1 (as specified in HW regs) - * NOTE: Not the same as actable[1] (as specified in JPEG Spec) */ - JPEGD_INFO_LOG("INTERNAL: Write tables: AC1 (luma)\n"); - if (JPG_VLC->acTable0.vals) { - for (i = 0; i < 162; i++) { - if (i < JPG_VLC->acTable0.tableLength) { - tableValue = (RK_U8) JPG_VLC->acTable0.vals[i]; - } else { - tableValue = 0; - } - - if (shifter == 32) - tableWord = (tableValue << (shifter - 8)); - else - tableWord |= (tableValue << (shifter - 8)); - - shifter -= 8; - - if (shifter == 0) { - *(pTableBase) = tableWord; - pTableBase++; - shifter = 32; - } - } - } else { - for (i = 0; i < 162; i++) { - tableWord = 0; - shifter -= 8; - - if (shifter == 0) { - *(pTableBase) = tableWord; - pTableBase++; - shifter = 32; - } - } - } - - /* Write AC Table 2 */ - JPEGD_INFO_LOG("INTERNAL: Write zero table (YUV400): \n"); - for (i = 0; i < 162; i++) { - tableValue = 0; - - if (shifter == 32) - tableWord = (tableValue << (shifter - 8)); - else - tableWord |= (tableValue << (shifter - 8)); - - shifter -= 8; - - if (shifter == 0) { - *(pTableBase) = tableWord; - pTableBase++; - shifter = 32; - } - } - } else { - /* Write AC Table 1 (as specified in HW regs) - * NOTE: Not the same as actable[1] (as specified in JPEG Spec) */ - if (JPG_VLC->acTable1.vals) { - JPEGD_INFO_LOG("INTERNAL: Write tables: AC1 (luma)\n"); - for (i = 0; i < 162; i++) { - if (i < JPG_VLC->acTable1.tableLength) { - tableValue = (RK_U8) JPG_VLC->acTable1.vals[i]; - } else { - tableValue = 0; - } - - if (shifter == 32) - tableWord = (tableValue << (shifter - 8)); - else - tableWord |= (tableValue << (shifter - 8)); - - shifter -= 8; - - if (shifter == 0) { - *(pTableBase) = tableWord; - pTableBase++; - shifter = 32; - } - } - } else { - for (i = 0; i < 162; i++) { - tableWord = 0; - - shifter -= 8; - - if (shifter == 0) { - *(pTableBase) = tableWord; - pTableBase++; - shifter = 32; - } - } - } - - /* Write AC Table 2 */ - JPEGD_INFO_LOG("INTERNAL: writeTables: padding zero (YUV400)\n"); - for (i = 0; i < 162; i++) { - tableValue = 0; - - if (shifter == 32) - tableWord = (tableValue << (shifter - 8)); - else - tableWord |= (tableValue << (shifter - 8)); - - shifter -= 8; - - if (shifter == 0) { - *(pTableBase) = tableWord; - pTableBase++; - shifter = 32; - } - } - } - - /* this trick is done because hw always wants luma table as dc hw table 1 */ - if (JPG_SCN->Td[pSyntax->info.componentId] == 0) { - if (JPG_VLC->dcTable0.vals) { - for (i = 0; i < 12; i++) { - if (i < JPG_VLC->dcTable0.tableLength) { - tableValue = (RK_U8) JPG_VLC->dcTable0.vals[i]; - } else { - tableValue = 0; - } - - if (shifter == 32) - tableWord = (tableValue << (shifter - 8)); - else - tableWord |= (tableValue << (shifter - 8)); - - shifter -= 8; - - if (shifter == 0) { - *(pTableBase) = tableWord; - pTableBase++; - shifter = 32; - } - } - } else { - for (i = 0; i < 12; i++) { - tableWord = 0; - shifter -= 8; - - if (shifter == 0) { - *(pTableBase) = tableWord; - pTableBase++; - shifter = 32; - } - } - } - - for (i = 0; i < 12; i++) { - tableValue = 0; - - if (shifter == 32) - tableWord = (tableValue << (shifter - 8)); - else - tableWord |= (tableValue << (shifter - 8)); - - shifter -= 8; - - if (shifter == 0) { - *(pTableBase) = tableWord; - pTableBase++; - shifter = 32; - } - } - } else { - if (JPG_VLC->dcTable1.vals) { - for (i = 0; i < 12; i++) { - if (i < JPG_VLC->dcTable1.tableLength) { - tableValue = (RK_U8) JPG_VLC->dcTable1.vals[i]; - } else { - tableValue = 0; - } - - if (shifter == 32) - tableWord = (tableValue << (shifter - 8)); - else - tableWord |= (tableValue << (shifter - 8)); - - shifter -= 8; - - if (shifter == 0) { - *(pTableBase) = tableWord; - pTableBase++; - shifter = 32; - } - } - } else { - for (i = 0; i < 12; i++) { - tableWord = 0; - shifter -= 8; - - if (shifter == 0) { - *(pTableBase) = tableWord; - pTableBase++; - shifter = 32; - } - } - } - - for (i = 0; i < 12; i++) { - tableValue = 0; - - if (shifter == 32) - tableWord = (tableValue << (shifter - 8)); - else - tableWord |= (tableValue << (shifter - 8)); - - shifter -= 8; - - if (shifter == 0) { - *(pTableBase) = tableWord; - pTableBase++; - shifter = 32; - } - } - } - } - - } - - for (i = 0; i < 4; i++) { - tableValue = 0; - - if (shifter == 32) - tableWord = (tableValue << (shifter - 8)); - else - tableWord |= (tableValue << (shifter - 8)); - - shifter -= 8; - - if (shifter == 0) { - *(pTableBase) = tableWord; - pTableBase++; - shifter = 32; - } - } - FUN_TEST("Exit"); -} - -MPP_RET jpegd_allocate_chroma_out_buffer(JpegSyntaxParam *pSyntax) -{ - FUN_TEST("Enter"); - if (NULL == pSyntax) { - JPEGD_ERROR_LOG("NULL pointer"); - return MPP_ERR_NULL_PTR; - } - - if (pSyntax->ppInstance == NULL || (pSyntax->ppInstance != NULL && !pSyntax->ppControl.usePipeline)) { - if (pSyntax->info.givenOutLuma.vir_addr == NULL) { - JPEGD_INFO_LOG("givenOutLuma is NULL"); - - /* luma bus address to output */ - pSyntax->info.outLuma = pSyntax->asicBuff.outLumaBuffer; - - if (pSyntax->image.sizeChroma) { - JPEGD_INFO_LOG("sizeChroma:%d", pSyntax->image.sizeChroma); - JPEGD_INFO_LOG("sizeLuma:%d, outLumaBuffer.phy_addr:%x", pSyntax->image.sizeLuma, pSyntax->asicBuff.outLumaBuffer.phy_addr); - - pSyntax->asicBuff.outChromaBuffer.phy_addr = pSyntax->asicBuff.outLumaBuffer.phy_addr + (pSyntax->image.sizeLuma << 10); - - if (pSyntax->info.operationType != JPEGDEC_BASELINE) { - pSyntax->asicBuff.outChromaBuffer2.phy_addr = pSyntax->asicBuff.outChromaBuffer.phy_addr + ((pSyntax->image.sizeChroma / 2) << 10); - } else { - pSyntax->asicBuff.outChromaBuffer2.phy_addr = 0; - } - - // chroma bus address to output - pSyntax->info.outChroma = pSyntax->asicBuff.outChromaBuffer; - pSyntax->info.outChroma2 = pSyntax->asicBuff.outChromaBuffer2; - } - } else { - JPEGD_INFO_LOG("givenOutLuma is not NULL"); - pSyntax->asicBuff.outLumaBuffer.vir_addr = pSyntax->info.givenOutLuma.vir_addr; - pSyntax->asicBuff.outLumaBuffer.phy_addr = pSyntax->info.givenOutLuma.phy_addr; - - pSyntax->asicBuff.outChromaBuffer.vir_addr = pSyntax->info.givenOutChroma.vir_addr; - pSyntax->asicBuff.outChromaBuffer.phy_addr = pSyntax->info.givenOutChroma.phy_addr; - pSyntax->asicBuff.outChromaBuffer2.vir_addr = pSyntax->info.givenOutChroma2.vir_addr; - pSyntax->asicBuff.outChromaBuffer2.phy_addr = pSyntax->info.givenOutChroma2.phy_addr; - - /* luma bus address to output */ - pSyntax->info.outLuma = pSyntax->asicBuff.outLumaBuffer; - - if (pSyntax->image.sizeChroma) { - // chroma bus address to output - pSyntax->info.outChroma = pSyntax->asicBuff.outChromaBuffer; - pSyntax->info.outChroma2 = pSyntax->asicBuff.outChromaBuffer2; - } - - /* flag to release */ - pSyntax->info.userAllocMem = 1; - } - - JPEGD_INFO_LOG("Luma virtual: %p, phy_addr: %x\n", pSyntax->asicBuff.outLumaBuffer.vir_addr, - pSyntax->asicBuff.outLumaBuffer.phy_addr); - JPEGD_INFO_LOG("Chroma virtual: %p, phy_addr: %x\n", pSyntax->asicBuff.outChromaBuffer.vir_addr, - pSyntax->asicBuff.outChromaBuffer.phy_addr); - } - FUN_TEST("Exit"); - return MPP_OK; -} - -MPP_RET jpegd_set_post_processor(JpegHalContext *pCtx, JpegSyntaxParam *pSyntax) -{ - FUN_TEST("Enter"); - if (NULL == pCtx || NULL == pSyntax) { - JPEGD_ERROR_LOG("NULL pointer"); - return MPP_ERR_NULL_PTR; - } - - PostProcessInfo *ppInfo = &(pSyntax->ppInfo); - JpegRegSet *reg = &(pCtx->regs); - int inColor = pSyntax->ppInputFomart; - int outColor = ppInfo->outFomart; - int dither = ppInfo->shouldDither; - int inWidth = pSyntax->imageInfo.outputWidth; - int inHeigth = pSyntax->imageInfo.outputHeight; - int outWidth = pSyntax->ppScaleW; - int outHeight = pSyntax->ppScaleH; - - reg->reg0.sw_pp_axi_rd_id = 0; - reg->reg0.sw_pp_axi_wr_id = 0; - reg->reg0.sw_pp_scmd_dis = 1; - reg->reg0.sw_pp_max_burst = 16; - - reg->reg18_pp_in_lu_base = 0; - - reg->reg34.sw_ext_orig_width = inWidth >> 4; - - reg->reg37.sw_pp_in_a2_endsel = 1; - reg->reg37.sw_pp_in_a1_swap32 = 1; - reg->reg37.sw_pp_in_a1_endian = 1; - reg->reg37.sw_pp_in_swap32_e = 1; - reg->reg37.sw_pp_in_endian = 1; - reg->reg37.sw_pp_out_endian = 1; - reg->reg37.sw_pp_out_swap32_e = 1; - - reg->reg41.sw_pp_clk_gate_e = 1; - reg->reg41.sw_pp_ahb_hlock_e = 1; - reg->reg41.sw_pp_data_disc_e = 1; - - if (ppInfo->cropW <= 0) { - reg->reg34.sw_pp_in_w_ext = (((inWidth / 16) & 0xE00) >> 9); - reg->reg34.sw_pp_in_width = ((inWidth / 16) & 0x1FF); - reg->reg34.sw_pp_in_h_ext = (((inHeigth / 16) & 0x700) >> 8); - reg->reg34.sw_pp_in_height = ((inHeigth / 16) & 0x0FF); - } else { - reg->reg34.sw_pp_in_w_ext = (((ppInfo->cropW / 16) & 0xE00) >> 9); - reg->reg34.sw_pp_in_width = ((ppInfo->cropW / 16) & 0x1FF); - reg->reg34.sw_pp_in_h_ext = (((ppInfo->cropH / 16) & 0x700) >> 8); - reg->reg34.sw_pp_in_height = ((ppInfo->cropH / 16) & 0x0FF); - - reg->reg14.sw_crop_startx_ext = (((ppInfo->cropX / 16) & 0xE00) >> 9); - reg->reg14.sw_crop_startx = ((ppInfo->cropX / 16) & 0x1FF); - reg->reg14.sw_crop_starty_ext = (((ppInfo->cropY / 16) & 0x700) >> 8); - reg->reg14.sw_crop_starty = ((ppInfo->cropY / 16) & 0x0FF); - - if (ppInfo->cropW & 0x0F) { - reg->reg14.sw_pp_crop8_r_e = 1; - } else { - reg->reg14.sw_pp_crop8_r_e = 0; - } - if (ppInfo->cropH & 0x0F) { - reg->reg14.sw_pp_crop8_d_e = 1; - } else { - reg->reg14.sw_pp_crop8_d_e = 0; - } - inWidth = ppInfo->cropW; - inHeigth = ppInfo->cropH; - } - - reg->reg39.sw_display_width = outWidth; - reg->reg35.sw_pp_out_width = outWidth; - reg->reg35.sw_pp_out_height = outHeight; - reg->reg21_pp_out_lu_base = pSyntax->asicBuff.outLumaBuffer.phy_addr; - - switch (inColor) { - case PP_IN_FORMAT_YUV422INTERLAVE: - reg->reg38.sw_pp_in_format = 0; - break; - case PP_IN_FORMAT_YUV420SEMI: - reg->reg38.sw_pp_in_format = 1; - break; - case PP_IN_FORMAT_YUV420PLANAR: - reg->reg38.sw_pp_in_format = 2; - break; - case PP_IN_FORMAT_YUV400: - reg->reg38.sw_pp_in_format = 3; - break; - case PP_IN_FORMAT_YUV422SEMI: - reg->reg38.sw_pp_in_format = 4; - break; - case PP_IN_FORMAT_YUV420SEMITIELED: - reg->reg38.sw_pp_in_format = 5; - break; - case PP_IN_FORMAT_YUV440SEMI: - reg->reg38.sw_pp_in_format = 6; - break; - case PP_IN_FORMAT_YUV444_SEMI: - reg->reg38.sw_pp_in_format = 7; - reg->reg38.sw_pp_in_format_es = 0; - break; - case PP_IN_FORMAT_YUV411_SEMI: - reg->reg38.sw_pp_in_format = 0; - reg->reg38.sw_pp_in_format_es = 1; - break; - default: - JPEGD_ERROR_LOG("unsupported format:%d", inColor); - return -1; - } - -#define VIDEORANGE 1 //0 or 1 - int videoRange = VIDEORANGE; - - reg->reg15.sw_rangemap_coef_y = 9; - reg->reg15.sw_rangemap_coef_c = 9; - /* brightness */ - reg->reg3.sw_pp_color_coefff = BRIGHTNESS; - - if (outColor <= PP_OUT_FORMAT_ARGB) { - /*Bt.601*/ - unsigned int a = 298; - unsigned int b = 409; - unsigned int c = 208; - unsigned int d = 100; - unsigned int e = 516; - - /*Bt.709 - unsigned int a = 298; - unsigned int b = 459; - unsigned int c = 137; - unsigned int d = 55; - unsigned int e = 544;*/ - - int satur = 0, tmp; - if (videoRange != 0) { - /*Bt.601*/ - a = 256; - b = 350; - c = 179; - d = 86; - e = 443; - /*Bt.709 - a = 256; - b = 403; - c = 120; - d = 48; - e = 475;*/ - - reg->reg15.sw_ycbcr_range = videoRange; - } - int contrast = CONTRAST; - if (contrast != 0) { - int thr1y, thr2y, off1, off2, thr1, thr2, a1, a2; - if (videoRange == 0) { - int tmp1, tmp2; - /* Contrast */ - thr1 = (219 * (contrast + 128)) / 512; - thr1y = (219 - 2 * thr1) / 2; - thr2 = 219 - thr1; - thr2y = 219 - thr1y; - - tmp1 = (thr1y * 256) / thr1; - tmp2 = ((thr2y - thr1y) * 256) / (thr2 - thr1); - off1 = ((thr1y - ((tmp2 * thr1) / 256)) * a) / 256; - off2 = ((thr2y - ((tmp1 * thr2) / 256)) * a) / 256; - - tmp1 = (64 * (contrast + 128)) / 128; - tmp2 = 256 * (128 - tmp1); - a1 = (tmp2 + off2) / thr1; - a2 = a1 + (256 * (off2 - 1)) / (thr2 - thr1); - } else { - /* Contrast */ - thr1 = (64 * (contrast + 128)) / 128; - thr1y = 128 - thr1; - thr2 = 256 - thr1; - thr2y = 256 - thr1y; - a1 = (thr1y * 256) / thr1; - a2 = ((thr2y - thr1y) * 256) / (thr2 - thr1); - off1 = thr1y - (a2 * thr1) / 256; - off2 = thr2y - (a1 * thr2) / 256; - } - - if (a1 > 1023) - a1 = 1023; - else if (a1 < 0) - a1 = 0; - - if (a2 > 1023) - a2 = 1023; - else if (a2 < 0) - a2 = 0; - - if (thr1 > 255) - thr1 = 255; - else if (thr1 < 0) - thr1 = 0; - - if (thr2 > 255) - thr2 = 255; - else if (thr2 < 0) - thr2 = 0; - - if (off1 > 511) - off1 = 511; - else if (off1 < -512) - off1 = -512; - - if (off2 > 511) - off2 = 511; - else if (off2 < -512) - off2 = -512; - - reg->reg31.sw_contrast_thr1 = thr1; - reg->reg31.sw_contrast_thr2 = thr2; - reg->reg32.sw_contrast_off1 = off1; - reg->reg32.sw_contrast_off2 = off2; - - reg->reg1.sw_color_coeffa1 = a1; - reg->reg1.sw_color_coeffa2 = a2; - } else { - reg->reg31.sw_contrast_thr1 = 55; - reg->reg31.sw_contrast_thr2 = 165; - reg->reg32.sw_contrast_off1 = 0; - reg->reg32.sw_contrast_off2 = 0; - - tmp = a; - if (tmp > 1023) - tmp = 1023; - else if (tmp < 0) - tmp = 0; - - reg->reg1.sw_color_coeffa1 = tmp; - reg->reg1.sw_color_coeffa2 = tmp; - } - - reg->reg37.sw_pp_out_endian = 0; - - /* saturation */ - satur = 64 + SATURATION; - - tmp = (satur * (int) b) / 64; - if (tmp > 1023) - tmp = 1023; - else if (tmp < 0) - tmp = 0; - reg->reg1.sw_color_coeffb = (unsigned int) tmp; - - tmp = (satur * (int) c) / 64; - if (tmp > 1023) - tmp = 1023; - else if (tmp < 0) - tmp = 0; - reg->reg2.sw_color_coeffc = (unsigned int) tmp; - - tmp = (satur * (int) d) / 64; - if (tmp > 1023) - tmp = 1023; - else if (tmp < 0) - tmp = 0; - reg->reg2.sw_color_coeffd = (unsigned int) tmp; - - tmp = (satur * (int) e) / 64; - if (tmp > 1023) - tmp = 1023; - else if (tmp < 0) - tmp = 0; - reg->reg2.sw_color_coeffe = (unsigned int) tmp; - } - - switch (outColor) { - case PP_OUT_FORMAT_RGB565: - reg->reg9_r_mask = 0xF800F800; - reg->reg10_g_mask = 0x07E007E0; - reg->reg11_b_mask = 0x001F001F; - reg->reg16.sw_rgb_r_padd = 0; - reg->reg16.sw_rgb_g_padd = 5; - reg->reg16.sw_rgb_b_padd = 11; - if (dither) { //always do dither - JPEGD_VERBOSE_LOG("we do dither."); - reg->reg36.sw_dither_select_r = 2; - reg->reg36.sw_dither_select_g = 3; - reg->reg36.sw_dither_select_b = 2; - } else { - JPEGD_VERBOSE_LOG("we do not dither."); - } - reg->reg37.sw_rgb_pix_in32 = 1; - reg->reg37.sw_pp_out_swap16_e = 1; - reg->reg38.sw_pp_out_format = 0; - break; - case PP_OUT_FORMAT_ARGB: - reg->reg9_r_mask = 0x000000FF | (0xff << 24); - reg->reg10_g_mask = 0x0000FF00 | (0xff << 24); - reg->reg11_b_mask = 0x00FF0000 | (0xff << 24); - - reg->reg16.sw_rgb_r_padd = 24; - reg->reg16.sw_rgb_g_padd = 16; - reg->reg16.sw_rgb_b_padd = 8; - - reg->reg37.sw_rgb_pix_in32 = 0; - reg->reg38.sw_pp_out_format = 0; - break; - case PP_OUT_FORMAT_YUV422INTERLAVE: - reg->reg38.sw_pp_out_format = 3; - break; - case PP_OUT_FORMAT_YUV420INTERLAVE: { - RK_U32 phy_addr = pSyntax->asicBuff.outLumaBuffer.phy_addr; - if (VPUClientGetIOMMUStatus() <= 0) { - reg->reg22_pp_out_ch_base = (phy_addr + outWidth * outHeight); - } else { - if (outWidth * outHeight > 0x400000) { - JPEGD_ERROR_LOG("out offset big than 22bit iommu map may be error"); - } else { - reg->reg22_pp_out_ch_base = (phy_addr | ((outWidth * outHeight) << 10)); - } - } - reg->reg38.sw_pp_out_format = 5; - JPEGD_INFO_LOG("outWidth:%d, outHeight:%d", outWidth, outHeight); - JPEGD_INFO_LOG("outLumaBuffer:%x, reg22:%x", phy_addr, reg->reg22_pp_out_ch_base); - } - break; - default: - JPEGD_ERROR_LOG("unsuppotred format:%d", outColor); - return -1; - } - - reg->reg38.sw_rotation_mode = 0; - - unsigned int inw, inh; - unsigned int outw, outh; - - inw = inWidth - 1; - inh = inHeigth - 1; - outw = outWidth - 1; - outh = outHeight - 1; - - if (inw < outw) { - reg->reg4.sw_hor_scale_mode = 1; - reg->reg4.sw_scale_wratio = (outw << 16) / inw; - reg->reg6.sw_wscale_invra = (inw << 16) / outw; - } else if (inw > outw) { - reg->reg4.sw_hor_scale_mode = 2; - reg->reg6.sw_wscale_invra = ((outw + 1) << 16) / (inw + 1); - } else - reg->reg4.sw_hor_scale_mode = 0; - - if (inh < outh) { - reg->reg4.sw_ver_scale_mode = 1; - reg->reg5.sw_scale_hratio = (outh << 16) / inh; - reg->reg6.sw_hscale_invra = (inh << 16) / outh; - } else if (inh > outh) { - reg->reg4.sw_ver_scale_mode = 2; - reg->reg6.sw_hscale_invra = ((outh + 1) << 16) / (inh + 1) + 1; - } else - reg->reg4.sw_ver_scale_mode = 0; - - reg->reg41.sw_pp_pipeline_e = ppInfo->enable; - FUN_TEST("Exit"); - return 0; -} - -JpegDecRet jpegd_configure_regs(JpegSyntaxParam *pSyntax, JpegHalContext *pCtx) -{ - FUN_TEST("Enter"); - JpegRegSet *reg = &(pCtx->regs); - - reg->reg50_dec_ctrl.sw_filtering_dis = 1; - - reg->reg53_dec_mode = JPEG_RK70_MODE_JPEG; - - reg->reg57_enable_ctrl.sw_dec_out_dis = 0; - reg->reg57_enable_ctrl.sw_rlc_mode_e = pSyntax->info.rlcMode; - - /* frame size, round up the number of mbs */ - reg->reg120.sw_pic_mb_h_ext = ((((pSyntax->info.Y) >> (4)) & 0x700) >> 8); - reg->reg120.sw_pic_mb_w_ext = ((((pSyntax->info.X) >> (4)) & 0xE00) >> 9); - reg->reg120.sw_pic_mb_width = ((pSyntax->info.X) >> (4)) & 0x1FF; - reg->reg120.sw_pic_mb_hight_p = ((pSyntax->info.Y) >> (4)) & 0x0FF; - - reg->reg121.sw_pjpeg_fildown_e = pSyntax->info.fillBottom; - reg->reg121.sw_pjpeg_ss = pSyntax->scan.Ss; /* Set spectral selection start coefficient */ - reg->reg121.sw_pjpeg_se = pSyntax->scan.Se; /* Set spectral selection end coefficient */ - reg->reg121.sw_pjpeg_ah = pSyntax->scan.Ah; /* Set the point transform used in the preceding scan */ - reg->reg121.sw_pjpeg_al = pSyntax->scan.Al; /* Set the point transform value */ - - reg->reg122.sw_jpeg_qtables = pSyntax->info.amountOfQTables; - reg->reg122.sw_jpeg_mode = pSyntax->info.yCbCrMode; - reg->reg122.sw_jpeg_filright_e = pSyntax->info.fillRight; - - reg->reg148.sw_slice_h = pSyntax->info.sliceHeight; - - /* Set JPEG operation mode */ - if (pSyntax->info.operationType != JPEGDEC_PROGRESSIVE) { - reg->reg57_enable_ctrl.sw_pjpeg_e = 0; - } else { - reg->reg57_enable_ctrl.sw_pjpeg_e = 1; - } - - /* Set needed progressive parameters */ - if (pSyntax->info.operationType == JPEGDEC_PROGRESSIVE) { // TODO: unsupported so far - JPEGD_INFO_LOG("JPEGDEC_PROGRESSIVE"); - } - - if (pSyntax->info.operationType == JPEGDEC_BASELINE) { - /* write "length amounts" */ - JPEGD_VERBOSE_LOG("Write VLC length amounts to register\n"); - jpegd_write_len_bits(pSyntax, pCtx); - - /* Create AC/DC/QP tables for HW */ - JPEGD_VERBOSE_LOG("Write AC,DC,QP tables to base\n"); - jpegd_write_tables(pSyntax, pCtx); - } else if (pSyntax->info.operationType == JPEGDEC_NONINTERLEAVED) { - JPEGD_INFO_LOG("JPEGDEC_NONINTERLEAVED"); - } else { - JPEGD_INFO_LOG("other operation type"); - } - - /* Select which tables the chromas use */ - jpegd_select_chroma_table(pSyntax, pCtx); - - /* write table base */ - reg->reg61_qtable_base = mpp_buffer_get_fd(pCtx->pTableBase); - - /* set up stream position for HW decode */ - jpegd_set_stream_params(pSyntax, pCtx); - - /* set restart interval */ - if (pSyntax->frame.Ri) { - reg->reg122.sw_sync_marker_e = 1; - reg->reg123.sw_pjpeg_rest_freq = pSyntax->frame.Ri; - } else { - reg->reg122.sw_sync_marker_e = 0; - } - - /* PP depending register writes */ - if (pSyntax->ppInstance != NULL && pSyntax->ppControl.usePipeline) { - JPEGD_INFO_LOG("ppInstance is not NULL!"); - reg->reg57_enable_ctrl.sw_dec_out_dis = 1; - - /* set output to zero, because of pp */ - /* Luminance output */ - reg->reg63_dec_out_base = 0; - - /* Chrominance output */ - if (pSyntax->image.sizeChroma) { - reg->reg131_jpg_ch_out_base = 0; - } - - if (pSyntax->info.sliceStartCount == JPEGDEC_SLICE_START_VALUE) { - /* Enable pp */ - } - - pSyntax->info.pipeline = 1; - } else { - JPEGD_INFO_LOG("ppInstance is NULL!"); - - if (pSyntax->info.operationType == JPEGDEC_BASELINE) { - /* Luminance output */ - JPEGD_INFO_LOG("INTERNAL: Set LUMA OUTPUT data base address\n"); - JPEGD_INFO_LOG("Luma virtual: %p, phy_addr: %x\n", pSyntax->asicBuff.outLumaBuffer.vir_addr, - pSyntax->asicBuff.outLumaBuffer.phy_addr); - reg->reg63_dec_out_base = pSyntax->asicBuff.outLumaBuffer.phy_addr; - - /* Chrominance output */ - if (pSyntax->image.sizeChroma) { - JPEGD_INFO_LOG("INTERNAL: Set CHROMA OUTPUT data base address\n"); - JPEGD_INFO_LOG("Chroma virtual: %p, phy_addr: %x\n", pSyntax->asicBuff.outChromaBuffer.vir_addr, - pSyntax->asicBuff.outChromaBuffer.phy_addr); - reg->reg131_jpg_ch_out_base = pSyntax->asicBuff.outChromaBuffer.phy_addr; - } - } else { - JPEGD_INFO_LOG("NON_JPEGDEC_BASELINE"); - } - - pSyntax->info.pipeline = 0; - } - - pSyntax->info.sliceStartCount = 1; - //pSyntax->asicRunning = 1; - - /* Enable jpeg mode and set slice mode */ - JPEGD_VERBOSE_LOG("Enable jpeg\n"); - reg->reg57_enable_ctrl.sw_dec_e = 1; - - FUN_TEST("Exit"); - return MPP_OK; -} - -static MPP_RET jpegd_regs_init(JpegRegSet *reg) -{ - FUN_TEST("Enter"); - reg->reg50_dec_ctrl.sw_dec_out_tiled_e = 0; - reg->reg50_dec_ctrl.sw_dec_scmd_dis = DEC_RK70_SCMD_DISABLE; - reg->reg50_dec_ctrl.sw_dec_latency = DEC_RK70_LATENCY_COMPENSATION; - - reg->reg54_endian.sw_dec_in_endian = DEC_RK70_BIG_ENDIAN; - reg->reg54_endian.sw_dec_out_endian = DEC_RK70_LITTLE_ENDIAN; - reg->reg54_endian.sw_dec_strendian_e = DEC_RK70_LITTLE_ENDIAN; - reg->reg54_endian.sw_dec_outswap32_e = DEC_RK70_LITTLE_ENDIAN; - reg->reg54_endian.sw_dec_inswap32_e = 1; - reg->reg54_endian.sw_dec_strswap32_e = 1; - - reg->reg55_Interrupt.sw_dec_irq_dis = 0; - - reg->reg56_axi_ctrl.sw_dec_axi_rn_id = 0xff; - reg->reg56_axi_ctrl.sw_dec_axi_wr_id = 0; - reg->reg56_axi_ctrl.sw_dec_max_burst = DEC_RK70_BUS_BURST_LENGTH_16; - reg->reg56_axi_ctrl.sw_dec_data_disc_e = DEC_RK70_DATA_DISCARD_ENABLE; - - reg->reg57_enable_ctrl.sw_dec_timeout_e = 1; - reg->reg57_enable_ctrl.sw_dec_clk_gate_e = 1; - - FUN_TEST("Exit"); - return MPP_OK; -} - -MPP_RET jpegd_gen_regs(JpegHalContext *ctx, JpegSyntaxParam *syntax) -{ - FUN_TEST("Enter"); - if (NULL == ctx || NULL == syntax) { - JPEGD_ERROR_LOG("NULL pointer"); - return MPP_ERR_NULL_PTR; - } - JpegDecRet retCode; - JpegHalContext *pCtx = ctx; - JpegSyntaxParam *pSyntax = syntax; - - retCode = JPEGDEC_OK; - if (pSyntax->image.headerReady) { - JPEGD_INFO_LOG("image header is ready"); - do { /* loop until decoding control should return for user */ - if (pSyntax->ppInstance != NULL) { /* if pp enabled ==> set pp control */ - pSyntax->ppControl.usePipeline = 1; - } - - /* check if we had to load input buffer or not */ - if (!pSyntax->info.inputBufferEmpty) { - /* Start HW or continue after pause */ - if (!pSyntax->info.SliceReadyForPause) { - if (!pSyntax->info.progressiveScanReady || pSyntax->info.nonInterleavedScanReady) { - JPEGD_INFO_LOG("Start to configure registers\n"); - retCode = jpegd_configure_regs(pSyntax, pCtx); - - pSyntax->info.nonInterleavedScanReady = 0; - if (retCode != JPEGDEC_OK) { - return retCode; - } - } else { - JPEGD_INFO_LOG("Continue HW decoding after progressive scan ready"); - pSyntax->info.progressiveScanReady = 0; - } - } else { - JPEGD_INFO_LOG("Continue HW decoding after slice ready"); - } - - pSyntax->info.SliceCount++; - } else { - JPEGD_INFO_LOG("Continue HW decoding after input buffer has been loaded"); - jpegd_input_buff_load_init(pSyntax); - - /* buffer loaded ==> reset flag */ - pSyntax->info.inputBufferEmpty = 0; - } - } while (0 /*!pSyntax->image.imageReady*/); // TODO: when to end this loop?? - } - - FUN_TEST("Exit"); - return MPP_OK; -} - -MPP_RET hal_jpegd_init(void *hal, MppHalCfg *cfg) -{ - FUN_TEST("Enter"); - MPP_RET ret = MPP_OK; - JpegHalContext *JpegHalCtx = (JpegHalContext *)hal; - if (NULL == JpegHalCtx) { - JpegHalCtx = (JpegHalContext *)mpp_calloc(JpegHalContext, 1); - if (NULL == JpegHalCtx) { - JPEGD_ERROR_LOG("NULL pointer"); - return MPP_ERR_NULL_PTR; - } - } - - //configure - JpegHalCtx->packet_slots = cfg->packet_slots; - JpegHalCtx->frame_slots = cfg->frame_slots; - - //get vpu socket -#ifdef RKPLATFORM - if (JpegHalCtx->vpu_socket <= 0) { - JpegHalCtx->vpu_socket = VPUClientInit(VPU_DEC); - if (JpegHalCtx->vpu_socket <= 0) { - JPEGD_ERROR_LOG("get vpu_socket(%d) <= 0, failed. \n", JpegHalCtx->vpu_socket); - return MPP_ERR_UNKNOW; - } else { - JPEGD_VERBOSE_LOG("get vpu_socket(%d), success. \n", JpegHalCtx->vpu_socket); - } - } -#endif - - //init regs - JpegRegSet *reg = &(JpegHalCtx->regs); - memset(reg, 0, sizeof(JpegRegSet)); - jpegd_regs_init(reg); - - //malloc hw buf - if (JpegHalCtx->group == NULL) { -#ifdef RKPLATFORM - JPEGD_VERBOSE_LOG("mpp_buffer_group_get_internal used ion in"); - ret = mpp_buffer_group_get_internal(&JpegHalCtx->group, MPP_BUFFER_TYPE_ION); -#else - ret = mpp_buffer_group_get_internal(&JpegHalCtx->group, MPP_BUFFER_TYPE_NORMAL); -#endif - if (MPP_OK != ret) { - JPEGD_ERROR_LOG("mpp_buffer_group_get failed\n"); - return ret; - } - } - - ret = mpp_buffer_get(JpegHalCtx->group, &JpegHalCtx->frame_buf, JPEGD_STREAM_BUFF_SIZE); - if (MPP_OK != ret) { - JPEGD_ERROR_LOG("get buffer failed\n"); - return ret; - } - - ret = mpp_buffer_get(JpegHalCtx->group, &JpegHalCtx->pTableBase, JPEGDEC_BASELINE_TABLE_SIZE); - if (MPP_OK != ret) { - JPEGD_ERROR_LOG("get buffer failed\n"); - return ret; - } - - JpegHalCtx->output_fmt = MPP_FMT_YUV420SP; - JpegHalCtx->set_output_fmt_flag = 0; - - //init dbg stuff - JpegHalCtx->hal_debug_enable = 0; - JpegHalCtx->frame_count = 0; - JpegHalCtx->output_yuv_count = 0; - - FUN_TEST("Exit"); - return MPP_OK; -} - -MPP_RET hal_jpegd_deinit(void *hal) -{ - FUN_TEST("Enter"); - MPP_RET ret = MPP_OK; - JpegHalContext *JpegHalCtx = (JpegHalContext *)hal; - -#ifdef RKPLATFORM - if (JpegHalCtx->vpu_socket >= 0) { - VPUClientRelease(JpegHalCtx->vpu_socket); - } -#endif - - if (JpegHalCtx->frame_buf) { - ret = mpp_buffer_put(JpegHalCtx->frame_buf); - if (MPP_OK != ret) { - JPEGD_ERROR_LOG("put buffer failed\n"); - return ret; - } - } - - if (JpegHalCtx->pTableBase) { - ret = mpp_buffer_put(JpegHalCtx->pTableBase); - if (MPP_OK != ret) { - JPEGD_ERROR_LOG("put buffer failed\n"); - return ret; - } - } - - if (JpegHalCtx->group) { - ret = mpp_buffer_group_put(JpegHalCtx->group); - if (MPP_OK != ret) { - JPEGD_ERROR_LOG("group free buffer failed\n"); - return ret; - } - } - - JpegHalCtx->output_fmt = MPP_FMT_YUV420SP; - JpegHalCtx->set_output_fmt_flag = 0; - JpegHalCtx->hal_debug_enable = 0; - JpegHalCtx->frame_count = 0; - JpegHalCtx->output_yuv_count = 0; - - return MPP_OK; - FUN_TEST("Exit"); -} - -MPP_RET hal_jpegd_gen_regs(void *hal, HalTaskInfo *syn) -{ - FUN_TEST("Enter"); - if (NULL == hal || NULL == syn) { - JPEGD_ERROR_LOG("NULL pointer"); - return MPP_ERR_NULL_PTR; - } - - MPP_RET ret = MPP_OK; - JpegHalContext *JpegHalCtx = (JpegHalContext *)hal; - JpegSyntaxParam *pSyntax = (JpegSyntaxParam *)syn->dec.syntax.data; -#ifdef RKPLATFORM - MppBuffer streambuf = NULL; - MppBuffer outputBuf = NULL; -#endif - - if (syn->dec.valid) { - syn->dec.valid = 0; - jpegd_set_output_format(JpegHalCtx, pSyntax); - -#ifdef RKPLATFORM - if (JpegHalCtx->set_output_fmt_flag && (JpegHalCtx->vpu_socket > 0)) { - VPUClientRelease(JpegHalCtx->vpu_socket); - JpegHalCtx->vpu_socket = 0; - - JpegHalCtx->vpu_socket = VPUClientInit(VPU_DEC_PP); - if (JpegHalCtx->vpu_socket <= 0) { - JPEGD_ERROR_LOG("get vpu_socket(%d) <= 0, failed. \n", JpegHalCtx->vpu_socket); - return MPP_ERR_UNKNOW; - } else { - JPEGD_VERBOSE_LOG("get vpu_socket(%d), success. \n", JpegHalCtx->vpu_socket); - } - } - - mpp_buf_slot_get_prop(JpegHalCtx->packet_slots, syn->dec.input, SLOT_BUFFER, &streambuf); - pSyntax->stream.streamBus = mpp_buffer_get_fd(streambuf); - - mpp_buf_slot_get_prop(JpegHalCtx->frame_slots, syn->dec.output, SLOT_BUFFER, &outputBuf); - pSyntax->asicBuff.outLumaBuffer.phy_addr = mpp_buffer_get_fd(outputBuf); - - jpegd_allocate_chroma_out_buffer(pSyntax); -#endif - - ret = jpegd_set_post_processor(JpegHalCtx, pSyntax); - - ret = jpegd_gen_regs(JpegHalCtx, pSyntax); - - if (JpegHalCtx->hal_debug_enable && JpegHalCtx->frame_count < 3) { - RK_U32 idx = 0; - RK_U32 *pRegs = (RK_U32 *) & (JpegHalCtx->regs); - JPEGD_INFO_LOG("sizeof(JpegRegSet)=%d, sizeof(pRegs[0])=%d", sizeof(JpegRegSet), sizeof(pRegs[0])); - - JpegHalCtx->frame_count++; - for (idx = 0; idx < sizeof(JpegRegSet) / sizeof(pRegs[0]); idx++) { - JPEGD_INFO_LOG("frame_%d_reg[%d]=0x%08x", JpegHalCtx->frame_count, idx, pRegs[idx]); - } - } - - syn->dec.valid = 1; - } - - return ret; - FUN_TEST("Exit"); -} - -MPP_RET hal_jpegd_start(void *hal, HalTaskInfo *task) -{ - FUN_TEST("Enter"); - MPP_RET ret = MPP_OK; - JpegHalContext *JpegHalCtx = (JpegHalContext *)hal; - -#ifdef RKPLATFORM - RK_U32 *p_regs = (RK_U32 *)&JpegHalCtx->regs; - ret = VPUClientSendReg(JpegHalCtx->vpu_socket, p_regs, JPEGD_REG_NUM); - if (ret != 0) { - JPEGD_ERROR_LOG("VPUClientSendReg Failed!!!\n"); - return MPP_ERR_VPUHW; - } -#endif - (void)JpegHalCtx; - (void)task; - FUN_TEST("Exit"); - return ret; -} - -MPP_RET hal_jpegd_wait(void *hal, HalTaskInfo *task) -{ - FUN_TEST("Enter"); - MPP_RET ret = MPP_OK; - JpegHalContext *JpegHalCtx = (JpegHalContext *)hal; - (void)JpegHalCtx; - (void)task; - -#ifdef RKPLATFORM - JpegRegSet reg_out; - VPU_CMD_TYPE cmd = 0; - RK_S32 length = 0; - memset(®_out, 0, sizeof(JpegRegSet)); - - ret = VPUClientWaitResult(JpegHalCtx->vpu_socket, (RK_U32 *)®_out, JPEGD_REG_NUM, &cmd, &length); - if (reg_out.reg55_Interrupt.sw_dec_bus_int) { - JPEGD_ERROR_LOG("IRQ BUS ERROR!"); - } else if (reg_out.reg55_Interrupt.sw_dec_error_int) { - JPEGD_ERROR_LOG("IRQ STREAM ERROR!"); - } else if (reg_out.reg55_Interrupt.sw_dec_timeout) { - JPEGD_ERROR_LOG("IRQ TIMEOUT!"); - } else if (reg_out.reg55_Interrupt.sw_dec_buffer_int) { - JPEGD_ERROR_LOG("IRQ BUFFER EMPTY!"); - } else if (reg_out.reg55_Interrupt.sw_dec_irq) { - JPEGD_INFO_LOG("DECODE SUCCESS!"); - } - - /* debug information */ - if (JpegHalCtx->hal_debug_enable && JpegHalCtx->output_yuv_count < 3) { - static FILE *jpg_file; - static char name[32]; - MppBuffer outputBuf = NULL; - void *pOutYUV = NULL; - mpp_buf_slot_get_prop(JpegHalCtx->frame_slots, task->dec.output, SLOT_BUFFER, &outputBuf); - pOutYUV = mpp_buffer_get_ptr(outputBuf); - - snprintf(name, sizeof(name), "/tmp/output%02d.yuv", JpegHalCtx->output_yuv_count); - jpg_file = fopen(name, "wb+"); - if (jpg_file) { - JpegSyntaxParam *pTmpSyn = (JpegSyntaxParam *)task->dec.syntax.data; - RK_U32 width = pTmpSyn->frame.hwX; - RK_U32 height = pTmpSyn->frame.hwY; - - JPEGD_INFO_LOG("output YUV(%d*%d) saving to %s\n", width, height, name); - JPEGD_INFO_LOG("pOutYUV:%p", pOutYUV); - fwrite(pOutYUV, width * height * 3 / 2, 1, jpg_file); - fclose(jpg_file); - JpegHalCtx->output_yuv_count++; - } - } -#endif - - FUN_TEST("Exit"); - return ret; -} - -MPP_RET hal_jpegd_reset(void *hal) -{ - FUN_TEST("Enter"); - MPP_RET ret = MPP_OK; - JpegHalContext *JpegHalCtx = (JpegHalContext *)hal; - (void)JpegHalCtx; - - return ret; -} - -MPP_RET hal_jpegd_flush(void *hal) -{ - FUN_TEST("Enter"); - MPP_RET ret = MPP_OK; - - (void)hal; - return ret; -} - -MPP_RET hal_jpegd_control(void *hal, RK_S32 cmd_type, void *param) -{ - FUN_TEST("Enter"); - MPP_RET ret = MPP_OK; - JpegHalContext *JpegHalCtx = (JpegHalContext *)hal; - if (NULL == JpegHalCtx) { - JPEGD_ERROR_LOG("NULL pointer"); - return MPP_ERR_NULL_PTR; - } - - switch (cmd_type) { - case MPP_DEC_SET_OUTPUT_FORMAT: { - JpegHalCtx->output_fmt = *((MppFrameFormat *)param); - JpegHalCtx->set_output_fmt_flag = 1; - JPEGD_INFO_LOG("output_format:%d\n", JpegHalCtx->output_fmt); - } break; - default : - ret = MPP_NOK; - } - FUN_TEST("Exit"); - return ret; -} - -const MppHalApi hal_api_jpegd = { - "jpegd_rkdec", - MPP_CTX_DEC, - MPP_VIDEO_CodingMJPEG, - sizeof(JpegHalContext), - 0, - hal_jpegd_init, - hal_jpegd_deinit, - hal_jpegd_gen_regs, - hal_jpegd_start, - hal_jpegd_wait, - hal_jpegd_reset, - hal_jpegd_flush, - hal_jpegd_control, -}; - - +/* + * + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#define MODULE_TAG "JPEGHAL" + +#include +#include + +#include "mpp_buffer.h" +#include "mpp_log.h" +#include "mpp_err.h" +#include "mpp_mem.h" +#include "mpp_bitread.h" +#include "mpp_dec.h" +#include "vpu.h" +#include "mpp_buffer.h" +#include "mpp_env.h" +#include "mpp_bitput.h" + +#include "jpegd_api.h" +#include "hal_jpegd_reg.h" + +static const RK_U8 zzOrder[64] = { + 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, + 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, + 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51, + 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63 +}; + +void jpegd_input_buff_load_init(JpegSyntaxParam *pSyntax) +{ + FUN_TEST("Enter"); + // TODO: no need so far + (void)pSyntax; + FUN_TEST("Exit"); +} + +static void jpegd_write_len_bits(JpegSyntaxParam *pSyntax, JpegHalContext *pCtx) +{ + FUN_TEST("Enter"); + ScanInfo *JPG_SCN = &pSyntax->scan; + HuffmanTables *JPG_VLC = &pSyntax->vlc; + JpegRegSet *reg = &(pCtx->regs); + + VlcTable *pTable1 = NULL; + VlcTable *pTable2 = NULL; + + /* first select the table we'll use */ + + /* this trick is done because hw always wants luma table as ac hw table 1 */ + if (JPG_SCN->Ta[0] == 0) { + pTable1 = &(JPG_VLC->acTable0); + pTable2 = &(JPG_VLC->acTable1); + } else { + pTable1 = &(JPG_VLC->acTable1); + pTable2 = &(JPG_VLC->acTable0); + } + + JPEGD_ASSERT(pTable1); + JPEGD_ASSERT(pTable2); + + /* write AC table 1 (luma) */ + reg->reg134.sw_ac1_code1_cnt = pTable1->bits[0]; + reg->reg134.sw_ac1_code2_cnt = pTable1->bits[1]; + reg->reg134.sw_ac1_code3_cnt = pTable1->bits[2]; + reg->reg134.sw_ac1_code4_cnt = pTable1->bits[3]; + reg->reg134.sw_ac1_code5_cnt = pTable1->bits[4]; + reg->reg134.sw_ac1_code6_cnt = pTable1->bits[5]; + + reg->reg135.sw_ac1_code7_cnt = pTable1->bits[6]; + reg->reg135.sw_ac1_code8_cnt = pTable1->bits[7]; + reg->reg135.sw_ac1_code9_cnt = pTable1->bits[8]; + reg->reg135.sw_ac1_code10_cnt = pTable1->bits[9]; + + reg->reg136.sw_ac1_code11_cnt = pTable1->bits[10]; + reg->reg136.sw_ac1_code12_cnt = pTable1->bits[11]; + reg->reg136.sw_ac1_code13_cnt = pTable1->bits[12]; + reg->reg136.sw_ac1_code14_cnt = pTable1->bits[13]; + + reg->reg137.sw_ac1_code15_cnt = pTable1->bits[14]; + reg->reg137.sw_ac1_code16_cnt = pTable1->bits[15]; + + /* table AC2 (the not-luma table) */ + reg->reg137.sw_ac2_code1_cnt = pTable2->bits[0]; + reg->reg137.sw_ac2_code2_cnt = pTable2->bits[1]; + reg->reg137.sw_ac2_code3_cnt = pTable2->bits[2]; + reg->reg137.sw_ac2_code4_cnt = pTable2->bits[3]; + + reg->reg138.sw_ac2_code5_cnt = pTable2->bits[4]; + reg->reg138.sw_ac2_code6_cnt = pTable2->bits[5]; + reg->reg138.sw_ac2_code7_cnt = pTable2->bits[6]; + reg->reg138.sw_ac2_code8_cnt = pTable2->bits[7]; + + reg->reg139.sw_ac2_code9_cnt = pTable2->bits[8]; + reg->reg139.sw_ac2_code10_cnt = pTable2->bits[9]; + reg->reg139.sw_ac2_code11_cnt = pTable2->bits[10]; + reg->reg139.sw_ac2_code12_cnt = pTable2->bits[11]; + + reg->reg140.sw_ac2_code13_cnt = pTable2->bits[12]; + reg->reg140.sw_ac2_code14_cnt = pTable2->bits[13]; + reg->reg140.sw_ac2_code15_cnt = pTable2->bits[14]; + reg->reg140.sw_ac2_code16_cnt = pTable2->bits[15]; + + if (JPG_SCN->Td[0] == 0) { + pTable1 = &(JPG_VLC->dcTable0); + pTable2 = &(JPG_VLC->dcTable1); + } else { + pTable1 = &(JPG_VLC->dcTable1); + pTable2 = &(JPG_VLC->dcTable0); + } + + JPEGD_ASSERT(pTable1); + JPEGD_ASSERT(pTable2); + + /* write DC table 1 (luma) */ + reg->reg141.sw_dc1_code1_cnt = pTable1->bits[0]; + reg->reg141.sw_dc1_code2_cnt = pTable1->bits[1]; + reg->reg141.sw_dc1_code3_cnt = pTable1->bits[2]; + reg->reg141.sw_dc1_code4_cnt = pTable1->bits[3]; + reg->reg141.sw_dc1_code5_cnt = pTable1->bits[4]; + reg->reg141.sw_dc1_code6_cnt = pTable1->bits[5]; + reg->reg141.sw_dc1_code7_cnt = pTable1->bits[6]; + reg->reg141.sw_dc1_code8_cnt = pTable1->bits[7]; + + reg->reg142.sw_dc1_code9_cnt = pTable1->bits[8]; + reg->reg142.sw_dc1_code10_cnt = pTable1->bits[9]; + reg->reg142.sw_dc1_code11_cnt = pTable1->bits[10]; + reg->reg142.sw_dc1_code12_cnt = pTable1->bits[11]; + reg->reg142.sw_dc1_code13_cnt = pTable1->bits[12]; + reg->reg142.sw_dc1_code14_cnt = pTable1->bits[13]; + reg->reg142.sw_dc1_code15_cnt = pTable1->bits[14]; + reg->reg142.sw_dc1_code16_cnt = pTable1->bits[15]; + + /* table DC2 (the not-luma table) */ + reg->reg143.sw_dc2_code1_cnt = pTable2->bits[0]; + reg->reg143.sw_dc2_code2_cnt = pTable2->bits[1]; + reg->reg143.sw_dc2_code3_cnt = pTable2->bits[2]; + reg->reg143.sw_dc2_code4_cnt = pTable2->bits[3]; + reg->reg143.sw_dc2_code5_cnt = pTable2->bits[4]; + reg->reg143.sw_dc2_code6_cnt = pTable2->bits[5]; + reg->reg143.sw_dc2_code7_cnt = pTable2->bits[6]; + reg->reg143.sw_dc2_code8_cnt = pTable2->bits[7]; + + reg->reg144.sw_dc2_code9_cnt = pTable2->bits[8]; + reg->reg144.sw_dc2_code10_cnt = pTable2->bits[9]; + reg->reg144.sw_dc2_code11_cnt = pTable2->bits[10]; + reg->reg144.sw_dc2_code12_cnt = pTable2->bits[11]; + reg->reg144.sw_dc2_code13_cnt = pTable2->bits[12]; + reg->reg144.sw_dc2_code14_cnt = pTable2->bits[13]; + reg->reg144.sw_dc2_code15_cnt = pTable2->bits[14]; + reg->reg144.sw_dc2_code16_cnt = pTable2->bits[15]; + + FUN_TEST("Exit"); + return; +} + +static void jpegd_set_stream_params(JpegSyntaxParam *pSyntax, JpegHalContext *pCtx) +{ + FUN_TEST("Enter"); + StreamStorage *JPG_STR = &pSyntax->stream; + JpegRegSet *reg = &(pCtx->regs); + + RK_U32 addrTmp = 0; + RK_U32 amountOfStream = 0; + + JPEGD_INFO_LOG("read %d bits\n", JPG_STR->readBits); + JPEGD_INFO_LOG("read %d bytes\n", JPG_STR->readBits / 8); + JPEGD_INFO_LOG("Stream physical address start: 0x%08x\n", JPG_STR->streamBus); + JPEGD_INFO_LOG("Stream virtual address start: %p\n", JPG_STR->pStartOfStream); + + /* calculate and set stream start address to hw */ + addrTmp = (((RK_U32) JPG_STR->pStartOfStream & 0x3) + + (RK_U32) (JPG_STR->pCurrPos - JPG_STR->pStartOfStream)) & (~7); + + JPEGD_INFO_LOG("pStartOfStream data: 0x%x, 0x%x, 0x%x, 0x%x", JPG_STR->pStartOfStream[JPG_STR->streamLength - 4], + JPG_STR->pStartOfStream[JPG_STR->streamLength - 3], + JPG_STR->pStartOfStream[JPG_STR->streamLength - 2], + JPG_STR->pStartOfStream[JPG_STR->streamLength - 1]); + + if (VPUClientGetIOMMUStatus() <= 0) { + reg->reg64_rlc_vlc_base = JPG_STR->streamBus + addrTmp; + } else { + reg->reg64_rlc_vlc_base = JPG_STR->streamBus | (addrTmp << 10); + } + JPEGD_INFO_LOG("reg64_rlc_vlc_base: 0x%08x\n", reg->reg64_rlc_vlc_base); + + /* calculate and set stream start bit to hw */ + + /* change current pos to bus address style */ + /* remove three lowest bits and add the difference to bitPosInWord */ + /* used as bit pos in word not as bit pos in byte actually... */ + switch ((RK_U32) JPG_STR->pCurrPos & (7)) { + case 0: + break; + case 1: + JPG_STR->bitPosInByte += 8; + break; + case 2: + JPG_STR->bitPosInByte += 16; + break; + case 3: + JPG_STR->bitPosInByte += 24; + break; + case 4: + JPG_STR->bitPosInByte += 32; + break; + case 5: + JPG_STR->bitPosInByte += 40; + break; + case 6: + JPG_STR->bitPosInByte += 48; + break; + case 7: + JPG_STR->bitPosInByte += 56; + break; + default: + JPEGD_ASSERT(0); + break; + } + + reg->reg122.sw_strm_start_bit = JPG_STR->bitPosInByte; + + /* set up stream length for HW. + * length = size of original buffer - stream we already decoded in SW */ + JPG_STR->pCurrPos = (RK_U8 *) ((RK_U32) JPG_STR->pCurrPos & (~7)); + + if (pSyntax->info.inputStreaming) { + JPEGD_VERBOSE_LOG("inputStreaming-1, inputBufferLen:%d", pSyntax->info.inputBufferLen); + amountOfStream = (pSyntax->info.inputBufferLen - + (RK_U32) (JPG_STR->pCurrPos - JPG_STR->pStartOfStream)); + + reg->reg51_stream_info.sw_stream_len = amountOfStream; + pSyntax->info.streamEnd = 1; + } else { + JPEGD_VERBOSE_LOG("inputStreaming-2"); + amountOfStream = (JPG_STR->streamLength - + (RK_U32) (JPG_STR->pCurrPos - JPG_STR->pStartOfStream)); + + reg->reg51_stream_info.sw_stream_len = amountOfStream; + + /* because no input streaming, frame should be ready during decoding this buffer */ + pSyntax->info.streamEnd = 1; + } + + reg->reg122.sw_jpeg_stream_all = pSyntax->info.streamEnd; + + JPEGD_INFO_LOG("streamLength: %d\n", JPG_STR->streamLength); + JPEGD_INFO_LOG("pCurrPos: %p\n", JPG_STR->pCurrPos); + JPEGD_INFO_LOG("pStartOfStream: %p\n", JPG_STR->pStartOfStream); + JPEGD_INFO_LOG("bitPosInByte: 0x%08x\n", JPG_STR->bitPosInByte); + + FUN_TEST("Exit"); + return; +} + +static void jpegd_select_chroma_table(JpegSyntaxParam *pSyntax, JpegHalContext *pCtx) +{ + FUN_TEST("Enter"); + ScanInfo *JPG_SCN = &pSyntax->scan; + JpegRegSet *reg = &(pCtx->regs); + + /* this trick is done because hw always wants luma table as ac hw table 1 */ + if (JPG_SCN->Ta[0] == 0) { + reg->reg122.sw_cr_ac_vlctable = JPG_SCN->Ta[2]; + reg->reg122.sw_cb_ac_vlctable = JPG_SCN->Ta[1]; + } else { + if (JPG_SCN->Ta[0] == JPG_SCN->Ta[1]) + reg->reg122.sw_cb_ac_vlctable = 0; + else + reg->reg122.sw_cb_ac_vlctable = 1; + + if (JPG_SCN->Ta[0] == JPG_SCN->Ta[2]) + reg->reg122.sw_cr_ac_vlctable = 0; + else + reg->reg122.sw_cr_ac_vlctable = 1; + } + + /* Third DC table selectors */ + if (pSyntax->info.operationType != JPEGDEC_PROGRESSIVE) { + JPEGD_INFO_LOG("NON_PROGRESSIVE"); + if (JPG_SCN->Td[0] == 0) { + reg->reg122.sw_cr_dc_vlctable = JPG_SCN->Td[2]; + reg->reg122.sw_cb_dc_vlctable = JPG_SCN->Td[1]; + } else { + if (JPG_SCN->Td[0] == JPG_SCN->Td[1]) + reg->reg122.sw_cb_dc_vlctable = 0; + else + reg->reg122.sw_cb_dc_vlctable = 1; + + if (JPG_SCN->Td[0] == JPG_SCN->Td[2]) + reg->reg122.sw_cr_dc_vlctable = 0; + else + reg->reg122.sw_cr_dc_vlctable = 1; + } + + reg->reg122.sw_cr_dc_vlctable3 = 0; + reg->reg122.sw_cb_dc_vlctable3 = 0; + } else { + JPEGD_INFO_LOG("JPEGDEC_PROGRESSIVE"); + } + + FUN_TEST("Exit"); + return; +} + +MPP_RET jpegd_set_output_format(JpegHalContext *pCtx, JpegSyntaxParam *pSyntax) +{ + FUN_TEST("Enter"); + MPP_RET ret = MPP_OK; + if (NULL == pSyntax || NULL == pCtx) { + JPEGD_ERROR_LOG("NULL pointer"); + return MPP_ERR_NULL_PTR; + } + PostProcessInfo ppInfo; + RK_U32 ppInputFomart = 0; + RK_U32 ppScaleW = 640, ppScaleH = 480; + + if (pCtx->set_output_fmt_flag && (pCtx->output_fmt != pSyntax->imageInfo.outputFormat)) { + /* Using pp to convert all format to yuv420sp */ + switch (pSyntax->imageInfo.outputFormat) { + case JPEGDEC_YCbCr400: + ppInputFomart = PP_IN_FORMAT_YUV400; + break; + case MPP_FMT_YUV420SP: + ppInputFomart = PP_IN_FORMAT_YUV420SEMI; + break; + case MPP_FMT_YUV422SP: + ppInputFomart = PP_IN_FORMAT_YUV422SEMI; + break; + case JPEGDEC_YCbCr440: + ppInputFomart = PP_IN_FORMAT_YUV440SEMI; + break; + case JPEGDEC_YCbCr411_SEMIPLANAR: + ppInputFomart = PP_IN_FORMAT_YUV411_SEMI; + break; + case JPEGDEC_YCbCr444_SEMIPLANAR: + ppInputFomart = PP_IN_FORMAT_YUV444_SEMI; + break; + } + + // set pp info + memset(&ppInfo, 0, sizeof(ppInfo)); + ppInfo.enable = 1; + ppInfo.outFomart = 5; //PP_OUT_FORMAT_YUV420INTERLAVE + ppScaleW = pSyntax->imageInfo.outputWidth; + ppScaleH = pSyntax->imageInfo.outputHeight; + if (ppScaleW > 1920) { // || ppScaleH > 1920) { + ppScaleW = (ppScaleW + 15) & (~15); //(ppScaleW + 15)/16*16; + ppScaleH = (ppScaleH + 15) & (~15); + } else { + ppScaleW = (ppScaleW + 7) & (~7); // pp dest width must be dividable by 8 + ppScaleH = (ppScaleH + 1) & (~1); // must be dividable by 2.in pp downscaling ,the output lines always equal (desire lines - 1); + } + + JPEGD_INFO_LOG("Post Process! ppScaleW:%d, ppScaleH:%d", ppScaleW, ppScaleH); + pSyntax->ppInstance = (void *)1; + } else { + /* keep original output format */ + memset(&ppInfo, 0, sizeof(ppInfo)); + ppInfo.outFomart = 5; //PP_OUT_FORMAT_YUV420INTERLAVE + ppScaleW = pSyntax->imageInfo.outputWidth; + ppScaleH = pSyntax->imageInfo.outputHeight; + + ppScaleW = (ppScaleW + 15) & (~15); + ppScaleH = (ppScaleH + 15) & (~15); + + switch (pSyntax->imageInfo.outputFormat) { + case JPEGDEC_YCbCr400: + ppInputFomart = PP_IN_FORMAT_YUV400; + break; + case MPP_FMT_YUV420SP: + ppInputFomart = PP_IN_FORMAT_YUV420SEMI; + break; + case MPP_FMT_YUV422SP: + ppInputFomart = PP_IN_FORMAT_YUV422SEMI; + break; + case JPEGDEC_YCbCr440: + ppInputFomart = PP_IN_FORMAT_YUV440SEMI; + break; + case JPEGDEC_YCbCr411_SEMIPLANAR: + ppInputFomart = PP_IN_FORMAT_YUV411_SEMI; + break; + case JPEGDEC_YCbCr444_SEMIPLANAR: + ppInputFomart = PP_IN_FORMAT_YUV444_SEMI; + break; + } + + pSyntax->ppInstance = (void *)0; + } + + memcpy(&(pSyntax->ppInfo), &(ppInfo), sizeof(PostProcessInfo)); + pSyntax->ppScaleW = ppScaleW; + pSyntax->ppScaleH = ppScaleH; + pSyntax->ppInputFomart = ppInputFomart; + + FUN_TEST("Exit"); + return ret; +} + +static void jpegd_write_tables(JpegSyntaxParam *pSyntax, JpegHalContext *pCtx) +{ + FUN_TEST("Enter"); + ScanInfo *JPG_SCN = &pSyntax->scan; + HuffmanTables *JPG_VLC = &pSyntax->vlc; + QuantTables *JPG_QTB = &pSyntax->quant; + FrameInfo *JPG_FRM = &pSyntax->frame; + + RK_U32 i, j = 0; + RK_U32 shifter = 32; + RK_U32 tableWord = 0; + RK_U32 tableValue = 0; + RK_U8 tableTmp[64] = { 0 }; + RK_U32 *pTableBase = NULL; + + pTableBase = (RK_U32 *)mpp_buffer_get_ptr(pCtx->pTableBase); + + /* QP tables for all components */ + for (j = 0; j < pSyntax->info.amountOfQTables; j++) { + if ((JPG_FRM->component[j].Tq) == 0) { + for (i = 0; i < 64; i++) { + tableTmp[zzOrder[i]] = (RK_U8) JPG_QTB->table0[i]; + } + + /* update shifter */ + shifter = 32; + + for (i = 0; i < 64; i++) { + shifter -= 8; + + if (shifter == 24) + tableWord = (tableTmp[i] << shifter); + else + tableWord |= (tableTmp[i] << shifter); + + if (shifter == 0) { + *(pTableBase) = tableWord; + pTableBase++; + shifter = 32; + } + } + } else { + for (i = 0; i < 64; i++) { + tableTmp[zzOrder[i]] = (RK_U8) JPG_QTB->table1[i]; + } + + /* update shifter */ + shifter = 32; + + for (i = 0; i < 64; i++) { + shifter -= 8; + + if (shifter == 24) + tableWord = (tableTmp[i] << shifter); + else + tableWord |= (tableTmp[i] << shifter); + + if (shifter == 0) { + *(pTableBase) = tableWord; + pTableBase++; + shifter = 32; + } + } + } + } + + /* update shifter */ + shifter = 32; + + if (pSyntax->info.yCbCrMode != JPEGDEC_YUV400) { + /* this trick is done because hw always wants luma table as ac hw table 1 */ + if (JPG_SCN->Ta[0] == 0) { + /* Write AC Table 1 (as specified in HW regs) + * NOTE: Not the same as actable[1] (as specified in JPEG Spec) */ + JPEGD_VERBOSE_LOG("INTERNAL: Write tables: AC1 (luma)\n"); + if (JPG_VLC->acTable0.vals) { + for (i = 0; i < 162; i++) { + if (i < JPG_VLC->acTable0.tableLength) { + tableValue = (RK_U8) JPG_VLC->acTable0.vals[i]; + } else { + tableValue = 0; + } + + if (shifter == 32) + tableWord = (tableValue << (shifter - 8)); + else + tableWord |= (tableValue << (shifter - 8)); + + shifter -= 8; + + if (shifter == 0) { + *(pTableBase) = tableWord; + pTableBase++; + shifter = 32; + } + } + } else { + for (i = 0; i < 162; i++) { + tableWord = 0; + shifter -= 8; + + if (shifter == 0) { + *(pTableBase) = tableWord; + pTableBase++; + shifter = 32; + } + } + } + + /* Write AC Table 2 */ + JPEGD_VERBOSE_LOG("INTERNAL: Write tables: AC2 (not-luma)\n"); + if (JPG_VLC->acTable1.vals) { + for (i = 0; i < 162; i++) { + if (i < JPG_VLC->acTable1.tableLength) { + tableValue = (RK_U8) JPG_VLC->acTable1.vals[i]; + } else { + tableValue = 0; + } + + if (shifter == 32) + tableWord = (tableValue << (shifter - 8)); + else + tableWord |= (tableValue << (shifter - 8)); + + shifter -= 8; + + if (shifter == 0) { + *(pTableBase) = tableWord; + pTableBase++; + shifter = 32; + } + } + } else { + for (i = 0; i < 162; i++) { + tableWord = 0; + shifter -= 8; + + if (shifter == 0) { + *(pTableBase) = tableWord; + pTableBase++; + shifter = 32; + } + } + } + } else { + /* Write AC Table 1 (as specified in HW regs) + * NOTE: Not the same as actable[1] (as specified in JPEG Spec) */ + if (JPG_VLC->acTable1.vals) { + JPEGD_INFO_LOG("INTERNAL: Write tables: AC1 (luma)\n"); + for (i = 0; i < 162; i++) { + if (i < JPG_VLC->acTable1.tableLength) { + tableValue = (RK_U8) JPG_VLC->acTable1.vals[i]; + } else { + tableValue = 0; + } + + if (shifter == 32) + tableWord = (tableValue << (shifter - 8)); + else + tableWord |= (tableValue << (shifter - 8)); + + shifter -= 8; + + if (shifter == 0) { + *(pTableBase) = tableWord; + pTableBase++; + shifter = 32; + } + } + } else { + for (i = 0; i < 162; i++) { + tableWord = 0; + shifter -= 8; + + if (shifter == 0) { + *(pTableBase) = tableWord; + pTableBase++; + shifter = 32; + } + } + } + + /* Write AC Table 2 */ + if (JPG_VLC->acTable0.vals) { + JPEGD_INFO_LOG("INTERNAL: writeTables: AC2 (not-luma)\n"); + for (i = 0; i < 162; i++) { + if (i < JPG_VLC->acTable0.tableLength) { + tableValue = (RK_U8) JPG_VLC->acTable0.vals[i]; + } else { + tableValue = 0; + } + + if (shifter == 32) + tableWord = (tableValue << (shifter - 8)); + else + tableWord |= (tableValue << (shifter - 8)); + + shifter -= 8; + + if (shifter == 0) { + *(pTableBase) = tableWord; + pTableBase++; + shifter = 32; + } + } + } else { + for (i = 0; i < 162; i++) { + tableWord = 0; + shifter -= 8; + + if (shifter == 0) { + *(pTableBase) = tableWord; + pTableBase++; + shifter = 32; + } + } + } + } + + /* this trick is done because hw always wants luma table as dc hw table 1 */ + if (JPG_SCN->Td[0] == 0) { + if (JPG_VLC->dcTable0.vals) { + for (i = 0; i < 12; i++) { + if (i < JPG_VLC->dcTable0.tableLength) { + tableValue = (RK_U8) JPG_VLC->dcTable0.vals[i]; + } else { + tableValue = 0; + } + + if (shifter == 32) + tableWord = (tableValue << (shifter - 8)); + else + tableWord |= (tableValue << (shifter - 8)); + + shifter -= 8; + + if (shifter == 0) { + *(pTableBase) = tableWord; + pTableBase++; + shifter = 32; + } + } + } else { + for (i = 0; i < 12; i++) { + tableWord = 0; + shifter -= 8; + + if (shifter == 0) { + *(pTableBase) = tableWord; + pTableBase++; + shifter = 32; + } + } + } + + if (JPG_VLC->dcTable1.vals) { + for (i = 0; i < 12; i++) { + if (i < JPG_VLC->dcTable1.tableLength) { + tableValue = (RK_U8) JPG_VLC->dcTable1.vals[i]; + } else { + tableValue = 0; + } + + if (shifter == 32) + tableWord = (tableValue << (shifter - 8)); + else + tableWord |= (tableValue << (shifter - 8)); + + shifter -= 8; + + if (shifter == 0) { + *(pTableBase) = tableWord; + pTableBase++; + shifter = 32; + } + } + } else { + for (i = 0; i < 12; i++) { + tableWord = 0; + shifter -= 8; + + if (shifter == 0) { + *(pTableBase) = tableWord; + pTableBase++; + shifter = 32; + } + } + } + + } else { + if (JPG_VLC->dcTable1.vals) { + for (i = 0; i < 12; i++) { + if (i < JPG_VLC->dcTable1.tableLength) { + tableValue = (RK_U8) JPG_VLC->dcTable1.vals[i]; + } else { + tableValue = 0; + } + + if (shifter == 32) + tableWord = (tableValue << (shifter - 8)); + else + tableWord |= (tableValue << (shifter - 8)); + + shifter -= 8; + + if (shifter == 0) { + *(pTableBase) = tableWord; + pTableBase++; + shifter = 32; + } + } + } else { + for (i = 0; i < 12; i++) { + tableWord = 0; + shifter -= 8; + + if (shifter == 0) { + *(pTableBase) = tableWord; + pTableBase++; + shifter = 32; + } + } + } + + if (JPG_VLC->dcTable0.vals) { + for (i = 0; i < 12; i++) { + if (i < JPG_VLC->dcTable0.tableLength) { + tableValue = (RK_U8) JPG_VLC->dcTable0.vals[i]; + } else { + tableValue = 0; + } + + if (shifter == 32) + tableWord = (tableValue << (shifter - 8)); + else + tableWord |= (tableValue << (shifter - 8)); + + shifter -= 8; + + if (shifter == 0) { + *(pTableBase) = tableWord; + pTableBase++; + shifter = 32; + } + } + } else { + for (i = 0; i < 12; i++) { + tableWord = 0; + shifter -= 8; + + if (shifter == 0) { + *(pTableBase) = tableWord; + pTableBase++; + shifter = 32; + } + } + } + } + } else { /* YUV400 */ + if (!pSyntax->info.nonInterleavedScanReady) { + /* this trick is done because hw always wants luma table as ac hw table 1 */ + if (JPG_SCN->Ta[0] == 0) { + /* Write AC Table 1 (as specified in HW regs) + * NOTE: Not the same as actable[1] (as specified in JPEG Spec) */ + JPEGD_INFO_LOG("INTERNAL: Write tables: AC1 (luma)\n"); + if (JPG_VLC->acTable0.vals) { + for (i = 0; i < 162; i++) { + if (i < JPG_VLC->acTable0.tableLength) { + tableValue = (RK_U8) JPG_VLC->acTable0.vals[i]; + } else { + tableValue = 0; + } + + if (shifter == 32) + tableWord = (tableValue << (shifter - 8)); + else + tableWord |= (tableValue << (shifter - 8)); + + shifter -= 8; + + if (shifter == 0) { + *(pTableBase) = tableWord; + pTableBase++; + shifter = 32; + } + } + } else { + for (i = 0; i < 162; i++) { + tableWord = 0; + shifter -= 8; + + if (shifter == 0) { + *(pTableBase) = tableWord; + pTableBase++; + shifter = 32; + } + } + } + + /* Write AC Table 2 */ + JPEGD_INFO_LOG("INTERNAL: Write zero table (YUV400): \n"); + for (i = 0; i < 162; i++) { + tableValue = 0; + + if (shifter == 32) + tableWord = (tableValue << (shifter - 8)); + else + tableWord |= (tableValue << (shifter - 8)); + + shifter -= 8; + + if (shifter == 0) { + *(pTableBase) = tableWord; + pTableBase++; + shifter = 32; + } + } + } else { + /* Write AC Table 1 (as specified in HW regs) + * NOTE: Not the same as actable[1] (as specified in JPEG Spec) */ + if (JPG_VLC->acTable1.vals) { + JPEGD_INFO_LOG("INTERNAL: Write tables: AC1 (luma)\n"); + for (i = 0; i < 162; i++) { + if (i < JPG_VLC->acTable1.tableLength) { + tableValue = (RK_U8) JPG_VLC->acTable1.vals[i]; + } else { + tableValue = 0; + } + + if (shifter == 32) + tableWord = (tableValue << (shifter - 8)); + else + tableWord |= (tableValue << (shifter - 8)); + + shifter -= 8; + + if (shifter == 0) { + *(pTableBase) = tableWord; + pTableBase++; + shifter = 32; + } + } + } else { + for (i = 0; i < 162; i++) { + tableWord = 0; + + shifter -= 8; + + if (shifter == 0) { + *(pTableBase) = tableWord; + pTableBase++; + shifter = 32; + } + } + } + + /* Write AC Table 2 */ + JPEGD_INFO_LOG("INTERNAL: writeTables: padding zero (YUV400)\n"); + for (i = 0; i < 162; i++) { + tableValue = 0; + + if (shifter == 32) + tableWord = (tableValue << (shifter - 8)); + else + tableWord |= (tableValue << (shifter - 8)); + + shifter -= 8; + + if (shifter == 0) { + *(pTableBase) = tableWord; + pTableBase++; + shifter = 32; + } + } + } + + /* this trick is done because hw always wants luma table as dc hw table 1 */ + if (JPG_SCN->Td[0] == 0) { + if (JPG_VLC->dcTable0.vals) { + for (i = 0; i < 12; i++) { + if (i < JPG_VLC->dcTable0.tableLength) { + tableValue = (RK_U8) JPG_VLC->dcTable0.vals[i]; + } else { + tableValue = 0; + } + + if (shifter == 32) + tableWord = (tableValue << (shifter - 8)); + else + tableWord |= (tableValue << (shifter - 8)); + + shifter -= 8; + + if (shifter == 0) { + *(pTableBase) = tableWord; + pTableBase++; + shifter = 32; + } + } + } else { + for (i = 0; i < 12; i++) { + tableWord = 0; + shifter -= 8; + + if (shifter == 0) { + *(pTableBase) = tableWord; + pTableBase++; + shifter = 32; + } + } + } + + for (i = 0; i < 12; i++) { + tableValue = 0; + + if (shifter == 32) + tableWord = (tableValue << (shifter - 8)); + else + tableWord |= (tableValue << (shifter - 8)); + + shifter -= 8; + + if (shifter == 0) { + *(pTableBase) = tableWord; + pTableBase++; + shifter = 32; + } + } + } else { + if (JPG_VLC->dcTable1.vals) { + for (i = 0; i < 12; i++) { + if (i < JPG_VLC->dcTable1.tableLength) { + tableValue = (RK_U8) JPG_VLC->dcTable1.vals[i]; + } else { + tableValue = 0; + } + + if (shifter == 32) + tableWord = (tableValue << (shifter - 8)); + else + tableWord |= (tableValue << (shifter - 8)); + + shifter -= 8; + + if (shifter == 0) { + *(pTableBase) = tableWord; + pTableBase++; + shifter = 32; + } + } + } else { + for (i = 0; i < 12; i++) { + tableWord = 0; + shifter -= 8; + + if (shifter == 0) { + *(pTableBase) = tableWord; + pTableBase++; + shifter = 32; + } + } + } + + for (i = 0; i < 12; i++) { + tableValue = 0; + + if (shifter == 32) + tableWord = (tableValue << (shifter - 8)); + else + tableWord |= (tableValue << (shifter - 8)); + + shifter -= 8; + + if (shifter == 0) { + *(pTableBase) = tableWord; + pTableBase++; + shifter = 32; + } + } + } + } else { + /* this trick is done because hw always wants luma table as ac hw table 1 */ + if (JPG_SCN->Ta[pSyntax->info.componentId] == 0) { + /* Write AC Table 1 (as specified in HW regs) + * NOTE: Not the same as actable[1] (as specified in JPEG Spec) */ + JPEGD_INFO_LOG("INTERNAL: Write tables: AC1 (luma)\n"); + if (JPG_VLC->acTable0.vals) { + for (i = 0; i < 162; i++) { + if (i < JPG_VLC->acTable0.tableLength) { + tableValue = (RK_U8) JPG_VLC->acTable0.vals[i]; + } else { + tableValue = 0; + } + + if (shifter == 32) + tableWord = (tableValue << (shifter - 8)); + else + tableWord |= (tableValue << (shifter - 8)); + + shifter -= 8; + + if (shifter == 0) { + *(pTableBase) = tableWord; + pTableBase++; + shifter = 32; + } + } + } else { + for (i = 0; i < 162; i++) { + tableWord = 0; + shifter -= 8; + + if (shifter == 0) { + *(pTableBase) = tableWord; + pTableBase++; + shifter = 32; + } + } + } + + /* Write AC Table 2 */ + JPEGD_INFO_LOG("INTERNAL: Write zero table (YUV400): \n"); + for (i = 0; i < 162; i++) { + tableValue = 0; + + if (shifter == 32) + tableWord = (tableValue << (shifter - 8)); + else + tableWord |= (tableValue << (shifter - 8)); + + shifter -= 8; + + if (shifter == 0) { + *(pTableBase) = tableWord; + pTableBase++; + shifter = 32; + } + } + } else { + /* Write AC Table 1 (as specified in HW regs) + * NOTE: Not the same as actable[1] (as specified in JPEG Spec) */ + if (JPG_VLC->acTable1.vals) { + JPEGD_INFO_LOG("INTERNAL: Write tables: AC1 (luma)\n"); + for (i = 0; i < 162; i++) { + if (i < JPG_VLC->acTable1.tableLength) { + tableValue = (RK_U8) JPG_VLC->acTable1.vals[i]; + } else { + tableValue = 0; + } + + if (shifter == 32) + tableWord = (tableValue << (shifter - 8)); + else + tableWord |= (tableValue << (shifter - 8)); + + shifter -= 8; + + if (shifter == 0) { + *(pTableBase) = tableWord; + pTableBase++; + shifter = 32; + } + } + } else { + for (i = 0; i < 162; i++) { + tableWord = 0; + + shifter -= 8; + + if (shifter == 0) { + *(pTableBase) = tableWord; + pTableBase++; + shifter = 32; + } + } + } + + /* Write AC Table 2 */ + JPEGD_INFO_LOG("INTERNAL: writeTables: padding zero (YUV400)\n"); + for (i = 0; i < 162; i++) { + tableValue = 0; + + if (shifter == 32) + tableWord = (tableValue << (shifter - 8)); + else + tableWord |= (tableValue << (shifter - 8)); + + shifter -= 8; + + if (shifter == 0) { + *(pTableBase) = tableWord; + pTableBase++; + shifter = 32; + } + } + } + + /* this trick is done because hw always wants luma table as dc hw table 1 */ + if (JPG_SCN->Td[pSyntax->info.componentId] == 0) { + if (JPG_VLC->dcTable0.vals) { + for (i = 0; i < 12; i++) { + if (i < JPG_VLC->dcTable0.tableLength) { + tableValue = (RK_U8) JPG_VLC->dcTable0.vals[i]; + } else { + tableValue = 0; + } + + if (shifter == 32) + tableWord = (tableValue << (shifter - 8)); + else + tableWord |= (tableValue << (shifter - 8)); + + shifter -= 8; + + if (shifter == 0) { + *(pTableBase) = tableWord; + pTableBase++; + shifter = 32; + } + } + } else { + for (i = 0; i < 12; i++) { + tableWord = 0; + shifter -= 8; + + if (shifter == 0) { + *(pTableBase) = tableWord; + pTableBase++; + shifter = 32; + } + } + } + + for (i = 0; i < 12; i++) { + tableValue = 0; + + if (shifter == 32) + tableWord = (tableValue << (shifter - 8)); + else + tableWord |= (tableValue << (shifter - 8)); + + shifter -= 8; + + if (shifter == 0) { + *(pTableBase) = tableWord; + pTableBase++; + shifter = 32; + } + } + } else { + if (JPG_VLC->dcTable1.vals) { + for (i = 0; i < 12; i++) { + if (i < JPG_VLC->dcTable1.tableLength) { + tableValue = (RK_U8) JPG_VLC->dcTable1.vals[i]; + } else { + tableValue = 0; + } + + if (shifter == 32) + tableWord = (tableValue << (shifter - 8)); + else + tableWord |= (tableValue << (shifter - 8)); + + shifter -= 8; + + if (shifter == 0) { + *(pTableBase) = tableWord; + pTableBase++; + shifter = 32; + } + } + } else { + for (i = 0; i < 12; i++) { + tableWord = 0; + shifter -= 8; + + if (shifter == 0) { + *(pTableBase) = tableWord; + pTableBase++; + shifter = 32; + } + } + } + + for (i = 0; i < 12; i++) { + tableValue = 0; + + if (shifter == 32) + tableWord = (tableValue << (shifter - 8)); + else + tableWord |= (tableValue << (shifter - 8)); + + shifter -= 8; + + if (shifter == 0) { + *(pTableBase) = tableWord; + pTableBase++; + shifter = 32; + } + } + } + } + + } + + for (i = 0; i < 4; i++) { + tableValue = 0; + + if (shifter == 32) + tableWord = (tableValue << (shifter - 8)); + else + tableWord |= (tableValue << (shifter - 8)); + + shifter -= 8; + + if (shifter == 0) { + *(pTableBase) = tableWord; + pTableBase++; + shifter = 32; + } + } + FUN_TEST("Exit"); +} + +MPP_RET jpegd_allocate_chroma_out_buffer(JpegSyntaxParam *pSyntax) +{ + FUN_TEST("Enter"); + if (NULL == pSyntax) { + JPEGD_ERROR_LOG("NULL pointer"); + return MPP_ERR_NULL_PTR; + } + + if (pSyntax->ppInstance == NULL || (pSyntax->ppInstance != NULL && !pSyntax->ppControl.usePipeline)) { + if (pSyntax->info.givenOutLuma.vir_addr == NULL) { + JPEGD_INFO_LOG("givenOutLuma is NULL"); + + /* luma bus address to output */ + pSyntax->info.outLuma = pSyntax->asicBuff.outLumaBuffer; + + if (pSyntax->image.sizeChroma) { + JPEGD_INFO_LOG("sizeChroma:%d", pSyntax->image.sizeChroma); + JPEGD_INFO_LOG("sizeLuma:%d, outLumaBuffer.phy_addr:%x", pSyntax->image.sizeLuma, pSyntax->asicBuff.outLumaBuffer.phy_addr); + + pSyntax->asicBuff.outChromaBuffer.phy_addr = pSyntax->asicBuff.outLumaBuffer.phy_addr + (pSyntax->image.sizeLuma << 10); + + if (pSyntax->info.operationType != JPEGDEC_BASELINE) { + pSyntax->asicBuff.outChromaBuffer2.phy_addr = pSyntax->asicBuff.outChromaBuffer.phy_addr + ((pSyntax->image.sizeChroma / 2) << 10); + } else { + pSyntax->asicBuff.outChromaBuffer2.phy_addr = 0; + } + + // chroma bus address to output + pSyntax->info.outChroma = pSyntax->asicBuff.outChromaBuffer; + pSyntax->info.outChroma2 = pSyntax->asicBuff.outChromaBuffer2; + } + } else { + JPEGD_INFO_LOG("givenOutLuma is not NULL"); + pSyntax->asicBuff.outLumaBuffer.vir_addr = pSyntax->info.givenOutLuma.vir_addr; + pSyntax->asicBuff.outLumaBuffer.phy_addr = pSyntax->info.givenOutLuma.phy_addr; + + pSyntax->asicBuff.outChromaBuffer.vir_addr = pSyntax->info.givenOutChroma.vir_addr; + pSyntax->asicBuff.outChromaBuffer.phy_addr = pSyntax->info.givenOutChroma.phy_addr; + pSyntax->asicBuff.outChromaBuffer2.vir_addr = pSyntax->info.givenOutChroma2.vir_addr; + pSyntax->asicBuff.outChromaBuffer2.phy_addr = pSyntax->info.givenOutChroma2.phy_addr; + + /* luma bus address to output */ + pSyntax->info.outLuma = pSyntax->asicBuff.outLumaBuffer; + + if (pSyntax->image.sizeChroma) { + // chroma bus address to output + pSyntax->info.outChroma = pSyntax->asicBuff.outChromaBuffer; + pSyntax->info.outChroma2 = pSyntax->asicBuff.outChromaBuffer2; + } + + /* flag to release */ + pSyntax->info.userAllocMem = 1; + } + + JPEGD_INFO_LOG("Luma virtual: %p, phy_addr: %x\n", pSyntax->asicBuff.outLumaBuffer.vir_addr, + pSyntax->asicBuff.outLumaBuffer.phy_addr); + JPEGD_INFO_LOG("Chroma virtual: %p, phy_addr: %x\n", pSyntax->asicBuff.outChromaBuffer.vir_addr, + pSyntax->asicBuff.outChromaBuffer.phy_addr); + } + FUN_TEST("Exit"); + return MPP_OK; +} + +MPP_RET jpegd_set_post_processor(JpegHalContext *pCtx, JpegSyntaxParam *pSyntax) +{ + FUN_TEST("Enter"); + if (NULL == pCtx || NULL == pSyntax) { + JPEGD_ERROR_LOG("NULL pointer"); + return MPP_ERR_NULL_PTR; + } + + PostProcessInfo *ppInfo = &(pSyntax->ppInfo); + JpegRegSet *reg = &(pCtx->regs); + int inColor = pSyntax->ppInputFomart; + int outColor = ppInfo->outFomart; + int dither = ppInfo->shouldDither; + int inWidth = pSyntax->imageInfo.outputWidth; + int inHeigth = pSyntax->imageInfo.outputHeight; + int outWidth = pSyntax->ppScaleW; + int outHeight = pSyntax->ppScaleH; + + reg->reg0.sw_pp_axi_rd_id = 0; + reg->reg0.sw_pp_axi_wr_id = 0; + reg->reg0.sw_pp_scmd_dis = 1; + reg->reg0.sw_pp_max_burst = 16; + + reg->reg18_pp_in_lu_base = 0; + + reg->reg34.sw_ext_orig_width = inWidth >> 4; + + reg->reg37.sw_pp_in_a2_endsel = 1; + reg->reg37.sw_pp_in_a1_swap32 = 1; + reg->reg37.sw_pp_in_a1_endian = 1; + reg->reg37.sw_pp_in_swap32_e = 1; + reg->reg37.sw_pp_in_endian = 1; + reg->reg37.sw_pp_out_endian = 1; + reg->reg37.sw_pp_out_swap32_e = 1; + + reg->reg41.sw_pp_clk_gate_e = 1; + reg->reg41.sw_pp_ahb_hlock_e = 1; + reg->reg41.sw_pp_data_disc_e = 1; + + if (ppInfo->cropW <= 0) { + reg->reg34.sw_pp_in_w_ext = (((inWidth / 16) & 0xE00) >> 9); + reg->reg34.sw_pp_in_width = ((inWidth / 16) & 0x1FF); + reg->reg34.sw_pp_in_h_ext = (((inHeigth / 16) & 0x700) >> 8); + reg->reg34.sw_pp_in_height = ((inHeigth / 16) & 0x0FF); + } else { + reg->reg34.sw_pp_in_w_ext = (((ppInfo->cropW / 16) & 0xE00) >> 9); + reg->reg34.sw_pp_in_width = ((ppInfo->cropW / 16) & 0x1FF); + reg->reg34.sw_pp_in_h_ext = (((ppInfo->cropH / 16) & 0x700) >> 8); + reg->reg34.sw_pp_in_height = ((ppInfo->cropH / 16) & 0x0FF); + + reg->reg14.sw_crop_startx_ext = (((ppInfo->cropX / 16) & 0xE00) >> 9); + reg->reg14.sw_crop_startx = ((ppInfo->cropX / 16) & 0x1FF); + reg->reg14.sw_crop_starty_ext = (((ppInfo->cropY / 16) & 0x700) >> 8); + reg->reg14.sw_crop_starty = ((ppInfo->cropY / 16) & 0x0FF); + + if (ppInfo->cropW & 0x0F) { + reg->reg14.sw_pp_crop8_r_e = 1; + } else { + reg->reg14.sw_pp_crop8_r_e = 0; + } + if (ppInfo->cropH & 0x0F) { + reg->reg14.sw_pp_crop8_d_e = 1; + } else { + reg->reg14.sw_pp_crop8_d_e = 0; + } + inWidth = ppInfo->cropW; + inHeigth = ppInfo->cropH; + } + + reg->reg39.sw_display_width = outWidth; + reg->reg35.sw_pp_out_width = outWidth; + reg->reg35.sw_pp_out_height = outHeight; + reg->reg21_pp_out_lu_base = pSyntax->asicBuff.outLumaBuffer.phy_addr; + + switch (inColor) { + case PP_IN_FORMAT_YUV422INTERLAVE: + reg->reg38.sw_pp_in_format = 0; + break; + case PP_IN_FORMAT_YUV420SEMI: + reg->reg38.sw_pp_in_format = 1; + break; + case PP_IN_FORMAT_YUV420PLANAR: + reg->reg38.sw_pp_in_format = 2; + break; + case PP_IN_FORMAT_YUV400: + reg->reg38.sw_pp_in_format = 3; + break; + case PP_IN_FORMAT_YUV422SEMI: + reg->reg38.sw_pp_in_format = 4; + break; + case PP_IN_FORMAT_YUV420SEMITIELED: + reg->reg38.sw_pp_in_format = 5; + break; + case PP_IN_FORMAT_YUV440SEMI: + reg->reg38.sw_pp_in_format = 6; + break; + case PP_IN_FORMAT_YUV444_SEMI: + reg->reg38.sw_pp_in_format = 7; + reg->reg38.sw_pp_in_format_es = 0; + break; + case PP_IN_FORMAT_YUV411_SEMI: + reg->reg38.sw_pp_in_format = 0; + reg->reg38.sw_pp_in_format_es = 1; + break; + default: + JPEGD_ERROR_LOG("unsupported format:%d", inColor); + return -1; + } + +#define VIDEORANGE 1 //0 or 1 + int videoRange = VIDEORANGE; + + reg->reg15.sw_rangemap_coef_y = 9; + reg->reg15.sw_rangemap_coef_c = 9; + /* brightness */ + reg->reg3.sw_pp_color_coefff = BRIGHTNESS; + + if (outColor <= PP_OUT_FORMAT_ARGB) { + /*Bt.601*/ + unsigned int a = 298; + unsigned int b = 409; + unsigned int c = 208; + unsigned int d = 100; + unsigned int e = 516; + + /*Bt.709 + unsigned int a = 298; + unsigned int b = 459; + unsigned int c = 137; + unsigned int d = 55; + unsigned int e = 544;*/ + + int satur = 0, tmp; + if (videoRange != 0) { + /*Bt.601*/ + a = 256; + b = 350; + c = 179; + d = 86; + e = 443; + /*Bt.709 + a = 256; + b = 403; + c = 120; + d = 48; + e = 475;*/ + + reg->reg15.sw_ycbcr_range = videoRange; + } + int contrast = CONTRAST; + if (contrast != 0) { + int thr1y, thr2y, off1, off2, thr1, thr2, a1, a2; + if (videoRange == 0) { + int tmp1, tmp2; + /* Contrast */ + thr1 = (219 * (contrast + 128)) / 512; + thr1y = (219 - 2 * thr1) / 2; + thr2 = 219 - thr1; + thr2y = 219 - thr1y; + + tmp1 = (thr1y * 256) / thr1; + tmp2 = ((thr2y - thr1y) * 256) / (thr2 - thr1); + off1 = ((thr1y - ((tmp2 * thr1) / 256)) * a) / 256; + off2 = ((thr2y - ((tmp1 * thr2) / 256)) * a) / 256; + + tmp1 = (64 * (contrast + 128)) / 128; + tmp2 = 256 * (128 - tmp1); + a1 = (tmp2 + off2) / thr1; + a2 = a1 + (256 * (off2 - 1)) / (thr2 - thr1); + } else { + /* Contrast */ + thr1 = (64 * (contrast + 128)) / 128; + thr1y = 128 - thr1; + thr2 = 256 - thr1; + thr2y = 256 - thr1y; + a1 = (thr1y * 256) / thr1; + a2 = ((thr2y - thr1y) * 256) / (thr2 - thr1); + off1 = thr1y - (a2 * thr1) / 256; + off2 = thr2y - (a1 * thr2) / 256; + } + + if (a1 > 1023) + a1 = 1023; + else if (a1 < 0) + a1 = 0; + + if (a2 > 1023) + a2 = 1023; + else if (a2 < 0) + a2 = 0; + + if (thr1 > 255) + thr1 = 255; + else if (thr1 < 0) + thr1 = 0; + + if (thr2 > 255) + thr2 = 255; + else if (thr2 < 0) + thr2 = 0; + + if (off1 > 511) + off1 = 511; + else if (off1 < -512) + off1 = -512; + + if (off2 > 511) + off2 = 511; + else if (off2 < -512) + off2 = -512; + + reg->reg31.sw_contrast_thr1 = thr1; + reg->reg31.sw_contrast_thr2 = thr2; + reg->reg32.sw_contrast_off1 = off1; + reg->reg32.sw_contrast_off2 = off2; + + reg->reg1.sw_color_coeffa1 = a1; + reg->reg1.sw_color_coeffa2 = a2; + } else { + reg->reg31.sw_contrast_thr1 = 55; + reg->reg31.sw_contrast_thr2 = 165; + reg->reg32.sw_contrast_off1 = 0; + reg->reg32.sw_contrast_off2 = 0; + + tmp = a; + if (tmp > 1023) + tmp = 1023; + else if (tmp < 0) + tmp = 0; + + reg->reg1.sw_color_coeffa1 = tmp; + reg->reg1.sw_color_coeffa2 = tmp; + } + + reg->reg37.sw_pp_out_endian = 0; + + /* saturation */ + satur = 64 + SATURATION; + + tmp = (satur * (int) b) / 64; + if (tmp > 1023) + tmp = 1023; + else if (tmp < 0) + tmp = 0; + reg->reg1.sw_color_coeffb = (unsigned int) tmp; + + tmp = (satur * (int) c) / 64; + if (tmp > 1023) + tmp = 1023; + else if (tmp < 0) + tmp = 0; + reg->reg2.sw_color_coeffc = (unsigned int) tmp; + + tmp = (satur * (int) d) / 64; + if (tmp > 1023) + tmp = 1023; + else if (tmp < 0) + tmp = 0; + reg->reg2.sw_color_coeffd = (unsigned int) tmp; + + tmp = (satur * (int) e) / 64; + if (tmp > 1023) + tmp = 1023; + else if (tmp < 0) + tmp = 0; + reg->reg2.sw_color_coeffe = (unsigned int) tmp; + } + + switch (outColor) { + case PP_OUT_FORMAT_RGB565: + reg->reg9_r_mask = 0xF800F800; + reg->reg10_g_mask = 0x07E007E0; + reg->reg11_b_mask = 0x001F001F; + reg->reg16.sw_rgb_r_padd = 0; + reg->reg16.sw_rgb_g_padd = 5; + reg->reg16.sw_rgb_b_padd = 11; + if (dither) { //always do dither + JPEGD_VERBOSE_LOG("we do dither."); + reg->reg36.sw_dither_select_r = 2; + reg->reg36.sw_dither_select_g = 3; + reg->reg36.sw_dither_select_b = 2; + } else { + JPEGD_VERBOSE_LOG("we do not dither."); + } + reg->reg37.sw_rgb_pix_in32 = 1; + reg->reg37.sw_pp_out_swap16_e = 1; + reg->reg38.sw_pp_out_format = 0; + break; + case PP_OUT_FORMAT_ARGB: + reg->reg9_r_mask = 0x000000FF | (0xff << 24); + reg->reg10_g_mask = 0x0000FF00 | (0xff << 24); + reg->reg11_b_mask = 0x00FF0000 | (0xff << 24); + + reg->reg16.sw_rgb_r_padd = 24; + reg->reg16.sw_rgb_g_padd = 16; + reg->reg16.sw_rgb_b_padd = 8; + + reg->reg37.sw_rgb_pix_in32 = 0; + reg->reg38.sw_pp_out_format = 0; + break; + case PP_OUT_FORMAT_YUV422INTERLAVE: + reg->reg38.sw_pp_out_format = 3; + break; + case PP_OUT_FORMAT_YUV420INTERLAVE: { + RK_U32 phy_addr = pSyntax->asicBuff.outLumaBuffer.phy_addr; + if (VPUClientGetIOMMUStatus() <= 0) { + reg->reg22_pp_out_ch_base = (phy_addr + outWidth * outHeight); + } else { + if (outWidth * outHeight > 0x400000) { + JPEGD_ERROR_LOG("out offset big than 22bit iommu map may be error"); + } else { + reg->reg22_pp_out_ch_base = (phy_addr | ((outWidth * outHeight) << 10)); + } + } + reg->reg38.sw_pp_out_format = 5; + JPEGD_INFO_LOG("outWidth:%d, outHeight:%d", outWidth, outHeight); + JPEGD_INFO_LOG("outLumaBuffer:%x, reg22:%x", phy_addr, reg->reg22_pp_out_ch_base); + } + break; + default: + JPEGD_ERROR_LOG("unsuppotred format:%d", outColor); + return -1; + } + + reg->reg38.sw_rotation_mode = 0; + + unsigned int inw, inh; + unsigned int outw, outh; + + inw = inWidth - 1; + inh = inHeigth - 1; + outw = outWidth - 1; + outh = outHeight - 1; + + if (inw < outw) { + reg->reg4.sw_hor_scale_mode = 1; + reg->reg4.sw_scale_wratio = (outw << 16) / inw; + reg->reg6.sw_wscale_invra = (inw << 16) / outw; + } else if (inw > outw) { + reg->reg4.sw_hor_scale_mode = 2; + reg->reg6.sw_wscale_invra = ((outw + 1) << 16) / (inw + 1); + } else + reg->reg4.sw_hor_scale_mode = 0; + + if (inh < outh) { + reg->reg4.sw_ver_scale_mode = 1; + reg->reg5.sw_scale_hratio = (outh << 16) / inh; + reg->reg6.sw_hscale_invra = (inh << 16) / outh; + } else if (inh > outh) { + reg->reg4.sw_ver_scale_mode = 2; + reg->reg6.sw_hscale_invra = ((outh + 1) << 16) / (inh + 1) + 1; + } else + reg->reg4.sw_ver_scale_mode = 0; + + reg->reg41.sw_pp_pipeline_e = ppInfo->enable; + FUN_TEST("Exit"); + return 0; +} + +JpegDecRet jpegd_configure_regs(JpegSyntaxParam *pSyntax, JpegHalContext *pCtx) +{ + FUN_TEST("Enter"); + JpegRegSet *reg = &(pCtx->regs); + + reg->reg50_dec_ctrl.sw_filtering_dis = 1; + + reg->reg53_dec_mode = JPEG_RK70_MODE_JPEG; + + reg->reg57_enable_ctrl.sw_dec_out_dis = 0; + reg->reg57_enable_ctrl.sw_rlc_mode_e = pSyntax->info.rlcMode; + + /* frame size, round up the number of mbs */ + reg->reg120.sw_pic_mb_h_ext = ((((pSyntax->info.Y) >> (4)) & 0x700) >> 8); + reg->reg120.sw_pic_mb_w_ext = ((((pSyntax->info.X) >> (4)) & 0xE00) >> 9); + reg->reg120.sw_pic_mb_width = ((pSyntax->info.X) >> (4)) & 0x1FF; + reg->reg120.sw_pic_mb_hight_p = ((pSyntax->info.Y) >> (4)) & 0x0FF; + + reg->reg121.sw_pjpeg_fildown_e = pSyntax->info.fillBottom; + reg->reg121.sw_pjpeg_ss = pSyntax->scan.Ss; /* Set spectral selection start coefficient */ + reg->reg121.sw_pjpeg_se = pSyntax->scan.Se; /* Set spectral selection end coefficient */ + reg->reg121.sw_pjpeg_ah = pSyntax->scan.Ah; /* Set the point transform used in the preceding scan */ + reg->reg121.sw_pjpeg_al = pSyntax->scan.Al; /* Set the point transform value */ + + reg->reg122.sw_jpeg_qtables = pSyntax->info.amountOfQTables; + reg->reg122.sw_jpeg_mode = pSyntax->info.yCbCrMode; + reg->reg122.sw_jpeg_filright_e = pSyntax->info.fillRight; + + reg->reg148.sw_slice_h = pSyntax->info.sliceHeight; + + /* Set JPEG operation mode */ + if (pSyntax->info.operationType != JPEGDEC_PROGRESSIVE) { + reg->reg57_enable_ctrl.sw_pjpeg_e = 0; + } else { + reg->reg57_enable_ctrl.sw_pjpeg_e = 1; + } + + /* Set needed progressive parameters */ + if (pSyntax->info.operationType == JPEGDEC_PROGRESSIVE) { // TODO: unsupported so far + JPEGD_INFO_LOG("JPEGDEC_PROGRESSIVE"); + } + + if (pSyntax->info.operationType == JPEGDEC_BASELINE) { + /* write "length amounts" */ + JPEGD_VERBOSE_LOG("Write VLC length amounts to register\n"); + jpegd_write_len_bits(pSyntax, pCtx); + + /* Create AC/DC/QP tables for HW */ + JPEGD_VERBOSE_LOG("Write AC,DC,QP tables to base\n"); + jpegd_write_tables(pSyntax, pCtx); + } else if (pSyntax->info.operationType == JPEGDEC_NONINTERLEAVED) { + JPEGD_INFO_LOG("JPEGDEC_NONINTERLEAVED"); + } else { + JPEGD_INFO_LOG("other operation type"); + } + + /* Select which tables the chromas use */ + jpegd_select_chroma_table(pSyntax, pCtx); + + /* write table base */ + reg->reg61_qtable_base = mpp_buffer_get_fd(pCtx->pTableBase); + + /* set up stream position for HW decode */ + jpegd_set_stream_params(pSyntax, pCtx); + + /* set restart interval */ + if (pSyntax->frame.Ri) { + reg->reg122.sw_sync_marker_e = 1; + reg->reg123.sw_pjpeg_rest_freq = pSyntax->frame.Ri; + } else { + reg->reg122.sw_sync_marker_e = 0; + } + + /* PP depending register writes */ + if (pSyntax->ppInstance != NULL && pSyntax->ppControl.usePipeline) { + JPEGD_INFO_LOG("ppInstance is not NULL!"); + reg->reg57_enable_ctrl.sw_dec_out_dis = 1; + + /* set output to zero, because of pp */ + /* Luminance output */ + reg->reg63_dec_out_base = 0; + + /* Chrominance output */ + if (pSyntax->image.sizeChroma) { + reg->reg131_jpg_ch_out_base = 0; + } + + if (pSyntax->info.sliceStartCount == JPEGDEC_SLICE_START_VALUE) { + /* Enable pp */ + } + + pSyntax->info.pipeline = 1; + } else { + JPEGD_INFO_LOG("ppInstance is NULL!"); + + if (pSyntax->info.operationType == JPEGDEC_BASELINE) { + /* Luminance output */ + JPEGD_INFO_LOG("INTERNAL: Set LUMA OUTPUT data base address\n"); + JPEGD_INFO_LOG("Luma virtual: %p, phy_addr: %x\n", pSyntax->asicBuff.outLumaBuffer.vir_addr, + pSyntax->asicBuff.outLumaBuffer.phy_addr); + reg->reg63_dec_out_base = pSyntax->asicBuff.outLumaBuffer.phy_addr; + + /* Chrominance output */ + if (pSyntax->image.sizeChroma) { + JPEGD_INFO_LOG("INTERNAL: Set CHROMA OUTPUT data base address\n"); + JPEGD_INFO_LOG("Chroma virtual: %p, phy_addr: %x\n", pSyntax->asicBuff.outChromaBuffer.vir_addr, + pSyntax->asicBuff.outChromaBuffer.phy_addr); + reg->reg131_jpg_ch_out_base = pSyntax->asicBuff.outChromaBuffer.phy_addr; + } + } else { + JPEGD_INFO_LOG("NON_JPEGDEC_BASELINE"); + } + + pSyntax->info.pipeline = 0; + } + + pSyntax->info.sliceStartCount = 1; + //pSyntax->asicRunning = 1; + + /* Enable jpeg mode and set slice mode */ + JPEGD_VERBOSE_LOG("Enable jpeg\n"); + reg->reg57_enable_ctrl.sw_dec_e = 1; + + FUN_TEST("Exit"); + return MPP_OK; +} + +static MPP_RET jpegd_regs_init(JpegRegSet *reg) +{ + FUN_TEST("Enter"); + reg->reg50_dec_ctrl.sw_dec_out_tiled_e = 0; + reg->reg50_dec_ctrl.sw_dec_scmd_dis = DEC_RK70_SCMD_DISABLE; + reg->reg50_dec_ctrl.sw_dec_latency = DEC_RK70_LATENCY_COMPENSATION; + + reg->reg54_endian.sw_dec_in_endian = DEC_RK70_BIG_ENDIAN; + reg->reg54_endian.sw_dec_out_endian = DEC_RK70_LITTLE_ENDIAN; + reg->reg54_endian.sw_dec_strendian_e = DEC_RK70_LITTLE_ENDIAN; + reg->reg54_endian.sw_dec_outswap32_e = DEC_RK70_LITTLE_ENDIAN; + reg->reg54_endian.sw_dec_inswap32_e = 1; + reg->reg54_endian.sw_dec_strswap32_e = 1; + + reg->reg55_Interrupt.sw_dec_irq_dis = 0; + + reg->reg56_axi_ctrl.sw_dec_axi_rn_id = 0xff; + reg->reg56_axi_ctrl.sw_dec_axi_wr_id = 0; + reg->reg56_axi_ctrl.sw_dec_max_burst = DEC_RK70_BUS_BURST_LENGTH_16; + reg->reg56_axi_ctrl.sw_dec_data_disc_e = DEC_RK70_DATA_DISCARD_ENABLE; + + reg->reg57_enable_ctrl.sw_dec_timeout_e = 1; + reg->reg57_enable_ctrl.sw_dec_clk_gate_e = 1; + + FUN_TEST("Exit"); + return MPP_OK; +} + +MPP_RET jpegd_gen_regs(JpegHalContext *ctx, JpegSyntaxParam *syntax) +{ + FUN_TEST("Enter"); + if (NULL == ctx || NULL == syntax) { + JPEGD_ERROR_LOG("NULL pointer"); + return MPP_ERR_NULL_PTR; + } + JpegDecRet retCode; + JpegHalContext *pCtx = ctx; + JpegSyntaxParam *pSyntax = syntax; + + retCode = JPEGDEC_OK; + if (pSyntax->image.headerReady) { + JPEGD_INFO_LOG("image header is ready"); + do { /* loop until decoding control should return for user */ + if (pSyntax->ppInstance != NULL) { /* if pp enabled ==> set pp control */ + pSyntax->ppControl.usePipeline = 1; + } + + /* check if we had to load input buffer or not */ + if (!pSyntax->info.inputBufferEmpty) { + /* Start HW or continue after pause */ + if (!pSyntax->info.SliceReadyForPause) { + if (!pSyntax->info.progressiveScanReady || pSyntax->info.nonInterleavedScanReady) { + JPEGD_INFO_LOG("Start to configure registers\n"); + retCode = jpegd_configure_regs(pSyntax, pCtx); + + pSyntax->info.nonInterleavedScanReady = 0; + if (retCode != JPEGDEC_OK) { + return retCode; + } + } else { + JPEGD_INFO_LOG("Continue HW decoding after progressive scan ready"); + pSyntax->info.progressiveScanReady = 0; + } + } else { + JPEGD_INFO_LOG("Continue HW decoding after slice ready"); + } + + pSyntax->info.SliceCount++; + } else { + JPEGD_INFO_LOG("Continue HW decoding after input buffer has been loaded"); + jpegd_input_buff_load_init(pSyntax); + + /* buffer loaded ==> reset flag */ + pSyntax->info.inputBufferEmpty = 0; + } + } while (0 /*!pSyntax->image.imageReady*/); // TODO: when to end this loop?? + } + + FUN_TEST("Exit"); + return MPP_OK; +} + +MPP_RET hal_jpegd_init(void *hal, MppHalCfg *cfg) +{ + FUN_TEST("Enter"); + MPP_RET ret = MPP_OK; + JpegHalContext *JpegHalCtx = (JpegHalContext *)hal; + if (NULL == JpegHalCtx) { + JpegHalCtx = (JpegHalContext *)mpp_calloc(JpegHalContext, 1); + if (NULL == JpegHalCtx) { + JPEGD_ERROR_LOG("NULL pointer"); + return MPP_ERR_NULL_PTR; + } + } + + //configure + JpegHalCtx->packet_slots = cfg->packet_slots; + JpegHalCtx->frame_slots = cfg->frame_slots; + + //get vpu socket +#ifdef RKPLATFORM + if (JpegHalCtx->vpu_socket <= 0) { + JpegHalCtx->vpu_socket = VPUClientInit(VPU_DEC); + if (JpegHalCtx->vpu_socket <= 0) { + JPEGD_ERROR_LOG("get vpu_socket(%d) <= 0, failed. \n", JpegHalCtx->vpu_socket); + return MPP_ERR_UNKNOW; + } else { + JPEGD_VERBOSE_LOG("get vpu_socket(%d), success. \n", JpegHalCtx->vpu_socket); + } + } +#endif + + //init regs + JpegRegSet *reg = &(JpegHalCtx->regs); + memset(reg, 0, sizeof(JpegRegSet)); + jpegd_regs_init(reg); + + //malloc hw buf + if (JpegHalCtx->group == NULL) { +#ifdef RKPLATFORM + JPEGD_VERBOSE_LOG("mpp_buffer_group_get_internal used ion in"); + ret = mpp_buffer_group_get_internal(&JpegHalCtx->group, MPP_BUFFER_TYPE_ION); +#else + ret = mpp_buffer_group_get_internal(&JpegHalCtx->group, MPP_BUFFER_TYPE_NORMAL); +#endif + if (MPP_OK != ret) { + JPEGD_ERROR_LOG("mpp_buffer_group_get failed\n"); + return ret; + } + } + + ret = mpp_buffer_get(JpegHalCtx->group, &JpegHalCtx->frame_buf, JPEGD_STREAM_BUFF_SIZE); + if (MPP_OK != ret) { + JPEGD_ERROR_LOG("get buffer failed\n"); + return ret; + } + + ret = mpp_buffer_get(JpegHalCtx->group, &JpegHalCtx->pTableBase, JPEGDEC_BASELINE_TABLE_SIZE); + if (MPP_OK != ret) { + JPEGD_ERROR_LOG("get buffer failed\n"); + return ret; + } + + JpegHalCtx->output_fmt = MPP_FMT_YUV420SP; + JpegHalCtx->set_output_fmt_flag = 0; + + //init dbg stuff + JpegHalCtx->hal_debug_enable = 0; + JpegHalCtx->frame_count = 0; + JpegHalCtx->output_yuv_count = 0; + + FUN_TEST("Exit"); + return MPP_OK; +} + +MPP_RET hal_jpegd_deinit(void *hal) +{ + FUN_TEST("Enter"); + MPP_RET ret = MPP_OK; + JpegHalContext *JpegHalCtx = (JpegHalContext *)hal; + +#ifdef RKPLATFORM + if (JpegHalCtx->vpu_socket >= 0) { + VPUClientRelease(JpegHalCtx->vpu_socket); + } +#endif + + if (JpegHalCtx->frame_buf) { + ret = mpp_buffer_put(JpegHalCtx->frame_buf); + if (MPP_OK != ret) { + JPEGD_ERROR_LOG("put buffer failed\n"); + return ret; + } + } + + if (JpegHalCtx->pTableBase) { + ret = mpp_buffer_put(JpegHalCtx->pTableBase); + if (MPP_OK != ret) { + JPEGD_ERROR_LOG("put buffer failed\n"); + return ret; + } + } + + if (JpegHalCtx->group) { + ret = mpp_buffer_group_put(JpegHalCtx->group); + if (MPP_OK != ret) { + JPEGD_ERROR_LOG("group free buffer failed\n"); + return ret; + } + } + + JpegHalCtx->output_fmt = MPP_FMT_YUV420SP; + JpegHalCtx->set_output_fmt_flag = 0; + JpegHalCtx->hal_debug_enable = 0; + JpegHalCtx->frame_count = 0; + JpegHalCtx->output_yuv_count = 0; + + return MPP_OK; + FUN_TEST("Exit"); +} + +MPP_RET hal_jpegd_gen_regs(void *hal, HalTaskInfo *syn) +{ + FUN_TEST("Enter"); + if (NULL == hal || NULL == syn) { + JPEGD_ERROR_LOG("NULL pointer"); + return MPP_ERR_NULL_PTR; + } + + MPP_RET ret = MPP_OK; + JpegHalContext *JpegHalCtx = (JpegHalContext *)hal; + JpegSyntaxParam *pSyntax = (JpegSyntaxParam *)syn->dec.syntax.data; +#ifdef RKPLATFORM + MppBuffer streambuf = NULL; + MppBuffer outputBuf = NULL; +#endif + + if (syn->dec.valid) { + syn->dec.valid = 0; + jpegd_set_output_format(JpegHalCtx, pSyntax); + +#ifdef RKPLATFORM + if (JpegHalCtx->set_output_fmt_flag && (JpegHalCtx->vpu_socket > 0)) { + VPUClientRelease(JpegHalCtx->vpu_socket); + JpegHalCtx->vpu_socket = 0; + + JpegHalCtx->vpu_socket = VPUClientInit(VPU_DEC_PP); + if (JpegHalCtx->vpu_socket <= 0) { + JPEGD_ERROR_LOG("get vpu_socket(%d) <= 0, failed. \n", JpegHalCtx->vpu_socket); + return MPP_ERR_UNKNOW; + } else { + JPEGD_VERBOSE_LOG("get vpu_socket(%d), success. \n", JpegHalCtx->vpu_socket); + } + } + + mpp_buf_slot_get_prop(JpegHalCtx->packet_slots, syn->dec.input, SLOT_BUFFER, &streambuf); + pSyntax->stream.streamBus = mpp_buffer_get_fd(streambuf); + + mpp_buf_slot_get_prop(JpegHalCtx->frame_slots, syn->dec.output, SLOT_BUFFER, &outputBuf); + pSyntax->asicBuff.outLumaBuffer.phy_addr = mpp_buffer_get_fd(outputBuf); + + jpegd_allocate_chroma_out_buffer(pSyntax); +#endif + + ret = jpegd_set_post_processor(JpegHalCtx, pSyntax); + + ret = jpegd_gen_regs(JpegHalCtx, pSyntax); + + if (JpegHalCtx->hal_debug_enable && JpegHalCtx->frame_count < 3) { + RK_U32 idx = 0; + RK_U32 *pRegs = (RK_U32 *) & (JpegHalCtx->regs); + JPEGD_INFO_LOG("sizeof(JpegRegSet)=%d, sizeof(pRegs[0])=%d", sizeof(JpegRegSet), sizeof(pRegs[0])); + + JpegHalCtx->frame_count++; + for (idx = 0; idx < sizeof(JpegRegSet) / sizeof(pRegs[0]); idx++) { + JPEGD_INFO_LOG("frame_%d_reg[%d]=0x%08x", JpegHalCtx->frame_count, idx, pRegs[idx]); + } + } + + syn->dec.valid = 1; + } + + return ret; + FUN_TEST("Exit"); +} + +MPP_RET hal_jpegd_start(void *hal, HalTaskInfo *task) +{ + FUN_TEST("Enter"); + MPP_RET ret = MPP_OK; + JpegHalContext *JpegHalCtx = (JpegHalContext *)hal; + +#ifdef RKPLATFORM + RK_U32 *p_regs = (RK_U32 *)&JpegHalCtx->regs; + ret = VPUClientSendReg(JpegHalCtx->vpu_socket, p_regs, JPEGD_REG_NUM); + if (ret != 0) { + JPEGD_ERROR_LOG("VPUClientSendReg Failed!!!\n"); + return MPP_ERR_VPUHW; + } +#endif + (void)JpegHalCtx; + (void)task; + FUN_TEST("Exit"); + return ret; +} + +MPP_RET hal_jpegd_wait(void *hal, HalTaskInfo *task) +{ + FUN_TEST("Enter"); + MPP_RET ret = MPP_OK; + JpegHalContext *JpegHalCtx = (JpegHalContext *)hal; + (void)JpegHalCtx; + (void)task; + +#ifdef RKPLATFORM + JpegRegSet reg_out; + VPU_CMD_TYPE cmd = 0; + RK_S32 length = 0; + memset(®_out, 0, sizeof(JpegRegSet)); + + ret = VPUClientWaitResult(JpegHalCtx->vpu_socket, (RK_U32 *)®_out, JPEGD_REG_NUM, &cmd, &length); + if (reg_out.reg55_Interrupt.sw_dec_bus_int) { + JPEGD_ERROR_LOG("IRQ BUS ERROR!"); + } else if (reg_out.reg55_Interrupt.sw_dec_error_int) { + JPEGD_ERROR_LOG("IRQ STREAM ERROR!"); + } else if (reg_out.reg55_Interrupt.sw_dec_timeout) { + JPEGD_ERROR_LOG("IRQ TIMEOUT!"); + } else if (reg_out.reg55_Interrupt.sw_dec_buffer_int) { + JPEGD_ERROR_LOG("IRQ BUFFER EMPTY!"); + } else if (reg_out.reg55_Interrupt.sw_dec_irq) { + JPEGD_INFO_LOG("DECODE SUCCESS!"); + } + + /* debug information */ + if (JpegHalCtx->hal_debug_enable && JpegHalCtx->output_yuv_count < 3) { + static FILE *jpg_file; + static char name[32]; + MppBuffer outputBuf = NULL; + void *pOutYUV = NULL; + mpp_buf_slot_get_prop(JpegHalCtx->frame_slots, task->dec.output, SLOT_BUFFER, &outputBuf); + pOutYUV = mpp_buffer_get_ptr(outputBuf); + + snprintf(name, sizeof(name), "/tmp/output%02d.yuv", JpegHalCtx->output_yuv_count); + jpg_file = fopen(name, "wb+"); + if (jpg_file) { + JpegSyntaxParam *pTmpSyn = (JpegSyntaxParam *)task->dec.syntax.data; + RK_U32 width = pTmpSyn->frame.hwX; + RK_U32 height = pTmpSyn->frame.hwY; + + JPEGD_INFO_LOG("output YUV(%d*%d) saving to %s\n", width, height, name); + JPEGD_INFO_LOG("pOutYUV:%p", pOutYUV); + fwrite(pOutYUV, width * height * 3 / 2, 1, jpg_file); + fclose(jpg_file); + JpegHalCtx->output_yuv_count++; + } + } +#endif + + FUN_TEST("Exit"); + return ret; +} + +MPP_RET hal_jpegd_reset(void *hal) +{ + FUN_TEST("Enter"); + MPP_RET ret = MPP_OK; + JpegHalContext *JpegHalCtx = (JpegHalContext *)hal; + (void)JpegHalCtx; + + return ret; +} + +MPP_RET hal_jpegd_flush(void *hal) +{ + FUN_TEST("Enter"); + MPP_RET ret = MPP_OK; + + (void)hal; + return ret; +} + +MPP_RET hal_jpegd_control(void *hal, RK_S32 cmd_type, void *param) +{ + FUN_TEST("Enter"); + MPP_RET ret = MPP_OK; + JpegHalContext *JpegHalCtx = (JpegHalContext *)hal; + if (NULL == JpegHalCtx) { + JPEGD_ERROR_LOG("NULL pointer"); + return MPP_ERR_NULL_PTR; + } + + switch (cmd_type) { + case MPP_DEC_SET_OUTPUT_FORMAT: { + JpegHalCtx->output_fmt = *((MppFrameFormat *)param); + JpegHalCtx->set_output_fmt_flag = 1; + JPEGD_INFO_LOG("output_format:%d\n", JpegHalCtx->output_fmt); + } break; + default : + ret = MPP_NOK; + } + FUN_TEST("Exit"); + return ret; +} + +const MppHalApi hal_api_jpegd = { + "jpegd_rkdec", + MPP_CTX_DEC, + MPP_VIDEO_CodingMJPEG, + sizeof(JpegHalContext), + 0, + hal_jpegd_init, + hal_jpegd_deinit, + hal_jpegd_gen_regs, + hal_jpegd_start, + hal_jpegd_wait, + hal_jpegd_reset, + hal_jpegd_flush, + hal_jpegd_control, +}; + + diff --git a/mpp/hal/vpu/m2vd/hal_m2vd_api.c b/mpp/hal/vpu/m2vd/hal_m2vd_api.c index 6cbb94e1..205f1ad7 100644 --- a/mpp/hal/vpu/m2vd/hal_m2vd_api.c +++ b/mpp/hal/vpu/m2vd/hal_m2vd_api.c @@ -1,43 +1,43 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define MODULE_TAG "hal_m2vd_api" - -#include - -#include "mpp_hal.h" -#include "hal_m2vd_reg.h" - -const MppHalApi hal_api_m2vd = { - "m2vd_rkdec", - MPP_CTX_DEC, - MPP_VIDEO_CodingMPEG2, - sizeof(M2VDHalContext), - 0, - hal_m2vd_init, - hal_m2vd_deinit, - hal_m2vd_gen_regs, - hal_m2vd_start, - hal_m2vd_wait, - hal_m2vd_reset, - hal_m2vd_flush, - hal_m2vd_control, -}; - - - - - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define MODULE_TAG "hal_m2vd_api" + +#include + +#include "mpp_hal.h" +#include "hal_m2vd_reg.h" + +const MppHalApi hal_api_m2vd = { + "m2vd_rkdec", + MPP_CTX_DEC, + MPP_VIDEO_CodingMPEG2, + sizeof(M2VDHalContext), + 0, + hal_m2vd_init, + hal_m2vd_deinit, + hal_m2vd_gen_regs, + hal_m2vd_start, + hal_m2vd_wait, + hal_m2vd_reset, + hal_m2vd_flush, + hal_m2vd_control, +}; + + + + + diff --git a/mpp/hal/vpu/m2vd/hal_m2vd_reg.c b/mpp/hal/vpu/m2vd/hal_m2vd_reg.c index ae38da69..d7009185 100644 --- a/mpp/hal/vpu/m2vd/hal_m2vd_reg.c +++ b/mpp/hal/vpu/m2vd/hal_m2vd_reg.c @@ -1,404 +1,404 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define MODULE_TAG "hal_m2vd_reg" -#include -#include "vpu.h" -#include "hal_m2vd_reg.h" -#include "mpp_log.h" -#include "mpp_env.h" - -RK_U32 m2vh_debug = 0; - -#define M2VD_BUF_SIZE_QPTAB (256) - -#define DEC_RKV_LITTLE_ENDIAN 1 -#define DEC_RKV_BIG_ENDIAN 0 -#define DEC_RKV_BUS_BURST_LENGTH_UNDEFINED 0 -#define DEC_RKV_BUS_BURST_LENGTH_4 4 -#define DEC_RKV_BUS_BURST_LENGTH_8 8 -#define DEC_RKV_BUS_BURST_LENGTH_16 16 - -#define FUN_T(tag) \ - do {\ - if (M2VH_DBG_FUNCTION & m2vh_debug)\ - { mpp_log("%s: line(%d), func(%s)", tag, __LINE__, __FUNCTION__); }\ - } while (0) - -typedef enum M2VDPicCodingType_t { - M2VD_CODING_TYPE_I = 1, - M2VD_CODING_TYPE_P = 2, - M2VD_CODING_TYPE_B = 3, - M2VD_CODING_TYPE_D = 4 -} M2VDPicCodingType; - -typedef enum M2VDPicStruct_t { - M2VD_PIC_STRUCT_TOP_FIELD = 1, - M2VD_PIC_STRUCT_BOTTOM_FIELD = 2, - M2VD_PIC_STRUCT_FRAME = 3 -} M2VDPicStruct; - -MPP_RET hal_m2vd_init(void *hal, MppHalCfg *cfg) -{ - MPP_RET ret = MPP_OK; - M2VDHalContext *p = (M2VDHalContext *)hal; - M2VDRegSet *reg = &p->regs; - FUN_T("FUN_I"); - - - //configure - p->packet_slots = cfg->packet_slots; - p->frame_slots = cfg->frame_slots; - - mpp_env_get_u32("m2vh_debug", &m2vh_debug, 0); - //get vpu socket -#ifdef RKPLATFORM - if (p->vpu_socket <= 0) { - p->vpu_socket = VPUClientInit(VPU_DEC); - if (p->vpu_socket <= 0) { - mpp_err("get vpu_socket(%d) <=0, failed. \n", p->vpu_socket); - return MPP_ERR_UNKNOW; - } else { - mpp_log("get vpu_socket(%d), success. \n", p->vpu_socket); - } - } -#endif - if (p->group == NULL) { - -#ifdef RKPLATFORM - mpp_err("mpp_buffer_group_get_internal used ion in"); - ret = mpp_buffer_group_get_internal(&p->group, MPP_BUFFER_TYPE_ION); -#else - ret = mpp_buffer_group_get_internal(&p->group, MPP_BUFFER_TYPE_NORMAL); -#endif - if (MPP_OK != ret) { - mpp_err("m2v_hal mpp_buffer_group_get failed\n"); - return ret; - } - } - ret = mpp_buffer_get(p->group, &p->qp_table, M2VD_BUF_SIZE_QPTAB); - if (MPP_OK != ret) { - mpp_err("m2v_hal qtable_base get buffer failed\n"); - return ret; - } - - - //init regs - memset(&p->regs, 0, sizeof(M2VDRegSet)); - reg->config3.sw_dec_axi_rn_id = 0; - reg->control.sw_dec_timeout_e = 1; - reg->config2.sw_dec_strswap32_e = 1; //change - reg->config2.sw_dec_strendian_e = DEC_RKV_LITTLE_ENDIAN; - reg->config2.sw_dec_inswap32_e = 1; //change - reg->config2.sw_dec_outswap32_e = 1; //change - - - reg->control.sw_dec_clk_gate_e = 1; //change - reg->config2.sw_dec_in_endian = DEC_RKV_LITTLE_ENDIAN; //change - reg->config2.sw_dec_out_endian = DEC_RKV_LITTLE_ENDIAN; - - reg->config1.sw_dec_out_tiled_e = 0; - reg->config3.sw_dec_max_burst = DEC_RKV_BUS_BURST_LENGTH_16; - reg->config1.sw_dec_scmd_dis = 0; - reg->config1.sw_dec_adv_pre_dis = 0; - reg->error_position.sw_apf_threshold = 8; - - reg->config1.sw_dec_latency = 0; - reg->config3.sw_dec_data_disc_e = 0; - - reg->interrupt.sw_dec_irq = 0; - reg->config3.sw_dec_axi_rn_id = 0; - reg->config3.sw_dec_axi_wr_id = 0; - - reg->sw_dec_mode = 8; - - if (M2VH_DBG_DUMP_REG & m2vh_debug) { - p->fp_reg_in = fopen("/sdcard/m2vd_dbg_reg_in.txt", "wb"); - if (p->fp_reg_in == NULL) { - mpp_log("file open error: %s", "/sdcard/m2vd_dbg_reg_in.txt"); - } - p->fp_reg_out = fopen("/sdcard/m2vd_dbg_reg_out.txt", "wb"); - if (p->fp_reg_out == NULL) { - mpp_log("file open error: %s", "/sdcard/m2vd_dbg_reg_out.txt"); - } - } else { - p->fp_reg_in = NULL; - p->fp_reg_out = NULL; - } - - FUN_T("FUN_O"); - - return ret; -} - -MPP_RET hal_m2vd_deinit(void *hal) -{ - MPP_RET ret = MPP_OK; - FUN_T("FUN_I"); - M2VDHalContext *p = (M2VDHalContext *)hal; -#ifdef RKPLATFORM - if (p->vpu_socket >= 0) { - VPUClientRelease(p->vpu_socket); - - } -#endif - if (p->qp_table) { - ret = mpp_buffer_put(p->qp_table); - if (MPP_OK != ret) { - mpp_err("m2v_hal qp_table put buffer failed\n"); - return ret; - } - } - - if (p->group) { - ret = mpp_buffer_group_put(p->group); - if (MPP_OK != ret) { - mpp_err("m2v_hal group free buffer failed\n"); - return ret; - } - } - if (p->fp_reg_in) { - fclose(p->fp_reg_in); - p->fp_reg_in = NULL; - } - if (p->fp_reg_out) { - fclose(p->fp_reg_out); - p->fp_reg_out = NULL; - } - - FUN_T("FUN_O"); - return ret; -} - -MPP_RET hal_m2vd_gen_regs(void *hal, HalTaskInfo *task) -{ - MPP_RET ret = MPP_OK; - if (task->dec.valid) { - void *q_table = NULL; -#ifdef RKPLATFORM - MppBuffer streambuf = NULL; - MppBuffer framebuf = NULL; -#endif - M2VDHalContext *ctx = (M2VDHalContext *)hal; - M2VDDxvaParam *dx = (M2VDDxvaParam *)task->dec.syntax.data; - M2VDRegSet *pRegs = &ctx->regs; - task->dec.valid = 0; - q_table = mpp_buffer_get_ptr(ctx->qp_table); - memcpy(q_table, dx->qp_tab, M2VD_BUF_SIZE_QPTAB); - - pRegs->ppReg[0] = 0; - pRegs->dec_info.sw_mv_accuracy_fwd = 1; - pRegs->dec_info.sw_mv_accuracy_bwd = 1; - - if (dx->seq_ext_head_dec_flag) { - pRegs->sw_dec_mode = 5; - pRegs->dec_info.sw_fcode_fwd_hor = dx->pic.full_pel_forward_vector; - pRegs->dec_info.sw_fcode_fwd_ver = dx->pic.forward_f_code; - pRegs->dec_info.sw_fcode_bwd_hor = dx->pic.full_pel_backward_vector; - pRegs->dec_info.sw_fcode_bwd_ver = dx->pic.backward_f_code; - - } else { - pRegs->sw_dec_mode = 6; - pRegs->dec_info.sw_fcode_fwd_hor = dx->pic.forward_f_code; - pRegs->dec_info.sw_fcode_fwd_ver = dx->pic.forward_f_code; - pRegs->dec_info.sw_fcode_bwd_hor = dx->pic.backward_f_code; - pRegs->dec_info.sw_fcode_bwd_ver = dx->pic.backward_f_code; - if (dx->pic.full_pel_forward_vector) - pRegs->dec_info.sw_mv_accuracy_fwd = 0; - if (dx->pic.full_pel_backward_vector) - pRegs->dec_info.sw_mv_accuracy_bwd = 0; - } - - pRegs->pic_params.sw_pic_mb_width = (dx->seq.decode_width + 15) >> 4; - pRegs->pic_params.sw_pic_mb_height_p = (dx->seq.decode_height + 15) >> 4; - pRegs->control.sw_pic_interlace_e = 1 - dx->seq_ext.progressive_sequence; - if (dx->pic_code_ext.picture_structure == M2VD_PIC_STRUCT_FRAME) - pRegs->control.sw_pic_fieldmode_e = 0; - else { - pRegs->control.sw_pic_fieldmode_e = 1; - pRegs->control.sw_pic_topfield_e = dx->pic_code_ext.picture_structure == 1; - } - if (dx->pic.picture_coding_type == M2VD_CODING_TYPE_B) - pRegs->control.sw_pic_b_e = 1; - else - pRegs->control.sw_pic_b_e = 0; - if (dx->pic.picture_coding_type == M2VD_CODING_TYPE_I) - pRegs->control.sw_pic_inter_e = 0; - else - pRegs->control.sw_pic_inter_e = 1; - - pRegs->pic_params.sw_topfieldfirst_e = dx->pic_code_ext.top_field_first; - pRegs->control.sw_fwd_interlace_e = 0; - pRegs->control.sw_write_mvs_e = 0;//concealment_motion_vectors; - pRegs->pic_params.sw_alt_scan_e = dx->pic_code_ext.alternate_scan; - pRegs->dec_info.sw_alt_scan_flag_e = dx->pic_code_ext.alternate_scan; - - pRegs->stream_bitinfo.sw_qscale_type = dx->pic_code_ext.q_scale_type; - pRegs->stream_bitinfo.sw_intra_dc_prec = dx->pic_code_ext.intra_dc_precision; - pRegs->stream_bitinfo.sw_con_mv_e = dx->pic_code_ext.concealment_motion_vectors; - pRegs->stream_bitinfo.sw_intra_vlc_tab = dx->pic_code_ext.intra_vlc_format; - pRegs->stream_bitinfo.sw_frame_pred_dct = dx->pic_code_ext.frame_pred_frame_dct; - pRegs->stream_buffinfo.sw_init_qp = 1; -#ifdef RKPLATFORM //current strem in frame out config - mpp_buf_slot_get_prop(ctx->packet_slots, task->dec.input, SLOT_BUFFER, &streambuf); - pRegs->VLC_base = mpp_buffer_get_fd(streambuf); - - if (VPUClientGetIOMMUStatus() > 0) { - pRegs->VLC_base |= (dx->bitstream_offset << 10); - } else { - pRegs->VLC_base += dx->bitstream_offset; - } - mpp_buf_slot_get_prop(ctx->frame_slots, dx->CurrPic.Index7Bits, SLOT_BUFFER, &framebuf); - - - if ((dx->pic_code_ext.picture_structure == M2VD_PIC_STRUCT_TOP_FIELD) || - (dx->pic_code_ext.picture_structure == M2VD_PIC_STRUCT_FRAME)) { - pRegs->cur_pic_base = mpp_buffer_get_fd(framebuf); //just index need map - } else { - if (VPUClientGetIOMMUStatus() > 0) { - pRegs->cur_pic_base = mpp_buffer_get_fd(framebuf) | (((dx->seq.decode_width + 15) & (~15)) << 10); - } else { - pRegs->cur_pic_base = mpp_buffer_get_fd(framebuf) + ((dx->seq.decode_width + 15) & (~15)); - } - } - - //ref & qtable config - mpp_buf_slot_get_prop(ctx->frame_slots, dx->frame_refs[0].Index7Bits, SLOT_BUFFER, &framebuf); - pRegs->ref0 = mpp_buffer_get_fd(framebuf); //just index need map - - mpp_buf_slot_get_prop(ctx->frame_slots, dx->frame_refs[1].Index7Bits, SLOT_BUFFER, &framebuf); - pRegs->ref1 = mpp_buffer_get_fd(framebuf); //just index need map - - mpp_buf_slot_get_prop(ctx->frame_slots, dx->frame_refs[2].Index7Bits, SLOT_BUFFER, &framebuf); - pRegs->ref2 = mpp_buffer_get_fd(framebuf); //just index need map - - mpp_buf_slot_get_prop(ctx->frame_slots, dx->frame_refs[3].Index7Bits, SLOT_BUFFER, &framebuf); - pRegs->ref3 = mpp_buffer_get_fd(framebuf); //just index need map - - pRegs->slice_table = mpp_buffer_get_fd(ctx->qp_table); -#endif - pRegs->error_position.sw_startmb_x = 0; - pRegs->error_position.sw_startmb_y = 0; - pRegs->control.sw_dec_out_dis = 0; - pRegs->config1.sw_filtering_dis = 1; - - pRegs->stream_buffinfo.sw_stream_len = dx->bitstream_length; - pRegs->stream_bitinfo.sw_stream_start_bit = dx->bitstream_start_bit; - pRegs->control.sw_dec_e = 1; - - if (M2VH_DBG_REG & m2vh_debug) { - RK_U32 j = 0; - RK_U32 *p_reg = (RK_U32 *)pRegs; - for (j = 50; j < 159; j++) { - mpp_log("reg[%d] = 0x%08x", j, p_reg[j]); - } - } - if (ctx->fp_reg_in) { - int k = 0; - RK_U32 *p_reg = (RK_U32*)pRegs; - mpp_log("fwrite regs start"); - fprintf(ctx->fp_reg_in, "Frame #%d\n", ctx->dec_frame_cnt); - for (k = 0; k < M2VD_REG_NUM; k++) - fprintf(ctx->fp_reg_in, "[(D)%03d, (X)%03x] %08x\n", k, k, p_reg[k]); - fflush(ctx->fp_reg_in); - } - - task->dec.valid = 1; - ctx->dec_frame_cnt++; - } - return ret; - -} - -MPP_RET hal_m2vd_start(void *hal, HalTaskInfo *task) -{ - MPP_RET ret = MPP_OK; -#ifdef RKPLATFORM - M2VDHalContext *ctx = (M2VDHalContext *)hal; - RK_U32 *p_regs = (RK_U32 *)&ctx->regs; - FUN_T("FUN_I"); - ret = VPUClientSendReg(ctx->vpu_socket, p_regs, M2VD_REG_NUM); - if (ret != 0) { - mpp_err("VPUClientSendReg Failed!!!\n"); - return MPP_ERR_VPUHW; - } -#endif - (void)task; - (void)hal; - FUN_T("FUN_O"); - return ret; -} - -MPP_RET hal_m2vd_wait(void *hal, HalTaskInfo *task) -{ - MPP_RET ret = MPP_OK; -#ifdef RKPLATFORM - M2VDRegSet reg_out; - VPU_CMD_TYPE cmd = 0; - RK_S32 length = 0; - M2VDHalContext *ctx = (M2VDHalContext *)hal; - FUN_T("FUN_I"); - memset(®_out, 0, sizeof(M2VDRegSet)); - ret = VPUClientWaitResult(ctx->vpu_socket, (RK_U32 *)®_out, - M2VD_REG_NUM, &cmd, &length); - if (ctx->fp_reg_out) { - int k = 0; - RK_U32 *p_reg = (RK_U32*)®_out; - fprintf(ctx->fp_reg_out, "Frame #%d\n", ctx->dec_frame_cnt); - for (k = 0; k < M2VD_REG_NUM; k++) - fprintf(ctx->fp_reg_out, "[(D)%03d, (X)%03x] %08x\n", k, k, p_reg[k]); - fflush(ctx->fp_reg_out); - } - if (M2VH_DBG_IRQ & m2vh_debug) - mpp_log("VPUClientWaitResult return interrupt:%08x", reg_out.interrupt); -#endif - if (ret) { - mpp_log("VPUClientWaitResult return error:%d", ret); - } - (void)hal; - (void)task; - FUN_T("FUN_O"); - return ret; -} - -MPP_RET hal_m2vd_reset(void *hal) -{ - MPP_RET ret = MPP_OK; - FUN_T("FUN_I"); - (void)hal; - FUN_T("FUN_O"); - return ret; -} - -MPP_RET hal_m2vd_flush(void *hal) -{ - MPP_RET ret = MPP_OK; - FUN_T("FUN_I"); - (void)hal; - FUN_T("FUN_O"); - return ret; -} -MPP_RET hal_m2vd_control(void *hal, RK_S32 cmd_type, void *param) -{ - MPP_RET ret = MPP_OK; - FUN_T("FUN_I"); - (void)hal; - (void)cmd_type; - (void)param; - FUN_T("FUN_O"); - return ret; -} - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define MODULE_TAG "hal_m2vd_reg" +#include +#include "vpu.h" +#include "hal_m2vd_reg.h" +#include "mpp_log.h" +#include "mpp_env.h" + +RK_U32 m2vh_debug = 0; + +#define M2VD_BUF_SIZE_QPTAB (256) + +#define DEC_RKV_LITTLE_ENDIAN 1 +#define DEC_RKV_BIG_ENDIAN 0 +#define DEC_RKV_BUS_BURST_LENGTH_UNDEFINED 0 +#define DEC_RKV_BUS_BURST_LENGTH_4 4 +#define DEC_RKV_BUS_BURST_LENGTH_8 8 +#define DEC_RKV_BUS_BURST_LENGTH_16 16 + +#define FUN_T(tag) \ + do {\ + if (M2VH_DBG_FUNCTION & m2vh_debug)\ + { mpp_log("%s: line(%d), func(%s)", tag, __LINE__, __FUNCTION__); }\ + } while (0) + +typedef enum M2VDPicCodingType_t { + M2VD_CODING_TYPE_I = 1, + M2VD_CODING_TYPE_P = 2, + M2VD_CODING_TYPE_B = 3, + M2VD_CODING_TYPE_D = 4 +} M2VDPicCodingType; + +typedef enum M2VDPicStruct_t { + M2VD_PIC_STRUCT_TOP_FIELD = 1, + M2VD_PIC_STRUCT_BOTTOM_FIELD = 2, + M2VD_PIC_STRUCT_FRAME = 3 +} M2VDPicStruct; + +MPP_RET hal_m2vd_init(void *hal, MppHalCfg *cfg) +{ + MPP_RET ret = MPP_OK; + M2VDHalContext *p = (M2VDHalContext *)hal; + M2VDRegSet *reg = &p->regs; + FUN_T("FUN_I"); + + + //configure + p->packet_slots = cfg->packet_slots; + p->frame_slots = cfg->frame_slots; + + mpp_env_get_u32("m2vh_debug", &m2vh_debug, 0); + //get vpu socket +#ifdef RKPLATFORM + if (p->vpu_socket <= 0) { + p->vpu_socket = VPUClientInit(VPU_DEC); + if (p->vpu_socket <= 0) { + mpp_err("get vpu_socket(%d) <=0, failed. \n", p->vpu_socket); + return MPP_ERR_UNKNOW; + } else { + mpp_log("get vpu_socket(%d), success. \n", p->vpu_socket); + } + } +#endif + if (p->group == NULL) { + +#ifdef RKPLATFORM + mpp_err("mpp_buffer_group_get_internal used ion in"); + ret = mpp_buffer_group_get_internal(&p->group, MPP_BUFFER_TYPE_ION); +#else + ret = mpp_buffer_group_get_internal(&p->group, MPP_BUFFER_TYPE_NORMAL); +#endif + if (MPP_OK != ret) { + mpp_err("m2v_hal mpp_buffer_group_get failed\n"); + return ret; + } + } + ret = mpp_buffer_get(p->group, &p->qp_table, M2VD_BUF_SIZE_QPTAB); + if (MPP_OK != ret) { + mpp_err("m2v_hal qtable_base get buffer failed\n"); + return ret; + } + + + //init regs + memset(&p->regs, 0, sizeof(M2VDRegSet)); + reg->config3.sw_dec_axi_rn_id = 0; + reg->control.sw_dec_timeout_e = 1; + reg->config2.sw_dec_strswap32_e = 1; //change + reg->config2.sw_dec_strendian_e = DEC_RKV_LITTLE_ENDIAN; + reg->config2.sw_dec_inswap32_e = 1; //change + reg->config2.sw_dec_outswap32_e = 1; //change + + + reg->control.sw_dec_clk_gate_e = 1; //change + reg->config2.sw_dec_in_endian = DEC_RKV_LITTLE_ENDIAN; //change + reg->config2.sw_dec_out_endian = DEC_RKV_LITTLE_ENDIAN; + + reg->config1.sw_dec_out_tiled_e = 0; + reg->config3.sw_dec_max_burst = DEC_RKV_BUS_BURST_LENGTH_16; + reg->config1.sw_dec_scmd_dis = 0; + reg->config1.sw_dec_adv_pre_dis = 0; + reg->error_position.sw_apf_threshold = 8; + + reg->config1.sw_dec_latency = 0; + reg->config3.sw_dec_data_disc_e = 0; + + reg->interrupt.sw_dec_irq = 0; + reg->config3.sw_dec_axi_rn_id = 0; + reg->config3.sw_dec_axi_wr_id = 0; + + reg->sw_dec_mode = 8; + + if (M2VH_DBG_DUMP_REG & m2vh_debug) { + p->fp_reg_in = fopen("/sdcard/m2vd_dbg_reg_in.txt", "wb"); + if (p->fp_reg_in == NULL) { + mpp_log("file open error: %s", "/sdcard/m2vd_dbg_reg_in.txt"); + } + p->fp_reg_out = fopen("/sdcard/m2vd_dbg_reg_out.txt", "wb"); + if (p->fp_reg_out == NULL) { + mpp_log("file open error: %s", "/sdcard/m2vd_dbg_reg_out.txt"); + } + } else { + p->fp_reg_in = NULL; + p->fp_reg_out = NULL; + } + + FUN_T("FUN_O"); + + return ret; +} + +MPP_RET hal_m2vd_deinit(void *hal) +{ + MPP_RET ret = MPP_OK; + FUN_T("FUN_I"); + M2VDHalContext *p = (M2VDHalContext *)hal; +#ifdef RKPLATFORM + if (p->vpu_socket >= 0) { + VPUClientRelease(p->vpu_socket); + + } +#endif + if (p->qp_table) { + ret = mpp_buffer_put(p->qp_table); + if (MPP_OK != ret) { + mpp_err("m2v_hal qp_table put buffer failed\n"); + return ret; + } + } + + if (p->group) { + ret = mpp_buffer_group_put(p->group); + if (MPP_OK != ret) { + mpp_err("m2v_hal group free buffer failed\n"); + return ret; + } + } + if (p->fp_reg_in) { + fclose(p->fp_reg_in); + p->fp_reg_in = NULL; + } + if (p->fp_reg_out) { + fclose(p->fp_reg_out); + p->fp_reg_out = NULL; + } + + FUN_T("FUN_O"); + return ret; +} + +MPP_RET hal_m2vd_gen_regs(void *hal, HalTaskInfo *task) +{ + MPP_RET ret = MPP_OK; + if (task->dec.valid) { + void *q_table = NULL; +#ifdef RKPLATFORM + MppBuffer streambuf = NULL; + MppBuffer framebuf = NULL; +#endif + M2VDHalContext *ctx = (M2VDHalContext *)hal; + M2VDDxvaParam *dx = (M2VDDxvaParam *)task->dec.syntax.data; + M2VDRegSet *pRegs = &ctx->regs; + task->dec.valid = 0; + q_table = mpp_buffer_get_ptr(ctx->qp_table); + memcpy(q_table, dx->qp_tab, M2VD_BUF_SIZE_QPTAB); + + pRegs->ppReg[0] = 0; + pRegs->dec_info.sw_mv_accuracy_fwd = 1; + pRegs->dec_info.sw_mv_accuracy_bwd = 1; + + if (dx->seq_ext_head_dec_flag) { + pRegs->sw_dec_mode = 5; + pRegs->dec_info.sw_fcode_fwd_hor = dx->pic.full_pel_forward_vector; + pRegs->dec_info.sw_fcode_fwd_ver = dx->pic.forward_f_code; + pRegs->dec_info.sw_fcode_bwd_hor = dx->pic.full_pel_backward_vector; + pRegs->dec_info.sw_fcode_bwd_ver = dx->pic.backward_f_code; + + } else { + pRegs->sw_dec_mode = 6; + pRegs->dec_info.sw_fcode_fwd_hor = dx->pic.forward_f_code; + pRegs->dec_info.sw_fcode_fwd_ver = dx->pic.forward_f_code; + pRegs->dec_info.sw_fcode_bwd_hor = dx->pic.backward_f_code; + pRegs->dec_info.sw_fcode_bwd_ver = dx->pic.backward_f_code; + if (dx->pic.full_pel_forward_vector) + pRegs->dec_info.sw_mv_accuracy_fwd = 0; + if (dx->pic.full_pel_backward_vector) + pRegs->dec_info.sw_mv_accuracy_bwd = 0; + } + + pRegs->pic_params.sw_pic_mb_width = (dx->seq.decode_width + 15) >> 4; + pRegs->pic_params.sw_pic_mb_height_p = (dx->seq.decode_height + 15) >> 4; + pRegs->control.sw_pic_interlace_e = 1 - dx->seq_ext.progressive_sequence; + if (dx->pic_code_ext.picture_structure == M2VD_PIC_STRUCT_FRAME) + pRegs->control.sw_pic_fieldmode_e = 0; + else { + pRegs->control.sw_pic_fieldmode_e = 1; + pRegs->control.sw_pic_topfield_e = dx->pic_code_ext.picture_structure == 1; + } + if (dx->pic.picture_coding_type == M2VD_CODING_TYPE_B) + pRegs->control.sw_pic_b_e = 1; + else + pRegs->control.sw_pic_b_e = 0; + if (dx->pic.picture_coding_type == M2VD_CODING_TYPE_I) + pRegs->control.sw_pic_inter_e = 0; + else + pRegs->control.sw_pic_inter_e = 1; + + pRegs->pic_params.sw_topfieldfirst_e = dx->pic_code_ext.top_field_first; + pRegs->control.sw_fwd_interlace_e = 0; + pRegs->control.sw_write_mvs_e = 0;//concealment_motion_vectors; + pRegs->pic_params.sw_alt_scan_e = dx->pic_code_ext.alternate_scan; + pRegs->dec_info.sw_alt_scan_flag_e = dx->pic_code_ext.alternate_scan; + + pRegs->stream_bitinfo.sw_qscale_type = dx->pic_code_ext.q_scale_type; + pRegs->stream_bitinfo.sw_intra_dc_prec = dx->pic_code_ext.intra_dc_precision; + pRegs->stream_bitinfo.sw_con_mv_e = dx->pic_code_ext.concealment_motion_vectors; + pRegs->stream_bitinfo.sw_intra_vlc_tab = dx->pic_code_ext.intra_vlc_format; + pRegs->stream_bitinfo.sw_frame_pred_dct = dx->pic_code_ext.frame_pred_frame_dct; + pRegs->stream_buffinfo.sw_init_qp = 1; +#ifdef RKPLATFORM //current strem in frame out config + mpp_buf_slot_get_prop(ctx->packet_slots, task->dec.input, SLOT_BUFFER, &streambuf); + pRegs->VLC_base = mpp_buffer_get_fd(streambuf); + + if (VPUClientGetIOMMUStatus() > 0) { + pRegs->VLC_base |= (dx->bitstream_offset << 10); + } else { + pRegs->VLC_base += dx->bitstream_offset; + } + mpp_buf_slot_get_prop(ctx->frame_slots, dx->CurrPic.Index7Bits, SLOT_BUFFER, &framebuf); + + + if ((dx->pic_code_ext.picture_structure == M2VD_PIC_STRUCT_TOP_FIELD) || + (dx->pic_code_ext.picture_structure == M2VD_PIC_STRUCT_FRAME)) { + pRegs->cur_pic_base = mpp_buffer_get_fd(framebuf); //just index need map + } else { + if (VPUClientGetIOMMUStatus() > 0) { + pRegs->cur_pic_base = mpp_buffer_get_fd(framebuf) | (((dx->seq.decode_width + 15) & (~15)) << 10); + } else { + pRegs->cur_pic_base = mpp_buffer_get_fd(framebuf) + ((dx->seq.decode_width + 15) & (~15)); + } + } + + //ref & qtable config + mpp_buf_slot_get_prop(ctx->frame_slots, dx->frame_refs[0].Index7Bits, SLOT_BUFFER, &framebuf); + pRegs->ref0 = mpp_buffer_get_fd(framebuf); //just index need map + + mpp_buf_slot_get_prop(ctx->frame_slots, dx->frame_refs[1].Index7Bits, SLOT_BUFFER, &framebuf); + pRegs->ref1 = mpp_buffer_get_fd(framebuf); //just index need map + + mpp_buf_slot_get_prop(ctx->frame_slots, dx->frame_refs[2].Index7Bits, SLOT_BUFFER, &framebuf); + pRegs->ref2 = mpp_buffer_get_fd(framebuf); //just index need map + + mpp_buf_slot_get_prop(ctx->frame_slots, dx->frame_refs[3].Index7Bits, SLOT_BUFFER, &framebuf); + pRegs->ref3 = mpp_buffer_get_fd(framebuf); //just index need map + + pRegs->slice_table = mpp_buffer_get_fd(ctx->qp_table); +#endif + pRegs->error_position.sw_startmb_x = 0; + pRegs->error_position.sw_startmb_y = 0; + pRegs->control.sw_dec_out_dis = 0; + pRegs->config1.sw_filtering_dis = 1; + + pRegs->stream_buffinfo.sw_stream_len = dx->bitstream_length; + pRegs->stream_bitinfo.sw_stream_start_bit = dx->bitstream_start_bit; + pRegs->control.sw_dec_e = 1; + + if (M2VH_DBG_REG & m2vh_debug) { + RK_U32 j = 0; + RK_U32 *p_reg = (RK_U32 *)pRegs; + for (j = 50; j < 159; j++) { + mpp_log("reg[%d] = 0x%08x", j, p_reg[j]); + } + } + if (ctx->fp_reg_in) { + int k = 0; + RK_U32 *p_reg = (RK_U32*)pRegs; + mpp_log("fwrite regs start"); + fprintf(ctx->fp_reg_in, "Frame #%d\n", ctx->dec_frame_cnt); + for (k = 0; k < M2VD_REG_NUM; k++) + fprintf(ctx->fp_reg_in, "[(D)%03d, (X)%03x] %08x\n", k, k, p_reg[k]); + fflush(ctx->fp_reg_in); + } + + task->dec.valid = 1; + ctx->dec_frame_cnt++; + } + return ret; + +} + +MPP_RET hal_m2vd_start(void *hal, HalTaskInfo *task) +{ + MPP_RET ret = MPP_OK; +#ifdef RKPLATFORM + M2VDHalContext *ctx = (M2VDHalContext *)hal; + RK_U32 *p_regs = (RK_U32 *)&ctx->regs; + FUN_T("FUN_I"); + ret = VPUClientSendReg(ctx->vpu_socket, p_regs, M2VD_REG_NUM); + if (ret != 0) { + mpp_err("VPUClientSendReg Failed!!!\n"); + return MPP_ERR_VPUHW; + } +#endif + (void)task; + (void)hal; + FUN_T("FUN_O"); + return ret; +} + +MPP_RET hal_m2vd_wait(void *hal, HalTaskInfo *task) +{ + MPP_RET ret = MPP_OK; +#ifdef RKPLATFORM + M2VDRegSet reg_out; + VPU_CMD_TYPE cmd = 0; + RK_S32 length = 0; + M2VDHalContext *ctx = (M2VDHalContext *)hal; + FUN_T("FUN_I"); + memset(®_out, 0, sizeof(M2VDRegSet)); + ret = VPUClientWaitResult(ctx->vpu_socket, (RK_U32 *)®_out, + M2VD_REG_NUM, &cmd, &length); + if (ctx->fp_reg_out) { + int k = 0; + RK_U32 *p_reg = (RK_U32*)®_out; + fprintf(ctx->fp_reg_out, "Frame #%d\n", ctx->dec_frame_cnt); + for (k = 0; k < M2VD_REG_NUM; k++) + fprintf(ctx->fp_reg_out, "[(D)%03d, (X)%03x] %08x\n", k, k, p_reg[k]); + fflush(ctx->fp_reg_out); + } + if (M2VH_DBG_IRQ & m2vh_debug) + mpp_log("VPUClientWaitResult return interrupt:%08x", reg_out.interrupt); +#endif + if (ret) { + mpp_log("VPUClientWaitResult return error:%d", ret); + } + (void)hal; + (void)task; + FUN_T("FUN_O"); + return ret; +} + +MPP_RET hal_m2vd_reset(void *hal) +{ + MPP_RET ret = MPP_OK; + FUN_T("FUN_I"); + (void)hal; + FUN_T("FUN_O"); + return ret; +} + +MPP_RET hal_m2vd_flush(void *hal) +{ + MPP_RET ret = MPP_OK; + FUN_T("FUN_I"); + (void)hal; + FUN_T("FUN_O"); + return ret; +} +MPP_RET hal_m2vd_control(void *hal, RK_S32 cmd_type, void *param) +{ + MPP_RET ret = MPP_OK; + FUN_T("FUN_I"); + (void)hal; + (void)cmd_type; + (void)param; + FUN_T("FUN_O"); + return ret; +} + diff --git a/mpp/hal/vpu/m2vd/hal_m2vd_reg.h b/mpp/hal/vpu/m2vd/hal_m2vd_reg.h index 527d77f2..1e50187d 100644 --- a/mpp/hal/vpu/m2vd/hal_m2vd_reg.h +++ b/mpp/hal/vpu/m2vd/hal_m2vd_reg.h @@ -1,324 +1,324 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __HAL_M2VD_REG_H__ -#define __HAL_M2VD_REG_H__ - -#include "m2vd_syntax.h" -#include "hal_task.h" -#include "mpp_hal.h" -#include "mpp_buf_slot.h" -#include - - -extern RK_U32 m2vh_debug; - -#define M2VH_DBG_FUNCTION (0x00000001) -#define M2VH_DBG_REG (0x00000002) -#define M2VH_DBG_DUMP_REG (0x00000004) -#define M2VH_DBG_IRQ (0x00000008) - - - - -#define M2VD_REG_NUM 159 - - -typedef struct { - RK_U32 build_version : 3; - RK_U32 product_IDen : 1; - RK_U32 minor_version : 8; - RK_U32 major_version : 4; - RK_U32 product_numer : 16; -} ID_reg; - -typedef struct { - RK_U32 sw_dec_irq : 1; - RK_U32 sw_dec_irq_dis : 1; - RK_U32 reserve0 : 2; - RK_U32 sw_dec_rdy_int : 1; - RK_U32 sw_dec_bus_int : 1; - RK_U32 sw_dec_buffer_int : 1; - RK_U32 reserve1 : 1; - RK_U32 sw_dec_aso_int : 1; - RK_U32 sw_dec_slice_int : 1; - RK_U32 sw_dec_pic_inf : 1; - RK_U32 reserve2 : 1; - RK_U32 sw_dec_error_int: 1; - RK_U32 sw_dec_timeout : 1; - RK_U32 reserve3 : 18; -} Dec_Interrupt_reg; - - -typedef struct { - RK_U32 sw_dec_out_tiled_e : 1; - RK_U32 sw_dec_latency : 6; - RK_U32 sw_pic_fixed_quant : 1; - RK_U32 sw_filtering_dis : 1; - RK_U32 sw_skip_mode : 1; - RK_U32 sw_dec_scmd_dis : 1; - RK_U32 sw_dec_adv_pre_dis : 1; - RK_U32 sw_priority_mode : 1; //chang - RK_U32 sw_refbu2_thr : 12; - RK_U32 sw_refbu2_picid : 5; - RK_U32 reserve1 : 2; -} Device_config_reg1; - - -typedef struct { - RK_U32 sw_stream_len : 24; - RK_U32 reserve1 : 1; - RK_U32 sw_init_qp : 6; - RK_U32 reserve2 : 1; -} Dec_control_reg3; - - -typedef struct { - RK_U32 sw_dec_in_endian : 1; - RK_U32 sw_dec_out_endian : 1; - RK_U32 sw_dec_inswap32_e : 1; - RK_U32 sw_dec_outswap32_e : 1; - RK_U32 sw_dec_strswap32_e : 1; - RK_U32 sw_dec_strendian_e : 1; - RK_U32 reserve3 : 26; -} Device_config_reg2; - - -typedef struct { - RK_U32 sw_dec_axi_rn_id : 8; - RK_U32 sw_dec_axi_wr_id : 8; - RK_U32 sw_dec_max_burst : 5; - RK_U32 resever : 1; - RK_U32 sw_dec_data_disc_e : 1; - RK_U32 resever1 : 9; -} Device_config_reg3; - -typedef struct { - RK_U32 sw_dec_e : 1; - RK_U32 sw_refbu2_buf_e : 1; - RK_U32 sw_dec_out_dis : 1; - RK_U32 resever : 1; - RK_U32 sw_dec_clk_gate_e : 1; - RK_U32 sw_dec_timeout_e : 1; - RK_U32 sw_picord_count_e : 1; - RK_U32 sw_seq_mbaff_e : 1; - RK_U32 sw_reftopfirst_e : 1; - RK_U32 sw_ref_topfield_e : 1; - RK_U32 sw_write_mvs_e : 1; - RK_U32 sw_sorenson_e : 1; - RK_U32 sw_fwd_interlace_e : 1; - RK_U32 sw_pic_topfield_e : 1 ; - RK_U32 sw_pic_inter_e : 1; - RK_U32 sw_pic_b_e : 1; - RK_U32 sw_pic_fieldmode_e : 1; - RK_U32 sw_pic_interlace_e : 1; - RK_U32 sw_pjpeg_e : 1; - RK_U32 sw_divx3_e : 1; - RK_U32 sw_rlc_mode_e : 1; - RK_U32 sw_ch_8pix_ileav_e : 1; - RK_U32 sw_start_code_e : 1; - RK_U32 resever1 : 8; - RK_U32 sw_dec_ahb_hlock_e : 1; - -} Dec_control_reg0; - -typedef struct { - RK_U32 sw_ref_frames : 5; - RK_U32 sw_topfieldfirst_e : 1; - RK_U32 sw_alt_scan_e : 1; - RK_U32 sw_mb_height_off : 4; - RK_U32 sw_pic_mb_height_p : 8; - RK_U32 sw_mb_width_off : 4; - RK_U32 sw_pic_mb_width : 9; -} Dec_control_reg1; - -typedef struct { - RK_U32 sw_frame_pred_dct : 1; - RK_U32 sw_intra_vlc_tab : 1; - RK_U32 sw_intra_dc_prec : 2; - RK_U32 sw_con_mv_e : 1; - RK_U32 reserve : 19; - RK_U32 sw_qscale_type : 1; - RK_U32 reserve1 : 1; - RK_U32 sw_stream_start_bit : 6; -} Dec_control_reg2; - -typedef struct { - RK_U32 reserve : 1; - RK_U32 sw_mv_accuracy_bwd : 1; - RK_U32 sw_mv_accuracy_fwd : 1; - RK_U32 sw_fcode_bwd_ver : 4; - RK_U32 sw_fcode_bwd_hor : 4; - RK_U32 sw_fcode_fwd_ver : 4; - RK_U32 sw_fcode_fwd_hor : 4; - RK_U32 sw_alt_scan_flag_e : 1; - RK_U32 reserve1 : 12; -} Dec_BaseAdd_Ref4_reg; - - -typedef struct { - RK_U32 sw_startmb_y : 8; - RK_U32 sw_startmb_x : 9; - RK_U32 sw_apf_threshold : 14; - RK_U32 sw_reserve : 1; -} Dec_Error_concealment_reg; - -typedef struct { - RK_U32 sw_dec_max_owidth : 11; - RK_U32 sw_dec_soren_prof : 1; - RK_U32 sw_dec_bus_width : 2; - RK_U32 sw_dec_synth_lan : 2; - RK_U32 sw_dec_bus_strd : 4; - RK_U32 sw_ref_buff_exist : 1; - RK_U32 sw_dec_obuff_leve : 1; - RK_U32 sw_dec_pjpeg_exist : 1; - RK_U32 sw_vp6_prof : 1; - RK_U32 sw_dec_h264_prof : 2; - RK_U32 sw_dec_mpeg4_prof : 2; - RK_U32 sw_dec_jpeg_prof : 1; - RK_U32 sw_dec_vc1_prof : 2; - RK_U32 sw_dec_mpeg2_prof : 1; -} Dec_Synthesis_config_reg; - -typedef struct { - RK_U32 sw_refbu_y_offset : 9; - RK_U32 sw_reserve : 3; - RK_U32 sw_refbu_fparmod_e : 1; - RK_U32 sw_refbu_eval_e : 1; - RK_U32 sw_refbu_picid : 5; - RK_U32 sw_refbu_thr : 12; - RK_U32 sw_refbu_e : 1; -} Dec_Refpicbuff_control_reg; - -typedef struct { - RK_U32 sw_refbu_intra_sum : 16; - RK_U32 sw_refbu_hit_sum : 16; -} Dec_Refpicbuff_info1_reg; - -typedef struct { - RK_U32 sw_refbu_mv_sum : 22; - RK_U32 sw_reserve : 10; -} Dec_Refpicbuff_info2_reg; - -typedef struct { - RK_U32 sw_reserve : 25; - RK_U32 sw_dec_rtl_rom : 1; - RK_U32 sw_dec_rv_prof : 2; - RK_U32 sw_ref_buff2_exist : 1; - RK_U32 sw_dec_divx_prof : 1; - RK_U32 sw_dec_refbu_ilace : 1; - RK_U32 sw_dec_jpeg_exten : 1; -} Dec_Syn_configinfo_reg; - -typedef struct { - RK_U32 sw_refbu_top_sum : 16; - RK_U32 sw_refbu_bot_sum : 16; -} Dec_Refpicbuff_info3_reg; - -typedef struct { - RK_U32 sw_reserve0 : 24; - RK_U32 sw_dec_vc1 : 1; - RK_U32 sw_dec_vp6 : 1; - RK_U32 sw_dec_jpeg : 1; - RK_U32 sw_dec_sorenson : 1; - RK_U32 sw_dec_mpeg2 : 1; - RK_U32 sw_dec_mpeg4 : 1; - RK_U32 sw_dec_h264 : 1; - RK_U32 sw_reserve1 : 2; -} Dec_fuse_reg; - -typedef struct { - RK_U32 debug_dec_mb_count : 13; - RK_U32 debug_referreq1 : 1; - RK_U32 debug_referreq0 : 1; - RK_U32 debug_filter_req : 1; - RK_U32 debug_framerdy : 1; - RK_U32 debug_strm_da_e : 1; - RK_U32 debug_res_c_req : 1; - RK_U32 debug_res_y_req : 1; - RK_U32 debug_rlc_req : 1; - RK_U32 debug_mv_req : 10; -} Dec_Debug_reg; - -typedef struct { - RK_U32 sw_reserve : 2; - RK_U32 sw_dec_ch8pix_base : 30; -} Dec_BaseAdd_ch8pix_reg; - -typedef struct M2VDRegSet_t { - unsigned long ppReg[50]; - Device_config_reg1 config1; - Dec_control_reg3 stream_buffinfo; - Dec_Error_concealment_reg error_position; - RK_U32 sw_dec_mode; - Device_config_reg2 config2; - Dec_Interrupt_reg interrupt; - Device_config_reg3 config3; - Dec_control_reg0 control; - RK_U32 reserve0[2]; - Dec_BaseAdd_ch8pix_reg ch8pix; - RK_U32 slice_table; - RK_U32 directmv_reg; - RK_U32 cur_pic_base; - RK_U32 VLC_base; - Dec_Refpicbuff_control_reg refbuff_ctl; - RK_U32 reserve1; - Dec_Syn_configinfo_reg syn_cfg; - Dec_Refpicbuff_info3_reg refbuff_info3; - Dec_Refpicbuff_info1_reg refbuff_info1; - Dec_Refpicbuff_info2_reg refbuff_info2; - Dec_Synthesis_config_reg syn_config; - RK_U32 reserve2; - Dec_Debug_reg debug_info; - RK_U32 reserve3[46]; - Dec_control_reg1 pic_params; - RK_U32 reserve4; - Dec_control_reg2 stream_bitinfo; - RK_U32 reserve5[8]; - RK_U32 ref0; - RK_U32 reserve6[2]; - RK_U32 ref2; - RK_U32 ref3; - Dec_BaseAdd_Ref4_reg dec_info; - RK_U32 reserve7[11]; - RK_U32 ref1; - RK_U32 reserve8[10]; - - -} M2VDRegSet; - -typedef struct M2VDHalContext_t { - MppBufSlots packet_slots; - MppBufSlots frame_slots; - RK_S32 vpu_socket; - M2VDRegSet regs; - MppBufferGroup group; - MppBuffer qp_table; - RK_U32 dec_frame_cnt; - FILE *fp_reg_in; - FILE *fp_reg_out; -} M2VDHalContext; - -MPP_RET hal_m2vd_init (void *hal, MppHalCfg *cfg); -MPP_RET hal_m2vd_deinit (void *hal); -MPP_RET hal_m2vd_gen_regs(void *hal, HalTaskInfo *task); -MPP_RET hal_m2vd_start (void *hal, HalTaskInfo *task); -MPP_RET hal_m2vd_wait (void *hal, HalTaskInfo *task); -MPP_RET hal_m2vd_reset (void *hal); -MPP_RET hal_m2vd_flush (void *hal); -MPP_RET hal_m2vd_control (void *hal, RK_S32 cmd_type, void *param); - -#endif +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __HAL_M2VD_REG_H__ +#define __HAL_M2VD_REG_H__ + +#include "m2vd_syntax.h" +#include "hal_task.h" +#include "mpp_hal.h" +#include "mpp_buf_slot.h" +#include + + +extern RK_U32 m2vh_debug; + +#define M2VH_DBG_FUNCTION (0x00000001) +#define M2VH_DBG_REG (0x00000002) +#define M2VH_DBG_DUMP_REG (0x00000004) +#define M2VH_DBG_IRQ (0x00000008) + + + + +#define M2VD_REG_NUM 159 + + +typedef struct { + RK_U32 build_version : 3; + RK_U32 product_IDen : 1; + RK_U32 minor_version : 8; + RK_U32 major_version : 4; + RK_U32 product_numer : 16; +} ID_reg; + +typedef struct { + RK_U32 sw_dec_irq : 1; + RK_U32 sw_dec_irq_dis : 1; + RK_U32 reserve0 : 2; + RK_U32 sw_dec_rdy_int : 1; + RK_U32 sw_dec_bus_int : 1; + RK_U32 sw_dec_buffer_int : 1; + RK_U32 reserve1 : 1; + RK_U32 sw_dec_aso_int : 1; + RK_U32 sw_dec_slice_int : 1; + RK_U32 sw_dec_pic_inf : 1; + RK_U32 reserve2 : 1; + RK_U32 sw_dec_error_int: 1; + RK_U32 sw_dec_timeout : 1; + RK_U32 reserve3 : 18; +} Dec_Interrupt_reg; + + +typedef struct { + RK_U32 sw_dec_out_tiled_e : 1; + RK_U32 sw_dec_latency : 6; + RK_U32 sw_pic_fixed_quant : 1; + RK_U32 sw_filtering_dis : 1; + RK_U32 sw_skip_mode : 1; + RK_U32 sw_dec_scmd_dis : 1; + RK_U32 sw_dec_adv_pre_dis : 1; + RK_U32 sw_priority_mode : 1; //chang + RK_U32 sw_refbu2_thr : 12; + RK_U32 sw_refbu2_picid : 5; + RK_U32 reserve1 : 2; +} Device_config_reg1; + + +typedef struct { + RK_U32 sw_stream_len : 24; + RK_U32 reserve1 : 1; + RK_U32 sw_init_qp : 6; + RK_U32 reserve2 : 1; +} Dec_control_reg3; + + +typedef struct { + RK_U32 sw_dec_in_endian : 1; + RK_U32 sw_dec_out_endian : 1; + RK_U32 sw_dec_inswap32_e : 1; + RK_U32 sw_dec_outswap32_e : 1; + RK_U32 sw_dec_strswap32_e : 1; + RK_U32 sw_dec_strendian_e : 1; + RK_U32 reserve3 : 26; +} Device_config_reg2; + + +typedef struct { + RK_U32 sw_dec_axi_rn_id : 8; + RK_U32 sw_dec_axi_wr_id : 8; + RK_U32 sw_dec_max_burst : 5; + RK_U32 resever : 1; + RK_U32 sw_dec_data_disc_e : 1; + RK_U32 resever1 : 9; +} Device_config_reg3; + +typedef struct { + RK_U32 sw_dec_e : 1; + RK_U32 sw_refbu2_buf_e : 1; + RK_U32 sw_dec_out_dis : 1; + RK_U32 resever : 1; + RK_U32 sw_dec_clk_gate_e : 1; + RK_U32 sw_dec_timeout_e : 1; + RK_U32 sw_picord_count_e : 1; + RK_U32 sw_seq_mbaff_e : 1; + RK_U32 sw_reftopfirst_e : 1; + RK_U32 sw_ref_topfield_e : 1; + RK_U32 sw_write_mvs_e : 1; + RK_U32 sw_sorenson_e : 1; + RK_U32 sw_fwd_interlace_e : 1; + RK_U32 sw_pic_topfield_e : 1 ; + RK_U32 sw_pic_inter_e : 1; + RK_U32 sw_pic_b_e : 1; + RK_U32 sw_pic_fieldmode_e : 1; + RK_U32 sw_pic_interlace_e : 1; + RK_U32 sw_pjpeg_e : 1; + RK_U32 sw_divx3_e : 1; + RK_U32 sw_rlc_mode_e : 1; + RK_U32 sw_ch_8pix_ileav_e : 1; + RK_U32 sw_start_code_e : 1; + RK_U32 resever1 : 8; + RK_U32 sw_dec_ahb_hlock_e : 1; + +} Dec_control_reg0; + +typedef struct { + RK_U32 sw_ref_frames : 5; + RK_U32 sw_topfieldfirst_e : 1; + RK_U32 sw_alt_scan_e : 1; + RK_U32 sw_mb_height_off : 4; + RK_U32 sw_pic_mb_height_p : 8; + RK_U32 sw_mb_width_off : 4; + RK_U32 sw_pic_mb_width : 9; +} Dec_control_reg1; + +typedef struct { + RK_U32 sw_frame_pred_dct : 1; + RK_U32 sw_intra_vlc_tab : 1; + RK_U32 sw_intra_dc_prec : 2; + RK_U32 sw_con_mv_e : 1; + RK_U32 reserve : 19; + RK_U32 sw_qscale_type : 1; + RK_U32 reserve1 : 1; + RK_U32 sw_stream_start_bit : 6; +} Dec_control_reg2; + +typedef struct { + RK_U32 reserve : 1; + RK_U32 sw_mv_accuracy_bwd : 1; + RK_U32 sw_mv_accuracy_fwd : 1; + RK_U32 sw_fcode_bwd_ver : 4; + RK_U32 sw_fcode_bwd_hor : 4; + RK_U32 sw_fcode_fwd_ver : 4; + RK_U32 sw_fcode_fwd_hor : 4; + RK_U32 sw_alt_scan_flag_e : 1; + RK_U32 reserve1 : 12; +} Dec_BaseAdd_Ref4_reg; + + +typedef struct { + RK_U32 sw_startmb_y : 8; + RK_U32 sw_startmb_x : 9; + RK_U32 sw_apf_threshold : 14; + RK_U32 sw_reserve : 1; +} Dec_Error_concealment_reg; + +typedef struct { + RK_U32 sw_dec_max_owidth : 11; + RK_U32 sw_dec_soren_prof : 1; + RK_U32 sw_dec_bus_width : 2; + RK_U32 sw_dec_synth_lan : 2; + RK_U32 sw_dec_bus_strd : 4; + RK_U32 sw_ref_buff_exist : 1; + RK_U32 sw_dec_obuff_leve : 1; + RK_U32 sw_dec_pjpeg_exist : 1; + RK_U32 sw_vp6_prof : 1; + RK_U32 sw_dec_h264_prof : 2; + RK_U32 sw_dec_mpeg4_prof : 2; + RK_U32 sw_dec_jpeg_prof : 1; + RK_U32 sw_dec_vc1_prof : 2; + RK_U32 sw_dec_mpeg2_prof : 1; +} Dec_Synthesis_config_reg; + +typedef struct { + RK_U32 sw_refbu_y_offset : 9; + RK_U32 sw_reserve : 3; + RK_U32 sw_refbu_fparmod_e : 1; + RK_U32 sw_refbu_eval_e : 1; + RK_U32 sw_refbu_picid : 5; + RK_U32 sw_refbu_thr : 12; + RK_U32 sw_refbu_e : 1; +} Dec_Refpicbuff_control_reg; + +typedef struct { + RK_U32 sw_refbu_intra_sum : 16; + RK_U32 sw_refbu_hit_sum : 16; +} Dec_Refpicbuff_info1_reg; + +typedef struct { + RK_U32 sw_refbu_mv_sum : 22; + RK_U32 sw_reserve : 10; +} Dec_Refpicbuff_info2_reg; + +typedef struct { + RK_U32 sw_reserve : 25; + RK_U32 sw_dec_rtl_rom : 1; + RK_U32 sw_dec_rv_prof : 2; + RK_U32 sw_ref_buff2_exist : 1; + RK_U32 sw_dec_divx_prof : 1; + RK_U32 sw_dec_refbu_ilace : 1; + RK_U32 sw_dec_jpeg_exten : 1; +} Dec_Syn_configinfo_reg; + +typedef struct { + RK_U32 sw_refbu_top_sum : 16; + RK_U32 sw_refbu_bot_sum : 16; +} Dec_Refpicbuff_info3_reg; + +typedef struct { + RK_U32 sw_reserve0 : 24; + RK_U32 sw_dec_vc1 : 1; + RK_U32 sw_dec_vp6 : 1; + RK_U32 sw_dec_jpeg : 1; + RK_U32 sw_dec_sorenson : 1; + RK_U32 sw_dec_mpeg2 : 1; + RK_U32 sw_dec_mpeg4 : 1; + RK_U32 sw_dec_h264 : 1; + RK_U32 sw_reserve1 : 2; +} Dec_fuse_reg; + +typedef struct { + RK_U32 debug_dec_mb_count : 13; + RK_U32 debug_referreq1 : 1; + RK_U32 debug_referreq0 : 1; + RK_U32 debug_filter_req : 1; + RK_U32 debug_framerdy : 1; + RK_U32 debug_strm_da_e : 1; + RK_U32 debug_res_c_req : 1; + RK_U32 debug_res_y_req : 1; + RK_U32 debug_rlc_req : 1; + RK_U32 debug_mv_req : 10; +} Dec_Debug_reg; + +typedef struct { + RK_U32 sw_reserve : 2; + RK_U32 sw_dec_ch8pix_base : 30; +} Dec_BaseAdd_ch8pix_reg; + +typedef struct M2VDRegSet_t { + unsigned long ppReg[50]; + Device_config_reg1 config1; + Dec_control_reg3 stream_buffinfo; + Dec_Error_concealment_reg error_position; + RK_U32 sw_dec_mode; + Device_config_reg2 config2; + Dec_Interrupt_reg interrupt; + Device_config_reg3 config3; + Dec_control_reg0 control; + RK_U32 reserve0[2]; + Dec_BaseAdd_ch8pix_reg ch8pix; + RK_U32 slice_table; + RK_U32 directmv_reg; + RK_U32 cur_pic_base; + RK_U32 VLC_base; + Dec_Refpicbuff_control_reg refbuff_ctl; + RK_U32 reserve1; + Dec_Syn_configinfo_reg syn_cfg; + Dec_Refpicbuff_info3_reg refbuff_info3; + Dec_Refpicbuff_info1_reg refbuff_info1; + Dec_Refpicbuff_info2_reg refbuff_info2; + Dec_Synthesis_config_reg syn_config; + RK_U32 reserve2; + Dec_Debug_reg debug_info; + RK_U32 reserve3[46]; + Dec_control_reg1 pic_params; + RK_U32 reserve4; + Dec_control_reg2 stream_bitinfo; + RK_U32 reserve5[8]; + RK_U32 ref0; + RK_U32 reserve6[2]; + RK_U32 ref2; + RK_U32 ref3; + Dec_BaseAdd_Ref4_reg dec_info; + RK_U32 reserve7[11]; + RK_U32 ref1; + RK_U32 reserve8[10]; + + +} M2VDRegSet; + +typedef struct M2VDHalContext_t { + MppBufSlots packet_slots; + MppBufSlots frame_slots; + RK_S32 vpu_socket; + M2VDRegSet regs; + MppBufferGroup group; + MppBuffer qp_table; + RK_U32 dec_frame_cnt; + FILE *fp_reg_in; + FILE *fp_reg_out; +} M2VDHalContext; + +MPP_RET hal_m2vd_init (void *hal, MppHalCfg *cfg); +MPP_RET hal_m2vd_deinit (void *hal); +MPP_RET hal_m2vd_gen_regs(void *hal, HalTaskInfo *task); +MPP_RET hal_m2vd_start (void *hal, HalTaskInfo *task); +MPP_RET hal_m2vd_wait (void *hal, HalTaskInfo *task); +MPP_RET hal_m2vd_reset (void *hal); +MPP_RET hal_m2vd_flush (void *hal); +MPP_RET hal_m2vd_control (void *hal, RK_S32 cmd_type, void *param); + +#endif diff --git a/mpp/hal/vpu/mpg4d/hal_mpg4d_reg.c b/mpp/hal/vpu/mpg4d/hal_mpg4d_reg.c index 2696664d..af203958 100644 --- a/mpp/hal/vpu/mpg4d/hal_mpg4d_reg.c +++ b/mpp/hal/vpu/mpg4d/hal_mpg4d_reg.c @@ -1,543 +1,543 @@ -/* - * - * Copyright 2016 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* -* @file hal_vpu_mpg4d_reg.c -* @brief -* @author gzl(lance.gao@rock-chips.com) - -* @version 1.0.0 -* @history -* 2016.04.11 : Create -*/ - -#define MODULE_TAG "hal_vpu_mpg4d" - -#include -#include - -#include "mpp_log.h" -#include "mpp_err.h" -#include "mpp_mem.h" -#include "mpp_env.h" -#include "mpp_buffer.h" - -#include "vpu.h" -#include "mpp_dec.h" -#include "mpg4d_syntax.h" -#include "hal_mpg4d_api.h" -#include "hal_mpg4d_reg.h" - -#define MPEG4_MAX_MV_BUF_SIZE ((1920/16)*(1088/16)*4*sizeof(RK_U32)) - -typedef struct mpeg4d_reg_context { - MppBufSlots frm_slots; - MppBufSlots pkt_slots; - MppBufferGroup group; - IOInterruptCB int_cb; - - // save fd for curr/ref0/ref1 for reg_gen - RK_S32 vpu_fd; - RK_S32 fd_curr; - RK_S32 fd_ref0; - RK_S32 fd_ref1; - - // mv info buffer - // NOTE: mv buffer fix to 1080p size for convenience - MppBuffer mv_buf; - MppBuffer qp_table; - - VpuMpg4dRegSet_t* regs; -} hal_mpg4_ctx; - -RK_U32 mpg4d_hal_debug = 0; - -static RK_U8 default_intra_matrix[64] = { - 8, 17, 18, 19, 21, 23, 25, 27, - 17, 18, 19, 21, 23, 25, 27, 28, - 20, 21, 22, 23, 24, 26, 28, 30, - 21, 22, 23, 24, 26, 28, 30, 32, - 22, 23, 24, 26, 28, 30, 32, 35, - 23, 24, 26, 28, 30, 32, 35, 38, - 25, 26, 28, 30, 32, 35, 38, 41, - 27, 28, 30, 32, 35, 38, 41, 45 -}; - -static RK_U8 default_inter_matrix[64] = { - 16, 17, 18, 19, 20, 21, 22, 23, - 17, 18, 19, 20, 21, 22, 23, 24, - 18, 19, 20, 21, 22, 23, 24, 25, - 19, 20, 21, 22, 23, 24, 26, 27, - 20, 21, 22, 23, 25, 26, 27, 28, - 21, 22, 23, 24, 26, 27, 28, 30, - 22, 23, 24, 26, 27, 28, 30, 31, - 23, 24, 25, 27, 28, 30, 31, 33 -}; - -static void vpu_mpg4d_get_buffer_by_index(hal_mpg4_ctx *ctx, RK_S32 index, MppBuffer *buffer) -{ - if (index >= 0) { - mpp_buf_slot_get_prop(ctx->frm_slots, index, SLOT_BUFFER, buffer); - mpp_assert(*buffer); - } -} - -static void vpu_mpg4d_setup_regs_by_syntax(hal_mpg4_ctx *ctx, MppSyntax syntax) -{ - VpuMpg4dRegSet_t *regs = ctx->regs; - DXVA2_DecodeBufferDesc **data = syntax.data; - DXVA_PicParams_MPEG4_PART2 *pp = NULL; - DXVA_QmatrixData *qm = NULL; - RK_S32 mv_buf_fd = mpp_buffer_get_fd(ctx->mv_buf); - RK_U32 stream_length = 0; - RK_U32 stream_used = 0; - RK_U32 i; - - for (i = 0; i < syntax.number; i++) { - DXVA2_DecodeBufferDesc *desc = data[i]; - switch (desc->CompressedBufferType) { - case DXVA2_PictureParametersBufferType : { - pp = (DXVA_PicParams_MPEG4_PART2 *)desc->pvPVPState; - } break; - case DXVA2_InverseQuantizationMatrixBufferType : { - qm = (DXVA_QmatrixData *)desc->pvPVPState; - } break; - case DXVA2_BitStreamDateBufferType : { - stream_length = desc->DataSize; - stream_used = desc->DataOffset; - } break; - default : { - mpp_err_f("found invalid buffer descriptor type %d\n", desc->CompressedBufferType); - } break; - } - } - - mpp_assert(pp); - mpp_assert(qm); - mpp_assert(stream_length); - mpp_assert(stream_used); - - // copy qp table to buffer - { - RK_U8 *dst = (RK_U8 *)mpp_buffer_get_ptr(ctx->qp_table); - RK_U8 *src = (qm->bNewQmatrix[0]) ? (qm->Qmatrix[0]) : (default_intra_matrix); - - memcpy(dst, src, 64); - dst += 64; - - src = (qm->bNewQmatrix[1]) ? (qm->Qmatrix[1]) : (default_inter_matrix); - memcpy(dst, src, 64); - } - - regs->reg120.sw_pic_mb_width = (pp->vop_width + 15) >> 4; - regs->reg120.sw_pic_mb_hight_p = (pp->vop_height + 15) >> 4; - if (pp->custorm_version == 4) { - regs->reg120.sw_mb_width_off = pp->vop_width & 0xf; - regs->reg120.sw_mb_height_off = pp->vop_height & 0xf; - } else { - regs->reg120.sw_mb_width_off = 0; - regs->reg120.sw_mb_height_off = 0; - } - regs->reg53_dec_mode = 1; - regs->reg120.sw_alt_scan_e = pp->alternate_vertical_scan_flag; - regs->reg52_error_concealment.sw_startmb_x = 0; - regs->reg52_error_concealment.sw_startmb_y = 0; - regs->reg50_dec_ctrl.sw_filtering_dis = 1; - regs->reg136.sw_rounding = pp->vop_rounding_type; - regs->reg122.sw_intradc_vlc_thr = pp->intra_dc_vlc_thr; - regs->reg51_stream_info.sw_init_qp = pp->vop_quant; - regs->reg122.sw_sync_markers_en = 1; - - { - /* - * update stream base address here according to consumed bit length - * 1. hardware start address has to be 64 bit align - * 2. hardware need to know which is the start bit in - * 2. pass (10bit fd + (offset << 10)) register value to kernel - */ - RK_U32 val = regs->reg64_input_stream_base; - RK_U32 consumed_bytes = stream_used >> 3; - RK_U32 consumed_bytes_align = consumed_bytes & (~0x7); - RK_U32 start_bit_offset = stream_used & 0x3F; - RK_U32 left_bytes = stream_length - consumed_bytes_align; - - val += (consumed_bytes_align << 10); - regs->reg64_input_stream_base = val; - regs->reg122.sw_stream_start_word = start_bit_offset; - regs->reg51_stream_info.sw_stream_len = left_bytes; - } - regs->reg122.sw_vop_time_incr = pp->vop_time_increment_resolution; - - switch (pp->vop_coding_type) { - case MPEG4_B_VOP : { - RK_U32 time_bp = pp->time_bp; - RK_U32 time_pp = pp->time_pp; - - RK_U32 trb_per_trd_d0 = ((((RK_S64)(1 * time_bp + 0)) << 27) + 1 * (time_pp - 1)) / time_pp; - RK_U32 trb_per_trd_d1 = ((((RK_S64)(2 * time_bp + 1)) << 27) + 2 * (time_pp - 0)) / (2 * time_pp + 1); - RK_U32 trb_per_trd_dm1 = ((((RK_S64)(2 * time_bp - 1)) << 27) + 2 * (time_pp - 1)) / (2 * time_pp - 1); - - regs->reg57_enable_ctrl.sw_pic_b_e = 1; - regs->reg57_enable_ctrl.sw_pic_inter_e = 1; - regs->reg136.sw_rounding = 0; - regs->reg131_ref0_base = 1; - - mpp_assert(ctx->fd_ref1 >= 0); - if (ctx->fd_ref1 >= 0) { - regs->reg131_ref0_base = (RK_U32)ctx->fd_ref1; - regs->reg148_ref1_base = (RK_U32)ctx->fd_ref1; - } else { - regs->reg131_ref0_base = (RK_U32)ctx->fd_curr; - regs->reg148_ref1_base = (RK_U32)ctx->fd_curr; - } - - mpp_assert(ctx->fd_ref0 >= 0); - if (ctx->fd_ref0 >= 0) { - regs->reg134_ref2_base = (RK_U32)ctx->fd_ref0; - regs->reg135_ref3_base = (RK_U32)ctx->fd_ref0; - } else { - regs->reg134_ref2_base = (RK_U32)ctx->fd_curr; - regs->reg135_ref3_base = (RK_U32)ctx->fd_curr; - } - - regs->reg136.sw_hrz_bit_of_fwd_mv = pp->vop_fcode_forward; - regs->reg136.sw_vrz_bit_of_fwd_mv = pp->vop_fcode_forward; - regs->reg136.sw_hrz_bit_of_bwd_mv = pp->vop_fcode_backward; - regs->reg136.sw_vrz_bit_of_bwd_mv = pp->vop_fcode_backward; - regs->reg57_enable_ctrl.sw_write_mvs_e = 0; - regs->reg62_directmv_base = mv_buf_fd; - regs->reg137.sw_trb_per_trd_d0 = trb_per_trd_d0; - regs->reg139.sw_trb_per_trd_d1 = trb_per_trd_d1; - regs->reg138.sw_trb_per_trd_dm1 = trb_per_trd_dm1; - } break; - case MPEG4_P_VOP : { - regs->reg57_enable_ctrl.sw_pic_b_e = 0; - regs->reg57_enable_ctrl.sw_pic_inter_e = 1; - - if (ctx->fd_ref0 >= 0) { - regs->reg131_ref0_base = (RK_U32)ctx->fd_ref0; - regs->reg148_ref1_base = (RK_U32)ctx->fd_ref0; - } else { - regs->reg131_ref0_base = (RK_U32)ctx->fd_curr; - regs->reg148_ref1_base = (RK_U32)ctx->fd_curr; - } - regs->reg134_ref2_base = (RK_U32)ctx->fd_curr; - regs->reg135_ref3_base = (RK_U32)ctx->fd_curr; - - regs->reg136.sw_hrz_bit_of_fwd_mv = pp->vop_fcode_forward; - regs->reg136.sw_vrz_bit_of_fwd_mv = pp->vop_fcode_forward; - regs->reg57_enable_ctrl.sw_write_mvs_e = 1; - regs->reg62_directmv_base = mv_buf_fd; - } break; - case MPEG4_I_VOP : { - regs->reg57_enable_ctrl.sw_pic_b_e = 0; - regs->reg57_enable_ctrl.sw_pic_inter_e = 0; - - regs->reg131_ref0_base = (RK_U32)ctx->fd_curr; - regs->reg148_ref1_base = (RK_U32)ctx->fd_curr; - regs->reg134_ref2_base = (RK_U32)ctx->fd_curr; - regs->reg135_ref3_base = (RK_U32)ctx->fd_curr; - - regs->reg57_enable_ctrl.sw_write_mvs_e = 0; - regs->reg62_directmv_base = mv_buf_fd; - - regs->reg136.sw_hrz_bit_of_fwd_mv = 1; - regs->reg136.sw_vrz_bit_of_fwd_mv = 1; - } break; - default : { - /* no nothing */ - } break; - } - - if (pp->interlaced) { - regs->reg57_enable_ctrl.sw_pic_interlace_e = 1; - regs->reg57_enable_ctrl.sw_pic_fieldmode_e = 0; - regs->reg120.sw_topfieldfirst_e = pp->top_field_first; - } - - regs->reg136.sw_prev_pic_type = pp->prev_coding_type; - regs->reg122.sw_quant_type_1_en = pp->quant_type; - regs->reg61_qtable_base = mpp_buffer_get_fd(ctx->qp_table); - regs->reg136.sw_fwd_mv_y_resolution = pp->quarter_sample; - -} - -MPP_RET hal_vpu_mpg4d_init(void *hal, MppHalCfg *cfg) -{ - MPP_RET ret = MPP_OK; - VpuMpg4dRegSet_t *regs = NULL; - MppBufferGroup group = NULL; - MppBuffer mv_buf = NULL; - MppBuffer qp_table = NULL; - hal_mpg4_ctx *ctx = (hal_mpg4_ctx *)hal; - RK_S32 vpu_fd = -1; - - mpp_assert(hal); - - - ret = mpp_buffer_group_get_internal(&group, MPP_BUFFER_TYPE_ION); - if (ret) { - mpp_err_f("failed to get buffer group ret %d\n", ret); - goto ERR_RET; - } - - ret = mpp_buffer_get(group, &mv_buf, MPEG4_MAX_MV_BUF_SIZE); - if (ret) { - mpp_err_f("failed to get mv buffer ret %d\n", ret); - goto ERR_RET; - } - - ret = mpp_buffer_get(group, &qp_table, 64 * 2 * sizeof(RK_U8)); - if (ret) { - mpp_err_f("failed to get qp talbe buffer ret %d\n", ret); - goto ERR_RET; - } - - regs = mpp_calloc(VpuMpg4dRegSet_t, 1); - if (NULL == regs) { - mpp_err_f("failed to malloc register ret\n"); - ret = MPP_ERR_MALLOC; - goto ERR_RET; - } - -#ifdef RKPLATFORM - vpu_fd = VPUClientInit(VPU_DEC); - if (vpu_fd < 0) { - mpp_err_f("failed to open vpu client\n"); - ret = MPP_ERR_UNKNOW; - goto ERR_RET; - } -#endif - - /* - * basic register configuration setup here - */ - regs->reg54_endian.sw_dec_out_endian = 1; - regs->reg54_endian.sw_dec_in_endian = 1; - regs->reg54_endian.sw_dec_inswap32_e = 1; - regs->reg54_endian.sw_dec_outswap32_e = 1; - regs->reg54_endian.sw_dec_strswap32_e = 1; - regs->reg54_endian.sw_dec_strendian_e = 1; - regs->reg56_axi_ctrl.sw_dec_max_burst = 16; - regs->reg52_error_concealment.sw_apf_threshold = 1; - regs->reg57_enable_ctrl.sw_dec_timeout_e = 1; - regs->reg57_enable_ctrl.sw_dec_clk_gate_e = 1; - regs->reg57_enable_ctrl.sw_dec_e = 1; - regs->reg59.sw_pred_bc_tap_0_0 = -1; - regs->reg59.sw_pred_bc_tap_0_1 = 3; - regs->reg59.sw_pred_bc_tap_0_2 = -6; - regs->reg153.sw_pred_bc_tap_0_3 = 20; - - ctx->frm_slots = cfg->frame_slots; - ctx->pkt_slots = cfg->packet_slots; - ctx->int_cb = cfg->hal_int_cb; - ctx->group = group; - ctx->vpu_fd = vpu_fd; - ctx->mv_buf = mv_buf; - ctx->qp_table = qp_table; - ctx->regs = regs; - - mpp_env_get_u32("mpg4d_hal_debug", &mpg4d_hal_debug, 0); - - return ret; -ERR_RET: - if (regs) { - mpp_free(regs); - regs = NULL; - } - - if (qp_table) { - mpp_buffer_put(qp_table); - qp_table = NULL; - } - - if (mv_buf) { - mpp_buffer_put(mv_buf); - mv_buf = NULL; - } - - if (group) { - mpp_buffer_group_put(group); - group = NULL; - } - - return ret; -} - -MPP_RET hal_vpu_mpg4d_deinit(void *hal) -{ - MPP_RET ret = MPP_OK; - hal_mpg4_ctx *ctx = (hal_mpg4_ctx *)hal; - - mpp_assert(hal); - - if (ctx->regs) { - mpp_free(ctx->regs); - ctx->regs = NULL; - } - - if (ctx->qp_table) { - mpp_buffer_put(ctx->qp_table); - ctx->qp_table = NULL; - } - - if (ctx->mv_buf) { - mpp_buffer_put(ctx->mv_buf); - ctx->mv_buf = NULL; - } - - if (ctx->group) { - mpp_buffer_group_put(ctx->group); - ctx->group = NULL; - } - -#ifdef RKPLATFORM - if (ctx->vpu_fd >= 0) { - VPUClientRelease(ctx->vpu_fd); - ctx->vpu_fd = -1; - } -#endif - - return ret; -} - -MPP_RET hal_vpu_mpg4d_gen_regs(void *hal, HalTaskInfo *syn) -{ - MPP_RET ret = MPP_OK; - hal_mpg4_ctx *ctx = (hal_mpg4_ctx *)hal; - HalDecTask *task = &syn->dec; - MppBuffer buf_frm_curr = NULL; - MppBuffer buf_frm_ref0 = NULL; - MppBuffer buf_frm_ref1 = NULL; - MppBuffer buf_pkt = NULL; - VpuMpg4dRegSet_t *regs = ctx->regs; - - mpp_assert(task->valid); - mpp_assert(task->input >= 0); - mpp_assert(task->output >= 0); - - /* setup buffer for input / output / reference */ - mpp_buf_slot_get_prop(ctx->pkt_slots, task->input, SLOT_BUFFER, &buf_pkt); - mpp_assert(buf_pkt); - vpu_mpg4d_get_buffer_by_index(ctx, task->output, &buf_frm_curr); - vpu_mpg4d_get_buffer_by_index(ctx, task->refer[0], &buf_frm_ref0); - vpu_mpg4d_get_buffer_by_index(ctx, task->refer[1], &buf_frm_ref1); - - /* address registers setup first */ - ctx->fd_curr = mpp_buffer_get_fd(buf_frm_curr); - ctx->fd_ref0 = (buf_frm_ref0) ? (mpp_buffer_get_fd(buf_frm_ref0)) : (-1); - ctx->fd_ref1 = (buf_frm_ref1) ? (mpp_buffer_get_fd(buf_frm_ref1)) : (-1); - regs->reg63_cur_pic_base = (RK_U32)ctx->fd_curr; - regs->reg64_input_stream_base = mpp_buffer_get_fd(buf_pkt); - - /* setup other registers, here will update packet address */ - vpu_mpg4d_setup_regs_by_syntax(ctx, task->syntax); - - return ret; -} - -MPP_RET hal_vpu_mpg4d_start(void *hal, HalTaskInfo *task) -{ - MPP_RET ret = MPP_OK; - hal_mpg4_ctx *ctx = (hal_mpg4_ctx *)hal; - -#ifdef RKPLATFORM - RK_U32 reg_count = (sizeof(*ctx->regs) / sizeof(RK_U32)); - RK_U32* regs = (RK_U32 *)ctx->regs; - - if (mpg4d_hal_debug & MPG4D_HAL_DBG_REG_PUT) { - RK_U32 i = 0; - for (i = 0; i < reg_count; i++) { - mpp_log("reg[%03d]: %08x\n", i, regs[i]); - } - } - - ret = VPUClientSendReg(ctx->vpu_fd, regs, reg_count); -#endif - (void)ret; - (void)task; - return ret; -} - -MPP_RET hal_vpu_mpg4d_wait(void *hal, HalTaskInfo *task) -{ - MPP_RET ret = MPP_OK; - hal_mpg4_ctx *ctx = (hal_mpg4_ctx *)hal; -#ifdef RKPLATFORM - VpuMpg4dRegSet_t reg_out; - RK_U32* regs = (RK_U32 *)®_out; - RK_U32 reg_count = (sizeof(reg_out) / sizeof(RK_U32)); - VPU_CMD_TYPE cmd = 0; - RK_S32 length = 0; - - ret = VPUClientWaitResult(ctx->vpu_fd, regs, (sizeof(reg_out) / sizeof(RK_U32)), - &cmd, &length); - - if (mpg4d_hal_debug & MPG4D_HAL_DBG_REG_GET) { - RK_U32 i = 0; - - for (i = 0; i < reg_count; i++) { - mpp_log("reg[%03d]: %08x\n", i, regs[i]); - } - } -#endif - (void)ret; - (void)task; - return ret; -} - -MPP_RET hal_vpu_mpg4d_reset(void *hal) -{ - MPP_RET ret = MPP_OK; - (void)hal; - return ret; -} - -MPP_RET hal_vpu_mpg4d_flush(void *hal) -{ - MPP_RET ret = MPP_OK; - - (void)hal; - return ret; -} - -MPP_RET hal_vpu_mpg4d_control(void *hal, RK_S32 cmd_type, void *param) -{ - MPP_RET ret = MPP_OK; - - (void)hal; - (void)cmd_type; - (void)param; - return ret; -} - -const MppHalApi hal_api_mpg4d = { - "mpg4d_vpu", - MPP_CTX_DEC, - MPP_VIDEO_CodingMPEG4, - sizeof(hal_mpg4_ctx), - 0, - hal_vpu_mpg4d_init, - hal_vpu_mpg4d_deinit, - hal_vpu_mpg4d_gen_regs, - hal_vpu_mpg4d_start, - hal_vpu_mpg4d_wait, - hal_vpu_mpg4d_reset, - hal_vpu_mpg4d_flush, - hal_vpu_mpg4d_control, -}; - +/* + * + * Copyright 2016 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* +* @file hal_vpu_mpg4d_reg.c +* @brief +* @author gzl(lance.gao@rock-chips.com) + +* @version 1.0.0 +* @history +* 2016.04.11 : Create +*/ + +#define MODULE_TAG "hal_vpu_mpg4d" + +#include +#include + +#include "mpp_log.h" +#include "mpp_err.h" +#include "mpp_mem.h" +#include "mpp_env.h" +#include "mpp_buffer.h" + +#include "vpu.h" +#include "mpp_dec.h" +#include "mpg4d_syntax.h" +#include "hal_mpg4d_api.h" +#include "hal_mpg4d_reg.h" + +#define MPEG4_MAX_MV_BUF_SIZE ((1920/16)*(1088/16)*4*sizeof(RK_U32)) + +typedef struct mpeg4d_reg_context { + MppBufSlots frm_slots; + MppBufSlots pkt_slots; + MppBufferGroup group; + IOInterruptCB int_cb; + + // save fd for curr/ref0/ref1 for reg_gen + RK_S32 vpu_fd; + RK_S32 fd_curr; + RK_S32 fd_ref0; + RK_S32 fd_ref1; + + // mv info buffer + // NOTE: mv buffer fix to 1080p size for convenience + MppBuffer mv_buf; + MppBuffer qp_table; + + VpuMpg4dRegSet_t* regs; +} hal_mpg4_ctx; + +RK_U32 mpg4d_hal_debug = 0; + +static RK_U8 default_intra_matrix[64] = { + 8, 17, 18, 19, 21, 23, 25, 27, + 17, 18, 19, 21, 23, 25, 27, 28, + 20, 21, 22, 23, 24, 26, 28, 30, + 21, 22, 23, 24, 26, 28, 30, 32, + 22, 23, 24, 26, 28, 30, 32, 35, + 23, 24, 26, 28, 30, 32, 35, 38, + 25, 26, 28, 30, 32, 35, 38, 41, + 27, 28, 30, 32, 35, 38, 41, 45 +}; + +static RK_U8 default_inter_matrix[64] = { + 16, 17, 18, 19, 20, 21, 22, 23, + 17, 18, 19, 20, 21, 22, 23, 24, + 18, 19, 20, 21, 22, 23, 24, 25, + 19, 20, 21, 22, 23, 24, 26, 27, + 20, 21, 22, 23, 25, 26, 27, 28, + 21, 22, 23, 24, 26, 27, 28, 30, + 22, 23, 24, 26, 27, 28, 30, 31, + 23, 24, 25, 27, 28, 30, 31, 33 +}; + +static void vpu_mpg4d_get_buffer_by_index(hal_mpg4_ctx *ctx, RK_S32 index, MppBuffer *buffer) +{ + if (index >= 0) { + mpp_buf_slot_get_prop(ctx->frm_slots, index, SLOT_BUFFER, buffer); + mpp_assert(*buffer); + } +} + +static void vpu_mpg4d_setup_regs_by_syntax(hal_mpg4_ctx *ctx, MppSyntax syntax) +{ + VpuMpg4dRegSet_t *regs = ctx->regs; + DXVA2_DecodeBufferDesc **data = syntax.data; + DXVA_PicParams_MPEG4_PART2 *pp = NULL; + DXVA_QmatrixData *qm = NULL; + RK_S32 mv_buf_fd = mpp_buffer_get_fd(ctx->mv_buf); + RK_U32 stream_length = 0; + RK_U32 stream_used = 0; + RK_U32 i; + + for (i = 0; i < syntax.number; i++) { + DXVA2_DecodeBufferDesc *desc = data[i]; + switch (desc->CompressedBufferType) { + case DXVA2_PictureParametersBufferType : { + pp = (DXVA_PicParams_MPEG4_PART2 *)desc->pvPVPState; + } break; + case DXVA2_InverseQuantizationMatrixBufferType : { + qm = (DXVA_QmatrixData *)desc->pvPVPState; + } break; + case DXVA2_BitStreamDateBufferType : { + stream_length = desc->DataSize; + stream_used = desc->DataOffset; + } break; + default : { + mpp_err_f("found invalid buffer descriptor type %d\n", desc->CompressedBufferType); + } break; + } + } + + mpp_assert(pp); + mpp_assert(qm); + mpp_assert(stream_length); + mpp_assert(stream_used); + + // copy qp table to buffer + { + RK_U8 *dst = (RK_U8 *)mpp_buffer_get_ptr(ctx->qp_table); + RK_U8 *src = (qm->bNewQmatrix[0]) ? (qm->Qmatrix[0]) : (default_intra_matrix); + + memcpy(dst, src, 64); + dst += 64; + + src = (qm->bNewQmatrix[1]) ? (qm->Qmatrix[1]) : (default_inter_matrix); + memcpy(dst, src, 64); + } + + regs->reg120.sw_pic_mb_width = (pp->vop_width + 15) >> 4; + regs->reg120.sw_pic_mb_hight_p = (pp->vop_height + 15) >> 4; + if (pp->custorm_version == 4) { + regs->reg120.sw_mb_width_off = pp->vop_width & 0xf; + regs->reg120.sw_mb_height_off = pp->vop_height & 0xf; + } else { + regs->reg120.sw_mb_width_off = 0; + regs->reg120.sw_mb_height_off = 0; + } + regs->reg53_dec_mode = 1; + regs->reg120.sw_alt_scan_e = pp->alternate_vertical_scan_flag; + regs->reg52_error_concealment.sw_startmb_x = 0; + regs->reg52_error_concealment.sw_startmb_y = 0; + regs->reg50_dec_ctrl.sw_filtering_dis = 1; + regs->reg136.sw_rounding = pp->vop_rounding_type; + regs->reg122.sw_intradc_vlc_thr = pp->intra_dc_vlc_thr; + regs->reg51_stream_info.sw_init_qp = pp->vop_quant; + regs->reg122.sw_sync_markers_en = 1; + + { + /* + * update stream base address here according to consumed bit length + * 1. hardware start address has to be 64 bit align + * 2. hardware need to know which is the start bit in + * 2. pass (10bit fd + (offset << 10)) register value to kernel + */ + RK_U32 val = regs->reg64_input_stream_base; + RK_U32 consumed_bytes = stream_used >> 3; + RK_U32 consumed_bytes_align = consumed_bytes & (~0x7); + RK_U32 start_bit_offset = stream_used & 0x3F; + RK_U32 left_bytes = stream_length - consumed_bytes_align; + + val += (consumed_bytes_align << 10); + regs->reg64_input_stream_base = val; + regs->reg122.sw_stream_start_word = start_bit_offset; + regs->reg51_stream_info.sw_stream_len = left_bytes; + } + regs->reg122.sw_vop_time_incr = pp->vop_time_increment_resolution; + + switch (pp->vop_coding_type) { + case MPEG4_B_VOP : { + RK_U32 time_bp = pp->time_bp; + RK_U32 time_pp = pp->time_pp; + + RK_U32 trb_per_trd_d0 = ((((RK_S64)(1 * time_bp + 0)) << 27) + 1 * (time_pp - 1)) / time_pp; + RK_U32 trb_per_trd_d1 = ((((RK_S64)(2 * time_bp + 1)) << 27) + 2 * (time_pp - 0)) / (2 * time_pp + 1); + RK_U32 trb_per_trd_dm1 = ((((RK_S64)(2 * time_bp - 1)) << 27) + 2 * (time_pp - 1)) / (2 * time_pp - 1); + + regs->reg57_enable_ctrl.sw_pic_b_e = 1; + regs->reg57_enable_ctrl.sw_pic_inter_e = 1; + regs->reg136.sw_rounding = 0; + regs->reg131_ref0_base = 1; + + mpp_assert(ctx->fd_ref1 >= 0); + if (ctx->fd_ref1 >= 0) { + regs->reg131_ref0_base = (RK_U32)ctx->fd_ref1; + regs->reg148_ref1_base = (RK_U32)ctx->fd_ref1; + } else { + regs->reg131_ref0_base = (RK_U32)ctx->fd_curr; + regs->reg148_ref1_base = (RK_U32)ctx->fd_curr; + } + + mpp_assert(ctx->fd_ref0 >= 0); + if (ctx->fd_ref0 >= 0) { + regs->reg134_ref2_base = (RK_U32)ctx->fd_ref0; + regs->reg135_ref3_base = (RK_U32)ctx->fd_ref0; + } else { + regs->reg134_ref2_base = (RK_U32)ctx->fd_curr; + regs->reg135_ref3_base = (RK_U32)ctx->fd_curr; + } + + regs->reg136.sw_hrz_bit_of_fwd_mv = pp->vop_fcode_forward; + regs->reg136.sw_vrz_bit_of_fwd_mv = pp->vop_fcode_forward; + regs->reg136.sw_hrz_bit_of_bwd_mv = pp->vop_fcode_backward; + regs->reg136.sw_vrz_bit_of_bwd_mv = pp->vop_fcode_backward; + regs->reg57_enable_ctrl.sw_write_mvs_e = 0; + regs->reg62_directmv_base = mv_buf_fd; + regs->reg137.sw_trb_per_trd_d0 = trb_per_trd_d0; + regs->reg139.sw_trb_per_trd_d1 = trb_per_trd_d1; + regs->reg138.sw_trb_per_trd_dm1 = trb_per_trd_dm1; + } break; + case MPEG4_P_VOP : { + regs->reg57_enable_ctrl.sw_pic_b_e = 0; + regs->reg57_enable_ctrl.sw_pic_inter_e = 1; + + if (ctx->fd_ref0 >= 0) { + regs->reg131_ref0_base = (RK_U32)ctx->fd_ref0; + regs->reg148_ref1_base = (RK_U32)ctx->fd_ref0; + } else { + regs->reg131_ref0_base = (RK_U32)ctx->fd_curr; + regs->reg148_ref1_base = (RK_U32)ctx->fd_curr; + } + regs->reg134_ref2_base = (RK_U32)ctx->fd_curr; + regs->reg135_ref3_base = (RK_U32)ctx->fd_curr; + + regs->reg136.sw_hrz_bit_of_fwd_mv = pp->vop_fcode_forward; + regs->reg136.sw_vrz_bit_of_fwd_mv = pp->vop_fcode_forward; + regs->reg57_enable_ctrl.sw_write_mvs_e = 1; + regs->reg62_directmv_base = mv_buf_fd; + } break; + case MPEG4_I_VOP : { + regs->reg57_enable_ctrl.sw_pic_b_e = 0; + regs->reg57_enable_ctrl.sw_pic_inter_e = 0; + + regs->reg131_ref0_base = (RK_U32)ctx->fd_curr; + regs->reg148_ref1_base = (RK_U32)ctx->fd_curr; + regs->reg134_ref2_base = (RK_U32)ctx->fd_curr; + regs->reg135_ref3_base = (RK_U32)ctx->fd_curr; + + regs->reg57_enable_ctrl.sw_write_mvs_e = 0; + regs->reg62_directmv_base = mv_buf_fd; + + regs->reg136.sw_hrz_bit_of_fwd_mv = 1; + regs->reg136.sw_vrz_bit_of_fwd_mv = 1; + } break; + default : { + /* no nothing */ + } break; + } + + if (pp->interlaced) { + regs->reg57_enable_ctrl.sw_pic_interlace_e = 1; + regs->reg57_enable_ctrl.sw_pic_fieldmode_e = 0; + regs->reg120.sw_topfieldfirst_e = pp->top_field_first; + } + + regs->reg136.sw_prev_pic_type = pp->prev_coding_type; + regs->reg122.sw_quant_type_1_en = pp->quant_type; + regs->reg61_qtable_base = mpp_buffer_get_fd(ctx->qp_table); + regs->reg136.sw_fwd_mv_y_resolution = pp->quarter_sample; + +} + +MPP_RET hal_vpu_mpg4d_init(void *hal, MppHalCfg *cfg) +{ + MPP_RET ret = MPP_OK; + VpuMpg4dRegSet_t *regs = NULL; + MppBufferGroup group = NULL; + MppBuffer mv_buf = NULL; + MppBuffer qp_table = NULL; + hal_mpg4_ctx *ctx = (hal_mpg4_ctx *)hal; + RK_S32 vpu_fd = -1; + + mpp_assert(hal); + + + ret = mpp_buffer_group_get_internal(&group, MPP_BUFFER_TYPE_ION); + if (ret) { + mpp_err_f("failed to get buffer group ret %d\n", ret); + goto ERR_RET; + } + + ret = mpp_buffer_get(group, &mv_buf, MPEG4_MAX_MV_BUF_SIZE); + if (ret) { + mpp_err_f("failed to get mv buffer ret %d\n", ret); + goto ERR_RET; + } + + ret = mpp_buffer_get(group, &qp_table, 64 * 2 * sizeof(RK_U8)); + if (ret) { + mpp_err_f("failed to get qp talbe buffer ret %d\n", ret); + goto ERR_RET; + } + + regs = mpp_calloc(VpuMpg4dRegSet_t, 1); + if (NULL == regs) { + mpp_err_f("failed to malloc register ret\n"); + ret = MPP_ERR_MALLOC; + goto ERR_RET; + } + +#ifdef RKPLATFORM + vpu_fd = VPUClientInit(VPU_DEC); + if (vpu_fd < 0) { + mpp_err_f("failed to open vpu client\n"); + ret = MPP_ERR_UNKNOW; + goto ERR_RET; + } +#endif + + /* + * basic register configuration setup here + */ + regs->reg54_endian.sw_dec_out_endian = 1; + regs->reg54_endian.sw_dec_in_endian = 1; + regs->reg54_endian.sw_dec_inswap32_e = 1; + regs->reg54_endian.sw_dec_outswap32_e = 1; + regs->reg54_endian.sw_dec_strswap32_e = 1; + regs->reg54_endian.sw_dec_strendian_e = 1; + regs->reg56_axi_ctrl.sw_dec_max_burst = 16; + regs->reg52_error_concealment.sw_apf_threshold = 1; + regs->reg57_enable_ctrl.sw_dec_timeout_e = 1; + regs->reg57_enable_ctrl.sw_dec_clk_gate_e = 1; + regs->reg57_enable_ctrl.sw_dec_e = 1; + regs->reg59.sw_pred_bc_tap_0_0 = -1; + regs->reg59.sw_pred_bc_tap_0_1 = 3; + regs->reg59.sw_pred_bc_tap_0_2 = -6; + regs->reg153.sw_pred_bc_tap_0_3 = 20; + + ctx->frm_slots = cfg->frame_slots; + ctx->pkt_slots = cfg->packet_slots; + ctx->int_cb = cfg->hal_int_cb; + ctx->group = group; + ctx->vpu_fd = vpu_fd; + ctx->mv_buf = mv_buf; + ctx->qp_table = qp_table; + ctx->regs = regs; + + mpp_env_get_u32("mpg4d_hal_debug", &mpg4d_hal_debug, 0); + + return ret; +ERR_RET: + if (regs) { + mpp_free(regs); + regs = NULL; + } + + if (qp_table) { + mpp_buffer_put(qp_table); + qp_table = NULL; + } + + if (mv_buf) { + mpp_buffer_put(mv_buf); + mv_buf = NULL; + } + + if (group) { + mpp_buffer_group_put(group); + group = NULL; + } + + return ret; +} + +MPP_RET hal_vpu_mpg4d_deinit(void *hal) +{ + MPP_RET ret = MPP_OK; + hal_mpg4_ctx *ctx = (hal_mpg4_ctx *)hal; + + mpp_assert(hal); + + if (ctx->regs) { + mpp_free(ctx->regs); + ctx->regs = NULL; + } + + if (ctx->qp_table) { + mpp_buffer_put(ctx->qp_table); + ctx->qp_table = NULL; + } + + if (ctx->mv_buf) { + mpp_buffer_put(ctx->mv_buf); + ctx->mv_buf = NULL; + } + + if (ctx->group) { + mpp_buffer_group_put(ctx->group); + ctx->group = NULL; + } + +#ifdef RKPLATFORM + if (ctx->vpu_fd >= 0) { + VPUClientRelease(ctx->vpu_fd); + ctx->vpu_fd = -1; + } +#endif + + return ret; +} + +MPP_RET hal_vpu_mpg4d_gen_regs(void *hal, HalTaskInfo *syn) +{ + MPP_RET ret = MPP_OK; + hal_mpg4_ctx *ctx = (hal_mpg4_ctx *)hal; + HalDecTask *task = &syn->dec; + MppBuffer buf_frm_curr = NULL; + MppBuffer buf_frm_ref0 = NULL; + MppBuffer buf_frm_ref1 = NULL; + MppBuffer buf_pkt = NULL; + VpuMpg4dRegSet_t *regs = ctx->regs; + + mpp_assert(task->valid); + mpp_assert(task->input >= 0); + mpp_assert(task->output >= 0); + + /* setup buffer for input / output / reference */ + mpp_buf_slot_get_prop(ctx->pkt_slots, task->input, SLOT_BUFFER, &buf_pkt); + mpp_assert(buf_pkt); + vpu_mpg4d_get_buffer_by_index(ctx, task->output, &buf_frm_curr); + vpu_mpg4d_get_buffer_by_index(ctx, task->refer[0], &buf_frm_ref0); + vpu_mpg4d_get_buffer_by_index(ctx, task->refer[1], &buf_frm_ref1); + + /* address registers setup first */ + ctx->fd_curr = mpp_buffer_get_fd(buf_frm_curr); + ctx->fd_ref0 = (buf_frm_ref0) ? (mpp_buffer_get_fd(buf_frm_ref0)) : (-1); + ctx->fd_ref1 = (buf_frm_ref1) ? (mpp_buffer_get_fd(buf_frm_ref1)) : (-1); + regs->reg63_cur_pic_base = (RK_U32)ctx->fd_curr; + regs->reg64_input_stream_base = mpp_buffer_get_fd(buf_pkt); + + /* setup other registers, here will update packet address */ + vpu_mpg4d_setup_regs_by_syntax(ctx, task->syntax); + + return ret; +} + +MPP_RET hal_vpu_mpg4d_start(void *hal, HalTaskInfo *task) +{ + MPP_RET ret = MPP_OK; + hal_mpg4_ctx *ctx = (hal_mpg4_ctx *)hal; + +#ifdef RKPLATFORM + RK_U32 reg_count = (sizeof(*ctx->regs) / sizeof(RK_U32)); + RK_U32* regs = (RK_U32 *)ctx->regs; + + if (mpg4d_hal_debug & MPG4D_HAL_DBG_REG_PUT) { + RK_U32 i = 0; + for (i = 0; i < reg_count; i++) { + mpp_log("reg[%03d]: %08x\n", i, regs[i]); + } + } + + ret = VPUClientSendReg(ctx->vpu_fd, regs, reg_count); +#endif + (void)ret; + (void)task; + return ret; +} + +MPP_RET hal_vpu_mpg4d_wait(void *hal, HalTaskInfo *task) +{ + MPP_RET ret = MPP_OK; + hal_mpg4_ctx *ctx = (hal_mpg4_ctx *)hal; +#ifdef RKPLATFORM + VpuMpg4dRegSet_t reg_out; + RK_U32* regs = (RK_U32 *)®_out; + RK_U32 reg_count = (sizeof(reg_out) / sizeof(RK_U32)); + VPU_CMD_TYPE cmd = 0; + RK_S32 length = 0; + + ret = VPUClientWaitResult(ctx->vpu_fd, regs, (sizeof(reg_out) / sizeof(RK_U32)), + &cmd, &length); + + if (mpg4d_hal_debug & MPG4D_HAL_DBG_REG_GET) { + RK_U32 i = 0; + + for (i = 0; i < reg_count; i++) { + mpp_log("reg[%03d]: %08x\n", i, regs[i]); + } + } +#endif + (void)ret; + (void)task; + return ret; +} + +MPP_RET hal_vpu_mpg4d_reset(void *hal) +{ + MPP_RET ret = MPP_OK; + (void)hal; + return ret; +} + +MPP_RET hal_vpu_mpg4d_flush(void *hal) +{ + MPP_RET ret = MPP_OK; + + (void)hal; + return ret; +} + +MPP_RET hal_vpu_mpg4d_control(void *hal, RK_S32 cmd_type, void *param) +{ + MPP_RET ret = MPP_OK; + + (void)hal; + (void)cmd_type; + (void)param; + return ret; +} + +const MppHalApi hal_api_mpg4d = { + "mpg4d_vpu", + MPP_CTX_DEC, + MPP_VIDEO_CodingMPEG4, + sizeof(hal_mpg4_ctx), + 0, + hal_vpu_mpg4d_init, + hal_vpu_mpg4d_deinit, + hal_vpu_mpg4d_gen_regs, + hal_vpu_mpg4d_start, + hal_vpu_mpg4d_wait, + hal_vpu_mpg4d_reset, + hal_vpu_mpg4d_flush, + hal_vpu_mpg4d_control, +}; + diff --git a/mpp/hal/vpu/mpg4d/hal_mpg4d_reg.h b/mpp/hal/vpu/mpg4d/hal_mpg4d_reg.h index 30919d39..2057fd56 100644 --- a/mpp/hal/vpu/mpg4d/hal_mpg4d_reg.h +++ b/mpp/hal/vpu/mpg4d/hal_mpg4d_reg.h @@ -1,398 +1,398 @@ -/* - * Copyright 2016 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __HAL_MPG4D_REG_H__ -#define __HAL_MPG4D_REG_H__ - -#include "rk_type.h" - -typedef struct { - RK_U32 reg00_49[50]; - - struct { - RK_U32 sw_dec_out_tiled_e : 1; - RK_U32 sw_dec_latency : 6; - RK_U32 sw_pic_fixed_quant : 1; - RK_U32 sw_filtering_dis : 1; - RK_U32 sw_divx_enable : 1; - RK_U32 sw_dec_scmd_dis : 1; - RK_U32 sw_dec_adv_pre_dis : 1; - RK_U32 sw_priority_mode : 1; - RK_U32 sw_refbu2_thr : 12; - RK_U32 sw_refbu2_picid : 5; - RK_U32 reserve1 : 2; - } reg50_dec_ctrl; - - struct { - RK_U32 sw_stream_len : 24; - RK_U32 reserve1 : 1; - RK_U32 sw_init_qp : 6; - RK_U32 reserve2 : 1; - } reg51_stream_info; - - struct { - RK_U32 sw_startmb_y : 8; - RK_U32 sw_startmb_x : 9; - RK_U32 sw_apf_threshold : 14; - RK_U32 sw_reserve : 1; - } reg52_error_concealment; - - RK_U32 reg53_dec_mode; - - struct { - RK_U32 sw_dec_in_endian : 1; - RK_U32 sw_dec_out_endian : 1; - RK_U32 sw_dec_inswap32_e : 1; - RK_U32 sw_dec_outswap32_e : 1; - RK_U32 sw_dec_strswap32_e : 1; - RK_U32 sw_dec_strendian_e : 1; - RK_U32 reserve3 : 26; - } reg54_endian; - - struct { - RK_U32 sw_dec_irq : 1; - RK_U32 sw_dec_irq_dis : 1; - RK_U32 reserve0 : 2; - RK_U32 sw_dec_rdy_int : 1; - RK_U32 sw_dec_bus_int : 1; - RK_U32 sw_dec_buf_empty_int: 1; - RK_U32 reserve1 : 1; - RK_U32 sw_dec_aso_int : 1; - RK_U32 sw_dec_slice_int : 1; - RK_U32 sw_dec_b_pic_inf : 1; - RK_U32 reserve2 : 1; - RK_U32 sw_dec_error_int : 1; - RK_U32 sw_dec_timeout : 1; - RK_U32 reserve3 : 18; - } reg55_Interrupt; - - struct { - RK_U32 sw_dec_axi_rn_id : 8; - RK_U32 sw_dec_axi_wr_id : 8; - RK_U32 sw_dec_max_burst : 5; - RK_U32 reserve0 : 1; - RK_U32 sw_dec_data_disc_e : 1; - RK_U32 reserve1 : 9; - } reg56_axi_ctrl; - - struct { - RK_U32 sw_dec_e : 1; - RK_U32 sw_refbu2_buf_e : 1; - RK_U32 sw_dec_out_dis : 1; - RK_U32 reserve : 1; - RK_U32 sw_dec_clk_gate_e : 1; - RK_U32 sw_dec_timeout_e : 1; - RK_U32 sw_picord_count_e : 1; - RK_U32 sw_seq_mbaff_e : 1; - RK_U32 sw_reftopfirst_e : 1; - RK_U32 sw_ref_topfield_e : 1; - RK_U32 sw_write_mvs_e : 1; - RK_U32 sw_sorenson_e : 1; - RK_U32 sw_fwd_interlace_e : 1; - RK_U32 sw_pic_topfield_e : 1; - RK_U32 sw_pic_inter_e : 1; - RK_U32 sw_pic_b_e : 1; - RK_U32 sw_pic_fieldmode_e : 1; - RK_U32 sw_pic_interlace_e : 1; - RK_U32 sw_pjpeg_e : 1; - RK_U32 sw_divx3_e : 1; - RK_U32 sw_rlc_mode_e : 1; - RK_U32 sw_ch_8pix_ileav_e : 1; - RK_U32 sw_start_code_e : 1; - RK_U32 reserve1 : 8; - RK_U32 sw_dec_ahb_hlock_e : 1; - } reg57_enable_ctrl; - - struct { - RK_U32 sw_soft_rst : 1; - RK_U32 reverse0 : 31; - } reg58; - - struct { - RK_U32 reserve : 2; - RK_U32 sw_pred_bc_tap_0_2 : 10; - RK_U32 sw_pred_bc_tap_0_1 : 10; - RK_U32 sw_pred_bc_tap_0_0 : 10; - } reg59; - - RK_U32 reg60_addit_ch_st_base; - RK_U32 reg61_qtable_base; - RK_U32 reg62_directmv_base; - RK_U32 reg63_cur_pic_base; - RK_U32 reg64_input_stream_base; - - struct { - RK_U32 sw_refbu_y_offset : 9; - RK_U32 sw_reserve : 3; - RK_U32 sw_refbu_fparmod_e : 1; - RK_U32 sw_refbu_eval_e : 1; - RK_U32 sw_refbu_picid : 5; - RK_U32 sw_refbu_thr : 12; - RK_U32 sw_refbu_e : 1; - } reg65_refpicbuf_ctrl; - - struct { - RK_U32 build_version : 3; - RK_U32 product_IDen : 1; - RK_U32 minor_version : 8; - RK_U32 major_version : 4; - RK_U32 product_numer : 16; - } reg66_id; - - struct { - RK_U32 sw_reserve : 25; - RK_U32 sw_dec_rtl_rom : 1; - RK_U32 sw_dec_rv_prof : 2; - RK_U32 sw_ref_buff2_exist : 1; - RK_U32 sw_dec_divx_prof : 1; - RK_U32 sw_dec_refbu_ilace : 1; - RK_U32 sw_dec_jpeg_exten : 1; - } reg67_synthesis_cfg; - - struct { - RK_U32 sw_refbu_top_sum : 16; - RK_U32 sw_refbu_bot_sum : 16; - } reg68_sum_of_partitions; - - struct { - RK_U32 sw_refbu_intra_sum : 16; - RK_U32 sw_refbu_hit_sum : 16; - } reg69_sum_inf; - - struct { - RK_U32 sw_refbu_mv_sum : 22; - RK_U32 sw_reserve : 10; - } reg70_sum_mv; - - RK_U32 reg71_119_reserve[49]; - - struct { - RK_U32 sw_reserve0 : 5; - RK_U32 sw_topfieldfirst_e : 1; - RK_U32 sw_alt_scan_e : 1; - RK_U32 sw_mb_height_off : 4; - RK_U32 sw_pic_mb_hight_p : 8; - RK_U32 sw_mb_width_off : 4; - RK_U32 sw_pic_mb_width : 9; - } reg120; - - struct { - RK_U32 sw_reserve : 5; - RK_U32 sw_vp7_version : 1; - RK_U32 sw_dc_match0 : 3; - RK_U32 sw_dc_match1 : 3; - RK_U32 sw_eable_bilinear : 1; - RK_U32 sw_remain_mv : 1; - RK_U32 sw_reserve1 : 6; - RK_U32 sw_dct2_start_bit : 6; - RK_U32 sw_dct1_start_bit : 6; - } reg121; - - struct { - RK_U32 sw_vop_time_incr : 16; - RK_U32 sw_intradc_vlc_thr : 3; - RK_U32 sw_ch_qp_offset : 5; - RK_U32 sw_quant_type_1_en : 1; - RK_U32 sw_sync_markers_en : 1; - RK_U32 sw_stream_start_word: 6; - } reg122; - - struct { - RK_U32 sw_dc_comp1 : 16; - RK_U32 sw_dc_comp0 : 16; - } reg123; - - struct { - RK_U32 sw_stream1_len : 24; - RK_U32 sw_coeffs_part_am : 4; - RK_U32 sw_reserve : 4; - } reg124; - - struct { - RK_U32 reserve : 2; - RK_U32 sw_pred_bc_tap_5_3 : 10; - RK_U32 sw_pred_bc_tap_5_2 : 10; - RK_U32 sw_pred_bc_tap_5_1 : 10; - } reg125; - - struct { - RK_U32 reserve : 2; - RK_U32 sw_pred_bc_tap_6_2 : 10; - RK_U32 sw_pred_bc_tap_6_1 : 10; - RK_U32 sw_pred_bc_tap_6_0 : 10; - } reg126; - - struct { - RK_U32 reserve : 2; - RK_U32 sw_pred_bc_tap_7_1 : 10; - RK_U32 sw_pred_bc_tap_7_0 : 10; - RK_U32 sw_pred_bc_tap_6_3 : 10; - } reg127; - - struct { - RK_U32 sw_pred_tap_6_4 : 2; - RK_U32 sw_pred_tap_6_M1 : 2; - RK_U32 sw_pred_tap_4_4 : 2; - RK_U32 sw_pred_tap_4_M1 : 2; - RK_U32 sw_pred_tap_2_4 : 2; - RK_U32 sw_pred_tap_2_M1 : 2; - RK_U32 sw_pred_bc_tap_7_3 : 10; - RK_U32 sw_pred_bc_tap_7_2 : 10; - } reg128; - - struct { - RK_U32 sw_filt_level_3 : 6; - RK_U32 sw_filt_level_2 : 6; - RK_U32 sw_filt_level_1 : 6; - RK_U32 sw_filt_level_0 : 6; - RK_U32 reserve : 8; - } reg129; - - struct { - RK_U32 sw_quant_1 : 11; - RK_U32 sw_quant_0 : 11; - RK_U32 sw_quant_delta_1 : 5; - RK_U32 sw_quant_delta_0 : 5; - } reg130; - - - RK_U32 reg131_ref0_base; - - struct { - RK_U32 sw_filt_mb_adj_3 : 7; - RK_U32 sw_filt_mb_adj_2 : 7; - RK_U32 sw_filt_mb_adj_1 : 7; - RK_U32 sw_filt_mb_adj_0 : 7; - RK_U32 sw_filt_sharpness : 3; - RK_U32 sw_filt_type : 1; - } reg132; - - - struct { - RK_U32 sw_filt_ref_adj_3 : 7; - RK_U32 sw_filt_ref_adj_2 : 7; - RK_U32 sw_filt_ref_adj_1 : 7; - RK_U32 sw_filt_ref_adj_0 : 7; - RK_U32 sw_reserve : 4; - } reg133; - - RK_U32 reg134_ref2_base; - RK_U32 reg135_ref3_base; - - struct { - RK_U32 sw_prev_pic_type : 1; - RK_U32 sw_rounding : 1; - RK_U32 sw_fwd_mv_y_resolution : 1; - RK_U32 sw_vrz_bit_of_bwd_mv : 4; - RK_U32 sw_hrz_bit_of_bwd_mv : 4; - RK_U32 sw_vrz_bit_of_fwd_mv : 4; - RK_U32 sw_hrz_bit_of_fwd_mv : 4; - RK_U32 sw_alt_scan : 1; - RK_U32 sw_reserve : 12; - } reg136; - - struct { - RK_U32 sw_trb_per_trd_d0 : 27; - RK_U32 sw_reserve : 5; - } reg137; - - struct { - RK_U32 sw_trb_per_trd_dm1 : 27; - RK_U32 sw_reserve : 5; - } reg138; - - struct { - RK_U32 sw_trb_per_trd_d1 : 27; - RK_U32 sw_reserve : 5; - } reg139; - - RK_U32 reg_dct_strm_base[5]; - RK_U32 reg145_bitpl_ctrl_base; - RK_U32 reg_dct_strm1_base[2]; - - RK_U32 reg148_ref1_base; - - RK_U32 reg149_segment_map_base; - - - struct { - RK_U32 sw_dct_start_bit_7 : 6; - RK_U32 sw_dct_start_bit_6 : 6; - RK_U32 sw_dct_start_bit_5 : 6; - RK_U32 sw_dct_start_bit_4 : 6; - RK_U32 sw_dct_start_bit_3 : 6; - RK_U32 sw_reserve : 2; - } reg150; - - struct { - RK_U32 sw_quant_3 : 11; - RK_U32 sw_quant_2 : 11; - RK_U32 sw_quant_delta_3 : 5; - RK_U32 sw_quant_delta_2 : 5; - } reg151; - - struct { - RK_U32 sw_quant_5 : 11; - RK_U32 sw_quant_4 : 11; - RK_U32 sw_quant_delta_4 : 5; - RK_U32 sw_reserve : 5; - } reg152; - - struct { - RK_U32 reserve : 2; - RK_U32 sw_pred_bc_tap_1_1 : 10; - RK_U32 sw_pred_bc_tap_1_0 : 10; - RK_U32 sw_pred_bc_tap_0_3 : 10; - } reg153; - - struct { - RK_U32 reserve : 2; - RK_U32 sw_pred_bc_tap_2_0 : 10; - RK_U32 sw_pred_bc_tap_1_3 : 10; - RK_U32 sw_pred_bc_tap_1_2 : 10; - } reg154; - - struct { - RK_U32 reserve : 2; - RK_U32 sw_pred_bc_tap_2_3 : 10; - RK_U32 sw_pred_bc_tap_2_2 : 10; - RK_U32 sw_pred_bc_tap_2_1 : 10; - } reg155; - - struct { - RK_U32 reserve : 2; - RK_U32 sw_pred_bc_tap_3_2 : 10; - RK_U32 sw_pred_bc_tap_3_1 : 10; - RK_U32 sw_pred_bc_tap_3_0 : 10; - } reg156; - - struct { - RK_U32 reserve : 2; - RK_U32 sw_pred_bc_tap_4_1 : 10; - RK_U32 sw_pred_bc_tap_4_0 : 10; - RK_U32 sw_pred_bc_tap_3_3 : 10; - } reg157; - - struct { - RK_U32 reserve : 2; - RK_U32 sw_pred_bc_tap_5_0 : 10; - RK_U32 sw_pred_bc_tap_4_3 : 10; - RK_U32 sw_pred_bc_tap_4_2 : 10; - } reg158; -} VpuMpg4dRegSet_t; - -#endif - +/* + * Copyright 2016 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __HAL_MPG4D_REG_H__ +#define __HAL_MPG4D_REG_H__ + +#include "rk_type.h" + +typedef struct { + RK_U32 reg00_49[50]; + + struct { + RK_U32 sw_dec_out_tiled_e : 1; + RK_U32 sw_dec_latency : 6; + RK_U32 sw_pic_fixed_quant : 1; + RK_U32 sw_filtering_dis : 1; + RK_U32 sw_divx_enable : 1; + RK_U32 sw_dec_scmd_dis : 1; + RK_U32 sw_dec_adv_pre_dis : 1; + RK_U32 sw_priority_mode : 1; + RK_U32 sw_refbu2_thr : 12; + RK_U32 sw_refbu2_picid : 5; + RK_U32 reserve1 : 2; + } reg50_dec_ctrl; + + struct { + RK_U32 sw_stream_len : 24; + RK_U32 reserve1 : 1; + RK_U32 sw_init_qp : 6; + RK_U32 reserve2 : 1; + } reg51_stream_info; + + struct { + RK_U32 sw_startmb_y : 8; + RK_U32 sw_startmb_x : 9; + RK_U32 sw_apf_threshold : 14; + RK_U32 sw_reserve : 1; + } reg52_error_concealment; + + RK_U32 reg53_dec_mode; + + struct { + RK_U32 sw_dec_in_endian : 1; + RK_U32 sw_dec_out_endian : 1; + RK_U32 sw_dec_inswap32_e : 1; + RK_U32 sw_dec_outswap32_e : 1; + RK_U32 sw_dec_strswap32_e : 1; + RK_U32 sw_dec_strendian_e : 1; + RK_U32 reserve3 : 26; + } reg54_endian; + + struct { + RK_U32 sw_dec_irq : 1; + RK_U32 sw_dec_irq_dis : 1; + RK_U32 reserve0 : 2; + RK_U32 sw_dec_rdy_int : 1; + RK_U32 sw_dec_bus_int : 1; + RK_U32 sw_dec_buf_empty_int: 1; + RK_U32 reserve1 : 1; + RK_U32 sw_dec_aso_int : 1; + RK_U32 sw_dec_slice_int : 1; + RK_U32 sw_dec_b_pic_inf : 1; + RK_U32 reserve2 : 1; + RK_U32 sw_dec_error_int : 1; + RK_U32 sw_dec_timeout : 1; + RK_U32 reserve3 : 18; + } reg55_Interrupt; + + struct { + RK_U32 sw_dec_axi_rn_id : 8; + RK_U32 sw_dec_axi_wr_id : 8; + RK_U32 sw_dec_max_burst : 5; + RK_U32 reserve0 : 1; + RK_U32 sw_dec_data_disc_e : 1; + RK_U32 reserve1 : 9; + } reg56_axi_ctrl; + + struct { + RK_U32 sw_dec_e : 1; + RK_U32 sw_refbu2_buf_e : 1; + RK_U32 sw_dec_out_dis : 1; + RK_U32 reserve : 1; + RK_U32 sw_dec_clk_gate_e : 1; + RK_U32 sw_dec_timeout_e : 1; + RK_U32 sw_picord_count_e : 1; + RK_U32 sw_seq_mbaff_e : 1; + RK_U32 sw_reftopfirst_e : 1; + RK_U32 sw_ref_topfield_e : 1; + RK_U32 sw_write_mvs_e : 1; + RK_U32 sw_sorenson_e : 1; + RK_U32 sw_fwd_interlace_e : 1; + RK_U32 sw_pic_topfield_e : 1; + RK_U32 sw_pic_inter_e : 1; + RK_U32 sw_pic_b_e : 1; + RK_U32 sw_pic_fieldmode_e : 1; + RK_U32 sw_pic_interlace_e : 1; + RK_U32 sw_pjpeg_e : 1; + RK_U32 sw_divx3_e : 1; + RK_U32 sw_rlc_mode_e : 1; + RK_U32 sw_ch_8pix_ileav_e : 1; + RK_U32 sw_start_code_e : 1; + RK_U32 reserve1 : 8; + RK_U32 sw_dec_ahb_hlock_e : 1; + } reg57_enable_ctrl; + + struct { + RK_U32 sw_soft_rst : 1; + RK_U32 reverse0 : 31; + } reg58; + + struct { + RK_U32 reserve : 2; + RK_U32 sw_pred_bc_tap_0_2 : 10; + RK_U32 sw_pred_bc_tap_0_1 : 10; + RK_U32 sw_pred_bc_tap_0_0 : 10; + } reg59; + + RK_U32 reg60_addit_ch_st_base; + RK_U32 reg61_qtable_base; + RK_U32 reg62_directmv_base; + RK_U32 reg63_cur_pic_base; + RK_U32 reg64_input_stream_base; + + struct { + RK_U32 sw_refbu_y_offset : 9; + RK_U32 sw_reserve : 3; + RK_U32 sw_refbu_fparmod_e : 1; + RK_U32 sw_refbu_eval_e : 1; + RK_U32 sw_refbu_picid : 5; + RK_U32 sw_refbu_thr : 12; + RK_U32 sw_refbu_e : 1; + } reg65_refpicbuf_ctrl; + + struct { + RK_U32 build_version : 3; + RK_U32 product_IDen : 1; + RK_U32 minor_version : 8; + RK_U32 major_version : 4; + RK_U32 product_numer : 16; + } reg66_id; + + struct { + RK_U32 sw_reserve : 25; + RK_U32 sw_dec_rtl_rom : 1; + RK_U32 sw_dec_rv_prof : 2; + RK_U32 sw_ref_buff2_exist : 1; + RK_U32 sw_dec_divx_prof : 1; + RK_U32 sw_dec_refbu_ilace : 1; + RK_U32 sw_dec_jpeg_exten : 1; + } reg67_synthesis_cfg; + + struct { + RK_U32 sw_refbu_top_sum : 16; + RK_U32 sw_refbu_bot_sum : 16; + } reg68_sum_of_partitions; + + struct { + RK_U32 sw_refbu_intra_sum : 16; + RK_U32 sw_refbu_hit_sum : 16; + } reg69_sum_inf; + + struct { + RK_U32 sw_refbu_mv_sum : 22; + RK_U32 sw_reserve : 10; + } reg70_sum_mv; + + RK_U32 reg71_119_reserve[49]; + + struct { + RK_U32 sw_reserve0 : 5; + RK_U32 sw_topfieldfirst_e : 1; + RK_U32 sw_alt_scan_e : 1; + RK_U32 sw_mb_height_off : 4; + RK_U32 sw_pic_mb_hight_p : 8; + RK_U32 sw_mb_width_off : 4; + RK_U32 sw_pic_mb_width : 9; + } reg120; + + struct { + RK_U32 sw_reserve : 5; + RK_U32 sw_vp7_version : 1; + RK_U32 sw_dc_match0 : 3; + RK_U32 sw_dc_match1 : 3; + RK_U32 sw_eable_bilinear : 1; + RK_U32 sw_remain_mv : 1; + RK_U32 sw_reserve1 : 6; + RK_U32 sw_dct2_start_bit : 6; + RK_U32 sw_dct1_start_bit : 6; + } reg121; + + struct { + RK_U32 sw_vop_time_incr : 16; + RK_U32 sw_intradc_vlc_thr : 3; + RK_U32 sw_ch_qp_offset : 5; + RK_U32 sw_quant_type_1_en : 1; + RK_U32 sw_sync_markers_en : 1; + RK_U32 sw_stream_start_word: 6; + } reg122; + + struct { + RK_U32 sw_dc_comp1 : 16; + RK_U32 sw_dc_comp0 : 16; + } reg123; + + struct { + RK_U32 sw_stream1_len : 24; + RK_U32 sw_coeffs_part_am : 4; + RK_U32 sw_reserve : 4; + } reg124; + + struct { + RK_U32 reserve : 2; + RK_U32 sw_pred_bc_tap_5_3 : 10; + RK_U32 sw_pred_bc_tap_5_2 : 10; + RK_U32 sw_pred_bc_tap_5_1 : 10; + } reg125; + + struct { + RK_U32 reserve : 2; + RK_U32 sw_pred_bc_tap_6_2 : 10; + RK_U32 sw_pred_bc_tap_6_1 : 10; + RK_U32 sw_pred_bc_tap_6_0 : 10; + } reg126; + + struct { + RK_U32 reserve : 2; + RK_U32 sw_pred_bc_tap_7_1 : 10; + RK_U32 sw_pred_bc_tap_7_0 : 10; + RK_U32 sw_pred_bc_tap_6_3 : 10; + } reg127; + + struct { + RK_U32 sw_pred_tap_6_4 : 2; + RK_U32 sw_pred_tap_6_M1 : 2; + RK_U32 sw_pred_tap_4_4 : 2; + RK_U32 sw_pred_tap_4_M1 : 2; + RK_U32 sw_pred_tap_2_4 : 2; + RK_U32 sw_pred_tap_2_M1 : 2; + RK_U32 sw_pred_bc_tap_7_3 : 10; + RK_U32 sw_pred_bc_tap_7_2 : 10; + } reg128; + + struct { + RK_U32 sw_filt_level_3 : 6; + RK_U32 sw_filt_level_2 : 6; + RK_U32 sw_filt_level_1 : 6; + RK_U32 sw_filt_level_0 : 6; + RK_U32 reserve : 8; + } reg129; + + struct { + RK_U32 sw_quant_1 : 11; + RK_U32 sw_quant_0 : 11; + RK_U32 sw_quant_delta_1 : 5; + RK_U32 sw_quant_delta_0 : 5; + } reg130; + + + RK_U32 reg131_ref0_base; + + struct { + RK_U32 sw_filt_mb_adj_3 : 7; + RK_U32 sw_filt_mb_adj_2 : 7; + RK_U32 sw_filt_mb_adj_1 : 7; + RK_U32 sw_filt_mb_adj_0 : 7; + RK_U32 sw_filt_sharpness : 3; + RK_U32 sw_filt_type : 1; + } reg132; + + + struct { + RK_U32 sw_filt_ref_adj_3 : 7; + RK_U32 sw_filt_ref_adj_2 : 7; + RK_U32 sw_filt_ref_adj_1 : 7; + RK_U32 sw_filt_ref_adj_0 : 7; + RK_U32 sw_reserve : 4; + } reg133; + + RK_U32 reg134_ref2_base; + RK_U32 reg135_ref3_base; + + struct { + RK_U32 sw_prev_pic_type : 1; + RK_U32 sw_rounding : 1; + RK_U32 sw_fwd_mv_y_resolution : 1; + RK_U32 sw_vrz_bit_of_bwd_mv : 4; + RK_U32 sw_hrz_bit_of_bwd_mv : 4; + RK_U32 sw_vrz_bit_of_fwd_mv : 4; + RK_U32 sw_hrz_bit_of_fwd_mv : 4; + RK_U32 sw_alt_scan : 1; + RK_U32 sw_reserve : 12; + } reg136; + + struct { + RK_U32 sw_trb_per_trd_d0 : 27; + RK_U32 sw_reserve : 5; + } reg137; + + struct { + RK_U32 sw_trb_per_trd_dm1 : 27; + RK_U32 sw_reserve : 5; + } reg138; + + struct { + RK_U32 sw_trb_per_trd_d1 : 27; + RK_U32 sw_reserve : 5; + } reg139; + + RK_U32 reg_dct_strm_base[5]; + RK_U32 reg145_bitpl_ctrl_base; + RK_U32 reg_dct_strm1_base[2]; + + RK_U32 reg148_ref1_base; + + RK_U32 reg149_segment_map_base; + + + struct { + RK_U32 sw_dct_start_bit_7 : 6; + RK_U32 sw_dct_start_bit_6 : 6; + RK_U32 sw_dct_start_bit_5 : 6; + RK_U32 sw_dct_start_bit_4 : 6; + RK_U32 sw_dct_start_bit_3 : 6; + RK_U32 sw_reserve : 2; + } reg150; + + struct { + RK_U32 sw_quant_3 : 11; + RK_U32 sw_quant_2 : 11; + RK_U32 sw_quant_delta_3 : 5; + RK_U32 sw_quant_delta_2 : 5; + } reg151; + + struct { + RK_U32 sw_quant_5 : 11; + RK_U32 sw_quant_4 : 11; + RK_U32 sw_quant_delta_4 : 5; + RK_U32 sw_reserve : 5; + } reg152; + + struct { + RK_U32 reserve : 2; + RK_U32 sw_pred_bc_tap_1_1 : 10; + RK_U32 sw_pred_bc_tap_1_0 : 10; + RK_U32 sw_pred_bc_tap_0_3 : 10; + } reg153; + + struct { + RK_U32 reserve : 2; + RK_U32 sw_pred_bc_tap_2_0 : 10; + RK_U32 sw_pred_bc_tap_1_3 : 10; + RK_U32 sw_pred_bc_tap_1_2 : 10; + } reg154; + + struct { + RK_U32 reserve : 2; + RK_U32 sw_pred_bc_tap_2_3 : 10; + RK_U32 sw_pred_bc_tap_2_2 : 10; + RK_U32 sw_pred_bc_tap_2_1 : 10; + } reg155; + + struct { + RK_U32 reserve : 2; + RK_U32 sw_pred_bc_tap_3_2 : 10; + RK_U32 sw_pred_bc_tap_3_1 : 10; + RK_U32 sw_pred_bc_tap_3_0 : 10; + } reg156; + + struct { + RK_U32 reserve : 2; + RK_U32 sw_pred_bc_tap_4_1 : 10; + RK_U32 sw_pred_bc_tap_4_0 : 10; + RK_U32 sw_pred_bc_tap_3_3 : 10; + } reg157; + + struct { + RK_U32 reserve : 2; + RK_U32 sw_pred_bc_tap_5_0 : 10; + RK_U32 sw_pred_bc_tap_4_3 : 10; + RK_U32 sw_pred_bc_tap_4_2 : 10; + } reg158; +} VpuMpg4dRegSet_t; + +#endif + diff --git a/mpp/hal/vpu/vp8d/hal_vp8d_api.c b/mpp/hal/vpu/vp8d/hal_vp8d_api.c index bb1c890c..19288262 100644 --- a/mpp/hal/vpu/vp8d/hal_vp8d_api.c +++ b/mpp/hal/vpu/vp8d/hal_vp8d_api.c @@ -1,43 +1,43 @@ -/* -* -* Copyright 2015 Rockchip Electronics Co. LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ -#define MODULE_TAG "hal_vp8d_api" - -#include - -#include "mpp_hal.h" -#include "hal_vp8d_reg.h" - -const MppHalApi hal_api_vp8d = { - "vp8d_rkdec", - MPP_CTX_DEC, - MPP_VIDEO_CodingVP8, - sizeof(VP8DHalContext_t), - 0, - hal_vp8d_init, - hal_vp8d_deinit, - hal_vp8d_gen_regs, - hal_vp8d_start, - hal_vp8d_wait, - hal_vp8d_reset, - hal_vp8d_flush, - hal_vp8d_control, -}; - - - - - +/* +* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#define MODULE_TAG "hal_vp8d_api" + +#include + +#include "mpp_hal.h" +#include "hal_vp8d_reg.h" + +const MppHalApi hal_api_vp8d = { + "vp8d_rkdec", + MPP_CTX_DEC, + MPP_VIDEO_CodingVP8, + sizeof(VP8DHalContext_t), + 0, + hal_vp8d_init, + hal_vp8d_deinit, + hal_vp8d_gen_regs, + hal_vp8d_start, + hal_vp8d_wait, + hal_vp8d_reset, + hal_vp8d_flush, + hal_vp8d_control, +}; + + + + + diff --git a/mpp/hal/vpu/vp8d/hal_vp8d_reg.c b/mpp/hal/vpu/vp8d/hal_vp8d_reg.c index 6967beb4..5ecdb158 100644 --- a/mpp/hal/vpu/vp8d/hal_vp8d_reg.c +++ b/mpp/hal/vpu/vp8d/hal_vp8d_reg.c @@ -1,822 +1,822 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define MODULE_TAG "hal_vp8d_reg" -#include - -#include "mpp_log.h" -#include "mpp_env.h" -#include "mpp_mem.h" - -#include "vpu.h" -#include "hal_vp8d_reg.h" - - -RK_U32 vp8h_debug = 0; - -#define VP8HWD_VP7 1 -#define VP8HWD_VP8 2 -#define VP8HWD_WEBP 3 - -#define DEC_MODE_VP7 9 -#define DEC_MODE_VP8 10 - -#define VP8D_PROB_TABLE_SIZE (1<<16) /* TODO */ -#define VP8D_MAX_SEGMAP_SIZE (2048 + 1024) //1920*1080 /* TODO */ -#define FUN_T(tag) \ - do {\ - if (VP8H_DBG_FUNCTION & vp8h_debug)\ - { mpp_log("%s: line(%d), func(%s)", tag, __LINE__, __FUNCTION__); }\ - } while (0) - -/* VP7 QP LUTs */ -static const RK_U16 YDcQLookup[128] = { - 4, 4, 5, 6, 6, 7, 8, 8, - 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 23, - 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 33, 34, 35, 36, 36, 37, - 38, 39, 39, 40, 41, 41, 42, 43, - 43, 44, 45, 45, 46, 47, 48, 48, - 49, 50, 51, 52, 53, 53, 54, 56, - 57, 58, 59, 60, 62, 63, 65, 66, - 68, 70, 72, 74, 76, 79, 81, 84, - 87, 90, 93, 96, 100, 104, 108, 112, - 116, 121, 126, 131, 136, 142, 148, 154, - 160, 167, 174, 182, 189, 198, 206, 215, - 224, 234, 244, 254, 265, 277, 288, 301, - 313, 327, 340, 355, 370, 385, 401, 417, - 434, 452, 470, 489, 509, 529, 550, 572 -}; - -static const RK_U16 YAcQLookup[128] = { - 4, 4, 5, 5, 6, 6, 7, 8, - 9, 10, 11, 12, 13, 15, 16, 17, - 19, 20, 22, 23, 25, 26, 28, 29, - 31, 32, 34, 35, 37, 38, 40, 41, - 42, 44, 45, 46, 48, 49, 50, 51, - 53, 54, 55, 56, 57, 58, 59, 61, - 62, 63, 64, 65, 67, 68, 69, 70, - 72, 73, 75, 76, 78, 80, 82, 84, - 86, 88, 91, 93, 96, 99, 102, 105, - 109, 112, 116, 121, 125, 130, 135, 140, - 146, 152, 158, 165, 172, 180, 188, 196, - 205, 214, 224, 234, 245, 256, 268, 281, - 294, 308, 322, 337, 353, 369, 386, 404, - 423, 443, 463, 484, 506, 529, 553, 578, - 604, 631, 659, 688, 718, 749, 781, 814, - 849, 885, 922, 960, 1000, 1041, 1083, 1127 - -}; - -static const RK_U16 Y2DcQLookup[128] = { - 7, 9, 11, 13, 15, 17, 19, 21, - 23, 26, 28, 30, 33, 35, 37, 39, - 42, 44, 46, 48, 51, 53, 55, 57, - 59, 61, 63, 65, 67, 69, 70, 72, - 74, 75, 77, 78, 80, 81, 83, 84, - 85, 87, 88, 89, 90, 92, 93, 94, - 95, 96, 97, 99, 100, 101, 102, 104, - 105, 106, 108, 109, 111, 113, 114, 116, - 118, 120, 123, 125, 128, 131, 134, 137, - 140, 144, 148, 152, 156, 161, 166, 171, - 176, 182, 188, 195, 202, 209, 217, 225, - 234, 243, 253, 263, 274, 285, 297, 309, - 322, 336, 350, 365, 381, 397, 414, 432, - 450, 470, 490, 511, 533, 556, 579, 604, - 630, 656, 684, 713, 742, 773, 805, 838, - 873, 908, 945, 983, 1022, 1063, 1105, 1148 -}; - -static const RK_U16 Y2AcQLookup[128] = { - 7, 9, 11, 13, 16, 18, 21, 24, - 26, 29, 32, 35, 38, 41, 43, 46, - 49, 52, 55, 58, 61, 64, 66, 69, - 72, 74, 77, 79, 82, 84, 86, 88, - 91, 93, 95, 97, 98, 100, 102, 104, - 105, 107, 109, 110, 112, 113, 115, 116, - 117, 119, 120, 122, 123, 125, 127, 128, - 130, 132, 134, 136, 138, 141, 143, 146, - 149, 152, 155, 158, 162, 166, 171, 175, - 180, 185, 191, 197, 204, 210, 218, 226, - 234, 243, 252, 262, 273, 284, 295, 308, - 321, 335, 350, 365, 381, 398, 416, 435, - 455, 476, 497, 520, 544, 569, 595, 622, - 650, 680, 711, 743, 776, 811, 848, 885, - 925, 965, 1008, 1052, 1097, 1144, 1193, 1244, - 1297, 1351, 1407, 1466, 1526, 1588, 1652, 1719 -}; - -static const RK_U16 UvDcQLookup[128] = { - 4, 4, 5, 6, 6, 7, 8, 8, - 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 23, - 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 33, 34, 35, 36, 36, 37, - 38, 39, 39, 40, 41, 41, 42, 43, - 43, 44, 45, 45, 46, 47, 48, 48, - 49, 50, 51, 52, 53, 53, 54, 56, - 57, 58, 59, 60, 62, 63, 65, 66, - 68, 70, 72, 74, 76, 79, 81, 84, - 87, 90, 93, 96, 100, 104, 108, 112, - 116, 121, 126, 131, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132, - 132, 132, 132, 132, 132, 132, 132, 132 -}; - - -static const RK_U16 UvAcQLookup[128] = { - 4, 4, 5, 5, 6, 6, 7, 8, - 9, 10, 11, 12, 13, 15, 16, 17, - 19, 20, 22, 23, 25, 26, 28, 29, - 31, 32, 34, 35, 37, 38, 40, 41, - 42, 44, 45, 46, 48, 49, 50, 51, - 53, 54, 55, 56, 57, 58, 59, 61, - 62, 63, 64, 65, 67, 68, 69, 70, - 72, 73, 75, 76, 78, 80, 82, 84, - 86, 88, 91, 93, 96, 99, 102, 105, - 109, 112, 116, 121, 125, 130, 135, 140, - 146, 152, 158, 165, 172, 180, 188, 196, - 205, 214, 224, 234, 245, 256, 268, 281, - 294, 308, 322, 337, 353, 369, 386, 404, - 423, 443, 463, 484, 506, 529, 553, 578, - 604, 631, 659, 688, 718, 749, 781, 814, - 849, 885, 922, 960, 1000, 1041, 1083, 1127 -}; - -#define CLIP3(l, h, v) ((v) < (l) ? (l) : ((v) > (h) ? (h) : (v))) - -static const RK_U32 mcFilter[8][6] = { - { 0, 0, 128, 0, 0, 0 }, - { 0, -6, 123, 12, -1, 0 }, - { 2, -11, 108, 36, -8, 1 }, - { 0, -9, 93, 50, -6, 0 }, - { 3, -16, 77, 77, -16, 3 }, - { 0, -6, 50, 93, -9, 0 }, - { 1, -8, 36, 108, -11, 2 }, - { 0, -1, 12, 123, -6, 0 } -}; - -MPP_RET hal_vp8d_init(void *hal, MppHalCfg *cfg) -{ - MPP_RET ret = MPP_OK; - VP8DHalContext_t *ctx = (VP8DHalContext_t *)hal; - - FUN_T("FUN_IN"); - //configure - ctx->packet_slots = cfg->packet_slots; - ctx->frame_slots = cfg->frame_slots; - - mpp_env_get_u32("vp8h_debug", &vp8h_debug, 0); - //get vpu socket -#ifdef RKPLATFORM - if (ctx->vpu_socket <= 0) { - ctx->vpu_socket = VPUClientInit(VPU_DEC); - if (ctx->vpu_socket <= 0) { - mpp_err("get vpu_socket(%d) <=0, failed. \n", ctx->vpu_socket); - - FUN_T("FUN_OUT"); - return MPP_ERR_UNKNOW; - } else { - mpp_log("get vpu_socket(%d), success. \n", ctx->vpu_socket); - } - } -#endif - if (NULL == ctx->regs) { - ctx->regs = mpp_calloc_size(void, sizeof(VP8DRegSet_t)); - if (NULL == ctx->regs) { - mpp_err("hal_vp8 reg alloc failed\n"); - - FUN_T("FUN_OUT"); - return MPP_ERR_NOMEM; - } - } - - if (NULL == ctx->group) { -#ifdef RKPLATFORM - mpp_err("mpp_buffer_group_get_internal used ion in"); - ret = mpp_buffer_group_get_internal(&ctx->group, MPP_BUFFER_TYPE_ION); -#else - ret = mpp_buffer_group_get_internal(&ctx->group, MPP_BUFFER_TYPE_NORMAL); -#endif - if (MPP_OK != ret) { - mpp_err("hal_vp8 mpp_buffer_group_get failed\n"); - - FUN_T("FUN_OUT"); - return ret; - } - } - ret = mpp_buffer_get(ctx->group, &ctx->probe_table, VP8D_PROB_TABLE_SIZE); - if (MPP_OK != ret) { - mpp_err("hal_vp8 probe_table get buffer failed\n"); - - FUN_T("FUN_OUT"); - return ret; - } - - ret = mpp_buffer_get(ctx->group, &ctx->seg_map, VP8D_MAX_SEGMAP_SIZE); - - if (MPP_OK != ret) { - mpp_err("hal_vp8 seg_map get buffer failed\n"); - FUN_T("FUN_OUT"); - return ret; - } - - return ret; -} - -MPP_RET hal_vp8d_deinit(void *hal) -{ - MPP_RET ret = MPP_OK; - - FUN_T("FUN_IN"); - VP8DHalContext_t *ctx = (VP8DHalContext_t *)hal; -#ifdef RKPLATFORM - if (ctx->vpu_socket >= 0) { - VPUClientRelease(ctx->vpu_socket); - - } -#endif - if (ctx->probe_table) { - ret = mpp_buffer_put(ctx->probe_table); - if (MPP_OK != ret) { - mpp_err("hal_vp8 probe table put buffer failed\n"); - } - } - - if (ctx->seg_map) { - ret = mpp_buffer_put(ctx->seg_map); - if (MPP_OK != ret) { - mpp_err("hal_vp8 seg map put buffer failed\n"); - } - } - - if (ctx->group) { - ret = mpp_buffer_group_put(ctx->group); - if (MPP_OK != ret) { - mpp_err("hal_vp8 group free buffer failed\n"); - } - } - - if (ctx->regs) { - mpp_free(ctx->regs); - ctx->regs = NULL; - } - - FUN_T("FUN_OUT"); - return ret; -} - -MPP_RET hal_vp8_init_hwcfg(VP8DHalContext_t *ctx) -{ - - VP8DRegSet_t *reg = (VP8DRegSet_t *)ctx->regs; - - FUN_T("FUN_IN"); - memset(reg, 0, sizeof(VP8DRegSet_t)); - reg->reg50_dec_ctrl.sw_dec_out_tiled_e = 0; - reg->reg50_dec_ctrl.sw_dec_scmd_dis = 0; - reg->reg50_dec_ctrl.sw_dec_adv_pre_dis = 0; - reg->reg50_dec_ctrl.sw_dec_latency = 0; - - reg->reg53_dec_mode = DEC_MODE_VP8; - - reg->reg54_endian.sw_dec_in_endian = 1; - reg->reg54_endian.sw_dec_out_endian = 1; - reg->reg54_endian.sw_dec_inswap32_e = 1; - reg->reg54_endian.sw_dec_outswap32_e = 1; - reg->reg54_endian.sw_dec_strswap32_e = 1; - reg->reg54_endian.sw_dec_strendian_e = 1; - - reg->reg55_Interrupt.sw_dec_irq = 0; - - reg->reg56_axi_ctrl.sw_dec_axi_rn_id = 0; - reg->reg56_axi_ctrl.sw_dec_axi_wr_id = 0; - - reg->reg56_axi_ctrl.sw_dec_data_disc_e = 0; - reg->reg56_axi_ctrl.sw_dec_max_burst = 16; - reg->reg57_enable_ctrl.sw_dec_timeout_e = 1; - reg->reg57_enable_ctrl.sw_dec_clk_gate_e = 1; - reg->reg57_enable_ctrl.sw_dec_out_dis = 0; - -#ifdef RKPLATFORM - reg->reg149_segment_map_base = mpp_buffer_get_fd(ctx->seg_map); - reg->reg61_qtable_base = mpp_buffer_get_fd(ctx->probe_table); -#endif - - FUN_T("FUN_OUT"); - return MPP_OK; -} - -MPP_RET hal_vp8d_pre_filter_tap_set(VP8DHalContext_t *ctx) -{ - VP8DRegSet_t *regs = (VP8DRegSet_t *)ctx->regs; - - FUN_T("FUN_IN"); - regs->reg59.sw_pred_bc_tap_0_0 = mcFilter[0][1]; - regs->reg59.sw_pred_bc_tap_0_1 = mcFilter[0][2]; - regs->reg59.sw_pred_bc_tap_0_2 = mcFilter[0][3]; - regs->reg153.sw_pred_bc_tap_0_3 = mcFilter[0][4]; - regs->reg153.sw_pred_bc_tap_1_0 = mcFilter[1][1]; - regs->reg153.sw_pred_bc_tap_1_1 = mcFilter[1][2]; - regs->reg154.sw_pred_bc_tap_1_2 = mcFilter[1][3]; - regs->reg154.sw_pred_bc_tap_1_3 = mcFilter[1][4]; - regs->reg154.sw_pred_bc_tap_2_0 = mcFilter[2][1]; - regs->reg155.sw_pred_bc_tap_2_1 = mcFilter[2][2]; - regs->reg155.sw_pred_bc_tap_2_2 = mcFilter[2][3]; - regs->reg155.sw_pred_bc_tap_2_3 = mcFilter[2][4]; - - regs->reg156.sw_pred_bc_tap_3_0 = mcFilter[3][1]; - regs->reg156.sw_pred_bc_tap_3_1 = mcFilter[3][2]; - regs->reg156.sw_pred_bc_tap_3_2 = mcFilter[3][3]; - regs->reg157.sw_pred_bc_tap_3_3 = mcFilter[3][4]; - regs->reg157.sw_pred_bc_tap_4_0 = mcFilter[4][1]; - regs->reg157.sw_pred_bc_tap_4_1 = mcFilter[4][2]; - regs->reg158.sw_pred_bc_tap_4_2 = mcFilter[4][3]; - regs->reg158.sw_pred_bc_tap_4_3 = mcFilter[4][4]; - regs->reg158.sw_pred_bc_tap_5_0 = mcFilter[5][1]; - - regs->reg125.sw_pred_bc_tap_5_1 = mcFilter[5][2]; - - regs->reg125.sw_pred_bc_tap_5_2 = mcFilter[5][3]; - - regs->reg125.sw_pred_bc_tap_5_3 = mcFilter[5][4]; - regs->reg126.sw_pred_bc_tap_6_0 = mcFilter[6][1]; - regs->reg126.sw_pred_bc_tap_6_1 = mcFilter[6][2]; - regs->reg126.sw_pred_bc_tap_6_2 = mcFilter[6][3]; - regs->reg127.sw_pred_bc_tap_6_3 = mcFilter[6][4]; - regs->reg127.sw_pred_bc_tap_7_0 = mcFilter[7][1]; - regs->reg127.sw_pred_bc_tap_7_1 = mcFilter[7][2]; - regs->reg128.sw_pred_bc_tap_7_2 = mcFilter[7][3]; - regs->reg128.sw_pred_bc_tap_7_3 = mcFilter[7][4]; - - regs->reg128.sw_pred_tap_2_M1 = mcFilter[2][0]; - regs->reg128.sw_pred_tap_2_4 = mcFilter[2][5]; - regs->reg128.sw_pred_tap_4_M1 = mcFilter[4][0]; - regs->reg128.sw_pred_tap_4_4 = mcFilter[4][5]; - regs->reg128.sw_pred_tap_6_M1 = mcFilter[6][0]; - regs->reg128.sw_pred_tap_6_4 = mcFilter[6][5]; - - FUN_T("FUN_OUT"); - return MPP_OK; -} - -MPP_RET hal_vp8d_dct_partition_cfg(VP8DHalContext_t *ctx, HalTaskInfo *task) -{ - RK_U32 i = 0, len = 0, len1 = 0; - RK_U32 extraBytesPacked = 0; - RK_U32 addr = 0, byte_offset = 0; -#ifdef RKPLATFORM - RK_U32 fd = 0; - MppBuffer streambuf = NULL; -#endif - VP8DRegSet_t *regs = (VP8DRegSet_t *)ctx->regs; - DXVA_PicParams_VP8 *pic_param = (DXVA_PicParams_VP8 *)task->dec.syntax.data; - - - FUN_T("FUN_IN"); -#ifdef RKPLATFORM - mpp_buf_slot_get_prop(ctx->packet_slots, task->dec.input, SLOT_BUFFER, &streambuf); - fd = mpp_buffer_get_fd(streambuf); - regs->reg145_bitpl_ctrl_base = fd; - if (VPUClientGetIOMMUStatus() > 0) { - regs->reg145_bitpl_ctrl_base |= (pic_param->stream_start_offset << 10); - } else { - regs->reg145_bitpl_ctrl_base += pic_param->stream_start_offset; - } - regs->reg122.sw_strm1_start_bit = pic_param->stream_start_bit; -#endif - /* calculate dct partition length here instead */ - if (pic_param->decMode == VP8HWD_VP8 && !pic_param->frame_type) - extraBytesPacked += 7; - len = pic_param->streamEndPos + pic_param->frameTagSize - pic_param->dctPartitionOffsets[0]; - len += ( (1 << pic_param->log2_nbr_of_dct_partitions) - 1) * 3; - len1 = extraBytesPacked + pic_param->dctPartitionOffsets[0]; - len += (len1 & 0x7); - regs->reg51_stream_info.sw_stream_len = len; - - //mpp_log("offsetToDctParts = %d pic_param->frameTagSize %d pic_param->stream_start_offset = %d extraBytesPacked = %d", - // pic_param->offsetToDctParts,pic_param->frameTagSize , - // pic_param->stream_start_offset,extraBytesPacked); - - len = pic_param->offsetToDctParts + pic_param->frameTagSize - - (pic_param->stream_start_offset - extraBytesPacked); - if (pic_param->decMode == VP8HWD_VP7) /* give extra byte for VP7 to pass test cases */ - len ++; - - regs->reg124.sw_stream1_len = len; - regs->reg124.sw_coeffs_part_am = (1 << pic_param->log2_nbr_of_dct_partitions) - 1; - for (i = 0; i < (RK_U32)(1 << pic_param->log2_nbr_of_dct_partitions); i++) { - addr = extraBytesPacked + pic_param->dctPartitionOffsets[i]; - byte_offset = addr & 0x7; - addr = addr & 0xFFFFFFF8; -#ifdef RKPLATFORM - if ( i == 0) { - if (VPUClientGetIOMMUStatus() > 0) { - regs->reg64_input_stream_base = fd | (addr << 10); - } else { - regs->reg_dct_strm_base[i] = fd + addr; - } - } else if ( i <= 5) { - if (VPUClientGetIOMMUStatus() > 0) { - regs->reg_dct_strm_base[i] = fd | (addr << 10); - } else { - regs->reg_dct_strm_base[i] = fd + addr; - } - } else { - if (VPUClientGetIOMMUStatus() > 0) { - regs->reg_dct_strm1_base[i - 6] = fd | (addr << 10); - } else { - regs->reg_dct_strm_base[i - 6] = fd + addr; - } - } -#endif - switch (i) { - case 0: - regs->reg122.sw_strm_start_bit = byte_offset * 8; - break; - case 1: - regs->reg121.sw_dct1_start_bit = byte_offset * 8; - break; - case 2: - regs->reg121.sw_dct2_start_bit = byte_offset * 8; - break; - case 3: - regs->reg150.sw_dct_start_bit_3 = byte_offset * 8; - break; - case 4: - regs->reg150.sw_dct_start_bit_4 = byte_offset * 8; - break; - case 5: - regs->reg150.sw_dct_start_bit_5 = byte_offset * 8; - break; - case 6: - regs->reg150.sw_dct_start_bit_6 = byte_offset * 8; - break; - case 7: - regs->reg150.sw_dct_start_bit_6 = byte_offset * 8; - break; - default: - break; - } - } - - FUN_T("FUN_OUT"); - return MPP_OK; -} -void hal_vp8hw_asic_probe_update(DXVA_PicParams_VP8 *p, RK_U8 *probTbl) -{ - RK_U8 *dst; - RK_U32 i, j, k; - - FUN_T("FUN_IN"); - /* first probs */ - dst = probTbl; - - dst[0] = p->probe_skip_false; - dst[1] = p->prob_intra; - dst[2] = p->prob_last; - dst[3] = p->prob_golden; - dst[4] = p->stVP8Segments.mb_segment_tree_probs[0]; - dst[5] = p->stVP8Segments.mb_segment_tree_probs[1]; - dst[6] = p->stVP8Segments.mb_segment_tree_probs[2]; - dst[7] = 0; /*unused*/ - - dst += 8; - dst[0] = p->intra_16x16_prob[0]; - dst[1] = p->intra_16x16_prob[1]; - dst[2] = p->intra_16x16_prob[2]; - dst[3] = p->intra_16x16_prob[3]; - dst[4] = p->intra_chroma_prob[0]; - dst[5] = p->intra_chroma_prob[1]; - dst[6] = p->intra_chroma_prob[2]; - dst[7] = 0; /*unused*/ - - /* mv probs */ - dst += 8; - dst[0] = p->vp8_mv_update_probs[0][0]; /* is short */ - dst[1] = p->vp8_mv_update_probs[1][0]; - dst[2] = p->vp8_mv_update_probs[0][1]; /* sign */ - dst[3] = p->vp8_mv_update_probs[1][1]; - dst[4] = p->vp8_mv_update_probs[0][8 + 9]; - dst[5] = p->vp8_mv_update_probs[0][9 + 9]; - dst[6] = p->vp8_mv_update_probs[1][8 + 9]; - dst[7] = p->vp8_mv_update_probs[1][9 + 9]; - dst += 8; - for ( i = 0 ; i < 2 ; ++i ) { - for ( j = 0 ; j < 8 ; j += 4 ) { - dst[0] = p->vp8_mv_update_probs[i][j + 9 + 0]; - dst[1] = p->vp8_mv_update_probs[i][j + 9 + 1]; - dst[2] = p->vp8_mv_update_probs[i][j + 9 + 2]; - dst[3] = p->vp8_mv_update_probs[i][j + 9 + 3]; - dst += 4; - } - } - for ( i = 0 ; i < 2 ; ++i ) { - dst[0] = p->vp8_mv_update_probs[i][0 + 2]; - dst[1] = p->vp8_mv_update_probs[i][1 + 2]; - dst[2] = p->vp8_mv_update_probs[i][2 + 2]; - dst[3] = p->vp8_mv_update_probs[i][3 + 2]; - dst[4] = p->vp8_mv_update_probs[i][4 + 2]; - dst[5] = p->vp8_mv_update_probs[i][5 + 2]; - dst[6] = p->vp8_mv_update_probs[i][6 + 2]; - dst[7] = 0; /*unused*/ - dst += 8; - } - - /* coeff probs (header part) */ - dst = (RK_U8*)probTbl; - dst += (8 * 7); - for ( i = 0 ; i < 4 ; ++i ) { - for ( j = 0 ; j < 8 ; ++j ) { - for ( k = 0 ; k < 3 ; ++k ) { - dst[0] = p->vp8_coef_update_probs[i][j][k][0]; - dst[1] = p->vp8_coef_update_probs[i][j][k][1]; - dst[2] = p->vp8_coef_update_probs[i][j][k][2]; - dst[3] = p->vp8_coef_update_probs[i][j][k][3]; - dst += 4; - } - } - } - - /* coeff probs (footer part) */ - dst = (RK_U8*)probTbl; - dst += (8 * 55); - for ( i = 0 ; i < 4 ; ++i ) { - for ( j = 0 ; j < 8 ; ++j ) { - for ( k = 0 ; k < 3 ; ++k ) { - dst[0] = p->vp8_coef_update_probs[i][j][k][4]; - dst[1] = p->vp8_coef_update_probs[i][j][k][5]; - dst[2] = p->vp8_coef_update_probs[i][j][k][6]; - dst[3] = p->vp8_coef_update_probs[i][j][k][7]; - dst[4] = p->vp8_coef_update_probs[i][j][k][8]; - dst[5] = p->vp8_coef_update_probs[i][j][k][9]; - dst[6] = p->vp8_coef_update_probs[i][j][k][10]; - dst[7] = 0; /*unused*/ - dst += 8; - } - } - } - FUN_T("FUN_OUT"); - return ; -} -MPP_RET hal_vp8d_gen_regs(void* hal, HalTaskInfo *task) -{ - MPP_RET ret = MPP_OK; - RK_U32 mb_width = 0, mb_height = 0; -#ifdef RKPLATFORM - MppBuffer framebuf = NULL; - RK_U8 *segmap_ptr = NULL; - RK_U8 *probe_ptr = NULL; -#endif - VP8DHalContext_t *ctx = (VP8DHalContext_t *)hal; - VP8DRegSet_t *regs = (VP8DRegSet_t *)ctx->regs; - DXVA_PicParams_VP8 *pic_param = (DXVA_PicParams_VP8 *)task->dec.syntax.data; - - FUN_T("FUN_IN"); - hal_vp8_init_hwcfg(ctx); - mb_width = (pic_param->width + 15) >> 4; - mb_height = (pic_param->height + 15) >> 4; - // mpp_log("mb_width = %d mb_height = %d", mb_width, mb_height); - regs->reg120.sw_pic_mb_width = mb_width & 0x1FF; - regs->reg120.sw_pic_mb_hight_p = mb_height & 0xFF; - regs->reg120.sw_pic_mb_w_ext = mb_width >> 9; - regs->reg120.sw_pic_mb_h_ext = mb_height >> 8; - -#ifdef RKPLATFORM - if (!pic_param->frame_type) { - segmap_ptr = mpp_buffer_get_ptr(ctx->seg_map); - if (NULL != segmap_ptr) { - memset(segmap_ptr, 0, VP8D_MAX_SEGMAP_SIZE); - } - } - - probe_ptr = mpp_buffer_get_ptr(ctx->probe_table); - if (NULL != probe_ptr) { - hal_vp8hw_asic_probe_update(pic_param, probe_ptr); - } - mpp_buf_slot_get_prop(ctx->frame_slots, pic_param->CurrPic.Index7Bits, SLOT_BUFFER, &framebuf); - regs->reg63_cur_pic_base = mpp_buffer_get_fd(framebuf); - if (!pic_param->frame_type) { //key frame - if ((mb_width * mb_height) << 8 > 0x400000) { - mpp_log("mb_width*mb_height is big then 0x400000,iommu err"); - } - regs->reg131_ref0_base = regs->reg63_cur_pic_base | ((mb_width * mb_height) << 18); - } else if (pic_param->lst_fb_idx.Index7Bits < 0x7f) { //config ref0 base - mpp_buf_slot_get_prop(ctx->frame_slots, pic_param->lst_fb_idx.Index7Bits, SLOT_BUFFER, &framebuf); - regs->reg131_ref0_base = mpp_buffer_get_fd(framebuf); - } else { - regs->reg131_ref0_base = regs->reg63_cur_pic_base; - } - - /* golden reference */ - if (pic_param->gld_fb_idx.Index7Bits < 0x7f) { - mpp_buf_slot_get_prop(ctx->frame_slots, pic_param->gld_fb_idx.Index7Bits, SLOT_BUFFER, &framebuf); - regs->reg136_golden_ref_base = mpp_buffer_get_fd(framebuf); - } else { - regs->reg136_golden_ref_base = regs->reg63_cur_pic_base; - } - - if (VPUClientGetIOMMUStatus() > 0) { - regs->reg136_golden_ref_base = regs->reg136_golden_ref_base | (pic_param->ref_frame_sign_bias_golden << 10); - } else { - regs->reg136_golden_ref_base = regs->reg136_golden_ref_base + pic_param->ref_frame_sign_bias_golden; - } - - /* alternate reference */ - if (pic_param->alt_fb_idx.Index7Bits < 0x7f) { - mpp_buf_slot_get_prop(ctx->frame_slots, pic_param->alt_fb_idx.Index7Bits, SLOT_BUFFER, &framebuf); - regs->reg137.alternate_ref_base = mpp_buffer_get_fd(framebuf); - } else { - regs->reg137.alternate_ref_base = regs->reg63_cur_pic_base; - } - - if (VPUClientGetIOMMUStatus() > 0) { - regs->reg137.alternate_ref_base = regs->reg137.alternate_ref_base | (pic_param->ref_frame_sign_bias_altref << 10); - } else { - regs->reg137.alternate_ref_base = regs->reg137.alternate_ref_base + pic_param->ref_frame_sign_bias_altref; - } - - if (VPUClientGetIOMMUStatus() > 0) { - regs->reg149_segment_map_base = regs->reg149_segment_map_base | - ((pic_param->stVP8Segments.segmentation_enabled + (pic_param->stVP8Segments.update_mb_segmentation_map << 1)) << 10); - } else { - regs->reg149_segment_map_base = regs->reg149_segment_map_base + - (pic_param->stVP8Segments.segmentation_enabled + (pic_param->stVP8Segments.update_mb_segmentation_map << 1)); - } - -#endif - regs->reg57_enable_ctrl.sw_pic_inter_e = pic_param->frame_type; - regs->reg50_dec_ctrl.sw_skip_mode = !pic_param->mb_no_coeff_skip; - - if (!pic_param->stVP8Segments.segmentation_enabled) { - regs->reg129.sw_filt_level_0 = pic_param->filter_level; - } else if (pic_param->stVP8Segments.update_mb_segmentation_data) { - regs->reg129.sw_filt_level_0 = pic_param->stVP8Segments.segment_feature_data[1][0]; - regs->reg129.sw_filt_level_1 = pic_param->stVP8Segments.segment_feature_data[1][1]; - regs->reg129.sw_filt_level_2 = pic_param->stVP8Segments.segment_feature_data[1][2]; - regs->reg129.sw_filt_level_3 = pic_param->stVP8Segments.segment_feature_data[1][3]; - } else { - regs->reg129.sw_filt_level_0 = CLIP3(0, 63, (RK_S32)pic_param->filter_level + pic_param->stVP8Segments.segment_feature_data[1][0]); - regs->reg129.sw_filt_level_1 = CLIP3(0, 63, (RK_S32)pic_param->filter_level + pic_param->stVP8Segments.segment_feature_data[1][1]); - regs->reg129.sw_filt_level_2 = CLIP3(0, 63, (RK_S32)pic_param->filter_level + pic_param->stVP8Segments.segment_feature_data[1][2]); - regs->reg129.sw_filt_level_3 = CLIP3(0, 63, (RK_S32)pic_param->filter_level + pic_param->stVP8Segments.segment_feature_data[1][3]); - } - - regs->reg132.sw_filt_type = pic_param->filter_type; - regs->reg132.sw_filt_sharpness = pic_param->sharpness; - - if (pic_param->filter_level == 0) { - regs->reg50_dec_ctrl.sw_filtering_dis = 1; - } - - if (pic_param->version != 3) { - regs->reg121.sw_romain_mv = 1; - } - - if (pic_param->decMode == VP8HWD_VP8 && (pic_param->version & 0x3)) { - regs->reg121.sw_eable_bilinear = 1; - } - regs->reg122.sw_boolean_value = pic_param->bool_value; - regs->reg122.sw_boolean_range = pic_param->bool_range; - - { - if (!pic_param->stVP8Segments.segmentation_enabled) - regs->reg130.sw_quant_0 = pic_param->y1ac_delta_q; - else if (pic_param->stVP8Segments.update_mb_segmentation_data) { /* absolute mode */ - regs->reg130.sw_quant_0 = pic_param->stVP8Segments.segment_feature_data[0][0]; - regs->reg130.sw_quant_1 = pic_param->stVP8Segments.segment_feature_data[0][1]; - regs->reg151.sw_quant_2 = pic_param->stVP8Segments.segment_feature_data[0][2]; - regs->reg151.sw_quant_3 = pic_param->stVP8Segments.segment_feature_data[0][3]; - } else { /* delta mode */ - regs->reg130.sw_quant_0 = CLIP3(0, 127, pic_param->y1ac_delta_q + pic_param->stVP8Segments.segment_feature_data[0][0]); - regs->reg130.sw_quant_1 = CLIP3(0, 127, pic_param->y1ac_delta_q + pic_param->stVP8Segments.segment_feature_data[0][1]); - regs->reg151.sw_quant_2 = CLIP3(0, 127, pic_param->y1ac_delta_q + pic_param->stVP8Segments.segment_feature_data[0][2]); - regs->reg151.sw_quant_3 = CLIP3(0, 127, pic_param->y1ac_delta_q + pic_param->stVP8Segments.segment_feature_data[0][3]); - } - - regs->reg130.sw_quant_delta_0 = pic_param->y1dc_delta_q; - regs->reg130.sw_quant_delta_1 = pic_param->y2dc_delta_q; - regs->reg151.sw_quant_delta_2 = pic_param->y2ac_delta_q; - regs->reg151.sw_quant_delta_3 = pic_param->uvdc_delta_q; - regs->reg152.sw_quant_delta_4 = pic_param->uvac_delta_q; - - if (pic_param->mode_ref_lf_delta_enabled) { - regs->reg133.sw_filt_ref_adj_0 = pic_param->ref_lf_deltas[0]; - regs->reg133.sw_filt_ref_adj_1 = pic_param->ref_lf_deltas[1]; - regs->reg133.sw_filt_ref_adj_2 = pic_param->ref_lf_deltas[2]; - regs->reg133.sw_filt_ref_adj_3 = pic_param->ref_lf_deltas[3]; - regs->reg132.sw_filt_mb_adj_0 = pic_param->mode_lf_deltas[0]; - regs->reg132.sw_filt_mb_adj_1 = pic_param->mode_lf_deltas[1]; - regs->reg132.sw_filt_mb_adj_2 = pic_param->mode_lf_deltas[2]; - regs->reg132.sw_filt_mb_adj_3 = pic_param->mode_lf_deltas[3]; - } - - } - - if ((pic_param->version & 0x3) == 0) - hal_vp8d_pre_filter_tap_set(ctx); - - hal_vp8d_dct_partition_cfg(ctx, task); - regs->reg57_enable_ctrl.sw_dec_e = 1; - - FUN_T("FUN_OUT"); - return ret; -} - -MPP_RET hal_vp8d_start(void *hal, HalTaskInfo *task) -{ - MPP_RET ret = MPP_OK; - -#ifdef RKPLATFORM - RK_U32 i = 0; - VP8DHalContext_t *ctx = (VP8DHalContext_t *)hal; - VP8DRegSet_t *regs = (VP8DRegSet_t *)ctx->regs; - RK_U8 *p = ctx->regs; - - - FUN_T("FUN_IN"); - - for (i = 0; i < 159; i++) { - vp8h_dbg(VP8H_DBG_REG, "vp8d: regs[%02d]=%08X\n", i, *((RK_U32*)p)); - // mpp_log("vp8d: regs[%02d]=%08X\n", i, *((RK_U32*)p)); - p += 4; - } - ret = VPUClientSendReg(ctx->vpu_socket, (RK_U32 *)regs, VP8D_REG_NUM); - if (ret != 0) { - mpp_err("VPUClientSendReg Failed!!!\n"); - return MPP_ERR_VPUHW; - } - - FUN_T("FUN_OUT"); -#endif - (void)task; - (void)hal; - return ret; -} - -MPP_RET hal_vp8d_wait(void *hal, HalTaskInfo *task) -{ - MPP_RET ret = MPP_OK; -#ifdef RKPLATFORM - VP8DRegSet_t reg_out; - VPU_CMD_TYPE cmd = 0; - RK_S32 length = 0; - VP8DHalContext_t *ctx = (VP8DHalContext_t *)hal; - FUN_T("FUN_IN"); - memset(®_out, 0, sizeof(VP8DRegSet_t)); - ret = VPUClientWaitResult(ctx->vpu_socket, (RK_U32 *)®_out, - VP8D_REG_NUM, &cmd, &length); - FUN_T("FUN_OUT"); -#endif - (void)hal; - (void)task; - return ret; -} - -MPP_RET hal_vp8d_reset(void *hal) -{ - MPP_RET ret = MPP_OK; - - FUN_T("FUN_IN"); - (void)hal; - FUN_T("FUN_OUT"); - return ret; -} - -MPP_RET hal_vp8d_flush(void *hal) -{ - MPP_RET ret = MPP_OK; - - FUN_T("FUN_IN"); - (void)hal; - FUN_T("FUN_OUT"); - return ret; -} - -MPP_RET hal_vp8d_control(void *hal, RK_S32 cmd_type, void *param) -{ - MPP_RET ret = MPP_OK; - - FUN_T("FUN_IN"); - (void)hal; - (void)cmd_type; - (void)param; - FUN_T("FUN_OUT"); - return ret; -} +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define MODULE_TAG "hal_vp8d_reg" +#include + +#include "mpp_log.h" +#include "mpp_env.h" +#include "mpp_mem.h" + +#include "vpu.h" +#include "hal_vp8d_reg.h" + + +RK_U32 vp8h_debug = 0; + +#define VP8HWD_VP7 1 +#define VP8HWD_VP8 2 +#define VP8HWD_WEBP 3 + +#define DEC_MODE_VP7 9 +#define DEC_MODE_VP8 10 + +#define VP8D_PROB_TABLE_SIZE (1<<16) /* TODO */ +#define VP8D_MAX_SEGMAP_SIZE (2048 + 1024) //1920*1080 /* TODO */ +#define FUN_T(tag) \ + do {\ + if (VP8H_DBG_FUNCTION & vp8h_debug)\ + { mpp_log("%s: line(%d), func(%s)", tag, __LINE__, __FUNCTION__); }\ + } while (0) + +/* VP7 QP LUTs */ +static const RK_U16 YDcQLookup[128] = { + 4, 4, 5, 6, 6, 7, 8, 8, + 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 23, + 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 33, 34, 35, 36, 36, 37, + 38, 39, 39, 40, 41, 41, 42, 43, + 43, 44, 45, 45, 46, 47, 48, 48, + 49, 50, 51, 52, 53, 53, 54, 56, + 57, 58, 59, 60, 62, 63, 65, 66, + 68, 70, 72, 74, 76, 79, 81, 84, + 87, 90, 93, 96, 100, 104, 108, 112, + 116, 121, 126, 131, 136, 142, 148, 154, + 160, 167, 174, 182, 189, 198, 206, 215, + 224, 234, 244, 254, 265, 277, 288, 301, + 313, 327, 340, 355, 370, 385, 401, 417, + 434, 452, 470, 489, 509, 529, 550, 572 +}; + +static const RK_U16 YAcQLookup[128] = { + 4, 4, 5, 5, 6, 6, 7, 8, + 9, 10, 11, 12, 13, 15, 16, 17, + 19, 20, 22, 23, 25, 26, 28, 29, + 31, 32, 34, 35, 37, 38, 40, 41, + 42, 44, 45, 46, 48, 49, 50, 51, + 53, 54, 55, 56, 57, 58, 59, 61, + 62, 63, 64, 65, 67, 68, 69, 70, + 72, 73, 75, 76, 78, 80, 82, 84, + 86, 88, 91, 93, 96, 99, 102, 105, + 109, 112, 116, 121, 125, 130, 135, 140, + 146, 152, 158, 165, 172, 180, 188, 196, + 205, 214, 224, 234, 245, 256, 268, 281, + 294, 308, 322, 337, 353, 369, 386, 404, + 423, 443, 463, 484, 506, 529, 553, 578, + 604, 631, 659, 688, 718, 749, 781, 814, + 849, 885, 922, 960, 1000, 1041, 1083, 1127 + +}; + +static const RK_U16 Y2DcQLookup[128] = { + 7, 9, 11, 13, 15, 17, 19, 21, + 23, 26, 28, 30, 33, 35, 37, 39, + 42, 44, 46, 48, 51, 53, 55, 57, + 59, 61, 63, 65, 67, 69, 70, 72, + 74, 75, 77, 78, 80, 81, 83, 84, + 85, 87, 88, 89, 90, 92, 93, 94, + 95, 96, 97, 99, 100, 101, 102, 104, + 105, 106, 108, 109, 111, 113, 114, 116, + 118, 120, 123, 125, 128, 131, 134, 137, + 140, 144, 148, 152, 156, 161, 166, 171, + 176, 182, 188, 195, 202, 209, 217, 225, + 234, 243, 253, 263, 274, 285, 297, 309, + 322, 336, 350, 365, 381, 397, 414, 432, + 450, 470, 490, 511, 533, 556, 579, 604, + 630, 656, 684, 713, 742, 773, 805, 838, + 873, 908, 945, 983, 1022, 1063, 1105, 1148 +}; + +static const RK_U16 Y2AcQLookup[128] = { + 7, 9, 11, 13, 16, 18, 21, 24, + 26, 29, 32, 35, 38, 41, 43, 46, + 49, 52, 55, 58, 61, 64, 66, 69, + 72, 74, 77, 79, 82, 84, 86, 88, + 91, 93, 95, 97, 98, 100, 102, 104, + 105, 107, 109, 110, 112, 113, 115, 116, + 117, 119, 120, 122, 123, 125, 127, 128, + 130, 132, 134, 136, 138, 141, 143, 146, + 149, 152, 155, 158, 162, 166, 171, 175, + 180, 185, 191, 197, 204, 210, 218, 226, + 234, 243, 252, 262, 273, 284, 295, 308, + 321, 335, 350, 365, 381, 398, 416, 435, + 455, 476, 497, 520, 544, 569, 595, 622, + 650, 680, 711, 743, 776, 811, 848, 885, + 925, 965, 1008, 1052, 1097, 1144, 1193, 1244, + 1297, 1351, 1407, 1466, 1526, 1588, 1652, 1719 +}; + +static const RK_U16 UvDcQLookup[128] = { + 4, 4, 5, 6, 6, 7, 8, 8, + 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 23, + 24, 25, 26, 27, 28, 29, 30, 31, + 32, 33, 33, 34, 35, 36, 36, 37, + 38, 39, 39, 40, 41, 41, 42, 43, + 43, 44, 45, 45, 46, 47, 48, 48, + 49, 50, 51, 52, 53, 53, 54, 56, + 57, 58, 59, 60, 62, 63, 65, 66, + 68, 70, 72, 74, 76, 79, 81, 84, + 87, 90, 93, 96, 100, 104, 108, 112, + 116, 121, 126, 131, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132, + 132, 132, 132, 132, 132, 132, 132, 132 +}; + + +static const RK_U16 UvAcQLookup[128] = { + 4, 4, 5, 5, 6, 6, 7, 8, + 9, 10, 11, 12, 13, 15, 16, 17, + 19, 20, 22, 23, 25, 26, 28, 29, + 31, 32, 34, 35, 37, 38, 40, 41, + 42, 44, 45, 46, 48, 49, 50, 51, + 53, 54, 55, 56, 57, 58, 59, 61, + 62, 63, 64, 65, 67, 68, 69, 70, + 72, 73, 75, 76, 78, 80, 82, 84, + 86, 88, 91, 93, 96, 99, 102, 105, + 109, 112, 116, 121, 125, 130, 135, 140, + 146, 152, 158, 165, 172, 180, 188, 196, + 205, 214, 224, 234, 245, 256, 268, 281, + 294, 308, 322, 337, 353, 369, 386, 404, + 423, 443, 463, 484, 506, 529, 553, 578, + 604, 631, 659, 688, 718, 749, 781, 814, + 849, 885, 922, 960, 1000, 1041, 1083, 1127 +}; + +#define CLIP3(l, h, v) ((v) < (l) ? (l) : ((v) > (h) ? (h) : (v))) + +static const RK_U32 mcFilter[8][6] = { + { 0, 0, 128, 0, 0, 0 }, + { 0, -6, 123, 12, -1, 0 }, + { 2, -11, 108, 36, -8, 1 }, + { 0, -9, 93, 50, -6, 0 }, + { 3, -16, 77, 77, -16, 3 }, + { 0, -6, 50, 93, -9, 0 }, + { 1, -8, 36, 108, -11, 2 }, + { 0, -1, 12, 123, -6, 0 } +}; + +MPP_RET hal_vp8d_init(void *hal, MppHalCfg *cfg) +{ + MPP_RET ret = MPP_OK; + VP8DHalContext_t *ctx = (VP8DHalContext_t *)hal; + + FUN_T("FUN_IN"); + //configure + ctx->packet_slots = cfg->packet_slots; + ctx->frame_slots = cfg->frame_slots; + + mpp_env_get_u32("vp8h_debug", &vp8h_debug, 0); + //get vpu socket +#ifdef RKPLATFORM + if (ctx->vpu_socket <= 0) { + ctx->vpu_socket = VPUClientInit(VPU_DEC); + if (ctx->vpu_socket <= 0) { + mpp_err("get vpu_socket(%d) <=0, failed. \n", ctx->vpu_socket); + + FUN_T("FUN_OUT"); + return MPP_ERR_UNKNOW; + } else { + mpp_log("get vpu_socket(%d), success. \n", ctx->vpu_socket); + } + } +#endif + if (NULL == ctx->regs) { + ctx->regs = mpp_calloc_size(void, sizeof(VP8DRegSet_t)); + if (NULL == ctx->regs) { + mpp_err("hal_vp8 reg alloc failed\n"); + + FUN_T("FUN_OUT"); + return MPP_ERR_NOMEM; + } + } + + if (NULL == ctx->group) { +#ifdef RKPLATFORM + mpp_err("mpp_buffer_group_get_internal used ion in"); + ret = mpp_buffer_group_get_internal(&ctx->group, MPP_BUFFER_TYPE_ION); +#else + ret = mpp_buffer_group_get_internal(&ctx->group, MPP_BUFFER_TYPE_NORMAL); +#endif + if (MPP_OK != ret) { + mpp_err("hal_vp8 mpp_buffer_group_get failed\n"); + + FUN_T("FUN_OUT"); + return ret; + } + } + ret = mpp_buffer_get(ctx->group, &ctx->probe_table, VP8D_PROB_TABLE_SIZE); + if (MPP_OK != ret) { + mpp_err("hal_vp8 probe_table get buffer failed\n"); + + FUN_T("FUN_OUT"); + return ret; + } + + ret = mpp_buffer_get(ctx->group, &ctx->seg_map, VP8D_MAX_SEGMAP_SIZE); + + if (MPP_OK != ret) { + mpp_err("hal_vp8 seg_map get buffer failed\n"); + FUN_T("FUN_OUT"); + return ret; + } + + return ret; +} + +MPP_RET hal_vp8d_deinit(void *hal) +{ + MPP_RET ret = MPP_OK; + + FUN_T("FUN_IN"); + VP8DHalContext_t *ctx = (VP8DHalContext_t *)hal; +#ifdef RKPLATFORM + if (ctx->vpu_socket >= 0) { + VPUClientRelease(ctx->vpu_socket); + + } +#endif + if (ctx->probe_table) { + ret = mpp_buffer_put(ctx->probe_table); + if (MPP_OK != ret) { + mpp_err("hal_vp8 probe table put buffer failed\n"); + } + } + + if (ctx->seg_map) { + ret = mpp_buffer_put(ctx->seg_map); + if (MPP_OK != ret) { + mpp_err("hal_vp8 seg map put buffer failed\n"); + } + } + + if (ctx->group) { + ret = mpp_buffer_group_put(ctx->group); + if (MPP_OK != ret) { + mpp_err("hal_vp8 group free buffer failed\n"); + } + } + + if (ctx->regs) { + mpp_free(ctx->regs); + ctx->regs = NULL; + } + + FUN_T("FUN_OUT"); + return ret; +} + +MPP_RET hal_vp8_init_hwcfg(VP8DHalContext_t *ctx) +{ + + VP8DRegSet_t *reg = (VP8DRegSet_t *)ctx->regs; + + FUN_T("FUN_IN"); + memset(reg, 0, sizeof(VP8DRegSet_t)); + reg->reg50_dec_ctrl.sw_dec_out_tiled_e = 0; + reg->reg50_dec_ctrl.sw_dec_scmd_dis = 0; + reg->reg50_dec_ctrl.sw_dec_adv_pre_dis = 0; + reg->reg50_dec_ctrl.sw_dec_latency = 0; + + reg->reg53_dec_mode = DEC_MODE_VP8; + + reg->reg54_endian.sw_dec_in_endian = 1; + reg->reg54_endian.sw_dec_out_endian = 1; + reg->reg54_endian.sw_dec_inswap32_e = 1; + reg->reg54_endian.sw_dec_outswap32_e = 1; + reg->reg54_endian.sw_dec_strswap32_e = 1; + reg->reg54_endian.sw_dec_strendian_e = 1; + + reg->reg55_Interrupt.sw_dec_irq = 0; + + reg->reg56_axi_ctrl.sw_dec_axi_rn_id = 0; + reg->reg56_axi_ctrl.sw_dec_axi_wr_id = 0; + + reg->reg56_axi_ctrl.sw_dec_data_disc_e = 0; + reg->reg56_axi_ctrl.sw_dec_max_burst = 16; + reg->reg57_enable_ctrl.sw_dec_timeout_e = 1; + reg->reg57_enable_ctrl.sw_dec_clk_gate_e = 1; + reg->reg57_enable_ctrl.sw_dec_out_dis = 0; + +#ifdef RKPLATFORM + reg->reg149_segment_map_base = mpp_buffer_get_fd(ctx->seg_map); + reg->reg61_qtable_base = mpp_buffer_get_fd(ctx->probe_table); +#endif + + FUN_T("FUN_OUT"); + return MPP_OK; +} + +MPP_RET hal_vp8d_pre_filter_tap_set(VP8DHalContext_t *ctx) +{ + VP8DRegSet_t *regs = (VP8DRegSet_t *)ctx->regs; + + FUN_T("FUN_IN"); + regs->reg59.sw_pred_bc_tap_0_0 = mcFilter[0][1]; + regs->reg59.sw_pred_bc_tap_0_1 = mcFilter[0][2]; + regs->reg59.sw_pred_bc_tap_0_2 = mcFilter[0][3]; + regs->reg153.sw_pred_bc_tap_0_3 = mcFilter[0][4]; + regs->reg153.sw_pred_bc_tap_1_0 = mcFilter[1][1]; + regs->reg153.sw_pred_bc_tap_1_1 = mcFilter[1][2]; + regs->reg154.sw_pred_bc_tap_1_2 = mcFilter[1][3]; + regs->reg154.sw_pred_bc_tap_1_3 = mcFilter[1][4]; + regs->reg154.sw_pred_bc_tap_2_0 = mcFilter[2][1]; + regs->reg155.sw_pred_bc_tap_2_1 = mcFilter[2][2]; + regs->reg155.sw_pred_bc_tap_2_2 = mcFilter[2][3]; + regs->reg155.sw_pred_bc_tap_2_3 = mcFilter[2][4]; + + regs->reg156.sw_pred_bc_tap_3_0 = mcFilter[3][1]; + regs->reg156.sw_pred_bc_tap_3_1 = mcFilter[3][2]; + regs->reg156.sw_pred_bc_tap_3_2 = mcFilter[3][3]; + regs->reg157.sw_pred_bc_tap_3_3 = mcFilter[3][4]; + regs->reg157.sw_pred_bc_tap_4_0 = mcFilter[4][1]; + regs->reg157.sw_pred_bc_tap_4_1 = mcFilter[4][2]; + regs->reg158.sw_pred_bc_tap_4_2 = mcFilter[4][3]; + regs->reg158.sw_pred_bc_tap_4_3 = mcFilter[4][4]; + regs->reg158.sw_pred_bc_tap_5_0 = mcFilter[5][1]; + + regs->reg125.sw_pred_bc_tap_5_1 = mcFilter[5][2]; + + regs->reg125.sw_pred_bc_tap_5_2 = mcFilter[5][3]; + + regs->reg125.sw_pred_bc_tap_5_3 = mcFilter[5][4]; + regs->reg126.sw_pred_bc_tap_6_0 = mcFilter[6][1]; + regs->reg126.sw_pred_bc_tap_6_1 = mcFilter[6][2]; + regs->reg126.sw_pred_bc_tap_6_2 = mcFilter[6][3]; + regs->reg127.sw_pred_bc_tap_6_3 = mcFilter[6][4]; + regs->reg127.sw_pred_bc_tap_7_0 = mcFilter[7][1]; + regs->reg127.sw_pred_bc_tap_7_1 = mcFilter[7][2]; + regs->reg128.sw_pred_bc_tap_7_2 = mcFilter[7][3]; + regs->reg128.sw_pred_bc_tap_7_3 = mcFilter[7][4]; + + regs->reg128.sw_pred_tap_2_M1 = mcFilter[2][0]; + regs->reg128.sw_pred_tap_2_4 = mcFilter[2][5]; + regs->reg128.sw_pred_tap_4_M1 = mcFilter[4][0]; + regs->reg128.sw_pred_tap_4_4 = mcFilter[4][5]; + regs->reg128.sw_pred_tap_6_M1 = mcFilter[6][0]; + regs->reg128.sw_pred_tap_6_4 = mcFilter[6][5]; + + FUN_T("FUN_OUT"); + return MPP_OK; +} + +MPP_RET hal_vp8d_dct_partition_cfg(VP8DHalContext_t *ctx, HalTaskInfo *task) +{ + RK_U32 i = 0, len = 0, len1 = 0; + RK_U32 extraBytesPacked = 0; + RK_U32 addr = 0, byte_offset = 0; +#ifdef RKPLATFORM + RK_U32 fd = 0; + MppBuffer streambuf = NULL; +#endif + VP8DRegSet_t *regs = (VP8DRegSet_t *)ctx->regs; + DXVA_PicParams_VP8 *pic_param = (DXVA_PicParams_VP8 *)task->dec.syntax.data; + + + FUN_T("FUN_IN"); +#ifdef RKPLATFORM + mpp_buf_slot_get_prop(ctx->packet_slots, task->dec.input, SLOT_BUFFER, &streambuf); + fd = mpp_buffer_get_fd(streambuf); + regs->reg145_bitpl_ctrl_base = fd; + if (VPUClientGetIOMMUStatus() > 0) { + regs->reg145_bitpl_ctrl_base |= (pic_param->stream_start_offset << 10); + } else { + regs->reg145_bitpl_ctrl_base += pic_param->stream_start_offset; + } + regs->reg122.sw_strm1_start_bit = pic_param->stream_start_bit; +#endif + /* calculate dct partition length here instead */ + if (pic_param->decMode == VP8HWD_VP8 && !pic_param->frame_type) + extraBytesPacked += 7; + len = pic_param->streamEndPos + pic_param->frameTagSize - pic_param->dctPartitionOffsets[0]; + len += ( (1 << pic_param->log2_nbr_of_dct_partitions) - 1) * 3; + len1 = extraBytesPacked + pic_param->dctPartitionOffsets[0]; + len += (len1 & 0x7); + regs->reg51_stream_info.sw_stream_len = len; + + //mpp_log("offsetToDctParts = %d pic_param->frameTagSize %d pic_param->stream_start_offset = %d extraBytesPacked = %d", + // pic_param->offsetToDctParts,pic_param->frameTagSize , + // pic_param->stream_start_offset,extraBytesPacked); + + len = pic_param->offsetToDctParts + pic_param->frameTagSize - + (pic_param->stream_start_offset - extraBytesPacked); + if (pic_param->decMode == VP8HWD_VP7) /* give extra byte for VP7 to pass test cases */ + len ++; + + regs->reg124.sw_stream1_len = len; + regs->reg124.sw_coeffs_part_am = (1 << pic_param->log2_nbr_of_dct_partitions) - 1; + for (i = 0; i < (RK_U32)(1 << pic_param->log2_nbr_of_dct_partitions); i++) { + addr = extraBytesPacked + pic_param->dctPartitionOffsets[i]; + byte_offset = addr & 0x7; + addr = addr & 0xFFFFFFF8; +#ifdef RKPLATFORM + if ( i == 0) { + if (VPUClientGetIOMMUStatus() > 0) { + regs->reg64_input_stream_base = fd | (addr << 10); + } else { + regs->reg_dct_strm_base[i] = fd + addr; + } + } else if ( i <= 5) { + if (VPUClientGetIOMMUStatus() > 0) { + regs->reg_dct_strm_base[i] = fd | (addr << 10); + } else { + regs->reg_dct_strm_base[i] = fd + addr; + } + } else { + if (VPUClientGetIOMMUStatus() > 0) { + regs->reg_dct_strm1_base[i - 6] = fd | (addr << 10); + } else { + regs->reg_dct_strm_base[i - 6] = fd + addr; + } + } +#endif + switch (i) { + case 0: + regs->reg122.sw_strm_start_bit = byte_offset * 8; + break; + case 1: + regs->reg121.sw_dct1_start_bit = byte_offset * 8; + break; + case 2: + regs->reg121.sw_dct2_start_bit = byte_offset * 8; + break; + case 3: + regs->reg150.sw_dct_start_bit_3 = byte_offset * 8; + break; + case 4: + regs->reg150.sw_dct_start_bit_4 = byte_offset * 8; + break; + case 5: + regs->reg150.sw_dct_start_bit_5 = byte_offset * 8; + break; + case 6: + regs->reg150.sw_dct_start_bit_6 = byte_offset * 8; + break; + case 7: + regs->reg150.sw_dct_start_bit_6 = byte_offset * 8; + break; + default: + break; + } + } + + FUN_T("FUN_OUT"); + return MPP_OK; +} +void hal_vp8hw_asic_probe_update(DXVA_PicParams_VP8 *p, RK_U8 *probTbl) +{ + RK_U8 *dst; + RK_U32 i, j, k; + + FUN_T("FUN_IN"); + /* first probs */ + dst = probTbl; + + dst[0] = p->probe_skip_false; + dst[1] = p->prob_intra; + dst[2] = p->prob_last; + dst[3] = p->prob_golden; + dst[4] = p->stVP8Segments.mb_segment_tree_probs[0]; + dst[5] = p->stVP8Segments.mb_segment_tree_probs[1]; + dst[6] = p->stVP8Segments.mb_segment_tree_probs[2]; + dst[7] = 0; /*unused*/ + + dst += 8; + dst[0] = p->intra_16x16_prob[0]; + dst[1] = p->intra_16x16_prob[1]; + dst[2] = p->intra_16x16_prob[2]; + dst[3] = p->intra_16x16_prob[3]; + dst[4] = p->intra_chroma_prob[0]; + dst[5] = p->intra_chroma_prob[1]; + dst[6] = p->intra_chroma_prob[2]; + dst[7] = 0; /*unused*/ + + /* mv probs */ + dst += 8; + dst[0] = p->vp8_mv_update_probs[0][0]; /* is short */ + dst[1] = p->vp8_mv_update_probs[1][0]; + dst[2] = p->vp8_mv_update_probs[0][1]; /* sign */ + dst[3] = p->vp8_mv_update_probs[1][1]; + dst[4] = p->vp8_mv_update_probs[0][8 + 9]; + dst[5] = p->vp8_mv_update_probs[0][9 + 9]; + dst[6] = p->vp8_mv_update_probs[1][8 + 9]; + dst[7] = p->vp8_mv_update_probs[1][9 + 9]; + dst += 8; + for ( i = 0 ; i < 2 ; ++i ) { + for ( j = 0 ; j < 8 ; j += 4 ) { + dst[0] = p->vp8_mv_update_probs[i][j + 9 + 0]; + dst[1] = p->vp8_mv_update_probs[i][j + 9 + 1]; + dst[2] = p->vp8_mv_update_probs[i][j + 9 + 2]; + dst[3] = p->vp8_mv_update_probs[i][j + 9 + 3]; + dst += 4; + } + } + for ( i = 0 ; i < 2 ; ++i ) { + dst[0] = p->vp8_mv_update_probs[i][0 + 2]; + dst[1] = p->vp8_mv_update_probs[i][1 + 2]; + dst[2] = p->vp8_mv_update_probs[i][2 + 2]; + dst[3] = p->vp8_mv_update_probs[i][3 + 2]; + dst[4] = p->vp8_mv_update_probs[i][4 + 2]; + dst[5] = p->vp8_mv_update_probs[i][5 + 2]; + dst[6] = p->vp8_mv_update_probs[i][6 + 2]; + dst[7] = 0; /*unused*/ + dst += 8; + } + + /* coeff probs (header part) */ + dst = (RK_U8*)probTbl; + dst += (8 * 7); + for ( i = 0 ; i < 4 ; ++i ) { + for ( j = 0 ; j < 8 ; ++j ) { + for ( k = 0 ; k < 3 ; ++k ) { + dst[0] = p->vp8_coef_update_probs[i][j][k][0]; + dst[1] = p->vp8_coef_update_probs[i][j][k][1]; + dst[2] = p->vp8_coef_update_probs[i][j][k][2]; + dst[3] = p->vp8_coef_update_probs[i][j][k][3]; + dst += 4; + } + } + } + + /* coeff probs (footer part) */ + dst = (RK_U8*)probTbl; + dst += (8 * 55); + for ( i = 0 ; i < 4 ; ++i ) { + for ( j = 0 ; j < 8 ; ++j ) { + for ( k = 0 ; k < 3 ; ++k ) { + dst[0] = p->vp8_coef_update_probs[i][j][k][4]; + dst[1] = p->vp8_coef_update_probs[i][j][k][5]; + dst[2] = p->vp8_coef_update_probs[i][j][k][6]; + dst[3] = p->vp8_coef_update_probs[i][j][k][7]; + dst[4] = p->vp8_coef_update_probs[i][j][k][8]; + dst[5] = p->vp8_coef_update_probs[i][j][k][9]; + dst[6] = p->vp8_coef_update_probs[i][j][k][10]; + dst[7] = 0; /*unused*/ + dst += 8; + } + } + } + FUN_T("FUN_OUT"); + return ; +} +MPP_RET hal_vp8d_gen_regs(void* hal, HalTaskInfo *task) +{ + MPP_RET ret = MPP_OK; + RK_U32 mb_width = 0, mb_height = 0; +#ifdef RKPLATFORM + MppBuffer framebuf = NULL; + RK_U8 *segmap_ptr = NULL; + RK_U8 *probe_ptr = NULL; +#endif + VP8DHalContext_t *ctx = (VP8DHalContext_t *)hal; + VP8DRegSet_t *regs = (VP8DRegSet_t *)ctx->regs; + DXVA_PicParams_VP8 *pic_param = (DXVA_PicParams_VP8 *)task->dec.syntax.data; + + FUN_T("FUN_IN"); + hal_vp8_init_hwcfg(ctx); + mb_width = (pic_param->width + 15) >> 4; + mb_height = (pic_param->height + 15) >> 4; + // mpp_log("mb_width = %d mb_height = %d", mb_width, mb_height); + regs->reg120.sw_pic_mb_width = mb_width & 0x1FF; + regs->reg120.sw_pic_mb_hight_p = mb_height & 0xFF; + regs->reg120.sw_pic_mb_w_ext = mb_width >> 9; + regs->reg120.sw_pic_mb_h_ext = mb_height >> 8; + +#ifdef RKPLATFORM + if (!pic_param->frame_type) { + segmap_ptr = mpp_buffer_get_ptr(ctx->seg_map); + if (NULL != segmap_ptr) { + memset(segmap_ptr, 0, VP8D_MAX_SEGMAP_SIZE); + } + } + + probe_ptr = mpp_buffer_get_ptr(ctx->probe_table); + if (NULL != probe_ptr) { + hal_vp8hw_asic_probe_update(pic_param, probe_ptr); + } + mpp_buf_slot_get_prop(ctx->frame_slots, pic_param->CurrPic.Index7Bits, SLOT_BUFFER, &framebuf); + regs->reg63_cur_pic_base = mpp_buffer_get_fd(framebuf); + if (!pic_param->frame_type) { //key frame + if ((mb_width * mb_height) << 8 > 0x400000) { + mpp_log("mb_width*mb_height is big then 0x400000,iommu err"); + } + regs->reg131_ref0_base = regs->reg63_cur_pic_base | ((mb_width * mb_height) << 18); + } else if (pic_param->lst_fb_idx.Index7Bits < 0x7f) { //config ref0 base + mpp_buf_slot_get_prop(ctx->frame_slots, pic_param->lst_fb_idx.Index7Bits, SLOT_BUFFER, &framebuf); + regs->reg131_ref0_base = mpp_buffer_get_fd(framebuf); + } else { + regs->reg131_ref0_base = regs->reg63_cur_pic_base; + } + + /* golden reference */ + if (pic_param->gld_fb_idx.Index7Bits < 0x7f) { + mpp_buf_slot_get_prop(ctx->frame_slots, pic_param->gld_fb_idx.Index7Bits, SLOT_BUFFER, &framebuf); + regs->reg136_golden_ref_base = mpp_buffer_get_fd(framebuf); + } else { + regs->reg136_golden_ref_base = regs->reg63_cur_pic_base; + } + + if (VPUClientGetIOMMUStatus() > 0) { + regs->reg136_golden_ref_base = regs->reg136_golden_ref_base | (pic_param->ref_frame_sign_bias_golden << 10); + } else { + regs->reg136_golden_ref_base = regs->reg136_golden_ref_base + pic_param->ref_frame_sign_bias_golden; + } + + /* alternate reference */ + if (pic_param->alt_fb_idx.Index7Bits < 0x7f) { + mpp_buf_slot_get_prop(ctx->frame_slots, pic_param->alt_fb_idx.Index7Bits, SLOT_BUFFER, &framebuf); + regs->reg137.alternate_ref_base = mpp_buffer_get_fd(framebuf); + } else { + regs->reg137.alternate_ref_base = regs->reg63_cur_pic_base; + } + + if (VPUClientGetIOMMUStatus() > 0) { + regs->reg137.alternate_ref_base = regs->reg137.alternate_ref_base | (pic_param->ref_frame_sign_bias_altref << 10); + } else { + regs->reg137.alternate_ref_base = regs->reg137.alternate_ref_base + pic_param->ref_frame_sign_bias_altref; + } + + if (VPUClientGetIOMMUStatus() > 0) { + regs->reg149_segment_map_base = regs->reg149_segment_map_base | + ((pic_param->stVP8Segments.segmentation_enabled + (pic_param->stVP8Segments.update_mb_segmentation_map << 1)) << 10); + } else { + regs->reg149_segment_map_base = regs->reg149_segment_map_base + + (pic_param->stVP8Segments.segmentation_enabled + (pic_param->stVP8Segments.update_mb_segmentation_map << 1)); + } + +#endif + regs->reg57_enable_ctrl.sw_pic_inter_e = pic_param->frame_type; + regs->reg50_dec_ctrl.sw_skip_mode = !pic_param->mb_no_coeff_skip; + + if (!pic_param->stVP8Segments.segmentation_enabled) { + regs->reg129.sw_filt_level_0 = pic_param->filter_level; + } else if (pic_param->stVP8Segments.update_mb_segmentation_data) { + regs->reg129.sw_filt_level_0 = pic_param->stVP8Segments.segment_feature_data[1][0]; + regs->reg129.sw_filt_level_1 = pic_param->stVP8Segments.segment_feature_data[1][1]; + regs->reg129.sw_filt_level_2 = pic_param->stVP8Segments.segment_feature_data[1][2]; + regs->reg129.sw_filt_level_3 = pic_param->stVP8Segments.segment_feature_data[1][3]; + } else { + regs->reg129.sw_filt_level_0 = CLIP3(0, 63, (RK_S32)pic_param->filter_level + pic_param->stVP8Segments.segment_feature_data[1][0]); + regs->reg129.sw_filt_level_1 = CLIP3(0, 63, (RK_S32)pic_param->filter_level + pic_param->stVP8Segments.segment_feature_data[1][1]); + regs->reg129.sw_filt_level_2 = CLIP3(0, 63, (RK_S32)pic_param->filter_level + pic_param->stVP8Segments.segment_feature_data[1][2]); + regs->reg129.sw_filt_level_3 = CLIP3(0, 63, (RK_S32)pic_param->filter_level + pic_param->stVP8Segments.segment_feature_data[1][3]); + } + + regs->reg132.sw_filt_type = pic_param->filter_type; + regs->reg132.sw_filt_sharpness = pic_param->sharpness; + + if (pic_param->filter_level == 0) { + regs->reg50_dec_ctrl.sw_filtering_dis = 1; + } + + if (pic_param->version != 3) { + regs->reg121.sw_romain_mv = 1; + } + + if (pic_param->decMode == VP8HWD_VP8 && (pic_param->version & 0x3)) { + regs->reg121.sw_eable_bilinear = 1; + } + regs->reg122.sw_boolean_value = pic_param->bool_value; + regs->reg122.sw_boolean_range = pic_param->bool_range; + + { + if (!pic_param->stVP8Segments.segmentation_enabled) + regs->reg130.sw_quant_0 = pic_param->y1ac_delta_q; + else if (pic_param->stVP8Segments.update_mb_segmentation_data) { /* absolute mode */ + regs->reg130.sw_quant_0 = pic_param->stVP8Segments.segment_feature_data[0][0]; + regs->reg130.sw_quant_1 = pic_param->stVP8Segments.segment_feature_data[0][1]; + regs->reg151.sw_quant_2 = pic_param->stVP8Segments.segment_feature_data[0][2]; + regs->reg151.sw_quant_3 = pic_param->stVP8Segments.segment_feature_data[0][3]; + } else { /* delta mode */ + regs->reg130.sw_quant_0 = CLIP3(0, 127, pic_param->y1ac_delta_q + pic_param->stVP8Segments.segment_feature_data[0][0]); + regs->reg130.sw_quant_1 = CLIP3(0, 127, pic_param->y1ac_delta_q + pic_param->stVP8Segments.segment_feature_data[0][1]); + regs->reg151.sw_quant_2 = CLIP3(0, 127, pic_param->y1ac_delta_q + pic_param->stVP8Segments.segment_feature_data[0][2]); + regs->reg151.sw_quant_3 = CLIP3(0, 127, pic_param->y1ac_delta_q + pic_param->stVP8Segments.segment_feature_data[0][3]); + } + + regs->reg130.sw_quant_delta_0 = pic_param->y1dc_delta_q; + regs->reg130.sw_quant_delta_1 = pic_param->y2dc_delta_q; + regs->reg151.sw_quant_delta_2 = pic_param->y2ac_delta_q; + regs->reg151.sw_quant_delta_3 = pic_param->uvdc_delta_q; + regs->reg152.sw_quant_delta_4 = pic_param->uvac_delta_q; + + if (pic_param->mode_ref_lf_delta_enabled) { + regs->reg133.sw_filt_ref_adj_0 = pic_param->ref_lf_deltas[0]; + regs->reg133.sw_filt_ref_adj_1 = pic_param->ref_lf_deltas[1]; + regs->reg133.sw_filt_ref_adj_2 = pic_param->ref_lf_deltas[2]; + regs->reg133.sw_filt_ref_adj_3 = pic_param->ref_lf_deltas[3]; + regs->reg132.sw_filt_mb_adj_0 = pic_param->mode_lf_deltas[0]; + regs->reg132.sw_filt_mb_adj_1 = pic_param->mode_lf_deltas[1]; + regs->reg132.sw_filt_mb_adj_2 = pic_param->mode_lf_deltas[2]; + regs->reg132.sw_filt_mb_adj_3 = pic_param->mode_lf_deltas[3]; + } + + } + + if ((pic_param->version & 0x3) == 0) + hal_vp8d_pre_filter_tap_set(ctx); + + hal_vp8d_dct_partition_cfg(ctx, task); + regs->reg57_enable_ctrl.sw_dec_e = 1; + + FUN_T("FUN_OUT"); + return ret; +} + +MPP_RET hal_vp8d_start(void *hal, HalTaskInfo *task) +{ + MPP_RET ret = MPP_OK; + +#ifdef RKPLATFORM + RK_U32 i = 0; + VP8DHalContext_t *ctx = (VP8DHalContext_t *)hal; + VP8DRegSet_t *regs = (VP8DRegSet_t *)ctx->regs; + RK_U8 *p = ctx->regs; + + + FUN_T("FUN_IN"); + + for (i = 0; i < 159; i++) { + vp8h_dbg(VP8H_DBG_REG, "vp8d: regs[%02d]=%08X\n", i, *((RK_U32*)p)); + // mpp_log("vp8d: regs[%02d]=%08X\n", i, *((RK_U32*)p)); + p += 4; + } + ret = VPUClientSendReg(ctx->vpu_socket, (RK_U32 *)regs, VP8D_REG_NUM); + if (ret != 0) { + mpp_err("VPUClientSendReg Failed!!!\n"); + return MPP_ERR_VPUHW; + } + + FUN_T("FUN_OUT"); +#endif + (void)task; + (void)hal; + return ret; +} + +MPP_RET hal_vp8d_wait(void *hal, HalTaskInfo *task) +{ + MPP_RET ret = MPP_OK; +#ifdef RKPLATFORM + VP8DRegSet_t reg_out; + VPU_CMD_TYPE cmd = 0; + RK_S32 length = 0; + VP8DHalContext_t *ctx = (VP8DHalContext_t *)hal; + FUN_T("FUN_IN"); + memset(®_out, 0, sizeof(VP8DRegSet_t)); + ret = VPUClientWaitResult(ctx->vpu_socket, (RK_U32 *)®_out, + VP8D_REG_NUM, &cmd, &length); + FUN_T("FUN_OUT"); +#endif + (void)hal; + (void)task; + return ret; +} + +MPP_RET hal_vp8d_reset(void *hal) +{ + MPP_RET ret = MPP_OK; + + FUN_T("FUN_IN"); + (void)hal; + FUN_T("FUN_OUT"); + return ret; +} + +MPP_RET hal_vp8d_flush(void *hal) +{ + MPP_RET ret = MPP_OK; + + FUN_T("FUN_IN"); + (void)hal; + FUN_T("FUN_OUT"); + return ret; +} + +MPP_RET hal_vp8d_control(void *hal, RK_S32 cmd_type, void *param) +{ + MPP_RET ret = MPP_OK; + + FUN_T("FUN_IN"); + (void)hal; + (void)cmd_type; + (void)param; + FUN_T("FUN_OUT"); + return ret; +} diff --git a/mpp/hal/vpu/vp8d/hal_vp8d_reg.h b/mpp/hal/vpu/vp8d/hal_vp8d_reg.h index 3cf8baf7..d758b4de 100644 --- a/mpp/hal/vpu/vp8d/hal_vp8d_reg.h +++ b/mpp/hal/vpu/vp8d/hal_vp8d_reg.h @@ -1,439 +1,439 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef __HAL_VP8D_REG_H__ -#define __HAL_VP8D_REG_H__ -#include - -#include "mpp_hal.h" -#include "mpp_buf_slot.h" - -#include "vp8d_syntax.h" -#include "hal_task.h" - -extern RK_U32 vp8h_debug; -#define VP8H_DBG_FUNCTION (0x00000001) -#define VP8H_DBG_REG (0x00000002) -#define VP8H_DBG_DUMP_REG (0x00000004) -#define VP8H_DBG_IRQ (0x00000008) - -#define VP8D_REG_NUM 159 -#define vp8h_dbg(flag, fmt, ...) _mpp_dbg_f(vp8h_debug, flag, fmt, ## __VA_ARGS__) - -typedef struct { - unsigned long ppReg[50]; - struct { - RK_U32 sw_dec_out_tiled_e : 1; - RK_U32 sw_dec_latency : 6; - RK_U32 sw_pic_fixed_quant : 1; - RK_U32 sw_filtering_dis : 1; - RK_U32 sw_skip_mode : 1; - RK_U32 sw_dec_scmd_dis : 1; - RK_U32 sw_dec_adv_pre_dis : 1; - RK_U32 sw_priority_mode : 1; - RK_U32 sw_refbu2_thr : 12; - RK_U32 sw_refbu2_picid : 5; - RK_U32 reserve1 : 2; - } reg50_dec_ctrl; - - struct { - RK_U32 sw_stream_len : 24; - RK_U32 reserve1 : 1; - RK_U32 sw_init_qp : 6; - RK_U32 reserve2 : 1; - } reg51_stream_info; - - struct { - RK_U32 sw_startmb_y : 8; - RK_U32 sw_startmb_x : 9; - RK_U32 sw_apf_threshold : 14; - RK_U32 sw_reserve : 1; - } reg52_error_concealment; - - RK_U32 reg53_dec_mode; - - struct { - RK_U32 sw_dec_in_endian : 1; - RK_U32 sw_dec_out_endian : 1; - RK_U32 sw_dec_inswap32_e : 1; - RK_U32 sw_dec_outswap32_e : 1; - RK_U32 sw_dec_strswap32_e : 1; - RK_U32 sw_dec_strendian_e : 1; - RK_U32 reserve3 : 26; - } reg54_endian; - - struct { - RK_U32 sw_dec_irq : 1; - RK_U32 sw_dec_irq_dis : 1; - RK_U32 reserve0 : 2; - RK_U32 sw_dec_rdy_int : 1; - RK_U32 sw_dec_bus_int : 1; - RK_U32 sw_dec_buffer_int : 1; - RK_U32 reserve1 : 1; - RK_U32 sw_dec_aso_int : 1; - RK_U32 sw_dec_slice_int : 1; - RK_U32 sw_dec_pic_inf : 1; - RK_U32 reserve2 : 1; - RK_U32 sw_dec_error_int: 1; - RK_U32 sw_dec_timeout : 1; - RK_U32 reserve3 : 18; - } reg55_Interrupt; - - struct { - RK_U32 sw_dec_axi_rn_id : 8; - RK_U32 sw_dec_axi_wr_id : 8; - RK_U32 sw_dec_max_burst : 5; - RK_U32 resever : 1; - RK_U32 sw_dec_data_disc_e : 1; - RK_U32 resever1 : 9; - } reg56_axi_ctrl; - - struct { - RK_U32 sw_dec_e : 1; - RK_U32 sw_refbu2_buf_e : 1; - RK_U32 sw_dec_out_dis : 1; - RK_U32 resever : 1; - RK_U32 sw_dec_clk_gate_e : 1; - RK_U32 sw_dec_timeout_e : 1; - RK_U32 sw_picord_count_e : 1; - RK_U32 sw_seq_mbaff_e : 1; - RK_U32 sw_reftopfirst_e : 1; - RK_U32 sw_ref_topfield_e : 1; - RK_U32 sw_write_mvs_e : 1; - RK_U32 sw_sorenson_e : 1; - RK_U32 sw_fwd_interlace_e : 1; - RK_U32 sw_pic_topfield_e : 1 ; - RK_U32 sw_pic_inter_e : 1; - RK_U32 sw_pic_b_e : 1; - RK_U32 sw_pic_fieldmode_e : 1; - RK_U32 sw_pic_interlace_e : 1; - RK_U32 sw_pjpeg_e : 1; - RK_U32 sw_divx3_e : 1; - RK_U32 sw_rlc_mode_e : 1; - RK_U32 sw_ch_8pix_ileav_e : 1; - RK_U32 sw_start_code_e : 1; - RK_U32 resever1 : 8; - RK_U32 sw_dec_ahb_hlock_e : 1; - - } reg57_enable_ctrl; - - RK_U32 reg58_soft_rest; - - struct { - RK_U32 resever : 2; - RK_U32 sw_pred_bc_tap_0_2 : 10; - RK_U32 sw_pred_bc_tap_0_1 : 10; - RK_U32 sw_pred_bc_tap_0_0 : 10; - } reg59; - - RK_U32 reg60_addit_ch_st_base; - RK_U32 reg61_qtable_base; - RK_U32 reg62_directmv_base; - RK_U32 reg63_cur_pic_base; - RK_U32 reg64_input_stream_base; - - struct { - RK_U32 sw_refbu_y_offset : 9; - RK_U32 sw_reserve : 3; - RK_U32 sw_refbu_fparmod_e : 1; - RK_U32 sw_refbu_eval_e : 1; - RK_U32 sw_refbu_picid : 5; - RK_U32 sw_refbu_thr : 12; - RK_U32 sw_refbu_e : 1; - } reg65_refpicbuf_ctrl; - - struct { - RK_U32 build_version : 3; - RK_U32 product_IDen : 1; - RK_U32 minor_version : 8; - RK_U32 major_version : 4; - RK_U32 product_numer : 16; - } reg66_id; - - struct { - RK_U32 sw_reserve : 25; - RK_U32 sw_dec_rtl_rom : 1; - RK_U32 sw_dec_rv_prof : 2; - RK_U32 sw_ref_buff2_exist : 1; - RK_U32 sw_dec_divx_prof : 1; - RK_U32 sw_dec_refbu_ilace : 1; - RK_U32 sw_dec_jpeg_exten : 1; - } reg67_synthesis_cfg; - - struct { - RK_U32 sw_refbu_top_sum : 16; - RK_U32 sw_refbu_bot_sum : 16; - } reg68_sum_of_partitions; - - struct { - RK_U32 sw_refbu_intra_sum : 16; - RK_U32 sw_refbu_hit_sum : 16; - } reg69_sum_inf; - - struct { - RK_U32 sw_refbu_mv_sum : 22; - RK_U32 sw_reserve : 10; - } reg70_sum_mv; - - RK_U32 reg71_119_reserve[49]; - - struct { - RK_U32 sw_pic_mb_h_ext : 3; - RK_U32 sw_pic_mb_w_ext : 3; - RK_U32 sw_alt_scan_e : 1; - RK_U32 sw_mb_height_off : 4; - RK_U32 sw_pic_mb_hight_p : 8; - RK_U32 sw_mb_width_off : 4; - RK_U32 sw_pic_mb_width : 9; - } reg120; - - struct { - RK_U32 sw_resever : 5; - RK_U32 sw_vp7_version : 1; - RK_U32 sw_dc_match0 : 3; - RK_U32 sw_dc_match1 : 3; - RK_U32 sw_eable_bilinear : 1; - RK_U32 sw_romain_mv : 1; - RK_U32 sw_resever1 : 6; - RK_U32 sw_dct2_start_bit : 6; - RK_U32 sw_dct1_start_bit : 6; - } reg121; - - struct { - RK_U32 sw_boolean_range : 8; - RK_U32 sw_boolean_value : 8; - RK_U32 sw_multistream_e : 1; - RK_U32 sw_huffman_e : 1; - RK_U32 sw_strm1_start_bit : 6; - RK_U32 sw_resever : 2; - RK_U32 sw_strm_start_bit : 6; - } reg122; - - struct { - RK_U32 sw_dc_comp1 : 16; - RK_U32 sw_dc_comp0 : 16; - } reg123; - - struct { - RK_U32 sw_stream1_len : 24; - RK_U32 sw_coeffs_part_am : 4; - RK_U32 sw_resever : 4; - } reg124; - - struct { - RK_U32 resever : 2; - RK_U32 sw_pred_bc_tap_5_3 : 10; - RK_U32 sw_pred_bc_tap_5_2 : 10; - RK_U32 sw_pred_bc_tap_5_1 : 10; - } reg125; - - struct { - RK_U32 resever : 2; - RK_U32 sw_pred_bc_tap_6_2 : 10; - RK_U32 sw_pred_bc_tap_6_1 : 10; - RK_U32 sw_pred_bc_tap_6_0 : 10; - } reg126; - - struct { - RK_U32 resever : 2; - RK_U32 sw_pred_bc_tap_7_1 : 10; - RK_U32 sw_pred_bc_tap_7_0 : 10; - RK_U32 sw_pred_bc_tap_6_3 : 10; - } reg127; - - struct { - RK_U32 sw_pred_tap_6_4 : 2; - RK_U32 sw_pred_tap_6_M1 : 2; - RK_U32 sw_pred_tap_4_4 : 2; - RK_U32 sw_pred_tap_4_M1 : 2; - RK_U32 sw_pred_tap_2_4 : 2; - RK_U32 sw_pred_tap_2_M1 : 2; - RK_U32 sw_pred_bc_tap_7_3 : 10; - RK_U32 sw_pred_bc_tap_7_2 : 10; - } reg128; - - struct { - RK_U32 sw_filt_level_3 : 6; - RK_U32 sw_filt_level_2 : 6; - RK_U32 sw_filt_level_1 : 6; - RK_U32 sw_filt_level_0 : 6; - RK_U32 resever : 8; - } reg129; - - struct { - RK_U32 sw_quant_1 : 11; - RK_U32 sw_quant_0 : 11; - RK_U32 sw_quant_delta_1 : 5; - RK_U32 sw_quant_delta_0 : 5; - } reg130; - - - RK_U32 reg131_ref0_base; - - struct { - RK_U32 sw_filt_mb_adj_3 : 7; - RK_U32 sw_filt_mb_adj_2 : 7; - RK_U32 sw_filt_mb_adj_1 : 7; - RK_U32 sw_filt_mb_adj_0 : 7; - RK_U32 sw_filt_sharpness : 3; - RK_U32 sw_filt_type : 1; - } reg132; - - - struct { - RK_U32 sw_filt_ref_adj_3 : 7; - RK_U32 sw_filt_ref_adj_2 : 7; - RK_U32 sw_filt_ref_adj_1 : 7; - RK_U32 sw_filt_ref_adj_0 : 7; - RK_U32 sw_resver : 4; - } reg133; - - RK_U32 reg134; - RK_U32 reg135; - - RK_U32 reg136_golden_ref_base; - - union { - RK_U32 alternate_ref_base; - struct { - RK_U32 sw_scan_map_5 : 6; - RK_U32 sw_scan_map_4 : 6; - RK_U32 sw_scan_map_3 : 6; - RK_U32 sw_scan_map_2 : 6; - RK_U32 sw_scan_map_1 : 6; - RK_U32 sw_resver : 2; - }; - } reg137; - - struct { - RK_U32 sw_scan_map_10 : 6; - RK_U32 sw_scan_map_9 : 6; - RK_U32 sw_scan_map_8 : 6; - RK_U32 sw_scan_map_7 : 6; - RK_U32 sw_scan_map_6 : 6; - RK_U32 sw_resver : 2; - } reg138; - - struct { - RK_U32 sw_scan_map_15 : 6; - RK_U32 sw_scan_map_14 : 6; - RK_U32 sw_scan_map_13 : 6; - RK_U32 sw_scan_map_12 : 6; - RK_U32 sw_scan_map_11 : 6; - RK_U32 sw_resver : 2; - } reg139; - - RK_U32 reg_dct_strm_base[5]; - RK_U32 reg145_bitpl_ctrl_base; - RK_U32 reg_dct_strm1_base[2]; - - struct { - RK_U32 sw_slice_h : 8; - RK_U32 sw_resver : 24; - } reg148; - - RK_U32 reg149_segment_map_base; - - - struct { - RK_U32 sw_dct_start_bit_7 : 6; - RK_U32 sw_dct_start_bit_6 : 6; - RK_U32 sw_dct_start_bit_5 : 6; - RK_U32 sw_dct_start_bit_4 : 6; - RK_U32 sw_dct_start_bit_3 : 6; - RK_U32 sw_resver : 2; - } reg150; - - struct { - RK_U32 sw_quant_3 : 11; - RK_U32 sw_quant_2 : 11; - RK_U32 sw_quant_delta_3 : 5; - RK_U32 sw_quant_delta_2 : 5; - } reg151; - - struct { - RK_U32 sw_quant_5 : 11; - RK_U32 sw_quant_4 : 11; - RK_U32 sw_quant_delta_4 : 5; - RK_U32 sw_resver : 5; - } reg152; - - struct { - RK_U32 resever : 2; - RK_U32 sw_pred_bc_tap_1_1 : 10; - RK_U32 sw_pred_bc_tap_1_0 : 10; - RK_U32 sw_pred_bc_tap_0_3 : 10; - } reg153; - - struct { - RK_U32 resever : 2; - RK_U32 sw_pred_bc_tap_2_0 : 10; - RK_U32 sw_pred_bc_tap_1_3 : 10; - RK_U32 sw_pred_bc_tap_1_2 : 10; - } reg154; - - struct { - RK_U32 resever : 2; - RK_U32 sw_pred_bc_tap_2_3 : 10; - RK_U32 sw_pred_bc_tap_2_2 : 10; - RK_U32 sw_pred_bc_tap_2_1 : 10; - } reg155; - - struct { - RK_U32 resever : 2; - RK_U32 sw_pred_bc_tap_3_2 : 10; - RK_U32 sw_pred_bc_tap_3_1 : 10; - RK_U32 sw_pred_bc_tap_3_0 : 10; - } reg156; - - struct { - RK_U32 resever : 2; - RK_U32 sw_pred_bc_tap_4_1 : 10; - RK_U32 sw_pred_bc_tap_4_0 : 10; - RK_U32 sw_pred_bc_tap_3_3 : 10; - } reg157; - - struct { - RK_U32 resever : 2; - RK_U32 sw_pred_bc_tap_5_0 : 10; - RK_U32 sw_pred_bc_tap_4_3 : 10; - RK_U32 sw_pred_bc_tap_4_2 : 10; - } reg158; -} VP8DRegSet_t; - -typedef struct VP8DHalContext { - MppBufSlots packet_slots; - MppBufSlots frame_slots; - RK_S32 vpu_socket; - void *regs; - RK_U8 reg_size; - MppBufferGroup group; - MppBuffer probe_table; - MppBuffer seg_map; - RK_U32 dec_frame_cnt; - FILE *fp_reg_in; - FILE *fp_reg_out; -} VP8DHalContext_t; - -MPP_RET hal_vp8d_init (void *hal, MppHalCfg *cfg); -MPP_RET hal_vp8d_deinit (void *hal); -MPP_RET hal_vp8d_gen_regs(void *hal, HalTaskInfo *task); -MPP_RET hal_vp8d_start (void *hal, HalTaskInfo *task); -MPP_RET hal_vp8d_wait (void *hal, HalTaskInfo *task); -MPP_RET hal_vp8d_reset (void *hal); -MPP_RET hal_vp8d_flush (void *hal); -MPP_RET hal_vp8d_control (void *hal, RK_S32 cmd_type, void *param); - -#endif +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef __HAL_VP8D_REG_H__ +#define __HAL_VP8D_REG_H__ +#include + +#include "mpp_hal.h" +#include "mpp_buf_slot.h" + +#include "vp8d_syntax.h" +#include "hal_task.h" + +extern RK_U32 vp8h_debug; +#define VP8H_DBG_FUNCTION (0x00000001) +#define VP8H_DBG_REG (0x00000002) +#define VP8H_DBG_DUMP_REG (0x00000004) +#define VP8H_DBG_IRQ (0x00000008) + +#define VP8D_REG_NUM 159 +#define vp8h_dbg(flag, fmt, ...) _mpp_dbg_f(vp8h_debug, flag, fmt, ## __VA_ARGS__) + +typedef struct { + unsigned long ppReg[50]; + struct { + RK_U32 sw_dec_out_tiled_e : 1; + RK_U32 sw_dec_latency : 6; + RK_U32 sw_pic_fixed_quant : 1; + RK_U32 sw_filtering_dis : 1; + RK_U32 sw_skip_mode : 1; + RK_U32 sw_dec_scmd_dis : 1; + RK_U32 sw_dec_adv_pre_dis : 1; + RK_U32 sw_priority_mode : 1; + RK_U32 sw_refbu2_thr : 12; + RK_U32 sw_refbu2_picid : 5; + RK_U32 reserve1 : 2; + } reg50_dec_ctrl; + + struct { + RK_U32 sw_stream_len : 24; + RK_U32 reserve1 : 1; + RK_U32 sw_init_qp : 6; + RK_U32 reserve2 : 1; + } reg51_stream_info; + + struct { + RK_U32 sw_startmb_y : 8; + RK_U32 sw_startmb_x : 9; + RK_U32 sw_apf_threshold : 14; + RK_U32 sw_reserve : 1; + } reg52_error_concealment; + + RK_U32 reg53_dec_mode; + + struct { + RK_U32 sw_dec_in_endian : 1; + RK_U32 sw_dec_out_endian : 1; + RK_U32 sw_dec_inswap32_e : 1; + RK_U32 sw_dec_outswap32_e : 1; + RK_U32 sw_dec_strswap32_e : 1; + RK_U32 sw_dec_strendian_e : 1; + RK_U32 reserve3 : 26; + } reg54_endian; + + struct { + RK_U32 sw_dec_irq : 1; + RK_U32 sw_dec_irq_dis : 1; + RK_U32 reserve0 : 2; + RK_U32 sw_dec_rdy_int : 1; + RK_U32 sw_dec_bus_int : 1; + RK_U32 sw_dec_buffer_int : 1; + RK_U32 reserve1 : 1; + RK_U32 sw_dec_aso_int : 1; + RK_U32 sw_dec_slice_int : 1; + RK_U32 sw_dec_pic_inf : 1; + RK_U32 reserve2 : 1; + RK_U32 sw_dec_error_int: 1; + RK_U32 sw_dec_timeout : 1; + RK_U32 reserve3 : 18; + } reg55_Interrupt; + + struct { + RK_U32 sw_dec_axi_rn_id : 8; + RK_U32 sw_dec_axi_wr_id : 8; + RK_U32 sw_dec_max_burst : 5; + RK_U32 resever : 1; + RK_U32 sw_dec_data_disc_e : 1; + RK_U32 resever1 : 9; + } reg56_axi_ctrl; + + struct { + RK_U32 sw_dec_e : 1; + RK_U32 sw_refbu2_buf_e : 1; + RK_U32 sw_dec_out_dis : 1; + RK_U32 resever : 1; + RK_U32 sw_dec_clk_gate_e : 1; + RK_U32 sw_dec_timeout_e : 1; + RK_U32 sw_picord_count_e : 1; + RK_U32 sw_seq_mbaff_e : 1; + RK_U32 sw_reftopfirst_e : 1; + RK_U32 sw_ref_topfield_e : 1; + RK_U32 sw_write_mvs_e : 1; + RK_U32 sw_sorenson_e : 1; + RK_U32 sw_fwd_interlace_e : 1; + RK_U32 sw_pic_topfield_e : 1 ; + RK_U32 sw_pic_inter_e : 1; + RK_U32 sw_pic_b_e : 1; + RK_U32 sw_pic_fieldmode_e : 1; + RK_U32 sw_pic_interlace_e : 1; + RK_U32 sw_pjpeg_e : 1; + RK_U32 sw_divx3_e : 1; + RK_U32 sw_rlc_mode_e : 1; + RK_U32 sw_ch_8pix_ileav_e : 1; + RK_U32 sw_start_code_e : 1; + RK_U32 resever1 : 8; + RK_U32 sw_dec_ahb_hlock_e : 1; + + } reg57_enable_ctrl; + + RK_U32 reg58_soft_rest; + + struct { + RK_U32 resever : 2; + RK_U32 sw_pred_bc_tap_0_2 : 10; + RK_U32 sw_pred_bc_tap_0_1 : 10; + RK_U32 sw_pred_bc_tap_0_0 : 10; + } reg59; + + RK_U32 reg60_addit_ch_st_base; + RK_U32 reg61_qtable_base; + RK_U32 reg62_directmv_base; + RK_U32 reg63_cur_pic_base; + RK_U32 reg64_input_stream_base; + + struct { + RK_U32 sw_refbu_y_offset : 9; + RK_U32 sw_reserve : 3; + RK_U32 sw_refbu_fparmod_e : 1; + RK_U32 sw_refbu_eval_e : 1; + RK_U32 sw_refbu_picid : 5; + RK_U32 sw_refbu_thr : 12; + RK_U32 sw_refbu_e : 1; + } reg65_refpicbuf_ctrl; + + struct { + RK_U32 build_version : 3; + RK_U32 product_IDen : 1; + RK_U32 minor_version : 8; + RK_U32 major_version : 4; + RK_U32 product_numer : 16; + } reg66_id; + + struct { + RK_U32 sw_reserve : 25; + RK_U32 sw_dec_rtl_rom : 1; + RK_U32 sw_dec_rv_prof : 2; + RK_U32 sw_ref_buff2_exist : 1; + RK_U32 sw_dec_divx_prof : 1; + RK_U32 sw_dec_refbu_ilace : 1; + RK_U32 sw_dec_jpeg_exten : 1; + } reg67_synthesis_cfg; + + struct { + RK_U32 sw_refbu_top_sum : 16; + RK_U32 sw_refbu_bot_sum : 16; + } reg68_sum_of_partitions; + + struct { + RK_U32 sw_refbu_intra_sum : 16; + RK_U32 sw_refbu_hit_sum : 16; + } reg69_sum_inf; + + struct { + RK_U32 sw_refbu_mv_sum : 22; + RK_U32 sw_reserve : 10; + } reg70_sum_mv; + + RK_U32 reg71_119_reserve[49]; + + struct { + RK_U32 sw_pic_mb_h_ext : 3; + RK_U32 sw_pic_mb_w_ext : 3; + RK_U32 sw_alt_scan_e : 1; + RK_U32 sw_mb_height_off : 4; + RK_U32 sw_pic_mb_hight_p : 8; + RK_U32 sw_mb_width_off : 4; + RK_U32 sw_pic_mb_width : 9; + } reg120; + + struct { + RK_U32 sw_resever : 5; + RK_U32 sw_vp7_version : 1; + RK_U32 sw_dc_match0 : 3; + RK_U32 sw_dc_match1 : 3; + RK_U32 sw_eable_bilinear : 1; + RK_U32 sw_romain_mv : 1; + RK_U32 sw_resever1 : 6; + RK_U32 sw_dct2_start_bit : 6; + RK_U32 sw_dct1_start_bit : 6; + } reg121; + + struct { + RK_U32 sw_boolean_range : 8; + RK_U32 sw_boolean_value : 8; + RK_U32 sw_multistream_e : 1; + RK_U32 sw_huffman_e : 1; + RK_U32 sw_strm1_start_bit : 6; + RK_U32 sw_resever : 2; + RK_U32 sw_strm_start_bit : 6; + } reg122; + + struct { + RK_U32 sw_dc_comp1 : 16; + RK_U32 sw_dc_comp0 : 16; + } reg123; + + struct { + RK_U32 sw_stream1_len : 24; + RK_U32 sw_coeffs_part_am : 4; + RK_U32 sw_resever : 4; + } reg124; + + struct { + RK_U32 resever : 2; + RK_U32 sw_pred_bc_tap_5_3 : 10; + RK_U32 sw_pred_bc_tap_5_2 : 10; + RK_U32 sw_pred_bc_tap_5_1 : 10; + } reg125; + + struct { + RK_U32 resever : 2; + RK_U32 sw_pred_bc_tap_6_2 : 10; + RK_U32 sw_pred_bc_tap_6_1 : 10; + RK_U32 sw_pred_bc_tap_6_0 : 10; + } reg126; + + struct { + RK_U32 resever : 2; + RK_U32 sw_pred_bc_tap_7_1 : 10; + RK_U32 sw_pred_bc_tap_7_0 : 10; + RK_U32 sw_pred_bc_tap_6_3 : 10; + } reg127; + + struct { + RK_U32 sw_pred_tap_6_4 : 2; + RK_U32 sw_pred_tap_6_M1 : 2; + RK_U32 sw_pred_tap_4_4 : 2; + RK_U32 sw_pred_tap_4_M1 : 2; + RK_U32 sw_pred_tap_2_4 : 2; + RK_U32 sw_pred_tap_2_M1 : 2; + RK_U32 sw_pred_bc_tap_7_3 : 10; + RK_U32 sw_pred_bc_tap_7_2 : 10; + } reg128; + + struct { + RK_U32 sw_filt_level_3 : 6; + RK_U32 sw_filt_level_2 : 6; + RK_U32 sw_filt_level_1 : 6; + RK_U32 sw_filt_level_0 : 6; + RK_U32 resever : 8; + } reg129; + + struct { + RK_U32 sw_quant_1 : 11; + RK_U32 sw_quant_0 : 11; + RK_U32 sw_quant_delta_1 : 5; + RK_U32 sw_quant_delta_0 : 5; + } reg130; + + + RK_U32 reg131_ref0_base; + + struct { + RK_U32 sw_filt_mb_adj_3 : 7; + RK_U32 sw_filt_mb_adj_2 : 7; + RK_U32 sw_filt_mb_adj_1 : 7; + RK_U32 sw_filt_mb_adj_0 : 7; + RK_U32 sw_filt_sharpness : 3; + RK_U32 sw_filt_type : 1; + } reg132; + + + struct { + RK_U32 sw_filt_ref_adj_3 : 7; + RK_U32 sw_filt_ref_adj_2 : 7; + RK_U32 sw_filt_ref_adj_1 : 7; + RK_U32 sw_filt_ref_adj_0 : 7; + RK_U32 sw_resver : 4; + } reg133; + + RK_U32 reg134; + RK_U32 reg135; + + RK_U32 reg136_golden_ref_base; + + union { + RK_U32 alternate_ref_base; + struct { + RK_U32 sw_scan_map_5 : 6; + RK_U32 sw_scan_map_4 : 6; + RK_U32 sw_scan_map_3 : 6; + RK_U32 sw_scan_map_2 : 6; + RK_U32 sw_scan_map_1 : 6; + RK_U32 sw_resver : 2; + }; + } reg137; + + struct { + RK_U32 sw_scan_map_10 : 6; + RK_U32 sw_scan_map_9 : 6; + RK_U32 sw_scan_map_8 : 6; + RK_U32 sw_scan_map_7 : 6; + RK_U32 sw_scan_map_6 : 6; + RK_U32 sw_resver : 2; + } reg138; + + struct { + RK_U32 sw_scan_map_15 : 6; + RK_U32 sw_scan_map_14 : 6; + RK_U32 sw_scan_map_13 : 6; + RK_U32 sw_scan_map_12 : 6; + RK_U32 sw_scan_map_11 : 6; + RK_U32 sw_resver : 2; + } reg139; + + RK_U32 reg_dct_strm_base[5]; + RK_U32 reg145_bitpl_ctrl_base; + RK_U32 reg_dct_strm1_base[2]; + + struct { + RK_U32 sw_slice_h : 8; + RK_U32 sw_resver : 24; + } reg148; + + RK_U32 reg149_segment_map_base; + + + struct { + RK_U32 sw_dct_start_bit_7 : 6; + RK_U32 sw_dct_start_bit_6 : 6; + RK_U32 sw_dct_start_bit_5 : 6; + RK_U32 sw_dct_start_bit_4 : 6; + RK_U32 sw_dct_start_bit_3 : 6; + RK_U32 sw_resver : 2; + } reg150; + + struct { + RK_U32 sw_quant_3 : 11; + RK_U32 sw_quant_2 : 11; + RK_U32 sw_quant_delta_3 : 5; + RK_U32 sw_quant_delta_2 : 5; + } reg151; + + struct { + RK_U32 sw_quant_5 : 11; + RK_U32 sw_quant_4 : 11; + RK_U32 sw_quant_delta_4 : 5; + RK_U32 sw_resver : 5; + } reg152; + + struct { + RK_U32 resever : 2; + RK_U32 sw_pred_bc_tap_1_1 : 10; + RK_U32 sw_pred_bc_tap_1_0 : 10; + RK_U32 sw_pred_bc_tap_0_3 : 10; + } reg153; + + struct { + RK_U32 resever : 2; + RK_U32 sw_pred_bc_tap_2_0 : 10; + RK_U32 sw_pred_bc_tap_1_3 : 10; + RK_U32 sw_pred_bc_tap_1_2 : 10; + } reg154; + + struct { + RK_U32 resever : 2; + RK_U32 sw_pred_bc_tap_2_3 : 10; + RK_U32 sw_pred_bc_tap_2_2 : 10; + RK_U32 sw_pred_bc_tap_2_1 : 10; + } reg155; + + struct { + RK_U32 resever : 2; + RK_U32 sw_pred_bc_tap_3_2 : 10; + RK_U32 sw_pred_bc_tap_3_1 : 10; + RK_U32 sw_pred_bc_tap_3_0 : 10; + } reg156; + + struct { + RK_U32 resever : 2; + RK_U32 sw_pred_bc_tap_4_1 : 10; + RK_U32 sw_pred_bc_tap_4_0 : 10; + RK_U32 sw_pred_bc_tap_3_3 : 10; + } reg157; + + struct { + RK_U32 resever : 2; + RK_U32 sw_pred_bc_tap_5_0 : 10; + RK_U32 sw_pred_bc_tap_4_3 : 10; + RK_U32 sw_pred_bc_tap_4_2 : 10; + } reg158; +} VP8DRegSet_t; + +typedef struct VP8DHalContext { + MppBufSlots packet_slots; + MppBufSlots frame_slots; + RK_S32 vpu_socket; + void *regs; + RK_U8 reg_size; + MppBufferGroup group; + MppBuffer probe_table; + MppBuffer seg_map; + RK_U32 dec_frame_cnt; + FILE *fp_reg_in; + FILE *fp_reg_out; +} VP8DHalContext_t; + +MPP_RET hal_vp8d_init (void *hal, MppHalCfg *cfg); +MPP_RET hal_vp8d_deinit (void *hal); +MPP_RET hal_vp8d_gen_regs(void *hal, HalTaskInfo *task); +MPP_RET hal_vp8d_start (void *hal, HalTaskInfo *task); +MPP_RET hal_vp8d_wait (void *hal, HalTaskInfo *task); +MPP_RET hal_vp8d_reset (void *hal); +MPP_RET hal_vp8d_flush (void *hal); +MPP_RET hal_vp8d_control (void *hal, RK_S32 cmd_type, void *param); + +#endif diff --git a/mpp/legacy/CMakeLists.txt b/mpp/legacy/CMakeLists.txt index b56a485c..4e8ca94b 100644 --- a/mpp/legacy/CMakeLists.txt +++ b/mpp/legacy/CMakeLists.txt @@ -1,31 +1,31 @@ -# vim: syntax=cmake -include_directories(.) - -# ---------------------------------------------------------------------------- -# add mpp implement -# ---------------------------------------------------------------------------- -set (MPP_LEGACY_SRC - vpu_api.cpp - vpu_api_legacy.cpp - vpu_mem_legacy.c - rk_list.cpp - ppOp.cpp - ../mpp_info.cpp - ) - -add_library(mpp_legacy STATIC ${MPP_LEGACY_SRC}) -set_target_properties(mpp_legacy PROPERTIES FOLDER "mpp/legacy") -target_link_libraries(mpp_legacy mpp) - -add_library(mpp_legacy_shared SHARED ${MPP_LEGACY_SRC}) -set_target_properties(mpp_legacy_shared PROPERTIES FOLDER "mpp/legacy") -set_target_properties(mpp_legacy_shared PROPERTIES OUTPUT_NAME "vpu") -set_target_properties(mpp_legacy_shared PROPERTIES CLEAN_DIRECT_OUTPUT 1) -set_target_properties(mpp_legacy_shared PROPERTIES C_VISIBILITY_PRESET default) -set_target_properties(mpp_legacy_shared PROPERTIES CXX_VISIBILITY_PRESET default) - -if(RKPLATFORM) - target_link_libraries(mpp_legacy_shared worker_vpu dl mpp_shared) -else() - target_link_libraries(mpp_legacy_shared mpp_shared) -endif() +# vim: syntax=cmake +include_directories(.) + +# ---------------------------------------------------------------------------- +# add mpp implement +# ---------------------------------------------------------------------------- +set (MPP_LEGACY_SRC + vpu_api.cpp + vpu_api_legacy.cpp + vpu_mem_legacy.c + rk_list.cpp + ppOp.cpp + ../mpp_info.cpp + ) + +add_library(mpp_legacy STATIC ${MPP_LEGACY_SRC}) +set_target_properties(mpp_legacy PROPERTIES FOLDER "mpp/legacy") +target_link_libraries(mpp_legacy mpp) + +add_library(mpp_legacy_shared SHARED ${MPP_LEGACY_SRC}) +set_target_properties(mpp_legacy_shared PROPERTIES FOLDER "mpp/legacy") +set_target_properties(mpp_legacy_shared PROPERTIES OUTPUT_NAME "vpu") +set_target_properties(mpp_legacy_shared PROPERTIES CLEAN_DIRECT_OUTPUT 1) +set_target_properties(mpp_legacy_shared PROPERTIES C_VISIBILITY_PRESET default) +set_target_properties(mpp_legacy_shared PROPERTIES CXX_VISIBILITY_PRESET default) + +if(RKPLATFORM) + target_link_libraries(mpp_legacy_shared worker_vpu dl mpp_shared) +else() + target_link_libraries(mpp_legacy_shared mpp_shared) +endif() diff --git a/mpp/legacy/ppOp.cpp b/mpp/legacy/ppOp.cpp index ca1c515b..3b61baf8 100644 --- a/mpp/legacy/ppOp.cpp +++ b/mpp/legacy/ppOp.cpp @@ -1,247 +1,247 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define LOG_TAG "PpOp" - -#include "vpu.h" -#include "ppOp.h" - -#ifdef RKPLATFORM - -namespace android -{ - -status_t ppOpInit(PP_OP_HANDLE *hnd, PP_OPERATION *init) -{ - (void)hnd; - (void)init; - return 0; -} - -status_t ppOpSet(PP_OP_HANDLE hnd, PP_SET_OPT opt, RK_U32 val) -{ - (void)hnd; - (void)opt; - (void)val; - return 0; -} - -status_t ppOpPerform(PP_OP_HANDLE hnd) -{ - (void)hnd; - return 0;//VPU_REG_NUM_PP); -} - -status_t ppOpSync(PP_OP_HANDLE hnd) -{ - (void)hnd; - return 0; -} - -status_t ppOpRelease(PP_OP_HANDLE hnd) -{ - (void)hnd; - return 0; -} - -} -#endif - -#if BUILD_PPOP_TEST -#define SRC_WIDTH (1920)//(1920) -#define SRC_HEIGHT (1080)//(1080) -#define SRC_SIZE (SRC_WIDTH*SRC_HEIGHT*2) - -#define DST_WIDTH (720)//(720) -#define DST_HEIGHT (1280) -#define DST_SIZE (DST_WIDTH*DST_HEIGHT*2) - -#include "vpu_mem.h" -#include "vpu.h" -#include "ppOp.h" - -int main() -{ - FILE *fpr, *fpw; - int wid_alig16 = ((SRC_WIDTH + 15) & (~0xf)); - int hei_alig16 = ((SRC_HEIGHT + 15) & (~0xf)); - int src_vir_width = 1920;//2048; - int src_vir_height = 1088;//1088; - int dst_vir_width = 800;//800; - int dst_vir_height = 1280;//1280; - int framecnt = 0; - char *tmpbuf = (char *)malloc(src_vir_width * src_vir_height / 2); - RK_S32 ret = 0, i, j; - - ALOGI("ppOp test start\n"); - VPUMemLinear_t src, dst; - android::PP_OP_HANDLE hnd; - int vpuFd = VPUClientInit(VPU_PP); - ret |= VPUMallocLinear(&src, src_vir_width * src_vir_height * 2); //SRC_SIZE); - ret |= VPUMallocLinear(&dst, dst_vir_width * dst_vir_height * 2); //DST_SIZE); - if (ret) { - ALOGE("failed to malloc vpu_mem"); - goto end; - } - if (vpuFd < 0) { - ALOGE("failed to open vpu client"); - goto end; - } - - { -#if 0 - int i, j; - char *tmp = (char *)src.vir_addr; - for (i = 0; i < SRC_HEIGHT; i++) { - memset(tmp, (i & 0xff), SRC_WIDTH); - tmp += SRC_WIDTH; - } -#endif - -#if 1 - char *tmp = (char *)src.vir_addr; - fpr = fopen("/sdcard/testin.yuv", "rb"); - for (i = 0; i < SRC_HEIGHT; i++) { - if (fpr)fread(tmp, 1, SRC_WIDTH, fpr); - tmp += src_vir_width; - } - tmp = (char *)src.vir_addr; - if (fpr)fread(&tmp[src_vir_width * src_vir_height], 1, SRC_WIDTH * SRC_HEIGHT / 2, fpr); - if (fpr)fclose(fpr); - - for (i = 0; i < SRC_HEIGHT / 2; i++) { //planar to semi planar - for (j = 0; j < SRC_WIDTH / 2; j++) { //planar to semi planar - tmpbuf[i * src_vir_width + j * 2 + 0] = tmp[src_vir_width * src_vir_height + i * SRC_WIDTH / 2 + j]; - tmpbuf[i * src_vir_width + j * 2 + 1] = tmp[src_vir_width * src_vir_height + SRC_WIDTH * SRC_HEIGHT / 4 + i * SRC_WIDTH / 2 + j]; - } - } - memcpy(&tmp[src_vir_width * src_vir_height], tmpbuf, src_vir_width * src_vir_height / 2); - //memset(&tmp[SRC_WIDTH*SRC_HEIGHT], 0x80, SRC_WIDTH*SRC_HEIGHT/2); -#endif - VPUMemClean(&src); - } - - while (1) { - printf("framecnt=%d\n", framecnt); - - if (framecnt++ >= 1) - break; - - wid_alig16 = ((SRC_WIDTH + 15) & (~0xf)); - hei_alig16 = ((SRC_HEIGHT + 15) & (~0xf)); - - android::PP_OPERATION opt; - memset(&opt, 0, sizeof(opt)); - opt.srcAddr = src.phy_addr; - opt.srcFormat = PP_IN_FORMAT_YUV420SEMI; - opt.srcWidth = SRC_WIDTH; - opt.srcHeight = SRC_HEIGHT; - opt.srcHStride = src_vir_width; - opt.srcVStride = src_vir_height; - opt.srcX = 0; - opt.srcY = 0; - if (wid_alig16 != SRC_WIDTH) - opt.srcCrop8R = 1; - if (hei_alig16 != SRC_HEIGHT) - opt.srcCrop8D = 1; - - wid_alig16 = ((DST_WIDTH + 15) & (~0xf)); - hei_alig16 = ((DST_HEIGHT + 15) & (~0xf)); - - opt.dstAddr = dst.phy_addr; - opt.dstFormat = PP_OUT_FORMAT_YUV420INTERLAVE; - opt.dstWidth = DST_WIDTH; - opt.dstHeight = DST_HEIGHT; - opt.dstHStride = dst_vir_width; - opt.dstVStride = dst_vir_height; - opt.dstX = 0; - opt.dstY = 0; - - opt.deinterlace = 0; - - opt.rotation = PP_ROTATION_RIGHT_90;//PP_ROTATION_RIGHT_90;//PP_ROTATION_RIGHT_90;//PP_ROTATION_RIGHT_90; - - opt.vpuFd = vpuFd; - ret |= android::ppOpInit(&hnd, &opt); - if (ret) { - ALOGE("ppOpInit failed"); - hnd = NULL; - goto end; - } - ret = android::ppOpPerform(hnd); - if (ret) { - ALOGE("ppOpPerform failed"); - } - ret = android::ppOpSync(hnd); - if (ret) { - ALOGE("ppOpSync failed"); - } - ret = android::ppOpRelease(hnd); - if (ret) { - ALOGE("ppOpPerform failed"); - } - - VPUMemInvalidate(&dst); - { -#if 0 - int i, j, ret = 0; - char *tmp = (char *)dst.vir_addr; - /*for(i=0; i<3; i++) - { - printf("col out_pos=%d, 0x%x\n", i*DST_WIDTH, tmp[i*DST_WIDTH]); - } - for(i=0; i<3; i++) - { - printf("las out_pos=%d, 0x%x\n", (DST_HEIGHT-1-i)*DST_WIDTH, tmp[(DST_HEIGHT-1-i)*DST_WIDTH]); - }*/ - for (i = 0; i < DST_HEIGHT; i++) { - for (j = 0; j < DST_WIDTH; j++) { - if ( tmp[i * DST_WIDTH + j] != (i & 0xff)) - ret = 1; - } - } - if ( ret) - printf("framecount=%d pp operation is failed!\n", (framecnt - 1)); - else - printf("framecount=%d pp operation is suceess!\n", (framecnt - 1)); - - memset(dst.vir_addr, 0xff, DST_SIZE); - VPUMemClean(&dst); -#endif - -#if 1 - char *tmp = (char *)dst.vir_addr; - //memset(&tmp[DST_WIDTH*DST_HEIGHT], 0x80, DST_WIDTH*DST_HEIGHT/2); - //VPUMemClean(&dst); - fpw = fopen("/data/testout.yuv", "wb+"); - - if (fpw)fwrite((char *)(dst.vir_addr), 1, dst_vir_width * dst_vir_height * 3 / 2, fpw); - if (fpw)fclose(fpw); -#endif - } - } - -end: - if (tmpbuf)free(tmpbuf); - if (src.phy_addr) VPUFreeLinear(&src); - if (dst.phy_addr) VPUFreeLinear(&dst); - if (vpuFd > 0) VPUClientRelease(vpuFd); - ALOGI("ppOp test end\n"); - return 0; -} - -#endif - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "PpOp" + +#include "vpu.h" +#include "ppOp.h" + +#ifdef RKPLATFORM + +namespace android +{ + +status_t ppOpInit(PP_OP_HANDLE *hnd, PP_OPERATION *init) +{ + (void)hnd; + (void)init; + return 0; +} + +status_t ppOpSet(PP_OP_HANDLE hnd, PP_SET_OPT opt, RK_U32 val) +{ + (void)hnd; + (void)opt; + (void)val; + return 0; +} + +status_t ppOpPerform(PP_OP_HANDLE hnd) +{ + (void)hnd; + return 0;//VPU_REG_NUM_PP); +} + +status_t ppOpSync(PP_OP_HANDLE hnd) +{ + (void)hnd; + return 0; +} + +status_t ppOpRelease(PP_OP_HANDLE hnd) +{ + (void)hnd; + return 0; +} + +} +#endif + +#if BUILD_PPOP_TEST +#define SRC_WIDTH (1920)//(1920) +#define SRC_HEIGHT (1080)//(1080) +#define SRC_SIZE (SRC_WIDTH*SRC_HEIGHT*2) + +#define DST_WIDTH (720)//(720) +#define DST_HEIGHT (1280) +#define DST_SIZE (DST_WIDTH*DST_HEIGHT*2) + +#include "vpu_mem.h" +#include "vpu.h" +#include "ppOp.h" + +int main() +{ + FILE *fpr, *fpw; + int wid_alig16 = ((SRC_WIDTH + 15) & (~0xf)); + int hei_alig16 = ((SRC_HEIGHT + 15) & (~0xf)); + int src_vir_width = 1920;//2048; + int src_vir_height = 1088;//1088; + int dst_vir_width = 800;//800; + int dst_vir_height = 1280;//1280; + int framecnt = 0; + char *tmpbuf = (char *)malloc(src_vir_width * src_vir_height / 2); + RK_S32 ret = 0, i, j; + + ALOGI("ppOp test start\n"); + VPUMemLinear_t src, dst; + android::PP_OP_HANDLE hnd; + int vpuFd = VPUClientInit(VPU_PP); + ret |= VPUMallocLinear(&src, src_vir_width * src_vir_height * 2); //SRC_SIZE); + ret |= VPUMallocLinear(&dst, dst_vir_width * dst_vir_height * 2); //DST_SIZE); + if (ret) { + ALOGE("failed to malloc vpu_mem"); + goto end; + } + if (vpuFd < 0) { + ALOGE("failed to open vpu client"); + goto end; + } + + { +#if 0 + int i, j; + char *tmp = (char *)src.vir_addr; + for (i = 0; i < SRC_HEIGHT; i++) { + memset(tmp, (i & 0xff), SRC_WIDTH); + tmp += SRC_WIDTH; + } +#endif + +#if 1 + char *tmp = (char *)src.vir_addr; + fpr = fopen("/sdcard/testin.yuv", "rb"); + for (i = 0; i < SRC_HEIGHT; i++) { + if (fpr)fread(tmp, 1, SRC_WIDTH, fpr); + tmp += src_vir_width; + } + tmp = (char *)src.vir_addr; + if (fpr)fread(&tmp[src_vir_width * src_vir_height], 1, SRC_WIDTH * SRC_HEIGHT / 2, fpr); + if (fpr)fclose(fpr); + + for (i = 0; i < SRC_HEIGHT / 2; i++) { //planar to semi planar + for (j = 0; j < SRC_WIDTH / 2; j++) { //planar to semi planar + tmpbuf[i * src_vir_width + j * 2 + 0] = tmp[src_vir_width * src_vir_height + i * SRC_WIDTH / 2 + j]; + tmpbuf[i * src_vir_width + j * 2 + 1] = tmp[src_vir_width * src_vir_height + SRC_WIDTH * SRC_HEIGHT / 4 + i * SRC_WIDTH / 2 + j]; + } + } + memcpy(&tmp[src_vir_width * src_vir_height], tmpbuf, src_vir_width * src_vir_height / 2); + //memset(&tmp[SRC_WIDTH*SRC_HEIGHT], 0x80, SRC_WIDTH*SRC_HEIGHT/2); +#endif + VPUMemClean(&src); + } + + while (1) { + printf("framecnt=%d\n", framecnt); + + if (framecnt++ >= 1) + break; + + wid_alig16 = ((SRC_WIDTH + 15) & (~0xf)); + hei_alig16 = ((SRC_HEIGHT + 15) & (~0xf)); + + android::PP_OPERATION opt; + memset(&opt, 0, sizeof(opt)); + opt.srcAddr = src.phy_addr; + opt.srcFormat = PP_IN_FORMAT_YUV420SEMI; + opt.srcWidth = SRC_WIDTH; + opt.srcHeight = SRC_HEIGHT; + opt.srcHStride = src_vir_width; + opt.srcVStride = src_vir_height; + opt.srcX = 0; + opt.srcY = 0; + if (wid_alig16 != SRC_WIDTH) + opt.srcCrop8R = 1; + if (hei_alig16 != SRC_HEIGHT) + opt.srcCrop8D = 1; + + wid_alig16 = ((DST_WIDTH + 15) & (~0xf)); + hei_alig16 = ((DST_HEIGHT + 15) & (~0xf)); + + opt.dstAddr = dst.phy_addr; + opt.dstFormat = PP_OUT_FORMAT_YUV420INTERLAVE; + opt.dstWidth = DST_WIDTH; + opt.dstHeight = DST_HEIGHT; + opt.dstHStride = dst_vir_width; + opt.dstVStride = dst_vir_height; + opt.dstX = 0; + opt.dstY = 0; + + opt.deinterlace = 0; + + opt.rotation = PP_ROTATION_RIGHT_90;//PP_ROTATION_RIGHT_90;//PP_ROTATION_RIGHT_90;//PP_ROTATION_RIGHT_90; + + opt.vpuFd = vpuFd; + ret |= android::ppOpInit(&hnd, &opt); + if (ret) { + ALOGE("ppOpInit failed"); + hnd = NULL; + goto end; + } + ret = android::ppOpPerform(hnd); + if (ret) { + ALOGE("ppOpPerform failed"); + } + ret = android::ppOpSync(hnd); + if (ret) { + ALOGE("ppOpSync failed"); + } + ret = android::ppOpRelease(hnd); + if (ret) { + ALOGE("ppOpPerform failed"); + } + + VPUMemInvalidate(&dst); + { +#if 0 + int i, j, ret = 0; + char *tmp = (char *)dst.vir_addr; + /*for(i=0; i<3; i++) + { + printf("col out_pos=%d, 0x%x\n", i*DST_WIDTH, tmp[i*DST_WIDTH]); + } + for(i=0; i<3; i++) + { + printf("las out_pos=%d, 0x%x\n", (DST_HEIGHT-1-i)*DST_WIDTH, tmp[(DST_HEIGHT-1-i)*DST_WIDTH]); + }*/ + for (i = 0; i < DST_HEIGHT; i++) { + for (j = 0; j < DST_WIDTH; j++) { + if ( tmp[i * DST_WIDTH + j] != (i & 0xff)) + ret = 1; + } + } + if ( ret) + printf("framecount=%d pp operation is failed!\n", (framecnt - 1)); + else + printf("framecount=%d pp operation is suceess!\n", (framecnt - 1)); + + memset(dst.vir_addr, 0xff, DST_SIZE); + VPUMemClean(&dst); +#endif + +#if 1 + char *tmp = (char *)dst.vir_addr; + //memset(&tmp[DST_WIDTH*DST_HEIGHT], 0x80, DST_WIDTH*DST_HEIGHT/2); + //VPUMemClean(&dst); + fpw = fopen("/data/testout.yuv", "wb+"); + + if (fpw)fwrite((char *)(dst.vir_addr), 1, dst_vir_width * dst_vir_height * 3 / 2, fpw); + if (fpw)fclose(fpw); +#endif + } + } + +end: + if (tmpbuf)free(tmpbuf); + if (src.phy_addr) VPUFreeLinear(&src); + if (dst.phy_addr) VPUFreeLinear(&dst); + if (vpuFd > 0) VPUClientRelease(vpuFd); + ALOGI("ppOp test end\n"); + return 0; +} + +#endif + diff --git a/mpp/legacy/ppOp.h b/mpp/legacy/ppOp.h index b6cd2f87..757164fa 100644 --- a/mpp/legacy/ppOp.h +++ b/mpp/legacy/ppOp.h @@ -1,116 +1,116 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _PPOP_H_ -#define _PPOP_H_ - -#ifdef RKPLATFORM -#include - -typedef RK_S32 status_t; - -namespace android -{ - -#define PP_IN_FORMAT_YUV422INTERLAVE 0 -#define PP_IN_FORMAT_YUV420SEMI 1 -#define PP_IN_FORMAT_YUV420PLANAR 2 -#define PP_IN_FORMAT_YUV400 3 -#define PP_IN_FORMAT_YUV422SEMI 4 -#define PP_IN_FORMAT_YUV420SEMITIELED 5 -#define PP_IN_FORMAT_YUV440SEMI 6 -#define PP_IN_FORMAT_YUV444_SEMI 7 -#define PP_IN_FORMAT_YUV411_SEMI 8 - -#define PP_OUT_FORMAT_RGB565 0 -#define PP_OUT_FORMAT_ARGB 1 -#define PP_OUT_FORMAT_ABGR 2 -#define PP_OUT_FORMAT_YUV422INTERLAVE 3 -#define PP_OUT_FORMAT_YUV420INTERLAVE 5 - -#define PP_ROTATION_NONE 0U -#define PP_ROTATION_RIGHT_90 1U -#define PP_ROTATION_LEFT_90 2U -#define PP_ROTATION_HOR_FLIP 3U -#define PP_ROTATION_VER_FLIP 4U -#define PP_ROTATION_180 5U - -typedef struct { - RK_U32 srcAddr; // 16 align - RK_U32 srcFormat; - RK_U32 srcWidth; // 16 align max 2048 - RK_U32 srcHeight; // 16 align max 2048 - RK_U32 srcHStride; // 16 align max 2048 - RK_U32 srcVStride; // 16 align max 2048 - RK_U32 srcCrop8R; // crop rigth - RK_U32 srcCrop8D; // crop down - RK_U32 srcX; // src x - RK_U32 srcY; // src y - RK_U32 srcReserv[2]; - - RK_U32 dstAddr; // 16 align - RK_U32 dstFormat; - RK_U32 dstWidth; // 16 align max 2048 - RK_U32 dstHeight; // 16 align max 2048 - RK_U32 dstHStride; // 16 align max 2048 - RK_U32 dstVStride; // 16 align max 2048 - RK_U32 dstReserv[2]; - RK_U32 dstX; // dst x - RK_U32 dstY; // dst y - - RK_U32 vpuFd; // VPUClient handle - RK_U32 rotation; // rotation angel - RK_U32 yuvFullRange; // yuv is full range or not, set yuv trans table - RK_U32 deinterlace; // do deinterlace or not - RK_U32 optReserv[13]; -} PP_OPERATION; - - -typedef enum { - PP_SET_SRC_ADDR = 0, - PP_SET_SRC_FORMAT, - PP_SET_SRC_WIDTH, - PP_SET_SRC_HEIGHT, - PP_SET_SRC_HSTRIDE, - PP_SET_SRC_VSTRIDE, - - PP_SET_DST_ADDR = 8, - PP_SET_DST_FORMAT, - PP_SET_DST_WIDTH, - PP_SET_DST_HEIGHT, - PP_SET_DST_HSTRIDE, - PP_SET_DST_VSTRIDE, - - PP_SET_VPU_FD = 16, // important must be set or use ppOpSet to set this fd - PP_SET_ROTATION, - PP_SET_YUV_RANGE, - PP_SET_DEINTERLACE, - - PP_SET_BUTT = 32, -} PP_SET_OPT; - -typedef void* PP_OP_HANDLE; - -status_t ppOpInit(PP_OP_HANDLE *hnd, PP_OPERATION *init); -status_t ppOpSet(PP_OP_HANDLE hnd, PP_SET_OPT opt, RK_U32 val); -status_t ppOpPerform(PP_OP_HANDLE hnd); -status_t ppOpSync(PP_OP_HANDLE hnd); -status_t ppOpRelease(PP_OP_HANDLE hnd); - -} -#endif -#endif // _PPOP_H_ - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _PPOP_H_ +#define _PPOP_H_ + +#ifdef RKPLATFORM +#include + +typedef RK_S32 status_t; + +namespace android +{ + +#define PP_IN_FORMAT_YUV422INTERLAVE 0 +#define PP_IN_FORMAT_YUV420SEMI 1 +#define PP_IN_FORMAT_YUV420PLANAR 2 +#define PP_IN_FORMAT_YUV400 3 +#define PP_IN_FORMAT_YUV422SEMI 4 +#define PP_IN_FORMAT_YUV420SEMITIELED 5 +#define PP_IN_FORMAT_YUV440SEMI 6 +#define PP_IN_FORMAT_YUV444_SEMI 7 +#define PP_IN_FORMAT_YUV411_SEMI 8 + +#define PP_OUT_FORMAT_RGB565 0 +#define PP_OUT_FORMAT_ARGB 1 +#define PP_OUT_FORMAT_ABGR 2 +#define PP_OUT_FORMAT_YUV422INTERLAVE 3 +#define PP_OUT_FORMAT_YUV420INTERLAVE 5 + +#define PP_ROTATION_NONE 0U +#define PP_ROTATION_RIGHT_90 1U +#define PP_ROTATION_LEFT_90 2U +#define PP_ROTATION_HOR_FLIP 3U +#define PP_ROTATION_VER_FLIP 4U +#define PP_ROTATION_180 5U + +typedef struct { + RK_U32 srcAddr; // 16 align + RK_U32 srcFormat; + RK_U32 srcWidth; // 16 align max 2048 + RK_U32 srcHeight; // 16 align max 2048 + RK_U32 srcHStride; // 16 align max 2048 + RK_U32 srcVStride; // 16 align max 2048 + RK_U32 srcCrop8R; // crop rigth + RK_U32 srcCrop8D; // crop down + RK_U32 srcX; // src x + RK_U32 srcY; // src y + RK_U32 srcReserv[2]; + + RK_U32 dstAddr; // 16 align + RK_U32 dstFormat; + RK_U32 dstWidth; // 16 align max 2048 + RK_U32 dstHeight; // 16 align max 2048 + RK_U32 dstHStride; // 16 align max 2048 + RK_U32 dstVStride; // 16 align max 2048 + RK_U32 dstReserv[2]; + RK_U32 dstX; // dst x + RK_U32 dstY; // dst y + + RK_U32 vpuFd; // VPUClient handle + RK_U32 rotation; // rotation angel + RK_U32 yuvFullRange; // yuv is full range or not, set yuv trans table + RK_U32 deinterlace; // do deinterlace or not + RK_U32 optReserv[13]; +} PP_OPERATION; + + +typedef enum { + PP_SET_SRC_ADDR = 0, + PP_SET_SRC_FORMAT, + PP_SET_SRC_WIDTH, + PP_SET_SRC_HEIGHT, + PP_SET_SRC_HSTRIDE, + PP_SET_SRC_VSTRIDE, + + PP_SET_DST_ADDR = 8, + PP_SET_DST_FORMAT, + PP_SET_DST_WIDTH, + PP_SET_DST_HEIGHT, + PP_SET_DST_HSTRIDE, + PP_SET_DST_VSTRIDE, + + PP_SET_VPU_FD = 16, // important must be set or use ppOpSet to set this fd + PP_SET_ROTATION, + PP_SET_YUV_RANGE, + PP_SET_DEINTERLACE, + + PP_SET_BUTT = 32, +} PP_SET_OPT; + +typedef void* PP_OP_HANDLE; + +status_t ppOpInit(PP_OP_HANDLE *hnd, PP_OPERATION *init); +status_t ppOpSet(PP_OP_HANDLE hnd, PP_SET_OPT opt, RK_U32 val); +status_t ppOpPerform(PP_OP_HANDLE hnd); +status_t ppOpSync(PP_OP_HANDLE hnd); +status_t ppOpRelease(PP_OP_HANDLE hnd); + +} +#endif +#endif // _PPOP_H_ + diff --git a/mpp/legacy/vpu_api_legacy.h b/mpp/legacy/vpu_api_legacy.h index 4863b868..8fc3df26 100644 --- a/mpp/legacy/vpu_api_legacy.h +++ b/mpp/legacy/vpu_api_legacy.h @@ -1,94 +1,94 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _VPU_API_LEGACY_H_ -#define _VPU_API_LEGACY_H_ - -#include "vpu_api.h" -#include "rk_mpi.h" -#include - -#define OMX_BUFFERFLAG_EOS 0x00000001 - -#define VPU_API_DBG_FUNCTION (0x00000001) -#define VPU_API_DBG_DUMP_YUV (0x00000002) -#define VPU_API_DBG_DUMP_LOG (0x00000004) -#define VPU_API_DBG_INPUT (0x00000010) -#define VPU_API_DBG_OUTPUT (0x00000020) - -#define vpu_api_dbg(flag, fmt, ...) _mpp_dbg(vpu_api_debug, flag, fmt, ## __VA_ARGS__) -#define vpu_api_dbg_f(flag, fmt, ...) _mpp_dbg_f(vpu_api_debug, flag, fmt, ## __VA_ARGS__) - -#define vpu_api_dbg_func(fmt, ...) vpu_api_dbg_f(VPU_API_DBG_FUNCTION, fmt, ## __VA_ARGS__) -#define vpu_api_dbg_input(fmt, ...) vpu_api_dbg_f(VPU_API_DBG_INPUT, fmt, ## __VA_ARGS__) -#define vpu_api_dbg_output(fmt, ...) vpu_api_dbg_f(VPU_API_DBG_OUTPUT, fmt, ## __VA_ARGS__) - -extern RK_U32 vpu_api_debug; - -typedef enum { - INPUT_FORMAT_MAP, -} PerformCmd; - -class VpuApiLegacy -{ -public: - VpuApiLegacy(); - ~VpuApiLegacy(); - - RK_S32 init(VpuCodecContext *ctx, RK_U8 *extraData, RK_U32 extra_size); - RK_S32 flush(VpuCodecContext *ctx); - - RK_S32 decode(VpuCodecContext *ctx, VideoPacket_t *pkt, DecoderOut_t *aDecOut); - RK_S32 decode_sendstream(VideoPacket_t *pkt); - RK_S32 decode_getoutframe(DecoderOut_t *aDecOut); - RK_S32 preProcessPacket(VpuCodecContext *ctx, VideoPacket_t *pkt); - - RK_S32 encode(VpuCodecContext *ctx, EncInputStream_t *aEncInStrm, EncoderOut_t *aEncOut); - RK_S32 encoder_sendframe(VpuCodecContext *ctx, EncInputStream_t *aEncInStrm); - RK_S32 encoder_getstream(VpuCodecContext *ctx, EncoderOut_t *aEncOut); - - RK_S32 perform(PerformCmd cmd, RK_S32 *data); - RK_S32 control(VpuCodecContext *ctx, VPU_API_CMD cmd, void *param); - -private: - RK_S32 getDecoderFormat(VpuCodecContext *ctx, DecoderFormat_t *decoder_format); - -private: - MppCtx mpp_ctx; - MppApi *mpi; - RK_U32 init_ok; - RK_U32 frame_count; - RK_U32 set_eos; - - RK_U32 block_input; - RK_U32 block_output; - - FILE *fp; - RK_U8 *fp_buf; - - /* encoder parameters */ - MppBufferGroup memGroup; - RK_U8* outData; - EncInputPictureType enc_in_fmt; - - RK_S32 fd_input; - RK_S32 fd_output; - - RK_U32 mEosSet; -}; - -#endif /*_VPU_API_H_*/ - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _VPU_API_LEGACY_H_ +#define _VPU_API_LEGACY_H_ + +#include "vpu_api.h" +#include "rk_mpi.h" +#include + +#define OMX_BUFFERFLAG_EOS 0x00000001 + +#define VPU_API_DBG_FUNCTION (0x00000001) +#define VPU_API_DBG_DUMP_YUV (0x00000002) +#define VPU_API_DBG_DUMP_LOG (0x00000004) +#define VPU_API_DBG_INPUT (0x00000010) +#define VPU_API_DBG_OUTPUT (0x00000020) + +#define vpu_api_dbg(flag, fmt, ...) _mpp_dbg(vpu_api_debug, flag, fmt, ## __VA_ARGS__) +#define vpu_api_dbg_f(flag, fmt, ...) _mpp_dbg_f(vpu_api_debug, flag, fmt, ## __VA_ARGS__) + +#define vpu_api_dbg_func(fmt, ...) vpu_api_dbg_f(VPU_API_DBG_FUNCTION, fmt, ## __VA_ARGS__) +#define vpu_api_dbg_input(fmt, ...) vpu_api_dbg_f(VPU_API_DBG_INPUT, fmt, ## __VA_ARGS__) +#define vpu_api_dbg_output(fmt, ...) vpu_api_dbg_f(VPU_API_DBG_OUTPUT, fmt, ## __VA_ARGS__) + +extern RK_U32 vpu_api_debug; + +typedef enum { + INPUT_FORMAT_MAP, +} PerformCmd; + +class VpuApiLegacy +{ +public: + VpuApiLegacy(); + ~VpuApiLegacy(); + + RK_S32 init(VpuCodecContext *ctx, RK_U8 *extraData, RK_U32 extra_size); + RK_S32 flush(VpuCodecContext *ctx); + + RK_S32 decode(VpuCodecContext *ctx, VideoPacket_t *pkt, DecoderOut_t *aDecOut); + RK_S32 decode_sendstream(VideoPacket_t *pkt); + RK_S32 decode_getoutframe(DecoderOut_t *aDecOut); + RK_S32 preProcessPacket(VpuCodecContext *ctx, VideoPacket_t *pkt); + + RK_S32 encode(VpuCodecContext *ctx, EncInputStream_t *aEncInStrm, EncoderOut_t *aEncOut); + RK_S32 encoder_sendframe(VpuCodecContext *ctx, EncInputStream_t *aEncInStrm); + RK_S32 encoder_getstream(VpuCodecContext *ctx, EncoderOut_t *aEncOut); + + RK_S32 perform(PerformCmd cmd, RK_S32 *data); + RK_S32 control(VpuCodecContext *ctx, VPU_API_CMD cmd, void *param); + +private: + RK_S32 getDecoderFormat(VpuCodecContext *ctx, DecoderFormat_t *decoder_format); + +private: + MppCtx mpp_ctx; + MppApi *mpi; + RK_U32 init_ok; + RK_U32 frame_count; + RK_U32 set_eos; + + RK_U32 block_input; + RK_U32 block_output; + + FILE *fp; + RK_U8 *fp_buf; + + /* encoder parameters */ + MppBufferGroup memGroup; + RK_U8* outData; + EncInputPictureType enc_in_fmt; + + RK_S32 fd_input; + RK_S32 fd_output; + + RK_U32 mEosSet; +}; + +#endif /*_VPU_API_H_*/ + diff --git a/mpp/legacy/vpu_mem_legacy.c b/mpp/legacy/vpu_mem_legacy.c index bab33ff4..7679628f 100644 --- a/mpp/legacy/vpu_mem_legacy.c +++ b/mpp/legacy/vpu_mem_legacy.c @@ -1,273 +1,273 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "mpp_buffer.h" -#include "vpu_mem_legacy.h" -#include "mpp_log.h" -#include "mpp_mem.h" -#include "vpu.h" -#include - -static RK_S32 commit_memory_handle(vpu_display_mem_pool *p, RK_S32 mem_hdl, RK_S32 size) -{ - MppBufferInfo info; - vpu_display_mem_pool_impl *p_mempool = (vpu_display_mem_pool_impl *)p; - - memset(&info, 0, sizeof(MppBufferInfo)); - info.type = MPP_BUFFER_TYPE_ION; - info.fd = mem_hdl; - info.size = size & 0x07ffffff; - info.index = (size & 0xf8000000) >> 27; - - p_mempool->size = size; - p_mempool->buff_size = size; - - mpp_buffer_commit(p_mempool->group, &info); - return info.fd; -} - -static void* get_free_memory_vpumem(vpu_display_mem_pool *p) -{ - MPP_RET ret = MPP_OK; - MppBuffer buffer = NULL; - VPUMemLinear_t *dmabuf = mpp_calloc(VPUMemLinear_t, 1); - vpu_display_mem_pool_impl *p_mempool = (vpu_display_mem_pool_impl *)p; - if (dmabuf == NULL) { - return NULL; - } - ret = mpp_buffer_get(p_mempool->group, &buffer, p_mempool->size); - if (MPP_OK != ret) { - mpp_free(dmabuf); - return NULL; - } - dmabuf->phy_addr = (RK_U32)mpp_buffer_get_fd(buffer); - dmabuf->vir_addr = (RK_U32*)mpp_buffer_get_ptr(buffer); - dmabuf->size = p_mempool->size; - dmabuf->offset = (RK_U32*)buffer; - return dmabuf; - -} - -static RK_S32 inc_used_memory_handle_ref(vpu_display_mem_pool *p, void * hdl) -{ - VPUMemLinear_t *dmabuf = (VPUMemLinear_t *)hdl; - MppBuffer buffer = (MppBuffer)dmabuf->offset; - if (buffer != NULL) { - mpp_buffer_inc_ref(buffer); - } - - (void)p; - return MPP_OK; -} - -static RK_S32 put_used_memory_handle(vpu_display_mem_pool *p, void *hdl) -{ - VPUMemLinear_t *dmabuf = (VPUMemLinear_t *)hdl; - MppBuffer buf = (MppBuffer)dmabuf->offset; - if (buf != NULL) { - mpp_buffer_put(buf); - } - (void)p; - return MPP_OK; -} - -static RK_S32 get_free_memory_num(vpu_display_mem_pool *p) -{ - vpu_display_mem_pool_impl *p_mempool = (vpu_display_mem_pool_impl *)p; - if (p_mempool->group != NULL) { - return mpp_buffer_group_unused(p_mempool->group); - } - return 0; -} - -static RK_S32 reset_vpu_mem_pool(vpu_display_mem_pool *p) -{ - vpu_display_mem_pool_impl *p_mempool = (vpu_display_mem_pool_impl *)p; - mpp_buffer_group_clear(p_mempool->group); - return 0; -} - - -vpu_display_mem_pool* open_vpu_memory_pool() -{ - vpu_display_mem_pool_impl *p_mempool = mpp_calloc(vpu_display_mem_pool_impl, 1); - - if (NULL == p_mempool) { - return NULL; - } - mpp_buffer_group_get_external(&p_mempool->group, MPP_BUFFER_TYPE_ION); - if (NULL == p_mempool->group) { - return NULL; - } - p_mempool->commit_hdl = commit_memory_handle; - p_mempool->get_free = get_free_memory_vpumem; - p_mempool->put_used = put_used_memory_handle; - p_mempool->inc_used = inc_used_memory_handle_ref; - p_mempool->reset = reset_vpu_mem_pool; - p_mempool->get_unused_num = get_free_memory_num; - p_mempool->version = 1; - p_mempool->buff_size = -1; - return (vpu_display_mem_pool*)p_mempool; -} - -void close_vpu_memory_pool(vpu_display_mem_pool *p) -{ - vpu_display_mem_pool_impl *p_mempool = (vpu_display_mem_pool_impl *)p; - - mpp_buffer_group_put(p_mempool->group); - mpp_free(p_mempool); - return; -} - -int create_vpu_memory_pool_allocator(vpu_display_mem_pool **ipool, int num, int size) -{ - vpu_display_mem_pool_impl *p_mempool = mpp_calloc(vpu_display_mem_pool_impl, 1); - if (NULL == p_mempool) { - return -1; - } - mpp_buffer_group_get_internal(&p_mempool->group, MPP_BUFFER_TYPE_ION); - mpp_buffer_group_limit_config(p_mempool->group, size, num + 4); - p_mempool->commit_hdl = commit_memory_handle; - p_mempool->get_free = get_free_memory_vpumem; - p_mempool->put_used = put_used_memory_handle; - p_mempool->inc_used = inc_used_memory_handle_ref; - p_mempool->reset = reset_vpu_mem_pool; - p_mempool->get_unused_num = get_free_memory_num; - p_mempool->version = 0; - p_mempool->buff_size = size; - p_mempool->size = size; - *ipool = (vpu_display_mem_pool*)p_mempool; - return 0; -} - -void release_vpu_memory_pool_allocator(vpu_display_mem_pool *ipool) -{ - vpu_display_mem_pool_impl *p_mempool = (vpu_display_mem_pool_impl *)ipool; - if (p_mempool == NULL) { - return; - } - - if (p_mempool->group) { - mpp_buffer_group_put(p_mempool->group); - p_mempool->group = NULL; - } - mpp_free(p_mempool); - p_mempool = NULL; - return; -} - -RK_S32 VPUMemJudgeIommu() -{ - int ret = 0; -#ifdef RKPLATFORM - if (VPUClientGetIOMMUStatus() > 0) { - //mpp_err("media.used.iommu"); - ret = 1; - } -#endif - return ret; -} - - -RK_S32 VPUMallocLinear(VPUMemLinear_t *p, RK_U32 size) -{ - int ret = 0; - MppBuffer buffer = NULL; - ret = mpp_buffer_get(NULL, &buffer, size); - if (ret != MPP_OK) { - return -1; - } - p->phy_addr = (RK_U32)mpp_buffer_get_fd(buffer); - p->vir_addr = (RK_U32*)mpp_buffer_get_ptr(buffer); - p->size = size; - p->offset = (RK_U32*)buffer; - return 0; -} - -RK_S32 VPUMallocLinearFromRender(VPUMemLinear_t *p, RK_U32 size, void *ctx) -{ - VPUMemLinear_t *dma_buf = NULL; - vpu_display_mem_pool_impl *p_mempool = (vpu_display_mem_pool_impl *)ctx; - if (ctx == NULL) { - return VPUMallocLinear(p, size); - } - dma_buf = (VPUMemLinear_t *)p_mempool->get_free((vpu_display_mem_pool *)ctx); - memset(p, 0, sizeof(VPUMemLinear_t)); - if (dma_buf != NULL) { - if (dma_buf->size < size) { - mpp_free(dma_buf); - return -1; - } - memcpy(p, dma_buf, sizeof(VPUMemLinear_t)); - mpp_free(dma_buf); - return 0; - } - return -1; -} - - -RK_S32 VPUFreeLinear(VPUMemLinear_t *p) -{ - if (p->offset != NULL) { - put_used_memory_handle(NULL, p); - } - return 0; -} - - -RK_S32 VPUMemDuplicate(VPUMemLinear_t *dst, VPUMemLinear_t *src) -{ - MppBuffer buffer = (MppBuffer)src->offset; - if (buffer != NULL) { - mpp_buffer_inc_ref(buffer); - } - memcpy(dst, src, sizeof(VPUMemLinear_t)); - return 0; -} - -RK_S32 VPUMemLink(VPUMemLinear_t *p) -{ - (void)p; - return 0; -} - -RK_S32 VPUMemFlush(VPUMemLinear_t *p) -{ - (void)p; - return 0; -} - -RK_S32 VPUMemClean(VPUMemLinear_t *p) -{ - (void)p; - return 0; -} - - -RK_S32 VPUMemInvalidate(VPUMemLinear_t *p) -{ - (void)p; - return 0; -} - -RK_S32 VPUMemGetFD(VPUMemLinear_t *p) -{ - RK_S32 fd = 0; - MppBuffer buffer = (MppBuffer)p->offset; - fd = mpp_buffer_get_fd(buffer); - return fd; -} - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mpp_buffer.h" +#include "vpu_mem_legacy.h" +#include "mpp_log.h" +#include "mpp_mem.h" +#include "vpu.h" +#include + +static RK_S32 commit_memory_handle(vpu_display_mem_pool *p, RK_S32 mem_hdl, RK_S32 size) +{ + MppBufferInfo info; + vpu_display_mem_pool_impl *p_mempool = (vpu_display_mem_pool_impl *)p; + + memset(&info, 0, sizeof(MppBufferInfo)); + info.type = MPP_BUFFER_TYPE_ION; + info.fd = mem_hdl; + info.size = size & 0x07ffffff; + info.index = (size & 0xf8000000) >> 27; + + p_mempool->size = size; + p_mempool->buff_size = size; + + mpp_buffer_commit(p_mempool->group, &info); + return info.fd; +} + +static void* get_free_memory_vpumem(vpu_display_mem_pool *p) +{ + MPP_RET ret = MPP_OK; + MppBuffer buffer = NULL; + VPUMemLinear_t *dmabuf = mpp_calloc(VPUMemLinear_t, 1); + vpu_display_mem_pool_impl *p_mempool = (vpu_display_mem_pool_impl *)p; + if (dmabuf == NULL) { + return NULL; + } + ret = mpp_buffer_get(p_mempool->group, &buffer, p_mempool->size); + if (MPP_OK != ret) { + mpp_free(dmabuf); + return NULL; + } + dmabuf->phy_addr = (RK_U32)mpp_buffer_get_fd(buffer); + dmabuf->vir_addr = (RK_U32*)mpp_buffer_get_ptr(buffer); + dmabuf->size = p_mempool->size; + dmabuf->offset = (RK_U32*)buffer; + return dmabuf; + +} + +static RK_S32 inc_used_memory_handle_ref(vpu_display_mem_pool *p, void * hdl) +{ + VPUMemLinear_t *dmabuf = (VPUMemLinear_t *)hdl; + MppBuffer buffer = (MppBuffer)dmabuf->offset; + if (buffer != NULL) { + mpp_buffer_inc_ref(buffer); + } + + (void)p; + return MPP_OK; +} + +static RK_S32 put_used_memory_handle(vpu_display_mem_pool *p, void *hdl) +{ + VPUMemLinear_t *dmabuf = (VPUMemLinear_t *)hdl; + MppBuffer buf = (MppBuffer)dmabuf->offset; + if (buf != NULL) { + mpp_buffer_put(buf); + } + (void)p; + return MPP_OK; +} + +static RK_S32 get_free_memory_num(vpu_display_mem_pool *p) +{ + vpu_display_mem_pool_impl *p_mempool = (vpu_display_mem_pool_impl *)p; + if (p_mempool->group != NULL) { + return mpp_buffer_group_unused(p_mempool->group); + } + return 0; +} + +static RK_S32 reset_vpu_mem_pool(vpu_display_mem_pool *p) +{ + vpu_display_mem_pool_impl *p_mempool = (vpu_display_mem_pool_impl *)p; + mpp_buffer_group_clear(p_mempool->group); + return 0; +} + + +vpu_display_mem_pool* open_vpu_memory_pool() +{ + vpu_display_mem_pool_impl *p_mempool = mpp_calloc(vpu_display_mem_pool_impl, 1); + + if (NULL == p_mempool) { + return NULL; + } + mpp_buffer_group_get_external(&p_mempool->group, MPP_BUFFER_TYPE_ION); + if (NULL == p_mempool->group) { + return NULL; + } + p_mempool->commit_hdl = commit_memory_handle; + p_mempool->get_free = get_free_memory_vpumem; + p_mempool->put_used = put_used_memory_handle; + p_mempool->inc_used = inc_used_memory_handle_ref; + p_mempool->reset = reset_vpu_mem_pool; + p_mempool->get_unused_num = get_free_memory_num; + p_mempool->version = 1; + p_mempool->buff_size = -1; + return (vpu_display_mem_pool*)p_mempool; +} + +void close_vpu_memory_pool(vpu_display_mem_pool *p) +{ + vpu_display_mem_pool_impl *p_mempool = (vpu_display_mem_pool_impl *)p; + + mpp_buffer_group_put(p_mempool->group); + mpp_free(p_mempool); + return; +} + +int create_vpu_memory_pool_allocator(vpu_display_mem_pool **ipool, int num, int size) +{ + vpu_display_mem_pool_impl *p_mempool = mpp_calloc(vpu_display_mem_pool_impl, 1); + if (NULL == p_mempool) { + return -1; + } + mpp_buffer_group_get_internal(&p_mempool->group, MPP_BUFFER_TYPE_ION); + mpp_buffer_group_limit_config(p_mempool->group, size, num + 4); + p_mempool->commit_hdl = commit_memory_handle; + p_mempool->get_free = get_free_memory_vpumem; + p_mempool->put_used = put_used_memory_handle; + p_mempool->inc_used = inc_used_memory_handle_ref; + p_mempool->reset = reset_vpu_mem_pool; + p_mempool->get_unused_num = get_free_memory_num; + p_mempool->version = 0; + p_mempool->buff_size = size; + p_mempool->size = size; + *ipool = (vpu_display_mem_pool*)p_mempool; + return 0; +} + +void release_vpu_memory_pool_allocator(vpu_display_mem_pool *ipool) +{ + vpu_display_mem_pool_impl *p_mempool = (vpu_display_mem_pool_impl *)ipool; + if (p_mempool == NULL) { + return; + } + + if (p_mempool->group) { + mpp_buffer_group_put(p_mempool->group); + p_mempool->group = NULL; + } + mpp_free(p_mempool); + p_mempool = NULL; + return; +} + +RK_S32 VPUMemJudgeIommu() +{ + int ret = 0; +#ifdef RKPLATFORM + if (VPUClientGetIOMMUStatus() > 0) { + //mpp_err("media.used.iommu"); + ret = 1; + } +#endif + return ret; +} + + +RK_S32 VPUMallocLinear(VPUMemLinear_t *p, RK_U32 size) +{ + int ret = 0; + MppBuffer buffer = NULL; + ret = mpp_buffer_get(NULL, &buffer, size); + if (ret != MPP_OK) { + return -1; + } + p->phy_addr = (RK_U32)mpp_buffer_get_fd(buffer); + p->vir_addr = (RK_U32*)mpp_buffer_get_ptr(buffer); + p->size = size; + p->offset = (RK_U32*)buffer; + return 0; +} + +RK_S32 VPUMallocLinearFromRender(VPUMemLinear_t *p, RK_U32 size, void *ctx) +{ + VPUMemLinear_t *dma_buf = NULL; + vpu_display_mem_pool_impl *p_mempool = (vpu_display_mem_pool_impl *)ctx; + if (ctx == NULL) { + return VPUMallocLinear(p, size); + } + dma_buf = (VPUMemLinear_t *)p_mempool->get_free((vpu_display_mem_pool *)ctx); + memset(p, 0, sizeof(VPUMemLinear_t)); + if (dma_buf != NULL) { + if (dma_buf->size < size) { + mpp_free(dma_buf); + return -1; + } + memcpy(p, dma_buf, sizeof(VPUMemLinear_t)); + mpp_free(dma_buf); + return 0; + } + return -1; +} + + +RK_S32 VPUFreeLinear(VPUMemLinear_t *p) +{ + if (p->offset != NULL) { + put_used_memory_handle(NULL, p); + } + return 0; +} + + +RK_S32 VPUMemDuplicate(VPUMemLinear_t *dst, VPUMemLinear_t *src) +{ + MppBuffer buffer = (MppBuffer)src->offset; + if (buffer != NULL) { + mpp_buffer_inc_ref(buffer); + } + memcpy(dst, src, sizeof(VPUMemLinear_t)); + return 0; +} + +RK_S32 VPUMemLink(VPUMemLinear_t *p) +{ + (void)p; + return 0; +} + +RK_S32 VPUMemFlush(VPUMemLinear_t *p) +{ + (void)p; + return 0; +} + +RK_S32 VPUMemClean(VPUMemLinear_t *p) +{ + (void)p; + return 0; +} + + +RK_S32 VPUMemInvalidate(VPUMemLinear_t *p) +{ + (void)p; + return 0; +} + +RK_S32 VPUMemGetFD(VPUMemLinear_t *p) +{ + RK_S32 fd = 0; + MppBuffer buffer = (MppBuffer)p->offset; + fd = mpp_buffer_get_fd(buffer); + return fd; +} + diff --git a/mpp/legacy/vpu_mem_legacy.h b/mpp/legacy/vpu_mem_legacy.h index 81855d23..98fd7b99 100644 --- a/mpp/legacy/vpu_mem_legacy.h +++ b/mpp/legacy/vpu_mem_legacy.h @@ -1,27 +1,27 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef _VPU_MEM_H_ -#define _VPU_MEM_H_ - -#include "vpu_api.h" - -typedef struct vpu_display_mem_pool_impl { - vpu_display_mem_pool_FIELDS - MppBufferGroup group; - RK_S32 size; -} vpu_display_mem_pool_impl; - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _VPU_MEM_H_ +#define _VPU_MEM_H_ + +#include "vpu_api.h" + +typedef struct vpu_display_mem_pool_impl { + vpu_display_mem_pool_FIELDS + MppBufferGroup group; + RK_S32 size; +} vpu_display_mem_pool_impl; + #endif //_VPU_MEM_H_ \ No newline at end of file diff --git a/mpp/mpi.cpp b/mpp/mpi.cpp index 60945add..2988e3d9 100644 --- a/mpp/mpi.cpp +++ b/mpp/mpi.cpp @@ -1,463 +1,463 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define MODULE_TAG "mpi" - -#include - -#include "rk_mpi.h" - -#include "mpp_log.h" -#include "mpp_mem.h" -#include "mpi_impl.h" -#include "mpp.h" -#include "mpp_info.h" -#include "mpp_common.h" - -typedef struct { - MppCtxType type; - MppCodingType coding; - const char *type_name; - const char *coding_name; -} MppCodingTypeInfo; - -static MppCodingTypeInfo support_list[] = { - { MPP_CTX_DEC, MPP_VIDEO_CodingMPEG2, "dec", "mpeg2", }, - { MPP_CTX_DEC, MPP_VIDEO_CodingMPEG4, "dec", "mpeg4", }, - { MPP_CTX_DEC, MPP_VIDEO_CodingH263, "dec", "h.263", }, - { MPP_CTX_DEC, MPP_VIDEO_CodingAVC, "dec", "h.264/AVC", }, - { MPP_CTX_DEC, MPP_VIDEO_CodingHEVC, "dec", "h.265/HEVC", }, - { MPP_CTX_DEC, MPP_VIDEO_CodingVP8, "dec", "vp8", }, - { MPP_CTX_DEC, MPP_VIDEO_CodingVP9, "dec", "VP9", }, - { MPP_CTX_DEC, MPP_VIDEO_CodingAVS, "dec", "avs+", }, - { MPP_CTX_DEC, MPP_VIDEO_CodingMJPEG, "dec", "jpeg", }, - { MPP_CTX_ENC, MPP_VIDEO_CodingAVC, "enc", "h.264/AVC", }, - { MPP_CTX_ENC, MPP_VIDEO_CodingMJPEG, "enc", "jpeg", }, -}; - -#define check_mpp_ctx(ctx) _check_mpp_ctx(ctx, __FUNCTION__) - -static MPP_RET _check_mpp_ctx(MpiImpl *p, const char *caller) -{ - if (NULL == p || p->check != p || NULL == p->ctx) { - _mpp_err(MODULE_TAG, "found invalid context %p\n", caller, p); - return MPP_ERR_UNKNOW; - } - return MPP_OK; -} - -static MPP_RET mpi_decode(MppCtx ctx, MppPacket packet, MppFrame *frame) -{ - MPP_RET ret = MPP_NOK; - MpiImpl *p = (MpiImpl *)ctx; - - mpi_dbg_func("enter ctx %p packet %p frame %p\n", ctx, packet, frame); - do { - ret = check_mpp_ctx(p); - if (ret) - break; - - if (NULL == frame || NULL == packet) { - mpp_err_f("found NULL input packet %p frame %p\n", packet, frame); - ret = MPP_ERR_NULL_PTR; - break; - } - // TODO: do decode here - } while (0); - - mpi_dbg_func("leave ret %d\n", ret); - return ret; -} - -static MPP_RET mpi_decode_put_packet(MppCtx ctx, MppPacket packet) -{ - MPP_RET ret = MPP_NOK; - MpiImpl *p = (MpiImpl *)ctx; - - mpi_dbg_func("enter ctx %p packet %p\n", ctx, packet); - do { - ret = check_mpp_ctx(p); - if (ret) - break; - - if (NULL == packet) { - mpp_err_f("found NULL input packet\n"); - ret = MPP_ERR_NULL_PTR; - break; - } - - ret = p->ctx->put_packet(packet); - } while (0); - - mpi_dbg_func("leave ret %d\n", ret); - return ret; -} - -static MPP_RET mpi_decode_get_frame(MppCtx ctx, MppFrame *frame) -{ - MPP_RET ret = MPP_NOK; - MpiImpl *p = (MpiImpl *)ctx; - - mpi_dbg_func("enter ctx %p frame %p\n", ctx, frame); - do { - ret = check_mpp_ctx(p); - if (ret) - break; - - if (NULL == frame) { - mpp_err_f("found NULL input frame\n"); - ret = MPP_ERR_NULL_PTR; - break; - } - - ret = p->ctx->get_frame(frame); - } while (0); - - mpi_dbg_func("leave ret %d\n", ret); - return ret; -} - -static MPP_RET mpi_encode(MppCtx ctx, MppFrame frame, MppPacket *packet) -{ - MPP_RET ret = MPP_NOK; - MpiImpl *p = (MpiImpl *)ctx; - - mpi_dbg_func("enter ctx %p frame %p packet %p\n", ctx, frame, packet); - do { - ret = check_mpp_ctx(p); - if (ret) - break; - - if (NULL == frame || NULL == packet) { - mpp_err_f("found NULL input frame %p packet %p\n", frame, packet); - ret = MPP_ERR_NULL_PTR; - break; - } - - // TODO: do encode here - } while (0); - - mpi_dbg_func("leave ret %d\n", ret); - return ret; -} - -static MPP_RET mpi_encode_put_frame(MppCtx ctx, MppFrame frame) -{ - MPP_RET ret = MPP_NOK; - MpiImpl *p = (MpiImpl *)ctx; - - mpi_dbg_func("enter ctx %p frame %p\n", ctx, frame); - do { - ret = check_mpp_ctx(p); - if (ret) - break; - - if (NULL == frame) { - mpp_err_f("found NULL input frame\n"); - ret = MPP_ERR_NULL_PTR; - break; - } - - ret = p->ctx->put_frame(frame); - } while (0); - - mpi_dbg_func("leave ret %d\n", ret); - return ret; -} - -static MPP_RET mpi_encode_get_packet(MppCtx ctx, MppPacket *packet) -{ - MPP_RET ret = MPP_NOK; - MpiImpl *p = (MpiImpl *)ctx; - - mpi_dbg_func("enter ctx %p packet %p\n", ctx, packet); - do { - ret = check_mpp_ctx(p); - if (ret) - break; - - if (NULL == packet) { - mpp_err_f("found NULL input packet\n"); - ret = MPP_ERR_NULL_PTR; - break; - } - - ret = p->ctx->get_packet(packet); - } while (0); - - mpi_dbg_func("leave ret %d\n", ret); - return ret; -} - -static MPP_RET mpi_isp(MppCtx ctx, MppFrame dst, MppFrame src) -{ - MPP_RET ret = MPP_OK; - mpi_dbg_func("enter ctx %p dst %p src %p\n", ctx, dst, src); - - // TODO: do isp process here - - mpi_dbg_func("leave ret %d\n", ret); - return MPP_OK; -} - -static MPP_RET mpi_isp_put_frame(MppCtx ctx, MppFrame frame) -{ - MPP_RET ret = MPP_OK; - mpi_dbg_func("enter ctx %p frame %p\n", ctx, frame); - - // TODO: do isp put frame process here - - mpi_dbg_func("leave ret %d\n", ret); - return ret; -} - -static MPP_RET mpi_isp_get_frame(MppCtx ctx, MppFrame *frame) -{ - MPP_RET ret = MPP_OK; - mpi_dbg_func("enter ctx %p frame %p\n", ctx, frame); - - // TODO: do isp get frame process here - - mpi_dbg_func("leave ret %d\n", ret); - return ret; -} - -static MPP_RET mpi_dequeue(MppCtx ctx, MppPortType type, MppTask *task) -{ - MPP_RET ret = MPP_NOK; - MpiImpl *p = (MpiImpl *)ctx; - - mpi_dbg_func("enter ctx %p type %d task %p\n", ctx, type, task); - do { - ret = check_mpp_ctx(p); - if (ret) - break;; - - if (type >= MPP_PORT_BUTT || NULL == task) { - mpp_err_f("invalid input type %d task %p\n", type, task); - ret = MPP_ERR_UNKNOW; - break; - } - - ret = p->ctx->dequeue(type, task); - } while (0); - - mpi_dbg_func("leave ret %d\n", ret); - return ret; -} - -static MPP_RET mpi_enqueue(MppCtx ctx, MppPortType type, MppTask task) -{ - MPP_RET ret = MPP_NOK; - MpiImpl *p = (MpiImpl *)ctx; - - mpi_dbg_func("enter ctx %p type %d task %p\n", ctx, type, task); - do { - ret = check_mpp_ctx(p); - if (ret) - break;; - - if (type >= MPP_PORT_BUTT || NULL == task) { - mpp_err_f("invalid input type %d task %p\n", type, task); - ret = MPP_ERR_UNKNOW; - break; - } - - ret = p->ctx->enqueue(type, task); - } while (0); - - mpi_dbg_func("leave ret %d\n", ret); - return ret; -} - -static MPP_RET mpi_reset(MppCtx ctx) -{ - MPP_RET ret = MPP_NOK; - MpiImpl *p = (MpiImpl *)ctx; - - mpi_dbg_func("enter ctx %p\n", ctx); - do { - ret = check_mpp_ctx(p); - if (ret) - break;; - - ret = p->ctx->reset(); - } while (0); - - mpi_dbg_func("leave ret %d\n", ret); - return ret; -} - -static MPP_RET mpi_control(MppCtx ctx, MpiCmd cmd, MppParam param) -{ - MPP_RET ret = MPP_NOK; - MpiImpl *p = (MpiImpl *)ctx; - - mpi_dbg_func("enter ctx %p cmd %x parm %p\n", ctx, cmd, param); - do { - ret = check_mpp_ctx(p); - if (ret) - break;; - - ret = p->ctx->control(cmd, param); - } while (0); - - mpi_dbg_func("leave ret %d\n", ret); - return ret; -} - -static MppApi mpp_api = { - sizeof(mpp_api), - 0, - mpi_decode, - mpi_decode_put_packet, - mpi_decode_get_frame, - mpi_encode, - mpi_encode_put_frame, - mpi_encode_get_packet, - mpi_isp, - mpi_isp_put_frame, - mpi_isp_get_frame, - mpi_dequeue, - mpi_enqueue, - mpi_reset, - mpi_control, - {0}, -}; - -MPP_RET mpp_create(MppCtx *ctx, MppApi **mpi) -{ - if (NULL == ctx || NULL == mpi) { - mpp_err_f("invalid input ctx %p mpi %p\n", ctx, mpi); - return MPP_ERR_NULL_PTR; - } - - - *ctx = NULL; - *mpi = NULL; - - MPP_RET ret = MPP_OK; - mpi_dbg_func("enter ctx %p mpi %p\n", ctx, mpi); - do { - MpiImpl *p = mpp_malloc(MpiImpl, 1); - if (NULL == p) { - mpp_err_f("failed to allocate context\n"); - ret = MPP_ERR_MALLOC; - break; - } - - memset(p, 0, sizeof(*p)); - p->ctx = new Mpp(); - if (NULL == p->ctx) { - mpp_free(p); - mpp_err_f("failed to new Mpp\n"); - ret = MPP_ERR_MALLOC; - break; - } - - mpp_api.version = mpp_info_get_revision(); - p->api = &mpp_api; - p->check = p; - *ctx = p; - *mpi = p->api; - } while (0); - - mpp_log("mpp version: %s\n", mpp_info_get(INFO_ALL)); - - mpi_dbg_func("leave ret %d ctx %p mpi %p\n", ret, *ctx, *mpi); - return ret; -} - -MPP_RET mpp_init(MppCtx ctx, MppCtxType type, MppCodingType coding) -{ - MPP_RET ret = MPP_OK; - MpiImpl *p = (MpiImpl*)ctx; - - mpi_dbg_func("enter ctx %p type %d coding %d\n", ctx, type, coding); - do { - ret = check_mpp_ctx(p); - if (ret) - break; - - if (type >= MPP_CTX_BUTT || - coding >= MPP_VIDEO_CodingMax) { - mpp_err_f("invalid input type %d coding %d\n", type, coding); - ret = MPP_ERR_UNKNOW; - break; - } - - ret = p->ctx->init(type, coding); - p->type = type; - p->coding = coding; - } while (0); - - get_mpi_debug(); - mpi_dbg_func("leave ret %d\n", ret); - return ret; -} - -MPP_RET mpp_destroy(MppCtx ctx) -{ - mpi_dbg_func("enter ctx %p\n", ctx); - - MPP_RET ret = MPP_OK; - MpiImpl *p = (MpiImpl*)ctx; - - do { - ret = check_mpp_ctx(p); - if (ret) - return ret; - - if (p->ctx) - delete p->ctx; - - mpp_free(p); - } while (0); - - mpi_dbg_func("leave ret %d\n", ret); - return ret; -} - -MPP_RET mpp_check_support_format(MppCtxType type, MppCodingType coding) -{ - MPP_RET ret = MPP_NOK; - RK_U32 i = 0; - - for (i = 0; i < MPP_ARRAY_ELEMS(support_list); i++) { - MppCodingTypeInfo *info = &support_list[i]; - if (type == info->type && - coding == info->coding) { - ret = MPP_OK; - break; - } - } - return ret; -} - -void mpp_show_support_format() -{ - RK_U32 i = 0; - - mpp_log("mpp coding type support list:"); - - for (i = 0; i < MPP_ARRAY_ELEMS(support_list); i++) { - MppCodingTypeInfo *info = &support_list[i]; - mpp_log("type: %s id %d coding: %-16s id %d\n", - info->type_name, info->type, - info->coding_name, info->coding); - } -} - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define MODULE_TAG "mpi" + +#include + +#include "rk_mpi.h" + +#include "mpp_log.h" +#include "mpp_mem.h" +#include "mpi_impl.h" +#include "mpp.h" +#include "mpp_info.h" +#include "mpp_common.h" + +typedef struct { + MppCtxType type; + MppCodingType coding; + const char *type_name; + const char *coding_name; +} MppCodingTypeInfo; + +static MppCodingTypeInfo support_list[] = { + { MPP_CTX_DEC, MPP_VIDEO_CodingMPEG2, "dec", "mpeg2", }, + { MPP_CTX_DEC, MPP_VIDEO_CodingMPEG4, "dec", "mpeg4", }, + { MPP_CTX_DEC, MPP_VIDEO_CodingH263, "dec", "h.263", }, + { MPP_CTX_DEC, MPP_VIDEO_CodingAVC, "dec", "h.264/AVC", }, + { MPP_CTX_DEC, MPP_VIDEO_CodingHEVC, "dec", "h.265/HEVC", }, + { MPP_CTX_DEC, MPP_VIDEO_CodingVP8, "dec", "vp8", }, + { MPP_CTX_DEC, MPP_VIDEO_CodingVP9, "dec", "VP9", }, + { MPP_CTX_DEC, MPP_VIDEO_CodingAVS, "dec", "avs+", }, + { MPP_CTX_DEC, MPP_VIDEO_CodingMJPEG, "dec", "jpeg", }, + { MPP_CTX_ENC, MPP_VIDEO_CodingAVC, "enc", "h.264/AVC", }, + { MPP_CTX_ENC, MPP_VIDEO_CodingMJPEG, "enc", "jpeg", }, +}; + +#define check_mpp_ctx(ctx) _check_mpp_ctx(ctx, __FUNCTION__) + +static MPP_RET _check_mpp_ctx(MpiImpl *p, const char *caller) +{ + if (NULL == p || p->check != p || NULL == p->ctx) { + _mpp_err(MODULE_TAG, "found invalid context %p\n", caller, p); + return MPP_ERR_UNKNOW; + } + return MPP_OK; +} + +static MPP_RET mpi_decode(MppCtx ctx, MppPacket packet, MppFrame *frame) +{ + MPP_RET ret = MPP_NOK; + MpiImpl *p = (MpiImpl *)ctx; + + mpi_dbg_func("enter ctx %p packet %p frame %p\n", ctx, packet, frame); + do { + ret = check_mpp_ctx(p); + if (ret) + break; + + if (NULL == frame || NULL == packet) { + mpp_err_f("found NULL input packet %p frame %p\n", packet, frame); + ret = MPP_ERR_NULL_PTR; + break; + } + // TODO: do decode here + } while (0); + + mpi_dbg_func("leave ret %d\n", ret); + return ret; +} + +static MPP_RET mpi_decode_put_packet(MppCtx ctx, MppPacket packet) +{ + MPP_RET ret = MPP_NOK; + MpiImpl *p = (MpiImpl *)ctx; + + mpi_dbg_func("enter ctx %p packet %p\n", ctx, packet); + do { + ret = check_mpp_ctx(p); + if (ret) + break; + + if (NULL == packet) { + mpp_err_f("found NULL input packet\n"); + ret = MPP_ERR_NULL_PTR; + break; + } + + ret = p->ctx->put_packet(packet); + } while (0); + + mpi_dbg_func("leave ret %d\n", ret); + return ret; +} + +static MPP_RET mpi_decode_get_frame(MppCtx ctx, MppFrame *frame) +{ + MPP_RET ret = MPP_NOK; + MpiImpl *p = (MpiImpl *)ctx; + + mpi_dbg_func("enter ctx %p frame %p\n", ctx, frame); + do { + ret = check_mpp_ctx(p); + if (ret) + break; + + if (NULL == frame) { + mpp_err_f("found NULL input frame\n"); + ret = MPP_ERR_NULL_PTR; + break; + } + + ret = p->ctx->get_frame(frame); + } while (0); + + mpi_dbg_func("leave ret %d\n", ret); + return ret; +} + +static MPP_RET mpi_encode(MppCtx ctx, MppFrame frame, MppPacket *packet) +{ + MPP_RET ret = MPP_NOK; + MpiImpl *p = (MpiImpl *)ctx; + + mpi_dbg_func("enter ctx %p frame %p packet %p\n", ctx, frame, packet); + do { + ret = check_mpp_ctx(p); + if (ret) + break; + + if (NULL == frame || NULL == packet) { + mpp_err_f("found NULL input frame %p packet %p\n", frame, packet); + ret = MPP_ERR_NULL_PTR; + break; + } + + // TODO: do encode here + } while (0); + + mpi_dbg_func("leave ret %d\n", ret); + return ret; +} + +static MPP_RET mpi_encode_put_frame(MppCtx ctx, MppFrame frame) +{ + MPP_RET ret = MPP_NOK; + MpiImpl *p = (MpiImpl *)ctx; + + mpi_dbg_func("enter ctx %p frame %p\n", ctx, frame); + do { + ret = check_mpp_ctx(p); + if (ret) + break; + + if (NULL == frame) { + mpp_err_f("found NULL input frame\n"); + ret = MPP_ERR_NULL_PTR; + break; + } + + ret = p->ctx->put_frame(frame); + } while (0); + + mpi_dbg_func("leave ret %d\n", ret); + return ret; +} + +static MPP_RET mpi_encode_get_packet(MppCtx ctx, MppPacket *packet) +{ + MPP_RET ret = MPP_NOK; + MpiImpl *p = (MpiImpl *)ctx; + + mpi_dbg_func("enter ctx %p packet %p\n", ctx, packet); + do { + ret = check_mpp_ctx(p); + if (ret) + break; + + if (NULL == packet) { + mpp_err_f("found NULL input packet\n"); + ret = MPP_ERR_NULL_PTR; + break; + } + + ret = p->ctx->get_packet(packet); + } while (0); + + mpi_dbg_func("leave ret %d\n", ret); + return ret; +} + +static MPP_RET mpi_isp(MppCtx ctx, MppFrame dst, MppFrame src) +{ + MPP_RET ret = MPP_OK; + mpi_dbg_func("enter ctx %p dst %p src %p\n", ctx, dst, src); + + // TODO: do isp process here + + mpi_dbg_func("leave ret %d\n", ret); + return MPP_OK; +} + +static MPP_RET mpi_isp_put_frame(MppCtx ctx, MppFrame frame) +{ + MPP_RET ret = MPP_OK; + mpi_dbg_func("enter ctx %p frame %p\n", ctx, frame); + + // TODO: do isp put frame process here + + mpi_dbg_func("leave ret %d\n", ret); + return ret; +} + +static MPP_RET mpi_isp_get_frame(MppCtx ctx, MppFrame *frame) +{ + MPP_RET ret = MPP_OK; + mpi_dbg_func("enter ctx %p frame %p\n", ctx, frame); + + // TODO: do isp get frame process here + + mpi_dbg_func("leave ret %d\n", ret); + return ret; +} + +static MPP_RET mpi_dequeue(MppCtx ctx, MppPortType type, MppTask *task) +{ + MPP_RET ret = MPP_NOK; + MpiImpl *p = (MpiImpl *)ctx; + + mpi_dbg_func("enter ctx %p type %d task %p\n", ctx, type, task); + do { + ret = check_mpp_ctx(p); + if (ret) + break;; + + if (type >= MPP_PORT_BUTT || NULL == task) { + mpp_err_f("invalid input type %d task %p\n", type, task); + ret = MPP_ERR_UNKNOW; + break; + } + + ret = p->ctx->dequeue(type, task); + } while (0); + + mpi_dbg_func("leave ret %d\n", ret); + return ret; +} + +static MPP_RET mpi_enqueue(MppCtx ctx, MppPortType type, MppTask task) +{ + MPP_RET ret = MPP_NOK; + MpiImpl *p = (MpiImpl *)ctx; + + mpi_dbg_func("enter ctx %p type %d task %p\n", ctx, type, task); + do { + ret = check_mpp_ctx(p); + if (ret) + break;; + + if (type >= MPP_PORT_BUTT || NULL == task) { + mpp_err_f("invalid input type %d task %p\n", type, task); + ret = MPP_ERR_UNKNOW; + break; + } + + ret = p->ctx->enqueue(type, task); + } while (0); + + mpi_dbg_func("leave ret %d\n", ret); + return ret; +} + +static MPP_RET mpi_reset(MppCtx ctx) +{ + MPP_RET ret = MPP_NOK; + MpiImpl *p = (MpiImpl *)ctx; + + mpi_dbg_func("enter ctx %p\n", ctx); + do { + ret = check_mpp_ctx(p); + if (ret) + break;; + + ret = p->ctx->reset(); + } while (0); + + mpi_dbg_func("leave ret %d\n", ret); + return ret; +} + +static MPP_RET mpi_control(MppCtx ctx, MpiCmd cmd, MppParam param) +{ + MPP_RET ret = MPP_NOK; + MpiImpl *p = (MpiImpl *)ctx; + + mpi_dbg_func("enter ctx %p cmd %x parm %p\n", ctx, cmd, param); + do { + ret = check_mpp_ctx(p); + if (ret) + break;; + + ret = p->ctx->control(cmd, param); + } while (0); + + mpi_dbg_func("leave ret %d\n", ret); + return ret; +} + +static MppApi mpp_api = { + sizeof(mpp_api), + 0, + mpi_decode, + mpi_decode_put_packet, + mpi_decode_get_frame, + mpi_encode, + mpi_encode_put_frame, + mpi_encode_get_packet, + mpi_isp, + mpi_isp_put_frame, + mpi_isp_get_frame, + mpi_dequeue, + mpi_enqueue, + mpi_reset, + mpi_control, + {0}, +}; + +MPP_RET mpp_create(MppCtx *ctx, MppApi **mpi) +{ + if (NULL == ctx || NULL == mpi) { + mpp_err_f("invalid input ctx %p mpi %p\n", ctx, mpi); + return MPP_ERR_NULL_PTR; + } + + + *ctx = NULL; + *mpi = NULL; + + MPP_RET ret = MPP_OK; + mpi_dbg_func("enter ctx %p mpi %p\n", ctx, mpi); + do { + MpiImpl *p = mpp_malloc(MpiImpl, 1); + if (NULL == p) { + mpp_err_f("failed to allocate context\n"); + ret = MPP_ERR_MALLOC; + break; + } + + memset(p, 0, sizeof(*p)); + p->ctx = new Mpp(); + if (NULL == p->ctx) { + mpp_free(p); + mpp_err_f("failed to new Mpp\n"); + ret = MPP_ERR_MALLOC; + break; + } + + mpp_api.version = mpp_info_get_revision(); + p->api = &mpp_api; + p->check = p; + *ctx = p; + *mpi = p->api; + } while (0); + + mpp_log("mpp version: %s\n", mpp_info_get(INFO_ALL)); + + mpi_dbg_func("leave ret %d ctx %p mpi %p\n", ret, *ctx, *mpi); + return ret; +} + +MPP_RET mpp_init(MppCtx ctx, MppCtxType type, MppCodingType coding) +{ + MPP_RET ret = MPP_OK; + MpiImpl *p = (MpiImpl*)ctx; + + mpi_dbg_func("enter ctx %p type %d coding %d\n", ctx, type, coding); + do { + ret = check_mpp_ctx(p); + if (ret) + break; + + if (type >= MPP_CTX_BUTT || + coding >= MPP_VIDEO_CodingMax) { + mpp_err_f("invalid input type %d coding %d\n", type, coding); + ret = MPP_ERR_UNKNOW; + break; + } + + ret = p->ctx->init(type, coding); + p->type = type; + p->coding = coding; + } while (0); + + get_mpi_debug(); + mpi_dbg_func("leave ret %d\n", ret); + return ret; +} + +MPP_RET mpp_destroy(MppCtx ctx) +{ + mpi_dbg_func("enter ctx %p\n", ctx); + + MPP_RET ret = MPP_OK; + MpiImpl *p = (MpiImpl*)ctx; + + do { + ret = check_mpp_ctx(p); + if (ret) + return ret; + + if (p->ctx) + delete p->ctx; + + mpp_free(p); + } while (0); + + mpi_dbg_func("leave ret %d\n", ret); + return ret; +} + +MPP_RET mpp_check_support_format(MppCtxType type, MppCodingType coding) +{ + MPP_RET ret = MPP_NOK; + RK_U32 i = 0; + + for (i = 0; i < MPP_ARRAY_ELEMS(support_list); i++) { + MppCodingTypeInfo *info = &support_list[i]; + if (type == info->type && + coding == info->coding) { + ret = MPP_OK; + break; + } + } + return ret; +} + +void mpp_show_support_format() +{ + RK_U32 i = 0; + + mpp_log("mpp coding type support list:"); + + for (i = 0; i < MPP_ARRAY_ELEMS(support_list); i++) { + MppCodingTypeInfo *info = &support_list[i]; + mpp_log("type: %s id %d coding: %-16s id %d\n", + info->type_name, info->type, + info->coding_name, info->coding); + } +} + diff --git a/mpp/mpi_impl.cpp b/mpp/mpi_impl.cpp index e3ee6583..04bf8d76 100644 --- a/mpp/mpi_impl.cpp +++ b/mpp/mpi_impl.cpp @@ -1,31 +1,31 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define MODULE_TAG "mpi" - -#include "rk_mpi.h" -#include "mpp_log.h" -#include "mpp_env.h" -#include "mpi_impl.h" - -RK_U32 mpi_debug = 0; - -void get_mpi_debug() -{ - mpp_env_get_u32("mpi_debug", &mpi_debug, 0); - mpp_env_get_u32("mpp_debug", &mpp_debug, 0); -} - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define MODULE_TAG "mpi" + +#include "rk_mpi.h" +#include "mpp_log.h" +#include "mpp_env.h" +#include "mpi_impl.h" + +RK_U32 mpi_debug = 0; + +void get_mpi_debug() +{ + mpp_env_get_u32("mpi_debug", &mpi_debug, 0); + mpp_env_get_u32("mpp_debug", &mpp_debug, 0); +} + diff --git a/mpp/mpi_impl.h b/mpp/mpi_impl.h index 4e41c1ee..e88148ae 100644 --- a/mpp/mpi_impl.h +++ b/mpp/mpi_impl.h @@ -1,54 +1,54 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __MPP_IMPL_H__ -#define __MPP_IMPL_H__ - -#include "mpp.h" -#include "vpu_api.h" - -#define MPI_DBG_FUNCTION (0x00000001) - - - -#define mpi_dbg(flag, fmt, ...) _mpp_dbg(mpi_debug, flag, fmt, ## __VA_ARGS__) -#define mpi_dbg_f(flag, fmt, ...) _mpp_dbg_f(mpi_debug, flag, fmt, ## __VA_ARGS__) - -#define mpi_dbg_func(fmt, ...) mpi_dbg_f(MPI_DBG_FUNCTION, fmt, ## __VA_ARGS__) - -typedef struct MpiImpl_t MpiImpl; - -struct MpiImpl_t { - MpiImpl *check; - MppCtxType type; - MppCodingType coding; - - MppApi *api; - Mpp *ctx; -}; - -#ifdef __cplusplus -extern "C" { -#endif - -extern RK_U32 mpi_debug; -void get_mpi_debug(); - -#ifdef __cplusplus -} -#endif - -#endif /*__MPP_IMPL_H__*/ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPP_IMPL_H__ +#define __MPP_IMPL_H__ + +#include "mpp.h" +#include "vpu_api.h" + +#define MPI_DBG_FUNCTION (0x00000001) + + + +#define mpi_dbg(flag, fmt, ...) _mpp_dbg(mpi_debug, flag, fmt, ## __VA_ARGS__) +#define mpi_dbg_f(flag, fmt, ...) _mpp_dbg_f(mpi_debug, flag, fmt, ## __VA_ARGS__) + +#define mpi_dbg_func(fmt, ...) mpi_dbg_f(MPI_DBG_FUNCTION, fmt, ## __VA_ARGS__) + +typedef struct MpiImpl_t MpiImpl; + +struct MpiImpl_t { + MpiImpl *check; + MppCtxType type; + MppCodingType coding; + + MppApi *api; + Mpp *ctx; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +extern RK_U32 mpi_debug; +void get_mpi_debug(); + +#ifdef __cplusplus +} +#endif + +#endif /*__MPP_IMPL_H__*/ diff --git a/mpp/mpp.cpp b/mpp/mpp.cpp index 6aaea5f7..24033de9 100644 --- a/mpp/mpp.cpp +++ b/mpp/mpp.cpp @@ -1,682 +1,682 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define MODULE_TAG "mpp" - -#include "mpp_log.h" -#include "mpp_mem.h" -#include "mpp_env.h" -#include "mpp_time.h" - -#include "mpp.h" -#include "mpp_dec.h" -#include "mpp_enc.h" -#include "mpp_hal.h" -#include "mpp_task_impl.h" -#include "mpp_buffer_impl.h" -#include "mpp_frame_impl.h" -#include "mpp_packet_impl.h" - -#define MPP_TEST_FRAME_SIZE SZ_1M -#define MPP_TEST_PACKET_SIZE SZ_512K - -Mpp::Mpp() - : mPackets(NULL), - mFrames(NULL), - mTasks(NULL), - mPacketPutCount(0), - mPacketGetCount(0), - mFramePutCount(0), - mFrameGetCount(0), - mTaskPutCount(0), - mTaskGetCount(0), - mPacketGroup(NULL), - mFrameGroup(NULL), - mExternalFrameGroup(0), - mInputPort(NULL), - mOutputPort(NULL), - mInputTaskQueue(NULL), - mOutputTaskQueue(NULL), - mThreadCodec(NULL), - mThreadHal(NULL), - mDec(NULL), - mEnc(NULL), - mType(MPP_CTX_BUTT), - mCoding(MPP_VIDEO_CodingUnused), - mInitDone(0), - mPacketBlock(0), - mInputBlock(0), - mOutputBlock(0), - mMultiFrame(0), - mInputTask(NULL), - mStatus(0), - mParserFastMode(0), - mParserNeedSplit(0), - mParserInternalPts(0) -{ -} - -MPP_RET Mpp::init(MppCtxType type, MppCodingType coding) -{ - if (mpp_check_support_format(type, coding)) { - mpp_err("unable to create unsupported type %d coding %d\n", type, coding); - return MPP_NOK; - } - - mType = type; - mCoding = coding; - switch (mType) { - case MPP_CTX_DEC : { - mPackets = new mpp_list((node_destructor)mpp_packet_deinit); - mFrames = new mpp_list((node_destructor)mpp_frame_deinit); - mTasks = new mpp_list((node_destructor)NULL); - - MppDecCfg cfg = { - coding, - mParserFastMode, - mParserNeedSplit, - mParserInternalPts, - this, - }; - mpp_dec_init(&mDec, &cfg); - - mThreadCodec = new MppThread(mpp_dec_parser_thread, this, "mpp_dec_parser"); - mThreadHal = new MppThread(mpp_dec_hal_thread, this, "mpp_dec_hal"); - - mpp_buffer_group_get_internal(&mPacketGroup, MPP_BUFFER_TYPE_ION); - mpp_buffer_group_limit_config(mPacketGroup, 0, 3); - - mpp_task_queue_init(&mInputTaskQueue); - mpp_task_queue_init(&mOutputTaskQueue); - mpp_task_queue_setup(mInputTaskQueue, 4); - mpp_task_queue_setup(mOutputTaskQueue, 4); - } break; - case MPP_CTX_ENC : { - mFrames = new mpp_list((node_destructor)NULL); - mPackets = new mpp_list((node_destructor)mpp_packet_deinit); - mTasks = new mpp_list((node_destructor)NULL); - - mpp_enc_init(&mEnc, coding); - mThreadCodec = new MppThread(mpp_enc_control_thread, this, "mpp_enc_ctrl"); - //mThreadHal = new MppThread(mpp_enc_hal_thread, this, "mpp_enc_hal"); - - mpp_buffer_group_get_internal(&mPacketGroup, MPP_BUFFER_TYPE_ION); - mpp_buffer_group_get_internal(&mFrameGroup, MPP_BUFFER_TYPE_ION); - - mpp_task_queue_init(&mInputTaskQueue); - mpp_task_queue_init(&mOutputTaskQueue); - mpp_task_queue_setup(mInputTaskQueue, 1); - mpp_task_queue_setup(mOutputTaskQueue, 1); - } break; - default : { - mpp_err("Mpp error type %d\n", mType); - } break; - } - - mInputPort = mpp_task_queue_get_port(mInputTaskQueue, MPP_PORT_INPUT); - mOutputPort = mpp_task_queue_get_port(mOutputTaskQueue, MPP_PORT_OUTPUT); - - if (mFrames && mPackets && - (mDec) && - mThreadCodec && mThreadHal && - mPacketGroup) { - mThreadCodec->start(); - mThreadHal->start(); - mInitDone = 1; - } else if (mFrames && mPackets && - (mEnc) && - mThreadCodec/* && mThreadHal */ && - mPacketGroup) { - mThreadCodec->start(); - //mThreadHal->start(); // TODO - mInitDone = 1; - } else { - mpp_err("error found on mpp initialization\n"); - clear(); - } - - mpp_env_get_u32("mpp_debug", &mpp_debug, 0); - return MPP_OK; -} - -Mpp::~Mpp () -{ - clear(); -} - -void Mpp::clear() -{ - // MUST: release listener here - if (mFrameGroup) - mpp_buffer_group_set_listener((MppBufferGroupImpl *)mFrameGroup, NULL); - - if (mThreadCodec) - mThreadCodec->stop(); - if (mThreadHal) - mThreadHal->stop(); - - if (mThreadCodec) { - delete mThreadCodec; - mThreadCodec = NULL; - } - if (mThreadHal) { - delete mThreadHal; - mThreadHal = NULL; - } - - if (mInputTaskQueue) { - mpp_task_queue_deinit(mInputTaskQueue); - mInputTaskQueue = NULL; - } - if (mOutputTaskQueue) { - mpp_task_queue_deinit(mOutputTaskQueue); - mOutputTaskQueue = NULL; - } - - mInputPort = NULL; - mOutputPort = NULL; - - if (mDec || mEnc) { - if (mType == MPP_CTX_DEC) { - mpp_dec_deinit(mDec); - mDec = NULL; - } else { - mpp_enc_deinit(mEnc); - mEnc = NULL; - } - } - if (mPackets) { - delete mPackets; - mPackets = NULL; - } - if (mFrames) { - delete mFrames; - mFrames = NULL; - } - if (mTasks) { - delete mTasks; - mTasks = NULL; - } - if (mPacketGroup) { - mpp_buffer_group_put(mPacketGroup); - mPacketGroup = NULL; - } - if (mFrameGroup && !mExternalFrameGroup) { - mpp_buffer_group_put(mFrameGroup); - mFrameGroup = NULL; - } -} - -MPP_RET Mpp::put_packet(MppPacket packet) -{ - if (!mInitDone) - return MPP_NOK; - - AutoMutex autoLock(mPackets->mutex()); - RK_U32 eos = mpp_packet_get_eos(packet); - - if (mPackets->list_size() < 4 || eos) { - MppPacket pkt; - if (MPP_OK != mpp_packet_copy_init(&pkt, packet)) - return MPP_NOK; - - mPackets->add_at_tail(&pkt, sizeof(pkt)); - mPacketPutCount++; - mThreadCodec->signal(); - return MPP_OK; - } - - return MPP_NOK; -} - -MPP_RET Mpp::get_frame(MppFrame *frame) -{ - if (!mInitDone) - return MPP_NOK; - - AutoMutex autoLock(mFrames->mutex()); - MppFrame first = NULL; - - if (0 == mFrames->list_size()) { - mThreadCodec->signal(); - if (mOutputBlock) - mFrames->wait(); - msleep(1); - } - - if (mFrames->list_size()) { - mFrames->del_at_head(&first, sizeof(frame)); - mFrameGetCount++; - mThreadHal->signal(); - - if (mMultiFrame) { - MppFrame prev = first; - MppFrame next = NULL; - while (mFrames->list_size()) { - mFrames->del_at_head(&next, sizeof(frame)); - mFrameGetCount++; - mThreadHal->signal(); - mpp_frame_set_next(prev, next); - prev = next; - } - } - } - *frame = first; - return MPP_OK; -} - -MPP_RET Mpp::put_frame(MppFrame frame) -{ - if (!mInitDone) - return MPP_NOK; - - MPP_RET ret = MPP_NOK; - MppTask task = mInputTask; - - do { - if (NULL == task) { - ret = dequeue(MPP_PORT_INPUT, &task); - if (ret) { - mpp_log_f("failed to dequeue from input port ret %d\n", ret); - break; - } - } - - /* FIXME: use wait to do block wait */ - if (mInputBlock && NULL == task) { - msleep(2); - continue; - } - - mpp_assert(task); - - ret = mpp_task_meta_set_frame(task, MPP_META_KEY_INPUT_FRM, frame); - if (ret) { - mpp_log_f("failed to set input frame to task ret %d\n", ret); - break; - } - - ret = enqueue(MPP_PORT_INPUT, task); - if (ret) { - mpp_log_f("failed to enqueue task to input port ret %d\n", ret); - break; - } - - if (mInputBlock) { - while (MPP_NOK == mpp_port_can_dequeue(mInputPort)) { - msleep(2); - } - - ret = dequeue(MPP_PORT_INPUT, &task); - if (ret) { - mpp_log_f("failed to dequeue from input port ret %d\n", ret); - break; - } - - mpp_assert(task); - ret = mpp_task_meta_get_frame(task, MPP_META_KEY_INPUT_FRM, &frame); - if (frame) { - mpp_frame_deinit(&frame); - frame = NULL; - } - } - - break; - } while (1); - - mInputTask = task; - - return ret; -} - -MPP_RET Mpp::get_packet(MppPacket *packet) -{ - if (!mInitDone) - return MPP_NOK; - - MPP_RET ret = MPP_OK; - MppTask task = NULL; - - do { - if (NULL == task) { - ret = dequeue(MPP_PORT_OUTPUT, &task); - if (ret) { - mpp_log_f("failed to dequeue from output port ret %d\n", ret); - break; - } - } - - /* FIXME: use wait to do block wait */ - if (NULL == task) { - if (mOutputBlock) { - msleep(2); - continue; - } else { - break; - } - } - - mpp_assert(task); - - ret = mpp_task_meta_get_packet(task, MPP_META_KEY_OUTPUT_PKT, packet); - if (ret) { - mpp_log_f("failed to get output packet from task ret %d\n", ret); - break; - } - - mpp_assert(*packet); - - if (mpp_debug & MPP_DBG_PTS) - mpp_log_f("pts %lld\n", mpp_packet_get_pts(*packet)); - - ret = enqueue(MPP_PORT_OUTPUT, task); - if (ret) { - mpp_log_f("failed to enqueue task to output port ret %d\n", ret); - } - - break; - } while (1); - - return ret; -} - -MPP_RET Mpp::dequeue(MppPortType type, MppTask *task) -{ - if (!mInitDone) - return MPP_NOK; - - MPP_RET ret = MPP_NOK; - AutoMutex autoLock(mPortLock); - MppTaskQueue port = NULL; - switch (type) { - case MPP_PORT_INPUT : { - port = mInputPort; - } break; - case MPP_PORT_OUTPUT : { - port = mOutputPort; - } break; - default : { - } break; - } - - if (port) - ret = mpp_port_dequeue(port, task); - - return ret; -} - -MPP_RET Mpp::enqueue(MppPortType type, MppTask task) -{ - if (!mInitDone) - return MPP_NOK; - - MPP_RET ret = MPP_NOK; - AutoMutex autoLock(mPortLock); - MppTaskQueue port = NULL; - switch (type) { - case MPP_PORT_INPUT : { - port = mInputPort; - } break; - case MPP_PORT_OUTPUT : { - port = mOutputPort; - } break; - default : { - } break; - } - - if (port) { - mThreadCodec->lock(); - ret = mpp_port_enqueue(port, task); - if (MPP_OK == ret) { - // if enqueue success wait up thread - mThreadCodec->signal(); - } - mThreadCodec->unlock(); - } - - return ret; -} - -MPP_RET Mpp::control(MpiCmd cmd, MppParam param) -{ - MPP_RET ret = MPP_NOK; - - switch (cmd & CMD_MODULE_ID_MASK) { - case CMD_MODULE_OSAL : { - ret = control_osal(cmd, param); - } break; - case CMD_MODULE_MPP : { - mpp_assert(cmd > MPP_CMD_BASE); - mpp_assert(cmd < MPP_CMD_END); - - ret = control_mpp(cmd, param); - } break; - case CMD_MODULE_CODEC : { - switch (cmd & CMD_CTX_ID_MASK) { - case CMD_CTX_ID_DEC : { - mpp_assert(mType == MPP_CTX_DEC || mType == MPP_CTX_BUTT); - mpp_assert(cmd > MPP_DEC_CMD_BASE); - mpp_assert(cmd < MPP_DEC_CMD_END); - - ret = control_dec(cmd, param); - } break; - case CMD_CTX_ID_ENC : { - mpp_assert(mType == MPP_CTX_ENC); - mpp_assert(cmd > MPP_ENC_CMD_BASE); - mpp_assert(cmd < MPP_ENC_CMD_END); - - ret = control_enc(cmd, param); - } break; - case CMD_CTX_ID_ISP : { - mpp_assert(mType == MPP_CTX_ISP); - ret = control_isp(cmd, param); - } break; - default : { - mpp_assert(cmd > MPP_CODEC_CMD_BASE); - mpp_assert(cmd < MPP_CODEC_CMD_END); - - ret = control_codec(cmd, param); - } break; - } - } break; - default : { - } break; - } - - if (ret) - mpp_err("command %x param %p ret %d\n", cmd, param, ret); - - return ret; -} - -MPP_RET Mpp::reset() -{ - if (!mInitDone) - return MPP_OK; - - MppPacket pkt = NULL; - - /* - * On mp4 case extra data of sps/pps will be put at the beginning - * If these packet was reset before they are send to decoder then - * decoder can not get these important information to continue decoding - * To avoid this case happen we need to save it on reset beginning - * then restore it on reset end. - */ - mPackets->lock(); - if (mPackets->list_size()) { - mPackets->del_at_head(&pkt, sizeof(pkt)); - } - mPackets->flush(); - mPackets->unlock(); - - mFrames->lock(); - mFrames->flush(); - mFrames->unlock(); - - mThreadCodec->lock(THREAD_RESET); - - if (mType == MPP_CTX_DEC) { - mpp_dec_reset(mDec); - mThreadCodec->lock(); - mThreadCodec->signal(); - mThreadCodec->unlock(); - mThreadCodec->wait(THREAD_RESET); - } else { - mpp_enc_reset(mEnc); - } - mThreadCodec->unlock(THREAD_RESET); - - if (pkt != NULL) { - RK_U32 flags = mpp_packet_get_flag(pkt); - - if (flags & MPP_PACKET_FLAG_EXTRA_DATA) { - put_packet(pkt); - } - mpp_packet_deinit(&pkt); - pkt = NULL; - } - - return MPP_OK; -} - - -MPP_RET Mpp::control_mpp(MpiCmd cmd, MppParam param) -{ - MPP_RET ret = MPP_OK; - - switch (cmd) { - case MPP_SET_INPUT_BLOCK: { - RK_U32 block = *((RK_U32 *)param); - mInputBlock = block; - } break; - case MPP_SET_OUTPUT_BLOCK: { - RK_U32 block = *((RK_U32 *)param); - mOutputBlock = block; - } break; - default : { - ret = MPP_NOK; - } break; - } - return ret; -} - -MPP_RET Mpp::control_osal(MpiCmd cmd, MppParam param) -{ - MPP_RET ret = MPP_NOK; - - mpp_assert(cmd > MPP_OSAL_CMD_BASE); - mpp_assert(cmd < MPP_OSAL_CMD_END); - - (void)cmd; - (void)param; - return ret; -} - -MPP_RET Mpp::control_codec(MpiCmd cmd, MppParam param) -{ - MPP_RET ret = MPP_NOK; - - (void)cmd; - (void)param; - return ret; -} - -MPP_RET Mpp::control_dec(MpiCmd cmd, MppParam param) -{ - MPP_RET ret = MPP_NOK; - - switch (cmd) { - case MPP_DEC_SET_FRAME_INFO: { - ret = mpp_dec_control(mDec, cmd, param); - } break; - case MPP_DEC_SET_EXT_BUF_GROUP: { - mFrameGroup = (MppBufferGroup)param; - if (param) { - mExternalFrameGroup = 1; - ret = mpp_buffer_group_set_listener((MppBufferGroupImpl *)param, (void *)mThreadCodec); - mThreadCodec->signal(); - } else { - mExternalFrameGroup = 0; - ret = mpp_buffer_group_set_listener(NULL, (void *)mThreadCodec); - } - } break; - case MPP_DEC_SET_INFO_CHANGE_READY: { - ret = mpp_buf_slot_ready(mDec->frame_slots); - } break; - case MPP_DEC_SET_INTERNAL_PTS_ENABLE: { - if (mCoding == MPP_VIDEO_CodingMPEG2 || mCoding == MPP_VIDEO_CodingMPEG4) { - ret = mpp_dec_control(mDec, cmd, param); - } else { - mpp_err("coding %x does not support use internal pts control\n", mCoding); - } - } break; - case MPP_DEC_SET_PARSER_SPLIT_MODE: { - RK_U32 flag = *((RK_U32 *)param); - mParserNeedSplit = flag; - ret = MPP_OK; - } break; - case MPP_DEC_SET_PARSER_FAST_MODE: { - RK_U32 flag = *((RK_U32 *)param); - mParserFastMode = flag; - ret = MPP_OK; - } break; - case MPP_DEC_GET_STREAM_COUNT: { - AutoMutex autoLock(mPackets->mutex()); - *((RK_S32 *)param) = mPackets->list_size(); - ret = MPP_OK; - } break; - case MPP_DEC_GET_VPUMEM_USED_COUNT: { - ret = mpp_dec_control(mDec, cmd, param); - } break; - case MPP_DEC_SET_OUTPUT_FORMAT: { - ret = mpp_dec_control(mDec, cmd, param); - } break; - default : { - } break; - } - return ret; -} - -MPP_RET Mpp::control_enc(MpiCmd cmd, MppParam param) -{ - MPP_RET ret = MPP_NOK; - - switch (cmd) { - case MPP_ENC_SET_CFG : - case MPP_ENC_GET_CFG : - case MPP_ENC_GET_EXTRA_INFO : { - mpp_assert(mEnc); - ret = mpp_enc_control(mEnc, cmd, param); - } break; - default : { - } break; - } - return ret; -} - -MPP_RET Mpp::control_isp(MpiCmd cmd, MppParam param) -{ - MPP_RET ret = MPP_NOK; - - mpp_assert(cmd > MPP_ISP_CMD_BASE); - mpp_assert(cmd < MPP_ISP_CMD_END); - - (void)cmd; - (void)param; - return ret; -} - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define MODULE_TAG "mpp" + +#include "mpp_log.h" +#include "mpp_mem.h" +#include "mpp_env.h" +#include "mpp_time.h" + +#include "mpp.h" +#include "mpp_dec.h" +#include "mpp_enc.h" +#include "mpp_hal.h" +#include "mpp_task_impl.h" +#include "mpp_buffer_impl.h" +#include "mpp_frame_impl.h" +#include "mpp_packet_impl.h" + +#define MPP_TEST_FRAME_SIZE SZ_1M +#define MPP_TEST_PACKET_SIZE SZ_512K + +Mpp::Mpp() + : mPackets(NULL), + mFrames(NULL), + mTasks(NULL), + mPacketPutCount(0), + mPacketGetCount(0), + mFramePutCount(0), + mFrameGetCount(0), + mTaskPutCount(0), + mTaskGetCount(0), + mPacketGroup(NULL), + mFrameGroup(NULL), + mExternalFrameGroup(0), + mInputPort(NULL), + mOutputPort(NULL), + mInputTaskQueue(NULL), + mOutputTaskQueue(NULL), + mThreadCodec(NULL), + mThreadHal(NULL), + mDec(NULL), + mEnc(NULL), + mType(MPP_CTX_BUTT), + mCoding(MPP_VIDEO_CodingUnused), + mInitDone(0), + mPacketBlock(0), + mInputBlock(0), + mOutputBlock(0), + mMultiFrame(0), + mInputTask(NULL), + mStatus(0), + mParserFastMode(0), + mParserNeedSplit(0), + mParserInternalPts(0) +{ +} + +MPP_RET Mpp::init(MppCtxType type, MppCodingType coding) +{ + if (mpp_check_support_format(type, coding)) { + mpp_err("unable to create unsupported type %d coding %d\n", type, coding); + return MPP_NOK; + } + + mType = type; + mCoding = coding; + switch (mType) { + case MPP_CTX_DEC : { + mPackets = new mpp_list((node_destructor)mpp_packet_deinit); + mFrames = new mpp_list((node_destructor)mpp_frame_deinit); + mTasks = new mpp_list((node_destructor)NULL); + + MppDecCfg cfg = { + coding, + mParserFastMode, + mParserNeedSplit, + mParserInternalPts, + this, + }; + mpp_dec_init(&mDec, &cfg); + + mThreadCodec = new MppThread(mpp_dec_parser_thread, this, "mpp_dec_parser"); + mThreadHal = new MppThread(mpp_dec_hal_thread, this, "mpp_dec_hal"); + + mpp_buffer_group_get_internal(&mPacketGroup, MPP_BUFFER_TYPE_ION); + mpp_buffer_group_limit_config(mPacketGroup, 0, 3); + + mpp_task_queue_init(&mInputTaskQueue); + mpp_task_queue_init(&mOutputTaskQueue); + mpp_task_queue_setup(mInputTaskQueue, 4); + mpp_task_queue_setup(mOutputTaskQueue, 4); + } break; + case MPP_CTX_ENC : { + mFrames = new mpp_list((node_destructor)NULL); + mPackets = new mpp_list((node_destructor)mpp_packet_deinit); + mTasks = new mpp_list((node_destructor)NULL); + + mpp_enc_init(&mEnc, coding); + mThreadCodec = new MppThread(mpp_enc_control_thread, this, "mpp_enc_ctrl"); + //mThreadHal = new MppThread(mpp_enc_hal_thread, this, "mpp_enc_hal"); + + mpp_buffer_group_get_internal(&mPacketGroup, MPP_BUFFER_TYPE_ION); + mpp_buffer_group_get_internal(&mFrameGroup, MPP_BUFFER_TYPE_ION); + + mpp_task_queue_init(&mInputTaskQueue); + mpp_task_queue_init(&mOutputTaskQueue); + mpp_task_queue_setup(mInputTaskQueue, 1); + mpp_task_queue_setup(mOutputTaskQueue, 1); + } break; + default : { + mpp_err("Mpp error type %d\n", mType); + } break; + } + + mInputPort = mpp_task_queue_get_port(mInputTaskQueue, MPP_PORT_INPUT); + mOutputPort = mpp_task_queue_get_port(mOutputTaskQueue, MPP_PORT_OUTPUT); + + if (mFrames && mPackets && + (mDec) && + mThreadCodec && mThreadHal && + mPacketGroup) { + mThreadCodec->start(); + mThreadHal->start(); + mInitDone = 1; + } else if (mFrames && mPackets && + (mEnc) && + mThreadCodec/* && mThreadHal */ && + mPacketGroup) { + mThreadCodec->start(); + //mThreadHal->start(); // TODO + mInitDone = 1; + } else { + mpp_err("error found on mpp initialization\n"); + clear(); + } + + mpp_env_get_u32("mpp_debug", &mpp_debug, 0); + return MPP_OK; +} + +Mpp::~Mpp () +{ + clear(); +} + +void Mpp::clear() +{ + // MUST: release listener here + if (mFrameGroup) + mpp_buffer_group_set_listener((MppBufferGroupImpl *)mFrameGroup, NULL); + + if (mThreadCodec) + mThreadCodec->stop(); + if (mThreadHal) + mThreadHal->stop(); + + if (mThreadCodec) { + delete mThreadCodec; + mThreadCodec = NULL; + } + if (mThreadHal) { + delete mThreadHal; + mThreadHal = NULL; + } + + if (mInputTaskQueue) { + mpp_task_queue_deinit(mInputTaskQueue); + mInputTaskQueue = NULL; + } + if (mOutputTaskQueue) { + mpp_task_queue_deinit(mOutputTaskQueue); + mOutputTaskQueue = NULL; + } + + mInputPort = NULL; + mOutputPort = NULL; + + if (mDec || mEnc) { + if (mType == MPP_CTX_DEC) { + mpp_dec_deinit(mDec); + mDec = NULL; + } else { + mpp_enc_deinit(mEnc); + mEnc = NULL; + } + } + if (mPackets) { + delete mPackets; + mPackets = NULL; + } + if (mFrames) { + delete mFrames; + mFrames = NULL; + } + if (mTasks) { + delete mTasks; + mTasks = NULL; + } + if (mPacketGroup) { + mpp_buffer_group_put(mPacketGroup); + mPacketGroup = NULL; + } + if (mFrameGroup && !mExternalFrameGroup) { + mpp_buffer_group_put(mFrameGroup); + mFrameGroup = NULL; + } +} + +MPP_RET Mpp::put_packet(MppPacket packet) +{ + if (!mInitDone) + return MPP_NOK; + + AutoMutex autoLock(mPackets->mutex()); + RK_U32 eos = mpp_packet_get_eos(packet); + + if (mPackets->list_size() < 4 || eos) { + MppPacket pkt; + if (MPP_OK != mpp_packet_copy_init(&pkt, packet)) + return MPP_NOK; + + mPackets->add_at_tail(&pkt, sizeof(pkt)); + mPacketPutCount++; + mThreadCodec->signal(); + return MPP_OK; + } + + return MPP_NOK; +} + +MPP_RET Mpp::get_frame(MppFrame *frame) +{ + if (!mInitDone) + return MPP_NOK; + + AutoMutex autoLock(mFrames->mutex()); + MppFrame first = NULL; + + if (0 == mFrames->list_size()) { + mThreadCodec->signal(); + if (mOutputBlock) + mFrames->wait(); + msleep(1); + } + + if (mFrames->list_size()) { + mFrames->del_at_head(&first, sizeof(frame)); + mFrameGetCount++; + mThreadHal->signal(); + + if (mMultiFrame) { + MppFrame prev = first; + MppFrame next = NULL; + while (mFrames->list_size()) { + mFrames->del_at_head(&next, sizeof(frame)); + mFrameGetCount++; + mThreadHal->signal(); + mpp_frame_set_next(prev, next); + prev = next; + } + } + } + *frame = first; + return MPP_OK; +} + +MPP_RET Mpp::put_frame(MppFrame frame) +{ + if (!mInitDone) + return MPP_NOK; + + MPP_RET ret = MPP_NOK; + MppTask task = mInputTask; + + do { + if (NULL == task) { + ret = dequeue(MPP_PORT_INPUT, &task); + if (ret) { + mpp_log_f("failed to dequeue from input port ret %d\n", ret); + break; + } + } + + /* FIXME: use wait to do block wait */ + if (mInputBlock && NULL == task) { + msleep(2); + continue; + } + + mpp_assert(task); + + ret = mpp_task_meta_set_frame(task, MPP_META_KEY_INPUT_FRM, frame); + if (ret) { + mpp_log_f("failed to set input frame to task ret %d\n", ret); + break; + } + + ret = enqueue(MPP_PORT_INPUT, task); + if (ret) { + mpp_log_f("failed to enqueue task to input port ret %d\n", ret); + break; + } + + if (mInputBlock) { + while (MPP_NOK == mpp_port_can_dequeue(mInputPort)) { + msleep(2); + } + + ret = dequeue(MPP_PORT_INPUT, &task); + if (ret) { + mpp_log_f("failed to dequeue from input port ret %d\n", ret); + break; + } + + mpp_assert(task); + ret = mpp_task_meta_get_frame(task, MPP_META_KEY_INPUT_FRM, &frame); + if (frame) { + mpp_frame_deinit(&frame); + frame = NULL; + } + } + + break; + } while (1); + + mInputTask = task; + + return ret; +} + +MPP_RET Mpp::get_packet(MppPacket *packet) +{ + if (!mInitDone) + return MPP_NOK; + + MPP_RET ret = MPP_OK; + MppTask task = NULL; + + do { + if (NULL == task) { + ret = dequeue(MPP_PORT_OUTPUT, &task); + if (ret) { + mpp_log_f("failed to dequeue from output port ret %d\n", ret); + break; + } + } + + /* FIXME: use wait to do block wait */ + if (NULL == task) { + if (mOutputBlock) { + msleep(2); + continue; + } else { + break; + } + } + + mpp_assert(task); + + ret = mpp_task_meta_get_packet(task, MPP_META_KEY_OUTPUT_PKT, packet); + if (ret) { + mpp_log_f("failed to get output packet from task ret %d\n", ret); + break; + } + + mpp_assert(*packet); + + if (mpp_debug & MPP_DBG_PTS) + mpp_log_f("pts %lld\n", mpp_packet_get_pts(*packet)); + + ret = enqueue(MPP_PORT_OUTPUT, task); + if (ret) { + mpp_log_f("failed to enqueue task to output port ret %d\n", ret); + } + + break; + } while (1); + + return ret; +} + +MPP_RET Mpp::dequeue(MppPortType type, MppTask *task) +{ + if (!mInitDone) + return MPP_NOK; + + MPP_RET ret = MPP_NOK; + AutoMutex autoLock(mPortLock); + MppTaskQueue port = NULL; + switch (type) { + case MPP_PORT_INPUT : { + port = mInputPort; + } break; + case MPP_PORT_OUTPUT : { + port = mOutputPort; + } break; + default : { + } break; + } + + if (port) + ret = mpp_port_dequeue(port, task); + + return ret; +} + +MPP_RET Mpp::enqueue(MppPortType type, MppTask task) +{ + if (!mInitDone) + return MPP_NOK; + + MPP_RET ret = MPP_NOK; + AutoMutex autoLock(mPortLock); + MppTaskQueue port = NULL; + switch (type) { + case MPP_PORT_INPUT : { + port = mInputPort; + } break; + case MPP_PORT_OUTPUT : { + port = mOutputPort; + } break; + default : { + } break; + } + + if (port) { + mThreadCodec->lock(); + ret = mpp_port_enqueue(port, task); + if (MPP_OK == ret) { + // if enqueue success wait up thread + mThreadCodec->signal(); + } + mThreadCodec->unlock(); + } + + return ret; +} + +MPP_RET Mpp::control(MpiCmd cmd, MppParam param) +{ + MPP_RET ret = MPP_NOK; + + switch (cmd & CMD_MODULE_ID_MASK) { + case CMD_MODULE_OSAL : { + ret = control_osal(cmd, param); + } break; + case CMD_MODULE_MPP : { + mpp_assert(cmd > MPP_CMD_BASE); + mpp_assert(cmd < MPP_CMD_END); + + ret = control_mpp(cmd, param); + } break; + case CMD_MODULE_CODEC : { + switch (cmd & CMD_CTX_ID_MASK) { + case CMD_CTX_ID_DEC : { + mpp_assert(mType == MPP_CTX_DEC || mType == MPP_CTX_BUTT); + mpp_assert(cmd > MPP_DEC_CMD_BASE); + mpp_assert(cmd < MPP_DEC_CMD_END); + + ret = control_dec(cmd, param); + } break; + case CMD_CTX_ID_ENC : { + mpp_assert(mType == MPP_CTX_ENC); + mpp_assert(cmd > MPP_ENC_CMD_BASE); + mpp_assert(cmd < MPP_ENC_CMD_END); + + ret = control_enc(cmd, param); + } break; + case CMD_CTX_ID_ISP : { + mpp_assert(mType == MPP_CTX_ISP); + ret = control_isp(cmd, param); + } break; + default : { + mpp_assert(cmd > MPP_CODEC_CMD_BASE); + mpp_assert(cmd < MPP_CODEC_CMD_END); + + ret = control_codec(cmd, param); + } break; + } + } break; + default : { + } break; + } + + if (ret) + mpp_err("command %x param %p ret %d\n", cmd, param, ret); + + return ret; +} + +MPP_RET Mpp::reset() +{ + if (!mInitDone) + return MPP_OK; + + MppPacket pkt = NULL; + + /* + * On mp4 case extra data of sps/pps will be put at the beginning + * If these packet was reset before they are send to decoder then + * decoder can not get these important information to continue decoding + * To avoid this case happen we need to save it on reset beginning + * then restore it on reset end. + */ + mPackets->lock(); + if (mPackets->list_size()) { + mPackets->del_at_head(&pkt, sizeof(pkt)); + } + mPackets->flush(); + mPackets->unlock(); + + mFrames->lock(); + mFrames->flush(); + mFrames->unlock(); + + mThreadCodec->lock(THREAD_RESET); + + if (mType == MPP_CTX_DEC) { + mpp_dec_reset(mDec); + mThreadCodec->lock(); + mThreadCodec->signal(); + mThreadCodec->unlock(); + mThreadCodec->wait(THREAD_RESET); + } else { + mpp_enc_reset(mEnc); + } + mThreadCodec->unlock(THREAD_RESET); + + if (pkt != NULL) { + RK_U32 flags = mpp_packet_get_flag(pkt); + + if (flags & MPP_PACKET_FLAG_EXTRA_DATA) { + put_packet(pkt); + } + mpp_packet_deinit(&pkt); + pkt = NULL; + } + + return MPP_OK; +} + + +MPP_RET Mpp::control_mpp(MpiCmd cmd, MppParam param) +{ + MPP_RET ret = MPP_OK; + + switch (cmd) { + case MPP_SET_INPUT_BLOCK: { + RK_U32 block = *((RK_U32 *)param); + mInputBlock = block; + } break; + case MPP_SET_OUTPUT_BLOCK: { + RK_U32 block = *((RK_U32 *)param); + mOutputBlock = block; + } break; + default : { + ret = MPP_NOK; + } break; + } + return ret; +} + +MPP_RET Mpp::control_osal(MpiCmd cmd, MppParam param) +{ + MPP_RET ret = MPP_NOK; + + mpp_assert(cmd > MPP_OSAL_CMD_BASE); + mpp_assert(cmd < MPP_OSAL_CMD_END); + + (void)cmd; + (void)param; + return ret; +} + +MPP_RET Mpp::control_codec(MpiCmd cmd, MppParam param) +{ + MPP_RET ret = MPP_NOK; + + (void)cmd; + (void)param; + return ret; +} + +MPP_RET Mpp::control_dec(MpiCmd cmd, MppParam param) +{ + MPP_RET ret = MPP_NOK; + + switch (cmd) { + case MPP_DEC_SET_FRAME_INFO: { + ret = mpp_dec_control(mDec, cmd, param); + } break; + case MPP_DEC_SET_EXT_BUF_GROUP: { + mFrameGroup = (MppBufferGroup)param; + if (param) { + mExternalFrameGroup = 1; + ret = mpp_buffer_group_set_listener((MppBufferGroupImpl *)param, (void *)mThreadCodec); + mThreadCodec->signal(); + } else { + mExternalFrameGroup = 0; + ret = mpp_buffer_group_set_listener(NULL, (void *)mThreadCodec); + } + } break; + case MPP_DEC_SET_INFO_CHANGE_READY: { + ret = mpp_buf_slot_ready(mDec->frame_slots); + } break; + case MPP_DEC_SET_INTERNAL_PTS_ENABLE: { + if (mCoding == MPP_VIDEO_CodingMPEG2 || mCoding == MPP_VIDEO_CodingMPEG4) { + ret = mpp_dec_control(mDec, cmd, param); + } else { + mpp_err("coding %x does not support use internal pts control\n", mCoding); + } + } break; + case MPP_DEC_SET_PARSER_SPLIT_MODE: { + RK_U32 flag = *((RK_U32 *)param); + mParserNeedSplit = flag; + ret = MPP_OK; + } break; + case MPP_DEC_SET_PARSER_FAST_MODE: { + RK_U32 flag = *((RK_U32 *)param); + mParserFastMode = flag; + ret = MPP_OK; + } break; + case MPP_DEC_GET_STREAM_COUNT: { + AutoMutex autoLock(mPackets->mutex()); + *((RK_S32 *)param) = mPackets->list_size(); + ret = MPP_OK; + } break; + case MPP_DEC_GET_VPUMEM_USED_COUNT: { + ret = mpp_dec_control(mDec, cmd, param); + } break; + case MPP_DEC_SET_OUTPUT_FORMAT: { + ret = mpp_dec_control(mDec, cmd, param); + } break; + default : { + } break; + } + return ret; +} + +MPP_RET Mpp::control_enc(MpiCmd cmd, MppParam param) +{ + MPP_RET ret = MPP_NOK; + + switch (cmd) { + case MPP_ENC_SET_CFG : + case MPP_ENC_GET_CFG : + case MPP_ENC_GET_EXTRA_INFO : { + mpp_assert(mEnc); + ret = mpp_enc_control(mEnc, cmd, param); + } break; + default : { + } break; + } + return ret; +} + +MPP_RET Mpp::control_isp(MpiCmd cmd, MppParam param) +{ + MPP_RET ret = MPP_NOK; + + mpp_assert(cmd > MPP_ISP_CMD_BASE); + mpp_assert(cmd < MPP_ISP_CMD_END); + + (void)cmd; + (void)param; + return ret; +} + diff --git a/mpp/mpp.h b/mpp/mpp.h index 541eac1c..fd3bb223 100644 --- a/mpp/mpp.h +++ b/mpp/mpp.h @@ -1,169 +1,169 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __MPP_H__ -#define __MPP_H__ - -#include "mpp_list.h" -#include "mpp_dec.h" -#include "mpp_enc.h" -#include "mpp_task.h" - -#define MPP_DBG_FUNCTION (0x00000001) -#define MPP_DBG_PACKET (0x00000002) -#define MPP_DBG_FRAME (0x00000004) -#define MPP_DBG_BUFFER (0x00000008) - -/* - * mpp hierarchy - * - * mpp layer create mpp_dec or mpp_dec instance - * mpp_dec create its parser and hal module - * mpp_enc create its control and hal module - * - * +-------+ - * | | - * +-------------+ mpp +-------------+ - * | | | | - * | +-------+ | - * | | - * | | - * | | - * +-----+-----+ +-----+-----+ - * | | | | - * +---+ mpp_dec +--+ +--+ mpp_enc +---+ - * | | | | | | | | - * | +-----------+ | | +-----------+ | - * | | | | - * | | | | - * | | | | - * +-------v------+ +-----v-----+ +-----v-----+ +------v-------+ - * | | | | | | | | - * | dec_parser | | dec_hal | | enc_hal | | enc_control | - * | | | | | | | | - * +--------------+ +-----------+ +-----------+ +--------------+ - */ - -#ifdef __cplusplus - -class Mpp -{ -public: - Mpp(); - ~Mpp(); - MPP_RET init(MppCtxType type, MppCodingType coding); - MPP_RET put_packet(MppPacket packet); - MPP_RET get_frame(MppFrame *frame); - - MPP_RET put_frame(MppFrame frame); - MPP_RET get_packet(MppPacket *packet); - - MPP_RET dequeue(MppPortType type, MppTask *task); - MPP_RET enqueue(MppPortType type, MppTask task); - - MPP_RET reset(); - MPP_RET control(MpiCmd cmd, MppParam param); - - mpp_list *mPackets; - mpp_list *mFrames; - mpp_list *mTasks; - - /* counters for debug */ - RK_U32 mPacketPutCount; - RK_U32 mPacketGetCount; - RK_U32 mFramePutCount; - RK_U32 mFrameGetCount; - RK_U32 mTaskPutCount; - RK_U32 mTaskGetCount; - - /* - * packet buffer group - * - packets in I/O, can be ion buffer or normal buffer - * frame buffer group - * - frames in I/O, normally should be a ion buffer group - */ - MppBufferGroup mPacketGroup; - MppBufferGroup mFrameGroup; - RK_U32 mExternalFrameGroup; - - /* - * Mpp task queue for advance task mode - */ - Mutex mPortLock; - MppPort mInputPort; - MppPort mOutputPort; - - MppTaskQueue mInputTaskQueue; - MppTaskQueue mOutputTaskQueue; - - /* - * There are two threads for each decoder/encoder: codec thread and hal thread - * - * codec thread generate protocol syntax structure and send to hardware - * hal thread wait hardware return and do corresponding process - * - * Two threads work parallelly so that all decoder/encoder will share this - * acceleration mechanism - */ - MppThread *mThreadCodec; - MppThread *mThreadHal; - - MppDec *mDec; - MppEnc *mEnc; - -private: - void clear(); - - MppCtxType mType; - MppCodingType mCoding; - - RK_U32 mInitDone; - RK_U32 mPacketBlock; - RK_U32 mInputBlock; - RK_U32 mOutputBlock; - RK_U32 mMultiFrame; - - // task for put_frame / put_packet - MppTask mInputTask; - - RK_U32 mStatus; - - /* decoder paramter before init */ - RK_U32 mParserFastMode; - RK_U32 mParserNeedSplit; - RK_U32 mParserInternalPts; /* for MPEG2/MPEG4 */ - - /* encoder paramter before init */ - MppEncConfig mControlCfg; - RK_U32 mControlCfgReady; - - MPP_RET control_mpp(MpiCmd cmd, MppParam param); - MPP_RET control_osal(MpiCmd cmd, MppParam param); - MPP_RET control_codec(MpiCmd cmd, MppParam param); - MPP_RET control_dec(MpiCmd cmd, MppParam param); - MPP_RET control_enc(MpiCmd cmd, MppParam param); - MPP_RET control_isp(MpiCmd cmd, MppParam param); - - Mpp(const Mpp &); - Mpp &operator=(const Mpp &); -}; - - -extern "C" { -} -#endif - -#endif /*__MPP_H__*/ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPP_H__ +#define __MPP_H__ + +#include "mpp_list.h" +#include "mpp_dec.h" +#include "mpp_enc.h" +#include "mpp_task.h" + +#define MPP_DBG_FUNCTION (0x00000001) +#define MPP_DBG_PACKET (0x00000002) +#define MPP_DBG_FRAME (0x00000004) +#define MPP_DBG_BUFFER (0x00000008) + +/* + * mpp hierarchy + * + * mpp layer create mpp_dec or mpp_dec instance + * mpp_dec create its parser and hal module + * mpp_enc create its control and hal module + * + * +-------+ + * | | + * +-------------+ mpp +-------------+ + * | | | | + * | +-------+ | + * | | + * | | + * | | + * +-----+-----+ +-----+-----+ + * | | | | + * +---+ mpp_dec +--+ +--+ mpp_enc +---+ + * | | | | | | | | + * | +-----------+ | | +-----------+ | + * | | | | + * | | | | + * | | | | + * +-------v------+ +-----v-----+ +-----v-----+ +------v-------+ + * | | | | | | | | + * | dec_parser | | dec_hal | | enc_hal | | enc_control | + * | | | | | | | | + * +--------------+ +-----------+ +-----------+ +--------------+ + */ + +#ifdef __cplusplus + +class Mpp +{ +public: + Mpp(); + ~Mpp(); + MPP_RET init(MppCtxType type, MppCodingType coding); + MPP_RET put_packet(MppPacket packet); + MPP_RET get_frame(MppFrame *frame); + + MPP_RET put_frame(MppFrame frame); + MPP_RET get_packet(MppPacket *packet); + + MPP_RET dequeue(MppPortType type, MppTask *task); + MPP_RET enqueue(MppPortType type, MppTask task); + + MPP_RET reset(); + MPP_RET control(MpiCmd cmd, MppParam param); + + mpp_list *mPackets; + mpp_list *mFrames; + mpp_list *mTasks; + + /* counters for debug */ + RK_U32 mPacketPutCount; + RK_U32 mPacketGetCount; + RK_U32 mFramePutCount; + RK_U32 mFrameGetCount; + RK_U32 mTaskPutCount; + RK_U32 mTaskGetCount; + + /* + * packet buffer group + * - packets in I/O, can be ion buffer or normal buffer + * frame buffer group + * - frames in I/O, normally should be a ion buffer group + */ + MppBufferGroup mPacketGroup; + MppBufferGroup mFrameGroup; + RK_U32 mExternalFrameGroup; + + /* + * Mpp task queue for advance task mode + */ + Mutex mPortLock; + MppPort mInputPort; + MppPort mOutputPort; + + MppTaskQueue mInputTaskQueue; + MppTaskQueue mOutputTaskQueue; + + /* + * There are two threads for each decoder/encoder: codec thread and hal thread + * + * codec thread generate protocol syntax structure and send to hardware + * hal thread wait hardware return and do corresponding process + * + * Two threads work parallelly so that all decoder/encoder will share this + * acceleration mechanism + */ + MppThread *mThreadCodec; + MppThread *mThreadHal; + + MppDec *mDec; + MppEnc *mEnc; + +private: + void clear(); + + MppCtxType mType; + MppCodingType mCoding; + + RK_U32 mInitDone; + RK_U32 mPacketBlock; + RK_U32 mInputBlock; + RK_U32 mOutputBlock; + RK_U32 mMultiFrame; + + // task for put_frame / put_packet + MppTask mInputTask; + + RK_U32 mStatus; + + /* decoder paramter before init */ + RK_U32 mParserFastMode; + RK_U32 mParserNeedSplit; + RK_U32 mParserInternalPts; /* for MPEG2/MPEG4 */ + + /* encoder paramter before init */ + MppEncConfig mControlCfg; + RK_U32 mControlCfgReady; + + MPP_RET control_mpp(MpiCmd cmd, MppParam param); + MPP_RET control_osal(MpiCmd cmd, MppParam param); + MPP_RET control_codec(MpiCmd cmd, MppParam param); + MPP_RET control_dec(MpiCmd cmd, MppParam param); + MPP_RET control_enc(MpiCmd cmd, MppParam param); + MPP_RET control_isp(MpiCmd cmd, MppParam param); + + Mpp(const Mpp &); + Mpp &operator=(const Mpp &); +}; + + +extern "C" { +} +#endif + +#endif /*__MPP_H__*/ diff --git a/mpp/mpp_info.cpp b/mpp/mpp_info.cpp index e0acdbe8..f180a4aa 100644 --- a/mpp/mpp_info.cpp +++ b/mpp/mpp_info.cpp @@ -1,103 +1,103 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define MODULE_TAG "mpp_info" - -#include -#include - -#include "mpp_log.h" -#include "mpp_env.h" -#include "mpp_info.h" - -#include "version.h" - -/* - * To avoid string | grep author getting multiple results - * use commit to replace author - */ -static char mpp_version_revision[] = MPP_VERSION; -static char mpp_version_commit[] = MPP_AUTHOR; -static char mpp_version_date[] = MPP_DATE; -static char mpp_version_one_line[] = MPP_ONE_LINE; -static char mpp_version_number[] = MPP_VER_NUM; - -static RK_CHIP_TYPE chip_version(void) -{ - RK_CHIP_TYPE type = NONE; - char *value = NULL; - RK_S32 ret = mpp_env_get_str("ro.product.board", &value, NULL); - - if (0 == ret) { - if (strstr(value, "rk29")) { - mpp_log("rk29 board found in board property"); - type = RK29; - } else if (strstr(value, "rk30")) { - mpp_log("rk30 board found in board property"); - type = RK30; - } - } - if (NONE == type) { - ret = mpp_env_get_str("ro.board.platform", &value, NULL); - if (0 == ret) { - if (strstr(value, "rk29")) { - mpp_log("rk29 board found in platform property"); - type = RK29; - } else if (strstr(value, "rk30")) { - mpp_log("rk30 board found in platform property"); - type = RK30; - } - } - } - - if (NONE == type) { - mpp_log("can not found matched chip type"); - } - return type; -} - -const char *mpp_info_get(MPP_INFO_TYPE type) -{ - switch (type) { - case INFO_ALL : { - return mpp_version_one_line; - } break; - case INFO_REVISION : { - return mpp_version_revision; - } break; - case INFO_DATE : { - return mpp_version_date; - } break; - case INFO_AUTHOR : { - return mpp_version_commit; - } break; - default : { - mpp_err_f("invalid info type %d\n", type); - } break; - } - return NULL; -} - -RK_CHIP_TYPE get_chip_type() -{ - return chip_version(); -} - -int mpp_info_get_revision() -{ - return atoi(mpp_version_number); -} - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define MODULE_TAG "mpp_info" + +#include +#include + +#include "mpp_log.h" +#include "mpp_env.h" +#include "mpp_info.h" + +#include "version.h" + +/* + * To avoid string | grep author getting multiple results + * use commit to replace author + */ +static char mpp_version_revision[] = MPP_VERSION; +static char mpp_version_commit[] = MPP_AUTHOR; +static char mpp_version_date[] = MPP_DATE; +static char mpp_version_one_line[] = MPP_ONE_LINE; +static char mpp_version_number[] = MPP_VER_NUM; + +static RK_CHIP_TYPE chip_version(void) +{ + RK_CHIP_TYPE type = NONE; + char *value = NULL; + RK_S32 ret = mpp_env_get_str("ro.product.board", &value, NULL); + + if (0 == ret) { + if (strstr(value, "rk29")) { + mpp_log("rk29 board found in board property"); + type = RK29; + } else if (strstr(value, "rk30")) { + mpp_log("rk30 board found in board property"); + type = RK30; + } + } + if (NONE == type) { + ret = mpp_env_get_str("ro.board.platform", &value, NULL); + if (0 == ret) { + if (strstr(value, "rk29")) { + mpp_log("rk29 board found in platform property"); + type = RK29; + } else if (strstr(value, "rk30")) { + mpp_log("rk30 board found in platform property"); + type = RK30; + } + } + } + + if (NONE == type) { + mpp_log("can not found matched chip type"); + } + return type; +} + +const char *mpp_info_get(MPP_INFO_TYPE type) +{ + switch (type) { + case INFO_ALL : { + return mpp_version_one_line; + } break; + case INFO_REVISION : { + return mpp_version_revision; + } break; + case INFO_DATE : { + return mpp_version_date; + } break; + case INFO_AUTHOR : { + return mpp_version_commit; + } break; + default : { + mpp_err_f("invalid info type %d\n", type); + } break; + } + return NULL; +} + +RK_CHIP_TYPE get_chip_type() +{ + return chip_version(); +} + +int mpp_info_get_revision() +{ + return atoi(mpp_version_number); +} + diff --git a/mpp/test/avsd_test.c b/mpp/test/avsd_test.c index 8e1f86d2..8fc49bde 100644 --- a/mpp/test/avsd_test.c +++ b/mpp/test/avsd_test.c @@ -1,470 +1,470 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define MODULE_TAG "avsd_test" - -#if defined(_WIN32) -#include "vld.h" -#endif -#include - -#include "vpu_api.h" -#include "mpp_env.h" -#include "mpp_log.h" -#include "mpp_dec.h" -#include "mpp_hal.h" -#include "mpp_mem.h" -#include "mpp_common.h" -#include "mpp_packet.h" -#include "mpp_packet_impl.h" -#include "mpp_buffer.h" -#include "mpp_buffer_impl.h" -#include "mpp_hal.h" -#include "mpp_thread.h" - -#include "hal_task.h" -#include "avsd_api.h" -#include "avsd_parse.h" -#include "hal_avsd_api.h" - - -#define AVSD_TEST_ERROR (0x00000001) -#define AVSD_TEST_ASSERT (0x00000002) -#define AVSD_TEST_WARNNING (0x00000004) -#define AVSD_TEST_TRACE (0x00000008) - -#define AVSD_TEST_DUMPYUV (0x00000010) - - -#define AVSD_TEST_LOG(level, fmt, ...)\ -do {\ -if (level & rkv_avsd_test_debug)\ - { mpp_log(fmt, ## __VA_ARGS__); }\ -} while (0) - - -typedef struct ParserImpl_t { - ParserCfg cfg; - - const ParserApi *api; - void *ctx; -} ParserImpl; - - -static RK_U32 rkv_avsd_test_debug = 0; - -typedef struct inp_par_t { - FILE *fp_in; - FILE *fp_out; - FILE *fp_read; - RK_U8 *pbuf; - RK_U32 bufsize; - RK_U32 len; - - RK_U32 output_dec_pic; // output_dec_pic - - RK_U32 dec_num; // to be decoded - RK_U32 dec_no; // current decoded number - - RK_U32 is_eof; -} InputParams; - - -typedef struct avsd_test_ctx_t { - MppDec m_api; - InputParams m_in; - HalTaskInfo m_task; - - MppBuffer m_dec_pkt_buf; - MppBuffer m_dec_pic_buf; - MppBufferGroup mFrameGroup; - MppBufferGroup mStreamGroup; -} AvsdTestCtx_t; - -static MPP_RET decoder_deinit(AvsdTestCtx_t *pctx) -{ - MppDec *pApi = &pctx->m_api; - - if (pApi->parser) { - parser_deinit(pApi->parser); - pApi->parser = NULL; - } - if (pApi->hal) { - mpp_hal_deinit(pApi->hal); - pApi->hal = NULL; - } - if (pApi->frame_slots) { - mpp_buf_slot_deinit(pApi->frame_slots); - pApi->frame_slots = NULL; - } - if (pApi->packet_slots) { - mpp_buf_slot_deinit(pApi->packet_slots); - pApi->packet_slots = NULL; - } - if (pctx->m_dec_pkt_buf) { - mpp_buffer_put(pctx->m_dec_pkt_buf); - pctx->m_dec_pkt_buf = NULL; - } - if (pctx->m_dec_pic_buf) { - mpp_buffer_put(pctx->m_dec_pic_buf); - pctx->m_dec_pic_buf = NULL; - } - if (pctx->mFrameGroup) { - mpp_err("mFrameGroup deInit"); - mpp_buffer_group_put(pctx->mFrameGroup); - pctx->mFrameGroup = NULL; - } - if (pctx->mStreamGroup) { - mpp_err("mStreamGroup deInit"); - mpp_buffer_group_put(pctx->mStreamGroup); - pctx->mStreamGroup = NULL; - } - - return MPP_OK; -} - -static MPP_RET decoder_init(AvsdTestCtx_t *pctx) -{ - - MPP_RET ret = MPP_ERR_UNKNOW; - ParserCfg parser_cfg; - MppHalCfg hal_cfg; - MppDec *pApi = &pctx->m_api; - - if (pctx->mFrameGroup == NULL) { - ret = mpp_buffer_group_get_internal(&pctx->mFrameGroup, MPP_BUFFER_TYPE_NORMAL); - if (MPP_OK != ret) { - mpp_err("avsd mpp_buffer_group_get failed\n"); - goto __FAILED; - } - } - if (pctx->mStreamGroup == NULL) { - ret = mpp_buffer_group_get_internal(&pctx->mStreamGroup, MPP_BUFFER_TYPE_NORMAL); - if (MPP_OK != ret) { - mpp_err("avsd mpp_buffer_group_get failed\n"); - goto __FAILED; - } - } - // codec - pApi->coding = MPP_VIDEO_CodingAVS; - // malloc slot - FUN_CHECK(ret = mpp_buf_slot_init(&pApi->frame_slots)); - MEM_CHECK(ret, pApi->frame_slots); - ret = mpp_buf_slot_init(&pApi->packet_slots); - MEM_CHECK(ret, pApi->packet_slots); - mpp_buf_slot_setup(pApi->packet_slots, 2); - // init parser part - memset(&parser_cfg, 0, sizeof(parser_cfg)); - parser_cfg.coding = pApi->coding; - parser_cfg.frame_slots = pApi->frame_slots; - parser_cfg.packet_slots = pApi->packet_slots; - parser_cfg.task_count = 2; - FUN_CHECK(ret = parser_init(&pApi->parser, &parser_cfg)); - - // init hal part - memset(&hal_cfg, 0, sizeof(hal_cfg)); - hal_cfg.type = MPP_CTX_DEC; - hal_cfg.coding = pApi->coding; - hal_cfg.work_mode = HAL_MODE_LIBVPU; - hal_cfg.device_id = HAL_RKVDEC; - hal_cfg.frame_slots = pApi->frame_slots; - hal_cfg.packet_slots = pApi->packet_slots; - hal_cfg.task_count = parser_cfg.task_count; - hal_cfg.hal_int_cb.opaque = ((ParserImpl *)(pApi->parser))->ctx; - hal_cfg.hal_int_cb.callBack = api_avsd_parser.callback; - //api_avsd_parser.callback(hal_cfg.hal_int_cb.opaque, NULL); - FUN_CHECK(ret = mpp_hal_init(&pApi->hal, &hal_cfg)); - pApi->tasks = hal_cfg.tasks; - - return MPP_OK; - -__FAILED: - decoder_deinit(pctx); - - return ret; -} - -static MPP_RET avsd_flush_frames(MppDec *pApi, FILE *fp) -{ - RK_S32 slot_idx = 0; - MppFrame out_frame = NULL; - - while (MPP_OK == mpp_buf_slot_dequeue(pApi->frame_slots, &slot_idx, QUEUE_DISPLAY)) { - mpp_buf_slot_get_prop(pApi->frame_slots, slot_idx, SLOT_FRAME, &out_frame); - if (out_frame) { - RK_U32 stride_w, stride_h; - void *ptr = NULL; - MppBuffer framebuf; - stride_w = mpp_frame_get_hor_stride(out_frame); - stride_h = mpp_frame_get_ver_stride(out_frame); - framebuf = mpp_frame_get_buffer(out_frame); - ptr = mpp_buffer_get_ptr(framebuf); - if (fp) { - fwrite(ptr, 1, stride_w * stride_h * 3 / 2, fp); - fflush(fp); - } - mpp_frame_deinit(&out_frame); - out_frame = NULL; - } - mpp_buf_slot_clr_flag(pApi->frame_slots, slot_idx, SLOT_QUEUE_USE); - } - - return MPP_OK; -} - - -static MPP_RET avsd_input_deinit(InputParams *inp) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - - MPP_FREE(inp->pbuf); - MPP_FCLOSE(inp->fp_in); - MPP_FCLOSE(inp->fp_out); - MPP_FCLOSE(inp->fp_read); - return ret = MPP_OK; -} - -static MPP_RET avsd_input_init(InputParams *inp, RK_S32 ac, char *av[]) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - char infile_name[128]; //!< Telenor AVS input - char outfile_name[128]; //!< Decoded YUV 4:2:0 output - RK_S32 CLcount = 1; - - inp->output_dec_pic = 0; - while (CLcount < ac) { - if (!strncmp(av[CLcount], "-h", 2)) { - mpp_log("Options:"); - mpp_log(" -h : prints help message."); - mpp_log(" -i :[file] Set input AVS+ bitstream file."); - mpp_log(" -o :[file] Set output YUV file."); - mpp_log(" -n :[number] Set decoded frames."); - CLcount += 1; - } else if (!strncmp(av[CLcount], "-i", 2)) { - strncpy(infile_name, av[CLcount + 1], strlen((const char*)av[CLcount + 1]) + 1); - CLcount += 2; - } else if (!strncmp(av[CLcount], "-n", 2)) { - if (!sscanf(av[CLcount + 1], "%d", &inp->dec_num)) { - goto __FAILED; - } - CLcount += 2; - } else if (!strncmp(av[CLcount], "-o", 2)) { - if (rkv_avsd_test_debug & AVSD_TEST_DUMPYUV) { - inp->output_dec_pic = 1; - strncpy(outfile_name, av[CLcount + 1], strlen((const char*)av[CLcount + 1]) + 1); - } - CLcount += 2; - } else { - mpp_err("error, %s cannot explain command! \n", av[CLcount]); - goto __FAILED; - } - } - if ((inp->fp_in = fopen(infile_name, "rb")) == 0) { - mpp_err("error, open file %s ", infile_name); - goto __FAILED; - } - if (inp->output_dec_pic) { - if ((inp->fp_out = fopen(outfile_name, "wb")) == 0) { - mpp_err("error, open file %s ", outfile_name); - goto __FAILED; - } - } - if ((inp->fp_read = fopen("F:/avs_log/avs_read.txt", "wb")) == 0) { - mpp_log("error, open file %s", "F:/avs_log/avs_read.txt"); - goto __FAILED; - } - - //!< malloc read buffer - inp->bufsize = 30 * 1024; - MEM_CHECK(ret, inp->pbuf = mpp_malloc(RK_U8, inp->bufsize)); - - AVSD_TEST_LOG(AVSD_TEST_TRACE, "------------------------------------------------------------"); - AVSD_TEST_LOG(AVSD_TEST_TRACE, "Input AVS+ bitstream : %s", infile_name); - AVSD_TEST_LOG(AVSD_TEST_TRACE, "Output decoded YUV : %s", outfile_name); - AVSD_TEST_LOG(AVSD_TEST_TRACE, "------------------------------------------------------------"); - AVSD_TEST_LOG(AVSD_TEST_TRACE, "Frame TR QP SnrY SnrU SnrV Time(ms) FRM/FLD"); - - return MPP_OK; -__FAILED: - avsd_deinit(inp); - - return ret; -} - - -static MPP_RET avsd_read_data(InputParams *inp) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - - inp->len = (RK_U32)fread(inp->pbuf, sizeof(RK_U8), inp->bufsize, inp->fp_in); - inp->is_eof = feof(inp->fp_in); - - if (inp->fp_read) { - fwrite(inp->pbuf, inp->len, 1, inp->fp_read); - fflush(inp->fp_read); - } - - return ret = MPP_OK; -} - -static MPP_RET decoder_single_test(AvsdTestCtx_t *pctx) -{ - MppPacket pkt = NULL; - RK_U32 end_of_flag = 0; - MPP_RET ret = MPP_ERR_UNKNOW; - - MppDec *pApi = &pctx->m_api; - InputParams *inp = &pctx->m_in; - HalTaskInfo *task = &pctx->m_task; - //!< initial task - memset(task, 0, sizeof(HalTaskInfo)); - memset(task->dec.refer, -1, sizeof(task->dec.refer)); - task->dec.input = -1; - do { - //!< get one packet - if (pkt == NULL) { - if (inp->is_eof || - (inp->dec_num && (inp->dec_no >= inp->dec_num))) { - mpp_packet_init(&pkt, NULL, 0); - mpp_packet_set_eos(pkt); - } else { - FUN_CHECK(ret = avsd_read_data(inp)); - mpp_packet_init(&pkt, inp->pbuf, inp->len); - } - } - //!< prepare - FUN_CHECK(ret = parser_prepare(pApi->parser, pkt, &task->dec)); - - //!< parse - if (task->dec.valid) { - MppBufferImpl *buf = NULL; - - task->dec.valid = 0; - if (task->dec.input < 0) { - mpp_buf_slot_get_unused(pApi->packet_slots, &task->dec.input); - } - mpp_buf_slot_get_prop(pApi->packet_slots, task->dec.input, SLOT_BUFFER, &pctx->m_dec_pkt_buf); - if (NULL == pctx->m_dec_pkt_buf) { - size_t stream_size = mpp_packet_get_size(task->dec.input_packet); - mpp_buffer_get(pctx->mStreamGroup, &pctx->m_dec_pkt_buf, stream_size); - if (pctx->m_dec_pkt_buf) - mpp_buf_slot_set_prop(pApi->packet_slots, task->dec.input, SLOT_BUFFER, pctx->m_dec_pkt_buf); - } - buf = (MppBufferImpl *)pctx->m_dec_pkt_buf; - memcpy(buf->info.ptr, mpp_packet_get_data(task->dec.input_packet), mpp_packet_get_length(task->dec.input_packet)); - - mpp_buf_slot_set_flag(pApi->packet_slots, task->dec.input, SLOT_CODEC_READY); - mpp_buf_slot_set_flag(pApi->packet_slots, task->dec.input, SLOT_HAL_INPUT); - FUN_CHECK(ret = parser_parse(pApi->parser, &task->dec)); - - AVSD_TEST_LOG(AVSD_TEST_TRACE, "[AVSD_TEST] ---- decoder, read_one_frame Frame_no = %d", inp->dec_no); - inp->dec_no++; - } - //!< deinit packet - if (mpp_packet_get_length(pkt) == 0) { - if (mpp_packet_get_eos(pkt)) { - if (task->dec.valid) { - mpp_buf_slot_clr_flag(pApi->packet_slots, task->dec.input, SLOT_HAL_INPUT); - mpp_buf_slot_clr_flag(pApi->frame_slots, task->dec.output, SLOT_HAL_OUTPUT); - task->dec.valid = 0; - } - end_of_flag = 1; //!< end of stream - } - mpp_packet_deinit(&pkt); - pkt = NULL; - } - //!< run hal module - if (task->dec.valid) { - if (mpp_buf_slot_is_changed(pApi->frame_slots)) { - mpp_buf_slot_ready(pApi->frame_slots); - } - mpp_buf_slot_get_prop(pApi->frame_slots, task->dec.output, SLOT_BUFFER, &pctx->m_dec_pic_buf); - if (NULL == pctx->m_dec_pic_buf) { - RK_U32 size = 1920 * 1088 * 3 / 2;// (RK_U32)mpp_buf_slot_get_size(pApi->frame_slots); - mpp_buffer_get(pctx->mFrameGroup, &pctx->m_dec_pic_buf, size); - if (pctx->m_dec_pic_buf) - mpp_buf_slot_set_prop(pApi->frame_slots, task->dec.output, SLOT_BUFFER, pctx->m_dec_pic_buf); - } - FUN_CHECK(ret = mpp_hal_reg_gen(pApi->hal, task)); - - FUN_CHECK(ret = mpp_hal_hw_start(pApi->hal, task)); - FUN_CHECK(ret = mpp_hal_hw_wait(pApi->hal, task)); - if (pctx->m_dec_pkt_buf) { - mpp_buffer_put(pctx->m_dec_pkt_buf); - pctx->m_dec_pkt_buf = NULL; - } - mpp_buf_slot_clr_flag(pApi->packet_slots, task->dec.input, SLOT_HAL_INPUT); - mpp_buf_slot_clr_flag(pApi->frame_slots, task->dec.output, SLOT_HAL_OUTPUT); - //!< write frame out - avsd_flush_frames(pApi, inp->fp_out); - //!< clear refrece flag - { - RK_U32 i = 0; - for (i = 0; i < MPP_ARRAY_ELEMS(task->dec.refer); i++) { - if (task->dec.refer[i] >= 0) { - mpp_buf_slot_clr_flag(pApi->frame_slots, task->dec.refer[i], SLOT_HAL_INPUT); - } - } - } - //!< reset task - memset(task, 0, sizeof(HalTaskInfo)); - memset(task->dec.refer, -1, sizeof(task->dec.refer)); - task->dec.input = -1; - - } - } while (!end_of_flag); - - //!< flush dpb and send to display - FUN_CHECK(ret = mpp_dec_flush(pApi)); - - ret = MPP_OK; -__FAILED: - return ret; -} - - -int main(int argc, char **argv) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - AvsdTestCtx_t m_decoder; - AvsdTestCtx_t *p_dec = &m_decoder; - -#if defined(_MSC_VER) - mpp_env_set_u32("rkv_avsd_test_debug", 0xFF); -#endif - mpp_env_get_u32("rkv_avsd_test_debug", &rkv_avsd_test_debug, 0x0F); - memset(p_dec, 0, sizeof(AvsdTestCtx_t)); - // read file - FUN_CHECK(ret = avsd_input_init(&p_dec->m_in, argc, argv)); - // init - decoder_init(p_dec); - // decode - ret = decoder_single_test(p_dec); - if (ret != MPP_OK) { - AVSD_TEST_LOG(AVSD_TEST_TRACE, "[AVSD_TEST] Single-thread test error."); - goto __FAILED; - } - - ret = MPP_OK; -__FAILED: - decoder_deinit(p_dec); - avsd_input_deinit(&p_dec->m_in); - - AVSD_TEST_LOG(AVSD_TEST_TRACE, "[AVSD_TEST] decoder_deinit over."); - - return ret; -} - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define MODULE_TAG "avsd_test" + +#if defined(_WIN32) +#include "vld.h" +#endif +#include + +#include "vpu_api.h" +#include "mpp_env.h" +#include "mpp_log.h" +#include "mpp_dec.h" +#include "mpp_hal.h" +#include "mpp_mem.h" +#include "mpp_common.h" +#include "mpp_packet.h" +#include "mpp_packet_impl.h" +#include "mpp_buffer.h" +#include "mpp_buffer_impl.h" +#include "mpp_hal.h" +#include "mpp_thread.h" + +#include "hal_task.h" +#include "avsd_api.h" +#include "avsd_parse.h" +#include "hal_avsd_api.h" + + +#define AVSD_TEST_ERROR (0x00000001) +#define AVSD_TEST_ASSERT (0x00000002) +#define AVSD_TEST_WARNNING (0x00000004) +#define AVSD_TEST_TRACE (0x00000008) + +#define AVSD_TEST_DUMPYUV (0x00000010) + + +#define AVSD_TEST_LOG(level, fmt, ...)\ +do {\ +if (level & rkv_avsd_test_debug)\ + { mpp_log(fmt, ## __VA_ARGS__); }\ +} while (0) + + +typedef struct ParserImpl_t { + ParserCfg cfg; + + const ParserApi *api; + void *ctx; +} ParserImpl; + + +static RK_U32 rkv_avsd_test_debug = 0; + +typedef struct inp_par_t { + FILE *fp_in; + FILE *fp_out; + FILE *fp_read; + RK_U8 *pbuf; + RK_U32 bufsize; + RK_U32 len; + + RK_U32 output_dec_pic; // output_dec_pic + + RK_U32 dec_num; // to be decoded + RK_U32 dec_no; // current decoded number + + RK_U32 is_eof; +} InputParams; + + +typedef struct avsd_test_ctx_t { + MppDec m_api; + InputParams m_in; + HalTaskInfo m_task; + + MppBuffer m_dec_pkt_buf; + MppBuffer m_dec_pic_buf; + MppBufferGroup mFrameGroup; + MppBufferGroup mStreamGroup; +} AvsdTestCtx_t; + +static MPP_RET decoder_deinit(AvsdTestCtx_t *pctx) +{ + MppDec *pApi = &pctx->m_api; + + if (pApi->parser) { + parser_deinit(pApi->parser); + pApi->parser = NULL; + } + if (pApi->hal) { + mpp_hal_deinit(pApi->hal); + pApi->hal = NULL; + } + if (pApi->frame_slots) { + mpp_buf_slot_deinit(pApi->frame_slots); + pApi->frame_slots = NULL; + } + if (pApi->packet_slots) { + mpp_buf_slot_deinit(pApi->packet_slots); + pApi->packet_slots = NULL; + } + if (pctx->m_dec_pkt_buf) { + mpp_buffer_put(pctx->m_dec_pkt_buf); + pctx->m_dec_pkt_buf = NULL; + } + if (pctx->m_dec_pic_buf) { + mpp_buffer_put(pctx->m_dec_pic_buf); + pctx->m_dec_pic_buf = NULL; + } + if (pctx->mFrameGroup) { + mpp_err("mFrameGroup deInit"); + mpp_buffer_group_put(pctx->mFrameGroup); + pctx->mFrameGroup = NULL; + } + if (pctx->mStreamGroup) { + mpp_err("mStreamGroup deInit"); + mpp_buffer_group_put(pctx->mStreamGroup); + pctx->mStreamGroup = NULL; + } + + return MPP_OK; +} + +static MPP_RET decoder_init(AvsdTestCtx_t *pctx) +{ + + MPP_RET ret = MPP_ERR_UNKNOW; + ParserCfg parser_cfg; + MppHalCfg hal_cfg; + MppDec *pApi = &pctx->m_api; + + if (pctx->mFrameGroup == NULL) { + ret = mpp_buffer_group_get_internal(&pctx->mFrameGroup, MPP_BUFFER_TYPE_NORMAL); + if (MPP_OK != ret) { + mpp_err("avsd mpp_buffer_group_get failed\n"); + goto __FAILED; + } + } + if (pctx->mStreamGroup == NULL) { + ret = mpp_buffer_group_get_internal(&pctx->mStreamGroup, MPP_BUFFER_TYPE_NORMAL); + if (MPP_OK != ret) { + mpp_err("avsd mpp_buffer_group_get failed\n"); + goto __FAILED; + } + } + // codec + pApi->coding = MPP_VIDEO_CodingAVS; + // malloc slot + FUN_CHECK(ret = mpp_buf_slot_init(&pApi->frame_slots)); + MEM_CHECK(ret, pApi->frame_slots); + ret = mpp_buf_slot_init(&pApi->packet_slots); + MEM_CHECK(ret, pApi->packet_slots); + mpp_buf_slot_setup(pApi->packet_slots, 2); + // init parser part + memset(&parser_cfg, 0, sizeof(parser_cfg)); + parser_cfg.coding = pApi->coding; + parser_cfg.frame_slots = pApi->frame_slots; + parser_cfg.packet_slots = pApi->packet_slots; + parser_cfg.task_count = 2; + FUN_CHECK(ret = parser_init(&pApi->parser, &parser_cfg)); + + // init hal part + memset(&hal_cfg, 0, sizeof(hal_cfg)); + hal_cfg.type = MPP_CTX_DEC; + hal_cfg.coding = pApi->coding; + hal_cfg.work_mode = HAL_MODE_LIBVPU; + hal_cfg.device_id = HAL_RKVDEC; + hal_cfg.frame_slots = pApi->frame_slots; + hal_cfg.packet_slots = pApi->packet_slots; + hal_cfg.task_count = parser_cfg.task_count; + hal_cfg.hal_int_cb.opaque = ((ParserImpl *)(pApi->parser))->ctx; + hal_cfg.hal_int_cb.callBack = api_avsd_parser.callback; + //api_avsd_parser.callback(hal_cfg.hal_int_cb.opaque, NULL); + FUN_CHECK(ret = mpp_hal_init(&pApi->hal, &hal_cfg)); + pApi->tasks = hal_cfg.tasks; + + return MPP_OK; + +__FAILED: + decoder_deinit(pctx); + + return ret; +} + +static MPP_RET avsd_flush_frames(MppDec *pApi, FILE *fp) +{ + RK_S32 slot_idx = 0; + MppFrame out_frame = NULL; + + while (MPP_OK == mpp_buf_slot_dequeue(pApi->frame_slots, &slot_idx, QUEUE_DISPLAY)) { + mpp_buf_slot_get_prop(pApi->frame_slots, slot_idx, SLOT_FRAME, &out_frame); + if (out_frame) { + RK_U32 stride_w, stride_h; + void *ptr = NULL; + MppBuffer framebuf; + stride_w = mpp_frame_get_hor_stride(out_frame); + stride_h = mpp_frame_get_ver_stride(out_frame); + framebuf = mpp_frame_get_buffer(out_frame); + ptr = mpp_buffer_get_ptr(framebuf); + if (fp) { + fwrite(ptr, 1, stride_w * stride_h * 3 / 2, fp); + fflush(fp); + } + mpp_frame_deinit(&out_frame); + out_frame = NULL; + } + mpp_buf_slot_clr_flag(pApi->frame_slots, slot_idx, SLOT_QUEUE_USE); + } + + return MPP_OK; +} + + +static MPP_RET avsd_input_deinit(InputParams *inp) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + + MPP_FREE(inp->pbuf); + MPP_FCLOSE(inp->fp_in); + MPP_FCLOSE(inp->fp_out); + MPP_FCLOSE(inp->fp_read); + return ret = MPP_OK; +} + +static MPP_RET avsd_input_init(InputParams *inp, RK_S32 ac, char *av[]) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + char infile_name[128]; //!< Telenor AVS input + char outfile_name[128]; //!< Decoded YUV 4:2:0 output + RK_S32 CLcount = 1; + + inp->output_dec_pic = 0; + while (CLcount < ac) { + if (!strncmp(av[CLcount], "-h", 2)) { + mpp_log("Options:"); + mpp_log(" -h : prints help message."); + mpp_log(" -i :[file] Set input AVS+ bitstream file."); + mpp_log(" -o :[file] Set output YUV file."); + mpp_log(" -n :[number] Set decoded frames."); + CLcount += 1; + } else if (!strncmp(av[CLcount], "-i", 2)) { + strncpy(infile_name, av[CLcount + 1], strlen((const char*)av[CLcount + 1]) + 1); + CLcount += 2; + } else if (!strncmp(av[CLcount], "-n", 2)) { + if (!sscanf(av[CLcount + 1], "%d", &inp->dec_num)) { + goto __FAILED; + } + CLcount += 2; + } else if (!strncmp(av[CLcount], "-o", 2)) { + if (rkv_avsd_test_debug & AVSD_TEST_DUMPYUV) { + inp->output_dec_pic = 1; + strncpy(outfile_name, av[CLcount + 1], strlen((const char*)av[CLcount + 1]) + 1); + } + CLcount += 2; + } else { + mpp_err("error, %s cannot explain command! \n", av[CLcount]); + goto __FAILED; + } + } + if ((inp->fp_in = fopen(infile_name, "rb")) == 0) { + mpp_err("error, open file %s ", infile_name); + goto __FAILED; + } + if (inp->output_dec_pic) { + if ((inp->fp_out = fopen(outfile_name, "wb")) == 0) { + mpp_err("error, open file %s ", outfile_name); + goto __FAILED; + } + } + if ((inp->fp_read = fopen("F:/avs_log/avs_read.txt", "wb")) == 0) { + mpp_log("error, open file %s", "F:/avs_log/avs_read.txt"); + goto __FAILED; + } + + //!< malloc read buffer + inp->bufsize = 30 * 1024; + MEM_CHECK(ret, inp->pbuf = mpp_malloc(RK_U8, inp->bufsize)); + + AVSD_TEST_LOG(AVSD_TEST_TRACE, "------------------------------------------------------------"); + AVSD_TEST_LOG(AVSD_TEST_TRACE, "Input AVS+ bitstream : %s", infile_name); + AVSD_TEST_LOG(AVSD_TEST_TRACE, "Output decoded YUV : %s", outfile_name); + AVSD_TEST_LOG(AVSD_TEST_TRACE, "------------------------------------------------------------"); + AVSD_TEST_LOG(AVSD_TEST_TRACE, "Frame TR QP SnrY SnrU SnrV Time(ms) FRM/FLD"); + + return MPP_OK; +__FAILED: + avsd_deinit(inp); + + return ret; +} + + +static MPP_RET avsd_read_data(InputParams *inp) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + + inp->len = (RK_U32)fread(inp->pbuf, sizeof(RK_U8), inp->bufsize, inp->fp_in); + inp->is_eof = feof(inp->fp_in); + + if (inp->fp_read) { + fwrite(inp->pbuf, inp->len, 1, inp->fp_read); + fflush(inp->fp_read); + } + + return ret = MPP_OK; +} + +static MPP_RET decoder_single_test(AvsdTestCtx_t *pctx) +{ + MppPacket pkt = NULL; + RK_U32 end_of_flag = 0; + MPP_RET ret = MPP_ERR_UNKNOW; + + MppDec *pApi = &pctx->m_api; + InputParams *inp = &pctx->m_in; + HalTaskInfo *task = &pctx->m_task; + //!< initial task + memset(task, 0, sizeof(HalTaskInfo)); + memset(task->dec.refer, -1, sizeof(task->dec.refer)); + task->dec.input = -1; + do { + //!< get one packet + if (pkt == NULL) { + if (inp->is_eof || + (inp->dec_num && (inp->dec_no >= inp->dec_num))) { + mpp_packet_init(&pkt, NULL, 0); + mpp_packet_set_eos(pkt); + } else { + FUN_CHECK(ret = avsd_read_data(inp)); + mpp_packet_init(&pkt, inp->pbuf, inp->len); + } + } + //!< prepare + FUN_CHECK(ret = parser_prepare(pApi->parser, pkt, &task->dec)); + + //!< parse + if (task->dec.valid) { + MppBufferImpl *buf = NULL; + + task->dec.valid = 0; + if (task->dec.input < 0) { + mpp_buf_slot_get_unused(pApi->packet_slots, &task->dec.input); + } + mpp_buf_slot_get_prop(pApi->packet_slots, task->dec.input, SLOT_BUFFER, &pctx->m_dec_pkt_buf); + if (NULL == pctx->m_dec_pkt_buf) { + size_t stream_size = mpp_packet_get_size(task->dec.input_packet); + mpp_buffer_get(pctx->mStreamGroup, &pctx->m_dec_pkt_buf, stream_size); + if (pctx->m_dec_pkt_buf) + mpp_buf_slot_set_prop(pApi->packet_slots, task->dec.input, SLOT_BUFFER, pctx->m_dec_pkt_buf); + } + buf = (MppBufferImpl *)pctx->m_dec_pkt_buf; + memcpy(buf->info.ptr, mpp_packet_get_data(task->dec.input_packet), mpp_packet_get_length(task->dec.input_packet)); + + mpp_buf_slot_set_flag(pApi->packet_slots, task->dec.input, SLOT_CODEC_READY); + mpp_buf_slot_set_flag(pApi->packet_slots, task->dec.input, SLOT_HAL_INPUT); + FUN_CHECK(ret = parser_parse(pApi->parser, &task->dec)); + + AVSD_TEST_LOG(AVSD_TEST_TRACE, "[AVSD_TEST] ---- decoder, read_one_frame Frame_no = %d", inp->dec_no); + inp->dec_no++; + } + //!< deinit packet + if (mpp_packet_get_length(pkt) == 0) { + if (mpp_packet_get_eos(pkt)) { + if (task->dec.valid) { + mpp_buf_slot_clr_flag(pApi->packet_slots, task->dec.input, SLOT_HAL_INPUT); + mpp_buf_slot_clr_flag(pApi->frame_slots, task->dec.output, SLOT_HAL_OUTPUT); + task->dec.valid = 0; + } + end_of_flag = 1; //!< end of stream + } + mpp_packet_deinit(&pkt); + pkt = NULL; + } + //!< run hal module + if (task->dec.valid) { + if (mpp_buf_slot_is_changed(pApi->frame_slots)) { + mpp_buf_slot_ready(pApi->frame_slots); + } + mpp_buf_slot_get_prop(pApi->frame_slots, task->dec.output, SLOT_BUFFER, &pctx->m_dec_pic_buf); + if (NULL == pctx->m_dec_pic_buf) { + RK_U32 size = 1920 * 1088 * 3 / 2;// (RK_U32)mpp_buf_slot_get_size(pApi->frame_slots); + mpp_buffer_get(pctx->mFrameGroup, &pctx->m_dec_pic_buf, size); + if (pctx->m_dec_pic_buf) + mpp_buf_slot_set_prop(pApi->frame_slots, task->dec.output, SLOT_BUFFER, pctx->m_dec_pic_buf); + } + FUN_CHECK(ret = mpp_hal_reg_gen(pApi->hal, task)); + + FUN_CHECK(ret = mpp_hal_hw_start(pApi->hal, task)); + FUN_CHECK(ret = mpp_hal_hw_wait(pApi->hal, task)); + if (pctx->m_dec_pkt_buf) { + mpp_buffer_put(pctx->m_dec_pkt_buf); + pctx->m_dec_pkt_buf = NULL; + } + mpp_buf_slot_clr_flag(pApi->packet_slots, task->dec.input, SLOT_HAL_INPUT); + mpp_buf_slot_clr_flag(pApi->frame_slots, task->dec.output, SLOT_HAL_OUTPUT); + //!< write frame out + avsd_flush_frames(pApi, inp->fp_out); + //!< clear refrece flag + { + RK_U32 i = 0; + for (i = 0; i < MPP_ARRAY_ELEMS(task->dec.refer); i++) { + if (task->dec.refer[i] >= 0) { + mpp_buf_slot_clr_flag(pApi->frame_slots, task->dec.refer[i], SLOT_HAL_INPUT); + } + } + } + //!< reset task + memset(task, 0, sizeof(HalTaskInfo)); + memset(task->dec.refer, -1, sizeof(task->dec.refer)); + task->dec.input = -1; + + } + } while (!end_of_flag); + + //!< flush dpb and send to display + FUN_CHECK(ret = mpp_dec_flush(pApi)); + + ret = MPP_OK; +__FAILED: + return ret; +} + + +int main(int argc, char **argv) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + AvsdTestCtx_t m_decoder; + AvsdTestCtx_t *p_dec = &m_decoder; + +#if defined(_MSC_VER) + mpp_env_set_u32("rkv_avsd_test_debug", 0xFF); +#endif + mpp_env_get_u32("rkv_avsd_test_debug", &rkv_avsd_test_debug, 0x0F); + memset(p_dec, 0, sizeof(AvsdTestCtx_t)); + // read file + FUN_CHECK(ret = avsd_input_init(&p_dec->m_in, argc, argv)); + // init + decoder_init(p_dec); + // decode + ret = decoder_single_test(p_dec); + if (ret != MPP_OK) { + AVSD_TEST_LOG(AVSD_TEST_TRACE, "[AVSD_TEST] Single-thread test error."); + goto __FAILED; + } + + ret = MPP_OK; +__FAILED: + decoder_deinit(p_dec); + avsd_input_deinit(&p_dec->m_in); + + AVSD_TEST_LOG(AVSD_TEST_TRACE, "[AVSD_TEST] decoder_deinit over."); + + return ret; +} + diff --git a/mpp/test/h264d_test.c b/mpp/test/h264d_test.c index 716f6a45..ae25aeda 100644 --- a/mpp/test/h264d_test.c +++ b/mpp/test/h264d_test.c @@ -1,620 +1,620 @@ -/* -* Copyright 2015 Rockchip Electronics Co. LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#define MODULE_TAG "h264d_test" - - -#if defined(_WIN32) -#include "vld.h" -#endif -#include - -#include "vpu_api.h" - -#include "h264d_log.h" -#include "mpp_env.h" -#include "mpp_dec.h" -#include "mpp_hal.h" -#include "mpp_mem.h" -#include "mpp_packet.h" -#include "mpp_packet_impl.h" -#include "mpp_buffer.h" -#include "mpp_buffer_impl.h" -#include "mpp_hal.h" - -#include "h264d_log.h" -#include "h264d_rwfile.h" -#include "h264d_api.h" -#include "hal_task.h" -#include "hal_h264d_api.h" -#include "mpp_thread.h" - -typedef enum { - HAL_THREAD_UNINITED, - HAL_THREAD_RUNNING, - HAL_THREAD_WAITING, - HAL_THREAD_STOPPING, -} HalStatus; - -typedef struct hal_thread_param_t { - HalStatus hal_status; - pthread_t halThread; - pthread_mutex_t parLock; - pthread_cond_t parCond; - pthread_mutex_t halLock; - pthread_cond_t halCond; -} HalThreadPar_t; - -typedef struct h264d_test_ctx_t { - MppDec m_api; - InputParams m_in; - HalTaskInfo m_task; - HalThreadPar_t m_hal; - MppBuffer m_dec_pkt_buf; - MppBuffer m_dec_pic_buf; - MppBufferGroup mFrameGroup; - MppBufferGroup mStreamGroup; -} H264dTestCtx_t; - -static MPP_RET manual_set_env(void) -{ -#if defined(_MSC_VER) - mpp_env_set_u32("h264d_log_help", 1); - mpp_env_set_u32("h264d_log_show", 1); - mpp_env_set_u32("h264d_log_ctrl", 0x800B); - mpp_env_set_u32("h264d_log_level", 5); - mpp_env_set_u32("h264d_log_decframe", 0); - mpp_env_set_u32("h264d_log_begframe", 0); - mpp_env_set_u32("h264d_log_endframe", 0); - mpp_env_set_u32("h264d_log_yuv", 0); - mpp_env_set_u32("h264d_chg_org", 0); //!< 0:VDPU 1: RKVDEC - mpp_env_set_str("h264d_log_outpath", "F:/h264_log/allegro_dat"); - mpp_env_set_str("h264d_log_cmppath", "F:/h264_log_driver/trunk_dat"); -#endif - return MPP_OK; -} - - -static MPP_RET decoder_deinit(H264dTestCtx_t *pctx) -{ - MppDec *pApi = &pctx->m_api; - - if (pApi->parser) { - parser_deinit(pApi->parser); - pApi->parser = NULL; - } - if (pApi->hal) { - mpp_hal_deinit(pApi->hal); - pApi->hal = NULL; - } - if (pApi->frame_slots) { - mpp_buf_slot_deinit(pApi->frame_slots); - pApi->frame_slots = NULL; - } - if (pApi->packet_slots) { - mpp_buf_slot_deinit(pApi->packet_slots); - pApi->packet_slots = NULL; - } - if (pctx->m_dec_pkt_buf) { - mpp_buffer_put(pctx->m_dec_pkt_buf); - } - if (pctx->m_dec_pic_buf) { - mpp_buffer_put(pctx->m_dec_pic_buf); - } - if (pctx->mFrameGroup != NULL) { - mpp_err("mFrameGroup deInit"); - mpp_buffer_group_put(pctx->mFrameGroup); - } - if (pctx->mStreamGroup != NULL) { - mpp_err("mStreamGroup deInit"); - mpp_buffer_group_put(pctx->mStreamGroup); - } - return MPP_OK; -} - -static MPP_RET decoder_init(H264dTestCtx_t *pctx) -{ - - MPP_RET ret = MPP_ERR_UNKNOW; - ParserCfg parser_cfg; - MppHalCfg hal_cfg; - MppDec *pApi = &pctx->m_api; - - manual_set_env(); // set env, in windows - - mpp_env_get_u32("rkv_h264d_test_debug", &rkv_h264d_test_debug, 0); - - if (pctx->mFrameGroup == NULL) { - ret = mpp_buffer_group_get_internal(&pctx->mFrameGroup, MPP_BUFFER_TYPE_ION); - if (MPP_OK != ret) { - mpp_err("h264d mpp_buffer_group_get failed\n"); - goto __FAILED; - } - } - if (pctx->mStreamGroup == NULL) { - ret = mpp_buffer_group_get_internal(&pctx->mStreamGroup, MPP_BUFFER_TYPE_ION); - if (MPP_OK != ret) { - mpp_err("h264d mpp_buffer_group_get failed\n"); - goto __FAILED; - } - } - // codec - pApi->coding = MPP_VIDEO_CodingAVC; - // malloc slot - FUN_CHECK(ret = mpp_buf_slot_init(&pApi->frame_slots)); - MEM_CHECK(ret, pApi->frame_slots); - ret = mpp_buf_slot_init(&pApi->packet_slots); - MEM_CHECK(ret, pApi->packet_slots); - mpp_buf_slot_setup(pApi->packet_slots, 2); - // init parser part - memset(&parser_cfg, 0, sizeof(parser_cfg)); - parser_cfg.coding = pApi->coding; - parser_cfg.frame_slots = pApi->frame_slots; - parser_cfg.packet_slots = pApi->packet_slots; - parser_cfg.task_count = 2; - FUN_CHECK(ret = parser_init(&pApi->parser, &parser_cfg)); - // init hal part - memset(&hal_cfg, 0, sizeof(hal_cfg)); - hal_cfg.type = MPP_CTX_DEC; - hal_cfg.coding = pApi->coding; - hal_cfg.work_mode = HAL_MODE_LIBVPU; - { - RK_U32 hal_device_id = 0; - mpp_env_get_u32("h264d_chg_org", &hal_device_id, 1); - if (hal_device_id == 1) { - hal_cfg.device_id = HAL_RKVDEC; - } else { - hal_cfg.device_id = HAL_VDPU; - } - } - hal_cfg.frame_slots = pApi->frame_slots; - hal_cfg.packet_slots = pApi->packet_slots; - hal_cfg.task_count = parser_cfg.task_count; - FUN_CHECK(ret = mpp_hal_init(&pApi->hal, &hal_cfg)); - pApi->tasks = hal_cfg.tasks; - - return MPP_OK; - -__FAILED: - decoder_deinit(pctx); - - return ret; -} - -static MPP_RET flush_decoded_frames(MppDec *pApi, FILE *fp) -{ - RK_S32 slot_idx = 0; - MppFrame out_frame = NULL; - - while (MPP_OK == mpp_buf_slot_dequeue(pApi->frame_slots, &slot_idx, QUEUE_DISPLAY)) { - mpp_buf_slot_get_prop(pApi->frame_slots, slot_idx, SLOT_FRAME, &out_frame); - if (out_frame) { - RK_U32 stride_w, stride_h; - void *ptr = NULL; - MppBuffer framebuf; - stride_w = mpp_frame_get_hor_stride(out_frame); - stride_h = mpp_frame_get_ver_stride(out_frame); - framebuf = mpp_frame_get_buffer(out_frame); - ptr = mpp_buffer_get_ptr(framebuf); - if ((rkv_h264d_test_debug & H264D_TEST_DUMPYUV) && fp) { - fwrite(ptr, 1, stride_w * stride_h * 3 / 2, fp); - fflush(fp); - } - mpp_frame_deinit(&out_frame); - out_frame = NULL; - } - mpp_buf_slot_clr_flag(pApi->frame_slots, slot_idx, SLOT_QUEUE_USE); - } - - return MPP_OK; -} - -static MPP_RET decoder_single_test(H264dTestCtx_t *pctx) -{ - MppPacket pkt = NULL; - RK_U32 end_of_flag = 0; - MPP_RET ret = MPP_ERR_UNKNOW; - - MppDec *pApi = &pctx->m_api; - InputParams *pIn = &pctx->m_in; - HalTaskInfo *task = &pctx->m_task; - //!< initial task - memset(task, 0, sizeof(HalTaskInfo)); - memset(task->dec.refer, -1, sizeof(task->dec.refer)); - task->dec.input = -1; - do { - //!< get one packet - if (pkt == NULL) { - if (pIn->is_eof || - (pIn->iDecFrmNum && (pIn->iFrmdecoded >= pIn->iDecFrmNum))) { - mpp_packet_init(&pkt, NULL, 0); - mpp_packet_set_eos(pkt); - } else { - FUN_CHECK(ret = h264d_read_one_frame(pIn)); - mpp_packet_init(&pkt, pIn->strm.pbuf, pIn->strm.strmbytes); - } - H264D_TEST_LOG(H264D_TEST_TRACE, "[H264D_TEST] ---- decoder, read_one_frame Frame_no = %d", pIn->iFrmdecoded); - pIn->iFrmdecoded++; - } - //!< prepare - FUN_CHECK(ret = parser_prepare(pApi->parser, pkt, &task->dec)); - - //!< parse - if (task->dec.valid) { - MppBufferImpl *buf = NULL; - - task->dec.valid = 0; - if (task->dec.input < 0) { - mpp_buf_slot_get_unused(pApi->packet_slots, &task->dec.input); - } - mpp_buf_slot_get_prop(pApi->packet_slots, task->dec.input, SLOT_BUFFER, &pctx->m_dec_pkt_buf); - if (NULL == pctx->m_dec_pkt_buf) { - size_t stream_size = mpp_packet_get_size(task->dec.input_packet); - mpp_buffer_get(pctx->mStreamGroup, &pctx->m_dec_pkt_buf, stream_size); - if (pctx->m_dec_pkt_buf) - mpp_buf_slot_set_prop(pApi->packet_slots, task->dec.input, SLOT_BUFFER, pctx->m_dec_pkt_buf); - } - buf = (MppBufferImpl *)pctx->m_dec_pkt_buf; - memcpy(buf->info.ptr, mpp_packet_get_data(task->dec.input_packet), mpp_packet_get_length(task->dec.input_packet)); - - mpp_buf_slot_set_flag(pApi->packet_slots, task->dec.input, SLOT_CODEC_READY); - mpp_buf_slot_set_flag(pApi->packet_slots, task->dec.input, SLOT_HAL_INPUT); - FUN_CHECK(ret = parser_parse(pApi->parser, &task->dec)); - } - //!< deinit packet - if (mpp_packet_get_length(pkt) == 0) { - if (mpp_packet_get_eos(pkt)) { - end_of_flag = 1; //!< end of stream - task->dec.valid = 0; - mpp_buf_slot_clr_flag(pApi->packet_slots, task->dec.input, SLOT_HAL_INPUT); - mpp_buf_slot_clr_flag(pApi->frame_slots, task->dec.output, SLOT_HAL_OUTPUT); - } - mpp_packet_deinit(&pkt); - pkt = NULL; - } - //!< run hal module - if (task->dec.valid) { - if (mpp_buf_slot_is_changed(pApi->frame_slots)) { - mpp_buf_slot_ready(pApi->frame_slots); - } - mpp_buf_slot_get_prop(pApi->frame_slots, task->dec.output, SLOT_BUFFER, &pctx->m_dec_pic_buf); - if (NULL == pctx->m_dec_pic_buf) { - RK_U32 size = (RK_U32)mpp_buf_slot_get_size(pApi->frame_slots); - mpp_buffer_get(pctx->mFrameGroup, &pctx->m_dec_pic_buf, size); - if (pctx->m_dec_pic_buf) - mpp_buf_slot_set_prop(pApi->frame_slots, task->dec.output, SLOT_BUFFER, pctx->m_dec_pic_buf); - } - FUN_CHECK(ret = mpp_hal_reg_gen(pApi->hal, task)); - - FUN_CHECK(ret = mpp_hal_hw_start(pApi->hal, task)); - FUN_CHECK(ret = mpp_hal_hw_wait(pApi->hal, task)); - if (pctx->m_dec_pkt_buf) { - mpp_buffer_put(pctx->m_dec_pkt_buf); - pctx->m_dec_pkt_buf = NULL; - } - mpp_buf_slot_clr_flag(pApi->packet_slots, task->dec.input, SLOT_HAL_INPUT); - mpp_buf_slot_clr_flag(pApi->frame_slots, task->dec.output, SLOT_HAL_OUTPUT); - //!< write frame out - flush_decoded_frames(pApi, pIn->fp_yuv_data); - //!< clear refrece flag - { - RK_U32 i = 0; - for (i = 0; i < MPP_ARRAY_ELEMS(task->dec.refer); i++) { - if (task->dec.refer[i] >= 0) { - mpp_buf_slot_clr_flag(pApi->frame_slots, task->dec.refer[i], SLOT_HAL_INPUT); - } - } - } - //!< reset task - memset(task, 0, sizeof(HalTaskInfo)); - memset(task->dec.refer, -1, sizeof(task->dec.refer)); - task->dec.input = -1; - - } - } while (!end_of_flag); - //!< flush dpb and send to display - FUN_CHECK(ret = mpp_dec_flush(pApi)); - flush_decoded_frames(pApi, pIn->fp_yuv_data); - - ret = MPP_OK; -__FAILED: - return ret; -} - -static void *hal_thread_run(void *in_ctx) -{ - H264dTestCtx_t *pctx = (H264dTestCtx_t *)in_ctx; - - MppDec *pApi = &pctx->m_api; - InputParams *pIn = &pctx->m_in; - HalTaskInfo *task = &pctx->m_task; - HalThreadPar_t *p_hal = &pctx->m_hal; - HalStatus hal_status = p_hal->hal_status; - - do { - //!< wait - { - pthread_mutex_lock(&p_hal->halLock); - H264D_TEST_LOG(H264D_TEST_TRACE, "[hal_thread] pthread_cond_wait(par_Cond)."); - pthread_cond_wait(&p_hal->parCond, &p_hal->halLock); - pthread_mutex_unlock(&p_hal->halLock); - } - //!< break - { - pthread_mutex_lock(&p_hal->halLock); - hal_status = p_hal->hal_status; - pthread_mutex_unlock(&p_hal->halLock); - } - H264D_TEST_LOG(H264D_TEST_TRACE, "[hal_thread] hal_status=%d.", hal_status); - if (hal_status == HAL_THREAD_STOPPING) { - H264D_TEST_LOG(H264D_TEST_TRACE, "[hal_thread] 2222222222."); - break; - } - //!< signal - { - pthread_mutex_lock(&p_hal->halLock); - mpp_hal_hw_wait(pctx->m_api.hal, &pctx->m_task); - //pthread_cond_signal(&p_hal->halCond); - H264D_TEST_LOG(H264D_TEST_TRACE, "[hal_thread] pthread_cond_signal(hal_Cond)."); - pthread_mutex_unlock(&p_hal->halLock); - } - { - if (pctx->m_dec_pkt_buf) { - mpp_buffer_put(pctx->m_dec_pkt_buf); - } - mpp_buf_slot_clr_flag(pApi->packet_slots, task->dec.input, SLOT_HAL_INPUT); - mpp_buf_slot_clr_flag(pApi->frame_slots, task->dec.output, SLOT_HAL_OUTPUT); - //!< write frame out - flush_decoded_frames(pApi, pIn->fp_yuv_data); - //!< clear refrece flag - { - RK_U32 i = 0; - for (i = 0; i < MPP_ARRAY_ELEMS(task->dec.refer); i++) { - if (task->dec.refer[i] >= 0) { - mpp_buf_slot_clr_flag(pApi->frame_slots, task->dec.refer[i], SLOT_HAL_INPUT); - } - } - } - //!< reset task - memset(task, 0, sizeof(HalTaskInfo)); - memset(task->dec.refer, -1, sizeof(task->dec.refer)); - task->dec.input = -1; - } - pthread_cond_signal(&p_hal->halCond); - - } while (hal_status != HAL_THREAD_STOPPING); - H264D_TEST_LOG(H264D_TEST_TRACE, "[hal_thread] 4444444444444444"); - - return NULL; -} - -static MPP_RET decoder_muti_deinit(H264dTestCtx_t *pctx) -{ - void *ptr = NULL; - HalThreadPar_t *p_hal = &pctx->m_hal; - - H264D_TEST_LOG(H264D_TEST_TRACE, "decoder_deinit In."); - pthread_join(p_hal->halThread, &ptr); - H264D_TEST_LOG(H264D_TEST_TRACE, "halThread(%p)destroy success", &p_hal->halThread); - - pthread_cond_destroy(&p_hal->parCond); - pthread_cond_destroy(&p_hal->halCond); - pthread_mutex_destroy(&p_hal->parLock); - pthread_mutex_destroy(&p_hal->halLock); - H264D_TEST_LOG(H264D_TEST_TRACE, "3333333333333"); - H264D_TEST_LOG(H264D_TEST_TRACE, "decoder_deinit Ok."); - - return MPP_OK; -} - -static MPP_RET decoder_muti_init(H264dTestCtx_t *pctx) -{ - HalThreadPar_t *p_hal = &pctx->m_hal; - - p_hal->hal_status = HAL_THREAD_RUNNING; - //!< create lock and condition - { - pthread_mutexattr_t attr; - pthread_mutexattr_init(&attr); - pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); - pthread_mutex_init(&p_hal->parLock, &attr); - pthread_mutex_init(&p_hal->halLock, &attr); - pthread_mutexattr_destroy(&attr); - - pthread_cond_init(&p_hal->parCond, NULL); - pthread_cond_init(&p_hal->halCond, NULL); - H264D_TEST_LOG(H264D_TEST_TRACE, "mutex and condition create success."); - pthread_mutex_lock(&p_hal->halLock); - pthread_cond_signal(&p_hal->halCond); - H264D_TEST_LOG(H264D_TEST_TRACE, "pthread_cond_signal(hal_Cond)."); - pthread_mutex_unlock(&p_hal->halLock); - - } - //!< create hal thread - { - pthread_attr_t attr; - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); - if (0 == pthread_create(&p_hal->halThread, &attr, hal_thread_run, pctx)) { - H264D_TEST_LOG(H264D_TEST_TRACE, "hal_thread(%p) create success.", &p_hal->halThread); - } - pthread_attr_destroy(&attr); - } - return MPP_OK; -} - -static MPP_RET decoder_muti_test(H264dTestCtx_t *pctx) -{ - MppPacket pkt = NULL; - RK_U32 end_of_flag = 0; - MPP_RET ret = MPP_ERR_UNKNOW; - - MppDec *pApi = &pctx->m_api; - InputParams *pIn = &pctx->m_in; - HalTaskInfo *task = &pctx->m_task; - //!< init decoder - FUN_CHECK(ret = decoder_muti_init(pctx)); - //!< initial task - memset(task, 0, sizeof(HalTaskInfo)); - memset(task->dec.refer, -1, sizeof(task->dec.refer)); - task->dec.input = -1; - do { - //!< get one packet - if (pkt == NULL) { - if (pIn->is_eof || - (pIn->iDecFrmNum && (pIn->iFrmdecoded >= pIn->iDecFrmNum))) { - mpp_packet_init(&pkt, NULL, 0); - mpp_packet_set_eos(pkt); - } else { - FUN_CHECK(ret = h264d_read_one_frame(pIn)); - mpp_packet_init(&pkt, pIn->strm.pbuf, pIn->strm.strmbytes); - } - H264D_TEST_LOG(H264D_TEST_TRACE, "[H264D_TEST] ---- decoder, read_one_frame Frame_no = %d", pIn->iFrmdecoded); - pIn->iFrmdecoded++; - } - //!< prepare - FUN_CHECK(ret = parser_prepare(pApi->parser, pkt, &task->dec)); - { - HalThreadPar_t *p_hal = &pctx->m_hal; - pthread_mutex_lock(&p_hal->parLock); - H264D_TEST_LOG(H264D_TEST_TRACE, "pthread_cond_wait(hal Cond)."); - pthread_cond_wait(&p_hal->halCond, &p_hal->parLock); - pthread_mutex_unlock(&p_hal->parLock); - } - //!< parse - if (task->dec.valid) { - MppBufferImpl *buf = NULL; - - task->dec.valid = 0; - if (task->dec.input < 0) { - mpp_buf_slot_get_unused(pApi->packet_slots, &task->dec.input); - } - - mpp_buf_slot_get_prop(pApi->packet_slots, task->dec.input, SLOT_BUFFER, &pctx->m_dec_pkt_buf); - if (NULL == pctx->m_dec_pkt_buf) { - size_t stream_size = mpp_packet_get_size(task->dec.input_packet); - mpp_buffer_get(pctx->mStreamGroup, &pctx->m_dec_pkt_buf, stream_size); - if (pctx->m_dec_pkt_buf) - mpp_buf_slot_set_prop(pApi->packet_slots, task->dec.input, SLOT_BUFFER, pctx->m_dec_pkt_buf); - } - buf = (MppBufferImpl *)pctx->m_dec_pkt_buf; - memcpy(buf->info.ptr, mpp_packet_get_data(task->dec.input_packet), mpp_packet_get_length(task->dec.input_packet)); - - mpp_buf_slot_set_flag(pApi->packet_slots, task->dec.input, SLOT_CODEC_READY); - mpp_buf_slot_set_flag(pApi->packet_slots, task->dec.input, SLOT_HAL_INPUT); - FUN_CHECK(ret = parser_parse(pApi->parser, &task->dec)); - } - //!< deinit packet - if (mpp_packet_get_length(pkt) == 0) { - if (mpp_packet_get_eos(pkt)) { - end_of_flag = 1; //!< end of stream - task->dec.valid = 0; - { - HalThreadPar_t *p_hal = &pctx->m_hal; - pthread_mutex_lock(&p_hal->parLock); - p_hal->hal_status = HAL_THREAD_STOPPING; - pthread_cond_signal(&p_hal->parCond); - H264D_TEST_LOG(H264D_TEST_TRACE, "1111111111111111"); - pthread_mutex_unlock(&p_hal->parLock); - } - - mpp_buf_slot_clr_flag(pApi->packet_slots, task->dec.input, SLOT_HAL_INPUT); - mpp_buf_slot_clr_flag(pApi->frame_slots, task->dec.output, SLOT_HAL_OUTPUT); - } - mpp_packet_deinit(&pkt); - pkt = NULL; - } - //!< run hal module - if (task->dec.valid) { - if (mpp_buf_slot_is_changed(pApi->frame_slots)) { - mpp_buf_slot_ready(pApi->frame_slots); - } - mpp_buf_slot_get_prop(pApi->frame_slots, task->dec.output, SLOT_BUFFER, &pctx->m_dec_pic_buf); - if (NULL == pctx->m_dec_pic_buf) { - RK_U32 size = (RK_U32)mpp_buf_slot_get_size(pApi->frame_slots); - mpp_buffer_get(pctx->mFrameGroup, &pctx->m_dec_pic_buf, size); - if (pctx->m_dec_pic_buf) - mpp_buf_slot_set_prop(pApi->frame_slots, task->dec.output, SLOT_BUFFER, pctx->m_dec_pic_buf); - } - FUN_CHECK(ret = mpp_hal_reg_gen(pApi->hal, task)); - - FUN_CHECK(ret = mpp_hal_hw_start(pApi->hal, task)); - { - HalThreadPar_t *p_hal = &pctx->m_hal; - - pthread_mutex_lock(&p_hal->parLock); - pthread_cond_signal(&p_hal->parCond); - H264D_TEST_LOG(H264D_TEST_TRACE, "pthread_cond_single(par Cond)."); - pthread_mutex_unlock(&p_hal->parLock); - } - } - } while (!end_of_flag); - //!< flush dpb and send to display - FUN_CHECK(ret = mpp_dec_flush(pApi)); - flush_decoded_frames(pApi, pIn->fp_yuv_data); - - ret = MPP_OK; -__FAILED: - decoder_muti_deinit(pctx); - - return ret; -} - - -int main(int argc, char **argv) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - InputParams *pInput = NULL; - H264dTestCtx_t *pctx = NULL; - - MEM_CHECK(ret, pctx = mpp_calloc(H264dTestCtx_t, 1)); - // prepare - pInput = &pctx->m_in; - FUN_CHECK(ret = h264d_configure(pInput, argc, argv)); - FUN_CHECK(ret = h264d_open_files(pInput)); - FUN_CHECK(ret = h264d_alloc_frame_buffer(pInput)); - // init - decoder_init(pctx); - // decode - if (rkv_h264d_test_debug & H264D_TEST_MUTI_THREAD) { - ret = decoder_muti_test(pctx); - if (ret != MPP_OK) { - H264D_TEST_LOG(H264D_TEST_TRACE, "[H264D_TEST] Muti-thread test error."); - goto __FAILED; - } - } else { - ret = decoder_single_test(pctx); - if (ret != MPP_OK) { - H264D_TEST_LOG(H264D_TEST_TRACE, "[H264D_TEST] Single-thread test error."); - goto __FAILED; - } - } - ret = MPP_OK; - -__FAILED: - decoder_deinit(pctx); - h264d_free_frame_buffer(pInput); - if ((ret == MPP_OK) - && (H264D_TEST_FPGA & rkv_h264d_test_debug)) { - h264d_write_fpga_data(pInput); //!< for fpga debug - } - h264d_close_files(pInput); - MPP_FREE(pctx); - H264D_TEST_LOG(H264D_TEST_TRACE, "[H264D_TEST] decoder_deinit over."); - - return ret; -} - +/* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#define MODULE_TAG "h264d_test" + + +#if defined(_WIN32) +#include "vld.h" +#endif +#include + +#include "vpu_api.h" + +#include "h264d_log.h" +#include "mpp_env.h" +#include "mpp_dec.h" +#include "mpp_hal.h" +#include "mpp_mem.h" +#include "mpp_packet.h" +#include "mpp_packet_impl.h" +#include "mpp_buffer.h" +#include "mpp_buffer_impl.h" +#include "mpp_hal.h" + +#include "h264d_log.h" +#include "h264d_rwfile.h" +#include "h264d_api.h" +#include "hal_task.h" +#include "hal_h264d_api.h" +#include "mpp_thread.h" + +typedef enum { + HAL_THREAD_UNINITED, + HAL_THREAD_RUNNING, + HAL_THREAD_WAITING, + HAL_THREAD_STOPPING, +} HalStatus; + +typedef struct hal_thread_param_t { + HalStatus hal_status; + pthread_t halThread; + pthread_mutex_t parLock; + pthread_cond_t parCond; + pthread_mutex_t halLock; + pthread_cond_t halCond; +} HalThreadPar_t; + +typedef struct h264d_test_ctx_t { + MppDec m_api; + InputParams m_in; + HalTaskInfo m_task; + HalThreadPar_t m_hal; + MppBuffer m_dec_pkt_buf; + MppBuffer m_dec_pic_buf; + MppBufferGroup mFrameGroup; + MppBufferGroup mStreamGroup; +} H264dTestCtx_t; + +static MPP_RET manual_set_env(void) +{ +#if defined(_MSC_VER) + mpp_env_set_u32("h264d_log_help", 1); + mpp_env_set_u32("h264d_log_show", 1); + mpp_env_set_u32("h264d_log_ctrl", 0x800B); + mpp_env_set_u32("h264d_log_level", 5); + mpp_env_set_u32("h264d_log_decframe", 0); + mpp_env_set_u32("h264d_log_begframe", 0); + mpp_env_set_u32("h264d_log_endframe", 0); + mpp_env_set_u32("h264d_log_yuv", 0); + mpp_env_set_u32("h264d_chg_org", 0); //!< 0:VDPU 1: RKVDEC + mpp_env_set_str("h264d_log_outpath", "F:/h264_log/allegro_dat"); + mpp_env_set_str("h264d_log_cmppath", "F:/h264_log_driver/trunk_dat"); +#endif + return MPP_OK; +} + + +static MPP_RET decoder_deinit(H264dTestCtx_t *pctx) +{ + MppDec *pApi = &pctx->m_api; + + if (pApi->parser) { + parser_deinit(pApi->parser); + pApi->parser = NULL; + } + if (pApi->hal) { + mpp_hal_deinit(pApi->hal); + pApi->hal = NULL; + } + if (pApi->frame_slots) { + mpp_buf_slot_deinit(pApi->frame_slots); + pApi->frame_slots = NULL; + } + if (pApi->packet_slots) { + mpp_buf_slot_deinit(pApi->packet_slots); + pApi->packet_slots = NULL; + } + if (pctx->m_dec_pkt_buf) { + mpp_buffer_put(pctx->m_dec_pkt_buf); + } + if (pctx->m_dec_pic_buf) { + mpp_buffer_put(pctx->m_dec_pic_buf); + } + if (pctx->mFrameGroup != NULL) { + mpp_err("mFrameGroup deInit"); + mpp_buffer_group_put(pctx->mFrameGroup); + } + if (pctx->mStreamGroup != NULL) { + mpp_err("mStreamGroup deInit"); + mpp_buffer_group_put(pctx->mStreamGroup); + } + return MPP_OK; +} + +static MPP_RET decoder_init(H264dTestCtx_t *pctx) +{ + + MPP_RET ret = MPP_ERR_UNKNOW; + ParserCfg parser_cfg; + MppHalCfg hal_cfg; + MppDec *pApi = &pctx->m_api; + + manual_set_env(); // set env, in windows + + mpp_env_get_u32("rkv_h264d_test_debug", &rkv_h264d_test_debug, 0); + + if (pctx->mFrameGroup == NULL) { + ret = mpp_buffer_group_get_internal(&pctx->mFrameGroup, MPP_BUFFER_TYPE_ION); + if (MPP_OK != ret) { + mpp_err("h264d mpp_buffer_group_get failed\n"); + goto __FAILED; + } + } + if (pctx->mStreamGroup == NULL) { + ret = mpp_buffer_group_get_internal(&pctx->mStreamGroup, MPP_BUFFER_TYPE_ION); + if (MPP_OK != ret) { + mpp_err("h264d mpp_buffer_group_get failed\n"); + goto __FAILED; + } + } + // codec + pApi->coding = MPP_VIDEO_CodingAVC; + // malloc slot + FUN_CHECK(ret = mpp_buf_slot_init(&pApi->frame_slots)); + MEM_CHECK(ret, pApi->frame_slots); + ret = mpp_buf_slot_init(&pApi->packet_slots); + MEM_CHECK(ret, pApi->packet_slots); + mpp_buf_slot_setup(pApi->packet_slots, 2); + // init parser part + memset(&parser_cfg, 0, sizeof(parser_cfg)); + parser_cfg.coding = pApi->coding; + parser_cfg.frame_slots = pApi->frame_slots; + parser_cfg.packet_slots = pApi->packet_slots; + parser_cfg.task_count = 2; + FUN_CHECK(ret = parser_init(&pApi->parser, &parser_cfg)); + // init hal part + memset(&hal_cfg, 0, sizeof(hal_cfg)); + hal_cfg.type = MPP_CTX_DEC; + hal_cfg.coding = pApi->coding; + hal_cfg.work_mode = HAL_MODE_LIBVPU; + { + RK_U32 hal_device_id = 0; + mpp_env_get_u32("h264d_chg_org", &hal_device_id, 1); + if (hal_device_id == 1) { + hal_cfg.device_id = HAL_RKVDEC; + } else { + hal_cfg.device_id = HAL_VDPU; + } + } + hal_cfg.frame_slots = pApi->frame_slots; + hal_cfg.packet_slots = pApi->packet_slots; + hal_cfg.task_count = parser_cfg.task_count; + FUN_CHECK(ret = mpp_hal_init(&pApi->hal, &hal_cfg)); + pApi->tasks = hal_cfg.tasks; + + return MPP_OK; + +__FAILED: + decoder_deinit(pctx); + + return ret; +} + +static MPP_RET flush_decoded_frames(MppDec *pApi, FILE *fp) +{ + RK_S32 slot_idx = 0; + MppFrame out_frame = NULL; + + while (MPP_OK == mpp_buf_slot_dequeue(pApi->frame_slots, &slot_idx, QUEUE_DISPLAY)) { + mpp_buf_slot_get_prop(pApi->frame_slots, slot_idx, SLOT_FRAME, &out_frame); + if (out_frame) { + RK_U32 stride_w, stride_h; + void *ptr = NULL; + MppBuffer framebuf; + stride_w = mpp_frame_get_hor_stride(out_frame); + stride_h = mpp_frame_get_ver_stride(out_frame); + framebuf = mpp_frame_get_buffer(out_frame); + ptr = mpp_buffer_get_ptr(framebuf); + if ((rkv_h264d_test_debug & H264D_TEST_DUMPYUV) && fp) { + fwrite(ptr, 1, stride_w * stride_h * 3 / 2, fp); + fflush(fp); + } + mpp_frame_deinit(&out_frame); + out_frame = NULL; + } + mpp_buf_slot_clr_flag(pApi->frame_slots, slot_idx, SLOT_QUEUE_USE); + } + + return MPP_OK; +} + +static MPP_RET decoder_single_test(H264dTestCtx_t *pctx) +{ + MppPacket pkt = NULL; + RK_U32 end_of_flag = 0; + MPP_RET ret = MPP_ERR_UNKNOW; + + MppDec *pApi = &pctx->m_api; + InputParams *pIn = &pctx->m_in; + HalTaskInfo *task = &pctx->m_task; + //!< initial task + memset(task, 0, sizeof(HalTaskInfo)); + memset(task->dec.refer, -1, sizeof(task->dec.refer)); + task->dec.input = -1; + do { + //!< get one packet + if (pkt == NULL) { + if (pIn->is_eof || + (pIn->iDecFrmNum && (pIn->iFrmdecoded >= pIn->iDecFrmNum))) { + mpp_packet_init(&pkt, NULL, 0); + mpp_packet_set_eos(pkt); + } else { + FUN_CHECK(ret = h264d_read_one_frame(pIn)); + mpp_packet_init(&pkt, pIn->strm.pbuf, pIn->strm.strmbytes); + } + H264D_TEST_LOG(H264D_TEST_TRACE, "[H264D_TEST] ---- decoder, read_one_frame Frame_no = %d", pIn->iFrmdecoded); + pIn->iFrmdecoded++; + } + //!< prepare + FUN_CHECK(ret = parser_prepare(pApi->parser, pkt, &task->dec)); + + //!< parse + if (task->dec.valid) { + MppBufferImpl *buf = NULL; + + task->dec.valid = 0; + if (task->dec.input < 0) { + mpp_buf_slot_get_unused(pApi->packet_slots, &task->dec.input); + } + mpp_buf_slot_get_prop(pApi->packet_slots, task->dec.input, SLOT_BUFFER, &pctx->m_dec_pkt_buf); + if (NULL == pctx->m_dec_pkt_buf) { + size_t stream_size = mpp_packet_get_size(task->dec.input_packet); + mpp_buffer_get(pctx->mStreamGroup, &pctx->m_dec_pkt_buf, stream_size); + if (pctx->m_dec_pkt_buf) + mpp_buf_slot_set_prop(pApi->packet_slots, task->dec.input, SLOT_BUFFER, pctx->m_dec_pkt_buf); + } + buf = (MppBufferImpl *)pctx->m_dec_pkt_buf; + memcpy(buf->info.ptr, mpp_packet_get_data(task->dec.input_packet), mpp_packet_get_length(task->dec.input_packet)); + + mpp_buf_slot_set_flag(pApi->packet_slots, task->dec.input, SLOT_CODEC_READY); + mpp_buf_slot_set_flag(pApi->packet_slots, task->dec.input, SLOT_HAL_INPUT); + FUN_CHECK(ret = parser_parse(pApi->parser, &task->dec)); + } + //!< deinit packet + if (mpp_packet_get_length(pkt) == 0) { + if (mpp_packet_get_eos(pkt)) { + end_of_flag = 1; //!< end of stream + task->dec.valid = 0; + mpp_buf_slot_clr_flag(pApi->packet_slots, task->dec.input, SLOT_HAL_INPUT); + mpp_buf_slot_clr_flag(pApi->frame_slots, task->dec.output, SLOT_HAL_OUTPUT); + } + mpp_packet_deinit(&pkt); + pkt = NULL; + } + //!< run hal module + if (task->dec.valid) { + if (mpp_buf_slot_is_changed(pApi->frame_slots)) { + mpp_buf_slot_ready(pApi->frame_slots); + } + mpp_buf_slot_get_prop(pApi->frame_slots, task->dec.output, SLOT_BUFFER, &pctx->m_dec_pic_buf); + if (NULL == pctx->m_dec_pic_buf) { + RK_U32 size = (RK_U32)mpp_buf_slot_get_size(pApi->frame_slots); + mpp_buffer_get(pctx->mFrameGroup, &pctx->m_dec_pic_buf, size); + if (pctx->m_dec_pic_buf) + mpp_buf_slot_set_prop(pApi->frame_slots, task->dec.output, SLOT_BUFFER, pctx->m_dec_pic_buf); + } + FUN_CHECK(ret = mpp_hal_reg_gen(pApi->hal, task)); + + FUN_CHECK(ret = mpp_hal_hw_start(pApi->hal, task)); + FUN_CHECK(ret = mpp_hal_hw_wait(pApi->hal, task)); + if (pctx->m_dec_pkt_buf) { + mpp_buffer_put(pctx->m_dec_pkt_buf); + pctx->m_dec_pkt_buf = NULL; + } + mpp_buf_slot_clr_flag(pApi->packet_slots, task->dec.input, SLOT_HAL_INPUT); + mpp_buf_slot_clr_flag(pApi->frame_slots, task->dec.output, SLOT_HAL_OUTPUT); + //!< write frame out + flush_decoded_frames(pApi, pIn->fp_yuv_data); + //!< clear refrece flag + { + RK_U32 i = 0; + for (i = 0; i < MPP_ARRAY_ELEMS(task->dec.refer); i++) { + if (task->dec.refer[i] >= 0) { + mpp_buf_slot_clr_flag(pApi->frame_slots, task->dec.refer[i], SLOT_HAL_INPUT); + } + } + } + //!< reset task + memset(task, 0, sizeof(HalTaskInfo)); + memset(task->dec.refer, -1, sizeof(task->dec.refer)); + task->dec.input = -1; + + } + } while (!end_of_flag); + //!< flush dpb and send to display + FUN_CHECK(ret = mpp_dec_flush(pApi)); + flush_decoded_frames(pApi, pIn->fp_yuv_data); + + ret = MPP_OK; +__FAILED: + return ret; +} + +static void *hal_thread_run(void *in_ctx) +{ + H264dTestCtx_t *pctx = (H264dTestCtx_t *)in_ctx; + + MppDec *pApi = &pctx->m_api; + InputParams *pIn = &pctx->m_in; + HalTaskInfo *task = &pctx->m_task; + HalThreadPar_t *p_hal = &pctx->m_hal; + HalStatus hal_status = p_hal->hal_status; + + do { + //!< wait + { + pthread_mutex_lock(&p_hal->halLock); + H264D_TEST_LOG(H264D_TEST_TRACE, "[hal_thread] pthread_cond_wait(par_Cond)."); + pthread_cond_wait(&p_hal->parCond, &p_hal->halLock); + pthread_mutex_unlock(&p_hal->halLock); + } + //!< break + { + pthread_mutex_lock(&p_hal->halLock); + hal_status = p_hal->hal_status; + pthread_mutex_unlock(&p_hal->halLock); + } + H264D_TEST_LOG(H264D_TEST_TRACE, "[hal_thread] hal_status=%d.", hal_status); + if (hal_status == HAL_THREAD_STOPPING) { + H264D_TEST_LOG(H264D_TEST_TRACE, "[hal_thread] 2222222222."); + break; + } + //!< signal + { + pthread_mutex_lock(&p_hal->halLock); + mpp_hal_hw_wait(pctx->m_api.hal, &pctx->m_task); + //pthread_cond_signal(&p_hal->halCond); + H264D_TEST_LOG(H264D_TEST_TRACE, "[hal_thread] pthread_cond_signal(hal_Cond)."); + pthread_mutex_unlock(&p_hal->halLock); + } + { + if (pctx->m_dec_pkt_buf) { + mpp_buffer_put(pctx->m_dec_pkt_buf); + } + mpp_buf_slot_clr_flag(pApi->packet_slots, task->dec.input, SLOT_HAL_INPUT); + mpp_buf_slot_clr_flag(pApi->frame_slots, task->dec.output, SLOT_HAL_OUTPUT); + //!< write frame out + flush_decoded_frames(pApi, pIn->fp_yuv_data); + //!< clear refrece flag + { + RK_U32 i = 0; + for (i = 0; i < MPP_ARRAY_ELEMS(task->dec.refer); i++) { + if (task->dec.refer[i] >= 0) { + mpp_buf_slot_clr_flag(pApi->frame_slots, task->dec.refer[i], SLOT_HAL_INPUT); + } + } + } + //!< reset task + memset(task, 0, sizeof(HalTaskInfo)); + memset(task->dec.refer, -1, sizeof(task->dec.refer)); + task->dec.input = -1; + } + pthread_cond_signal(&p_hal->halCond); + + } while (hal_status != HAL_THREAD_STOPPING); + H264D_TEST_LOG(H264D_TEST_TRACE, "[hal_thread] 4444444444444444"); + + return NULL; +} + +static MPP_RET decoder_muti_deinit(H264dTestCtx_t *pctx) +{ + void *ptr = NULL; + HalThreadPar_t *p_hal = &pctx->m_hal; + + H264D_TEST_LOG(H264D_TEST_TRACE, "decoder_deinit In."); + pthread_join(p_hal->halThread, &ptr); + H264D_TEST_LOG(H264D_TEST_TRACE, "halThread(%p)destroy success", &p_hal->halThread); + + pthread_cond_destroy(&p_hal->parCond); + pthread_cond_destroy(&p_hal->halCond); + pthread_mutex_destroy(&p_hal->parLock); + pthread_mutex_destroy(&p_hal->halLock); + H264D_TEST_LOG(H264D_TEST_TRACE, "3333333333333"); + H264D_TEST_LOG(H264D_TEST_TRACE, "decoder_deinit Ok."); + + return MPP_OK; +} + +static MPP_RET decoder_muti_init(H264dTestCtx_t *pctx) +{ + HalThreadPar_t *p_hal = &pctx->m_hal; + + p_hal->hal_status = HAL_THREAD_RUNNING; + //!< create lock and condition + { + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&p_hal->parLock, &attr); + pthread_mutex_init(&p_hal->halLock, &attr); + pthread_mutexattr_destroy(&attr); + + pthread_cond_init(&p_hal->parCond, NULL); + pthread_cond_init(&p_hal->halCond, NULL); + H264D_TEST_LOG(H264D_TEST_TRACE, "mutex and condition create success."); + pthread_mutex_lock(&p_hal->halLock); + pthread_cond_signal(&p_hal->halCond); + H264D_TEST_LOG(H264D_TEST_TRACE, "pthread_cond_signal(hal_Cond)."); + pthread_mutex_unlock(&p_hal->halLock); + + } + //!< create hal thread + { + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); + if (0 == pthread_create(&p_hal->halThread, &attr, hal_thread_run, pctx)) { + H264D_TEST_LOG(H264D_TEST_TRACE, "hal_thread(%p) create success.", &p_hal->halThread); + } + pthread_attr_destroy(&attr); + } + return MPP_OK; +} + +static MPP_RET decoder_muti_test(H264dTestCtx_t *pctx) +{ + MppPacket pkt = NULL; + RK_U32 end_of_flag = 0; + MPP_RET ret = MPP_ERR_UNKNOW; + + MppDec *pApi = &pctx->m_api; + InputParams *pIn = &pctx->m_in; + HalTaskInfo *task = &pctx->m_task; + //!< init decoder + FUN_CHECK(ret = decoder_muti_init(pctx)); + //!< initial task + memset(task, 0, sizeof(HalTaskInfo)); + memset(task->dec.refer, -1, sizeof(task->dec.refer)); + task->dec.input = -1; + do { + //!< get one packet + if (pkt == NULL) { + if (pIn->is_eof || + (pIn->iDecFrmNum && (pIn->iFrmdecoded >= pIn->iDecFrmNum))) { + mpp_packet_init(&pkt, NULL, 0); + mpp_packet_set_eos(pkt); + } else { + FUN_CHECK(ret = h264d_read_one_frame(pIn)); + mpp_packet_init(&pkt, pIn->strm.pbuf, pIn->strm.strmbytes); + } + H264D_TEST_LOG(H264D_TEST_TRACE, "[H264D_TEST] ---- decoder, read_one_frame Frame_no = %d", pIn->iFrmdecoded); + pIn->iFrmdecoded++; + } + //!< prepare + FUN_CHECK(ret = parser_prepare(pApi->parser, pkt, &task->dec)); + { + HalThreadPar_t *p_hal = &pctx->m_hal; + pthread_mutex_lock(&p_hal->parLock); + H264D_TEST_LOG(H264D_TEST_TRACE, "pthread_cond_wait(hal Cond)."); + pthread_cond_wait(&p_hal->halCond, &p_hal->parLock); + pthread_mutex_unlock(&p_hal->parLock); + } + //!< parse + if (task->dec.valid) { + MppBufferImpl *buf = NULL; + + task->dec.valid = 0; + if (task->dec.input < 0) { + mpp_buf_slot_get_unused(pApi->packet_slots, &task->dec.input); + } + + mpp_buf_slot_get_prop(pApi->packet_slots, task->dec.input, SLOT_BUFFER, &pctx->m_dec_pkt_buf); + if (NULL == pctx->m_dec_pkt_buf) { + size_t stream_size = mpp_packet_get_size(task->dec.input_packet); + mpp_buffer_get(pctx->mStreamGroup, &pctx->m_dec_pkt_buf, stream_size); + if (pctx->m_dec_pkt_buf) + mpp_buf_slot_set_prop(pApi->packet_slots, task->dec.input, SLOT_BUFFER, pctx->m_dec_pkt_buf); + } + buf = (MppBufferImpl *)pctx->m_dec_pkt_buf; + memcpy(buf->info.ptr, mpp_packet_get_data(task->dec.input_packet), mpp_packet_get_length(task->dec.input_packet)); + + mpp_buf_slot_set_flag(pApi->packet_slots, task->dec.input, SLOT_CODEC_READY); + mpp_buf_slot_set_flag(pApi->packet_slots, task->dec.input, SLOT_HAL_INPUT); + FUN_CHECK(ret = parser_parse(pApi->parser, &task->dec)); + } + //!< deinit packet + if (mpp_packet_get_length(pkt) == 0) { + if (mpp_packet_get_eos(pkt)) { + end_of_flag = 1; //!< end of stream + task->dec.valid = 0; + { + HalThreadPar_t *p_hal = &pctx->m_hal; + pthread_mutex_lock(&p_hal->parLock); + p_hal->hal_status = HAL_THREAD_STOPPING; + pthread_cond_signal(&p_hal->parCond); + H264D_TEST_LOG(H264D_TEST_TRACE, "1111111111111111"); + pthread_mutex_unlock(&p_hal->parLock); + } + + mpp_buf_slot_clr_flag(pApi->packet_slots, task->dec.input, SLOT_HAL_INPUT); + mpp_buf_slot_clr_flag(pApi->frame_slots, task->dec.output, SLOT_HAL_OUTPUT); + } + mpp_packet_deinit(&pkt); + pkt = NULL; + } + //!< run hal module + if (task->dec.valid) { + if (mpp_buf_slot_is_changed(pApi->frame_slots)) { + mpp_buf_slot_ready(pApi->frame_slots); + } + mpp_buf_slot_get_prop(pApi->frame_slots, task->dec.output, SLOT_BUFFER, &pctx->m_dec_pic_buf); + if (NULL == pctx->m_dec_pic_buf) { + RK_U32 size = (RK_U32)mpp_buf_slot_get_size(pApi->frame_slots); + mpp_buffer_get(pctx->mFrameGroup, &pctx->m_dec_pic_buf, size); + if (pctx->m_dec_pic_buf) + mpp_buf_slot_set_prop(pApi->frame_slots, task->dec.output, SLOT_BUFFER, pctx->m_dec_pic_buf); + } + FUN_CHECK(ret = mpp_hal_reg_gen(pApi->hal, task)); + + FUN_CHECK(ret = mpp_hal_hw_start(pApi->hal, task)); + { + HalThreadPar_t *p_hal = &pctx->m_hal; + + pthread_mutex_lock(&p_hal->parLock); + pthread_cond_signal(&p_hal->parCond); + H264D_TEST_LOG(H264D_TEST_TRACE, "pthread_cond_single(par Cond)."); + pthread_mutex_unlock(&p_hal->parLock); + } + } + } while (!end_of_flag); + //!< flush dpb and send to display + FUN_CHECK(ret = mpp_dec_flush(pApi)); + flush_decoded_frames(pApi, pIn->fp_yuv_data); + + ret = MPP_OK; +__FAILED: + decoder_muti_deinit(pctx); + + return ret; +} + + +int main(int argc, char **argv) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + InputParams *pInput = NULL; + H264dTestCtx_t *pctx = NULL; + + MEM_CHECK(ret, pctx = mpp_calloc(H264dTestCtx_t, 1)); + // prepare + pInput = &pctx->m_in; + FUN_CHECK(ret = h264d_configure(pInput, argc, argv)); + FUN_CHECK(ret = h264d_open_files(pInput)); + FUN_CHECK(ret = h264d_alloc_frame_buffer(pInput)); + // init + decoder_init(pctx); + // decode + if (rkv_h264d_test_debug & H264D_TEST_MUTI_THREAD) { + ret = decoder_muti_test(pctx); + if (ret != MPP_OK) { + H264D_TEST_LOG(H264D_TEST_TRACE, "[H264D_TEST] Muti-thread test error."); + goto __FAILED; + } + } else { + ret = decoder_single_test(pctx); + if (ret != MPP_OK) { + H264D_TEST_LOG(H264D_TEST_TRACE, "[H264D_TEST] Single-thread test error."); + goto __FAILED; + } + } + ret = MPP_OK; + +__FAILED: + decoder_deinit(pctx); + h264d_free_frame_buffer(pInput); + if ((ret == MPP_OK) + && (H264D_TEST_FPGA & rkv_h264d_test_debug)) { + h264d_write_fpga_data(pInput); //!< for fpga debug + } + h264d_close_files(pInput); + MPP_FREE(pctx); + H264D_TEST_LOG(H264D_TEST_TRACE, "[H264D_TEST] decoder_deinit over."); + + return ret; +} + diff --git a/mpp/test/mpp_info_test.c b/mpp/test/mpp_info_test.c index aa51784f..d26205da 100644 --- a/mpp/test/mpp_info_test.c +++ b/mpp/test/mpp_info_test.c @@ -1,32 +1,32 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define MODULE_TAG "mpp_info_test" - -#include "mpp_log.h" -#include "mpp_info.h" - -int main() -{ - mpp_log("mpp revision is %d\n", mpp_info_get_revision()); - mpp_log("mpp info all:\n%s\n", mpp_info_get(INFO_ALL)); - mpp_log("mpp info revision: %s\n", mpp_info_get(INFO_REVISION)); - mpp_log("mpp info date : %s\n", mpp_info_get(INFO_DATE)); - mpp_log("mpp info author : %s\n", mpp_info_get(INFO_AUTHOR)); - - return 0; -} - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define MODULE_TAG "mpp_info_test" + +#include "mpp_log.h" +#include "mpp_info.h" + +int main() +{ + mpp_log("mpp revision is %d\n", mpp_info_get_revision()); + mpp_log("mpp info all:\n%s\n", mpp_info_get(INFO_ALL)); + mpp_log("mpp info revision: %s\n", mpp_info_get(INFO_REVISION)); + mpp_log("mpp info date : %s\n", mpp_info_get(INFO_DATE)); + mpp_log("mpp info author : %s\n", mpp_info_get(INFO_AUTHOR)); + + return 0; +} + diff --git a/mpp/test/vp9d_test.c b/mpp/test/vp9d_test.c index 16abfb87..ad599f30 100644 --- a/mpp/test/vp9d_test.c +++ b/mpp/test/vp9d_test.c @@ -1,145 +1,145 @@ -/* -* Copyright 2015 Rockchip Electronics Co. LTD -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#define MODULE_TAG "vp9d_test" - - -#if defined(_WIN32) -#include "vld.h" -#endif -#include -#include "mpp_log.h" -#include "mpp_env.h" -#include "mpp_dec.h" -#include "mpp_hal.h" -#include "mpp_mem.h" -#include "mpp_packet.h" -#include "mpp_packet_impl.h" -#include "mpp_hal.h" - -#include "vp9d_api.h" -#include "hal_vp9d_api.h" - - - -//!< memory malloc check -#define MEM_CHECK(ret, val, ...)\ - do{ if(!(val)) {\ - ret = MPP_ERR_MALLOC;\ - mpp_log("Function:%s:%d, ERROR: malloc buffer.\n", __FUNCTION__, __LINE__);\ - mpp_assert(0); goto __FAILED;\ - } } while (0) -//!< function return check -#define FUN_CHECK(val)\ - do{ if((val) < 0) {\ - goto __FAILED;\ - } } while (0) - - -static MPP_RET vp9_decoder_deinit(MppDec *pApi) -{ - if (pApi->frame_slots) { - mpp_buf_slot_deinit(pApi->frame_slots); - pApi->frame_slots = NULL; - } - if (pApi->parser) { - parser_deinit(pApi->parser); - pApi->parser = NULL; - } - if (pApi->hal) { - mpp_hal_deinit(pApi->hal); - pApi->hal = NULL; - } - - return MPP_OK; -} - -static MPP_RET vp9_decoder_init(MppDec *pApi) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - ParserCfg parser_cfg; - MppHalCfg hal_cfg; - - pApi->coding = MPP_VIDEO_CodingVP9; - // malloc slot - FUN_CHECK(ret = mpp_buf_slot_init(&pApi->frame_slots)); - MEM_CHECK(ret, pApi->frame_slots); - // init parser part - memset(&parser_cfg, 0, sizeof(parser_cfg)); - parser_cfg.coding = pApi->coding; - parser_cfg.frame_slots = pApi->frame_slots; - parser_cfg.packet_slots = pApi->packet_slots; - FUN_CHECK(ret = parser_init(&pApi->parser, &parser_cfg)); - - // init hal part - memset(&hal_cfg, 0, sizeof(hal_cfg)); - hal_cfg.type = MPP_CTX_DEC; - hal_cfg.coding = pApi->coding; - hal_cfg.work_mode = HAL_MODE_LIBVPU; - hal_cfg.device_id = HAL_RKVDEC; - hal_cfg.frame_slots = pApi->frame_slots; - hal_cfg.packet_slots = pApi->packet_slots; - hal_cfg.task_count = parser_cfg.task_count; - FUN_CHECK(ret = mpp_hal_init(&pApi->hal, &hal_cfg)); - pApi->tasks = hal_cfg.tasks; - - return MPP_OK; -__FAILED: - vp9_decoder_deinit(pApi); - - return ret; -} - - - -int main(int argc, char **argv) -{ - MPP_RET ret = MPP_ERR_UNKNOW; - MppPacket pkt = NULL; - MppDec *pApi = mpp_calloc(MppDec, 1); - HalTaskInfo *task = mpp_calloc_size(HalTaskInfo, sizeof(HalTaskInfo)); - mpp_log("+++++++ all test begin +++++++ \n"); - //!< init decoder - FUN_CHECK(ret = vp9_decoder_init(pApi)); - //!< initial packet - mpp_packet_init(&pkt, NULL, 0); - //!< initial task - memset(task, 0, sizeof(HalTaskInfo)); - memset(task->dec.refer, -1, sizeof(task->dec.refer)); - //!< prepare - FUN_CHECK(ret = parser_prepare(pApi->parser, pkt, &task->dec)); - //!< free packet - mpp_packet_deinit(&pkt); - //!< parse - FUN_CHECK(ret = parser_parse(pApi->parser, &task->dec)); - //!< hal module - FUN_CHECK(ret = mpp_hal_reg_gen(pApi->hal, task)); - FUN_CHECK(ret = mpp_hal_hw_start(pApi->hal, task)); - FUN_CHECK(ret = mpp_hal_hw_wait(pApi->hal, task)); - - (void)argv; - (void)argc; - - mpp_log("+++++++ all test end +++++++ \n"); - ret = MPP_OK; -__FAILED: - vp9_decoder_deinit(pApi); - MPP_FREE(pApi); - MPP_FREE(task); - - return ret; -} - +/* +* Copyright 2015 Rockchip Electronics Co. LTD +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#define MODULE_TAG "vp9d_test" + + +#if defined(_WIN32) +#include "vld.h" +#endif +#include +#include "mpp_log.h" +#include "mpp_env.h" +#include "mpp_dec.h" +#include "mpp_hal.h" +#include "mpp_mem.h" +#include "mpp_packet.h" +#include "mpp_packet_impl.h" +#include "mpp_hal.h" + +#include "vp9d_api.h" +#include "hal_vp9d_api.h" + + + +//!< memory malloc check +#define MEM_CHECK(ret, val, ...)\ + do{ if(!(val)) {\ + ret = MPP_ERR_MALLOC;\ + mpp_log("Function:%s:%d, ERROR: malloc buffer.\n", __FUNCTION__, __LINE__);\ + mpp_assert(0); goto __FAILED;\ + } } while (0) +//!< function return check +#define FUN_CHECK(val)\ + do{ if((val) < 0) {\ + goto __FAILED;\ + } } while (0) + + +static MPP_RET vp9_decoder_deinit(MppDec *pApi) +{ + if (pApi->frame_slots) { + mpp_buf_slot_deinit(pApi->frame_slots); + pApi->frame_slots = NULL; + } + if (pApi->parser) { + parser_deinit(pApi->parser); + pApi->parser = NULL; + } + if (pApi->hal) { + mpp_hal_deinit(pApi->hal); + pApi->hal = NULL; + } + + return MPP_OK; +} + +static MPP_RET vp9_decoder_init(MppDec *pApi) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + ParserCfg parser_cfg; + MppHalCfg hal_cfg; + + pApi->coding = MPP_VIDEO_CodingVP9; + // malloc slot + FUN_CHECK(ret = mpp_buf_slot_init(&pApi->frame_slots)); + MEM_CHECK(ret, pApi->frame_slots); + // init parser part + memset(&parser_cfg, 0, sizeof(parser_cfg)); + parser_cfg.coding = pApi->coding; + parser_cfg.frame_slots = pApi->frame_slots; + parser_cfg.packet_slots = pApi->packet_slots; + FUN_CHECK(ret = parser_init(&pApi->parser, &parser_cfg)); + + // init hal part + memset(&hal_cfg, 0, sizeof(hal_cfg)); + hal_cfg.type = MPP_CTX_DEC; + hal_cfg.coding = pApi->coding; + hal_cfg.work_mode = HAL_MODE_LIBVPU; + hal_cfg.device_id = HAL_RKVDEC; + hal_cfg.frame_slots = pApi->frame_slots; + hal_cfg.packet_slots = pApi->packet_slots; + hal_cfg.task_count = parser_cfg.task_count; + FUN_CHECK(ret = mpp_hal_init(&pApi->hal, &hal_cfg)); + pApi->tasks = hal_cfg.tasks; + + return MPP_OK; +__FAILED: + vp9_decoder_deinit(pApi); + + return ret; +} + + + +int main(int argc, char **argv) +{ + MPP_RET ret = MPP_ERR_UNKNOW; + MppPacket pkt = NULL; + MppDec *pApi = mpp_calloc(MppDec, 1); + HalTaskInfo *task = mpp_calloc_size(HalTaskInfo, sizeof(HalTaskInfo)); + mpp_log("+++++++ all test begin +++++++ \n"); + //!< init decoder + FUN_CHECK(ret = vp9_decoder_init(pApi)); + //!< initial packet + mpp_packet_init(&pkt, NULL, 0); + //!< initial task + memset(task, 0, sizeof(HalTaskInfo)); + memset(task->dec.refer, -1, sizeof(task->dec.refer)); + //!< prepare + FUN_CHECK(ret = parser_prepare(pApi->parser, pkt, &task->dec)); + //!< free packet + mpp_packet_deinit(&pkt); + //!< parse + FUN_CHECK(ret = parser_parse(pApi->parser, &task->dec)); + //!< hal module + FUN_CHECK(ret = mpp_hal_reg_gen(pApi->hal, task)); + FUN_CHECK(ret = mpp_hal_hw_start(pApi->hal, task)); + FUN_CHECK(ret = mpp_hal_hw_wait(pApi->hal, task)); + + (void)argv; + (void)argc; + + mpp_log("+++++++ all test end +++++++ \n"); + ret = MPP_OK; +__FAILED: + vp9_decoder_deinit(pApi); + MPP_FREE(pApi); + MPP_FREE(task); + + return ret; +} + diff --git a/osal/allocator/allocator_drm.h b/osal/allocator/allocator_drm.h index 29e4bc10..2493c46c 100644 --- a/osal/allocator/allocator_drm.h +++ b/osal/allocator/allocator_drm.h @@ -1,19 +1,19 @@ -/* - * Copyright 2010 Rockchip Electronics S.LSI Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "os_allocator.h" - -extern os_allocator allocator_drm; +/* + * Copyright 2010 Rockchip Electronics S.LSI Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "os_allocator.h" + +extern os_allocator allocator_drm; diff --git a/osal/allocator/allocator_ion.c b/osal/allocator/allocator_ion.c index bb59cff1..4e248df2 100644 --- a/osal/allocator/allocator_ion.c +++ b/osal/allocator/allocator_ion.c @@ -1,435 +1,435 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define MODULE_TAG "mpp_ion" - -#include -#include -#include -#include -#include -#include - -#if defined(ARMLINUX) -#include -#elif defined(ANDROID) -#include -#else -#include "ion.h" -#endif - -#include "os_mem.h" -#include "allocator_ion.h" - -#include "mpp_env.h" -#include "mpp_mem.h" -#include "mpp_log.h" -#include "mpp_common.h" - -static RK_U32 ion_debug = 0; - -#define ION_FUNCTION (0x00000001) -#define ION_DEVICE (0x00000002) -#define ION_CLINET (0x00000004) -#define ION_IOCTL (0x00000008) - -#define ION_DETECT_IOMMU_DISABLE (0x0) /* use ION_HEAP_TYPE_DMA */ -#define ION_DETECT_IOMMU_ENABLE (0x1) /* use ION_HEAP_TYPE_SYSTEM */ -#define ION_DETECT_NO_DTS (0x2) /* use ION_HEAP_TYPE_CARVEOUT */ - -#define ion_dbg(flag, fmt, ...) _mpp_dbg(ion_debug, flag, fmt, ## __VA_ARGS__) -#define ion_dbg_f(flag, fmt, ...) _mpp_dbg_f(ion_debug, flag, fmt, ## __VA_ARGS__) -#define ion_dbg_func(fmt, ...) ion_dbg_f(ION_FUNCTION, fmt, ## __VA_ARGS__) - -static int ion_ioctl(int fd, int req, void *arg) -{ - int ret = ioctl(fd, req, arg); - if (ret < 0) { - mpp_err("ion_ioctl %x failed with code %d: %s\n", req, - ret, strerror(errno)); - return -errno; - } - return ret; -} - -static int ion_alloc(int fd, size_t len, size_t align, unsigned int heap_mask, - unsigned int flags, ion_user_handle_t *handle) -{ - int ret = -EINVAL; - struct ion_allocation_data data = { - .len = len, - .align = align, - .heap_id_mask = heap_mask, - .flags = flags, - }; - - ion_dbg_func("enter: fd %d len %d align %d heap_mask %x flags %x", - fd, len, align, heap_mask, flags); - - if (handle) { - ret = ion_ioctl(fd, ION_IOC_ALLOC, &data); - if (ret >= 0) - *handle = data.handle; - } - - ion_dbg_func("leave: ret %d\n", ret); - - return ret; -} - -static int ion_free(int fd, ion_user_handle_t handle) -{ - int ret; - struct ion_handle_data data = { - .handle = handle, - }; - - ion_dbg_func("enter: fd %d\n", fd); - ret = ion_ioctl(fd, ION_IOC_FREE, &data); - ion_dbg_func("leave: ret %d\n", ret); - return ret; -} - -static int ion_map(int fd, ion_user_handle_t handle, size_t length, int prot, - int flags, off_t offset, unsigned char **ptr, int *map_fd) -{ - int ret; - struct ion_fd_data data = { - .handle = handle, - }; - - if (map_fd == NULL) - return -EINVAL; - if (ptr == NULL) - return -EINVAL; - - ret = ion_ioctl(fd, ION_IOC_MAP, &data); - if (ret < 0) - return ret; - *map_fd = data.fd; - if (*map_fd < 0) { - mpp_err("map ioctl returned negative fd\n"); - return -EINVAL; - } - *ptr = mmap(NULL, length, prot, flags, *map_fd, offset); - if (*ptr == MAP_FAILED) { - mpp_err("mmap failed: %s\n", strerror(errno)); - return -errno; - } - return ret; -} - -#include - -static const char *search_name = NULL; - -static int _compare_name(const struct dirent *dir) -{ - if (search_name && strstr(dir->d_name, search_name)) - return 1; - - return 0; -} - -/* - * directory search function: - * search directory with dir_name on path. - * if found match dir append name on path and return - * - * return 0 for failure - * return positive value for length of new path - */ -static RK_S32 find_dir_in_path(char *path, const char *dir_name, size_t max_length) -{ - struct dirent **dir; - RK_S32 path_len = strnlen(path, max_length); - RK_S32 new_path_len = 0; - RK_S32 n; - - search_name = dir_name; - n = scandir(path, &dir, _compare_name, alphasort); - if (n <= 0) { - mpp_err("scan %s for %s return %d\n", path, dir_name, n); - } else { - mpp_assert(n == 1); - - new_path_len = path_len; - new_path_len += snprintf(path + path_len, max_length - path_len - 1, - "/%s", dir[0]->d_name); - free(dir[0]); - free(dir); - } - search_name = NULL; - return new_path_len; -} - -RK_S32 check_sysfs_iommu() -{ - RK_U32 i = 0; - RK_U32 dts_info_found = 0; - RK_U32 ion_info_found = 0; - RK_S32 ret = ION_DETECT_IOMMU_DISABLE; - char path[256]; - static char *dts_devices[] = { - "vpu_service", - "hevc_service", - "rkvdec", - "rkvenc", - }; - static char *system_heaps[] = { - "vmalloc", - "system-heap", - }; - - mpp_env_get_u32("ion_debug", &ion_debug, 0); -#ifdef SOFIA_3GR_LINUX - return ret; -#endif - - for (i = 0; i < MPP_ARRAY_ELEMS(dts_devices); i++) { - snprintf(path, sizeof(path), "/proc/device-tree"); - if (find_dir_in_path(path, dts_devices[i], sizeof(path))) { - if (find_dir_in_path(path, "iommu_enabled", sizeof(path))) { - FILE *iommu_fp = fopen(path, "rb"); - - if (iommu_fp) { - RK_U32 iommu_enabled = 0; - fread(&iommu_enabled, sizeof(RK_U32), 1, iommu_fp); - mpp_log("%s iommu_enabled %d\n", dts_devices[i], (iommu_enabled > 0)); - fclose(iommu_fp); - if (iommu_enabled) - ret = ION_DETECT_IOMMU_ENABLE; - } - dts_info_found = 1; - break; - } - } - } - - if (!dts_info_found) { - for (i = 0; i < MPP_ARRAY_ELEMS(system_heaps); i++) { - snprintf(path, sizeof(path), "/sys/kernel/debug/ion/heaps"); - if (find_dir_in_path(path, system_heaps[i], sizeof(path))) { - mpp_log("%s found\n", system_heaps[i]); - ret = ION_DETECT_IOMMU_ENABLE; - ion_info_found = 1; - break; - } - } - } - - if (!dts_info_found && !ion_info_found) { - mpp_err("can not find any hint from all possible devices\n"); - ret = ION_DETECT_NO_DTS; - } - - return ret; -} - -typedef struct { - RK_U32 alignment; - RK_S32 ion_device; -} allocator_ctx_ion; - -#define VPU_IOC_MAGIC 'l' -#define VPU_IOC_PROBE_IOMMU_STATUS _IOR(VPU_IOC_MAGIC, 5, unsigned long) -#define VPU_IOC_PROBE_HEAP_STATUS _IOR(VPU_IOC_MAGIC, 6, unsigned long) -const char *dev_ion = "/dev/ion"; -static RK_S32 ion_heap_id = -1; -static RK_U32 ion_heap_mask = ION_HEAP_SYSTEM_MASK; - -MPP_RET os_allocator_ion_open(void **ctx, size_t alignment) -{ - RK_S32 fd; - allocator_ctx_ion *p; - - if (NULL == ctx) { - mpp_err("os_allocator_open Android do not accept NULL input\n"); - return MPP_ERR_NULL_PTR; - } - - *ctx = NULL; - - fd = open(dev_ion, O_RDWR); - if (fd < 0) { - mpp_err("open %s failed!\n", dev_ion); - return MPP_ERR_UNKNOW; - } - - ion_dbg(ION_DEVICE, "open ion dev fd %d\n", fd); - - p = mpp_malloc(allocator_ctx_ion, 1); - if (NULL == p) { - close(fd); - mpp_err("os_allocator_open Android failed to allocate context\n"); - return MPP_ERR_MALLOC; - } else { - /* - * do heap id detection here: - * if there is no vpu_service use default ION_HEAP_TYPE_SYSTEM_CONTIG - * if there is vpu_service then check the iommu_enable status - */ - if (ion_heap_id < 0) { - int detect_result = check_sysfs_iommu(); - const char *heap_name = NULL; - - switch (detect_result) { - case ION_DETECT_IOMMU_DISABLE : { - ion_heap_mask = (1 << ION_HEAP_TYPE_DMA); - ion_heap_id = ION_HEAP_TYPE_DMA; - heap_name = "ION_HEAP_TYPE_DMA"; - } break; - case ION_DETECT_IOMMU_ENABLE : { - ion_heap_mask = (1 << ION_HEAP_TYPE_SYSTEM); - ion_heap_id = ION_HEAP_TYPE_SYSTEM; - heap_name = "ION_HEAP_TYPE_SYSTEM"; - } break; - case ION_DETECT_NO_DTS : { - ion_heap_mask = (1 << ION_HEAP_TYPE_CARVEOUT); - ion_heap_id = ION_HEAP_TYPE_CARVEOUT; - heap_name = "ION_HEAP_TYPE_CARVEOUT"; - } break; - default : { - mpp_err("invalid detect result %d\n", detect_result); - ion_heap_mask = (1 << ION_HEAP_TYPE_DMA); - ion_heap_id = ION_HEAP_TYPE_DMA; - heap_name = "ION_HEAP_TYPE_DMA"; - } break; - } - mpp_log("using ion heap %s\n", heap_name); - } - p->alignment = alignment; - p->ion_device = fd; - *ctx = p; - } - - return MPP_OK; -} - -MPP_RET os_allocator_ion_alloc(void *ctx, MppBufferInfo *info) -{ - MPP_RET ret = MPP_OK; - allocator_ctx_ion *p = NULL; - - if (NULL == ctx) { - mpp_err("os_allocator_close Android do not accept NULL input\n"); - return MPP_ERR_NULL_PTR; - } - - ion_dbg_func("enter: ctx %p size %d\n", ctx, info->size); - - p = (allocator_ctx_ion *)ctx; - ret = ion_alloc(p->ion_device, info->size, p->alignment, - ion_heap_mask, 0, - (ion_user_handle_t *)&info->hnd); - if (ret) { - mpp_err("os_allocator_ion_alloc ion_alloc failed ret %d\n", ret); - return ret; - } - ret = ion_map(p->ion_device, (ion_user_handle_t)((intptr_t)info->hnd), info->size, - PROT_READ | PROT_WRITE, MAP_SHARED, (off_t)0, - (unsigned char**)&info->ptr, &info->fd); - if (ret) { - mpp_err("os_allocator_ion_alloc ion_map failed ret %d\n", ret); - } - - ion_dbg_func("leave: ret %d\n", ret); - return ret; -} - -MPP_RET os_allocator_ion_import(void *ctx, MppBufferInfo *data) -{ - MPP_RET ret = MPP_OK; - (void)ctx; - // NOTE: do not use the original buffer fd, - // use dup fd to avoid unexpected external fd close - ion_dbg_func("enter: ctx %p fd %d size %d\n", ctx, data->fd, data->size); - - data->fd = dup(data->fd); - data->ptr = mmap(NULL, data->size, PROT_READ | PROT_WRITE, MAP_SHARED, data->fd, 0); - if (data->ptr == MAP_FAILED) { - mpp_err_f("map error %s\n", strerror(errno)); - ret = MPP_NOK; - close(data->fd); - data->fd = -1; - data->ptr = NULL; - } - ion_dbg_func("leave: ret %d\n", ret); - return ret; -} - -MPP_RET os_allocator_ion_release(void *ctx, MppBufferInfo *data) -{ - ion_dbg_func("enter: ctx %p fd %d ptr %p size %d\n", ctx, data->fd, data->ptr, data->size); - - munmap(data->ptr, data->size); - close(data->fd); - - ion_dbg_func("leave\n"); - return MPP_OK; -} - -MPP_RET os_allocator_ion_free(void *ctx, MppBufferInfo *data) -{ - allocator_ctx_ion *p = NULL; - if (NULL == ctx) { - mpp_err("os_allocator_close Android do not accept NULL input\n"); - return MPP_ERR_NULL_PTR; - } - - ion_dbg_func("enter: ctx %p fd %d ptr %p size %d\n", ctx, data->fd, data->ptr, data->size); - - p = (allocator_ctx_ion *)ctx; - munmap(data->ptr, data->size); - close(data->fd); - ion_free(p->ion_device, (ion_user_handle_t)((intptr_t)data->hnd)); - - ion_dbg_func("leave\n"); - return MPP_OK; -} - -MPP_RET os_allocator_ion_close(void *ctx) -{ - int ret; - allocator_ctx_ion *p; - - if (NULL == ctx) { - mpp_err("os_allocator_close Android do not accept NULL input\n"); - return MPP_ERR_NULL_PTR; - } - - ion_dbg_func("enter: ctx\n", ctx); - - p = (allocator_ctx_ion *)ctx; - ret = close(p->ion_device); - mpp_free(p); - if (ret < 0) - ret = (MPP_RET) - errno; - - ion_dbg_func("leave: ret %d\n", ret); - - return ret; -} - -os_allocator allocator_ion = { - os_allocator_ion_open, - os_allocator_ion_alloc, - os_allocator_ion_free, - os_allocator_ion_import, - os_allocator_ion_release, - os_allocator_ion_close, -}; - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define MODULE_TAG "mpp_ion" + +#include +#include +#include +#include +#include +#include + +#if defined(ARMLINUX) +#include +#elif defined(ANDROID) +#include +#else +#include "ion.h" +#endif + +#include "os_mem.h" +#include "allocator_ion.h" + +#include "mpp_env.h" +#include "mpp_mem.h" +#include "mpp_log.h" +#include "mpp_common.h" + +static RK_U32 ion_debug = 0; + +#define ION_FUNCTION (0x00000001) +#define ION_DEVICE (0x00000002) +#define ION_CLINET (0x00000004) +#define ION_IOCTL (0x00000008) + +#define ION_DETECT_IOMMU_DISABLE (0x0) /* use ION_HEAP_TYPE_DMA */ +#define ION_DETECT_IOMMU_ENABLE (0x1) /* use ION_HEAP_TYPE_SYSTEM */ +#define ION_DETECT_NO_DTS (0x2) /* use ION_HEAP_TYPE_CARVEOUT */ + +#define ion_dbg(flag, fmt, ...) _mpp_dbg(ion_debug, flag, fmt, ## __VA_ARGS__) +#define ion_dbg_f(flag, fmt, ...) _mpp_dbg_f(ion_debug, flag, fmt, ## __VA_ARGS__) +#define ion_dbg_func(fmt, ...) ion_dbg_f(ION_FUNCTION, fmt, ## __VA_ARGS__) + +static int ion_ioctl(int fd, int req, void *arg) +{ + int ret = ioctl(fd, req, arg); + if (ret < 0) { + mpp_err("ion_ioctl %x failed with code %d: %s\n", req, + ret, strerror(errno)); + return -errno; + } + return ret; +} + +static int ion_alloc(int fd, size_t len, size_t align, unsigned int heap_mask, + unsigned int flags, ion_user_handle_t *handle) +{ + int ret = -EINVAL; + struct ion_allocation_data data = { + .len = len, + .align = align, + .heap_id_mask = heap_mask, + .flags = flags, + }; + + ion_dbg_func("enter: fd %d len %d align %d heap_mask %x flags %x", + fd, len, align, heap_mask, flags); + + if (handle) { + ret = ion_ioctl(fd, ION_IOC_ALLOC, &data); + if (ret >= 0) + *handle = data.handle; + } + + ion_dbg_func("leave: ret %d\n", ret); + + return ret; +} + +static int ion_free(int fd, ion_user_handle_t handle) +{ + int ret; + struct ion_handle_data data = { + .handle = handle, + }; + + ion_dbg_func("enter: fd %d\n", fd); + ret = ion_ioctl(fd, ION_IOC_FREE, &data); + ion_dbg_func("leave: ret %d\n", ret); + return ret; +} + +static int ion_map(int fd, ion_user_handle_t handle, size_t length, int prot, + int flags, off_t offset, unsigned char **ptr, int *map_fd) +{ + int ret; + struct ion_fd_data data = { + .handle = handle, + }; + + if (map_fd == NULL) + return -EINVAL; + if (ptr == NULL) + return -EINVAL; + + ret = ion_ioctl(fd, ION_IOC_MAP, &data); + if (ret < 0) + return ret; + *map_fd = data.fd; + if (*map_fd < 0) { + mpp_err("map ioctl returned negative fd\n"); + return -EINVAL; + } + *ptr = mmap(NULL, length, prot, flags, *map_fd, offset); + if (*ptr == MAP_FAILED) { + mpp_err("mmap failed: %s\n", strerror(errno)); + return -errno; + } + return ret; +} + +#include + +static const char *search_name = NULL; + +static int _compare_name(const struct dirent *dir) +{ + if (search_name && strstr(dir->d_name, search_name)) + return 1; + + return 0; +} + +/* + * directory search function: + * search directory with dir_name on path. + * if found match dir append name on path and return + * + * return 0 for failure + * return positive value for length of new path + */ +static RK_S32 find_dir_in_path(char *path, const char *dir_name, size_t max_length) +{ + struct dirent **dir; + RK_S32 path_len = strnlen(path, max_length); + RK_S32 new_path_len = 0; + RK_S32 n; + + search_name = dir_name; + n = scandir(path, &dir, _compare_name, alphasort); + if (n <= 0) { + mpp_err("scan %s for %s return %d\n", path, dir_name, n); + } else { + mpp_assert(n == 1); + + new_path_len = path_len; + new_path_len += snprintf(path + path_len, max_length - path_len - 1, + "/%s", dir[0]->d_name); + free(dir[0]); + free(dir); + } + search_name = NULL; + return new_path_len; +} + +RK_S32 check_sysfs_iommu() +{ + RK_U32 i = 0; + RK_U32 dts_info_found = 0; + RK_U32 ion_info_found = 0; + RK_S32 ret = ION_DETECT_IOMMU_DISABLE; + char path[256]; + static char *dts_devices[] = { + "vpu_service", + "hevc_service", + "rkvdec", + "rkvenc", + }; + static char *system_heaps[] = { + "vmalloc", + "system-heap", + }; + + mpp_env_get_u32("ion_debug", &ion_debug, 0); +#ifdef SOFIA_3GR_LINUX + return ret; +#endif + + for (i = 0; i < MPP_ARRAY_ELEMS(dts_devices); i++) { + snprintf(path, sizeof(path), "/proc/device-tree"); + if (find_dir_in_path(path, dts_devices[i], sizeof(path))) { + if (find_dir_in_path(path, "iommu_enabled", sizeof(path))) { + FILE *iommu_fp = fopen(path, "rb"); + + if (iommu_fp) { + RK_U32 iommu_enabled = 0; + fread(&iommu_enabled, sizeof(RK_U32), 1, iommu_fp); + mpp_log("%s iommu_enabled %d\n", dts_devices[i], (iommu_enabled > 0)); + fclose(iommu_fp); + if (iommu_enabled) + ret = ION_DETECT_IOMMU_ENABLE; + } + dts_info_found = 1; + break; + } + } + } + + if (!dts_info_found) { + for (i = 0; i < MPP_ARRAY_ELEMS(system_heaps); i++) { + snprintf(path, sizeof(path), "/sys/kernel/debug/ion/heaps"); + if (find_dir_in_path(path, system_heaps[i], sizeof(path))) { + mpp_log("%s found\n", system_heaps[i]); + ret = ION_DETECT_IOMMU_ENABLE; + ion_info_found = 1; + break; + } + } + } + + if (!dts_info_found && !ion_info_found) { + mpp_err("can not find any hint from all possible devices\n"); + ret = ION_DETECT_NO_DTS; + } + + return ret; +} + +typedef struct { + RK_U32 alignment; + RK_S32 ion_device; +} allocator_ctx_ion; + +#define VPU_IOC_MAGIC 'l' +#define VPU_IOC_PROBE_IOMMU_STATUS _IOR(VPU_IOC_MAGIC, 5, unsigned long) +#define VPU_IOC_PROBE_HEAP_STATUS _IOR(VPU_IOC_MAGIC, 6, unsigned long) +const char *dev_ion = "/dev/ion"; +static RK_S32 ion_heap_id = -1; +static RK_U32 ion_heap_mask = ION_HEAP_SYSTEM_MASK; + +MPP_RET os_allocator_ion_open(void **ctx, size_t alignment) +{ + RK_S32 fd; + allocator_ctx_ion *p; + + if (NULL == ctx) { + mpp_err("os_allocator_open Android do not accept NULL input\n"); + return MPP_ERR_NULL_PTR; + } + + *ctx = NULL; + + fd = open(dev_ion, O_RDWR); + if (fd < 0) { + mpp_err("open %s failed!\n", dev_ion); + return MPP_ERR_UNKNOW; + } + + ion_dbg(ION_DEVICE, "open ion dev fd %d\n", fd); + + p = mpp_malloc(allocator_ctx_ion, 1); + if (NULL == p) { + close(fd); + mpp_err("os_allocator_open Android failed to allocate context\n"); + return MPP_ERR_MALLOC; + } else { + /* + * do heap id detection here: + * if there is no vpu_service use default ION_HEAP_TYPE_SYSTEM_CONTIG + * if there is vpu_service then check the iommu_enable status + */ + if (ion_heap_id < 0) { + int detect_result = check_sysfs_iommu(); + const char *heap_name = NULL; + + switch (detect_result) { + case ION_DETECT_IOMMU_DISABLE : { + ion_heap_mask = (1 << ION_HEAP_TYPE_DMA); + ion_heap_id = ION_HEAP_TYPE_DMA; + heap_name = "ION_HEAP_TYPE_DMA"; + } break; + case ION_DETECT_IOMMU_ENABLE : { + ion_heap_mask = (1 << ION_HEAP_TYPE_SYSTEM); + ion_heap_id = ION_HEAP_TYPE_SYSTEM; + heap_name = "ION_HEAP_TYPE_SYSTEM"; + } break; + case ION_DETECT_NO_DTS : { + ion_heap_mask = (1 << ION_HEAP_TYPE_CARVEOUT); + ion_heap_id = ION_HEAP_TYPE_CARVEOUT; + heap_name = "ION_HEAP_TYPE_CARVEOUT"; + } break; + default : { + mpp_err("invalid detect result %d\n", detect_result); + ion_heap_mask = (1 << ION_HEAP_TYPE_DMA); + ion_heap_id = ION_HEAP_TYPE_DMA; + heap_name = "ION_HEAP_TYPE_DMA"; + } break; + } + mpp_log("using ion heap %s\n", heap_name); + } + p->alignment = alignment; + p->ion_device = fd; + *ctx = p; + } + + return MPP_OK; +} + +MPP_RET os_allocator_ion_alloc(void *ctx, MppBufferInfo *info) +{ + MPP_RET ret = MPP_OK; + allocator_ctx_ion *p = NULL; + + if (NULL == ctx) { + mpp_err("os_allocator_close Android do not accept NULL input\n"); + return MPP_ERR_NULL_PTR; + } + + ion_dbg_func("enter: ctx %p size %d\n", ctx, info->size); + + p = (allocator_ctx_ion *)ctx; + ret = ion_alloc(p->ion_device, info->size, p->alignment, + ion_heap_mask, 0, + (ion_user_handle_t *)&info->hnd); + if (ret) { + mpp_err("os_allocator_ion_alloc ion_alloc failed ret %d\n", ret); + return ret; + } + ret = ion_map(p->ion_device, (ion_user_handle_t)((intptr_t)info->hnd), info->size, + PROT_READ | PROT_WRITE, MAP_SHARED, (off_t)0, + (unsigned char**)&info->ptr, &info->fd); + if (ret) { + mpp_err("os_allocator_ion_alloc ion_map failed ret %d\n", ret); + } + + ion_dbg_func("leave: ret %d\n", ret); + return ret; +} + +MPP_RET os_allocator_ion_import(void *ctx, MppBufferInfo *data) +{ + MPP_RET ret = MPP_OK; + (void)ctx; + // NOTE: do not use the original buffer fd, + // use dup fd to avoid unexpected external fd close + ion_dbg_func("enter: ctx %p fd %d size %d\n", ctx, data->fd, data->size); + + data->fd = dup(data->fd); + data->ptr = mmap(NULL, data->size, PROT_READ | PROT_WRITE, MAP_SHARED, data->fd, 0); + if (data->ptr == MAP_FAILED) { + mpp_err_f("map error %s\n", strerror(errno)); + ret = MPP_NOK; + close(data->fd); + data->fd = -1; + data->ptr = NULL; + } + ion_dbg_func("leave: ret %d\n", ret); + return ret; +} + +MPP_RET os_allocator_ion_release(void *ctx, MppBufferInfo *data) +{ + ion_dbg_func("enter: ctx %p fd %d ptr %p size %d\n", ctx, data->fd, data->ptr, data->size); + + munmap(data->ptr, data->size); + close(data->fd); + + ion_dbg_func("leave\n"); + return MPP_OK; +} + +MPP_RET os_allocator_ion_free(void *ctx, MppBufferInfo *data) +{ + allocator_ctx_ion *p = NULL; + if (NULL == ctx) { + mpp_err("os_allocator_close Android do not accept NULL input\n"); + return MPP_ERR_NULL_PTR; + } + + ion_dbg_func("enter: ctx %p fd %d ptr %p size %d\n", ctx, data->fd, data->ptr, data->size); + + p = (allocator_ctx_ion *)ctx; + munmap(data->ptr, data->size); + close(data->fd); + ion_free(p->ion_device, (ion_user_handle_t)((intptr_t)data->hnd)); + + ion_dbg_func("leave\n"); + return MPP_OK; +} + +MPP_RET os_allocator_ion_close(void *ctx) +{ + int ret; + allocator_ctx_ion *p; + + if (NULL == ctx) { + mpp_err("os_allocator_close Android do not accept NULL input\n"); + return MPP_ERR_NULL_PTR; + } + + ion_dbg_func("enter: ctx\n", ctx); + + p = (allocator_ctx_ion *)ctx; + ret = close(p->ion_device); + mpp_free(p); + if (ret < 0) + ret = (MPP_RET) - errno; + + ion_dbg_func("leave: ret %d\n", ret); + + return ret; +} + +os_allocator allocator_ion = { + os_allocator_ion_open, + os_allocator_ion_alloc, + os_allocator_ion_free, + os_allocator_ion_import, + os_allocator_ion_release, + os_allocator_ion_close, +}; + diff --git a/osal/allocator/allocator_ion.h b/osal/allocator/allocator_ion.h index 313441d7..533e4873 100644 --- a/osal/allocator/allocator_ion.h +++ b/osal/allocator/allocator_ion.h @@ -1,20 +1,20 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "os_allocator.h" - -extern os_allocator allocator_ion; - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "os_allocator.h" + +extern os_allocator allocator_ion; + diff --git a/osal/android/os_env.c b/osal/android/os_env.c index d7141c48..bcdb2b7a 100644 --- a/osal/android/os_env.c +++ b/osal/android/os_env.c @@ -1,77 +1,77 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include "os_env.h" -#include - -/* - * NOTE: __system_property_set only available after android-21 - * So the library should compiled on latest ndk - */ - -RK_S32 os_get_env_u32(const char *name, RK_U32 *value, RK_U32 default_value) -{ - char prop[PROP_VALUE_MAX + 1]; - int len = __system_property_get(name, prop); - if (len > 0) { - char *endptr; - int base = (prop[0] == '0' && prop[1] == 'x') ? (16) : (10); - errno = 0; - *value = strtoul(prop, &endptr, base); - if (errno || (prop == endptr)) { - errno = 0; - *value = default_value; - } - } else { - *value = default_value; - } - return 0; -} - -RK_S32 os_get_env_str(const char *name, char **value, char *default_value) -{ - // use unsigned char to avoid warnning - static unsigned char env_str[2][PROP_VALUE_MAX + 1]; - static RK_U32 env_idx = 0; - char *prop = (char *)env_str[env_idx]; - int len = __system_property_get(name, prop); - if (len > 0) { - *value = prop; - env_idx = !env_idx; - } else { - *value = default_value; - } - return 0; -} - -RK_S32 os_set_env_u32(const char *name, RK_U32 value) -{ - char buf[PROP_VALUE_MAX + 1 + 2]; - snprintf(buf, sizeof(buf), "0x%x", value); - int len = __system_property_set(name, buf); - return (len) ? (0) : (-1); -} - -RK_S32 os_set_env_str(const char *name, char *value) -{ - int len = __system_property_set(name, value); - return (len) ? (0) : (-1); -} - - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include "os_env.h" +#include + +/* + * NOTE: __system_property_set only available after android-21 + * So the library should compiled on latest ndk + */ + +RK_S32 os_get_env_u32(const char *name, RK_U32 *value, RK_U32 default_value) +{ + char prop[PROP_VALUE_MAX + 1]; + int len = __system_property_get(name, prop); + if (len > 0) { + char *endptr; + int base = (prop[0] == '0' && prop[1] == 'x') ? (16) : (10); + errno = 0; + *value = strtoul(prop, &endptr, base); + if (errno || (prop == endptr)) { + errno = 0; + *value = default_value; + } + } else { + *value = default_value; + } + return 0; +} + +RK_S32 os_get_env_str(const char *name, char **value, char *default_value) +{ + // use unsigned char to avoid warnning + static unsigned char env_str[2][PROP_VALUE_MAX + 1]; + static RK_U32 env_idx = 0; + char *prop = (char *)env_str[env_idx]; + int len = __system_property_get(name, prop); + if (len > 0) { + *value = prop; + env_idx = !env_idx; + } else { + *value = default_value; + } + return 0; +} + +RK_S32 os_set_env_u32(const char *name, RK_U32 value) +{ + char buf[PROP_VALUE_MAX + 1 + 2]; + snprintf(buf, sizeof(buf), "0x%x", value); + int len = __system_property_set(name, buf); + return (len) ? (0) : (-1); +} + +RK_S32 os_set_env_str(const char *name, char *value) +{ + int len = __system_property_set(name, value); + return (len) ? (0) : (-1); +} + + diff --git a/osal/android/os_log.c b/osal/android/os_log.c index decb001a..0ad60798 100644 --- a/osal/android/os_log.c +++ b/osal/android/os_log.c @@ -1,28 +1,28 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include - -void os_log(const char* tag, const char* msg, va_list list) -{ - __android_log_vprint(ANDROID_LOG_INFO, tag, msg, list); -} - -void os_err(const char* tag, const char* msg, va_list list) -{ - __android_log_vprint(ANDROID_LOG_ERROR, tag, msg, list); -} - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +void os_log(const char* tag, const char* msg, va_list list) +{ + __android_log_vprint(ANDROID_LOG_INFO, tag, msg, list); +} + +void os_err(const char* tag, const char* msg, va_list list) +{ + __android_log_vprint(ANDROID_LOG_ERROR, tag, msg, list); +} + diff --git a/osal/android/os_mem.c b/osal/android/os_mem.c index 92f8d2fe..e0499fa7 100644 --- a/osal/android/os_mem.c +++ b/osal/android/os_mem.c @@ -1,48 +1,48 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include "os_mem.h" - -int os_malloc(void **memptr, size_t alignment, size_t size) -{ - (void)alignment; - int ret = 0; - void *ptr = malloc(size); - - if (ptr) { - *memptr = ptr; - } else { - *memptr = NULL; - ret = -1; - } - return ret; - - //return posix_memalign(memptr, alignment, size); -} - -int os_realloc(void *src, void **dst, size_t alignment, size_t size) -{ - (void)alignment; - *dst = realloc(src, size); - return (*dst) ? (0) : (-1); -} - -void os_free(void *ptr) -{ - free(ptr); -} - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "os_mem.h" + +int os_malloc(void **memptr, size_t alignment, size_t size) +{ + (void)alignment; + int ret = 0; + void *ptr = malloc(size); + + if (ptr) { + *memptr = ptr; + } else { + *memptr = NULL; + ret = -1; + } + return ret; + + //return posix_memalign(memptr, alignment, size); +} + +int os_realloc(void *src, void **dst, size_t alignment, size_t size) +{ + (void)alignment; + *dst = realloc(src, size); + return (*dst) ? (0) : (-1); +} + +void os_free(void *ptr) +{ + free(ptr); +} + diff --git a/osal/inc/mpp_allocator.h b/osal/inc/mpp_allocator.h index bd81da6a..8a2a71aa 100644 --- a/osal/inc/mpp_allocator.h +++ b/osal/inc/mpp_allocator.h @@ -1,47 +1,47 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __MPP_ALLOCATOR_H__ -#define __MPP_ALLOCATOR_H__ - -#include "rk_type.h" -#include "mpp_buffer.h" - -typedef void *MppAllocator; - -typedef struct MppAllocatorApi_t { - RK_U32 size; - RK_U32 version; - - MPP_RET (*alloc)(MppAllocator allocator, MppBufferInfo *data); - MPP_RET (*free)(MppAllocator allocator, MppBufferInfo *data); - MPP_RET (*import)(MppAllocator allocator, MppBufferInfo *data); - MPP_RET (*release)(MppAllocator allocator, MppBufferInfo *data); -} MppAllocatorApi; - -#ifdef __cplusplus -extern "C" { -#endif - -MPP_RET mpp_allocator_get(MppAllocator *allocator, MppAllocatorApi **api, MppBufferType type); -MPP_RET mpp_allocator_put(MppAllocator *allocator); - -#ifdef __cplusplus -} -#endif - -#endif /*__MPP_ALLOCATOR_H__*/ - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPP_ALLOCATOR_H__ +#define __MPP_ALLOCATOR_H__ + +#include "rk_type.h" +#include "mpp_buffer.h" + +typedef void *MppAllocator; + +typedef struct MppAllocatorApi_t { + RK_U32 size; + RK_U32 version; + + MPP_RET (*alloc)(MppAllocator allocator, MppBufferInfo *data); + MPP_RET (*free)(MppAllocator allocator, MppBufferInfo *data); + MPP_RET (*import)(MppAllocator allocator, MppBufferInfo *data); + MPP_RET (*release)(MppAllocator allocator, MppBufferInfo *data); +} MppAllocatorApi; + +#ifdef __cplusplus +extern "C" { +#endif + +MPP_RET mpp_allocator_get(MppAllocator *allocator, MppAllocatorApi **api, MppBufferType type); +MPP_RET mpp_allocator_put(MppAllocator *allocator); + +#ifdef __cplusplus +} +#endif + +#endif /*__MPP_ALLOCATOR_H__*/ + diff --git a/osal/inc/mpp_common.h b/osal/inc/mpp_common.h index 5a606c53..2bf2856d 100644 --- a/osal/inc/mpp_common.h +++ b/osal/inc/mpp_common.h @@ -1,185 +1,185 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __MPP_COMMON_H__ -#define __MPP_COMMON_H__ - -#include "rk_type.h" - -#define MPP_TAG_SIZE 32 - -#define MPP_MAX(a, b) ((a) > (b) ? (a) : (b)) -#define MPP_MAX3(a, b, c) MPP_MAX(MPP_MAX(a,b),c) -#define MPP_MAX4(a, b, c, d) MPP_MAX((a), MPP_MAX3((b), (c), (d))) - -#define MPP_MIN(a,b) ((a) > (b) ? (b) : (a)) -#define MPP_MIN3(a,b,c) MPP_MIN(MPP_MIN(a,b),c) -#define MPP_MIN4(a, b, c, d) MPP_MIN((a), MPP_MIN3((b), (c), (d))) - -#define MPP_SWAP(type, a, b) do {type SWAP_tmp = b; b = a; a = SWAP_tmp;} while(0) -#define MPP_ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0])) -#define MPP_ALIGN(x, a) (((x)+(a)-1)&~((a)-1)) -#define MPP_VSWAP(a, b) { a ^= b; b ^= a; a ^= b; } - -#define MPP_RB16(x) ((((const RK_U8*)(x))[0] << 8) | ((const RK_U8*)(x))[1]) -#define MPP_WB16(p, d) do { \ - ((RK_U8*)(p))[1] = (d); \ - ((RK_U8*)(p))[0] = (d)>>8; } while(0) - -#define MPP_RL16(x) ((((const RK_U8*)(x))[1] << 8) | \ - ((const RK_U8*)(x))[0]) -#define MPP_WL16(p, d) do { \ - ((RK_U8*)(p))[0] = (d); \ - ((RK_U8*)(p))[1] = (d)>>8; } while(0) - -#define MPP_RB32(x) ((((const RK_U8*)(x))[0] << 24) | \ - (((const RK_U8*)(x))[1] << 16) | \ - (((const RK_U8*)(x))[2] << 8) | \ - ((const RK_U8*)(x))[3]) -#define MPP_WB32(p, d) do { \ - ((RK_U8*)(p))[3] = (d); \ - ((RK_U8*)(p))[2] = (d)>>8; \ - ((RK_U8*)(p))[1] = (d)>>16; \ - ((RK_U8*)(p))[0] = (d)>>24; } while(0) - -#define MPP_RL32(x) ((((const RK_U8*)(x))[3] << 24) | \ - (((const RK_U8*)(x))[2] << 16) | \ - (((const RK_U8*)(x))[1] << 8) | \ - ((const RK_U8*)(x))[0]) -#define MPP_WL32(p, d) do { \ - ((RK_U8*)(p))[0] = (d); \ - ((RK_U8*)(p))[1] = (d)>>8; \ - ((RK_U8*)(p))[2] = (d)>>16; \ - ((RK_U8*)(p))[3] = (d)>>24; } while(0) - -#define MPP_RB64(x) (((RK_U64)((const RK_U8*)(x))[0] << 56) | \ - ((RK_U64)((const RK_U8*)(x))[1] << 48) | \ - ((RK_U64)((const RK_U8*)(x))[2] << 40) | \ - ((RK_U64)((const RK_U8*)(x))[3] << 32) | \ - ((RK_U64)((const RK_U8*)(x))[4] << 24) | \ - ((RK_U64)((const RK_U8*)(x))[5] << 16) | \ - ((RK_U64)((const RK_U8*)(x))[6] << 8) | \ - (RK_U64)((const RK_U8*)(x))[7]) -#define MPP_WB64(p, d) do { \ - ((RK_U8*)(p))[7] = (d); \ - ((RK_U8*)(p))[6] = (d)>>8; \ - ((RK_U8*)(p))[5] = (d)>>16; \ - ((RK_U8*)(p))[4] = (d)>>24; \ - ((RK_U8*)(p))[3] = (d)>>32; \ - ((RK_U8*)(p))[2] = (d)>>40; \ - ((RK_U8*)(p))[1] = (d)>>48; \ - ((RK_U8*)(p))[0] = (d)>>56; } while(0) - -#define MPP_RL64(x) (((RK_U64)((const RK_U8*)(x))[7] << 56) | \ - ((RK_U64)((const RK_U8*)(x))[6] << 48) | \ - ((RK_U64)((const RK_U8*)(x))[5] << 40) | \ - ((RK_U64)((const RK_U8*)(x))[4] << 32) | \ - ((RK_U64)((const RK_U8*)(x))[3] << 24) | \ - ((RK_U64)((const RK_U8*)(x))[2] << 16) | \ - ((RK_U64)((const RK_U8*)(x))[1] << 8) | \ - (RK_U64)((const RK_U8*)(x))[0]) -#define MPP_WL64(p, d) do { \ - ((RK_U8*)(p))[0] = (d); \ - ((RK_U8*)(p))[1] = (d)>>8; \ - ((RK_U8*)(p))[2] = (d)>>16; \ - ((RK_U8*)(p))[3] = (d)>>24; \ - ((RK_U8*)(p))[4] = (d)>>32; \ - ((RK_U8*)(p))[5] = (d)>>40; \ - ((RK_U8*)(p))[6] = (d)>>48; \ - ((RK_U8*)(p))[7] = (d)>>56; } while(0) - -#define MPP_RB24(x) ((((const RK_U8*)(x))[0] << 16) | \ - (((const RK_U8*)(x))[1] << 8) | \ - ((const RK_U8*)(x))[2]) -#define MPP_WB24(p, d) do { \ - ((RK_U8*)(p))[2] = (d); \ - ((RK_U8*)(p))[1] = (d)>>8; \ - ((RK_U8*)(p))[0] = (d)>>16; } while(0) - -#define MPP_RL24(x) ((((const RK_U8*)(x))[2] << 16) | \ - (((const RK_U8*)(x))[1] << 8) | \ - ((const RK_U8*)(x))[0]) - -#define MPP_WL24(p, d) do { \ - ((RK_U8*)(p))[0] = (d); \ - ((RK_U8*)(p))[1] = (d)>>8; \ - ((RK_U8*)(p))[2] = (d)>>16; } while(0) - -#include -#if defined(_WIN32) && !defined(__MINGW32CE__) -#define snprintf _snprintf -#define fseeko _fseeki64 - -#include -#include -#define chdir _chdir -#define mkdir _mkdir -#define access _access - -#define R_OK 4 /* Test for read permission. */ -#define W_OK 2 /* Test for write permission. */ -#define X_OK 1 /* Test for execute permission. */ -#define F_OK 0 /* Test for existence. */ - -#elif defined(__MINGW32CE__) -#define fseeko fseeko64 -#else -#include -#include -#include -#define mkdir(x) mkdir(x, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) -#endif - - -#define __RETURN __Return -#define __FAILED __failed - -#define ARG_T(t) t -#define ARG_N(a,b,c,d,N,...) N -#define ARG_N_HELPER(...) ARG_T(ARG_N(__VA_ARGS__)) -#define COUNT_ARG(...) ARG_N_HELPER(__VA_ARGS__,4,3,2,1,0) - - -#ifdef __cplusplus -extern "C" { -#endif - -RK_S32 mpp_log2(RK_U32 v); -RK_S32 mpp_log2_16bit(RK_U32 v); - -static __inline RK_S32 mpp_ceil_log2(RK_S32 x) -{ - return mpp_log2((x - 1) << 1); -} - -static __inline RK_S32 mpp_clip(RK_S32 a, RK_S32 amin, RK_S32 amax) -{ - if (a < amin) return amin; - else if (a > amax) return amax; - else return a; -} - -static __inline RK_U32 mpp_is_32bit() -{ - return ((sizeof(void *) == 4) ? (1) : (0)); -} - -#ifdef __cplusplus -} -#endif - -#endif /*__MPP_COMMON_H__*/ - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPP_COMMON_H__ +#define __MPP_COMMON_H__ + +#include "rk_type.h" + +#define MPP_TAG_SIZE 32 + +#define MPP_MAX(a, b) ((a) > (b) ? (a) : (b)) +#define MPP_MAX3(a, b, c) MPP_MAX(MPP_MAX(a,b),c) +#define MPP_MAX4(a, b, c, d) MPP_MAX((a), MPP_MAX3((b), (c), (d))) + +#define MPP_MIN(a,b) ((a) > (b) ? (b) : (a)) +#define MPP_MIN3(a,b,c) MPP_MIN(MPP_MIN(a,b),c) +#define MPP_MIN4(a, b, c, d) MPP_MIN((a), MPP_MIN3((b), (c), (d))) + +#define MPP_SWAP(type, a, b) do {type SWAP_tmp = b; b = a; a = SWAP_tmp;} while(0) +#define MPP_ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0])) +#define MPP_ALIGN(x, a) (((x)+(a)-1)&~((a)-1)) +#define MPP_VSWAP(a, b) { a ^= b; b ^= a; a ^= b; } + +#define MPP_RB16(x) ((((const RK_U8*)(x))[0] << 8) | ((const RK_U8*)(x))[1]) +#define MPP_WB16(p, d) do { \ + ((RK_U8*)(p))[1] = (d); \ + ((RK_U8*)(p))[0] = (d)>>8; } while(0) + +#define MPP_RL16(x) ((((const RK_U8*)(x))[1] << 8) | \ + ((const RK_U8*)(x))[0]) +#define MPP_WL16(p, d) do { \ + ((RK_U8*)(p))[0] = (d); \ + ((RK_U8*)(p))[1] = (d)>>8; } while(0) + +#define MPP_RB32(x) ((((const RK_U8*)(x))[0] << 24) | \ + (((const RK_U8*)(x))[1] << 16) | \ + (((const RK_U8*)(x))[2] << 8) | \ + ((const RK_U8*)(x))[3]) +#define MPP_WB32(p, d) do { \ + ((RK_U8*)(p))[3] = (d); \ + ((RK_U8*)(p))[2] = (d)>>8; \ + ((RK_U8*)(p))[1] = (d)>>16; \ + ((RK_U8*)(p))[0] = (d)>>24; } while(0) + +#define MPP_RL32(x) ((((const RK_U8*)(x))[3] << 24) | \ + (((const RK_U8*)(x))[2] << 16) | \ + (((const RK_U8*)(x))[1] << 8) | \ + ((const RK_U8*)(x))[0]) +#define MPP_WL32(p, d) do { \ + ((RK_U8*)(p))[0] = (d); \ + ((RK_U8*)(p))[1] = (d)>>8; \ + ((RK_U8*)(p))[2] = (d)>>16; \ + ((RK_U8*)(p))[3] = (d)>>24; } while(0) + +#define MPP_RB64(x) (((RK_U64)((const RK_U8*)(x))[0] << 56) | \ + ((RK_U64)((const RK_U8*)(x))[1] << 48) | \ + ((RK_U64)((const RK_U8*)(x))[2] << 40) | \ + ((RK_U64)((const RK_U8*)(x))[3] << 32) | \ + ((RK_U64)((const RK_U8*)(x))[4] << 24) | \ + ((RK_U64)((const RK_U8*)(x))[5] << 16) | \ + ((RK_U64)((const RK_U8*)(x))[6] << 8) | \ + (RK_U64)((const RK_U8*)(x))[7]) +#define MPP_WB64(p, d) do { \ + ((RK_U8*)(p))[7] = (d); \ + ((RK_U8*)(p))[6] = (d)>>8; \ + ((RK_U8*)(p))[5] = (d)>>16; \ + ((RK_U8*)(p))[4] = (d)>>24; \ + ((RK_U8*)(p))[3] = (d)>>32; \ + ((RK_U8*)(p))[2] = (d)>>40; \ + ((RK_U8*)(p))[1] = (d)>>48; \ + ((RK_U8*)(p))[0] = (d)>>56; } while(0) + +#define MPP_RL64(x) (((RK_U64)((const RK_U8*)(x))[7] << 56) | \ + ((RK_U64)((const RK_U8*)(x))[6] << 48) | \ + ((RK_U64)((const RK_U8*)(x))[5] << 40) | \ + ((RK_U64)((const RK_U8*)(x))[4] << 32) | \ + ((RK_U64)((const RK_U8*)(x))[3] << 24) | \ + ((RK_U64)((const RK_U8*)(x))[2] << 16) | \ + ((RK_U64)((const RK_U8*)(x))[1] << 8) | \ + (RK_U64)((const RK_U8*)(x))[0]) +#define MPP_WL64(p, d) do { \ + ((RK_U8*)(p))[0] = (d); \ + ((RK_U8*)(p))[1] = (d)>>8; \ + ((RK_U8*)(p))[2] = (d)>>16; \ + ((RK_U8*)(p))[3] = (d)>>24; \ + ((RK_U8*)(p))[4] = (d)>>32; \ + ((RK_U8*)(p))[5] = (d)>>40; \ + ((RK_U8*)(p))[6] = (d)>>48; \ + ((RK_U8*)(p))[7] = (d)>>56; } while(0) + +#define MPP_RB24(x) ((((const RK_U8*)(x))[0] << 16) | \ + (((const RK_U8*)(x))[1] << 8) | \ + ((const RK_U8*)(x))[2]) +#define MPP_WB24(p, d) do { \ + ((RK_U8*)(p))[2] = (d); \ + ((RK_U8*)(p))[1] = (d)>>8; \ + ((RK_U8*)(p))[0] = (d)>>16; } while(0) + +#define MPP_RL24(x) ((((const RK_U8*)(x))[2] << 16) | \ + (((const RK_U8*)(x))[1] << 8) | \ + ((const RK_U8*)(x))[0]) + +#define MPP_WL24(p, d) do { \ + ((RK_U8*)(p))[0] = (d); \ + ((RK_U8*)(p))[1] = (d)>>8; \ + ((RK_U8*)(p))[2] = (d)>>16; } while(0) + +#include +#if defined(_WIN32) && !defined(__MINGW32CE__) +#define snprintf _snprintf +#define fseeko _fseeki64 + +#include +#include +#define chdir _chdir +#define mkdir _mkdir +#define access _access + +#define R_OK 4 /* Test for read permission. */ +#define W_OK 2 /* Test for write permission. */ +#define X_OK 1 /* Test for execute permission. */ +#define F_OK 0 /* Test for existence. */ + +#elif defined(__MINGW32CE__) +#define fseeko fseeko64 +#else +#include +#include +#include +#define mkdir(x) mkdir(x, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) +#endif + + +#define __RETURN __Return +#define __FAILED __failed + +#define ARG_T(t) t +#define ARG_N(a,b,c,d,N,...) N +#define ARG_N_HELPER(...) ARG_T(ARG_N(__VA_ARGS__)) +#define COUNT_ARG(...) ARG_N_HELPER(__VA_ARGS__,4,3,2,1,0) + + +#ifdef __cplusplus +extern "C" { +#endif + +RK_S32 mpp_log2(RK_U32 v); +RK_S32 mpp_log2_16bit(RK_U32 v); + +static __inline RK_S32 mpp_ceil_log2(RK_S32 x) +{ + return mpp_log2((x - 1) << 1); +} + +static __inline RK_S32 mpp_clip(RK_S32 a, RK_S32 amin, RK_S32 amax) +{ + if (a < amin) return amin; + else if (a > amax) return amax; + else return a; +} + +static __inline RK_U32 mpp_is_32bit() +{ + return ((sizeof(void *) == 4) ? (1) : (0)); +} + +#ifdef __cplusplus +} +#endif + +#endif /*__MPP_COMMON_H__*/ + diff --git a/osal/inc/mpp_env.h b/osal/inc/mpp_env.h index 465434b0..1fe96108 100644 --- a/osal/inc/mpp_env.h +++ b/osal/inc/mpp_env.h @@ -1,37 +1,37 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __MPP_ENV_H__ -#define __MPP_ENV_H__ - -#include "rk_type.h" - -#ifdef __cplusplus -extern "C" { -#endif - -RK_S32 mpp_env_get_u32(const char *name, RK_U32 *value, RK_U32 default_value); -RK_S32 mpp_env_get_str(const char *name, char **value, char *default_value); - -RK_S32 mpp_env_set_u32(const char *name, RK_U32 value); -RK_S32 mpp_env_set_str(const char *name, char *value); - -#ifdef __cplusplus -} -#endif - -#endif /*__MPP_ENV_H__*/ - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPP_ENV_H__ +#define __MPP_ENV_H__ + +#include "rk_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +RK_S32 mpp_env_get_u32(const char *name, RK_U32 *value, RK_U32 default_value); +RK_S32 mpp_env_get_str(const char *name, char **value, char *default_value); + +RK_S32 mpp_env_set_u32(const char *name, RK_U32 value); +RK_S32 mpp_env_set_str(const char *name, char *value); + +#ifdef __cplusplus +} +#endif + +#endif /*__MPP_ENV_H__*/ + diff --git a/osal/inc/mpp_log.h b/osal/inc/mpp_log.h index 3ce21e26..1f146006 100644 --- a/osal/inc/mpp_log.h +++ b/osal/inc/mpp_log.h @@ -1,125 +1,125 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __MPP_LOG_H__ -#define __MPP_LOG_H__ - -#include "rk_type.h" -#include -#include - -/* - * mpp runtime log system usage: - * mpp_err is for error status message, it will print for sure. - * mpp_log is for important message like open/close/reset/flush, it will print too. - * mpp_dbg is for all optional message. it can be controlled by debug and flag. - */ - -#define mpp_log(fmt, ...) _mpp_log(MODULE_TAG, fmt, NULL, ## __VA_ARGS__) -#define mpp_err(fmt, ...) _mpp_err(MODULE_TAG, fmt, NULL, ## __VA_ARGS__) - -#define _mpp_dbg(debug, flag, fmt, ...) \ - do { \ - if (debug & flag) \ - mpp_log(fmt, ## __VA_ARGS__); \ - } while (0) - -#define mpp_dbg(flag, fmt, ...) _mpp_dbg(mpp_debug, flag, fmt, ## __VA_ARGS__) - -/* - * _f function will add function name to the log - */ -#define mpp_log_f(fmt, ...) _mpp_log(MODULE_TAG, fmt, __FUNCTION__, ## __VA_ARGS__) -#define mpp_err_f(fmt, ...) _mpp_err(MODULE_TAG, fmt, __FUNCTION__, ## __VA_ARGS__) -#define _mpp_dbg_f(debug, flag, fmt, ...) \ - do { \ - if (debug & flag) \ - mpp_log_f(fmt, ## __VA_ARGS__); \ - } while (0) - -#define mpp_dbg_f(flag, fmt, ...) _mpp_dbg_f(mpp_debug, flag, fmt, ## __VA_ARGS__) - - -#define MPP_DBG_TIMING (0x00000001) -#define MPP_DBG_PTS (0x00000002) -#define MPP_ABORT (0x10000000) - -/* - * mpp_dbg usage: - * - * in h264d module define module debug flag variable like: h265d_debug - * then define h265d_dbg macro as follow : - * - * extern RK_U32 h265d_debug; - * - * #define H265D_DBG_FUNCTION (0x00000001) - * #define H265D_DBG_VPS (0x00000002) - * #define H265D_DBG_SPS (0x00000004) - * #define H265D_DBG_PPS (0x00000008) - * #define H265D_DBG_SLICE_HDR (0x00000010) - * - * #define h265d_dbg(flag, fmt, ...) mpp_dbg(h265d_debug, flag, fmt, ## __VA_ARGS__) - * - * finally use environment control the debug flag - * - * mpp_get_env_u32("h264d_debug", &h265d_debug, 0) - * - */ -/* - * sub-module debug flag usage example: - * +------+-------------------+ - * | 8bit | 24bit | - * +------+-------------------+ - * 0~15 bit: software debug print - * 16~23 bit: hardware debug print - * 24~31 bit: information print format - */ - -#define mpp_abort() do { \ - if (mpp_debug & MPP_ABORT) { \ - abort(); \ - } \ -} while (0) - -#define MPP_STRINGS(x) MPP_TO_STRING(x) -#define MPP_TO_STRING(x) #x - -#define mpp_assert(cond) do { \ - if (!(cond)) { \ - mpp_err("Assertion %s failed at %s:%d\n", \ - MPP_STRINGS(cond), __FUNCTION__, __LINE__); \ - mpp_abort(); \ - } \ -} while (0) - - -#ifdef __cplusplus -extern "C" { -#endif - -extern RK_U32 mpp_debug; - -void mpp_log_set_flag(RK_U32 flag); -RK_U32 mpp_log_get_flag(); - -void _mpp_log(const char *tag, const char *fmt, const char *func, ...); -void _mpp_err(const char *tag, const char *fmt, const char *func, ...); - -#ifdef __cplusplus -} -#endif - -#endif /*__MPP_LOG_H__*/ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPP_LOG_H__ +#define __MPP_LOG_H__ + +#include "rk_type.h" +#include +#include + +/* + * mpp runtime log system usage: + * mpp_err is for error status message, it will print for sure. + * mpp_log is for important message like open/close/reset/flush, it will print too. + * mpp_dbg is for all optional message. it can be controlled by debug and flag. + */ + +#define mpp_log(fmt, ...) _mpp_log(MODULE_TAG, fmt, NULL, ## __VA_ARGS__) +#define mpp_err(fmt, ...) _mpp_err(MODULE_TAG, fmt, NULL, ## __VA_ARGS__) + +#define _mpp_dbg(debug, flag, fmt, ...) \ + do { \ + if (debug & flag) \ + mpp_log(fmt, ## __VA_ARGS__); \ + } while (0) + +#define mpp_dbg(flag, fmt, ...) _mpp_dbg(mpp_debug, flag, fmt, ## __VA_ARGS__) + +/* + * _f function will add function name to the log + */ +#define mpp_log_f(fmt, ...) _mpp_log(MODULE_TAG, fmt, __FUNCTION__, ## __VA_ARGS__) +#define mpp_err_f(fmt, ...) _mpp_err(MODULE_TAG, fmt, __FUNCTION__, ## __VA_ARGS__) +#define _mpp_dbg_f(debug, flag, fmt, ...) \ + do { \ + if (debug & flag) \ + mpp_log_f(fmt, ## __VA_ARGS__); \ + } while (0) + +#define mpp_dbg_f(flag, fmt, ...) _mpp_dbg_f(mpp_debug, flag, fmt, ## __VA_ARGS__) + + +#define MPP_DBG_TIMING (0x00000001) +#define MPP_DBG_PTS (0x00000002) +#define MPP_ABORT (0x10000000) + +/* + * mpp_dbg usage: + * + * in h264d module define module debug flag variable like: h265d_debug + * then define h265d_dbg macro as follow : + * + * extern RK_U32 h265d_debug; + * + * #define H265D_DBG_FUNCTION (0x00000001) + * #define H265D_DBG_VPS (0x00000002) + * #define H265D_DBG_SPS (0x00000004) + * #define H265D_DBG_PPS (0x00000008) + * #define H265D_DBG_SLICE_HDR (0x00000010) + * + * #define h265d_dbg(flag, fmt, ...) mpp_dbg(h265d_debug, flag, fmt, ## __VA_ARGS__) + * + * finally use environment control the debug flag + * + * mpp_get_env_u32("h264d_debug", &h265d_debug, 0) + * + */ +/* + * sub-module debug flag usage example: + * +------+-------------------+ + * | 8bit | 24bit | + * +------+-------------------+ + * 0~15 bit: software debug print + * 16~23 bit: hardware debug print + * 24~31 bit: information print format + */ + +#define mpp_abort() do { \ + if (mpp_debug & MPP_ABORT) { \ + abort(); \ + } \ +} while (0) + +#define MPP_STRINGS(x) MPP_TO_STRING(x) +#define MPP_TO_STRING(x) #x + +#define mpp_assert(cond) do { \ + if (!(cond)) { \ + mpp_err("Assertion %s failed at %s:%d\n", \ + MPP_STRINGS(cond), __FUNCTION__, __LINE__); \ + mpp_abort(); \ + } \ +} while (0) + + +#ifdef __cplusplus +extern "C" { +#endif + +extern RK_U32 mpp_debug; + +void mpp_log_set_flag(RK_U32 flag); +RK_U32 mpp_log_get_flag(); + +void _mpp_log(const char *tag, const char *fmt, const char *func, ...); +void _mpp_err(const char *tag, const char *fmt, const char *func, ...); + +#ifdef __cplusplus +} +#endif + +#endif /*__MPP_LOG_H__*/ diff --git a/osal/inc/mpp_mem.h b/osal/inc/mpp_mem.h index 1a2886c8..715e59cc 100644 --- a/osal/inc/mpp_mem.h +++ b/osal/inc/mpp_mem.h @@ -1,79 +1,79 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __MPP_MEM_H__ -#define __MPP_MEM_H__ - -#include - -#include "rk_type.h" -#include "mpp_err.h" - -#define mpp_malloc_tagged(type, count, tag) \ - (type*)mpp_osal_malloc(tag, sizeof(type) * (count)) - -#define mpp_malloc(type, count) \ - (type*)mpp_osal_malloc(MODULE_TAG, sizeof(type) * (count)) - -#define mpp_malloc_size(type, size) \ - (type*)mpp_osal_malloc(MODULE_TAG, size) - -#define mpp_calloc_size(type, size) \ - (type*)mpp_osal_calloc(MODULE_TAG, size) - -#define mpp_calloc(type, count) \ - (type*)mpp_osal_calloc(MODULE_TAG, sizeof(type) * (count)) - -#define mpp_realloc(ptr, type, count) \ - (type*)mpp_osal_realloc(MODULE_TAG, ptr, sizeof(type) * (count)) - -#define mpp_free(ptr) mpp_osal_free(ptr) - -#define MPP_FREE(ptr) do { if(ptr) mpp_free(ptr); ptr = NULL; } while (0) -#define MPP_FCLOSE(fp) do { if(fp) fclose(fp); fp = NULL; } while (0) - -#ifdef __cplusplus -extern "C" { -#endif - -void *mpp_osal_malloc(const char *tag, size_t size); -void *mpp_osal_calloc(const char *tag, size_t size); -void *mpp_osal_realloc(const char *tag, void *ptr, size_t size); -void mpp_osal_free(void *ptr); - -void mpp_show_mem_status(); - -/* - * mpp memory usage snapshot tool - * - * usage: - * call mpp_mem_get_snapshot on context init get one snapshot - * call mpp_mem_get_snapshot on context deinit get another snapshot - * call mpp_mem_diff_snapshot to show the difference between these two snapshot - * call mpp_mem_put_snapshot twice to release these two snapshot - */ -typedef void* MppMemSnapshot; - -MPP_RET mpp_mem_get_snapshot(MppMemSnapshot *hnd); -MPP_RET mpp_mem_put_snapshot(MppMemSnapshot *hnd); -MPP_RET mpp_mem_squash_snapshot(MppMemSnapshot hnd0, MppMemSnapshot hnd1); - -#ifdef __cplusplus -} -#endif - -#endif /*__MPP_MEM_H__*/ - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPP_MEM_H__ +#define __MPP_MEM_H__ + +#include + +#include "rk_type.h" +#include "mpp_err.h" + +#define mpp_malloc_tagged(type, count, tag) \ + (type*)mpp_osal_malloc(tag, sizeof(type) * (count)) + +#define mpp_malloc(type, count) \ + (type*)mpp_osal_malloc(MODULE_TAG, sizeof(type) * (count)) + +#define mpp_malloc_size(type, size) \ + (type*)mpp_osal_malloc(MODULE_TAG, size) + +#define mpp_calloc_size(type, size) \ + (type*)mpp_osal_calloc(MODULE_TAG, size) + +#define mpp_calloc(type, count) \ + (type*)mpp_osal_calloc(MODULE_TAG, sizeof(type) * (count)) + +#define mpp_realloc(ptr, type, count) \ + (type*)mpp_osal_realloc(MODULE_TAG, ptr, sizeof(type) * (count)) + +#define mpp_free(ptr) mpp_osal_free(ptr) + +#define MPP_FREE(ptr) do { if(ptr) mpp_free(ptr); ptr = NULL; } while (0) +#define MPP_FCLOSE(fp) do { if(fp) fclose(fp); fp = NULL; } while (0) + +#ifdef __cplusplus +extern "C" { +#endif + +void *mpp_osal_malloc(const char *tag, size_t size); +void *mpp_osal_calloc(const char *tag, size_t size); +void *mpp_osal_realloc(const char *tag, void *ptr, size_t size); +void mpp_osal_free(void *ptr); + +void mpp_show_mem_status(); + +/* + * mpp memory usage snapshot tool + * + * usage: + * call mpp_mem_get_snapshot on context init get one snapshot + * call mpp_mem_get_snapshot on context deinit get another snapshot + * call mpp_mem_diff_snapshot to show the difference between these two snapshot + * call mpp_mem_put_snapshot twice to release these two snapshot + */ +typedef void* MppMemSnapshot; + +MPP_RET mpp_mem_get_snapshot(MppMemSnapshot *hnd); +MPP_RET mpp_mem_put_snapshot(MppMemSnapshot *hnd); +MPP_RET mpp_mem_squash_snapshot(MppMemSnapshot hnd0, MppMemSnapshot hnd1); + +#ifdef __cplusplus +} +#endif + +#endif /*__MPP_MEM_H__*/ + diff --git a/osal/inc/mpp_thread.h b/osal/inc/mpp_thread.h index cbad7830..9e6a9907 100644 --- a/osal/inc/mpp_thread.h +++ b/osal/inc/mpp_thread.h @@ -1,246 +1,246 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * File : mpp_thread.h - * Description : thread library for different OS - * Author : herman.chen@rock-chips.com - * Date : 9:47 2015/7/27 - */ - -#ifndef __MPP_THREAD_H__ -#define __MPP_THREAD_H__ - -#if defined(_WIN32) && !defined(__MINGW32CE__) - -/* - * NOTE: POSIX Threads for Win32 - * Downloaded from http://www.sourceware.org/pthreads-win32/ - */ -#include "semaphore.h" -#include "pthread.h" -#pragma comment(lib, "pthreadVC2.lib") - -/* - * add pthread_setname_np for windows - */ -int pthread_setname_np(pthread_t thread, const char *name); - -#else - -#include -#include -#include - -#ifndef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP -#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP PTHREAD_RECURSIVE_MUTEX_INITIALIZER -#endif - -#endif - -#define THREAD_NAME_LEN 16 - -typedef void *(*MppThreadFunc)(void *); - -typedef enum { - MPP_THREAD_UNINITED, - MPP_THREAD_RUNNING, - MPP_THREAD_WAITING, - MPP_THREAD_STOPPING, -} MppThreadStatus; - -#ifdef __cplusplus - -#include "mpp_log.h" - -class Mutex; -class Condition; - -/* - * for shorter type name and function name - */ -class Mutex -{ -public: - Mutex(); - ~Mutex(); - - void lock(); - void unlock(); - int trylock(); - - class Autolock - { - public: - inline Autolock(Mutex& mutex) : mLock(mutex) { mLock.lock(); } - inline Autolock(Mutex* mutex) : mLock(*mutex) { mLock.lock(); } - inline ~Autolock() { mLock.unlock(); } - private: - Mutex& mLock; - }; - -private: - friend class Condition; - - pthread_mutex_t mMutex; - - Mutex(const Mutex &); - Mutex &operator = (const Mutex&); -}; - -inline Mutex::Mutex() -{ - pthread_mutexattr_t attr; - pthread_mutexattr_init(&attr); - pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); - pthread_mutex_init(&mMutex, &attr); - pthread_mutexattr_destroy(&attr); -} -inline Mutex::~Mutex() -{ - pthread_mutex_destroy(&mMutex); -} -inline void Mutex::lock() -{ - pthread_mutex_lock(&mMutex); -} -inline void Mutex::unlock() -{ - pthread_mutex_unlock(&mMutex); -} -inline int Mutex::trylock() -{ - return pthread_mutex_trylock(&mMutex); -} - -typedef Mutex::Autolock AutoMutex; - - -/* - * for shorter type name and function name - */ -class Condition -{ -public: - Condition(); - Condition(int type); - ~Condition(); - void wait(Mutex& mutex); - void timedwait(Mutex& mutex, RK_S64 timeout); - void signal(); - -private: - pthread_cond_t mCond; -}; - -inline Condition::Condition() -{ - pthread_cond_init(&mCond, NULL); -} -inline Condition::~Condition() -{ - pthread_cond_destroy(&mCond); -} -inline void Condition::wait(Mutex& mutex) -{ - pthread_cond_wait(&mCond, &mutex.mMutex); -} -inline void Condition::timedwait(Mutex& mutex, RK_S64 timeout) -{ - struct timespec time; - time.tv_sec = (time_t)(timeout >> 32); - time.tv_nsec = (long)timeout; - pthread_cond_timedwait(&mCond, &mutex.mMutex, &time); -} -inline void Condition::signal() -{ - pthread_cond_signal(&mCond); -} - -class MppMutexCond -{ -public: - MppMutexCond() {}; - ~MppMutexCond() {}; - - void lock() { mLock.lock(); } - void unlock() { mLock.unlock(); } - void wait() { mCondition.wait(mLock); } - void signal() { mCondition.signal(); } -private: - Mutex mLock; - Condition mCondition; -}; - -typedef enum MppThreadSignal_e { - THREAD_WORK, - THREAD_RESET, - THREAD_QUE_DISPLAY, - THREAD_SIGNAL_BUTT, -} MppThreadSignal; - -#define THREAD_NORMAL 0 -#define THRE 0 - -class MppThread -{ -public: - MppThread(MppThreadFunc func, void *ctx, const char *name = NULL); - ~MppThread() {}; - - MppThreadStatus get_status(); - void set_status(MppThreadStatus status); - - void start(); - void stop(); - - void lock(MppThreadSignal id = THREAD_WORK) { - mpp_assert(id < THREAD_SIGNAL_BUTT); - mMutexCond[id].lock(); - } - - void unlock(MppThreadSignal id = THREAD_WORK) { - mpp_assert(id < THREAD_SIGNAL_BUTT); - mMutexCond[id].unlock(); - } - - void wait(MppThreadSignal id = THREAD_WORK) { - mpp_assert(id < THREAD_SIGNAL_BUTT); - mMutexCond[id].wait(); - } - - void signal(MppThreadSignal id = THREAD_WORK) { - mpp_assert(id < THREAD_SIGNAL_BUTT); - mMutexCond[id].signal(); - } - -private: - pthread_t mThread; - MppMutexCond mMutexCond[THREAD_SIGNAL_BUTT]; - - MppThreadStatus mStatus; - MppThreadFunc mFunction; - char mName[THREAD_NAME_LEN]; - void *mContext; - - MppThread(); - MppThread(const MppThread &); - MppThread &operator=(const MppThread &); -}; - -#endif - -#endif /*__MPP_THREAD_H__*/ +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * File : mpp_thread.h + * Description : thread library for different OS + * Author : herman.chen@rock-chips.com + * Date : 9:47 2015/7/27 + */ + +#ifndef __MPP_THREAD_H__ +#define __MPP_THREAD_H__ + +#if defined(_WIN32) && !defined(__MINGW32CE__) + +/* + * NOTE: POSIX Threads for Win32 + * Downloaded from http://www.sourceware.org/pthreads-win32/ + */ +#include "semaphore.h" +#include "pthread.h" +#pragma comment(lib, "pthreadVC2.lib") + +/* + * add pthread_setname_np for windows + */ +int pthread_setname_np(pthread_t thread, const char *name); + +#else + +#include +#include +#include + +#ifndef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP +#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP PTHREAD_RECURSIVE_MUTEX_INITIALIZER +#endif + +#endif + +#define THREAD_NAME_LEN 16 + +typedef void *(*MppThreadFunc)(void *); + +typedef enum { + MPP_THREAD_UNINITED, + MPP_THREAD_RUNNING, + MPP_THREAD_WAITING, + MPP_THREAD_STOPPING, +} MppThreadStatus; + +#ifdef __cplusplus + +#include "mpp_log.h" + +class Mutex; +class Condition; + +/* + * for shorter type name and function name + */ +class Mutex +{ +public: + Mutex(); + ~Mutex(); + + void lock(); + void unlock(); + int trylock(); + + class Autolock + { + public: + inline Autolock(Mutex& mutex) : mLock(mutex) { mLock.lock(); } + inline Autolock(Mutex* mutex) : mLock(*mutex) { mLock.lock(); } + inline ~Autolock() { mLock.unlock(); } + private: + Mutex& mLock; + }; + +private: + friend class Condition; + + pthread_mutex_t mMutex; + + Mutex(const Mutex &); + Mutex &operator = (const Mutex&); +}; + +inline Mutex::Mutex() +{ + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&mMutex, &attr); + pthread_mutexattr_destroy(&attr); +} +inline Mutex::~Mutex() +{ + pthread_mutex_destroy(&mMutex); +} +inline void Mutex::lock() +{ + pthread_mutex_lock(&mMutex); +} +inline void Mutex::unlock() +{ + pthread_mutex_unlock(&mMutex); +} +inline int Mutex::trylock() +{ + return pthread_mutex_trylock(&mMutex); +} + +typedef Mutex::Autolock AutoMutex; + + +/* + * for shorter type name and function name + */ +class Condition +{ +public: + Condition(); + Condition(int type); + ~Condition(); + void wait(Mutex& mutex); + void timedwait(Mutex& mutex, RK_S64 timeout); + void signal(); + +private: + pthread_cond_t mCond; +}; + +inline Condition::Condition() +{ + pthread_cond_init(&mCond, NULL); +} +inline Condition::~Condition() +{ + pthread_cond_destroy(&mCond); +} +inline void Condition::wait(Mutex& mutex) +{ + pthread_cond_wait(&mCond, &mutex.mMutex); +} +inline void Condition::timedwait(Mutex& mutex, RK_S64 timeout) +{ + struct timespec time; + time.tv_sec = (time_t)(timeout >> 32); + time.tv_nsec = (long)timeout; + pthread_cond_timedwait(&mCond, &mutex.mMutex, &time); +} +inline void Condition::signal() +{ + pthread_cond_signal(&mCond); +} + +class MppMutexCond +{ +public: + MppMutexCond() {}; + ~MppMutexCond() {}; + + void lock() { mLock.lock(); } + void unlock() { mLock.unlock(); } + void wait() { mCondition.wait(mLock); } + void signal() { mCondition.signal(); } +private: + Mutex mLock; + Condition mCondition; +}; + +typedef enum MppThreadSignal_e { + THREAD_WORK, + THREAD_RESET, + THREAD_QUE_DISPLAY, + THREAD_SIGNAL_BUTT, +} MppThreadSignal; + +#define THREAD_NORMAL 0 +#define THRE 0 + +class MppThread +{ +public: + MppThread(MppThreadFunc func, void *ctx, const char *name = NULL); + ~MppThread() {}; + + MppThreadStatus get_status(); + void set_status(MppThreadStatus status); + + void start(); + void stop(); + + void lock(MppThreadSignal id = THREAD_WORK) { + mpp_assert(id < THREAD_SIGNAL_BUTT); + mMutexCond[id].lock(); + } + + void unlock(MppThreadSignal id = THREAD_WORK) { + mpp_assert(id < THREAD_SIGNAL_BUTT); + mMutexCond[id].unlock(); + } + + void wait(MppThreadSignal id = THREAD_WORK) { + mpp_assert(id < THREAD_SIGNAL_BUTT); + mMutexCond[id].wait(); + } + + void signal(MppThreadSignal id = THREAD_WORK) { + mpp_assert(id < THREAD_SIGNAL_BUTT); + mMutexCond[id].signal(); + } + +private: + pthread_t mThread; + MppMutexCond mMutexCond[THREAD_SIGNAL_BUTT]; + + MppThreadStatus mStatus; + MppThreadFunc mFunction; + char mName[THREAD_NAME_LEN]; + void *mContext; + + MppThread(); + MppThread(const MppThread &); + MppThread &operator=(const MppThread &); +}; + +#endif + +#endif /*__MPP_THREAD_H__*/ diff --git a/osal/inc/mpp_time.h b/osal/inc/mpp_time.h index 53078964..0c6d1d8c 100644 --- a/osal/inc/mpp_time.h +++ b/osal/inc/mpp_time.h @@ -1,45 +1,45 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __MPP_TIME_H__ -#define __MPP_TIME_H__ - -#include "rk_type.h" - -// TODO: add usleep function on windows - -#if defined(_WIN32) && !defined(__MINGW32CE__) -#include -#define msleep Sleep -#define sleep(x) Sleep((x)*1000) -#else -#include -#define msleep(x) usleep((x)*1000) -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -RK_S64 mpp_time(); -void mpp_time_diff(RK_S64 start, RK_S64 end, RK_S64 limit, char *fmt); - -#ifdef __cplusplus -} -#endif - -#endif /*__MPP_TIME_H__*/ - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPP_TIME_H__ +#define __MPP_TIME_H__ + +#include "rk_type.h" + +// TODO: add usleep function on windows + +#if defined(_WIN32) && !defined(__MINGW32CE__) +#include +#define msleep Sleep +#define sleep(x) Sleep((x)*1000) +#else +#include +#define msleep(x) usleep((x)*1000) +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +RK_S64 mpp_time(); +void mpp_time_diff(RK_S64 start, RK_S64 end, RK_S64 limit, char *fmt); + +#ifdef __cplusplus +} +#endif + +#endif /*__MPP_TIME_H__*/ + diff --git a/osal/linux/os_allocator.c b/osal/linux/os_allocator.c index 8b532cf0..28ec54f0 100644 --- a/osal/linux/os_allocator.c +++ b/osal/linux/os_allocator.c @@ -1,160 +1,160 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include - -#include "os_mem.h" -#include "os_allocator.h" - -#include "allocator_drm.h" -#include "allocator_ion.h" - -#include "mpp_mem.h" -#include "mpp_log.h" - -/* - * Linux only support MPP_BUFFER_TYPE_NORMAL so far - * we can support MPP_BUFFER_TYPE_V4L2 later - */ -typedef struct { - size_t alignment; - RK_S32 fd_count; -} allocator_ctx; - -MPP_RET os_allocator_normal_open(void **ctx, size_t alignment) -{ - MPP_RET ret = MPP_OK; - allocator_ctx *p = NULL; - - if (NULL == ctx) { - mpp_err("os_allocator_open Linux do not accept NULL input\n"); - return MPP_ERR_NULL_PTR; - } - - p = mpp_malloc(allocator_ctx, 1); - if (NULL == p) { - mpp_err("os_allocator_open Linux failed to allocate context\n"); - ret = MPP_ERR_MALLOC; - } else - p->alignment = alignment; - - p->fd_count = 0; - - *ctx = p; - return ret; -} - -MPP_RET os_allocator_normal_alloc(void *ctx, MppBufferInfo *info) -{ - allocator_ctx *p = NULL; - - if (NULL == ctx) { - mpp_err("os_allocator_alloc Linux found NULL context input\n"); - return MPP_ERR_NULL_PTR; - } - - p = (allocator_ctx *)ctx; - info->fd = p->fd_count++; - return os_malloc(&info->ptr, p->alignment, info->size); -} - -MPP_RET os_allocator_normal_free(void *ctx, MppBufferInfo *info) -{ - (void) ctx; - if (info->ptr) - os_free(info->ptr); - return MPP_OK; -} - -MPP_RET os_allocator_normal_import(void *ctx, MppBufferInfo *info) -{ - allocator_ctx *p = (allocator_ctx *)ctx; - mpp_assert(ctx); - mpp_assert(info->ptr); - mpp_assert(info->size); - info->hnd = NULL; - info->fd = p->fd_count++; - return MPP_OK; -} - -MPP_RET os_allocator_normal_release(void *ctx, MppBufferInfo *info) -{ - (void) ctx; - mpp_assert(info->ptr); - mpp_assert(info->size); - info->ptr = NULL; - info->size = 0; - info->hnd = NULL; - info->fd = -1; - return MPP_OK; -} - -MPP_RET os_allocator_normal_close(void *ctx) -{ - if (ctx) { - mpp_free(ctx); - return MPP_OK; - } - mpp_err("os_allocator_close Linux found NULL context input\n"); - return MPP_NOK; -} - -static os_allocator allocator_normal = { - os_allocator_normal_open, - os_allocator_normal_alloc, - os_allocator_normal_free, - os_allocator_normal_import, - os_allocator_normal_release, - os_allocator_normal_close, -}; - -static os_allocator allocator_v4l2 = { - os_allocator_normal_open, - os_allocator_normal_alloc, - os_allocator_normal_free, - os_allocator_normal_import, - os_allocator_normal_release, - os_allocator_normal_close, -}; - -MPP_RET os_allocator_get(os_allocator *api, MppBufferType type) -{ - MPP_RET ret = MPP_OK; - switch (type) { - case MPP_BUFFER_TYPE_NORMAL : { - *api = allocator_normal; - } break; - case MPP_BUFFER_TYPE_ION : { -#ifdef RKPLATFORM - *api = allocator_ion; -#else - *api = allocator_normal; -#endif - } break; - case MPP_BUFFER_TYPE_V4L2 : { - mpp_err("os_allocator_get Linux MPP_BUFFER_TYPE_V4L2 do not implement yet\n"); - *api = allocator_v4l2; - } break; - case MPP_BUFFER_TYPE_DRM : { - *api = allocator_drm; - } break; - default : { - ret = MPP_NOK; - } break; - } - return ret; -} - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "os_mem.h" +#include "os_allocator.h" + +#include "allocator_drm.h" +#include "allocator_ion.h" + +#include "mpp_mem.h" +#include "mpp_log.h" + +/* + * Linux only support MPP_BUFFER_TYPE_NORMAL so far + * we can support MPP_BUFFER_TYPE_V4L2 later + */ +typedef struct { + size_t alignment; + RK_S32 fd_count; +} allocator_ctx; + +MPP_RET os_allocator_normal_open(void **ctx, size_t alignment) +{ + MPP_RET ret = MPP_OK; + allocator_ctx *p = NULL; + + if (NULL == ctx) { + mpp_err("os_allocator_open Linux do not accept NULL input\n"); + return MPP_ERR_NULL_PTR; + } + + p = mpp_malloc(allocator_ctx, 1); + if (NULL == p) { + mpp_err("os_allocator_open Linux failed to allocate context\n"); + ret = MPP_ERR_MALLOC; + } else + p->alignment = alignment; + + p->fd_count = 0; + + *ctx = p; + return ret; +} + +MPP_RET os_allocator_normal_alloc(void *ctx, MppBufferInfo *info) +{ + allocator_ctx *p = NULL; + + if (NULL == ctx) { + mpp_err("os_allocator_alloc Linux found NULL context input\n"); + return MPP_ERR_NULL_PTR; + } + + p = (allocator_ctx *)ctx; + info->fd = p->fd_count++; + return os_malloc(&info->ptr, p->alignment, info->size); +} + +MPP_RET os_allocator_normal_free(void *ctx, MppBufferInfo *info) +{ + (void) ctx; + if (info->ptr) + os_free(info->ptr); + return MPP_OK; +} + +MPP_RET os_allocator_normal_import(void *ctx, MppBufferInfo *info) +{ + allocator_ctx *p = (allocator_ctx *)ctx; + mpp_assert(ctx); + mpp_assert(info->ptr); + mpp_assert(info->size); + info->hnd = NULL; + info->fd = p->fd_count++; + return MPP_OK; +} + +MPP_RET os_allocator_normal_release(void *ctx, MppBufferInfo *info) +{ + (void) ctx; + mpp_assert(info->ptr); + mpp_assert(info->size); + info->ptr = NULL; + info->size = 0; + info->hnd = NULL; + info->fd = -1; + return MPP_OK; +} + +MPP_RET os_allocator_normal_close(void *ctx) +{ + if (ctx) { + mpp_free(ctx); + return MPP_OK; + } + mpp_err("os_allocator_close Linux found NULL context input\n"); + return MPP_NOK; +} + +static os_allocator allocator_normal = { + os_allocator_normal_open, + os_allocator_normal_alloc, + os_allocator_normal_free, + os_allocator_normal_import, + os_allocator_normal_release, + os_allocator_normal_close, +}; + +static os_allocator allocator_v4l2 = { + os_allocator_normal_open, + os_allocator_normal_alloc, + os_allocator_normal_free, + os_allocator_normal_import, + os_allocator_normal_release, + os_allocator_normal_close, +}; + +MPP_RET os_allocator_get(os_allocator *api, MppBufferType type) +{ + MPP_RET ret = MPP_OK; + switch (type) { + case MPP_BUFFER_TYPE_NORMAL : { + *api = allocator_normal; + } break; + case MPP_BUFFER_TYPE_ION : { +#ifdef RKPLATFORM + *api = allocator_ion; +#else + *api = allocator_normal; +#endif + } break; + case MPP_BUFFER_TYPE_V4L2 : { + mpp_err("os_allocator_get Linux MPP_BUFFER_TYPE_V4L2 do not implement yet\n"); + *api = allocator_v4l2; + } break; + case MPP_BUFFER_TYPE_DRM : { + *api = allocator_drm; + } break; + default : { + ret = MPP_NOK; + } break; + } + return ret; +} + diff --git a/osal/linux/os_env.c b/osal/linux/os_env.c index 6c9f05bb..94e611ad 100644 --- a/osal/linux/os_env.c +++ b/osal/linux/os_env.c @@ -1,63 +1,63 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include "os_env.h" - -#define ENV_BUF_SIZE_LINUX 1024 - -RK_S32 os_get_env_u32(const char *name, RK_U32 *value, RK_U32 default_value) -{ - char *ptr = getenv(name); - if (NULL == ptr) { - *value = default_value; - } else { - char *endptr; - int base = (ptr[0] == '0' && ptr[1] == 'x') ? (16) : (10); - errno = 0; - *value = strtoul(ptr, &endptr, base); - if (errno || (ptr == endptr)) { - errno = 0; - *value = default_value; - } - } - return 0; -} - -RK_S32 os_get_env_str(const char *name, char **value, char *default_value) -{ - *value = getenv(name); - if (NULL == *value) { - *value = default_value; - } - return 0; -} - -RK_S32 os_set_env_u32(const char *name, RK_U32 value) -{ - char buf[ENV_BUF_SIZE_LINUX]; - snprintf(buf, sizeof(buf), "%u", value); - return setenv(name, buf, 1); -} - -RK_S32 os_set_env_str(const char *name, char *value) -{ - return setenv(name, value, 1); -} - - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include "os_env.h" + +#define ENV_BUF_SIZE_LINUX 1024 + +RK_S32 os_get_env_u32(const char *name, RK_U32 *value, RK_U32 default_value) +{ + char *ptr = getenv(name); + if (NULL == ptr) { + *value = default_value; + } else { + char *endptr; + int base = (ptr[0] == '0' && ptr[1] == 'x') ? (16) : (10); + errno = 0; + *value = strtoul(ptr, &endptr, base); + if (errno || (ptr == endptr)) { + errno = 0; + *value = default_value; + } + } + return 0; +} + +RK_S32 os_get_env_str(const char *name, char **value, char *default_value) +{ + *value = getenv(name); + if (NULL == *value) { + *value = default_value; + } + return 0; +} + +RK_S32 os_set_env_u32(const char *name, RK_U32 value) +{ + char buf[ENV_BUF_SIZE_LINUX]; + snprintf(buf, sizeof(buf), "%u", value); + return setenv(name, buf, 1); +} + +RK_S32 os_set_env_str(const char *name, char *value) +{ + return setenv(name, value, 1); +} + + diff --git a/osal/linux/os_log.c b/osal/linux/os_log.c index 18658a46..d43ff83f 100644 --- a/osal/linux/os_log.c +++ b/osal/linux/os_log.c @@ -1,35 +1,35 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include - -#define LINE_SZ 1024 - -void os_log(const char* tag, const char* msg, va_list list) -{ - char line[LINE_SZ] = {0}; - snprintf(line, sizeof(line), "%s: %s", tag, msg); - vfprintf(stdout, line, list); -} - -void os_err(const char* tag, const char* msg, va_list list) -{ - char line[LINE_SZ] = {0}; - snprintf(line, sizeof(line), "%s: %s", tag, msg); - vfprintf(stderr, line, list); -} - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#define LINE_SZ 1024 + +void os_log(const char* tag, const char* msg, va_list list) +{ + char line[LINE_SZ] = {0}; + snprintf(line, sizeof(line), "%s: %s", tag, msg); + vfprintf(stdout, line, list); +} + +void os_err(const char* tag, const char* msg, va_list list) +{ + char line[LINE_SZ] = {0}; + snprintf(line, sizeof(line), "%s: %s", tag, msg); + vfprintf(stderr, line, list); +} + diff --git a/osal/linux/os_mem.c b/osal/linux/os_mem.c index 4534f381..d4789dae 100644 --- a/osal/linux/os_mem.c +++ b/osal/linux/os_mem.c @@ -1,36 +1,36 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include "os_mem.h" - -int os_malloc(void **memptr, size_t alignment, size_t size) -{ - return posix_memalign(memptr, alignment, size); -} - -int os_realloc(void *src, void **dst, size_t alignment, size_t size) -{ - (void)alignment; - *dst = realloc(src, size); - return (*dst) ? (0) : (-1); -} - -void os_free(void *ptr) -{ - free(ptr); -} - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "os_mem.h" + +int os_malloc(void **memptr, size_t alignment, size_t size) +{ + return posix_memalign(memptr, alignment, size); +} + +int os_realloc(void *src, void **dst, size_t alignment, size_t size) +{ + (void)alignment; + *dst = realloc(src, size); + return (*dst) ? (0) : (-1); +} + +void os_free(void *ptr) +{ + free(ptr); +} + diff --git a/osal/mpp_allocator.cpp b/osal/mpp_allocator.cpp index 3ce07f5f..22a65762 100644 --- a/osal/mpp_allocator.cpp +++ b/osal/mpp_allocator.cpp @@ -1,168 +1,168 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define MODULE_TAG "mpp_allocator" - -#include "mpp_log.h" -#include "mpp_mem.h" -#include "mpp_allocator.h" -#include "mpp_allocator_impl.h" - -#include "os_allocator.h" - -#define MPP_ALLOCATOR_LOCK(p) pthread_mutex_lock(&(p)->lock); -#define MPP_ALLOCATOR_UNLOCK(p) pthread_mutex_unlock(&(p)->lock); - -MPP_RET mpp_allocator_alloc(MppAllocator allocator, MppBufferInfo *info) -{ - if (NULL == allocator || NULL == info) { - mpp_err_f("invalid input: allocator %p info %p\n", - allocator, info); - return MPP_ERR_UNKNOW; - } - - MPP_RET ret = MPP_NOK; - MppAllocatorImpl *p = (MppAllocatorImpl *)allocator; - MPP_ALLOCATOR_LOCK(p); - if (p->os_api.alloc && p->ctx) - ret = p->os_api.alloc(p->ctx, info); - MPP_ALLOCATOR_UNLOCK(p); - - return ret; -} - -MPP_RET mpp_allocator_free(MppAllocator allocator, MppBufferInfo *info) -{ - if (NULL == allocator || NULL == info) { - mpp_err_f("invalid input: allocator %p info %p\n", - allocator, info); - return MPP_ERR_UNKNOW; - } - - MPP_RET ret = MPP_NOK; - MppAllocatorImpl *p = (MppAllocatorImpl *)allocator; - MPP_ALLOCATOR_LOCK(p); - if (p->os_api.free && p->ctx) - ret = p->os_api.free(p->ctx, info); - MPP_ALLOCATOR_UNLOCK(p); - - return ret; -} - -MPP_RET mpp_allocator_import(MppAllocator allocator, MppBufferInfo *info) -{ - if (NULL == info) { - mpp_err_f("invalid input: info %p\n", info); - return MPP_ERR_UNKNOW; - } - - MPP_RET ret = MPP_NOK; - MppAllocatorImpl *p = (MppAllocatorImpl *)allocator; - MPP_ALLOCATOR_LOCK(p); - if (p->os_api.import && p->ctx) { - ret = p->os_api.import(p->ctx, info); - } - MPP_ALLOCATOR_UNLOCK(p); - - return ret; -} - - -MPP_RET mpp_allocator_release(MppAllocator allocator, MppBufferInfo *info) -{ - if (NULL == allocator || NULL == info) { - mpp_err_f("invalid input: allocator %p info %p\n", - allocator, info); - return MPP_ERR_UNKNOW; - } - - MPP_RET ret = MPP_NOK; - MppAllocatorImpl *p = (MppAllocatorImpl *)allocator; - MPP_ALLOCATOR_LOCK(p); - if (p->os_api.release && p->ctx) { - ret = p->os_api.release(p->ctx, info); - } - MPP_ALLOCATOR_UNLOCK(p); - - return ret; -} - -static MppAllocatorApi mpp_allocator_api = { - sizeof(mpp_allocator_api), - 1, - mpp_allocator_alloc, - mpp_allocator_free, - mpp_allocator_import, - mpp_allocator_release, -}; - -MPP_RET mpp_allocator_get(MppAllocator *allocator, MppAllocatorApi **api, MppBufferType type) -{ - if (NULL == allocator || NULL == api || type >= MPP_BUFFER_TYPE_BUTT) { - mpp_err_f("invalid input: allocator %p api %p type %d\n", - allocator, api, type); - return MPP_ERR_UNKNOW; - } - - MppAllocatorImpl *p = mpp_malloc(MppAllocatorImpl, 1); - if (NULL == p) { - mpp_err("mpp_allocator_get failed to malloc allocator context\n"); - return MPP_ERR_NULL_PTR; - } else - p->type = type; - - - MPP_RET ret = os_allocator_get(&p->os_api, type); - if (MPP_OK == ret) { - p->alignment = SZ_4K; - ret = p->os_api.open(&p->ctx, p->alignment); - } - if (MPP_OK == ret) { - pthread_mutexattr_t attr; - pthread_mutexattr_init(&attr); - pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); - pthread_mutex_init(&p->lock, &attr); - pthread_mutexattr_destroy(&attr); - - *allocator = p; - *api = &mpp_allocator_api; - } else { - mpp_err("mpp_allocator_get type %d failed\n", type); - mpp_free(p); - *allocator = NULL; - *api = NULL; - } - - return ret; -} - -MPP_RET mpp_allocator_put(MppAllocator *allocator) -{ - if (NULL == allocator) { - mpp_err_f("invalid input: allocator %p\n", allocator); - return MPP_ERR_NULL_PTR; - } - - MppAllocatorImpl *p = (MppAllocatorImpl *)*allocator; - *allocator = NULL; - if (p->os_api.close && p->ctx) - p->os_api.close(p->ctx); - pthread_mutex_destroy(&p->lock); - mpp_free(p); - - return MPP_OK; -} - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define MODULE_TAG "mpp_allocator" + +#include "mpp_log.h" +#include "mpp_mem.h" +#include "mpp_allocator.h" +#include "mpp_allocator_impl.h" + +#include "os_allocator.h" + +#define MPP_ALLOCATOR_LOCK(p) pthread_mutex_lock(&(p)->lock); +#define MPP_ALLOCATOR_UNLOCK(p) pthread_mutex_unlock(&(p)->lock); + +MPP_RET mpp_allocator_alloc(MppAllocator allocator, MppBufferInfo *info) +{ + if (NULL == allocator || NULL == info) { + mpp_err_f("invalid input: allocator %p info %p\n", + allocator, info); + return MPP_ERR_UNKNOW; + } + + MPP_RET ret = MPP_NOK; + MppAllocatorImpl *p = (MppAllocatorImpl *)allocator; + MPP_ALLOCATOR_LOCK(p); + if (p->os_api.alloc && p->ctx) + ret = p->os_api.alloc(p->ctx, info); + MPP_ALLOCATOR_UNLOCK(p); + + return ret; +} + +MPP_RET mpp_allocator_free(MppAllocator allocator, MppBufferInfo *info) +{ + if (NULL == allocator || NULL == info) { + mpp_err_f("invalid input: allocator %p info %p\n", + allocator, info); + return MPP_ERR_UNKNOW; + } + + MPP_RET ret = MPP_NOK; + MppAllocatorImpl *p = (MppAllocatorImpl *)allocator; + MPP_ALLOCATOR_LOCK(p); + if (p->os_api.free && p->ctx) + ret = p->os_api.free(p->ctx, info); + MPP_ALLOCATOR_UNLOCK(p); + + return ret; +} + +MPP_RET mpp_allocator_import(MppAllocator allocator, MppBufferInfo *info) +{ + if (NULL == info) { + mpp_err_f("invalid input: info %p\n", info); + return MPP_ERR_UNKNOW; + } + + MPP_RET ret = MPP_NOK; + MppAllocatorImpl *p = (MppAllocatorImpl *)allocator; + MPP_ALLOCATOR_LOCK(p); + if (p->os_api.import && p->ctx) { + ret = p->os_api.import(p->ctx, info); + } + MPP_ALLOCATOR_UNLOCK(p); + + return ret; +} + + +MPP_RET mpp_allocator_release(MppAllocator allocator, MppBufferInfo *info) +{ + if (NULL == allocator || NULL == info) { + mpp_err_f("invalid input: allocator %p info %p\n", + allocator, info); + return MPP_ERR_UNKNOW; + } + + MPP_RET ret = MPP_NOK; + MppAllocatorImpl *p = (MppAllocatorImpl *)allocator; + MPP_ALLOCATOR_LOCK(p); + if (p->os_api.release && p->ctx) { + ret = p->os_api.release(p->ctx, info); + } + MPP_ALLOCATOR_UNLOCK(p); + + return ret; +} + +static MppAllocatorApi mpp_allocator_api = { + sizeof(mpp_allocator_api), + 1, + mpp_allocator_alloc, + mpp_allocator_free, + mpp_allocator_import, + mpp_allocator_release, +}; + +MPP_RET mpp_allocator_get(MppAllocator *allocator, MppAllocatorApi **api, MppBufferType type) +{ + if (NULL == allocator || NULL == api || type >= MPP_BUFFER_TYPE_BUTT) { + mpp_err_f("invalid input: allocator %p api %p type %d\n", + allocator, api, type); + return MPP_ERR_UNKNOW; + } + + MppAllocatorImpl *p = mpp_malloc(MppAllocatorImpl, 1); + if (NULL == p) { + mpp_err("mpp_allocator_get failed to malloc allocator context\n"); + return MPP_ERR_NULL_PTR; + } else + p->type = type; + + + MPP_RET ret = os_allocator_get(&p->os_api, type); + if (MPP_OK == ret) { + p->alignment = SZ_4K; + ret = p->os_api.open(&p->ctx, p->alignment); + } + if (MPP_OK == ret) { + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&p->lock, &attr); + pthread_mutexattr_destroy(&attr); + + *allocator = p; + *api = &mpp_allocator_api; + } else { + mpp_err("mpp_allocator_get type %d failed\n", type); + mpp_free(p); + *allocator = NULL; + *api = NULL; + } + + return ret; +} + +MPP_RET mpp_allocator_put(MppAllocator *allocator) +{ + if (NULL == allocator) { + mpp_err_f("invalid input: allocator %p\n", allocator); + return MPP_ERR_NULL_PTR; + } + + MppAllocatorImpl *p = (MppAllocatorImpl *)*allocator; + *allocator = NULL; + if (p->os_api.close && p->ctx) + p->os_api.close(p->ctx); + pthread_mutex_destroy(&p->lock); + mpp_free(p); + + return MPP_OK; +} + diff --git a/osal/mpp_allocator_impl.h b/osal/mpp_allocator_impl.h index 3fddf611..9fd098c4 100644 --- a/osal/mpp_allocator_impl.h +++ b/osal/mpp_allocator_impl.h @@ -1,32 +1,32 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __MPP_ALLOCATOR_IMPL_H__ -#define __MPP_ALLOCATOR_IMPL_H__ - -#include "mpp_thread.h" -#include "os_allocator.h" - -typedef struct MppAllocatorImpl_t { - pthread_mutex_t lock; - MppBufferType type; - size_t alignment; - os_allocator os_api; - void *ctx; -} MppAllocatorImpl; - -#endif /*__MPP_ALLOCATOR_IMPL_H__*/ - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MPP_ALLOCATOR_IMPL_H__ +#define __MPP_ALLOCATOR_IMPL_H__ + +#include "mpp_thread.h" +#include "os_allocator.h" + +typedef struct MppAllocatorImpl_t { + pthread_mutex_t lock; + MppBufferType type; + size_t alignment; + os_allocator os_api; + void *ctx; +} MppAllocatorImpl; + +#endif /*__MPP_ALLOCATOR_IMPL_H__*/ + diff --git a/osal/mpp_common.cpp b/osal/mpp_common.cpp index ca7f893f..39f2eb4c 100644 --- a/osal/mpp_common.cpp +++ b/osal/mpp_common.cpp @@ -1,57 +1,57 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "mpp_common.h" - -static const RK_U8 log2_tab[256] = { - 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 -}; - -RK_S32 mpp_log2(RK_U32 v) -{ - RK_S32 n = 0; - if (v & 0xffff0000) { - v >>= 16; - n += 16; - } - if (v & 0xff00) { - v >>= 8; - n += 8; - } - n += log2_tab[v]; - - return n; -} - -RK_S32 mpp_log2_16bit(RK_U32 v) -{ - RK_S32 n = 0; - if (v & 0xff00) { - v >>= 8; - n += 8; - } - n += log2_tab[v]; - - return n; -} - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mpp_common.h" + +static const RK_U8 log2_tab[256] = { + 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 +}; + +RK_S32 mpp_log2(RK_U32 v) +{ + RK_S32 n = 0; + if (v & 0xffff0000) { + v >>= 16; + n += 16; + } + if (v & 0xff00) { + v >>= 8; + n += 8; + } + n += log2_tab[v]; + + return n; +} + +RK_S32 mpp_log2_16bit(RK_U32 v) +{ + RK_S32 n = 0; + if (v & 0xff00) { + v >>= 8; + n += 8; + } + n += log2_tab[v]; + + return n; +} + diff --git a/osal/mpp_env.cpp b/osal/mpp_env.cpp index 554561e0..98d98170 100644 --- a/osal/mpp_env.cpp +++ b/osal/mpp_env.cpp @@ -1,42 +1,42 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "mpp_env.h" -#include "os_env.h" - -// TODO: add previous value compare to save call times - -RK_S32 mpp_env_get_u32(const char *name, RK_U32 *value, RK_U32 default_value) -{ - return os_get_env_u32(name, value, default_value); -} - -RK_S32 mpp_env_get_str(const char *name, char **value, char *default_value) -{ - return os_get_env_str(name, value, default_value); -} - -RK_S32 mpp_env_set_u32(const char *name, RK_U32 value) -{ - return os_set_env_u32(name, value); -} - -RK_S32 mpp_env_set_str(const char *name, char *value) -{ - return os_set_env_str(name, value); -} - - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mpp_env.h" +#include "os_env.h" + +// TODO: add previous value compare to save call times + +RK_S32 mpp_env_get_u32(const char *name, RK_U32 *value, RK_U32 default_value) +{ + return os_get_env_u32(name, value, default_value); +} + +RK_S32 mpp_env_get_str(const char *name, char **value, char *default_value) +{ + return os_get_env_str(name, value, default_value); +} + +RK_S32 mpp_env_set_u32(const char *name, RK_U32 value) +{ + return os_set_env_u32(name, value); +} + +RK_S32 mpp_env_set_str(const char *name, char *value) +{ + return os_set_env_str(name, value); +} + + diff --git a/osal/mpp_mem.cpp b/osal/mpp_mem.cpp index 7067b510..3d4937e9 100644 --- a/osal/mpp_mem.cpp +++ b/osal/mpp_mem.cpp @@ -1,300 +1,300 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define MODULE_TAG "mpp_mem" - -#include - -#include "rk_type.h" -#include "mpp_err.h" - -#include "mpp_log.h" -#include "mpp_env.h" -#include "mpp_mem.h" -#include "mpp_list.h" -#include "mpp_common.h" - -#include "os_mem.h" - -// mpp_mem_flag bit mask -#define OSAL_MEM_LIST_EN (0x00000001) -#define OSAL_MEM_RUNTIME_LOG (0x00000002) - -// default memory align size is set to 32 -#define RK_OSAL_MEM_ALIGN 32 - -static RK_U32 mpp_mem_flag = 0; -static RK_U64 osal_mem_index = 0; -static struct list_head mem_list; -static pthread_mutex_t mem_list_lock; - -struct mem_node { - struct list_head list; - void *ptr; - size_t size; - RK_U64 index; - - /* memory node extra information */ - char tag[MPP_TAG_SIZE]; -}; - -static void get_osal_mem_flag() -{ - static RK_U32 once = 1; - if (once) { - mpp_env_get_u32("mpp_mem_flag", &mpp_mem_flag, 0); - - INIT_LIST_HEAD(&mem_list); - - pthread_mutexattr_t attr; - pthread_mutexattr_init(&attr); - pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); - pthread_mutex_init(&mem_list_lock, &attr); - pthread_mutexattr_destroy(&attr); - once = 0; - } -} - -void *mpp_osal_malloc(const char *tag, size_t size) -{ - void *ptr; - - get_osal_mem_flag(); - - os_malloc(&ptr, RK_OSAL_MEM_ALIGN, size); - - if (mpp_mem_flag & OSAL_MEM_RUNTIME_LOG) - mpp_log("mpp_malloc tag %-16s size %-8u ret %p\n", tag, size, ptr); - - if ((mpp_mem_flag & OSAL_MEM_LIST_EN) && ptr) { - struct mem_node *node = (struct mem_node *)malloc(sizeof(struct mem_node)); - mpp_assert(node); - INIT_LIST_HEAD(&node->list); - node->ptr = ptr; - node->size = size; - snprintf(node->tag, sizeof(node->tag), "%s", tag); - - pthread_mutex_lock(&mem_list_lock); - node->index = osal_mem_index++; - list_add_tail(&node->list, &mem_list); - pthread_mutex_unlock(&mem_list_lock); - } - - return ptr; -} - -void *mpp_osal_calloc(const char *tag, size_t size) -{ - void *ptr = mpp_osal_malloc(tag, size); - if (ptr) - memset(ptr, 0, size); - return ptr; -} - -void *mpp_osal_realloc(const char *tag, void *ptr, size_t size) -{ - void *ret; - - if (NULL == ptr) - return mpp_osal_malloc(tag, size); - - if (0 == size) - return NULL; - - get_osal_mem_flag(); - - if (mpp_mem_flag & OSAL_MEM_LIST_EN) { - struct mem_node *pos, *n; - - ret = NULL; - pthread_mutex_lock(&mem_list_lock); - list_for_each_entry_safe(pos, n, &mem_list, struct mem_node, list) { - if (ptr == pos->ptr) { - if (MPP_OK == os_realloc(ptr, &pos->ptr, RK_OSAL_MEM_ALIGN, size)) { - pos->size = size; - strncpy(pos->tag, tag, sizeof(pos->tag)); - ret = pos->ptr; - } else { - list_del_init(&pos->list); - free(pos); - } - break; - } - } - pthread_mutex_unlock(&mem_list_lock); - } else { - os_realloc(ptr, &ret, RK_OSAL_MEM_ALIGN, size); - } - - if (mpp_mem_flag & OSAL_MEM_RUNTIME_LOG) - mpp_log("mpp_realloc tag %-16s size %-8u ptr %p ret %p\n", tag, size, ptr, ret); - - if (NULL == ret) - mpp_err("mpp_realloc ptr %p to size %d failed\n", ptr, size); - - return ret; -} - -void mpp_osal_free(void *ptr) -{ - if (NULL == ptr) - return; - - get_osal_mem_flag(); - - if (mpp_mem_flag & OSAL_MEM_LIST_EN) { - struct mem_node *pos, *n; - RK_U32 found_match = 0; - - pthread_mutex_lock(&mem_list_lock); - list_for_each_entry_safe(pos, n, &mem_list, struct mem_node, list) { - if (ptr == pos->ptr) { - list_del_init(&pos->list); - free(pos); - found_match = 1; - break; - } - } - pthread_mutex_unlock(&mem_list_lock); - - if (!found_match) - mpp_err_f("can not found match on free %p\n", ptr); - } - - if (mpp_mem_flag & OSAL_MEM_RUNTIME_LOG) - mpp_log("mpp_free %p\n", ptr); - - os_free(ptr); -} - -/* - * dump memory status - * this function need MODULE_TAG statistic information - */ -void mpp_show_mem_status() -{ - struct mem_node *pos, *n; - - pthread_mutex_lock(&mem_list_lock); - list_for_each_entry_safe(pos, n, &mem_list, struct mem_node, list) { - mpp_log("unfree memory %p size %d tag %s index %llu", - pos->ptr, pos->size, pos->tag, pos->index); - } - pthread_mutex_unlock(&mem_list_lock); -} - -typedef struct MppMemSnapshotImpl { - struct list_head list; - RK_U64 total_size; - RK_U32 total_count; -} MppMemSnapshotImpl; - -MPP_RET mpp_mem_get_snapshot(MppMemSnapshot *hnd) -{ - struct mem_node *pos, *n; - MppMemSnapshotImpl *p = (MppMemSnapshotImpl *)malloc(sizeof(MppMemSnapshotImpl)); - if (!p) { - mpp_err_f("failed to alloc"); - *hnd = NULL; - return MPP_NOK; - } - - INIT_LIST_HEAD(&p->list); - p->total_size = 0; - p->total_count = 0; - - pthread_mutex_lock(&mem_list_lock); - list_for_each_entry_safe(pos, n, &mem_list, struct mem_node, list) { - struct mem_node *node = (struct mem_node *)malloc(sizeof(struct mem_node)); - mpp_assert(node); - - memcpy(node, pos, sizeof(*pos)); - INIT_LIST_HEAD(&node->list); - list_add_tail(&node->list, &p->list); - p->total_size += pos->size; - p->total_count++; - } - *hnd = p; - pthread_mutex_unlock(&mem_list_lock); - - return MPP_OK; -} - -MPP_RET mpp_mem_put_snapshot(MppMemSnapshot *hnd) -{ - if (hnd && *hnd) { - MppMemSnapshotImpl *p = (MppMemSnapshotImpl *)*hnd; - struct mem_node *pos, *n; - - pthread_mutex_lock(&mem_list_lock); - list_for_each_entry_safe(pos, n, &p->list, struct mem_node, list) { - list_del_init(&pos->list); - free(pos); - } - free(p); - *hnd = NULL; - pthread_mutex_unlock(&mem_list_lock); - } - - return MPP_OK; -} - -MPP_RET mpp_mem_squash_snapshot(MppMemSnapshot hnd0, MppMemSnapshot hnd1) -{ - if (!hnd0 || !hnd1) { - mpp_err_f("invalid input %p %p\n", hnd0, hnd1); - return MPP_NOK; - } - MppMemSnapshotImpl *p0 = (MppMemSnapshotImpl *)hnd0; - MppMemSnapshotImpl *p1 = (MppMemSnapshotImpl *)hnd1; - struct mem_node *pos0, *n0; - struct mem_node *pos1, *n1; - - mpp_log_f("snapshot0 total count %6d size %d\n", p0->total_count, p0->total_size); - mpp_log_f("snapshot1 total count %6d size %d\n", p1->total_count, p1->total_size); - - pthread_mutex_lock(&mem_list_lock); - /* handle 0 search */ - list_for_each_entry_safe(pos0, n0, &p0->list, struct mem_node, list) { - RK_U32 found_match = 0; - - list_for_each_entry_safe(pos1, n1, &p1->list, struct mem_node, list) { - if (pos0->index == pos1->index) { - list_del_init(&pos0->list); - list_del_init(&pos1->list); - free(pos0); - free(pos1); - found_match = 1; - break; - } - } - - if (!found_match) { - mpp_log_f("snapshot0 %p found mismatch memory %p size %d tag %s index %llu", - p0, pos0->ptr, pos0->size, pos0->tag, pos0->index); - } - } - - /* handle 1 search */ - list_for_each_entry_safe(pos1, n1, &p1->list, struct mem_node, list) { - mpp_log_f("snapshot1 %p found mismatch memory %p size %d tag %s index %llu", - p1, pos1->ptr, pos1->size, pos1->tag, pos1->index); - } - pthread_mutex_unlock(&mem_list_lock); - - return MPP_OK; -} - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define MODULE_TAG "mpp_mem" + +#include + +#include "rk_type.h" +#include "mpp_err.h" + +#include "mpp_log.h" +#include "mpp_env.h" +#include "mpp_mem.h" +#include "mpp_list.h" +#include "mpp_common.h" + +#include "os_mem.h" + +// mpp_mem_flag bit mask +#define OSAL_MEM_LIST_EN (0x00000001) +#define OSAL_MEM_RUNTIME_LOG (0x00000002) + +// default memory align size is set to 32 +#define RK_OSAL_MEM_ALIGN 32 + +static RK_U32 mpp_mem_flag = 0; +static RK_U64 osal_mem_index = 0; +static struct list_head mem_list; +static pthread_mutex_t mem_list_lock; + +struct mem_node { + struct list_head list; + void *ptr; + size_t size; + RK_U64 index; + + /* memory node extra information */ + char tag[MPP_TAG_SIZE]; +}; + +static void get_osal_mem_flag() +{ + static RK_U32 once = 1; + if (once) { + mpp_env_get_u32("mpp_mem_flag", &mpp_mem_flag, 0); + + INIT_LIST_HEAD(&mem_list); + + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&mem_list_lock, &attr); + pthread_mutexattr_destroy(&attr); + once = 0; + } +} + +void *mpp_osal_malloc(const char *tag, size_t size) +{ + void *ptr; + + get_osal_mem_flag(); + + os_malloc(&ptr, RK_OSAL_MEM_ALIGN, size); + + if (mpp_mem_flag & OSAL_MEM_RUNTIME_LOG) + mpp_log("mpp_malloc tag %-16s size %-8u ret %p\n", tag, size, ptr); + + if ((mpp_mem_flag & OSAL_MEM_LIST_EN) && ptr) { + struct mem_node *node = (struct mem_node *)malloc(sizeof(struct mem_node)); + mpp_assert(node); + INIT_LIST_HEAD(&node->list); + node->ptr = ptr; + node->size = size; + snprintf(node->tag, sizeof(node->tag), "%s", tag); + + pthread_mutex_lock(&mem_list_lock); + node->index = osal_mem_index++; + list_add_tail(&node->list, &mem_list); + pthread_mutex_unlock(&mem_list_lock); + } + + return ptr; +} + +void *mpp_osal_calloc(const char *tag, size_t size) +{ + void *ptr = mpp_osal_malloc(tag, size); + if (ptr) + memset(ptr, 0, size); + return ptr; +} + +void *mpp_osal_realloc(const char *tag, void *ptr, size_t size) +{ + void *ret; + + if (NULL == ptr) + return mpp_osal_malloc(tag, size); + + if (0 == size) + return NULL; + + get_osal_mem_flag(); + + if (mpp_mem_flag & OSAL_MEM_LIST_EN) { + struct mem_node *pos, *n; + + ret = NULL; + pthread_mutex_lock(&mem_list_lock); + list_for_each_entry_safe(pos, n, &mem_list, struct mem_node, list) { + if (ptr == pos->ptr) { + if (MPP_OK == os_realloc(ptr, &pos->ptr, RK_OSAL_MEM_ALIGN, size)) { + pos->size = size; + strncpy(pos->tag, tag, sizeof(pos->tag)); + ret = pos->ptr; + } else { + list_del_init(&pos->list); + free(pos); + } + break; + } + } + pthread_mutex_unlock(&mem_list_lock); + } else { + os_realloc(ptr, &ret, RK_OSAL_MEM_ALIGN, size); + } + + if (mpp_mem_flag & OSAL_MEM_RUNTIME_LOG) + mpp_log("mpp_realloc tag %-16s size %-8u ptr %p ret %p\n", tag, size, ptr, ret); + + if (NULL == ret) + mpp_err("mpp_realloc ptr %p to size %d failed\n", ptr, size); + + return ret; +} + +void mpp_osal_free(void *ptr) +{ + if (NULL == ptr) + return; + + get_osal_mem_flag(); + + if (mpp_mem_flag & OSAL_MEM_LIST_EN) { + struct mem_node *pos, *n; + RK_U32 found_match = 0; + + pthread_mutex_lock(&mem_list_lock); + list_for_each_entry_safe(pos, n, &mem_list, struct mem_node, list) { + if (ptr == pos->ptr) { + list_del_init(&pos->list); + free(pos); + found_match = 1; + break; + } + } + pthread_mutex_unlock(&mem_list_lock); + + if (!found_match) + mpp_err_f("can not found match on free %p\n", ptr); + } + + if (mpp_mem_flag & OSAL_MEM_RUNTIME_LOG) + mpp_log("mpp_free %p\n", ptr); + + os_free(ptr); +} + +/* + * dump memory status + * this function need MODULE_TAG statistic information + */ +void mpp_show_mem_status() +{ + struct mem_node *pos, *n; + + pthread_mutex_lock(&mem_list_lock); + list_for_each_entry_safe(pos, n, &mem_list, struct mem_node, list) { + mpp_log("unfree memory %p size %d tag %s index %llu", + pos->ptr, pos->size, pos->tag, pos->index); + } + pthread_mutex_unlock(&mem_list_lock); +} + +typedef struct MppMemSnapshotImpl { + struct list_head list; + RK_U64 total_size; + RK_U32 total_count; +} MppMemSnapshotImpl; + +MPP_RET mpp_mem_get_snapshot(MppMemSnapshot *hnd) +{ + struct mem_node *pos, *n; + MppMemSnapshotImpl *p = (MppMemSnapshotImpl *)malloc(sizeof(MppMemSnapshotImpl)); + if (!p) { + mpp_err_f("failed to alloc"); + *hnd = NULL; + return MPP_NOK; + } + + INIT_LIST_HEAD(&p->list); + p->total_size = 0; + p->total_count = 0; + + pthread_mutex_lock(&mem_list_lock); + list_for_each_entry_safe(pos, n, &mem_list, struct mem_node, list) { + struct mem_node *node = (struct mem_node *)malloc(sizeof(struct mem_node)); + mpp_assert(node); + + memcpy(node, pos, sizeof(*pos)); + INIT_LIST_HEAD(&node->list); + list_add_tail(&node->list, &p->list); + p->total_size += pos->size; + p->total_count++; + } + *hnd = p; + pthread_mutex_unlock(&mem_list_lock); + + return MPP_OK; +} + +MPP_RET mpp_mem_put_snapshot(MppMemSnapshot *hnd) +{ + if (hnd && *hnd) { + MppMemSnapshotImpl *p = (MppMemSnapshotImpl *)*hnd; + struct mem_node *pos, *n; + + pthread_mutex_lock(&mem_list_lock); + list_for_each_entry_safe(pos, n, &p->list, struct mem_node, list) { + list_del_init(&pos->list); + free(pos); + } + free(p); + *hnd = NULL; + pthread_mutex_unlock(&mem_list_lock); + } + + return MPP_OK; +} + +MPP_RET mpp_mem_squash_snapshot(MppMemSnapshot hnd0, MppMemSnapshot hnd1) +{ + if (!hnd0 || !hnd1) { + mpp_err_f("invalid input %p %p\n", hnd0, hnd1); + return MPP_NOK; + } + MppMemSnapshotImpl *p0 = (MppMemSnapshotImpl *)hnd0; + MppMemSnapshotImpl *p1 = (MppMemSnapshotImpl *)hnd1; + struct mem_node *pos0, *n0; + struct mem_node *pos1, *n1; + + mpp_log_f("snapshot0 total count %6d size %d\n", p0->total_count, p0->total_size); + mpp_log_f("snapshot1 total count %6d size %d\n", p1->total_count, p1->total_size); + + pthread_mutex_lock(&mem_list_lock); + /* handle 0 search */ + list_for_each_entry_safe(pos0, n0, &p0->list, struct mem_node, list) { + RK_U32 found_match = 0; + + list_for_each_entry_safe(pos1, n1, &p1->list, struct mem_node, list) { + if (pos0->index == pos1->index) { + list_del_init(&pos0->list); + list_del_init(&pos1->list); + free(pos0); + free(pos1); + found_match = 1; + break; + } + } + + if (!found_match) { + mpp_log_f("snapshot0 %p found mismatch memory %p size %d tag %s index %llu", + p0, pos0->ptr, pos0->size, pos0->tag, pos0->index); + } + } + + /* handle 1 search */ + list_for_each_entry_safe(pos1, n1, &p1->list, struct mem_node, list) { + mpp_log_f("snapshot1 %p found mismatch memory %p size %d tag %s index %llu", + p1, pos1->ptr, pos1->size, pos1->tag, pos1->index); + } + pthread_mutex_unlock(&mem_list_lock); + + return MPP_OK; +} + diff --git a/osal/mpp_thread.cpp b/osal/mpp_thread.cpp index 49322872..cee0ecf7 100644 --- a/osal/mpp_thread.cpp +++ b/osal/mpp_thread.cpp @@ -1,138 +1,138 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define MODULE_TAG "mpp_thread" - -#include - -#include "mpp_log.h" -#include "mpp_common.h" -#include "mpp_thread.h" - -#define MPP_THREAD_DBG_FUNCTION (0x00000001) - -static RK_U32 thread_debug = 0; - -#define thread_dbg(flag, fmt, ...) _mpp_dbg(thread_debug, flag, fmt, ## __VA_ARGS__) - -MppThread::MppThread(MppThreadFunc func, void *ctx, const char *name) - : mStatus(MPP_THREAD_UNINITED), - mFunction(func), - mContext(ctx) -{ - if (name) - strncpy(mName, name, sizeof(mName)); - else - snprintf(mName, sizeof(mName), "mpp_thread"); -} - -MppThreadStatus MppThread::get_status() -{ - return mStatus; -} -void MppThread::set_status(MppThreadStatus status) -{ - mStatus = status; -} - -void MppThread::start() -{ - pthread_attr_t attr; - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); - - if (MPP_THREAD_UNINITED == mStatus) { - // NOTE: set status here first to avoid unexpected loop quit racing condition - mStatus = MPP_THREAD_RUNNING; - if (0 == pthread_create(&mThread, &attr, mFunction, mContext)) { -#ifndef ARMLINUX - RK_S32 ret = pthread_setname_np(mThread, mName); - if (ret) - mpp_err("thread %p setname %s failed\n", mFunction, mName); -#endif - - thread_dbg(MPP_THREAD_DBG_FUNCTION, "thread %s %p context %p create success\n", - mName, mFunction, mContext); - } else - mStatus = MPP_THREAD_UNINITED; - } - pthread_attr_destroy(&attr); -} - -void MppThread::stop() -{ - if (MPP_THREAD_UNINITED != mStatus) { - lock(); - mStatus = MPP_THREAD_STOPPING; - mpp_log("MPP_THREAD_STOPPING status set mThread %p", this); - signal(); - unlock(); - void *dummy; - pthread_join(mThread, &dummy); - thread_dbg(MPP_THREAD_DBG_FUNCTION, "thread %s %p context %p destroy success\n", - mName, mFunction, mContext); - - mStatus = MPP_THREAD_UNINITED; - } -} - -#if defined(_WIN32) && !defined(__MINGW32CE__) -// -// Usage: SetThreadName ((DWORD)-1, "MainThread"); -// -#include -const DWORD MS_VC_EXCEPTION = 0x406D1388; - -#pragma pack(push,8) -typedef struct tagTHREADNAME_INFO { - DWORD dwType; // Must be 0x1000. - LPCSTR szName; // Pointer to name (in user addr space). - DWORD dwThreadID; // Thread ID (-1=caller thread). - DWORD dwFlags; // Reserved for future use, must be zero. -} THREADNAME_INFO; -#pragma pack(pop) - -void SetThreadName(DWORD dwThreadID, const char* threadName) -{ - THREADNAME_INFO info; - info.dwType = 0x1000; - info.szName = threadName; - info.dwThreadID = dwThreadID; - info.dwFlags = 0; -#pragma warning(push) -#pragma warning(disable: 6320 6322) - __try { - RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR*)&info); - } __except (EXCEPTION_EXECUTE_HANDLER) { - } -#pragma warning(pop) -} - - -#ifndef ARMLINUX -/* - * add pthread_setname_np for windows - */ -int pthread_setname_np(pthread_t thread, const char *name) -{ - DWORD dwThreadID = pthread_getw32threadid_np(thread); - SetThreadName(dwThreadID, name); - return 0; -} -#endif - -#endif - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define MODULE_TAG "mpp_thread" + +#include + +#include "mpp_log.h" +#include "mpp_common.h" +#include "mpp_thread.h" + +#define MPP_THREAD_DBG_FUNCTION (0x00000001) + +static RK_U32 thread_debug = 0; + +#define thread_dbg(flag, fmt, ...) _mpp_dbg(thread_debug, flag, fmt, ## __VA_ARGS__) + +MppThread::MppThread(MppThreadFunc func, void *ctx, const char *name) + : mStatus(MPP_THREAD_UNINITED), + mFunction(func), + mContext(ctx) +{ + if (name) + strncpy(mName, name, sizeof(mName)); + else + snprintf(mName, sizeof(mName), "mpp_thread"); +} + +MppThreadStatus MppThread::get_status() +{ + return mStatus; +} +void MppThread::set_status(MppThreadStatus status) +{ + mStatus = status; +} + +void MppThread::start() +{ + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); + + if (MPP_THREAD_UNINITED == mStatus) { + // NOTE: set status here first to avoid unexpected loop quit racing condition + mStatus = MPP_THREAD_RUNNING; + if (0 == pthread_create(&mThread, &attr, mFunction, mContext)) { +#ifndef ARMLINUX + RK_S32 ret = pthread_setname_np(mThread, mName); + if (ret) + mpp_err("thread %p setname %s failed\n", mFunction, mName); +#endif + + thread_dbg(MPP_THREAD_DBG_FUNCTION, "thread %s %p context %p create success\n", + mName, mFunction, mContext); + } else + mStatus = MPP_THREAD_UNINITED; + } + pthread_attr_destroy(&attr); +} + +void MppThread::stop() +{ + if (MPP_THREAD_UNINITED != mStatus) { + lock(); + mStatus = MPP_THREAD_STOPPING; + mpp_log("MPP_THREAD_STOPPING status set mThread %p", this); + signal(); + unlock(); + void *dummy; + pthread_join(mThread, &dummy); + thread_dbg(MPP_THREAD_DBG_FUNCTION, "thread %s %p context %p destroy success\n", + mName, mFunction, mContext); + + mStatus = MPP_THREAD_UNINITED; + } +} + +#if defined(_WIN32) && !defined(__MINGW32CE__) +// +// Usage: SetThreadName ((DWORD)-1, "MainThread"); +// +#include +const DWORD MS_VC_EXCEPTION = 0x406D1388; + +#pragma pack(push,8) +typedef struct tagTHREADNAME_INFO { + DWORD dwType; // Must be 0x1000. + LPCSTR szName; // Pointer to name (in user addr space). + DWORD dwThreadID; // Thread ID (-1=caller thread). + DWORD dwFlags; // Reserved for future use, must be zero. +} THREADNAME_INFO; +#pragma pack(pop) + +void SetThreadName(DWORD dwThreadID, const char* threadName) +{ + THREADNAME_INFO info; + info.dwType = 0x1000; + info.szName = threadName; + info.dwThreadID = dwThreadID; + info.dwFlags = 0; +#pragma warning(push) +#pragma warning(disable: 6320 6322) + __try { + RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR*)&info); + } __except (EXCEPTION_EXECUTE_HANDLER) { + } +#pragma warning(pop) +} + + +#ifndef ARMLINUX +/* + * add pthread_setname_np for windows + */ +int pthread_setname_np(pthread_t thread, const char *name) +{ + DWORD dwThreadID = pthread_getw32threadid_np(thread); + SetThreadName(dwThreadID, name); + return 0; +} +#endif + +#endif + diff --git a/osal/mpp_time.cpp b/osal/mpp_time.cpp index f5fa6336..a4925449 100644 --- a/osal/mpp_time.cpp +++ b/osal/mpp_time.cpp @@ -1,58 +1,58 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "mpp_log.h" -#include "mpp_time.h" - -#if _WIN32 -#include -#include - -RK_S64 mpp_time() -{ - if (!(mpp_debug & MPP_DBG_TIMING)) - return 0; - - struct timeb tb; - ftime(&tb); - return ((RK_S64)tb.time * 1000 + (RK_S64)tb.millitm) * 1000; -} - -#else -#include - -RK_S64 mpp_time() -{ - if (!(mpp_debug & MPP_DBG_TIMING)) - return 0; - - struct timeval tv_date; - gettimeofday(&tv_date, NULL); - return (RK_S64)tv_date.tv_sec * 1000000 + (RK_S64)tv_date.tv_usec; -} - -#endif - -void mpp_time_diff(RK_S64 start, RK_S64 end, RK_S64 limit, char *fmt) -{ - if (!(mpp_debug & MPP_DBG_TIMING)) - return; - - RK_S64 diff = end - start; - if (diff >= limit) - mpp_dbg(MPP_DBG_TIMING, "%s timing %.2f ms\n", fmt, diff / (float)1000); -} - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "mpp_log.h" +#include "mpp_time.h" + +#if _WIN32 +#include +#include + +RK_S64 mpp_time() +{ + if (!(mpp_debug & MPP_DBG_TIMING)) + return 0; + + struct timeb tb; + ftime(&tb); + return ((RK_S64)tb.time * 1000 + (RK_S64)tb.millitm) * 1000; +} + +#else +#include + +RK_S64 mpp_time() +{ + if (!(mpp_debug & MPP_DBG_TIMING)) + return 0; + + struct timeval tv_date; + gettimeofday(&tv_date, NULL); + return (RK_S64)tv_date.tv_sec * 1000000 + (RK_S64)tv_date.tv_usec; +} + +#endif + +void mpp_time_diff(RK_S64 start, RK_S64 end, RK_S64 limit, char *fmt) +{ + if (!(mpp_debug & MPP_DBG_TIMING)) + return; + + RK_S64 diff = end - start; + if (diff >= limit) + mpp_dbg(MPP_DBG_TIMING, "%s timing %.2f ms\n", fmt, diff / (float)1000); +} + diff --git a/osal/os_allocator.h b/osal/os_allocator.h index 9f95ac0e..71989ab0 100644 --- a/osal/os_allocator.h +++ b/osal/os_allocator.h @@ -1,43 +1,43 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __OS_ALLOCATOR_H__ -#define __OS_ALLOCATOR_H__ - -#include "mpp_allocator.h" - -typedef struct os_allocator_t { - MPP_RET (*open)(void **ctx, size_t alignment); - MPP_RET (*alloc)(void *ctx, MppBufferInfo *info); - MPP_RET (*free)(void *ctx, MppBufferInfo *info); - MPP_RET (*import)(void *ctx, MppBufferInfo *info); - MPP_RET (*release)(void *ctx, MppBufferInfo *info); - MPP_RET (*close)(void *ctx); -} os_allocator; - -#ifdef __cplusplus -extern "C" { -#endif - -MPP_RET os_allocator_get(os_allocator *api, MppBufferType type); - -#ifdef __cplusplus -} -#endif - -#endif /*__OS_ALLOCATOR_H__*/ - - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __OS_ALLOCATOR_H__ +#define __OS_ALLOCATOR_H__ + +#include "mpp_allocator.h" + +typedef struct os_allocator_t { + MPP_RET (*open)(void **ctx, size_t alignment); + MPP_RET (*alloc)(void *ctx, MppBufferInfo *info); + MPP_RET (*free)(void *ctx, MppBufferInfo *info); + MPP_RET (*import)(void *ctx, MppBufferInfo *info); + MPP_RET (*release)(void *ctx, MppBufferInfo *info); + MPP_RET (*close)(void *ctx); +} os_allocator; + +#ifdef __cplusplus +extern "C" { +#endif + +MPP_RET os_allocator_get(os_allocator *api, MppBufferType type); + +#ifdef __cplusplus +} +#endif + +#endif /*__OS_ALLOCATOR_H__*/ + + diff --git a/osal/os_env.h b/osal/os_env.h index 96d30699..35aeab58 100644 --- a/osal/os_env.h +++ b/osal/os_env.h @@ -1,37 +1,37 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __OS_ENV_H__ -#define __OS_ENV_H__ - -#include "rk_type.h" - -#ifdef __cplusplus -extern "C" { -#endif - -RK_S32 os_get_env_u32(const char *name, RK_U32 *value, RK_U32 default_value); -RK_S32 os_get_env_str(const char *name, char **value, char *default_value); - -RK_S32 os_set_env_u32(const char *name, RK_U32 value); -RK_S32 os_set_env_str(const char *name, char *value); - -#ifdef __cplusplus -} -#endif - -#endif /*__OS_ENV_H__*/ - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __OS_ENV_H__ +#define __OS_ENV_H__ + +#include "rk_type.h" + +#ifdef __cplusplus +extern "C" { +#endif + +RK_S32 os_get_env_u32(const char *name, RK_U32 *value, RK_U32 default_value); +RK_S32 os_get_env_str(const char *name, char **value, char *default_value); + +RK_S32 os_set_env_u32(const char *name, RK_U32 value); +RK_S32 os_set_env_str(const char *name, char *value); + +#ifdef __cplusplus +} +#endif + +#endif /*__OS_ENV_H__*/ + diff --git a/osal/os_log.h b/osal/os_log.h index 96040eb6..98dfdda1 100644 --- a/osal/os_log.h +++ b/osal/os_log.h @@ -1,39 +1,39 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * all os log function will provide two interface - * os_log and os_err - * os_log for general message - * os_err for error message - */ - -#ifndef __OS_LOG_H__ -#define __OS_LOG_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -void os_log(const char* tag, const char* msg, va_list list); -void os_err(const char* tag, const char* msg, va_list list); - -#ifdef __cplusplus -} -#endif - -#endif /*__OS_LOG_H__*/ - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * all os log function will provide two interface + * os_log and os_err + * os_log for general message + * os_err for error message + */ + +#ifndef __OS_LOG_H__ +#define __OS_LOG_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +void os_log(const char* tag, const char* msg, va_list list); +void os_err(const char* tag, const char* msg, va_list list); + +#ifdef __cplusplus +} +#endif + +#endif /*__OS_LOG_H__*/ + diff --git a/osal/os_mem.h b/osal/os_mem.h index 5eeb1b86..ccb1d256 100644 --- a/osal/os_mem.h +++ b/osal/os_mem.h @@ -1,34 +1,34 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __OS_MEM_H__ -#define __OS_MEM_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -int os_malloc(void **memptr, size_t alignment, size_t size); -int os_realloc(void *src, void **dst, size_t alignment, size_t size); -void os_free(void *ptr); - -#ifdef __cplusplus -} -#endif - -#endif /*__OS_MEM_H__*/ - - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __OS_MEM_H__ +#define __OS_MEM_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +int os_malloc(void **memptr, size_t alignment, size_t size); +int os_realloc(void *src, void **dst, size_t alignment, size_t size); +void os_free(void *ptr); + +#ifdef __cplusplus +} +#endif + +#endif /*__OS_MEM_H__*/ + + diff --git a/osal/test/mpp_env_test.c b/osal/test/mpp_env_test.c index 795b89f5..f3ce2bc1 100644 --- a/osal/test/mpp_env_test.c +++ b/osal/test/mpp_env_test.c @@ -1,47 +1,47 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define MODULE_TAG "mpp_env_test" -#include "mpp_env.h" -#include "mpp_log.h" - -const char env_debug[] = "test_env_debug"; -const char env_string[] = "test_env_string"; -char env_test_string[] = "just for debug"; - -int main() -{ - RK_U32 env_debug_u32 = 0x100; - char *env_string_str = env_test_string; - - mpp_env_set_u32(env_debug, env_debug_u32); - mpp_env_set_str(env_string, env_string_str); - mpp_log("set env: %s to %u\n", env_debug, env_debug_u32); - mpp_log("set env: %s to %s\n", env_string, env_string_str); - - env_debug_u32 = 0; - env_string_str = NULL; - mpp_log("clear local value to zero\n"); - - mpp_env_get_u32(env_debug, &env_debug_u32, 0); - mpp_env_get_str(env_string, &env_string_str, NULL); - - mpp_log("get env: %s is %u\n", env_debug, env_debug_u32); - mpp_log("get env: %s is %s\n", env_string, env_string_str); - - return 0; -} - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define MODULE_TAG "mpp_env_test" +#include "mpp_env.h" +#include "mpp_log.h" + +const char env_debug[] = "test_env_debug"; +const char env_string[] = "test_env_string"; +char env_test_string[] = "just for debug"; + +int main() +{ + RK_U32 env_debug_u32 = 0x100; + char *env_string_str = env_test_string; + + mpp_env_set_u32(env_debug, env_debug_u32); + mpp_env_set_str(env_string, env_string_str); + mpp_log("set env: %s to %u\n", env_debug, env_debug_u32); + mpp_log("set env: %s to %s\n", env_string, env_string_str); + + env_debug_u32 = 0; + env_string_str = NULL; + mpp_log("clear local value to zero\n"); + + mpp_env_get_u32(env_debug, &env_debug_u32, 0); + mpp_env_get_str(env_string, &env_string_str, NULL); + + mpp_log("get env: %s is %u\n", env_debug, env_debug_u32); + mpp_log("get env: %s is %s\n", env_string, env_string_str); + + return 0; +} + diff --git a/osal/window/os_allocator.c b/osal/window/os_allocator.c index 94c559c1..2a661978 100644 --- a/osal/window/os_allocator.c +++ b/osal/window/os_allocator.c @@ -1,134 +1,134 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "os_mem.h" -#include "os_allocator.h" - -#include "mpp_mem.h" -#include "mpp_log.h" - -/* - * window only support MPP_BUFFER_TYPE_NORMAL - */ - -typedef struct { - size_t alignment; - RK_S32 fd_count; -} allocator_ctx; - -MPP_RET os_allocator_open(void **ctx, size_t alignment) -{ - MPP_RET ret = MPP_OK; - allocator_ctx *p = NULL; - - if (NULL == ctx) { - mpp_err("os_allocator_open Window do not accept NULL input\n"); - return MPP_ERR_NULL_PTR; - } - - p = mpp_malloc(allocator_ctx, 1); - if (NULL == p) { - mpp_err("os_allocator_open Window failed to allocate context\n"); - ret = MPP_ERR_MALLOC; - } else - p->alignment = alignment; - - p->fd_count = 0; - - *ctx = p; - return ret; -} - -MPP_RET os_allocator_alloc(void *ctx, MppBufferInfo *info) -{ - allocator_ctx *p = NULL; - - if (NULL == ctx) { - mpp_err("os_allocator_alloc Window found NULL context input\n"); - return MPP_ERR_NULL_PTR; - } - - p = (allocator_ctx *)ctx; - info->fd = p->fd_count++; - return (MPP_RET)os_malloc(&info->ptr, p->alignment, info->size); -} - -MPP_RET os_allocator_free(void *ctx, MppBufferInfo *info) -{ - (void) ctx; - if (info->ptr) - os_free(info->ptr); - return MPP_OK; -} - -MPP_RET os_allocator_import(void *ctx, MppBufferInfo *info) -{ - allocator_ctx *p = (allocator_ctx *)ctx; - mpp_assert(ctx); - mpp_assert(info->ptr); - mpp_assert(info->size); - info->hnd = NULL; - info->fd = p->fd_count++; - return MPP_OK; -} - -MPP_RET os_allocator_release(void *ctx, MppBufferInfo *info) -{ - (void) ctx; - mpp_assert(info->ptr); - mpp_assert(info->size); - info->ptr = NULL; - info->size = 0; - info->hnd = NULL; - info->fd = -1; - return MPP_OK; -} - -MPP_RET os_allocator_close(void *ctx) -{ - if (ctx) { - mpp_free(ctx); - return MPP_OK; - } - mpp_err("os_allocator_close Window found NULL context input\n"); - return MPP_NOK; -} - -static os_allocator allocator_window = { - os_allocator_open, - os_allocator_alloc, - os_allocator_free, - os_allocator_import, - os_allocator_release, - os_allocator_close, -}; - -MPP_RET os_allocator_get(os_allocator *api, MppBufferType type) -{ - MPP_RET ret = MPP_OK; - switch (type) { - case MPP_BUFFER_TYPE_NORMAL : - case MPP_BUFFER_TYPE_ION : - case MPP_BUFFER_TYPE_V4L2 : { - *api = allocator_window; - } break; - default : { - ret = MPP_NOK; - } break; - } - return ret; -} - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "os_mem.h" +#include "os_allocator.h" + +#include "mpp_mem.h" +#include "mpp_log.h" + +/* + * window only support MPP_BUFFER_TYPE_NORMAL + */ + +typedef struct { + size_t alignment; + RK_S32 fd_count; +} allocator_ctx; + +MPP_RET os_allocator_open(void **ctx, size_t alignment) +{ + MPP_RET ret = MPP_OK; + allocator_ctx *p = NULL; + + if (NULL == ctx) { + mpp_err("os_allocator_open Window do not accept NULL input\n"); + return MPP_ERR_NULL_PTR; + } + + p = mpp_malloc(allocator_ctx, 1); + if (NULL == p) { + mpp_err("os_allocator_open Window failed to allocate context\n"); + ret = MPP_ERR_MALLOC; + } else + p->alignment = alignment; + + p->fd_count = 0; + + *ctx = p; + return ret; +} + +MPP_RET os_allocator_alloc(void *ctx, MppBufferInfo *info) +{ + allocator_ctx *p = NULL; + + if (NULL == ctx) { + mpp_err("os_allocator_alloc Window found NULL context input\n"); + return MPP_ERR_NULL_PTR; + } + + p = (allocator_ctx *)ctx; + info->fd = p->fd_count++; + return (MPP_RET)os_malloc(&info->ptr, p->alignment, info->size); +} + +MPP_RET os_allocator_free(void *ctx, MppBufferInfo *info) +{ + (void) ctx; + if (info->ptr) + os_free(info->ptr); + return MPP_OK; +} + +MPP_RET os_allocator_import(void *ctx, MppBufferInfo *info) +{ + allocator_ctx *p = (allocator_ctx *)ctx; + mpp_assert(ctx); + mpp_assert(info->ptr); + mpp_assert(info->size); + info->hnd = NULL; + info->fd = p->fd_count++; + return MPP_OK; +} + +MPP_RET os_allocator_release(void *ctx, MppBufferInfo *info) +{ + (void) ctx; + mpp_assert(info->ptr); + mpp_assert(info->size); + info->ptr = NULL; + info->size = 0; + info->hnd = NULL; + info->fd = -1; + return MPP_OK; +} + +MPP_RET os_allocator_close(void *ctx) +{ + if (ctx) { + mpp_free(ctx); + return MPP_OK; + } + mpp_err("os_allocator_close Window found NULL context input\n"); + return MPP_NOK; +} + +static os_allocator allocator_window = { + os_allocator_open, + os_allocator_alloc, + os_allocator_free, + os_allocator_import, + os_allocator_release, + os_allocator_close, +}; + +MPP_RET os_allocator_get(os_allocator *api, MppBufferType type) +{ + MPP_RET ret = MPP_OK; + switch (type) { + case MPP_BUFFER_TYPE_NORMAL : + case MPP_BUFFER_TYPE_ION : + case MPP_BUFFER_TYPE_V4L2 : { + *api = allocator_window; + } break; + default : { + ret = MPP_NOK; + } break; + } + return ret; +} + diff --git a/osal/window/os_env.c b/osal/window/os_env.c index 88b22fe7..ed6e8506 100644 --- a/osal/window/os_env.c +++ b/osal/window/os_env.c @@ -1,64 +1,64 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include "os_env.h" - -#define ENV_BUF_SIZE_WIN 1024 - -RK_S32 os_get_env_u32(const char *name, RK_U32 *value, RK_U32 default_value) -{ - char *ptr = getenv(name); - if (NULL == ptr) { - *value = default_value; - } else { - char *endptr; - int base = (ptr[0] == '0' && ptr[1] == 'x') ? (16) : (10); - errno = 0; - *value = strtoul(ptr, &endptr, base); - if (errno || (ptr == endptr)) { - errno = 0; - *value = default_value; - } - } - return 0; -} - -RK_S32 os_get_env_str(const char *name, char **value, char *default_value) -{ - *value = getenv(name); - if (NULL == *value) { - *value = default_value; - } - return 0; -} - -RK_S32 os_set_env_u32(const char *name, RK_U32 value) -{ - char buf[ENV_BUF_SIZE_WIN]; - _snprintf(buf, sizeof(buf), "%s=%lu", name, value); - return _putenv(buf); -} - -RK_S32 os_set_env_str(const char *name, char *value) -{ - char buf[ENV_BUF_SIZE_WIN]; - _snprintf(buf, sizeof(buf), "%s=%s", name, value); - return _putenv(buf); -} - - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include "os_env.h" + +#define ENV_BUF_SIZE_WIN 1024 + +RK_S32 os_get_env_u32(const char *name, RK_U32 *value, RK_U32 default_value) +{ + char *ptr = getenv(name); + if (NULL == ptr) { + *value = default_value; + } else { + char *endptr; + int base = (ptr[0] == '0' && ptr[1] == 'x') ? (16) : (10); + errno = 0; + *value = strtoul(ptr, &endptr, base); + if (errno || (ptr == endptr)) { + errno = 0; + *value = default_value; + } + } + return 0; +} + +RK_S32 os_get_env_str(const char *name, char **value, char *default_value) +{ + *value = getenv(name); + if (NULL == *value) { + *value = default_value; + } + return 0; +} + +RK_S32 os_set_env_u32(const char *name, RK_U32 value) +{ + char buf[ENV_BUF_SIZE_WIN]; + _snprintf(buf, sizeof(buf), "%s=%lu", name, value); + return _putenv(buf); +} + +RK_S32 os_set_env_str(const char *name, char *value) +{ + char buf[ENV_BUF_SIZE_WIN]; + _snprintf(buf, sizeof(buf), "%s=%s", name, value); + return _putenv(buf); +} + + diff --git a/osal/window/os_log.c b/osal/window/os_log.c index 38940931..51111804 100644 --- a/osal/window/os_log.c +++ b/osal/window/os_log.c @@ -1,35 +1,35 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include - -#define LINE_SZ 1024 - -void os_log(const char* tag, const char* msg, va_list list) -{ - char line[LINE_SZ] = {0}; - _snprintf(line, sizeof(line), "%s: %s", tag, msg); - vfprintf(stdout, line, list); -} - -void os_err(const char* tag, const char* msg, va_list list) -{ - char line[LINE_SZ] = {0}; - _snprintf(line, sizeof(line), "%s: %s", tag, msg); - vfprintf(stderr, line, list); -} - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#define LINE_SZ 1024 + +void os_log(const char* tag, const char* msg, va_list list) +{ + char line[LINE_SZ] = {0}; + _snprintf(line, sizeof(line), "%s: %s", tag, msg); + vfprintf(stdout, line, list); +} + +void os_err(const char* tag, const char* msg, va_list list) +{ + char line[LINE_SZ] = {0}; + _snprintf(line, sizeof(line), "%s: %s", tag, msg); + vfprintf(stderr, line, list); +} + diff --git a/osal/window/os_mem.c b/osal/window/os_mem.c index 28cddada..4da5f81d 100644 --- a/osal/window/os_mem.c +++ b/osal/window/os_mem.c @@ -1,36 +1,36 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include "os_mem.h" - -int os_malloc(void **memptr, size_t alignment, size_t size) -{ - *memptr = _aligned_malloc(size, alignment); - return (*memptr) ? (0) : (-1); -} - -int os_realloc(void *src, void **dst, size_t alignment, size_t size) -{ - *dst = _aligned_realloc(src, size, alignment); - return (*dst) ? (0) : (-1); -} - -void os_free(void *ptr) -{ - _aligned_free(ptr); -} - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "os_mem.h" + +int os_malloc(void **memptr, size_t alignment, size_t size) +{ + *memptr = _aligned_malloc(size, alignment); + return (*memptr) ? (0) : (-1); +} + +int os_realloc(void *src, void **dst, size_t alignment, size_t size) +{ + *dst = _aligned_realloc(src, size, alignment); + return (*dst) ? (0) : (-1); +} + +void os_free(void *ptr) +{ + _aligned_free(ptr); +} + diff --git a/osal/window/pthread/inc/pthread.h b/osal/window/pthread/inc/pthread.h index 436ea8b6..b4072f72 100644 --- a/osal/window/pthread/inc/pthread.h +++ b/osal/window/pthread/inc/pthread.h @@ -1,1368 +1,1368 @@ -/* This is an implementation of the threads API of POSIX 1003.1-2001. - * - * -------------------------------------------------------------------------- - * - * Pthreads-win32 - POSIX Threads Library for Win32 - * Copyright(C) 1998 John E. Bossom - * Copyright(C) 1999,2005 Pthreads-win32 contributors - * - * Contact Email: rpj@callisto.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * 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 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 in the file COPYING.LIB; - * if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#if !defined( PTHREAD_H ) -#define PTHREAD_H - -/* - * See the README file for an explanation of the pthreads-win32 version - * numbering scheme and how the DLL is named etc. - */ -#define PTW32_VERSION 2,9,1,0 -#define PTW32_VERSION_STRING "2, 9, 1, 0\0" - -/* There are three implementations of cancel cleanup. - * Note that pthread.h is included in both application - * compilation units and also internally for the library. - * The code here and within the library aims to work - * for all reasonable combinations of environments. - * - * The three implementations are: - * - * WIN32 SEH - * C - * C++ - * - * Please note that exiting a push/pop block via - * "return", "exit", "break", or "continue" will - * lead to different behaviour amongst applications - * depending upon whether the library was built - * using SEH, C++, or C. For example, a library built - * with SEH will call the cleanup routine, while both - * C++ and C built versions will not. - */ - -/* - * Define defaults for cleanup code. - * Note: Unless the build explicitly defines one of the following, then - * we default to standard C style cleanup. This style uses setjmp/longjmp - * in the cancelation and thread exit implementations and therefore won't - * do stack unwinding if linked to applications that have it (e.g. - * C++ apps). This is currently consistent with most/all commercial Unix - * POSIX threads implementations. - */ -#if !defined( __CLEANUP_SEH ) && !defined( __CLEANUP_CXX ) && !defined( __CLEANUP_C ) -# define __CLEANUP_C -#endif - -#if defined( __CLEANUP_SEH ) && ( !defined( _MSC_VER ) && !defined(PTW32_RC_MSC)) -#error ERROR [__FILE__, line __LINE__]: SEH is not supported for this compiler. -#endif - -/* - * Stop here if we are being included by the resource compiler. - */ -#if !defined(RC_INVOKED) - -#undef PTW32_LEVEL - -#if defined(_POSIX_SOURCE) -#define PTW32_LEVEL 0 -/* Early POSIX */ -#endif - -#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309 -#undef PTW32_LEVEL -#define PTW32_LEVEL 1 -/* Include 1b, 1c and 1d */ -#endif - -#if defined(INCLUDE_NP) -#undef PTW32_LEVEL -#define PTW32_LEVEL 2 -/* Include Non-Portable extensions */ -#endif - -#define PTW32_LEVEL_MAX 3 - -#if ( defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112 ) || !defined(PTW32_LEVEL) -#define PTW32_LEVEL PTW32_LEVEL_MAX -/* Include everything */ -#endif - -#if defined(_UWIN) -# define HAVE_STRUCT_TIMESPEC 1 -# define HAVE_SIGNAL_H 1 -# undef HAVE_PTW32_CONFIG_H -# pragma comment(lib, "pthread") -#endif - -/* - * ------------------------------------------------------------- - * - * - * Module: pthread.h - * - * Purpose: - * Provides an implementation of PThreads based upon the - * standard: - * - * POSIX 1003.1-2001 - * and - * The Single Unix Specification version 3 - * - * (these two are equivalent) - * - * in order to enhance code portability between Windows, - * various commercial Unix implementations, and Linux. - * - * See the ANNOUNCE file for a full list of conforming - * routines and defined constants, and a list of missing - * routines and constants not defined in this implementation. - * - * Authors: - * There have been many contributors to this library. - * The initial implementation was contributed by - * John Bossom, and several others have provided major - * sections or revisions of parts of the implementation. - * Often significant effort has been contributed to - * find and fix important bugs and other problems to - * improve the reliability of the library, which sometimes - * is not reflected in the amount of code which changed as - * result. - * As much as possible, the contributors are acknowledged - * in the ChangeLog file in the source code distribution - * where their changes are noted in detail. - * - * Contributors are listed in the CONTRIBUTORS file. - * - * As usual, all bouquets go to the contributors, and all - * brickbats go to the project maintainer. - * - * Maintainer: - * The code base for this project is coordinated and - * eventually pre-tested, packaged, and made available by - * - * Ross Johnson - * - * QA Testers: - * Ultimately, the library is tested in the real world by - * a host of competent and demanding scientists and - * engineers who report bugs and/or provide solutions - * which are then fixed or incorporated into subsequent - * versions of the library. Each time a bug is fixed, a - * test case is written to prove the fix and ensure - * that later changes to the code don't reintroduce the - * same error. The number of test cases is slowly growing - * and therefore so is the code reliability. - * - * Compliance: - * See the file ANNOUNCE for the list of implemented - * and not-implemented routines and defined options. - * Of course, these are all defined is this file as well. - * - * Web site: - * The source code and other information about this library - * are available from - * - * http://sources.redhat.com/pthreads-win32/ - * - * ------------------------------------------------------------- - */ - -/* Try to avoid including windows.h */ -#if (defined(__MINGW64__) || defined(__MINGW32__)) && defined(__cplusplus) -#define PTW32_INCLUDE_WINDOWS_H -#endif - -#if defined(PTW32_INCLUDE_WINDOWS_H) -#include -#endif - -#if defined(_MSC_VER) && _MSC_VER < 1300 || defined(__DMC__) -/* - * VC++6.0 or early compiler's header has no DWORD_PTR type. - */ -typedef unsigned long DWORD_PTR; -typedef unsigned long ULONG_PTR; -#endif -/* - * ----------------- - * autoconf switches - * ----------------- - */ - -#if defined(HAVE_PTW32_CONFIG_H) -#include "config.h" -#endif /* HAVE_PTW32_CONFIG_H */ - -#if !defined(NEED_FTIME) -#include -#else /* NEED_FTIME */ -/* use native WIN32 time API */ -#endif /* NEED_FTIME */ - -#if defined(HAVE_SIGNAL_H) -#include -#endif /* HAVE_SIGNAL_H */ - -#include - -/* - * Boolean values to make us independent of system includes. - */ -enum { - PTW32_FALSE = 0, - PTW32_TRUE = (! PTW32_FALSE) -}; - -/* - * This is a duplicate of what is in the autoconf config.h, - * which is only used when building the pthread-win32 libraries. - */ - -#if !defined(PTW32_CONFIG_H) -# if defined(WINCE) -# define NEED_ERRNO -# define NEED_SEM -# endif -# if defined(__MINGW64__) -# define HAVE_STRUCT_TIMESPEC -# define HAVE_MODE_T -# elif defined(_UWIN) || defined(__MINGW32__) -# define HAVE_MODE_T -# endif -#endif - -/* - * - */ - -#if PTW32_LEVEL >= PTW32_LEVEL_MAX -#if defined(NEED_ERRNO) -#include "need_errno.h" -#else -#include -#endif -#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ - -/* - * Several systems don't define some error numbers. - */ -#if !defined(ENOTSUP) -# define ENOTSUP 48 /* This is the value in Solaris. */ -#endif - -#if !defined(ETIMEDOUT) -# define ETIMEDOUT 10060 /* Same as WSAETIMEDOUT */ -#endif - -#if !defined(ENOSYS) -# define ENOSYS 140 /* Semi-arbitrary value */ -#endif - -#if !defined(EDEADLK) -# if defined(EDEADLOCK) -# define EDEADLK EDEADLOCK -# else -# define EDEADLK 36 /* This is the value in MSVC. */ -# endif -#endif - -/* POSIX 2008 - related to robust mutexes */ -#if !defined(EOWNERDEAD) -# define EOWNERDEAD 43 -#endif -#if !defined(ENOTRECOVERABLE) -# define ENOTRECOVERABLE 44 -#endif - -#include - -/* - * To avoid including windows.h we define only those things that we - * actually need from it. - */ -#if !defined(PTW32_INCLUDE_WINDOWS_H) -#if !defined(HANDLE) -# define PTW32__HANDLE_DEF -# define HANDLE void * -#endif -#if !defined(DWORD) -# define PTW32__DWORD_DEF -# define DWORD unsigned long -#endif -#endif - -#if !defined(HAVE_STRUCT_TIMESPEC) -#define HAVE_STRUCT_TIMESPEC -#if !defined(_TIMESPEC_DEFINED) -#define _TIMESPEC_DEFINED -struct timespec { - time_t tv_sec; - long tv_nsec; -}; -#endif /* _TIMESPEC_DEFINED */ -#endif /* HAVE_STRUCT_TIMESPEC */ - -#if !defined(SIG_BLOCK) -#define SIG_BLOCK 0 -#endif /* SIG_BLOCK */ - -#if !defined(SIG_UNBLOCK) -#define SIG_UNBLOCK 1 -#endif /* SIG_UNBLOCK */ - -#if !defined(SIG_SETMASK) -#define SIG_SETMASK 2 -#endif /* SIG_SETMASK */ - -#if defined(__cplusplus) -extern "C" -{ -#endif /* __cplusplus */ - -/* - * ------------------------------------------------------------- - * - * POSIX 1003.1-2001 Options - * ========================= - * - * Options are normally set in , which is not provided - * with pthreads-win32. - * - * For conformance with the Single Unix Specification (version 3), all of the - * options below are defined, and have a value of either -1 (not supported) - * or 200112L (supported). - * - * These options can neither be left undefined nor have a value of 0, because - * either indicates that sysconf(), which is not implemented, may be used at - * runtime to check the status of the option. - * - * _POSIX_THREADS (== 200112L) - * If == 200112L, you can use threads - * - * _POSIX_THREAD_ATTR_STACKSIZE (== 200112L) - * If == 200112L, you can control the size of a thread's - * stack - * pthread_attr_getstacksize - * pthread_attr_setstacksize - * - * _POSIX_THREAD_ATTR_STACKADDR (== -1) - * If == 200112L, you can allocate and control a thread's - * stack. If not supported, the following functions - * will return ENOSYS, indicating they are not - * supported: - * pthread_attr_getstackaddr - * pthread_attr_setstackaddr - * - * _POSIX_THREAD_PRIORITY_SCHEDULING (== -1) - * If == 200112L, you can use realtime scheduling. - * This option indicates that the behaviour of some - * implemented functions conforms to the additional TPS - * requirements in the standard. E.g. rwlocks favour - * writers over readers when threads have equal priority. - * - * _POSIX_THREAD_PRIO_INHERIT (== -1) - * If == 200112L, you can create priority inheritance - * mutexes. - * pthread_mutexattr_getprotocol + - * pthread_mutexattr_setprotocol + - * - * _POSIX_THREAD_PRIO_PROTECT (== -1) - * If == 200112L, you can create priority ceiling mutexes - * Indicates the availability of: - * pthread_mutex_getprioceiling - * pthread_mutex_setprioceiling - * pthread_mutexattr_getprioceiling - * pthread_mutexattr_getprotocol + - * pthread_mutexattr_setprioceiling - * pthread_mutexattr_setprotocol + - * - * _POSIX_THREAD_PROCESS_SHARED (== -1) - * If set, you can create mutexes and condition - * variables that can be shared with another - * process.If set, indicates the availability - * of: - * pthread_mutexattr_getpshared - * pthread_mutexattr_setpshared - * pthread_condattr_getpshared - * pthread_condattr_setpshared - * - * _POSIX_THREAD_SAFE_FUNCTIONS (== 200112L) - * If == 200112L you can use the special *_r library - * functions that provide thread-safe behaviour - * - * _POSIX_READER_WRITER_LOCKS (== 200112L) - * If == 200112L, you can use read/write locks - * - * _POSIX_SPIN_LOCKS (== 200112L) - * If == 200112L, you can use spin locks - * - * _POSIX_BARRIERS (== 200112L) - * If == 200112L, you can use barriers - * - * + These functions provide both 'inherit' and/or - * 'protect' protocol, based upon these macro - * settings. - * - * ------------------------------------------------------------- - */ - -/* - * POSIX Options - */ -#undef _POSIX_THREADS -#define _POSIX_THREADS 200809L - -#undef _POSIX_READER_WRITER_LOCKS -#define _POSIX_READER_WRITER_LOCKS 200809L - -#undef _POSIX_SPIN_LOCKS -#define _POSIX_SPIN_LOCKS 200809L - -#undef _POSIX_BARRIERS -#define _POSIX_BARRIERS 200809L - -#undef _POSIX_THREAD_SAFE_FUNCTIONS -#define _POSIX_THREAD_SAFE_FUNCTIONS 200809L - -#undef _POSIX_THREAD_ATTR_STACKSIZE -#define _POSIX_THREAD_ATTR_STACKSIZE 200809L - -/* - * The following options are not supported - */ -#undef _POSIX_THREAD_ATTR_STACKADDR -#define _POSIX_THREAD_ATTR_STACKADDR -1 - -#undef _POSIX_THREAD_PRIO_INHERIT -#define _POSIX_THREAD_PRIO_INHERIT -1 - -#undef _POSIX_THREAD_PRIO_PROTECT -#define _POSIX_THREAD_PRIO_PROTECT -1 - -/* TPS is not fully supported. */ -#undef _POSIX_THREAD_PRIORITY_SCHEDULING -#define _POSIX_THREAD_PRIORITY_SCHEDULING -1 - -#undef _POSIX_THREAD_PROCESS_SHARED -#define _POSIX_THREAD_PROCESS_SHARED -1 - - -/* - * POSIX 1003.1-2001 Limits - * =========================== - * - * These limits are normally set in , which is not provided with - * pthreads-win32. - * - * PTHREAD_DESTRUCTOR_ITERATIONS - * Maximum number of attempts to destroy - * a thread's thread-specific data on - * termination (must be at least 4) - * - * PTHREAD_KEYS_MAX - * Maximum number of thread-specific data keys - * available per process (must be at least 128) - * - * PTHREAD_STACK_MIN - * Minimum supported stack size for a thread - * - * PTHREAD_THREADS_MAX - * Maximum number of threads supported per - * process (must be at least 64). - * - * SEM_NSEMS_MAX - * The maximum number of semaphores a process can have. - * (must be at least 256) - * - * SEM_VALUE_MAX - * The maximum value a semaphore can have. - * (must be at least 32767) - * - */ -#undef _POSIX_THREAD_DESTRUCTOR_ITERATIONS -#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4 - -#undef PTHREAD_DESTRUCTOR_ITERATIONS -#define PTHREAD_DESTRUCTOR_ITERATIONS _POSIX_THREAD_DESTRUCTOR_ITERATIONS - -#undef _POSIX_THREAD_KEYS_MAX -#define _POSIX_THREAD_KEYS_MAX 128 - -#undef PTHREAD_KEYS_MAX -#define PTHREAD_KEYS_MAX _POSIX_THREAD_KEYS_MAX - -#undef PTHREAD_STACK_MIN -#define PTHREAD_STACK_MIN 0 - -#undef _POSIX_THREAD_THREADS_MAX -#define _POSIX_THREAD_THREADS_MAX 64 - - /* Arbitrary value */ -#undef PTHREAD_THREADS_MAX -#define PTHREAD_THREADS_MAX 2019 - -#undef _POSIX_SEM_NSEMS_MAX -#define _POSIX_SEM_NSEMS_MAX 256 - - /* Arbitrary value */ -#undef SEM_NSEMS_MAX -#define SEM_NSEMS_MAX 1024 - -#undef _POSIX_SEM_VALUE_MAX -#define _POSIX_SEM_VALUE_MAX 32767 - -#undef SEM_VALUE_MAX -#define SEM_VALUE_MAX INT_MAX - - -#if defined(__GNUC__) && !defined(__declspec) -# error Please upgrade your GNU compiler to one that supports __declspec. -#endif - -/* - * When building the library, you should define PTW32_BUILD so that - * the variables/functions are exported correctly. When using the library, - * do NOT define PTW32_BUILD, and then the variables/functions will - * be imported correctly. - */ -#if !defined(PTW32_STATIC_LIB) -# if defined(PTW32_BUILD) -# define PTW32_DLLPORT __declspec (dllexport) -# else -# define PTW32_DLLPORT __declspec (dllimport) -# endif -#else -# define PTW32_DLLPORT -#endif - -/* - * The Open Watcom C/C++ compiler uses a non-standard calling convention - * that passes function args in registers unless __cdecl is explicitly specified - * in exposed function prototypes. - * - * We force all calls to cdecl even though this could slow Watcom code down - * slightly. If you know that the Watcom compiler will be used to build both - * the DLL and application, then you can probably define this as a null string. - * Remember that pthread.h (this file) is used for both the DLL and application builds. - */ -#define PTW32_CDECL __cdecl - -#if defined(_UWIN) && PTW32_LEVEL >= PTW32_LEVEL_MAX -# include -#else -/* - * Generic handle type - intended to extend uniqueness beyond - * that available with a simple pointer. It should scale for either - * IA-32 or IA-64. - */ -typedef struct { - void * p; /* Pointer to actual object */ - unsigned int x; /* Extra information - reuse count etc */ -} ptw32_handle_t; - -typedef ptw32_handle_t pthread_t; -typedef struct pthread_attr_t_ * pthread_attr_t; -typedef struct pthread_once_t_ pthread_once_t; -typedef struct pthread_key_t_ * pthread_key_t; -typedef struct pthread_mutex_t_ * pthread_mutex_t; -typedef struct pthread_mutexattr_t_ * pthread_mutexattr_t; -typedef struct pthread_cond_t_ * pthread_cond_t; -typedef struct pthread_condattr_t_ * pthread_condattr_t; -#endif -typedef struct pthread_rwlock_t_ * pthread_rwlock_t; -typedef struct pthread_rwlockattr_t_ * pthread_rwlockattr_t; -typedef struct pthread_spinlock_t_ * pthread_spinlock_t; -typedef struct pthread_barrier_t_ * pthread_barrier_t; -typedef struct pthread_barrierattr_t_ * pthread_barrierattr_t; - -/* - * ==================== - * ==================== - * POSIX Threads - * ==================== - * ==================== - */ - -enum { -/* - * pthread_attr_{get,set}detachstate - */ - PTHREAD_CREATE_JOINABLE = 0, /* Default */ - PTHREAD_CREATE_DETACHED = 1, - -/* - * pthread_attr_{get,set}inheritsched - */ - PTHREAD_INHERIT_SCHED = 0, - PTHREAD_EXPLICIT_SCHED = 1, /* Default */ - -/* - * pthread_{get,set}scope - */ - PTHREAD_SCOPE_PROCESS = 0, - PTHREAD_SCOPE_SYSTEM = 1, /* Default */ - -/* - * pthread_setcancelstate paramters - */ - PTHREAD_CANCEL_ENABLE = 0, /* Default */ - PTHREAD_CANCEL_DISABLE = 1, - -/* - * pthread_setcanceltype parameters - */ - PTHREAD_CANCEL_ASYNCHRONOUS = 0, - PTHREAD_CANCEL_DEFERRED = 1, /* Default */ - -/* - * pthread_mutexattr_{get,set}pshared - * pthread_condattr_{get,set}pshared - */ - PTHREAD_PROCESS_PRIVATE = 0, - PTHREAD_PROCESS_SHARED = 1, - -/* - * pthread_mutexattr_{get,set}robust - */ - PTHREAD_MUTEX_STALLED = 0, /* Default */ - PTHREAD_MUTEX_ROBUST = 1, - -/* - * pthread_barrier_wait - */ - PTHREAD_BARRIER_SERIAL_THREAD = -1 -}; - -/* - * ==================== - * ==================== - * Cancelation - * ==================== - * ==================== - */ -#define PTHREAD_CANCELED ((void *)(size_t) -1) - - -/* - * ==================== - * ==================== - * Once Key - * ==================== - * ==================== - */ -#define PTHREAD_ONCE_INIT { PTW32_FALSE, 0, 0, 0} - -struct pthread_once_t_ -{ - int done; /* indicates if user function has been executed */ - void * lock; - int reserved1; - int reserved2; -}; - - -/* - * ==================== - * ==================== - * Object initialisers - * ==================== - * ==================== - */ -#define PTHREAD_MUTEX_INITIALIZER ((pthread_mutex_t)(size_t) -1) -#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER ((pthread_mutex_t)(size_t) -2) -#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER ((pthread_mutex_t)(size_t) -3) - -/* - * Compatibility with LinuxThreads - */ -#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP PTHREAD_RECURSIVE_MUTEX_INITIALIZER -#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP PTHREAD_ERRORCHECK_MUTEX_INITIALIZER - -#define PTHREAD_COND_INITIALIZER ((pthread_cond_t)(size_t) -1) - -#define PTHREAD_RWLOCK_INITIALIZER ((pthread_rwlock_t)(size_t) -1) - -#define PTHREAD_SPINLOCK_INITIALIZER ((pthread_spinlock_t)(size_t) -1) - - -/* - * Mutex types. - */ -enum -{ - /* Compatibility with LinuxThreads */ - PTHREAD_MUTEX_FAST_NP, - PTHREAD_MUTEX_RECURSIVE_NP, - PTHREAD_MUTEX_ERRORCHECK_NP, - PTHREAD_MUTEX_TIMED_NP = PTHREAD_MUTEX_FAST_NP, - PTHREAD_MUTEX_ADAPTIVE_NP = PTHREAD_MUTEX_FAST_NP, - /* For compatibility with POSIX */ - PTHREAD_MUTEX_NORMAL = PTHREAD_MUTEX_FAST_NP, - PTHREAD_MUTEX_RECURSIVE = PTHREAD_MUTEX_RECURSIVE_NP, - PTHREAD_MUTEX_ERRORCHECK = PTHREAD_MUTEX_ERRORCHECK_NP, - PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL -}; - - -typedef struct ptw32_cleanup_t ptw32_cleanup_t; - -#if defined(_MSC_VER) -/* Disable MSVC 'anachronism used' warning */ -#pragma warning( disable : 4229 ) -#endif - -typedef void (* PTW32_CDECL ptw32_cleanup_callback_t)(void *); - -#if defined(_MSC_VER) -#pragma warning( default : 4229 ) -#endif - -struct ptw32_cleanup_t -{ - ptw32_cleanup_callback_t routine; - void *arg; - struct ptw32_cleanup_t *prev; -}; - -#if defined(__CLEANUP_SEH) - /* - * WIN32 SEH version of cancel cleanup. - */ - -#define pthread_cleanup_push( _rout, _arg ) \ - { \ - ptw32_cleanup_t _cleanup; \ - \ - _cleanup.routine = (ptw32_cleanup_callback_t)(_rout); \ - _cleanup.arg = (_arg); \ - __try \ - { \ - -#define pthread_cleanup_pop( _execute ) \ - } \ - __finally \ - { \ - if( _execute || AbnormalTermination()) \ - { \ - (*(_cleanup.routine))( _cleanup.arg ); \ - } \ - } \ - } - -#else /* __CLEANUP_SEH */ - -#if defined(__CLEANUP_C) - - /* - * C implementation of PThreads cancel cleanup - */ - -#define pthread_cleanup_push( _rout, _arg ) \ - { \ - ptw32_cleanup_t _cleanup; \ - \ - ptw32_push_cleanup( &_cleanup, (ptw32_cleanup_callback_t) (_rout), (_arg) ); \ - -#define pthread_cleanup_pop( _execute ) \ - (void) ptw32_pop_cleanup( _execute ); \ - } - -#else /* __CLEANUP_C */ - -#if defined(__CLEANUP_CXX) - - /* - * C++ version of cancel cleanup. - * - John E. Bossom. - */ - - class PThreadCleanup { - /* - * PThreadCleanup - * - * Purpose - * This class is a C++ helper class that is - * used to implement pthread_cleanup_push/ - * pthread_cleanup_pop. - * The destructor of this class automatically - * pops the pushed cleanup routine regardless - * of how the code exits the scope - * (i.e. such as by an exception) - */ - ptw32_cleanup_callback_t cleanUpRout; - void * obj; - int executeIt; - - public: - PThreadCleanup() : - cleanUpRout( 0 ), - obj( 0 ), - executeIt( 0 ) - /* - * No cleanup performed - */ - { - } - - PThreadCleanup( - ptw32_cleanup_callback_t routine, - void * arg ) : - cleanUpRout( routine ), - obj( arg ), - executeIt( 1 ) - /* - * Registers a cleanup routine for 'arg' - */ - { - } - - ~PThreadCleanup() - { - if ( executeIt && ((void *) cleanUpRout != (void *) 0) ) - { - (void) (*cleanUpRout)( obj ); - } - } - - void execute( int exec ) - { - executeIt = exec; - } - }; - - /* - * C++ implementation of PThreads cancel cleanup; - * This implementation takes advantage of a helper - * class who's destructor automatically calls the - * cleanup routine if we exit our scope weirdly - */ -#define pthread_cleanup_push( _rout, _arg ) \ - { \ - PThreadCleanup cleanup((ptw32_cleanup_callback_t)(_rout), \ - (void *) (_arg) ); - -#define pthread_cleanup_pop( _execute ) \ - cleanup.execute( _execute ); \ - } - -#else - -#error ERROR [__FILE__, line __LINE__]: Cleanup type undefined. - -#endif /* __CLEANUP_CXX */ - -#endif /* __CLEANUP_C */ - -#endif /* __CLEANUP_SEH */ - -/* - * =============== - * =============== - * Methods - * =============== - * =============== - */ - -/* - * PThread Attribute Functions - */ -PTW32_DLLPORT int PTW32_CDECL pthread_attr_init (pthread_attr_t * attr); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_destroy (pthread_attr_t * attr); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_getdetachstate (const pthread_attr_t * attr, - int *detachstate); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_getstackaddr (const pthread_attr_t * attr, - void **stackaddr); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_getstacksize (const pthread_attr_t * attr, - size_t * stacksize); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_setdetachstate (pthread_attr_t * attr, - int detachstate); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_setstackaddr (pthread_attr_t * attr, - void *stackaddr); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_setstacksize (pthread_attr_t * attr, - size_t stacksize); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_getschedparam (const pthread_attr_t *attr, - struct sched_param *param); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_setschedparam (pthread_attr_t *attr, - const struct sched_param *param); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_setschedpolicy (pthread_attr_t *, - int); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_getschedpolicy (const pthread_attr_t *, - int *); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_setinheritsched(pthread_attr_t * attr, - int inheritsched); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_getinheritsched(const pthread_attr_t * attr, - int * inheritsched); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_setscope (pthread_attr_t *, - int); - -PTW32_DLLPORT int PTW32_CDECL pthread_attr_getscope (const pthread_attr_t *, - int *); - -/* - * PThread Functions - */ -PTW32_DLLPORT int PTW32_CDECL pthread_create (pthread_t * tid, - const pthread_attr_t * attr, - void *(PTW32_CDECL *start) (void *), - void *arg); - -PTW32_DLLPORT int PTW32_CDECL pthread_detach (pthread_t tid); - -PTW32_DLLPORT int PTW32_CDECL pthread_equal (pthread_t t1, - pthread_t t2); - -PTW32_DLLPORT void PTW32_CDECL pthread_exit (void *value_ptr); - -PTW32_DLLPORT int PTW32_CDECL pthread_join (pthread_t thread, - void **value_ptr); - -PTW32_DLLPORT pthread_t PTW32_CDECL pthread_self (void); - -PTW32_DLLPORT int PTW32_CDECL pthread_cancel (pthread_t thread); - -PTW32_DLLPORT int PTW32_CDECL pthread_setcancelstate (int state, - int *oldstate); - -PTW32_DLLPORT int PTW32_CDECL pthread_setcanceltype (int type, - int *oldtype); - -PTW32_DLLPORT void PTW32_CDECL pthread_testcancel (void); - -PTW32_DLLPORT int PTW32_CDECL pthread_once (pthread_once_t * once_control, - void (PTW32_CDECL *init_routine) (void)); - -#if PTW32_LEVEL >= PTW32_LEVEL_MAX -PTW32_DLLPORT ptw32_cleanup_t * PTW32_CDECL ptw32_pop_cleanup (int execute); - -PTW32_DLLPORT void PTW32_CDECL ptw32_push_cleanup (ptw32_cleanup_t * cleanup, - ptw32_cleanup_callback_t routine, - void *arg); -#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ - -/* - * Thread Specific Data Functions - */ -PTW32_DLLPORT int PTW32_CDECL pthread_key_create (pthread_key_t * key, - void (PTW32_CDECL *destructor) (void *)); - -PTW32_DLLPORT int PTW32_CDECL pthread_key_delete (pthread_key_t key); - -PTW32_DLLPORT int PTW32_CDECL pthread_setspecific (pthread_key_t key, - const void *value); - -PTW32_DLLPORT void * PTW32_CDECL pthread_getspecific (pthread_key_t key); - - -/* - * Mutex Attribute Functions - */ -PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_init (pthread_mutexattr_t * attr); - -PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_destroy (pthread_mutexattr_t * attr); - -PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_getpshared (const pthread_mutexattr_t - * attr, - int *pshared); - -PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_setpshared (pthread_mutexattr_t * attr, - int pshared); - -PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_settype (pthread_mutexattr_t * attr, int kind); -PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_gettype (const pthread_mutexattr_t * attr, int *kind); - -PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_setrobust( - pthread_mutexattr_t *attr, - int robust); -PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_getrobust( - const pthread_mutexattr_t * attr, - int * robust); - -/* - * Barrier Attribute Functions - */ -PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_init (pthread_barrierattr_t * attr); - -PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_destroy (pthread_barrierattr_t * attr); - -PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_getpshared (const pthread_barrierattr_t - * attr, - int *pshared); - -PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_setpshared (pthread_barrierattr_t * attr, - int pshared); - -/* - * Mutex Functions - */ -PTW32_DLLPORT int PTW32_CDECL pthread_mutex_init (pthread_mutex_t * mutex, - const pthread_mutexattr_t * attr); - -PTW32_DLLPORT int PTW32_CDECL pthread_mutex_destroy (pthread_mutex_t * mutex); - -PTW32_DLLPORT int PTW32_CDECL pthread_mutex_lock (pthread_mutex_t * mutex); - -PTW32_DLLPORT int PTW32_CDECL pthread_mutex_timedlock(pthread_mutex_t * mutex, - const struct timespec *abstime); - -PTW32_DLLPORT int PTW32_CDECL pthread_mutex_trylock (pthread_mutex_t * mutex); - -PTW32_DLLPORT int PTW32_CDECL pthread_mutex_unlock (pthread_mutex_t * mutex); - -PTW32_DLLPORT int PTW32_CDECL pthread_mutex_consistent (pthread_mutex_t * mutex); - -/* - * Spinlock Functions - */ -PTW32_DLLPORT int PTW32_CDECL pthread_spin_init (pthread_spinlock_t * lock, int pshared); - -PTW32_DLLPORT int PTW32_CDECL pthread_spin_destroy (pthread_spinlock_t * lock); - -PTW32_DLLPORT int PTW32_CDECL pthread_spin_lock (pthread_spinlock_t * lock); - -PTW32_DLLPORT int PTW32_CDECL pthread_spin_trylock (pthread_spinlock_t * lock); - -PTW32_DLLPORT int PTW32_CDECL pthread_spin_unlock (pthread_spinlock_t * lock); - -/* - * Barrier Functions - */ -PTW32_DLLPORT int PTW32_CDECL pthread_barrier_init (pthread_barrier_t * barrier, - const pthread_barrierattr_t * attr, - unsigned int count); - -PTW32_DLLPORT int PTW32_CDECL pthread_barrier_destroy (pthread_barrier_t * barrier); - -PTW32_DLLPORT int PTW32_CDECL pthread_barrier_wait (pthread_barrier_t * barrier); - -/* - * Condition Variable Attribute Functions - */ -PTW32_DLLPORT int PTW32_CDECL pthread_condattr_init (pthread_condattr_t * attr); - -PTW32_DLLPORT int PTW32_CDECL pthread_condattr_destroy (pthread_condattr_t * attr); - -PTW32_DLLPORT int PTW32_CDECL pthread_condattr_getpshared (const pthread_condattr_t * attr, - int *pshared); - -PTW32_DLLPORT int PTW32_CDECL pthread_condattr_setpshared (pthread_condattr_t * attr, - int pshared); - -/* - * Condition Variable Functions - */ -PTW32_DLLPORT int PTW32_CDECL pthread_cond_init (pthread_cond_t * cond, - const pthread_condattr_t * attr); - -PTW32_DLLPORT int PTW32_CDECL pthread_cond_destroy (pthread_cond_t * cond); - -PTW32_DLLPORT int PTW32_CDECL pthread_cond_wait (pthread_cond_t * cond, - pthread_mutex_t * mutex); - -PTW32_DLLPORT int PTW32_CDECL pthread_cond_timedwait (pthread_cond_t * cond, - pthread_mutex_t * mutex, - const struct timespec *abstime); - -PTW32_DLLPORT int PTW32_CDECL pthread_cond_signal (pthread_cond_t * cond); - -PTW32_DLLPORT int PTW32_CDECL pthread_cond_broadcast (pthread_cond_t * cond); - -/* - * Scheduling - */ -PTW32_DLLPORT int PTW32_CDECL pthread_setschedparam (pthread_t thread, - int policy, - const struct sched_param *param); - -PTW32_DLLPORT int PTW32_CDECL pthread_getschedparam (pthread_t thread, - int *policy, - struct sched_param *param); - -PTW32_DLLPORT int PTW32_CDECL pthread_setconcurrency (int); - -PTW32_DLLPORT int PTW32_CDECL pthread_getconcurrency (void); - -/* - * Read-Write Lock Functions - */ -PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_init(pthread_rwlock_t *lock, - const pthread_rwlockattr_t *attr); - -PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_destroy(pthread_rwlock_t *lock); - -PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_tryrdlock(pthread_rwlock_t *); - -PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_trywrlock(pthread_rwlock_t *); - -PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_rdlock(pthread_rwlock_t *lock); - -PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_timedrdlock(pthread_rwlock_t *lock, - const struct timespec *abstime); - -PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_wrlock(pthread_rwlock_t *lock); - -PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_timedwrlock(pthread_rwlock_t *lock, - const struct timespec *abstime); - -PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_unlock(pthread_rwlock_t *lock); - -PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_init (pthread_rwlockattr_t * attr); - -PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_destroy (pthread_rwlockattr_t * attr); - -PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_getpshared (const pthread_rwlockattr_t * attr, - int *pshared); - -PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_setpshared (pthread_rwlockattr_t * attr, - int pshared); - -#if PTW32_LEVEL >= PTW32_LEVEL_MAX - 1 - -/* - * Signal Functions. Should be defined in but MSVC and MinGW32 - * already have signal.h that don't define these. - */ -PTW32_DLLPORT int PTW32_CDECL pthread_kill(pthread_t thread, int sig); - -/* - * Non-portable functions - */ - -/* - * Compatibility with Linux. - */ -PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_setkind_np(pthread_mutexattr_t * attr, - int kind); -PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_getkind_np(pthread_mutexattr_t * attr, - int *kind); - -/* - * Possibly supported by other POSIX threads implementations - */ -PTW32_DLLPORT int PTW32_CDECL pthread_delay_np (struct timespec * interval); -PTW32_DLLPORT int PTW32_CDECL pthread_num_processors_np(void); -PTW32_DLLPORT unsigned __int64 PTW32_CDECL pthread_getunique_np(pthread_t thread); - -/* - * Useful if an application wants to statically link - * the lib rather than load the DLL at run-time. - */ -PTW32_DLLPORT int PTW32_CDECL pthread_win32_process_attach_np(void); -PTW32_DLLPORT int PTW32_CDECL pthread_win32_process_detach_np(void); -PTW32_DLLPORT int PTW32_CDECL pthread_win32_thread_attach_np(void); -PTW32_DLLPORT int PTW32_CDECL pthread_win32_thread_detach_np(void); - -/* - * Features that are auto-detected at load/run time. - */ -PTW32_DLLPORT int PTW32_CDECL pthread_win32_test_features_np(int); -enum ptw32_features { - PTW32_SYSTEM_INTERLOCKED_COMPARE_EXCHANGE = 0x0001, /* System provides it. */ - PTW32_ALERTABLE_ASYNC_CANCEL = 0x0002 /* Can cancel blocked threads. */ -}; - -/* - * Register a system time change with the library. - * Causes the library to perform various functions - * in response to the change. Should be called whenever - * the application's top level window receives a - * WM_TIMECHANGE message. It can be passed directly to - * pthread_create() as a new thread if desired. - */ -PTW32_DLLPORT void * PTW32_CDECL pthread_timechange_handler_np(void *); - -#endif /*PTW32_LEVEL >= PTW32_LEVEL_MAX - 1 */ - -#if PTW32_LEVEL >= PTW32_LEVEL_MAX - -/* - * Returns the Win32 HANDLE for the POSIX thread. - */ -PTW32_DLLPORT HANDLE PTW32_CDECL pthread_getw32threadhandle_np(pthread_t thread); -/* - * Returns the win32 thread ID for POSIX thread. - */ -PTW32_DLLPORT DWORD PTW32_CDECL pthread_getw32threadid_np (pthread_t thread); - - -/* - * Protected Methods - * - * This function blocks until the given WIN32 handle - * is signaled or pthread_cancel had been called. - * This function allows the caller to hook into the - * PThreads cancel mechanism. It is implemented using - * - * WaitForMultipleObjects - * - * on 'waitHandle' and a manually reset WIN32 Event - * used to implement pthread_cancel. The 'timeout' - * argument to TimedWait is simply passed to - * WaitForMultipleObjects. - */ -PTW32_DLLPORT int PTW32_CDECL pthreadCancelableWait (HANDLE waitHandle); -PTW32_DLLPORT int PTW32_CDECL pthreadCancelableTimedWait (HANDLE waitHandle, - DWORD timeout); - -#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ - -/* - * Thread-Safe C Runtime Library Mappings. - */ -#if !defined(_UWIN) -# if defined(NEED_ERRNO) - PTW32_DLLPORT int * PTW32_CDECL _errno( void ); -# else -# if !defined(errno) -# if (defined(_MT) || defined(_DLL)) - __declspec(dllimport) extern int * __cdecl _errno(void); -# define errno (*_errno()) -# endif -# endif -# endif -#endif - -/* - * Some compiler environments don't define some things. - */ -#if defined(__BORLANDC__) -# define _ftime ftime -# define _timeb timeb -#endif - -#if defined(__cplusplus) - -/* - * Internal exceptions - */ -class ptw32_exception {}; -class ptw32_exception_cancel : public ptw32_exception {}; -class ptw32_exception_exit : public ptw32_exception {}; - -#endif - -#if PTW32_LEVEL >= PTW32_LEVEL_MAX - -/* FIXME: This is only required if the library was built using SEH */ -/* - * Get internal SEH tag - */ -PTW32_DLLPORT DWORD PTW32_CDECL ptw32_get_exception_services_code(void); - -#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ - -#if !defined(PTW32_BUILD) - -#if defined(__CLEANUP_SEH) - -/* - * Redefine the SEH __except keyword to ensure that applications - * propagate our internal exceptions up to the library's internal handlers. - */ -#define __except( E ) \ - __except( ( GetExceptionCode() == ptw32_get_exception_services_code() ) \ - ? EXCEPTION_CONTINUE_SEARCH : ( E ) ) - -#endif /* __CLEANUP_SEH */ - -#if defined(__CLEANUP_CXX) - -/* - * Redefine the C++ catch keyword to ensure that applications - * propagate our internal exceptions up to the library's internal handlers. - */ -#if defined(_MSC_VER) - /* - * WARNING: Replace any 'catch( ... )' with 'PtW32CatchAll' - * if you want Pthread-Win32 cancelation and pthread_exit to work. - */ - -#if !defined(PtW32NoCatchWarn) - -#pragma message("Specify \"/DPtW32NoCatchWarn\" compiler flag to skip this message.") -#pragma message("------------------------------------------------------------------") -#pragma message("When compiling applications with MSVC++ and C++ exception handling:") -#pragma message(" Replace any 'catch( ... )' in routines called from POSIX threads") -#pragma message(" with 'PtW32CatchAll' or 'CATCHALL' if you want POSIX thread") -#pragma message(" cancelation and pthread_exit to work. For example:") -#pragma message("") -#pragma message(" #if defined(PtW32CatchAll)") -#pragma message(" PtW32CatchAll") -#pragma message(" #else") -#pragma message(" catch(...)") -#pragma message(" #endif") -#pragma message(" {") -#pragma message(" /* Catchall block processing */") -#pragma message(" }") -#pragma message("------------------------------------------------------------------") - -#endif - -#define PtW32CatchAll \ - catch( ptw32_exception & ) { throw; } \ - catch( ... ) - -#else /* _MSC_VER */ - -#define catch( E ) \ - catch( ptw32_exception & ) { throw; } \ - catch( E ) - -#endif /* _MSC_VER */ - -#endif /* __CLEANUP_CXX */ - -#endif /* ! PTW32_BUILD */ - -#if defined(__cplusplus) -} /* End of extern "C" */ -#endif /* __cplusplus */ - -#if defined(PTW32__HANDLE_DEF) -# undef HANDLE -#endif -#if defined(PTW32__DWORD_DEF) -# undef DWORD -#endif - -#undef PTW32_LEVEL -#undef PTW32_LEVEL_MAX - -#endif /* ! RC_INVOKED */ - -#endif /* PTHREAD_H */ +/* This is an implementation of the threads API of POSIX 1003.1-2001. + * + * -------------------------------------------------------------------------- + * + * Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * 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 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 in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#if !defined( PTHREAD_H ) +#define PTHREAD_H + +/* + * See the README file for an explanation of the pthreads-win32 version + * numbering scheme and how the DLL is named etc. + */ +#define PTW32_VERSION 2,9,1,0 +#define PTW32_VERSION_STRING "2, 9, 1, 0\0" + +/* There are three implementations of cancel cleanup. + * Note that pthread.h is included in both application + * compilation units and also internally for the library. + * The code here and within the library aims to work + * for all reasonable combinations of environments. + * + * The three implementations are: + * + * WIN32 SEH + * C + * C++ + * + * Please note that exiting a push/pop block via + * "return", "exit", "break", or "continue" will + * lead to different behaviour amongst applications + * depending upon whether the library was built + * using SEH, C++, or C. For example, a library built + * with SEH will call the cleanup routine, while both + * C++ and C built versions will not. + */ + +/* + * Define defaults for cleanup code. + * Note: Unless the build explicitly defines one of the following, then + * we default to standard C style cleanup. This style uses setjmp/longjmp + * in the cancelation and thread exit implementations and therefore won't + * do stack unwinding if linked to applications that have it (e.g. + * C++ apps). This is currently consistent with most/all commercial Unix + * POSIX threads implementations. + */ +#if !defined( __CLEANUP_SEH ) && !defined( __CLEANUP_CXX ) && !defined( __CLEANUP_C ) +# define __CLEANUP_C +#endif + +#if defined( __CLEANUP_SEH ) && ( !defined( _MSC_VER ) && !defined(PTW32_RC_MSC)) +#error ERROR [__FILE__, line __LINE__]: SEH is not supported for this compiler. +#endif + +/* + * Stop here if we are being included by the resource compiler. + */ +#if !defined(RC_INVOKED) + +#undef PTW32_LEVEL + +#if defined(_POSIX_SOURCE) +#define PTW32_LEVEL 0 +/* Early POSIX */ +#endif + +#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309 +#undef PTW32_LEVEL +#define PTW32_LEVEL 1 +/* Include 1b, 1c and 1d */ +#endif + +#if defined(INCLUDE_NP) +#undef PTW32_LEVEL +#define PTW32_LEVEL 2 +/* Include Non-Portable extensions */ +#endif + +#define PTW32_LEVEL_MAX 3 + +#if ( defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112 ) || !defined(PTW32_LEVEL) +#define PTW32_LEVEL PTW32_LEVEL_MAX +/* Include everything */ +#endif + +#if defined(_UWIN) +# define HAVE_STRUCT_TIMESPEC 1 +# define HAVE_SIGNAL_H 1 +# undef HAVE_PTW32_CONFIG_H +# pragma comment(lib, "pthread") +#endif + +/* + * ------------------------------------------------------------- + * + * + * Module: pthread.h + * + * Purpose: + * Provides an implementation of PThreads based upon the + * standard: + * + * POSIX 1003.1-2001 + * and + * The Single Unix Specification version 3 + * + * (these two are equivalent) + * + * in order to enhance code portability between Windows, + * various commercial Unix implementations, and Linux. + * + * See the ANNOUNCE file for a full list of conforming + * routines and defined constants, and a list of missing + * routines and constants not defined in this implementation. + * + * Authors: + * There have been many contributors to this library. + * The initial implementation was contributed by + * John Bossom, and several others have provided major + * sections or revisions of parts of the implementation. + * Often significant effort has been contributed to + * find and fix important bugs and other problems to + * improve the reliability of the library, which sometimes + * is not reflected in the amount of code which changed as + * result. + * As much as possible, the contributors are acknowledged + * in the ChangeLog file in the source code distribution + * where their changes are noted in detail. + * + * Contributors are listed in the CONTRIBUTORS file. + * + * As usual, all bouquets go to the contributors, and all + * brickbats go to the project maintainer. + * + * Maintainer: + * The code base for this project is coordinated and + * eventually pre-tested, packaged, and made available by + * + * Ross Johnson + * + * QA Testers: + * Ultimately, the library is tested in the real world by + * a host of competent and demanding scientists and + * engineers who report bugs and/or provide solutions + * which are then fixed or incorporated into subsequent + * versions of the library. Each time a bug is fixed, a + * test case is written to prove the fix and ensure + * that later changes to the code don't reintroduce the + * same error. The number of test cases is slowly growing + * and therefore so is the code reliability. + * + * Compliance: + * See the file ANNOUNCE for the list of implemented + * and not-implemented routines and defined options. + * Of course, these are all defined is this file as well. + * + * Web site: + * The source code and other information about this library + * are available from + * + * http://sources.redhat.com/pthreads-win32/ + * + * ------------------------------------------------------------- + */ + +/* Try to avoid including windows.h */ +#if (defined(__MINGW64__) || defined(__MINGW32__)) && defined(__cplusplus) +#define PTW32_INCLUDE_WINDOWS_H +#endif + +#if defined(PTW32_INCLUDE_WINDOWS_H) +#include +#endif + +#if defined(_MSC_VER) && _MSC_VER < 1300 || defined(__DMC__) +/* + * VC++6.0 or early compiler's header has no DWORD_PTR type. + */ +typedef unsigned long DWORD_PTR; +typedef unsigned long ULONG_PTR; +#endif +/* + * ----------------- + * autoconf switches + * ----------------- + */ + +#if defined(HAVE_PTW32_CONFIG_H) +#include "config.h" +#endif /* HAVE_PTW32_CONFIG_H */ + +#if !defined(NEED_FTIME) +#include +#else /* NEED_FTIME */ +/* use native WIN32 time API */ +#endif /* NEED_FTIME */ + +#if defined(HAVE_SIGNAL_H) +#include +#endif /* HAVE_SIGNAL_H */ + +#include + +/* + * Boolean values to make us independent of system includes. + */ +enum { + PTW32_FALSE = 0, + PTW32_TRUE = (! PTW32_FALSE) +}; + +/* + * This is a duplicate of what is in the autoconf config.h, + * which is only used when building the pthread-win32 libraries. + */ + +#if !defined(PTW32_CONFIG_H) +# if defined(WINCE) +# define NEED_ERRNO +# define NEED_SEM +# endif +# if defined(__MINGW64__) +# define HAVE_STRUCT_TIMESPEC +# define HAVE_MODE_T +# elif defined(_UWIN) || defined(__MINGW32__) +# define HAVE_MODE_T +# endif +#endif + +/* + * + */ + +#if PTW32_LEVEL >= PTW32_LEVEL_MAX +#if defined(NEED_ERRNO) +#include "need_errno.h" +#else +#include +#endif +#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ + +/* + * Several systems don't define some error numbers. + */ +#if !defined(ENOTSUP) +# define ENOTSUP 48 /* This is the value in Solaris. */ +#endif + +#if !defined(ETIMEDOUT) +# define ETIMEDOUT 10060 /* Same as WSAETIMEDOUT */ +#endif + +#if !defined(ENOSYS) +# define ENOSYS 140 /* Semi-arbitrary value */ +#endif + +#if !defined(EDEADLK) +# if defined(EDEADLOCK) +# define EDEADLK EDEADLOCK +# else +# define EDEADLK 36 /* This is the value in MSVC. */ +# endif +#endif + +/* POSIX 2008 - related to robust mutexes */ +#if !defined(EOWNERDEAD) +# define EOWNERDEAD 43 +#endif +#if !defined(ENOTRECOVERABLE) +# define ENOTRECOVERABLE 44 +#endif + +#include + +/* + * To avoid including windows.h we define only those things that we + * actually need from it. + */ +#if !defined(PTW32_INCLUDE_WINDOWS_H) +#if !defined(HANDLE) +# define PTW32__HANDLE_DEF +# define HANDLE void * +#endif +#if !defined(DWORD) +# define PTW32__DWORD_DEF +# define DWORD unsigned long +#endif +#endif + +#if !defined(HAVE_STRUCT_TIMESPEC) +#define HAVE_STRUCT_TIMESPEC +#if !defined(_TIMESPEC_DEFINED) +#define _TIMESPEC_DEFINED +struct timespec { + time_t tv_sec; + long tv_nsec; +}; +#endif /* _TIMESPEC_DEFINED */ +#endif /* HAVE_STRUCT_TIMESPEC */ + +#if !defined(SIG_BLOCK) +#define SIG_BLOCK 0 +#endif /* SIG_BLOCK */ + +#if !defined(SIG_UNBLOCK) +#define SIG_UNBLOCK 1 +#endif /* SIG_UNBLOCK */ + +#if !defined(SIG_SETMASK) +#define SIG_SETMASK 2 +#endif /* SIG_SETMASK */ + +#if defined(__cplusplus) +extern "C" +{ +#endif /* __cplusplus */ + +/* + * ------------------------------------------------------------- + * + * POSIX 1003.1-2001 Options + * ========================= + * + * Options are normally set in , which is not provided + * with pthreads-win32. + * + * For conformance with the Single Unix Specification (version 3), all of the + * options below are defined, and have a value of either -1 (not supported) + * or 200112L (supported). + * + * These options can neither be left undefined nor have a value of 0, because + * either indicates that sysconf(), which is not implemented, may be used at + * runtime to check the status of the option. + * + * _POSIX_THREADS (== 200112L) + * If == 200112L, you can use threads + * + * _POSIX_THREAD_ATTR_STACKSIZE (== 200112L) + * If == 200112L, you can control the size of a thread's + * stack + * pthread_attr_getstacksize + * pthread_attr_setstacksize + * + * _POSIX_THREAD_ATTR_STACKADDR (== -1) + * If == 200112L, you can allocate and control a thread's + * stack. If not supported, the following functions + * will return ENOSYS, indicating they are not + * supported: + * pthread_attr_getstackaddr + * pthread_attr_setstackaddr + * + * _POSIX_THREAD_PRIORITY_SCHEDULING (== -1) + * If == 200112L, you can use realtime scheduling. + * This option indicates that the behaviour of some + * implemented functions conforms to the additional TPS + * requirements in the standard. E.g. rwlocks favour + * writers over readers when threads have equal priority. + * + * _POSIX_THREAD_PRIO_INHERIT (== -1) + * If == 200112L, you can create priority inheritance + * mutexes. + * pthread_mutexattr_getprotocol + + * pthread_mutexattr_setprotocol + + * + * _POSIX_THREAD_PRIO_PROTECT (== -1) + * If == 200112L, you can create priority ceiling mutexes + * Indicates the availability of: + * pthread_mutex_getprioceiling + * pthread_mutex_setprioceiling + * pthread_mutexattr_getprioceiling + * pthread_mutexattr_getprotocol + + * pthread_mutexattr_setprioceiling + * pthread_mutexattr_setprotocol + + * + * _POSIX_THREAD_PROCESS_SHARED (== -1) + * If set, you can create mutexes and condition + * variables that can be shared with another + * process.If set, indicates the availability + * of: + * pthread_mutexattr_getpshared + * pthread_mutexattr_setpshared + * pthread_condattr_getpshared + * pthread_condattr_setpshared + * + * _POSIX_THREAD_SAFE_FUNCTIONS (== 200112L) + * If == 200112L you can use the special *_r library + * functions that provide thread-safe behaviour + * + * _POSIX_READER_WRITER_LOCKS (== 200112L) + * If == 200112L, you can use read/write locks + * + * _POSIX_SPIN_LOCKS (== 200112L) + * If == 200112L, you can use spin locks + * + * _POSIX_BARRIERS (== 200112L) + * If == 200112L, you can use barriers + * + * + These functions provide both 'inherit' and/or + * 'protect' protocol, based upon these macro + * settings. + * + * ------------------------------------------------------------- + */ + +/* + * POSIX Options + */ +#undef _POSIX_THREADS +#define _POSIX_THREADS 200809L + +#undef _POSIX_READER_WRITER_LOCKS +#define _POSIX_READER_WRITER_LOCKS 200809L + +#undef _POSIX_SPIN_LOCKS +#define _POSIX_SPIN_LOCKS 200809L + +#undef _POSIX_BARRIERS +#define _POSIX_BARRIERS 200809L + +#undef _POSIX_THREAD_SAFE_FUNCTIONS +#define _POSIX_THREAD_SAFE_FUNCTIONS 200809L + +#undef _POSIX_THREAD_ATTR_STACKSIZE +#define _POSIX_THREAD_ATTR_STACKSIZE 200809L + +/* + * The following options are not supported + */ +#undef _POSIX_THREAD_ATTR_STACKADDR +#define _POSIX_THREAD_ATTR_STACKADDR -1 + +#undef _POSIX_THREAD_PRIO_INHERIT +#define _POSIX_THREAD_PRIO_INHERIT -1 + +#undef _POSIX_THREAD_PRIO_PROTECT +#define _POSIX_THREAD_PRIO_PROTECT -1 + +/* TPS is not fully supported. */ +#undef _POSIX_THREAD_PRIORITY_SCHEDULING +#define _POSIX_THREAD_PRIORITY_SCHEDULING -1 + +#undef _POSIX_THREAD_PROCESS_SHARED +#define _POSIX_THREAD_PROCESS_SHARED -1 + + +/* + * POSIX 1003.1-2001 Limits + * =========================== + * + * These limits are normally set in , which is not provided with + * pthreads-win32. + * + * PTHREAD_DESTRUCTOR_ITERATIONS + * Maximum number of attempts to destroy + * a thread's thread-specific data on + * termination (must be at least 4) + * + * PTHREAD_KEYS_MAX + * Maximum number of thread-specific data keys + * available per process (must be at least 128) + * + * PTHREAD_STACK_MIN + * Minimum supported stack size for a thread + * + * PTHREAD_THREADS_MAX + * Maximum number of threads supported per + * process (must be at least 64). + * + * SEM_NSEMS_MAX + * The maximum number of semaphores a process can have. + * (must be at least 256) + * + * SEM_VALUE_MAX + * The maximum value a semaphore can have. + * (must be at least 32767) + * + */ +#undef _POSIX_THREAD_DESTRUCTOR_ITERATIONS +#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4 + +#undef PTHREAD_DESTRUCTOR_ITERATIONS +#define PTHREAD_DESTRUCTOR_ITERATIONS _POSIX_THREAD_DESTRUCTOR_ITERATIONS + +#undef _POSIX_THREAD_KEYS_MAX +#define _POSIX_THREAD_KEYS_MAX 128 + +#undef PTHREAD_KEYS_MAX +#define PTHREAD_KEYS_MAX _POSIX_THREAD_KEYS_MAX + +#undef PTHREAD_STACK_MIN +#define PTHREAD_STACK_MIN 0 + +#undef _POSIX_THREAD_THREADS_MAX +#define _POSIX_THREAD_THREADS_MAX 64 + + /* Arbitrary value */ +#undef PTHREAD_THREADS_MAX +#define PTHREAD_THREADS_MAX 2019 + +#undef _POSIX_SEM_NSEMS_MAX +#define _POSIX_SEM_NSEMS_MAX 256 + + /* Arbitrary value */ +#undef SEM_NSEMS_MAX +#define SEM_NSEMS_MAX 1024 + +#undef _POSIX_SEM_VALUE_MAX +#define _POSIX_SEM_VALUE_MAX 32767 + +#undef SEM_VALUE_MAX +#define SEM_VALUE_MAX INT_MAX + + +#if defined(__GNUC__) && !defined(__declspec) +# error Please upgrade your GNU compiler to one that supports __declspec. +#endif + +/* + * When building the library, you should define PTW32_BUILD so that + * the variables/functions are exported correctly. When using the library, + * do NOT define PTW32_BUILD, and then the variables/functions will + * be imported correctly. + */ +#if !defined(PTW32_STATIC_LIB) +# if defined(PTW32_BUILD) +# define PTW32_DLLPORT __declspec (dllexport) +# else +# define PTW32_DLLPORT __declspec (dllimport) +# endif +#else +# define PTW32_DLLPORT +#endif + +/* + * The Open Watcom C/C++ compiler uses a non-standard calling convention + * that passes function args in registers unless __cdecl is explicitly specified + * in exposed function prototypes. + * + * We force all calls to cdecl even though this could slow Watcom code down + * slightly. If you know that the Watcom compiler will be used to build both + * the DLL and application, then you can probably define this as a null string. + * Remember that pthread.h (this file) is used for both the DLL and application builds. + */ +#define PTW32_CDECL __cdecl + +#if defined(_UWIN) && PTW32_LEVEL >= PTW32_LEVEL_MAX +# include +#else +/* + * Generic handle type - intended to extend uniqueness beyond + * that available with a simple pointer. It should scale for either + * IA-32 or IA-64. + */ +typedef struct { + void * p; /* Pointer to actual object */ + unsigned int x; /* Extra information - reuse count etc */ +} ptw32_handle_t; + +typedef ptw32_handle_t pthread_t; +typedef struct pthread_attr_t_ * pthread_attr_t; +typedef struct pthread_once_t_ pthread_once_t; +typedef struct pthread_key_t_ * pthread_key_t; +typedef struct pthread_mutex_t_ * pthread_mutex_t; +typedef struct pthread_mutexattr_t_ * pthread_mutexattr_t; +typedef struct pthread_cond_t_ * pthread_cond_t; +typedef struct pthread_condattr_t_ * pthread_condattr_t; +#endif +typedef struct pthread_rwlock_t_ * pthread_rwlock_t; +typedef struct pthread_rwlockattr_t_ * pthread_rwlockattr_t; +typedef struct pthread_spinlock_t_ * pthread_spinlock_t; +typedef struct pthread_barrier_t_ * pthread_barrier_t; +typedef struct pthread_barrierattr_t_ * pthread_barrierattr_t; + +/* + * ==================== + * ==================== + * POSIX Threads + * ==================== + * ==================== + */ + +enum { +/* + * pthread_attr_{get,set}detachstate + */ + PTHREAD_CREATE_JOINABLE = 0, /* Default */ + PTHREAD_CREATE_DETACHED = 1, + +/* + * pthread_attr_{get,set}inheritsched + */ + PTHREAD_INHERIT_SCHED = 0, + PTHREAD_EXPLICIT_SCHED = 1, /* Default */ + +/* + * pthread_{get,set}scope + */ + PTHREAD_SCOPE_PROCESS = 0, + PTHREAD_SCOPE_SYSTEM = 1, /* Default */ + +/* + * pthread_setcancelstate paramters + */ + PTHREAD_CANCEL_ENABLE = 0, /* Default */ + PTHREAD_CANCEL_DISABLE = 1, + +/* + * pthread_setcanceltype parameters + */ + PTHREAD_CANCEL_ASYNCHRONOUS = 0, + PTHREAD_CANCEL_DEFERRED = 1, /* Default */ + +/* + * pthread_mutexattr_{get,set}pshared + * pthread_condattr_{get,set}pshared + */ + PTHREAD_PROCESS_PRIVATE = 0, + PTHREAD_PROCESS_SHARED = 1, + +/* + * pthread_mutexattr_{get,set}robust + */ + PTHREAD_MUTEX_STALLED = 0, /* Default */ + PTHREAD_MUTEX_ROBUST = 1, + +/* + * pthread_barrier_wait + */ + PTHREAD_BARRIER_SERIAL_THREAD = -1 +}; + +/* + * ==================== + * ==================== + * Cancelation + * ==================== + * ==================== + */ +#define PTHREAD_CANCELED ((void *)(size_t) -1) + + +/* + * ==================== + * ==================== + * Once Key + * ==================== + * ==================== + */ +#define PTHREAD_ONCE_INIT { PTW32_FALSE, 0, 0, 0} + +struct pthread_once_t_ +{ + int done; /* indicates if user function has been executed */ + void * lock; + int reserved1; + int reserved2; +}; + + +/* + * ==================== + * ==================== + * Object initialisers + * ==================== + * ==================== + */ +#define PTHREAD_MUTEX_INITIALIZER ((pthread_mutex_t)(size_t) -1) +#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER ((pthread_mutex_t)(size_t) -2) +#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER ((pthread_mutex_t)(size_t) -3) + +/* + * Compatibility with LinuxThreads + */ +#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP PTHREAD_RECURSIVE_MUTEX_INITIALIZER +#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP PTHREAD_ERRORCHECK_MUTEX_INITIALIZER + +#define PTHREAD_COND_INITIALIZER ((pthread_cond_t)(size_t) -1) + +#define PTHREAD_RWLOCK_INITIALIZER ((pthread_rwlock_t)(size_t) -1) + +#define PTHREAD_SPINLOCK_INITIALIZER ((pthread_spinlock_t)(size_t) -1) + + +/* + * Mutex types. + */ +enum +{ + /* Compatibility with LinuxThreads */ + PTHREAD_MUTEX_FAST_NP, + PTHREAD_MUTEX_RECURSIVE_NP, + PTHREAD_MUTEX_ERRORCHECK_NP, + PTHREAD_MUTEX_TIMED_NP = PTHREAD_MUTEX_FAST_NP, + PTHREAD_MUTEX_ADAPTIVE_NP = PTHREAD_MUTEX_FAST_NP, + /* For compatibility with POSIX */ + PTHREAD_MUTEX_NORMAL = PTHREAD_MUTEX_FAST_NP, + PTHREAD_MUTEX_RECURSIVE = PTHREAD_MUTEX_RECURSIVE_NP, + PTHREAD_MUTEX_ERRORCHECK = PTHREAD_MUTEX_ERRORCHECK_NP, + PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL +}; + + +typedef struct ptw32_cleanup_t ptw32_cleanup_t; + +#if defined(_MSC_VER) +/* Disable MSVC 'anachronism used' warning */ +#pragma warning( disable : 4229 ) +#endif + +typedef void (* PTW32_CDECL ptw32_cleanup_callback_t)(void *); + +#if defined(_MSC_VER) +#pragma warning( default : 4229 ) +#endif + +struct ptw32_cleanup_t +{ + ptw32_cleanup_callback_t routine; + void *arg; + struct ptw32_cleanup_t *prev; +}; + +#if defined(__CLEANUP_SEH) + /* + * WIN32 SEH version of cancel cleanup. + */ + +#define pthread_cleanup_push( _rout, _arg ) \ + { \ + ptw32_cleanup_t _cleanup; \ + \ + _cleanup.routine = (ptw32_cleanup_callback_t)(_rout); \ + _cleanup.arg = (_arg); \ + __try \ + { \ + +#define pthread_cleanup_pop( _execute ) \ + } \ + __finally \ + { \ + if( _execute || AbnormalTermination()) \ + { \ + (*(_cleanup.routine))( _cleanup.arg ); \ + } \ + } \ + } + +#else /* __CLEANUP_SEH */ + +#if defined(__CLEANUP_C) + + /* + * C implementation of PThreads cancel cleanup + */ + +#define pthread_cleanup_push( _rout, _arg ) \ + { \ + ptw32_cleanup_t _cleanup; \ + \ + ptw32_push_cleanup( &_cleanup, (ptw32_cleanup_callback_t) (_rout), (_arg) ); \ + +#define pthread_cleanup_pop( _execute ) \ + (void) ptw32_pop_cleanup( _execute ); \ + } + +#else /* __CLEANUP_C */ + +#if defined(__CLEANUP_CXX) + + /* + * C++ version of cancel cleanup. + * - John E. Bossom. + */ + + class PThreadCleanup { + /* + * PThreadCleanup + * + * Purpose + * This class is a C++ helper class that is + * used to implement pthread_cleanup_push/ + * pthread_cleanup_pop. + * The destructor of this class automatically + * pops the pushed cleanup routine regardless + * of how the code exits the scope + * (i.e. such as by an exception) + */ + ptw32_cleanup_callback_t cleanUpRout; + void * obj; + int executeIt; + + public: + PThreadCleanup() : + cleanUpRout( 0 ), + obj( 0 ), + executeIt( 0 ) + /* + * No cleanup performed + */ + { + } + + PThreadCleanup( + ptw32_cleanup_callback_t routine, + void * arg ) : + cleanUpRout( routine ), + obj( arg ), + executeIt( 1 ) + /* + * Registers a cleanup routine for 'arg' + */ + { + } + + ~PThreadCleanup() + { + if ( executeIt && ((void *) cleanUpRout != (void *) 0) ) + { + (void) (*cleanUpRout)( obj ); + } + } + + void execute( int exec ) + { + executeIt = exec; + } + }; + + /* + * C++ implementation of PThreads cancel cleanup; + * This implementation takes advantage of a helper + * class who's destructor automatically calls the + * cleanup routine if we exit our scope weirdly + */ +#define pthread_cleanup_push( _rout, _arg ) \ + { \ + PThreadCleanup cleanup((ptw32_cleanup_callback_t)(_rout), \ + (void *) (_arg) ); + +#define pthread_cleanup_pop( _execute ) \ + cleanup.execute( _execute ); \ + } + +#else + +#error ERROR [__FILE__, line __LINE__]: Cleanup type undefined. + +#endif /* __CLEANUP_CXX */ + +#endif /* __CLEANUP_C */ + +#endif /* __CLEANUP_SEH */ + +/* + * =============== + * =============== + * Methods + * =============== + * =============== + */ + +/* + * PThread Attribute Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_attr_init (pthread_attr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_destroy (pthread_attr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_getdetachstate (const pthread_attr_t * attr, + int *detachstate); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_getstackaddr (const pthread_attr_t * attr, + void **stackaddr); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_getstacksize (const pthread_attr_t * attr, + size_t * stacksize); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_setdetachstate (pthread_attr_t * attr, + int detachstate); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_setstackaddr (pthread_attr_t * attr, + void *stackaddr); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_setstacksize (pthread_attr_t * attr, + size_t stacksize); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_getschedparam (const pthread_attr_t *attr, + struct sched_param *param); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_setschedparam (pthread_attr_t *attr, + const struct sched_param *param); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_setschedpolicy (pthread_attr_t *, + int); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_getschedpolicy (const pthread_attr_t *, + int *); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_setinheritsched(pthread_attr_t * attr, + int inheritsched); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_getinheritsched(const pthread_attr_t * attr, + int * inheritsched); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_setscope (pthread_attr_t *, + int); + +PTW32_DLLPORT int PTW32_CDECL pthread_attr_getscope (const pthread_attr_t *, + int *); + +/* + * PThread Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_create (pthread_t * tid, + const pthread_attr_t * attr, + void *(PTW32_CDECL *start) (void *), + void *arg); + +PTW32_DLLPORT int PTW32_CDECL pthread_detach (pthread_t tid); + +PTW32_DLLPORT int PTW32_CDECL pthread_equal (pthread_t t1, + pthread_t t2); + +PTW32_DLLPORT void PTW32_CDECL pthread_exit (void *value_ptr); + +PTW32_DLLPORT int PTW32_CDECL pthread_join (pthread_t thread, + void **value_ptr); + +PTW32_DLLPORT pthread_t PTW32_CDECL pthread_self (void); + +PTW32_DLLPORT int PTW32_CDECL pthread_cancel (pthread_t thread); + +PTW32_DLLPORT int PTW32_CDECL pthread_setcancelstate (int state, + int *oldstate); + +PTW32_DLLPORT int PTW32_CDECL pthread_setcanceltype (int type, + int *oldtype); + +PTW32_DLLPORT void PTW32_CDECL pthread_testcancel (void); + +PTW32_DLLPORT int PTW32_CDECL pthread_once (pthread_once_t * once_control, + void (PTW32_CDECL *init_routine) (void)); + +#if PTW32_LEVEL >= PTW32_LEVEL_MAX +PTW32_DLLPORT ptw32_cleanup_t * PTW32_CDECL ptw32_pop_cleanup (int execute); + +PTW32_DLLPORT void PTW32_CDECL ptw32_push_cleanup (ptw32_cleanup_t * cleanup, + ptw32_cleanup_callback_t routine, + void *arg); +#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ + +/* + * Thread Specific Data Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_key_create (pthread_key_t * key, + void (PTW32_CDECL *destructor) (void *)); + +PTW32_DLLPORT int PTW32_CDECL pthread_key_delete (pthread_key_t key); + +PTW32_DLLPORT int PTW32_CDECL pthread_setspecific (pthread_key_t key, + const void *value); + +PTW32_DLLPORT void * PTW32_CDECL pthread_getspecific (pthread_key_t key); + + +/* + * Mutex Attribute Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_init (pthread_mutexattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_destroy (pthread_mutexattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_getpshared (const pthread_mutexattr_t + * attr, + int *pshared); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_setpshared (pthread_mutexattr_t * attr, + int pshared); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_settype (pthread_mutexattr_t * attr, int kind); +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_gettype (const pthread_mutexattr_t * attr, int *kind); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_setrobust( + pthread_mutexattr_t *attr, + int robust); +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_getrobust( + const pthread_mutexattr_t * attr, + int * robust); + +/* + * Barrier Attribute Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_init (pthread_barrierattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_destroy (pthread_barrierattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_getpshared (const pthread_barrierattr_t + * attr, + int *pshared); + +PTW32_DLLPORT int PTW32_CDECL pthread_barrierattr_setpshared (pthread_barrierattr_t * attr, + int pshared); + +/* + * Mutex Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_mutex_init (pthread_mutex_t * mutex, + const pthread_mutexattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutex_destroy (pthread_mutex_t * mutex); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutex_lock (pthread_mutex_t * mutex); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutex_timedlock(pthread_mutex_t * mutex, + const struct timespec *abstime); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutex_trylock (pthread_mutex_t * mutex); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutex_unlock (pthread_mutex_t * mutex); + +PTW32_DLLPORT int PTW32_CDECL pthread_mutex_consistent (pthread_mutex_t * mutex); + +/* + * Spinlock Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_spin_init (pthread_spinlock_t * lock, int pshared); + +PTW32_DLLPORT int PTW32_CDECL pthread_spin_destroy (pthread_spinlock_t * lock); + +PTW32_DLLPORT int PTW32_CDECL pthread_spin_lock (pthread_spinlock_t * lock); + +PTW32_DLLPORT int PTW32_CDECL pthread_spin_trylock (pthread_spinlock_t * lock); + +PTW32_DLLPORT int PTW32_CDECL pthread_spin_unlock (pthread_spinlock_t * lock); + +/* + * Barrier Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_barrier_init (pthread_barrier_t * barrier, + const pthread_barrierattr_t * attr, + unsigned int count); + +PTW32_DLLPORT int PTW32_CDECL pthread_barrier_destroy (pthread_barrier_t * barrier); + +PTW32_DLLPORT int PTW32_CDECL pthread_barrier_wait (pthread_barrier_t * barrier); + +/* + * Condition Variable Attribute Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_condattr_init (pthread_condattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_condattr_destroy (pthread_condattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_condattr_getpshared (const pthread_condattr_t * attr, + int *pshared); + +PTW32_DLLPORT int PTW32_CDECL pthread_condattr_setpshared (pthread_condattr_t * attr, + int pshared); + +/* + * Condition Variable Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_cond_init (pthread_cond_t * cond, + const pthread_condattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_cond_destroy (pthread_cond_t * cond); + +PTW32_DLLPORT int PTW32_CDECL pthread_cond_wait (pthread_cond_t * cond, + pthread_mutex_t * mutex); + +PTW32_DLLPORT int PTW32_CDECL pthread_cond_timedwait (pthread_cond_t * cond, + pthread_mutex_t * mutex, + const struct timespec *abstime); + +PTW32_DLLPORT int PTW32_CDECL pthread_cond_signal (pthread_cond_t * cond); + +PTW32_DLLPORT int PTW32_CDECL pthread_cond_broadcast (pthread_cond_t * cond); + +/* + * Scheduling + */ +PTW32_DLLPORT int PTW32_CDECL pthread_setschedparam (pthread_t thread, + int policy, + const struct sched_param *param); + +PTW32_DLLPORT int PTW32_CDECL pthread_getschedparam (pthread_t thread, + int *policy, + struct sched_param *param); + +PTW32_DLLPORT int PTW32_CDECL pthread_setconcurrency (int); + +PTW32_DLLPORT int PTW32_CDECL pthread_getconcurrency (void); + +/* + * Read-Write Lock Functions + */ +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_init(pthread_rwlock_t *lock, + const pthread_rwlockattr_t *attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_destroy(pthread_rwlock_t *lock); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_tryrdlock(pthread_rwlock_t *); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_trywrlock(pthread_rwlock_t *); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_rdlock(pthread_rwlock_t *lock); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_timedrdlock(pthread_rwlock_t *lock, + const struct timespec *abstime); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_wrlock(pthread_rwlock_t *lock); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_timedwrlock(pthread_rwlock_t *lock, + const struct timespec *abstime); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlock_unlock(pthread_rwlock_t *lock); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_init (pthread_rwlockattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_destroy (pthread_rwlockattr_t * attr); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_getpshared (const pthread_rwlockattr_t * attr, + int *pshared); + +PTW32_DLLPORT int PTW32_CDECL pthread_rwlockattr_setpshared (pthread_rwlockattr_t * attr, + int pshared); + +#if PTW32_LEVEL >= PTW32_LEVEL_MAX - 1 + +/* + * Signal Functions. Should be defined in but MSVC and MinGW32 + * already have signal.h that don't define these. + */ +PTW32_DLLPORT int PTW32_CDECL pthread_kill(pthread_t thread, int sig); + +/* + * Non-portable functions + */ + +/* + * Compatibility with Linux. + */ +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_setkind_np(pthread_mutexattr_t * attr, + int kind); +PTW32_DLLPORT int PTW32_CDECL pthread_mutexattr_getkind_np(pthread_mutexattr_t * attr, + int *kind); + +/* + * Possibly supported by other POSIX threads implementations + */ +PTW32_DLLPORT int PTW32_CDECL pthread_delay_np (struct timespec * interval); +PTW32_DLLPORT int PTW32_CDECL pthread_num_processors_np(void); +PTW32_DLLPORT unsigned __int64 PTW32_CDECL pthread_getunique_np(pthread_t thread); + +/* + * Useful if an application wants to statically link + * the lib rather than load the DLL at run-time. + */ +PTW32_DLLPORT int PTW32_CDECL pthread_win32_process_attach_np(void); +PTW32_DLLPORT int PTW32_CDECL pthread_win32_process_detach_np(void); +PTW32_DLLPORT int PTW32_CDECL pthread_win32_thread_attach_np(void); +PTW32_DLLPORT int PTW32_CDECL pthread_win32_thread_detach_np(void); + +/* + * Features that are auto-detected at load/run time. + */ +PTW32_DLLPORT int PTW32_CDECL pthread_win32_test_features_np(int); +enum ptw32_features { + PTW32_SYSTEM_INTERLOCKED_COMPARE_EXCHANGE = 0x0001, /* System provides it. */ + PTW32_ALERTABLE_ASYNC_CANCEL = 0x0002 /* Can cancel blocked threads. */ +}; + +/* + * Register a system time change with the library. + * Causes the library to perform various functions + * in response to the change. Should be called whenever + * the application's top level window receives a + * WM_TIMECHANGE message. It can be passed directly to + * pthread_create() as a new thread if desired. + */ +PTW32_DLLPORT void * PTW32_CDECL pthread_timechange_handler_np(void *); + +#endif /*PTW32_LEVEL >= PTW32_LEVEL_MAX - 1 */ + +#if PTW32_LEVEL >= PTW32_LEVEL_MAX + +/* + * Returns the Win32 HANDLE for the POSIX thread. + */ +PTW32_DLLPORT HANDLE PTW32_CDECL pthread_getw32threadhandle_np(pthread_t thread); +/* + * Returns the win32 thread ID for POSIX thread. + */ +PTW32_DLLPORT DWORD PTW32_CDECL pthread_getw32threadid_np (pthread_t thread); + + +/* + * Protected Methods + * + * This function blocks until the given WIN32 handle + * is signaled or pthread_cancel had been called. + * This function allows the caller to hook into the + * PThreads cancel mechanism. It is implemented using + * + * WaitForMultipleObjects + * + * on 'waitHandle' and a manually reset WIN32 Event + * used to implement pthread_cancel. The 'timeout' + * argument to TimedWait is simply passed to + * WaitForMultipleObjects. + */ +PTW32_DLLPORT int PTW32_CDECL pthreadCancelableWait (HANDLE waitHandle); +PTW32_DLLPORT int PTW32_CDECL pthreadCancelableTimedWait (HANDLE waitHandle, + DWORD timeout); + +#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ + +/* + * Thread-Safe C Runtime Library Mappings. + */ +#if !defined(_UWIN) +# if defined(NEED_ERRNO) + PTW32_DLLPORT int * PTW32_CDECL _errno( void ); +# else +# if !defined(errno) +# if (defined(_MT) || defined(_DLL)) + __declspec(dllimport) extern int * __cdecl _errno(void); +# define errno (*_errno()) +# endif +# endif +# endif +#endif + +/* + * Some compiler environments don't define some things. + */ +#if defined(__BORLANDC__) +# define _ftime ftime +# define _timeb timeb +#endif + +#if defined(__cplusplus) + +/* + * Internal exceptions + */ +class ptw32_exception {}; +class ptw32_exception_cancel : public ptw32_exception {}; +class ptw32_exception_exit : public ptw32_exception {}; + +#endif + +#if PTW32_LEVEL >= PTW32_LEVEL_MAX + +/* FIXME: This is only required if the library was built using SEH */ +/* + * Get internal SEH tag + */ +PTW32_DLLPORT DWORD PTW32_CDECL ptw32_get_exception_services_code(void); + +#endif /* PTW32_LEVEL >= PTW32_LEVEL_MAX */ + +#if !defined(PTW32_BUILD) + +#if defined(__CLEANUP_SEH) + +/* + * Redefine the SEH __except keyword to ensure that applications + * propagate our internal exceptions up to the library's internal handlers. + */ +#define __except( E ) \ + __except( ( GetExceptionCode() == ptw32_get_exception_services_code() ) \ + ? EXCEPTION_CONTINUE_SEARCH : ( E ) ) + +#endif /* __CLEANUP_SEH */ + +#if defined(__CLEANUP_CXX) + +/* + * Redefine the C++ catch keyword to ensure that applications + * propagate our internal exceptions up to the library's internal handlers. + */ +#if defined(_MSC_VER) + /* + * WARNING: Replace any 'catch( ... )' with 'PtW32CatchAll' + * if you want Pthread-Win32 cancelation and pthread_exit to work. + */ + +#if !defined(PtW32NoCatchWarn) + +#pragma message("Specify \"/DPtW32NoCatchWarn\" compiler flag to skip this message.") +#pragma message("------------------------------------------------------------------") +#pragma message("When compiling applications with MSVC++ and C++ exception handling:") +#pragma message(" Replace any 'catch( ... )' in routines called from POSIX threads") +#pragma message(" with 'PtW32CatchAll' or 'CATCHALL' if you want POSIX thread") +#pragma message(" cancelation and pthread_exit to work. For example:") +#pragma message("") +#pragma message(" #if defined(PtW32CatchAll)") +#pragma message(" PtW32CatchAll") +#pragma message(" #else") +#pragma message(" catch(...)") +#pragma message(" #endif") +#pragma message(" {") +#pragma message(" /* Catchall block processing */") +#pragma message(" }") +#pragma message("------------------------------------------------------------------") + +#endif + +#define PtW32CatchAll \ + catch( ptw32_exception & ) { throw; } \ + catch( ... ) + +#else /* _MSC_VER */ + +#define catch( E ) \ + catch( ptw32_exception & ) { throw; } \ + catch( E ) + +#endif /* _MSC_VER */ + +#endif /* __CLEANUP_CXX */ + +#endif /* ! PTW32_BUILD */ + +#if defined(__cplusplus) +} /* End of extern "C" */ +#endif /* __cplusplus */ + +#if defined(PTW32__HANDLE_DEF) +# undef HANDLE +#endif +#if defined(PTW32__DWORD_DEF) +# undef DWORD +#endif + +#undef PTW32_LEVEL +#undef PTW32_LEVEL_MAX + +#endif /* ! RC_INVOKED */ + +#endif /* PTHREAD_H */ diff --git a/osal/window/pthread/inc/sched.h b/osal/window/pthread/inc/sched.h index e25eb56b..f36a97a6 100644 --- a/osal/window/pthread/inc/sched.h +++ b/osal/window/pthread/inc/sched.h @@ -1,183 +1,183 @@ -/* - * Module: sched.h - * - * Purpose: - * Provides an implementation of POSIX realtime extensions - * as defined in - * - * POSIX 1003.1b-1993 (POSIX.1b) - * - * -------------------------------------------------------------------------- - * - * Pthreads-win32 - POSIX Threads Library for Win32 - * Copyright(C) 1998 John E. Bossom - * Copyright(C) 1999,2005 Pthreads-win32 contributors - * - * Contact Email: rpj@callisto.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * 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 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 in the file COPYING.LIB; - * if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ -#if !defined(_SCHED_H) -#define _SCHED_H - -#undef PTW32_SCHED_LEVEL - -#if defined(_POSIX_SOURCE) -#define PTW32_SCHED_LEVEL 0 -/* Early POSIX */ -#endif - -#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309 -#undef PTW32_SCHED_LEVEL -#define PTW32_SCHED_LEVEL 1 -/* Include 1b, 1c and 1d */ -#endif - -#if defined(INCLUDE_NP) -#undef PTW32_SCHED_LEVEL -#define PTW32_SCHED_LEVEL 2 -/* Include Non-Portable extensions */ -#endif - -#define PTW32_SCHED_LEVEL_MAX 3 - -#if ( defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112 ) || !defined(PTW32_SCHED_LEVEL) -#define PTW32_SCHED_LEVEL PTW32_SCHED_LEVEL_MAX -/* Include everything */ -#endif - - -#if defined(__GNUC__) && !defined(__declspec) -# error Please upgrade your GNU compiler to one that supports __declspec. -#endif - -/* - * When building the library, you should define PTW32_BUILD so that - * the variables/functions are exported correctly. When using the library, - * do NOT define PTW32_BUILD, and then the variables/functions will - * be imported correctly. - */ -#if !defined(PTW32_STATIC_LIB) -# if defined(PTW32_BUILD) -# define PTW32_DLLPORT __declspec (dllexport) -# else -# define PTW32_DLLPORT __declspec (dllimport) -# endif -#else -# define PTW32_DLLPORT -#endif - -/* - * This is a duplicate of what is in the autoconf config.h, - * which is only used when building the pthread-win32 libraries. - */ - -#if !defined(PTW32_CONFIG_H) -# if defined(WINCE) -# define NEED_ERRNO -# define NEED_SEM -# endif -# if defined(__MINGW64__) -# define HAVE_STRUCT_TIMESPEC -# define HAVE_MODE_T -# elif defined(_UWIN) || defined(__MINGW32__) -# define HAVE_MODE_T -# endif -#endif - -/* - * - */ - -#if PTW32_SCHED_LEVEL >= PTW32_SCHED_LEVEL_MAX -#if defined(NEED_ERRNO) -#include "need_errno.h" -#else -#include -#endif -#endif /* PTW32_SCHED_LEVEL >= PTW32_SCHED_LEVEL_MAX */ - -#if (defined(__MINGW64__) || defined(__MINGW32__)) || defined(_UWIN) -# if PTW32_SCHED_LEVEL >= PTW32_SCHED_LEVEL_MAX -/* For pid_t */ -# include -/* Required by Unix 98 */ -# include -# else - typedef int pid_t; -# endif -#else - typedef int pid_t; -#endif - -/* Thread scheduling policies */ - -enum { - SCHED_OTHER = 0, - SCHED_FIFO, - SCHED_RR, - SCHED_MIN = SCHED_OTHER, - SCHED_MAX = SCHED_RR -}; - -struct sched_param { - int sched_priority; -}; - -#if defined(__cplusplus) -extern "C" -{ -#endif /* __cplusplus */ - -PTW32_DLLPORT int __cdecl sched_yield (void); - -PTW32_DLLPORT int __cdecl sched_get_priority_min (int policy); - -PTW32_DLLPORT int __cdecl sched_get_priority_max (int policy); - -PTW32_DLLPORT int __cdecl sched_setscheduler (pid_t pid, int policy); - -PTW32_DLLPORT int __cdecl sched_getscheduler (pid_t pid); - -/* - * Note that this macro returns ENOTSUP rather than - * ENOSYS as might be expected. However, returning ENOSYS - * should mean that sched_get_priority_{min,max} are - * not implemented as well as sched_rr_get_interval. - * This is not the case, since we just don't support - * round-robin scheduling. Therefore I have chosen to - * return the same value as sched_setscheduler when - * SCHED_RR is passed to it. - */ -#define sched_rr_get_interval(_pid, _interval) \ - ( errno = ENOTSUP, (int) -1 ) - - -#if defined(__cplusplus) -} /* End of extern "C" */ -#endif /* __cplusplus */ - -#undef PTW32_SCHED_LEVEL -#undef PTW32_SCHED_LEVEL_MAX - -#endif /* !_SCHED_H */ - +/* + * Module: sched.h + * + * Purpose: + * Provides an implementation of POSIX realtime extensions + * as defined in + * + * POSIX 1003.1b-1993 (POSIX.1b) + * + * -------------------------------------------------------------------------- + * + * Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * 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 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 in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ +#if !defined(_SCHED_H) +#define _SCHED_H + +#undef PTW32_SCHED_LEVEL + +#if defined(_POSIX_SOURCE) +#define PTW32_SCHED_LEVEL 0 +/* Early POSIX */ +#endif + +#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309 +#undef PTW32_SCHED_LEVEL +#define PTW32_SCHED_LEVEL 1 +/* Include 1b, 1c and 1d */ +#endif + +#if defined(INCLUDE_NP) +#undef PTW32_SCHED_LEVEL +#define PTW32_SCHED_LEVEL 2 +/* Include Non-Portable extensions */ +#endif + +#define PTW32_SCHED_LEVEL_MAX 3 + +#if ( defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112 ) || !defined(PTW32_SCHED_LEVEL) +#define PTW32_SCHED_LEVEL PTW32_SCHED_LEVEL_MAX +/* Include everything */ +#endif + + +#if defined(__GNUC__) && !defined(__declspec) +# error Please upgrade your GNU compiler to one that supports __declspec. +#endif + +/* + * When building the library, you should define PTW32_BUILD so that + * the variables/functions are exported correctly. When using the library, + * do NOT define PTW32_BUILD, and then the variables/functions will + * be imported correctly. + */ +#if !defined(PTW32_STATIC_LIB) +# if defined(PTW32_BUILD) +# define PTW32_DLLPORT __declspec (dllexport) +# else +# define PTW32_DLLPORT __declspec (dllimport) +# endif +#else +# define PTW32_DLLPORT +#endif + +/* + * This is a duplicate of what is in the autoconf config.h, + * which is only used when building the pthread-win32 libraries. + */ + +#if !defined(PTW32_CONFIG_H) +# if defined(WINCE) +# define NEED_ERRNO +# define NEED_SEM +# endif +# if defined(__MINGW64__) +# define HAVE_STRUCT_TIMESPEC +# define HAVE_MODE_T +# elif defined(_UWIN) || defined(__MINGW32__) +# define HAVE_MODE_T +# endif +#endif + +/* + * + */ + +#if PTW32_SCHED_LEVEL >= PTW32_SCHED_LEVEL_MAX +#if defined(NEED_ERRNO) +#include "need_errno.h" +#else +#include +#endif +#endif /* PTW32_SCHED_LEVEL >= PTW32_SCHED_LEVEL_MAX */ + +#if (defined(__MINGW64__) || defined(__MINGW32__)) || defined(_UWIN) +# if PTW32_SCHED_LEVEL >= PTW32_SCHED_LEVEL_MAX +/* For pid_t */ +# include +/* Required by Unix 98 */ +# include +# else + typedef int pid_t; +# endif +#else + typedef int pid_t; +#endif + +/* Thread scheduling policies */ + +enum { + SCHED_OTHER = 0, + SCHED_FIFO, + SCHED_RR, + SCHED_MIN = SCHED_OTHER, + SCHED_MAX = SCHED_RR +}; + +struct sched_param { + int sched_priority; +}; + +#if defined(__cplusplus) +extern "C" +{ +#endif /* __cplusplus */ + +PTW32_DLLPORT int __cdecl sched_yield (void); + +PTW32_DLLPORT int __cdecl sched_get_priority_min (int policy); + +PTW32_DLLPORT int __cdecl sched_get_priority_max (int policy); + +PTW32_DLLPORT int __cdecl sched_setscheduler (pid_t pid, int policy); + +PTW32_DLLPORT int __cdecl sched_getscheduler (pid_t pid); + +/* + * Note that this macro returns ENOTSUP rather than + * ENOSYS as might be expected. However, returning ENOSYS + * should mean that sched_get_priority_{min,max} are + * not implemented as well as sched_rr_get_interval. + * This is not the case, since we just don't support + * round-robin scheduling. Therefore I have chosen to + * return the same value as sched_setscheduler when + * SCHED_RR is passed to it. + */ +#define sched_rr_get_interval(_pid, _interval) \ + ( errno = ENOTSUP, (int) -1 ) + + +#if defined(__cplusplus) +} /* End of extern "C" */ +#endif /* __cplusplus */ + +#undef PTW32_SCHED_LEVEL +#undef PTW32_SCHED_LEVEL_MAX + +#endif /* !_SCHED_H */ + diff --git a/osal/window/pthread/inc/semaphore.h b/osal/window/pthread/inc/semaphore.h index f7a4286e..c6e9407e 100644 --- a/osal/window/pthread/inc/semaphore.h +++ b/osal/window/pthread/inc/semaphore.h @@ -1,169 +1,169 @@ -/* - * Module: semaphore.h - * - * Purpose: - * Semaphores aren't actually part of the PThreads standard. - * They are defined by the POSIX Standard: - * - * POSIX 1003.1b-1993 (POSIX.1b) - * - * -------------------------------------------------------------------------- - * - * Pthreads-win32 - POSIX Threads Library for Win32 - * Copyright(C) 1998 John E. Bossom - * Copyright(C) 1999,2005 Pthreads-win32 contributors - * - * Contact Email: rpj@callisto.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * 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 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 in the file COPYING.LIB; - * if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ -#if !defined( SEMAPHORE_H ) -#define SEMAPHORE_H - -#undef PTW32_SEMAPHORE_LEVEL - -#if defined(_POSIX_SOURCE) -#define PTW32_SEMAPHORE_LEVEL 0 -/* Early POSIX */ -#endif - -#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309 -#undef PTW32_SEMAPHORE_LEVEL -#define PTW32_SEMAPHORE_LEVEL 1 -/* Include 1b, 1c and 1d */ -#endif - -#if defined(INCLUDE_NP) -#undef PTW32_SEMAPHORE_LEVEL -#define PTW32_SEMAPHORE_LEVEL 2 -/* Include Non-Portable extensions */ -#endif - -#define PTW32_SEMAPHORE_LEVEL_MAX 3 - -#if !defined(PTW32_SEMAPHORE_LEVEL) -#define PTW32_SEMAPHORE_LEVEL PTW32_SEMAPHORE_LEVEL_MAX -/* Include everything */ -#endif - -#if defined(__GNUC__) && ! defined (__declspec) -# error Please upgrade your GNU compiler to one that supports __declspec. -#endif - -/* - * When building the library, you should define PTW32_BUILD so that - * the variables/functions are exported correctly. When using the library, - * do NOT define PTW32_BUILD, and then the variables/functions will - * be imported correctly. - */ -#if !defined(PTW32_STATIC_LIB) -# if defined(PTW32_BUILD) -# define PTW32_DLLPORT __declspec (dllexport) -# else -# define PTW32_DLLPORT __declspec (dllimport) -# endif -#else -# define PTW32_DLLPORT -#endif - -/* - * This is a duplicate of what is in the autoconf config.h, - * which is only used when building the pthread-win32 libraries. - */ - -#if !defined(PTW32_CONFIG_H) -# if defined(WINCE) -# define NEED_ERRNO -# define NEED_SEM -# endif -# if defined(__MINGW64__) -# define HAVE_STRUCT_TIMESPEC -# define HAVE_MODE_T -# elif defined(_UWIN) || defined(__MINGW32__) -# define HAVE_MODE_T -# endif -#endif - -/* - * - */ - -#if PTW32_SEMAPHORE_LEVEL >= PTW32_SEMAPHORE_LEVEL_MAX -#if defined(NEED_ERRNO) -#include "need_errno.h" -#else -#include -#endif -#endif /* PTW32_SEMAPHORE_LEVEL >= PTW32_SEMAPHORE_LEVEL_MAX */ - -#define _POSIX_SEMAPHORES - -#if defined(__cplusplus) -extern "C" -{ -#endif /* __cplusplus */ - -#if !defined(HAVE_MODE_T) -typedef unsigned int mode_t; -#endif - - -typedef struct sem_t_ * sem_t; - -PTW32_DLLPORT int __cdecl sem_init (sem_t * sem, - int pshared, - unsigned int value); - -PTW32_DLLPORT int __cdecl sem_destroy (sem_t * sem); - -PTW32_DLLPORT int __cdecl sem_trywait (sem_t * sem); - -PTW32_DLLPORT int __cdecl sem_wait (sem_t * sem); - -PTW32_DLLPORT int __cdecl sem_timedwait (sem_t * sem, - const struct timespec * abstime); - -PTW32_DLLPORT int __cdecl sem_post (sem_t * sem); - -PTW32_DLLPORT int __cdecl sem_post_multiple (sem_t * sem, - int count); - -PTW32_DLLPORT int __cdecl sem_open (const char * name, - int oflag, - mode_t mode, - unsigned int value); - -PTW32_DLLPORT int __cdecl sem_close (sem_t * sem); - -PTW32_DLLPORT int __cdecl sem_unlink (const char * name); - -PTW32_DLLPORT int __cdecl sem_getvalue (sem_t * sem, - int * sval); - -#if defined(__cplusplus) -} /* End of extern "C" */ -#endif /* __cplusplus */ - -#undef PTW32_SEMAPHORE_LEVEL -#undef PTW32_SEMAPHORE_LEVEL_MAX - -#endif /* !SEMAPHORE_H */ +/* + * Module: semaphore.h + * + * Purpose: + * Semaphores aren't actually part of the PThreads standard. + * They are defined by the POSIX Standard: + * + * POSIX 1003.1b-1993 (POSIX.1b) + * + * -------------------------------------------------------------------------- + * + * Pthreads-win32 - POSIX Threads Library for Win32 + * Copyright(C) 1998 John E. Bossom + * Copyright(C) 1999,2005 Pthreads-win32 contributors + * + * Contact Email: rpj@callisto.canberra.edu.au + * + * The current list of contributors is contained + * in the file CONTRIBUTORS included with the source + * code distribution. The list can also be seen at the + * following World Wide Web location: + * http://sources.redhat.com/pthreads-win32/contributors.html + * + * 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 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 in the file COPYING.LIB; + * if not, write to the Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ +#if !defined( SEMAPHORE_H ) +#define SEMAPHORE_H + +#undef PTW32_SEMAPHORE_LEVEL + +#if defined(_POSIX_SOURCE) +#define PTW32_SEMAPHORE_LEVEL 0 +/* Early POSIX */ +#endif + +#if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309 +#undef PTW32_SEMAPHORE_LEVEL +#define PTW32_SEMAPHORE_LEVEL 1 +/* Include 1b, 1c and 1d */ +#endif + +#if defined(INCLUDE_NP) +#undef PTW32_SEMAPHORE_LEVEL +#define PTW32_SEMAPHORE_LEVEL 2 +/* Include Non-Portable extensions */ +#endif + +#define PTW32_SEMAPHORE_LEVEL_MAX 3 + +#if !defined(PTW32_SEMAPHORE_LEVEL) +#define PTW32_SEMAPHORE_LEVEL PTW32_SEMAPHORE_LEVEL_MAX +/* Include everything */ +#endif + +#if defined(__GNUC__) && ! defined (__declspec) +# error Please upgrade your GNU compiler to one that supports __declspec. +#endif + +/* + * When building the library, you should define PTW32_BUILD so that + * the variables/functions are exported correctly. When using the library, + * do NOT define PTW32_BUILD, and then the variables/functions will + * be imported correctly. + */ +#if !defined(PTW32_STATIC_LIB) +# if defined(PTW32_BUILD) +# define PTW32_DLLPORT __declspec (dllexport) +# else +# define PTW32_DLLPORT __declspec (dllimport) +# endif +#else +# define PTW32_DLLPORT +#endif + +/* + * This is a duplicate of what is in the autoconf config.h, + * which is only used when building the pthread-win32 libraries. + */ + +#if !defined(PTW32_CONFIG_H) +# if defined(WINCE) +# define NEED_ERRNO +# define NEED_SEM +# endif +# if defined(__MINGW64__) +# define HAVE_STRUCT_TIMESPEC +# define HAVE_MODE_T +# elif defined(_UWIN) || defined(__MINGW32__) +# define HAVE_MODE_T +# endif +#endif + +/* + * + */ + +#if PTW32_SEMAPHORE_LEVEL >= PTW32_SEMAPHORE_LEVEL_MAX +#if defined(NEED_ERRNO) +#include "need_errno.h" +#else +#include +#endif +#endif /* PTW32_SEMAPHORE_LEVEL >= PTW32_SEMAPHORE_LEVEL_MAX */ + +#define _POSIX_SEMAPHORES + +#if defined(__cplusplus) +extern "C" +{ +#endif /* __cplusplus */ + +#if !defined(HAVE_MODE_T) +typedef unsigned int mode_t; +#endif + + +typedef struct sem_t_ * sem_t; + +PTW32_DLLPORT int __cdecl sem_init (sem_t * sem, + int pshared, + unsigned int value); + +PTW32_DLLPORT int __cdecl sem_destroy (sem_t * sem); + +PTW32_DLLPORT int __cdecl sem_trywait (sem_t * sem); + +PTW32_DLLPORT int __cdecl sem_wait (sem_t * sem); + +PTW32_DLLPORT int __cdecl sem_timedwait (sem_t * sem, + const struct timespec * abstime); + +PTW32_DLLPORT int __cdecl sem_post (sem_t * sem); + +PTW32_DLLPORT int __cdecl sem_post_multiple (sem_t * sem, + int count); + +PTW32_DLLPORT int __cdecl sem_open (const char * name, + int oflag, + mode_t mode, + unsigned int value); + +PTW32_DLLPORT int __cdecl sem_close (sem_t * sem); + +PTW32_DLLPORT int __cdecl sem_unlink (const char * name); + +PTW32_DLLPORT int __cdecl sem_getvalue (sem_t * sem, + int * sval); + +#if defined(__cplusplus) +} /* End of extern "C" */ +#endif /* __cplusplus */ + +#undef PTW32_SEMAPHORE_LEVEL +#undef PTW32_SEMAPHORE_LEVEL_MAX + +#endif /* !SEMAPHORE_H */ diff --git a/osal/window/stdint.h b/osal/window/stdint.h index 6e72e7f7..b49ae630 100644 --- a/osal/window/stdint.h +++ b/osal/window/stdint.h @@ -1,13 +1,13 @@ -#pragma once - -/* a minimal set of C99 types for use with MSVC */ - -typedef signed char int8_t; -typedef short int int16_t; -typedef int int32_t; -typedef __int64 int64_t; - -typedef unsigned char uint8_t; -typedef unsigned short int uint16_t; -typedef unsigned int uint32_t; -typedef unsigned __int64 uint64_t; +#pragma once + +/* a minimal set of C99 types for use with MSVC */ + +typedef signed char int8_t; +typedef short int int16_t; +typedef int int32_t; +typedef __int64 int64_t; + +typedef unsigned char uint8_t; +typedef unsigned short int uint16_t; +typedef unsigned int uint32_t; +typedef unsigned __int64 uint64_t; diff --git a/test/mpi_dec_test.c b/test/mpi_dec_test.c index 8db6a87f..c165801c 100644 --- a/test/mpi_dec_test.c +++ b/test/mpi_dec_test.c @@ -1,402 +1,402 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#if defined(_WIN32) -#include "vld.h" -#endif - -#define MODULE_TAG "mpi_dec_test" - -#include -#include "rk_mpi.h" - -#include "mpp_log.h" -#include "mpp_mem.h" -#include "mpp_env.h" -#include "mpp_time.h" - -#include "utils.h" - -#define MPI_DEC_LOOP_COUNT 4 -#define MPI_DEC_STREAM_SIZE (SZ_64K) -#define MAX_FILE_NAME_LENGTH 256 - -typedef struct { - char file_input[MAX_FILE_NAME_LENGTH]; - char file_output[MAX_FILE_NAME_LENGTH]; - MppCodingType type; - RK_U32 width; - RK_U32 height; - RK_U32 debug; - - RK_U32 have_input; - RK_U32 have_output; -} MpiDecTestCmd; - -static OptionInfo mpi_dec_cmd[] = { - {"i", "input_file", "input bitstream file"}, - {"o", "output_file", "output bitstream file, "}, - {"w", "width", "the width of input bitstream"}, - {"h", "height", "the height of input bitstream"}, - {"t", "type", "input stream coding type"}, - {"d", "debug", "debug flag"}, -}; - -int mpi_dec_test(MpiDecTestCmd *cmd) -{ - MPP_RET ret = MPP_OK; - RK_U32 pkt_eos = 0; - RK_U32 frm_eos = 0; - FILE *fp_input = NULL; - FILE *fp_output = NULL; - - // base flow context - MppCtx ctx = NULL; - MppApi *mpi = NULL; - - // input / output - MppPacket packet = NULL; - MppFrame frame = NULL; - - MpiCmd mpi_cmd = MPP_CMD_BASE; - MppParam param = NULL; - RK_U32 need_split = 1; - - // paramter for resource malloc - RK_U32 width = cmd->width; - RK_U32 height = cmd->height; - MppCodingType type = cmd->type; - - // resources - char *buf = NULL; - size_t packet_size = MPI_DEC_STREAM_SIZE; - size_t read_size = 0; - RK_U32 frame_count = 0; - - mpp_log("mpi_dec_test start\n"); - - if (cmd->have_input) { - fp_input = fopen(cmd->file_input, "rb"); - if (NULL == fp_input) { - mpp_err("failed to open input file %s\n", cmd->file_input); - goto MPP_TEST_OUT; - } - } - - if (cmd->have_output) { - fp_output = fopen(cmd->file_output, "w+b"); - if (NULL == fp_output) { - mpp_err("failed to open output file %s\n", cmd->file_output); - goto MPP_TEST_OUT; - } - } - - buf = mpp_malloc(char, packet_size); - if (NULL == buf) { - mpp_err("mpi_dec_test malloc input stream buffer failed\n"); - goto MPP_TEST_OUT; - } - - ret = mpp_packet_init(&packet, buf, packet_size); - if (ret) { - mpp_err("mpp_packet_init failed\n"); - goto MPP_TEST_OUT; - } - - mpp_log("mpi_dec_test decoder test start w %d h %d type %d\n", width, height, type); - - // decoder demo - ret = mpp_create(&ctx, &mpi); - - if (MPP_OK != ret) { - mpp_err("mpp_create failed\n"); - goto MPP_TEST_OUT; - } - - // NOTE: decoder split mode need to be set before init - mpi_cmd = MPP_DEC_SET_PARSER_SPLIT_MODE; - param = &need_split; - ret = mpi->control(ctx, mpi_cmd, param); - if (MPP_OK != ret) { - mpp_err("mpi->control failed\n"); - goto MPP_TEST_OUT; - } - - ret = mpp_init(ctx, MPP_CTX_DEC, type); - if (MPP_OK != ret) { - mpp_err("mpp_init failed\n"); - goto MPP_TEST_OUT; - } - - while (!pkt_eos) { - RK_S32 pkt_done = 0; - read_size = fread(buf, 1, packet_size, fp_input); - if (read_size != packet_size || feof(fp_input)) { - mpp_log("found last packet\n"); - pkt_eos = 1; - } - - // write data to packet - mpp_packet_write(packet, 0, buf, read_size); - // reset pos - mpp_packet_set_pos(packet, buf); - // setup eos flag - if (pkt_eos) - mpp_packet_set_eos(packet); - - frame = NULL; - do { - // send the packet first if packet is not done - if (!pkt_done) { - ret = mpi->decode_put_packet(ctx, packet); - if (MPP_OK == ret) - pkt_done = 1; - } - - // then get all available frame and release - do { - RK_S32 get_frm = 0; - ret = mpi->decode_get_frame(ctx, &frame); - if (MPP_OK != ret) { - mpp_err("decode_get_frame failed ret %d\n", ret); - goto MPP_TEST_OUT; - } - - if (frame) { - if (mpp_frame_get_info_change(frame)) { - mpp_log("decode_get_frame get info changed found\n"); - mpi->control(ctx, MPP_DEC_SET_INFO_CHANGE_READY, NULL); - } else { - mpp_log("decode_get_frame get frame %d\n", frame_count++); - if (fp_output) - dump_mpp_frame_to_file(frame, fp_output); - } - frm_eos = mpp_frame_get_eos(frame); - mpp_frame_deinit(&frame); - frame = NULL; - get_frm = 1; - } - - // if last packet is send but last frame is not found continue - if (pkt_eos && pkt_done && !frm_eos) - continue; - - if (get_frm) - continue; - - break; - } while (1); - - if (pkt_done) - break; - - msleep(50); - } while (1); - } - - ret = mpi->reset(ctx); - if (MPP_OK != ret) { - mpp_err("mpi->reset failed\n"); - goto MPP_TEST_OUT; - } - -MPP_TEST_OUT: - if (packet) { - mpp_packet_deinit(&packet); - packet = NULL; - } - - if (ctx) { - mpp_destroy(ctx); - ctx = NULL; - } - - if (buf) { - mpp_free(buf); - buf = NULL; - } - - if (fp_output) { - fclose(fp_output); - fp_output = NULL; - } - - if (fp_input) { - fclose(fp_input); - fp_input = NULL; - } - - if (MPP_OK == ret) - mpp_log("mpi_dec_test success\n"); - else - mpp_err("mpi_dec_test failed ret %d\n", ret); - - return ret; -} - - -static void mpi_dec_test_help() -{ - mpp_log("usage: mpi_dec_test [options]\n"); - show_options(mpi_dec_cmd); - mpp_show_support_format(); -} - -static RK_S32 mpi_dec_test_parse_options(int argc, char **argv, MpiDecTestCmd* cmd) -{ - const char *opt; - const char *next; - RK_S32 optindex = 1; - RK_S32 handleoptions = 1; - RK_S32 err = MPP_NOK; - - if ((argc < 2) || (cmd == NULL)) { - err = 1; - return err; - } - - /* parse options */ - while (optindex < argc) { - opt = (const char*)argv[optindex++]; - next = (const char*)argv[optindex]; - - if (handleoptions && opt[0] == '-' && opt[1] != '\0') { - if (opt[1] == '-') { - if (opt[2] != '\0') { - opt++; - } else { - handleoptions = 0; - continue; - } - } - - opt++; - - switch (*opt) { - case 'i': - if (next) { - strncpy(cmd->file_input, next, MAX_FILE_NAME_LENGTH); - cmd->file_input[strlen(next)] = '\0'; - cmd->have_input = 1; - } else { - mpp_err("input file is invalid\n"); - goto PARSE_OPINIONS_OUT; - } - break; - case 'o': - if (next) { - strncpy(cmd->file_output, next, MAX_FILE_NAME_LENGTH); - cmd->file_output[strlen(next)] = '\0'; - cmd->have_output = 1; - } else { - mpp_log("output file is invalid\n"); - goto PARSE_OPINIONS_OUT; - } - break; - case 'd': - if (next) { - cmd->debug = atoi(next);; - } else { - mpp_err("invalid debug flag\n"); - goto PARSE_OPINIONS_OUT; - } - break; - case 'w': - if (next) { - cmd->width = atoi(next); - } else { - mpp_err("invalid input width\n"); - goto PARSE_OPINIONS_OUT; - } - break; - case 'h': - if ((*(opt + 1) != '\0') && !strncmp(opt, "help", 4)) { - mpi_dec_test_help(); - err = 1; - goto PARSE_OPINIONS_OUT; - } else if (next) { - cmd->height = atoi(next); - } else { - mpp_log("input height is invalid\n"); - goto PARSE_OPINIONS_OUT; - } - break; - case 't': - if (next) { - cmd->type = (MppCodingType)atoi(next); - err = mpp_check_support_format(MPP_CTX_DEC, cmd->type); - } - - if (!next || err) { - mpp_err("invalid input coding type\n"); - goto PARSE_OPINIONS_OUT; - } - break; - default: - goto PARSE_OPINIONS_OUT; - break; - } - - optindex++; - } - } - - err = 0; - -PARSE_OPINIONS_OUT: - return err; -} - -static void mpi_dec_test_show_options(MpiDecTestCmd* cmd) -{ - mpp_log("cmd parse result:\n"); - mpp_log("input file name: %s\n", cmd->file_input); - mpp_log("output file name: %s\n", cmd->file_output); - mpp_log("width : %4d\n", cmd->width); - mpp_log("height : %4d\n", cmd->height); - mpp_log("type : %d\n", cmd->type); - mpp_log("debug flag : %x\n", cmd->debug); -} - -int main(int argc, char **argv) -{ - RK_S32 ret = 0; - MpiDecTestCmd cmd_ctx; - MpiDecTestCmd* cmd = &cmd_ctx; - - memset((void*)cmd, 0, sizeof(*cmd)); - - // parse the cmd option - ret = mpi_dec_test_parse_options(argc, argv, cmd); - if (ret) { - if (ret < 0) { - mpp_err("mpi_dec_test_parse_options: input parameter invalid\n"); - } - - mpi_dec_test_help(); - return ret; - } - - mpi_dec_test_show_options(cmd); - - mpp_env_set_u32("mpi_debug", cmd->debug); - - mpi_dec_test(cmd); - - mpp_env_set_u32("mpi_debug", 0x0); - return 0; -} - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined(_WIN32) +#include "vld.h" +#endif + +#define MODULE_TAG "mpi_dec_test" + +#include +#include "rk_mpi.h" + +#include "mpp_log.h" +#include "mpp_mem.h" +#include "mpp_env.h" +#include "mpp_time.h" + +#include "utils.h" + +#define MPI_DEC_LOOP_COUNT 4 +#define MPI_DEC_STREAM_SIZE (SZ_64K) +#define MAX_FILE_NAME_LENGTH 256 + +typedef struct { + char file_input[MAX_FILE_NAME_LENGTH]; + char file_output[MAX_FILE_NAME_LENGTH]; + MppCodingType type; + RK_U32 width; + RK_U32 height; + RK_U32 debug; + + RK_U32 have_input; + RK_U32 have_output; +} MpiDecTestCmd; + +static OptionInfo mpi_dec_cmd[] = { + {"i", "input_file", "input bitstream file"}, + {"o", "output_file", "output bitstream file, "}, + {"w", "width", "the width of input bitstream"}, + {"h", "height", "the height of input bitstream"}, + {"t", "type", "input stream coding type"}, + {"d", "debug", "debug flag"}, +}; + +int mpi_dec_test(MpiDecTestCmd *cmd) +{ + MPP_RET ret = MPP_OK; + RK_U32 pkt_eos = 0; + RK_U32 frm_eos = 0; + FILE *fp_input = NULL; + FILE *fp_output = NULL; + + // base flow context + MppCtx ctx = NULL; + MppApi *mpi = NULL; + + // input / output + MppPacket packet = NULL; + MppFrame frame = NULL; + + MpiCmd mpi_cmd = MPP_CMD_BASE; + MppParam param = NULL; + RK_U32 need_split = 1; + + // paramter for resource malloc + RK_U32 width = cmd->width; + RK_U32 height = cmd->height; + MppCodingType type = cmd->type; + + // resources + char *buf = NULL; + size_t packet_size = MPI_DEC_STREAM_SIZE; + size_t read_size = 0; + RK_U32 frame_count = 0; + + mpp_log("mpi_dec_test start\n"); + + if (cmd->have_input) { + fp_input = fopen(cmd->file_input, "rb"); + if (NULL == fp_input) { + mpp_err("failed to open input file %s\n", cmd->file_input); + goto MPP_TEST_OUT; + } + } + + if (cmd->have_output) { + fp_output = fopen(cmd->file_output, "w+b"); + if (NULL == fp_output) { + mpp_err("failed to open output file %s\n", cmd->file_output); + goto MPP_TEST_OUT; + } + } + + buf = mpp_malloc(char, packet_size); + if (NULL == buf) { + mpp_err("mpi_dec_test malloc input stream buffer failed\n"); + goto MPP_TEST_OUT; + } + + ret = mpp_packet_init(&packet, buf, packet_size); + if (ret) { + mpp_err("mpp_packet_init failed\n"); + goto MPP_TEST_OUT; + } + + mpp_log("mpi_dec_test decoder test start w %d h %d type %d\n", width, height, type); + + // decoder demo + ret = mpp_create(&ctx, &mpi); + + if (MPP_OK != ret) { + mpp_err("mpp_create failed\n"); + goto MPP_TEST_OUT; + } + + // NOTE: decoder split mode need to be set before init + mpi_cmd = MPP_DEC_SET_PARSER_SPLIT_MODE; + param = &need_split; + ret = mpi->control(ctx, mpi_cmd, param); + if (MPP_OK != ret) { + mpp_err("mpi->control failed\n"); + goto MPP_TEST_OUT; + } + + ret = mpp_init(ctx, MPP_CTX_DEC, type); + if (MPP_OK != ret) { + mpp_err("mpp_init failed\n"); + goto MPP_TEST_OUT; + } + + while (!pkt_eos) { + RK_S32 pkt_done = 0; + read_size = fread(buf, 1, packet_size, fp_input); + if (read_size != packet_size || feof(fp_input)) { + mpp_log("found last packet\n"); + pkt_eos = 1; + } + + // write data to packet + mpp_packet_write(packet, 0, buf, read_size); + // reset pos + mpp_packet_set_pos(packet, buf); + // setup eos flag + if (pkt_eos) + mpp_packet_set_eos(packet); + + frame = NULL; + do { + // send the packet first if packet is not done + if (!pkt_done) { + ret = mpi->decode_put_packet(ctx, packet); + if (MPP_OK == ret) + pkt_done = 1; + } + + // then get all available frame and release + do { + RK_S32 get_frm = 0; + ret = mpi->decode_get_frame(ctx, &frame); + if (MPP_OK != ret) { + mpp_err("decode_get_frame failed ret %d\n", ret); + goto MPP_TEST_OUT; + } + + if (frame) { + if (mpp_frame_get_info_change(frame)) { + mpp_log("decode_get_frame get info changed found\n"); + mpi->control(ctx, MPP_DEC_SET_INFO_CHANGE_READY, NULL); + } else { + mpp_log("decode_get_frame get frame %d\n", frame_count++); + if (fp_output) + dump_mpp_frame_to_file(frame, fp_output); + } + frm_eos = mpp_frame_get_eos(frame); + mpp_frame_deinit(&frame); + frame = NULL; + get_frm = 1; + } + + // if last packet is send but last frame is not found continue + if (pkt_eos && pkt_done && !frm_eos) + continue; + + if (get_frm) + continue; + + break; + } while (1); + + if (pkt_done) + break; + + msleep(50); + } while (1); + } + + ret = mpi->reset(ctx); + if (MPP_OK != ret) { + mpp_err("mpi->reset failed\n"); + goto MPP_TEST_OUT; + } + +MPP_TEST_OUT: + if (packet) { + mpp_packet_deinit(&packet); + packet = NULL; + } + + if (ctx) { + mpp_destroy(ctx); + ctx = NULL; + } + + if (buf) { + mpp_free(buf); + buf = NULL; + } + + if (fp_output) { + fclose(fp_output); + fp_output = NULL; + } + + if (fp_input) { + fclose(fp_input); + fp_input = NULL; + } + + if (MPP_OK == ret) + mpp_log("mpi_dec_test success\n"); + else + mpp_err("mpi_dec_test failed ret %d\n", ret); + + return ret; +} + + +static void mpi_dec_test_help() +{ + mpp_log("usage: mpi_dec_test [options]\n"); + show_options(mpi_dec_cmd); + mpp_show_support_format(); +} + +static RK_S32 mpi_dec_test_parse_options(int argc, char **argv, MpiDecTestCmd* cmd) +{ + const char *opt; + const char *next; + RK_S32 optindex = 1; + RK_S32 handleoptions = 1; + RK_S32 err = MPP_NOK; + + if ((argc < 2) || (cmd == NULL)) { + err = 1; + return err; + } + + /* parse options */ + while (optindex < argc) { + opt = (const char*)argv[optindex++]; + next = (const char*)argv[optindex]; + + if (handleoptions && opt[0] == '-' && opt[1] != '\0') { + if (opt[1] == '-') { + if (opt[2] != '\0') { + opt++; + } else { + handleoptions = 0; + continue; + } + } + + opt++; + + switch (*opt) { + case 'i': + if (next) { + strncpy(cmd->file_input, next, MAX_FILE_NAME_LENGTH); + cmd->file_input[strlen(next)] = '\0'; + cmd->have_input = 1; + } else { + mpp_err("input file is invalid\n"); + goto PARSE_OPINIONS_OUT; + } + break; + case 'o': + if (next) { + strncpy(cmd->file_output, next, MAX_FILE_NAME_LENGTH); + cmd->file_output[strlen(next)] = '\0'; + cmd->have_output = 1; + } else { + mpp_log("output file is invalid\n"); + goto PARSE_OPINIONS_OUT; + } + break; + case 'd': + if (next) { + cmd->debug = atoi(next);; + } else { + mpp_err("invalid debug flag\n"); + goto PARSE_OPINIONS_OUT; + } + break; + case 'w': + if (next) { + cmd->width = atoi(next); + } else { + mpp_err("invalid input width\n"); + goto PARSE_OPINIONS_OUT; + } + break; + case 'h': + if ((*(opt + 1) != '\0') && !strncmp(opt, "help", 4)) { + mpi_dec_test_help(); + err = 1; + goto PARSE_OPINIONS_OUT; + } else if (next) { + cmd->height = atoi(next); + } else { + mpp_log("input height is invalid\n"); + goto PARSE_OPINIONS_OUT; + } + break; + case 't': + if (next) { + cmd->type = (MppCodingType)atoi(next); + err = mpp_check_support_format(MPP_CTX_DEC, cmd->type); + } + + if (!next || err) { + mpp_err("invalid input coding type\n"); + goto PARSE_OPINIONS_OUT; + } + break; + default: + goto PARSE_OPINIONS_OUT; + break; + } + + optindex++; + } + } + + err = 0; + +PARSE_OPINIONS_OUT: + return err; +} + +static void mpi_dec_test_show_options(MpiDecTestCmd* cmd) +{ + mpp_log("cmd parse result:\n"); + mpp_log("input file name: %s\n", cmd->file_input); + mpp_log("output file name: %s\n", cmd->file_output); + mpp_log("width : %4d\n", cmd->width); + mpp_log("height : %4d\n", cmd->height); + mpp_log("type : %d\n", cmd->type); + mpp_log("debug flag : %x\n", cmd->debug); +} + +int main(int argc, char **argv) +{ + RK_S32 ret = 0; + MpiDecTestCmd cmd_ctx; + MpiDecTestCmd* cmd = &cmd_ctx; + + memset((void*)cmd, 0, sizeof(*cmd)); + + // parse the cmd option + ret = mpi_dec_test_parse_options(argc, argv, cmd); + if (ret) { + if (ret < 0) { + mpp_err("mpi_dec_test_parse_options: input parameter invalid\n"); + } + + mpi_dec_test_help(); + return ret; + } + + mpi_dec_test_show_options(cmd); + + mpp_env_set_u32("mpi_debug", cmd->debug); + + mpi_dec_test(cmd); + + mpp_env_set_u32("mpi_debug", 0x0); + return 0; +} + diff --git a/test/mpi_enc_test.c b/test/mpi_enc_test.c index 175bd4e2..3ec3f8ee 100644 --- a/test/mpi_enc_test.c +++ b/test/mpi_enc_test.c @@ -1,535 +1,535 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#if defined(_WIN32) -#include "vld.h" -#endif - -#define MODULE_TAG "mpi_enc_test" - -#include -#include "rk_mpi.h" - -#include "mpp_log.h" -#include "mpp_env.h" -#include "mpp_time.h" -#include "mpp_common.h" - -#include "utils.h" - -#include "vpu_api.h" - -#define MPI_ENC_IO_COUNT (4) -#define MAX_FILE_NAME_LENGTH 256 - -typedef struct { - char file_input[MAX_FILE_NAME_LENGTH]; - char file_output[MAX_FILE_NAME_LENGTH]; - MppCodingType type; - RK_U32 width; - RK_U32 height; - MppFrameFormat format; - RK_U32 debug; - - RK_U32 have_input; - RK_U32 have_output; -} MpiEncTestCmd; - -static OptionInfo mpi_enc_cmd[] = { - {"i", "input_file", "input bitstream file"}, - {"o", "output_file", "output bitstream file, "}, - {"w", "width", "the width of input bitstream"}, - {"h", "height", "the height of input bitstream"}, - {"f", "format", "the picture format of input bitstream"}, - {"t", "type", "input stream coding type"}, - {"d", "debug", "debug flag"}, -}; - -int mpi_enc_test(MpiEncTestCmd *cmd) -{ - MPP_RET ret = MPP_OK; - RK_U32 frm_eos = 0; - RK_U32 pkt_eos = 0; - FILE *fp_input = NULL; - FILE *fp_output = NULL; - - // base flow context - MppCtx ctx = NULL; - MppApi *mpi = NULL; - MppEncConfig mpp_cfg; - - // input / output - RK_S32 i; - MppBufferGroup frm_grp = NULL; - MppBufferGroup pkt_grp = NULL; - MppFrame frame = NULL; - MppPacket packet = NULL; - MppBuffer frm_buf[MPI_ENC_IO_COUNT] = { NULL }; - MppBuffer pkt_buf[MPI_ENC_IO_COUNT] = { NULL }; - - // paramter for resource malloc - RK_U32 width = cmd->width; - RK_U32 height = cmd->height; - RK_U32 hor_stride = MPP_ALIGN(width, 16); - RK_U32 ver_stride = MPP_ALIGN(height, 16); - MppFrameFormat fmt = cmd->format; - MppCodingType type = cmd->type; - - // resources - size_t frame_size = hor_stride * ver_stride * 3 / 2; - size_t packet_size = width * height; /* NOTE: packet buffer may overflow */ - size_t read_size = 0; - RK_U32 frame_count = 0; - RK_U64 stream_size = 0; - - mpp_log("mpi_enc_test start\n"); - - if (cmd->have_input) { - fp_input = fopen(cmd->file_input, "rb"); - if (NULL == fp_input) { - mpp_err("failed to open input file %s\n", cmd->file_input); - ret = MPP_ERR_OPEN_FILE; - goto MPP_TEST_OUT; - } - } - - if (cmd->have_output) { - fp_output = fopen(cmd->file_output, "w+b"); - if (NULL == fp_output) { - mpp_err("failed to open output file %s\n", cmd->file_output); - ret = MPP_ERR_OPEN_FILE; - goto MPP_TEST_OUT; - } - } - - ret = mpp_buffer_group_get_internal(&frm_grp, MPP_BUFFER_TYPE_ION); - if (ret) { - mpp_err("failed to get buffer group for input frame ret %d\n", ret); - goto MPP_TEST_OUT; - } - - ret = mpp_buffer_group_get_internal(&pkt_grp, MPP_BUFFER_TYPE_ION); - if (ret) { - mpp_err("failed to get buffer group for output packet ret %d\n", ret); - goto MPP_TEST_OUT; - } - - for (i = 0; i < MPI_ENC_IO_COUNT; i++) { - ret = mpp_buffer_get(frm_grp, &frm_buf[i], frame_size); - if (ret) { - mpp_err("failed to get buffer for input frame ret %d\n", ret); - goto MPP_TEST_OUT; - } - - ret = mpp_buffer_get(pkt_grp, &pkt_buf[i], packet_size); - if (ret) { - mpp_err("failed to get buffer for input frame ret %d\n", ret); - goto MPP_TEST_OUT; - } - } - - mpp_log("mpi_enc_test encoder test start w %d h %d type %d\n", width, height, type); - - // encoder demo - ret = mpp_create(&ctx, &mpi); - - if (MPP_OK != ret) { - mpp_err("mpp_create failed\n"); - goto MPP_TEST_OUT; - } - - ret = mpp_init(ctx, MPP_CTX_ENC, type); - if (MPP_OK != ret) { - mpp_err("mpp_init failed\n"); - goto MPP_TEST_OUT; - } - - memset(&mpp_cfg, 0, sizeof(mpp_cfg)); - mpp_cfg.size = sizeof(mpp_cfg); - mpp_cfg.width = width; - mpp_cfg.height = height; - mpp_cfg.format = fmt; - mpp_cfg.rc_mode = 0; - mpp_cfg.skip_cnt = 0; - mpp_cfg.fps_in = 30; - mpp_cfg.fps_out = 30; - mpp_cfg.bps = width * height * 2 * mpp_cfg.fps_in; - mpp_cfg.qp = 24; - mpp_cfg.gop = 60; - - mpp_cfg.profile = 100; - mpp_cfg.level = 41; - mpp_cfg.cabac_en = 1; - - ret = mpi->control(ctx, MPP_ENC_SET_CFG, &mpp_cfg); - if (MPP_OK != ret) { - mpp_err("mpi control enc set cfg failed\n"); - goto MPP_TEST_OUT; - } - - ret = mpi->control(ctx, MPP_ENC_GET_EXTRA_INFO, &packet); - if (MPP_OK != ret) { - mpp_err("mpi control enc get extra info failed\n"); - goto MPP_TEST_OUT; - } - - /* get and write sps/pps for H.264 */ - if (packet) { - void *ptr = mpp_packet_get_pos(packet); - size_t len = mpp_packet_get_length(packet); - - if (fp_output) - fwrite(ptr, 1, len, fp_output); - - packet = NULL; - } - - ret = mpp_frame_init(&frame); - if (MPP_OK != ret) { - mpp_err("mpp_frame_init failed\n"); - goto MPP_TEST_OUT; - } - - mpp_frame_set_width(frame, width); - mpp_frame_set_height(frame, height); - mpp_frame_set_hor_stride(frame, hor_stride); - mpp_frame_set_ver_stride(frame, ver_stride); - - i = 0; - while (!pkt_eos) { - MppTask task = NULL; - RK_S32 index = i++; - MppBuffer frm_buf_in = frm_buf[index]; - MppBuffer pkt_buf_out = pkt_buf[index]; - void *buf = mpp_buffer_get_ptr(frm_buf_in); - - if (i == MPI_ENC_IO_COUNT) - i = 0; - - read_size = fread(buf, 1, frame_size, fp_input); - if (read_size != frame_size || feof(fp_input)) { - mpp_log("found last frame\n"); - frm_eos = 1; - } - - mpp_frame_set_buffer(frame, frm_buf_in); - mpp_frame_set_eos(frame, frm_eos); - - mpp_packet_init_with_buffer(&packet, pkt_buf_out); - - do { - ret = mpi->dequeue(ctx, MPP_PORT_INPUT, &task); - if (ret) { - mpp_err("mpp task input dequeue failed\n"); - goto MPP_TEST_OUT; - } - if (task == NULL) { - mpp_log("mpi dequeue from MPP_PORT_INPUT fail, task equal with NULL!"); - msleep(3); - } else { - MppFrame frame_out = NULL; - - mpp_task_meta_get_frame (task, MPP_META_KEY_INPUT_FRM, &frame_out); - if (frame_out) - mpp_assert(frame_out == frame); - - break; - } - } while (1); - - - mpp_task_meta_set_frame (task, MPP_META_KEY_INPUT_FRM, frame); - mpp_task_meta_set_packet(task, MPP_META_KEY_OUTPUT_PKT, packet); - - ret = mpi->enqueue(ctx, MPP_PORT_INPUT, task); - if (ret) { - mpp_err("mpp task input enqueue failed\n"); - goto MPP_TEST_OUT; - } - - msleep(20); - - do { - ret = mpi->dequeue(ctx, MPP_PORT_OUTPUT, &task); - if (ret) { - mpp_err("mpp task output dequeue failed\n"); - goto MPP_TEST_OUT; - } - - if (task) { - MppFrame packet_out = NULL; - - mpp_task_meta_get_packet(task, MPP_META_KEY_OUTPUT_PKT, &packet_out); - - mpp_assert(packet_out == packet); - if (packet) { - // write packet to file here - void *ptr = mpp_packet_get_pos(packet); - size_t len = mpp_packet_get_length(packet); - - pkt_eos = mpp_packet_get_eos(packet); - - if (fp_output) - fwrite(ptr, 1, len, fp_output); - mpp_packet_deinit(&packet); - - mpp_log_f("encoded frame %d size %d\n", frame_count, len); - stream_size += len; - - if (pkt_eos) { - mpp_log("found last packet\n"); - mpp_assert(frm_eos); - } - } - frame_count++; - - ret = mpi->enqueue(ctx, MPP_PORT_OUTPUT, task); - if (ret) { - mpp_err("mpp task output enqueue failed\n"); - goto MPP_TEST_OUT; - } - break; - } - } while (1); - - if (frm_eos && pkt_eos) - break; - } - - ret = mpi->reset(ctx); - if (MPP_OK != ret) { - mpp_err("mpi->reset failed\n"); - goto MPP_TEST_OUT; - } - -MPP_TEST_OUT: - - if (ctx) { - mpp_destroy(ctx); - ctx = NULL; - } - - if (frame) { - mpp_frame_deinit(&frame); - frame = NULL; - } - - for (i = 0; i < MPI_ENC_IO_COUNT; i++) { - if (frm_buf[i]) { - mpp_buffer_put(frm_buf[i]); - frm_buf[i] = NULL; - } - - if (pkt_buf[i]) { - mpp_buffer_put(pkt_buf[i]); - pkt_buf[i] = NULL; - } - } - - if (frm_grp) { - mpp_buffer_group_put(frm_grp); - frm_grp = NULL; - } - - if (pkt_grp) { - mpp_buffer_group_put(pkt_grp); - pkt_grp = NULL; - } - - if (fp_output) { - fclose(fp_output); - fp_output = NULL; - } - - if (fp_input) { - fclose(fp_input); - fp_input = NULL; - } - - if (MPP_OK == ret) - mpp_log("mpi_enc_test success total frame %d bps %lld\n", - frame_count, (RK_U64)((stream_size * 8 * mpp_cfg.fps_out) / frame_count)); - else - mpp_err("mpi_enc_test failed ret %d\n", ret); - - return ret; -} - - -static void mpi_enc_test_help() -{ - mpp_log("usage: mpi_enc_test [options]\n"); - show_options(mpi_enc_cmd); - mpp_show_support_format(); -} - -static RK_S32 mpi_enc_test_parse_options(int argc, char **argv, MpiEncTestCmd* cmd) -{ - const char *opt; - const char *next; - RK_S32 optindex = 1; - RK_S32 handleoptions = 1; - RK_S32 err = MPP_NOK; - - if ((argc < 2) || (cmd == NULL)) { - err = 1; - return err; - } - - /* parse options */ - while (optindex < argc) { - opt = (const char*)argv[optindex++]; - next = (const char*)argv[optindex]; - - if (handleoptions && opt[0] == '-' && opt[1] != '\0') { - if (opt[1] == '-') { - if (opt[2] != '\0') { - opt++; - } else { - handleoptions = 0; - continue; - } - } - - opt++; - - switch (*opt) { - case 'i': - if (next) { - strncpy(cmd->file_input, next, MAX_FILE_NAME_LENGTH); - cmd->file_input[strlen(next)] = '\0'; - cmd->have_input = 1; - } else { - mpp_err("input file is invalid\n"); - goto PARSE_OPINIONS_OUT; - } - break; - case 'o': - if (next) { - strncpy(cmd->file_output, next, MAX_FILE_NAME_LENGTH); - cmd->file_output[strlen(next)] = '\0'; - cmd->have_output = 1; - } else { - mpp_log("output file is invalid\n"); - goto PARSE_OPINIONS_OUT; - } - break; - case 'd': - if (next) { - cmd->debug = atoi(next);; - } else { - mpp_err("invalid debug flag\n"); - goto PARSE_OPINIONS_OUT; - } - break; - case 'w': - if (next) { - cmd->width = atoi(next); - } else { - mpp_err("invalid input width\n"); - goto PARSE_OPINIONS_OUT; - } - break; - case 'h': - if ((*(opt + 1) != '\0') && !strncmp(opt, "help", 4)) { - mpi_enc_test_help(); - err = 1; - goto PARSE_OPINIONS_OUT; - } else if (next) { - cmd->height = atoi(next); - } else { - mpp_log("input height is invalid\n"); - goto PARSE_OPINIONS_OUT; - } - break; - case 'f': - if (next) { - cmd->format = (MppFrameFormat)atoi(next); - err = ((cmd->format >= MPP_FMT_YUV_BUTT && cmd->format < MPP_FRAME_FMT_RGB) || - cmd->format >= MPP_FMT_RGB_BUTT); - } - - if (!next || err) { - mpp_err("invalid input format %d\n", cmd->format); - goto PARSE_OPINIONS_OUT; - } - break; - case 't': - if (next) { - cmd->type = (MppCodingType)atoi(next); - err = mpp_check_support_format(MPP_CTX_ENC, cmd->type); - } - - if (!next || err) { - mpp_err("invalid input coding type\n"); - goto PARSE_OPINIONS_OUT; - } - break; - default: - goto PARSE_OPINIONS_OUT; - break; - } - - optindex++; - } - } - - err = 0; - -PARSE_OPINIONS_OUT: - return err; -} - -static void mpi_enc_test_show_options(MpiEncTestCmd* cmd) -{ - mpp_log("cmd parse result:\n"); - mpp_log("input file name: %s\n", cmd->file_input); - mpp_log("output file name: %s\n", cmd->file_output); - mpp_log("width : %d\n", cmd->width); - mpp_log("height : %d\n", cmd->height); - mpp_log("type : %d\n", cmd->type); - mpp_log("debug flag : %x\n", cmd->debug); -} - -int main(int argc, char **argv) -{ - RK_S32 ret = 0; - MpiEncTestCmd cmd_ctx; - MpiEncTestCmd* cmd = &cmd_ctx; - - memset((void*)cmd, 0, sizeof(*cmd)); - - // parse the cmd option - ret = mpi_enc_test_parse_options(argc, argv, cmd); - if (ret) { - if (ret < 0) { - mpp_err("mpi_enc_test_parse_options: input parameter invalid\n"); - } - - mpi_enc_test_help(); - return ret; - } - - mpi_enc_test_show_options(cmd); - - mpp_env_set_u32("mpi_debug", cmd->debug); - - mpi_enc_test(cmd); - - mpp_env_set_u32("mpi_debug", 0x0); - return 0; -} - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined(_WIN32) +#include "vld.h" +#endif + +#define MODULE_TAG "mpi_enc_test" + +#include +#include "rk_mpi.h" + +#include "mpp_log.h" +#include "mpp_env.h" +#include "mpp_time.h" +#include "mpp_common.h" + +#include "utils.h" + +#include "vpu_api.h" + +#define MPI_ENC_IO_COUNT (4) +#define MAX_FILE_NAME_LENGTH 256 + +typedef struct { + char file_input[MAX_FILE_NAME_LENGTH]; + char file_output[MAX_FILE_NAME_LENGTH]; + MppCodingType type; + RK_U32 width; + RK_U32 height; + MppFrameFormat format; + RK_U32 debug; + + RK_U32 have_input; + RK_U32 have_output; +} MpiEncTestCmd; + +static OptionInfo mpi_enc_cmd[] = { + {"i", "input_file", "input bitstream file"}, + {"o", "output_file", "output bitstream file, "}, + {"w", "width", "the width of input bitstream"}, + {"h", "height", "the height of input bitstream"}, + {"f", "format", "the picture format of input bitstream"}, + {"t", "type", "input stream coding type"}, + {"d", "debug", "debug flag"}, +}; + +int mpi_enc_test(MpiEncTestCmd *cmd) +{ + MPP_RET ret = MPP_OK; + RK_U32 frm_eos = 0; + RK_U32 pkt_eos = 0; + FILE *fp_input = NULL; + FILE *fp_output = NULL; + + // base flow context + MppCtx ctx = NULL; + MppApi *mpi = NULL; + MppEncConfig mpp_cfg; + + // input / output + RK_S32 i; + MppBufferGroup frm_grp = NULL; + MppBufferGroup pkt_grp = NULL; + MppFrame frame = NULL; + MppPacket packet = NULL; + MppBuffer frm_buf[MPI_ENC_IO_COUNT] = { NULL }; + MppBuffer pkt_buf[MPI_ENC_IO_COUNT] = { NULL }; + + // paramter for resource malloc + RK_U32 width = cmd->width; + RK_U32 height = cmd->height; + RK_U32 hor_stride = MPP_ALIGN(width, 16); + RK_U32 ver_stride = MPP_ALIGN(height, 16); + MppFrameFormat fmt = cmd->format; + MppCodingType type = cmd->type; + + // resources + size_t frame_size = hor_stride * ver_stride * 3 / 2; + size_t packet_size = width * height; /* NOTE: packet buffer may overflow */ + size_t read_size = 0; + RK_U32 frame_count = 0; + RK_U64 stream_size = 0; + + mpp_log("mpi_enc_test start\n"); + + if (cmd->have_input) { + fp_input = fopen(cmd->file_input, "rb"); + if (NULL == fp_input) { + mpp_err("failed to open input file %s\n", cmd->file_input); + ret = MPP_ERR_OPEN_FILE; + goto MPP_TEST_OUT; + } + } + + if (cmd->have_output) { + fp_output = fopen(cmd->file_output, "w+b"); + if (NULL == fp_output) { + mpp_err("failed to open output file %s\n", cmd->file_output); + ret = MPP_ERR_OPEN_FILE; + goto MPP_TEST_OUT; + } + } + + ret = mpp_buffer_group_get_internal(&frm_grp, MPP_BUFFER_TYPE_ION); + if (ret) { + mpp_err("failed to get buffer group for input frame ret %d\n", ret); + goto MPP_TEST_OUT; + } + + ret = mpp_buffer_group_get_internal(&pkt_grp, MPP_BUFFER_TYPE_ION); + if (ret) { + mpp_err("failed to get buffer group for output packet ret %d\n", ret); + goto MPP_TEST_OUT; + } + + for (i = 0; i < MPI_ENC_IO_COUNT; i++) { + ret = mpp_buffer_get(frm_grp, &frm_buf[i], frame_size); + if (ret) { + mpp_err("failed to get buffer for input frame ret %d\n", ret); + goto MPP_TEST_OUT; + } + + ret = mpp_buffer_get(pkt_grp, &pkt_buf[i], packet_size); + if (ret) { + mpp_err("failed to get buffer for input frame ret %d\n", ret); + goto MPP_TEST_OUT; + } + } + + mpp_log("mpi_enc_test encoder test start w %d h %d type %d\n", width, height, type); + + // encoder demo + ret = mpp_create(&ctx, &mpi); + + if (MPP_OK != ret) { + mpp_err("mpp_create failed\n"); + goto MPP_TEST_OUT; + } + + ret = mpp_init(ctx, MPP_CTX_ENC, type); + if (MPP_OK != ret) { + mpp_err("mpp_init failed\n"); + goto MPP_TEST_OUT; + } + + memset(&mpp_cfg, 0, sizeof(mpp_cfg)); + mpp_cfg.size = sizeof(mpp_cfg); + mpp_cfg.width = width; + mpp_cfg.height = height; + mpp_cfg.format = fmt; + mpp_cfg.rc_mode = 0; + mpp_cfg.skip_cnt = 0; + mpp_cfg.fps_in = 30; + mpp_cfg.fps_out = 30; + mpp_cfg.bps = width * height * 2 * mpp_cfg.fps_in; + mpp_cfg.qp = 24; + mpp_cfg.gop = 60; + + mpp_cfg.profile = 100; + mpp_cfg.level = 41; + mpp_cfg.cabac_en = 1; + + ret = mpi->control(ctx, MPP_ENC_SET_CFG, &mpp_cfg); + if (MPP_OK != ret) { + mpp_err("mpi control enc set cfg failed\n"); + goto MPP_TEST_OUT; + } + + ret = mpi->control(ctx, MPP_ENC_GET_EXTRA_INFO, &packet); + if (MPP_OK != ret) { + mpp_err("mpi control enc get extra info failed\n"); + goto MPP_TEST_OUT; + } + + /* get and write sps/pps for H.264 */ + if (packet) { + void *ptr = mpp_packet_get_pos(packet); + size_t len = mpp_packet_get_length(packet); + + if (fp_output) + fwrite(ptr, 1, len, fp_output); + + packet = NULL; + } + + ret = mpp_frame_init(&frame); + if (MPP_OK != ret) { + mpp_err("mpp_frame_init failed\n"); + goto MPP_TEST_OUT; + } + + mpp_frame_set_width(frame, width); + mpp_frame_set_height(frame, height); + mpp_frame_set_hor_stride(frame, hor_stride); + mpp_frame_set_ver_stride(frame, ver_stride); + + i = 0; + while (!pkt_eos) { + MppTask task = NULL; + RK_S32 index = i++; + MppBuffer frm_buf_in = frm_buf[index]; + MppBuffer pkt_buf_out = pkt_buf[index]; + void *buf = mpp_buffer_get_ptr(frm_buf_in); + + if (i == MPI_ENC_IO_COUNT) + i = 0; + + read_size = fread(buf, 1, frame_size, fp_input); + if (read_size != frame_size || feof(fp_input)) { + mpp_log("found last frame\n"); + frm_eos = 1; + } + + mpp_frame_set_buffer(frame, frm_buf_in); + mpp_frame_set_eos(frame, frm_eos); + + mpp_packet_init_with_buffer(&packet, pkt_buf_out); + + do { + ret = mpi->dequeue(ctx, MPP_PORT_INPUT, &task); + if (ret) { + mpp_err("mpp task input dequeue failed\n"); + goto MPP_TEST_OUT; + } + if (task == NULL) { + mpp_log("mpi dequeue from MPP_PORT_INPUT fail, task equal with NULL!"); + msleep(3); + } else { + MppFrame frame_out = NULL; + + mpp_task_meta_get_frame (task, MPP_META_KEY_INPUT_FRM, &frame_out); + if (frame_out) + mpp_assert(frame_out == frame); + + break; + } + } while (1); + + + mpp_task_meta_set_frame (task, MPP_META_KEY_INPUT_FRM, frame); + mpp_task_meta_set_packet(task, MPP_META_KEY_OUTPUT_PKT, packet); + + ret = mpi->enqueue(ctx, MPP_PORT_INPUT, task); + if (ret) { + mpp_err("mpp task input enqueue failed\n"); + goto MPP_TEST_OUT; + } + + msleep(20); + + do { + ret = mpi->dequeue(ctx, MPP_PORT_OUTPUT, &task); + if (ret) { + mpp_err("mpp task output dequeue failed\n"); + goto MPP_TEST_OUT; + } + + if (task) { + MppFrame packet_out = NULL; + + mpp_task_meta_get_packet(task, MPP_META_KEY_OUTPUT_PKT, &packet_out); + + mpp_assert(packet_out == packet); + if (packet) { + // write packet to file here + void *ptr = mpp_packet_get_pos(packet); + size_t len = mpp_packet_get_length(packet); + + pkt_eos = mpp_packet_get_eos(packet); + + if (fp_output) + fwrite(ptr, 1, len, fp_output); + mpp_packet_deinit(&packet); + + mpp_log_f("encoded frame %d size %d\n", frame_count, len); + stream_size += len; + + if (pkt_eos) { + mpp_log("found last packet\n"); + mpp_assert(frm_eos); + } + } + frame_count++; + + ret = mpi->enqueue(ctx, MPP_PORT_OUTPUT, task); + if (ret) { + mpp_err("mpp task output enqueue failed\n"); + goto MPP_TEST_OUT; + } + break; + } + } while (1); + + if (frm_eos && pkt_eos) + break; + } + + ret = mpi->reset(ctx); + if (MPP_OK != ret) { + mpp_err("mpi->reset failed\n"); + goto MPP_TEST_OUT; + } + +MPP_TEST_OUT: + + if (ctx) { + mpp_destroy(ctx); + ctx = NULL; + } + + if (frame) { + mpp_frame_deinit(&frame); + frame = NULL; + } + + for (i = 0; i < MPI_ENC_IO_COUNT; i++) { + if (frm_buf[i]) { + mpp_buffer_put(frm_buf[i]); + frm_buf[i] = NULL; + } + + if (pkt_buf[i]) { + mpp_buffer_put(pkt_buf[i]); + pkt_buf[i] = NULL; + } + } + + if (frm_grp) { + mpp_buffer_group_put(frm_grp); + frm_grp = NULL; + } + + if (pkt_grp) { + mpp_buffer_group_put(pkt_grp); + pkt_grp = NULL; + } + + if (fp_output) { + fclose(fp_output); + fp_output = NULL; + } + + if (fp_input) { + fclose(fp_input); + fp_input = NULL; + } + + if (MPP_OK == ret) + mpp_log("mpi_enc_test success total frame %d bps %lld\n", + frame_count, (RK_U64)((stream_size * 8 * mpp_cfg.fps_out) / frame_count)); + else + mpp_err("mpi_enc_test failed ret %d\n", ret); + + return ret; +} + + +static void mpi_enc_test_help() +{ + mpp_log("usage: mpi_enc_test [options]\n"); + show_options(mpi_enc_cmd); + mpp_show_support_format(); +} + +static RK_S32 mpi_enc_test_parse_options(int argc, char **argv, MpiEncTestCmd* cmd) +{ + const char *opt; + const char *next; + RK_S32 optindex = 1; + RK_S32 handleoptions = 1; + RK_S32 err = MPP_NOK; + + if ((argc < 2) || (cmd == NULL)) { + err = 1; + return err; + } + + /* parse options */ + while (optindex < argc) { + opt = (const char*)argv[optindex++]; + next = (const char*)argv[optindex]; + + if (handleoptions && opt[0] == '-' && opt[1] != '\0') { + if (opt[1] == '-') { + if (opt[2] != '\0') { + opt++; + } else { + handleoptions = 0; + continue; + } + } + + opt++; + + switch (*opt) { + case 'i': + if (next) { + strncpy(cmd->file_input, next, MAX_FILE_NAME_LENGTH); + cmd->file_input[strlen(next)] = '\0'; + cmd->have_input = 1; + } else { + mpp_err("input file is invalid\n"); + goto PARSE_OPINIONS_OUT; + } + break; + case 'o': + if (next) { + strncpy(cmd->file_output, next, MAX_FILE_NAME_LENGTH); + cmd->file_output[strlen(next)] = '\0'; + cmd->have_output = 1; + } else { + mpp_log("output file is invalid\n"); + goto PARSE_OPINIONS_OUT; + } + break; + case 'd': + if (next) { + cmd->debug = atoi(next);; + } else { + mpp_err("invalid debug flag\n"); + goto PARSE_OPINIONS_OUT; + } + break; + case 'w': + if (next) { + cmd->width = atoi(next); + } else { + mpp_err("invalid input width\n"); + goto PARSE_OPINIONS_OUT; + } + break; + case 'h': + if ((*(opt + 1) != '\0') && !strncmp(opt, "help", 4)) { + mpi_enc_test_help(); + err = 1; + goto PARSE_OPINIONS_OUT; + } else if (next) { + cmd->height = atoi(next); + } else { + mpp_log("input height is invalid\n"); + goto PARSE_OPINIONS_OUT; + } + break; + case 'f': + if (next) { + cmd->format = (MppFrameFormat)atoi(next); + err = ((cmd->format >= MPP_FMT_YUV_BUTT && cmd->format < MPP_FRAME_FMT_RGB) || + cmd->format >= MPP_FMT_RGB_BUTT); + } + + if (!next || err) { + mpp_err("invalid input format %d\n", cmd->format); + goto PARSE_OPINIONS_OUT; + } + break; + case 't': + if (next) { + cmd->type = (MppCodingType)atoi(next); + err = mpp_check_support_format(MPP_CTX_ENC, cmd->type); + } + + if (!next || err) { + mpp_err("invalid input coding type\n"); + goto PARSE_OPINIONS_OUT; + } + break; + default: + goto PARSE_OPINIONS_OUT; + break; + } + + optindex++; + } + } + + err = 0; + +PARSE_OPINIONS_OUT: + return err; +} + +static void mpi_enc_test_show_options(MpiEncTestCmd* cmd) +{ + mpp_log("cmd parse result:\n"); + mpp_log("input file name: %s\n", cmd->file_input); + mpp_log("output file name: %s\n", cmd->file_output); + mpp_log("width : %d\n", cmd->width); + mpp_log("height : %d\n", cmd->height); + mpp_log("type : %d\n", cmd->type); + mpp_log("debug flag : %x\n", cmd->debug); +} + +int main(int argc, char **argv) +{ + RK_S32 ret = 0; + MpiEncTestCmd cmd_ctx; + MpiEncTestCmd* cmd = &cmd_ctx; + + memset((void*)cmd, 0, sizeof(*cmd)); + + // parse the cmd option + ret = mpi_enc_test_parse_options(argc, argv, cmd); + if (ret) { + if (ret < 0) { + mpp_err("mpi_enc_test_parse_options: input parameter invalid\n"); + } + + mpi_enc_test_help(); + return ret; + } + + mpi_enc_test_show_options(cmd); + + mpp_env_set_u32("mpi_debug", cmd->debug); + + mpi_enc_test(cmd); + + mpp_env_set_u32("mpi_debug", 0x0); + return 0; +} + diff --git a/test/mpi_test.c b/test/mpi_test.c index 193365b9..7b950063 100644 --- a/test/mpi_test.c +++ b/test/mpi_test.c @@ -1,294 +1,294 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#if defined(_WIN32) -#include "vld.h" -#endif - -#define MODULE_TAG "mpi_test" - -#include -#include "rk_mpi.h" -#include "mpp_log.h" -#include "mpp_env.h" - - -#define MPI_DEC_LOOP_COUNT 4 -#define MPI_ENC_LOOP_COUNT 4 - -#define MPI_STREAM_SIZE (SZ_512K) - -int mpi_test() -{ - MPP_RET ret; - MppCtx ctx = NULL; - MppApi *mpi = NULL; - MppEncConfig cfg; - - MppPacket dec_in = NULL; - MppFrame dec_out = NULL; - - MppFrame enc_in = NULL; - MppPacket enc_out = NULL; - - MpiCmd cmd = MPP_CMD_BASE; - MppParam param = NULL; - RK_U32 output_block = 1; - - RK_S32 i; - char *buf = NULL; - RK_S32 size = MPI_STREAM_SIZE; - - mpp_log("mpi_test start\n"); - - buf = (char *)malloc(size); - if (NULL == buf) { - mpp_err("mpi_test malloc failed\n"); - goto MPP_TEST_FAILED; - } - - mpp_log("mpi_test decoder test start\n"); - - // decoder demo - ret = mpp_create(&ctx, &mpi); - - if (MPP_OK != ret) { - mpp_err("mpp_create failed\n"); - goto MPP_TEST_FAILED; - } - ret = mpp_init(ctx, MPP_CTX_DEC, MPP_VIDEO_CodingUnused); - if (MPP_OK != ret) { - mpp_err("mpp_init failed\n"); - goto MPP_TEST_FAILED; - } - - // NOTE: decoder do not need control function - cmd = MPP_SET_OUTPUT_BLOCK; - param = &output_block; - ret = mpi->control(ctx, cmd, param); - if (MPP_OK != ret) { - mpp_err("mpi->control failed\n"); - goto MPP_TEST_FAILED; - } - - // interface with both input and output - for (i = 0; i < MPI_DEC_LOOP_COUNT; i++) { - mpp_packet_init(&dec_in, buf, size); - - // IMPORTANT: eos flag will flush all decoded frame - if (i == MPI_DEC_LOOP_COUNT - 1) - mpp_packet_set_eos(dec_in); - - // TODO: read stream data to buf - - ret = mpi->decode(ctx, dec_in, &dec_out); - if (MPP_OK != ret) { - goto MPP_TEST_FAILED; - } - - if (dec_out) { - // interface may output multiple frame at one time - do { - MppFrame next = mpp_frame_get_next(dec_out); - - // TODO: diaplay function called here - - mpp_frame_deinit(&dec_out); - dec_out = next; - } while (dec_out); - } - - mpp_packet_deinit(&dec_in); - } - - // interface with input and output separated - for (i = 0; i < MPI_DEC_LOOP_COUNT; i++) { - mpp_packet_init(&dec_in, buf, size); - mpp_packet_set_pts(dec_in, i); - - // IMPORTANT: eos flag will flush all decoded frame - if (i == MPI_DEC_LOOP_COUNT - 1) - mpp_packet_set_eos(dec_in); - - // TODO: read stream data to buf - - ret = mpi->decode_put_packet(ctx, dec_in); - if (MPP_OK != ret) { - goto MPP_TEST_FAILED; - } - - mpp_packet_deinit(&dec_in); - } - - for (i = 0; i < MPI_DEC_LOOP_COUNT; ) { - ret = mpi->decode_get_frame(ctx, &dec_out); - if (MPP_OK != ret) { - goto MPP_TEST_FAILED; - } - - if (dec_out) { - // interface may output multiple frame at one time - do { - MppFrame next = mpp_frame_get_next(dec_out); - - // TODO: diaplay function called here - /* - * NOTE: check info_change is needed - * step 1 : check info change flag - * step 2 : if info change then request new buffer - * step 3 : when new buffer is ready set control to mpp - */ - if (mpp_frame_get_info_change(dec_out)) { - mpp_log("decode_get_frame get info changed found\n"); - - // if work in external buffer mode re-commit buffer here - mpi->control(ctx, MPP_DEC_SET_INFO_CHANGE_READY, NULL); - } else - i++; - - mpp_frame_deinit(&dec_out); - dec_out = next; - } while (dec_out); - } - } - - - ret = mpi->reset(ctx); - if (MPP_OK != ret) { - mpp_err("mpi->reset failed\n"); - goto MPP_TEST_FAILED; - } - - mpp_destroy(ctx); - - - mpp_log("mpi_test encoder test start\n"); - - // encoder demo - ret = mpp_create(&ctx, &mpi); - if (MPP_OK != ret) { - mpp_err("mpp_create failed\n"); - goto MPP_TEST_FAILED; - } - - ret = mpp_init(ctx, MPP_CTX_ENC, MPP_VIDEO_CodingUnused); - if (MPP_OK != ret) { - mpp_err("mpp_init failed\n"); - goto MPP_TEST_FAILED; - } - - memset(&cfg, 0, sizeof(cfg)); - - cmd = MPP_ENC_SET_CFG; - param = &cfg; - - ret = mpi->control(ctx, cmd, param); - if (MPP_OK != ret) { - mpp_err("mpi->control failed\n"); - goto MPP_TEST_FAILED; - } - - // interface with both input and output - for (i = 0; i < MPI_ENC_LOOP_COUNT; i++) { - mpp_frame_init(&enc_in); - - mpi->encode(ctx, enc_in, &enc_out); - if (MPP_OK != ret) { - goto MPP_TEST_FAILED; - } - - if (enc_out) - mpp_packet_deinit(&enc_out); - - mpp_frame_deinit(&enc_in); - } - - // interface with input and output separated - for (i = 0; i < MPI_ENC_LOOP_COUNT; i++) { - mpp_frame_init(&enc_in); - - // TODO: read stream data to buf - - mpi->encode_put_frame(ctx, enc_in); - if (MPP_OK != ret) { - goto MPP_TEST_FAILED; - } - - mpp_frame_deinit(&enc_in); - } - - for (i = 0; i < MPI_ENC_LOOP_COUNT; i++) { - mpi->encode_get_packet(ctx, &enc_out); - if (MPP_OK != ret) { - goto MPP_TEST_FAILED; - } - - if (enc_out) { - mpp_packet_deinit(&enc_out); - } - } - - - ret = mpi->reset(ctx); - if (MPP_OK != ret) { - mpp_err("mpi->reset failed\n"); - goto MPP_TEST_FAILED; - } - - if (dec_in) - mpp_packet_deinit(&dec_in); - - if (enc_in) - mpp_frame_deinit(&enc_in); - - mpp_destroy(ctx); - free(buf); - - mpp_log("mpi_test success\n"); - - return 0; - -MPP_TEST_FAILED: - if (dec_in) - mpp_packet_deinit(&dec_in); - - if (enc_in) - mpp_frame_deinit(&enc_in); - - if (ctx) - mpp_destroy(ctx); - if (buf) - free(buf); - - mpp_log("mpi_test failed\n"); - - return -1; -} - - -int main(int argc, char **argv) -{ - (void)argc; - (void)argv; - - mpp_env_set_u32("mpi_debug", 0x1); - - mpi_test(); - - mpp_env_set_u32("mpi_debug", 0x0); - return 0; -} - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined(_WIN32) +#include "vld.h" +#endif + +#define MODULE_TAG "mpi_test" + +#include +#include "rk_mpi.h" +#include "mpp_log.h" +#include "mpp_env.h" + + +#define MPI_DEC_LOOP_COUNT 4 +#define MPI_ENC_LOOP_COUNT 4 + +#define MPI_STREAM_SIZE (SZ_512K) + +int mpi_test() +{ + MPP_RET ret; + MppCtx ctx = NULL; + MppApi *mpi = NULL; + MppEncConfig cfg; + + MppPacket dec_in = NULL; + MppFrame dec_out = NULL; + + MppFrame enc_in = NULL; + MppPacket enc_out = NULL; + + MpiCmd cmd = MPP_CMD_BASE; + MppParam param = NULL; + RK_U32 output_block = 1; + + RK_S32 i; + char *buf = NULL; + RK_S32 size = MPI_STREAM_SIZE; + + mpp_log("mpi_test start\n"); + + buf = (char *)malloc(size); + if (NULL == buf) { + mpp_err("mpi_test malloc failed\n"); + goto MPP_TEST_FAILED; + } + + mpp_log("mpi_test decoder test start\n"); + + // decoder demo + ret = mpp_create(&ctx, &mpi); + + if (MPP_OK != ret) { + mpp_err("mpp_create failed\n"); + goto MPP_TEST_FAILED; + } + ret = mpp_init(ctx, MPP_CTX_DEC, MPP_VIDEO_CodingUnused); + if (MPP_OK != ret) { + mpp_err("mpp_init failed\n"); + goto MPP_TEST_FAILED; + } + + // NOTE: decoder do not need control function + cmd = MPP_SET_OUTPUT_BLOCK; + param = &output_block; + ret = mpi->control(ctx, cmd, param); + if (MPP_OK != ret) { + mpp_err("mpi->control failed\n"); + goto MPP_TEST_FAILED; + } + + // interface with both input and output + for (i = 0; i < MPI_DEC_LOOP_COUNT; i++) { + mpp_packet_init(&dec_in, buf, size); + + // IMPORTANT: eos flag will flush all decoded frame + if (i == MPI_DEC_LOOP_COUNT - 1) + mpp_packet_set_eos(dec_in); + + // TODO: read stream data to buf + + ret = mpi->decode(ctx, dec_in, &dec_out); + if (MPP_OK != ret) { + goto MPP_TEST_FAILED; + } + + if (dec_out) { + // interface may output multiple frame at one time + do { + MppFrame next = mpp_frame_get_next(dec_out); + + // TODO: diaplay function called here + + mpp_frame_deinit(&dec_out); + dec_out = next; + } while (dec_out); + } + + mpp_packet_deinit(&dec_in); + } + + // interface with input and output separated + for (i = 0; i < MPI_DEC_LOOP_COUNT; i++) { + mpp_packet_init(&dec_in, buf, size); + mpp_packet_set_pts(dec_in, i); + + // IMPORTANT: eos flag will flush all decoded frame + if (i == MPI_DEC_LOOP_COUNT - 1) + mpp_packet_set_eos(dec_in); + + // TODO: read stream data to buf + + ret = mpi->decode_put_packet(ctx, dec_in); + if (MPP_OK != ret) { + goto MPP_TEST_FAILED; + } + + mpp_packet_deinit(&dec_in); + } + + for (i = 0; i < MPI_DEC_LOOP_COUNT; ) { + ret = mpi->decode_get_frame(ctx, &dec_out); + if (MPP_OK != ret) { + goto MPP_TEST_FAILED; + } + + if (dec_out) { + // interface may output multiple frame at one time + do { + MppFrame next = mpp_frame_get_next(dec_out); + + // TODO: diaplay function called here + /* + * NOTE: check info_change is needed + * step 1 : check info change flag + * step 2 : if info change then request new buffer + * step 3 : when new buffer is ready set control to mpp + */ + if (mpp_frame_get_info_change(dec_out)) { + mpp_log("decode_get_frame get info changed found\n"); + + // if work in external buffer mode re-commit buffer here + mpi->control(ctx, MPP_DEC_SET_INFO_CHANGE_READY, NULL); + } else + i++; + + mpp_frame_deinit(&dec_out); + dec_out = next; + } while (dec_out); + } + } + + + ret = mpi->reset(ctx); + if (MPP_OK != ret) { + mpp_err("mpi->reset failed\n"); + goto MPP_TEST_FAILED; + } + + mpp_destroy(ctx); + + + mpp_log("mpi_test encoder test start\n"); + + // encoder demo + ret = mpp_create(&ctx, &mpi); + if (MPP_OK != ret) { + mpp_err("mpp_create failed\n"); + goto MPP_TEST_FAILED; + } + + ret = mpp_init(ctx, MPP_CTX_ENC, MPP_VIDEO_CodingUnused); + if (MPP_OK != ret) { + mpp_err("mpp_init failed\n"); + goto MPP_TEST_FAILED; + } + + memset(&cfg, 0, sizeof(cfg)); + + cmd = MPP_ENC_SET_CFG; + param = &cfg; + + ret = mpi->control(ctx, cmd, param); + if (MPP_OK != ret) { + mpp_err("mpi->control failed\n"); + goto MPP_TEST_FAILED; + } + + // interface with both input and output + for (i = 0; i < MPI_ENC_LOOP_COUNT; i++) { + mpp_frame_init(&enc_in); + + mpi->encode(ctx, enc_in, &enc_out); + if (MPP_OK != ret) { + goto MPP_TEST_FAILED; + } + + if (enc_out) + mpp_packet_deinit(&enc_out); + + mpp_frame_deinit(&enc_in); + } + + // interface with input and output separated + for (i = 0; i < MPI_ENC_LOOP_COUNT; i++) { + mpp_frame_init(&enc_in); + + // TODO: read stream data to buf + + mpi->encode_put_frame(ctx, enc_in); + if (MPP_OK != ret) { + goto MPP_TEST_FAILED; + } + + mpp_frame_deinit(&enc_in); + } + + for (i = 0; i < MPI_ENC_LOOP_COUNT; i++) { + mpi->encode_get_packet(ctx, &enc_out); + if (MPP_OK != ret) { + goto MPP_TEST_FAILED; + } + + if (enc_out) { + mpp_packet_deinit(&enc_out); + } + } + + + ret = mpi->reset(ctx); + if (MPP_OK != ret) { + mpp_err("mpi->reset failed\n"); + goto MPP_TEST_FAILED; + } + + if (dec_in) + mpp_packet_deinit(&dec_in); + + if (enc_in) + mpp_frame_deinit(&enc_in); + + mpp_destroy(ctx); + free(buf); + + mpp_log("mpi_test success\n"); + + return 0; + +MPP_TEST_FAILED: + if (dec_in) + mpp_packet_deinit(&dec_in); + + if (enc_in) + mpp_frame_deinit(&enc_in); + + if (ctx) + mpp_destroy(ctx); + if (buf) + free(buf); + + mpp_log("mpi_test failed\n"); + + return -1; +} + + +int main(int argc, char **argv) +{ + (void)argc; + (void)argv; + + mpp_env_set_u32("mpi_debug", 0x1); + + mpi_test(); + + mpp_env_set_u32("mpi_debug", 0x0); + return 0; +} + diff --git a/test/mpp_buffer_test.c b/test/mpp_buffer_test.c index 6ef111ae..2527b674 100644 --- a/test/mpp_buffer_test.c +++ b/test/mpp_buffer_test.c @@ -1,291 +1,291 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define MODULE_TAG "mpp_buffer_test" - -#include - -#if defined(_WIN32) -#include "vld.h" -#endif -#include "mpp_log.h" -#include "mpp_env.h" -#include "mpp_buffer.h" -#include "mpp_allocator.h" - -#define MPP_BUFFER_TEST_DEBUG_FLAG (0xf) -#define MPP_BUFFER_TEST_SIZE (SZ_1K*4) -#define MPP_BUFFER_TEST_COMMIT_COUNT 10 -#define MPP_BUFFER_TEST_NORMAL_COUNT 10 - -int main() -{ - MPP_RET ret = MPP_OK; - MppAllocator allocator = NULL; - MppAllocatorApi *api = NULL; - MppBufferInfo commit; - MppBufferGroup group = NULL; - MppBuffer commit_buffer[MPP_BUFFER_TEST_COMMIT_COUNT]; - void *commit_ptr[MPP_BUFFER_TEST_COMMIT_COUNT]; - MppBuffer normal_buffer[MPP_BUFFER_TEST_NORMAL_COUNT]; - MppBuffer legacy_buffer = NULL; - size_t size = MPP_BUFFER_TEST_SIZE; - RK_S32 count = MPP_BUFFER_TEST_COMMIT_COUNT; - RK_S32 i; - RK_U32 debug = 0; - - mpp_env_set_u32("mpp_buffer_debug", MPP_BUFFER_TEST_DEBUG_FLAG); - mpp_env_get_u32("mpp_buffer_debug", &debug, 0); - - mpp_log("mpp_buffer_test start with debug 0x%x\n", debug); - - memset(commit_ptr, 0, sizeof(commit_ptr)); - memset(commit_buffer, 0, sizeof(commit_buffer)); - memset(normal_buffer, 0, sizeof(normal_buffer)); - - ret = mpp_buffer_group_get_external(&group, MPP_BUFFER_TYPE_NORMAL); - if (MPP_OK != ret) { - mpp_err("mpp_buffer_test mpp_buffer_group_get failed\n"); - goto MPP_BUFFER_failed; - } - - mpp_log("mpp_buffer_test commit mode with unused status start\n"); - - commit.type = MPP_BUFFER_TYPE_NORMAL; - commit.size = size; - - for (i = 0; i < count; i++) { - commit_ptr[i] = malloc(size); - if (NULL == commit_ptr[i]) { - mpp_err("mpp_buffer_test malloc failed\n"); - goto MPP_BUFFER_failed; - } - - commit.ptr = commit_ptr[i]; - - ret = mpp_buffer_commit(group, &commit); - if (MPP_OK != ret) { - mpp_err("mpp_buffer_test mpp_buffer_commit failed\n"); - goto MPP_BUFFER_failed; - } - } - - for (i = 0; i < count; i++) { - ret = mpp_buffer_get(group, &commit_buffer[i], size); - if (MPP_OK != ret) { - mpp_err("mpp_buffer_test mpp_buffer_get commit mode failed\n"); - goto MPP_BUFFER_failed; - } - } - - for (i = 0; i < count; i++) { - if (commit_buffer[i]) { - ret = mpp_buffer_put(commit_buffer[i]); - if (MPP_OK != ret) { - mpp_err("mpp_buffer_test mpp_buffer_put commit mode failed\n"); - goto MPP_BUFFER_failed; - } - commit_buffer[i] = NULL; - } - } - - for (i = 0; i < count; i++) { - if (commit_ptr[i]) { - free(commit_ptr[i]); - commit_ptr[i] = NULL; - } - } - - mpp_buffer_group_put(group); - - mpp_log("mpp_buffer_test commit mode with unused status success\n"); - - - mpp_log("mpp_buffer_test commit mode with used status start\n"); - - ret = mpp_allocator_get(&allocator, &api, MPP_BUFFER_TYPE_ION); - if (MPP_OK != ret) { - mpp_err("mpp_buffer_test mpp_allocator_get ion failed\n"); - goto MPP_BUFFER_failed; - } - - commit.type = MPP_BUFFER_TYPE_ION; - commit.size = size; - - for (i = 0; i < count; i++) { - ret = api->alloc(allocator, &commit); - if (ret) { - mpp_err("mpp_buffer_test mpp_allocator_alloc failed\n"); - goto MPP_BUFFER_failed; - } - - mpp_log("allocator get ptr %p with fd %d\n", commit.ptr, commit.fd); - - /* - * NOTE: commit buffer info will be directly return within new MppBuffer - * This mode allow input group is NULL - */ - ret = mpp_buffer_import(&commit_buffer[i], &commit); - if (MPP_OK != ret) { - mpp_err("mpp_buffer_test mpp_buffer_commit failed\n"); - goto MPP_BUFFER_failed; - } - - /* - * test imported buffer - */ - { - void *ptr = mpp_buffer_get_ptr(commit_buffer[i]); - if (NULL == ptr) { - mpp_err("mpp_buffer_test mpp_buffer_get_ptr failed\n"); - goto MPP_BUFFER_failed; - } - - mpp_log("get ptr %p from fd %d\n", ptr, mpp_buffer_get_fd(commit_buffer[i])); - - memset(ptr, 0, mpp_buffer_get_size(commit_buffer[i])); - } - } - - for (i = 0; i < count; i++) { - if (commit_buffer[i]) { - ret = mpp_buffer_info_get(commit_buffer[i], &commit); - if (MPP_OK != ret) { - mpp_err("mpp_buffer_test mpp_buffer_info_get failed\n"); - goto MPP_BUFFER_failed; - } - - ret = mpp_buffer_put(commit_buffer[i]); - if (MPP_OK != ret) { - mpp_err("mpp_buffer_test mpp_buffer_put commit mode failed\n"); - goto MPP_BUFFER_failed; - } - - commit_buffer[i] = NULL; - - /* NOTE: buffer info from allocator need to be free directly */ - ret = api->free(allocator, &commit); - if (MPP_OK != ret) { - mpp_err("mpp_buffer_test api->free failed\n"); - goto MPP_BUFFER_failed; - } - } - } - - ret = mpp_allocator_put(&allocator); - if (MPP_OK != ret) { - mpp_err("mpp_buffer_test mpp_allocator_put failed\n"); - goto MPP_BUFFER_failed; - } - - mpp_log("mpp_buffer_test commit mode with used status success\n"); - - - mpp_log("mpp_buffer_test normal mode start\n"); - - ret = mpp_buffer_group_get_internal(&group, MPP_BUFFER_TYPE_ION); - if (MPP_OK != ret) { - mpp_err("mpp_buffer_test mpp_buffer_group_get failed\n"); - goto MPP_BUFFER_failed; - } - - count = MPP_BUFFER_TEST_NORMAL_COUNT; - - mpp_buffer_group_limit_config(group, 0, count); - - for (i = 0; i < count; i++) { - ret = mpp_buffer_get(group, &normal_buffer[i], (i + 1) * SZ_1K); - if (MPP_OK != ret) { - mpp_err("mpp_buffer_test mpp_buffer_get mode normal failed\n"); - goto MPP_BUFFER_failed; - } - } - - for (i = 0; i < count; i++) { - if (normal_buffer[i]) { - ret = mpp_buffer_put(normal_buffer[i]); - if (MPP_OK != ret) { - mpp_err("mpp_buffer_test mpp_buffer_get mode normal failed\n"); - goto MPP_BUFFER_failed; - } - normal_buffer[i] = NULL; - } - } - - mpp_log("mpp_buffer_test normal mode success\n"); - - if (group) { - mpp_buffer_group_put(group); - group = NULL; - } - - mpp_log("mpp_buffer_test success\n"); - - ret = mpp_buffer_get(NULL, &legacy_buffer, MPP_BUFFER_TEST_SIZE); - if (MPP_OK != ret) { - mpp_log("mpp_buffer_test mpp_buffer_get legacy buffer failed\n"); - goto MPP_BUFFER_failed; - } - - ret = mpp_buffer_put(legacy_buffer); - if (MPP_OK != ret) { - mpp_log("mpp_buffer_test mpp_buffer_put legacy buffer failed\n"); - goto MPP_BUFFER_failed; - } - - mpp_env_set_u32("mpp_buffer_debug", 0); - - return ret; - -MPP_BUFFER_failed: - for (i = 0; i < MPP_BUFFER_TEST_COMMIT_COUNT; i++) { - if (commit_buffer[i]) - mpp_buffer_put(commit_buffer[i]); - } - - for (i = 0; i < MPP_BUFFER_TEST_COMMIT_COUNT; i++) { - if (commit_ptr[i]) { - free(commit_ptr[i]); - commit_ptr[i] = NULL; - } - } - for (i = 0; i < MPP_BUFFER_TEST_NORMAL_COUNT; i++) { - if (normal_buffer[i]) - mpp_buffer_put(normal_buffer[i]); - } - - if (group) { - mpp_buffer_group_put(group); - group = NULL; - } - - if (legacy_buffer) { - mpp_buffer_put(legacy_buffer); - legacy_buffer = NULL; - } - - if (allocator) { - mpp_allocator_put(&allocator); - } - mpp_assert(NULL == allocator); - - mpp_log("mpp_buffer_test failed\n"); - - mpp_env_set_u32("mpp_buffer_debug", 0); - - return ret; -} - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define MODULE_TAG "mpp_buffer_test" + +#include + +#if defined(_WIN32) +#include "vld.h" +#endif +#include "mpp_log.h" +#include "mpp_env.h" +#include "mpp_buffer.h" +#include "mpp_allocator.h" + +#define MPP_BUFFER_TEST_DEBUG_FLAG (0xf) +#define MPP_BUFFER_TEST_SIZE (SZ_1K*4) +#define MPP_BUFFER_TEST_COMMIT_COUNT 10 +#define MPP_BUFFER_TEST_NORMAL_COUNT 10 + +int main() +{ + MPP_RET ret = MPP_OK; + MppAllocator allocator = NULL; + MppAllocatorApi *api = NULL; + MppBufferInfo commit; + MppBufferGroup group = NULL; + MppBuffer commit_buffer[MPP_BUFFER_TEST_COMMIT_COUNT]; + void *commit_ptr[MPP_BUFFER_TEST_COMMIT_COUNT]; + MppBuffer normal_buffer[MPP_BUFFER_TEST_NORMAL_COUNT]; + MppBuffer legacy_buffer = NULL; + size_t size = MPP_BUFFER_TEST_SIZE; + RK_S32 count = MPP_BUFFER_TEST_COMMIT_COUNT; + RK_S32 i; + RK_U32 debug = 0; + + mpp_env_set_u32("mpp_buffer_debug", MPP_BUFFER_TEST_DEBUG_FLAG); + mpp_env_get_u32("mpp_buffer_debug", &debug, 0); + + mpp_log("mpp_buffer_test start with debug 0x%x\n", debug); + + memset(commit_ptr, 0, sizeof(commit_ptr)); + memset(commit_buffer, 0, sizeof(commit_buffer)); + memset(normal_buffer, 0, sizeof(normal_buffer)); + + ret = mpp_buffer_group_get_external(&group, MPP_BUFFER_TYPE_NORMAL); + if (MPP_OK != ret) { + mpp_err("mpp_buffer_test mpp_buffer_group_get failed\n"); + goto MPP_BUFFER_failed; + } + + mpp_log("mpp_buffer_test commit mode with unused status start\n"); + + commit.type = MPP_BUFFER_TYPE_NORMAL; + commit.size = size; + + for (i = 0; i < count; i++) { + commit_ptr[i] = malloc(size); + if (NULL == commit_ptr[i]) { + mpp_err("mpp_buffer_test malloc failed\n"); + goto MPP_BUFFER_failed; + } + + commit.ptr = commit_ptr[i]; + + ret = mpp_buffer_commit(group, &commit); + if (MPP_OK != ret) { + mpp_err("mpp_buffer_test mpp_buffer_commit failed\n"); + goto MPP_BUFFER_failed; + } + } + + for (i = 0; i < count; i++) { + ret = mpp_buffer_get(group, &commit_buffer[i], size); + if (MPP_OK != ret) { + mpp_err("mpp_buffer_test mpp_buffer_get commit mode failed\n"); + goto MPP_BUFFER_failed; + } + } + + for (i = 0; i < count; i++) { + if (commit_buffer[i]) { + ret = mpp_buffer_put(commit_buffer[i]); + if (MPP_OK != ret) { + mpp_err("mpp_buffer_test mpp_buffer_put commit mode failed\n"); + goto MPP_BUFFER_failed; + } + commit_buffer[i] = NULL; + } + } + + for (i = 0; i < count; i++) { + if (commit_ptr[i]) { + free(commit_ptr[i]); + commit_ptr[i] = NULL; + } + } + + mpp_buffer_group_put(group); + + mpp_log("mpp_buffer_test commit mode with unused status success\n"); + + + mpp_log("mpp_buffer_test commit mode with used status start\n"); + + ret = mpp_allocator_get(&allocator, &api, MPP_BUFFER_TYPE_ION); + if (MPP_OK != ret) { + mpp_err("mpp_buffer_test mpp_allocator_get ion failed\n"); + goto MPP_BUFFER_failed; + } + + commit.type = MPP_BUFFER_TYPE_ION; + commit.size = size; + + for (i = 0; i < count; i++) { + ret = api->alloc(allocator, &commit); + if (ret) { + mpp_err("mpp_buffer_test mpp_allocator_alloc failed\n"); + goto MPP_BUFFER_failed; + } + + mpp_log("allocator get ptr %p with fd %d\n", commit.ptr, commit.fd); + + /* + * NOTE: commit buffer info will be directly return within new MppBuffer + * This mode allow input group is NULL + */ + ret = mpp_buffer_import(&commit_buffer[i], &commit); + if (MPP_OK != ret) { + mpp_err("mpp_buffer_test mpp_buffer_commit failed\n"); + goto MPP_BUFFER_failed; + } + + /* + * test imported buffer + */ + { + void *ptr = mpp_buffer_get_ptr(commit_buffer[i]); + if (NULL == ptr) { + mpp_err("mpp_buffer_test mpp_buffer_get_ptr failed\n"); + goto MPP_BUFFER_failed; + } + + mpp_log("get ptr %p from fd %d\n", ptr, mpp_buffer_get_fd(commit_buffer[i])); + + memset(ptr, 0, mpp_buffer_get_size(commit_buffer[i])); + } + } + + for (i = 0; i < count; i++) { + if (commit_buffer[i]) { + ret = mpp_buffer_info_get(commit_buffer[i], &commit); + if (MPP_OK != ret) { + mpp_err("mpp_buffer_test mpp_buffer_info_get failed\n"); + goto MPP_BUFFER_failed; + } + + ret = mpp_buffer_put(commit_buffer[i]); + if (MPP_OK != ret) { + mpp_err("mpp_buffer_test mpp_buffer_put commit mode failed\n"); + goto MPP_BUFFER_failed; + } + + commit_buffer[i] = NULL; + + /* NOTE: buffer info from allocator need to be free directly */ + ret = api->free(allocator, &commit); + if (MPP_OK != ret) { + mpp_err("mpp_buffer_test api->free failed\n"); + goto MPP_BUFFER_failed; + } + } + } + + ret = mpp_allocator_put(&allocator); + if (MPP_OK != ret) { + mpp_err("mpp_buffer_test mpp_allocator_put failed\n"); + goto MPP_BUFFER_failed; + } + + mpp_log("mpp_buffer_test commit mode with used status success\n"); + + + mpp_log("mpp_buffer_test normal mode start\n"); + + ret = mpp_buffer_group_get_internal(&group, MPP_BUFFER_TYPE_ION); + if (MPP_OK != ret) { + mpp_err("mpp_buffer_test mpp_buffer_group_get failed\n"); + goto MPP_BUFFER_failed; + } + + count = MPP_BUFFER_TEST_NORMAL_COUNT; + + mpp_buffer_group_limit_config(group, 0, count); + + for (i = 0; i < count; i++) { + ret = mpp_buffer_get(group, &normal_buffer[i], (i + 1) * SZ_1K); + if (MPP_OK != ret) { + mpp_err("mpp_buffer_test mpp_buffer_get mode normal failed\n"); + goto MPP_BUFFER_failed; + } + } + + for (i = 0; i < count; i++) { + if (normal_buffer[i]) { + ret = mpp_buffer_put(normal_buffer[i]); + if (MPP_OK != ret) { + mpp_err("mpp_buffer_test mpp_buffer_get mode normal failed\n"); + goto MPP_BUFFER_failed; + } + normal_buffer[i] = NULL; + } + } + + mpp_log("mpp_buffer_test normal mode success\n"); + + if (group) { + mpp_buffer_group_put(group); + group = NULL; + } + + mpp_log("mpp_buffer_test success\n"); + + ret = mpp_buffer_get(NULL, &legacy_buffer, MPP_BUFFER_TEST_SIZE); + if (MPP_OK != ret) { + mpp_log("mpp_buffer_test mpp_buffer_get legacy buffer failed\n"); + goto MPP_BUFFER_failed; + } + + ret = mpp_buffer_put(legacy_buffer); + if (MPP_OK != ret) { + mpp_log("mpp_buffer_test mpp_buffer_put legacy buffer failed\n"); + goto MPP_BUFFER_failed; + } + + mpp_env_set_u32("mpp_buffer_debug", 0); + + return ret; + +MPP_BUFFER_failed: + for (i = 0; i < MPP_BUFFER_TEST_COMMIT_COUNT; i++) { + if (commit_buffer[i]) + mpp_buffer_put(commit_buffer[i]); + } + + for (i = 0; i < MPP_BUFFER_TEST_COMMIT_COUNT; i++) { + if (commit_ptr[i]) { + free(commit_ptr[i]); + commit_ptr[i] = NULL; + } + } + for (i = 0; i < MPP_BUFFER_TEST_NORMAL_COUNT; i++) { + if (normal_buffer[i]) + mpp_buffer_put(normal_buffer[i]); + } + + if (group) { + mpp_buffer_group_put(group); + group = NULL; + } + + if (legacy_buffer) { + mpp_buffer_put(legacy_buffer); + legacy_buffer = NULL; + } + + if (allocator) { + mpp_allocator_put(&allocator); + } + mpp_assert(NULL == allocator); + + mpp_log("mpp_buffer_test failed\n"); + + mpp_env_set_u32("mpp_buffer_debug", 0); + + return ret; +} + diff --git a/test/mpp_packet_test.c b/test/mpp_packet_test.c index 459f4f10..5964e062 100644 --- a/test/mpp_packet_test.c +++ b/test/mpp_packet_test.c @@ -1,67 +1,67 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define MODULE_TAG "mpp_packet_test" - -#include - -#include "mpp_log.h" -#include "mpp_packet.h" - -#define MPP_PACKET_TEST_SIZE 1024 - -int main() -{ - MPP_RET ret = MPP_ERR_UNKNOW; - MppPacket packet = NULL; - void *data = NULL; - size_t size = MPP_PACKET_TEST_SIZE; - - mpp_log("mpp_packet_test start\n"); - - data = malloc(size); - if (NULL == data) { - mpp_err("mpp_packet_test malloc failed\n"); - goto MPP_PACKET_failed; - } - - ret = mpp_packet_init(&packet, data, size); - if (MPP_OK != ret) { - mpp_err("mpp_packet_test mpp_packet_init failed\n"); - goto MPP_PACKET_failed; - } - mpp_packet_set_eos(packet); - if (MPP_OK != ret) { - mpp_err("mpp_packet_test mpp_packet_set_eos failed\n"); - goto MPP_PACKET_failed; - } - mpp_packet_deinit(&packet); - - free(data); - mpp_log("mpp_packet_test success\n"); - return ret; - -MPP_PACKET_failed: - if (packet) - mpp_packet_deinit(&packet); - - if (data) - free(data); - - mpp_log("mpp_packet_test failed\n"); - return ret; -} - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define MODULE_TAG "mpp_packet_test" + +#include + +#include "mpp_log.h" +#include "mpp_packet.h" + +#define MPP_PACKET_TEST_SIZE 1024 + +int main() +{ + MPP_RET ret = MPP_ERR_UNKNOW; + MppPacket packet = NULL; + void *data = NULL; + size_t size = MPP_PACKET_TEST_SIZE; + + mpp_log("mpp_packet_test start\n"); + + data = malloc(size); + if (NULL == data) { + mpp_err("mpp_packet_test malloc failed\n"); + goto MPP_PACKET_failed; + } + + ret = mpp_packet_init(&packet, data, size); + if (MPP_OK != ret) { + mpp_err("mpp_packet_test mpp_packet_init failed\n"); + goto MPP_PACKET_failed; + } + mpp_packet_set_eos(packet); + if (MPP_OK != ret) { + mpp_err("mpp_packet_test mpp_packet_set_eos failed\n"); + goto MPP_PACKET_failed; + } + mpp_packet_deinit(&packet); + + free(data); + mpp_log("mpp_packet_test success\n"); + return ret; + +MPP_PACKET_failed: + if (packet) + mpp_packet_deinit(&packet); + + if (data) + free(data); + + mpp_log("mpp_packet_test failed\n"); + return ret; +} + diff --git a/utils/utils.h b/utils/utils.h index c2243e1a..4f2a143f 100644 --- a/utils/utils.h +++ b/utils/utils.h @@ -1,46 +1,46 @@ -/* - * Copyright 2015 Rockchip Electronics Co. LTD - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __UTILS_H__ -#define __UTILS_H__ - -#include -#include "mpp_frame.h" - -typedef struct OptionInfo_t { - const char* name; - const char* argname; - const char* help; -} OptionInfo; - -#define show_options(opt) \ - do { \ - _show_options(sizeof(opt)/sizeof(OptionInfo), opt); \ - } while (0) - -#ifdef __cplusplus -extern "C" { -#endif - -void _show_options(int count, OptionInfo *options); -void dump_mpp_frame_to_file(MppFrame frame, FILE *fp); - -#ifdef __cplusplus -} -#endif - -#endif /*__UTILS_H__*/ - +/* + * Copyright 2015 Rockchip Electronics Co. LTD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __UTILS_H__ +#define __UTILS_H__ + +#include +#include "mpp_frame.h" + +typedef struct OptionInfo_t { + const char* name; + const char* argname; + const char* help; +} OptionInfo; + +#define show_options(opt) \ + do { \ + _show_options(sizeof(opt)/sizeof(OptionInfo), opt); \ + } while (0) + +#ifdef __cplusplus +extern "C" { +#endif + +void _show_options(int count, OptionInfo *options); +void dump_mpp_frame_to_file(MppFrame frame, FILE *fp); + +#ifdef __cplusplus +} +#endif + +#endif /*__UTILS_H__*/ +