Skip to content

Instantly share code, notes, and snippets.

@tmm1
Last active July 17, 2019 18:03
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save tmm1/280f11b9c252cec87167c4bd406b508c to your computer and use it in GitHub Desktop.
Save tmm1/280f11b9c252cec87167c4bd406b508c to your computer and use it in GitHub Desktop.
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