Synology FFmpeg Hardware Transcoding
Recently I needed to convert one of my H.265 4K videos to an H.264 MP4 file for playback on an older device. As the original video was already on the NAS, I thought about converting it right there using the DiskStations's CPU.
FFmpeg was installed on the NAS in two versions. One bundled with the VideoStation app. The other one I downloaded a while ago via the Package Center from the cytec repository. The second one enables transcoding of DTS audio tracks. These FFmpeg installations are intended for the live transcoding for playback in the web browser or the DS Video iOS and Android apps.
I ssh'd into the NAS and changed to the respective directory. I then started FFmpeg to start transcoding the video.
$ ffmpeg -i /volume1/video/test.mkv -codec:video libx264 -codec:audio copy /volume1/video/test.mp4
The transcoding generally works, but the abismal speed of way below 1 FPS kept this from beeing a viable solution.
I knew that most Synology DiskStations have a dedicated hardware de- and encoder for live video transcoding. So does mine. My DS 418's hardware transcoding chip supports up to 10-bit 4K 60 FPS H.265 live transcoding. I didn't know at the time but I later found it specifically means transcoding to H.264 or MPEG2. For my case that was enough.
The transcoding speed I saw was nowhere near those 60 FPS, so I figured the special transcoding unit wasn't used. I knew from browser playback in the VideoStation web app that hardware transcoding generally works, which means there has to be another tool which is used by the VideoStation transcoding engine.
So my search began. I went into the VideoStation's folder.
$ cd /var/packages/VideoStation/target/bin
Inside, there are a lot of tools.
$ ls -1A
cffmpeg
check_folder_conf
db_setup_handler
dtvstreamserver
dvblast
dvblastctl
ffmpeg
ffprobe
gst-inspect-1.0
gst-launch-1.0
gst-plugin-scanner
hdhomerun_config
hdhomerunscan
lsdvb
scan
synocodectool
synodtvd_ffmpeg_record
synodvbepg
syno-gst
synovideoconversion
synovideoindex
synovideopreprocess
synovideostation
synovideostation_update_conf
synovideostation_user_del
synovideosubtitleextraction
szap
szap-s2
tzap
video_hash
w_scan
First of all I tried the FFmpeg version lying there1.
$ sudo /var/packages/VideoStation/target/bin/ffmpeg -i /volume1/video/test.mkv -codec:video libx264 -codec:audio copy /volume1/video/test.mp4
[...]
Unknown encoder 'libx264'
In contrast to the FFmpeg version from the Package Center this one can't convert videos to the H.264 codec. I re-checked.
$ ffmpeg -encoders | grep h264
[ffmpeg version 2.7.1 ...]
V..... libx264 libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (codec h264)
V..... libx264rgb libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 RGB (codec h264)
$ sudo /var/packages/VideoStation/target/bin/ffmpeg -encoders | grep h264
[ffmpeg version 2.7.1 ...]
*Nothing*
Seems right. I was reinforced in my theory that there was a seperate tool which utilizes the hardware encoding. I tried some of the other tools in the same directory. I started with cffmpeg
.
$ /var/packages/VideoStation/target/bin/cffmpeg
usage:
cffmpeg [option]
-b number: broadcastPort
-o string: output file (*.m3u8 and *.ts) path
-p string: prefix *.ts file in *.m3u8
-P string: profile hd_high, hd_medium, hd_low, sd_high ...
-T number: number of Tuner
-h -? : display this help and exit
The profile parameter looked promising. When invocing synovideoconversion
I got a similar result.
$ sudo /var/packages/VideoStation/target/bin/synovideoconversion
/var/packages/VideoStation/target/bin/synovideoconversion -i [input file] -o [output file] -v [video profile: (original, high, medium, low)] -a [audio track: track id]-u [file owner: uid]
This was a great step in the right direction – I could convert video to H.264 using one of the profiles –, but I still didn't know what exactly those profiles mean. I'd prefer to choose the bitrate myself. And while I could choose an audio track, I could't convert it to a specific format using this command.
That's when I found a post by MrEricM in the Synology Forums mentioning syno-gst
which can also be found in the same folder as the other tools. Looking into it, it seems to be exactly the tool I was looking for.
$ /var/packages/VideoStation/target/bin/syno-gst -h
Usage: ./syno-gst [options...] -i <input> -o <output>
Usage: ./syno-gst [options...] -i <input> --info
-h, --help : show this help
-v, --verbose : show more information
-r, --report : print transcoding progress
[Argument Required]
-s, --seek : set seek time
-i, --input : set input file
-f, --format : set output format [mpegts|mpegps|mp4]
-o, --output : set output path [fd:<number>|<path>]
--vb : set output video bitrate (unit: bps)
--ab : set output audio bitrate (unit: bps)
--width : set output video width
--height : set output video height
--vcodec : set output video codec [h264|mpeg2]
--acodec : set output audio codec [mp3|aac|mp2|copy|none]
--aidx : set select audio index
--info : print basic information
--shiftpts : shift output pts by seek time (only for mpegts)
--inputfd : set input fd
--container : set container
[Example]
./syno-gst -v -i "/volume1/video/test.mp4" -s 300 -f mpegts --acodec mp3 -o /tmp/123.ts --width 1280 --height 720 --vb 1000000
./syno-gst -i "/volume1/video/test.mp4" --info
It supports converting videos to either H.264 or – for even older devices – MPEG2. I have the choice between several formats for the audio (including just copying it). I can choose the resolution and bitrate of the resulting video track as well as the audio bitrate.
So to converted the 4K HEVC test file to a 1080p H.264 MP4. I used the following command. The bitrates ought to be given in bytes. I added the -rv
parameter to get more info in general and especially the progress.
$ sudo /var/packages/VideoStation/target/bin/syno-gst -i "/volume1/video/test.mkv" -o "/volume1/video/test.mp4" -f mp4 --vcodec h264 --acodec none --vb 35000000 --width 1920 --height 1080 -rv
And voilà, the transcoding process worked at about 2x speed, which seems reasonable considering the hardware transcoder supports 4K 60 FPS live transcoding and my test file is a 4K 30 FPS video. I finally got the hardware transcoder to work!
It is important to note though that it only works one way. So sadly I can't use it to convert my older videos to the HEVC format using it. During my following tests I found out some other limitations and quirks.
Although I can enter in the desired width and height of the target video, the tool selects from one of a few presets which come close to the desired resolution. It is actually enough to provide either the height or the width parameter to make it choose between the presets. Those presets are the following:
xxxxxxxxxx
320 x 176 (why?)
848 x 464 (why?)
1280 x 720 (the only reasonable one)
1920 x 1072 (just, why?)
I really don't understand Synology's reasons for the chosen presets. The 720p one is obvious to me, but why there's no real 1080p option is a mystery to me. It's also interesting that the resulting H.264 video cannot be bigger than that, so no 4K as the export.
There is a video bitrate parameter (--vb
) which accepts vaulues in bits per second. The parameter doesn't seem to work in any way I'd expect though. While higher settings result in higher average bitrates, there's no direct correlation. I compiled a list of some values I tried and the resulting average bitrates of the exported video.
Input Output
500000000 = 500 Mbit/s 226 Mbit/s
400000000 = 400 Mbit/s 128 Mbit/s
250000000 = 250 Mbit/s 1.2 Mbit/s
25000000 = 25 Mbit/s 1.1 Mbit/s
2500000 = 2.5 Mbit/s 499 Kbit/s
300000 = 300 Kbit/s 170 Kbit/s
150000 = 150 Kbit/s 126 Kbit/s
Without providing the bitrate parameter, I get a warning that the value "0" of type 'guint' is invalid or out of range for property 'bitrate' of type 'guint'
and the conversion uses the minimum bitrate setting, resulting in an avg. bitrate of 115 Kbit/s. Same thing happens if I provide a value outside of the expected range. I don't know what the specific range is though.
I discovered another odd thing during my tests. While IINA plays the resulting file just fine, QuickTime has some problems resulting in a green screen after the initial frame, unless I skip to an arbitrary position in the video. After that everything plays fine.
I hope I could help someone who's having a similar problem.