[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