[FFmpeg-user] Calculating output dimensions to avoid conflicting stream par values in Adaptation Set
Richard Hristov
richardhristov at gmail.com
Tue Feb 2 11:11:07 EET 2021
Hello, I'm working on a service which handles transcoding user generated
videos in order to host them as VODs on the web.
The service uses ffmpeg to transcode the videos and I have recently been
working on adding dash/hls support to enable the videos to start up
faster and handle multiple bandwidth situations. ffmpeg's dash output
format with hls enabled seems to work well enough for this purpose,
however I have ran into an issue for which I can't figure out a fix.
The input videos have a wide range of formats and dimensions, which
causes trouble when using multiple inputs at different dimensions. I
currently prepare my input streams by fixing their smaller dimension to
a certain size and letting the other one be auto generated to preserve
aspect ratio using the scale filter, like so: -filter:v "scale=-2:720";
This is done for multiple "targets" such as 1080p, 480p etc.
If the video is using an aspect ratio of 16/9, this works fine. However,
certain aspect ratios will cause the dash command to fail with the error
"Conflicting stream par values in Adaptation Set". For example, I've had
a user upload a video with the dimensions 1920x1012, this aspect ratio
is the fraction 227/253 and in this case ffmpeg's scale filter
calculated the following outputs: 684x360, 888x468, 1366x720. Since all
of these are a different fraction than the source, ffmpeg compensates by
setting the sar and dar to avoid distortion, however it will then fail
at the dash/hls stream generation step.
How would I go about fixing this issue for all input dimensions? Is it
possible to force ffmpeg to transcode to outputs which conform to the
same aspect ratio so that the dash/hls step doesn't fail?
Here are the ffmpeg commands which cause the issue:
ffmpeg -i "" -c:v libx264 -crf 23 -fs 1073741824 -preset faster
-maxrate:v 350k -bufsize:v 700k -filter:v "scale=-2:360" -map 0:v:0 -c:a
aac -b:a 128k -map 0:a:0 -dn -sn -y 1.mpd_360.mp4
ffmpeg -i "" -c:v libx264 -crf 23 -fs 1073741824 -preset faster
-maxrate:v 650k -bufsize:v 1300k -filter:v "scale=-2:468" -map 0:v:0
-c:a aac -b:a 128k -map 0:a:0 -dn -sn -y 1.mpd_468.mp4
ffmpeg -i "" -c:v libx264 -crf 23 -fs 1073741824 -preset faster
-maxrate:v 1300k -bufsize:v 2600k -filter:v "scale=-2:720" -map 0:v:0
-c:a aac -b:a 128k -map 0:a:0 -dn -sn -y 1.mpd_720.mp4
ffmpeg -sn -dn -i 1.mpd_360.mp4 -sn -dn -i 1.mpd_468.mp4 -sn -dn -i
1.mpd_720.mp4 -map 0 -map 1 -map 2 -c:a copy -c:v copy -use_timeline 1
-use_template 1 -adaptation_sets "id=0,streams=v id=1,streams=a"
-hls_playlist true -f dash -y 1.mpd
The input's dimensions are 1920x1012. The ffmpeg website has an example
command to generate a dash stream which does this all in a single
command but it will then be unable to handle variable bitrate and it
will write completely bogus bitrates to the dash and hls manifests, so I
used multiple commands instead and I generated the manifests after the
individual streams have finished transcoding.
Thanks for the help in advance
Richard Hristov
More information about the ffmpeg-user
mailing list