J'essaie d'encoder une vidéo .mp4 à partir d'un ensemble d'images en utilisant FFMPEG en utilisant le codec libx264.
Voici la commande que j'exécute:
/usr/local/bin/ffmpeg -r 24 -i frame_%05d.jpg -vcodec libx264 -y -an video.mp4
J'obtiens parfois l'erreur suivante:
[libx264 @ 0xa3b85a0] height not divisible by 2 (520x369)
Après quelques recherches, il semble que le problème ait quelque chose à voir avec l'algorithme de mise à l'échelle et peut être résolu en ajoutant un argument -vf.
Cependant, dans mon cas, je ne veux pas faire de mise à l'échelle. Idéalement, je veux garder les dimensions exactement les mêmes que les cadres. Aucun conseil? Existe-t-il une sorte de rapport hauteur / largeur que h264 applique?
-vf pad="width=ceil(iw/2)*2:height=ceil(ih/2)*2"
, qui n'est même pas l'une des réponses. La bonne réponse à la question de tout le monde est celle de LordNeckbeard."scale="
place de"pad="
s'il / elle ne veut pas de pixels de remplissage colorés?Réponses:
La réponse à la question d'origine qui ne souhaite pas mettre à l'échelle la vidéo est:
Commander:
Fondamentalement, .h264 a besoin de dimensions égales, donc ce filtre:
Vous pouvez changer la couleur du remplissage en ajoutant un paramètre de filtre
:color=white
. Voir la documentation de pad .la source
-vf pad="width=iw:height=ih+1:x=0:y=0:color=white"
. La documentation du pad ffmpeg est ici: ffmpeg.org/ffmpeg-filters.html#pad-1 .-vf pad="width=ceil(iw/2)*2:height=ceil(ih/2)*2"
.Juste utiliser
-2
À partir de la documentation du filtre de balance :
Exemples
Définissez la largeur sur 1280, et la hauteur sera automatiquement calculée pour conserver le rapport hauteur / largeur, et la hauteur sera divisible par 2:
Identique à ci-dessus, mais avec une hauteur déclarée à la place; laissant la largeur à traiter par le filtre:
"divisible par 2"
Comme requis par x264, le "divisible par 2 pour la largeur et la hauteur" est nécessaire pour les sorties sous-échantillonnées de chrominance YUV 4: 2: 0. 4: 2: 2 aurait besoin de "divisible par 2 pour la largeur", et 4: 4: 4 n'a pas ces restrictions. Cependant, la plupart des lecteurs non basés sur FFmpeg ne peuvent décoder correctement que 4: 2: 0, c'est pourquoi vous voyez souvent des
ffmpeg
commandes avec l'-pix_fmt yuv420p
option lors de la sortie de vidéo H.264.Caveat
Malheureusement, vous ne pouvez pas utiliser
-2
à la fois la largeur et la hauteur, mais si vous avez déjà spécifié une dimension, l'utilisation-2
est une solution simple.la source
-vf scale=-2:-2
ne marche pas? Dans mon cas, je souhaite conserver autant que possible la taille du fichier d'origine. Ce qui a fonctionné pour moi était-vf scale=-2:ih
. Mais cela ne fonctionne pas si les deux h / w sont inégaux.-2
dépend de la valeur déclarée de l'autre dimension.Size values less than -1 are not acceptable.
mais la réponse de @Zbyszek a parfaitement fonctionné.ffmpeg
. Vous pouvez télécharger une version statique .Si vous souhaitez définir une largeur de sortie et obtenir une sortie avec le même rapport que l'original
et pour ne pas tomber avec ce problème, vous pouvez utiliser
(Juste pour les personnes qui cherchent comment faire cela avec la mise à l'échelle)
la source
scale="trunc(oh*a/2)*2:720"
Le problème avec les
scale
solutions ici est qu'elles déforment l'image / la vidéo source, ce qui n'est presque jamais ce que vous voulez.Au lieu de cela, j'ai trouvé que la meilleure solution consiste à ajouter un tampon de 1 pixel à la dimension impaire. (Par défaut, le rembourrage est noir et difficile à remarquer.)
Le problème avec les autres
pad
solutions est qu'elles ne se généralisent pas sur des dimensions arbitraires car elles bourrent toujours.Cette solution n'ajoute un pad de 1 pixel à la hauteur et / ou à la largeur que s'ils sont impairs:
C'est idéal car il fait toujours ce qu'il faut, même si aucun rembourrage n'est nécessaire.
la source
scale=iw+mod(iw,2):ih+mod(ih,2):flags=neighbor
. Cela ne peut augmenter chaque dimension que de 1, si nécessaire, et dupliquera la dernière ligne / colonne.Cela est probablement dû au fait que la vidéo H264 est généralement convertie de l'espace RVB en espace YUV au format 4: 2: 0 avant d'appliquer la compression (bien que la conversion de format elle-même soit un algorithme de compression avec perte entraînant une économie d'espace de 50%).
Le YUV-420 commence par une image RVB (rouge vert bleu) et la convertit en YUV (essentiellement un canal d'intensité et deux canaux "teinte"). Les canaux Hue sont ensuite sous-échantillonnés en créant un échantillon de teinte pour chaque carré 2X2 de cette teinte.
Si vous avez un nombre impair de pixels RVB horizontalement ou verticalement, vous aurez des données incomplètes pour la dernière colonne ou ligne de pixels dans l'espace de teinte sous-échantillonné du cadre YUV.
la source
LordNeckbeard a la bonne réponse, très vite
Pour Android, n'oubliez pas d'ajouter
la source
--disable-asm
dans son script de construction x264 . Cela entraîne une lenteur inutile et significative (vous pouvez vérifier le journal ffmpeg et s'il apparaît,using cpu capabilties: none!
c'est mauvais). Je ne sais pas pourquoi ils ont ajouté cela, mais je ne suis pas un développeur Android.Vous pouvez également utiliser la
bitand
fonction au lieu detrunc
:bitand (x, 65534)
fera la même chose
trunc(x/2)*2
et il est plus transparent à mon avis.(Considérez 65534 comme un nombre magique ici;))
Ma tâche consistait à mettre automatiquement à l'échelle un grand nombre de fichiers vidéo en demi-résolution .
scale=-2,ih/2
conduisent à des images légèrement flouesraison:
scale
met à l'échelle les dimensions réelles du cadreSolution:
explication:
setsar=1
signifie que output_dimensions est désormais définitif, aucune correction de rapport hauteur / largeur ne doit être appliquéeQuelqu'un pourrait trouver cela utile.
la source