Add initial cmake support for building the rocdecode library
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
build/
|
||||
samples/*/build
|
||||
.vscode/
|
||||
@@ -0,0 +1,65 @@
|
||||
################################################################################
|
||||
# Copyright (c) 2023 Advanced Micro Devices, Inc.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
#
|
||||
################################################################################
|
||||
|
||||
cmake_minimum_required (VERSION 3.0)
|
||||
project(rocdecode)
|
||||
set(VERSION "0.2.0")
|
||||
|
||||
set(CMAKE_INSTALL_LIBDIR "lib" CACHE STRING "Library install directory")
|
||||
set(CMAKE_INSTALL_INCLUDEDIR "include" CACHE STRING "Include install directory")
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(ROCM_PATH /opt/rocm CACHE PATH "Default ROCm installation path")
|
||||
|
||||
# avoid setting the default installation path to /usr/local
|
||||
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
|
||||
set(CMAKE_INSTALL_PREFIX ${ROCM_PATH} CACHE PATH "rocDecode default installation path" FORCE)
|
||||
endif(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
|
||||
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
|
||||
list(APPEND CMAKE_PREFIX_PATH ${ROCM_PATH}/hip ${ROCM_PATH})
|
||||
set(CMAKE_CXX_COMPILER ${ROCM_PATH}/llvm/bin/clang++)
|
||||
|
||||
set(DEFAULT_AMDGPU_TARGETS "gfx803;gfx900;gfx906;gfx908;gfx90a;gfx940;gfx1030;gfx1031;gfx1032")
|
||||
set(AMDGPU_TARGETS "${DEFAULT_AMDGPU_TARGETS}" CACHE STRING "List of specific machine types for library to target")
|
||||
|
||||
find_package(HIP QUIET)
|
||||
find_package(Libva QUIET)
|
||||
|
||||
if(HIP_FOUND AND Libva_FOUND)
|
||||
list(APPEND SOURCES ${PROJECT_SOURCE_DIR} src/rocdecode_api.cpp src/rocdecoder.cpp)
|
||||
add_library(${PROJECT_NAME} SHARED ${SOURCES})
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++17")
|
||||
target_link_libraries(${PROJECT_NAME} Libva::va Libva::va_drm hip::device)
|
||||
install(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR})
|
||||
install(FILES api/rocdecode.h utils/videoDemuxer.hpp DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME})
|
||||
|
||||
else()
|
||||
if (NOT HIP_FOUND)
|
||||
message(FATAL_ERROR "-- ERROR!: HIP Not Found! - please install ROCm and HIP!")
|
||||
endif()
|
||||
if (NOT Libva_FOUND)
|
||||
message(FATAL_ERROR "-- ERROR!: libva-dev Not Found - please install libva-dev!")
|
||||
endif()
|
||||
message("-- ERROR!: ${PROJECT_NAME} excluded! please install all the dependencies and try again!")
|
||||
endif()
|
||||
@@ -1,2 +1,31 @@
|
||||
# rocDecode
|
||||
rocDecode is a high performance video decode SDK for AMD hardware
|
||||
|
||||
## Prerequisites:
|
||||
|
||||
* One of the supported GPUs by ROCm: [AMD Radeon™ Graphics](https://docs.amd.com/bundle/Hardware_and_Software_Reference_Guide/page/Hardware_and_Software_Support.html)
|
||||
* Linux distribution
|
||||
+ **Ubuntu** - `20.04` / `22.04`
|
||||
* Install [ROCm5.5 or later](https://docs.amd.com)
|
||||
+ **Note** - both graphics and rocm use-cases must be installed (i.e., sudo amdgpu-install --usecase=graphics,rocm).
|
||||
* CMake 3.0 or later
|
||||
* libva-dev 2.7 or later
|
||||
* [FFMPEG n4.4.2 or later](https://github.com/FFmpeg/FFmpeg/releases/tag/n4.4.2)
|
||||
|
||||
* **Note** [vcnDECODE-setup.py](vcnDECODE-setup.py) script can be used for installing all the dependencies
|
||||
|
||||
## Build instructions:
|
||||
Please follow the instructions below to build and install the vcndecode library.
|
||||
```
|
||||
cd rocDecode
|
||||
mkdir build; cd build
|
||||
cmake ..
|
||||
make -j8
|
||||
sudo make install
|
||||
```
|
||||
|
||||
## Samples:
|
||||
The tool provides a few samples to decode videos [here](samples/). Please refer to the individual folders to build and run the samples.
|
||||
|
||||
## Docker:
|
||||
Docker files to build vcnDECODE containers are available [here](docker/)
|
||||
@@ -0,0 +1,163 @@
|
||||
################################################################################
|
||||
# Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved.
|
||||
################################################################################
|
||||
# - Try to find ffmpeg libraries (libavcodec, libavformat and libavutil)
|
||||
# Once done this will define
|
||||
#
|
||||
# FFMPEG_FOUND - system has ffmpeg or libav
|
||||
# FFMPEG_INCLUDE_DIR - the ffmpeg include directory
|
||||
# FFMPEG_LIBRARIES - Link these to use ffmpeg
|
||||
################################################################################
|
||||
|
||||
set(ENV{PKG_CONFIG_PATH} "$ENV{PKG_CONFIG_PATH}:/usr/local/lib/pkgconfig")
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
find_package_handle_standard_args(
|
||||
FFmpeg
|
||||
FOUND_VAR FFMPEG_FOUND
|
||||
REQUIRED_VARS
|
||||
FFMPEG_LIBRARIES
|
||||
FFMPEG_INCLUDE_DIR
|
||||
AVCODEC_INCLUDE_DIR
|
||||
AVCODEC_LIBRARY
|
||||
AVFORMAT_INCLUDE_DIR
|
||||
AVFORMAT_LIBRARY
|
||||
AVUTIL_INCLUDE_DIR
|
||||
AVUTIL_LIBRARY
|
||||
SWSCALE_INCLUDE_DIR
|
||||
SWSCALE_LIBRARY
|
||||
VERSION_VAR FFMPEG_VERSION
|
||||
)
|
||||
|
||||
if(FFMPEG_LIBRARIES AND FFMPEG_INCLUDE_DIR)
|
||||
set(FFMPEG_FOUND TRUE)
|
||||
else()
|
||||
# use pkg-config to get the directories and then use these values
|
||||
# in the FIND_PATH() and FIND_LIBRARY() calls
|
||||
find_package(PkgConfig)
|
||||
if(PKG_CONFIG_FOUND)
|
||||
pkg_check_modules(_FFMPEG_AVCODEC libavcodec)
|
||||
pkg_check_modules(_FFMPEG_AVFORMAT libavformat)
|
||||
pkg_check_modules(_FFMPEG_AVUTIL libavutil)
|
||||
endif()
|
||||
|
||||
# AVCODEC
|
||||
find_path(AVCODEC_INCLUDE_DIR
|
||||
NAMES libavcodec/avcodec.h
|
||||
PATHS ${_FFMPEG_AVCODEC_INCLUDE_DIRS}
|
||||
/usr/local/include
|
||||
/usr/include
|
||||
/opt/local/include
|
||||
/sw/include
|
||||
PATH_SUFFIXES ffmpeg libav
|
||||
)
|
||||
mark_as_advanced(AVCODEC_INCLUDE_DIR)
|
||||
find_library(AVCODEC_LIBRARY
|
||||
NAMES avcodec
|
||||
PATHS ${_FFMPEG_AVCODEC_LIBRARY_DIRS}
|
||||
/usr/local/lib
|
||||
/usr/lib
|
||||
/opt/local/lib
|
||||
/sw/lib
|
||||
)
|
||||
mark_as_advanced(AVCODEC_LIBRARY)
|
||||
|
||||
# AVFORMAT
|
||||
find_path(AVFORMAT_INCLUDE_DIR
|
||||
NAMES libavformat/avformat.h
|
||||
PATHS ${_FFMPEG_AVFORMAT_INCLUDE_DIRS}
|
||||
/usr/local/include
|
||||
/usr/include
|
||||
/opt/local/include
|
||||
/sw/include
|
||||
PATH_SUFFIXES ffmpeg libav
|
||||
)
|
||||
mark_as_advanced(AVFORMAT_INCLUDE_DIR)
|
||||
find_library(AVFORMAT_LIBRARY
|
||||
NAMES avformat
|
||||
PATHS ${_FFMPEG_AVFORMAT_LIBRARY_DIRS}
|
||||
/usr/local/lib
|
||||
/usr/lib
|
||||
/opt/local/lib
|
||||
/sw/lib
|
||||
)
|
||||
mark_as_advanced(AVFORMAT_LIBRARY)
|
||||
|
||||
# AVUTIL
|
||||
find_path(AVUTIL_INCLUDE_DIR
|
||||
NAMES libavutil/avutil.h
|
||||
PATHS ${_FFMPEG_AVUTIL_INCLUDE_DIRS}
|
||||
/usr/local/include
|
||||
/usr/include
|
||||
/opt/local/include
|
||||
/sw/include
|
||||
PATH_SUFFIXES ffmpeg libav
|
||||
)
|
||||
mark_as_advanced(AVUTIL_INCLUDE_DIR)
|
||||
find_library(AVUTIL_LIBRARY
|
||||
NAMES avutil
|
||||
PATHS ${_FFMPEG_AVUTIL_LIBRARY_DIRS}
|
||||
/usr/local/lib
|
||||
/usr/lib
|
||||
/opt/local/lib
|
||||
/sw/lib
|
||||
)
|
||||
mark_as_advanced(AVUTIL_LIBRARY)
|
||||
|
||||
# SWSCALE
|
||||
find_path(SWSCALE_INCLUDE_DIR
|
||||
NAMES libswscale/swscale.h
|
||||
PATHS ${_FFMPEG_SWSCALE_INCLUDE_DIRS}
|
||||
/usr/local/include
|
||||
/usr/include
|
||||
/opt/local/include
|
||||
/sw/include
|
||||
PATH_SUFFIXES ffmpeg libav sw
|
||||
)
|
||||
mark_as_advanced(SWSCALE_INCLUDE_DIR)
|
||||
find_library(SWSCALE_LIBRARY
|
||||
NAMES swscale
|
||||
PATHS ${_FFMPEG_SWSCALE_LIBRARY_DIRS}
|
||||
/usr/local/lib
|
||||
/usr/lib
|
||||
/opt/local/lib
|
||||
/sw/lib
|
||||
)
|
||||
mark_as_advanced(SWSCALE_LIBRARY)
|
||||
|
||||
if(AVCODEC_LIBRARY AND AVFORMAT_LIBRARY)
|
||||
set(FFMPEG_FOUND TRUE)
|
||||
endif()
|
||||
|
||||
if(_FFMPEG_AVCODEC_VERSION VERSION_LESS 58.18.100 OR _FFMPEG_AVFORMAT_VERSION VERSION_LESS 58.12.100 OR _FFMPEG_AVUTIL_VERSION VERSION_LESS 56.14.100)
|
||||
if(FFMPEG_FOUND)
|
||||
message("-- ${White}FFMPEG required min version - 4.0.4 Found:${FFMPEG_VERSION}")
|
||||
message("-- ${White}AVCODEC required min version - 58.18.100 Found:${_FFMPEG_AVCODEC_VERSION}${ColourReset}")
|
||||
message("-- ${White}AVFORMAT required min version - 58.12.100 Found:${_FFMPEG_AVFORMAT_VERSION}${ColourReset}")
|
||||
message("-- ${White}AVUTIL required min version - 56.14.100 Found:${_FFMPEG_AVUTIL_VERSION}${ColourReset}")
|
||||
endif()
|
||||
set(FFMPEG_FOUND FALSE)
|
||||
message( "-- ${Yellow}NOTE: FindFFmpeg failed to find -- FFMPEG${ColourReset}" )
|
||||
endif()
|
||||
|
||||
if(FFMPEG_FOUND)
|
||||
set(FFMPEG_INCLUDE_DIR ${AVFORMAT_INCLUDE_DIR} CACHE INTERNAL "")
|
||||
set(FFMPEG_LIBRARIES
|
||||
${AVCODEC_LIBRARY}
|
||||
${AVFORMAT_LIBRARY}
|
||||
${AVUTIL_LIBRARY}
|
||||
${SWSCALE_LIBRARY}
|
||||
CACHE INTERNAL ""
|
||||
)
|
||||
endif()
|
||||
|
||||
if(FFMPEG_FOUND)
|
||||
if(NOT FFMPEG_FIND_QUIETLY)
|
||||
message("-- ${White}Using FFMPEG -- Libraries:${FFMPEG_LIBRARIES} Includes:${FFMPEG_INCLUDE_DIR}${ColourReset}")
|
||||
endif()
|
||||
else()
|
||||
if(FFMPEG_FIND_REQUIRED)
|
||||
message(FATAL_ERROR "{Red}FindFFmpeg -- libavcodec or libavformat or libavutil NOT FOUND${ColourReset}")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
@@ -0,0 +1,34 @@
|
||||
################################################################################
|
||||
#
|
||||
# MIT License
|
||||
#
|
||||
# Copyright (c) 2022 Advanced Micro Devices, Inc.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
#
|
||||
|
||||
find_package(PkgConfig)
|
||||
pkg_check_modules(Libdrm libdrm)
|
||||
if(Libdrm_FOUND)
|
||||
if(NOT TARGET Libdrm::drm)
|
||||
add_library(Libdrm::drm UNKNOWN IMPORTED)
|
||||
set_target_properties(Libdrm::drm PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${Libdrm_INCLUDE_DIRS}"
|
||||
IMPORTED_LOCATION "${Libdrm_LINK_LIBRARIES}")
|
||||
endif()
|
||||
endif()
|
||||
@@ -0,0 +1,47 @@
|
||||
################################################################################
|
||||
#
|
||||
# MIT License
|
||||
#
|
||||
# Copyright (c) 2022 Advanced Micro Devices, Inc.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
#
|
||||
|
||||
find_package(Libdrm REQUIRED)
|
||||
find_library(LIBVA_LIBRARY NAMES va)
|
||||
find_library(LIBVA_DRM_LIBRARY NAMES va-drm)
|
||||
find_path(LIBVA_INCLUDE_DIR NAMES va/va.h)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(Libva DEFAULT_MSG LIBVA_INCLUDE_DIR LIBVA_LIBRARY LIBVA_DRM_LIBRARY)
|
||||
mark_as_advanced(LIBVA_INCLUDE_DIR LIBVA_LIBRARY LIBVA_DRM_LIBRARY)
|
||||
|
||||
if(Libva_FOUND)
|
||||
if(NOT TARGET Libva::va)
|
||||
add_library(Libva::va UNKNOWN IMPORTED)
|
||||
set_target_properties(Libva::va PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${LIBVA_INCLUDE_DIR}"
|
||||
IMPORTED_LOCATION "${LIBVA_LIBRARY}")
|
||||
endif()
|
||||
if(NOT TARGET Libva::va_drm)
|
||||
add_library(Libva::va_drm UNKNOWN IMPORTED)
|
||||
target_link_libraries(Libva::va_drm INTERFACE Libdrm::drm)
|
||||
set_target_properties(Libva::va_drm PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${LIBVA_INCLUDE_DIR}"
|
||||
IMPORTED_LOCATION "${LIBVA_DRM_LIBRARY}")
|
||||
endif()
|
||||
endif()
|
||||
@@ -0,0 +1,13 @@
|
||||
# rocDecoder Docker
|
||||
|
||||
## Build - dockerfiles
|
||||
|
||||
```
|
||||
sudo docker build -f {DOCKER_FILE_NAME}.dockerfile -t {DOCKER_IMAGE_NAME} .
|
||||
```
|
||||
|
||||
## Run - docker
|
||||
|
||||
```
|
||||
sudo docker run -it --device=/dev/kfd --device=/dev/dri --cap-add=SYS_RAWIO --device=/dev/mem --group-add video --network host --env DISPLAY=unix$DISPLAY --privileged --volume $XAUTH:/root/.Xauthority --volume /tmp/.X11-unix/:/tmp/.X11-unix {DOCKER_IMAGE_NAME}
|
||||
```
|
||||
@@ -0,0 +1,28 @@
|
||||
FROM ubuntu:20.04
|
||||
|
||||
# install base dependencies
|
||||
RUN apt-get update -y
|
||||
#RUN apt-get dist-upgrade -y
|
||||
RUN DEBIAN_FRONTEND=noninteractive apt-get -y install gcc g++ cmake pkg-config git apt-utils sudo vainfo dialog
|
||||
|
||||
RUN DEBIAN_FRONTEND=noninteractive dpkg --add-architecture i386
|
||||
|
||||
# install ROCm
|
||||
RUN DEBIAN_FRONTEND=noninteractive apt-get -y install initramfs-tools libnuma-dev wget keyboard-configuration && \
|
||||
wget https://repo.radeon.com/amdgpu-install/5.5/ubuntu/focal/amdgpu-install_5.5.50500-1_all.deb && \
|
||||
sudo apt-get install ./amdgpu-install_5.5.50500-1_all.deb && \
|
||||
sudo amdgpu-install -y --usecase=graphics,rocm
|
||||
|
||||
# install FFMPEG, and other dependencies
|
||||
RUN DEBIAN_FRONTEND=noninteractive apt-get -y install autoconf automake build-essential cmake git-core libass-dev libfreetype6-dev libsdl2-dev libtool libva-dev \
|
||||
libvdpau-dev libvorbis-dev libxcb1-dev libxcb-shm0-dev libxcb-xfixes0-dev pkg-config texinfo wget zlib1g-dev \
|
||||
nasm yasm libx264-dev libx265-dev libnuma-dev libfdk-aac-dev unzip && \
|
||||
wget https://github.com/FFmpeg/FFmpeg/archive/refs/tags/n4.4.2.zip && unzip n4.4.2.zip && cd FFmpeg-n4.4.2/ && sudo ldconfig && \
|
||||
export PKG_CONFIG_PATH="/usr/local/lib/pkgconfig/" && \
|
||||
./configure --enable-shared --disable-static && \
|
||||
make -j8 && sudo make install && cd
|
||||
|
||||
ENV LD_LIBRARY_PATH="/usr/local/lib:/usr/local/lib64/:/usr/local/lib/x86_64-linux-gnu:$LD_LIBRARY_PATH"
|
||||
|
||||
WORKDIR /workspace
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
FROM ubuntu:22.04
|
||||
|
||||
# install base dependencies
|
||||
RUN apt-get update -y
|
||||
#RUN apt-get dist-upgrade -y
|
||||
RUN DEBIAN_FRONTEND=noninteractive apt-get -y install gcc g++ cmake pkg-config git apt-utils sudo vainfo dialog libstdc++-12-dev
|
||||
|
||||
RUN DEBIAN_FRONTEND=noninteractive dpkg --add-architecture i386
|
||||
|
||||
# install ROCm
|
||||
RUN DEBIAN_FRONTEND=noninteractive apt-get -y install initramfs-tools libnuma-dev wget keyboard-configuration && \
|
||||
wget https://repo.radeon.com/amdgpu-install/5.5/ubuntu/jammy/amdgpu-install_5.5.50500-1_all.deb && \
|
||||
sudo apt-get install ./amdgpu-install_5.5.50500-1_all.deb && \
|
||||
sudo amdgpu-install -y --usecase=graphics,rocm
|
||||
|
||||
# install FFMPEG, and other dependencies
|
||||
RUN DEBIAN_FRONTEND=noninteractive apt-get -y install autoconf automake build-essential cmake git-core libass-dev libfreetype6-dev libsdl2-dev libtool libva-dev \
|
||||
libvdpau-dev libvorbis-dev libxcb1-dev libxcb-shm0-dev libxcb-xfixes0-dev pkg-config texinfo wget zlib1g-dev \
|
||||
nasm yasm libx264-dev libx265-dev libnuma-dev libfdk-aac-dev unzip && \
|
||||
wget https://github.com/FFmpeg/FFmpeg/archive/refs/tags/n4.4.2.zip && unzip n4.4.2.zip && cd FFmpeg-n4.4.2/ && sudo ldconfig && \
|
||||
export PKG_CONFIG_PATH="/usr/local/lib/pkgconfig/" && \
|
||||
./configure --enable-shared --disable-static && \
|
||||
make -j8 && sudo make install && cd
|
||||
|
||||
ENV LD_LIBRARY_PATH="/usr/local/lib:/usr/local/lib64/:/usr/local/lib/x86_64-linux-gnu:$LD_LIBRARY_PATH"
|
||||
|
||||
WORKDIR /workspace
|
||||
@@ -0,0 +1,215 @@
|
||||
# Copyright (c) 2023 Advanced Micro Devices, Inc. All rights reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
import os
|
||||
import sys
|
||||
import argparse
|
||||
import platform
|
||||
if sys.version_info[0] < 3:
|
||||
import commands
|
||||
else:
|
||||
import subprocess
|
||||
|
||||
__version__ = "1.0"
|
||||
__status__ = "Shipping"
|
||||
|
||||
# Arguments
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--directory', type=str, default='~/rocDecode-deps',
|
||||
help='Setup home directory - optional (default:~/)')
|
||||
parser.add_argument('--ffmpeg', type=str, default='yes',
|
||||
help='FFMPEG V4.4.2 Installation (default:yes) [options:yes/no]')
|
||||
parser.add_argument('--reinstall', type=str, default='no',
|
||||
help='Remove previous setup and reinstall - optional (default:no) [options:yes/no]')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
setupDir = args.directory
|
||||
ffmpegInstall = args.ffmpeg
|
||||
reinstall = args.reinstall
|
||||
|
||||
if ffmpegInstall not in ('no', 'yes'):
|
||||
print(
|
||||
"ERROR: FFMPEG Install Option Not Supported - [Supported Options: no or yes]")
|
||||
exit()
|
||||
|
||||
# get platfrom info
|
||||
platfromInfo = platform.platform()
|
||||
|
||||
# sudo requirement check
|
||||
sudoLocation = ''
|
||||
userName = ''
|
||||
if sys.version_info[0] < 3:
|
||||
status, sudoLocation = commands.getstatusoutput("which sudo")
|
||||
if sudoLocation != '/usr/bin/sudo':
|
||||
status, userName = commands.getstatusoutput("whoami")
|
||||
else:
|
||||
status, sudoLocation = subprocess.getstatusoutput("which sudo")
|
||||
if sudoLocation != '/usr/bin/sudo':
|
||||
status, userName = subprocess.getstatusoutput("whoami")
|
||||
|
||||
# Setup Directory for Deps
|
||||
if setupDir == '~/rocDecode-deps':
|
||||
setupDir_deps = setupDir
|
||||
else:
|
||||
setupDir_deps = setupDir+'/rocDecode-deps'
|
||||
|
||||
# setup directory path
|
||||
deps_dir = os.path.expanduser(setupDir_deps)
|
||||
deps_dir = os.path.abspath(deps_dir)
|
||||
|
||||
# setup for Linux
|
||||
linuxSystemInstall = ''
|
||||
linuxCMake = 'cmake'
|
||||
linuxSystemInstall_check = ''
|
||||
linuxFlag = ''
|
||||
if "centos" in platfromInfo or "redhat" in platfromInfo:
|
||||
linuxSystemInstall = 'yum -y'
|
||||
linuxSystemInstall_check = '--nogpgcheck'
|
||||
if "centos-7" in platfromInfo or "redhat-7" in platfromInfo:
|
||||
linuxCMake = 'cmake3'
|
||||
os.system(linuxSystemInstall+' install cmake3')
|
||||
elif "Ubuntu" in platfromInfo or os.path.exists('/usr/bin/apt-get'):
|
||||
linuxSystemInstall = 'apt-get -y'
|
||||
linuxSystemInstall_check = '--allow-unauthenticated'
|
||||
linuxFlag = '-S'
|
||||
if not "Ubuntu" in platfromInfo:
|
||||
platfromInfo = platfromInfo+'-Ubuntu'
|
||||
elif os.path.exists('/usr/bin/zypper'):
|
||||
linuxSystemInstall = 'zypper -n'
|
||||
linuxSystemInstall_check = '--no-gpg-checks'
|
||||
platfromInfo = platfromInfo+'-SLES'
|
||||
else:
|
||||
print("\nrocDecode Setup on "+platfromInfo+" is unsupported\n")
|
||||
print("\nrocDecode Setup Supported on: Ubuntu 20/22; CentOS 7/8; RedHat 7/8; & SLES 15-SP2\n")
|
||||
exit()
|
||||
|
||||
# rocDecode Setup
|
||||
print("\nrocDecode Setup on: "+platfromInfo+"\n")
|
||||
|
||||
if userName == 'root':
|
||||
os.system(linuxSystemInstall+' update')
|
||||
os.system(linuxSystemInstall+' install sudo')
|
||||
|
||||
# Delete previous install
|
||||
if os.path.exists(deps_dir) and reinstall == 'yes':
|
||||
os.system('sudo -v')
|
||||
os.system('sudo rm -rf '+deps_dir)
|
||||
print("\nrocDecode Setup: Removing Previous Install -- "+deps_dir+"\n")
|
||||
|
||||
# Re-Install
|
||||
if os.path.exists(deps_dir):
|
||||
print("\nrocDecode Setup: Re-Installing Libraries from -- "+deps_dir+"\n")
|
||||
if ffmpegInstall == 'yes':
|
||||
# FFMPEG
|
||||
if os.path.exists(deps_dir+'/FFmpeg-n4.4.2'):
|
||||
os.system('sudo -v')
|
||||
os.system('(cd '+deps_dir+'/FFmpeg-n4.4.2; sudo ' +
|
||||
linuxFlag+' make install -j8)')
|
||||
|
||||
print("\nrocDecode Dependencies Re-Installed with rocDecode-setup.py V-"+__version__+"\n")
|
||||
exit()
|
||||
# Clean Install
|
||||
else:
|
||||
print("\nrocDecode Dependencies Installation with rocDecode-setup.py V-"+__version__+"\n")
|
||||
os.system('mkdir '+deps_dir)
|
||||
# Create Build folder
|
||||
os.system('(cd '+deps_dir+'; mkdir build )')
|
||||
# install pre-reqs
|
||||
os.system('sudo -v')
|
||||
os.system('sudo '+linuxFlag+' '+linuxSystemInstall+' ' +
|
||||
linuxSystemInstall_check+' install gcc cmake git wget unzip pkg-config inxi vainfo')
|
||||
|
||||
# Get Installation Source
|
||||
if ffmpegInstall == 'yes':
|
||||
os.system(
|
||||
'(cd '+deps_dir+'; wget https://github.com/FFmpeg/FFmpeg/archive/refs/tags/n4.4.2.zip && unzip n4.4.2.zip )')
|
||||
|
||||
# Install ffmpeg
|
||||
if ffmpegInstall == 'yes':
|
||||
if "Ubuntu" in platfromInfo:
|
||||
os.system('sudo -v')
|
||||
os.system('sudo '+linuxFlag+' '+linuxSystemInstall+' '+linuxSystemInstall_check +
|
||||
' install autoconf automake build-essential git-core libass-dev libfreetype6-dev')
|
||||
os.system('sudo -v')
|
||||
os.system('sudo '+linuxFlag+' '+linuxSystemInstall+' '+linuxSystemInstall_check +
|
||||
' install libsdl2-dev libtool libva-dev libvdpau-dev libvorbis-dev libxcb1-dev')
|
||||
os.system('sudo -v')
|
||||
os.system('sudo '+linuxFlag+' '+linuxSystemInstall+' '+linuxSystemInstall_check +
|
||||
' install libxcb-shm0-dev libxcb-xfixes0-dev pkg-config texinfo zlib1g-dev')
|
||||
os.system('sudo -v')
|
||||
os.system('sudo '+linuxFlag+' '+linuxSystemInstall+' '+linuxSystemInstall_check +
|
||||
' install nasm yasm libx264-dev libx265-dev libnuma-dev libfdk-aac-dev')
|
||||
else:
|
||||
os.system('sudo '+linuxFlag+' '+linuxSystemInstall+' '+linuxSystemInstall_check +
|
||||
' install autoconf automake bzip2 bzip2-devel freetype-devel')
|
||||
os.system('sudo '+linuxFlag+' '+linuxSystemInstall+' '+linuxSystemInstall_check +
|
||||
' install gcc-c++ libtool make pkgconfig zlib-devel')
|
||||
# Nasm
|
||||
os.system('sudo '+linuxFlag+' '+linuxSystemInstall+' '+linuxSystemInstall_check +
|
||||
' install nasm')
|
||||
if "centos-7" in platfromInfo or "redhat-7" in platfromInfo:
|
||||
# Yasm
|
||||
os.system('sudo '+linuxFlag+' '+linuxSystemInstall+' '+linuxSystemInstall_check +
|
||||
' install http://repo.okay.com.mx/centos/7/x86_64/release/okay-release-1-1.noarch.rpm')
|
||||
os.system('sudo '+linuxFlag+' '+linuxSystemInstall+' '+linuxSystemInstall_check +
|
||||
' --enablerepo=extras install epel-release')
|
||||
os.system('sudo '+linuxFlag+' '+linuxSystemInstall+' '+linuxSystemInstall_check +
|
||||
' install yasm')
|
||||
# libx264 & libx265
|
||||
os.system('sudo '+linuxFlag+' '+linuxSystemInstall+' '+linuxSystemInstall_check +
|
||||
' install libx264-devel libx265-devel')
|
||||
# libfdk_aac
|
||||
os.system('sudo '+linuxFlag+' '+linuxSystemInstall+' '+linuxSystemInstall_check +
|
||||
' install https://forensics.cert.org/cert-forensics-tools-release-el7.rpm')
|
||||
os.system('sudo '+linuxFlag+' '+linuxSystemInstall+' '+linuxSystemInstall_check +
|
||||
' --enablerepo=forensics install fdk-aac')
|
||||
# libASS
|
||||
os.system('sudo '+linuxFlag+' '+linuxSystemInstall+' '+linuxSystemInstall_check +
|
||||
' install libass-devel')
|
||||
elif "centos-8" in platfromInfo or "redhat-8" in platfromInfo:
|
||||
# el8 x86_64 packages
|
||||
os.system('sudo '+linuxFlag+' '+linuxSystemInstall+' '+linuxSystemInstall_check +
|
||||
' install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm')
|
||||
os.system('sudo '+linuxFlag+' '+linuxSystemInstall+' '+linuxSystemInstall_check +
|
||||
' install https://download1.rpmfusion.org/free/el/rpmfusion-free-release-8.noarch.rpm https://download1.rpmfusion.org/nonfree/el/rpmfusion-nonfree-release-8.noarch.rpm')
|
||||
os.system('sudo '+linuxFlag+' '+linuxSystemInstall+' '+linuxSystemInstall_check +
|
||||
' install http://mirror.centos.org/centos/8/PowerTools/x86_64/os/Packages/SDL2-2.0.10-2.el8.x86_64.rpm')
|
||||
os.system('sudo '+linuxFlag+' '+linuxSystemInstall+' '+linuxSystemInstall_check +
|
||||
' install ffmpeg ffmpeg-devel')
|
||||
elif "SLES" in platfromInfo:
|
||||
# FFMPEG-4 packages
|
||||
os.system(
|
||||
'sudo zypper ar -cfp 90 \'https://ftp.gwdg.de/pub/linux/misc/packman/suse/openSUSE_Leap_$releasever/Essentials\' packman-essentials')
|
||||
os.system('sudo '+linuxFlag+' '+linuxSystemInstall+' '+linuxSystemInstall_check +
|
||||
' install ffmpeg-4')
|
||||
|
||||
# FFMPEG 4 from source -- for Ubuntu, CentOS 7, & RedHat 7
|
||||
if "Ubuntu" in platfromInfo or "centos-7" in platfromInfo or "redhat-7" in platfromInfo:
|
||||
os.system('sudo -v')
|
||||
os.system(
|
||||
'(cd '+deps_dir+'/FFmpeg-n4.4.2; sudo '+linuxFlag+' ldconfig )')
|
||||
os.system('(cd '+deps_dir+'/FFmpeg-n4.4.2; export PKG_CONFIG_PATH="/usr/local/lib/pkgconfig/"; ./configure --enable-shared --disable-static)')
|
||||
os.system('(cd '+deps_dir+'/FFmpeg-n4.4.2; make -j8 )')
|
||||
os.system('sudo -v')
|
||||
os.system('(cd '+deps_dir+'/FFmpeg-n4.4.2; sudo ' +
|
||||
linuxFlag+' make install )')
|
||||
|
||||
print("\nrocDecode Dependencies Installed with rocDecode-setup.py V-"+__version__+"\n")
|
||||
@@ -0,0 +1,54 @@
|
||||
################################################################################
|
||||
# Copyright (c) 2023 Advanced Micro Devices, Inc.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
#
|
||||
################################################################################
|
||||
|
||||
cmake_minimum_required (VERSION 3.0)
|
||||
project(videodecode)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(ROCM_PATH /opt/rocm CACHE PATH "default ROCm installation path")
|
||||
list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/../../cmake)
|
||||
list(APPEND CMAKE_PREFIX_PATH ${ROCM_PATH}/hip ${ROCM_PATH})
|
||||
set(CMAKE_CXX_COMPILER ${ROCM_PATH}/llvm/bin/clang++)
|
||||
|
||||
set(DEFAULT_AMDGPU_TARGETS "gfx803;gfx900;gfx906;gfx908;gfx90a;gfx940;gfx1030;gfx1031;gfx1032")
|
||||
set(AMDGPU_TARGETS "${DEFAULT_AMDGPU_TARGETS}" CACHE STRING "List of specific machine types for library to target")
|
||||
find_package(HIP QUIET)
|
||||
find_package(FFmpeg QUIET)
|
||||
find_package(Libva QUIET)
|
||||
if(HIP_FOUND AND FFMPEG_FOUND AND Libva_FOUND)
|
||||
include_directories (${ROCM_PATH}/include/rocdecode)
|
||||
list(APPEND SOURCES ${PROJECT_SOURCE_DIR} videodecode.cpp)
|
||||
add_executable(${PROJECT_NAME} ${SOURCES})
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++17")
|
||||
target_link_libraries(${PROJECT_NAME} ${AVUTIL_LIBRARY} ${AVCODEC_LIBRARY} ${AVFORMAT_LIBRARY} Libva::va Libva::va_drm hip::device rocdecode)
|
||||
else()
|
||||
if (NOT HIP_FOUND)
|
||||
message(FATAL_ERROR "-- ERROR!: HIP Not Found! - please install ROCm and HIP!")
|
||||
endif()
|
||||
if (NOT FFMPEG_FOUND)
|
||||
message(FATAL_ERROR "-- ERROR!: FFMPEG Not Found! - please insatll FFMPEG!")
|
||||
endif()
|
||||
if (NOT Libva_FOUND)
|
||||
message(FATAL_ERROR "-- ERROR!: libva-dev Not Found - please install libva-dev!")
|
||||
endif()
|
||||
message("-- ERROR!: ${PROJECT_NAME} excluded! please install all the dependencies and try again!")
|
||||
endif()
|
||||
@@ -0,0 +1,11 @@
|
||||
# Video Decode Sample
|
||||
This sample illustrates the FFMPEG demuxer to get the individual frames which are then decoded on AMD hardware using VAAPI. This sample supports both YUV420 8-bit and 10-bit streams.
|
||||
|
||||
## Build and run the sample:
|
||||
```
|
||||
mkdir build
|
||||
cd build
|
||||
cmake ..
|
||||
make -j
|
||||
./videodecode -i <input video file - required> -o <optional; output path to save decoded YUV frames> -d <GPU device ID, 0 for the first device, 1 for the second device, etc>
|
||||
```
|
||||
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
Copyright (c) 2023 - 2023 Advanced Micro Devices, Inc. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <unistd.h>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <chrono>
|
||||
#include <sys/stat.h>
|
||||
#include <libgen.h>
|
||||
#include <filesystem>
|
||||
#include "videoDemuxer.hpp"
|
||||
#include "rocdecode.h"
|
||||
|
||||
void ShowHelpAndExit(const char *option = NULL) {
|
||||
std::cout << "Options:" << std::endl
|
||||
<< "-i Input File Path - required" << std::endl
|
||||
<< "-o Output File Path - dumps output if requested; optional" << std::endl
|
||||
<< "-d GPU device ID (0 for the first device, 1 for the second, etc.); optional; default: 0" << std::endl;
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
std::string inputFilePath, outputFilePath;
|
||||
int dumpOutputFrames = 0;
|
||||
int isOutputRGB = 0;
|
||||
int deviceId = 0;
|
||||
// Parse command-line arguments
|
||||
if(argc < 1) {
|
||||
ShowHelpAndExit();
|
||||
}
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (!strcmp(argv[i], "-h")) {
|
||||
ShowHelpAndExit();
|
||||
}
|
||||
if (!strcmp(argv[i], "-i")) {
|
||||
if (++i == argc) {
|
||||
ShowHelpAndExit("-i");
|
||||
}
|
||||
inputFilePath = argv[i];
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(argv[i], "-o")) {
|
||||
if (++i == argc) {
|
||||
ShowHelpAndExit("-o");
|
||||
}
|
||||
outputFilePath = argv[i];
|
||||
dumpOutputFrames = 1;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(argv[i], "-d")) {
|
||||
if (++i == argc) {
|
||||
ShowHelpAndExit("-d");
|
||||
}
|
||||
deviceId = atoi(argv[i]);
|
||||
continue;
|
||||
}
|
||||
ShowHelpAndExit(argv[i]);
|
||||
}
|
||||
|
||||
VideoDemuxer demuxer(inputFilePath.c_str());
|
||||
//VideoDecode viddec(deviceId);
|
||||
|
||||
std::string deviceName, gcnArchName, drmNode;
|
||||
int pciBusID, pciDomainID, pciDeviceID;
|
||||
|
||||
/*viddec.getDeviceinfo(deviceName, gcnArchName, pciBusID, pciDomainID, pciDeviceID, drmNode);
|
||||
std::cout << "info: Using GPU device " << deviceId << ": (drm node: " << drmNode << ") " << deviceName << "[" << gcnArchName << "] on PCI bus " <<
|
||||
std::setfill('0') << std::setw(2) << std::right << std::hex << pciBusID << ":" << std::setfill('0') << std::setw(2) <<
|
||||
std::right << std::hex << pciDomainID << "." << pciDeviceID << std::dec << std::endl;
|
||||
std::cout << "info: decoding started, please wait!" << std::endl;*/
|
||||
|
||||
int nVideoBytes = 0, nFrameReturned = 0, nFrame = 0;
|
||||
uint8_t *pVideo = nullptr;
|
||||
uint8_t *pFrame = nullptr;
|
||||
int64_t pts = 0;
|
||||
//outputImageInfo *pImageInfo;
|
||||
bool bDecodeOutSemiPlanar = false;
|
||||
|
||||
uint32_t width, height;
|
||||
//vcnImageFormat_t subsampling;
|
||||
double totalDecTime = 0;
|
||||
|
||||
do {
|
||||
auto startTime = std::chrono::high_resolution_clock::now();
|
||||
demuxer.demux(&pVideo, &nVideoBytes, &pts);
|
||||
//nFrameReturned = viddec.decode(pVideo, nVideoBytes, pts);
|
||||
auto endTime = std::chrono::high_resolution_clock::now();
|
||||
auto timePerFrame = std::chrono::duration<double, std::milli>(endTime - startTime).count();
|
||||
totalDecTime += timePerFrame;
|
||||
/*if (!nFrame && !viddec.getOutputImageInfo(&pImageInfo)){
|
||||
std::cerr << "Error: Failed to get Output Image Info!" << std::endl;
|
||||
break;
|
||||
}*/
|
||||
|
||||
if (dumpOutputFrames) {
|
||||
for (int i = 0; i < nFrameReturned; i++) {
|
||||
/*pFrame = viddec.getFrame(&pts);
|
||||
viddec.saveImage(outputFilePath, pFrame, pImageInfo, false);
|
||||
// release frame
|
||||
viddec.releaseFrame(pts);*/
|
||||
}
|
||||
}
|
||||
nFrame += nFrameReturned;
|
||||
} while (nVideoBytes);
|
||||
|
||||
// Flush last frames from the decoder if any
|
||||
do {
|
||||
// send null packet to decoder to flush out
|
||||
pVideo = nullptr; nVideoBytes = 0;
|
||||
int64_t pts = 0;
|
||||
//nFrameReturned = viddec.decode(pVideo, nVideoBytes, pts);
|
||||
} while (nFrameReturned);
|
||||
|
||||
/*std::cout << "info: Video codec format: " << viddec.getCodecFmtName(viddec.getVcnVideoCodecId()) << std::endl;
|
||||
std::cout << "info: Video size: [ " << pImageInfo->nOutputWidth << ", " << pImageInfo->nOutputHeight << " ]" << std::endl;
|
||||
std::cout << "info: Video pix format: " << viddec.getPixFmtName(pImageInfo->chromaFormat) << std::endl;
|
||||
std::cout << "info: Video Bit depth: " << pImageInfo->nBitDepth << std::endl;
|
||||
std::cout << "info: Total frame decoded: " << nFrame << std::endl;
|
||||
if (!dumpOutputFrames) {
|
||||
std::cout << "info: avg decoding time per frame (ms): " << totalDecTime / nFrame << std::endl;
|
||||
std::cout << "info: avg FPS: " << (nFrame / totalDecTime) * 1000 << std::endl;
|
||||
}*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
Copyright (c) 2023 - 2023 Advanced Micro Devices, Inc. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
@@ -30,5 +30,4 @@ THE SOFTWARE.
|
||||
#include <sstream>
|
||||
#include <string.h>
|
||||
#include "../api/rocdecode.h"
|
||||
#include "../utils/ffmpeg_demux.h"
|
||||
#include <map>
|
||||
@@ -1,23 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2023 - 2023 Advanced Micro Devices, Inc. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
@@ -0,0 +1,263 @@
|
||||
/*
|
||||
Copyright (c) 2023 - 2023 Advanced Micro Devices, Inc. All rights reserved.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
extern "C" {
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libavutil/pixdesc.h>
|
||||
#include <libavutil/hwcontext.h>
|
||||
#include <libavutil/hwcontext_vaapi.h>
|
||||
#include <va/va.h>
|
||||
#include <va/va_drmcommon.h>
|
||||
}
|
||||
|
||||
// Video Demuxer Interface class
|
||||
class VideoDemuxer {
|
||||
public:
|
||||
class StreamProvider {
|
||||
public:
|
||||
virtual ~StreamProvider() {}
|
||||
virtual int getData(uint8_t *pBuf, int nBuf) = 0;
|
||||
};
|
||||
VideoDemuxer(const char *inputFilePath) : VideoDemuxer(createFmtContextUtil(inputFilePath)) {}
|
||||
VideoDemuxer(StreamProvider *pStreamProvider) : VideoDemuxer(createFmtContextUtil(pStreamProvider)) {av_io_ctx_ = av_fmt_input_ctx_->pb;}
|
||||
~VideoDemuxer();
|
||||
bool demux(uint8_t **ppVideo, int *pnVideoBytes, int64_t *pts = nullptr);
|
||||
private:
|
||||
VideoDemuxer(AVFormatContext *av_fmt_input_ctx_);
|
||||
AVFormatContext *createFmtContextUtil(StreamProvider *pStreamProvider);
|
||||
AVFormatContext *createFmtContextUtil(const char *inputFilePath);
|
||||
static int readPacket(void *pData, uint8_t *pBuf, int nBuf);
|
||||
AVFormatContext *av_fmt_input_ctx_ = nullptr;
|
||||
AVIOContext *av_io_ctx_ = nullptr;
|
||||
AVPacket* packet_ = nullptr;
|
||||
AVPacket* packetFiltered_ = nullptr;
|
||||
AVBSFContext *av_bsf_ctx_ = nullptr;
|
||||
AVCodecID av_videoCodecID_;
|
||||
uint8_t *pDataWithHeader = nullptr;
|
||||
int av_stream_ = 0;
|
||||
bool isH264_ = false;
|
||||
bool isHEVC_ = false;
|
||||
bool isMPEG4_ = false;
|
||||
int64_t defaultTimeScale = 1000;
|
||||
double timeBase = 0.0;
|
||||
unsigned int frameCnt = 0;
|
||||
};
|
||||
|
||||
VideoDemuxer::~VideoDemuxer() {
|
||||
if (!av_fmt_input_ctx_) {
|
||||
return;
|
||||
}
|
||||
if (packet_) {
|
||||
av_packet_free(&packet_);
|
||||
}
|
||||
if (packetFiltered_) {
|
||||
av_packet_free(&packetFiltered_);
|
||||
}
|
||||
if (av_bsf_ctx_) {
|
||||
av_bsf_free(&av_bsf_ctx_);
|
||||
}
|
||||
avformat_close_input(&av_fmt_input_ctx_);
|
||||
if (av_io_ctx_) {
|
||||
av_freep(&av_io_ctx_->buffer);
|
||||
av_freep(&av_io_ctx_);
|
||||
}
|
||||
if (pDataWithHeader) {
|
||||
av_free(pDataWithHeader);
|
||||
}
|
||||
}
|
||||
|
||||
bool VideoDemuxer::demux(uint8_t **ppVideo, int *pnVideoBytes, int64_t *pts) {
|
||||
if (!av_fmt_input_ctx_) {
|
||||
return false;
|
||||
}
|
||||
*pnVideoBytes = 0;
|
||||
if (packet_->data) {
|
||||
av_packet_unref(packet_);
|
||||
}
|
||||
int ret = 0;
|
||||
while ((ret = av_read_frame(av_fmt_input_ctx_, packet_)) >= 0 && packet_->stream_index != av_stream_) {
|
||||
av_packet_unref(packet_);
|
||||
}
|
||||
if (ret < 0) {
|
||||
return false;
|
||||
}
|
||||
if (isH264_ || isHEVC_) {
|
||||
if (packetFiltered_->data) {
|
||||
av_packet_unref(packetFiltered_);
|
||||
}
|
||||
if (av_bsf_send_packet(av_bsf_ctx_, packet_) != 0) {
|
||||
std::cerr << "ERROR: av_bsf_send_packet failed!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
if (av_bsf_receive_packet(av_bsf_ctx_, packetFiltered_) != 0) {
|
||||
std::cerr << "ERROR: av_bsf_receive_packet failed!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
*ppVideo = packetFiltered_->data;
|
||||
*pnVideoBytes = packetFiltered_->size;
|
||||
if (pts)
|
||||
*pts = (int64_t) (packetFiltered_->pts * defaultTimeScale * timeBase);
|
||||
} else {
|
||||
if (isMPEG4_ && (frameCnt == 0)) {
|
||||
int extDataSize = av_fmt_input_ctx_->streams[av_stream_]->codecpar->extradata_size;
|
||||
if (extDataSize > 0) {
|
||||
pDataWithHeader = (uint8_t *)av_malloc(extDataSize + packet_->size - 3 * sizeof(uint8_t));
|
||||
if (!pDataWithHeader) {
|
||||
std::cerr << "ERROR: av_malloc failed!" << std::endl;
|
||||
return false;
|
||||
}
|
||||
memcpy(pDataWithHeader, av_fmt_input_ctx_->streams[av_stream_]->codecpar->extradata, extDataSize);
|
||||
memcpy(pDataWithHeader + extDataSize, packet_->data + 3, packet_->size - 3 * sizeof(uint8_t));
|
||||
*ppVideo = pDataWithHeader;
|
||||
*pnVideoBytes = extDataSize + packet_->size - 3 * sizeof(uint8_t);
|
||||
}
|
||||
} else {
|
||||
*ppVideo = packet_->data;
|
||||
*pnVideoBytes = packet_->size;
|
||||
}
|
||||
if (pts)
|
||||
*pts = (int64_t)(packet_->pts * defaultTimeScale * timeBase);
|
||||
}
|
||||
frameCnt++;
|
||||
return true;
|
||||
}
|
||||
|
||||
VideoDemuxer::VideoDemuxer(AVFormatContext *av_fmt_input_ctx_) : av_fmt_input_ctx_(av_fmt_input_ctx_) {
|
||||
if (!av_fmt_input_ctx_) {
|
||||
std::cerr << "ERROR: av_fmt_input_ctx_ is not vaild!" << std::endl;
|
||||
return;
|
||||
}
|
||||
packet_ = av_packet_alloc();
|
||||
packetFiltered_ = av_packet_alloc();
|
||||
if (!packet_ || !packetFiltered_) {
|
||||
std::cerr << "ERROR: av_packet_alloc failed!" << std::endl;
|
||||
return;
|
||||
}
|
||||
if (avformat_find_stream_info(av_fmt_input_ctx_, nullptr) < 0) {
|
||||
std::cerr << "ERROR: avformat_find_stream_info failed!" << std::endl;
|
||||
return;
|
||||
}
|
||||
av_stream_ = av_find_best_stream(av_fmt_input_ctx_, AVMEDIA_TYPE_VIDEO, -1, -1, nullptr, 0);
|
||||
if (av_stream_ < 0) {
|
||||
std::cerr << "ERROR: av_find_best_stream failed!" << std::endl;
|
||||
av_packet_free(&packet_);
|
||||
av_packet_free(&packetFiltered_);
|
||||
return;
|
||||
}
|
||||
av_videoCodecID_ = av_fmt_input_ctx_->streams[av_stream_]->codecpar->codec_id;
|
||||
AVRational rTimeBase = av_fmt_input_ctx_->streams[av_stream_]->time_base;
|
||||
timeBase = av_q2d(rTimeBase);
|
||||
|
||||
isH264_ = av_videoCodecID_ == AV_CODEC_ID_H264 && (!strcmp(av_fmt_input_ctx_->iformat->long_name, "QuickTime / MOV")
|
||||
|| !strcmp(av_fmt_input_ctx_->iformat->long_name, "FLV (Flash Video)")
|
||||
|| !strcmp(av_fmt_input_ctx_->iformat->long_name, "Matroska / WebM"));
|
||||
isHEVC_ = av_videoCodecID_ == AV_CODEC_ID_HEVC && (!strcmp(av_fmt_input_ctx_->iformat->long_name, "QuickTime / MOV")
|
||||
|| !strcmp(av_fmt_input_ctx_->iformat->long_name, "FLV (Flash Video)")
|
||||
|| !strcmp(av_fmt_input_ctx_->iformat->long_name, "Matroska / WebM"));
|
||||
isMPEG4_ = av_videoCodecID_ == AV_CODEC_ID_MPEG4 && (!strcmp(av_fmt_input_ctx_->iformat->long_name, "QuickTime / MOV")
|
||||
|| !strcmp(av_fmt_input_ctx_->iformat->long_name, "FLV (Flash Video)")
|
||||
|| !strcmp(av_fmt_input_ctx_->iformat->long_name, "Matroska / WebM"));
|
||||
|
||||
if (isH264_) {
|
||||
const AVBitStreamFilter *bsf = av_bsf_get_by_name("h264_mp4toannexb");
|
||||
if (!bsf) {
|
||||
std::cerr << "ERROR: av_bsf_get_by_name() failed" << std::endl;
|
||||
av_packet_free(&packet_);
|
||||
av_packet_free(&packetFiltered_);
|
||||
return;
|
||||
}
|
||||
if (av_bsf_alloc(bsf, &av_bsf_ctx_) != 0) {
|
||||
std::cerr << "ERROR: av_bsf_alloc failed!" << std::endl;
|
||||
return;
|
||||
}
|
||||
avcodec_parameters_copy(av_bsf_ctx_->par_in, av_fmt_input_ctx_->streams[av_stream_]->codecpar);
|
||||
if (av_bsf_init(av_bsf_ctx_) < 0) {
|
||||
std::cerr << "ERROR: av_bsf_init failed!" << std::endl;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (isHEVC_) {
|
||||
const AVBitStreamFilter *bsf = av_bsf_get_by_name("hevc_mp4toannexb");
|
||||
if (!bsf) {
|
||||
std::cerr << "ERROR: av_bsf_get_by_name() failed" << std::endl;
|
||||
av_packet_free(&packet_);
|
||||
av_packet_free(&packetFiltered_);
|
||||
return;
|
||||
}
|
||||
if (av_bsf_alloc(bsf, &av_bsf_ctx_) != 0 ) {
|
||||
std::cerr << "ERROR: av_bsf_alloc failed!" << std::endl;
|
||||
return;
|
||||
}
|
||||
avcodec_parameters_copy(av_bsf_ctx_->par_in, av_fmt_input_ctx_->streams[av_stream_]->codecpar);
|
||||
if (av_bsf_init(av_bsf_ctx_) < 0) {
|
||||
std::cerr << "ERROR: av_bsf_init failed!" << std::endl;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AVFormatContext *VideoDemuxer::createFmtContextUtil(StreamProvider *pStreamProvider) {
|
||||
AVFormatContext *ctx = nullptr;
|
||||
if (!(ctx = avformat_alloc_context())) {
|
||||
std::cerr << "ERROR: avformat_alloc_context failed" << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
uint8_t *avioc_buffer = nullptr;
|
||||
int avioc_buffer_size = 8 * 1024 * 1024;
|
||||
avioc_buffer = (uint8_t *)av_malloc(avioc_buffer_size);
|
||||
if (!avioc_buffer) {
|
||||
std::cerr << "ERROR: av_malloc failed!" << std::endl;;
|
||||
return nullptr;
|
||||
}
|
||||
av_io_ctx_ = avio_alloc_context(avioc_buffer, avioc_buffer_size,
|
||||
0, pStreamProvider, &readPacket, nullptr, nullptr);
|
||||
if (!av_io_ctx_) {
|
||||
std::cerr << "ERROR: avio_alloc_context failed!" << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
ctx->pb = av_io_ctx_;
|
||||
|
||||
if (avformat_open_input(&ctx, nullptr, nullptr, nullptr) != 0) {
|
||||
std::cerr << "ERROR: avformat_open_input failed!" << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
return ctx;
|
||||
}
|
||||
|
||||
AVFormatContext *VideoDemuxer::createFmtContextUtil(const char *inputFilePath) {
|
||||
avformat_network_init();
|
||||
av_log_set_level(AV_LOG_QUIET);
|
||||
AVFormatContext *ctx = nullptr;
|
||||
if (avformat_open_input(&ctx, inputFilePath, nullptr, nullptr) != 0 ) {
|
||||
std::cerr << "ERROR: avformat_open_input failed!" << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
return ctx;
|
||||
}
|
||||
|
||||
int VideoDemuxer::readPacket(void *pData, uint8_t *pBuf, int nBuf) {
|
||||
return ((StreamProvider *)pData)->getData(pBuf, nBuf);
|
||||
}
|
||||
Verwijs in nieuw issue
Block a user