Last active
July 17, 2019 18:03
-
-
Save tmm1/280f11b9c252cec87167c4bd406b508c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/SynoBuildConf/abiconfig b/SynoBuildConf/abiconfig | |
new file mode 100644 | |
index 0000000000..70e02a72b5 | |
--- /dev/null | |
+++ b/SynoBuildConf/abiconfig | |
@@ -0,0 +1,4 @@ | |
+{ | |
+ "skip_including": ["d3d11va.h", "dxva2.h", "qsv.h", "vda.h", "vdpau.h", "xvmc.h"], | |
+ "defines": "#define __STDC_CONSTANT_MACROS" | |
+} | |
diff --git a/SynoBuildConf/build b/SynoBuildConf/build | |
new file mode 100644 | |
index 0000000000..b2b571e726 | |
--- /dev/null | |
+++ b/SynoBuildConf/build | |
@@ -0,0 +1,130 @@ | |
+#!/bin/bash | |
+# Copyright (c) 2000-2015 Synology Inc. All rights reserved. | |
+ | |
+case ${MakeClean} in | |
+ [Yy][Ee][Ss]) | |
+ if [ -f config.mak ]; then | |
+ make distclean | |
+ fi | |
+ ;; | |
+esac | |
+ | |
+case ${CleanOnly} in | |
+ [Yy][Ee][Ss]) | |
+ return | |
+ ;; | |
+esac | |
+ | |
+CONFIGURE="./configure.syno" | |
+case "$PLATFORM_FAMILY" in | |
+ SYNOPLAT_F_I686|SYNOPLAT_F_X86_64) | |
+ arch="i686" | |
+ ;; | |
+ SYNOPLAT_F_PPC) | |
+ arch="powerpc" | |
+ BIG_ENDIAN="yes" | |
+ ;; | |
+ SYNOPLAT_F_ARMV5|SYNOPLAT_F_ARMV7) | |
+ arch="arm" | |
+ ;; | |
+ SYNOPLAT_F_ARMV8) | |
+ arch="arm64" | |
+ ;; | |
+ *) | |
+ SkipThisProject | |
+ return | |
+ ;; | |
+esac | |
+ | |
+EVANSPORT_INC="-I${SysRootInclude}/intelce-utilities -I${SysRootInclude}/intelce-utilities/linux_user" | |
+EVANSPORT_LIB="-L${SysRootLib}/intelce-utilities -Wl,-rpath-link=${SysRootLib}/intelce-utilities" | |
+ | |
+JSONC_INC=$(pkg-config --cflags json-c) | |
+JSONC_LIB=$(pkg-config --libs json-c) | |
+ | |
+CFLAGS="${CFLAGS} -DSYNO_DSM" | |
+ | |
+COMMON_CONFIG=" | |
+ --prefix=/usr | |
+ --incdir=\${prefix}/include/ffmpeg | |
+ --arch=${arch} | |
+ --target-os=linux | |
+ --cross-prefix=${ToolChainPrefix} | |
+ --enable-cross-compile | |
+ --enable-optimizations | |
+ --enable-pic | |
+ --enable-gpl | |
+ --enable-shared | |
+ --disable-static | |
+ --enable-version3 | |
+ --enable-nonfree | |
+ --enable-libfaac | |
+ --enable-encoders | |
+ --enable-pthreads | |
+ --disable-bzlib --disable-protocol=rtp --disable-muxer=image2 --disable-muxer=image2pipe | |
+ --disable-swscale-alpha | |
+ --disable-ffserver | |
+ --disable-ffplay | |
+ --disable-devices | |
+ --disable-bzlib | |
+ --disable-altivec | |
+ --enable-libopencore-amrnb | |
+ --enable-libopencore-amrwb | |
+ --enable-libmp3lame | |
+ --disable-vaapi | |
+ --disable-decoder=amrnb | |
+ --disable-encoder=zmbv | |
+ --disable-encoder=dca | |
+ --disable-encoder=ac3 | |
+ --disable-encoder=ac3_fixed | |
+ --disable-encoder=eac3 | |
+ --disable-decoder=dca | |
+ --disable-decoder=eac3 | |
+ --disable-decoder=truehd | |
+ --cc=${CC} | |
+ " | |
+ | |
+if checkPlatformFunction SYNO_PLAT_NEON_LIBSWSCALE; then | |
+ # for alpine neon libswscale patch | |
+ export EXPORT_BUILD_TARGET="ALPINE" | |
+fi | |
+ | |
+if checkPlatformFunction SYNO_FEA_FFMPEG_SMD; then | |
+ # for evansport platform | |
+ # add -DSYNO_EVANSPORT for header files in intelce-utilities | |
+ env CC=${CC} \ | |
+ CFLAGS="${CFLAGS} ${EVANSPORT_INC} ${JSONC_INC} -DSYNO_ENABLE_SMD -DSYNO_EVANSPORT" \ | |
+ LDFLAGS="${LDFLAGS} ${EVANSPORT_LIB}" \ | |
+ CHECK_CFLAG="gnu99" \ | |
+ EVANSPORT_LIB="${EVANSPORT_LIB}" \ | |
+ ${CONFIGURE} \ | |
+ ${COMMON_CONFIG} \ | |
+ --enable-yasm \ | |
+ --enable-libx264 \ | |
+ --enable-encoder=libx264 \ | |
+ --enable-libh264_smd \ | |
+ --enable-smd \ | |
+ --disable-filter=hqdn3d \ | |
+ --extra-libs="-lgdl -losal -lpal -lsven -lismd_core -lismd_audio -lismd_viddec -lismd_videnc -lismd_vidpproc -lplatform_config -lffmpeg_plugin ${JSONC_LIB}" | |
+elif checkPlatformFunction SYNO_FEA_FFMPEG_ENABLE_X264; then | |
+ # for x86_64, alpine | |
+ env CC=${CC} \ | |
+ CFLAGS="${CFLAGS}" \ | |
+ LDFLAGS="${LDFLAGS}" \ | |
+ ${CONFIGURE} \ | |
+ ${COMMON_CONFIG} \ | |
+ --enable-yasm \ | |
+ --enable-libx264 \ | |
+ --enable-encoder=libx264 | |
+else | |
+ env CC=${CC} \ | |
+ CFLAGS="${CFLAGS}" \ | |
+ LDFLAGS="${LDFLAGS}" \ | |
+ bigendian_platform="${BIG_ENDIAN}" \ | |
+ ${CONFIGURE} \ | |
+ ${COMMON_CONFIG} | |
+fi | |
+ | |
+make ${MAKE_FLAGS} | |
+make tools/qt-faststart ${MAKE_FLAGS} | |
+# vim:ft=sh | |
diff --git a/SynoBuildConf/build-virtual-media-server b/SynoBuildConf/build-virtual-media-server | |
new file mode 100755 | |
index 0000000000..b629df93b6 | |
--- /dev/null | |
+++ b/SynoBuildConf/build-virtual-media-server | |
@@ -0,0 +1,164 @@ | |
+#!/bin/bash | |
+# Copyright (c) 2000-2013 Synology Inc. All rights reserved. | |
+ | |
+case ${MakeClean} in | |
+ [Yy][Ee][Ss]) | |
+ if [ -f config.mak ]; then | |
+ make distclean | |
+ fi | |
+ ;; | |
+esac | |
+ | |
+case ${CleanOnly} in | |
+ [Yy][Ee][Ss]) | |
+ return | |
+ ;; | |
+esac | |
+ | |
+CONFIGURE="./configure.syno" | |
+case "$BUILD_TARGET" in | |
+ X64|BROMOLOW|CEDARVIEW|EVANSPORT|AVOTON|DOCKERX64|BROMOLOWESM|BRASWELL|APOLLOLAKE|GRANTLEY|BROADWELL|KVMX64|DENVERTON|BROADWELLNK|PURLEY|COFFEELAKE) | |
+ arch="i686" | |
+ ;; | |
+ PPC_QORIQ|PPC_853X) | |
+ arch="powerpc" | |
+ BIG_ENDIAN="yes" | |
+ ;; | |
+ ALPINE) | |
+ arch="armv7" | |
+ ALPINE_EXTRA_CFLAGS="-DSYNO_PLAT_NEON_LIBSWSCALE -I${SysRootPrefix}/pkg/include" | |
+ ALPINE_EXTRA_LDFLAGS="-L${SysRootPrefix}/pkg/lib" | |
+ ;; | |
+ MARVELL_ARMADA370|MARVELL_ARMADA375|MARVELL_ARMADAXP|MARVELL_ARMADA38X|MINDSPEED_COMCERTO2K|BROADCOM_NORTHSTARPLUS|STM_MONACO|HISILICON_HI3535|HISILICON_HI3536) | |
+ arch="armv7" | |
+ ;; | |
+ REALTEK_RTD1296|MARVELL_ARMADA37XX) | |
+ arch="aarch64" | |
+ ;; | |
+ MARVELL_88F6281) | |
+ arch="arm" | |
+ ;; | |
+ *) | |
+ echo "This platform($BUILD_TARGET) is not supported yet." | |
+ return | |
+ ;; | |
+esac | |
+ | |
+STANDALONE="FALSE" | |
+ | |
+JSONC_INC=$(pkg-config --cflags json-c) | |
+JSONC_LIB=$(pkg-config --libs json-c) | |
+ | |
+if [ "TRUE" = "${STANDALONE}" ]; then | |
+ CUSTOM_CONFIG=" | |
+ --disable-shared | |
+ --enable-static | |
+ " | |
+ CUSTOM_CFLAGS="-DSTANDALONE" | |
+else | |
+ CUSTOM_CONFIG=" | |
+ --enable-shared | |
+ --disable-static | |
+ " | |
+ CUSTOM_CFLAGS="" | |
+fi | |
+ | |
+COMMON_RPATH="-Wl,-rpath=/var/packages/MediaServer/target/lib/ffmpeg -Wl,-rpath=/var/packages/MediaServer/target/lib" | |
+CFLAGS="${CFLAGS} ${CUSTOM_CFLAGS} -DSYNO_MEDIASERVER" | |
+LDFLAGS="${LDFLAGS} ${COMMON_RPATH}" | |
+ | |
+COMMON_CONFIG=" | |
+ --prefix=/usr/pkg | |
+ --incdir=\${prefix}/include/ffmpeg | |
+ --arch=${arch} | |
+ --target-os=linux | |
+ --cross-prefix=${ToolChainPrefix} | |
+ --enable-cross-compile | |
+ --enable-optimizations | |
+ --enable-pic | |
+ --enable-gpl | |
+ --enable-version3 | |
+ --enable-nonfree | |
+ --enable-libfaac | |
+ --enable-encoders | |
+ --enable-pthreads | |
+ --disable-muxer=image2 --disable-muxer=image2pipe | |
+ --disable-swscale-alpha | |
+ --disable-ffplay | |
+ --disable-doc | |
+ --disable-devices | |
+ --disable-bzlib | |
+ --disable-altivec | |
+ --enable-libopencore-amrnb | |
+ --enable-libopencore-amrwb | |
+ --enable-libmp3lame | |
+ --disable-decoder=amrnb | |
+ --disable-encoder=zmbv | |
+ --cc=${CC} | |
+ ${CUSTOM_CONFIG} | |
+ " | |
+ | |
+export EXPORT_BUILD_TARGET="${BUILD_TARGET}" | |
+ | |
+if [ "i686" = "${arch}" -a "EVANSPORT" = "${BUILD_TARGET}" ]; then | |
+ | |
+EVANSPORT_INC="-I${SysRootInclude}/intelce-utilities -I${SysRootInclude}/intelce-utilities/linux_user" | |
+EVANSPORT_LDFLAGS="-L${SysRootLib}/intelce-utilities" | |
+EVANSPORT_RPATH_LINK="-Wl,-rpath-link=${SysRootLib}/intelce-utilities" | |
+ | |
+# for evansport platform | |
+# add -DSYNO_EVANSPORT for header files in intelce-utilities | |
+ | |
+env CC=${CC} \ | |
+ CFLAGS="${CFLAGS} ${EVANSPORT_INC} ${JSONC_INC} -DSYNO_ENABLE_SMD -DSYNO_EVANSPORT" \ | |
+ LDFLAGS="${LDFLAGS} ${EVANSPORT_LDFLAGS} ${EVANSPORT_RPATH_LINK}" \ | |
+ CHECK_CFLAG="gnu99" \ | |
+ EVANSPORT_LIB="${EVANSPORT_RPATH_LINK}" \ | |
+ ${CONFIGURE} \ | |
+ ${COMMON_CONFIG} \ | |
+ --enable-yasm \ | |
+ --enable-libx264 \ | |
+ --enable-encoder=libx264 \ | |
+ --enable-libh264_smd \ | |
+ --enable-smd \ | |
+ --disable-filter=hqdn3d \ | |
+ --extra-libs="${JSONC_LIB} -lgdl -losal -lpal -lsven -lismd_core -lismd_audio -lismd_viddec -lismd_videnc -lismd_vidpproc -lplatform_config -lffmpeg_plugin" | |
+ | |
+elif [ "i686" = "${arch}" -o "ALPINE" = "${BUILD_TARGET}" ]; then | |
+env CC=${CC} \ | |
+ CFLAGS="${CFLAGS} ${ALPINE_EXTRA_CFLAGS}" \ | |
+ LDFLAGS="${LDFLAGS} ${ALPINE_EXTRA_LDFLAGS}" \ | |
+ ${CONFIGURE} \ | |
+ ${COMMON_CONFIG} \ | |
+ --enable-yasm \ | |
+ --enable-libx264 \ | |
+ --enable-encoder=libx264 | |
+ | |
+#support floating point platform with lame | |
+elif [ "powerpc" = "${arch}" -o "armv7" = "${arch}" -o "aarch64" = "${arch}" ]; then | |
+env CC=${CC} \ | |
+ CFLAGS="${CFLAGS}" \ | |
+ LDFLAGS="${LDFLAGS}" \ | |
+ bigendian_platform="${BIG_ENDIAN}" \ | |
+ ${CONFIGURE} \ | |
+ ${COMMON_CONFIG} \ | |
+ --enable-libfdk-aac | |
+ | |
+#only support fixed point platform with shine | |
+elif [ "arm" = "${arch}" ]; then | |
+env CC=${CC} \ | |
+ CFLAGS="${CFLAGS}" \ | |
+ LDFLAGS="${LDFLAGS}" \ | |
+ ${CONFIGURE} \ | |
+ ${COMMON_CONFIG} \ | |
+ --enable-libshine \ | |
+ --enable-libfdk-aac | |
+ | |
+else | |
+ echo "This platform($BUILD_TARGET) is not supported yet." | |
+ return | |
+fi | |
+ | |
+make ${MAKE_FLAGS} | |
+make tools/qt-faststart ${MAKE_FLAGS} | |
+# vim:ft=sh | |
diff --git a/SynoBuildConf/build-virtual-mplayer2 b/SynoBuildConf/build-virtual-mplayer2 | |
new file mode 100755 | |
index 0000000000..94bcca96ce | |
--- /dev/null | |
+++ b/SynoBuildConf/build-virtual-mplayer2 | |
@@ -0,0 +1,110 @@ | |
+#!/bin/bash | |
+# Copyright (c) 2000-2015 Synology Inc. All rights reserved. | |
+ | |
+case ${MakeClean} in | |
+ [Yy][Ee][Ss]) | |
+ if [ -f config.mak ]; then | |
+ make distclean | |
+ fi | |
+ ;; | |
+esac | |
+ | |
+case ${CleanOnly} in | |
+ [Yy][Ee][Ss]) | |
+ return | |
+ ;; | |
+esac | |
+ | |
+CONFIGURE="./configure.syno" | |
+case "$BUILD_TARGET" in | |
+ X64|BROMOLOW|CEDARVIEW|EVANSPORT|GRANTLEY|BRASWELL|APOLLOLAKE|BROADWELL|AVOTON|KVMX64|DENVERTON|BROADWELLNK|PURLEY|COFFEELAKE) | |
+ arch="i686" | |
+ ;; | |
+ PPC_QORIQ) | |
+ arch="powerpc" | |
+ BIG_ENDIAN="yes" | |
+ ;; | |
+ PPC_853X|PPC_854X) | |
+ arch="powerpc" | |
+ BIG_ENDIAN="yes" | |
+ # let 853x use mp3float to decode mp3, to avoid Audio Station bug #1134 | |
+ extra_config="--disable-decoder=mp3" | |
+ ;; | |
+ MARVELL_ARMADA370|MARVELL_ARMADAXP|MARVELL_ARMADA375|MARVELL_ARMADA38X) | |
+ arch="armada" | |
+ ;; | |
+ ALPINE) | |
+ ALPINE_EXTRA_CFLAGS="-DSYNO_PLAT_NEON_LIBSWSCALE" | |
+ arch="arm" | |
+ ;; | |
+ REALTEK_RTD1296|MARVELL_ARMADA37XX) | |
+ arch="aarch64" | |
+ ;; | |
+ MINDSPEED_COMCERTO2K|BROADCOM_NORTHSTARPLUS|STM_MONACO|HISILICON_HI3535|HISILICON_HI3536) | |
+ arch="arm" | |
+ ;; | |
+ MARVELL_88F6281) | |
+ arch="arm" | |
+ ;; | |
+ TI_816X) | |
+ arch="arm" | |
+ ;; | |
+ *) | |
+ echo "This platform($BUILD_TARGET) is not supported yet. Error me!!" | |
+ return | |
+ ;; | |
+esac | |
+ | |
+COMMON_INC="" | |
+COMMON_LIB="" | |
+ | |
+COMMON_CONFIG=" | |
+ --arch=${arch} | |
+ --target-os=linux | |
+ --cross-prefix=${ToolChainPrefix} | |
+ --enable-cross-compile | |
+ --enable-optimizations | |
+ --enable-pic | |
+ --enable-shared | |
+ --disable-static | |
+ --enable-version3 | |
+ --enable-encoders | |
+ --enable-pthreads | |
+ --enable-libmp3lame | |
+ --enable-libsoxr | |
+ --disable-swscale-alpha | |
+ --disable-postproc | |
+ --disable-ffserver | |
+ --disable-ffplay | |
+ --disable-bzlib | |
+ --disable-altivec | |
+ --disable-decoder=amrnb | |
+ --disable-indev=alsa | |
+ --disable-outdev=alsa | |
+ --disable-encoder=zmbv | |
+ --disable-encoder=dca | |
+ --disable-encoder=ac3 | |
+ --disable-encoder=ac3_fixed | |
+ --disable-encoder=eac3 | |
+ --disable-decoder=dca | |
+ --disable-decoder=eac3 | |
+ --disable-decoder=truehd | |
+ --enable-avresample | |
+ --disable-doc | |
+ " | |
+ | |
+export EXPORT_BUILD_TARGET="${BUILD_TARGET}" | |
+ | |
+env CC=${CC} \ | |
+ CFLAGS="${CFLAGS} ${ALPINE_EXTRA_CFLAGS} -DSYNO_AUDIOSTATION" \ | |
+ CHECK_CFLAG="gnu99" \ | |
+ LDFLAGS="${LDFLAGS} \ | |
+ -Wl,-rpath,/var/packages/AudioStation/target/lib/ffmpeg \ | |
+ -Wl,-rpath,/var/packages/AudioStation/target/lib" \ | |
+ bigendian_platform="${BIG_ENDIAN}" \ | |
+ ${CONFIGURE} \ | |
+ ${COMMON_CONFIG} \ | |
+ ${extra_config} | |
+ | |
+make ${MAKE_FLAGS} | |
+# vim:ft=sh | |
diff --git a/SynoBuildConf/build-virtual-video-station b/SynoBuildConf/build-virtual-video-station | |
new file mode 100755 | |
index 0000000000..f1887fe92a | |
--- /dev/null | |
+++ b/SynoBuildConf/build-virtual-video-station | |
@@ -0,0 +1,165 @@ | |
+#!/bin/bash | |
+# Copyright (c) 2000-2013 Synology Inc. All rights reserved. | |
+ | |
+case ${MakeClean} in | |
+ [Yy][Ee][Ss]) | |
+ if [ -f config.mak ]; then | |
+ make distclean | |
+ fi | |
+ ;; | |
+esac | |
+ | |
+case ${CleanOnly} in | |
+ [Yy][Ee][Ss]) | |
+ return | |
+ ;; | |
+esac | |
+ | |
+CONFIGURE="./configure.syno" | |
+case "$BUILD_TARGET" in | |
+ X64|BROMOLOW|CEDARVIEW|EVANSPORT|AVOTON|DOCKERX64|BROMOLOWESM|BRASWELL|APOLLOLAKE|GRANTLEY|BROADWELL|KVMX64|DENVERTON|BROADWELLNK|PURLEY|COFFEELAKE) | |
+ arch="i686" | |
+ ;; | |
+ PPC_QORIQ|PPC_853X) | |
+ arch="powerpc" | |
+ BIG_ENDIAN="yes" | |
+ ;; | |
+ ALPINE) | |
+ arch="armv7" | |
+ ALPINE_EXTRA_CFLAGS="-DSYNO_PLAT_NEON_LIBSWSCALE -I${SysRootPrefix}/pkg/include" | |
+ ALPINE_EXTRA_LDFLAGS="-L${SysRootPrefix}/pkg/lib" | |
+ ;; | |
+ MARVELL_ARMADA370|MARVELL_ARMADA375|MARVELL_ARMADAXP|MARVELL_ARMADA38X|MINDSPEED_COMCERTO2K|BROADCOM_NORTHSTARPLUS|STM_MONACO|HISILICON_HI3535|HISILICON_HI3536) | |
+ arch="armv7" | |
+ ;; | |
+ REALTEK_RTD1296|MARVELL_ARMADA37XX) | |
+ arch="aarch64" | |
+ ;; | |
+ MARVELL_88F6281) | |
+ arch="arm" | |
+ ;; | |
+ *) | |
+ echo "This platform($BUILD_TARGET) is not supported yet." | |
+ return | |
+ ;; | |
+esac | |
+ | |
+STANDALONE="FALSE" | |
+ | |
+JSONC_INC=$(pkg-config --cflags json-c) | |
+JSONC_LIB=$(pkg-config --libs json-c) | |
+ | |
+if [ "TRUE" = "${STANDALONE}" ]; then | |
+ CUSTOM_CONFIG=" | |
+ --disable-shared | |
+ --enable-static | |
+ " | |
+ CUSTOM_CFLAGS="-DSTANDALONE" | |
+else | |
+ CUSTOM_CONFIG=" | |
+ --enable-shared | |
+ --disable-static | |
+ " | |
+ CUSTOM_CFLAGS="" | |
+fi | |
+ | |
+COMMON_RPATH="-Wl,-rpath=/var/packages/VideoStation/target/lib/ffmpeg -Wl,-rpath=/var/packages/VideoStation/target/lib" | |
+CFLAGS="${CFLAGS} ${CUSTOM_CFLAGS} -DSYNO_VIDEOSTATION" | |
+LDFLAGS="${LDFLAGS} ${COMMON_RPATH}" | |
+ | |
+COMMON_CONFIG=" | |
+ --prefix=/usr/pkg | |
+ --incdir=\${prefix}/include/ffmpeg | |
+ --arch=${arch} | |
+ --target-os=linux | |
+ --cross-prefix=${ToolChainPrefix} | |
+ --enable-cross-compile | |
+ --enable-optimizations | |
+ --enable-pic | |
+ --enable-gpl | |
+ --enable-version3 | |
+ --enable-nonfree | |
+ --enable-libfaac | |
+ --enable-encoders | |
+ --enable-pthreads | |
+ --disable-muxer=image2 --disable-muxer=image2pipe | |
+ --disable-swscale-alpha | |
+ --disable-ffplay | |
+ --disable-ffserver | |
+ --disable-doc | |
+ --disable-devices | |
+ --disable-bzlib | |
+ --disable-altivec | |
+ --enable-libopencore-amrnb | |
+ --enable-libopencore-amrwb | |
+ --enable-libmp3lame | |
+ --disable-decoder=amrnb | |
+ --disable-encoder=zmbv | |
+ --cc=${CC} | |
+ ${CUSTOM_CONFIG} | |
+ " | |
+ | |
+export EXPORT_BUILD_TARGET="${BUILD_TARGET}" | |
+ | |
+if [ "i686" = "${arch}" -a "EVANSPORT" = "${BUILD_TARGET}" ]; then | |
+ | |
+EVANSPORT_INC="-I${SysRootInclude}/intelce-utilities -I${SysRootInclude}/intelce-utilities/linux_user" | |
+EVANSPORT_LDFLAGS="-L${SysRootLib}/intelce-utilities" | |
+EVANSPORT_RPATH_LINK="-Wl,-rpath-link=${SysRootLib}/intelce-utilities" | |
+ | |
+# for evansport platform | |
+# add -DSYNO_EVANSPORT for header files in intelce-utilities | |
+ | |
+env CC=${CC} \ | |
+ CFLAGS="${CFLAGS} ${EVANSPORT_INC} ${JSONC_INC} -DSYNO_ENABLE_SMD -DSYNO_EVANSPORT" \ | |
+ LDFLAGS="${LDFLAGS} ${EVANSPORT_LDFLAGS} ${EVANSPORT_RPATH_LINK}" \ | |
+ CHECK_CFLAG="gnu99" \ | |
+ EVANSPORT_LIB="${EVANSPORT_RPATH_LINK}" \ | |
+ ${CONFIGURE} \ | |
+ ${COMMON_CONFIG} \ | |
+ --enable-yasm \ | |
+ --enable-libx264 \ | |
+ --enable-encoder=libx264 \ | |
+ --enable-libh264_smd \ | |
+ --enable-smd \ | |
+ --disable-filter=hqdn3d \ | |
+ --extra-libs="${JSONC_LIB} -lgdl -losal -lpal -lsven -lismd_core -lismd_audio -lismd_viddec -lismd_videnc -lismd_vidpproc -lplatform_config -lffmpeg_plugin" | |
+ | |
+elif [ "i686" = "${arch}" -o "ALPINE" = "${BUILD_TARGET}" ]; then | |
+env CC=${CC} \ | |
+ CFLAGS="${CFLAGS} ${ALPINE_EXTRA_CFLAGS}" \ | |
+ LDFLAGS="${LDFLAGS} ${ALPINE_EXTRA_LDFLAGS}" \ | |
+ ${CONFIGURE} \ | |
+ ${COMMON_CONFIG} \ | |
+ --enable-yasm \ | |
+ --enable-libx264 \ | |
+ --enable-encoder=libx264 | |
+ | |
+#support floating point platform with lame | |
+elif [ "powerpc" = "${arch}" -o "armv7" = "${arch}" -o "aarch64" = "${arch}" ]; then | |
+env CC=${CC} \ | |
+ CFLAGS="${CFLAGS}" \ | |
+ LDFLAGS="${LDFLAGS}" \ | |
+ bigendian_platform="${BIG_ENDIAN}" \ | |
+ ${CONFIGURE} \ | |
+ ${COMMON_CONFIG} \ | |
+ --enable-libfdk-aac | |
+ | |
+#only support fixed point platform with shine | |
+elif [ "arm" = "${arch}" ]; then | |
+env CC=${CC} \ | |
+ CFLAGS="${CFLAGS}" \ | |
+ LDFLAGS="${LDFLAGS}" \ | |
+ ${CONFIGURE} \ | |
+ ${COMMON_CONFIG} \ | |
+ --enable-libshine \ | |
+ --enable-libfdk-aac | |
+ | |
+else | |
+ echo "This platform($BUILD_TARGET) is not supported yet." | |
+ return | |
+fi | |
+ | |
+make ${MAKE_FLAGS} | |
+make tools/qt-faststart ${MAKE_FLAGS} | |
+# vim:ft=sh | |
diff --git a/SynoBuildConf/depends b/SynoBuildConf/depends | |
new file mode 100644 | |
index 0000000000..928b66dbc1 | |
--- /dev/null | |
+++ b/SynoBuildConf/depends | |
@@ -0,0 +1,10 @@ | |
+[BuildDependent-Tag] | |
+opencore-amr-0.1.2 | |
+xz-5.x | |
+intelce-utilities | |
+json-c-0.x | |
+zlib-1.x | |
+lame-3.99.x | |
+faac-1.28 | |
+x264 | |
+ | |
diff --git a/SynoBuildConf/depends-virtual-media-server b/SynoBuildConf/depends-virtual-media-server | |
new file mode 100755 | |
index 0000000000..b63acaefc5 | |
--- /dev/null | |
+++ b/SynoBuildConf/depends-virtual-media-server | |
@@ -0,0 +1,20 @@ | |
+[BuildDependent] | |
+libshine-3.0.x | |
+fdk-aac-0.1.x | |
+x264-virtual-media-server | |
+ | |
+[BuildDependent-Tag] | |
+opencore-amr-0.1.2 | |
+xz-5.x | |
+intelce-utilities | |
+json-c-0.x | |
+zlib-1.x | |
+lame-3.99.x | |
+faac-1.28 | |
+ | |
+[ReferenceOnly-Tag] | |
+ | |
+[ReferenceOnly] | |
+ | |
+[default] | |
+all="6.0" | |
diff --git a/SynoBuildConf/depends-virtual-mplayer2 b/SynoBuildConf/depends-virtual-mplayer2 | |
new file mode 100755 | |
index 0000000000..a050cea864 | |
--- /dev/null | |
+++ b/SynoBuildConf/depends-virtual-mplayer2 | |
@@ -0,0 +1,11 @@ | |
+[BuildDependent] | |
+soxr | |
+ | |
+[BuildDependent-Tag] | |
+ | |
+[ReferenceOnly-Tag] | |
+ | |
+[ReferenceOnly] | |
+ | |
+[default] | |
+all="6.0" | |
diff --git a/SynoBuildConf/depends-virtual-video-station b/SynoBuildConf/depends-virtual-video-station | |
new file mode 100755 | |
index 0000000000..6f40bd495f | |
--- /dev/null | |
+++ b/SynoBuildConf/depends-virtual-video-station | |
@@ -0,0 +1,20 @@ | |
+[BuildDependent] | |
+libshine-3.0.x | |
+fdk-aac-0.1.x | |
+x264-virtual-video-station | |
+ | |
+[BuildDependent-Tag] | |
+opencore-amr-0.1.2 | |
+xz-5.x | |
+intelce-utilities | |
+json-c-0.x | |
+zlib-1.x | |
+lame-3.99.x | |
+faac-1.28 | |
+ | |
+[ReferenceOnly-Tag] | |
+ | |
+[ReferenceOnly] | |
+ | |
+[default] | |
+all="6.0" | |
diff --git a/SynoBuildConf/error-virtual-media-server b/SynoBuildConf/error-virtual-media-server | |
new file mode 100644 | |
index 0000000000..3525a4713b | |
--- /dev/null | |
+++ b/SynoBuildConf/error-virtual-media-server | |
@@ -0,0 +1,3 @@ | |
+{ | |
+ "Error": ["OS_INFO"] | |
+} | |
diff --git a/SynoBuildConf/error-virtual-video-station b/SynoBuildConf/error-virtual-video-station | |
new file mode 100644 | |
index 0000000000..3525a4713b | |
--- /dev/null | |
+++ b/SynoBuildConf/error-virtual-video-station | |
@@ -0,0 +1,3 @@ | |
+{ | |
+ "Error": ["OS_INFO"] | |
+} | |
diff --git a/SynoBuildConf/install b/SynoBuildConf/install | |
new file mode 100644 | |
index 0000000000..c8761311cd | |
--- /dev/null | |
+++ b/SynoBuildConf/install | |
@@ -0,0 +1,31 @@ | |
+#!/bin/bash | |
+# Copyright (c) 2000-2015 Synology Inc. All rights reserved. | |
+ | |
+INSTALL_DIRS=" | |
+ /lib | |
+ /usr/bin | |
+" | |
+INSTALL_LIB=" | |
+ ./libavcodec/libavcodec.so.56 | |
+ ./libavdevice/libavdevice.so.56 | |
+ ./libavfilter/libavfilter.so.5 | |
+ ./libavformat/libavformat.so.56 | |
+ ./libavutil/libavutil.so.54 | |
+ ./libpostproc/libpostproc.so.53 | |
+ ./libswresample/libswresample.so.1 | |
+ ./libswscale/libswscale.so.3 | |
+" | |
+INSTALL_USR_BIN=" | |
+ ./tools/qt-faststart | |
+" | |
+DoInstall | |
+ | |
+# to avoid SynoInstall strip check lead to error | |
+# install ffmpeg_g when DEBUG | |
+if [ "x$NOSTRIP" != "xNOSTRIP" ]; then | |
+ InstallFiles "/usr/bin" 755 ffmpeg | |
+else | |
+ InstallFiles "/usr/bin" 755 ffmpeg_g | |
+fi | |
+ | |
+# vim:ft=sh | |
diff --git a/SynoBuildConf/install-dev b/SynoBuildConf/install-dev | |
new file mode 100644 | |
index 0000000000..45f4195424 | |
--- /dev/null | |
+++ b/SynoBuildConf/install-dev | |
@@ -0,0 +1,20 @@ | |
+#!/bin/bash | |
+# Copyright (c) 2000-2015 Synology Inc. All rights reserved. | |
+ | |
+case ${CleanOnly} in | |
+ [Yy][Ee][Ss]) | |
+ return | |
+ ;; | |
+esac | |
+ | |
+FFMEPG_INCLUDE="$DebDevDir$SynoIncludeDir/ffmpeg" | |
+[ -d $FFMEPG_INCLUDE ] || install -d $FFMEPG_INCLUDE | |
+install -m 644 synoconfig.h "$FFMEPG_INCLUDE" | |
+ | |
+make DESTDIR=$DebDevDir install | |
+ | |
+# Remove document | |
+rm -rf "$DebDevDir${SynoDir}/share" | |
+rm -rf "$DebDevDir${SynoDir}/bin" | |
+ | |
+# vim:ft=sh | |
diff --git a/SynoBuildConf/install-dev-virtual-media-server b/SynoBuildConf/install-dev-virtual-media-server | |
new file mode 100755 | |
index 0000000000..16bf3da105 | |
--- /dev/null | |
+++ b/SynoBuildConf/install-dev-virtual-media-server | |
@@ -0,0 +1,20 @@ | |
+#!/bin/bash | |
+# Copyright (c) 2000-2013 Synology Inc. All rights reserved. | |
+ | |
+case ${CleanOnly} in | |
+ [Yy][Ee][Ss]) | |
+ return | |
+ ;; | |
+esac | |
+ | |
+SynoPkgDir="/usr/pkg" | |
+FFMEPG_INCLUDE="$DebDevDir$SynoPkgDir/include/ffmpeg" | |
+[ -d $FFMEPG_INCLUDE ] || install -d $FFMEPG_INCLUDE | |
+install -m 644 synoconfig.h "$FFMEPG_INCLUDE" | |
+ | |
+make DESTDIR=$DebDevDir install | |
+# Remove document | |
+rm -rf "$DebDevDir${SynoPkgDir}/share" | |
+rm -rf "$DebDevDir${SynoPkgDir}/bin" | |
+ | |
+# vim:ft=sh | |
diff --git a/SynoBuildConf/install-dev-virtual-video-station b/SynoBuildConf/install-dev-virtual-video-station | |
new file mode 100755 | |
index 0000000000..16bf3da105 | |
--- /dev/null | |
+++ b/SynoBuildConf/install-dev-virtual-video-station | |
@@ -0,0 +1,20 @@ | |
+#!/bin/bash | |
+# Copyright (c) 2000-2013 Synology Inc. All rights reserved. | |
+ | |
+case ${CleanOnly} in | |
+ [Yy][Ee][Ss]) | |
+ return | |
+ ;; | |
+esac | |
+ | |
+SynoPkgDir="/usr/pkg" | |
+FFMEPG_INCLUDE="$DebDevDir$SynoPkgDir/include/ffmpeg" | |
+[ -d $FFMEPG_INCLUDE ] || install -d $FFMEPG_INCLUDE | |
+install -m 644 synoconfig.h "$FFMEPG_INCLUDE" | |
+ | |
+make DESTDIR=$DebDevDir install | |
+# Remove document | |
+rm -rf "$DebDevDir${SynoPkgDir}/share" | |
+rm -rf "$DebDevDir${SynoPkgDir}/bin" | |
+ | |
+# vim:ft=sh | |
diff --git a/SynoBuildConf/install-virtual-media-server b/SynoBuildConf/install-virtual-media-server | |
new file mode 100755 | |
index 0000000000..7ef6aec144 | |
--- /dev/null | |
+++ b/SynoBuildConf/install-virtual-media-server | |
@@ -0,0 +1,50 @@ | |
+#!/bin/bash | |
+# Copyright (c) 2000-2012 Synology Inc. All rights reserved. | |
+libshine="libshine-3.0.x" | |
+libfdkaac="fdk-aac-0.1.x" | |
+ | |
+case "$BUILD_TARGET" in | |
+ X64|BROMOLOW|CEDARVIEW|EVANSPORT|AVOTON|DOCKERX64|GRANTLEY|BRASWELL|APOLLOLAKE|BROADWELL|KVMX64|ALPINE|DENVERTON|BROADWELLNK|PURLEY|COFFEELAKE) | |
+ IncludeProjects="" | |
+ ;; | |
+ PPC_853X|PPC_QORIQ| \ | |
+ MARVELL_88F6281|MARVELL_ARMADAXP|MARVELL_ARMADA370|MARVELL_ARMADA375|MARVELL_ARMADA38X|REALTEK_RTD1296|\ | |
+ MINDSPEED_COMCERTO2K|BROADCOM_NORTHSTARPLUS|STM_MONACO|HISILICON_HI3536|MARVELL_ARMADA37XX) | |
+ IncludeProjects="${libshine} ${libfdkaac}" | |
+ ;; | |
+ *) | |
+ echo "This platform($BUILD_TARGET) is not supported yet." | |
+ exit 1 | |
+ ;; | |
+esac | |
+ | |
+# install related projects | |
+for prj in $IncludeProjects; do | |
+ env INST_DIR="$INST_DIR" \ | |
+ $ScriptsDir/SynoInstall --single ${prj} | |
+done | |
+ | |
+# install ffmpeg project | |
+InstallPreparePkgDir $INST_DIR "lib/ffmpeg" | |
+InstallPreparePkgDir $INST_DIR "bin" | |
+ | |
+LibList=( | |
+ libavcodec/libavcodec.so.56 | |
+ libavdevice/libavdevice.so.56 | |
+ libavfilter/libavfilter.so.5 | |
+ libavformat/libavformat.so.56 | |
+ libavutil/libavutil.so.54 | |
+ libpostproc/libpostproc.so.53 | |
+ libswresample/libswresample.so.1 | |
+ libswscale/libswscale.so.3 | |
+ ) | |
+ | |
+LibNum=${#LibList[@]} | |
+ | |
+for (( i=0 ; i < $LibNum ; i++ )) | |
+do | |
+ echo "install ${LibList[$i]}" | |
+ InstallPkgFiles $INST_DIR "lib/ffmpeg" 644 ${LibList[$i]} | |
+done | |
+ | |
+InstallPkgFiles $INST_DIR "bin" 755 "ffmpeg ffserver ffprobe" | |
diff --git a/SynoBuildConf/install-virtual-mplayer2 b/SynoBuildConf/install-virtual-mplayer2 | |
new file mode 100755 | |
index 0000000000..5e984171af | |
--- /dev/null | |
+++ b/SynoBuildConf/install-virtual-mplayer2 | |
@@ -0,0 +1,30 @@ | |
+#!/bin/bash | |
+# Copyright (c) 2000-2012 Synology Inc. All rights reserved. | |
+ | |
+INST_DIR="/tmp/_audiostation" | |
+ | |
+InstallPreparePkgDir $INST_DIR "lib/ffmpeg" | |
+InstallPreparePkgDir $INST_DIR "bin" | |
+ | |
+LibList=( | |
+ libavcodec/libavcodec.so.56 | |
+ libavdevice/libavdevice.so.56 | |
+ libavfilter/libavfilter.so.5 | |
+ libavformat/libavformat.so.56 | |
+ libavutil/libavutil.so.54 | |
+ libswresample/libswresample.so.1 | |
+ libswscale/libswscale.so.3 | |
+ libavresample/libavresample.so.2 | |
+ ) | |
+ | |
+LibNum=${#LibList[@]} | |
+ | |
+for (( i=0 ; i < $LibNum ; i++ )) | |
+do | |
+echo "install ${LibList[$i]}" | |
+InstallPkgFiles $INST_DIR "lib/ffmpeg" 644 ${LibList[$i]} | |
+done | |
+ | |
+InstallPkgFiles $INST_DIR "bin" 755 "ffmpeg" | |
+ | |
+DoInstall | |
diff --git a/SynoBuildConf/install-virtual-video-station b/SynoBuildConf/install-virtual-video-station | |
new file mode 100755 | |
index 0000000000..aa753c4f02 | |
--- /dev/null | |
+++ b/SynoBuildConf/install-virtual-video-station | |
@@ -0,0 +1,50 @@ | |
+#!/bin/bash | |
+# Copyright (c) 2000-2012 Synology Inc. All rights reserved. | |
+libshine="libshine-3.0.x" | |
+libfdkaac="fdk-aac-0.1.x" | |
+ | |
+case "$BUILD_TARGET" in | |
+ X64|BROMOLOW|CEDARVIEW|EVANSPORT|AVOTON|DOCKERX64|GRANTLEY|BRASWELL|APOLLOLAKE|BROADWELL|KVMX64|ALPINE|DENVERTON|BROADWELLNK|PURLEY|COFFEELAKE) | |
+ IncludeProjects="" | |
+ ;; | |
+ PPC_853X|PPC_QORIQ| \ | |
+ MARVELL_88F6281|MARVELL_ARMADAXP|MARVELL_ARMADA370|MARVELL_ARMADA375|MARVELL_ARMADA38X|REALTEK_RTD1296|\ | |
+ MINDSPEED_COMCERTO2K|BROADCOM_NORTHSTARPLUS|STM_MONACO|HISILICON_HI3536|MARVELL_ARMADA37XX) | |
+ IncludeProjects="${libshine} ${libfdkaac}" | |
+ ;; | |
+ *) | |
+ echo "This platform($BUILD_TARGET) is not supported yet." | |
+ exit 1 | |
+ ;; | |
+esac | |
+ | |
+# install related projects | |
+for prj in $IncludeProjects; do | |
+ env INST_DIR="$INST_DIR" \ | |
+ $ScriptsDir/SynoInstall --single ${prj} | |
+done | |
+ | |
+# install ffmpeg project | |
+InstallPreparePkgDir $INST_DIR "lib/ffmpeg" | |
+InstallPreparePkgDir $INST_DIR "bin" | |
+ | |
+LibList=( | |
+ libavcodec/libavcodec.so.56 | |
+ libavdevice/libavdevice.so.56 | |
+ libavfilter/libavfilter.so.5 | |
+ libavformat/libavformat.so.56 | |
+ libavutil/libavutil.so.54 | |
+ libpostproc/libpostproc.so.53 | |
+ libswresample/libswresample.so.1 | |
+ libswscale/libswscale.so.3 | |
+ ) | |
+ | |
+LibNum=${#LibList[@]} | |
+ | |
+for (( i=0 ; i < $LibNum ; i++ )) | |
+do | |
+ echo "install ${LibList[$i]}" | |
+ InstallPkgFiles $INST_DIR "lib/ffmpeg" 644 ${LibList[$i]} | |
+done | |
+ | |
+InstallPkgFiles $INST_DIR "bin" 755 "ffmpeg ffprobe" | |
diff --git a/VERSION b/VERSION | |
new file mode 100644 | |
index 0000000000..860487ca19 | |
--- /dev/null | |
+++ b/VERSION | |
@@ -0,0 +1 @@ | |
+2.7.1 | |
diff --git a/configure b/configure | |
index 3960b735c1..0a4efb8a8e 100755 | |
--- a/configure | |
+++ b/configure | |
@@ -281,6 +281,7 @@ External library support: | |
--enable-x11grab enable X11 grabbing (legacy) [no] | |
--disable-xlib disable xlib [autodetect] | |
--disable-zlib disable zlib [autodetect] | |
+ --enable-smd enable hardware decoding[disables software decoding] | |
Toolchain options: | |
--arch=ARCH select architecture [$arch] | |
@@ -419,7 +420,7 @@ log(){ | |
log_file(){ | |
log BEGIN $1 | |
- pr -n -t $1 >> $logfile | |
+# pr -n -t $1 >> $logfile | |
log END $1 | |
} | |
@@ -1412,6 +1413,7 @@ EXTERNAL_LIBRARY_LIST=" | |
libwavpack | |
libwebp | |
libx264 | |
+ libh264_smd | |
libx265 | |
libxavs | |
libxcb | |
@@ -1433,6 +1435,7 @@ EXTERNAL_LIBRARY_LIST=" | |
x11grab | |
xlib | |
zlib | |
+ smd | |
" | |
DOCUMENT_LIST=" | |
@@ -2476,6 +2479,7 @@ libwavpack_encoder_deps="libwavpack" | |
libwebp_encoder_deps="libwebp" | |
libwebp_anim_encoder_deps="libwebp" | |
libx264_encoder_deps="libx264" | |
+libh264_smd_encoder_deps="libh264_smd" | |
libx264rgb_encoder_deps="libx264" | |
libx264rgb_encoder_select="libx264_encoder" | |
libx265_encoder_deps="libx265" | |
@@ -2965,7 +2969,7 @@ print_3_columns() { | |
show_list() { | |
suffix=_$1 | |
shift | |
- echo $* | sed s/$suffix//g | print_3_columns | |
+# echo $* | sed s/$suffix//g | print_3_columns | |
exit 0 | |
} | |
@@ -3549,14 +3553,14 @@ probe_cc(){ | |
_type=pathscale | |
_ident=$($_cc -v 2>&1 | head -n1 | tr -d :) | |
_depflags='-MMD -MF $(@:.o=.d) -MT $@' | |
- _cflags_speed='-O2' | |
+ _cflags_speed='-O3' | |
_cflags_size='-Os' | |
_flags_filter='filter_out -Wdisabled-optimization' | |
elif $_cc -v 2>&1 | grep -q Open64; then | |
_type=open64 | |
_ident=$($_cc -v 2>&1 | head -n1 | tr -d :) | |
_depflags='-MMD -MF $(@:.o=.d) -MT $@' | |
- _cflags_speed='-O2' | |
+ _cflags_speed='-O3' | |
_cflags_size='-Os' | |
_flags_filter='filter_out -Wdisabled-optimization|-Wtype-limits|-fno-signed-zeros' | |
elif $_cc -V 2>&1 | grep -q Portland; then | |
@@ -4096,7 +4100,13 @@ fi | |
add_cppflags -D_ISOC99_SOURCE | |
add_cxxflags -D__STDC_CONSTANT_MACROS | |
-check_cflags -std=c99 | |
+ | |
+if [ "${CHECK_CFLAG}" = gnu99 ]; then | |
+ check_cflags -std=gnu99 | |
+else | |
+ check_cflags -std=c99 | |
+fi | |
+ | |
check_cc -D_FILE_OFFSET_BITS=64 <<EOF && add_cppflags -D_FILE_OFFSET_BITS=64 | |
#include <stdlib.h> | |
EOF | |
@@ -4605,7 +4615,9 @@ EOF | |
check_cc <<EOF || die "endian test failed" | |
unsigned int endian = 'B' << 24 | 'I' << 16 | 'G' << 8 | 'E'; | |
EOF | |
-od -t x1 $TMPO | grep -q '42 *49 *47 *45' && enable bigendian | |
+if [ "yes" = "$bigendian_platform" ]; then | |
+ enable bigendian | |
+fi | |
if ! enabled ppc64 || enabled bigendian; then | |
disable vsx | |
@@ -5122,7 +5134,7 @@ enabled libpulse && require_pkg_config libpulse pulse/pulseaudio.h pa_c | |
enabled libquvi && require_pkg_config libquvi quvi/quvi.h quvi_init | |
enabled librtmp && require_pkg_config librtmp librtmp/rtmp.h RTMP_Socket | |
enabled libschroedinger && require_pkg_config schroedinger-1.0 schroedinger/schro.h schro_init | |
-enabled libshine && require_pkg_config shine shine/layer3.h shine_encode_buffer | |
+enabled libshine && require shine shine/layer3.h shine_encode_buffer -lm -lshine | |
enabled libsmbclient && { use_pkg_config smbclient libsmbclient.h smbc_init || | |
require smbclient libsmbclient.h smbc_init -lsmbclient; } | |
enabled libsoxr && require libsoxr soxr.h soxr_create -lsoxr | |
@@ -5152,6 +5164,7 @@ enabled libwavpack && require libwavpack wavpack/wavpack.h WavpackOpenFil | |
enabled libwebp && { | |
enabled libwebp_encoder && require_pkg_config "libwebp >= 0.2.0" webp/encode.h WebPGetEncoderVersion | |
enabled libwebp_anim_encoder && { use_pkg_config "libwebpmux >= 0.4.0" webp/mux.h WebPAnimEncoderOptionsInit || disable libwebp_anim_encoder; } } | |
+enabled libh264_smd && require libffmpeg_plugin libffmpeg_plugin/ismd_ffmpeg_video_enc.h ismd_ffmpeg_video_encoder_dequeue -lffmpeg_plugin | |
enabled libx264 && { use_pkg_config x264 "stdint.h x264.h" x264_encoder_encode || | |
{ require libx264 x264.h x264_encoder_encode -lx264 && | |
warn "using libx264 without pkg-config"; } } && | |
@@ -5512,7 +5525,7 @@ elif enabled gcc; then | |
check_cflags -Werror=implicit-function-declaration | |
check_cflags -Werror=missing-prototypes | |
check_cflags -Werror=return-type | |
- check_cflags -Werror=vla | |
+# check_cflags -Werror=vla | |
check_cflags -Wformat | |
check_cflags -fdiagnostics-color=auto | |
enabled extra_warnings || check_disable_warning -Wno-maybe-uninitialized | |
@@ -5779,7 +5792,7 @@ echo | |
for type in decoder encoder hwaccel parser demuxer muxer protocol filter bsf indev outdev; do | |
echo "Enabled ${type}s:" | |
eval list=\$$(toupper $type)_LIST | |
- print_enabled '_*' $list | print_3_columns | |
+# print_enabled '_*' $list | print_3_columns | |
echo | |
done | |
@@ -6041,7 +6054,7 @@ Version: $version | |
Requires: $(enabled shared || echo $requires) | |
Requires.private: $(enabled shared && echo $requires) | |
Conflicts: | |
-Libs: -L\${libdir} $(enabled rpath && echo "-Wl,-rpath,\${libdir}") -l${shortname} $(enabled shared || echo $libs) | |
+Libs: -L\${libdir} ${EVANSPORT_LIB} $(enabled rpath && echo "-Wl,-rpath,\${libdir}") -l${shortname} $(enabled shared || echo $libs) | |
Libs.private: $(enabled shared && echo $libs) | |
Cflags: -I\${includedir} | |
EOF | |
diff --git a/ffmpeg.c b/ffmpeg.c | |
index f5029987ad..46ea2358dd 100644 | |
--- a/ffmpeg.c | |
+++ b/ffmpeg.c | |
@@ -104,6 +104,87 @@ | |
#include "libavutil/avassert.h" | |
+#include "synoconfig.h" | |
+ | |
+#ifdef SYNO_EVANSPORT_SMD | |
+//smd headers | |
+#include "osal_type.h" | |
+#include "ismd_vidpproc.h" | |
+#include "libffmpeg_plugin/ismd_ffmpeg_util.h" | |
+#include "libffmpeg_plugin/ismd_ffmpeg_video_dec.h" | |
+#include "libffmpeg_plugin/ismd_ffmpeg_video_enc.h" | |
+#include "libffmpeg_plugin/ismd_ffmpeg_bitstream.h" | |
+ | |
+#include "libavcodec/ismd_ffmpeg_audio_util.h" | |
+#include "libavformat/avformat.h" | |
+#include "libavcodec/h264_smd.h" | |
+#include "libavcodec/vc1.h" | |
+#include "libavcodec/avcodec.h" | |
+#include "libavcodec/syno_trans_loading.h" | |
+#if CONFIG_LIBX264_ENCODER | |
+#include <x264.h> | |
+#endif | |
+ | |
+typedef struct X264Context { | |
+ AVClass *class; | |
+#if CONFIG_LIBX264_ENCODER | |
+ x264_param_t params; | |
+ x264_t *enc; | |
+ x264_picture_t pic; | |
+#endif | |
+ uint8_t *sei; | |
+ int sei_size; | |
+ char *preset; | |
+ char *tune; | |
+ char *profile; | |
+ char *level; | |
+ int fastfirstpass; | |
+ char *wpredp; | |
+ char *x264opts; | |
+ float crf; | |
+ float crf_max; | |
+ int cqp; | |
+ int aq_mode; | |
+ float aq_strength; | |
+ char *psy_rd; | |
+ int psy; | |
+ int rc_lookahead; | |
+ int weightp; | |
+ int weightb; | |
+ int ssim; | |
+ int intra_refresh; | |
+ int bluray_compat; | |
+ int b_bias; | |
+ int b_pyramid; | |
+ int mixed_refs; | |
+ int dct8x8; | |
+ int fast_pskip; | |
+ int aud; | |
+ int mbtree; | |
+ char *deblock; | |
+ float cplxblur; | |
+ char *partitions; | |
+ int direct_pred; | |
+ int slice_max_size; | |
+ char *stats; | |
+ int nal_hrd; | |
+ int avcintra_class; | |
+ char *x264_params; | |
+#ifdef SYNO_EVANSPORT_FLV_EXTRADATA | |
+ bool dont_free_extradata; | |
+#endif | |
+} X264Context; | |
+ | |
+static viddec_struct_t vid_dec; | |
+static videnc_struct_t vid_enc; | |
+bool smd_video_pipeline = false; | |
+int smd_frame_rate; | |
+static ismd_codec_type_t get_smd_codec_id(enum AVCodecID ffmpeg_codec_id); | |
+bool first_read_pts = true; | |
+int64_t last_pts = -1; | |
+//smd end | |
+#endif | |
+ | |
const char program_name[] = "ffmpeg"; | |
const int program_birth_year = 2000; | |
@@ -426,12 +507,27 @@ const AVIOInterruptCB int_cb = { decode_interrupt_cb, NULL }; | |
static void ffmpeg_cleanup(int ret) | |
{ | |
int i, j; | |
+#ifdef SYNO_EVANSPORT_SMD | |
+ ismd_result_t ret_val = ISMD_ERROR_UNSPECIFIED; | |
+#endif | |
if (do_benchmark) { | |
int maxrss = getmaxrss() / 1024; | |
printf("bench: maxrss=%ikB\n", maxrss); | |
} | |
+#ifdef SYNO_EVANSPORT_SMD | |
+ /**************** smd code *******************/ | |
+ synoRemovePID(getpid()); | |
+ if(smd_video_pipeline) | |
+ { | |
+ ret_val = ismd_ffmpeg_free_vid_enc_res(&vid_enc); | |
+ if(ret_val != ISMD_SUCCESS) | |
+ av_log(NULL,AV_LOG_ERROR,"could not free video encoder resources\n"); | |
+ } | |
+ /**************** smd code end*******************/ | |
+#endif | |
+ | |
for (i = 0; i < nb_filtergraphs; i++) { | |
FilterGraph *fg = filtergraphs[i]; | |
avfilter_graph_free(&fg->graph); | |
@@ -1018,6 +1114,12 @@ static void do_video_out(AVFormatContext *s, | |
} | |
ost->last_droped = nb_frames == nb0_frames && next_picture; | |
+#ifdef SYNO_EVANSPORT_SMD | |
+ if (smd_video_pipeline) { | |
+ nb_frames = 1; | |
+ } | |
+#endif | |
+ | |
/* duplicates frame if needed */ | |
for (i = 0; i < nb_frames; i++) { | |
AVFrame *in_picture; | |
@@ -1061,6 +1163,10 @@ static void do_video_out(AVFormatContext *s, | |
int got_packet, forced_keyframe = 0; | |
double pts_time; | |
+#ifdef SYNO_EVANSPORT_SMD | |
+ if(!smd_video_pipeline) | |
+ { | |
+#endif | |
if (enc->flags & (CODEC_FLAG_INTERLACED_DCT|CODEC_FLAG_INTERLACED_ME) && | |
ost->top_field_first >= 0) | |
in_picture->top_field_first = !!ost->top_field_first; | |
@@ -1127,6 +1233,123 @@ static void do_video_out(AVFormatContext *s, | |
ret = avcodec_encode_video2(enc, &pkt, in_picture, &got_packet); | |
update_benchmark("encode_video %d.%d", ost->file_index, ost->index); | |
+ | |
+#ifdef SYNO_EVANSPORT_SMD | |
+ } else { | |
+ unsigned long fps_num; | |
+ unsigned long fps_den; | |
+ unsigned long macroblock_per_sec; | |
+ unsigned long max_macroblock_per_sec; | |
+ char* level; | |
+ bool override; | |
+ double temp_num; | |
+ int pkt_size; | |
+ X264Context *x4 = enc->priv_data; | |
+ smd_h264_picture_t pic_out; | |
+ got_packet = 0; | |
+ ret = 0; | |
+ | |
+ if ((pkt_size = syno_ismd_ffmpeg_video_encoder_get_first_node_size(&vid_enc)) < 0) { | |
+ av_log(NULL, AV_LOG_FATAL, "ismd_ffmpeg_video_encoder_dequeue_size_syno\n"); | |
+ exit_program(1); | |
+ } | |
+ if (pkt_size > 0) { | |
+ if (syno_alloc_packet(&pkt, pkt_size) < 0) { | |
+ av_log(NULL, AV_LOG_FATAL, "syno_alloc_packet error at encoder SMD\n"); | |
+ exit_program(1); | |
+ } | |
+ ret = ismd_ffmpeg_video_encoder_dequeue(pkt.data, &pic_out,&vid_enc); | |
+ if (ret != pkt_size) { | |
+ av_log(NULL, AV_LOG_FATAL, "ismd_ffmpeg_video_encoder_dequeue size not conform\n"); | |
+ } | |
+ memset(pkt.data + pkt.size, 0, FF_INPUT_BUFFER_PADDING_SIZE); | |
+ } | |
+ | |
+ if(ret > 0) | |
+ { | |
+ if (enable_dtv_smd) { | |
+ enc->coded_frame->pts = av_rescale_q(pic_out.i_pts, AV_TIME_BASE_Q, enc->time_base); | |
+ if (AV_NOPTS_VALUE != enc->coded_frame->pts) { | |
+ pkt.pts= enc->coded_frame->pts; | |
+ } | |
+ } else { | |
+ //TODO call just once | |
+ ismd_result_t ret_smd = ismd_viddec_get_frame_rate(vid_dec.viddec_handle, &fps_num, &fps_den, &override); | |
+ if (ret_smd == ISMD_SUCCESS) | |
+ { | |
+ temp_num = 90000/(double)fps_num; | |
+ smd_frame_rate = temp_num*fps_den;//smd clock resuolution is 90000 ticks | |
+ macroblock_per_sec = ((enc->width*enc->height)/256) *(fps_num/fps_den); | |
+ if(!x4->level) | |
+ level = "4.1"; | |
+ else | |
+ level = x4->level; | |
+ max_macroblock_per_sec = ismd_ffmpeg_max_macroblock(level); | |
+ if(macroblock_per_sec > max_macroblock_per_sec) | |
+ { | |
+ av_log(enc,AV_LOG_INFO,"macroblocks_per_sec requested %ld\n",macroblock_per_sec); | |
+ av_log(enc,AV_LOG_INFO,"max macroblocks_per_sec suppored for level %s are %ld\n",level,max_macroblock_per_sec); | |
+ av_log(enc,AV_LOG_INFO,"please try transcoding to lower resolution\n"); | |
+ exit_program(1); | |
+ } | |
+ } | |
+ | |
+ enc->coded_frame->pts = pic_out.i_pts/smd_frame_rate; | |
+ if (AV_NOPTS_VALUE != enc->coded_frame->pts) { | |
+ pkt.pts= enc->coded_frame->pts; | |
+ if (ist) { | |
+ pkt.pts += av_rescale_q(input_files[ist->file_index]->first_pts, AV_TIME_BASE_Q, enc->time_base); | |
+ } | |
+ } | |
+ } | |
+ | |
+ switch (pic_out.i_type) | |
+ { | |
+ case SLICE_P: | |
+ av_log(NULL,AV_LOG_DEBUG,"\n********returning pict type AV_PICTURE_TYPE_P\n"); | |
+ enc->coded_frame->pict_type = AV_PICTURE_TYPE_P; | |
+ break; | |
+ case SLICE_B: | |
+ av_log(NULL,AV_LOG_DEBUG,"\n********returning pict type AV_PICTURE_TYPE_B\n"); | |
+ enc->coded_frame->pict_type = AV_PICTURE_TYPE_B; | |
+ break; | |
+ case SLICE_I: | |
+ av_log(NULL,AV_LOG_DEBUG,"\n********returning pict type AV_PICTURE_TYPE_I\n"); | |
+ enc->coded_frame->pict_type = AV_PICTURE_TYPE_I; | |
+ break; | |
+ default: | |
+ enc->coded_frame->pict_type = AV_PICTURE_TYPE_NONE; | |
+ av_log(NULL,AV_LOG_DEBUG,"\n********ERROR invalid picture type ************\n"); | |
+ | |
+ } | |
+ enc->coded_frame->key_frame = pic_out.b_keyframe; | |
+ if (pic_out.b_keyframe) { | |
+ pkt.flags |= AV_PKT_FLAG_KEY; | |
+ } | |
+ if (enable_dtv_smd) { | |
+ // enable dtv_smd flag, every frame is carryed the same timestamp from input file | |
+ // on hardware pipeline mode. But we encounter problem of non monotonically increasing | |
+ // timestamp. min_heap is reorder frame and filter some abnormal frame. | |
+ ret = syno_smd_push_heap(&pkt); | |
+ if (ret < 0) { | |
+ av_log(NULL, AV_LOG_FATAL, "syno_smd_push_heap failed\n"); | |
+ exit_program(1); | |
+ } | |
+ if (0 == syno_smd_get_heap(&pkt, 0)) { | |
+ if (last_pts >= pkt.pts) { | |
+ av_free_packet(&pkt); | |
+ } else { | |
+ last_pts = pkt.pts; | |
+ got_packet = 1; | |
+ } | |
+ } | |
+ } else { | |
+ got_packet = 1; | |
+ } | |
+ } | |
+ } | |
+#endif | |
+ | |
if (ret < 0) { | |
av_log(NULL, AV_LOG_FATAL, "Video encoding failed\n"); | |
exit_program(1); | |
@@ -1631,6 +1854,9 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti | |
static void flush_encoders(void) | |
{ | |
int i, ret; | |
+#ifdef SYNO_EVANSPORT_SMD | |
+ InputStream *ist = NULL; | |
+#endif | |
for (i = 0; i < nb_output_streams; i++) { | |
OutputStream *ost = output_streams[i]; | |
@@ -1656,6 +1882,9 @@ static void flush_encoders(void) | |
desc = "Audio"; | |
break; | |
case AVMEDIA_TYPE_VIDEO: | |
+#ifdef SYNO_EVANSPORT_SMD | |
+ usleep(1000); | |
+#endif | |
encode = avcodec_encode_video2; | |
desc = "Video"; | |
break; | |
@@ -1671,9 +1900,111 @@ static void flush_encoders(void) | |
pkt.data = NULL; | |
pkt.size = 0; | |
+#ifdef SYNO_EVANSPORT_SMD | |
+ if (!smd_video_pipeline || AVMEDIA_TYPE_VIDEO != ost->st->codec->codec_type ) { | |
+#endif | |
update_benchmark(NULL); | |
ret = encode(enc, &pkt, NULL, &got_packet); | |
update_benchmark("flush %s %d.%d", desc, ost->file_index, ost->index); | |
+#ifdef SYNO_EVANSPORT_SMD | |
+ } else { | |
+ unsigned long fps_num; | |
+ unsigned long fps_den; | |
+ bool override; | |
+ double temp_num; | |
+ int pkt_size; | |
+ smd_h264_picture_t pic_out; | |
+ ret = 0; | |
+ | |
+ if ((pkt_size = syno_ismd_ffmpeg_video_encoder_get_first_node_size(&vid_enc)) < 0) { | |
+ av_log(NULL, AV_LOG_FATAL, "ismd_ffmpeg_video_encoder_dequeue_size_syno\n"); | |
+ exit_program(1); | |
+ } | |
+ if (pkt_size > 0) { | |
+ if (syno_alloc_packet(&pkt, pkt_size) < 0) { | |
+ av_log(NULL, AV_LOG_FATAL, "syno_alloc_packet error at encoder SMD\n"); | |
+ exit_program(1); | |
+ } | |
+ ret = ismd_ffmpeg_video_encoder_dequeue(pkt.data, &pic_out,&vid_enc); | |
+ if (ret != pkt_size) { | |
+ av_log(NULL, AV_LOG_FATAL, "ismd_ffmpeg_video_encoder_dequeue size not conform\n"); | |
+ } | |
+ memset(pkt.data + pkt.size, 0, FF_INPUT_BUFFER_PADDING_SIZE); | |
+ } | |
+ | |
+ if(ret > 0) | |
+ { | |
+ if (enable_dtv_smd) { | |
+ enc->coded_frame->pts = av_rescale_q(pic_out.i_pts, AV_TIME_BASE_Q, enc->time_base); | |
+ if (AV_NOPTS_VALUE != enc->coded_frame->pts) { | |
+ pkt.pts= enc->coded_frame->pts; | |
+ } | |
+ } else { | |
+ //TODO call just once | |
+ ismd_result_t ret_smd = ismd_viddec_get_frame_rate(vid_dec.viddec_handle, &fps_num, &fps_den, &override);//this actually returns fps | |
+ if (ret_smd == ISMD_SUCCESS) | |
+ { | |
+ temp_num = 90000/(double)fps_num; | |
+ smd_frame_rate = temp_num*fps_den;//smd clock resuolution is 90000 ticks | |
+ } | |
+ av_log(NULL,AV_LOG_DEBUG,"\n********pts from encoder %lld\n",pic_out.i_pts); | |
+ | |
+ enc->coded_frame->pts = pic_out.i_pts/smd_frame_rate; | |
+ if (AV_NOPTS_VALUE != enc->coded_frame->pts) { | |
+ pkt.pts= enc->coded_frame->pts; | |
+ if (ost->source_index >= 0) | |
+ ist = input_streams[ost->source_index]; | |
+ if (ist) { | |
+ pkt.pts += av_rescale_q(input_files[ist->file_index]->first_pts, AV_TIME_BASE_Q, enc->time_base); | |
+ } | |
+ } | |
+ } | |
+ | |
+ switch (pic_out.i_type) | |
+ { | |
+ case SLICE_P: | |
+ av_log(NULL,AV_LOG_DEBUG,"\n*******returning pict type AV_PICTURE_TYPE_P\n"); | |
+ enc->coded_frame->pict_type = AV_PICTURE_TYPE_P; | |
+ break; | |
+ case SLICE_B: | |
+ av_log(NULL,AV_LOG_DEBUG,"\n*****returning pict type AV_PICTURE_TYPE_B\n"); | |
+ enc->coded_frame->pict_type = AV_PICTURE_TYPE_B; | |
+ break; | |
+ case SLICE_I: | |
+ av_log(NULL,AV_LOG_DEBUG,"\n******returning pict type AV_PICTURE_TYPE_I\n"); | |
+ enc->coded_frame->pict_type = AV_PICTURE_TYPE_I; | |
+ break; | |
+ default: | |
+ enc->coded_frame->pict_type = AV_PICTURE_TYPE_NONE; | |
+ av_log(NULL,AV_LOG_DEBUG,"\n*****ERROR invalid picture type ************\n"); | |
+ | |
+ } | |
+ enc->coded_frame->key_frame = pic_out.b_keyframe; | |
+ if (pic_out.b_keyframe) { | |
+ pkt.flags |= AV_PKT_FLAG_KEY; | |
+ } | |
+ | |
+ if (enable_dtv_smd) { | |
+ //TODO we should care about flush heap buffer | |
+ ret = syno_smd_push_heap(&pkt); | |
+ if (ret < 0) { | |
+ av_log(NULL, AV_LOG_FATAL, "syno_smd_push_heap failed\n"); | |
+ exit_program(1); | |
+ } | |
+ if (0 == syno_smd_get_heap(&pkt, 1)) { | |
+ if (last_pts >= pkt.pts) { | |
+ av_free_packet(&pkt); | |
+ } else { | |
+ last_pts = pkt.pts; | |
+ got_packet = 1; | |
+ } | |
+ } | |
+ } else { | |
+ got_packet = 1; | |
+ } | |
+ } | |
+ } | |
+#endif | |
if (ret < 0) { | |
av_log(NULL, AV_LOG_FATAL, "%s encoding failed\n", desc); | |
exit_program(1); | |
@@ -1681,6 +2012,9 @@ static void flush_encoders(void) | |
if (ost->logfile && enc->stats_out) { | |
fprintf(ost->logfile, "%s", enc->stats_out); | |
} | |
+#ifdef SYNO_EVANSPORT_SMD | |
+ if(!smd_video_pipeline) { | |
+#endif | |
if (!got_packet) { | |
stop_encoding = 1; | |
break; | |
@@ -1692,6 +2026,21 @@ static void flush_encoders(void) | |
av_packet_rescale_ts(&pkt, enc->time_base, ost->st->time_base); | |
pkt_size = pkt.size; | |
write_frame(os, &pkt, ost); | |
+#ifdef SYNO_EVANSPORT_SMD | |
+ } else { | |
+ if ((ret <= 0) && (vid_enc.eos_received)) { | |
+ stop_encoding = 1; | |
+ break; | |
+ } | |
+ if (ret >0) { | |
+ if (pkt.pts != AV_NOPTS_VALUE) | |
+ pkt.pts = av_rescale_q(pkt.pts, enc->time_base, ost->st->time_base); | |
+ if (pkt.dts != AV_NOPTS_VALUE) | |
+ pkt.dts = av_rescale_q(pkt.dts, enc->time_base, ost->st->time_base); | |
+ write_frame(os, &pkt, ost); | |
+ } | |
+ } | |
+#endif | |
if (ost->enc_ctx->codec_type == AVMEDIA_TYPE_VIDEO && vstats_filename) { | |
do_video_stats(ost, pkt_size); | |
} | |
@@ -1979,6 +2328,29 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output) | |
static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output) | |
{ | |
+#ifdef SYNO_EVANSPORT_SMD | |
+ /********************* smd implementation *****************/ | |
+ const uint8_t *buf = pkt->data; | |
+ int buf_size = pkt->size; | |
+ uint8_t* buf_with_start_code = NULL; | |
+ int new_buf_size = buf_size; | |
+ uint8_t* sps_pps_buf =NULL; | |
+ AVCodecContext *avctx = ist->dec_ctx; | |
+ | |
+ ismd_buffer_handle_t ismd_buf = -1; | |
+ ismd_result_t result = ISMD_SUCCESS; | |
+ int sps_pps_buf_size =0; | |
+ bool first_time =true; | |
+ unsigned char pSeqHeaderRbdu[8]; | |
+ unsigned char SPMP_PESpacket_PayloadFormatHeader[16]; | |
+ int size_SPMP_PESpacket_PayloadFormatHeader; | |
+ int max_bufsize =0; | |
+ ismd_codec_type_t smd_codec; | |
+ H264Context *h; | |
+ VC1Context *v; | |
+ /********************* end *****************/ | |
+#endif | |
+ | |
AVFrame *decoded_frame, *f; | |
int i, ret = 0, err = 0, resample_changed; | |
int64_t best_effort_timestamp; | |
@@ -1991,6 +2363,10 @@ static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output) | |
decoded_frame = ist->decoded_frame; | |
pkt->dts = av_rescale_q(ist->dts, AV_TIME_BASE_Q, ist->st->time_base); | |
+#ifdef SYNO_EVANSPORT_SMD | |
+ if(!smd_video_pipeline) | |
+ { | |
+#endif | |
update_benchmark(NULL); | |
ret = avcodec_decode_video2(ist->dec_ctx, | |
decoded_frame, got_output, pkt); | |
@@ -2116,6 +2492,251 @@ static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output) | |
} | |
} | |
+#ifdef SYNO_EVANSPORT_SMD | |
+ } else { | |
+ int64_t pts; | |
+ ret = pkt->size; | |
+ if (pkt->pts != AV_NOPTS_VALUE) { | |
+ pts = av_rescale_q(pkt->pts, ist->st->time_base, AV_TIME_BASE_Q); | |
+ } else { | |
+ pts = av_rescale_q(pkt->dts, ist->st->time_base, AV_TIME_BASE_Q); | |
+ } | |
+ /******************** write data to decoder input port *******************/ | |
+ smd_codec = get_smd_codec_id(ist->st->codec->codec_id); | |
+// av_log(NULL,AV_LOG_DEBUG,"\nin transcode_video smd_codec %d\n",smd_codec); | |
+ switch (smd_codec) | |
+ { | |
+ //no special handling is required for mpeg2 mpeg4 | |
+ //we are not supporting msmpeg4 | |
+ case ISMD_CODEC_TYPE_MPEG2: | |
+ case ISMD_CODEC_TYPE_MPEG4: | |
+ av_log(NULL, AV_LOG_DEBUG, "\n********* in ISMD_CODEC_TYPE_MPEG2/ISMD_CODEC_TYPE_MPEG4 case **************\n"); | |
+ av_log(NULL, AV_LOG_DEBUG, "\navctx->extradata_size %d\n",avctx->extradata_size); | |
+ //send headers before first packet | |
+ if((vid_dec.send_sps_pps) && (avctx->extradata_size > 0)) | |
+ { | |
+ if ((result = ismd_buffer_alloc(CHUNK_SIZE, &ismd_buf)) == ISMD_SUCCESS) | |
+ { | |
+ av_log(NULL, AV_LOG_DEBUG,"\n********* sending extradata size %d ********\n",avctx->extradata_size); | |
+ if (enable_dtv_smd) { | |
+ result = syno_ismd_ffmpeg_fill_viddec_buffer(avctx->extradata, ismd_buf,avctx->extradata_size, pts); | |
+ } else { | |
+ result = ismd_ffmpeg_fill_viddec_buffer(avctx->extradata, ismd_buf,avctx->extradata_size); | |
+ } | |
+ if (result == ISMD_SUCCESS) | |
+ { | |
+ // decode it asynchronously | |
+ if ((result = ismd_ffmpeg_decoder_port_write(&vid_dec,ismd_buf)) != ISMD_SUCCESS) | |
+ { | |
+ av_log(NULL, AV_LOG_ERROR,"error: unable to decode smd_buffers11 [%d]\n", result); | |
+ } | |
+ } | |
+ } | |
+ else | |
+ { | |
+ av_log(NULL, AV_LOG_INFO,"error: unable to allocate buffer in decode_frame111 [%d]\n", result); | |
+ } | |
+ vid_dec.send_sps_pps = false; | |
+ } | |
+ //Mpeg1Context *s = avctx->priv_data; | |
+ buf_with_start_code = buf;//format is not avc1 so coming buffer is in Byte-stream format.no conversion required | |
+ if (enable_dtv_smd) { | |
+ syno_ismd_ffmpeg_decode_vid_buf(&vid_dec, buf_with_start_code, new_buf_size, pts); | |
+ } else { | |
+ ismd_ffmpeg_decode_vid_buf(&vid_dec, buf_with_start_code, new_buf_size); | |
+ } | |
+ break; | |
+ case ISMD_CODEC_TYPE_H264: | |
+ h = avctx->priv_data; | |
+ if(buf_size > 4) | |
+ { | |
+ if(h->is_avc) | |
+ { | |
+ buf_with_start_code = av_malloc(pkt->size);//allocate memory for new buffer | |
+ if(buf_with_start_code == NULL) | |
+ { | |
+ av_log(NULL,AV_LOG_ERROR,"\ncould not allocate memory for new buffer \n"); | |
+ assert(0); | |
+ } | |
+ if((vid_dec.send_sps_pps) && avctx->extradata_size > 0 && avctx->extradata) | |
+ { | |
+ sps_pps_buf_size = ismd_ffmpeg_h264_viddec_extract_sps_pps(avctx->extradata,avctx->extradata_size, &sps_pps_buf); | |
+ } | |
+ | |
+ new_buf_size = ismd_ffmpeg_unit_to_byte_stream(&buf_with_start_code, buf, pkt->size, h->nal_length_size); | |
+ } | |
+ else | |
+ { | |
+ buf_with_start_code = buf;//format is not avc1 so coming buffer is in Byte-stream format.no conversion required | |
+ } | |
+ } | |
+ | |
+ /******************** write sps/pps buffer for avc1 at decoder i/p port ************************************************/ | |
+ if((vid_dec.send_sps_pps) && h->is_avc) | |
+ { | |
+ if ((result = ismd_buffer_alloc(CHUNK_SIZE, &ismd_buf)) == ISMD_SUCCESS) | |
+ { | |
+ av_log(NULL, AV_LOG_DEBUG,"\n********* sending sps pps buffer write size %d ********\n",sps_pps_buf_size); | |
+ if (enable_dtv_smd) { | |
+ result = syno_ismd_ffmpeg_fill_viddec_buffer(sps_pps_buf, ismd_buf, sps_pps_buf_size, pts); | |
+ } else { | |
+ result = ismd_ffmpeg_fill_viddec_buffer(sps_pps_buf, ismd_buf, sps_pps_buf_size); | |
+ } | |
+ if (result == ISMD_SUCCESS) | |
+ { | |
+ // decode it asynchronously | |
+ if ((result = ismd_ffmpeg_decoder_port_write(&vid_dec,ismd_buf)) != ISMD_SUCCESS) | |
+ { | |
+ av_log(NULL, AV_LOG_ERROR,"error: unable to decode smd_buffers11 [%d]\n", result); | |
+ } | |
+ } | |
+ } | |
+ else | |
+ { | |
+ av_log(NULL, AV_LOG_INFO,"error: unable to allocate buffer in decode_frame111 [%d]\n", result); | |
+ } | |
+ vid_dec.send_sps_pps = false; | |
+ } | |
+ /******************** write nal data of slice data at decoder i/p port ************************************************/ | |
+ if (enable_dtv_smd) { | |
+ syno_ismd_ffmpeg_decode_vid_buf(&vid_dec, buf_with_start_code, new_buf_size, pts); | |
+ } else { | |
+ ismd_ffmpeg_decode_vid_buf(&vid_dec, buf_with_start_code, new_buf_size); | |
+ } | |
+ | |
+ if((h->is_avc)&& buf_with_start_code) | |
+ { | |
+ av_free(buf_with_start_code); | |
+ buf_with_start_code = NULL; | |
+ } | |
+ break; | |
+ case ISMD_CODEC_TYPE_VC1: | |
+ v = avctx->priv_data; | |
+ if (first_time && (buf_size >= 4)&& (!IS_MARKER(AV_RB32(buf)))) /*frame starts with marker and needs to be parsed */ | |
+ { | |
+ vid_dec.vc1_without_start_code = true;//not compatible with smd | |
+ first_time = false; | |
+ | |
+ } | |
+ if(vid_dec.vc1_without_start_code) | |
+ { | |
+ //write sps to decoder port first this comes out-of-band in wvc1 | |
+ if((vid_dec.send_sps_pps) && avctx->extradata_size > 0 && avctx->extradata) | |
+ { | |
+ uint8_t* seq_header_buf = av_malloc(16);//TODO free buffer | |
+ switch (v->profile) | |
+ { | |
+ case PROFILE_ADVANCED: | |
+ if ((result = ismd_buffer_alloc(CHUNK_SIZE, &ismd_buf)) == ISMD_SUCCESS) | |
+ { | |
+ if (enable_dtv_smd) { | |
+ result = syno_ismd_ffmpeg_fill_viddec_buffer(avctx->extradata+1, ismd_buf, avctx->extradata_size-1, pts); | |
+ } else { | |
+ result = ismd_ffmpeg_fill_viddec_buffer(avctx->extradata+1, ismd_buf, avctx->extradata_size-1); | |
+ } | |
+ if (result == ISMD_SUCCESS) | |
+ { | |
+ // decode it asynchronously | |
+ if ((result = ismd_ffmpeg_decoder_port_write(&vid_dec,ismd_buf)) != ISMD_SUCCESS) | |
+ { | |
+ av_log(NULL, AV_LOG_ERROR,"error: unable to decode smd_buffers [%d]\n", result); | |
+ } | |
+ } | |
+ } | |
+ break; | |
+ case PROFILE_SIMPLE: | |
+ case PROFILE_MAIN: | |
+ size_SPMP_PESpacket_PayloadFormatHeader = ismd_ffmpeg_vc1_viddec_SPMP_PESpacket_PayloadFormatHeader (pSeqHeaderRbdu, SPMP_PESpacket_PayloadFormatHeader, avctx->extradata, avctx->extradata_size, avctx->width, avctx->height); | |
+ | |
+ if ((result = ismd_buffer_alloc(CHUNK_SIZE, &ismd_buf)) == ISMD_SUCCESS) | |
+ { | |
+ if (enable_dtv_smd) { | |
+ result = syno_ismd_ffmpeg_fill_viddec_buffer(SPMP_PESpacket_PayloadFormatHeader, ismd_buf, size_SPMP_PESpacket_PayloadFormatHeader, pts); | |
+ } else { | |
+ result = ismd_ffmpeg_fill_viddec_buffer(SPMP_PESpacket_PayloadFormatHeader, ismd_buf, size_SPMP_PESpacket_PayloadFormatHeader); | |
+ } | |
+ if (result == ISMD_SUCCESS) | |
+ { | |
+ // decode it asynchronously | |
+ if ((result = ismd_ffmpeg_decoder_port_write(&vid_dec,ismd_buf)) != ISMD_SUCCESS) | |
+ { | |
+ av_log(NULL, AV_LOG_ERROR,"error: unable to decode smd_buffers [%d]\n", result); | |
+ } | |
+ } | |
+ } | |
+ break; | |
+ } | |
+ vid_dec.send_sps_pps = false; | |
+ av_free(seq_header_buf); | |
+ } | |
+ | |
+ //need to insert start code | |
+ switch (v->profile) | |
+ { | |
+ case PROFILE_ADVANCED: | |
+ //insert start code | |
+ av_log(NULL, AV_LOG_DEBUG, "\n***start code not found*** profile %d PROFILE_ADVANCED %d\n",v->profile,PROFILE_ADVANCED); | |
+ buf_with_start_code = av_malloc(4 + buf_size);//TODO free memory | |
+ | |
+ new_buf_size = ismd_ffmpeg_vc1_viddec_convert_AP(buf_with_start_code, buf, buf_size); | |
+ | |
+ break; | |
+ case PROFILE_SIMPLE: | |
+ case PROFILE_MAIN: | |
+ // Calculate maximum buffer size, make room for encapsulation | |
+ // SMPTE-421M-FDSI doc, Annex-E | |
+ max_bufsize = ( (pkt->size + 3 ) / 3 ) * 4; | |
+ buf_with_start_code = av_malloc(max_bufsize); | |
+ av_log(NULL, AV_LOG_DEBUG, "\n* pkt size %d max_bufsize %d*\n",pkt->size,max_bufsize); | |
+ | |
+ new_buf_size = ismd_ffmpeg_vc1_viddec_convert_SPMP(buf_with_start_code, pkt->data, pkt->size, max_bufsize); | |
+ | |
+ break; | |
+ } | |
+ | |
+ } | |
+ else | |
+ buf_with_start_code = buf; | |
+ /*********** write buffer data ************************/ | |
+ if (enable_dtv_smd) { | |
+ syno_ismd_ffmpeg_decode_vid_buf(&vid_dec, buf_with_start_code, new_buf_size, pts); | |
+ } else { | |
+ ismd_ffmpeg_decode_vid_buf(&vid_dec, buf_with_start_code, new_buf_size); | |
+ } | |
+ | |
+ if((vid_dec.vc1_without_start_code)&& buf_with_start_code) | |
+ { | |
+ av_free(buf_with_start_code); | |
+ } | |
+ | |
+ break; | |
+ default: | |
+ av_log(NULL,AV_LOG_ERROR,"\n********smd can't handle this codec***********\n"); | |
+ return -1; | |
+ } | |
+ | |
+ if(vid_dec.eos_written) | |
+ *got_output = 0; | |
+ if (!*got_output || ret < 0) { | |
+ if (!pkt->size) { | |
+ for (i = 0; i < ist->nb_filters; i++) | |
+ av_buffersrc_add_ref(ist->filters[i]->filter, NULL, 0); | |
+ } | |
+ } | |
+ | |
+ pkt->size = 0; | |
+ | |
+ //rate_emu_sleep(ist); | |
+ for (i = 0; i < nb_output_streams; i++) { | |
+ OutputStream *ost = output_streams[i]; | |
+ | |
+ if (!check_output_constraints(ist, ost) || !ost->encoding_needed) | |
+ continue; | |
+ do_video_out(output_files[ost->file_index]->ctx, ost, decoded_frame, 0); | |
+ } | |
+ } | |
+#endif | |
+ | |
fail: | |
av_frame_unref(ist->filter_frame); | |
av_frame_unref(decoded_frame); | |
@@ -2221,7 +2842,12 @@ static int process_input_packet(InputStream *ist, const AVPacket *pkt) | |
} | |
// while we have more to decode or while the decoder did output something on EOF | |
+#ifdef SYNO_EVANSPORT_SMD | |
+ //to resolve ctrl-C issue | |
+ while (ist->decoding_needed && (avpkt.size > 0 || (!pkt && (got_output >0)))) { | |
+#else | |
while (ist->decoding_needed && (avpkt.size > 0 || (!pkt && got_output))) { | |
+#endif | |
int duration; | |
handle_eof: | |
@@ -2555,6 +3181,48 @@ static void report_new_stream(int input_index, AVPacket *pkt) | |
file->nb_streams_warn = pkt->stream_index + 1; | |
} | |
+#ifdef SYNO_EVANSPORT_SMD | |
+static ismd_codec_type_t get_smd_codec_id(enum AVCodecID ffmpeg_codec_id) | |
+{ | |
+ switch (ffmpeg_codec_id) | |
+ { | |
+ case AV_CODEC_ID_MPEG2VIDEO_SYNO: | |
+ return ISMD_CODEC_TYPE_MPEG2; | |
+ case AV_CODEC_ID_H264_SYNO: | |
+ return ISMD_CODEC_TYPE_H264; | |
+ case AV_CODEC_ID_VC1_SYNO: | |
+ case AV_CODEC_ID_WMV3_SYNO: | |
+ return ISMD_CODEC_TYPE_VC1; | |
+ case AV_CODEC_ID_MPEG4_SYNO: | |
+ return ISMD_CODEC_TYPE_MPEG4; | |
+ default: | |
+ return ISMD_CODEC_TYPE_INVALID; | |
+ } | |
+} | |
+#endif | |
+ | |
+#ifdef SYNO_EVANSPORT_HANDBRAKE_MP4 | |
+static int IsFileEncodeByHandBrake() | |
+{ | |
+ int i; | |
+ AVDictionaryEntry *tag = NULL; | |
+ | |
+ for (i = 0; i < nb_input_files; i++) { | |
+ InputFile *ifile = input_files[i]; | |
+ if (0 != strcmp(ifile->ctx->iformat->name, "mov,mp4,m4a,3gp,3g2,mj2")) { | |
+ continue; | |
+ } | |
+ while ((tag = av_dict_get(ifile->ctx->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) { | |
+ if (0 == strncmp(tag->key, "encoder", 7) && 0 == strncmp(tag->value, "HandBrake", 9)) { | |
+ return 1; | |
+ } | |
+ } | |
+ } | |
+ | |
+ return 0; | |
+} | |
+#endif | |
+ | |
static void set_encoder_id(OutputFile *of, OutputStream *ost) | |
{ | |
AVDictionaryEntry *e; | |
@@ -2598,6 +3266,14 @@ static void set_encoder_id(OutputFile *of, OutputStream *ost) | |
static int transcode_init(void) | |
{ | |
+#ifdef SYNO_EVANSPORT_SMD | |
+ /************** smd implementation ***********/ | |
+ ismd_result_t result = ISMD_ERROR_UNSPECIFIED; | |
+ char *hw_decoder_name; | |
+ ismd_codec_type_t smd_codec; | |
+ /************** end ***********/ | |
+#endif | |
+ | |
int ret = 0, i, j, k; | |
AVFormatContext *oc; | |
OutputStream *ost; | |
@@ -3256,6 +3932,102 @@ static int transcode_init(void) | |
transcode_init_done = 1; | |
+#ifdef SYNO_EVANSPORT_SMD | |
+ /******************************* create smd video pipeline here ********************/ | |
+ for (i = 0; i < nb_output_streams; i++) | |
+ { | |
+ AVCodecContext *codec = NULL; | |
+ ost = output_streams[i]; | |
+ codec = ost->st->codec; | |
+ | |
+ if (codec->codec_id == AV_CODEC_ID_H264) | |
+ break; | |
+ } | |
+ //don't create pipeline in case of stream copy | |
+ if(!ost->stream_copy) | |
+ { | |
+ AVCodecContext *icodec = NULL; | |
+ AVCodecContext *codec = NULL; | |
+ codec = ost->enc_ctx; | |
+ av_log(NULL, AV_LOG_DEBUG,"\n**** encoder codec id **** %d width %d height %d aspect num %d den %d\n", codec->codec_id,codec->width,codec->height,codec->sample_aspect_ratio.num,codec->sample_aspect_ratio.den); | |
+ | |
+ for (i = 0; i < nb_input_streams; i++) | |
+ { | |
+ ist = input_streams[i]; | |
+ icodec = ist->st->codec; | |
+ av_log(NULL,AV_LOG_DEBUG,"\nicodec->codec_id %d\n",icodec->codec_id); | |
+ if(icodec->codec_type == AVMEDIA_TYPE_VIDEO) | |
+ { | |
+ //set up video decoder | |
+ if(((icodec->codec_id == AV_CODEC_ID_MPEG2VIDEO_SYNO) || (icodec->codec_id == AV_CODEC_ID_H264_SYNO) ||\ | |
+ (icodec->codec_id == AV_CODEC_ID_VC1_SYNO) ||(icodec->codec_id == AV_CODEC_ID_WMV3_SYNO)||\ | |
+ (icodec->codec_id == AV_CODEC_ID_MPEG4_SYNO)) && \ | |
+ ((codec->codec_id == AV_CODEC_ID_H264) && (0 == strcmp(codec->codec->name, "h264_smd")))) | |
+ { | |
+ av_log(NULL,AV_LOG_DEBUG,"\npipeline check successful\n"); | |
+ bool smd_video_available = ismd_ffmpeg_is_video_enc_avail(); | |
+ if(!smd_video_available) | |
+ { | |
+#if CONFIG_LIBX264_ENCODER | |
+ av_log( NULL, AV_LOG_INFO, "\nVideo hardware encoder not available for encoding.Falling back to software\n"); | |
+ return 0; | |
+#else | |
+ av_log( NULL, AV_LOG_ERROR, "\nVideo hardware encoder not available for encoding. and software fallback not possible\n"); | |
+ return -1; | |
+#endif | |
+ } | |
+ | |
+ smd_codec = get_smd_codec_id(icodec->codec_id); | |
+ hw_decoder_name = ismd_ffmpeg_enum_to_string(smd_codec); | |
+ av_log(NULL, AV_LOG_DEBUG,"\n**** About to open stream for decoding with codec type **** %d smd_codec %d \n", icodec->codec_id, smd_codec); | |
+ if ((result = ismd_viddec_open(smd_codec, &vid_dec.viddec_handle) != ISMD_SUCCESS)) | |
+ { | |
+ av_log(NULL, AV_LOG_ERROR,"\n ismd_viddec_open : failed error %d\n",result); | |
+ return -1; | |
+ } | |
+ } | |
+ } | |
+ } | |
+ if(ISMD_SUCCESS == result) | |
+ { | |
+#ifdef SYNO_EVANSPORT_HANDBRAKE_MP4 | |
+ if (IsFileEncodeByHandBrake()) { | |
+ enable_dtv_smd = 1; | |
+ } | |
+#endif | |
+ if (ost->encoding_needed) | |
+ { | |
+ //close H.264 smd encoder because transcoding will be done through pipeline | |
+#ifdef SYNO_EVANSPORT_FLV_EXTRADATA | |
+ X264Context *x4 = ost->enc_ctx->priv_data; | |
+ x4->dont_free_extradata = true; | |
+#endif | |
+ ost->enc_ctx->codec->close(ost->enc_ctx); | |
+#ifdef SYNO_EVANSPORT_FLV_EXTRADATA | |
+ x4->dont_free_extradata = false; | |
+#endif | |
+ ost->enc_ctx->coded_frame = av_frame_alloc(); | |
+ if (!ost->enc_ctx->coded_frame) | |
+ return AVERROR(ENOMEM); | |
+ } | |
+ result = ismd_ffmpeg_create_video_pipeline(codec , &vid_dec , &vid_enc, enable_dtv_smd); | |
+ if (result != ISMD_SUCCESS) | |
+ { | |
+ av_log(NULL,AV_LOG_ERROR,"\n FAILURE: could not start video pipeline error: %d\n",result); | |
+ return -1; | |
+ } | |
+ if (!synoAddPID(getpid())) { | |
+ av_log(NULL, AV_LOG_ERROR, "Syno check hardware transcode falied\n"); | |
+ return -1; | |
+ } | |
+ av_log(NULL, AV_LOG_DEBUG, "\nvideo pipeline created successfully\n"); | |
+ av_log( NULL, AV_LOG_INFO, "****** Using SMD H/W %s Decoder and H/W H.264 Encoder(Pipelined Mode)*******\n",hw_decoder_name); | |
+ smd_video_pipeline = true; | |
+ } | |
+ } | |
+ /******************************* end ********************/ | |
+#endif | |
+ | |
return 0; | |
} | |
@@ -3747,6 +4519,23 @@ static int process_input(int file_index) | |
} | |
} | |
+#ifdef SYNO_EVANSPORT_SMD | |
+ if (first_read_pts && AVMEDIA_TYPE_VIDEO == ist->st->codec->codec_type && | |
+ (AV_CODEC_ID_H264_SYNO != ist->st->codec->codec_id || AV_PKT_FLAG_KEY & pkt.flags)) { | |
+ if (AV_NOPTS_VALUE != pkt.pts) { | |
+ first_read_pts = false; | |
+ ifile->first_pts = av_rescale_q(pkt.pts, ist->st->time_base, AV_TIME_BASE_Q); | |
+ av_log(NULL, AV_LOG_DEBUG, "first_pts %s pts_time %s frome pts\n" | |
+ , av_ts2str(ifile->first_pts), av_ts2timestr(ifile->first_pts, &AV_TIME_BASE_Q)); | |
+ } else if (AV_NOPTS_VALUE != pkt.dts){ | |
+ first_read_pts = false; | |
+ ifile->first_pts = av_rescale_q(pkt.dts, ist->st->time_base, AV_TIME_BASE_Q)+1; | |
+ av_log(NULL, AV_LOG_DEBUG, "first_pts %s pts_time %s frome dts\n" | |
+ , av_ts2str(ifile->first_pts), av_ts2timestr(ifile->first_pts, &AV_TIME_BASE_Q)); | |
+ } | |
+ } | |
+#endif | |
+ | |
if (pkt.dts != AV_NOPTS_VALUE) | |
ifile->last_ts = av_rescale_q(pkt.dts, ist->st->time_base, AV_TIME_BASE_Q); | |
diff --git a/ffmpeg.h b/ffmpeg.h | |
index 7fd129a283..f03f1deb64 100644 | |
--- a/ffmpeg.h | |
+++ b/ffmpeg.h | |
@@ -48,6 +48,8 @@ | |
#include "libswresample/swresample.h" | |
+#include "synoconfig.h" | |
+ | |
#define VSYNC_AUTO -1 | |
#define VSYNC_PASSTHROUGH 0 | |
#define VSYNC_CFR 1 | |
@@ -341,6 +343,9 @@ typedef struct InputFile { | |
int ist_index; /* index of first stream in input_streams */ | |
int64_t input_ts_offset; | |
int64_t ts_offset; | |
+#ifdef SYNO_EVANSPORT_SMD | |
+ int64_t first_pts; /* remember first video pts for handle resume problem on VideoStation */ | |
+#endif | |
int64_t last_ts; | |
int64_t start_time; /* user-specified start time in AV_TIME_BASE or AV_NOPTS_VALUE */ | |
int seek_timestamp; | |
@@ -506,6 +511,9 @@ extern int print_stats; | |
extern int qp_hist; | |
extern int stdin_interaction; | |
extern int frame_bits_per_raw_sample; | |
+// SYNO_EVANSPORT_DTV_SMD_AVSYNC | |
+extern int enable_dtv_smd; | |
+// SYNO_EVANSPORT_DTV_SMD_AVSYNC | |
extern AVIOContext *progress_avio; | |
extern float max_error_rate; | |
extern int vdpau_api_ver; | |
diff --git a/ffmpeg_opt.c b/ffmpeg_opt.c | |
index 79cb5caa34..b465eaad3d 100644 | |
--- a/ffmpeg_opt.c | |
+++ b/ffmpeg_opt.c | |
@@ -41,6 +41,12 @@ | |
#include "libavutil/pixdesc.h" | |
#include "libavutil/pixfmt.h" | |
+#include "synoconfig.h" | |
+ | |
+#ifdef SYNO_DTV_SKIP_UNKNOWN_TRACK | |
+#include <strings.h> | |
+#endif | |
+ | |
#define MATCH_PER_STREAM_OPT(name, type, outvar, fmtctx, st)\ | |
{\ | |
int i, ret;\ | |
@@ -102,7 +108,18 @@ int qp_hist = 0; | |
int stdin_interaction = 1; | |
int frame_bits_per_raw_sample = 0; | |
float max_error_rate = 2.0/3; | |
- | |
+// SYNO_EVANSPORT_DTV_SMD_AVSYNC | |
+int enable_dtv_smd = 0; | |
+// SYNO_EVANSPORT_DTV_SMD_AVSYNC | |
+#ifdef SYNO_DTV_SKIP_UNKNOWN_TRACK | |
+int dtv_skip_unknown = 0; | |
+#endif | |
+#ifdef SYNO_DTV_SKIP_VISUAL_IMPAIRED_TRACK | |
+int dtv_skip_visual_impaired = 0; | |
+#endif | |
+#ifdef SYNO_DTV_SKIP_TELETEXT | |
+int dtv_skip_teletext = 0; | |
+#endif | |
static int intra_only = 0; | |
static int file_overwrite = 0; | |
@@ -114,6 +131,10 @@ static int input_stream_potentially_available = 0; | |
static int ignore_unknown_streams = 0; | |
static int copy_unknown_streams = 0; | |
+#ifdef SYNO_EVANSPORT_AUTO_HW_DECODER | |
+static int auto_detect_HWdecoder = 0; | |
+#endif | |
+ | |
static void uninit_options(OptionsContext *o) | |
{ | |
const OptionDef *po = options; | |
@@ -294,6 +315,33 @@ static int opt_map(void *optctx, const char *opt, const char *arg) | |
if (check_stream_specifier(input_files[file_idx]->ctx, input_files[file_idx]->ctx->streams[i], | |
*p == ':' ? p + 1 : p) <= 0) | |
continue; | |
+#ifdef SYNO_DTV_SKIP_UNKNOWN_TRACK | |
+ if (dtv_skip_unknown) { | |
+ char buf[256]; | |
+ AVStream *st = input_files[file_idx]->ctx->streams[i]; | |
+ avcodec_string(buf, sizeof(buf), st->codec, 0); | |
+ if (!strncasecmp(buf, "unknown", 7)) { | |
+ continue; | |
+ } | |
+ if (strstr(buf, "0 channels") != NULL) { | |
+ continue; | |
+ } | |
+ } | |
+#endif | |
+#ifdef SYNO_DTV_SKIP_VISUAL_IMPAIRED_TRACK | |
+ if (dtv_skip_visual_impaired) { | |
+ AVStream *st = input_files[file_idx]->ctx->streams[i]; | |
+ if (st->disposition & AV_DISPOSITION_VISUAL_IMPAIRED) { | |
+ continue; | |
+ } | |
+ } | |
+#endif | |
+#ifdef SYNO_DTV_SKIP_TELETEXT | |
+ if (dtv_skip_teletext && | |
+ AV_CODEC_ID_DVB_TELETEXT == input_files[file_idx]->ctx->streams[i]->codec->codec_id) { | |
+ continue; | |
+ } | |
+#endif | |
GROW_ARRAY(o->stream_maps, o->nb_stream_maps); | |
m = &o->stream_maps[o->nb_stream_maps - 1]; | |
@@ -561,6 +609,88 @@ static AVCodec *find_codec_or_die(const char *name, enum AVMediaType type, int e | |
return codec; | |
} | |
+#ifdef SYNO_SKIP_DISABLED_AUDIO_STREAM | |
+static int IsAudioCopyStream(OptionsContext *o, AVFormatContext *oc) | |
+{ | |
+ int ret = 0; | |
+ char *audio_codec_name = NULL; | |
+ | |
+ MATCH_PER_TYPE_OPT(codec_names, str, audio_codec_name, oc, "a"); | |
+ | |
+ if (audio_codec_name && 0 == strcmp(audio_codec_name, "copy")) { | |
+ ret = 1; | |
+ } | |
+ | |
+ return ret; | |
+} | |
+ | |
+static int IsSkipAudioStream(const InputStream *ist, OptionsContext *o, AVFormatContext *oc) | |
+{ | |
+ if (ist->st->codec->codec_id == AV_CODEC_ID_DTS | |
+ || ist->st->codec->codec_id == AV_CODEC_ID_EAC3 | |
+ || ist->st->codec->codec_id == AV_CODEC_ID_TRUEHD) | |
+ { | |
+ // if not stream copy | |
+ if (!IsAudioCopyStream(o, oc)) { | |
+ return 1; | |
+ } | |
+ } | |
+ | |
+ return 0; | |
+} | |
+#endif | |
+ | |
+#ifdef SYNO_EVANSPORT_AUTO_HW_DECODER | |
+static AVCodec *choose_decoder_smd(OptionsContext *o, AVFormatContext *s, AVStream *st) | |
+{ | |
+ char *codec_name = NULL; | |
+ AVCodec *result_codec; | |
+ enum AVCodecID smd_codecID; | |
+ | |
+ MATCH_PER_STREAM_OPT(codec_names, str, codec_name, s, st); | |
+ if (codec_name) { | |
+ AVCodec *codec = find_codec_or_die(codec_name, st->codec->codec_type, 0); | |
+ st->codec->codec_id = codec->id; | |
+ result_codec = codec; | |
+ } else { | |
+ result_codec = avcodec_find_decoder(st->codec->codec_id); | |
+ } | |
+ | |
+ if (!result_codec || !auto_detect_HWdecoder) { | |
+ return result_codec; | |
+ } | |
+ | |
+ switch (result_codec->id) { | |
+ case AV_CODEC_ID_H264: | |
+ if (FF_PROFILE_H264_HIGH_10 == st->codec->profile || FF_PROFILE_H264_HIGH_10_INTRA == st->codec->profile) { | |
+ return result_codec; | |
+ } | |
+ smd_codecID = AV_CODEC_ID_H264_SYNO; | |
+ break; | |
+ case AV_CODEC_ID_MPEG2VIDEO: | |
+ smd_codecID = AV_CODEC_ID_MPEG2VIDEO_SYNO; | |
+ break; | |
+ case AV_CODEC_ID_VC1: | |
+ smd_codecID = AV_CODEC_ID_VC1_SYNO; | |
+ break; | |
+ case AV_CODEC_ID_WMV3: | |
+ smd_codecID = AV_CODEC_ID_WMV3_SYNO; | |
+ break; | |
+ case AV_CODEC_ID_MPEG4: | |
+ smd_codecID = AV_CODEC_ID_MPEG4_SYNO; | |
+ break; | |
+ default: | |
+ smd_codecID = AV_CODEC_ID_NONE; | |
+ } | |
+ if (AV_CODEC_ID_NONE != smd_codecID) { | |
+ result_codec = avcodec_find_decoder(smd_codecID); | |
+ st->codec->codec_id = result_codec->id; | |
+ } | |
+ | |
+ return result_codec; | |
+} | |
+#endif | |
+ | |
static AVCodec *choose_decoder(OptionsContext *o, AVFormatContext *s, AVStream *st) | |
{ | |
char *codec_name = NULL; | |
@@ -615,7 +745,12 @@ static void add_input_streams(OptionsContext *o, AVFormatContext *ic) | |
st->codec->codec_tag = tag; | |
} | |
+#ifdef SYNO_EVANSPORT_AUTO_HW_DECODER | |
+ ist->dec = choose_decoder_smd(o, ic, st); | |
+#else | |
ist->dec = choose_decoder(o, ic, st); | |
+#endif | |
+ | |
ist->decoder_opts = filter_codec_opts(o->g->codec_opts, ist->st->codec->codec_id, ic, st, ist->dec); | |
ist->reinit_filters = -1; | |
@@ -1937,6 +2072,12 @@ static int open_output_file(OptionsContext *o, const char *filename) | |
int channels = 0, idx = -1; | |
for (i = 0; i < nb_input_streams; i++) { | |
ist = input_streams[i]; | |
+#ifdef SYNO_SKIP_DISABLED_AUDIO_STREAM | |
+ if (IsSkipAudioStream(ist, o, oc)) { | |
+ // if not stream copy | |
+ continue; | |
+ } | |
+#endif | |
if (ist->st->codec->codec_type == AVMEDIA_TYPE_AUDIO && | |
ist->st->codec->channels > channels) { | |
channels = ist->st->codec->channels; | |
@@ -2025,6 +2166,12 @@ loop_end: | |
continue; | |
if(o-> data_disable && ist->st->codec->codec_type == AVMEDIA_TYPE_DATA) | |
continue; | |
+#ifdef SYNO_SKIP_DISABLED_AUDIO_STREAM | |
+ if (IsSkipAudioStream(ist, o, oc)) { | |
+ // if not stream copy | |
+ continue; | |
+ } | |
+#endif | |
switch (ist->st->codec->codec_type) { | |
case AVMEDIA_TYPE_VIDEO: ost = new_video_stream (o, oc, src_idx); break; | |
@@ -2878,6 +3025,27 @@ static int opt_progress(void *optctx, const char *opt, const char *arg) | |
const OptionDef options[] = { | |
/* main options */ | |
#include "cmdutils_common_opts.h" | |
+#ifdef SYNO_EVANSPORT_AUTO_HW_DECODER | |
+ { "prefer_smd", OPT_BOOL, { &auto_detect_HWdecoder }, | |
+ "enable auto detect Hardware decoder" }, | |
+#endif | |
+#ifdef SYNO_EVANSPORT_DTV_SMD_AVSYNC | |
+ { "dtv_smd", OPT_BOOL, { &enable_dtv_smd}, | |
+ "enable passthough timestamp in hardware pipeline mode" }, | |
+#endif | |
+#ifdef SYNO_DTV_SKIP_UNKNOWN_TRACK | |
+ { "dtv_skip_unknown", OPT_BOOL, { &dtv_skip_unknown}, | |
+ "skip unknown codec track during dtv streaming" }, | |
+#endif | |
+#ifdef SYNO_DTV_SKIP_VISUAL_IMPAIRED_TRACK | |
+ { "dtv_skip_visual_impaired", OPT_BOOL, { &dtv_skip_visual_impaired }, | |
+ "skip visual impaired track during dtv streaming" }, | |
+#endif | |
+#ifdef SYNO_DTV_SKIP_TELETEXT | |
+ { "dtv_skip_teletext", OPT_BOOL, { &dtv_skip_teletext }, | |
+ "skip subtitle streams in teletext codec during dtv streaming" }, | |
+#endif | |
+ | |
{ "f", HAS_ARG | OPT_STRING | OPT_OFFSET | | |
OPT_INPUT | OPT_OUTPUT, { .off = OFFSET(format) }, | |
"force format", "fmt" }, | |
diff --git a/ffserver.c b/ffserver.c | |
index 2b19bba9ba..da48630c60 100644 | |
--- a/ffserver.c | |
+++ b/ffserver.c | |
@@ -71,6 +71,8 @@ | |
#include "cmdutils.h" | |
#include "ffserver_config.h" | |
+#include "synoconfig.h" | |
+ | |
const char program_name[] = "ffserver"; | |
const int program_birth_year = 2000; | |
@@ -2574,8 +2576,10 @@ static int http_receive_data(HTTPContext *c) | |
} else if (c->buffer_ptr - c->buffer >= 2 && | |
!memcmp(c->buffer_ptr - 1, "\r\n", 2)) { | |
c->chunk_size = strtol(c->buffer, 0, 16); | |
- if (c->chunk_size == 0) // end of stream | |
+ if (c->chunk_size <= 0) { // end of stream or invalid chunk size | |
+ c->chunk_size = 0; | |
goto fail; | |
+ } | |
c->buffer_ptr = c->buffer; | |
break; | |
} else if (++loop_run > 10) { | |
@@ -2598,6 +2602,7 @@ static int http_receive_data(HTTPContext *c) | |
/* end of connection : close it */ | |
goto fail; | |
else { | |
+ av_assert0(len <= c->chunk_size); | |
c->chunk_size -= len; | |
c->buffer_ptr += len; | |
c->data_count += len; | |
@@ -3425,9 +3430,11 @@ static int add_av_stream(FFServerStream *feed, AVStream *st) | |
switch(av->codec_type) { | |
case AVMEDIA_TYPE_AUDIO: | |
+#ifndef SYNO_FFSERVER_MULTIPLE_AUDIO_TRACK | |
if (av1->channels == av->channels && | |
av1->sample_rate == av->sample_rate) | |
return i; | |
+#endif | |
break; | |
case AVMEDIA_TYPE_VIDEO: | |
if (av1->width == av->width && | |
diff --git a/ffserver_config.c b/ffserver_config.c | |
index 06bd8ac44a..83785ec6ad 100644 | |
--- a/ffserver_config.c | |
+++ b/ffserver_config.c | |
@@ -31,6 +31,8 @@ | |
#include "cmdutils.h" | |
#include "ffserver_config.h" | |
+#include "synoconfig.h" | |
+ | |
#define MAX_CHILD_ARGS 64 | |
static int ffserver_save_avoption(const char *opt, const char *arg, int type, | |
@@ -797,6 +799,9 @@ static int ffserver_parse_config_stream(FFServerConfig *config, const char *cmd, | |
char arg[1024], arg2[1024]; | |
FFServerStream *stream; | |
int val; | |
+#ifdef SYNO_FFSERVER_MULTIPLE_AUDIO_TRACK | |
+ int num_audio_track = 1; | |
+#endif | |
av_assert0(pstream); | |
stream = *pstream; | |
@@ -1086,6 +1091,11 @@ static int ffserver_parse_config_stream(FFServerConfig *config, const char *cmd, | |
config->no_video = 1; | |
} else if (!av_strcasecmp(cmd, "NoAudio")) { | |
config->no_audio = 1; | |
+#ifdef SYNO_FFSERVER_MULTIPLE_AUDIO_TRACK | |
+ } else if (!av_strcasecmp(cmd, "SynoNumAudioTrack")) { | |
+ ffserver_get_arg(arg, sizeof(arg), p); | |
+ num_audio_track = atoi(arg); | |
+#endif | |
} else if (!av_strcasecmp(cmd, "ACL")) { | |
ffserver_parse_acl_row(stream, NULL, NULL, *p, config->filename, | |
config->line_num); | |
@@ -1120,8 +1130,15 @@ static int ffserver_parse_config_stream(FFServerConfig *config, const char *cmd, | |
config->dummy_actx->codec_id = config->guessed_audio_codec_id; | |
if (!config->no_audio && | |
config->dummy_actx->codec_id != AV_CODEC_ID_NONE) { | |
+#ifdef SYNO_FFSERVER_MULTIPLE_AUDIO_TRACK | |
+ for (int i = 0; i < num_audio_track; i ++) { | |
+ AVCodecContext *audio_enc = avcodec_alloc_context3(avcodec_find_encoder(config->dummy_actx->codec_id)); | |
+ add_codec(stream, audio_enc, config); | |
+ } | |
+#else | |
AVCodecContext *audio_enc = avcodec_alloc_context3(avcodec_find_encoder(config->dummy_actx->codec_id)); | |
add_codec(stream, audio_enc, config); | |
+#endif | |
} | |
if (config->dummy_vctx->codec_id == AV_CODEC_ID_NONE) | |
config->dummy_vctx->codec_id = config->guessed_video_codec_id; | |
diff --git a/libavcodec/Makefile b/libavcodec/Makefile | |
index bfd6425fd5..c7bcc28745 100644 | |
--- a/libavcodec/Makefile | |
+++ b/libavcodec/Makefile | |
@@ -37,6 +37,12 @@ OBJS = allcodecs.o \ | |
vorbis_parser.o \ | |
xiph.o \ | |
+ifdef CONFIG_SMD | |
+OBJS += ismd_ffmpeg_audio_util.o | |
+OBJS += syno_trans_loading.o | |
+endif | |
+OBJS += synog1codecpatent.o | |
+ | |
# subsystems | |
OBJS-$(CONFIG_AANDCTTABLES) += aandcttab.o | |
OBJS-$(CONFIG_AC3DSP) += ac3dsp.o | |
diff --git a/libavcodec/aacdec.c b/libavcodec/aacdec.c | |
index 622cc5c087..7312cb63c8 100644 | |
--- a/libavcodec/aacdec.c | |
+++ b/libavcodec/aacdec.c | |
@@ -113,6 +113,9 @@ | |
# include "mips/aacdec_mips.h" | |
#endif | |
+#include "synoconfig.h" | |
+#include "synog1codecpatent.h" | |
+ | |
static VLC vlc_scalefactors; | |
static VLC vlc_spectral[11]; | |
@@ -1098,6 +1101,12 @@ static av_cold int aac_decode_init(AVCodecContext *avctx) | |
avctx->sample_fmt = AV_SAMPLE_FMT_FLTP; | |
+#ifdef SYNO_CODEC_PATENT_G1 | |
+ if (0 != ActivateCodec("aac_dec")) { | |
+ return -1; | |
+ } | |
+#endif | |
+ | |
if (avctx->extradata_size > 0) { | |
if ((ret = decode_audio_specific_config(ac, ac->avctx, &ac->oc[1].m4ac, | |
avctx->extradata, | |
diff --git a/libavcodec/aacenc.c b/libavcodec/aacenc.c | |
index 897c3a10df..9b96ca7f43 100644 | |
--- a/libavcodec/aacenc.c | |
+++ b/libavcodec/aacenc.c | |
@@ -45,6 +45,9 @@ | |
#include "psymodel.h" | |
+#include "synoconfig.h" | |
+#include "synog1codecpatent.h" | |
+ | |
#define AAC_MAX_CHANNELS 6 | |
#define ERROR_IF(cond, ...) \ | |
@@ -764,6 +767,12 @@ static av_cold int aac_encode_init(AVCodecContext *avctx) | |
uint8_t grouping[AAC_MAX_CHANNELS]; | |
int lengths[2]; | |
+#ifdef SYNO_CODEC_PATENT_G1 | |
+ if (0 != ActivateCodec("aac_enc")) { | |
+ return -1; | |
+ } | |
+#endif | |
+ | |
avctx->frame_size = 1024; | |
for (i = 0; i < 16; i++) | |
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c | |
index ce977467f9..ea48a5e0d3 100644 | |
--- a/libavcodec/allcodecs.c | |
+++ b/libavcodec/allcodecs.c | |
@@ -28,6 +28,8 @@ | |
#include "avcodec.h" | |
#include "version.h" | |
+#include "synoconfig.h" | |
+ | |
#define REGISTER_HWACCEL(X, x) \ | |
{ \ | |
extern AVHWAccel ff_##x##_hwaccel; \ | |
@@ -175,6 +177,9 @@ void avcodec_register_all(void) | |
REGISTER_ENCDEC (H263, h263); | |
REGISTER_DECODER(H263I, h263i); | |
REGISTER_ENCDEC (H263P, h263p); | |
+#ifdef SYNO_EVANSPORT_SMD | |
+ REGISTER_DECODER(H264, h264_smd); | |
+#endif | |
REGISTER_DECODER(H264, h264); | |
REGISTER_DECODER(H264_CRYSTALHD, h264_crystalhd); | |
REGISTER_DECODER(H264_MMAL, h264_mmal); | |
@@ -212,7 +217,13 @@ void avcodec_register_all(void) | |
REGISTER_DECODER(MPEG_XVMC, mpeg_xvmc); | |
#endif /* FF_API_XVMC */ | |
REGISTER_ENCDEC (MPEG1VIDEO, mpeg1video); | |
+#ifdef SYNO_EVANSPORT_SMD | |
+ REGISTER_DECODER(MPEG2VIDEO, mpeg2video_smd); | |
+#endif | |
REGISTER_ENCDEC (MPEG2VIDEO, mpeg2video); | |
+#ifdef SYNO_EVANSPORT_SMD | |
+ REGISTER_DECODER(MPEG4, mpeg4_smd); | |
+#endif | |
REGISTER_ENCDEC (MPEG4, mpeg4); | |
REGISTER_DECODER(MPEG4_CRYSTALHD, mpeg4_crystalhd); | |
REGISTER_DECODER(MPEG4_VDPAU, mpeg4_vdpau); | |
@@ -296,6 +307,9 @@ void avcodec_register_all(void) | |
REGISTER_ENCDEC (V410, v410); | |
REGISTER_DECODER(VB, vb); | |
REGISTER_DECODER(VBLE, vble); | |
+#ifdef SYNO_EVANSPORT_SMD | |
+ REGISTER_DECODER(VC1, vc1_smd); | |
+#endif | |
REGISTER_DECODER(VC1, vc1); | |
REGISTER_DECODER(VC1_CRYSTALHD, vc1_crystalhd); | |
REGISTER_DECODER(VC1_VDPAU, vc1_vdpau); | |
@@ -315,6 +329,9 @@ void avcodec_register_all(void) | |
REGISTER_DECODER(WEBP, webp); | |
REGISTER_ENCDEC (WMV1, wmv1); | |
REGISTER_ENCDEC (WMV2, wmv2); | |
+#ifdef SYNO_EVANSPORT_SMD | |
+ REGISTER_DECODER(WMV3, wmv3_smd); | |
+#endif | |
REGISTER_DECODER(WMV3, wmv3); | |
REGISTER_DECODER(WMV3_CRYSTALHD, wmv3_crystalhd); | |
REGISTER_DECODER(WMV3_VDPAU, wmv3_vdpau); | |
@@ -545,6 +562,9 @@ void avcodec_register_all(void) | |
REGISTER_ENCODER(LIBWAVPACK, libwavpack); | |
REGISTER_ENCODER(LIBWEBP_ANIM, libwebp_anim); /* preferred over libwebp */ | |
REGISTER_ENCODER(LIBWEBP, libwebp); | |
+#ifdef SYNO_EVANSPORT_SMD | |
+ REGISTER_ENCODER(H264_SMD, h264_smd); | |
+#endif | |
REGISTER_ENCODER(LIBX264, libx264); | |
REGISTER_ENCODER(LIBX264RGB, libx264rgb); | |
REGISTER_ENCODER(LIBX265, libx265); | |
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h | |
index 4aeb57aed4..b3cd447ed2 100644 | |
--- a/libavcodec/avcodec.h | |
+++ b/libavcodec/avcodec.h | |
@@ -42,6 +42,8 @@ | |
#include "version.h" | |
+#include "synoconfig.h" | |
+ | |
/** | |
* @defgroup libavc Encoding/Decoding Library | |
* @{ | |
@@ -294,6 +296,14 @@ enum AVCodecID { | |
AV_CODEC_ID_TDSC, | |
AV_CODEC_ID_HQ_HQA, | |
+#ifdef SYNO_EVANSPORT_SMD | |
+ AV_CODEC_ID_H264_SYNO, | |
+ AV_CODEC_ID_MPEG2VIDEO_SYNO, | |
+ AV_CODEC_ID_VC1_SYNO, | |
+ AV_CODEC_ID_WMV3_SYNO, | |
+ AV_CODEC_ID_MPEG4_SYNO, | |
+#endif | |
+ | |
AV_CODEC_ID_BRENDER_PIX= MKBETAG('B','P','I','X'), | |
AV_CODEC_ID_Y41P = MKBETAG('Y','4','1','P'), | |
AV_CODEC_ID_ESCAPE130 = MKBETAG('E','1','3','0'), | |
@@ -3701,6 +3711,10 @@ void avcodec_free_frame(AVFrame **frame); | |
*/ | |
int avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options); | |
+#ifdef SYNO_EVANSPORT_SMD | |
+int syno_alloc_packet(AVPacket *avpkt, int size); | |
+#endif | |
+ | |
/** | |
* Close a given AVCodecContext and free all the data associated with it | |
* (but not the AVCodecContext itself). | |
diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c | |
index c1694f3383..7704e4db4a 100644 | |
--- a/libavcodec/codec_desc.c | |
+++ b/libavcodec/codec_desc.c | |
@@ -26,6 +26,8 @@ | |
#include "avcodec.h" | |
#include "version.h" | |
+#include "synoconfig.h" | |
+ | |
#define MT(...) (const char *const[]){ __VA_ARGS__, NULL } | |
static const AVCodecDescriptor codec_descriptors[] = { | |
@@ -1252,6 +1254,43 @@ static const AVCodecDescriptor codec_descriptors[] = { | |
.long_name = NULL_IF_CONFIG_SMALL("Canopus HQ/HQA"), | |
.props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, | |
}, | |
+#ifdef SYNO_EVANSPORT_SMD | |
+ { | |
+ .id = AV_CODEC_ID_WMV3_SYNO, | |
+ .type = AVMEDIA_TYPE_VIDEO, | |
+ .name = "wmv3_smd", | |
+ .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 9 Hardware(SMD) Decoder"), | |
+ .props = AV_CODEC_PROP_LOSSY, | |
+ }, | |
+ { | |
+ .id = AV_CODEC_ID_VC1_SYNO, | |
+ .type = AVMEDIA_TYPE_VIDEO, | |
+ .name = "vc1_smd", | |
+ .long_name = NULL_IF_CONFIG_SMALL("SMPTE VC-1 Hardware(SMD) Decoder"), | |
+ .props = AV_CODEC_PROP_LOSSY, | |
+ }, | |
+ { | |
+ .id = AV_CODEC_ID_MPEG2VIDEO_SYNO, | |
+ .type = AVMEDIA_TYPE_VIDEO, | |
+ .name = "mpeg2video_smd", | |
+ .long_name = NULL_IF_CONFIG_SMALL("MPEG-2 video Hardware(SMD) Decoder"), | |
+ .props = AV_CODEC_PROP_LOSSY, | |
+ }, | |
+ { | |
+ .id = AV_CODEC_ID_MPEG4_SYNO, | |
+ .type = AVMEDIA_TYPE_VIDEO, | |
+ .name = "mpeg4_smd", | |
+ .long_name = NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Hardware(SMD) Decoder"), | |
+ .props = AV_CODEC_PROP_LOSSY, | |
+ }, | |
+ { | |
+ .id = AV_CODEC_ID_H264_SYNO, | |
+ .type = AVMEDIA_TYPE_VIDEO, | |
+ .name = "h264_smd", | |
+ .long_name = NULL_IF_CONFIG_SMALL("H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 Hardware(SMD) Decoder"), | |
+ .props = AV_CODEC_PROP_LOSSY | AV_CODEC_PROP_LOSSLESS, | |
+ }, | |
+#endif | |
/* image codecs */ | |
{ | |
diff --git a/libavcodec/dvbsub.c b/libavcodec/dvbsub.c | |
index dd84a07664..4102087311 100644 | |
--- a/libavcodec/dvbsub.c | |
+++ b/libavcodec/dvbsub.c | |
@@ -22,6 +22,8 @@ | |
#include "bytestream.h" | |
#include "libavutil/colorspace.h" | |
+#include "synoconfig.h" | |
+ | |
typedef struct DVBSubtitleContext { | |
int object_version; | |
} DVBSubtitleContext; | |
@@ -261,6 +263,10 @@ static int encode_dvb_subtitles(DVBSubtitleContext *s, | |
if (h->num_rects && !h->rects) | |
return -1; | |
+#ifndef SYNO_DTV_MPEGTS_DVBSUB_ENCODING | |
+ *q++ = 0x00; /* subtitle_stream_id */ | |
+#endif | |
+ | |
/* page composition segment */ | |
*q++ = 0x0f; /* sync_byte */ | |
@@ -435,6 +441,10 @@ static int encode_dvb_subtitles(DVBSubtitleContext *s, | |
bytestream_put_be16(&pseg_len, q - pseg_len - 2); | |
+#ifndef SYNO_DTV_MPEGTS_DVBSUB_ENCODING | |
+ *q++ = 0xff; /* end of PES data */ | |
+#endif | |
+ | |
s->object_version = (s->object_version + 1) & 0xf; | |
return q - outbuf; | |
} | |
diff --git a/libavcodec/h263.h b/libavcodec/h263.h | |
index 1f954cdf6f..77248a7788 100644 | |
--- a/libavcodec/h263.h | |
+++ b/libavcodec/h263.h | |
@@ -26,6 +26,8 @@ | |
#include "mpegvideo.h" | |
#include "rl.h" | |
+#include "synoconfig.h" | |
+ | |
#if !FF_API_ASPECT_EXTENDED | |
#define FF_ASPECT_EXTENDED 15 | |
#endif | |
@@ -77,13 +79,20 @@ extern uint8_t ff_h263_static_rl_table_store[2][2][2*MAX_RUN + MAX_LEVEL + 3]; | |
extern const enum AVPixelFormat ff_h263_hwaccel_pixfmt_list_420[]; | |
- | |
int ff_h263_decode_motion(MpegEncContext * s, int pred, int f_code); | |
av_const int ff_h263_aspect_to_info(AVRational aspect); | |
int ff_h263_decode_init(AVCodecContext *avctx); | |
+#ifdef SYNO_EVANSPORT_SMD | |
+int ff_h263_decode_init_smd(AVCodecContext *avctx); | |
+#endif | |
int ff_h263_decode_frame(AVCodecContext *avctx, | |
void *data, int *got_frame, | |
AVPacket *avpkt); | |
+#ifdef SYNO_EVANSPORT_SMD | |
+int ff_h263_decode_frame_smd(AVCodecContext *avctx, | |
+ void *data, int *data_size, | |
+ AVPacket *avpkt); | |
+#endif | |
int ff_h263_decode_end(AVCodecContext *avctx); | |
void ff_h263_encode_mb(MpegEncContext *s, | |
int16_t block[6][64], | |
diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c | |
index 15f073ae66..efa533574e 100644 | |
--- a/libavcodec/h263dec.c | |
+++ b/libavcodec/h263dec.c | |
@@ -45,6 +45,16 @@ | |
#include "thread.h" | |
#include "wmv2.h" | |
+#include "synoconfig.h" | |
+ | |
+#ifdef SYNO_EVANSPORT_SMD | |
+#include "libffmpeg_plugin/ismd_ffmpeg_util.h" | |
+#include "libffmpeg_plugin/ismd_ffmpeg_video_dec.h" | |
+#include "libavformat/avformat.h" | |
+static viddec_struct_t smd_mpeg4_vid_dec; | |
+bool smd_mpeg4_vid_dec_available = false; | |
+#endif | |
+ | |
static enum AVPixelFormat h263_get_format(AVCodecContext *avctx) | |
{ | |
if (avctx->codec->id == AV_CODEC_ID_MSS2) | |
@@ -84,6 +94,10 @@ av_cold int ff_h263_decode_init(AVCodecContext *avctx) | |
break; | |
case AV_CODEC_ID_MPEG4: | |
break; | |
+#ifdef SYNO_EVANSPORT_SMD | |
+ case AV_CODEC_ID_MPEG4_SYNO: | |
+ break; | |
+#endif | |
case AV_CODEC_ID_MSMPEG4V1: | |
s->h263_pred = 1; | |
s->msmpeg4_version = 1; | |
@@ -106,6 +120,10 @@ av_cold int ff_h263_decode_init(AVCodecContext *avctx) | |
break; | |
case AV_CODEC_ID_VC1: | |
case AV_CODEC_ID_WMV3: | |
+#ifdef SYNO_EVANSPORT_SMD | |
+ case AV_CODEC_ID_VC1_SYNO: | |
+ case AV_CODEC_ID_WMV3_SYNO: | |
+#endif | |
case AV_CODEC_ID_VC1IMAGE: | |
case AV_CODEC_ID_WMV3IMAGE: | |
case AV_CODEC_ID_MSS2: | |
@@ -130,9 +148,15 @@ av_cold int ff_h263_decode_init(AVCodecContext *avctx) | |
s->ehc_mode = 1; | |
/* for h263, we allocate the images after having read the header */ | |
+#ifdef SYNO_EVANSPORT_SMD | |
+ if (avctx->codec->id != AV_CODEC_ID_H263 && | |
+ avctx->codec->id != AV_CODEC_ID_H263P && | |
+ (avctx->codec->id != AV_CODEC_ID_MPEG4 && avctx->codec->id != AV_CODEC_ID_MPEG4_SYNO)) { | |
+#else | |
if (avctx->codec->id != AV_CODEC_ID_H263 && | |
avctx->codec->id != AV_CODEC_ID_H263P && | |
avctx->codec->id != AV_CODEC_ID_MPEG4) { | |
+#endif | |
avctx->pix_fmt = h263_get_format(avctx); | |
ff_mpv_idct_init(s); | |
if ((ret = ff_mpv_common_init(s)) < 0) | |
@@ -146,11 +170,60 @@ av_cold int ff_h263_decode_init(AVCodecContext *avctx) | |
return 0; | |
} | |
+#ifdef SYNO_EVANSPORT_SMD | |
+av_cold int ff_h263_decode_init_smd(AVCodecContext *avctx) | |
+{ | |
+ ismd_result_t ret_val = ISMD_ERROR_UNSPECIFIED; | |
+ if((avctx->codec_id == AV_CODEC_ID_MSMPEG4V1) || (avctx->codec_id == AV_CODEC_ID_MSMPEG4V2) || (avctx->codec_id == AV_CODEC_ID_MSMPEG4V3)) | |
+ { | |
+ av_log(NULL,AV_LOG_INFO,"\nThis video format is not supported by smd.Falling back to software\n"); | |
+ return 0; | |
+ } | |
+ | |
+ smd_mpeg4_vid_dec.codec = ISMD_CODEC_TYPE_MPEG4; | |
+ // 1. Setup a single stream | |
+ ret_val = ismd_ffmpeg_setup_viddec_stream(&smd_mpeg4_vid_dec); | |
+ if(ISMD_SUCCESS == ret_val) | |
+ { | |
+ // 2. Start the stream | |
+ ret_val = ismd_ffmpeg_start_viddec_stream(&smd_mpeg4_vid_dec); | |
+ } | |
+ if(ret_val != ISMD_SUCCESS) | |
+ { | |
+ av_log(avctx,AV_LOG_INFO,"\nMPEG2 Hardware video decoder not available.Falling Back to software.\n"); | |
+ av_log(avctx,AV_LOG_INFO,"\nMPEG2 can't fall back to software.\n"); | |
+ return -1; | |
+ } | |
+ else | |
+ { | |
+ av_log(avctx,AV_LOG_INFO,"\n******************Using MPEG4 Hardware video decoder**************\n"); | |
+ smd_mpeg4_vid_dec_available = true; | |
+ smd_mpeg4_vid_dec.y_mem = NULL; | |
+ smd_mpeg4_vid_dec.u_mem = NULL; | |
+ smd_mpeg4_vid_dec.v_mem = NULL; | |
+ smd_mpeg4_vid_dec.send_sps_pps = true; | |
+ } | |
+ return 0; | |
+} | |
+#endif | |
+ | |
av_cold int ff_h263_decode_end(AVCodecContext *avctx) | |
{ | |
+#ifdef SYNO_EVANSPORT_SMD | |
+ ismd_result_t ret_val = ISMD_ERROR_UNSPECIFIED; | |
+#endif | |
MpegEncContext *s = avctx->priv_data; | |
ff_mpv_common_end(s); | |
+#ifdef SYNO_EVANSPORT_SMD | |
+ if(smd_mpeg4_vid_dec_available) | |
+ { | |
+ ret_val = ismd_ffmpeg_free_vid_dec_res(&smd_mpeg4_vid_dec); | |
+ if(ret_val != ISMD_SUCCESS) | |
+ av_log(avctx,AV_LOG_ERROR,"could not free video decoder resources\n"); | |
+ } | |
+ smd_mpeg4_vid_dec_available = false; | |
+#endif | |
return 0; | |
} | |
@@ -716,6 +789,80 @@ frame_end: | |
return get_consumed_bytes(s, buf_size); | |
} | |
+#ifdef SYNO_EVANSPORT_SMD | |
+int ff_h263_decode_frame_smd(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) | |
+{ | |
+ ismd_result_t ret_val = ISMD_ERROR_UNSPECIFIED; | |
+ ismd_result_t result = ISMD_ERROR_UNSPECIFIED; | |
+ ismd_buffer_handle_t ismd_buf = -1; | |
+ const uint8_t *buf = avpkt->data; | |
+ int buf_size = avpkt->size; | |
+ AVFrame *pict = data; | |
+ | |
+ int got_frame = 0; | |
+ smd_video_frame decoded_frame; | |
+ struct timespec ts; | |
+ | |
+ if(smd_mpeg4_vid_dec_available) | |
+ { | |
+ //send headers before first packet | |
+ if((smd_mpeg4_vid_dec.send_sps_pps) && (avctx->extradata_size > 0)) | |
+ { | |
+ if ((result = ismd_buffer_alloc(CHUNK_SIZE, &ismd_buf)) == ISMD_SUCCESS) | |
+ { | |
+ if ((result = ismd_ffmpeg_fill_viddec_buffer(avctx->extradata, ismd_buf,avctx->extradata_size)) == ISMD_SUCCESS) | |
+ { | |
+ // decode it asynchronously | |
+ if ((result = ismd_ffmpeg_decoder_port_write(&smd_mpeg4_vid_dec,ismd_buf)) != ISMD_SUCCESS) | |
+ { | |
+ av_log(NULL, AV_LOG_ERROR,"error: unable to decode smd_buffers11 [%d]\n", result); | |
+ } | |
+ } | |
+ } | |
+ else | |
+ { | |
+ av_log(NULL, AV_LOG_INFO,"error: unable to allocate buffer in decode_frame111 [%d]\n", result); | |
+ } | |
+ smd_mpeg4_vid_dec.send_sps_pps = false; | |
+ } | |
+ | |
+ ret_val = ismd_ffmpeg_decode_vid_buf(&smd_mpeg4_vid_dec, buf, buf_size); | |
+ if(ret_val != ISMD_SUCCESS) | |
+ { | |
+ av_log(avctx,AV_LOG_ERROR,"\nismd_ffmpeg_decode_buf failed error:%d buf_size %d\n",ret_val,buf_size); | |
+ return -1; | |
+ } | |
+ ts.tv_sec = 0; | |
+ ts.tv_nsec = 10; | |
+ nanosleep (&ts, NULL); | |
+ | |
+ ismd_ffmpeg_get_decoded_data(&decoded_frame, &smd_mpeg4_vid_dec, &got_frame); | |
+ if(got_frame) | |
+ { | |
+ *data_size = sizeof(AVFrame); | |
+ avctx->width = decoded_frame.width; | |
+ avctx->height = decoded_frame.height; | |
+ avctx->pix_fmt = PIX_FMT_YUV420P; | |
+ | |
+ pict->pkt_pts = AV_NOPTS_VALUE; | |
+ pict->pts = AV_NOPTS_VALUE ; | |
+ pict->data[0] = (uint8_t*)decoded_frame.y_mem; | |
+ pict->data[1] = (uint8_t*)decoded_frame.u_mem; | |
+ pict->data[2] = (uint8_t*)decoded_frame.v_mem; | |
+ pict->linesize[0] = decoded_frame.linesize_y; | |
+ pict->linesize[1] = decoded_frame.linesize_u; | |
+ pict->linesize[2] = decoded_frame.linesize_v; | |
+ | |
+ } | |
+ return buf_size; | |
+ } | |
+ else | |
+ { | |
+ return ff_h263_decode_frame(avctx, data, data_size, avpkt); | |
+ } | |
+} | |
+#endif | |
+ | |
const enum AVPixelFormat ff_h263_hwaccel_pixfmt_list_420[] = { | |
#if CONFIG_H263_VAAPI_HWACCEL || CONFIG_MPEG4_VAAPI_HWACCEL | |
AV_PIX_FMT_VAAPI_VLD, | |
diff --git a/libavcodec/h264.c b/libavcodec/h264.c | |
index 9a002142cc..b73d84d488 100644 | |
--- a/libavcodec/h264.c | |
+++ b/libavcodec/h264.c | |
@@ -51,6 +51,17 @@ | |
#include "thread.h" | |
#include "vdpau_compat.h" | |
+#include "synoconfig.h" | |
+#include "synog1codecpatent.h" | |
+ | |
+#ifdef SYNO_EVANSPORT_SMD | |
+#include "libffmpeg_plugin/ismd_ffmpeg_util.h" | |
+#include "libffmpeg_plugin/ismd_ffmpeg_video_dec.h" | |
+#include "libavformat/avformat.h" | |
+static viddec_struct_t smd_h264_vid_dec; | |
+bool smd_h264_vid_dec_available = false; | |
+#endif | |
+ | |
const uint16_t ff_h264_mb_sizes[4] = { 256, 384, 512, 768 }; | |
int avpriv_h264_has_num_reorder_frames(AVCodecContext *avctx) | |
@@ -646,6 +657,12 @@ av_cold int ff_h264_decode_init(AVCodecContext *avctx) | |
H264Context *h = avctx->priv_data; | |
int ret; | |
+#ifdef SYNO_CODEC_PATENT_G1 | |
+ if (0 != ActivateCodec("h264_dec")) { | |
+ return -1; | |
+ } | |
+#endif | |
+ | |
ret = h264_init_context(avctx, h); | |
if (ret < 0) | |
return ret; | |
@@ -658,7 +675,11 @@ av_cold int ff_h264_decode_init(AVCodecContext *avctx) | |
ff_init_cabac_states(); | |
+#ifdef SYNO_EVANSPORT_SMD | |
+ if (avctx->codec_id == AV_CODEC_ID_H264 || avctx->codec_id == AV_CODEC_ID_H264_SYNO) { | |
+#else | |
if (avctx->codec_id == AV_CODEC_ID_H264) { | |
+#endif | |
if (avctx->ticks_per_frame == 1) { | |
if(h->avctx->time_base.den < INT_MAX/2) { | |
h->avctx->time_base.den *= 2; | |
@@ -698,6 +719,41 @@ av_cold int ff_h264_decode_init(AVCodecContext *avctx) | |
return 0; | |
} | |
+#ifdef SYNO_EVANSPORT_SMD | |
+static av_cold int ff_h264_decode_init_smd(AVCodecContext *avctx){ | |
+ ismd_result_t ret_val = ISMD_ERROR_UNSPECIFIED; | |
+ int result; | |
+ result = ff_h264_decode_init(avctx); | |
+ | |
+ /********************* SMD code *******************/ | |
+ smd_h264_vid_dec.codec = ISMD_CODEC_TYPE_H264; | |
+ // 1. Setup a single stream | |
+ ret_val = ismd_ffmpeg_setup_viddec_stream(&smd_h264_vid_dec); | |
+ if(ISMD_SUCCESS == ret_val) | |
+ { | |
+ // 2. Start the stream | |
+ ret_val = ismd_ffmpeg_start_viddec_stream(&smd_h264_vid_dec); | |
+ } | |
+ if(ret_val != ISMD_SUCCESS) | |
+ { | |
+ av_log(avctx,AV_LOG_INFO,"\nH.264 Hardware video decoder not available.\n"); | |
+ av_log(avctx,AV_LOG_INFO,"\nH.264 can't fall back to software.\n"); | |
+ result = -1; | |
+ } | |
+ else | |
+ { | |
+ av_log(avctx,AV_LOG_INFO,"\n******************Using H.264 Hardware video decoder**************\n"); | |
+ smd_h264_vid_dec_available = true; | |
+ smd_h264_vid_dec.y_mem = NULL; | |
+ smd_h264_vid_dec.u_mem = NULL; | |
+ smd_h264_vid_dec.v_mem = NULL; | |
+ smd_h264_vid_dec.send_sps_pps = true; | |
+ } | |
+ return result; | |
+ /********************** SMD END *********************/ | |
+} | |
+#endif | |
+ | |
static int decode_init_thread_copy(AVCodecContext *avctx) | |
{ | |
H264Context *h = avctx->priv_data; | |
@@ -1848,6 +1904,129 @@ static int h264_decode_frame(AVCodecContext *avctx, void *data, | |
return get_consumed_bytes(buf_index, buf_size); | |
} | |
+#ifdef SYNO_EVANSPORT_SMD | |
+static int h264_decode_frame_smd(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) | |
+{ | |
+ ismd_result_t ret_val = ISMD_ERROR_UNSPECIFIED; | |
+ const uint8_t *buf = avpkt->data; | |
+ int buf_size = avpkt->size; | |
+ H264Context *h = avctx->priv_data; | |
+ AVFrame *pict = data; | |
+ uint8_t* buf_with_start_code =NULL; | |
+ int new_buf_size = buf_size; | |
+ uint8_t* sps_pps_buf =NULL; | |
+ /**************************** SMD **********************************/ | |
+ ismd_buffer_handle_t ismd_buf = -1; | |
+ int sps_pps_buf_size =0; | |
+ ismd_result_t result = ISMD_SUCCESS; | |
+ int got_frame = 0; | |
+ smd_video_frame decoded_frame; | |
+ struct timespec ts; | |
+ if(smd_h264_vid_dec_available) | |
+ { | |
+ if(buf_size > 4) | |
+ { | |
+ if(h->is_avc) | |
+ { | |
+ av_log(NULL,AV_LOG_DEBUG,"\nh.264 content is in avc1 format\n"); | |
+ //in most of the cases h->nal_length_size is 4.This fields contains | |
+ //total length of the following nal unit. | |
+ //start code length is also 4 so you don't need | |
+ //to allocate buffer more than avpkt->size because you can write insert | |
+ //start code in place of h->nal_length_size field | |
+ //but this may not work when h->nal_length_size is 2 which is very rare | |
+ | |
+ buf_with_start_code = av_malloc(avpkt->size);//allocate memory for new buffer | |
+ if(buf_with_start_code == NULL) | |
+ { | |
+ av_log(NULL,AV_LOG_ERROR,"\ncould not allocate memory for new buffer \n"); | |
+ assert(0); | |
+ } | |
+ if((smd_h264_vid_dec.send_sps_pps) && avctx->extradata_size > 0 && avctx->extradata) | |
+ { | |
+ sps_pps_buf_size = ismd_ffmpeg_h264_viddec_extract_sps_pps(avctx->extradata,avctx->extradata_size, &sps_pps_buf); | |
+ } | |
+ | |
+ new_buf_size = ismd_ffmpeg_unit_to_byte_stream(&buf_with_start_code, buf, avpkt->size, h->nal_length_size); | |
+ } | |
+ else | |
+ { | |
+ buf_with_start_code = buf;//incoming buffer is in Byte-stream format.no conversion req. | |
+ } | |
+ } | |
+ /*********** write sps/pps buffer for avc1 at decoder i/p port*********************/ | |
+ //send sps pps before first packet | |
+ if((smd_h264_vid_dec.send_sps_pps) && h->is_avc) | |
+ { | |
+ if ((result = ismd_buffer_alloc(CHUNK_SIZE, &ismd_buf)) == ISMD_SUCCESS) | |
+ { | |
+ av_log(NULL, AV_LOG_DEBUG,"\n********* sending sps pps buffer write size %d ********\n",sps_pps_buf_size); | |
+ av_log(NULL,AV_LOG_DEBUG,"\n sps_pps_buf %p\n",sps_pps_buf); | |
+ if ((result = ismd_ffmpeg_fill_viddec_buffer(sps_pps_buf, ismd_buf,sps_pps_buf_size)) == ISMD_SUCCESS) | |
+ { | |
+ // decode it asynchronously | |
+ if ((result = ismd_ffmpeg_decoder_port_write(&smd_h264_vid_dec,ismd_buf)) != ISMD_SUCCESS) | |
+ { | |
+ av_log(NULL, AV_LOG_ERROR,"error: unable to decode smd_buffers11 [%d]\n", result); | |
+ } | |
+ | |
+ } | |
+ } | |
+ else | |
+ { | |
+ av_log(NULL, AV_LOG_INFO,"error: unable to allocate buffer in decode_frame111 [%d]\n", result); | |
+ } | |
+ smd_h264_vid_dec.send_sps_pps = false; | |
+ } | |
+ | |
+ ret_val = ismd_ffmpeg_decode_vid_buf(&smd_h264_vid_dec, buf_with_start_code, new_buf_size); | |
+ if(ret_val != ISMD_SUCCESS) | |
+ { | |
+ av_log(avctx,AV_LOG_ERROR,"\nismd_ffmpeg_decode_vid_buf failed error:%d \n",ret_val); | |
+ return -1; | |
+ } | |
+ | |
+ if((h->is_avc)&& buf_with_start_code) | |
+ { | |
+ av_free(buf_with_start_code); | |
+ buf_with_start_code = NULL; | |
+ } | |
+ | |
+ /**************** SMD port Read **********************/ | |
+ ts.tv_sec = 0; | |
+ ts.tv_nsec = 10; | |
+ nanosleep (&ts, NULL); | |
+ | |
+ ismd_ffmpeg_get_decoded_data(&decoded_frame, &smd_h264_vid_dec, &got_frame); | |
+ | |
+ if(got_frame) | |
+ { | |
+ av_log(NULL,AV_LOG_DEBUG,"\n$$$$$$ width %d height %d linesize[0] %d linesize[1] %d linesize[2] %d\n",decoded_frame.width,decoded_frame.height,decoded_frame.linesize_y,decoded_frame.linesize_u,decoded_frame.linesize_v); | |
+ *data_size = sizeof(AVFrame); | |
+ avctx->width = decoded_frame.width; | |
+ avctx->height = decoded_frame.height; | |
+ avctx->pix_fmt = PIX_FMT_YUV420P; | |
+ | |
+ pict->pkt_pts = AV_NOPTS_VALUE; | |
+ pict->pts = AV_NOPTS_VALUE ; | |
+ pict->data[0] = (uint8_t*)decoded_frame.y_mem; | |
+ pict->data[1] = (uint8_t*)decoded_frame.u_mem; | |
+ pict->data[2] = (uint8_t*)decoded_frame.v_mem; | |
+ pict->linesize[0] = decoded_frame.linesize_y; | |
+ pict->linesize[1] = decoded_frame.linesize_u; | |
+ pict->linesize[2] = decoded_frame.linesize_v; | |
+ } | |
+ | |
+ /********************** SMD port read END ************************************/ | |
+ return buf_size; | |
+ } | |
+ else | |
+ { | |
+ return h264_decode_frame(avctx, data, data_size, avpkt); | |
+ } | |
+} | |
+#endif | |
+ | |
av_cold void ff_h264_free_context(H264Context *h) | |
{ | |
int i; | |
@@ -1876,6 +2055,9 @@ av_cold void ff_h264_free_context(H264Context *h) | |
static av_cold int h264_decode_end(AVCodecContext *avctx) | |
{ | |
+#ifdef SYNO_EVANSPORT_SMD | |
+ ismd_result_t ret_val = ISMD_ERROR_UNSPECIFIED; | |
+#endif | |
H264Context *h = avctx->priv_data; | |
ff_h264_remove_all_refs(h); | |
@@ -1886,6 +2068,16 @@ static av_cold int h264_decode_end(AVCodecContext *avctx) | |
ff_h264_unref_picture(h, &h->last_pic_for_ec); | |
av_frame_free(&h->last_pic_for_ec.f); | |
+#ifdef SYNO_EVANSPORT_SMD | |
+ if(smd_h264_vid_dec_available) | |
+ { | |
+ ret_val = ismd_ffmpeg_free_vid_dec_res(&smd_h264_vid_dec); | |
+ if(ret_val != ISMD_SUCCESS) | |
+ av_log(avctx,AV_LOG_ERROR,"could not free video decoder resources\n"); | |
+ } | |
+ smd_h264_vid_dec_available = false; | |
+#endif | |
+ | |
return 0; | |
} | |
@@ -1898,6 +2090,14 @@ static const AVOption h264_options[] = { | |
{ NULL }, | |
}; | |
+#ifdef SYNO_EVANSPORT_SMD | |
+static const AVOption h264_options_smd[] = { | |
+ {"is_avc", "is avc", offsetof(H264Context, is_avc), FF_OPT_TYPE_INT, {.i64 = 0}, 0, 1, 0}, | |
+ {"nal_length_size", "nal_length_size", offsetof(H264Context, nal_length_size), FF_OPT_TYPE_INT, {.i64 = 0}, 0, 4, 0}, | |
+ {NULL} | |
+}; | |
+#endif | |
+ | |
static const AVClass h264_class = { | |
.class_name = "H264 Decoder", | |
.item_name = av_default_item_name, | |
@@ -1905,6 +2105,15 @@ static const AVClass h264_class = { | |
.version = LIBAVUTIL_VERSION_INT, | |
}; | |
+#ifdef SYNO_EVANSPORT_SMD | |
+static const AVClass h264_class_smd = { | |
+ .class_name = "H264 Decoder", | |
+ .item_name = av_default_item_name, | |
+ .option = h264_options_smd, | |
+ .version = LIBAVUTIL_VERSION_INT, | |
+}; | |
+#endif | |
+ | |
static const AVProfile profiles[] = { | |
{ FF_PROFILE_H264_BASELINE, "Baseline" }, | |
{ FF_PROFILE_H264_CONSTRAINED_BASELINE, "Constrained Baseline" }, | |
@@ -1941,6 +2150,25 @@ AVCodec ff_h264_decoder = { | |
.priv_class = &h264_class, | |
}; | |
+#ifdef SYNO_EVANSPORT_SMD | |
+AVCodec ff_h264_smd_decoder = { | |
+ .name = "h264_smd", | |
+ .long_name = NULL_IF_CONFIG_SMALL("H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 Hardware(SMD) Decoder"), | |
+ .type = AVMEDIA_TYPE_VIDEO, | |
+ .id = AV_CODEC_ID_H264_SYNO, | |
+ .priv_data_size = sizeof(H264Context), | |
+ .init = ff_h264_decode_init_smd, | |
+ .close = h264_decode_end, | |
+ .decode = h264_decode_frame_smd, | |
+ .capabilities = CODEC_CAP_DELAY, | |
+ .flush = flush_dpb, | |
+ .init_thread_copy = ONLY_IF_THREADS_ENABLED(decode_init_thread_copy), | |
+ .update_thread_context = ONLY_IF_THREADS_ENABLED(ff_h264_update_thread_context), | |
+ .profiles = NULL_IF_CONFIG_SMALL(profiles), | |
+ .priv_class = &h264_class_smd, | |
+}; | |
+#endif | |
+ | |
#if CONFIG_H264_VDPAU_DECODER | |
static const AVClass h264_vdpau_class = { | |
.class_name = "H264 VDPAU Decoder", | |
diff --git a/libavcodec/h264_mp4toannexb_bsf.c b/libavcodec/h264_mp4toannexb_bsf.c | |
index ae96ee953d..237b1087ef 100644 | |
--- a/libavcodec/h264_mp4toannexb_bsf.c | |
+++ b/libavcodec/h264_mp4toannexb_bsf.c | |
@@ -25,6 +25,8 @@ | |
#include "libavutil/mem.h" | |
#include "avcodec.h" | |
+#include "synoconfig.h" | |
+ | |
typedef struct H264BSFContext { | |
int32_t sps_offset; | |
int32_t pps_offset; | |
@@ -150,6 +152,15 @@ static int h264_mp4toannexb_filter(AVBitStreamFilterContext *bsfc, | |
const uint8_t *buf_end = buf + buf_size; | |
int ret = 0; | |
+#ifdef SYNO_VIDEOSTATION_REMUX_REPEAT_HEADER | |
+ uint8_t repeatheader = 0; | |
+ uint8_t last_unit_type = 0; | |
+ if (args && !strncmp(args, "repeatheader", 12)) { | |
+ av_log(avctx, AV_LOG_DEBUG, "Repeat SPS/PPS for every IDR Slice\n"); | |
+ repeatheader = 1; | |
+ } | |
+#endif | |
+ | |
/* nothing to filter */ | |
if (!avctx->extradata || avctx->extradata_size < 6) { | |
*poutbuf = (uint8_t *)buf; | |
@@ -229,6 +240,14 @@ static int h264_mp4toannexb_filter(AVBitStreamFilterContext *bsfc, | |
avctx->extradata + ctx->pps_offset, avctx->extradata_size - ctx->pps_offset, | |
buf, nal_size)) < 0) | |
goto fail; | |
+#ifdef SYNO_VIDEOSTATION_REMUX_REPEAT_HEADER | |
+ } else if (ctx->new_idr && repeatheader && unit_type == 5 && last_unit_type != 8) { | |
+ if ((ret=alloc_and_copy(poutbuf, poutbuf_size, | |
+ avctx->extradata, avctx->extradata_size, | |
+ buf, nal_size)) < 0) { | |
+ goto fail; | |
+ } | |
+#endif | |
} else { | |
if ((ret=alloc_and_copy(poutbuf, poutbuf_size, | |
NULL, 0, buf, nal_size)) < 0) | |
@@ -243,6 +262,9 @@ static int h264_mp4toannexb_filter(AVBitStreamFilterContext *bsfc, | |
next_nal: | |
buf += nal_size; | |
cumul_size += nal_size + ctx->length_size; | |
+#ifdef SYNO_VIDEOSTATION_REMUX_REPEAT_HEADER | |
+ last_unit_type = unit_type; | |
+#endif | |
} while (cumul_size < buf_size); | |
return 1; | |
diff --git a/libavcodec/h264_parser.c b/libavcodec/h264_parser.c | |
index 19d1aa3f21..1ef7610858 100644 | |
--- a/libavcodec/h264_parser.c | |
+++ b/libavcodec/h264_parser.c | |
@@ -34,6 +34,8 @@ | |
#include "internal.h" | |
#include "mpegutils.h" | |
+#include "synoconfig.h" | |
+ | |
typedef struct H264ParseContext { | |
H264Context h; | |
ParseContext pc; | |
@@ -85,8 +87,13 @@ static int h264_find_frame_end(H264ParseContext *p, const uint8_t *buf, | |
state >>= 1; // 2->1, 1->0, 0->0 | |
} else if (state <= 5) { | |
int nalu_type = buf[i] & 0x1F; | |
+#ifdef SYNO_FIX_MP4_REMUX_H264PARSER | |
+ if (nalu_type == NAL_SEI || nalu_type == NAL_SPS || | |
+ nalu_type == NAL_AUD) { | |
+#else | |
if (nalu_type == NAL_SEI || nalu_type == NAL_SPS || | |
nalu_type == NAL_PPS || nalu_type == NAL_AUD) { | |
+#endif | |
if (pc->frame_start_found) { | |
i++; | |
goto found; | |
@@ -618,7 +625,11 @@ static av_cold int init(AVCodecParserContext *s) | |
} | |
AVCodecParser ff_h264_parser = { | |
+#ifdef SYNO_EVANSPORT_SMD | |
+ .codec_ids = { AV_CODEC_ID_H264, AV_CODEC_ID_H264_SYNO }, | |
+#else | |
.codec_ids = { AV_CODEC_ID_H264 }, | |
+#endif | |
.priv_data_size = sizeof(H264ParseContext), | |
.parser_init = init, | |
.parser_parse = h264_parse, | |
diff --git a/libavcodec/h264_smd.h b/libavcodec/h264_smd.h | |
new file mode 100644 | |
index 0000000000..9e33b08fa6 | |
--- /dev/null | |
+++ b/libavcodec/h264_smd.h | |
@@ -0,0 +1,804 @@ | |
+/* | |
+ * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder | |
+ * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> | |
+ * | |
+ * This file is part of FFmpeg. | |
+ * | |
+ * FFmpeg 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. | |
+ * | |
+ * FFmpeg 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 FFmpeg; if not, write to the Free Software | |
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
+ */ | |
+ | |
+/** | |
+ * @file | |
+ * H.264 / AVC / MPEG4 part10 codec. | |
+ * @author Michael Niedermayer <michaelni@gmx.at> | |
+ */ | |
+ | |
+#ifndef AVCODEC_H264_H | |
+#define AVCODEC_H264_H | |
+ | |
+#include "synoconfig.h" | |
+ | |
+#ifdef SYNO_EVANSPORT_SMD | |
+ | |
+#include "libavutil/intreadwrite.h" | |
+#include "cabac.h" | |
+#include "error_resilience.h" | |
+#include "get_bits.h" | |
+#include "h264chroma.h" | |
+#include "h264dsp.h" | |
+#include "h264pred.h" | |
+#include "h264qpel.h" | |
+#include "internal.h" | |
+#include "mpegutils.h" | |
+#include "parser.h" | |
+#include "qpeldsp.h" | |
+#include "rectangle.h" | |
+#include "videodsp.h" | |
+ | |
+#define H264_MAX_PICTURE_COUNT 36 | |
+#define H264_MAX_THREADS 32 | |
+ | |
+#define MAX_SPS_COUNT 32 | |
+#define MAX_PPS_COUNT 256 | |
+ | |
+#define MAX_MMCO_COUNT 66 | |
+ | |
+#define MAX_DELAYED_PIC_COUNT 16 | |
+ | |
+#define MAX_MBPAIR_SIZE (256*1024) // a tighter bound could be calculated if someone cares about a few bytes | |
+ | |
+/* Compiling in interlaced support reduces the speed | |
+ * of progressive decoding by about 2%. */ | |
+#define ALLOW_INTERLACE | |
+ | |
+#define FMO 0 | |
+ | |
+/** | |
+ * The maximum number of slices supported by the decoder. | |
+ * must be a power of 2 | |
+ */ | |
+#define MAX_SLICES 32 | |
+ | |
+#ifdef ALLOW_INTERLACE | |
+#define MB_MBAFF(h) (h)->mb_mbaff | |
+#define MB_FIELD(sl) (sl)->mb_field_decoding_flag | |
+#define FRAME_MBAFF(h) (h)->mb_aff_frame | |
+#define FIELD_PICTURE(h) ((h)->picture_structure != PICT_FRAME) | |
+#define LEFT_MBS 2 | |
+#define LTOP 0 | |
+#define LBOT 1 | |
+#define LEFT(i) (i) | |
+#else | |
+#define MB_MBAFF(h) 0 | |
+#define MB_FIELD(sl) 0 | |
+#define FRAME_MBAFF(h) 0 | |
+#define FIELD_PICTURE(h) 0 | |
+#undef IS_INTERLACED | |
+#define IS_INTERLACED(mb_type) 0 | |
+#define LEFT_MBS 1 | |
+#define LTOP 0 | |
+#define LBOT 0 | |
+#define LEFT(i) 0 | |
+#endif | |
+#define FIELD_OR_MBAFF_PICTURE(h) (FRAME_MBAFF(h) || FIELD_PICTURE(h)) | |
+ | |
+#ifndef CABAC | |
+#define CABAC(h) (h)->pps.cabac | |
+#endif | |
+ | |
+#define CHROMA(h) ((h)->sps.chroma_format_idc) | |
+#define CHROMA422(h) ((h)->sps.chroma_format_idc == 2) | |
+#define CHROMA444(h) ((h)->sps.chroma_format_idc == 3) | |
+ | |
+#define EXTENDED_SAR 255 | |
+ | |
+#define MB_TYPE_REF0 MB_TYPE_ACPRED // dirty but it fits in 16 bit | |
+#define MB_TYPE_8x8DCT 0x01000000 | |
+#define IS_REF0(a) ((a) & MB_TYPE_REF0) | |
+#define IS_8x8DCT(a) ((a) & MB_TYPE_8x8DCT) | |
+ | |
+#define QP_MAX_NUM (51 + 6*6) // The maximum supported qp | |
+ | |
+/* NAL unit types */ | |
+enum { | |
+ NAL_SLICE_SMD = 1, | |
+ NAL_DPA_SMD = 2, | |
+ NAL_DPB_SMD = 3, | |
+ NAL_DPC_SMD = 4, | |
+ NAL_IDR_SLICE_SMD = 5, | |
+ NAL_SEI_SMD = 6, | |
+ NAL_SPS_SMD = 7, | |
+ NAL_PPS_SMD = 8, | |
+ NAL_AUD_SMD = 9, | |
+ NAL_END_SEQUENCE_SMD = 10, | |
+ NAL_END_STREAM_SMD = 11, | |
+ NAL_FILLER_DATA_SMD = 12, | |
+ NAL_SPS_EXT_SMD = 13, | |
+ NAL_AUXILIARY_SLICE_SMD = 19, | |
+ NAL_FF_IGNORE_SMD = 0xff0f001, | |
+}; | |
+ | |
+/** | |
+ * SEI message types | |
+ */ | |
+typedef enum { | |
+ SEI_TYPE_BUFFERING_PERIOD = 0, ///< buffering period (H.264, D.1.1) | |
+ SEI_TYPE_PIC_TIMING = 1, ///< picture timing | |
+ SEI_TYPE_USER_DATA_ITU_T_T35 = 4, ///< user data registered by ITU-T Recommendation T.35 | |
+ SEI_TYPE_USER_DATA_UNREGISTERED = 5, ///< unregistered user data | |
+ SEI_TYPE_RECOVERY_POINT = 6, ///< recovery point (frame # to decoder sync) | |
+ SEI_TYPE_FRAME_PACKING = 45, ///< frame packing arrangement | |
+ SEI_TYPE_DISPLAY_ORIENTATION = 47, ///< display orientation | |
+} SEI_Type; | |
+ | |
+/** | |
+ * pic_struct in picture timing SEI message | |
+ */ | |
+typedef enum { | |
+ SEI_PIC_STRUCT_FRAME = 0, ///< 0: %frame | |
+ SEI_PIC_STRUCT_TOP_FIELD = 1, ///< 1: top field | |
+ SEI_PIC_STRUCT_BOTTOM_FIELD = 2, ///< 2: bottom field | |
+ SEI_PIC_STRUCT_TOP_BOTTOM = 3, ///< 3: top field, bottom field, in that order | |
+ SEI_PIC_STRUCT_BOTTOM_TOP = 4, ///< 4: bottom field, top field, in that order | |
+ SEI_PIC_STRUCT_TOP_BOTTOM_TOP = 5, ///< 5: top field, bottom field, top field repeated, in that order | |
+ SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM = 6, ///< 6: bottom field, top field, bottom field repeated, in that order | |
+ SEI_PIC_STRUCT_FRAME_DOUBLING = 7, ///< 7: %frame doubling | |
+ SEI_PIC_STRUCT_FRAME_TRIPLING = 8 ///< 8: %frame tripling | |
+} SEI_PicStructType; | |
+ | |
+/** | |
+ * frame_packing_arrangement types | |
+ */ | |
+typedef enum { | |
+ SEI_FPA_TYPE_CHECKERBOARD = 0, | |
+ SEI_FPA_TYPE_INTERLEAVE_COLUMN = 1, | |
+ SEI_FPA_TYPE_INTERLEAVE_ROW = 2, | |
+ SEI_FPA_TYPE_SIDE_BY_SIDE = 3, | |
+ SEI_FPA_TYPE_TOP_BOTTOM = 4, | |
+ SEI_FPA_TYPE_INTERLEAVE_TEMPORAL = 5, | |
+ SEI_FPA_TYPE_2D = 6, | |
+} SEI_FpaType; | |
+ | |
+/** | |
+ * Sequence parameter set | |
+ */ | |
+typedef struct SPS { | |
+ unsigned int sps_id; | |
+ int profile_idc; | |
+ int level_idc; | |
+ int chroma_format_idc; | |
+ int transform_bypass; ///< qpprime_y_zero_transform_bypass_flag | |
+ int log2_max_frame_num; ///< log2_max_frame_num_minus4 + 4 | |
+ int poc_type; ///< pic_order_cnt_type | |
+ int log2_max_poc_lsb; ///< log2_max_pic_order_cnt_lsb_minus4 | |
+ int delta_pic_order_always_zero_flag; | |
+ int offset_for_non_ref_pic; | |
+ int offset_for_top_to_bottom_field; | |
+ int poc_cycle_length; ///< num_ref_frames_in_pic_order_cnt_cycle | |
+ int ref_frame_count; ///< num_ref_frames | |
+ int gaps_in_frame_num_allowed_flag; | |
+ int mb_width; ///< pic_width_in_mbs_minus1 + 1 | |
+ int mb_height; ///< pic_height_in_map_units_minus1 + 1 | |
+ int frame_mbs_only_flag; | |
+ int mb_aff; ///< mb_adaptive_frame_field_flag | |
+ int direct_8x8_inference_flag; | |
+ int crop; ///< frame_cropping_flag | |
+ | |
+ /* those 4 are already in luma samples */ | |
+ unsigned int crop_left; ///< frame_cropping_rect_left_offset | |
+ unsigned int crop_right; ///< frame_cropping_rect_right_offset | |
+ unsigned int crop_top; ///< frame_cropping_rect_top_offset | |
+ unsigned int crop_bottom; ///< frame_cropping_rect_bottom_offset | |
+ int vui_parameters_present_flag; | |
+ AVRational sar; | |
+ int video_signal_type_present_flag; | |
+ int full_range; | |
+ int colour_description_present_flag; | |
+ enum AVColorPrimaries color_primaries; | |
+ enum AVColorTransferCharacteristic color_trc; | |
+ enum AVColorSpace colorspace; | |
+ int timing_info_present_flag; | |
+ uint32_t num_units_in_tick; | |
+ uint32_t time_scale; | |
+ int fixed_frame_rate_flag; | |
+ short offset_for_ref_frame[256]; // FIXME dyn aloc? | |
+ int bitstream_restriction_flag; | |
+ int num_reorder_frames; | |
+ int scaling_matrix_present; | |
+ uint8_t scaling_matrix4[6][16]; | |
+ uint8_t scaling_matrix8[6][64]; | |
+ int nal_hrd_parameters_present_flag; | |
+ int vcl_hrd_parameters_present_flag; | |
+ int pic_struct_present_flag; | |
+ int time_offset_length; | |
+ int cpb_cnt; ///< See H.264 E.1.2 | |
+ int initial_cpb_removal_delay_length; ///< initial_cpb_removal_delay_length_minus1 + 1 | |
+ int cpb_removal_delay_length; ///< cpb_removal_delay_length_minus1 + 1 | |
+ int dpb_output_delay_length; ///< dpb_output_delay_length_minus1 + 1 | |
+ int bit_depth_luma; ///< bit_depth_luma_minus8 + 8 | |
+ int bit_depth_chroma; ///< bit_depth_chroma_minus8 + 8 | |
+ int residual_color_transform_flag; ///< residual_colour_transform_flag | |
+ int constraint_set_flags; ///< constraint_set[0-3]_flag | |
+ int new; ///< flag to keep track if the decoder context needs re-init due to changed SPS | |
+} SPS; | |
+ | |
+/** | |
+ * Picture parameter set | |
+ */ | |
+typedef struct PPS { | |
+ unsigned int sps_id; | |
+ int cabac; ///< entropy_coding_mode_flag | |
+ int pic_order_present; ///< pic_order_present_flag | |
+ int slice_group_count; ///< num_slice_groups_minus1 + 1 | |
+ int mb_slice_group_map_type; | |
+ unsigned int ref_count[2]; ///< num_ref_idx_l0/1_active_minus1 + 1 | |
+ int weighted_pred; ///< weighted_pred_flag | |
+ int weighted_bipred_idc; | |
+ int init_qp; ///< pic_init_qp_minus26 + 26 | |
+ int init_qs; ///< pic_init_qs_minus26 + 26 | |
+ int chroma_qp_index_offset[2]; | |
+ int deblocking_filter_parameters_present; ///< deblocking_filter_parameters_present_flag | |
+ int constrained_intra_pred; ///< constrained_intra_pred_flag | |
+ int redundant_pic_cnt_present; ///< redundant_pic_cnt_present_flag | |
+ int transform_8x8_mode; ///< transform_8x8_mode_flag | |
+ uint8_t scaling_matrix4[6][16]; | |
+ uint8_t scaling_matrix8[6][64]; | |
+ uint8_t chroma_qp_table[2][QP_MAX_NUM+1]; ///< pre-scaled (with chroma_qp_index_offset) version of qp_table | |
+ int chroma_qp_diff; | |
+} PPS; | |
+ | |
+/** | |
+ * Frame Packing Arrangement Type | |
+ */ | |
+typedef struct FPA { | |
+ int frame_packing_arrangement_id; | |
+ int frame_packing_arrangement_cancel_flag; ///< is previous arrangement canceled, -1 if never received | |
+ SEI_FpaType frame_packing_arrangement_type; | |
+ int frame_packing_arrangement_repetition_period; | |
+ int content_interpretation_type; | |
+ int quincunx_sampling_flag; | |
+} FPA; | |
+ | |
+/** | |
+ * Memory management control operation opcode. | |
+ */ | |
+typedef enum MMCOOpcode { | |
+ MMCO_END = 0, | |
+ MMCO_SHORT2UNUSED, | |
+ MMCO_LONG2UNUSED, | |
+ MMCO_SHORT2LONG, | |
+ MMCO_SET_MAX_LONG, | |
+ MMCO_RESET, | |
+ MMCO_LONG, | |
+} MMCOOpcode; | |
+ | |
+/** | |
+ * Memory management control operation. | |
+ */ | |
+typedef struct MMCO { | |
+ MMCOOpcode opcode; | |
+ int short_pic_num; ///< pic_num without wrapping (pic_num & max_pic_num) | |
+ int long_arg; ///< index, pic_num, or num long refs depending on opcode | |
+} MMCO; | |
+ | |
+typedef struct H264Picture { | |
+ AVFrame *f; | |
+ ThreadFrame tf; | |
+ | |
+ AVBufferRef *qscale_table_buf; | |
+ int8_t *qscale_table; | |
+ | |
+ AVBufferRef *motion_val_buf[2]; | |
+ int16_t (*motion_val[2])[2]; | |
+ | |
+ AVBufferRef *mb_type_buf; | |
+ uint32_t *mb_type; | |
+ | |
+ AVBufferRef *hwaccel_priv_buf; | |
+ void *hwaccel_picture_private; ///< hardware accelerator private data | |
+ | |
+ AVBufferRef *ref_index_buf[2]; | |
+ int8_t *ref_index[2]; | |
+ | |
+ int field_poc[2]; ///< top/bottom POC | |
+ int poc; ///< frame POC | |
+ int frame_num; ///< frame_num (raw frame_num from slice header) | |
+ int mmco_reset; /**< MMCO_RESET set this 1. Reordering code must | |
+ not mix pictures before and after MMCO_RESET. */ | |
+ int pic_id; /**< pic_num (short -> no wrap version of pic_num, | |
+ pic_num & max_pic_num; long -> long_pic_num) */ | |
+ int long_ref; ///< 1->long term reference 0->short term reference | |
+ int ref_poc[2][2][32]; ///< POCs of the frames/fields used as reference (FIXME need per slice) | |
+ int ref_count[2][2]; ///< number of entries in ref_poc (FIXME need per slice) | |
+ int mbaff; ///< 1 -> MBAFF frame 0-> not MBAFF | |
+ int field_picture; ///< whether or not picture was encoded in separate fields | |
+ | |
+ int reference; | |
+ int recovered; ///< picture at IDR or recovery point + recovery count | |
+ int invalid_gap; | |
+ int sei_recovery_frame_cnt; | |
+ | |
+ int crop; | |
+ int crop_left; | |
+ int crop_top; | |
+} H264Picture; | |
+ | |
+typedef struct H264Ref { | |
+ uint8_t *data[3]; | |
+ int linesize[3]; | |
+ | |
+ int reference; | |
+ int poc; | |
+ int pic_id; | |
+ | |
+ H264Picture *parent; | |
+} H264Ref; | |
+ | |
+typedef struct H264SliceContext { | |
+ struct H264Context *h264; | |
+ GetBitContext gb; | |
+ ERContext er; | |
+ | |
+ int slice_num; | |
+ int slice_type; | |
+ int slice_type_nos; ///< S free slice type (SI/SP are remapped to I/P) | |
+ int slice_type_fixed; | |
+ | |
+ int qscale; | |
+ int chroma_qp[2]; // QPc | |
+ int qp_thresh; ///< QP threshold to skip loopfilter | |
+ int last_qscale_diff; | |
+ | |
+ // deblock | |
+ int deblocking_filter; ///< disable_deblocking_filter_idc with 1 <-> 0 | |
+ int slice_alpha_c0_offset; | |
+ int slice_beta_offset; | |
+ | |
+ // Weighted pred stuff | |
+ int use_weight; | |
+ int use_weight_chroma; | |
+ int luma_log2_weight_denom; | |
+ int chroma_log2_weight_denom; | |
+ int luma_weight_flag[2]; ///< 7.4.3.2 luma_weight_lX_flag | |
+ int chroma_weight_flag[2]; ///< 7.4.3.2 chroma_weight_lX_flag | |
+ // The following 2 can be changed to int8_t but that causes 10cpu cycles speedloss | |
+ int luma_weight[48][2][2]; | |
+ int chroma_weight[48][2][2][2]; | |
+ int implicit_weight[48][48][2]; | |
+ | |
+ int prev_mb_skipped; | |
+ int next_mb_skipped; | |
+ | |
+ int chroma_pred_mode; | |
+ int intra16x16_pred_mode; | |
+ | |
+ int8_t intra4x4_pred_mode_cache[5 * 8]; | |
+ int8_t(*intra4x4_pred_mode); | |
+ | |
+ int topleft_mb_xy; | |
+ int top_mb_xy; | |
+ int topright_mb_xy; | |
+ int left_mb_xy[LEFT_MBS]; | |
+ | |
+ int topleft_type; | |
+ int top_type; | |
+ int topright_type; | |
+ int left_type[LEFT_MBS]; | |
+ | |
+ const uint8_t *left_block; | |
+ int topleft_partition; | |
+ | |
+ unsigned int topleft_samples_available; | |
+ unsigned int top_samples_available; | |
+ unsigned int topright_samples_available; | |
+ unsigned int left_samples_available; | |
+ | |
+ ptrdiff_t linesize, uvlinesize; | |
+ ptrdiff_t mb_linesize; ///< may be equal to s->linesize or s->linesize * 2, for mbaff | |
+ ptrdiff_t mb_uvlinesize; | |
+ | |
+ int mb_x, mb_y; | |
+ int mb_xy; | |
+ int resync_mb_x; | |
+ int resync_mb_y; | |
+ int mb_index_end; | |
+ int mb_skip_run; | |
+ int is_complex; | |
+ | |
+ int mb_field_decoding_flag; | |
+ int mb_mbaff; ///< mb_aff_frame && mb_field_decoding_flag | |
+ | |
+ int redundant_pic_count; | |
+ | |
+ /** | |
+ * number of neighbors (top and/or left) that used 8x8 dct | |
+ */ | |
+ int neighbor_transform_size; | |
+ | |
+ int direct_spatial_mv_pred; | |
+ int col_parity; | |
+ int col_fieldoff; | |
+ | |
+ int cbp; | |
+ int top_cbp; | |
+ int left_cbp; | |
+ | |
+ int dist_scale_factor[32]; | |
+ int dist_scale_factor_field[2][32]; | |
+ int map_col_to_list0[2][16 + 32]; | |
+ int map_col_to_list0_field[2][2][16 + 32]; | |
+ | |
+ /** | |
+ * num_ref_idx_l0/1_active_minus1 + 1 | |
+ */ | |
+ unsigned int ref_count[2]; ///< counts frames or fields, depending on current mb mode | |
+ unsigned int list_count; | |
+ H264Ref ref_list[2][48]; /**< 0..15: frame refs, 16..47: mbaff field refs. | |
+ * Reordered version of default_ref_list | |
+ * according to picture reordering in slice header */ | |
+ int ref2frm[MAX_SLICES][2][64]; ///< reference to frame number lists, used in the loop filter, the first 2 are for -2,-1 | |
+ | |
+ const uint8_t *intra_pcm_ptr; | |
+ int16_t *dc_val_base; | |
+ | |
+ uint8_t *bipred_scratchpad; | |
+ uint8_t *edge_emu_buffer; | |
+ uint8_t (*top_borders[2])[(16 * 3) * 2]; | |
+ int bipred_scratchpad_allocated; | |
+ int edge_emu_buffer_allocated; | |
+ int top_borders_allocated[2]; | |
+ | |
+ /** | |
+ * non zero coeff count cache. | |
+ * is 64 if not available. | |
+ */ | |
+ DECLARE_ALIGNED(8, uint8_t, non_zero_count_cache)[15 * 8]; | |
+ | |
+ /** | |
+ * Motion vector cache. | |
+ */ | |
+ DECLARE_ALIGNED(16, int16_t, mv_cache)[2][5 * 8][2]; | |
+ DECLARE_ALIGNED(8, int8_t, ref_cache)[2][5 * 8]; | |
+ DECLARE_ALIGNED(16, uint8_t, mvd_cache)[2][5 * 8][2]; | |
+ uint8_t direct_cache[5 * 8]; | |
+ | |
+ DECLARE_ALIGNED(8, uint16_t, sub_mb_type)[4]; | |
+ | |
+ ///< as a dct coefficient is int32_t in high depth, we need to reserve twice the space. | |
+ DECLARE_ALIGNED(16, int16_t, mb)[16 * 48 * 2]; | |
+ DECLARE_ALIGNED(16, int16_t, mb_luma_dc)[3][16 * 2]; | |
+ ///< as mb is addressed by scantable[i] and scantable is uint8_t we can either | |
+ ///< check that i is not too large or ensure that there is some unused stuff after mb | |
+ int16_t mb_padding[256 * 2]; | |
+ | |
+ uint8_t (*mvd_table[2])[2]; | |
+ | |
+ /** | |
+ * Cabac | |
+ */ | |
+ CABACContext cabac; | |
+ uint8_t cabac_state[1024]; | |
+ int cabac_init_idc; | |
+ | |
+ // rbsp buffer used for this slice | |
+ uint8_t *rbsp_buffer; | |
+ unsigned int rbsp_buffer_size; | |
+} H264SliceContext; | |
+ | |
+/** | |
+ * H264Context | |
+ */ | |
+typedef struct H264Context { | |
+ AVClass *av_class; | |
+ AVCodecContext *avctx; | |
+ VideoDSPContext vdsp; | |
+ H264DSPContext h264dsp; | |
+ H264ChromaContext h264chroma; | |
+ H264QpelContext h264qpel; | |
+ GetBitContext gb; | |
+ | |
+ H264Picture DPB[H264_MAX_PICTURE_COUNT]; | |
+ H264Picture *cur_pic_ptr; | |
+ H264Picture cur_pic; | |
+ H264Picture last_pic_for_ec; | |
+ | |
+ H264SliceContext *slice_ctx; | |
+ int nb_slice_ctx; | |
+ | |
+ int pixel_shift; ///< 0 for 8-bit H264, 1 for high-bit-depth H264 | |
+ | |
+ /* coded dimensions -- 16 * mb w/h */ | |
+ int width, height; | |
+ int chroma_x_shift, chroma_y_shift; | |
+ | |
+ int droppable; | |
+ int coded_picture_number; | |
+ int low_delay; | |
+ | |
+ int context_initialized; | |
+ int flags; | |
+ int workaround_bugs; | |
+ | |
+ int8_t(*intra4x4_pred_mode); | |
+ H264PredContext hpc; | |
+ | |
+ uint8_t (*non_zero_count)[48]; | |
+ | |
+#define LIST_NOT_USED -1 // FIXME rename? | |
+#define PART_NOT_AVAILABLE -2 | |
+ | |
+ /** | |
+ * block_offset[ 0..23] for frame macroblocks | |
+ * block_offset[24..47] for field macroblocks | |
+ */ | |
+ int block_offset[2 * (16 * 3)]; | |
+ | |
+ uint32_t *mb2b_xy; // FIXME are these 4 a good idea? | |
+ uint32_t *mb2br_xy; | |
+ int b_stride; // FIXME use s->b4_stride | |
+ | |
+ unsigned current_sps_id; ///< id of the current SPS | |
+ SPS sps; ///< current sps | |
+ PPS pps; ///< current pps | |
+ | |
+ int au_pps_id; ///< pps_id of current access unit | |
+ | |
+ uint32_t dequant4_buffer[6][QP_MAX_NUM + 1][16]; // FIXME should these be moved down? | |
+ uint32_t dequant8_buffer[6][QP_MAX_NUM + 1][64]; | |
+ uint32_t(*dequant4_coeff[6])[16]; | |
+ uint32_t(*dequant8_coeff[6])[64]; | |
+ | |
+ uint16_t *slice_table; ///< slice_table_base + 2*mb_stride + 1 | |
+ | |
+ // interlacing specific flags | |
+ int mb_aff_frame; | |
+ int picture_structure; | |
+ int first_field; | |
+ | |
+ uint8_t *list_counts; ///< Array of list_count per MB specifying the slice type | |
+ | |
+ /* 0x100 -> non null luma_dc, 0x80/0x40 -> non null chroma_dc (cb/cr), 0x?0 -> chroma_cbp(0, 1, 2), 0x0? luma_cbp */ | |
+ uint16_t *cbp_table; | |
+ | |
+ /* chroma_pred_mode for i4x4 or i16x16, else 0 */ | |
+ uint8_t *chroma_pred_mode_table; | |
+ uint8_t (*mvd_table[2])[2]; | |
+ uint8_t *direct_table; | |
+ | |
+ uint8_t zigzag_scan[16]; | |
+ uint8_t zigzag_scan8x8[64]; | |
+ uint8_t zigzag_scan8x8_cavlc[64]; | |
+ uint8_t field_scan[16]; | |
+ uint8_t field_scan8x8[64]; | |
+ uint8_t field_scan8x8_cavlc[64]; | |
+ uint8_t zigzag_scan_q0[16]; | |
+ uint8_t zigzag_scan8x8_q0[64]; | |
+ uint8_t zigzag_scan8x8_cavlc_q0[64]; | |
+ uint8_t field_scan_q0[16]; | |
+ uint8_t field_scan8x8_q0[64]; | |
+ uint8_t field_scan8x8_cavlc_q0[64]; | |
+ | |
+ int x264_build; | |
+ | |
+ int mb_y; | |
+ int mb_height, mb_width; | |
+ int mb_stride; | |
+ int mb_num; | |
+ | |
+ // ============================================================= | |
+ // Things below are not used in the MB or more inner code | |
+ | |
+ int nal_ref_idc; | |
+ int nal_unit_type; | |
+ | |
+ /** | |
+ * Used to parse AVC variant of h264 | |
+ */ | |
+ int is_avc; ///< this flag is != 0 if codec is avc1 | |
+ int nal_length_size; ///< Number of bytes used for nal length (1, 2 or 4) | |
+ | |
+ int bit_depth_luma; ///< luma bit depth from sps to detect changes | |
+ int chroma_format_idc; ///< chroma format from sps to detect changes | |
+ | |
+ SPS *sps_buffers[MAX_SPS_COUNT]; | |
+ PPS *pps_buffers[MAX_PPS_COUNT]; | |
+ | |
+ int dequant_coeff_pps; ///< reinit tables when pps changes | |
+ | |
+ uint16_t *slice_table_base; | |
+ | |
+ // POC stuff | |
+ int poc_lsb; | |
+ int poc_msb; | |
+ int delta_poc_bottom; | |
+ int delta_poc[2]; | |
+ int frame_num; | |
+ int prev_poc_msb; ///< poc_msb of the last reference pic for POC type 0 | |
+ int prev_poc_lsb; ///< poc_lsb of the last reference pic for POC type 0 | |
+ int frame_num_offset; ///< for POC type 2 | |
+ int prev_frame_num_offset; ///< for POC type 2 | |
+ int prev_frame_num; ///< frame_num of the last pic for POC type 1/2 | |
+ | |
+ /** | |
+ * frame_num for frames or 2 * frame_num + 1 for field pics. | |
+ */ | |
+ int curr_pic_num; | |
+ | |
+ /** | |
+ * max_frame_num or 2 * max_frame_num for field pics. | |
+ */ | |
+ int max_pic_num; | |
+ | |
+ H264Ref default_ref_list[2][32]; ///< base reference list for all slices of a coded picture | |
+ H264Picture *short_ref[32]; | |
+ H264Picture *long_ref[32]; | |
+ H264Picture *delayed_pic[MAX_DELAYED_PIC_COUNT + 2]; // FIXME size? | |
+ int last_pocs[MAX_DELAYED_PIC_COUNT]; | |
+ H264Picture *next_output_pic; | |
+ int next_outputed_poc; | |
+ | |
+ /** | |
+ * memory management control operations buffer. | |
+ */ | |
+ MMCO mmco[MAX_MMCO_COUNT]; | |
+ int mmco_index; | |
+ int mmco_reset; | |
+ | |
+ int long_ref_count; ///< number of actual long term references | |
+ int short_ref_count; ///< number of actual short term references | |
+ | |
+ /** | |
+ * @name Members for slice based multithreading | |
+ * @{ | |
+ */ | |
+ /** | |
+ * current slice number, used to initialize slice_num of each thread/context | |
+ */ | |
+ int current_slice; | |
+ | |
+ /** | |
+ * Max number of threads / contexts. | |
+ * This is equal to AVCodecContext.thread_count unless | |
+ * multithreaded decoding is impossible, in which case it is | |
+ * reduced to 1. | |
+ */ | |
+ int max_contexts; | |
+ | |
+ int slice_context_count; | |
+ | |
+ /** | |
+ * 1 if the single thread fallback warning has already been | |
+ * displayed, 0 otherwise. | |
+ */ | |
+ int single_decode_warning; | |
+ | |
+ enum AVPictureType pict_type; | |
+ | |
+ int last_slice_type; | |
+ unsigned int last_ref_count[2]; | |
+ /** @} */ | |
+ | |
+ /** | |
+ * pic_struct in picture timing SEI message | |
+ */ | |
+ SEI_PicStructType sei_pic_struct; | |
+ | |
+ /** | |
+ * Complement sei_pic_struct | |
+ * SEI_PIC_STRUCT_TOP_BOTTOM and SEI_PIC_STRUCT_BOTTOM_TOP indicate interlaced frames. | |
+ * However, soft telecined frames may have these values. | |
+ * This is used in an attempt to flag soft telecine progressive. | |
+ */ | |
+ int prev_interlaced_frame; | |
+ | |
+ /** | |
+ * frame_packing_arrangment SEI message | |
+ */ | |
+ int sei_frame_packing_present; | |
+ int frame_packing_arrangement_type; | |
+ int content_interpretation_type; | |
+ int quincunx_subsampling; | |
+ | |
+ /** | |
+ * display orientation SEI message | |
+ */ | |
+ int sei_display_orientation_present; | |
+ int sei_anticlockwise_rotation; | |
+ int sei_hflip, sei_vflip; | |
+ | |
+ /** | |
+ * Bit set of clock types for fields/frames in picture timing SEI message. | |
+ * For each found ct_type, appropriate bit is set (e.g., bit 1 for | |
+ * interlaced). | |
+ */ | |
+ int sei_ct_type; | |
+ | |
+ /** | |
+ * dpb_output_delay in picture timing SEI message, see H.264 C.2.2 | |
+ */ | |
+ int sei_dpb_output_delay; | |
+ | |
+ /** | |
+ * cpb_removal_delay in picture timing SEI message, see H.264 C.1.2 | |
+ */ | |
+ int sei_cpb_removal_delay; | |
+ | |
+ /** | |
+ * recovery_frame_cnt from SEI message | |
+ * | |
+ * Set to -1 if no recovery point SEI message found or to number of frames | |
+ * before playback synchronizes. Frames having recovery point are key | |
+ * frames. | |
+ */ | |
+ int sei_recovery_frame_cnt; | |
+ | |
+ /** | |
+ * Are the SEI recovery points looking valid. | |
+ */ | |
+ int valid_recovery_point; | |
+ | |
+ FPA sei_fpa; | |
+ | |
+ /** | |
+ * recovery_frame is the frame_num at which the next frame should | |
+ * be fully constructed. | |
+ * | |
+ * Set to -1 when not expecting a recovery point. | |
+ */ | |
+ int recovery_frame; | |
+ | |
+/** | |
+ * We have seen an IDR, so all the following frames in coded order are correctly | |
+ * decodable. | |
+ */ | |
+#define FRAME_RECOVERED_IDR (1 << 0) | |
+/** | |
+ * Sufficient number of frames have been decoded since a SEI recovery point, | |
+ * so all the following frames in presentation order are correct. | |
+ */ | |
+#define FRAME_RECOVERED_SEI (1 << 1) | |
+ | |
+ int frame_recovered; ///< Initial frame has been completely recovered | |
+ | |
+ int has_recovery_point; | |
+ | |
+ int missing_fields; | |
+ | |
+ // Timestamp stuff | |
+ int sei_buffering_period_present; ///< Buffering period SEI flag | |
+ int initial_cpb_removal_delay[32]; ///< Initial timestamps for CPBs | |
+ | |
+ int cur_chroma_format_idc; | |
+ int cur_bit_depth_luma; | |
+ int16_t slice_row[MAX_SLICES]; ///< to detect when MAX_SLICES is too low | |
+ | |
+ uint8_t parse_history[6]; | |
+ int parse_history_count; | |
+ int parse_last_mb; | |
+ | |
+ int enable_er; | |
+ | |
+ AVBufferPool *qscale_table_pool; | |
+ AVBufferPool *mb_type_pool; | |
+ AVBufferPool *motion_val_pool; | |
+ AVBufferPool *ref_index_pool; | |
+ | |
+ /* Motion Estimation */ | |
+ qpel_mc_func (*qpel_put)[16]; | |
+ qpel_mc_func (*qpel_avg)[16]; | |
+} H264Context; | |
+ | |
+#endif /* SYNO_EVANSPORT_SMD */ | |
+#endif /* AVCODEC_H264_H */ | |
diff --git a/libavcodec/hevc.c b/libavcodec/hevc.c | |
index 1d2fa9c81d..707b7f54fb 100644 | |
--- a/libavcodec/hevc.c | |
+++ b/libavcodec/hevc.c | |
@@ -39,6 +39,9 @@ | |
#include "golomb.h" | |
#include "hevc.h" | |
+#include "synoconfig.h" | |
+#include "synog1codecpatent.h" | |
+ | |
const uint8_t ff_hevc_pel_weight[65] = { [2] = 0, [4] = 1, [6] = 2, [8] = 3, [12] = 4, [16] = 5, [24] = 6, [32] = 7, [48] = 8, [64] = 9 }; | |
/** | |
@@ -3447,6 +3450,12 @@ static av_cold int hevc_decode_init(AVCodecContext *avctx) | |
HEVCContext *s = avctx->priv_data; | |
int ret; | |
+#ifdef SYNO_CODEC_PATENT_G1 | |
+ if (0 != ActivateCodec("hevc_dec")) { | |
+ return -1; | |
+ } | |
+#endif | |
+ | |
ff_init_cabac_states(); | |
avctx->internal->allocate_progress = 1; | |
diff --git a/libavcodec/ismd_ffmpeg_audio_util.c b/libavcodec/ismd_ffmpeg_audio_util.c | |
new file mode 100644 | |
index 0000000000..2d4106a3c5 | |
--- /dev/null | |
+++ b/libavcodec/ismd_ffmpeg_audio_util.c | |
@@ -0,0 +1,1213 @@ | |
+/* | |
+ * This file contains utility functions | |
+ * Copyright (c) 2012, Intel Corporation. | |
+ * | |
+ * This program is free software; you can redistribute it and/or modify it | |
+ * under the terms and conditions of the GNU Lesser General Public License, | |
+ * version 2.1, as published by the Free Software Foundation. | |
+ * | |
+ * This program is distributed in the hope 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 program; if not, write to the Free Software Foundation, Inc., | |
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | |
+ * | |
+ */ | |
+ | |
+#include "avcodec.h" | |
+#include "wma.h" | |
+#include "libavformat/avformat.h" | |
+#include "libavcodec/h264_smd.h" | |
+#include "libavcodec/vc1.h" | |
+#if CONFIG_LIBX264_ENCODER | |
+#include <x264.h> | |
+#endif | |
+ | |
+#include "synoconfig.h" | |
+ | |
+#ifdef SYNO_EVANSPORT_SMD | |
+#include "osal_type.h" | |
+#include "ismd_vidpproc.h" | |
+#include "libffmpeg_plugin/ismd_ffmpeg_util.h" | |
+#include "libffmpeg_plugin/ismd_ffmpeg_video_dec.h" | |
+#include "libffmpeg_plugin/ismd_ffmpeg_video_enc.h" | |
+#include "libffmpeg_plugin/ismd_ffmpeg_bitstream.h" | |
+#include "libffmpeg_plugin/ismd_ffmpeg_audio_dec.h" //ISMD HEDAER FILE | |
+#include "libffmpeg_plugin/ismd_ffmpeg_audio_enc.h" | |
+#include "ismd_ffmpeg_audio_util.h" | |
+ | |
+#define SZ_MAX_PACKATES 40 | |
+static AVPacket packets[SZ_MAX_PACKATES]; | |
+static int nb_packet = 0; | |
+ | |
+typedef struct X264Context { | |
+ AVClass *class; | |
+#if CONFIG_LIBX264_ENCODER | |
+ x264_param_t params; | |
+ x264_t *enc; | |
+ x264_picture_t pic; | |
+#endif | |
+ uint8_t *sei; | |
+ int sei_size; | |
+ char *preset; | |
+ char *tune; | |
+ char *profile; | |
+ char *level; | |
+ int fastfirstpass; | |
+ char *wpredp; | |
+ char *x264opts; | |
+ float crf; | |
+ float crf_max; | |
+ int cqp; | |
+ int aq_mode; | |
+ float aq_strength; | |
+ char *psy_rd; | |
+ int psy; | |
+ int rc_lookahead; | |
+ int weightp; | |
+ int weightb; | |
+ int ssim; | |
+ int intra_refresh; | |
+ int bluray_compat; | |
+ int b_bias; | |
+ int b_pyramid; | |
+ int mixed_refs; | |
+ int dct8x8; | |
+ int fast_pskip; | |
+ int aud; | |
+ int mbtree; | |
+ char *deblock; | |
+ float cplxblur; | |
+ char *partitions; | |
+ int direct_pred; | |
+ int slice_max_size; | |
+ char *stats; | |
+ int nal_hrd; | |
+ int avcintra_class; | |
+ char *x264_params; | |
+} X264Context; | |
+ | |
+int ismd_ffmpeg_get_ismd_audio_channel_config(AVCodecContext *avctx) | |
+{ | |
+ int ffmpeg_ch_config =avctx->channel_layout; | |
+ int ismd_ch_config=0; | |
+ switch(ffmpeg_ch_config) | |
+ { | |
+ case AV_CH_LAYOUT_MONO: // (AV_CH_FRONT_CENTER) | |
+ ismd_ch_config =ISMD_AUDIO_CHANNEL_CENTER;//ISMD_AUDIO_DUAL_MONO; | |
+ break; | |
+ case AV_CH_LAYOUT_STEREO: // (AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT) | |
+ ismd_ch_config = ISMD_AUDIO_CHANNEL_LEFT|ISMD_AUDIO_CHANNEL_RIGHT;//ISMD_AUDIO_STEREO; | |
+ break; | |
+ case AV_CH_LAYOUT_2POINT1: //(AV_CH_LAYOUT_STEREO|AV_CH_LOW_FREQUENCY) | |
+ ismd_ch_config =ISMD_AUDIO_STEREO; | |
+ break; | |
+ case AV_CH_LAYOUT_2_1: //(AV_CH_LAYOUT_STEREO|AV_CH_BACK_CENTER) | |
+ ismd_ch_config =ISMD_AUDIO_STEREO; | |
+ break; | |
+ case AV_CH_LAYOUT_SURROUND: //(AV_CH_LAYOUT_STEREO|AV_CH_FRONT_CENTER) | |
+ ismd_ch_config =ISMD_AUDIO_STEREO; | |
+ break; | |
+ case AV_CH_LAYOUT_3POINT1: //(AV_CH_LAYOUT_SURROUND|AV_CH_LOW_FREQUENCY) | |
+ ismd_ch_config =ISMD_AUDIO_STEREO; | |
+ break; | |
+ case AV_CH_LAYOUT_4POINT0: //(AV_CH_LAYOUT_SURROUND|AV_CH_BACK_CENTER) | |
+ ismd_ch_config =ISMD_AUDIO_STEREO; | |
+ break; | |
+ case AV_CH_LAYOUT_4POINT1: //(AV_CH_LAYOUT_4POINT0|AV_CH_LOW_FREQUENCY) | |
+ ismd_ch_config =ISMD_AUDIO_STEREO; | |
+ break; | |
+ case AV_CH_LAYOUT_2_2: //(AV_CH_LAYOUT_STEREO|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT) | |
+ ismd_ch_config =ISMD_AUDIO_STEREO; | |
+ break; | |
+ case AV_CH_LAYOUT_QUAD: //(AV_CH_LAYOUT_STEREO|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT) | |
+ ismd_ch_config =ISMD_AUDIO_STEREO; | |
+ break; | |
+ case AV_CH_LAYOUT_5POINT0: //(AV_CH_LAYOUT_SURROUND|AV_CH_SIDE_LEFT|AV_CH_SIDE_RIGHT) | |
+ ismd_ch_config =ISMD_AUDIO_STEREO; | |
+ break; | |
+ case AV_CH_LAYOUT_5POINT1: //(AV_CH_LAYOUT_5POINT0|AV_CH_LOW_FREQUENCY) | |
+ ismd_ch_config =ISMD_AUDIO_5_1;//ISMD_AUDIO_STEREO; | |
+ break; | |
+ case AV_CH_LAYOUT_5POINT0_BACK: //(AV_CH_LAYOUT_SURROUND|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT) | |
+ ismd_ch_config =ISMD_AUDIO_STEREO; | |
+ break; | |
+ case AV_CH_LAYOUT_5POINT1_BACK: //(AV_CH_LAYOUT_5POINT0_BACK|AV_CH_LOW_FREQUENCY) | |
+ ismd_ch_config =ISMD_AUDIO_5_1; | |
+ break; | |
+ case AV_CH_LAYOUT_6POINT0: //(AV_CH_LAYOUT_5POINT0|AV_CH_BACK_CENTER) | |
+ ismd_ch_config =ISMD_AUDIO_5_1; | |
+ break; | |
+ case AV_CH_LAYOUT_6POINT0_FRONT: //(AV_CH_LAYOUT_2_2|AV_CH_FRONT_LEFT_OF_CENTER|AV_CH_FRONT_RIGHT_OF_CENTER) | |
+ ismd_ch_config =ISMD_AUDIO_5_1; | |
+ break; | |
+ case AV_CH_LAYOUT_HEXAGONAL: //(AV_CH_LAYOUT_5POINT0_BACK|AV_CH_BACK_CENTER) | |
+ ismd_ch_config =ISMD_AUDIO_5_1; | |
+ break; | |
+ case AV_CH_LAYOUT_6POINT1: //(AV_CH_LAYOUT_5POINT1|AV_CH_BACK_CENTER) | |
+ ismd_ch_config =ISMD_AUDIO_5_1; | |
+ break; | |
+ case AV_CH_LAYOUT_6POINT1_BACK: //(AV_CH_LAYOUT_5POINT1_BACK|AV_CH_BACK_CENTER) | |
+ ismd_ch_config =ISMD_AUDIO_5_1; | |
+ break; | |
+ case AV_CH_LAYOUT_6POINT1_FRONT: //(AV_CH_LAYOUT_6POINT0_FRONT|AV_CH_LOW_FREQUENCY) | |
+ ismd_ch_config =ISMD_AUDIO_5_1; | |
+ break; | |
+ case AV_CH_LAYOUT_7POINT0: //(AV_CH_LAYOUT_5POINT0|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT) | |
+ ismd_ch_config =ISMD_AUDIO_5_1; | |
+ break; | |
+ case AV_CH_LAYOUT_7POINT0_FRONT: //(AV_CH_LAYOUT_5POINT0|AV_CH_FRONT_LEFT_OF_CENTER|AV_CH_FRONT_RIGHT_OF_CENTER) | |
+ ismd_ch_config =ISMD_AUDIO_7_1; | |
+ break; | |
+ case AV_CH_LAYOUT_7POINT1: //(AV_CH_LAYOUT_5POINT1|AV_CH_BACK_LEFT|AV_CH_BACK_RIGHT) | |
+ ismd_ch_config =ISMD_AUDIO_7_1; | |
+ break; | |
+ case AV_CH_LAYOUT_7POINT1_WIDE: //(AV_CH_LAYOUT_5POINT1|AV_CH_FRONT_LEFT_OF_CENTER|AV_CH_FRONT_RIGHT_OF_CENTER) | |
+ ismd_ch_config =ISMD_AUDIO_7_1; | |
+ break; | |
+ case AV_CH_LAYOUT_OCTAGONAL: //(AV_CH_LAYOUT_5POINT0|AV_CH_BACK_LEFT|AV_CH_BACK_CENTER|AV_CH_BACK_RIGHT) | |
+ ismd_ch_config =ISMD_AUDIO_7_1; | |
+ break; | |
+ case AV_CH_LAYOUT_STEREO_DOWNMIX: //(AV_CH_STEREO_LEFT|AV_CH_STEREO_RIGHT) | |
+ ismd_ch_config =ISMD_AUDIO_7_1; | |
+ break; | |
+ default: | |
+ av_log(NULL,AV_LOG_ERROR,"Invalid channel layout %llu\n",avctx->channel_layout); | |
+ return -1; | |
+ } | |
+ return ismd_ch_config; | |
+} | |
+ismd_result_t ismd_ffmpeg_config_aud_dec(AVCodecContext *avctx , audiodec_struct* p_aud_dec , ismd_audio_format_t ip_aud_fmt, int aac_bs_fmt) | |
+{ | |
+ int encode_option =0; | |
+ int ismd_channel_layout; | |
+ uint8_t *extradata; | |
+ | |
+ switch(ip_aud_fmt) | |
+ { | |
+ case ISMD_AUDIO_MEDIA_FMT_WM9: | |
+ /* extract flag infos */ | |
+ extradata = avctx->extradata; | |
+ | |
+ if (avctx->codec->id == CODEC_ID_WMAV1 && avctx->extradata_size >= 4) { | |
+ encode_option= AV_RL16(extradata+2); | |
+ } else if (avctx->codec->id == CODEC_ID_WMAV2 && avctx->extradata_size >= 6) { | |
+ encode_option = AV_RL16(extradata+4); | |
+ } | |
+ //FILLING WMA DATA STRUCTURE | |
+ p_aud_dec->current_input.wma_fmt_param.sample_rate= avctx->sample_rate; | |
+ p_aud_dec->current_input.wma_fmt_param.num_channels = avctx->channels; | |
+ p_aud_dec->current_input.wma_fmt_param.bitrate = avctx->bit_rate/8;//byte rate | |
+ if (avctx->codec->id == CODEC_ID_WMAV1) | |
+ p_aud_dec->current_input.wma_fmt_param.format_tag = 0x160; | |
+ else if (avctx->codec->id == CODEC_ID_WMAV2) | |
+ p_aud_dec->current_input.wma_fmt_param.format_tag = 0x161; | |
+ if(avctx->sample_fmt== AV_SAMPLE_FMT_S16) | |
+ p_aud_dec->current_input.wma_fmt_param.sample_size = 16; | |
+ else if(avctx->sample_fmt== AV_SAMPLE_FMT_S32) | |
+ p_aud_dec->current_input.wma_fmt_param.sample_size = 32; | |
+ p_aud_dec->current_input.wma_fmt_param.block_align = avctx->block_align; | |
+ p_aud_dec->current_input.wma_fmt_param.encode_option = encode_option; | |
+ | |
+ //Setting Audio i/p Config | |
+ p_aud_dec->current_input.format = ISMD_AUDIO_MEDIA_FMT_WM9; | |
+ | |
+ if(avctx->sample_fmt == AV_SAMPLE_FMT_S16) | |
+ p_aud_dec->current_input.sample_size= 16; | |
+ else if(avctx->sample_fmt == AV_SAMPLE_FMT_S32) | |
+ p_aud_dec->current_input.sample_size= 32; | |
+ | |
+ //Setting Audio o/p Config | |
+ if(avctx->sample_fmt == AV_SAMPLE_FMT_S16) | |
+ p_aud_dec->out_config.sample_size = 16; | |
+ else if(avctx->sample_fmt == AV_SAMPLE_FMT_S32) | |
+ p_aud_dec->out_config.sample_size= 32; | |
+ | |
+ break; | |
+ case ISMD_AUDIO_MEDIA_FMT_DTS: | |
+ //Setting Audio i/p Config | |
+ if(avctx->profile ==20) //DTS | |
+ p_aud_dec->current_input.format =ISMD_AUDIO_MEDIA_FMT_DTS; //DTS Audio | |
+ else if(avctx->profile ==50) //DTS_HD_HRA | |
+ p_aud_dec->current_input.format =ISMD_AUDIO_MEDIA_FMT_DTS_HD_HRA; //DTS High Defination High Resolution Audio | |
+ else if(avctx->profile ==30) //DTS_ES | |
+ p_aud_dec->current_input.format =ISMD_AUDIO_MEDIA_FMT_DTS_HD_MA; //DTS-HD Master Audio | |
+ else if(avctx->profile ==40) //DTS_96_24 | |
+ p_aud_dec->current_input.format =ISMD_AUDIO_MEDIA_FMT_DTS_HD_MA; //DTS-HD Master Audio | |
+ else if(avctx->profile ==60) | |
+ p_aud_dec->current_input.format =ISMD_AUDIO_MEDIA_FMT_DTS_HD_MA; //DTS-HD Master Audio | |
+ /* DTS Express also known an DTS_LBR DTS Lowbit Rate */ | |
+ | |
+ if(avctx->sample_fmt == AV_SAMPLE_FMT_S16) | |
+ p_aud_dec->current_input.sample_size= 16; | |
+ else if(avctx->sample_fmt == AV_SAMPLE_FMT_S32) | |
+ p_aud_dec->current_input.sample_size= 32; | |
+ | |
+ //Setting Audio o/p Config | |
+ if(avctx->sample_fmt == AV_SAMPLE_FMT_S16) | |
+ p_aud_dec->out_config.sample_size = 16; | |
+ else if(avctx->sample_fmt == AV_SAMPLE_FMT_S32) | |
+ p_aud_dec->out_config.sample_size= 32; | |
+ break; | |
+ case ISMD_AUDIO_MEDIA_FMT_DD: | |
+ if(avctx->codec->id == CODEC_ID_AC3) | |
+ p_aud_dec->current_input.format = ISMD_AUDIO_MEDIA_FMT_DD; | |
+ else if(avctx->codec->id == CODEC_ID_EAC3) | |
+ p_aud_dec->current_input.format = ISMD_AUDIO_MEDIA_FMT_DD_PLUS; | |
+ | |
+ if(avctx->sample_fmt == AV_SAMPLE_FMT_S16) | |
+ p_aud_dec->current_input.sample_size= 16; | |
+ else if(avctx->sample_fmt == AV_SAMPLE_FMT_S32) | |
+ p_aud_dec->current_input.sample_size= 32; | |
+ | |
+ //Setting Audio o/p Config | |
+ if(avctx->sample_fmt == AV_SAMPLE_FMT_S16) | |
+ p_aud_dec->out_config.sample_size = 16; | |
+ else if(avctx->sample_fmt == AV_SAMPLE_FMT_S32) | |
+ p_aud_dec->out_config.sample_size= 32; | |
+ break; | |
+ case ISMD_AUDIO_MEDIA_FMT_TRUE_HD: | |
+ p_aud_dec->current_input.format =ISMD_AUDIO_MEDIA_FMT_TRUE_HD; | |
+ | |
+ if(avctx->sample_fmt == AV_SAMPLE_FMT_FLT) | |
+ p_aud_dec->current_input.sample_size= 32; | |
+ if((avctx->sample_fmt == AV_SAMPLE_FMT_S16)||(avctx->sample_fmt == AV_SAMPLE_FMT_S16P)) | |
+ p_aud_dec->current_input.sample_size= 16; | |
+ else if((avctx->sample_fmt == AV_SAMPLE_FMT_S32)||(avctx->sample_fmt == AV_SAMPLE_FMT_S32P)) | |
+ p_aud_dec->current_input.sample_size= 32; | |
+ | |
+ //Setting Audio o/p Config | |
+ if(avctx->sample_fmt == AV_SAMPLE_FMT_FLT) | |
+ p_aud_dec->out_config.sample_size= 32; | |
+ if((avctx->sample_fmt == AV_SAMPLE_FMT_S16)||(avctx->sample_fmt == AV_SAMPLE_FMT_S16P)) | |
+ p_aud_dec->out_config.sample_size = 16; | |
+ else if((avctx->sample_fmt == AV_SAMPLE_FMT_S32)||(avctx->sample_fmt == AV_SAMPLE_FMT_S32P)) | |
+ p_aud_dec->out_config.sample_size= 32; | |
+ break; | |
+ case ISMD_AUDIO_MEDIA_FMT_AAC: | |
+ p_aud_dec->current_input.format = ip_aud_fmt; | |
+ | |
+ if(avctx->sample_fmt == AV_SAMPLE_FMT_S16) | |
+ p_aud_dec->current_input.sample_size= 16; | |
+ else if(avctx->sample_fmt == AV_SAMPLE_FMT_S32) | |
+ p_aud_dec->current_input.sample_size= 32; | |
+ | |
+ //Setting Audio o/p Config | |
+ if(avctx->sample_fmt == AV_SAMPLE_FMT_S16) | |
+ p_aud_dec->out_config.sample_size = 16; | |
+ else if(avctx->sample_fmt == AV_SAMPLE_FMT_S32) | |
+ p_aud_dec->out_config.sample_size= 32; | |
+ | |
+ p_aud_dec->aac_bs_format = aac_bs_fmt; | |
+ break; | |
+ case ISMD_AUDIO_MEDIA_FMT_AAC_LOAS: | |
+ p_aud_dec->current_input.format = ip_aud_fmt; | |
+ | |
+ if(avctx->sample_fmt == AV_SAMPLE_FMT_S16) | |
+ p_aud_dec->current_input.sample_size= 16; | |
+ else if(avctx->sample_fmt == AV_SAMPLE_FMT_S32) | |
+ p_aud_dec->current_input.sample_size= 32; | |
+ | |
+ //Setting Audio o/p Config | |
+ if(avctx->sample_fmt == AV_SAMPLE_FMT_S16) | |
+ p_aud_dec->out_config.sample_size = 16; | |
+ else if(avctx->sample_fmt == AV_SAMPLE_FMT_S32) | |
+ p_aud_dec->out_config.sample_size= 32; | |
+ | |
+ break; | |
+ case ISMD_AUDIO_MEDIA_FMT_MPEG: | |
+ p_aud_dec->current_input.format = ip_aud_fmt; | |
+ | |
+ if(avctx->sample_fmt == AV_SAMPLE_FMT_S16) | |
+ p_aud_dec->current_input.sample_size= 16; | |
+ else if(avctx->sample_fmt == AV_SAMPLE_FMT_S32) | |
+ p_aud_dec->current_input.sample_size= 32; | |
+ | |
+ //Setting Audio o/p Config | |
+ if(avctx->sample_fmt == AV_SAMPLE_FMT_S16) | |
+ p_aud_dec->out_config.sample_size = 16; | |
+ else if(avctx->sample_fmt == AV_SAMPLE_FMT_S32) | |
+ p_aud_dec->out_config.sample_size= 32; | |
+ | |
+ break; | |
+ default: | |
+ av_log(avctx,AV_LOG_ERROR,"\ninput format %d is not supported by smd audio decoder\n",ip_aud_fmt); | |
+ return ISMD_ERROR_UNSPECIFIED; | |
+ } | |
+ //common configuration | |
+ p_aud_dec->pass_through_config.dts_or_dolby_convert = false; | |
+ p_aud_dec->pass_through_config.is_pass_through = false; | |
+ | |
+ //Setting Audio i/p Config | |
+ p_aud_dec->current_input.ch_config = avctx->channel_layout; | |
+ p_aud_dec->current_input.channels = avctx->channels; | |
+ p_aud_dec->current_input.sample_rate = avctx->sample_rate; | |
+ p_aud_dec->current_input.is_timed_stream = false; | |
+ | |
+ //Setting Audio o/p Config | |
+ p_aud_dec->out_config.sample_rate = avctx->sample_rate; | |
+ ismd_channel_layout = ismd_ffmpeg_get_ismd_audio_channel_config(avctx); | |
+ if(ismd_channel_layout == -1) | |
+ { | |
+ av_log(avctx,AV_LOG_ERROR,"\nthis channel layout is not supported by smd\n"); | |
+ return ISMD_ERROR_UNSPECIFIED; | |
+ } | |
+ p_aud_dec->out_config.ch_config = ismd_channel_layout; | |
+ p_aud_dec->out_config.out_mode = ISMD_AUDIO_OUTPUT_PCM; | |
+ p_aud_dec->out_config.stream_delay= 0; | |
+ | |
+ return ISMD_SUCCESS; | |
+} | |
+ | |
+ismd_result_t ismd_ffmpeg_config_aud_enc(AVCodecContext *avctx , audenc_struct_t* p_aud_enc , ismd_audio_output_mode_t op_aud_mode) | |
+{ | |
+ int ismd_channel_layout; | |
+ | |
+ switch(op_aud_mode) | |
+ { | |
+ case ISMD_AUDIO_OUTPUT_ENCODED_DTS: | |
+ p_aud_enc->out_config.out_mode = ISMD_AUDIO_OUTPUT_ENCODED_DTS; | |
+ break; | |
+ case ISMD_AUDIO_OUTPUT_ENCODED_AAC: | |
+ p_aud_enc->out_config.out_mode = ISMD_AUDIO_OUTPUT_ENCODED_AAC; | |
+ break; | |
+ case ISMD_AUDIO_OUTPUT_ENCODED_DOLBY_DIGITAL: | |
+ p_aud_enc->out_config.out_mode = ISMD_AUDIO_OUTPUT_ENCODED_DOLBY_DIGITAL; | |
+ break; | |
+ default: | |
+ av_log(avctx,AV_LOG_ERROR,"\noutput format %d is not supported by smd audio encoder\n",op_aud_mode); | |
+ return ISMD_ERROR_UNSPECIFIED; | |
+ } | |
+ //common configuration | |
+ | |
+ //Setting Audio I/P Config | |
+ p_aud_enc->current_input.sample_size = 16; | |
+ p_aud_enc->current_input.sample_rate = avctx->sample_rate; | |
+ p_aud_enc->current_input.channels = avctx->channels; | |
+ ismd_channel_layout = ismd_ffmpeg_get_ismd_audio_channel_config(avctx); | |
+ if(ismd_channel_layout == -1) | |
+ { | |
+ av_log(avctx,AV_LOG_ERROR,"\nthis channel layout is not supported by smd\n"); | |
+ return ISMD_ERROR_UNSPECIFIED; | |
+ } | |
+ | |
+ p_aud_enc->current_input.ch_config = ismd_channel_layout; | |
+ | |
+ //Setting Audio O/P Config | |
+ p_aud_enc->out_config.ch_config = ismd_channel_layout; | |
+ p_aud_enc->out_config.sample_rate = avctx->sample_rate; | |
+ if(avctx->sample_fmt == AV_SAMPLE_FMT_S16) | |
+ p_aud_enc->out_config.sample_size = 16; | |
+ else if(avctx->sample_fmt == AV_SAMPLE_FMT_S32) | |
+ p_aud_enc->out_config.sample_size = 32; | |
+ else | |
+ { | |
+ av_log(NULL,AV_LOG_ERROR,"Invalid Sample size %d\n",avctx->sample_fmt); | |
+ return ISMD_ERROR_UNSPECIFIED; | |
+ } | |
+ | |
+ return ISMD_SUCCESS; | |
+} | |
+ | |
+ismd_result_t ismd_ffmpeg_setup_aud_dec(AVCodecContext *avctx , audiodec_struct* p_aud_dec , ismd_audio_format_t ip_aud_fmt, int aac_bs_fmt) | |
+{ | |
+ ismd_result_t result = ISMD_ERROR_UNSPECIFIED; | |
+ | |
+ //config h/w audio decoder | |
+ result = ismd_ffmpeg_config_aud_dec(avctx ,p_aud_dec,ip_aud_fmt,aac_bs_fmt); | |
+ if (result != ISMD_SUCCESS) | |
+ { | |
+ av_log( NULL, AV_LOG_ERROR, "SMD audio decoder configuration failed %d\n",result); | |
+ return result; | |
+ } | |
+ | |
+ //initialize audio h/w resources | |
+ result = ismd_ffmpeg_smd_decode_init(p_aud_dec); | |
+ if (result != ISMD_SUCCESS) | |
+ { | |
+ av_log( NULL, AV_LOG_ERROR, "SMD audio decoder handlers initilization failed error: %d\n",result); | |
+ return result; | |
+ } | |
+ //setup o/p thread for decoder | |
+ result = ismd_ffmpeg_setup_auddec_op_thread(p_aud_dec); | |
+ if (result != ISMD_SUCCESS) | |
+ { | |
+ av_log(NULL, AV_LOG_ERROR, "\nSMD audio decoder o/p thread creation failed file %s\n",__FILE__); | |
+ return result; | |
+ } | |
+ | |
+ return ISMD_SUCCESS; | |
+} | |
+ | |
+ismd_result_t ismd_ffmpeg_setup_aud_enc(AVCodecContext *avctx , audenc_struct_t* p_aud_enc , ismd_audio_output_mode_t op_aud_mode) | |
+{ | |
+ ismd_result_t result = ISMD_ERROR_UNSPECIFIED; | |
+ | |
+ //config h/w audio encoder | |
+ result = ismd_ffmpeg_config_aud_enc(avctx ,p_aud_enc, op_aud_mode); | |
+ if (result != ISMD_SUCCESS) | |
+ { | |
+ av_log( NULL, AV_LOG_ERROR, "SMD audio encoder configuration failed %d\n",result); | |
+ return result; | |
+ } | |
+ | |
+ //initialize audio h/w resources | |
+ if((result =ismd_ffmpeg_smd_encode_init(p_aud_enc)) != ISMD_SUCCESS) | |
+ { | |
+ av_log(avctx, AV_LOG_ERROR, "SMD audio encoder handlers initilization failed error: %s\n",ismd_ffmpeg_result_to_string(result)); | |
+ return result; | |
+ } | |
+ | |
+ av_log(avctx,AV_LOG_DEBUG,"ismd_ffmpeg_smd_encode_init result %d\n",result); | |
+ //setup o/p thread for encoder | |
+ result = ismd_ffmpeg_setup_audenc_op_thread(p_aud_enc); | |
+ if (result != ISMD_SUCCESS) | |
+ { | |
+ av_log(NULL, AV_LOG_ERROR, "\nSMD audio encoder o/p thread creation failed file %s\n",__FILE__); | |
+ return result; | |
+ } | |
+ | |
+ return ISMD_SUCCESS; | |
+} | |
+ | |
+ismd_result_t ismd_ffmpeg_dec_aud_buf(AVCodecContext *avctx ,void *out_data, audiodec_struct* p_aud_dec,const uint8_t *ip_buf,int buf_size,int *got_frame_ptr) | |
+{ | |
+ ismd_result_t result = ISMD_ERROR_UNSPECIFIED; | |
+ long int data_copied=0; | |
+ char *decoded_samples; | |
+ AVFrame frame; | |
+ struct timespec ts; | |
+ | |
+ //if inupt pkt has some data to decode | |
+ if(buf_size > 0) | |
+ { | |
+ result = ismd_ffmpeg_audio_port_write(p_aud_dec, ip_buf, buf_size,ISMD_NO_PTS ); | |
+ if (result != ISMD_SUCCESS) | |
+ { | |
+ av_log( NULL, AV_LOG_ERROR, "\nismd_ffmpeg_audio_port_write failed error: %d\n",result); | |
+ return result; | |
+ } | |
+ } | |
+ | |
+ if(buf_size == 0) | |
+ { | |
+ //last frame received | |
+ //need to put some sleep to flush out audio decoder | |
+ ts.tv_sec = 0; | |
+ ts.tv_nsec = 100; | |
+ nanosleep (&ts, NULL); | |
+ } | |
+ //Decode data to be returned | |
+ decoded_samples = (char *)av_malloc(1); | |
+ decoded_samples = ismd_ffmpeg_aud_dec_dequeue(p_aud_dec, &decoded_samples, &data_copied); | |
+ if(data_copied > 0) | |
+ { | |
+ // get output buffer | |
+ frame.nb_samples = data_copied/(2* avctx->channels); | |
+ if ((avctx->get_buffer(avctx, &frame)) < 0) | |
+ { | |
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); | |
+ } | |
+ memcpy(frame.data[0], decoded_samples, data_copied); | |
+ *got_frame_ptr = 1; | |
+ frame.pts = AV_NOPTS_VALUE; | |
+ *(AVFrame *)out_data = frame; | |
+ } | |
+ else | |
+ { | |
+ *got_frame_ptr = 0; | |
+ } | |
+ av_free(decoded_samples); | |
+ | |
+ return ISMD_SUCCESS; | |
+} | |
+ismd_result_t ismd_ffmpeg_enc_aud_samples(AVCodecContext *avctx ,AVPacket *avpkt, audenc_struct_t* p_aud_enc, void *pcm_samples,int frame_bytes) | |
+{ | |
+ ismd_result_t result = ISMD_ERROR_UNSPECIFIED; | |
+ struct timespec ts; | |
+ int pkt_size = 0; | |
+ | |
+ if(pcm_samples) | |
+ { | |
+ result = ismd_ffmpeg_audio_encoder_port_write(p_aud_enc ,pcm_samples, frame_bytes, ISMD_NO_PTS ); | |
+ if (result != ISMD_SUCCESS) | |
+ { | |
+ av_log( NULL, AV_LOG_ERROR, "\nismd_ffmpeg_audio_encoder_port_write failed error: %d\n",result); | |
+ return result; | |
+ } | |
+ } | |
+ if(pcm_samples == NULL) | |
+ { | |
+ if(p_aud_enc->eos_written == false) | |
+ { | |
+ av_log(NULL, AV_LOG_DEBUG, "\n************ writing eos to audio encoder**************\n"); | |
+ ismd_ffmpeg_send_eos_audenc(p_aud_enc); | |
+ p_aud_enc->eos_written = true; | |
+ } | |
+ av_log(NULL, AV_LOG_DEBUG, "\n************ p_aud_enc->eos_received %d***\n",p_aud_enc->eos_received); | |
+ //last frame received | |
+ //need to put some sleep to flush out audio encoder | |
+ ts.tv_sec = 0; | |
+ ts.tv_nsec = 100; | |
+ nanosleep (&ts, NULL); | |
+ } | |
+ | |
+ if ((pkt_size = syno_ismd_ffmpeg_audio_encoder_get_first_node_size(p_aud_enc)) < 0) { | |
+ av_log(NULL, AV_LOG_FATAL, "ismd_ffmpeg_video_encoder_dequeue_size_syno\n"); | |
+ return -1; | |
+ } | |
+ if (pkt_size > 0) { | |
+ if (syno_alloc_packet(avpkt, pkt_size) < 0) { | |
+ av_log(NULL, AV_LOG_FATAL, "syno_alloc_packet error at encoder SMD\n"); | |
+ return -1; | |
+ } | |
+ ismd_ffmpeg_aud_encoder_dequeue(p_aud_enc, avpkt->data, &avpkt->size); | |
+ if (avpkt->size != pkt_size) { | |
+ av_log(NULL, AV_LOG_FATAL, "ismd_ffmpeg_video_encoder_dequeue size not conform\n"); | |
+ } | |
+ memset(avpkt->data + avpkt->size, 0, FF_INPUT_BUFFER_PADDING_SIZE); | |
+ } | |
+ if(pcm_samples == NULL) | |
+ av_log( NULL, AV_LOG_DEBUG, "\nNULL frame received in ismd_ffmpeg_enc_aud_samples data copied %d\n", avpkt->size); | |
+ | |
+ return ISMD_SUCCESS; | |
+} | |
+int ismd_ffmpeg_got_codec_parameters(AVCodecContext *avctx) | |
+{ | |
+ int val; | |
+ switch (avctx->codec_type) { | |
+ case AVMEDIA_TYPE_AUDIO: | |
+ av_log(avctx,AV_LOG_DEBUG,"sample rate %d channels %d sample_fmt %d frame_size %d codec id %d channel_layout %lld\n",avctx->sample_rate,avctx->channels,avctx->sample_fmt,avctx->frame_size,avctx->codec_id,avctx->channel_layout); | |
+ val = avctx->sample_rate && avctx->channels && avctx->sample_fmt != AV_SAMPLE_FMT_NONE && avctx->channel_layout; | |
+ break; | |
+ case AVMEDIA_TYPE_VIDEO: | |
+ val = avctx->width && avctx->pix_fmt != PIX_FMT_NONE; | |
+ break; | |
+ case AVMEDIA_TYPE_DATA: | |
+ if(avctx->codec_id == CODEC_ID_NONE) return 1; | |
+ default: | |
+ val = 1; | |
+ break; | |
+ } | |
+ return avctx->codec_id != CODEC_ID_NONE && val != 0; | |
+} | |
+ismd_result_t ismd_ffmpeg_create_video_pipeline(AVCodecContext *ocodec , viddec_struct_t* p_vid_dec , videnc_struct_t* p_vid_enc, const int dtv_smd) | |
+{ | |
+ ismd_result_t result = ISMD_ERROR_UNSPECIFIED; | |
+ ismd_dev_t vidpproc_handle; | |
+ ismd_port_handle_t vidpproc_ip_port; /* input port */ | |
+ ismd_port_handle_t vidpproc_op_port; /* output port */ | |
+ ismd_videnc_stream_init_params_t videnc_stream_init_params; | |
+ ismd_videnc_codec_init_params_t videnc_codec_init_params; | |
+ ismd_videnc_h264_encoder_params_t videnc_h264_encoder_params; | |
+ X264Context *x4; | |
+ int profile,level; | |
+ int result_temp = -1; | |
+ uint32_t max_bitrate; | |
+ osal_result thread_result; | |
+ char port_read_thread[15]; | |
+ if ((result = ismd_viddec_get_input_port(p_vid_dec->viddec_handle,&p_vid_dec->ip_port)) != ISMD_SUCCESS) | |
+ { | |
+ av_log(NULL, AV_LOG_ERROR,"\nismd_viddec_get_input_port: failed error %d\n",result); | |
+ return result; | |
+ } | |
+ // get outport for video decoder | |
+ if ((result = ismd_viddec_get_output_port(p_vid_dec->viddec_handle,&p_vid_dec->op_port)) != ISMD_SUCCESS) | |
+ | |
+ { | |
+ av_log(NULL, AV_LOG_ERROR,"\nismd_viddec_get_output_port: failed error %d\n",result); | |
+ return result; | |
+ } | |
+ result = ismd_event_alloc(&p_vid_dec->input_port_event); | |
+ if (result != ISMD_SUCCESS) | |
+ { | |
+ av_log(NULL,AV_LOG_ERROR,"\nismd_event_alloc failed error %d\n",result); | |
+ return result; | |
+ } | |
+ result = ismd_port_attach(p_vid_dec->ip_port, p_vid_dec->input_port_event, ISMD_QUEUE_EVENT_NOT_FULL, ISMD_QUEUE_WATERMARK_NONE); | |
+ if (result != ISMD_SUCCESS) | |
+ { | |
+ av_log(NULL,AV_LOG_ERROR,"\nismd_port_attach failed error %d\n",result); | |
+ return result; | |
+ } | |
+ | |
+ result = ismd_event_reset(p_vid_dec->input_port_event); | |
+ if (result != ISMD_SUCCESS) | |
+ { | |
+ av_log(NULL,AV_LOG_ERROR,"\n ismd_event_reset failed error %d\n",result); | |
+ return result; | |
+ } | |
+ | |
+ if (dtv_smd) { | |
+ result = ismd_viddec_set_pts_interpolation_policy(p_vid_dec->viddec_handle, ISMD_VIDDEC_NO_PTS_INTERPOLATION , ISMD_NO_PTS); | |
+ } else { | |
+ result = ismd_viddec_set_pts_interpolation_policy(p_vid_dec->viddec_handle, ISMD_VIDDEC_INTERPOLATE_ALL_PTS, ISMD_NO_PTS); | |
+ } | |
+ | |
+ if (result != ISMD_SUCCESS) | |
+ { | |
+ av_log(NULL,AV_LOG_ERROR,"\nismd_viddec_set_pts_interpolation_policy failed error %d\n",result); | |
+ return result; | |
+ } | |
+ | |
+ p_vid_dec->send_sps_pps =true; | |
+ result = ismd_dev_set_state(p_vid_dec->viddec_handle, ISMD_DEV_STATE_PAUSE); | |
+ if (result != ISMD_SUCCESS) | |
+ { | |
+ av_log(NULL,AV_LOG_ERROR,"\nismd_dev_set_state failed error %d\n",result); | |
+ return -1; | |
+ } | |
+ //setup video post processor | |
+ result = ismd_vidpproc_open(&vidpproc_handle) ; | |
+ if (result != ISMD_SUCCESS) | |
+ { | |
+ av_log(NULL,AV_LOG_ERROR,"\nismd_vidpproc_open failed error %d\n",result); | |
+ return -1; | |
+ } | |
+ result = ismd_vidpproc_deringing_disable(vidpproc_handle) ; | |
+ if (result != ISMD_SUCCESS) | |
+ { | |
+ av_log(NULL,AV_LOG_ERROR,"\nismd_vidpproc_deringing_disable failed error %d\n",result); | |
+ return -1; | |
+ } | |
+ | |
+ result = ismd_vidpproc_gaussian_enable(vidpproc_handle) ; | |
+ if (result != ISMD_SUCCESS) | |
+ { | |
+ av_log(NULL,AV_LOG_ERROR,"\nismd_vidpproc_gaussian_enable failed error %d\n",result); | |
+ return -1; | |
+ } | |
+ result = ismd_vidpproc_pan_scan_enable(vidpproc_handle); | |
+ if (result != ISMD_SUCCESS) | |
+ { | |
+ av_log(NULL,AV_LOG_ERROR,"\nismd_vidpproc_pan_scan_enable failed error %d\n",result); | |
+ return -1; | |
+ } | |
+ result = ismd_vidpproc_get_input_port(vidpproc_handle, &vidpproc_ip_port) ; | |
+ if (result != ISMD_SUCCESS) | |
+ { | |
+ av_log(NULL,AV_LOG_ERROR,"\nismd_vidpproc_get_input_port failed error %d\n",result); | |
+ return -1; | |
+ } | |
+ result = ismd_vidpproc_get_output_port(vidpproc_handle, &vidpproc_op_port) ; | |
+ if (result != ISMD_SUCCESS) | |
+ { | |
+ av_log(NULL,AV_LOG_ERROR,"\nismd_vidpproc_get_output_port failed error %d\n",result); | |
+ return -1; | |
+ } | |
+ if(ocodec->width > 1920) | |
+ { | |
+ av_log(NULL,AV_LOG_ERROR,"\ninvalid dest width requested:%d",ocodec->width); | |
+ av_log(NULL,AV_LOG_ERROR,"\nmax width supported by smd :1920\n"); | |
+ return -1; | |
+ } | |
+ if(ocodec->height > 1400) | |
+ { | |
+ av_log(NULL,AV_LOG_ERROR,"\ninvalid dest height requested:%d",ocodec->height); | |
+ av_log(NULL,AV_LOG_ERROR,"\nmax height supported by smd :1400\n"); | |
+ return -1; | |
+ } | |
+ result = ismd_vidpproc_set_dest_params(vidpproc_handle,ocodec->width,ocodec->height,ocodec->sample_aspect_ratio.num,ocodec->sample_aspect_ratio.den);//for scaling | |
+ if (result != ISMD_SUCCESS) | |
+ { | |
+ av_log(NULL,AV_LOG_ERROR,"\nismd_vidpproc_set_dest_params failed error %d\n",result); | |
+ return -1; | |
+ } | |
+ result = ismd_dev_set_state(vidpproc_handle, ISMD_DEV_STATE_STOP); | |
+ if (result != ISMD_SUCCESS) | |
+ { | |
+ av_log(NULL,AV_LOG_ERROR,"\nismd_dev_set_state failed error %d\n",result); | |
+ return -1; | |
+ } | |
+ //setup video encoder | |
+ | |
+ videnc_stream_init_params.max_frame_width = 1920; // Default to HD | |
+ videnc_stream_init_params.max_frame_height = 1088; | |
+ videnc_stream_init_params.scene_change_control.lookahead_count = 0; | |
+ x4 = ocodec->priv_data; | |
+ if(x4->profile) | |
+ { | |
+ profile = ismd_ffmpeg_profile_string_to_int(x4->profile); | |
+ if(profile < 0) | |
+ { | |
+ av_log(NULL, AV_LOG_ERROR, "\nprofile not supported\n"); | |
+ return -1; | |
+ } | |
+ else | |
+ { | |
+ videnc_codec_init_params.h264_init_params.profile = profile; | |
+ } | |
+ } | |
+ else | |
+ { | |
+ videnc_codec_init_params.h264_init_params.profile = ISMD_VIDENC_H264_PROFILE_HIGH; | |
+ } | |
+ | |
+ if(x4->level) | |
+ { | |
+ level = ismd_ffmpeg_level_string_to_int(x4->level); | |
+ if(level < 0) | |
+ { | |
+ av_log(NULL, AV_LOG_ERROR, "\nlevel %s not supported\n",x4->level); | |
+ return -1; | |
+ } | |
+ else | |
+ { | |
+ videnc_codec_init_params.h264_init_params.level = level; | |
+ } | |
+ } | |
+ else | |
+ { | |
+ videnc_codec_init_params.h264_init_params.level = ISMD_VIDENC_H264_LEVEL_4_1; | |
+ } | |
+ | |
+ videnc_stream_init_params.scene_change_control.scene_change_detect_enabled = false; | |
+ result = ismd_videnc_open(ISMD_CODEC_TYPE_H264,&videnc_stream_init_params, &videnc_codec_init_params, &p_vid_enc->videnc_handle); | |
+ if(result != ISMD_SUCCESS) | |
+ { | |
+ av_log(NULL,AV_LOG_ERROR,"failed at ismd_videnc_open error %d\n", result); | |
+ return -1; | |
+ } | |
+ result = ismd_videnc_get_input_port(p_vid_enc->videnc_handle, &p_vid_enc->ip_port); | |
+ if(result != ISMD_SUCCESS) | |
+ { | |
+ av_log(NULL,AV_LOG_ERROR,"failed at ismd_videnc_get_input_port error %d\n",result); | |
+ return -1; | |
+ } | |
+ result = ismd_videnc_get_output_port(p_vid_enc->videnc_handle, &p_vid_enc->op_port); | |
+ if(result != ISMD_SUCCESS) | |
+ { | |
+ av_log(NULL,AV_LOG_ERROR,"failed at ismd_videnc_get_output_port error %d\n",result); | |
+ return -1; | |
+ } | |
+ result = ismd_event_alloc(&p_vid_enc->output_port_event); | |
+ if (result != ISMD_SUCCESS) | |
+ { | |
+ av_log(NULL,AV_LOG_ERROR,"\nismd_event_alloc failed error %d\n",result); | |
+ return -1; | |
+ } | |
+ result = ismd_port_attach(p_vid_enc->op_port, p_vid_enc->output_port_event,ISMD_QUEUE_EVENT_NOT_EMPTY|ISMD_QUEUE_EVENT_FULL, ISMD_QUEUE_EVENT_HIGH_WATERMARK); | |
+ | |
+ if (result != ISMD_SUCCESS) | |
+ { | |
+ av_log(NULL,AV_LOG_ERROR,"\nismd_port_attach222 failed error %d\n",result); | |
+ return -1; | |
+ } | |
+ result = ismd_event_reset(p_vid_enc->output_port_event); | |
+ if (result != ISMD_SUCCESS) | |
+ { | |
+ av_log(NULL,AV_LOG_ERROR,"\n FAILURE: ismd_event_reset222 failed error %d\n",result); | |
+ return -1; | |
+ } | |
+ | |
+ result = ismd_videnc_h264_get_encoding_params(p_vid_enc->videnc_handle, &videnc_h264_encoder_params); | |
+ if(result != ISMD_SUCCESS) | |
+ { | |
+ av_log(NULL,AV_LOG_ERROR,"failed at ismd_videnc_h264_get_encoding_params error %d\n",result); | |
+ return -1; | |
+ } | |
+ | |
+ videnc_h264_encoder_params.chroma_format = ISMD_VIDENC_H264_CHROMA_FORMAT_4_2_0; //can only be configured at compile time in libx264 | |
+ if((videnc_codec_init_params.h264_init_params.profile != ISMD_VIDENC_H264_PROFILE_BASELINE)&&(ocodec->coder_type != 0)) | |
+ { | |
+ videnc_h264_encoder_params.entropy = ISMD_VIDENC_H264_ENTROPY_MODE_CABAC; | |
+ } | |
+ videnc_h264_encoder_params.aspect_ratio =ISMD_VIDENC_H264_ASPECT_RATIO_NONE; | |
+ videnc_h264_encoder_params.bitrate_settings.bitrate_mode = ISMD_VIDENC_H264_RATE_CONTROL_VBR; | |
+ result_temp = ismd_ffmpeg_get_max_bitrate(videnc_codec_init_params.h264_init_params.profile, videnc_codec_init_params.h264_init_params.level,&max_bitrate); | |
+ if(result_temp < 0) | |
+ { | |
+ av_log(NULL, AV_LOG_ERROR, "\nEroor setting max_bitrate error %d\n",result_temp); | |
+ return -1; | |
+ } | |
+ else | |
+ { | |
+ videnc_h264_encoder_params.bitrate_settings.max_bitrate = max_bitrate;// 40000000; | |
+ } | |
+ if(ocodec->bit_rate) | |
+ { | |
+ videnc_h264_encoder_params.bitrate_settings.bitrate = ocodec->bit_rate; | |
+ } | |
+ else | |
+ { | |
+ videnc_h264_encoder_params.bitrate_settings.bitrate = 3000000;//300000;// 3000000; | |
+ } | |
+ if(ocodec->gop_size >= 0) | |
+ { | |
+ videnc_h264_encoder_params.gop_settings.GOP_length = ocodec->gop_size; | |
+ } | |
+ else | |
+ { | |
+ videnc_h264_encoder_params.gop_settings.GOP_length = 24; | |
+ } | |
+ if(ocodec->max_b_frames >= 0) | |
+ { | |
+ if(ocodec->max_b_frames < 3) | |
+ videnc_h264_encoder_params.gop_settings.num_of_B_frames = ocodec->max_b_frames; | |
+ else | |
+ return -1; | |
+ } | |
+ else | |
+ { | |
+ videnc_h264_encoder_params.gop_settings.num_of_B_frames = 2;//[0..2] Maximum number of consecutive B Frame in a GOP. | |
+ } | |
+ if(ocodec->keyint_min >= 0) | |
+ { | |
+ videnc_h264_encoder_params.gop_settings.IDR_Frequency = ocodec->keyint_min; | |
+ } | |
+ else | |
+ { | |
+ videnc_h264_encoder_params.gop_settings.IDR_Frequency = 24;//0 is a special value to be set when scd(EPU) enabled | |
+ } | |
+ videnc_h264_encoder_params.qp_mode = ISMD_VIDENC_H264_QP_UNIFORM; | |
+ | |
+ if(ismd_ffmpeg_videnc_h264_set_encoding_params(p_vid_enc->videnc_handle,&videnc_h264_encoder_params) != ISMD_SUCCESS) | |
+ { | |
+ av_log(NULL,AV_LOG_ERROR,"\nError setting h264 encoding parameters\n"); | |
+ return -1; | |
+ | |
+ } | |
+ p_vid_enc->eos_received = false; | |
+ result = ismd_dev_set_state(p_vid_enc->videnc_handle, ISMD_DEV_STATE_STOP); | |
+ if (result != ISMD_SUCCESS) | |
+ { | |
+ av_log(NULL,AV_LOG_ERROR,"\n FAILURE: could not stop video decoder error %d\n",result); | |
+ return -1; | |
+ } | |
+ //now connect the pipeline | |
+ result = ismd_port_connect(p_vid_dec->op_port, vidpproc_ip_port); | |
+ if (result != ISMD_SUCCESS) | |
+ { | |
+ av_log(NULL,AV_LOG_ERROR,"\n FAILURE: could not connect decoder to postproc error %d\n",result); | |
+ return -1; | |
+ } | |
+ result = ismd_port_connect(vidpproc_op_port,p_vid_enc->ip_port); | |
+ if (result != ISMD_SUCCESS) | |
+ { | |
+ av_log(NULL,AV_LOG_ERROR,"\n FAILURE: could not connect postproc to encoder error %d\n",result); | |
+ return -1; | |
+ } | |
+ | |
+ //set the pipeline to play state | |
+ result = ismd_dev_set_state(p_vid_enc->videnc_handle, ISMD_DEV_STATE_PLAY); | |
+ if (result != ISMD_SUCCESS) | |
+ { | |
+ av_log(NULL,AV_LOG_ERROR,"\n FAILURE: could not start video encoder error %d\n",result); | |
+ return -1; | |
+ } | |
+ result = ismd_dev_set_state(vidpproc_handle, ISMD_DEV_STATE_PLAY); | |
+ if (result != ISMD_SUCCESS) | |
+ { | |
+ av_log(NULL,AV_LOG_ERROR,"\n FAILURE: could not start video post processor error %d\n",result); | |
+ return -1; | |
+ } | |
+ result = ismd_dev_set_state(p_vid_dec->viddec_handle, ISMD_DEV_STATE_PLAY); | |
+ if (result != ISMD_SUCCESS) | |
+ { | |
+ av_log(NULL,AV_LOG_ERROR,"\n FAILURE: could not start video decoder error %d\n",result); | |
+ return -1; | |
+ } | |
+ pthread_mutex_init(&p_vid_enc->mutex, NULL); | |
+ thread_result = os_thread_create(&p_vid_enc->output_thread, ismd_ffmpeg_videnc_output_thread, (void*)(p_vid_enc), 0, 0, port_read_thread); | |
+ if (thread_result != OSAL_SUCCESS) | |
+ { | |
+ av_log(NULL, AV_LOG_ERROR, "\nvideo encoder o/p thread creation failed\n"); | |
+ return -1; | |
+ } | |
+ | |
+ return ISMD_SUCCESS; | |
+} | |
+ | |
+ismd_result_t ismd_ffmpeg_fill_videnc_buffer(AVCodecContext *ctx, AVFrame* frame,ismd_buffer_handle_t h, int64_t pts, int* data_used) | |
+{ | |
+ ismd_result_t result = ISMD_SUCCESS; | |
+ ismd_buffer_descriptor_t d; | |
+ ismd_frame_attributes_t* attribs; | |
+ char *virt_addr = NULL; | |
+ void* y_addr = NULL; | |
+ void* u_addr = NULL; | |
+ void* v_addr = NULL; | |
+ int total_data_copied = 0; | |
+ unsigned int image_size; | |
+ int k = 0; | |
+ int x = 0; | |
+ int y = 0; | |
+ char *y_mem=frame->data[0]; | |
+ char *u_mem=frame->data[1]; | |
+ char *v_mem=frame->data[2]; | |
+ if ((result = ismd_buffer_read_desc(h, &d)) == ISMD_SUCCESS) | |
+ { | |
+ if (0 == d.phys.size) | |
+ { | |
+ return -1; | |
+ } | |
+ image_size = 2048 * ((3*ctx->height)/2); | |
+ virt_addr = OS_MAP_IO_TO_MEM_NOCACHE(d.phys.base,image_size); | |
+ av_log(NULL,AV_LOG_DEBUG,"\n **d.phys.base %u d.phys.size %d image_size %d frame size %d virt_addr %p\n",d.phys.base,d.phys.size,image_size,ctx->width*(3*ctx->height)/2,virt_addr); | |
+ if(virt_addr == NULL) | |
+ av_log(NULL,AV_LOG_ERROR,"\n *********** ERROR********* OS_MAP_IO_TO_MEM_NOCACHE failed\n"); | |
+ attribs = (ismd_frame_attributes_t *)(&d.attributes); | |
+ attribs->local_pts = pts; | |
+ attribs->original_pts = pts; | |
+ attribs->cont_rate = 3000; | |
+ attribs->local_cont_rate= 3000; | |
+ attribs->polarity = ISMD_POLARITY_FRAME; | |
+ attribs->pixel_format = ISMD_PF_NV12; | |
+ attribs->cont_size.width = ctx->width; | |
+ attribs->cont_size.height = ctx->height; | |
+ attribs->scanline_stride = 2048; | |
+ av_log(NULL,AV_LOG_DEBUG,"\nctx->width %d ctx->height %d linesize[0] %d linesize[1] %d linesize[2] %d d.phys.base %d attribs->y %d attribs->u %d\n",ctx->width,ctx->height,frame->linesize[0],frame->linesize[1],frame->linesize[2],d.phys.base,attribs->y,attribs->u); | |
+ attribs->y = 0; | |
+ attribs->u = attribs->scanline_stride * ctx->height; | |
+ y_addr = virt_addr + attribs->y; | |
+ u_addr = virt_addr + attribs->u; | |
+ v_addr = virt_addr + attribs->u; | |
+ //LUMA | |
+ for(k=0; k<ctx->height ; k++) | |
+ { | |
+ memmove(y_addr,(y_mem + (k*frame->linesize[0])),ctx->width); | |
+ total_data_copied +=ctx->width; | |
+ y_addr =(char*)y_addr+ 2048; | |
+ | |
+ } | |
+ total_data_copied -=ctx->width; | |
+ // similarily CHROMA | |
+ //Be sure how you feeding Chroma as NV12(interleaved) UV(planar). | |
+ //Update this accordingly attribs->pixel_format = ISMD_PF_NV12; | |
+ | |
+ // | |
+ // UV | |
+ // | |
+ | |
+ for ( y = 0; y < ctx->height / 2; y++ ) | |
+ { | |
+ for (x = 0; x < ctx->width/2; x++ ) | |
+ { | |
+ ((char*)u_addr)[2*x] = u_mem[x]; | |
+ ((char*)v_addr)[2*x+1] = v_mem[x]; | |
+ total_data_copied +=2; | |
+ | |
+ } | |
+ u_addr=(char*)u_addr+2048; | |
+ u_mem+=frame->linesize[1]; | |
+ | |
+ v_addr=(char*)v_addr+2048; | |
+ v_mem+=frame->linesize[2]; | |
+ } | |
+ av_log(NULL,AV_LOG_DEBUG,"\n linesize[0] %d frame->linesize[1] %d frame->linesize[2] %d\n",frame->linesize[0],frame->linesize[1],frame->linesize[2]); | |
+ total_data_copied -=2; | |
+ *data_used = total_data_copied; | |
+ if(total_data_copied > d.phys.size) | |
+ av_log(NULL,AV_LOG_ERROR,"\n ********************* ERROR********* d.phys.size %d total_data_copied %d \n",d.phys.size,total_data_copied); | |
+ | |
+ result = ismd_buffer_update_desc(h, &d); | |
+ if(result != ISMD_SUCCESS) | |
+ { | |
+ av_log(NULL,AV_LOG_ERROR,"\n###### ff_fill_videnc_buffer ismd_buffer_update_desc failed ISMD_ERROR_OUT_OF_RANGE %d result %d SYSTEM_STRIDE %d ######\n",ISMD_ERROR_OUT_OF_RANGE,result,SYSTEM_STRIDE); | |
+ return -1; | |
+ } | |
+ OS_UNMAP_IO_FROM_MEM(virt_addr, image_size); | |
+ } | |
+ return result; | |
+} | |
+ | |
+ismd_result_t syno_ismd_ffmpeg_fill_viddec_buffer(const uint8_t *buf, ismd_buffer_handle_t h,size_t buffer_size, int64_t pts) | |
+{ | |
+ ismd_result_t result = ISMD_SUCCESS; | |
+ ismd_buffer_descriptor_t d; | |
+ ismd_frame_attributes_t *frame = NULL; | |
+ char *virt_addr = NULL; | |
+ | |
+ if ((result = ismd_buffer_read_desc(h, &d)) == ISMD_SUCCESS) | |
+ { | |
+ | |
+ if (0 == d.phys.size) | |
+ { | |
+ return result; | |
+ } | |
+ virt_addr = OS_MAP_IO_TO_MEM_CACHE(d.phys.base,d.phys.size); | |
+ frame = (ismd_frame_attributes_t *) (&d.attributes); | |
+ frame->local_pts = pts; | |
+ frame->original_pts = pts; | |
+ | |
+ memmove((void *)virt_addr,buf,buffer_size); | |
+ OS_UNMAP_IO_FROM_MEM(virt_addr, d.phys.size); | |
+ d.phys.level = buffer_size; | |
+ result = ismd_buffer_update_desc(h, &d); | |
+ } | |
+ return result; | |
+} | |
+ | |
+ismd_result_t syno_ismd_ffmpeg_decode_vid_buf(viddec_struct_t* viddec, const uint8_t* buf, int buf_size, int64_t pts) | |
+{ | |
+ ismd_result_t result = ISMD_SUCCESS; | |
+ int size_quotient; | |
+ long data_written=0; | |
+ int loop; | |
+ long write_size=CHUNK_SIZE; | |
+ ismd_buffer_handle_t ismd_buf = -1; | |
+ | |
+ if (buf_size > 0) | |
+ { | |
+ size_quotient = buf_size / CHUNK_SIZE; | |
+ if(size_quotient >0) | |
+ write_size=CHUNK_SIZE; | |
+ else | |
+ write_size=buf_size; | |
+ | |
+ //write data to video decoder input port in CHUNK_SIZE | |
+ for(loop = 0;loop <= size_quotient; loop++) | |
+ { | |
+ //DEBUG_MSG(g_debug_level,DEBUG_VERBOSITY_4,("** buf_size %d CHUNK_SIZE %d size_quotient %d *****",buf_size,CHUNK_SIZE,size_quotient)); | |
+ | |
+ if(buf_size > 0) | |
+ { | |
+ if ((result = ismd_buffer_alloc(CHUNK_SIZE, &ismd_buf)) == ISMD_SUCCESS) | |
+ { | |
+ //DEBUG_MSG(g_debug_level,DEBUG_VERBOSITY_4,("**write size %ld ********",write_size)); | |
+ if ((result = syno_ismd_ffmpeg_fill_viddec_buffer(buf+data_written, ismd_buf,write_size ,pts)) == ISMD_SUCCESS) | |
+ { | |
+ // decode it asynchronously | |
+ if ((result = ismd_ffmpeg_decoder_port_write(viddec,ismd_buf)) != ISMD_SUCCESS) | |
+ { | |
+ //DEBUG_MSG(g_debug_level,DEBUG_VERBOSITY_1,("\n** error: unable to decode smd_buffers22 [%d] buf_size %d\n", result,buf_size)); | |
+ } | |
+ data_written += write_size; | |
+ viddec->input_buffers += write_size; | |
+ if((buf_size - data_written) < CHUNK_SIZE) | |
+ { | |
+ write_size = buf_size - data_written; | |
+ } | |
+ else | |
+ { | |
+ write_size = CHUNK_SIZE; | |
+ } | |
+ //DEBUG_MSG(g_debug_level,DEBUG_VERBOSITY_4,("Total bytes written to i/p port till now %d",viddec->input_buffers)); | |
+ } | |
+ else | |
+ { | |
+ result= ismd_buffer_dereference(ismd_buf); | |
+ //DEBUG_MSG(g_debug_level,DEBUG_VERBOSITY_1,("\n********unable to fill out smd_buffer\n")); | |
+ } | |
+ } | |
+ else | |
+ { | |
+ // alloc memory failed | |
+ // retry after a delay | |
+ if (result == ISMD_ERROR_NO_RESOURCES) | |
+ { | |
+ //DEBUG_MSG(g_debug_level,DEBUG_VERBOSITY_1,("\nunable to allocate buffer in decode_frame error: [%d]\n",result)); | |
+ } | |
+ else | |
+ { | |
+ //DEBUG_MSG(g_debug_level,DEBUG_VERBOSITY_1,("\narning: unable to allocate input buffer [%d]\n",result)); | |
+ } | |
+ } | |
+ | |
+ } | |
+ } | |
+ } | |
+ else | |
+ { | |
+ if((buf_size == 0)&&(viddec->eos_written == false)) | |
+ { | |
+ result = ismd_ffmpeg_send_eos_viddec(viddec); | |
+ if(ISMD_SUCCESS == result) | |
+ { | |
+ //DEBUG_MSG(g_debug_level,DEBUG_VERBOSITY_4,("written eos to video decoder result %d",result)); | |
+ viddec->eos_written = true; | |
+ } | |
+ } | |
+ | |
+ } | |
+ return result; | |
+} | |
+ | |
+static void syno_heap_bubble_up(AVPacket *avpkt, int index) | |
+{ | |
+ while (index) { | |
+ int parent = (index - 1) >> 1; | |
+ if (packets[parent].pts < avpkt->pts) { | |
+ break; | |
+ } | |
+ av_copy_packet(&packets[index], &packets[parent]); | |
+ av_free_packet(&packets[parent]); | |
+ index = parent; | |
+ } | |
+ av_copy_packet(&packets[index], avpkt); | |
+ av_free_packet(avpkt); | |
+ | |
+ return 0; | |
+} | |
+ | |
+static void syno_heap_bubble_down(AVPacket *avpkt, int index) | |
+{ | |
+ while (1) { | |
+ int child = 2 * index + 1; | |
+ if (child >= nb_packet) { | |
+ break; | |
+ } | |
+ if (child+1 < nb_packet && packets[child+1].pts < packets[child].pts) { | |
+ child++; | |
+ } | |
+ if (avpkt->pts < packets[child].pts) { | |
+ break; | |
+ } | |
+ av_copy_packet(&packets[index], &packets[child]); | |
+ av_free_packet(&packets[child]); | |
+ index = child; | |
+ } | |
+ av_copy_packet(&packets[index], avpkt); | |
+ av_free_packet(avpkt); | |
+} | |
+ | |
+int syno_smd_push_heap(AVPacket *avpkt) | |
+{ | |
+ if (NULL == avpkt) { | |
+ return -1; | |
+ } | |
+ | |
+ if (nb_packet >= SZ_MAX_PACKATES) { | |
+ //av_free_packet(packets[nb_packet-1]); | |
+ av_free_packet(avpkt); | |
+ return 0; | |
+ } else { | |
+ nb_packet++; | |
+ } | |
+ syno_heap_bubble_up(avpkt, nb_packet-1); | |
+ return 0; | |
+} | |
+ | |
+//* @return < 0, error. | |
+// 0, get a packst. | |
+// 1, finish. | |
+// 2, not ready. | |
+int syno_smd_get_heap(AVPacket *avpkt, int flush) | |
+{ | |
+ if (NULL == avpkt) { | |
+ return -1; | |
+ } | |
+ | |
+ if (1 == flush && nb_packet <= 0) { | |
+ return 1; | |
+ } | |
+ | |
+ if (0 == flush && nb_packet <= 32) { | |
+ return 2; | |
+ } | |
+ | |
+ av_init_packet(avpkt); | |
+ av_copy_packet(avpkt, &packets[0]); | |
+ av_free_packet(&packets[0]); | |
+ | |
+ nb_packet--; | |
+ if (0 == nb_packet){ | |
+ return 1;//finish | |
+ } | |
+ syno_heap_bubble_down(&packets[nb_packet], 0); | |
+ return 0; | |
+} | |
+#endif | |
diff --git a/libavcodec/ismd_ffmpeg_audio_util.h b/libavcodec/ismd_ffmpeg_audio_util.h | |
new file mode 100644 | |
index 0000000000..d016361003 | |
--- /dev/null | |
+++ b/libavcodec/ismd_ffmpeg_audio_util.h | |
@@ -0,0 +1,55 @@ | |
+/* | |
+ * This file contains utility functions | |
+ * Copyright (c) 2012, Intel Corporation. | |
+ * | |
+ * This program is free software; you can redistribute it and/or modify it | |
+ * under the terms and conditions of the GNU Lesser General Public License, | |
+ * version 2.1, as published by the Free Software Foundation. | |
+ * | |
+ * This program is distributed in the hope 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 program; if not, write to the Free Software Foundation, Inc., | |
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | |
+ * | |
+ */ | |
+ | |
+#ifndef AVCODEC_SMDAUDIOUTILS_H | |
+#define AVCODEC_SMDAUDIOUTILS_H | |
+ | |
+#include "synoconfig.h" | |
+ | |
+#ifdef SYNO_EVANSPORT_SMD | |
+#include "libffmpeg_plugin/ismd_ffmpeg_video_dec.h" | |
+#include "libffmpeg_plugin/ismd_ffmpeg_video_enc.h" | |
+#include "ismd_audio_defs.h" | |
+#include "libffmpeg_plugin/ismd_ffmpeg_audio_dec.h" | |
+#include "libffmpeg_plugin/ismd_ffmpeg_audio_enc.h" | |
+int ismd_ffmpeg_get_ismd_audio_channel_config(AVCodecContext *avctx); | |
+ | |
+ismd_result_t ismd_ffmpeg_setup_aud_dec(AVCodecContext *avctx , audiodec_struct* p_aud_dec , ismd_audio_format_t ip_aud_fmt, int aac_bs_fmt); | |
+ | |
+ismd_result_t ismd_ffmpeg_setup_aud_enc(AVCodecContext *avctx , audenc_struct_t* p_aud_enc , ismd_audio_output_mode_t op_aud_mode); | |
+ | |
+ismd_result_t ismd_ffmpeg_config_aud_dec(AVCodecContext *avctx , audiodec_struct* p_aud_dec , ismd_audio_format_t ip_aud_fmt, int aac_bs_fmt); | |
+ | |
+ismd_result_t ismd_ffmpeg_config_aud_enc(AVCodecContext *avctx , audenc_struct_t* p_aud_enc , ismd_audio_output_mode_t op_aud_mode); | |
+ | |
+ismd_result_t ismd_ffmpeg_create_video_pipeline(AVCodecContext *avctx , viddec_struct_t* p_vid_dec , videnc_struct_t* p_vid_enc, const int dtv_smd); | |
+ | |
+ismd_result_t ismd_ffmpeg_dec_aud_buf(AVCodecContext *avctx ,void *out_data, audiodec_struct* p_aud_dec,const uint8_t *ip_buf,int buf_size,int *got_frame_ptr); | |
+ | |
+ismd_result_t ismd_ffmpeg_enc_aud_samples(AVCodecContext *avctx ,AVPacket *avpkt, audenc_struct_t* p_aud_enc, void *pcm_samples,int frame_bytes); | |
+ | |
+int ismd_ffmpeg_got_codec_parameters(AVCodecContext *avctx); | |
+ismd_result_t ismd_ffmpeg_fill_videnc_buffer(AVCodecContext *ctx, AVFrame* frame,ismd_buffer_handle_t h, int64_t pts, int* data_used); | |
+ | |
+ismd_result_t syno_ismd_ffmpeg_decode_vid_buf(viddec_struct_t* viddec, const uint8_t* buf, int buf_size, int64_t pts); | |
+ismd_result_t syno_ismd_ffmpeg_fill_viddec_buffer(const uint8_t *buf, ismd_buffer_handle_t h,size_t buffer_size, int64_t pts); | |
+int syno_smd_push_heap(AVPacket *avpkt); | |
+int syno_smd_get_heap(AVPacket *avpkt, int flush); | |
+#endif | |
+#endif | |
diff --git a/libavcodec/libavcodec.v b/libavcodec/libavcodec.v | |
index c923cd378f..659bde20a8 100644 | |
--- a/libavcodec/libavcodec.v | |
+++ b/libavcodec/libavcodec.v | |
@@ -3,5 +3,7 @@ LIBAVCODEC_$MAJOR { | |
#deprecated, remove after next bump | |
audio_resample; | |
audio_resample_close; | |
+ ismd*; | |
+ syno*; | |
local: *; | |
}; | |
diff --git a/libavcodec/libfaac.c b/libavcodec/libfaac.c | |
index 69c186b11a..de789c10e8 100644 | |
--- a/libavcodec/libfaac.c | |
+++ b/libavcodec/libfaac.c | |
@@ -32,6 +32,8 @@ | |
#include "audio_frame_queue.h" | |
#include "internal.h" | |
+#include "synoconfig.h" | |
+#include "synog1codecpatent.h" | |
/* libfaac has an encoder delay of 1024 samples */ | |
#define FAAC_DELAY_SAMPLES 1024 | |
@@ -68,6 +70,12 @@ static av_cold int Faac_encode_init(AVCodecContext *avctx) | |
unsigned long samples_input, max_bytes_output; | |
int ret; | |
+#ifdef SYNO_CODEC_PATENT_G1 | |
+ if (0 != ActivateCodec("aac_enc")) { | |
+ return -1; | |
+ } | |
+#endif | |
+ | |
/* number of channels */ | |
if (avctx->channels < 1 || avctx->channels > 6) { | |
av_log(avctx, AV_LOG_ERROR, "encoding %d channel(s) is not allowed\n", avctx->channels); | |
diff --git a/libavcodec/libfdk-aacenc.c b/libavcodec/libfdk-aacenc.c | |
index 3eadb36b83..4fdc7954cf 100644 | |
--- a/libavcodec/libfdk-aacenc.c | |
+++ b/libavcodec/libfdk-aacenc.c | |
@@ -26,6 +26,9 @@ | |
#include "audio_frame_queue.h" | |
#include "internal.h" | |
+#include "synoconfig.h" | |
+#include "synog1codecpatent.h" | |
+ | |
typedef struct AACContext { | |
const AVClass *class; | |
HANDLE_AACENCODER handle; | |
@@ -111,6 +114,12 @@ static av_cold int aac_encode_init(AVCodecContext *avctx) | |
int aot = FF_PROFILE_AAC_LOW + 1; | |
int sce = 0, cpe = 0; | |
+#ifdef SYNO_CODEC_PATENT_G1 | |
+ if (0 != ActivateCodec("aac_enc")) { | |
+ return -1; | |
+ } | |
+#endif | |
+ | |
if ((err = aacEncOpen(&s->handle, 0, avctx->channels)) != AACENC_OK) { | |
av_log(avctx, AV_LOG_ERROR, "Unable to open the encoder: %s\n", | |
aac_get_error(err)); | |
diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c | |
index d25f69afbb..9eccc7fb99 100644 | |
--- a/libavcodec/libx264.c | |
+++ b/libavcodec/libx264.c | |
@@ -39,6 +39,20 @@ | |
#include <stdlib.h> | |
#include <string.h> | |
+#include "synoconfig.h" | |
+#include "synog1codecpatent.h" | |
+ | |
+#ifdef SYNO_EVANSPORT_SMD | |
+#include "libffmpeg_plugin/ismd_ffmpeg_video_enc.h" | |
+#include "libffmpeg_plugin/ismd_ffmpeg_util.h" | |
+#include "libavcodec/ismd_ffmpeg_audio_util.h" | |
+#include "syno_trans_loading.h" | |
+static videnc_struct_t vid_enc; | |
+static bool eos_written=false; | |
+static bool smd_h264_enc_video_available = false; | |
+static bool x264_closed = false; | |
+#endif | |
+ | |
typedef struct X264Context { | |
AVClass *class; | |
x264_param_t params; | |
@@ -82,6 +96,11 @@ typedef struct X264Context { | |
int nal_hrd; | |
int avcintra_class; | |
char *x264_params; | |
+#ifdef SYNO_EVANSPORT_SMD | |
+#ifdef SYNO_EVANSPORT_FLV_EXTRADATA | |
+ bool dont_free_extradata; | |
+#endif | |
+#endif | |
} X264Context; | |
static void X264_log(void *p, int level, const char *fmt, va_list args) | |
@@ -300,10 +319,147 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame, | |
return 0; | |
} | |
+#ifdef SYNO_EVANSPORT_SMD | |
+static int X264_frame_smd(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame,int *got_packet) | |
+{ | |
+ ismd_buffer_handle_t ismd_buf = -1; | |
+ ismd_result_t result = ISMD_SUCCESS; | |
+ int data_consumed = 0; | |
+ smd_h264_picture_t pic_out; | |
+ struct timespec ts; | |
+ int ret =0, pkt_size; | |
+ | |
+ if(smd_h264_enc_video_available) | |
+ { | |
+ av_log(NULL, AV_LOG_DEBUG,"\n*********using hardware encoder **************\n"); | |
+ if(frame != NULL) | |
+ { | |
+ av_log(NULL, AV_LOG_DEBUG,"\n*********i/p frame pts %lld*********\n",frame->pts); | |
+ | |
+ if ((result = ismd_frame_buffer_alloc(ctx->width, (3*ctx->height)/2, &ismd_buf)) == ISMD_SUCCESS) | |
+ { | |
+ av_log(NULL, AV_LOG_DEBUG, "\n********* ismd_frame_buffer_alloc SUCCESS ***********\n"); | |
+ if ((result = ismd_ffmpeg_fill_videnc_buffer(ctx,frame,ismd_buf,frame->pts, &data_consumed)) == ISMD_SUCCESS) | |
+ { | |
+ // encode it asynchronously | |
+ if ((result = ismd_ffmpeg_encode_buf(&vid_enc, ismd_buf)) != ISMD_SUCCESS) | |
+ { | |
+ av_log(NULL, AV_LOG_ERROR,"error: unable to decode smd_buffers [%d]\n", result); | |
+ } | |
+ //av_log(NULL, AV_LOG_INFO, "\n*********after ff_encode_buf **************\n"); | |
+ //data_written += write_size; | |
+ //vid_enc.input_buffers += write_size; | |
+ av_log(NULL, AV_LOG_DEBUG,"\n********* bytes written to i/p port %d ********\n",data_consumed); | |
+ //av_log(NULL, AV_LOG_INFO,"\n********* Total bytes written to i/p port till now %d ********\n",vid_enc.input_buffers); | |
+ } | |
+ else | |
+ { | |
+ result= ismd_buffer_dereference(ismd_buf); | |
+ av_log(NULL, AV_LOG_ERROR,"\nX264_frame unable to fill smd_buffer\n"); | |
+ } | |
+ } | |
+ else | |
+ { | |
+ // alloc memory failed | |
+ // retry after a delay | |
+ if (result == ISMD_ERROR_NO_RESOURCES) | |
+ { | |
+ av_log(NULL,AV_LOG_ERROR,"\n**************buffer allocation failed error: [%d]************\n", result); | |
+ } | |
+ else | |
+ { | |
+ av_log(NULL,AV_LOG_ERROR,"warning: unable to allocate input buffer [%d]\n", result); | |
+ } | |
+ } | |
+ } | |
+ else | |
+ { | |
+ av_log(NULL, AV_LOG_DEBUG, "\n************************** null frame received *************************\n"); | |
+ if(eos_written == false) | |
+ { | |
+ av_log(NULL, AV_LOG_DEBUG, "\n******************* writing eos *************************\n"); | |
+ ismd_ffmpeg_send_eos_videnc(&vid_enc); | |
+ eos_written = true; | |
+ } | |
+ } | |
+ | |
+ if ((pkt_size = syno_ismd_ffmpeg_video_encoder_get_first_node_size(&vid_enc)) < 0) { | |
+ av_log(NULL, AV_LOG_FATAL, "ismd_ffmpeg_video_encoder_dequeue_size_syno\n"); | |
+ return -1; | |
+ } | |
+ if (pkt_size > 0) { | |
+ if (syno_alloc_packet(pkt, pkt_size) < 0) { | |
+ av_log(NULL, AV_LOG_FATAL, "syno_alloc_packet error at encoder SMD\n"); | |
+ return -1; | |
+ } | |
+ ret = ismd_ffmpeg_video_encoder_dequeue(pkt->data, &pic_out,&vid_enc); | |
+ if (ret != pkt_size) { | |
+ av_log(NULL, AV_LOG_FATAL, "ismd_ffmpeg_video_encoder_dequeue size not conform\n"); | |
+ } | |
+ memset(pkt->data + pkt->size, 0, FF_INPUT_BUFFER_PADDING_SIZE); | |
+ } | |
+ | |
+ if(ret <= 0) | |
+ { | |
+ ts.tv_sec = 0; | |
+ ts.tv_nsec = 10; | |
+ nanosleep (&ts, NULL); | |
+ } | |
+ if(ret > 0) | |
+ { | |
+ | |
+ switch (pic_out.i_type) | |
+ { | |
+ case SLICE_P: | |
+ av_log(NULL,AV_LOG_DEBUG,"\n********returning pict type AV_PICTURE_TYPE_P\n"); | |
+ ctx->coded_frame->pict_type = AV_PICTURE_TYPE_P; | |
+ break; | |
+ case SLICE_B: | |
+ av_log(NULL,AV_LOG_DEBUG,"\n********returning pict type AV_PICTURE_TYPE_B\n"); | |
+ ctx->coded_frame->pict_type = AV_PICTURE_TYPE_B; | |
+ break; | |
+ case SLICE_I: | |
+ av_log(NULL,AV_LOG_DEBUG,"\n********returning pict type AV_PICTURE_TYPE_I\n"); | |
+ ctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; | |
+ break; | |
+ default: | |
+ ctx->coded_frame->pict_type = AV_PICTURE_TYPE_NONE; | |
+ av_log(NULL,AV_LOG_DEBUG,"\n********ERROR invalid picture type ************\n"); | |
+ | |
+ } | |
+ ctx->coded_frame->key_frame = pic_out.b_keyframe; | |
+ ctx->coded_frame->pts = pic_out.i_pts; | |
+ pkt->pts = pic_out.i_pts; | |
+ ctx->coded_frame->key_frame = pic_out.b_keyframe; | |
+ if (pic_out.b_keyframe) { | |
+ pkt->flags |= AV_PKT_FLAG_KEY; | |
+ } | |
+ av_log(NULL,AV_LOG_DEBUG,"\n********frame pts %lld ************\n",pic_out.i_pts); | |
+ } | |
+ *got_packet = ret; | |
+ return 0; | |
+ | |
+ } | |
+ else | |
+ { | |
+ return X264_frame(ctx, pkt, frame, got_packet); | |
+ } | |
+} | |
+#endif | |
+ | |
static av_cold int X264_close(AVCodecContext *avctx) | |
{ | |
+#ifdef SYNO_EVANSPORT_SMD | |
+ ismd_result_t ret_val = ISMD_ERROR_UNSPECIFIED; | |
+#endif | |
X264Context *x4 = avctx->priv_data; | |
+#ifdef SYNO_EVANSPORT_SMD | |
+#ifdef SYNO_EVANSPORT_FLV_EXTRADATA | |
+ if (!x264_closed && !x4->dont_free_extradata) | |
+#endif | |
+ { | |
+#endif | |
av_freep(&avctx->extradata); | |
av_freep(&x4->sei); | |
@@ -311,7 +467,25 @@ static av_cold int X264_close(AVCodecContext *avctx) | |
x264_encoder_close(x4->enc); | |
x4->enc = NULL; | |
} | |
- | |
+#ifdef SYNO_EVANSPORT_SMD | |
+ x264_closed =true; | |
+ } | |
+ av_log(NULL,AV_LOG_DEBUG,"\nin X264_close smd_h264_enc_video_available %d\n",smd_h264_enc_video_available); | |
+ //SMD CLOSE | |
+ if(smd_h264_enc_video_available) | |
+ { | |
+ if(eos_written == false) | |
+ { | |
+ av_log(NULL, AV_LOG_DEBUG, "\n************* writing eos *************\n"); | |
+ ismd_ffmpeg_send_eos_videnc(&vid_enc); | |
+ eos_written = true; | |
+ ret_val = ismd_ffmpeg_free_vid_enc_res(&vid_enc); | |
+ if(ret_val != ISMD_SUCCESS) | |
+ av_log(NULL,AV_LOG_ERROR,"could not free video encoder resources\n"); | |
+ smd_h264_enc_video_available = false; | |
+ } | |
+ } | |
+#endif | |
av_frame_free(&avctx->coded_frame); | |
return 0; | |
@@ -372,6 +546,12 @@ static av_cold int X264_init(AVCodecContext *avctx) | |
X264Context *x4 = avctx->priv_data; | |
int sw,sh; | |
+#ifdef SYNO_CODEC_PATENT_G1 | |
+ if (0 != ActivateCodec("h264_enc")) { | |
+ return -1; | |
+ } | |
+#endif | |
+ | |
if (avctx->global_quality > 0) | |
av_log(avctx, AV_LOG_WARNING, "-qscale is ignored, -crf is recommended.\n"); | |
@@ -727,6 +907,207 @@ static av_cold int X264_init(AVCodecContext *avctx) | |
return 0; | |
} | |
+#ifdef SYNO_EVANSPORT_SMD | |
+static av_cold int X264_init_smd(AVCodecContext *avctx) | |
+{ | |
+ ismd_videnc_stream_init_params_t videnc_stream_init_params; | |
+ ismd_videnc_codec_init_params_t videnc_codec_init_params; | |
+ ismd_videnc_h264_encoder_params_t videnc_h264_encoder_params; | |
+ ismd_result_t result = ISMD_ERROR_UNSPECIFIED; | |
+ int profile,level; | |
+ int result_temp = -1; | |
+ uint32_t max_bitrate; | |
+ osal_result thread_result; | |
+ char port_read_thread[15]; | |
+ videnc_struct_t* p_vid_enc = &vid_enc; | |
+ int ret; | |
+ | |
+ X264Context *x4 = avctx->priv_data; | |
+ | |
+ ret = X264_init(avctx); | |
+ | |
+ if (!synoAddPID(getpid())) { | |
+ av_log(avctx, AV_LOG_ERROR, "Syno check hardware transcode falied\n"); | |
+ return -1; | |
+ } | |
+ | |
+ smd_h264_enc_video_available = ismd_ffmpeg_is_video_enc_avail(); | |
+ av_log(NULL,AV_LOG_DEBUG,"\nin X264_init_smd smd_h264_enc_video_available %d\n",smd_h264_enc_video_available); | |
+ av_log(avctx,AV_LOG_DEBUG,"in X264_init_smd ismd_ffmpeg_is_video_enc_avail returned %d \n",smd_h264_enc_video_available); | |
+ if(!smd_h264_enc_video_available) | |
+ { | |
+ av_log( NULL, AV_LOG_INFO, "\nVideo hardware encoder not available for encoding.Falling back to software\n"); | |
+ } | |
+ else | |
+ { | |
+ av_log( NULL, AV_LOG_INFO, "\n*********Using Hardware H.264 Encoder **************\n" ); | |
+ //setup video encoder | |
+ | |
+ videnc_stream_init_params.max_frame_width = 1920; // Default to HD | |
+ videnc_stream_init_params.max_frame_height = 1088; | |
+ videnc_stream_init_params.scene_change_control.lookahead_count = 0; | |
+ | |
+ if(x4->profile) | |
+ { | |
+ profile = ismd_ffmpeg_profile_string_to_int(x4->profile); | |
+ if(profile < 0) | |
+ { | |
+ av_log(NULL, AV_LOG_ERROR, "\nprofile not supported\n"); | |
+ return -1; | |
+ } | |
+ else | |
+ { | |
+ videnc_codec_init_params.h264_init_params.profile = profile; | |
+ } | |
+ } | |
+ else | |
+ { | |
+ videnc_codec_init_params.h264_init_params.profile = ISMD_VIDENC_H264_PROFILE_HIGH; | |
+ } | |
+ if(x4->level) | |
+ { | |
+ level = ismd_ffmpeg_level_string_to_int(x4->level); | |
+ if(level < 0) | |
+ { | |
+ av_log(NULL, AV_LOG_ERROR, "\nlevel %s not supported\n",x4->level); | |
+ return -1; | |
+ } | |
+ else | |
+ { | |
+ videnc_codec_init_params.h264_init_params.level = level; | |
+ } | |
+ } | |
+ else | |
+ { | |
+ videnc_codec_init_params.h264_init_params.level = ISMD_VIDENC_H264_LEVEL_4_1; | |
+ } | |
+ videnc_stream_init_params.scene_change_control.scene_change_detect_enabled = false; | |
+ result = ismd_videnc_open(ISMD_CODEC_TYPE_H264,&videnc_stream_init_params, &videnc_codec_init_params, &p_vid_enc->videnc_handle); | |
+ if(result != ISMD_SUCCESS) | |
+ { | |
+ av_log(NULL,AV_LOG_ERROR,"failed at ismd_videnc_open error %d\n", result); | |
+ return -1; | |
+ } | |
+ result = ismd_videnc_get_input_port(p_vid_enc->videnc_handle, &p_vid_enc->ip_port); | |
+ if(result != ISMD_SUCCESS) | |
+ { | |
+ av_log(NULL,AV_LOG_ERROR,"failed at ismd_videnc_get_input_port error %d\n",result); | |
+ return -1; | |
+ } | |
+ result = ismd_videnc_get_output_port(p_vid_enc->videnc_handle, &p_vid_enc->op_port); | |
+ if(result != ISMD_SUCCESS) | |
+ { | |
+ av_log(NULL,AV_LOG_ERROR,"failed at ismd_videnc_get_output_port error %d\n",result); | |
+ return -1; | |
+ } | |
+ result = ismd_event_alloc(&p_vid_enc->output_port_event); | |
+ if (result != ISMD_SUCCESS) | |
+ { | |
+ av_log(NULL,AV_LOG_ERROR,"\nismd_event_alloc failed error %d\n",result); | |
+ return -1; | |
+ } | |
+ result = ismd_port_attach(p_vid_enc->op_port, p_vid_enc->output_port_event,ISMD_QUEUE_EVENT_NOT_EMPTY|ISMD_QUEUE_EVENT_FULL, ISMD_QUEUE_EVENT_HIGH_WATERMARK); | |
+ if (result != ISMD_SUCCESS) | |
+ { | |
+ av_log(NULL,AV_LOG_ERROR,"\nismd_port_attach222 failed error %d\n",result); | |
+ return -1; | |
+ } | |
+ result = ismd_event_reset(p_vid_enc->output_port_event); | |
+ if (result != ISMD_SUCCESS) | |
+ { | |
+ av_log(NULL,AV_LOG_ERROR,"\n FAILURE: ismd_event_reset222 failed error %d\n",result); | |
+ return -1; | |
+ } | |
+ | |
+ result = ismd_videnc_h264_get_encoding_params(p_vid_enc->videnc_handle, &videnc_h264_encoder_params); | |
+ if(result != ISMD_SUCCESS) | |
+ { | |
+ av_log(NULL,AV_LOG_ERROR,"failed at ismd_videnc_h264_get_encoding_params error %d\n",result); | |
+ return -1; | |
+ } | |
+ | |
+ videnc_h264_encoder_params.chroma_format = ISMD_VIDENC_H264_CHROMA_FORMAT_4_2_0; //can only be configured at compile time in libx264 | |
+ if((videnc_codec_init_params.h264_init_params.profile != ISMD_VIDENC_H264_PROFILE_BASELINE)&&(avctx->coder_type != 0)) | |
+ { | |
+ videnc_h264_encoder_params.entropy = ISMD_VIDENC_H264_ENTROPY_MODE_CABAC; | |
+ } | |
+ videnc_h264_encoder_params.aspect_ratio =ISMD_VIDENC_H264_ASPECT_RATIO_NONE; | |
+ videnc_h264_encoder_params.bitrate_settings.bitrate_mode = ISMD_VIDENC_H264_RATE_CONTROL_VBR; | |
+ result_temp = ismd_ffmpeg_get_max_bitrate(videnc_codec_init_params.h264_init_params.profile, videnc_codec_init_params.h264_init_params.level,&max_bitrate); | |
+ if(result_temp < 0) | |
+ { | |
+ av_log(NULL, AV_LOG_ERROR, "\nEroor setting max_bitrate error %d\n",result_temp); | |
+ return -1; | |
+ } | |
+ else | |
+ { | |
+ videnc_h264_encoder_params.bitrate_settings.max_bitrate = max_bitrate;// 40000000; | |
+ } | |
+ if(avctx->bit_rate) | |
+ { | |
+ videnc_h264_encoder_params.bitrate_settings.bitrate = avctx->bit_rate; | |
+ } | |
+ else | |
+ { | |
+ videnc_h264_encoder_params.bitrate_settings.bitrate = 3000000;//300000;// 3000000; | |
+ } | |
+ if(avctx->gop_size >= 0) | |
+ { | |
+ videnc_h264_encoder_params.gop_settings.GOP_length = avctx->gop_size; | |
+ } | |
+ else | |
+ { | |
+ videnc_h264_encoder_params.gop_settings.GOP_length = 24; | |
+ } | |
+ if(avctx->max_b_frames >= 0) | |
+ { | |
+ if(avctx->max_b_frames < 3) | |
+ videnc_h264_encoder_params.gop_settings.num_of_B_frames = avctx->max_b_frames; | |
+ else | |
+ return -1; | |
+ } | |
+ else | |
+ { | |
+ videnc_h264_encoder_params.gop_settings.num_of_B_frames = 2;//[0..2] Maximum number of consecutive B Frame in a GOP. | |
+ } | |
+ if(avctx->keyint_min >= 0) | |
+ { | |
+ videnc_h264_encoder_params.gop_settings.IDR_Frequency = avctx->keyint_min; | |
+ } | |
+ else | |
+ { | |
+ videnc_h264_encoder_params.gop_settings.IDR_Frequency = 24;//0 is a special value to be set when scd(EPU) enabled | |
+ } | |
+ videnc_h264_encoder_params.qp_mode = ISMD_VIDENC_H264_QP_UNIFORM; | |
+ | |
+ if(ismd_ffmpeg_videnc_h264_set_encoding_params(p_vid_enc->videnc_handle,&videnc_h264_encoder_params) != ISMD_SUCCESS) | |
+ { | |
+ av_log(NULL,AV_LOG_ERROR,"\nError setting h264 encoding parameters\n"); | |
+ return -1; | |
+ | |
+ } | |
+ p_vid_enc->eos_received = false; | |
+ | |
+ //set the video encoder to play state | |
+ result = ismd_dev_set_state(p_vid_enc->videnc_handle, ISMD_DEV_STATE_PLAY); | |
+ if (result != ISMD_SUCCESS) | |
+ { | |
+ av_log(NULL,AV_LOG_ERROR,"\n FAILURE: could not start video encoder error %d\n",result); | |
+ return -1; | |
+ } | |
+ | |
+ pthread_mutex_init(&p_vid_enc->mutex, NULL); | |
+ thread_result = os_thread_create(&p_vid_enc->output_thread, ismd_ffmpeg_videnc_output_thread, (void*)(p_vid_enc), 0, 0, port_read_thread); | |
+ if (thread_result != OSAL_SUCCESS) | |
+ { | |
+ av_log(NULL, AV_LOG_ERROR, "\nvideo encoder o/p thread creation failed\n"); | |
+ return -1; | |
+ } | |
+ } | |
+ return ret; | |
+} | |
+#endif | |
+ | |
static const enum AVPixelFormat pix_fmts_8bit[] = { | |
AV_PIX_FMT_YUV420P, | |
AV_PIX_FMT_YUVJ420P, | |
@@ -840,6 +1221,15 @@ static const AVClass x264_class = { | |
.version = LIBAVUTIL_VERSION_INT, | |
}; | |
+#ifdef SYNO_EVANSPORT_SMD | |
+static const AVClass x264_class_smd = { | |
+ .class_name = "h264_smd", | |
+ .item_name = av_default_item_name, | |
+ .option = options, | |
+ .version = LIBAVUTIL_VERSION_INT, | |
+}; | |
+#endif | |
+ | |
static const AVClass rgbclass = { | |
.class_name = "libx264rgb", | |
.item_name = av_default_item_name, | |
@@ -895,6 +1285,23 @@ AVCodec ff_libx264_encoder = { | |
FF_CODEC_CAP_INIT_CLEANUP, | |
}; | |
+#ifdef SYNO_EVANSPORT_SMD | |
+AVCodec ff_h264_smd_encoder = { | |
+ .name = "h264_smd", | |
+ .long_name = NULL_IF_CONFIG_SMALL("libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10"), | |
+ .type = AVMEDIA_TYPE_VIDEO, | |
+ .id = AV_CODEC_ID_H264, | |
+ .priv_data_size = sizeof(X264Context), | |
+ .init = X264_init_smd, | |
+ .encode2 = X264_frame_smd, | |
+ .close = X264_close, | |
+ .capabilities = CODEC_CAP_DELAY, | |
+ .priv_class = &x264_class_smd, | |
+ .defaults = x264_defaults, | |
+ .init_static_data = X264_init_static, | |
+}; | |
+#endif | |
+ | |
AVCodec ff_libx264rgb_encoder = { | |
.name = "libx264rgb", | |
.long_name = NULL_IF_CONFIG_SMALL("libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 RGB"), | |
diff --git a/libavcodec/mpeg12dec.c b/libavcodec/mpeg12dec.c | |
index b0e5ae9adc..0b1e454f1c 100644 | |
--- a/libavcodec/mpeg12dec.c | |
+++ b/libavcodec/mpeg12dec.c | |
@@ -49,6 +49,16 @@ | |
#include "vdpau_compat.h" | |
#include "xvmc_internal.h" | |
+#include "synoconfig.h" | |
+ | |
+#ifdef SYNO_EVANSPORT_SMD | |
+#include "libffmpeg_plugin/ismd_ffmpeg_util.h" | |
+#include "libffmpeg_plugin/ismd_ffmpeg_video_dec.h" | |
+#include "libavformat/avformat.h" | |
+static viddec_struct_t smd_mpeg2_vid_dec; | |
+bool smd_mpeg2_vid_dec_available = false; | |
+#endif | |
+ | |
typedef struct Mpeg1Context { | |
MpegEncContext mpeg_enc_ctx; | |
int mpeg_enc_ctx_allocated; /* true if decoding context allocated */ | |
@@ -1145,6 +1155,41 @@ static av_cold int mpeg_decode_init(AVCodecContext *avctx) | |
return 0; | |
} | |
+#ifdef SYNO_EVANSPORT_SMD | |
+static av_cold int mpeg_decode_init_smd(AVCodecContext *avctx) | |
+{ | |
+ ismd_result_t ret_val = ISMD_ERROR_UNSPECIFIED; | |
+ int result; | |
+ result = mpeg_decode_init(avctx); | |
+ | |
+ /********************* SMD code *******************/ | |
+ smd_mpeg2_vid_dec.codec = ISMD_CODEC_TYPE_MPEG2; | |
+ // 1. Setup a single stream | |
+ ret_val = ismd_ffmpeg_setup_viddec_stream(&smd_mpeg2_vid_dec); | |
+ if(ISMD_SUCCESS == ret_val) | |
+ { | |
+ // 2. Start the stream | |
+ ret_val = ismd_ffmpeg_start_viddec_stream(&smd_mpeg2_vid_dec); | |
+ } | |
+ if(ret_val != ISMD_SUCCESS) | |
+ { | |
+ av_log(avctx,AV_LOG_INFO,"\nMPEG2 Hardware video decoder not available.Falling Back to software.\n"); | |
+ av_log(avctx,AV_LOG_INFO,"\nMPEG2 can't fall back to software.\n"); | |
+ result = -1; | |
+ } | |
+ else | |
+ { | |
+ av_log(avctx,AV_LOG_INFO,"\n******************Using MPEG2 Hardware video decoder**************\n"); | |
+ smd_mpeg2_vid_dec_available = true; | |
+ smd_mpeg2_vid_dec.y_mem = NULL; | |
+ smd_mpeg2_vid_dec.u_mem = NULL; | |
+ smd_mpeg2_vid_dec.v_mem = NULL; | |
+ smd_mpeg2_vid_dec.send_sps_pps = true; | |
+ } | |
+ return result; | |
+} | |
+#endif | |
+ | |
static int mpeg_decode_update_thread_context(AVCodecContext *avctx, | |
const AVCodecContext *avctx_from) | |
{ | |
@@ -2808,6 +2853,57 @@ static int mpeg_decode_frame(AVCodecContext *avctx, void *data, | |
return ret; | |
} | |
+#ifdef SYNO_EVANSPORT_SMD | |
+static int mpeg_decode_frame_smd(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) | |
+{ | |
+ const uint8_t *buf = avpkt->data; | |
+ int buf_size = avpkt->size; | |
+ AVFrame *pict = data; | |
+ | |
+ ismd_result_t ret_val = ISMD_ERROR_UNSPECIFIED; | |
+ int got_frame = 0; | |
+ smd_video_frame decoded_frame; | |
+ struct timespec ts; | |
+ | |
+ if(smd_mpeg2_vid_dec_available) | |
+ { | |
+ ret_val = ismd_ffmpeg_decode_vid_buf(&smd_mpeg2_vid_dec, buf, buf_size); | |
+ if(ret_val != ISMD_SUCCESS) | |
+ { | |
+ av_log(avctx,AV_LOG_ERROR,"\nismd_ffmpeg_decode_buf failed error:%d buf_size %d\n",ret_val,buf_size); | |
+ return -1; | |
+ } | |
+ | |
+ ts.tv_sec = 0; | |
+ ts.tv_nsec = 10; | |
+ nanosleep (&ts, NULL); | |
+ | |
+ ismd_ffmpeg_get_decoded_data(&decoded_frame, &smd_mpeg2_vid_dec, &got_frame); | |
+ if(got_frame) | |
+ { | |
+ *data_size = sizeof(AVFrame); | |
+ avctx->width = decoded_frame.width; | |
+ avctx->height = decoded_frame.height; | |
+ avctx->pix_fmt = PIX_FMT_YUV420P; | |
+ | |
+ pict->pkt_pts = AV_NOPTS_VALUE; | |
+ pict->pts = AV_NOPTS_VALUE ; | |
+ pict->data[0] = (uint8_t*)decoded_frame.y_mem; | |
+ pict->data[1] = (uint8_t*)decoded_frame.u_mem; | |
+ pict->data[2] = (uint8_t*)decoded_frame.v_mem; | |
+ pict->linesize[0] = decoded_frame.linesize_y; | |
+ pict->linesize[1] = decoded_frame.linesize_u; | |
+ pict->linesize[2] = decoded_frame.linesize_v; | |
+ } | |
+ return buf_size; | |
+ } | |
+ else | |
+ { | |
+ return mpeg_decode_frame(avctx, data, data_size, avpkt); | |
+ } | |
+} | |
+#endif | |
+ | |
static void flush(AVCodecContext *avctx) | |
{ | |
Mpeg1Context *s = avctx->priv_data; | |
@@ -2819,11 +2915,25 @@ static void flush(AVCodecContext *avctx) | |
static av_cold int mpeg_decode_end(AVCodecContext *avctx) | |
{ | |
+#ifdef SYNO_EVANSPORT_SMD | |
+ ismd_result_t ret_val = ISMD_ERROR_UNSPECIFIED; | |
+#endif | |
Mpeg1Context *s = avctx->priv_data; | |
if (s->mpeg_enc_ctx_allocated) | |
ff_mpv_common_end(&s->mpeg_enc_ctx); | |
av_freep(&s->a53_caption); | |
+ | |
+#ifdef SYNO_EVANSPORT_SMD | |
+ if(smd_mpeg2_vid_dec_available) | |
+ { | |
+ ret_val = ismd_ffmpeg_free_vid_dec_res(&smd_mpeg2_vid_dec); | |
+ if(ret_val != ISMD_SUCCESS) | |
+ av_log(avctx,AV_LOG_ERROR,"could not free video decoder resources\n"); | |
+ } | |
+ smd_mpeg2_vid_dec_available = false; | |
+#endif | |
+ | |
return 0; | |
} | |
@@ -2873,6 +2983,23 @@ AVCodec ff_mpeg2video_decoder = { | |
.profiles = NULL_IF_CONFIG_SMALL(mpeg2_video_profiles), | |
}; | |
+#ifdef SYNO_EVANSPORT_SMD | |
+AVCodec ff_mpeg2video_smd_decoder = { | |
+ .name = "mpeg2video_smd", | |
+ .long_name = NULL_IF_CONFIG_SMALL("MPEG-2 video Hardware(SMD) Decoder"), | |
+ .type = AVMEDIA_TYPE_VIDEO, | |
+ .id = AV_CODEC_ID_MPEG2VIDEO_SYNO, | |
+ .priv_data_size = sizeof(Mpeg1Context), | |
+ .init = mpeg_decode_init_smd, | |
+ .close = mpeg_decode_end, | |
+ .decode = mpeg_decode_frame_smd, | |
+ .capabilities = CODEC_CAP_DELAY, | |
+ .flush = flush, | |
+ .max_lowres = 3, | |
+ .profiles = NULL_IF_CONFIG_SMALL(mpeg2_video_profiles), | |
+}; | |
+#endif | |
+ | |
//legacy decoder | |
AVCodec ff_mpegvideo_decoder = { | |
.name = "mpegvideo", | |
diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c | |
index e151f9ee8e..fa326a455b 100644 | |
--- a/libavcodec/mpeg4videodec.c | |
+++ b/libavcodec/mpeg4videodec.c | |
@@ -34,6 +34,9 @@ | |
#include "thread.h" | |
#include "xvididct.h" | |
+#include "synoconfig.h" | |
+#include "synog1codecpatent.h" | |
+ | |
/* The defines below define the number of bits that are read at once for | |
* reading vlc values. Changing these may improve speed and data cache needs | |
* be aware though that decreasing them may need the number of stages that is | |
@@ -2710,6 +2713,12 @@ static av_cold int decode_init(AVCodecContext *avctx) | |
MpegEncContext *s = &ctx->m; | |
int ret; | |
+#ifdef SYNO_CODEC_PATENT_G1 | |
+ if (0 != ActivateCodec("mpeg4part2_dec")) { | |
+ return -1; | |
+ } | |
+#endif | |
+ | |
ctx->divx_version = | |
ctx->divx_build = | |
ctx->xvid_build = | |
@@ -2731,6 +2740,17 @@ static av_cold int decode_init(AVCodecContext *avctx) | |
return 0; | |
} | |
+#ifdef SYNO_EVANSPORT_SMD | |
+static av_cold int decode_init_smd(AVCodecContext *avctx) | |
+{ | |
+ int result =0; | |
+ result = decode_init(avctx); | |
+ if (0 > ff_h263_decode_init_smd(avctx)) | |
+ return -1; | |
+ return result; | |
+} | |
+#endif | |
+ | |
static const AVProfile mpeg4_video_profiles[] = { | |
{ FF_PROFILE_MPEG4_SIMPLE, "Simple Profile" }, | |
{ FF_PROFILE_MPEG4_SIMPLE_SCALABLE, "Simple Scalable Profile" }, | |
@@ -2757,6 +2777,14 @@ static const AVOption mpeg4_options[] = { | |
{NULL} | |
}; | |
+#ifdef SYNO_EVANSPORT_SMD | |
+static const AVOption mpeg4_options_smd[] = { | |
+ {"quarter_sample", "1/4 subpel MC", offsetof(MpegEncContext, quarter_sample), FF_OPT_TYPE_INT, {.i64 = 0}, 0, 1, 0}, | |
+ {"divx_packed", "divx style packed b frames", offsetof(MpegEncContext, divx_packed), FF_OPT_TYPE_INT, {.i64 = 0}, 0, 1, 0}, | |
+ {NULL} | |
+}; | |
+#endif | |
+ | |
static const AVClass mpeg4_class = { | |
"MPEG4 Video Decoder", | |
av_default_item_name, | |
@@ -2764,6 +2792,15 @@ static const AVClass mpeg4_class = { | |
LIBAVUTIL_VERSION_INT, | |
}; | |
+#ifdef SYNO_EVANSPORT_SMD | |
+static const AVClass mpeg4_class_smd = { | |
+ "MPEG4 Video Decoder", | |
+ av_default_item_name, | |
+ mpeg4_options_smd, | |
+ LIBAVUTIL_VERSION_INT, | |
+}; | |
+#endif | |
+ | |
AVCodec ff_mpeg4_decoder = { | |
.name = "mpeg4", | |
.long_name = NULL_IF_CONFIG_SMALL("MPEG-4 part 2"), | |
@@ -2784,6 +2821,25 @@ AVCodec ff_mpeg4_decoder = { | |
.priv_class = &mpeg4_class, | |
}; | |
+#ifdef SYNO_EVANSPORT_SMD | |
+AVCodec ff_mpeg4_smd_decoder = { | |
+ .name = "mpeg4_smd", | |
+ .long_name = NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Hardware(SMD) Decoder"), | |
+ .type = AVMEDIA_TYPE_VIDEO, | |
+ .id = AV_CODEC_ID_MPEG4_SYNO, | |
+ .priv_data_size = sizeof(Mpeg4DecContext), | |
+ .init = decode_init_smd, | |
+ .close = ff_h263_decode_end, | |
+ .decode = ff_h263_decode_frame_smd, | |
+ .capabilities = CODEC_CAP_DELAY, | |
+ .flush = ff_mpeg_flush, | |
+ .max_lowres = 3, | |
+ .pix_fmts = ff_h263_hwaccel_pixfmt_list_420, | |
+ .profiles = NULL_IF_CONFIG_SMALL(mpeg4_video_profiles), | |
+ .update_thread_context = ONLY_IF_THREADS_ENABLED(ff_mpeg_update_thread_context), | |
+ .priv_class = &mpeg4_class_smd, | |
+}; | |
+#endif | |
#if CONFIG_MPEG4_VDPAU_DECODER | |
static const AVClass mpeg4_vdpau_class = { | |
diff --git a/libavcodec/mpeg4videoenc.c b/libavcodec/mpeg4videoenc.c | |
index bca294ebd8..bd9d22ac4c 100644 | |
--- a/libavcodec/mpeg4videoenc.c | |
+++ b/libavcodec/mpeg4videoenc.c | |
@@ -28,6 +28,9 @@ | |
#include "h263.h" | |
#include "mpeg4video.h" | |
+#include "synoconfig.h" | |
+#include "synog1codecpatent.h" | |
+ | |
/* The uni_DCtab_* tables below contain unified bits+length tables to encode DC | |
* differences in mpeg4. Unified in the sense that the specification specifies | |
* this encoding in several steps. */ | |
@@ -1300,6 +1303,12 @@ static av_cold int encode_init(AVCodecContext *avctx) | |
return AVERROR(EINVAL); | |
} | |
+#ifdef SYNO_CODEC_PATENT_G1 | |
+ if (0 != ActivateCodec("mpeg4part2_enc")) { | |
+ return -1; | |
+ } | |
+#endif | |
+ | |
if ((ret = ff_mpv_encode_init(avctx)) < 0) | |
return ret; | |
diff --git a/libavcodec/mpegvideo_parser.c b/libavcodec/mpegvideo_parser.c | |
index cbea9b6cec..bc91255d0b 100644 | |
--- a/libavcodec/mpegvideo_parser.c | |
+++ b/libavcodec/mpegvideo_parser.c | |
@@ -24,6 +24,8 @@ | |
#include "mpeg12.h" | |
#include "internal.h" | |
+#include "synoconfig.h" | |
+ | |
struct MpvParseContext { | |
ParseContext pc; | |
AVRational frame_rate; | |
@@ -73,7 +75,13 @@ static void mpegvideo_extract_headers(AVCodecParserContext *s, | |
frame_rate_index = buf[3] & 0xf; | |
pc->frame_rate = avctx->framerate = ff_mpeg12_frame_rate_tab[frame_rate_index]; | |
bit_rate = (buf[4]<<10) | (buf[5]<<2) | (buf[6]>>6); | |
+#ifdef SYNO_EVANSPORT_SMD | |
+ if (AV_CODEC_ID_MPEG2VIDEO_SYNO != avctx->codec_id) { | |
+#endif | |
avctx->codec_id = AV_CODEC_ID_MPEG1VIDEO; | |
+#ifdef SYNO_EVANSPORT_SMD | |
+ } | |
+#endif | |
avctx->ticks_per_frame = 1; | |
} | |
break; | |
@@ -98,7 +106,13 @@ static void mpegvideo_extract_headers(AVCodecParserContext *s, | |
set_dim_ret = ff_set_dimensions(avctx, pc->width, pc->height); | |
avctx->framerate.num = pc->frame_rate.num * (frame_rate_ext_n + 1); | |
avctx->framerate.den = pc->frame_rate.den * (frame_rate_ext_d + 1); | |
+#ifdef SYNO_EVANSPORT_SMD | |
+ if (AV_CODEC_ID_MPEG2VIDEO_SYNO != avctx->codec_id) { | |
+#endif | |
avctx->codec_id = AV_CODEC_ID_MPEG2VIDEO; | |
+#ifdef SYNO_EVANSPORT_SMD | |
+ } | |
+#endif | |
avctx->ticks_per_frame = 2; | |
} | |
break; | |
@@ -218,7 +232,11 @@ static int mpegvideo_parse_init(AVCodecParserContext *s) | |
} | |
AVCodecParser ff_mpegvideo_parser = { | |
+#ifdef SYNO_EVANSPORT_SMD | |
+ .codec_ids = { AV_CODEC_ID_MPEG1VIDEO, AV_CODEC_ID_MPEG2VIDEO, AV_CODEC_ID_MPEG2VIDEO_SYNO }, | |
+#else | |
.codec_ids = { AV_CODEC_ID_MPEG1VIDEO, AV_CODEC_ID_MPEG2VIDEO }, | |
+#endif | |
.priv_data_size = sizeof(struct MpvParseContext), | |
.parser_init = mpegvideo_parse_init, | |
.parser_parse = mpegvideo_parse, | |
diff --git a/libavcodec/ppc/blockdsp.c b/libavcodec/ppc/blockdsp.c | |
index 0059b3b448..b7e9a20840 100644 | |
--- a/libavcodec/ppc/blockdsp.c | |
+++ b/libavcodec/ppc/blockdsp.c | |
@@ -33,6 +33,8 @@ | |
#include "libavutil/ppc/types_altivec.h" | |
#include "libavcodec/blockdsp.h" | |
+#include "synoconfig.h" | |
+ | |
/* ***** WARNING ***** WARNING ***** WARNING ***** */ | |
/* | |
* clear_blocks_dcbz32_ppc will not work properly on PowerPC processors with | |
@@ -116,7 +118,15 @@ static long check_dcbzl_effect(void) | |
/* Below the constraint "b" seems to mean "address base register" | |
* in gcc-3.3 / RS/6000 speaks. Seems to avoid using r0, so.... */ | |
- __asm__ volatile ("dcbzl %0, %1" :: "b" (fakedata_middle), "r" (zero)); | |
+#ifdef SYNO_FIX_QORIQ_CORE_DUMP | |
+ #if SYNO_PLATFORM == PPC_QORIQ | |
+ __asm__ volatile("dcbz %0, %1" : : "r" (fakedata_middle), "r" (zero)); | |
+ #else | |
+ __asm__ volatile("dcbzl %0, %1" : : "b" (fakedata_middle), "r" (zero)); | |
+ #endif | |
+#else | |
+ __asm__ volatile("dcbzl %0, %1" : : "b" (fakedata_middle), "r" (zero)); | |
+#endif | |
for (i = 0; i < 1024; i++) | |
if (fakedata[i] == (char) 0) | |
diff --git a/libavcodec/srtenc.c b/libavcodec/srtenc.c | |
index 328797089c..4589c4512b 100644 | |
--- a/libavcodec/srtenc.c | |
+++ b/libavcodec/srtenc.c | |
@@ -26,6 +26,7 @@ | |
#include "ass_split.h" | |
#include "ass.h" | |
+#include "synoconfig.h" | |
#define SRT_STACK_SIZE 64 | |
@@ -193,7 +194,9 @@ static void srt_alignment_cb(void *priv, int alignment) | |
static void srt_cancel_overrides_cb(void *priv, const char *style) | |
{ | |
srt_stack_push_pop(priv, 0, 1); | |
+#ifndef SYNO_FILTER_SRT_TAGS | |
srt_style_apply(priv, style); | |
+#endif | |
} | |
static void srt_move_cb(void *priv, int x1, int y1, int x2, int y2, | |
@@ -221,6 +224,21 @@ static const ASSCodesCallbacks srt_callbacks = { | |
.end = srt_end_cb, | |
}; | |
+#ifdef SYNO_FILTER_SRT_TAGS | |
+static const ASSCodesCallbacks srt_callbacks_syno_notag = { | |
+ .text = srt_text_cb, | |
+ .new_line = srt_new_line_cb, | |
+ .style = NULL, | |
+ .color = NULL, | |
+ .font_name = NULL, | |
+ .font_size = NULL, | |
+ .alignment = NULL, | |
+ .cancel_overrides = srt_cancel_overrides_cb, | |
+ .move = NULL, | |
+ .end = srt_end_cb, | |
+}; | |
+#endif | |
+ | |
static int srt_encode_frame(AVCodecContext *avctx, | |
unsigned char *buf, int bufsize, const AVSubtitle *sub) | |
{ | |
@@ -240,8 +258,12 @@ static int srt_encode_frame(AVCodecContext *avctx, | |
dialog = ff_ass_split_dialog(s->ass_ctx, sub->rects[i]->ass, 0, &num); | |
for (; dialog && num--; dialog++) { | |
s->alignment_applied = 0; | |
+#ifdef SYNO_FILTER_SRT_TAGS | |
+ ff_ass_split_override_codes(&srt_callbacks_syno_notag, s, dialog->text); | |
+#else | |
srt_style_apply(s, dialog->style); | |
ff_ass_split_override_codes(&srt_callbacks, s, dialog->text); | |
+#endif | |
} | |
} | |
diff --git a/libavcodec/syno_trans_loading.c b/libavcodec/syno_trans_loading.c | |
new file mode 100644 | |
index 0000000000..d796f2c526 | |
--- /dev/null | |
+++ b/libavcodec/syno_trans_loading.c | |
@@ -0,0 +1,243 @@ | |
+#include <errno.h> | |
+#include <fcntl.h> | |
+#include <signal.h> | |
+#include <unistd.h> | |
+#include <sys/types.h> | |
+#include <sys/stat.h> | |
+#include <sys/types.h> | |
+#include <sys/file.h> | |
+#include <json.h> | |
+#include "libavutil/log.h" | |
+#include "syno_trans_loading.h" | |
+ | |
+#define SZ_DIR_TMP_VIDEO "/tmp/VideoStation" | |
+#define SZ_FILE_TRANS_ENABLE SZ_DIR_TMP_VIDEO"/enabled" | |
+#define SZ_JSON_KEY_PID "PID" | |
+#define SZ_JSON_KEY_HARDWARE_TRANSCODE "hardware_transcode" | |
+ | |
+#ifdef SYNO_EVANSPORT_SMD | |
+static int IsProcAlive(int pid) | |
+{ | |
+ if (!kill(pid, 0) || errno == EPERM) | |
+ return 1; | |
+ else | |
+ return 0; | |
+} | |
+ | |
+static int CheckPIDIsAlive(json_object *pTmpObj) | |
+{ | |
+ int iRet = 0, iPID = 0; | |
+ json_object *pPIDObj = NULL; | |
+ | |
+ if (!pTmpObj) { | |
+ goto Exit; | |
+ } | |
+ if (!json_object_is_type(pTmpObj, json_type_object)) { | |
+ goto Exit; | |
+ } | |
+ pPIDObj = json_object_object_get(pTmpObj, SZ_JSON_KEY_PID); | |
+ if (!json_object_is_type(pPIDObj, json_type_int)) { | |
+ goto Exit; | |
+ } | |
+ iPID = json_object_get_int(pPIDObj); | |
+ if (!IsProcAlive(iPID)) { | |
+ goto Exit; | |
+ } | |
+ iRet = iPID; | |
+Exit: | |
+ return iRet; | |
+} | |
+ | |
+static int CheckIsUseHardware(json_object *pTmpObj) | |
+{ | |
+ int iRet = 0; | |
+ json_object *pHardwareObj = NULL; | |
+ | |
+ if (!pTmpObj) { | |
+ goto Exit; | |
+ } | |
+ pHardwareObj = json_object_object_get(pTmpObj, SZ_JSON_KEY_HARDWARE_TRANSCODE); | |
+ if (!json_object_is_type(pHardwareObj, json_type_boolean)) { | |
+ goto Exit; | |
+ } | |
+ if (json_object_get_boolean(pHardwareObj)) { | |
+ iRet = 1; | |
+ } | |
+ | |
+Exit: | |
+ return iRet; | |
+} | |
+ | |
+static int WriteJosnToFile(json_object *pRootObj) | |
+{ | |
+ int iRet = -1; | |
+ if (!pRootObj) { | |
+ goto Exit; | |
+ } | |
+ | |
+ if (0 > json_object_to_file(SZ_FILE_TRANS_ENABLE, pRootObj)) { | |
+ goto Exit; | |
+ } | |
+ | |
+ if (0 != chmod(SZ_FILE_TRANS_ENABLE, 0777)) { | |
+ goto Exit; | |
+ } | |
+ iRet = 0; | |
+Exit: | |
+ return iRet; | |
+} | |
+ | |
+static int LockFile() | |
+{ | |
+ int fdLock = -1; | |
+ struct stat statBuf; | |
+ | |
+ if (0 != stat(SZ_DIR_TMP_VIDEO , &statBuf)) { | |
+ if (0 > mkdir(SZ_DIR_TMP_VIDEO, S_IRWXU | S_IRWXG | S_IRWXO)) { | |
+ goto Exit; | |
+ } | |
+ } | |
+ fdLock = open(SZ_FILE_TRANS_ENABLE, O_RDONLY | O_CREAT, 0777); | |
+ if (0 <= fdLock) { | |
+ flock(fdLock, LOCK_EX); | |
+ } | |
+ | |
+Exit: | |
+ return fdLock; | |
+} | |
+ | |
+/* @brief check Hardware transcode enable and add PID to file | |
+ * @param pidFFmpeg [in] pid of ffmpeg process | |
+ * @return [out] 1: success | |
+ * 0: failed | |
+ */ | |
+int synoAddPID(const pid_t pidFFmpeg) | |
+{ | |
+ int iRet = 0; | |
+ int i = 0, fdLock = -1, iHardwareUsage = 0, iPIDExist = 0, iPID = 0; | |
+ json_object *pRootObj = NULL, *pNewObj = NULL, *pTmpObj = NULL, | |
+ *pNewArray = NULL; | |
+ | |
+ if (0 >= pidFFmpeg) { | |
+ av_log(NULL, AV_LOG_ERROR, "pidFFmpeg %d failed\n", pidFFmpeg); | |
+ goto Exit; | |
+ } | |
+ | |
+ if (0 > (fdLock = LockFile())) { | |
+ av_log(NULL, AV_LOG_ERROR, "LockFile failed, fdLock %d\n", fdLock); | |
+ goto Exit; | |
+ } | |
+ | |
+ pNewArray = json_object_new_array(); | |
+ if (NULL == (pRootObj = json_object_from_file(SZ_FILE_TRANS_ENABLE))) { | |
+ goto Write; | |
+ } | |
+ | |
+ if (!json_object_is_type(pRootObj, json_type_array)) { | |
+ goto Write; | |
+ } | |
+ | |
+ for (i = 0; i < json_object_array_length(pRootObj); i++) { | |
+ pTmpObj = json_object_array_get_idx(pRootObj, i); | |
+ if (0 == (iPID = CheckPIDIsAlive(pTmpObj))) { | |
+ continue; | |
+ } | |
+ | |
+ if (pidFFmpeg == iPID) { | |
+ iPIDExist = 1; | |
+ } else if (CheckIsUseHardware(pTmpObj)) { | |
+ iHardwareUsage++; | |
+ } | |
+ json_object_array_add(pNewArray, pTmpObj); | |
+ } | |
+ | |
+ if (1 <= iHardwareUsage) { | |
+ av_log(NULL, AV_LOG_ERROR, "Hardware transcoding is busy!!\n"); | |
+ goto Exit; | |
+ } | |
+ | |
+Write: | |
+ if (!iPIDExist) { | |
+ pNewObj = json_object_new_object(); | |
+ json_object_object_add(pNewObj, SZ_JSON_KEY_PID, json_object_new_int(pidFFmpeg)); | |
+ json_object_object_add(pNewObj, SZ_JSON_KEY_HARDWARE_TRANSCODE, json_object_new_boolean(1)); | |
+ json_object_array_add(pNewArray, pNewObj); | |
+ } | |
+ WriteJosnToFile(pNewArray); | |
+ | |
+ iRet = 1; | |
+Exit: | |
+ if (0 <= fdLock) { | |
+ flock(fdLock, LOCK_UN); | |
+ close(fdLock); | |
+ } | |
+ | |
+ if (pRootObj) { | |
+ json_object_put(pRootObj); | |
+ } | |
+ if (pNewObj) { | |
+ json_object_put(pNewObj); | |
+ } | |
+ if (pNewArray) { | |
+ json_object_put(pNewArray); | |
+ } | |
+ return iRet; | |
+} | |
+ | |
+/* @brief remove pid from file | |
+ * @param pidFFmpeg [in] pid of ffmpeg process | |
+ * @return [out] 1: success | |
+ * 0: failed | |
+ */ | |
+int synoRemovePID(const pid_t pidFFmpeg) | |
+{ | |
+ int iRet = 0; | |
+ int i = 0, fdLock = -1, iPID = 0; | |
+ json_object *pRootObj = NULL, *pTmpObj = NULL, *pNewArray = NULL; | |
+ | |
+ if (0 >= pidFFmpeg) { | |
+ av_log(NULL, AV_LOG_ERROR, "pidFFmpeg %d failed\n", pidFFmpeg); | |
+ goto Exit; | |
+ } | |
+ | |
+ if (0 > (fdLock = LockFile())) { | |
+ av_log(NULL, AV_LOG_ERROR, "LockFile failed, fdLock %d\n", fdLock); | |
+ goto Exit; | |
+ } | |
+ | |
+ if (NULL == (pRootObj = json_object_from_file(SZ_FILE_TRANS_ENABLE))) { | |
+ goto Exit; | |
+ } | |
+ | |
+ if (!json_object_is_type(pRootObj, json_type_array)) { | |
+ goto Exit; | |
+ } | |
+ | |
+ pNewArray = json_object_new_array(); | |
+ for (i = 0; i < json_object_array_length(pRootObj); i++) { | |
+ pTmpObj = json_object_array_get_idx(pRootObj, i); | |
+ if (0 == (iPID = CheckPIDIsAlive(pTmpObj))) { | |
+ continue; | |
+ } | |
+ if (pidFFmpeg == iPID) { | |
+ continue; | |
+ } | |
+ json_object_array_add(pNewArray, pTmpObj); | |
+ } | |
+ WriteJosnToFile(pNewArray); | |
+ | |
+ iRet = 1; | |
+Exit: | |
+ if (0 <= fdLock) { | |
+ flock(fdLock, LOCK_UN); | |
+ close(fdLock); | |
+ } | |
+ if (pRootObj) { | |
+ json_object_put(pRootObj); | |
+ } | |
+ if (pNewArray) { | |
+ json_object_put(pNewArray); | |
+ } | |
+ return iRet; | |
+} | |
+#endif// SYNO_EVANSPORT_SMD | |
diff --git a/libavcodec/syno_trans_loading.h b/libavcodec/syno_trans_loading.h | |
new file mode 100644 | |
index 0000000000..0bd8e9e0ab | |
--- /dev/null | |
+++ b/libavcodec/syno_trans_loading.h | |
@@ -0,0 +1,11 @@ | |
+#ifndef _SYNO_TRANS_LOADING_H | |
+#define _SYNO_TRANS_LOADING_H | |
+ | |
+#include "synoconfig.h" | |
+#ifdef SYNO_EVANSPORT_SMD | |
+ | |
+int synoAddPID(const pid_t pidFFmpeg); | |
+int synoRemovePID(const pid_t pidFFmpeg); | |
+ | |
+#endif //SYNO_EVANSPORT_SMD | |
+#endif //_SYNO_TRANS_LOADING_H | |
diff --git a/libavcodec/synog1codecpatent.c b/libavcodec/synog1codecpatent.c | |
new file mode 100644 | |
index 0000000000..4ecd21e48f | |
--- /dev/null | |
+++ b/libavcodec/synog1codecpatent.c | |
@@ -0,0 +1,182 @@ | |
+#include <stdlib.h> | |
+#include <stdio.h> | |
+#include <stdarg.h> | |
+#include <string.h> | |
+ | |
+#include <errno.h> | |
+#include <fcntl.h> | |
+#include <unistd.h> | |
+#include <sys/stat.h> | |
+#include <sys/wait.h> | |
+ | |
+#include "synoconfig.h" | |
+#include "synog1codecpatent.h" | |
+ | |
+#if defined(SYNO_VIDEOSTATION) | |
+#define SZ_BIN_SYNOCODECPATENT "/var/packages/VideoStation/target/bin/synocodectool" | |
+#elif defined(SYNO_AUDIOSTATION) | |
+#define SZ_BIN_SYNOCODECPATENT "/var/packages/AudioStation/target/bin/synocodectool" | |
+#elif defined(SYNO_MEDIASERVER) | |
+#define SZ_BIN_SYNOCODECPATENT "/var/packages/MediaServer/target/bin/synocodectool" | |
+#else | |
+#define SZ_BIN_SYNOCODECPATENT "/usr/syno/bin/synocodectool" | |
+#endif | |
+ | |
+#ifdef SYNO_CODEC_PATENT_G1 | |
+ | |
+static pid_t SYNOProcForkEx(void) | |
+{ | |
+ int pid = -1; | |
+ int fd = -1; | |
+ int status = 0; | |
+ int waitRet = 0; | |
+ char *pEnvPath = NULL; | |
+ | |
+ fflush(NULL); | |
+ | |
+ pid = fork(); | |
+ if (0 > pid) { | |
+ return -1; | |
+ } else if (pid > 0) { | |
+ while (-1 == (waitRet = waitpid(pid, &status, 0)) && EINTR == errno) { | |
+ //do nothing | |
+ } | |
+ if (-1 != waitRet && 0 == WEXITSTATUS(status)) { | |
+ return 1; | |
+ } else if (-1 == waitRet && errno == ECHILD) { | |
+ return 1; | |
+ } | |
+ return -1; | |
+ } | |
+ | |
+ pEnvPath = getenv("PATH"); | |
+ if (pEnvPath) { | |
+ setenv("PATH", pEnvPath, 1); | |
+ } | |
+ | |
+ if (-1 != (fd = open("/dev/null", O_RDWR, 0))) { | |
+ (void) dup2(fd, STDIN_FILENO); | |
+ (void) dup2(fd, STDOUT_FILENO); | |
+ (void) dup2(fd, STDERR_FILENO); | |
+ if (2 < fd) | |
+ (void) close(fd); | |
+ } | |
+ | |
+ setsid(); | |
+ chdir("/"); | |
+ | |
+ return 0; | |
+} | |
+ | |
+static int SYNOExecl(const char *szPath, const char* szArg, ...) | |
+{ | |
+ int ret=-1, pid, nowait, status=0; | |
+ int fChildAlive = 0; | |
+ struct sigaction saOrg; | |
+ size_t i = 0; | |
+ size_t argc = 0; | |
+ const char *arg = NULL; | |
+ const char **argv = NULL; | |
+ va_list ap; | |
+ | |
+ // remove SA_NOCLDWAIT flags if set | |
+ sigaction(SIGCHLD, NULL, &saOrg); | |
+ nowait = (saOrg.sa_flags & SA_NOCLDWAIT); | |
+ saOrg.sa_flags &= ~SA_NOCLDWAIT; | |
+ sigaction(SIGCHLD, &saOrg, NULL); | |
+ | |
+ if ((pid = SYNOProcForkEx()) == 0) { | |
+ arg = szArg; | |
+ va_start(ap, szArg); | |
+ for(argc = 2; NULL != arg; ++argc) { | |
+ arg = va_arg(ap, const char*); | |
+ } | |
+ va_end(ap); | |
+ | |
+ argv = (const char**) calloc (argc, sizeof(const char*)); | |
+ | |
+ arg = szArg; | |
+ argv[0] = szPath; | |
+ argv[1] = szArg; | |
+ va_start(ap, szArg); | |
+ for (i = 2; NULL != arg; ++i) { | |
+ arg = va_arg(ap, const char*); | |
+ argv[i] = arg; | |
+ } | |
+ va_end(ap); | |
+ | |
+ execv(szPath, (char *const *) argv); | |
+ | |
+ free(argv); | |
+ // If any of the exec functions returns, an error will have occurred. The return value is 255 | |
+ _exit(-1); | |
+ } else if (pid != -1) { | |
+ while (-1 == (fChildAlive = waitpid(pid, &status, 0)) && EINTR == errno); | |
+ if (-1 != fChildAlive && WIFEXITED(status)) { | |
+ //child alive --> wait until child done and check its exit code. | |
+ ret = WEXITSTATUS(status); | |
+ } else if ( fChildAlive == -1 && errno == ECHILD ) { | |
+ //child doesn't alive --> see as success | |
+ ret = 0; | |
+ } | |
+ } | |
+ // restore SA_NOCLDWAIT flag if orginal set | |
+ if (nowait) { | |
+ sigaction(SIGCHLD, NULL, &saOrg); | |
+ saOrg.sa_flags |= SA_NOCLDWAIT; | |
+ sigaction(SIGCHLD, &saOrg, NULL); | |
+ } | |
+ return ret; | |
+} | |
+ | |
+static int FileExit(const char *szPath) | |
+{ | |
+ int iRet = 0; | |
+ struct stat statBuf; | |
+ | |
+ if (!szPath) { | |
+ goto Exit; | |
+ } | |
+ if (0 == stat(szPath, &statBuf) && S_ISREG(statBuf.st_mode)) { | |
+ iRet = 1; | |
+ } | |
+Exit: | |
+ return iRet; | |
+ | |
+} | |
+ | |
+/** | |
+ * check the codec can use, | |
+ * active, 0 | |
+ * not active or error, -1 | |
+ */ | |
+int ActivateCodec(const char *szCodecName) | |
+{ | |
+ int iRet = -1; | |
+ char *szEnvSkipActivate = NULL; | |
+ | |
+ //for some case like avformat_find_stream_info, don't need avtivate mechanism. | |
+ szEnvSkipActivate = getenv(SZ_SYNO_CODEC_SKIP_ACTIVATION); | |
+ if (szEnvSkipActivate && 0 == strcmp(szEnvSkipActivate, "yes")) { | |
+ return 0; | |
+ } | |
+ | |
+ if (!szCodecName) { | |
+ goto Exit; | |
+ } | |
+ | |
+ if (!FileExit(SZ_BIN_SYNOCODECPATENT)) { | |
+ goto Exit; | |
+ } | |
+ | |
+ if (0 != SYNOExecl(SZ_BIN_SYNOCODECPATENT, "--check_codec_activated", szCodecName, "--pkgname", SZ_PKG_NAME, NULL)) { | |
+ if (0 != SYNOExecl(SZ_BIN_SYNOCODECPATENT, "--activate_codec", szCodecName, "--pkgname", SZ_PKG_NAME, NULL)) { | |
+ goto Exit; | |
+ } | |
+ } | |
+ | |
+ iRet = 0; | |
+Exit: | |
+ return iRet; | |
+} | |
+#endif //SYNO_CODEC_PATENT_G1 | |
diff --git a/libavcodec/synog1codecpatent.h b/libavcodec/synog1codecpatent.h | |
new file mode 100644 | |
index 0000000000..f0bec20298 | |
--- /dev/null | |
+++ b/libavcodec/synog1codecpatent.h | |
@@ -0,0 +1,24 @@ | |
+#ifndef _SYNO_G1_CODEC_PATENT_H | |
+#define _SYNO_G1_CODEC_PATENT_H | |
+ | |
+#include "synoconfig.h" | |
+ | |
+#ifdef SYNO_CODEC_PATENT_G1 | |
+ | |
+#define SZ_SYNO_CODEC_SKIP_ACTIVATION "SYNO_CODEC_SKIP_ACTIVATION" | |
+ | |
+//TODO must change by define by package | |
+#if defined(SYNO_VIDEOSTATION) | |
+#define SZ_PKG_NAME "videostation" | |
+#elif defined(SYNO_AUDIOSTATION) | |
+#define SZ_PKG_NAME "audiostation" | |
+#elif defined(SYNO_MEDIASERVER) | |
+#define SZ_PKG_NAME "mediaserver" | |
+#else | |
+#define SZ_PKG_NAME "dsm" | |
+#endif | |
+ | |
+int ActivateCodec(const char *szCodecName); | |
+#endif //SYNO_CODEC_PATENT_G1 | |
+ | |
+#endif //_SYNO_G1_CODEC_PATENT_H | |
diff --git a/libavcodec/utils.c b/libavcodec/utils.c | |
index 558afebc2f..f414d739ea 100644 | |
--- a/libavcodec/utils.c | |
+++ b/libavcodec/utils.c | |
@@ -67,6 +67,9 @@ | |
#endif | |
#include "libavutil/ffversion.h" | |
+ | |
+#include "synoconfig.h" | |
+ | |
const char av_codec_ffversion[] = "FFmpeg version " FFMPEG_VERSION; | |
#if HAVE_PTHREADS || HAVE_W32THREADS || HAVE_OS2THREADS | |
@@ -1794,6 +1797,13 @@ int ff_alloc_packet(AVPacket *avpkt, int size) | |
return ff_alloc_packet2(NULL, avpkt, size); | |
} | |
+#ifdef SYNO_EVANSPORT_SMD | |
+int syno_alloc_packet(AVPacket *avpkt, int size) | |
+{ | |
+ return ff_alloc_packet2(NULL, avpkt, size); | |
+} | |
+#endif | |
+ | |
/** | |
* Pad last frame with silence. | |
*/ | |
diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c | |
index 3fa39a579e..c84d8c1483 100644 | |
--- a/libavcodec/vc1dec.c | |
+++ b/libavcodec/vc1dec.c | |
@@ -39,6 +39,16 @@ | |
#include "vdpau_compat.h" | |
#include "libavutil/avassert.h" | |
+#include "synoconfig.h" | |
+#include "synog1codecpatent.h" | |
+ | |
+#ifdef SYNO_EVANSPORT_SMD | |
+#include "libffmpeg_plugin/ismd_ffmpeg_util.h" | |
+#include "libffmpeg_plugin/ismd_ffmpeg_video_dec.h" | |
+#include "libavformat/avformat.h" | |
+static viddec_struct_t smd_vc1_vid_dec; | |
+bool smd_vc1_vid_dec_available = false; | |
+#endif | |
#if CONFIG_WMV3IMAGE_DECODER || CONFIG_VC1IMAGE_DECODER | |
@@ -422,6 +432,12 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx) | |
GetBitContext gb; | |
int ret; | |
+#ifdef SYNO_CODEC_PATENT_G1 | |
+ if (0 != ActivateCodec("vc1_dec")) { | |
+ return -1; | |
+ } | |
+#endif | |
+ | |
/* save the container output size for WMImage */ | |
v->output_width = avctx->width; | |
v->output_height = avctx->height; | |
@@ -453,7 +469,12 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx) | |
ff_h264chroma_init(&v->h264chroma, 8); | |
ff_qpeldsp_init(&s->qdsp); | |
+#ifdef SYNO_EVANSPORT_SMD | |
+ if ((avctx->codec_id == AV_CODEC_ID_WMV3 || avctx->codec_id == AV_CODEC_ID_WMV3_SYNO) || avctx->codec_id == AV_CODEC_ID_WMV3IMAGE) { | |
+#else | |
if (avctx->codec_id == AV_CODEC_ID_WMV3 || avctx->codec_id == AV_CODEC_ID_WMV3IMAGE) { | |
+#endif | |
+ | |
int count = 0; | |
// looks like WMV3 has a sequence header stored in the extradata | |
@@ -573,11 +594,49 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx) | |
return 0; | |
} | |
+#ifdef SYNO_EVANSPORT_SMD | |
+static av_cold int vc1_decode_init_smd(AVCodecContext *avctx) | |
+{ | |
+ ismd_result_t ret_val = ISMD_ERROR_UNSPECIFIED; | |
+ int result; | |
+ result = vc1_decode_init(avctx); | |
+ /********************* SMD code *******************/ | |
+ smd_vc1_vid_dec.codec = ISMD_CODEC_TYPE_VC1; | |
+ // 1. Setup a single stream | |
+ ret_val = ismd_ffmpeg_setup_viddec_stream(&smd_vc1_vid_dec); | |
+ if(ISMD_SUCCESS == ret_val) | |
+ { | |
+ // 2. Start the stream | |
+ ret_val = ismd_ffmpeg_start_viddec_stream(&smd_vc1_vid_dec); | |
+ } | |
+ if(ret_val != ISMD_SUCCESS) | |
+ { | |
+ av_log(avctx,AV_LOG_INFO,"\nVC1 Hardware video decoder not available.Falling Back to software.\n"); | |
+ av_log(avctx,AV_LOG_INFO,"\nVC1 can't fall back to software.\n"); | |
+ result = -1; | |
+ } | |
+ else | |
+ { | |
+ av_log(avctx,AV_LOG_INFO,"\n******************Using VC1 Hardware video decoder**************\n"); | |
+ smd_vc1_vid_dec_available = true; | |
+ smd_vc1_vid_dec.y_mem = NULL; | |
+ smd_vc1_vid_dec.u_mem = NULL; | |
+ smd_vc1_vid_dec.v_mem = NULL; | |
+ smd_vc1_vid_dec.send_sps_pps = true; | |
+ } | |
+ /********************** SMD END *********************/ | |
+ return result; | |
+} | |
+#endif | |
+ | |
/** Close a VC1/WMV3 decoder | |
* @warning Initial try at using MpegEncContext stuff | |
*/ | |
av_cold int ff_vc1_decode_end(AVCodecContext *avctx) | |
{ | |
+#ifdef SYNO_EVANSPORT_SMD | |
+ ismd_result_t ret_val = ISMD_ERROR_UNSPECIFIED; | |
+#endif | |
VC1Context *v = avctx->priv_data; | |
int i; | |
@@ -604,6 +663,17 @@ av_cold int ff_vc1_decode_end(AVCodecContext *avctx) | |
av_freep(&v->is_intra_base); // FIXME use v->mb_type[] | |
av_freep(&v->luma_mv_base); | |
ff_intrax8_common_end(&v->x8); | |
+ | |
+#ifdef SYNO_EVANSPORT_SMD | |
+ if(smd_vc1_vid_dec_available) | |
+ { | |
+ ret_val = ismd_ffmpeg_free_vid_dec_res(&smd_vc1_vid_dec); | |
+ if(ret_val != ISMD_SUCCESS) | |
+ av_log(avctx,AV_LOG_ERROR,"could not free video decoder resources\n"); | |
+ } | |
+ smd_vc1_vid_dec_available = false; | |
+#endif | |
+ | |
return 0; | |
} | |
@@ -1062,6 +1132,147 @@ err: | |
return -1; | |
} | |
+#ifdef SYNO_EVANSPORT_SMD | |
+static int vc1_decode_frame_smd(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) | |
+{ | |
+ ismd_result_t ret_val = ISMD_ERROR_UNSPECIFIED; | |
+ const uint8_t *buf = avpkt->data; | |
+ int buf_size = avpkt->size; | |
+ VC1Context *v = avctx->priv_data; | |
+ AVFrame *pict = data; | |
+ uint8_t* buf_with_start_code =NULL; | |
+ int new_buf_size = buf_size; | |
+ ismd_buffer_handle_t ismd_buf = -1; | |
+ ismd_result_t result = ISMD_SUCCESS; | |
+ static bool first_time = true; | |
+ int max_bufsize =0; | |
+ unsigned char pSeqHeaderRbdu[8]; | |
+ unsigned char SPMP_PESpacket_PayloadFormatHeader[16]; | |
+ int size_SPMP_PESpacket_PayloadFormatHeader; | |
+ int got_frame = 0; | |
+ smd_video_frame decoded_frame; | |
+ struct timespec ts; | |
+ if(smd_vc1_vid_dec_available) | |
+ { | |
+ | |
+ if ((buf_size >= 4)&& (!IS_MARKER(AV_RB32(buf))) && first_time) /* frame starts with marker and needs to be parsed */ | |
+ { | |
+ smd_vc1_vid_dec.vc1_without_start_code = true;//not compatible with smd | |
+ first_time = false; | |
+ | |
+ } | |
+ | |
+ if(smd_vc1_vid_dec.vc1_without_start_code) | |
+ { | |
+ //write sps to decoder port first this comes out-of-band in wvc1 | |
+ if((smd_vc1_vid_dec.send_sps_pps) && avctx->extradata_size > 0 && avctx->extradata) | |
+ { | |
+ uint8_t* seq_header_buf = av_malloc(16); | |
+ switch (v->profile) | |
+ { | |
+ case PROFILE_ADVANCED: | |
+ /***** write sps buffer for wvc1 at decoder i/p port **********************/ | |
+ if ((result = ismd_buffer_alloc(CHUNK_SIZE, &ismd_buf)) == ISMD_SUCCESS) | |
+ { | |
+ if ((result = ismd_ffmpeg_fill_viddec_buffer(avctx->extradata+1, ismd_buf,avctx->extradata_size-1)) == ISMD_SUCCESS) | |
+ { | |
+ // decode it asynchronously | |
+ if ((result = ismd_ffmpeg_decoder_port_write(&smd_vc1_vid_dec,ismd_buf)) != ISMD_SUCCESS) | |
+ { | |
+ av_log(avctx, AV_LOG_ERROR,"error: unable to decode smd_buffers [%d]\n", result); | |
+ } | |
+ } | |
+ } | |
+ break; | |
+ case PROFILE_SIMPLE: | |
+ case PROFILE_MAIN: | |
+ size_SPMP_PESpacket_PayloadFormatHeader = ismd_ffmpeg_vc1_viddec_SPMP_PESpacket_PayloadFormatHeader (pSeqHeaderRbdu, SPMP_PESpacket_PayloadFormatHeader, avctx->extradata, avctx->extradata_size, avctx->width, avctx->height); | |
+ | |
+ if ((result = ismd_buffer_alloc(CHUNK_SIZE, &ismd_buf)) == ISMD_SUCCESS) | |
+ { | |
+ if ((result = ismd_ffmpeg_fill_viddec_buffer(SPMP_PESpacket_PayloadFormatHeader, ismd_buf,size_SPMP_PESpacket_PayloadFormatHeader)) == ISMD_SUCCESS) | |
+ { | |
+ // decode it asynchronously | |
+ if ((result = ismd_ffmpeg_decoder_port_write(&smd_vc1_vid_dec,ismd_buf)) != ISMD_SUCCESS) | |
+ { | |
+ av_log(NULL, AV_LOG_ERROR,"error: unable to decode smd_buffers [%d]\n", result); | |
+ } | |
+ } | |
+ } | |
+ break; | |
+ } | |
+ smd_vc1_vid_dec.send_sps_pps = false; | |
+ av_free(seq_header_buf); | |
+ } | |
+ | |
+ //need to insert start code | |
+ switch (v->profile) | |
+ { | |
+ case PROFILE_ADVANCED: | |
+ //insert start code | |
+ buf_with_start_code = av_malloc(4 + buf_size);//TODO free memory | |
+ | |
+ new_buf_size = ismd_ffmpeg_vc1_viddec_convert_AP(buf_with_start_code, buf, buf_size); | |
+ | |
+ break; | |
+ case PROFILE_SIMPLE: | |
+ case PROFILE_MAIN: | |
+ // Calculate maximum buffer size, make room for encapsulation | |
+ // SMPTE-421M-FDSI doc, Annex-E | |
+ max_bufsize = ( (avpkt->size + 3 ) / 3 ) * 4; | |
+ buf_with_start_code = av_malloc(max_bufsize); | |
+ //insert start code | |
+ | |
+ new_buf_size = ismd_ffmpeg_vc1_viddec_convert_SPMP(buf_with_start_code, avpkt->data, avpkt->size, max_bufsize); | |
+ | |
+ break; | |
+ } | |
+ | |
+ } | |
+ else | |
+ buf_with_start_code = buf; | |
+ /*********** write buffer data ************************/ | |
+ ret_val = ismd_ffmpeg_decode_vid_buf(&smd_vc1_vid_dec, buf_with_start_code, new_buf_size); | |
+ | |
+ if(ret_val != ISMD_SUCCESS) | |
+ { | |
+ av_log(avctx,AV_LOG_ERROR,"\nismd_ffmpeg_decode_buf failed error:%d buf_size %d\n",ret_val,buf_size); | |
+ return -1; | |
+ } | |
+ | |
+ if((smd_vc1_vid_dec.vc1_without_start_code)&& buf_with_start_code) | |
+ { | |
+ av_free(buf_with_start_code); | |
+ } | |
+ ts.tv_sec = 0; | |
+ ts.tv_nsec = 10; | |
+ nanosleep (&ts, NULL); | |
+ | |
+ ismd_ffmpeg_get_decoded_data(&decoded_frame, &smd_vc1_vid_dec, &got_frame); | |
+ if(got_frame) | |
+ { | |
+ *data_size = 1; | |
+ avctx->width = decoded_frame.width; | |
+ avctx->height = decoded_frame.height; | |
+ avctx->pix_fmt = PIX_FMT_YUV420P; | |
+ | |
+ pict->pkt_pts = AV_NOPTS_VALUE; | |
+ pict->pts = AV_NOPTS_VALUE ; | |
+ pict->data[0] = (uint8_t*)decoded_frame.y_mem; | |
+ pict->data[1] = (uint8_t*)decoded_frame.u_mem; | |
+ pict->data[2] = (uint8_t*)decoded_frame.v_mem; | |
+ pict->linesize[0] = decoded_frame.linesize_y; | |
+ pict->linesize[1] = decoded_frame.linesize_u; | |
+ pict->linesize[2] = decoded_frame.linesize_v; | |
+ } | |
+ return buf_size; | |
+ } | |
+ else | |
+ { | |
+ return vc1_decode_frame(avctx, data, data_size, avpkt); | |
+ } | |
+} | |
+#endif | |
static const AVProfile profiles[] = { | |
{ FF_PROFILE_VC1_SIMPLE, "Simple" }, | |
@@ -1103,6 +1314,22 @@ AVCodec ff_vc1_decoder = { | |
.profiles = NULL_IF_CONFIG_SMALL(profiles) | |
}; | |
+#ifdef SYNO_EVANSPORT_SMD | |
+AVCodec ff_vc1_smd_decoder = { | |
+ .name = "vc1_smd", | |
+ .type = AVMEDIA_TYPE_VIDEO, | |
+ .id = AV_CODEC_ID_VC1_SYNO, | |
+ .priv_data_size = sizeof(VC1Context), | |
+ .init = vc1_decode_init_smd, | |
+ .close = ff_vc1_decode_end, | |
+ .decode = vc1_decode_frame_smd, | |
+ .capabilities = CODEC_CAP_DELAY, | |
+ .long_name = NULL_IF_CONFIG_SMALL("SMPTE VC-1 Hardware(SMD) Decoder"), | |
+ .pix_fmts = vc1_hwaccel_pixfmt_list_420, | |
+ .profiles = NULL_IF_CONFIG_SMALL(profiles) | |
+}; | |
+#endif | |
+ | |
#if CONFIG_WMV3_DECODER | |
AVCodec ff_wmv3_decoder = { | |
.name = "wmv3", | |
@@ -1120,6 +1347,22 @@ AVCodec ff_wmv3_decoder = { | |
}; | |
#endif | |
+#ifdef SYNO_EVANSPORT_SMD | |
+AVCodec ff_wmv3_smd_decoder = { | |
+ .name = "wmv3_smd", | |
+ .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 9 Hardware(SMD) Decoder"), | |
+ .type = AVMEDIA_TYPE_VIDEO, | |
+ .id = AV_CODEC_ID_WMV3_SYNO, | |
+ .priv_data_size = sizeof(VC1Context), | |
+ .init = vc1_decode_init_smd, | |
+ .close = ff_vc1_decode_end, | |
+ .decode = vc1_decode_frame_smd, | |
+ .capabilities = CODEC_CAP_DELAY, | |
+ .pix_fmts = vc1_hwaccel_pixfmt_list_420, | |
+ .profiles = NULL_IF_CONFIG_SMALL(profiles) | |
+}; | |
+#endif | |
+ | |
#if CONFIG_WMV3_VDPAU_DECODER | |
AVCodec ff_wmv3_vdpau_decoder = { | |
.name = "wmv3_vdpau", | |
diff --git a/libavformat/avidec.c b/libavformat/avidec.c | |
index 5348b44b74..7989e0f71a 100644 | |
--- a/libavformat/avidec.c | |
+++ b/libavformat/avidec.c | |
@@ -1077,6 +1077,11 @@ static int read_gab2_sub(AVFormatContext *s, AVStream *st, AVPacket *pkt) | |
if (!sub_demuxer) | |
goto error; | |
+#ifdef SYNO_FIX_CVE_2017_9993 | |
+ if (strcmp(sub_demuxer->name, "srt") && strcmp(sub_demuxer->name, "ass")) | |
+ goto error; | |
+#endif | |
+ | |
if (!(ast->sub_ctx = avformat_alloc_context())) | |
goto error; | |
diff --git a/libavformat/flacdec.c b/libavformat/flacdec.c | |
index 4207fd2bf6..0972f28ca4 100644 | |
--- a/libavformat/flacdec.c | |
+++ b/libavformat/flacdec.c | |
@@ -28,6 +28,8 @@ | |
#include "vorbiscomment.h" | |
#include "replaygain.h" | |
+#include "synoconfig.h" | |
+ | |
static int flac_read_header(AVFormatContext *s) | |
{ | |
int ret, metadata_last=0, metadata_type, metadata_size, found_streaminfo=0; | |
@@ -126,12 +128,14 @@ static int flac_read_header(AVFormatContext *s) | |
} | |
av_freep(&buffer); | |
} else if (metadata_type == FLAC_METADATA_TYPE_PICTURE) { | |
+#ifndef SYNO_SKIP_FLAC_PARSE_PICTURE | |
ret = ff_flac_parse_picture(s, buffer, metadata_size); | |
av_freep(&buffer); | |
if (ret < 0) { | |
av_log(s, AV_LOG_ERROR, "Error parsing attached picture.\n"); | |
return ret; | |
} | |
+#endif | |
} else { | |
/* STREAMINFO must be the first block */ | |
if (!found_streaminfo) { | |
diff --git a/libavformat/hls.c b/libavformat/hls.c | |
index 3f1d97eb6f..830330c5b5 100644 | |
--- a/libavformat/hls.c | |
+++ b/libavformat/hls.c | |
@@ -913,6 +913,27 @@ static void update_options(char **dest, const char *name, void *src) | |
av_freep(dest); | |
} | |
+static int check_url(const char *url) { | |
+ const char *proto_name = avio_find_protocol_name(url); | |
+ | |
+ if (!proto_name) | |
+ return AVERROR_INVALIDDATA; | |
+ | |
+#ifdef SYNO_FIX_CVE_2017_9993 | |
+ if (!av_strstart(proto_name, "http", NULL)) | |
+#else | |
+ if (!av_strstart(proto_name, "http", NULL) && !av_strstart(proto_name, "file", NULL)) | |
+#endif | |
+ return AVERROR_INVALIDDATA; | |
+ | |
+ if (!strncmp(proto_name, url, strlen(proto_name)) && url[strlen(proto_name)] == ':') | |
+ return 0; | |
+ else if (strcmp(proto_name, "file") || !strncmp(url, "file,", 5)) | |
+ return AVERROR_INVALIDDATA; | |
+ | |
+ return 0; | |
+} | |
+ | |
static int open_input(HLSContext *c, struct playlist *pls) | |
{ | |
AVDictionary *opts = NULL; | |
@@ -940,6 +961,10 @@ static int open_input(HLSContext *c, struct playlist *pls) | |
seg->url, seg->url_offset, pls->index); | |
if (seg->key_type == KEY_NONE) { | |
+ ret = check_url(seg->url); | |
+ if (ret < 0) | |
+ goto cleanup; | |
+ | |
ret = ffurl_open(&pls->input, seg->url, AVIO_FLAG_READ, | |
&pls->parent->interrupt_callback, &opts); | |
@@ -947,6 +972,10 @@ static int open_input(HLSContext *c, struct playlist *pls) | |
char iv[33], key[33], url[MAX_URL_SIZE]; | |
if (strcmp(seg->key, pls->key_url)) { | |
URLContext *uc; | |
+ ret = check_url(seg->key); | |
+ if (ret < 0) | |
+ goto cleanup; | |
+ | |
if (ffurl_open(&uc, seg->key, AVIO_FLAG_READ, | |
&pls->parent->interrupt_callback, &opts2) == 0) { | |
if (ffurl_read_complete(uc, pls->key, sizeof(pls->key)) | |
diff --git a/libavformat/http.c b/libavformat/http.c | |
index 2db2dea51e..093531f9b7 100644 | |
--- a/libavformat/http.c | |
+++ b/libavformat/http.c | |
@@ -52,8 +52,8 @@ typedef struct HTTPContext { | |
int line_count; | |
int http_code; | |
/* Used if "Transfer-Encoding: chunked" otherwise -1. */ | |
- int64_t chunksize; | |
- int64_t off, end_off, filesize; | |
+ uint64_t chunksize; | |
+ uint64_t off, end_off, filesize; | |
char *location; | |
HTTPAuthState auth_state; | |
HTTPAuthState proxy_auth_state; | |
@@ -81,9 +81,9 @@ typedef struct HTTPContext { | |
AVDictionary *cookie_dict; | |
int icy; | |
/* how much data was read since the last ICY metadata packet */ | |
- int icy_data_read; | |
+ uint64_t icy_data_read; | |
/* after how many bytes of read data a new metadata packet will be found */ | |
- int icy_metaint; | |
+ uint64_t icy_metaint; | |
char *icy_metadata_headers; | |
char *icy_metadata_packet; | |
AVDictionary *metadata; | |
@@ -358,7 +358,7 @@ static int http_open(URLContext *h, const char *uri, int flags, | |
else | |
h->is_streamed = 1; | |
- s->filesize = -1; | |
+ s->filesize = UINT64_MAX; | |
s->location = av_strdup(uri); | |
if (!s->location) | |
return AVERROR(ENOMEM); | |
@@ -458,9 +458,9 @@ static void parse_content_range(URLContext *h, const char *p) | |
if (!strncmp(p, "bytes ", 6)) { | |
p += 6; | |
- s->off = strtoll(p, NULL, 10); | |
+ s->off = strtoull(p, NULL, 10); | |
if ((slash = strchr(p, '/')) && strlen(slash) > 0) | |
- s->filesize = strtoll(slash + 1, NULL, 10); | |
+ s->filesize = strtoull(slash + 1, NULL, 10); | |
} | |
if (s->seekable == -1 && (!s->is_akamai || s->filesize != 2147483647)) | |
h->is_streamed = 0; /* we _can_ in fact seek */ | |
@@ -646,8 +646,9 @@ static int process_line(URLContext *h, char *line, int line_count, | |
if ((ret = parse_location(s, p)) < 0) | |
return ret; | |
*new_location = 1; | |
- } else if (!av_strcasecmp(tag, "Content-Length") && s->filesize == -1) { | |
- s->filesize = strtoll(p, NULL, 10); | |
+ } else if (!av_strcasecmp(tag, "Content-Length") && | |
+ s->filesize == UINT64_MAX) { | |
+ s->filesize = strtoull(p, NULL, 10); | |
} else if (!av_strcasecmp(tag, "Content-Range")) { | |
parse_content_range(h, p); | |
} else if (!av_strcasecmp(tag, "Accept-Ranges") && | |
@@ -656,7 +657,7 @@ static int process_line(URLContext *h, char *line, int line_count, | |
h->is_streamed = 0; | |
} else if (!av_strcasecmp(tag, "Transfer-Encoding") && | |
!av_strncasecmp(p, "chunked", 7)) { | |
- s->filesize = -1; | |
+ s->filesize = UINT64_MAX; | |
s->chunksize = 0; | |
} else if (!av_strcasecmp(tag, "WWW-Authenticate")) { | |
ff_http_auth_handle_header(&s->auth_state, tag, p); | |
@@ -680,7 +681,7 @@ static int process_line(URLContext *h, char *line, int line_count, | |
if (parse_cookie(s, p, &s->cookie_dict)) | |
av_log(h, AV_LOG_WARNING, "Unable to parse '%s'\n", p); | |
} else if (!av_strcasecmp(tag, "Icy-MetaInt")) { | |
- s->icy_metaint = strtoll(p, NULL, 10); | |
+ s->icy_metaint = strtoull(p, NULL, 10); | |
} else if (!av_strncasecmp(tag, "Icy-", 4)) { | |
if ((ret = parse_icy(s, tag, p)) < 0) | |
return ret; | |
@@ -810,7 +811,7 @@ static int http_read_header(URLContext *h, int *new_location) | |
char line[MAX_URL_SIZE]; | |
int err = 0; | |
- s->chunksize = -1; | |
+ s->chunksize = UINT64_MAX; | |
for (;;) { | |
if ((err = http_get_line(s, line, sizeof(line))) < 0) | |
@@ -844,7 +845,7 @@ static int http_connect(URLContext *h, const char *path, const char *local_path, | |
int post, err; | |
char headers[HTTP_HEADERS_SIZE] = ""; | |
char *authstr = NULL, *proxyauthstr = NULL; | |
- int64_t off = s->off; | |
+ uint64_t off = s->off; | |
int len = 0; | |
const char *method; | |
int send_expect_100 = 0; | |
@@ -892,7 +893,7 @@ static int http_connect(URLContext *h, const char *path, const char *local_path, | |
// server supports seeking by analysing the reply headers. | |
if (!has_header(s->headers, "\r\nRange: ") && !post && (s->off > 0 || s->end_off || s->seekable == -1)) { | |
len += av_strlcatf(headers + len, sizeof(headers) - len, | |
- "Range: bytes=%"PRId64"-", s->off); | |
+ "Range: bytes=%"PRIu64"-", s->off); | |
if (s->end_off) | |
len += av_strlcatf(headers + len, sizeof(headers) - len, | |
"%"PRId64, s->end_off - 1); | |
@@ -967,7 +968,7 @@ static int http_connect(URLContext *h, const char *path, const char *local_path, | |
s->line_count = 0; | |
s->off = 0; | |
s->icy_data_read = 0; | |
- s->filesize = -1; | |
+ s->filesize = UINT64_MAX; | |
s->willclose = 0; | |
s->end_chunked_post = 0; | |
s->end_header = 0; | |
@@ -1007,14 +1008,12 @@ static int http_buf_read(URLContext *h, uint8_t *buf, int size) | |
memcpy(buf, s->buf_ptr, len); | |
s->buf_ptr += len; | |
} else { | |
- if ((!s->willclose || s->chunksize < 0) && | |
- s->filesize >= 0 && s->off >= s->filesize) | |
+ if ((!s->willclose || s->chunksize < 0) && s->off >= s->filesize) | |
return AVERROR_EOF; | |
len = ffurl_read(s->hd, buf, size); | |
- if (!len && (!s->willclose || s->chunksize < 0) && | |
- s->filesize >= 0 && s->off < s->filesize) { | |
+ if (!len && (!s->willclose || s->chunksize < 0) && s->off < s->filesize) { | |
av_log(h, AV_LOG_ERROR, | |
- "Stream ends prematurely at %"PRId64", should be %"PRId64"\n", | |
+ "Stream ends prematurely at %"PRIu64", should be %"PRIu64"\n", | |
s->off, s->filesize | |
); | |
return AVERROR(EIO); | |
@@ -1077,7 +1076,7 @@ static int http_read_stream(URLContext *h, uint8_t *buf, int size) | |
return err; | |
} | |
- if (s->chunksize >= 0) { | |
+ if (s->chunksize != UINT64_MAX) { | |
if (!s->chunksize) { | |
char line[32]; | |
@@ -1086,13 +1085,19 @@ static int http_read_stream(URLContext *h, uint8_t *buf, int size) | |
return err; | |
} while (!*line); /* skip CR LF from last chunk */ | |
- s->chunksize = strtoll(line, NULL, 16); | |
+ s->chunksize = strtoull(line, NULL, 16); | |
- av_log(NULL, AV_LOG_TRACE, "Chunked encoding data size: %"PRId64"'\n", | |
+ av_log(h, AV_LOG_TRACE, | |
+ "Chunked encoding data size: %"PRIu64"'\n", | |
s->chunksize); | |
if (!s->chunksize) | |
return 0; | |
+ else if (s->chunksize == UINT64_MAX) { | |
+ av_log(h, AV_LOG_ERROR, "Invalid chunk size %"PRIu64"\n", | |
+ s->chunksize); | |
+ return AVERROR(EINVAL); | |
+ } | |
} | |
size = FFMIN(size, s->chunksize); | |
} | |
@@ -1102,10 +1107,10 @@ static int http_read_stream(URLContext *h, uint8_t *buf, int size) | |
#endif /* CONFIG_ZLIB */ | |
read_ret = http_buf_read(h, buf, size); | |
if (read_ret < 0 && s->reconnect && !h->is_streamed && s->filesize > 0 && s->off < s->filesize) { | |
- av_log(h, AV_LOG_INFO, "Will reconnect at %"PRId64".\n", s->off); | |
+ av_log(h, AV_LOG_INFO, "Will reconnect at %"PRIu64".\n", s->off); | |
seek_ret = http_seek_internal(h, s->off, SEEK_SET, 1); | |
if (seek_ret != s->off) { | |
- av_log(h, AV_LOG_ERROR, "Failed to reconnect at %"PRId64".\n", s->off); | |
+ av_log(h, AV_LOG_ERROR, "Failed to reconnect at %"PRIu64".\n", s->off); | |
return read_ret; | |
} | |
@@ -1159,10 +1164,11 @@ static int store_icy(URLContext *h, int size) | |
{ | |
HTTPContext *s = h->priv_data; | |
/* until next metadata packet */ | |
- int remaining = s->icy_metaint - s->icy_data_read; | |
+ uint64_t remaining; | |
- if (remaining < 0) | |
+ if (s->icy_metaint < s->icy_data_read) | |
return AVERROR_INVALIDDATA; | |
+ remaining = s->icy_metaint - s->icy_data_read; | |
if (!remaining) { | |
/* The metadata packet is variable sized. It has a 1 byte header | |
@@ -1275,7 +1281,7 @@ static int64_t http_seek_internal(URLContext *h, int64_t off, int whence, int fo | |
{ | |
HTTPContext *s = h->priv_data; | |
URLContext *old_hd = s->hd; | |
- int64_t old_off = s->off; | |
+ uint64_t old_off = s->off; | |
uint8_t old_buf[BUFFER_SIZE]; | |
int old_buf_size, ret; | |
AVDictionary *options = NULL; | |
@@ -1286,7 +1292,7 @@ static int64_t http_seek_internal(URLContext *h, int64_t off, int whence, int fo | |
((whence == SEEK_CUR && off == 0) || | |
(whence == SEEK_SET && off == s->off))) | |
return s->off; | |
- else if ((s->filesize == -1 && whence == SEEK_END) || h->is_streamed) | |
+ else if ((s->filesize == UINT64_MAX && whence == SEEK_END) || h->is_streamed) | |
return AVERROR(ENOSYS); | |
if (whence == SEEK_CUR) | |
@@ -1433,7 +1439,7 @@ redo: | |
s->buf_ptr = s->buffer; | |
s->buf_end = s->buffer; | |
s->line_count = 0; | |
- s->filesize = -1; | |
+ s->filesize = UINT64_MAX; | |
cur_auth_type = s->proxy_auth_state.auth_type; | |
/* Note: This uses buffering, potentially reading more than the | |
diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c | |
index 3b525ad4d4..670d31f70b 100644 | |
--- a/libavformat/matroskaenc.c | |
+++ b/libavformat/matroskaenc.c | |
@@ -52,6 +52,8 @@ | |
#include "libavcodec/mpeg4audio.h" | |
#include "libavcodec/internal.h" | |
+#include "synoconfig.h" | |
+ | |
typedef struct ebml_master { | |
int64_t pos; ///< absolute offset in the file where the master's elements start | |
int sizebytes; ///< how many bytes were reserved for the size | |
@@ -132,9 +134,13 @@ typedef struct MatroskaMuxContext { | |
int64_t last_track_timestamp[MAX_TRACKS]; | |
int allow_raw_vfw; | |
+#ifdef SYNO_VIDEOSTATION_WEBM_SEEK_TIME | |
+ int64_t seek_time; | |
+ AVPacket old_key_packet; | |
+ int unfilled; | |
+#endif | |
} MatroskaMuxContext; | |
- | |
/** 2 bytes * 3 for EBML IDs, 3 1-byte EBML lengths, 8 bytes for 64 bit | |
* offset, 4 bytes for target EBML ID */ | |
#define MAX_SEEKENTRY_SIZE 21 | |
@@ -1483,6 +1489,11 @@ static int mkv_write_header(AVFormatContext *s) | |
mkv->cluster_size_limit = 32 * 1024; | |
} | |
+#ifdef SYNO_VIDEOSTATION_WEBM_SEEK_TIME | |
+ av_init_packet(&mkv->old_key_packet); | |
+ mkv->unfilled = 1; | |
+#endif | |
+ | |
return 0; | |
} | |
@@ -1812,6 +1823,41 @@ static int mkv_write_packet(AVFormatContext *s, AVPacket *pkt) | |
int ret; | |
int start_new_cluster; | |
+#ifdef SYNO_VIDEOSTATION_WEBM_SEEK_TIME | |
+ int64_t pts = AV_NOPTS_VALUE; | |
+ if (0 < mkv->seek_time && mkv->unfilled) { | |
+ if (codec_type != AVMEDIA_TYPE_VIDEO) { | |
+ return 0; | |
+ } | |
+ | |
+ if (pkt->pts != AV_NOPTS_VALUE) { | |
+ pts = pkt->pts; | |
+ } else if (pkt->dts != AV_NOPTS_VALUE) { | |
+ pts = pkt->dts; | |
+ } | |
+ if (pts >= 0) { | |
+ if (pkt->flags & AV_PKT_FLAG_KEY) { | |
+ mkv->unfilled = 0; | |
+ } else if (NULL != mkv->old_key_packet.data) { | |
+ mkv->old_key_packet.pts = pkt->pts; | |
+ mkv->old_key_packet.dts = pkt->dts; | |
+ mkv->old_key_packet.duration = pkt->duration; | |
+ av_free_packet(pkt); | |
+ av_init_packet(pkt); | |
+ av_copy_packet(pkt, &mkv->old_key_packet); | |
+ mkv->unfilled = 0; | |
+ } | |
+ av_free_packet(&mkv->old_key_packet); | |
+ } else { | |
+ if (pkt->flags & AV_PKT_FLAG_KEY) { | |
+ av_free_packet(&mkv->old_key_packet); | |
+ av_copy_packet(&mkv->old_key_packet, pkt); | |
+ } | |
+ return 0; | |
+ } | |
+ } | |
+#endif | |
+ | |
if (mkv->tracks[pkt->stream_index].write_dts) | |
cluster_time = pkt->dts - mkv->cluster_pts; | |
else | |
@@ -2047,6 +2093,9 @@ static const AVOption options[] = { | |
{ "dash_track_number", "Track number for the DASH stream", OFFSET(dash_track_number), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 127, FLAGS }, | |
{ "live", "Write files assuming it is a live stream.", OFFSET(is_live), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, FLAGS }, | |
{ "allow_raw_vfw", "allow RAW VFW mode", OFFSET(allow_raw_vfw), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, FLAGS }, | |
+#ifdef SYNO_VIDEOSTATION_WEBM_SEEK_TIME | |
+ { "webm_seek_time", "seek time", OFFSET(seek_time), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, FLAGS }, | |
+#endif | |
{ NULL }, | |
}; | |
diff --git a/libavformat/mov.c b/libavformat/mov.c | |
index 5ea6932801..2141d2d676 100644 | |
--- a/libavformat/mov.c | |
+++ b/libavformat/mov.c | |
@@ -626,6 +626,8 @@ static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom) | |
title_size = atom.size - 24; | |
if (title_size > 0) { | |
+ if (title_size > FFMIN(INT_MAX, SIZE_MAX-1)) | |
+ return AVERROR_INVALIDDATA; | |
title_str = av_malloc(title_size + 1); /* Add null terminator */ | |
if (!title_str) | |
return AVERROR(ENOMEM); | |
@@ -3489,7 +3491,7 @@ static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom) | |
0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66 | |
}; | |
- if (atom.size < sizeof(uuid) || atom.size == INT64_MAX) | |
+ if (atom.size < sizeof(uuid) || atom.size >= FFMIN(INT_MAX, SIZE_MAX)) | |
return AVERROR_INVALIDDATA; | |
ret = avio_read(pb, uuid, sizeof(uuid)); | |
diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c | |
index 9efa9fc362..95f688dcf1 100644 | |
--- a/libavformat/mpegtsenc.c | |
+++ b/libavformat/mpegtsenc.c | |
@@ -34,6 +34,8 @@ | |
#include "internal.h" | |
#include "mpegts.h" | |
+#include "synoconfig.h" | |
+ | |
#define PCR_TIME_BASE 27000000 | |
/* write DVB SI sections */ | |
@@ -711,8 +713,12 @@ static int mpegts_write_header(AVFormatContext *s) | |
service->pcr_pid = ts_st->pid; | |
pcr_st = st; | |
} | |
+#ifdef SYNO_MPEGTS_FORAMT_AAC_COPY_FAILED | |
+ if (st->codec->codec_id == AV_CODEC_ID_AAC) { | |
+#else | |
if (st->codec->codec_id == AV_CODEC_ID_AAC && | |
st->codec->extradata_size > 0) { | |
+#endif | |
AVStream *ast; | |
ts_st->amux = avformat_alloc_context(); | |
if (!ts_st->amux) { | |
diff --git a/libavformat/rtmppkt.c b/libavformat/rtmppkt.c | |
index c474fb3d58..451507edd7 100644 | |
--- a/libavformat/rtmppkt.c | |
+++ b/libavformat/rtmppkt.c | |
@@ -235,6 +235,14 @@ static int rtmp_packet_read_one_chunk(URLContext *h, RTMPPacket *p, | |
if (hdr != RTMP_PS_TWELVEBYTES) | |
timestamp += prev_pkt[channel_id].timestamp; | |
+ if (prev_pkt[channel_id].read && size != prev_pkt[channel_id].size) { | |
+ av_log(NULL, AV_LOG_ERROR, "RTMP packet size mismatch %d != %d\n", | |
+ size, | |
+ prev_pkt[channel_id].size); | |
+ ff_rtmp_packet_destroy(&prev_pkt[channel_id]); | |
+ prev_pkt[channel_id].read = 0; | |
+ } | |
+ | |
if (!prev_pkt[channel_id].read) { | |
if ((ret = ff_rtmp_packet_create(p, channel_id, type, timestamp, | |
size)) < 0) | |
diff --git a/libavformat/segment.c b/libavformat/segment.c | |
index 4418d0f338..aef2a67984 100644 | |
--- a/libavformat/segment.c | |
+++ b/libavformat/segment.c | |
@@ -42,6 +42,8 @@ | |
#include "libavutil/time_internal.h" | |
#include "libavutil/timestamp.h" | |
+#include "synoconfig.h" | |
+ | |
typedef struct SegmentListEntry { | |
int index; | |
double start_time, end_time; | |
@@ -116,6 +118,13 @@ typedef struct SegmentContext { | |
SegmentListEntry cur_entry; | |
SegmentListEntry *segment_list_entries; | |
SegmentListEntry *segment_list_entries_end; | |
+ | |
+#ifdef SYNO_VIDEOSTATION_HLS_SEEK_TIME | |
+ int64_t seek_time; | |
+ AVPacket old_key_packet; | |
+ int filled; | |
+#endif | |
+ | |
} SegmentContext; | |
static void print_csv_escaped_str(AVIOContext *ctx, const char *str) | |
@@ -205,9 +214,15 @@ static int set_segment_filename(AVFormatContext *s) | |
seg->cur_entry.filename = av_mallocz(size); | |
if (!seg->cur_entry.filename) | |
return AVERROR(ENOMEM); | |
+#ifdef SYNO_VIDEOSTATION | |
+ snprintf(seg->cur_entry.filename, size, "%s%03d", | |
+ seg->entry_prefix ? seg->entry_prefix : "", | |
+ seg->segment_idx); | |
+#else | |
snprintf(seg->cur_entry.filename, size, "%s%s", | |
seg->entry_prefix ? seg->entry_prefix : "", | |
av_basename(oc->filename)); | |
+#endif | |
return 0; | |
} | |
@@ -729,6 +744,11 @@ static int seg_write_header(AVFormatContext *s) | |
oc->pb->seekable = 0; | |
} | |
+#ifdef SYNO_VIDEOSTATION_HLS_SEEK_TIME | |
+ av_init_packet(&seg->old_key_packet); | |
+ seg->filled = 1; | |
+#endif | |
+ | |
fail: | |
av_dict_free(&options); | |
if (ret < 0) | |
@@ -751,6 +771,41 @@ static int seg_write_packet(AVFormatContext *s, AVPacket *pkt) | |
if (!seg->avf) | |
return AVERROR(EINVAL); | |
+#ifdef SYNO_VIDEOSTATION_HLS_SEEK_TIME | |
+ int64_t pts = AV_NOPTS_VALUE; | |
+ if (0 < seg->seek_time && seg->filled) { | |
+ if (pkt->stream_index != seg->reference_stream_index) { | |
+ return 0; | |
+ } | |
+ | |
+ if (pkt->pts != AV_NOPTS_VALUE) { | |
+ pts = pkt->pts; | |
+ } else if (pkt->dts != AV_NOPTS_VALUE) { | |
+ pts = pkt->dts; | |
+ } | |
+ if (pts >= 0) { | |
+ if (pkt->flags & AV_PKT_FLAG_KEY) { | |
+ seg->filled = 0; | |
+ } else if (NULL != seg->old_key_packet.data) { | |
+ seg->old_key_packet.pts = pkt->pts; | |
+ seg->old_key_packet.dts = pkt->dts; | |
+ seg->old_key_packet.duration = pkt->duration; | |
+ av_free_packet(pkt); | |
+ av_init_packet(pkt); | |
+ av_copy_packet(pkt, &seg->old_key_packet); | |
+ seg->filled = 0; | |
+ } | |
+ av_free_packet(&seg->old_key_packet); | |
+ } else { | |
+ if (pkt->flags & AV_PKT_FLAG_KEY) { | |
+ av_free_packet(&seg->old_key_packet); | |
+ av_copy_packet(&seg->old_key_packet, pkt); | |
+ } | |
+ return 0; | |
+ } | |
+ } | |
+#endif | |
+ | |
if (seg->times) { | |
end_pts = seg->segment_count < seg->nb_times ? | |
seg->times[seg->segment_count] : INT64_MAX; | |
@@ -833,6 +888,15 @@ static int seg_write_packet(AVFormatContext *s, AVPacket *pkt) | |
av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &st->time_base), | |
av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &st->time_base)); | |
+#ifdef SYNO_VIDEOSTATION_HLS_SEEK_TIME | |
+ if (0 < seg->seek_time) { | |
+ if (pkt->pts != AV_NOPTS_VALUE) | |
+ pkt->pts += av_rescale_q(seg->seek_time, (AVRational) {1, 1000}, st->time_base); | |
+ if (pkt->dts != AV_NOPTS_VALUE) | |
+ pkt->dts += av_rescale_q(seg->seek_time, (AVRational) {1, 1000}, st->time_base); | |
+ } | |
+#endif | |
+ | |
ret = ff_write_chained(seg->avf, pkt->stream_index, pkt, s, seg->initial_offset || seg->reset_timestamps); | |
fail: | |
@@ -927,6 +991,9 @@ static const AVOption options[] = { | |
{ "write_header_trailer", "write a header to the first segment and a trailer to the last one", OFFSET(write_header_trailer), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, E }, | |
{ "reset_timestamps", "reset timestamps at the begin of each segment", OFFSET(reset_timestamps), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, E }, | |
{ "initial_offset", "set initial timestamp offset", OFFSET(initial_offset), AV_OPT_TYPE_DURATION, {.i64 = 0}, -INT64_MAX, INT64_MAX, E }, | |
+#ifdef SYNO_VIDEOSTATION_HLS_SEEK_TIME | |
+ { "hls_seek_time", "initial segment start time", OFFSET(seek_time), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, E }, | |
+#endif | |
{ NULL }, | |
}; | |
diff --git a/libavformat/smoothstreamingenc.c b/libavformat/smoothstreamingenc.c | |
index 07173a96f9..e9d54d32a8 100644 | |
--- a/libavformat/smoothstreamingenc.c | |
+++ b/libavformat/smoothstreamingenc.c | |
@@ -38,6 +38,8 @@ | |
#include "libavutil/mathematics.h" | |
#include "libavutil/intreadwrite.h" | |
+#include "synoconfig.h" | |
+ | |
typedef struct Fragment { | |
char file[1024]; | |
char infofile[1024]; | |
@@ -76,6 +78,15 @@ typedef struct SmoothStreamingContext { | |
OutputStream *streams; | |
int has_video, has_audio; | |
int nb_fragments; | |
+#ifdef SYNO_SMOOTH_STREAMING | |
+ char *fragment_url; | |
+ int fragment_length; | |
+ int seek_time; | |
+#ifdef SYNO_EVANSPORT_SMOOTH_STREAMING_TIMESTAMP_INACCURATE | |
+ AVPacket old_key_packet; | |
+ int filled; | |
+#endif | |
+#endif | |
} SmoothStreamingContext; | |
static int ism_write(void *opaque, uint8_t *buf, int buf_size) | |
@@ -254,7 +265,12 @@ static int write_manifest(AVFormatContext *s, int final) | |
avio_printf(out, ">\n"); | |
if (c->has_video) { | |
int last = -1, index = 0; | |
+#ifdef SYNO_SMOOTH_STREAMING | |
+ avio_printf(out, "<StreamIndex Type=\"video\" QualityLevels=\"%d\" Chunks=\"%d\" Url=\"%sQualityLevels({bitrate})/Fragments(video={start time})\">\n", video_streams, video_chunks, | |
+ (NULL == c->fragment_url) ? "" : c->fragment_url); | |
+#else | |
avio_printf(out, "<StreamIndex Type=\"video\" QualityLevels=\"%d\" Chunks=\"%d\" Url=\"QualityLevels({bitrate})/Fragments(video={start time})\">\n", video_streams, video_chunks); | |
+#endif | |
for (i = 0; i < s->nb_streams; i++) { | |
OutputStream *os = &c->streams[i]; | |
if (s->streams[i]->codec->codec_type != AVMEDIA_TYPE_VIDEO) | |
@@ -268,7 +284,12 @@ static int write_manifest(AVFormatContext *s, int final) | |
} | |
if (c->has_audio) { | |
int last = -1, index = 0; | |
+#ifdef SYNO_SMOOTH_STREAMING | |
+ avio_printf(out, "<StreamIndex Type=\"audio\" QualityLevels=\"%d\" Chunks=\"%d\" Url=\"%sQualityLevels({bitrate})/Fragments(audio={start time})\">\n", audio_streams, audio_chunks, | |
+ (NULL == c->fragment_url) ? "" : c->fragment_url); | |
+#else | |
avio_printf(out, "<StreamIndex Type=\"audio\" QualityLevels=\"%d\" Chunks=\"%d\" Url=\"QualityLevels({bitrate})/Fragments(audio={start time})\">\n", audio_streams, audio_chunks); | |
+#endif | |
for (i = 0; i < s->nb_streams; i++) { | |
OutputStream *os = &c->streams[i]; | |
if (s->streams[i]->codec->codec_type != AVMEDIA_TYPE_AUDIO) | |
@@ -398,6 +419,9 @@ static int ism_write_header(AVFormatContext *s) | |
} | |
ret = write_manifest(s, 0); | |
+#ifdef SYNO_EVANSPORT_SMOOTH_STREAMING_TIMESTAMP_INACCURATE | |
+ av_init_packet(&c->old_key_packet); | |
+#endif | |
fail: | |
if (ret) | |
ism_free(s); | |
@@ -538,6 +562,14 @@ static int ism_flush(AVFormatContext *s, int final) | |
size = os->tail_pos - os->cur_start_pos; | |
if ((ret = parse_fragment(s, filename, &start_ts, &duration, &moof_size, size)) < 0) | |
break; | |
+#ifdef SYNO_SMOOTH_STREAMING | |
+ if (0 != c->fragment_length) { | |
+ start_ts = (int64_t)((int64_t)os->nb_fragments * (int64_t)c->fragment_length * (int64_t)10000000); | |
+ } | |
+ if (0 != c->seek_time) { | |
+ start_ts += (int64_t)((int64_t)c->seek_time * (int64_t)10000000); | |
+ } | |
+#endif | |
snprintf(header_filename, sizeof(header_filename), "%s/FragmentInfo(%s=%"PRIu64")", os->dirname, os->stream_type_tag, start_ts); | |
snprintf(target_filename, sizeof(target_filename), "%s/Fragments(%s=%"PRIu64")", os->dirname, os->stream_type_tag, start_ts); | |
copy_moof(s, filename, header_filename, moof_size); | |
@@ -582,6 +614,34 @@ static int ism_write_packet(AVFormatContext *s, AVPacket *pkt) | |
int64_t end_dts = (c->nb_fragments + 1) * (int64_t) c->min_frag_duration; | |
int ret; | |
+#ifdef SYNO_EVANSPORT_SMOOTH_STREAMING_TIMESTAMP_INACCURATE | |
+ if (c->has_video && 0 != c->seek_time && c->filled) { | |
+ if (st->codec->codec_type != AVMEDIA_TYPE_VIDEO) { | |
+ return 0; | |
+ } | |
+ if (av_compare_ts(pkt->dts, st->time_base, (int64_t)((int64_t)c->seek_time * (int64_t)1000000), AV_TIME_BASE_Q) >= 0) { | |
+ if (pkt->flags & AV_PKT_FLAG_KEY) { | |
+ c->filled = 0; | |
+ } else if (NULL != c->old_key_packet.data) { | |
+ c->old_key_packet.pts = pkt->pts; | |
+ c->old_key_packet.dts = pkt->dts; | |
+ c->old_key_packet.duration = pkt->duration; | |
+ av_free_packet(pkt); | |
+ av_init_packet(pkt); | |
+ av_copy_packet(pkt, &c->old_key_packet); | |
+ c->filled = 0; | |
+ } | |
+ av_free_packet(&c->old_key_packet); | |
+ } else { | |
+ if (pkt->flags & AV_PKT_FLAG_KEY) { | |
+ av_free_packet(&c->old_key_packet); | |
+ av_copy_packet(&c->old_key_packet, pkt); | |
+ } | |
+ return 0; | |
+ } | |
+ } | |
+#endif | |
+ | |
if (st->first_dts == AV_NOPTS_VALUE) | |
st->first_dts = pkt->dts; | |
@@ -623,6 +683,14 @@ static const AVOption options[] = { | |
{ "lookahead_count", "number of lookahead fragments", OFFSET(lookahead_count), AV_OPT_TYPE_INT, { .i64 = 2 }, 0, INT_MAX, E }, | |
{ "min_frag_duration", "minimum fragment duration (in microseconds)", OFFSET(min_frag_duration), AV_OPT_TYPE_INT64, { .i64 = 5000000 }, 0, INT_MAX, E }, | |
{ "remove_at_exit", "remove all fragments when finished", OFFSET(remove_at_exit), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, E }, | |
+#ifdef SYNO_SMOOTH_STREAMING | |
+ { "fragment_url", "set fragment url in manifest", OFFSET(fragment_url), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, E }, | |
+ { "fragment_length", "let file name of output fragment mp4 with the duration (in seconds)", OFFSET(fragment_length), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, E }, | |
+ { "seek_time", "add seek time to fragment file (in seconds)", OFFSET(seek_time), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, E }, | |
+#ifdef SYNO_EVANSPORT_SMOOTH_STREAMING_TIMESTAMP_INACCURATE | |
+ { "filled", "filter out useless frame (hardware transcode)", OFFSET(filled), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, E }, | |
+#endif | |
+#endif | |
{ NULL }, | |
}; | |
diff --git a/libavformat/swfdec.c b/libavformat/swfdec.c | |
index d34d3d90df..7cf72432c9 100644 | |
--- a/libavformat/swfdec.c | |
+++ b/libavformat/swfdec.c | |
@@ -107,10 +107,10 @@ retry: | |
z->avail_out = buf_size; | |
ret = inflate(z, Z_NO_FLUSH); | |
- if (ret < 0) | |
- return AVERROR(EINVAL); | |
if (ret == Z_STREAM_END) | |
return AVERROR_EOF; | |
+ if (ret != Z_OK) | |
+ return AVERROR(EINVAL); | |
if (buf_size - z->avail_out == 0) | |
goto retry; | |
diff --git a/libavformat/utils.c b/libavformat/utils.c | |
index caa15abbae..4638fc596a 100644 | |
--- a/libavformat/utils.c | |
+++ b/libavformat/utils.c | |
@@ -52,6 +52,10 @@ | |
#include "url.h" | |
#include "libavutil/ffversion.h" | |
+ | |
+#include "synoconfig.h" | |
+#include "libavcodec/synog1codecpatent.h" | |
+ | |
const char av_format_ffversion[] = "FFmpeg version " FFMPEG_VERSION; | |
/** | |
@@ -3035,6 +3039,9 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) | |
int64_t max_stream_analyze_duration; | |
int64_t probesize = ic->probesize2; | |
+#ifdef SYNO_CODEC_PATENT_G1 | |
+ setenv(SZ_SYNO_CODEC_SKIP_ACTIVATION, "yes", 1); | |
+#endif | |
if (!max_analyze_duration) | |
max_analyze_duration = ic->max_analyze_duration; | |
if (ic->probesize) | |
@@ -3297,7 +3304,14 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) | |
int i = st->parser->parser->split(st->codec, pkt->data, pkt->size); | |
if (i > 0 && i < FF_MAX_EXTRADATA_SIZE) { | |
if (ff_alloc_extradata(st->codec, i)) | |
+#ifdef SYNO_CODEC_PATENT_G1 | |
+ { | |
+ unsetenv(SZ_SYNO_CODEC_SKIP_ACTIVATION); | |
+#endif | |
return AVERROR(ENOMEM); | |
+#ifdef SYNO_CODEC_PATENT_G1 | |
+ } | |
+#endif | |
memcpy(st->codec->extradata, pkt->data, | |
st->codec->extradata_size); | |
} | |
@@ -3473,6 +3487,9 @@ find_stream_info_err: | |
if (ic->pb) | |
av_log(ic, AV_LOG_DEBUG, "After avformat_find_stream_info() pos: %"PRId64" bytes read:%"PRId64" seeks:%d frames:%d\n", | |
avio_tell(ic->pb), ic->pb->bytes_read, ic->pb->seek_count, count); | |
+#ifdef SYNO_CODEC_PATENT_G1 | |
+ unsetenv(SZ_SYNO_CODEC_SKIP_ACTIVATION); | |
+#endif | |
return ret; | |
} | |
diff --git a/libavformat/wavenc.c b/libavformat/wavenc.c | |
index f89c91e8c7..800872363e 100644 | |
--- a/libavformat/wavenc.c | |
+++ b/libavformat/wavenc.c | |
@@ -46,6 +46,8 @@ | |
#include "internal.h" | |
#include "riff.h" | |
+#include "synoconfig.h" | |
+ | |
#define RF64_AUTO (-1) | |
#define RF64_NEVER 0 | |
#define RF64_ALWAYS 1 | |
@@ -86,6 +88,9 @@ typedef struct WAVMuxContext { | |
int peak_block_pos; | |
int peak_ppv; | |
int peak_bps; | |
+#ifdef SYNO_WRITE_RIFF_INFO_TAG_TO_WAV | |
+ int write_info_tag; | |
+#endif | |
} WAVMuxContext; | |
#if CONFIG_WAV_MUXER | |
@@ -364,7 +369,13 @@ static int wav_write_header(AVFormatContext *s) | |
if (wav->write_peak != 2) { | |
/* info header */ | |
+#ifdef SYNO_WRITE_RIFF_INFO_TAG_TO_WAV | |
+ if (wav->write_info_tag) { | |
+ ff_riff_write_info(s); | |
+ } | |
+#else | |
ff_riff_write_info(s); | |
+#endif | |
/* data header */ | |
wav->data = ff_start_tag(pb, "data"); | |
@@ -514,6 +525,9 @@ static const AVOption options[] = { | |
{ "peak_block_size", "Number of audio samples used to generate each peak frame.", OFFSET(peak_block_size), AV_OPT_TYPE_INT, { .i64 = 256 }, 0, 65536, ENC }, | |
{ "peak_format", "The format of the peak envelope data (1: uint8, 2: uint16).", OFFSET(peak_format), AV_OPT_TYPE_INT, { .i64 = PEAK_FORMAT_UINT16 }, PEAK_FORMAT_UINT8, PEAK_FORMAT_UINT16, ENC }, | |
{ "peak_ppv", "Number of peak points per peak value (1 or 2).", OFFSET(peak_ppv), AV_OPT_TYPE_INT, { .i64 = 2 }, 1, 2, ENC }, | |
+#ifdef SYNO_WRITE_RIFF_INFO_TAG_TO_WAV | |
+ { "write_info_tag", "Write RIFF info tag.", OFFSET(write_info_tag), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, ENC }, | |
+#endif | |
{ NULL }, | |
}; | |
diff --git a/libswscale/arm/Makefile b/libswscale/arm/Makefile | |
index 8b5a97b54c..4d7c4229dd 100644 | |
--- a/libswscale/arm/Makefile | |
+++ b/libswscale/arm/Makefile | |
@@ -2,3 +2,10 @@ | |
# NEON-OBJS += arm/rgb2yuv_neon_32.o | |
# NEON-OBJS += arm/rgb2yuv_neon_16.o | |
+ | |
+# for SYNO_ALPINE_NEON_LIBSWSCALE | |
+ifeq ($(EXPORT_BUILD_TARGET), ALPINE) | |
+OBJS += arm/swscale_arm.o | |
+ | |
+CFLAGS+= -mfpu=neon-vfpv4 -flax-vector-conversions -std=gnu99 | |
+endif | |
diff --git a/libswscale/arm/swscale_arm.c b/libswscale/arm/swscale_arm.c | |
new file mode 100644 | |
index 0000000000..170f458e76 | |
--- /dev/null | |
+++ b/libswscale/arm/swscale_arm.c | |
@@ -0,0 +1,409 @@ | |
+/* | |
+ * AltiVec-enhanced yuv2yuvX | |
+ * | |
+ * based on the equivalent C code in swscale.c | |
+ * | |
+ * This file is part of FFmpeg. | |
+ * | |
+ * FFmpeg 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. | |
+ * | |
+ * FFmpeg 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 FFmpeg; if not, write to the Free Software | |
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
+ */ | |
+ | |
+#include <inttypes.h> | |
+ | |
+#include "config.h" | |
+#include "libswscale/swscale.h" | |
+#include "libswscale/swscale_internal.h" | |
+#include "libavutil/attributes.h" | |
+#include "libavutil/cpu.h" | |
+#include <arm_neon.h> | |
+ | |
+#include <stdio.h> | |
+ | |
+#define PLD_NEXT(pointer) \ | |
+ asm( "pld [%0, #256] \n\t" : : "r"(pointer)); | |
+ | |
+static int ypfirst = 1; | |
+static int hsfirst = 1; | |
+ | |
+static inline int16_t filter_once(int filterSize, | |
+ const int16_t *filter, int16x8_t filterMask , | |
+ uint16x8_t rowSrcA, uint16x8_t rowSrcB) | |
+{ | |
+ int val; | |
+ int32x4_t mult; | |
+ int32x2_t aggregate; | |
+ int16_t filter9; | |
+ int16x8_t filterVec; | |
+ | |
+ filterVec = vld1q_s16(filter); | |
+ if (filterSize > 8) | |
+ filter9 = filter[8]; | |
+ PLD_NEXT(filter); | |
+ | |
+ if (filterSize < 8) | |
+ filterVec = vandq_s16(filterMask,filterVec); | |
+ | |
+ //now the two filters have 4 16u each. | |
+ if (filterSize > 8){ | |
+ val = vgetq_lane_u16(rowSrcB,0) * filter9 ; | |
+ } else | |
+ val=0; | |
+ | |
+ mult = vdupq_n_u32(0); | |
+ mult = vmlal_s16(mult,vget_low_s16(filterVec), vget_low_s16(rowSrcA)); | |
+ mult = vmlal_s16(mult,vget_high_s16(filterVec), vget_high_s16(rowSrcA)); | |
+ aggregate = vpadd_s32(vget_low_s32(mult), vget_high_s32(mult)); | |
+ aggregate = vpadd_s32(aggregate, aggregate); | |
+ val+=vget_lane_s32(aggregate,0); | |
+ | |
+ return FFMIN(val >> 7, (1 << 15) - 1); | |
+} | |
+ | |
+static inline void hScale8To15_arm_template(SwsContext *c, int16_t *dst, int dstW, | |
+ const uint8_t *src, const int16_t *filter, | |
+ const int32_t *filterPos | |
+ , int filterSize, int stepSize) | |
+{ | |
+ int i; | |
+ uint16x8_t rowSrcA, rowSrcB, rowSrcC; | |
+ int16x8_t filterMask; | |
+ int16_t filterMask_array[8]; | |
+ int srcCounter=0; | |
+ int srcCounterLast; | |
+ const uint8_t *srcPointer=src; | |
+ int srcCounterNext; | |
+ int filterMask_start; | |
+ | |
+ filterMask_start = filterSize > 8 ? 8 : 0; | |
+ for (i=filterMask_start; i<filterSize-filterMask_start; i++) | |
+ filterMask_array[i]=-1; | |
+ for (i=filterSize-filterMask_start; i<8; i++) | |
+ filterMask_array[i]=0; | |
+ filterMask=vld1q_u16(filterMask_array); | |
+ | |
+ if ((uintptr_t)srcPointer&0x7) | |
+ fprintf(stderr, "ERROR! src Pointer not aligned!(%d)/n",(uintptr_t)srcPointer&0x7); | |
+ rowSrcA = vmovl_u8(vld1_u8(srcPointer)); | |
+ srcPointer+=8; | |
+ rowSrcB = vmovl_u8(vld1_u8(srcPointer)); | |
+ srcPointer+=8; | |
+ i=0; | |
+ srcCounterNext = filterPos[0]; | |
+ //Loop-entry: a few first pixels might have | |
+ //0 for "filterpos". handle it outside the loop | |
+ //so we don't have to check inside the loop. | |
+ while (!srcCounterNext) { | |
+ dst[i] = filter_once(filterSize, filter, filterMask, rowSrcA, rowSrcB);; | |
+ filter +=filterSize; | |
+ i++; | |
+ srcCounterNext = filterPos[i]; | |
+ PLD_NEXT(filterPos+i); | |
+ } | |
+ srcCounterLast = filterPos[dstW-filterSize]; | |
+ while (srcCounter < srcCounterLast) { | |
+ int internalCount; | |
+ //8-wide buffer | |
+ rowSrcC = vmovl_u8(vld1_u8(srcPointer)); | |
+ srcPointer+=8; | |
+ PLD_NEXT(srcPointer); | |
+ | |
+ for (internalCount=0;internalCount<8/stepSize; internalCount++) | |
+ { | |
+ if (stepSize ==1) { | |
+ srcCounter++; | |
+ rowSrcA = vextq_u16(rowSrcA, rowSrcB,1); | |
+ rowSrcB = vextq_u16(rowSrcB, rowSrcC,1); | |
+ rowSrcC = vextq_u16(rowSrcC, rowSrcC,1); | |
+ } else { | |
+ srcCounter+=2; | |
+ rowSrcA = vextq_u16(rowSrcA, rowSrcB,2); | |
+ rowSrcB = vextq_u16(rowSrcB, rowSrcC,2); | |
+ rowSrcC = vextq_u16(rowSrcC, rowSrcC,2); | |
+ } | |
+ //*TODO: this "if" is cheating, and works only for shrinking | |
+ //with unnoticable visual difference | |
+ //a "while" would be more correct, but costs some performance | |
+ //TODO: or does it? | |
+ if (srcCounter >= srcCounterNext) { | |
+ dst[i] = filter_once(filterSize, filter, filterMask, rowSrcA, rowSrcB);; | |
+ filter +=filterSize; | |
+ i++; | |
+ srcCounterNext = filterPos[i]; | |
+ PLD_NEXT(filterPos+i); | |
+ } | |
+ } | |
+ } | |
+ | |
+ //Loop-exit: a few last pixels might have | |
+ //dstw-1 for "filterpos". handle it outside the loop | |
+ //so we don't have to check inside the loop. | |
+ while (i<dstW) { | |
+ dst[i] = filter_once(filterSize, filter, filterMask, rowSrcA, rowSrcB);; | |
+ filter +=filterSize; | |
+ i++; | |
+ srcCounterNext = filterPos[i]; | |
+ PLD_NEXT(filterPos+i); | |
+ } | |
+ | |
+} | |
+ | |
+extern void hScale8To15_c(SwsContext *c, int16_t *dst, int dstW, | |
+ const uint8_t *src, const int16_t *filter, | |
+ const int32_t *filterPos, int filterSize); | |
+ | |
+static void hScale8To15_arm(SwsContext *c, int16_t *dst, int dstW, | |
+ const uint8_t *src, const int16_t *filter, | |
+ const int32_t *filterPos, int filterSize) | |
+{ | |
+ if (filterSize == 6) | |
+ hScale8To15_arm_template(c, dst, dstW, src, filter, filterPos, 6, 1); | |
+ else if (filterSize == 8) | |
+ hScale8To15_arm_template(c, dst, dstW, src, filter, filterPos, 8, 1); | |
+ else if (filterSize == 9) | |
+ hScale8To15_arm_template(c, dst, dstW, src, filter, filterPos, 9, 2); | |
+ else { | |
+ hScale8To15_c(c, dst, dstW, src, filter, filterPos, filterSize); | |
+ if(hsfirst) { | |
+ fprintf(stderr, "filtersize not supported by hScale8To15_arm! (%d)\n",filterSize); | |
+ hsfirst = 0; | |
+ } | |
+ return; | |
+ } | |
+ if(hsfirst) { | |
+ fprintf(stderr, "filtersize supported by hScale8To15_arm! (%d)\n",filterSize); | |
+ hsfirst = 0; | |
+ } | |
+} | |
+ | |
+static inline void yuv2planeX_8_arm_template(const int16_t *filter, int filterSize, | |
+ const int16_t **src, uint8_t *dest, int dstW, | |
+ const uint8_t *dither, int offset) | |
+{ | |
+ int i; | |
+ | |
+ int32x4_t valsA, valsB; | |
+ | |
+ int16x4_t destA_t, destB_t; | |
+ int16x8_t dest_t; | |
+ uint8x8_t destVec; | |
+ int32x4_t ditherA, ditherB; | |
+ int16x4_t srcLoader; | |
+ int16x4_t filterVecA, filterVecB, filterVecC; | |
+ | |
+ ditherA=vdupq_n_u32(0); | |
+ ditherB=vdupq_n_u32(0); | |
+ ditherA=vsetq_lane_s16(dither[(offset + 0) & 7] << 12,ditherA,0); | |
+ ditherA=vsetq_lane_s16(dither[(offset + 1) & 7] << 12,ditherA,1); | |
+ ditherA=vsetq_lane_s16(dither[(offset + 2) & 7] << 12,ditherA,2); | |
+ ditherA=vsetq_lane_s16(dither[(offset + 3) & 7] << 12,ditherA,3); | |
+ ditherB=vsetq_lane_s16(dither[(offset + 4) & 7] << 12,ditherB,0); | |
+ ditherB=vsetq_lane_s16(dither[(offset + 5) & 7] << 12,ditherB,1); | |
+ ditherB=vsetq_lane_s16(dither[(offset + 6) & 7] << 12,ditherB,2); | |
+ ditherB=vsetq_lane_s16(dither[(offset + 7) & 7] << 12,ditherB,3); | |
+ | |
+ filterVecA = vld1_s16(filter); | |
+ if (filterSize > 4) | |
+ filterVecB = vld1_s16(filter+4); | |
+ if (filterSize > 8) | |
+ filterVecC = vld1_s16(filter+8); | |
+ | |
+ if (filterSize < 12) | |
+ filterVecC=vset_lane_s16(0,filterVecC,3); | |
+ if (filterSize < 11) | |
+ filterVecC=vset_lane_s16(0,filterVecC,2); | |
+ if (filterSize < 10) | |
+ filterVecC=vset_lane_s16(0,filterVecC,1); | |
+ if (filterSize < 9) | |
+ filterVecC=vset_lane_s16(0,filterVecC,0); | |
+ if (filterSize < 8) | |
+ filterVecB=vset_lane_s16(0,filterVecB,3); | |
+ if (filterSize < 7) | |
+ filterVecB=vset_lane_s16(0,filterVecB,2); | |
+ if (filterSize < 6) | |
+ filterVecB=vset_lane_s16(0,filterVecB,1); | |
+ if (filterSize < 5) | |
+ filterVecB=vset_lane_s16(0,filterVecB,0); | |
+ if (filterSize < 4) | |
+ filterVecA=vset_lane_s16(0,filterVecA,3); | |
+ if (filterSize < 3) | |
+ filterVecA=vset_lane_s16(0,filterVecA,2); | |
+ if (filterSize < 2) | |
+ filterVecA=vset_lane_s16(0,filterVecA,1); | |
+ | |
+ for (i=0; i<dstW; i+=8) { | |
+ valsA = ditherA; | |
+ valsB = ditherB; | |
+ | |
+ srcLoader=vld1_s16(src[0]+i); | |
+ valsA = vmlal_lane_s16(valsA, srcLoader, filterVecA, 0); | |
+ srcLoader=vld1_s16(src[0]+i+4); | |
+ valsB = vmlal_lane_s16(valsB, srcLoader, filterVecA, 0); | |
+ PLD_NEXT(src[0]+i); | |
+ if (filterSize > 1) { | |
+ srcLoader=vld1_s16(src[1]+i); | |
+ valsA = vmlal_lane_s16(valsA, srcLoader, filterVecA, 1); | |
+ srcLoader=vld1_s16(src[1]+i+4); | |
+ valsB = vmlal_lane_s16(valsB, srcLoader, filterVecA, 1); | |
+ PLD_NEXT(src[1]+i); | |
+ } | |
+ if (filterSize > 2) { | |
+ srcLoader=vld1_s16(src[2]+i); | |
+ valsA = vmlal_lane_s16(valsA, srcLoader, filterVecA, 2); | |
+ srcLoader=vld1_s16(src[2]+i+4); | |
+ valsB = vmlal_lane_s16(valsB, srcLoader, filterVecA, 2); | |
+ PLD_NEXT(src[2]+i); | |
+ } | |
+ if (filterSize > 3) { | |
+ srcLoader=vld1_s16(src[3]+i); | |
+ valsA = vmlal_lane_s16(valsA, srcLoader, filterVecA, 3); | |
+ srcLoader=vld1_s16(src[3]+i+4); | |
+ valsB = vmlal_lane_s16(valsB, srcLoader, filterVecA, 3); | |
+ PLD_NEXT(src[3]+i); | |
+ } | |
+ if (filterSize > 4) { | |
+ srcLoader=vld1_s16(src[4]+i); | |
+ valsA = vmlal_lane_s16(valsA, srcLoader, filterVecB, 0); | |
+ srcLoader=vld1_s16(src[4]+i+4); | |
+ valsB = vmlal_lane_s16(valsB, srcLoader, filterVecB, 0); | |
+ PLD_NEXT(src[4]+i); | |
+ } | |
+ if (filterSize > 5) { | |
+ srcLoader=vld1_s16(src[5]+i); | |
+ valsA = vmlal_lane_s16(valsA, srcLoader, filterVecB, 1); | |
+ srcLoader=vld1_s16(src[5]+i+4); | |
+ valsB = vmlal_lane_s16(valsB, srcLoader, filterVecB, 1); | |
+ PLD_NEXT(src[5]+i); | |
+ } | |
+ if (filterSize > 6) { | |
+ srcLoader=vld1_s16(src[6]+i); | |
+ valsA = vmlal_lane_s16(valsA, srcLoader, filterVecB, 2); | |
+ srcLoader=vld1_s16(src[6]+i+4); | |
+ valsB = vmlal_lane_s16(valsB, srcLoader, filterVecB, 2); | |
+ PLD_NEXT(src[6]+i); | |
+ } | |
+ if (filterSize > 7) { | |
+ srcLoader=vld1_s16(src[7]+i); | |
+ valsA = vmlal_lane_s16(valsA, srcLoader, filterVecB, 3); | |
+ srcLoader=vld1_s16(src[7]+i+4); | |
+ valsB = vmlal_lane_s16(valsB, srcLoader, filterVecB, 3); | |
+ PLD_NEXT(src[7]+i); | |
+ } | |
+ if (filterSize > 8) { | |
+ srcLoader=vld1_s16(src[8]+i); | |
+ valsA = vmlal_lane_s16(valsA, srcLoader, filterVecC, 0); | |
+ srcLoader=vld1_s16(src[8]+i+4); | |
+ valsB = vmlal_lane_s16(valsB, srcLoader, filterVecC, 0); | |
+ PLD_NEXT(src[8]+i); | |
+ } | |
+ if (filterSize > 9) { | |
+ srcLoader=vld1_s16(src[9]+i); | |
+ valsA = vmlal_lane_s16(valsA, srcLoader, filterVecC, 1); | |
+ srcLoader=vld1_s16(src[9]+i+4); | |
+ valsB = vmlal_lane_s16(valsB, srcLoader, filterVecC, 1); | |
+ PLD_NEXT(src[9]+i); | |
+ } | |
+ if (filterSize > 10) { | |
+ srcLoader=vld1_s16(src[10]+i); | |
+ valsA = vmlal_lane_s16(valsA, srcLoader, filterVecC, 2); | |
+ srcLoader=vld1_s16(src[10]+i+4); | |
+ valsB = vmlal_lane_s16(valsB, srcLoader, filterVecC, 2); | |
+ PLD_NEXT(src[10]+i); | |
+ } | |
+ if (filterSize > 11) { | |
+ srcLoader=vld1_s16(src[11]+i); | |
+ valsA = vmlal_lane_s16(valsA, srcLoader, filterVecC, 3); | |
+ srcLoader=vld1_s16(src[11]+i+4); | |
+ valsB = vmlal_lane_s16(valsB, srcLoader, filterVecC, 3); | |
+ PLD_NEXT(src[11]+i); | |
+ } | |
+ | |
+ valsA=vshrq_n_s32(valsA,16); | |
+ valsB=vshrq_n_s32(valsB,16); | |
+ | |
+ destA_t = vshrn_n_s32(valsA, 3); | |
+ destB_t = vshrn_n_s32(valsB, 3); | |
+ dest_t = vcombine_s16(destA_t,destB_t); | |
+ destVec = vqmovun_s16(dest_t); | |
+ vst1_u8(dest+i, destVec); | |
+ } | |
+} | |
+ | |
+extern void yuv2planeX_8_c(const int16_t *filter, int filterSize, | |
+ const int16_t **src, uint8_t *dest, int dstW, | |
+ const uint8_t *dither, int offset); | |
+ | |
+static void yuv2planeX_8_arm(const int16_t *filter, int filterSize, | |
+ const int16_t **src, uint8_t *dest, int dstW, | |
+ const uint8_t *dither, int offset) | |
+{ | |
+ if (filterSize==1) | |
+ yuv2planeX_8_arm_template(filter, 1, src, dest, dstW, dither, offset); | |
+ else if (filterSize==2) | |
+ yuv2planeX_8_arm_template(filter, 2, src, dest, dstW, dither, offset); | |
+ else if (filterSize==3) | |
+ yuv2planeX_8_arm_template(filter, 3, src, dest, dstW, dither, offset); | |
+ else if (filterSize==4) | |
+ yuv2planeX_8_arm_template(filter, 4, src, dest, dstW, dither, offset); | |
+ else if (filterSize==5) | |
+ yuv2planeX_8_arm_template(filter, 5, src, dest, dstW, dither, offset); | |
+ else if (filterSize==6) | |
+ yuv2planeX_8_arm_template(filter, 6, src, dest, dstW, dither, offset); | |
+ else if (filterSize==7) | |
+ yuv2planeX_8_arm_template(filter, 7, src, dest, dstW, dither, offset); | |
+ else if (filterSize==8) | |
+ yuv2planeX_8_arm_template(filter, 8, src, dest, dstW, dither, offset); | |
+ else if (filterSize==9) | |
+ yuv2planeX_8_arm_template(filter, 9, src, dest, dstW, dither, offset); | |
+ else if (filterSize==10) | |
+ yuv2planeX_8_arm_template(filter, 10, src, dest, dstW, dither, offset); | |
+ else if (filterSize==11) | |
+ yuv2planeX_8_arm_template(filter, 11, src, dest, dstW, dither, offset); | |
+ else if (filterSize==12) | |
+ yuv2planeX_8_arm_template(filter, 12, src, dest, dstW, dither, offset); | |
+ else { | |
+ yuv2planeX_8_c(filter, filterSize, src, dest, dstW, dither, offset); | |
+ if(ypfirst) { | |
+ fprintf(stderr, "filtersize not supported in yuv2planeX_8_arm! (%d)\n",filterSize); | |
+ ypfirst = 0; | |
+ } | |
+ return; | |
+ } | |
+ if(ypfirst) { | |
+ fprintf(stderr, "filtersize supported in yuv2planeX_8_arm! (%d)\n",filterSize); | |
+ ypfirst = 0; | |
+ } | |
+} | |
+ | |
+av_cold void ff_sws_init_swscale_arm(SwsContext *c) | |
+{ | |
+ if ((c->srcBpc == 8) && (c->dstBpc <= 14)) { | |
+ c->hyScale = c->hcScale = hScale8To15_arm; | |
+ } | |
+ fprintf(stderr, "Not using hScale8To15_arm c->srcBpc: %d, c->dstBpc:%d\n", c->srcBpc, c->dstBpc); | |
+} | |
+ | |
+void ff_sws_init_output_funcs_arm(SwsContext *c, | |
+ yuv2planarX_fn *yuv2planeX) | |
+{ | |
+ enum AVPixelFormat dstFormat = c->dstFormat; | |
+ | |
+ if (is16BPS(dstFormat)) { | |
+ fprintf(stderr, "Not using yuv2planeX_8_arm is16BPS \n"); | |
+ } else if (is9_OR_10BPS(dstFormat)) { | |
+ fprintf(stderr, "Not using yuv2planeX_8_arm is9_OR_10BPS \n"); | |
+ } else { | |
+ *yuv2planeX=yuv2planeX_8_arm; | |
+ } | |
+} | |
diff --git a/libswscale/output.c b/libswscale/output.c | |
index 6048e2bbd7..b88471f0b3 100644 | |
--- a/libswscale/output.c | |
+++ b/libswscale/output.c | |
@@ -36,6 +36,8 @@ | |
#include "swscale.h" | |
#include "swscale_internal.h" | |
+#include "synoconfig.h" | |
+ | |
DECLARE_ALIGNED(8, const uint8_t, ff_dither_2x2_4)[][8] = { | |
{ 1, 3, 1, 3, 1, 3, 1, 3, }, | |
{ 2, 0, 2, 0, 2, 0, 2, 0, }, | |
@@ -250,7 +252,15 @@ yuv2NBPS(14, LE, 0, 10, int16_t) | |
yuv2NBPS(16, BE, 1, 16, int32_t) | |
yuv2NBPS(16, LE, 0, 16, int32_t) | |
+#if defined(SYNO_ALPINE_NEON_LIBSWSCALE) | |
+void yuv2planeX_8_c(const int16_t *filter, int filterSize, | |
+ const int16_t **src, uint8_t *dest, int dstW, | |
+ const uint8_t *dither, int offset); | |
+ | |
+void yuv2planeX_8_c(const int16_t *filter, int filterSize, | |
+#else | |
static void yuv2planeX_8_c(const int16_t *filter, int filterSize, | |
+#endif | |
const int16_t **src, uint8_t *dest, int dstW, | |
const uint8_t *dither, int offset) | |
{ | |
diff --git a/libswscale/swscale.c b/libswscale/swscale.c | |
index 5312016927..54b97572d4 100644 | |
--- a/libswscale/swscale.c | |
+++ b/libswscale/swscale.c | |
@@ -36,6 +36,8 @@ | |
#include "swscale_internal.h" | |
#include "swscale.h" | |
+#include "synoconfig.h" | |
+ | |
DECLARE_ALIGNED(8, const uint8_t, ff_dither_8x8_128)[9][8] = { | |
{ 36, 68, 60, 92, 34, 66, 58, 90, }, | |
{ 100, 4, 124, 28, 98, 2, 122, 26, }, | |
@@ -132,7 +134,15 @@ static void hScale16To15_c(SwsContext *c, int16_t *dst, int dstW, | |
} | |
// bilinear / bicubic scaling | |
+#if defined(SYNO_ALPINE_NEON_LIBSWSCALE) | |
+void hScale8To15_c(SwsContext *c, int16_t *dst, int dstW, | |
+ const uint8_t *src, const int16_t *filter, | |
+ const int32_t *filterPos, int filterSize); | |
+ | |
+void hScale8To15_c(SwsContext *c, int16_t *dst, int dstW, | |
+#else | |
static void hScale8To15_c(SwsContext *c, int16_t *dst, int dstW, | |
+#endif | |
const uint8_t *src, const int16_t *filter, | |
const int32_t *filterPos, int filterSize) | |
{ | |
@@ -556,6 +566,10 @@ static int swscale(SwsContext *c, const uint8_t *src[], | |
* this array's tail */ | |
ff_sws_init_output_funcs(c, &yuv2plane1, &yuv2planeX, &yuv2nv12cX, | |
&yuv2packed1, &yuv2packed2, &yuv2packedX, &yuv2anyX); | |
+#if defined(SYNO_ALPINE_NEON_LIBSWSCALE) | |
+ if (ARCH_ARM) /* Should add check for neon existence */ | |
+ ff_sws_init_output_funcs_arm(c, &yuv2planeX); | |
+#endif | |
use_mmx_vfilter= 0; | |
} | |
@@ -729,6 +743,10 @@ static av_cold void sws_init_swscale(SwsContext *c) | |
&c->yuv2nv12cX, &c->yuv2packed1, | |
&c->yuv2packed2, &c->yuv2packedX, &c->yuv2anyX); | |
+#if defined(SYNO_ALPINE_NEON_LIBSWSCALE) | |
+ if (ARCH_ARM) /* Should add check for neon existence */ | |
+ ff_sws_init_output_funcs_arm(c, &c->yuv2planeX); | |
+#endif | |
ff_sws_init_input_funcs(c); | |
@@ -762,6 +780,10 @@ SwsFunc ff_getSwsFunc(SwsContext *c) | |
ff_sws_init_swscale_ppc(c); | |
if (ARCH_X86) | |
ff_sws_init_swscale_x86(c); | |
+#if defined(SYNO_ALPINE_NEON_LIBSWSCALE) | |
+ if (ARCH_ARM) /* Should add check for neon existence */ | |
+ ff_sws_init_swscale_arm(c); | |
+#endif | |
return swscale; | |
} | |
diff --git a/libswscale/swscale_internal.h b/libswscale/swscale_internal.h | |
index 2299aa5c87..84e11ebd0d 100644 | |
--- a/libswscale/swscale_internal.h | |
+++ b/libswscale/swscale_internal.h | |
@@ -37,6 +37,8 @@ | |
#include "libavutil/pixfmt.h" | |
#include "libavutil/pixdesc.h" | |
+#include "synoconfig.h" | |
+ | |
#define STR(s) AV_TOSTRING(s) // AV_STRINGIFY is too long | |
#define YUVRGB_TABLE_HEADROOM 256 | |
@@ -870,6 +872,11 @@ void ff_sws_init_output_funcs(SwsContext *c, | |
yuv2packed2_fn *yuv2packed2, | |
yuv2packedX_fn *yuv2packedX, | |
yuv2anyX_fn *yuv2anyX); | |
+#if defined(SYNO_ALPINE_NEON_LIBSWSCALE) | |
+void ff_sws_init_output_funcs_arm(SwsContext *c, | |
+ yuv2planarX_fn *yuv2planeX); | |
+void ff_sws_init_swscale_arm(SwsContext *c); | |
+#endif | |
void ff_sws_init_swscale_ppc(SwsContext *c); | |
void ff_sws_init_swscale_x86(SwsContext *c); | |
diff --git a/synoconfig.h b/synoconfig.h | |
new file mode 100644 | |
index 0000000000..f6fba53cd7 | |
--- /dev/null | |
+++ b/synoconfig.h | |
@@ -0,0 +1,190 @@ | |
+#ifndef MY_ABC_HERE | |
+#define MY_ABC_HERE | |
+#endif | |
+/* Fixed core dump when truncate recording in QORIQ platform | |
+ * See Surveillance bug 1151/1155 | |
+ */ | |
+#define SYNO_FIX_QORIQ_CORE_DUMP | |
+ | |
+/* Add ffmpeg option for smooth streaming. | |
+ * -fragment_url: | |
+ * This option can overwrite fragment url in Manifest for smooth streaming. | |
+ * -fragment_length: | |
+ * Let file name of output fragment mp4 with this duration | |
+ * This setting dependes on x264 option to make it work | |
+ * -seek_time: | |
+ * Let file name fo output fragment mp4 start with this seek time | |
+ * See Video Station #659 | |
+ */ | |
+#define SYNO_SMOOTH_STREAMING | |
+ | |
+/* Fixed h264_parser error in special MP4 remux | |
+ * some MP4 file could parser error with remain PPS information | |
+ * See Video Station #944 | |
+ */ | |
+#define SYNO_FIX_MP4_REMUX_H264PARSER | |
+ | |
+/* filter out some tag that not needed | |
+ * those tags producted at *.ass convert *.srt | |
+ * See Video Station #1031 | |
+ */ | |
+#define SYNO_FILTER_SRT_TAGS | |
+ | |
+/* skip parse_picture in flacdec.c | |
+ * to avoid gapless playback fails when flac has big embedded cover | |
+ * See Audio Station #1013 | |
+ */ | |
+#define SYNO_SKIP_FLAC_PARSE_PICTURE | |
+ | |
+/* add SynoCodecPantent mechanism | |
+ * h264, mpe4part2, aac , vc1 enc/dec should actived at the first time. | |
+ * See Video Station #1291 | |
+ */ | |
+#if defined(SYNO_VIDEOSTATION) || defined(SYNO_AUDIOSTATION) || defined(SYNO_MEDIASERVER) || defined(MY_DEF_HERE) | |
+#define SYNO_CODEC_PATENT_G1 | |
+#endif | |
+ | |
+/* let ffmpeg skip audio stream with disabled codec. | |
+ * e.g. DTS dec/enc ,AC3 enc | |
+ */ | |
+#if !defined(STANDALONE) && !defined(SYNO_VIDEOSTATION) && !defined(SYNO_MEDIASERVER) | |
+#define SYNO_SKIP_DISABLED_AUDIO_STREAM | |
+#endif | |
+ | |
+/* Optional for writing RIFF info tag to wav | |
+ * See Media Server #386 | |
+ */ | |
+#define SYNO_WRITE_RIFF_INFO_TAG_TO_WAV | |
+ | |
+/* Fixed aac copy failed on mpegts format. | |
+ * See Video Station #1730 | |
+ */ | |
+#define SYNO_MPEGTS_FORAMT_AAC_COPY_FAILED | |
+ | |
+/* Add ffmpeg option for HLS. | |
+ * -hls_seek_time: | |
+ * Let output fragment ts start with this seek time | |
+ * See Video Station #1758 | |
+ */ | |
+#if defined(SYNO_VIDEOSTATION) | |
+#define SYNO_VIDEOSTATION_HLS_SEEK_TIME | |
+#endif | |
+ | |
+/* Add ffmpeg option for h264 remux. | |
+ * -vbsf h264_mp4toannexb=repeatheader: | |
+ * Make output h264 stream contains SPS/PPS before every IDR Slice | |
+ * See Video Station #3545 | |
+ */ | |
+#if defined(SYNO_VIDEOSTATION) | |
+#define SYNO_VIDEOSTATION_REMUX_REPEAT_HEADER | |
+#endif | |
+ | |
+/* Use neon acceleration in libswscale, which boosts transcoding | |
+ * performance on Alpine platform. | |
+ * The patch is provided by AnnapurnaLabs. | |
+ * See Video Station #1858 | |
+ */ | |
+#if defined(SYNO_PLAT_NEON_LIBSWSCALE) | |
+#define SYNO_ALPINE_NEON_LIBSWSCALE | |
+#endif | |
+ | |
+/* Add ffmpeg option for WEBM. | |
+ * -webm_seek_time: | |
+ * Let output stream with the seek time | |
+ * See Video Station #2170 | |
+ */ | |
+#if defined(SYNO_VIDEOSTATION) | |
+#define SYNO_VIDEOSTATION_WEBM_SEEK_TIME | |
+#endif | |
+ | |
+/* Add hardward codec (smd) only on evansport platform | |
+ * See Video Station #1065, DSM #50422 | |
+ */ | |
+#if defined(MY_DEF_HERE) | |
+#define SYNO_EVANSPORT_SMD | |
+#endif | |
+ | |
+/* on Evansport, default always using software decoder. | |
+ * add new flag "-prefer_smd" can auto using hardware decoder. | |
+ * See Video Station #1234, DSM #50422 | |
+ */ | |
+#if defined(SYNO_EVANSPORT_SMD) | |
+#define SYNO_EVANSPORT_AUTO_HW_DECODER | |
+#endif | |
+ | |
+/* smooth streaming enable hardware transcoding on Evansport. | |
+ * fixed video not sync with subtitile. | |
+ * See Video Station #1244 | |
+ */ | |
+#if defined(SYNO_EVANSPORT_SMD) | |
+#define SYNO_EVANSPORT_SMOOTH_STREAMING_TIMESTAMP_INACCURATE | |
+#endif | |
+ | |
+/* Fixed DTV recoded file or DTV streaming A/V issue on Evansport. | |
+ * add flag "-dtv_smd" is used other way to calculate timestamp. | |
+ * in hardware pipeline mode. | |
+ * See Video Station #1652, #1716 | |
+ */ | |
+#if defined(SYNO_EVANSPORT_SMD) | |
+#define SYNO_EVANSPORT_DTV_SMD_AVSYNC | |
+#endif | |
+ | |
+/* Fixed mp4 can't hardwared trasncode that encoded by Handbrake. | |
+ * auto enable -dtv_smd flag when detecting Handbrake encoded file. | |
+ * See Video Station #1513 | |
+ */ | |
+#if defined(SYNO_EVANSPORT_SMD) && defined(SYNO_EVANSPORT_DTV_SMD_AVSYNC) | |
+#define SYNO_EVANSPORT_HANDBRAKE_MP4 | |
+#endif | |
+ | |
+/* Fixed evansport coredump transcode to flv on pipeline mode | |
+ * See Video Station #2132 | |
+ */ | |
+#if defined(SYNO_EVANSPORT_SMD) | |
+#define SYNO_EVANSPORT_FLV_EXTRADATA | |
+#endif | |
+ | |
+/* Add ffserver config option to support multiple audio track. | |
+ * See Video Station #2245 | |
+ */ | |
+#if defined(SYNO_VIDEOSTATION) | |
+#define SYNO_FFSERVER_MULTIPLE_AUDIO_TRACK | |
+#endif | |
+ | |
+/* Add skip unknown track config to support dtv streaming with unknown codec track. | |
+ * add flag "-dtv_skip_unknown" to skip unknown tracks. | |
+ * See Video Station #2470 | |
+ */ | |
+#if defined(SYNO_VIDEOSTATION) | |
+#define SYNO_DTV_SKIP_UNKNOWN_TRACK | |
+#endif | |
+ | |
+/* Add skip visual impaired track config to support dtv streaming with visual impaired track. | |
+ * add flag "-dtv_skip_visual_impaired" to skip visual impaired tracks. | |
+ * See Video Station #2525 | |
+ */ | |
+#if defined(SYNO_VIDEOSTATION) | |
+#define SYNO_DTV_SKIP_VISUAL_IMPAIRED_TRACK | |
+#endif | |
+ | |
+/* Skip subtitle streams in teletext codec to avoid the abort casued by non monotonically increasing dts. | |
+ * add flag "-dtv_skip_teletext" to skip subtitle streams in teletext codec. | |
+ * See Video Station #3925 | |
+ */ | |
+#if defined(SYNO_VIDEOSTATION) | |
+#define SYNO_DTV_SKIP_TELETEXT | |
+#endif | |
+ | |
+/* Add patch to fix mpegts dvbsub encoding | |
+ * https://trac.ffmpeg.org/ticket/2024 | |
+ * https://github.com/FFmpeg/FFmpeg/commit/c917cde9cc52ad1ca89926a617f847bc9861d5a0add | |
+ * See Video Station #2500 | |
+ */ | |
+#if defined(SYNO_VIDEOSTATION) | |
+#define SYNO_DTV_MPEGTS_DVBSUB_ENCODING | |
+#endif | |
+ | |
+/* Fixed CVE-2017-9993 | |
+ * See DSM #102750 | |
+ */ | |
+#define SYNO_FIX_CVE_2017_9993 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment