Compare commits
50 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 083443d67c | |||
| 4f0e9457d6 | |||
| 9a4c7b937f | |||
| abaa747ee5 | |||
| 3736130e5b | |||
| e0dd533ad6 | |||
| 97751fda3e | |||
| 1ef084f910 | |||
| 839e8baa20 | |||
| d918d9afe0 | |||
| 4866aaf7c5 | |||
| 3b6732bcb3 | |||
| aeff85620a | |||
| fd8fb39af9 | |||
| 5cd6683ddc | |||
| 87e5bc918a | |||
| 8146cab801 | |||
| 5469ba6d74 | |||
| e37d66a72e | |||
| cbbe688434 | |||
| 8194f34b5d | |||
| 54a7f22ee8 | |||
| 003e006ccb | |||
| d4bb784274 | |||
| 1a9da17c5a | |||
| 7e899776ec | |||
| cc9d291fb0 | |||
| 7570390be6 | |||
| 74e4e900bb | |||
| 2d18c4906f | |||
| 4bb04c52fb | |||
| 112fdae9f9 | |||
| dcbc1fdb3b | |||
| efa0670048 | |||
| d0e5f83ffb | |||
| 2ecaef7455 | |||
| 8709604ca1 | |||
| 43fd3d5df6 | |||
| 4c5a809388 | |||
| 5ff5a431c7 | |||
| 7ed9ad3467 | |||
| 5a3b625dbc | |||
| 799a7200ee | |||
| 515949a15a | |||
| 7fa569e34d | |||
| 536443919f | |||
| da903c558b | |||
| 9cfb29baa2 | |||
| 304208d40c | |||
| 6ceda54629 |
@@ -24,5 +24,3 @@ rcombs <rcombs@rcombs.me> <rodger.combs@gmail.com>
|
||||
<lq@chinaffmpeg.org> <liuqi05@kuaishou.com>
|
||||
<ruiling.song83@gmail.com> <ruiling.song@intel.com>
|
||||
Cosmin Stejerean <cosmin@cosmin.at> Cosmin Stejerean via ffmpeg-devel <ffmpeg-devel@ffmpeg.org>
|
||||
<wutong1208@outlook.com> <tong1.wu-at-intel.com@ffmpeg.org>
|
||||
<wutong1208@outlook.com> <tong1.wu@intel.com>
|
||||
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
language: c
|
||||
sudo: false
|
||||
os:
|
||||
- linux
|
||||
- osx
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- nasm
|
||||
- diffutils
|
||||
compiler:
|
||||
- clang
|
||||
- gcc
|
||||
matrix:
|
||||
exclude:
|
||||
- os: osx
|
||||
compiler: gcc
|
||||
cache:
|
||||
directories:
|
||||
- ffmpeg-samples
|
||||
before_install:
|
||||
- if [ "$TRAVIS_OS_NAME" == "osx" ]; then brew update; fi
|
||||
install:
|
||||
- if [ "$TRAVIS_OS_NAME" == "osx" ]; then brew install nasm; fi
|
||||
script:
|
||||
- mkdir -p ffmpeg-samples
|
||||
- ./configure --samples=ffmpeg-samples --cc=$CC
|
||||
- make -j 8
|
||||
- make fate-rsync
|
||||
- make check -j 8
|
||||
@@ -1,34 +1,6 @@
|
||||
Entries are sorted chronologically from oldest to youngest within each release,
|
||||
releases are sorted from youngest to oldest.
|
||||
|
||||
version 7.1:
|
||||
- Raw Captions with Time (RCWT) closed caption demuxer
|
||||
- LC3/LC3plus decoding/encoding using external library liblc3
|
||||
- ffmpeg CLI filtergraph chaining
|
||||
- LC3/LC3plus demuxer and muxer
|
||||
- pad_vaapi, drawbox_vaapi filters
|
||||
- vf_scale supports secondary ref input and framesync options
|
||||
- vf_scale2ref deprecated
|
||||
- qsv_params option added for QSV encoders
|
||||
- VVC decoder compatible with DVB test content
|
||||
- xHE-AAC decoder
|
||||
- removed DEC Alpha DSP and support code
|
||||
- VVC encoding support via libvvenc
|
||||
- perlin video source
|
||||
- D3D12VA HEVC encoder
|
||||
- Cropping metadata parsing and writing in Matroska and MP4/MOV de/muxers
|
||||
- Intel QSV-accelerated VVC decoding
|
||||
- MediaCodec AAC/AMR-NB/AMR-WB/MP3 decoding
|
||||
- YUV colorspace negotiation for codecs and filters, obsoleting the
|
||||
YUVJ pixel format
|
||||
- Vulkan H.264 encoder
|
||||
- Vulkan H.265 encoder
|
||||
- stream specifiers in fftools can now match by stream disposition
|
||||
- LCEVC enhancement data exporting in H.26x and MP4/ISOBMFF
|
||||
- LCEVC filter
|
||||
- MV-HEVC decoding
|
||||
|
||||
|
||||
version 7.0:
|
||||
- DXV DXT1 encoder
|
||||
- LEAD MCMP decoder
|
||||
|
||||
+48
-71
@@ -6,26 +6,10 @@ FFmpeg code.
|
||||
|
||||
Please try to keep entries where you are the maintainer up to date!
|
||||
|
||||
*Status*, one of the following:
|
||||
[X] Old code. Something tagged obsolete generally means it has been replaced by a better system and you should be using that.
|
||||
[0] No current maintainer [but maybe you could take the role as you write your new code].
|
||||
[1] It has a maintainer but they don't have time to do much other than throw the odd patch in.
|
||||
[2] Someone actually looks after it.
|
||||
|
||||
Names in () mean that the maintainer currently has no time to maintain the code.
|
||||
A (CC <address>) after the name means that the maintainer prefers to be CC-ed on
|
||||
patches and related discussions.
|
||||
|
||||
(L <address>) *Mailing list* that is relevant to this area
|
||||
(W <address>) *Web-page* with status/info
|
||||
(B <address>) URI for where to file *bugs*. A web-page with detailed bug
|
||||
filing info, a direct bug tracker link, or a mailto: URI.
|
||||
(P <address>) *Subsystem Profile* document for more details submitting
|
||||
patches to the given subsystem. This is either an in-tree file,
|
||||
or a URI. See Documentation/maintainer/maintainer-entry-profile.rst
|
||||
for details.
|
||||
(T <address>) *SCM* tree type and location.
|
||||
Type is one of: git, hg, quilt, stgit, topgit
|
||||
|
||||
|
||||
Applications
|
||||
============
|
||||
@@ -34,10 +18,10 @@ ffmpeg:
|
||||
ffmpeg.c Michael Niedermayer, Anton Khirnov
|
||||
|
||||
ffplay:
|
||||
ffplay.c [2] Marton Balint
|
||||
ffplay.c Marton Balint
|
||||
|
||||
ffprobe:
|
||||
ffprobe.c [2] Stefano Sabatini
|
||||
ffprobe.c Stefano Sabatini
|
||||
|
||||
Commandline utility code:
|
||||
cmdutils.c, cmdutils.h Michael Niedermayer
|
||||
@@ -50,24 +34,25 @@ Miscellaneous Areas
|
||||
===================
|
||||
|
||||
documentation Stefano Sabatini, Mike Melanson, Timothy Gu, Gyan Doshi
|
||||
project server day to day operations (L: root@ffmpeg.org) Árpád Gereöffy, Michael Niedermayer, Reimar Doeffinger, Alexander Strasser, Nikolay Aleksandrov, Timo Rothenpieler
|
||||
project server emergencies (L: root@ffmpeg.org) Árpád Gereöffy, Reimar Doeffinger, Alexander Strasser, Nikolay Aleksandrov, Timo Rothenpieler
|
||||
presets [0]
|
||||
project server day to day operations Árpád Gereöffy, Michael Niedermayer, Reimar Doeffinger, Alexander Strasser, Nikolay Aleksandrov
|
||||
project server emergencies Árpád Gereöffy, Reimar Doeffinger, Alexander Strasser, Nikolay Aleksandrov
|
||||
presets Robert Swain
|
||||
metadata subsystem Aurelien Jacobs
|
||||
release management Michael Niedermayer
|
||||
API tests [0]
|
||||
API tests Ludmila Glinskih
|
||||
|
||||
|
||||
Communication
|
||||
=============
|
||||
website (T: https://git.ffmpeg.org/ffmpeg-web) Deby Barbara Lepage
|
||||
fate.ffmpeg.org (L: fate-admin@ffmpeg.org) (W: https://fate.ffmpeg.org) (P: https://ffmpeg.org/fate.html) (S: https://git.ffmpeg.org/fateserver) Timo Rothenpieler
|
||||
Trac bug tracker (W: https://trac.ffmpeg.org) Alexander Strasser, Michael Niedermayer, Carl Eugen Hoyos
|
||||
Patchwork [2] (W: https://patchwork.ffmpeg.org) Andriy Gelman
|
||||
mailing lists (W: https://ffmpeg.org/contact.html#MailingLists) Baptiste Coudurier
|
||||
|
||||
website Deby Barbara Lepage
|
||||
fate.ffmpeg.org Timothy Gu
|
||||
Trac bug tracker Alexander Strasser, Michael Niedermayer, Carl Eugen Hoyos
|
||||
Patchwork Andriy Gelman
|
||||
mailing lists Baptiste Coudurier
|
||||
Twitter Reynaldo H. Verdejo Pinochet
|
||||
Launchpad Timothy Gu
|
||||
ffmpeg-security [2] (L: ffmpeg-security@ffmpeg.org) (W: https://ffmpeg.org/security.html) Michael Niedermayer, Reimar Doeffinger
|
||||
ffmpeg-security Andreas Cadhalpun, Carl Eugen Hoyos, Clément Bœsch, Michael Niedermayer, Reimar Doeffinger, rcombs, wm4
|
||||
|
||||
|
||||
libavutil
|
||||
@@ -84,22 +69,22 @@ Other:
|
||||
bswap.h
|
||||
des Reimar Doeffinger
|
||||
dynarray.h Nicolas George
|
||||
eval.c, eval.h [2] Michael Niedermayer
|
||||
eval.c, eval.h Michael Niedermayer
|
||||
float_dsp Loren Merritt
|
||||
hash Reimar Doeffinger
|
||||
hwcontext_cuda* Timo Rothenpieler
|
||||
hwcontext_vulkan* [2] Lynne
|
||||
hwcontext_vulkan* Lynne
|
||||
intfloat* Michael Niedermayer
|
||||
integer.c, integer.h Michael Niedermayer
|
||||
lzo Reimar Doeffinger
|
||||
mathematics.c, mathematics.h [2] Michael Niedermayer
|
||||
mem.c, mem.h [2] Michael Niedermayer
|
||||
mathematics.c, mathematics.h Michael Niedermayer
|
||||
mem.c, mem.h Michael Niedermayer
|
||||
opencl.c, opencl.h Wei Gao
|
||||
opt.c, opt.h Michael Niedermayer
|
||||
rational.c, rational.h [2] Michael Niedermayer
|
||||
rational.c, rational.h Michael Niedermayer
|
||||
rc4 Reimar Doeffinger
|
||||
ripemd.c, ripemd.h James Almer
|
||||
tx* [2] Lynne
|
||||
tx* Lynne
|
||||
|
||||
|
||||
libavcodec
|
||||
@@ -121,20 +106,20 @@ Generic Parts:
|
||||
DSP utilities:
|
||||
dsputils.c, dsputils.h Michael Niedermayer
|
||||
entropy coding:
|
||||
rangecoder.c, rangecoder.h [2] Michael Niedermayer
|
||||
rangecoder.c, rangecoder.h Michael Niedermayer
|
||||
lzw.* Michael Niedermayer
|
||||
floating point AAN DCT:
|
||||
faandct.c, faandct.h [2] Michael Niedermayer
|
||||
faandct.c, faandct.h Michael Niedermayer
|
||||
Golomb coding:
|
||||
golomb.c, golomb.h [2] Michael Niedermayer
|
||||
golomb.c, golomb.h Michael Niedermayer
|
||||
motion estimation:
|
||||
motion* Michael Niedermayer
|
||||
rate control:
|
||||
ratecontrol.c [2] Michael Niedermayer
|
||||
ratecontrol.c Michael Niedermayer
|
||||
simple IDCT:
|
||||
simple_idct.c, simple_idct.h [2] Michael Niedermayer
|
||||
simple_idct.c, simple_idct.h Michael Niedermayer
|
||||
postprocessing:
|
||||
libpostproc/* [2] Michael Niedermayer
|
||||
libpostproc/* Michael Niedermayer
|
||||
table generation:
|
||||
tableprint.c, tableprint.h Reimar Doeffinger
|
||||
fixed point FFT:
|
||||
@@ -142,7 +127,7 @@ Generic Parts:
|
||||
Text Subtitles Clément Bœsch
|
||||
|
||||
Codecs:
|
||||
4xm.c [2] Michael Niedermayer
|
||||
4xm.c Michael Niedermayer
|
||||
8bps.c Roberto Togni
|
||||
8svx.c Jaikrishnan Menon
|
||||
aacenc*, aaccoder.c Rostislav Pehlivanov
|
||||
@@ -178,7 +163,7 @@ Codecs:
|
||||
dvbsubdec.c Anshul Maheshwari
|
||||
eacmv*, eaidct*, eat* Peter Ross
|
||||
exif.c, exif.h Thilo Borgmann
|
||||
ffv1* [2] Michael Niedermayer
|
||||
ffv1* Michael Niedermayer
|
||||
ffwavesynth.c Nicolas George
|
||||
fifo.c Jan Sebechlebsky
|
||||
flicvideo.c Mike Melanson
|
||||
@@ -189,7 +174,6 @@ Codecs:
|
||||
h263* Michael Niedermayer
|
||||
h264* Loren Merritt, Michael Niedermayer
|
||||
hap* Tom Butterworth
|
||||
hevc/* Anton Khirnov
|
||||
huffyuv* Michael Niedermayer
|
||||
idcinvideo.c Mike Melanson
|
||||
interplayvideo.c Mike Melanson
|
||||
@@ -266,7 +250,7 @@ Codecs:
|
||||
vp8 David Conrad, Ronald Bultje
|
||||
vp9 Ronald Bultje
|
||||
vqavideo.c Mike Melanson
|
||||
vvc [2] Nuo Mi
|
||||
vvc Nuo Mi
|
||||
wmaprodec.c Sascha Sommer
|
||||
wmavoice.c Ronald S. Bultje
|
||||
wmv2.c Michael Niedermayer
|
||||
@@ -276,7 +260,6 @@ Codecs:
|
||||
Hardware acceleration:
|
||||
dxva2* Hendrik Leppkes, Laurent Aimar, Steve Lhomme
|
||||
d3d11va* Steve Lhomme
|
||||
d3d12va_encode* Tong Wu
|
||||
mediacodec* Matthieu Bouron, Aman Gupta, Zhao Zhili
|
||||
vaapi* Haihao Xiang
|
||||
vaapi_encode* Mark Thompson, Haihao Xiang
|
||||
@@ -341,13 +324,12 @@ Filters:
|
||||
vf_mestimate.c Davinder Singh
|
||||
vf_minterpolate.c Davinder Singh
|
||||
vf_readvitc.c Tobias Rapp (CC t.rapp at noa-archive dot com)
|
||||
vf_scale.c [2] Michael Niedermayer
|
||||
vf_scale.c Michael Niedermayer
|
||||
vf_tonemap_opencl.c Ruiling Song
|
||||
vf_yadif.c [2] Michael Niedermayer
|
||||
vf_xfade_vulkan.c [2] Marvin Scholz (CC <epirat07@gmail.com>)
|
||||
vf_yadif.c Michael Niedermayer
|
||||
|
||||
Sources:
|
||||
vsrc_mandelbrot.c [2] Michael Niedermayer
|
||||
vsrc_mandelbrot.c Michael Niedermayer
|
||||
|
||||
dnn Yejun Guo
|
||||
|
||||
@@ -365,7 +347,7 @@ Generic parts:
|
||||
Muxers/Demuxers:
|
||||
4xm.c Mike Melanson
|
||||
aadec.c Vesselin Bontchev (vesselin.bontchev at yandex dot com)
|
||||
adtsenc.c [0]
|
||||
adtsenc.c Robert Swain
|
||||
aiffdec.c Baptiste Coudurier, Matthieu Bouron
|
||||
aiffenc.c Baptiste Coudurier, Matthieu Bouron
|
||||
alp.c Zane van Iperen
|
||||
@@ -401,7 +383,6 @@ Muxers/Demuxers:
|
||||
gxf.c Reimar Doeffinger
|
||||
gxfenc.c Baptiste Coudurier
|
||||
hlsenc.c Christian Suloway, Steven Liu
|
||||
iamf* [2] James Almer
|
||||
idcin.c Mike Melanson
|
||||
idroqdec.c Mike Melanson
|
||||
iff.c Jaikrishnan Menon
|
||||
@@ -416,9 +397,9 @@ Muxers/Demuxers:
|
||||
libopenmpt.c Josh de Kock
|
||||
lmlm4.c Ivo van Poorten
|
||||
lxfdec.c Tomas Härdin
|
||||
matroska.c Andreas Rheinhardt
|
||||
matroskadec.c Andreas Rheinhardt
|
||||
matroskaenc.c Andreas Rheinhardt
|
||||
matroska.c Aurelien Jacobs, Andreas Rheinhardt
|
||||
matroskadec.c Aurelien Jacobs, Andreas Rheinhardt
|
||||
matroskaenc.c David Conrad, Andreas Rheinhardt
|
||||
matroska subtitles (matroskaenc.c) John Peebles
|
||||
metadata* Aurelien Jacobs
|
||||
microdvd* Aurelien Jacobs
|
||||
@@ -487,34 +468,33 @@ Protocols:
|
||||
libzmq.c Andriy Gelman
|
||||
mms*.c Ronald S. Bultje
|
||||
udp.c Luca Abeni
|
||||
icecast.c [2] Marvin Scholz (CC <epirat07@gmail.com>)
|
||||
icecast.c Marvin Scholz
|
||||
|
||||
|
||||
libswresample
|
||||
=============
|
||||
|
||||
Generic parts:
|
||||
audioconvert.c [2] Michael Niedermayer
|
||||
dither.c [2] Michael Niedermayer
|
||||
rematrix*.c [2] Michael Niedermayer
|
||||
swresample*.c [2] Michael Niedermayer
|
||||
audioconvert.c Michael Niedermayer
|
||||
dither.c Michael Niedermayer
|
||||
rematrix*.c Michael Niedermayer
|
||||
swresample*.c Michael Niedermayer
|
||||
|
||||
Resamplers:
|
||||
resample*.c [2] Michael Niedermayer
|
||||
resample*.c Michael Niedermayer
|
||||
soxr_resample.c Rob Sykes
|
||||
|
||||
|
||||
Operating systems / CPU architectures
|
||||
=====================================
|
||||
|
||||
*BSD [2] Brad Smith
|
||||
Alpha [0]
|
||||
Alpha Falk Hueffner
|
||||
MIPS Manojkumar Bhosale, Shiyou Yin
|
||||
LoongArch [2] Shiyou Yin
|
||||
LoongArch Shiyou Yin
|
||||
Mac OS X / PowerPC Romain Dolbeau, Guillaume Poirier
|
||||
Amiga / PowerPC Colin Ward
|
||||
Linux / PowerPC Lauri Kasanen
|
||||
RISC-V [2] Rémi Denis-Courmont
|
||||
RISC-V Rémi Denis-Courmont
|
||||
Windows MinGW Alex Beregszaszi, Ramiro Polla
|
||||
Windows Cygwin Victor Paesa
|
||||
Windows MSVC Hendrik Leppkes
|
||||
@@ -533,7 +513,6 @@ Benjamin Larsson
|
||||
Bobby Bingham
|
||||
Daniel Verkamp
|
||||
Derek Buitenhuis
|
||||
Fei Wang
|
||||
Ganesh Ajjanagadde
|
||||
Henrik Gramner
|
||||
Ivan Uskov
|
||||
@@ -556,12 +535,10 @@ wm4
|
||||
Releases
|
||||
========
|
||||
|
||||
7.0 Michael Niedermayer
|
||||
6.1 Michael Niedermayer
|
||||
5.1 Michael Niedermayer
|
||||
4.4 Michael Niedermayer
|
||||
3.4 Michael Niedermayer
|
||||
2.8 Michael Niedermayer
|
||||
2.7 Michael Niedermayer
|
||||
2.6 Michael Niedermayer
|
||||
2.5 Michael Niedermayer
|
||||
|
||||
If you want to maintain an older release, please contact us
|
||||
|
||||
|
||||
@@ -52,9 +52,6 @@ $(TOOLS): %$(EXESUF): %.o
|
||||
target_dec_%_fuzzer$(EXESUF): target_dec_%_fuzzer.o $(FF_DEP_LIBS)
|
||||
$(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $^ $(ELIBS) $(FF_EXTRALIBS) $(LIBFUZZER_PATH)
|
||||
|
||||
target_enc_%_fuzzer$(EXESUF): target_enc_%_fuzzer.o $(FF_DEP_LIBS)
|
||||
$(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $^ $(ELIBS) $(FF_EXTRALIBS) $(LIBFUZZER_PATH)
|
||||
|
||||
tools/target_bsf_%_fuzzer$(EXESUF): tools/target_bsf_%_fuzzer.o $(FF_DEP_LIBS)
|
||||
$(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $^ $(ELIBS) $(FF_EXTRALIBS) $(LIBFUZZER_PATH)
|
||||
|
||||
@@ -70,8 +67,6 @@ tools/target_io_dem_fuzzer$(EXESUF): tools/target_io_dem_fuzzer.o $(FF_DEP_LIBS)
|
||||
tools/target_sws_fuzzer$(EXESUF): tools/target_sws_fuzzer.o $(FF_DEP_LIBS)
|
||||
$(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $^ $(ELIBS) $(FF_EXTRALIBS) $(LIBFUZZER_PATH)
|
||||
|
||||
tools/target_swr_fuzzer$(EXESUF): tools/target_swr_fuzzer.o $(FF_DEP_LIBS)
|
||||
$(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $^ $(ELIBS) $(FF_EXTRALIBS) $(LIBFUZZER_PATH)
|
||||
|
||||
tools/enum_options$(EXESUF): ELIBS = $(FF_EXTRALIBS)
|
||||
tools/enum_options$(EXESUF): $(FF_DEP_LIBS)
|
||||
@@ -103,7 +98,7 @@ SUBDIR_VARS := CLEANFILES FFLIBS HOSTPROGS TESTPROGS TOOLS \
|
||||
ARMV5TE-OBJS ARMV6-OBJS ARMV8-OBJS VFP-OBJS NEON-OBJS \
|
||||
ALTIVEC-OBJS VSX-OBJS MMX-OBJS X86ASM-OBJS \
|
||||
MIPSFPU-OBJS MIPSDSPR2-OBJS MIPSDSP-OBJS MSA-OBJS \
|
||||
MMI-OBJS LSX-OBJS LASX-OBJS RV-OBJS RVV-OBJS RVVB-OBJS \
|
||||
MMI-OBJS LSX-OBJS LASX-OBJS RV-OBJS RVV-OBJS \
|
||||
OBJS SLIBOBJS SHLIBOBJS STLIBOBJS HOSTOBJS TESTOBJS
|
||||
|
||||
define RESET
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
|
||||
┌─────────────────────────────────────────┐
|
||||
│ RELEASE NOTES for FFmpeg 7.0 "Dijkstra" │
|
||||
└─────────────────────────────────────────┘
|
||||
|
||||
The FFmpeg Project proudly presents FFmpeg 7.0 "Dijkstra", about 6
|
||||
months after the release of FFmpeg 6.1.
|
||||
|
||||
A complete Changelog is available at the root of the project, and the
|
||||
complete Git history on https://git.ffmpeg.org/gitweb/ffmpeg.git
|
||||
|
||||
We hope you will like this release as much as we enjoyed working on it, and
|
||||
as usual, if you have any questions about it, or any FFmpeg related topic,
|
||||
feel free to join us on the #ffmpeg IRC channel (on irc.libera.chat) or ask
|
||||
on the mailing-lists.
|
||||
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*
|
||||
* based on vlc_atomic.h from VLC
|
||||
* Copyright (C) 2010 Rémi Denis-Courmont
|
||||
*/
|
||||
|
||||
#ifndef COMPAT_ATOMICS_GCC_STDATOMIC_H
|
||||
#define COMPAT_ATOMICS_GCC_STDATOMIC_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define ATOMIC_FLAG_INIT 0
|
||||
|
||||
#define ATOMIC_VAR_INIT(value) (value)
|
||||
|
||||
#define atomic_init(obj, value) \
|
||||
do { \
|
||||
*(obj) = (value); \
|
||||
} while(0)
|
||||
|
||||
#define kill_dependency(y) ((void)0)
|
||||
|
||||
#define atomic_thread_fence(order) \
|
||||
__sync_synchronize()
|
||||
|
||||
#define atomic_signal_fence(order) \
|
||||
((void)0)
|
||||
|
||||
#define atomic_is_lock_free(obj) 0
|
||||
|
||||
typedef _Bool atomic_flag;
|
||||
typedef _Bool atomic_bool;
|
||||
typedef char atomic_char;
|
||||
typedef signed char atomic_schar;
|
||||
typedef unsigned char atomic_uchar;
|
||||
typedef short atomic_short;
|
||||
typedef unsigned short atomic_ushort;
|
||||
typedef int atomic_int;
|
||||
typedef unsigned int atomic_uint;
|
||||
typedef long atomic_long;
|
||||
typedef unsigned long atomic_ulong;
|
||||
typedef long long atomic_llong;
|
||||
typedef unsigned long long atomic_ullong;
|
||||
typedef wchar_t atomic_wchar_t;
|
||||
typedef int_least8_t atomic_int_least8_t;
|
||||
typedef uint_least8_t atomic_uint_least8_t;
|
||||
typedef int_least16_t atomic_int_least16_t;
|
||||
typedef uint_least16_t atomic_uint_least16_t;
|
||||
typedef int_least32_t atomic_int_least32_t;
|
||||
typedef uint_least32_t atomic_uint_least32_t;
|
||||
typedef int_least64_t atomic_int_least64_t;
|
||||
typedef uint_least64_t atomic_uint_least64_t;
|
||||
typedef int_fast8_t atomic_int_fast8_t;
|
||||
typedef uint_fast8_t atomic_uint_fast8_t;
|
||||
typedef int_fast16_t atomic_int_fast16_t;
|
||||
typedef uint_fast16_t atomic_uint_fast16_t;
|
||||
typedef int_fast32_t atomic_int_fast32_t;
|
||||
typedef uint_fast32_t atomic_uint_fast32_t;
|
||||
typedef int_fast64_t atomic_int_fast64_t;
|
||||
typedef uint_fast64_t atomic_uint_fast64_t;
|
||||
typedef intptr_t atomic_intptr_t;
|
||||
typedef uintptr_t atomic_uintptr_t;
|
||||
typedef size_t atomic_size_t;
|
||||
typedef ptrdiff_t atomic_ptrdiff_t;
|
||||
typedef intmax_t atomic_intmax_t;
|
||||
typedef uintmax_t atomic_uintmax_t;
|
||||
|
||||
#define atomic_store(object, desired) \
|
||||
do { \
|
||||
*(object) = (desired); \
|
||||
__sync_synchronize(); \
|
||||
} while (0)
|
||||
|
||||
#define atomic_store_explicit(object, desired, order) \
|
||||
atomic_store(object, desired)
|
||||
|
||||
#define atomic_load(object) \
|
||||
(__sync_synchronize(), *(object))
|
||||
|
||||
#define atomic_load_explicit(object, order) \
|
||||
atomic_load(object)
|
||||
|
||||
#define atomic_exchange(object, desired) \
|
||||
({ \
|
||||
__typeof__(object) _obj = (object); \
|
||||
__typeof__(*object) _old; \
|
||||
do \
|
||||
_old = atomic_load(_obj); \
|
||||
while (!__sync_bool_compare_and_swap(_obj, _old, (desired))); \
|
||||
_old; \
|
||||
})
|
||||
|
||||
#define atomic_exchange_explicit(object, desired, order) \
|
||||
atomic_exchange(object, desired)
|
||||
|
||||
#define atomic_compare_exchange_strong(object, expected, desired) \
|
||||
({ \
|
||||
__typeof__(object) _exp = (expected); \
|
||||
__typeof__(*object) _old = *_exp; \
|
||||
*_exp = __sync_val_compare_and_swap((object), _old, (desired)); \
|
||||
*_exp == _old; \
|
||||
})
|
||||
|
||||
#define atomic_compare_exchange_strong_explicit(object, expected, desired, success, failure) \
|
||||
atomic_compare_exchange_strong(object, expected, desired)
|
||||
|
||||
#define atomic_compare_exchange_weak(object, expected, desired) \
|
||||
atomic_compare_exchange_strong(object, expected, desired)
|
||||
|
||||
#define atomic_compare_exchange_weak_explicit(object, expected, desired, success, failure) \
|
||||
atomic_compare_exchange_weak(object, expected, desired)
|
||||
|
||||
#define atomic_fetch_add(object, operand) \
|
||||
__sync_fetch_and_add(object, operand)
|
||||
|
||||
#define atomic_fetch_add_explicit(object, operand, order) \
|
||||
atomic_fetch_add(object, operand)
|
||||
|
||||
#define atomic_fetch_sub(object, operand) \
|
||||
__sync_fetch_and_sub(object, operand)
|
||||
|
||||
#define atomic_fetch_sub_explicit(object, operand, order) \
|
||||
atomic_fetch_sub(object, operand)
|
||||
|
||||
#define atomic_fetch_or(object, operand) \
|
||||
__sync_fetch_and_or(object, operand)
|
||||
|
||||
#define atomic_fetch_or_explicit(object, operand, order) \
|
||||
atomic_fetch_or(object, operand)
|
||||
|
||||
#define atomic_fetch_xor(object, operand) \
|
||||
__sync_fetch_and_xor(object, operand)
|
||||
|
||||
#define atomic_fetch_xor_explicit(object, operand, order) \
|
||||
atomic_fetch_xor(object, operand)
|
||||
|
||||
#define atomic_fetch_and(object, operand) \
|
||||
__sync_fetch_and_and(object, operand)
|
||||
|
||||
#define atomic_fetch_and_explicit(object, operand, order) \
|
||||
atomic_fetch_and(object, operand)
|
||||
|
||||
#define atomic_flag_test_and_set(object) \
|
||||
atomic_exchange(object, 1)
|
||||
|
||||
#define atomic_flag_test_and_set_explicit(object, order) \
|
||||
atomic_flag_test_and_set(object)
|
||||
|
||||
#define atomic_flag_clear(object) \
|
||||
atomic_store(object, 0)
|
||||
|
||||
#define atomic_flag_clear_explicit(object, order) \
|
||||
atomic_flag_clear(object)
|
||||
|
||||
#endif /* COMPAT_ATOMICS_GCC_STDATOMIC_H */
|
||||
@@ -1,6 +1,4 @@
|
||||
/*
|
||||
* Copyright © 2024 Rémi Denis-Courmont.
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
@@ -18,16 +16,24 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "libavutil/cpu.h"
|
||||
/*
|
||||
* based on vlc_atomic.h from VLC
|
||||
* Copyright (C) 2010 Rémi Denis-Courmont
|
||||
*/
|
||||
|
||||
#ifndef __riscv_zbb
|
||||
unsigned char ff_rv_zbb_supported = 0;
|
||||
#include <pthread.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __ELF__
|
||||
__attribute__((constructor))
|
||||
static void probe_zbb(void)
|
||||
#include "stdatomic.h"
|
||||
|
||||
static pthread_mutex_t atomic_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
void avpriv_atomic_lock(void)
|
||||
{
|
||||
ff_rv_zbb_supported = (av_get_cpu_flags() & AV_CPU_FLAG_RVB_BASIC) != 0;
|
||||
pthread_mutex_lock(&atomic_lock);
|
||||
}
|
||||
|
||||
void avpriv_atomic_unlock(void)
|
||||
{
|
||||
pthread_mutex_unlock(&atomic_lock);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,197 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*
|
||||
* based on vlc_atomic.h from VLC
|
||||
* Copyright (C) 2010 Rémi Denis-Courmont
|
||||
*/
|
||||
|
||||
#ifndef COMPAT_ATOMICS_PTHREAD_STDATOMIC_H
|
||||
#define COMPAT_ATOMICS_PTHREAD_STDATOMIC_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define ATOMIC_FLAG_INIT 0
|
||||
|
||||
#define ATOMIC_VAR_INIT(value) (value)
|
||||
|
||||
#define atomic_init(obj, value) \
|
||||
do { \
|
||||
*(obj) = (value); \
|
||||
} while(0)
|
||||
|
||||
#define kill_dependency(y) ((void)0)
|
||||
|
||||
#define atomic_signal_fence(order) \
|
||||
((void)0)
|
||||
|
||||
#define atomic_is_lock_free(obj) 0
|
||||
|
||||
typedef intptr_t atomic_flag;
|
||||
typedef intptr_t atomic_bool;
|
||||
typedef intptr_t atomic_char;
|
||||
typedef intptr_t atomic_schar;
|
||||
typedef intptr_t atomic_uchar;
|
||||
typedef intptr_t atomic_short;
|
||||
typedef intptr_t atomic_ushort;
|
||||
typedef intptr_t atomic_int;
|
||||
typedef intptr_t atomic_uint;
|
||||
typedef intptr_t atomic_long;
|
||||
typedef intptr_t atomic_ulong;
|
||||
typedef intptr_t atomic_llong;
|
||||
typedef intptr_t atomic_ullong;
|
||||
typedef intptr_t atomic_wchar_t;
|
||||
typedef intptr_t atomic_int_least8_t;
|
||||
typedef intptr_t atomic_uint_least8_t;
|
||||
typedef intptr_t atomic_int_least16_t;
|
||||
typedef intptr_t atomic_uint_least16_t;
|
||||
typedef intptr_t atomic_int_least32_t;
|
||||
typedef intptr_t atomic_uint_least32_t;
|
||||
typedef intptr_t atomic_int_least64_t;
|
||||
typedef intptr_t atomic_uint_least64_t;
|
||||
typedef intptr_t atomic_int_fast8_t;
|
||||
typedef intptr_t atomic_uint_fast8_t;
|
||||
typedef intptr_t atomic_int_fast16_t;
|
||||
typedef intptr_t atomic_uint_fast16_t;
|
||||
typedef intptr_t atomic_int_fast32_t;
|
||||
typedef intptr_t atomic_uint_fast32_t;
|
||||
typedef intptr_t atomic_int_fast64_t;
|
||||
typedef intptr_t atomic_uint_fast64_t;
|
||||
typedef intptr_t atomic_intptr_t;
|
||||
typedef intptr_t atomic_uintptr_t;
|
||||
typedef intptr_t atomic_size_t;
|
||||
typedef intptr_t atomic_ptrdiff_t;
|
||||
typedef intptr_t atomic_intmax_t;
|
||||
typedef intptr_t atomic_uintmax_t;
|
||||
|
||||
void avpriv_atomic_lock(void);
|
||||
void avpriv_atomic_unlock(void);
|
||||
|
||||
static inline void atomic_thread_fence(int order)
|
||||
{
|
||||
avpriv_atomic_lock();
|
||||
avpriv_atomic_unlock();
|
||||
}
|
||||
|
||||
static inline void atomic_store(intptr_t *object, intptr_t desired)
|
||||
{
|
||||
avpriv_atomic_lock();
|
||||
*object = desired;
|
||||
avpriv_atomic_unlock();
|
||||
}
|
||||
|
||||
#define atomic_store_explicit(object, desired, order) \
|
||||
atomic_store(object, desired)
|
||||
|
||||
static inline intptr_t atomic_load(intptr_t *object)
|
||||
{
|
||||
intptr_t ret;
|
||||
avpriv_atomic_lock();
|
||||
ret = *object;
|
||||
avpriv_atomic_unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define atomic_load_explicit(object, order) \
|
||||
atomic_load(object)
|
||||
|
||||
static inline intptr_t atomic_exchange(intptr_t *object, intptr_t desired)
|
||||
{
|
||||
intptr_t ret;
|
||||
avpriv_atomic_lock();
|
||||
ret = *object;
|
||||
*object = desired;
|
||||
avpriv_atomic_unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define atomic_exchange_explicit(object, desired, order) \
|
||||
atomic_exchange(object, desired)
|
||||
|
||||
static inline int atomic_compare_exchange_strong(intptr_t *object, intptr_t *expected,
|
||||
intptr_t desired)
|
||||
{
|
||||
int ret;
|
||||
avpriv_atomic_lock();
|
||||
if (*object == *expected) {
|
||||
ret = 1;
|
||||
*object = desired;
|
||||
} else {
|
||||
ret = 0;
|
||||
*expected = *object;
|
||||
}
|
||||
avpriv_atomic_unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define atomic_compare_exchange_strong_explicit(object, expected, desired, success, failure) \
|
||||
atomic_compare_exchange_strong(object, expected, desired)
|
||||
|
||||
#define atomic_compare_exchange_weak(object, expected, desired) \
|
||||
atomic_compare_exchange_strong(object, expected, desired)
|
||||
|
||||
#define atomic_compare_exchange_weak_explicit(object, expected, desired, success, failure) \
|
||||
atomic_compare_exchange_weak(object, expected, desired)
|
||||
|
||||
#define FETCH_MODIFY(opname, op) \
|
||||
static inline intptr_t atomic_fetch_ ## opname(intptr_t *object, intptr_t operand) \
|
||||
{ \
|
||||
intptr_t ret; \
|
||||
avpriv_atomic_lock(); \
|
||||
ret = *object; \
|
||||
*object = *object op operand; \
|
||||
avpriv_atomic_unlock(); \
|
||||
return ret; \
|
||||
}
|
||||
|
||||
FETCH_MODIFY(add, +)
|
||||
FETCH_MODIFY(sub, -)
|
||||
FETCH_MODIFY(or, |)
|
||||
FETCH_MODIFY(xor, ^)
|
||||
FETCH_MODIFY(and, &)
|
||||
|
||||
#undef FETCH_MODIFY
|
||||
|
||||
#define atomic_fetch_add_explicit(object, operand, order) \
|
||||
atomic_fetch_add(object, operand)
|
||||
|
||||
#define atomic_fetch_sub_explicit(object, operand, order) \
|
||||
atomic_fetch_sub(object, operand)
|
||||
|
||||
#define atomic_fetch_or_explicit(object, operand, order) \
|
||||
atomic_fetch_or(object, operand)
|
||||
|
||||
#define atomic_fetch_xor_explicit(object, operand, order) \
|
||||
atomic_fetch_xor(object, operand)
|
||||
|
||||
#define atomic_fetch_and_explicit(object, operand, order) \
|
||||
atomic_fetch_and(object, operand)
|
||||
|
||||
#define atomic_flag_test_and_set(object) \
|
||||
atomic_exchange(object, 1)
|
||||
|
||||
#define atomic_flag_test_and_set_explicit(object, order) \
|
||||
atomic_flag_test_and_set(object)
|
||||
|
||||
#define atomic_flag_clear(object) \
|
||||
atomic_store(object, 0)
|
||||
|
||||
#define atomic_flag_clear_explicit(object, order) \
|
||||
atomic_flag_clear(object)
|
||||
|
||||
#endif /* COMPAT_ATOMICS_PTHREAD_STDATOMIC_H */
|
||||
@@ -0,0 +1,186 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef COMPAT_ATOMICS_SUNCC_STDATOMIC_H
|
||||
#define COMPAT_ATOMICS_SUNCC_STDATOMIC_H
|
||||
|
||||
#include <atomic.h>
|
||||
#include <mbarrier.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define ATOMIC_FLAG_INIT 0
|
||||
|
||||
#define ATOMIC_VAR_INIT(value) (value)
|
||||
|
||||
#define atomic_init(obj, value) \
|
||||
do { \
|
||||
*(obj) = (value); \
|
||||
} while(0)
|
||||
|
||||
#define kill_dependency(y) ((void)0)
|
||||
|
||||
#define atomic_thread_fence(order) \
|
||||
__machine_rw_barrier();
|
||||
|
||||
#define atomic_signal_fence(order) \
|
||||
((void)0)
|
||||
|
||||
#define atomic_is_lock_free(obj) 0
|
||||
|
||||
typedef intptr_t atomic_flag;
|
||||
typedef intptr_t atomic_bool;
|
||||
typedef intptr_t atomic_char;
|
||||
typedef intptr_t atomic_schar;
|
||||
typedef intptr_t atomic_uchar;
|
||||
typedef intptr_t atomic_short;
|
||||
typedef intptr_t atomic_ushort;
|
||||
typedef intptr_t atomic_int;
|
||||
typedef intptr_t atomic_uint;
|
||||
typedef intptr_t atomic_long;
|
||||
typedef intptr_t atomic_ulong;
|
||||
typedef intptr_t atomic_llong;
|
||||
typedef intptr_t atomic_ullong;
|
||||
typedef intptr_t atomic_wchar_t;
|
||||
typedef intptr_t atomic_int_least8_t;
|
||||
typedef intptr_t atomic_uint_least8_t;
|
||||
typedef intptr_t atomic_int_least16_t;
|
||||
typedef intptr_t atomic_uint_least16_t;
|
||||
typedef intptr_t atomic_int_least32_t;
|
||||
typedef intptr_t atomic_uint_least32_t;
|
||||
typedef intptr_t atomic_int_least64_t;
|
||||
typedef intptr_t atomic_uint_least64_t;
|
||||
typedef intptr_t atomic_int_fast8_t;
|
||||
typedef intptr_t atomic_uint_fast8_t;
|
||||
typedef intptr_t atomic_int_fast16_t;
|
||||
typedef intptr_t atomic_uint_fast16_t;
|
||||
typedef intptr_t atomic_int_fast32_t;
|
||||
typedef intptr_t atomic_uint_fast32_t;
|
||||
typedef intptr_t atomic_int_fast64_t;
|
||||
typedef intptr_t atomic_uint_fast64_t;
|
||||
typedef intptr_t atomic_intptr_t;
|
||||
typedef intptr_t atomic_uintptr_t;
|
||||
typedef intptr_t atomic_size_t;
|
||||
typedef intptr_t atomic_ptrdiff_t;
|
||||
typedef intptr_t atomic_intmax_t;
|
||||
typedef intptr_t atomic_uintmax_t;
|
||||
|
||||
static inline void atomic_store(intptr_t *object, intptr_t desired)
|
||||
{
|
||||
*object = desired;
|
||||
__machine_rw_barrier();
|
||||
}
|
||||
|
||||
#define atomic_store_explicit(object, desired, order) \
|
||||
atomic_store(object, desired)
|
||||
|
||||
static inline intptr_t atomic_load(intptr_t *object)
|
||||
{
|
||||
__machine_rw_barrier();
|
||||
return *object;
|
||||
}
|
||||
|
||||
#define atomic_load_explicit(object, order) \
|
||||
atomic_load(object)
|
||||
|
||||
#define atomic_exchange(object, desired) \
|
||||
atomic_swap_ptr(object, desired)
|
||||
|
||||
#define atomic_exchange_explicit(object, desired, order) \
|
||||
atomic_exchange(object, desired)
|
||||
|
||||
static inline int atomic_compare_exchange_strong(intptr_t *object, intptr_t *expected,
|
||||
intptr_t desired)
|
||||
{
|
||||
intptr_t old = *expected;
|
||||
*expected = (intptr_t)atomic_cas_ptr(object, (void *)old, (void *)desired);
|
||||
return *expected == old;
|
||||
}
|
||||
|
||||
#define atomic_compare_exchange_strong_explicit(object, expected, desired, success, failure) \
|
||||
atomic_compare_exchange_strong(object, expected, desired)
|
||||
|
||||
#define atomic_compare_exchange_weak(object, expected, desired) \
|
||||
atomic_compare_exchange_strong(object, expected, desired)
|
||||
|
||||
#define atomic_compare_exchange_weak_explicit(object, expected, desired, success, failure) \
|
||||
atomic_compare_exchange_weak(object, expected, desired)
|
||||
|
||||
static inline intptr_t atomic_fetch_add(intptr_t *object, intptr_t operand)
|
||||
{
|
||||
return atomic_add_ptr_nv(object, operand) - operand;
|
||||
}
|
||||
|
||||
#define atomic_fetch_sub(object, operand) \
|
||||
atomic_fetch_add(object, -(operand))
|
||||
|
||||
static inline intptr_t atomic_fetch_or(intptr_t *object, intptr_t operand)
|
||||
{
|
||||
intptr_t old;
|
||||
do {
|
||||
old = atomic_load(object);
|
||||
} while (!atomic_compare_exchange_strong(object, old, old | operand));
|
||||
return old;
|
||||
}
|
||||
|
||||
static inline intptr_t atomic_fetch_xor(intptr_t *object, intptr_t operand)
|
||||
{
|
||||
intptr_t old;
|
||||
do {
|
||||
old = atomic_load(object);
|
||||
} while (!atomic_compare_exchange_strong(object, old, old ^ operand));
|
||||
return old;
|
||||
}
|
||||
|
||||
static inline intptr_t atomic_fetch_and(intptr_t *object, intptr_t operand)
|
||||
{
|
||||
intptr_t old;
|
||||
do {
|
||||
old = atomic_load(object);
|
||||
} while (!atomic_compare_exchange_strong(object, old, old & operand));
|
||||
return old;
|
||||
}
|
||||
|
||||
#define atomic_fetch_add_explicit(object, operand, order) \
|
||||
atomic_fetch_add(object, operand)
|
||||
|
||||
#define atomic_fetch_sub_explicit(object, operand, order) \
|
||||
atomic_fetch_sub(object, operand)
|
||||
|
||||
#define atomic_fetch_or_explicit(object, operand, order) \
|
||||
atomic_fetch_or(object, operand)
|
||||
|
||||
#define atomic_fetch_xor_explicit(object, operand, order) \
|
||||
atomic_fetch_xor(object, operand)
|
||||
|
||||
#define atomic_fetch_and_explicit(object, operand, order) \
|
||||
atomic_fetch_and(object, operand)
|
||||
|
||||
#define atomic_flag_test_and_set(object) \
|
||||
atomic_exchange(object, 1)
|
||||
|
||||
#define atomic_flag_test_and_set_explicit(object, order) \
|
||||
atomic_flag_test_and_set(object)
|
||||
|
||||
#define atomic_flag_clear(object) \
|
||||
atomic_store(object, 0)
|
||||
|
||||
#define atomic_flag_clear_explicit(object, order) \
|
||||
atomic_flag_clear(object)
|
||||
|
||||
#endif /* COMPAT_ATOMICS_SUNCC_STDATOMIC_H */
|
||||
@@ -1,599 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Rémi Denis-Courmont
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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 this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __STDC_VERSION_STDBIT_H__
|
||||
#define __STDC_VERSION_STDBIT_H__ 202311L
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <limits.h> /* CHAR_BIT */
|
||||
|
||||
#define __STDC_ENDIAN_LITTLE__ 1234
|
||||
#define __STDC_ENDIAN_BIG__ 4321
|
||||
|
||||
#ifdef __BYTE_ORDER__
|
||||
# if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
|
||||
# define __STDC_ENDIAN_NATIVE__ __STDC_ENDIAN_LITTLE__
|
||||
# elif (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
|
||||
# define __STDC_ENDIAN_NATIVE__ __STDC_ENDIAN_BIG__
|
||||
# else
|
||||
# define __STDC_ENDIAN_NATIVE__ 3412
|
||||
# endif
|
||||
#elif defined(_MSC_VER)
|
||||
# define __STDC_ENDIAN_NATIVE__ __STDC_ENDIAN_LITTLE__
|
||||
#else
|
||||
# error Not implemented.
|
||||
#endif
|
||||
|
||||
#define __stdbit_generic_type_func(func, value) \
|
||||
_Generic (value, \
|
||||
unsigned long long: stdc_##func##_ull((unsigned long long)(value)), \
|
||||
unsigned long: stdc_##func##_ul((unsigned long)(value)), \
|
||||
unsigned int: stdc_##func##_ui((unsigned int)(value)), \
|
||||
unsigned short: stdc_##func##_us((unsigned short)(value)), \
|
||||
unsigned char: stdc_##func##_uc((unsigned char)(value)))
|
||||
|
||||
#if defined (__GNUC__) || defined (__clang__)
|
||||
static inline unsigned int stdc_leading_zeros_ull(unsigned long long value)
|
||||
{
|
||||
return value ? __builtin_clzll(value) : (CHAR_BIT * sizeof (value));
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_leading_zeros_ul(unsigned long value)
|
||||
{
|
||||
return value ? __builtin_clzl(value) : (CHAR_BIT * sizeof (value));
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_leading_zeros_ui(unsigned int value)
|
||||
{
|
||||
return value ? __builtin_clz(value) : (CHAR_BIT * sizeof (value));
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_leading_zeros_us(unsigned short value)
|
||||
{
|
||||
return stdc_leading_zeros_ui(value)
|
||||
- CHAR_BIT * (sizeof (int) - sizeof (value));
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_leading_zeros_uc(unsigned char value)
|
||||
{
|
||||
return stdc_leading_zeros_ui(value) - (CHAR_BIT * (sizeof (int) - 1));
|
||||
}
|
||||
#else
|
||||
static inline unsigned int __stdc_leading_zeros(unsigned long long value,
|
||||
unsigned int size)
|
||||
{
|
||||
unsigned int zeros = size * CHAR_BIT;
|
||||
|
||||
while (value != 0) {
|
||||
value >>= 1;
|
||||
zeros--;
|
||||
}
|
||||
|
||||
return zeros;
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_leading_zeros_ull(unsigned long long value)
|
||||
{
|
||||
return __stdc_leading_zeros(value, sizeof (value));
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_leading_zeros_ul(unsigned long value)
|
||||
{
|
||||
return __stdc_leading_zeros(value, sizeof (value));
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_leading_zeros_ui(unsigned int value)
|
||||
{
|
||||
return __stdc_leading_zeros(value, sizeof (value));
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_leading_zeros_us(unsigned short value)
|
||||
{
|
||||
return __stdc_leading_zeros(value, sizeof (value));
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_leading_zeros_uc(unsigned char value)
|
||||
{
|
||||
return __stdc_leading_zeros(value, sizeof (value));
|
||||
}
|
||||
#endif
|
||||
|
||||
#define stdc_leading_zeros(value) \
|
||||
__stdbit_generic_type_func(leading_zeros, value)
|
||||
|
||||
static inline unsigned int stdc_leading_ones_ull(unsigned long long value)
|
||||
{
|
||||
return stdc_leading_zeros_ull(~value);
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_leading_ones_ul(unsigned long value)
|
||||
{
|
||||
return stdc_leading_zeros_ul(~value);
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_leading_ones_ui(unsigned int value)
|
||||
{
|
||||
return stdc_leading_zeros_ui(~value);
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_leading_ones_us(unsigned short value)
|
||||
{
|
||||
return stdc_leading_zeros_us(~value);
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_leading_ones_uc(unsigned char value)
|
||||
{
|
||||
return stdc_leading_zeros_uc(~value);
|
||||
}
|
||||
|
||||
#define stdc_leading_ones(value) \
|
||||
__stdbit_generic_type_func(leading_ones, value)
|
||||
|
||||
#if defined (__GNUC__) || defined (__clang__)
|
||||
static inline unsigned int stdc_trailing_zeros_ull(unsigned long long value)
|
||||
{
|
||||
return value ? (unsigned int)__builtin_ctzll(value)
|
||||
: (CHAR_BIT * sizeof (value));
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_trailing_zeros_ul(unsigned long value)
|
||||
{
|
||||
return value ? (unsigned int)__builtin_ctzl(value)
|
||||
: (CHAR_BIT * sizeof (value));
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_trailing_zeros_ui(unsigned int value)
|
||||
{
|
||||
return value ? (unsigned int)__builtin_ctz(value)
|
||||
: (CHAR_BIT * sizeof (value));
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_trailing_zeros_us(unsigned short value)
|
||||
{
|
||||
return value ? (unsigned int)__builtin_ctz(value)
|
||||
: (CHAR_BIT * sizeof (value));
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_trailing_zeros_uc(unsigned char value)
|
||||
{
|
||||
return value ? (unsigned int)__builtin_ctz(value)
|
||||
: (CHAR_BIT * sizeof (value));
|
||||
}
|
||||
#else
|
||||
static inline unsigned int __stdc_trailing_zeros(unsigned long long value,
|
||||
unsigned int size)
|
||||
{
|
||||
unsigned int zeros = 0;
|
||||
|
||||
if (!value)
|
||||
return size * CHAR_BIT;
|
||||
|
||||
while ((value & 1) == 0) {
|
||||
value >>= 1;
|
||||
zeros++;
|
||||
}
|
||||
|
||||
return zeros;
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_trailing_zeros_ull(unsigned long long value)
|
||||
{
|
||||
return __stdc_trailing_zeros(value, sizeof (value));
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_trailing_zeros_ul(unsigned long value)
|
||||
{
|
||||
return __stdc_trailing_zeros(value, sizeof (value));
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_trailing_zeros_ui(unsigned int value)
|
||||
{
|
||||
return __stdc_trailing_zeros(value, sizeof (value));
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_trailing_zeros_us(unsigned short value)
|
||||
{
|
||||
return __stdc_trailing_zeros(value, sizeof (value));
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_trailing_zeros_uc(unsigned char value)
|
||||
{
|
||||
return __stdc_trailing_zeros(value, sizeof (value));
|
||||
}
|
||||
#endif
|
||||
|
||||
#define stdc_trailing_zeros(value) \
|
||||
__stdbit_generic_type_func(trailing_zeros, value)
|
||||
|
||||
static inline unsigned int stdc_trailing_ones_ull(unsigned long long value)
|
||||
{
|
||||
return stdc_trailing_zeros_ull(~value);
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_trailing_ones_ul(unsigned long value)
|
||||
{
|
||||
return stdc_trailing_zeros_ul(~value);
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_trailing_ones_ui(unsigned int value)
|
||||
{
|
||||
return stdc_trailing_zeros_ui(~value);
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_trailing_ones_us(unsigned short value)
|
||||
{
|
||||
return stdc_trailing_zeros_us(~value);
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_trailing_ones_uc(unsigned char value)
|
||||
{
|
||||
return stdc_trailing_zeros_uc(~value);
|
||||
}
|
||||
|
||||
#define stdc_trailing_ones(value) \
|
||||
__stdbit_generic_type_func(trailing_ones, value)
|
||||
|
||||
static inline unsigned int stdc_first_leading_one_ull(unsigned long long value)
|
||||
{
|
||||
return value ? (stdc_leading_zeros_ull(value) + 1) : 0;
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_first_leading_one_ul(unsigned long value)
|
||||
{
|
||||
return value ? (stdc_leading_zeros_ul(value) + 1) : 0;
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_first_leading_one_ui(unsigned int value)
|
||||
{
|
||||
return value ? (stdc_leading_zeros_ui(value) + 1) : 0;
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_first_leading_one_us(unsigned short value)
|
||||
{
|
||||
return value ? (stdc_leading_zeros_us(value) + 1) : 0;
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_first_leading_one_uc(unsigned char value)
|
||||
{
|
||||
return value ? (stdc_leading_zeros_uc(value) + 1) : 0;
|
||||
}
|
||||
|
||||
#define stdc_first_leading_one(value) \
|
||||
__stdbit_generic_type_func(first_leading_one, value)
|
||||
|
||||
static inline unsigned int stdc_first_leading_zero_ull(unsigned long long value)
|
||||
{
|
||||
return stdc_leading_ones_ull(~value);
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_first_leading_zero_ul(unsigned long value)
|
||||
{
|
||||
return stdc_leading_ones_ul(~value);
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_first_leading_zero_ui(unsigned int value)
|
||||
{
|
||||
return stdc_leading_ones_ui(~value);
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_first_leading_zero_us(unsigned short value)
|
||||
{
|
||||
return stdc_leading_ones_us(~value);
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_first_leading_zero_uc(unsigned char value)
|
||||
{
|
||||
return stdc_leading_ones_uc(~value);
|
||||
}
|
||||
|
||||
#define stdc_first_leading_zero(value) \
|
||||
__stdbit_generic_type_func(first_leading_zero, value)
|
||||
|
||||
#if defined (__GNUC__) || defined (__clang__)
|
||||
static inline unsigned int stdc_first_trailing_one_ull(unsigned long long value)
|
||||
{
|
||||
return __builtin_ffsll(value);
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_first_trailing_one_ul(unsigned long value)
|
||||
{
|
||||
return __builtin_ffsl(value);
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_first_trailing_one_ui(unsigned int value)
|
||||
{
|
||||
return __builtin_ffs(value);
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_first_trailing_one_us(unsigned short value)
|
||||
{
|
||||
return __builtin_ffs(value);
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_first_trailing_one_uc(unsigned char value)
|
||||
{
|
||||
return __builtin_ffs(value);
|
||||
}
|
||||
#else
|
||||
static inline unsigned int stdc_first_trailing_one_ull(unsigned long long value)
|
||||
{
|
||||
return value ? (1 + stdc_trailing_zeros_ull(value)) : 0;
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_first_trailing_one_ul(unsigned long value)
|
||||
{
|
||||
return value ? (1 + stdc_trailing_zeros_ul(value)) : 0;
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_first_trailing_one_ui(unsigned int value)
|
||||
{
|
||||
return value ? (1 + stdc_trailing_zeros_ui(value)) : 0;
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_first_trailing_one_us(unsigned short value)
|
||||
{
|
||||
return value ? (1 + stdc_trailing_zeros_us(value)) : 0;
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_first_trailing_one_uc(unsigned char value)
|
||||
{
|
||||
return value ? (1 + stdc_trailing_zeros_uc(value)) : 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define stdc_first_trailing_one(value) \
|
||||
__stdbit_generic_type_func(first_trailing_one, value)
|
||||
|
||||
static inline unsigned int stdc_first_trailing_zero_ull(unsigned long long value)
|
||||
{
|
||||
return stdc_first_trailing_one_ull(~value);
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_first_trailing_zero_ul(unsigned long value)
|
||||
{
|
||||
return stdc_first_trailing_one_ul(~value);
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_first_trailing_zero_ui(unsigned int value)
|
||||
{
|
||||
return stdc_first_trailing_one_ui(~value);
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_first_trailing_zero_us(unsigned short value)
|
||||
{
|
||||
return stdc_first_trailing_one_us(~value);
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_first_trailing_zero_uc(unsigned char value)
|
||||
{
|
||||
return stdc_first_trailing_one_uc(~value);
|
||||
}
|
||||
|
||||
#define stdc_first_trailing_zero(value) \
|
||||
__stdbit_generic_type_func(first_trailing_zero, value)
|
||||
|
||||
#if defined (__GNUC__) || defined (__clang__)
|
||||
static inline unsigned int stdc_count_ones_ull(unsigned long long value)
|
||||
{
|
||||
return __builtin_popcountll(value);
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_count_ones_ul(unsigned long value)
|
||||
{
|
||||
return __builtin_popcountl(value);
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_count_ones_ui(unsigned int value)
|
||||
{
|
||||
return __builtin_popcount(value);
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_count_ones_us(unsigned short value)
|
||||
{
|
||||
return __builtin_popcount(value);
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_count_ones_uc(unsigned char value)
|
||||
{
|
||||
return __builtin_popcount(value);
|
||||
}
|
||||
#else
|
||||
static inline unsigned int __stdc_count_ones(unsigned long long value,
|
||||
unsigned int size)
|
||||
{
|
||||
unsigned int ones = 0;
|
||||
|
||||
for (unsigned int c = 0; c < (size * CHAR_BIT); c++) {
|
||||
ones += value & 1;
|
||||
value >>= 1;
|
||||
}
|
||||
|
||||
return ones;
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_count_ones_ull(unsigned long long value)
|
||||
{
|
||||
return __stdc_count_ones(value, sizeof (value));
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_count_ones_ul(unsigned long value)
|
||||
{
|
||||
return __stdc_count_ones(value, sizeof (value));
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_count_ones_ui(unsigned int value)
|
||||
{
|
||||
return __stdc_count_ones(value, sizeof (value));
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_count_ones_us(unsigned short value)
|
||||
{
|
||||
return __stdc_count_ones(value, sizeof (value));
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_count_ones_uc(unsigned char value)
|
||||
{
|
||||
return __stdc_count_ones(value, sizeof (value));
|
||||
}
|
||||
#endif
|
||||
|
||||
#define stdc_count_ones(value) \
|
||||
__stdbit_generic_type_func(count_ones, value)
|
||||
|
||||
static inline unsigned int stdc_count_zeros_ull(unsigned long long value)
|
||||
{
|
||||
return stdc_count_ones_ull(~value);
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_count_zeros_ul(unsigned long value)
|
||||
{
|
||||
return stdc_count_ones_ul(~value);
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_count_zeros_ui(unsigned int value)
|
||||
{
|
||||
return stdc_count_ones_ui(~value);
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_count_zeros_us(unsigned short value)
|
||||
{
|
||||
return stdc_count_ones_us(~value);
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_count_zeros_uc(unsigned char value)
|
||||
{
|
||||
return stdc_count_ones_uc(~value);
|
||||
}
|
||||
|
||||
#define stdc_count_zeros(value) \
|
||||
__stdbit_generic_type_func(count_zeros, value)
|
||||
|
||||
static inline bool stdc_has_single_bit_ull(unsigned long long value)
|
||||
{
|
||||
return value && (value & (value - 1)) == 0;
|
||||
}
|
||||
|
||||
static inline bool stdc_has_single_bit_ul(unsigned long value)
|
||||
{
|
||||
return value && (value & (value - 1)) == 0;
|
||||
}
|
||||
|
||||
static inline bool stdc_has_single_bit_ui(unsigned int value)
|
||||
{
|
||||
return value && (value & (value - 1)) == 0;
|
||||
}
|
||||
|
||||
static inline bool stdc_has_single_bit_us(unsigned short value)
|
||||
{
|
||||
return value && (value & (value - 1)) == 0;
|
||||
}
|
||||
|
||||
static inline bool stdc_has_single_bit_uc(unsigned char value)
|
||||
{
|
||||
return value && (value & (value - 1)) == 0;
|
||||
}
|
||||
|
||||
#define stdc_has_single_bit(value) \
|
||||
__stdbit_generic_type_func(has_single_bit, value)
|
||||
|
||||
static inline unsigned int stdc_bit_width_ull(unsigned long long value)
|
||||
{
|
||||
return (CHAR_BIT * sizeof (value)) - stdc_leading_zeros_ull(value);
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_bit_width_ul(unsigned long value)
|
||||
{
|
||||
return (CHAR_BIT * sizeof (value)) - stdc_leading_zeros_ul(value);
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_bit_width_ui(unsigned int value)
|
||||
{
|
||||
return (CHAR_BIT * sizeof (value)) - stdc_leading_zeros_ui(value);
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_bit_width_us(unsigned short value)
|
||||
{
|
||||
return (CHAR_BIT * sizeof (value)) - stdc_leading_zeros_us(value);
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_bit_width_uc(unsigned char value)
|
||||
{
|
||||
return (CHAR_BIT * sizeof (value)) - stdc_leading_zeros_uc(value);
|
||||
}
|
||||
|
||||
#define stdc_bit_width(value) \
|
||||
__stdbit_generic_type_func(bit_width, value)
|
||||
|
||||
static inline unsigned long long stdc_bit_floor_ull(unsigned long long value)
|
||||
{
|
||||
return value ? (1ULL << (stdc_bit_width_ull(value) - 1)) : 0ULL;
|
||||
}
|
||||
|
||||
static inline unsigned long stdc_bit_floor_ul(unsigned long value)
|
||||
{
|
||||
return value ? (1UL << (stdc_bit_width_ul(value) - 1)) : 0UL;
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_bit_floor_ui(unsigned int value)
|
||||
{
|
||||
return value ? (1U << (stdc_bit_width_ui(value) - 1)) : 0U;
|
||||
}
|
||||
|
||||
static inline unsigned short stdc_bit_floor_us(unsigned short value)
|
||||
{
|
||||
return value ? (1U << (stdc_bit_width_us(value) - 1)) : 0U;
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_bit_floor_uc(unsigned char value)
|
||||
{
|
||||
return value ? (1U << (stdc_bit_width_uc(value) - 1)) : 0U;
|
||||
}
|
||||
|
||||
#define stdc_bit_floor(value) \
|
||||
__stdbit_generic_type_func(bit_floor, value)
|
||||
|
||||
/* NOTE: Bit ceiling undefines overflow. */
|
||||
static inline unsigned long long stdc_bit_ceil_ull(unsigned long long value)
|
||||
{
|
||||
return 1ULL << (value ? stdc_bit_width_ull(value - 1) : 0);
|
||||
}
|
||||
|
||||
static inline unsigned long stdc_bit_ceil_ul(unsigned long value)
|
||||
{
|
||||
return 1UL << (value ? stdc_bit_width_ul(value - 1) : 0);
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_bit_ceil_ui(unsigned int value)
|
||||
{
|
||||
return 1U << (value ? stdc_bit_width_ui(value - 1) : 0);
|
||||
}
|
||||
|
||||
static inline unsigned short stdc_bit_ceil_us(unsigned short value)
|
||||
{
|
||||
return 1U << (value ? stdc_bit_width_us(value - 1) : 0);
|
||||
}
|
||||
|
||||
static inline unsigned int stdc_bit_ceil_uc(unsigned char value)
|
||||
{
|
||||
return 1U << (value ? stdc_bit_width_uc(value - 1) : 0);
|
||||
}
|
||||
|
||||
#define stdc_bit_ceil(value) \
|
||||
__stdbit_generic_type_func(bit_ceil, value)
|
||||
|
||||
#endif /* __STDC_VERSION_STDBIT_H__ */
|
||||
@@ -26,7 +26,6 @@
|
||||
|
||||
#include "config.h"
|
||||
#include "libavutil/macros.h"
|
||||
#include "libavutil/mem.h"
|
||||
#include "libavutil/wchar_filename.h"
|
||||
|
||||
static inline wchar_t *get_module_filename(HMODULE module)
|
||||
|
||||
@@ -140,7 +140,6 @@ Component options:
|
||||
--disable-error-resilience disable error resilience code
|
||||
--disable-lsp disable LSP code
|
||||
--disable-faan disable floating point AAN (I)DCT code
|
||||
--disable-iamf disable support for Immersive Audio Model
|
||||
--disable-pixelutils disable pixel utils in libavutil
|
||||
|
||||
Individual component options:
|
||||
@@ -245,8 +244,6 @@ External library support:
|
||||
--enable-libjxl enable JPEG XL de/encoding via libjxl [no]
|
||||
--enable-libklvanc enable Kernel Labs VANC processing [no]
|
||||
--enable-libkvazaar enable HEVC encoding via libkvazaar [no]
|
||||
--enable-liblc3 enable LC3 de/encoding via liblc3 [no]
|
||||
--enable-liblcevc-dec enable LCEVC decoding via liblcevc-dec [no]
|
||||
--enable-liblensfun enable lensfun lens correction [no]
|
||||
--enable-libmodplug enable ModPlug via libmodplug [no]
|
||||
--enable-libmp3lame enable MP3 encoding via libmp3lame [no]
|
||||
@@ -254,7 +251,7 @@ External library support:
|
||||
--enable-libopencore-amrwb enable AMR-WB decoding via libopencore-amrwb [no]
|
||||
--enable-libopencv enable video filtering via libopencv [no]
|
||||
--enable-libopenh264 enable H.264 encoding via OpenH264 [no]
|
||||
--enable-libopenjpeg enable JPEG 2000 encoding via OpenJPEG [no]
|
||||
--enable-libopenjpeg enable JPEG 2000 de/encoding via OpenJPEG [no]
|
||||
--enable-libopenmpt enable decoding tracked files via libopenmpt [no]
|
||||
--enable-libopenvino enable OpenVINO as a DNN module backend
|
||||
for DNN based filters like dnn_processing [no]
|
||||
@@ -294,7 +291,6 @@ External library support:
|
||||
--enable-libvorbis enable Vorbis en/decoding via libvorbis,
|
||||
native implementation exists [no]
|
||||
--enable-libvpx enable VP8 and VP9 de/encoding via libvpx [no]
|
||||
--enable-libvvenc enable H.266/VVC encoding via vvenc [no]
|
||||
--enable-libwebp enable WebP encoding via libwebp [no]
|
||||
--enable-libx264 enable H.264 encoding via x264 [no]
|
||||
--enable-libx265 enable HEVC encoding via x265 [no]
|
||||
@@ -1930,8 +1926,6 @@ EXTERNAL_LIBRARY_LIST="
|
||||
libjxl
|
||||
libklvanc
|
||||
libkvazaar
|
||||
liblc3
|
||||
liblcevc_dec
|
||||
libmodplug
|
||||
libmp3lame
|
||||
libmysofa
|
||||
@@ -1969,7 +1963,6 @@ EXTERNAL_LIBRARY_LIST="
|
||||
libvmaf
|
||||
libvorbis
|
||||
libvpx
|
||||
libvvenc
|
||||
libwebp
|
||||
libxevd
|
||||
libxeve
|
||||
@@ -2077,7 +2070,6 @@ SUBSYSTEM_LIST="
|
||||
error_resilience
|
||||
faan
|
||||
fast_unaligned
|
||||
iamf
|
||||
lsp
|
||||
pixelutils
|
||||
network
|
||||
@@ -2119,6 +2111,8 @@ THREADS_LIST="
|
||||
"
|
||||
|
||||
ATOMICS_LIST="
|
||||
atomics_gcc
|
||||
atomics_suncc
|
||||
atomics_win32
|
||||
"
|
||||
|
||||
@@ -2130,7 +2124,12 @@ AUTODETECT_LIBS="
|
||||
|
||||
ARCH_LIST="
|
||||
aarch64
|
||||
alpha
|
||||
arm
|
||||
avr32
|
||||
avr32_ap
|
||||
avr32_uc
|
||||
bfin
|
||||
ia64
|
||||
loongarch
|
||||
loongarch32
|
||||
@@ -2143,6 +2142,7 @@ ARCH_LIST="
|
||||
ppc64
|
||||
riscv
|
||||
s390
|
||||
sh4
|
||||
sparc
|
||||
sparc64
|
||||
tilegx
|
||||
@@ -2218,8 +2218,6 @@ ARCH_EXT_LIST_PPC="
|
||||
ARCH_EXT_LIST_RISCV="
|
||||
rv
|
||||
rvv
|
||||
rv_zicbop
|
||||
rv_zvbb
|
||||
"
|
||||
|
||||
ARCH_EXT_LIST_X86="
|
||||
@@ -2249,10 +2247,13 @@ ARCH_FEATURES="
|
||||
"
|
||||
|
||||
BUILTIN_LIST="
|
||||
atomic_cas_ptr
|
||||
machine_rw_barrier
|
||||
MemoryBarrier
|
||||
mm_empty
|
||||
rdtsc
|
||||
sem_timedwait
|
||||
sync_val_compare_and_swap
|
||||
"
|
||||
HAVE_LIST_CMDLINE="
|
||||
inline_asm
|
||||
@@ -2267,7 +2268,6 @@ HAVE_LIST_PUB="
|
||||
|
||||
HEADERS_LIST="
|
||||
arpa_inet_h
|
||||
asm_hwprobe_h
|
||||
asm_types_h
|
||||
cdio_paranoia_h
|
||||
cdio_paranoia_paranoia_h
|
||||
@@ -2294,7 +2294,6 @@ HEADERS_LIST="
|
||||
OpenGL_gl3_h
|
||||
poll_h
|
||||
pthread_np_h
|
||||
sys_hwprobe_h
|
||||
sys_param_h
|
||||
sys_resource_h
|
||||
sys_select_h
|
||||
@@ -2312,7 +2311,6 @@ HEADERS_LIST="
|
||||
|
||||
INTRINSICS_LIST="
|
||||
intrinsics_neon
|
||||
intrinsics_sse2
|
||||
"
|
||||
|
||||
MATH_FUNCS="
|
||||
@@ -2364,7 +2362,6 @@ SYSTEM_FUNCS="
|
||||
clock_gettime
|
||||
closesocket
|
||||
CommandLineToArgvW
|
||||
elf_aux_info
|
||||
fcntl
|
||||
getaddrinfo
|
||||
getauxval
|
||||
@@ -2413,7 +2410,6 @@ SYSTEM_FUNCS="
|
||||
sysconf
|
||||
sysctl
|
||||
sysctlbyname
|
||||
tempnam
|
||||
usleep
|
||||
UTGetOSTypeFromString
|
||||
VirtualAlloc
|
||||
@@ -2489,7 +2485,6 @@ TYPES_LIST="
|
||||
struct_sockaddr_storage
|
||||
struct_stat_st_mtim_tv_nsec
|
||||
struct_v4l2_frmivalenum_discrete
|
||||
struct_mfxConfigInterface
|
||||
"
|
||||
|
||||
HAVE_LIST="
|
||||
@@ -2522,7 +2517,6 @@ HAVE_LIST="
|
||||
opencl_videotoolbox
|
||||
perl
|
||||
pod2man
|
||||
posix_ioctl
|
||||
texi2html
|
||||
xmllint
|
||||
zlib_gzip
|
||||
@@ -2549,12 +2543,10 @@ CONFIG_EXTRA="
|
||||
cbs_mpeg2
|
||||
cbs_vp8
|
||||
cbs_vp9
|
||||
d3d12va_encode
|
||||
deflate_wrapper
|
||||
dirac_parse
|
||||
dnn
|
||||
dovi_rpudec
|
||||
dovi_rpuenc
|
||||
dovi_rpu
|
||||
dvprofile
|
||||
evcparse
|
||||
exif
|
||||
@@ -2586,7 +2578,6 @@ CONFIG_EXTRA="
|
||||
inflate_wrapper
|
||||
intrax8
|
||||
iso_media
|
||||
iso_writer
|
||||
ividsp
|
||||
jpegtables
|
||||
lgplv3
|
||||
@@ -2636,7 +2627,6 @@ CONFIG_EXTRA="
|
||||
vp3dsp
|
||||
vp56dsp
|
||||
vp8dsp
|
||||
vulkan_encode
|
||||
wma_freqs
|
||||
wmv2dsp
|
||||
"
|
||||
@@ -2746,7 +2736,6 @@ armv6t2_deps="arm"
|
||||
armv8_deps="aarch64"
|
||||
neon_deps_any="aarch64 arm"
|
||||
intrinsics_neon_deps="neon"
|
||||
intrinsics_sse2_deps="sse2"
|
||||
vfp_deps="arm"
|
||||
vfpv3_deps="vfp"
|
||||
setend_deps="arm"
|
||||
@@ -2764,8 +2753,6 @@ power8_deps="vsx"
|
||||
|
||||
rv_deps="riscv"
|
||||
rvv_deps="rv"
|
||||
rv_zicbop="riscv"
|
||||
rv_zvbb_deps="rvv"
|
||||
|
||||
loongson2_deps="mips"
|
||||
loongson3_deps="mips"
|
||||
@@ -2818,8 +2805,8 @@ for ext in $(filter_out mmx $ARCH_EXT_LIST_X86_SIMD); do
|
||||
done
|
||||
|
||||
aligned_stack_if_any="aarch64 ppc x86"
|
||||
fast_64bit_if_any="aarch64 ia64 mips64 parisc64 ppc64 riscv64 sparc64 x86_64"
|
||||
fast_clz_if_any="aarch64 mips ppc x86"
|
||||
fast_64bit_if_any="aarch64 alpha ia64 mips64 parisc64 ppc64 riscv64 sparc64 x86_64"
|
||||
fast_clz_if_any="aarch64 alpha avr32 mips ppc x86"
|
||||
fast_unaligned_if_any="aarch64 ppc x86"
|
||||
simd_align_16_if_any="altivec neon sse"
|
||||
simd_align_32_if_any="avx"
|
||||
@@ -2832,6 +2819,8 @@ valgrind_backtrace_conflict="optimizations"
|
||||
valgrind_backtrace_deps="valgrind_valgrind_h"
|
||||
|
||||
# threading support
|
||||
atomics_gcc_if="sync_val_compare_and_swap"
|
||||
atomics_suncc_if="atomic_cas_ptr machine_rw_barrier"
|
||||
atomics_win32_if="MemoryBarrier"
|
||||
atomics_native_if_any="$ATOMICS_LIST"
|
||||
w32threads_deps="atomics_native"
|
||||
@@ -2848,10 +2837,9 @@ cbs_vp8_select="cbs"
|
||||
cbs_vp9_select="cbs"
|
||||
deflate_wrapper_deps="zlib"
|
||||
dirac_parse_select="golomb"
|
||||
dovi_rpudec_select="golomb"
|
||||
dovi_rpuenc_select="golomb"
|
||||
dovi_rpu_select="golomb"
|
||||
dnn_suggest="libtensorflow libopenvino libtorch"
|
||||
dnn_deps="avformat swscale"
|
||||
dnn_deps_any="libtensorflow libopenvino libtorch"
|
||||
error_resilience_select="me_cmp"
|
||||
evcparse_select="golomb"
|
||||
faandct_deps="faan"
|
||||
@@ -2859,14 +2847,11 @@ faandct_select="fdctdsp"
|
||||
faanidct_deps="faan"
|
||||
faanidct_select="idctdsp"
|
||||
h264dsp_select="startcode"
|
||||
h264parse_select="golomb"
|
||||
h264_sei_select="atsc_a53 golomb"
|
||||
hevcparse_select="golomb"
|
||||
hevc_sei_select="atsc_a53 golomb"
|
||||
frame_thread_encoder_deps="encoders threads"
|
||||
iamfdec_deps="iamf"
|
||||
iamfdec_select="iso_media mpeg4audio"
|
||||
iamfenc_deps="iamf"
|
||||
inflate_wrapper_deps="zlib"
|
||||
intrax8_select="blockdsp wmv2dsp"
|
||||
iso_media_select="mpeg4audio"
|
||||
@@ -2879,7 +2864,6 @@ mpegvideoenc_select="aandcttables fdctdsp me_cmp mpegvideo pixblockdsp"
|
||||
msmpeg4dec_select="h263_decoder"
|
||||
msmpeg4enc_select="h263_encoder"
|
||||
vc1dsp_select="h264chroma qpeldsp startcode"
|
||||
wmv2dsp_select="qpeldsp"
|
||||
|
||||
# decoders / encoders
|
||||
aac_decoder_select="adts_header mpeg4audio sinewin"
|
||||
@@ -2911,9 +2895,7 @@ asv1_encoder_select="aandcttables bswapdsp fdctdsp pixblockdsp"
|
||||
asv2_decoder_select="blockdsp bswapdsp idctdsp"
|
||||
asv2_encoder_select="aandcttables bswapdsp fdctdsp pixblockdsp"
|
||||
atrac1_decoder_select="sinewin"
|
||||
atrac3p_decoder_select="sinewin"
|
||||
atrac3pal_decoder_select="sinewin"
|
||||
av1_decoder_select="atsc_a53 cbs_av1 dovi_rpudec"
|
||||
av1_decoder_select="atsc_a53 cbs_av1 dovi_rpu"
|
||||
bink_decoder_select="blockdsp hpeldsp"
|
||||
binkaudio_dct_decoder_select="wma_freqs"
|
||||
binkaudio_rdft_decoder_select="wma_freqs"
|
||||
@@ -2925,7 +2907,7 @@ cook_decoder_select="audiodsp sinewin"
|
||||
cri_decoder_select="mjpeg_decoder"
|
||||
cscd_decoder_suggest="zlib"
|
||||
dds_decoder_select="texturedsp"
|
||||
dirac_decoder_select="dirac_parse dwt golomb mpegvideoenc qpeldsp videodsp"
|
||||
dirac_decoder_select="dirac_parse dwt golomb videodsp mpegvideoenc"
|
||||
dnxhd_decoder_select="blockdsp idctdsp"
|
||||
dnxhd_encoder_select="blockdsp fdctdsp idctdsp mpegvideoenc pixblockdsp videodsp"
|
||||
dvvideo_decoder_select="dvprofile idctdsp"
|
||||
@@ -2954,7 +2936,6 @@ flv_decoder_select="h263_decoder"
|
||||
flv_encoder_select="h263_encoder"
|
||||
fourxm_decoder_select="blockdsp bswapdsp"
|
||||
fraps_decoder_select="bswapdsp huffman"
|
||||
ftr_decoder_select="adts_header"
|
||||
g2m_decoder_deps="zlib"
|
||||
g2m_decoder_select="blockdsp idctdsp jpegtables"
|
||||
g729_decoder_select="audiodsp"
|
||||
@@ -2970,7 +2951,7 @@ h264_decoder_suggest="error_resilience"
|
||||
hap_decoder_select="snappy texturedsp"
|
||||
hap_encoder_deps="libsnappy"
|
||||
hap_encoder_select="texturedspenc"
|
||||
hevc_decoder_select="bswapdsp cabac dovi_rpudec golomb hevcparse hevc_sei videodsp"
|
||||
hevc_decoder_select="bswapdsp cabac dovi_rpu golomb hevcparse hevc_sei videodsp"
|
||||
huffyuv_decoder_select="bswapdsp huffyuvdsp llviddsp"
|
||||
huffyuv_encoder_select="bswapdsp huffman huffyuvencdsp llvidencdsp"
|
||||
hymt_decoder_select="huffyuv_decoder"
|
||||
@@ -3019,7 +3000,7 @@ mpeg1video_decoder_select="mpegvideodec"
|
||||
mpeg1video_encoder_select="mpegvideoenc"
|
||||
mpeg2video_decoder_select="mpegvideodec"
|
||||
mpeg2video_encoder_select="mpegvideoenc"
|
||||
mpeg4_decoder_select="h263_decoder"
|
||||
mpeg4_decoder_select="h263_decoder mpeg4video_parser"
|
||||
mpeg4_encoder_select="h263_encoder qpeldsp"
|
||||
msa1_decoder_select="mss34dsp"
|
||||
mscc_decoder_select="inflate_wrapper"
|
||||
@@ -3040,7 +3021,7 @@ notchlc_decoder_select="lzf"
|
||||
nuv_decoder_select="idctdsp"
|
||||
opus_decoder_deps="swresample"
|
||||
opus_encoder_select="audio_frame_queue"
|
||||
pdv_decoder_select="inflate_wrapper"
|
||||
pdv_decoder_deps="zlib"
|
||||
png_decoder_select="inflate_wrapper"
|
||||
png_encoder_select="deflate_wrapper llvidencdsp"
|
||||
prores_decoder_select="blockdsp idctdsp"
|
||||
@@ -3144,7 +3125,7 @@ d3d11va_deps="dxva_h ID3D11VideoDecoder ID3D11VideoContext"
|
||||
d3d12va_deps="dxva_h ID3D12Device ID3D12VideoDecoder"
|
||||
dxva2_deps="dxva2api_h DXVA2_ConfigPictureDecode ole32 user32"
|
||||
ffnvcodec_deps_any="libdl LoadLibrary"
|
||||
mediacodec_deps="android mediandk"
|
||||
mediacodec_deps="android"
|
||||
nvdec_deps="ffnvcodec"
|
||||
vaapi_x11_deps="xlib_x11"
|
||||
videotoolbox_hwaccel_deps="videotoolbox pthreads"
|
||||
@@ -3287,7 +3268,6 @@ wmv3_vaapi_hwaccel_select="vc1_vaapi_hwaccel"
|
||||
wmv3_vdpau_hwaccel_select="vc1_vdpau_hwaccel"
|
||||
|
||||
# hardware-accelerated codecs
|
||||
d3d12va_encode_deps="d3d12va ID3D12VideoEncoder d3d12_encoder_feature"
|
||||
mediafoundation_deps="mftransform_h MFCreateAlignedMemoryBuffer"
|
||||
omx_deps="libdl pthreads"
|
||||
omx_rpi_select="omx"
|
||||
@@ -3296,7 +3276,6 @@ qsvdec_select="qsv"
|
||||
qsvenc_select="qsv"
|
||||
qsvvpp_select="qsv"
|
||||
vaapi_encode_deps="vaapi"
|
||||
vulkan_encode_deps="vulkan"
|
||||
v4l2_m2m_deps="linux_videodev2_h sem_timedwait"
|
||||
|
||||
bilateral_cuda_filter_deps="ffnvcodec"
|
||||
@@ -3323,26 +3302,13 @@ amf_deps_any="libdl LoadLibrary"
|
||||
nvenc_deps="ffnvcodec"
|
||||
nvenc_deps_any="libdl LoadLibrary"
|
||||
|
||||
aac_mediacodec_decoder_deps="mediacodec"
|
||||
aac_mediacodec_decoder_select="aac_adtstoasc_bsf aac_parser"
|
||||
aac_mf_encoder_deps="mediafoundation"
|
||||
ac3_mf_encoder_deps="mediafoundation"
|
||||
amrnb_mediacodec_decoder_deps="mediacodec"
|
||||
amrnb_mediacodec_decoder_select="amr_parser"
|
||||
amrwb_mediacodec_decoder_deps="mediacodec"
|
||||
amrwb_mediacodec_decoder_select="amr_parser"
|
||||
av1_amf_encoder_deps="amf"
|
||||
av1_cuvid_decoder_deps="cuvid CUVIDAV1PICPARAMS"
|
||||
av1_mediacodec_decoder_deps="mediacodec"
|
||||
av1_mediacodec_encoder_deps="mediacodec"
|
||||
av1_mediacodec_encoder_select="extract_extradata_bsf"
|
||||
av1_nvenc_encoder_deps="nvenc NV_ENC_PIC_PARAMS_AV1"
|
||||
av1_nvenc_encoder_select="atsc_a53"
|
||||
av1_qsv_decoder_select="qsvdec"
|
||||
av1_qsv_encoder_deps="libvpl"
|
||||
av1_qsv_encoder_select="qsvenc"
|
||||
av1_vaapi_encoder_deps="VAEncPictureParameterBufferAV1"
|
||||
av1_vaapi_encoder_select="cbs_av1 vaapi_encode"
|
||||
h263_v4l2m2m_decoder_deps="v4l2_m2m h263_v4l2_m2m"
|
||||
h263_v4l2m2m_encoder_deps="v4l2_m2m h263_v4l2_m2m"
|
||||
h264_amf_encoder_deps="amf"
|
||||
@@ -3351,7 +3317,7 @@ h264_cuvid_decoder_select="h264_mp4toannexb_bsf"
|
||||
h264_mediacodec_decoder_deps="mediacodec"
|
||||
h264_mediacodec_decoder_select="h264_mp4toannexb_bsf h264_parser"
|
||||
h264_mediacodec_encoder_deps="mediacodec"
|
||||
h264_mediacodec_encoder_select="extract_extradata_bsf h264_metadata"
|
||||
h264_mediacodec_encoder_select="h264_metadata"
|
||||
h264_mf_encoder_deps="mediafoundation"
|
||||
h264_mmal_decoder_deps="mmal"
|
||||
h264_nvenc_encoder_deps="nvenc"
|
||||
@@ -3362,18 +3328,16 @@ h264_qsv_encoder_select="atsc_a53 qsvenc"
|
||||
h264_rkmpp_decoder_deps="rkmpp"
|
||||
h264_rkmpp_decoder_select="h264_mp4toannexb_bsf"
|
||||
h264_vaapi_encoder_select="atsc_a53 cbs_h264 vaapi_encode"
|
||||
h264_vulkan_encoder_select="cbs_h264 vulkan_encode"
|
||||
h264_v4l2m2m_decoder_deps="v4l2_m2m h264_v4l2_m2m"
|
||||
h264_v4l2m2m_decoder_select="h264_mp4toannexb_bsf"
|
||||
h264_v4l2m2m_encoder_deps="v4l2_m2m h264_v4l2_m2m"
|
||||
hevc_amf_encoder_deps="amf"
|
||||
hevc_cuvid_decoder_deps="cuvid"
|
||||
hevc_cuvid_decoder_select="hevc_mp4toannexb_bsf"
|
||||
hevc_d3d12va_encoder_select="cbs_h265 d3d12va_encode"
|
||||
hevc_mediacodec_decoder_deps="mediacodec"
|
||||
hevc_mediacodec_decoder_select="hevc_mp4toannexb_bsf hevc_parser"
|
||||
hevc_mediacodec_encoder_deps="mediacodec"
|
||||
hevc_mediacodec_encoder_select="extract_extradata_bsf hevc_metadata"
|
||||
hevc_mediacodec_encoder_select="hevc_metadata"
|
||||
hevc_mf_encoder_deps="mediafoundation"
|
||||
hevc_nvenc_encoder_deps="nvenc"
|
||||
hevc_nvenc_encoder_select="atsc_a53"
|
||||
@@ -3383,7 +3347,6 @@ hevc_rkmpp_decoder_deps="rkmpp"
|
||||
hevc_rkmpp_decoder_select="hevc_mp4toannexb_bsf"
|
||||
hevc_vaapi_encoder_deps="VAEncPictureParameterBufferHEVC"
|
||||
hevc_vaapi_encoder_select="atsc_a53 cbs_h265 vaapi_encode"
|
||||
hevc_vulkan_encoder_select="atsc_a53 cbs_h265 vulkan_encode"
|
||||
hevc_v4l2m2m_decoder_deps="v4l2_m2m hevc_v4l2_m2m"
|
||||
hevc_v4l2m2m_decoder_select="hevc_mp4toannexb_bsf"
|
||||
hevc_v4l2m2m_encoder_deps="v4l2_m2m hevc_v4l2_m2m"
|
||||
@@ -3394,8 +3357,6 @@ mjpeg_qsv_encoder_select="qsvenc"
|
||||
mjpeg_vaapi_encoder_deps="VAEncPictureParameterBufferJPEG"
|
||||
mjpeg_vaapi_encoder_select="cbs_jpeg jpegtables vaapi_encode"
|
||||
mp3_mf_encoder_deps="mediafoundation"
|
||||
mp3_mediacodec_decoder_deps="mediacodec"
|
||||
mp3_mediacodec_decoder_select="mpegaudioheader"
|
||||
mpeg1_cuvid_decoder_deps="cuvid"
|
||||
mpeg1_v4l2m2m_decoder_deps="v4l2_m2m mpeg1_v4l2_m2m"
|
||||
mpeg2_cuvid_decoder_deps="cuvid"
|
||||
@@ -3408,7 +3369,6 @@ mpeg2_v4l2m2m_decoder_deps="v4l2_m2m mpeg2_v4l2_m2m"
|
||||
mpeg4_cuvid_decoder_deps="cuvid"
|
||||
mpeg4_mediacodec_decoder_deps="mediacodec"
|
||||
mpeg4_mediacodec_encoder_deps="mediacodec"
|
||||
mpeg4_mediacodec_encoder_select="extract_extradata_bsf"
|
||||
mpeg4_mmal_decoder_deps="mmal"
|
||||
mpeg4_omx_encoder_deps="omx"
|
||||
mpeg4_v4l2m2m_decoder_deps="v4l2_m2m mpeg4_v4l2_m2m"
|
||||
@@ -3436,13 +3396,17 @@ vp9_vaapi_encoder_select="vaapi_encode"
|
||||
vp9_qsv_encoder_deps="libmfx MFX_CODEC_VP9"
|
||||
vp9_qsv_encoder_select="qsvenc"
|
||||
vp9_v4l2m2m_decoder_deps="v4l2_m2m vp9_v4l2_m2m"
|
||||
vvc_qsv_decoder_select="vvc_mp4toannexb_bsf qsvdec"
|
||||
av1_qsv_decoder_select="qsvdec"
|
||||
av1_qsv_encoder_select="qsvenc"
|
||||
av1_qsv_encoder_deps="libvpl"
|
||||
av1_amf_encoder_deps="amf"
|
||||
av1_vaapi_encoder_deps="VAEncPictureParameterBufferAV1"
|
||||
av1_vaapi_encoder_select="cbs_av1 vaapi_encode"
|
||||
|
||||
# parsers
|
||||
aac_parser_select="adts_header mpeg4audio"
|
||||
av1_parser_select="cbs_av1"
|
||||
evc_parser_select="evcparse"
|
||||
ftr_parser_select="adts_header mpeg4audio"
|
||||
h264_parser_select="golomb h264dsp h264parse h264_sei"
|
||||
hevc_parser_select="hevcparse hevc_sei"
|
||||
mpegaudio_parser_select="mpegaudioheader"
|
||||
@@ -3455,7 +3419,6 @@ aac_adtstoasc_bsf_select="adts_header mpeg4audio"
|
||||
av1_frame_merge_bsf_select="cbs_av1"
|
||||
av1_frame_split_bsf_select="cbs_av1"
|
||||
av1_metadata_bsf_select="cbs_av1"
|
||||
dovi_rpu_bsf_select="cbs_h265 cbs_av1 dovi_rpudec dovi_rpuenc"
|
||||
dts2pts_bsf_select="cbs_h264 h264parse"
|
||||
eac3_core_bsf_select="ac3_parser"
|
||||
evc_frame_merge_bsf_select="evcparse"
|
||||
@@ -3514,14 +3477,14 @@ prores_videotoolbox_encoder_deps="pthreads"
|
||||
prores_videotoolbox_encoder_select="videotoolbox_encoder"
|
||||
libaom_av1_decoder_deps="libaom"
|
||||
libaom_av1_encoder_deps="libaom"
|
||||
libaom_av1_encoder_select="extract_extradata_bsf dovi_rpuenc"
|
||||
libaom_av1_encoder_select="extract_extradata_bsf"
|
||||
libaribb24_decoder_deps="libaribb24"
|
||||
libaribcaption_decoder_deps="libaribcaption"
|
||||
libcelt_decoder_deps="libcelt"
|
||||
libcodec2_decoder_deps="libcodec2"
|
||||
libcodec2_encoder_deps="libcodec2"
|
||||
libdav1d_decoder_deps="libdav1d"
|
||||
libdav1d_decoder_select="atsc_a53 dovi_rpudec"
|
||||
libdav1d_decoder_select="atsc_a53 dovi_rpu"
|
||||
libdavs2_decoder_deps="libdavs2"
|
||||
libdavs2_decoder_select="avs2_parser"
|
||||
libfdk_aac_decoder_deps="libfdk_aac"
|
||||
@@ -3537,9 +3500,6 @@ libilbc_encoder_deps="libilbc"
|
||||
libjxl_decoder_deps="libjxl libjxl_threads"
|
||||
libjxl_encoder_deps="libjxl libjxl_threads"
|
||||
libkvazaar_encoder_deps="libkvazaar"
|
||||
liblc3_decoder_deps="liblc3"
|
||||
liblc3_encoder_deps="liblc3"
|
||||
liblc3_encoder_select="audio_frame_queue"
|
||||
libmodplug_demuxer_deps="libmodplug"
|
||||
libmp3lame_encoder_deps="libmp3lame"
|
||||
libmp3lame_encoder_select="audio_frame_queue mpegaudioheader"
|
||||
@@ -3563,7 +3523,6 @@ libspeex_decoder_deps="libspeex"
|
||||
libspeex_encoder_deps="libspeex"
|
||||
libspeex_encoder_select="audio_frame_queue"
|
||||
libsvtav1_encoder_deps="libsvtav1"
|
||||
libsvtav1_encoder_select="dovi_rpuenc"
|
||||
libtheora_encoder_deps="libtheora"
|
||||
libtwolame_encoder_deps="libtwolame"
|
||||
libuavs3d_decoder_deps="libuavs3d"
|
||||
@@ -3575,7 +3534,6 @@ libvpx_vp8_decoder_deps="libvpx"
|
||||
libvpx_vp8_encoder_deps="libvpx"
|
||||
libvpx_vp9_decoder_deps="libvpx"
|
||||
libvpx_vp9_encoder_deps="libvpx"
|
||||
libvvenc_encoder_deps="libvvenc"
|
||||
libwebp_encoder_deps="libwebp"
|
||||
libwebp_anim_encoder_deps="libwebp"
|
||||
libx262_encoder_deps="libx262"
|
||||
@@ -3584,7 +3542,7 @@ libx264_encoder_select="atsc_a53 golomb"
|
||||
libx264rgb_encoder_deps="libx264"
|
||||
libx264rgb_encoder_select="libx264_encoder"
|
||||
libx265_encoder_deps="libx265"
|
||||
libx265_encoder_select="atsc_a53 dovi_rpuenc"
|
||||
libx265_encoder_select="atsc_a53"
|
||||
libxavs_encoder_deps="libxavs"
|
||||
libxavs2_encoder_deps="libxavs2"
|
||||
libxevd_decoder_deps="libxevd"
|
||||
@@ -3628,7 +3586,7 @@ evc_demuxer_select="evc_frame_merge_bsf evc_parser"
|
||||
f4v_muxer_select="mov_muxer"
|
||||
fifo_muxer_deps="threads"
|
||||
flac_demuxer_select="flac_parser"
|
||||
flv_muxer_select="aac_adtstoasc_bsf iso_writer"
|
||||
flv_muxer_select="aac_adtstoasc_bsf"
|
||||
gxf_muxer_select="pcm_rechunk_bsf"
|
||||
hds_muxer_select="flv_muxer"
|
||||
hls_demuxer_select="aac_demuxer ac3_demuxer adts_header ac3_parser eac3_demuxer mov_demuxer mpegts_demuxer"
|
||||
@@ -3646,20 +3604,19 @@ latm_muxer_select="aac_adtstoasc_bsf mpeg4audio"
|
||||
matroska_audio_muxer_select="matroska_muxer"
|
||||
matroska_demuxer_select="riffdec"
|
||||
matroska_demuxer_suggest="bzlib zlib"
|
||||
matroska_muxer_select="iso_writer mpeg4audio riffenc aac_adtstoasc_bsf pgs_frame_merge_bsf vp9_superframe_bsf"
|
||||
matroska_muxer_select="mpeg4audio riffenc aac_adtstoasc_bsf pgs_frame_merge_bsf vp9_superframe_bsf"
|
||||
mlp_demuxer_select="mlp_parser"
|
||||
mmf_muxer_select="riffenc"
|
||||
mov_demuxer_select="iso_media riffdec"
|
||||
mov_demuxer_suggest="iamfdec zlib"
|
||||
mov_muxer_select="iso_media iso_writer riffenc rtpenc_chain vp9_superframe_bsf aac_adtstoasc_bsf ac3_parser"
|
||||
mov_muxer_suggest="iamfenc"
|
||||
mov_demuxer_select="iso_media riffdec iamfdec"
|
||||
mov_demuxer_suggest="zlib"
|
||||
mov_muxer_select="iso_media riffenc rtpenc_chain vp9_superframe_bsf aac_adtstoasc_bsf ac3_parser iamfenc"
|
||||
mp3_demuxer_select="mpegaudio_parser"
|
||||
mp3_muxer_select="mpegaudioheader"
|
||||
mp4_muxer_select="mov_muxer"
|
||||
mpegts_demuxer_select="iso_media"
|
||||
mpegts_muxer_select="ac3_parser adts_muxer latm_muxer h264_mp4toannexb_bsf hevc_mp4toannexb_bsf vvc_mp4toannexb_bsf"
|
||||
mpegtsraw_demuxer_select="mpegts_demuxer"
|
||||
mxf_muxer_select="iso_writer pcm_rechunk_bsf rangecoder"
|
||||
mxf_muxer_select="pcm_rechunk_bsf rangecoder"
|
||||
mxf_d10_muxer_select="mxf_muxer"
|
||||
mxf_opatom_muxer_select="mxf_muxer"
|
||||
nut_muxer_select="riffenc"
|
||||
@@ -3672,7 +3629,6 @@ ogv_muxer_select="ogg_muxer"
|
||||
opus_muxer_select="ogg_muxer"
|
||||
psp_muxer_select="mov_muxer"
|
||||
rtp_demuxer_select="sdp_demuxer"
|
||||
rtp_muxer_select="iso_writer"
|
||||
rtp_mpegts_muxer_select="mpegts_muxer rtp_muxer"
|
||||
rtpdec_select="asf_demuxer mov_demuxer mpegts_demuxer rm_demuxer rtp_protocol srtp"
|
||||
rtsp_demuxer_select="http_protocol rtpdec"
|
||||
@@ -3884,11 +3840,9 @@ histeq_filter_deps="gpl"
|
||||
hqdn3d_filter_deps="gpl"
|
||||
iccdetect_filter_deps="lcms2"
|
||||
iccgen_filter_deps="lcms2"
|
||||
identity_filter_select="scene_sad"
|
||||
interlace_filter_deps="gpl"
|
||||
kerndeint_filter_deps="gpl"
|
||||
ladspa_filter_deps="ladspa libdl"
|
||||
lcevc_filter_deps="liblcevc_dec"
|
||||
lensfun_filter_deps="liblensfun version3"
|
||||
libplacebo_filter_deps="libplacebo vulkan"
|
||||
lv2_filter_deps="lv2"
|
||||
@@ -3992,8 +3946,6 @@ vstack_qsv_filter_deps="libmfx"
|
||||
vstack_qsv_filter_select="qsvvpp"
|
||||
xstack_qsv_filter_deps="libmfx"
|
||||
xstack_qsv_filter_select="qsvvpp"
|
||||
pad_vaapi_filter_deps="vaapi_1"
|
||||
drawbox_vaapi_filter_deps="vaapi_1"
|
||||
|
||||
# examples
|
||||
avio_http_serve_files_deps="avformat avutil fork"
|
||||
@@ -4027,7 +3979,7 @@ cws2fws_extralibs="zlib_extralibs"
|
||||
|
||||
# libraries, in any order
|
||||
avcodec_deps="avutil"
|
||||
avcodec_suggest="libm stdatomic liblcevc_dec"
|
||||
avcodec_suggest="libm stdatomic"
|
||||
avdevice_deps="avformat avcodec avutil"
|
||||
avdevice_suggest="libm stdatomic"
|
||||
avfilter_deps="avutil"
|
||||
@@ -4048,8 +4000,8 @@ avutil_extralibs="d3d11va_extralibs d3d12va_extralibs mediacodec_extralibs nanos
|
||||
|
||||
# programs
|
||||
ffmpeg_deps="avcodec avfilter avformat threads"
|
||||
ffmpeg_select="aformat_filter anull_filter atrim_filter crop_filter
|
||||
format_filter hflip_filter null_filter rotate_filter
|
||||
ffmpeg_select="aformat_filter anull_filter atrim_filter format_filter
|
||||
hflip_filter null_filter
|
||||
transpose_filter trim_filter vflip_filter"
|
||||
ffmpeg_suggest="ole32 psapi shell32"
|
||||
ffplay_deps="avcodec avformat avfilter swscale swresample sdl2"
|
||||
@@ -4128,7 +4080,6 @@ enable asm
|
||||
enable debug
|
||||
enable doc
|
||||
enable faan faandct faanidct
|
||||
enable iamf
|
||||
enable large_tests
|
||||
enable optimizations
|
||||
enable ptx_compression
|
||||
@@ -4549,49 +4500,37 @@ enabled ossfuzz && ! echo $CFLAGS | grep -q -- "-fsanitize=" && ! echo $CFLAGS
|
||||
add_ldflags -fsanitize=address,undefined -fsanitize-coverage=trace-pc-guard,trace-cmp
|
||||
}
|
||||
|
||||
add_sanitizer_flags(){
|
||||
case "$1" in
|
||||
asan)
|
||||
add_cflags -fsanitize=address
|
||||
add_ldflags -fsanitize=address
|
||||
;;
|
||||
lsan)
|
||||
add_cflags -fsanitize=leak
|
||||
add_ldflags -fsanitize=leak
|
||||
;;
|
||||
msan)
|
||||
add_cflags -fsanitize=memory -fsanitize-memory-track-origins
|
||||
add_ldflags -fsanitize=memory
|
||||
;;
|
||||
tsan)
|
||||
add_cflags -fsanitize=thread
|
||||
add_ldflags -fsanitize=thread
|
||||
;;
|
||||
usan)
|
||||
add_cflags -fsanitize=undefined
|
||||
add_ldflags -fsanitize=undefined
|
||||
;;
|
||||
?*)
|
||||
die "Unknown sanitizer $1"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
case "$toolchain" in
|
||||
clang-*)
|
||||
add_sanitizer_flags "${toolchain#clang-}"
|
||||
cc_default="clang"
|
||||
cxx_default="clang++"
|
||||
*-asan)
|
||||
cc_default="${toolchain%-asan}"
|
||||
add_cflags -fsanitize=address
|
||||
add_ldflags -fsanitize=address
|
||||
;;
|
||||
gcc-*)
|
||||
add_sanitizer_flags "${toolchain#gcc-}"
|
||||
cc_default="gcc"
|
||||
cxx_default="g++"
|
||||
# In case of tsan with gcc, PIC has to be enabled
|
||||
if [ "${toolchain#gcc-}" = "tsan" ]; then
|
||||
add_cflags -fPIC
|
||||
add_ldflags -fPIC
|
||||
fi
|
||||
*-lsan)
|
||||
cc_default="${toolchain%-lsan}"
|
||||
add_cflags -fsanitize=leak
|
||||
add_ldflags -fsanitize=leak
|
||||
;;
|
||||
*-msan)
|
||||
cc_default="${toolchain%-msan}"
|
||||
add_cflags -fsanitize=memory -fsanitize-memory-track-origins
|
||||
add_ldflags -fsanitize=memory
|
||||
;;
|
||||
*-tsan)
|
||||
cc_default="${toolchain%-tsan}"
|
||||
add_cflags -fsanitize=thread
|
||||
add_ldflags -fsanitize=thread
|
||||
case "$toolchain" in
|
||||
gcc-tsan)
|
||||
add_cflags -fPIC
|
||||
add_ldflags -fPIC
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*-usan)
|
||||
cc_default="${toolchain%-usan}"
|
||||
add_cflags -fsanitize=undefined
|
||||
add_ldflags -fsanitize=undefined
|
||||
;;
|
||||
valgrind-*)
|
||||
target_exec_default="valgrind"
|
||||
@@ -4787,7 +4726,7 @@ chmod +x $TMPE
|
||||
|
||||
# make sure we can execute files in $TMPDIR
|
||||
cat > $TMPSH 2>> $logfile <<EOF
|
||||
#!/bin/sh
|
||||
#! /bin/sh
|
||||
EOF
|
||||
chmod +x $TMPSH >> $logfile 2>&1
|
||||
if ! $TMPSH >> $logfile 2>&1; then
|
||||
@@ -5079,12 +5018,7 @@ probe_cc(){
|
||||
else
|
||||
_ident=$($_cc --version 2>/dev/null | head -n1 | tr -d '\r')
|
||||
fi
|
||||
if [ -x "$(command -v wslpath)" ]; then
|
||||
_DEPCMD='$(DEP$(1)) $(DEP$(1)FLAGS) $($(1)DEP_FLAGS) $< 2>&1 | awk '\''/including/ { sub(/^.*file: */, ""); if (!match($$0, / /)) { print $$0 } }'\'' | xargs -r -d\\n -n1 wslpath -u | awk '\''BEGIN { printf "%s:", "$@" }; { sub(/\r/,""); printf " %s", $$0 }; END { print "" }'\'' > $(@:.o=.d)'
|
||||
|
||||
else
|
||||
_DEPCMD='$(DEP$(1)) $(DEP$(1)FLAGS) $($(1)DEP_FLAGS) $< 2>&1 | awk '\''/including/ { sub(/^.*file: */, ""); gsub(/\\/, "/"); if (!match($$0, / /)) print "$@:", $$0 }'\'' > $(@:.o=.d)'
|
||||
fi
|
||||
_DEPCMD='$(DEP$(1)) $(DEP$(1)FLAGS) $($(1)DEP_FLAGS) $< 2>&1 | awk '\''/including/ { sub(/^.*file: */, ""); gsub(/\\/, "/"); if (!match($$0, / /)) print "$@:", $$0 }'\'' > $(@:.o=.d)'
|
||||
_DEPFLAGS='$(CPPFLAGS) $(CFLAGS) -showIncludes -Zs'
|
||||
_cflags_speed="-O2"
|
||||
_cflags_size="-O1"
|
||||
@@ -5278,6 +5212,9 @@ case "$arch" in
|
||||
s390|s390x)
|
||||
arch="s390"
|
||||
;;
|
||||
sh4|sh)
|
||||
arch="sh4"
|
||||
;;
|
||||
sun4*|sparc*)
|
||||
arch="sparc"
|
||||
;;
|
||||
@@ -5304,6 +5241,10 @@ if enabled aarch64; then
|
||||
;;
|
||||
esac
|
||||
|
||||
elif enabled alpha; then
|
||||
|
||||
cpuflags="-mcpu=$cpu"
|
||||
|
||||
elif enabled arm; then
|
||||
|
||||
check_arm_arch() {
|
||||
@@ -5370,6 +5311,31 @@ elif enabled arm; then
|
||||
|
||||
test_cflags -mfp16-format=ieee && add_cflags -mfp16-format=ieee
|
||||
|
||||
elif enabled avr32; then
|
||||
|
||||
case $cpu in
|
||||
ap7[02]0[0-2])
|
||||
subarch="avr32_ap"
|
||||
cpuflags="-mpart=$cpu"
|
||||
;;
|
||||
ap)
|
||||
subarch="avr32_ap"
|
||||
cpuflags="-march=$cpu"
|
||||
;;
|
||||
uc3[ab]*)
|
||||
subarch="avr32_uc"
|
||||
cpuflags="-mcpu=$cpu"
|
||||
;;
|
||||
uc)
|
||||
subarch="avr32_uc"
|
||||
cpuflags="-march=$cpu"
|
||||
;;
|
||||
esac
|
||||
|
||||
elif enabled bfin; then
|
||||
|
||||
cpuflags="-mcpu=$cpu"
|
||||
|
||||
elif enabled loongarch; then
|
||||
|
||||
enable local_aligned
|
||||
@@ -5548,9 +5514,6 @@ elif enabled ppc; then
|
||||
|
||||
elif enabled riscv; then
|
||||
|
||||
check_headers asm/hwprobe.h
|
||||
check_headers sys/hwprobe.h
|
||||
|
||||
if test_cpp_condition stddef.h "__riscv_zbb"; then
|
||||
enable fast_clz
|
||||
fi
|
||||
@@ -5596,12 +5559,6 @@ elif enabled x86; then
|
||||
;;
|
||||
esac
|
||||
|
||||
else
|
||||
|
||||
if test_cpp_condition inttypes.h "UINTPTR_MAX >= UINT64_MAX"; then
|
||||
enable fast_64bit
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
if [ "$cpu" != generic ]; then
|
||||
@@ -5666,7 +5623,7 @@ check_64bit(){
|
||||
}
|
||||
|
||||
case "$arch" in
|
||||
aarch64|ia64)
|
||||
aarch64|alpha|ia64)
|
||||
enabled shared && enable_weak pic
|
||||
;;
|
||||
loongarch)
|
||||
@@ -6145,16 +6102,18 @@ enabled pic && enable_weak_pic
|
||||
test_cc <<EOF || die "Symbol mangling check failed."
|
||||
int ff_extern;
|
||||
EOF
|
||||
sym=$($nm $TMPO | awk '/[ \t]+[^ \t]?ff_extern$/{ print substr($0, match($0, /[^ \t]?ff_extern$/)) }')
|
||||
sym=$($nm $TMPO | awk '/ff_extern/{ print substr($0, match($0, /[^ \t]*ff_extern/)) }')
|
||||
extern_prefix=${sym%%ff_extern*}
|
||||
|
||||
log "Symbol prefix detected as: '${extern_prefix}'"
|
||||
|
||||
! disabled inline_asm && check_inline_asm inline_asm '"" ::'
|
||||
|
||||
check_cc pragma_deprecated "" '_Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")'
|
||||
|
||||
test_cpp_condition stdlib.h "defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)" && enable bigendian
|
||||
# The global variable ensures the bits appear unchanged in the object file.
|
||||
test_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
|
||||
|
||||
check_cc const_nan math.h "struct { double d; } static const bar[] = { { NAN } }"
|
||||
|
||||
@@ -6247,6 +6206,10 @@ if enabled aarch64; then
|
||||
enabled_any ${v}_external ${v}_inline || disable $v
|
||||
done
|
||||
|
||||
elif enabled alpha; then
|
||||
|
||||
check_cflags -mieee
|
||||
|
||||
elif enabled arm; then
|
||||
|
||||
enabled msvc && check_cpp_condition thumb stddef.h "defined _M_ARMT"
|
||||
@@ -6393,8 +6356,6 @@ elif enabled riscv; then
|
||||
|
||||
enabled rv && check_inline_asm rv '".option arch, +zbb\nrev8 t0, t1"'
|
||||
enabled rvv && check_inline_asm rvv '".option arch, +v\nvsetivli zero, 0, e8, m1, ta, ma"'
|
||||
enabled rv_zicbop && check_inline_asm rv_zicbop '".option arch, +zicbop\nprefetch.r 64(a0)"'
|
||||
enabled rv_zvbb && check_inline_asm rv_zvbb '".option arch, +zvbb\nvclz.v v0, v8"'
|
||||
|
||||
elif enabled x86; then
|
||||
|
||||
@@ -6476,7 +6437,6 @@ elif enabled loongarch; then
|
||||
fi
|
||||
|
||||
check_cc intrinsics_neon arm_neon.h "int16x8_t test = vdupq_n_s16(0)"
|
||||
check_cc intrinsics_sse2 emmintrin.h "__m128i test = _mm_setzero_si128()"
|
||||
|
||||
check_ldflags -Wl,--as-needed
|
||||
check_ldflags -Wl,-z,noexecstack
|
||||
@@ -6521,7 +6481,10 @@ if ! disabled network; then
|
||||
fi
|
||||
fi
|
||||
|
||||
check_builtin atomic_cas_ptr atomic.h "void **ptr; void *oldval, *newval; atomic_cas_ptr(ptr, oldval, newval)"
|
||||
check_builtin machine_rw_barrier mbarrier.h "__machine_rw_barrier()"
|
||||
check_builtin MemoryBarrier windows.h "MemoryBarrier()"
|
||||
check_builtin sync_val_compare_and_swap "" "int *ptr; int oldval, newval; __sync_val_compare_and_swap(ptr, oldval, newval)"
|
||||
check_builtin gmtime_r time.h "time_t *time; struct tm *tm; gmtime_r(time, tm)"
|
||||
check_builtin localtime_r time.h "time_t *time; struct tm *tm; localtime_r(time, tm)"
|
||||
|
||||
@@ -6581,7 +6544,6 @@ check_struct "sys/stat.h" "struct stat" st_mtim.tv_nsec -D_BSD_SOURCE
|
||||
check_func strerror_r
|
||||
check_func sysconf
|
||||
check_func sysctl
|
||||
check_func tempnam
|
||||
check_func usleep
|
||||
|
||||
check_func_headers conio.h kbhit
|
||||
@@ -6591,7 +6553,6 @@ check_func_headers mach/mach_time.h mach_absolute_time
|
||||
check_func_headers stdlib.h getenv
|
||||
check_func_headers sys/stat.h lstat
|
||||
check_func_headers sys/auxv.h getauxval
|
||||
check_func_headers sys/auxv.h elf_aux_info
|
||||
check_func_headers sys/sysctl.h sysctlbyname
|
||||
|
||||
check_func_headers windows.h GetModuleHandle
|
||||
@@ -6659,8 +6620,8 @@ check_headers asm/types.h
|
||||
# some configurations also require linking to libatomic, so try
|
||||
# both with -latomic and without
|
||||
for LATOMIC in "-latomic" ""; do
|
||||
check_builtin stdatomic stdatomic.h \
|
||||
"atomic_int foo, bar = -1; atomic_store(&foo, 0); foo += bar" \
|
||||
check_builtin stdatomic stdatomic.h \
|
||||
"atomic_int foo, bar = ATOMIC_VAR_INIT(-1); atomic_store(&foo, 0); foo += bar" \
|
||||
$LATOMIC && eval stdatomic_extralibs="\$LATOMIC" && break
|
||||
done
|
||||
|
||||
@@ -6672,7 +6633,7 @@ check_lib shell32 "windows.h shellapi.h" CommandLineToArgvW -lshell32
|
||||
check_lib psapi "windows.h psapi.h" GetProcessMemoryInfo -lpsapi
|
||||
|
||||
check_lib android android/native_window.h ANativeWindow_acquire -landroid
|
||||
check_lib mediandk "stdint.h media/NdkMediaFormat.h" AMediaFormat_new -lmediandk
|
||||
check_lib mediandk "stdint.h media/NdkImage.h" AImage_delete -lmediandk
|
||||
check_lib camera2ndk "stdbool.h stdint.h camera/NdkCameraManager.h" ACameraManager_create -lcamera2ndk
|
||||
|
||||
enabled appkit && check_apple_framework AppKit
|
||||
@@ -6727,9 +6688,6 @@ check_type "windows.h d3d11.h" "ID3D11VideoDecoder"
|
||||
check_type "windows.h d3d11.h" "ID3D11VideoContext"
|
||||
check_type "windows.h d3d12.h" "ID3D12Device"
|
||||
check_type "windows.h d3d12video.h" "ID3D12VideoDecoder"
|
||||
check_type "windows.h d3d12video.h" "ID3D12VideoEncoder"
|
||||
test_code cc "windows.h d3d12video.h" "D3D12_FEATURE_VIDEO feature = D3D12_FEATURE_VIDEO_ENCODER_CODEC" && \
|
||||
test_code cc "windows.h d3d12video.h" "D3D12_FEATURE_DATA_VIDEO_ENCODER_RESOURCE_REQUIREMENTS req" && enable d3d12_encoder_feature
|
||||
check_type "windows.h" "DPI_AWARENESS_CONTEXT" -D_WIN32_WINNT=0x0A00
|
||||
check_type "d3d9.h dxva2api.h" DXVA2_ConfigPictureDecode -D_WIN32_WINNT=0x0602
|
||||
check_func_headers mfapi.h MFCreateAlignedMemoryBuffer -lmfplat
|
||||
@@ -6865,7 +6823,7 @@ enabled gnutls && require_pkg_config gnutls gnutls gnutls/gnutls.h gn
|
||||
enabled jni && { [ $target_os = "android" ] && check_headers jni.h && enabled pthreads || die "ERROR: jni not found"; }
|
||||
enabled ladspa && require_headers "ladspa.h dlfcn.h"
|
||||
enabled lcms2 && require_pkg_config lcms2 "lcms2 >= 2.13" lcms2.h cmsCreateContext
|
||||
enabled libaom && require_pkg_config libaom "aom >= 2.0.0" aom/aom_codec.h aom_codec_version
|
||||
enabled libaom && require_pkg_config libaom "aom >= 1.0.0" aom/aom_codec.h aom_codec_version
|
||||
enabled libaribb24 && { check_pkg_config libaribb24 "aribb24 > 1.0.3" "aribb24/aribb24.h" arib_instance_new ||
|
||||
{ enabled gpl && require_pkg_config libaribb24 aribb24 "aribb24/aribb24.h" arib_instance_new; } ||
|
||||
die "ERROR: libaribb24 requires version higher than 1.0.3 or --enable-gpl."; }
|
||||
@@ -6912,9 +6870,7 @@ enabled libjxl && require_pkg_config libjxl "libjxl >= 0.7.0" jxl/dec
|
||||
require_pkg_config libjxl_threads "libjxl_threads >= 0.7.0" jxl/thread_parallel_runner.h JxlThreadParallelRunner
|
||||
enabled libklvanc && require libklvanc libklvanc/vanc.h klvanc_context_create -lklvanc
|
||||
enabled libkvazaar && require_pkg_config libkvazaar "kvazaar >= 2.0.0" kvazaar.h kvz_api_get
|
||||
enabled liblc3 && require_pkg_config liblc3 "lc3 >= 1.1.0" lc3.h lc3_hr_setup_encoder
|
||||
enabled liblensfun && require_pkg_config liblensfun lensfun lensfun.h lf_db_create
|
||||
enabled liblcevc_dec && require_pkg_config liblcevc_dec "lcevc_dec >= 2.0.0" "LCEVC/lcevc_dec.h" LCEVC_CreateDecoder
|
||||
|
||||
if enabled libmfx && enabled libvpl; then
|
||||
die "ERROR: can not use libmfx and libvpl together"
|
||||
@@ -6942,7 +6898,6 @@ elif enabled libvpl; then
|
||||
check_pkg_config libmfx "vpl >= 2.6" "mfxvideo.h mfxdispatcher.h" MFXLoad || \
|
||||
die "ERROR: libvpl >= 2.6 not found"
|
||||
add_cflags -DMFX_DEPRECATED_OFF
|
||||
check_type "vpl/mfxdefs.h vpl/mfxvideo.h" "struct mfxConfigInterface"
|
||||
fi
|
||||
|
||||
if enabled libmfx; then
|
||||
@@ -7036,12 +6991,11 @@ enabled libvpx && {
|
||||
fi
|
||||
}
|
||||
|
||||
enabled libvvenc && require_pkg_config libvvenc "libvvenc >= 1.6.1" "vvenc/vvenc.h" vvenc_get_version
|
||||
enabled libwebp && {
|
||||
enabled libwebp_encoder && require_pkg_config libwebp "libwebp >= 0.2.0" webp/encode.h WebPGetEncoderVersion
|
||||
enabled libwebp_anim_encoder && check_pkg_config libwebp_anim_encoder "libwebpmux >= 0.4.0" webp/mux.h WebPAnimEncoderOptionsInit; }
|
||||
enabled libx264 && require_pkg_config libx264 x264 "stdint.h x264.h" x264_encoder_encode &&
|
||||
require_cpp_condition libx264 x264.h "X264_BUILD >= 155" && {
|
||||
require_cpp_condition libx264 x264.h "X264_BUILD >= 122" && {
|
||||
[ "$toolchain" != "msvc" ] ||
|
||||
require_cpp_condition libx264 x264.h "X264_BUILD >= 158"; } &&
|
||||
check_cpp_condition libx264_hdr10 x264.h "X264_BUILD >= 163" &&
|
||||
@@ -7051,7 +7005,7 @@ enabled libx265 && require_pkg_config libx265 x265 x265.h x265_api_get
|
||||
enabled libxavs && require libxavs "stdint.h xavs.h" xavs_encoder_encode "-lxavs $pthreads_extralibs $libm_extralibs"
|
||||
enabled libxavs2 && require_pkg_config libxavs2 "xavs2 >= 1.3.0" "stdint.h xavs2.h" xavs2_api_get
|
||||
enabled libxevd && require_pkg_config libxevd "xevd >= 0.4.1" "xevd.h" xevd_decode
|
||||
enabled libxeve && require_pkg_config libxeve "xeve >= 0.5.1" "xeve.h" xeve_encode
|
||||
enabled libxeve && require_pkg_config libxeve "xeve >= 0.4.3" "xeve.h" xeve_encode
|
||||
enabled libxvid && require libxvid xvid.h xvid_global -lxvidcore
|
||||
enabled libzimg && require_pkg_config libzimg "zimg >= 2.7.0" zimg.h zimg_get_api_version
|
||||
enabled libzmq && require_pkg_config libzmq "libzmq >= 4.2.1" zmq.h zmq_ctx_new
|
||||
@@ -7078,7 +7032,7 @@ enabled openal && { check_pkg_config openal "openal >= 1.1" "AL/al.h"
|
||||
{ test_cpp_condition "AL/al.h" "defined(AL_VERSION_1_1)" ||
|
||||
die "ERROR: openal must be installed and version must be 1.1 or compatible"; }
|
||||
enabled opencl && { check_pkg_config opencl OpenCL CL/cl.h clEnqueueNDRangeKernel ||
|
||||
check_lib opencl OpenCL/cl.h clEnqueueNDRangeKernel "-framework OpenCL" ||
|
||||
check_lib opencl OpenCL/cl.h clEnqueueNDRangeKernel -Wl,-framework,OpenCL ||
|
||||
check_lib opencl CL/cl.h clEnqueueNDRangeKernel -lOpenCL ||
|
||||
die "ERROR: opencl not found"; } &&
|
||||
{ test_cpp_condition "OpenCL/cl.h" "defined(CL_VERSION_1_2)" ||
|
||||
@@ -7086,8 +7040,8 @@ enabled opencl && { check_pkg_config opencl OpenCL CL/cl.h clEnqueueN
|
||||
die "ERROR: opencl must be installed and version must be 1.2 or compatible"; }
|
||||
enabled opengl && { check_lib opengl GL/glx.h glXGetProcAddress "-lGL" ||
|
||||
check_lib opengl windows.h wglGetProcAddress "-lopengl32 -lgdi32" ||
|
||||
check_lib opengl OpenGL/gl3.h glGetError "-framework OpenGL" ||
|
||||
check_lib opengl ES2/gl.h glGetError "-isysroot=${sysroot} -framework OpenGLES" ||
|
||||
check_lib opengl OpenGL/gl3.h glGetError "-Wl,-framework,OpenGL" ||
|
||||
check_lib opengl ES2/gl.h glGetError "-isysroot=${sysroot} -Wl,-framework,OpenGLES" ||
|
||||
die "ERROR: opengl not found."
|
||||
}
|
||||
enabled omx_rpi && { test_code cc OMX_Core.h OMX_IndexConfigBrcmVideoRequestIFrame ||
|
||||
@@ -7113,7 +7067,7 @@ enabled rkmpp && { require_pkg_config rkmpp rockchip_mpp rockchip/r
|
||||
{ enabled libdrm ||
|
||||
die "ERROR: rkmpp requires --enable-libdrm"; }
|
||||
}
|
||||
enabled vapoursynth && require_headers "vapoursynth/VSScript4.h vapoursynth/VapourSynth4.h"
|
||||
enabled vapoursynth && require_pkg_config vapoursynth "vapoursynth-script >= 42" VSScript.h vsscript_init
|
||||
|
||||
|
||||
if enabled gcrypt; then
|
||||
@@ -7155,12 +7109,12 @@ if enabled decklink; then
|
||||
fi
|
||||
|
||||
enabled securetransport &&
|
||||
check_func SecIdentityCreate "-framework CoreFoundation -framework Security" &&
|
||||
check_lib securetransport "Security/SecureTransport.h Security/Security.h" "SSLCreateContext" "-framework CoreFoundation -framework Security" ||
|
||||
check_func SecIdentityCreate "-Wl,-framework,CoreFoundation -Wl,-framework,Security" &&
|
||||
check_lib securetransport "Security/SecureTransport.h Security/Security.h" "SSLCreateContext" "-Wl,-framework,CoreFoundation -Wl,-framework,Security" ||
|
||||
disable securetransport
|
||||
|
||||
enabled securetransport &&
|
||||
check_func SecItemImport "-framework CoreFoundation -framework Security"
|
||||
check_func SecItemImport "-Wl,-framework,CoreFoundation -Wl,-framework,Security"
|
||||
|
||||
enabled schannel &&
|
||||
check_func_headers "windows.h security.h" InitializeSecurityContext -DSECURITY_WIN32 -lsecur32 &&
|
||||
@@ -7178,13 +7132,11 @@ pod2man --help > /dev/null 2>&1 && enable pod2man || disable pod2man
|
||||
rsync --help 2> /dev/null | grep -q 'contimeout' && enable rsync_contimeout || disable rsync_contimeout
|
||||
xmllint --version > /dev/null 2>&1 && enable xmllint || disable xmllint
|
||||
|
||||
check_headers linux/fb.h
|
||||
check_headers linux/videodev2.h
|
||||
test_code cc linux/videodev2.h "struct v4l2_frmsizeenum vfse; vfse.discrete.width = 0;" && enable_sanitized struct_v4l2_frmivalenum_discrete
|
||||
test_code cc sys/ioctl.h "int ioctl(int, int, ...)" && enable posix_ioctl
|
||||
|
||||
# check V4L2 codecs available in the API
|
||||
if enabled v4l2_m2m; then
|
||||
check_headers linux/fb.h
|
||||
check_headers linux/videodev2.h
|
||||
test_code cc linux/videodev2.h "struct v4l2_frmsizeenum vfse; vfse.discrete.width = 0;" && enable_sanitized struct_v4l2_frmivalenum_discrete
|
||||
check_cc v4l2_m2m linux/videodev2.h "int i = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_VIDEO_M2M | V4L2_BUF_FLAG_LAST;"
|
||||
check_cc vc1_v4l2_m2m linux/videodev2.h "int i = V4L2_PIX_FMT_VC1_ANNEX_G;"
|
||||
check_cc mpeg1_v4l2_m2m linux/videodev2.h "int i = V4L2_PIX_FMT_MPEG1;"
|
||||
@@ -7359,7 +7311,7 @@ fi
|
||||
|
||||
if enabled x86; then
|
||||
case $target_os in
|
||||
freebsd|mingw32*|mingw64*|win32|win64|linux|cygwin*)
|
||||
mingw32*|mingw64*|win32|win64|linux|cygwin*)
|
||||
;;
|
||||
*)
|
||||
disable ffnvcodec cuvid nvdec nvenc
|
||||
@@ -7397,7 +7349,7 @@ fi
|
||||
|
||||
enabled amf &&
|
||||
check_cpp_condition amf "AMF/core/Version.h" \
|
||||
"(AMF_VERSION_MAJOR << 48 | AMF_VERSION_MINOR << 32 | AMF_VERSION_RELEASE << 16 | AMF_VERSION_BUILD_NUM) >= 0x0001000400210000"
|
||||
"(AMF_VERSION_MAJOR << 48 | AMF_VERSION_MINOR << 32 | AMF_VERSION_RELEASE << 16 | AMF_VERSION_BUILD_NUM) >= 0x00010004001d0000"
|
||||
|
||||
# Funny iconv installations are not unusual, so check it after all flags have been set
|
||||
if enabled libc_iconv; then
|
||||
@@ -7780,18 +7732,21 @@ for thread in $THREADS_LIST; do
|
||||
done
|
||||
|
||||
if disabled stdatomic; then
|
||||
if enabled atomics_win32; then
|
||||
if enabled atomics_gcc; then
|
||||
add_cppflags '-I\$(SRC_PATH)/compat/atomics/gcc'
|
||||
elif enabled atomics_win32; then
|
||||
add_cppflags '-I\$(SRC_PATH)/compat/atomics/win32'
|
||||
elif enabled atomics_suncc; then
|
||||
add_cppflags '-I\$(SRC_PATH)/compat/atomics/suncc'
|
||||
elif enabled pthreads; then
|
||||
add_compat atomics/pthread/stdatomic.o
|
||||
add_cppflags '-I\$(SRC_PATH)/compat/atomics/pthread'
|
||||
else
|
||||
enabled threads && die "Threading is enabled, but no atomics are available"
|
||||
add_cppflags '-I\$(SRC_PATH)/compat/atomics/dummy'
|
||||
fi
|
||||
fi
|
||||
|
||||
check_builtin stdbit "stdbit.h assert.h" \
|
||||
'static_assert(__STDC_VERSION_STDBIT_H__ >= 202311L, "Compiler lacks stdbit.h")' || \
|
||||
add_cppflags '-I\$(SRC_PATH)/compat/stdbit'
|
||||
|
||||
# Check if requested libraries were found.
|
||||
for lib in $AUTODETECT_LIBS; do
|
||||
requested $lib && ! enabled $lib && die "ERROR: $lib requested but not found";
|
||||
@@ -7808,14 +7763,14 @@ enabled elbg_filter && prepend avfilter_deps "avcodec"
|
||||
enabled find_rect_filter && prepend avfilter_deps "avformat avcodec"
|
||||
enabled fsync_filter && prepend avfilter_deps "avformat"
|
||||
enabled mcdeint_filter && prepend avfilter_deps "avcodec"
|
||||
enabled movie_filter && prepend avfilter_deps "avformat avcodec"
|
||||
enabled movie_filter && prepend avfilter_deps "avformat avcodec"
|
||||
enabled pan_filter && prepend avfilter_deps "swresample"
|
||||
enabled pp_filter && prepend avfilter_deps "postproc"
|
||||
enabled qrencode_filter && prepend avfilter_deps "swscale"
|
||||
enabled qrencodesrc_filter && prepend avfilter_deps "swscale"
|
||||
enabled qrencode_filter && prepend_avfilter_deps "swscale"
|
||||
enabled qrencodesrc_filter && prepend_avfilter_deps "swscale"
|
||||
enabled removelogo_filter && prepend avfilter_deps "avformat avcodec swscale"
|
||||
enabled sab_filter && prepend avfilter_deps "swscale"
|
||||
enabled scale_filter && prepend avfilter_deps "swscale"
|
||||
enabled scale_filter && prepend avfilter_deps "swscale"
|
||||
enabled scale2ref_filter && prepend avfilter_deps "swscale"
|
||||
enabled showcqt_filter && prepend avfilter_deps "avformat swscale"
|
||||
enabled signature_filter && prepend avfilter_deps "avcodec avformat"
|
||||
@@ -7947,7 +7902,6 @@ if enabled loongarch; then
|
||||
echo "LASX enabled ${lasx-no}"
|
||||
fi
|
||||
if enabled riscv; then
|
||||
echo "RISC-V CBO Prefetch ${rv_zicbop-no}"
|
||||
echo "RISC-V Vector enabled ${rvv-no}"
|
||||
fi
|
||||
echo "debug symbols ${debug-no}"
|
||||
|
||||
-155
@@ -2,161 +2,6 @@ The last version increases of all libraries were on 2024-03-07
|
||||
|
||||
API changes, most recent first:
|
||||
|
||||
2024-09-23 - 6940a6de2f0 - lavu 59.38.100 - frame.h
|
||||
Add AV_FRAME_DATA_VIEW_ID.
|
||||
|
||||
2024-09-23 - 6147385393a - lavc 61.18.100 - avcodec.h
|
||||
Add a new flag AV_CODEC_EXPORT_DATA_ENHANCEMENTS for export_side_data.
|
||||
|
||||
2024-09-18 - df609af8e44 - lavc 61.17.100 - packet.h
|
||||
Add AV_PKT_DATA_LCEVC.
|
||||
|
||||
2024-09-18 - ba0ef0860f0 - lavf 61.5.100 - avformat.h
|
||||
Add AVStreamGroupLCEVC
|
||||
Add AV_STREAM_GROUP_PARAMS_LCEVC
|
||||
Add AVStreamGroup.params.lcevc
|
||||
|
||||
2024-09-18 - 58963182294 - lavc 61.16.100 - avcodec.h
|
||||
Add AV_CODEC_ID_LCEVC.
|
||||
|
||||
2024-09-18 - 90d12c24c51 - lavu 59.37.100 - frame.h
|
||||
Add AV_FRAME_DATA_LCEVC.
|
||||
|
||||
2024-09-08 - 3305767560a - lavc 61.13.100 - avcodec.h
|
||||
Add avcodec_get_supported_config() and enum AVCodecConfig; deprecate
|
||||
AVCodec.pix_fmts, AVCodec.sample_fmts, AVCodec.supported_framerates,
|
||||
AVCodec.supported_samplerates and AVCodec.ch_layouts.
|
||||
|
||||
2024-09-06 - c35a51f4bb1 - lavc 61.12.100 - defs.h
|
||||
Add AV_PROFILE_HEVC_MULTIVIEW_MAIN
|
||||
|
||||
2024-09-06 - 450a3f58edb - lavu 59.36.100 - opt.h
|
||||
Add av_opt_set_array() and AV_OPT_ARRAY_REPLACE.
|
||||
|
||||
2024-08-27 - d89930f8666 - lavu 59.35.100 - opt.h
|
||||
Add av_opt_get_array_size() and av_opt_get_array().
|
||||
|
||||
2024-08-18 - 8657eb9c3f4 - lavc 61.11.100 - avcodec.h
|
||||
Clarify the documentation for get_buffer*() functions, making it
|
||||
clear that the memory returned by them should not contain sensitive
|
||||
information. This is not a change in the API, it is how it already worked
|
||||
before.
|
||||
|
||||
2024-08-10 - 5f0f1f7b7a6 - lavu 59.34.100 - hwcontext_vulkan.h
|
||||
Add qf and nb_qf to AVVulkanDeviceContext.
|
||||
Deprecate queue_family_index, nb_graphics_queues,
|
||||
queue_family_tx_index, nb_tx_queues.
|
||||
queue_family_comp_index, nb_comp_queues.
|
||||
queue_family_encode_index, nb_encode_queues.
|
||||
queue_family_decode_index, and nb_decode_queues,
|
||||
from AVVulkanDeviceContext.
|
||||
|
||||
2024-07-30 - e0f9f4d4915 - lavu 59.32.100 - cpu.h
|
||||
Deprecate AV_CPU_FLAG_RVF and AV_CPU_FLAG_RVD without replacement.
|
||||
Deprecate AV_CPU_FLAG_RVB_ADDR, subsumed into AV_CPU_FLAG_RVB.
|
||||
|
||||
2024-07-29 - 753f2aeed76 - lavu 59.31.100 - intreadwrite.h
|
||||
Add AV_{R,W}{L,B}{16,32}A and AV_{R,W}B64A.
|
||||
|
||||
2024-07-28 - cbea92c84d4 - lavu 59.30.100 - dovi_meta.h
|
||||
Add AVDOVIDecoderConfigurationRecord.dv_md_compression.
|
||||
|
||||
2024-07-25 - 45d7078a218 - lavu 59.29.100 - cpu.h
|
||||
Add AV_CPU_FLAG_RVB.
|
||||
|
||||
2024-07-xx - xxxxxxxxxx - lavf 61 - avformat.h
|
||||
Deprecate avformat_transfer_internal_stream_timing_info()
|
||||
and av_stream_get_codec_timebase() without replacement.
|
||||
|
||||
2024-07-08 - 1b58f3af30c - lavc 61.10.100 - packet.h
|
||||
Add AV_PKT_DATA_FRAME_CROPPING.
|
||||
|
||||
2024-07-07 - 46f7ea44563 - lavf 61.5.100 - avformat.h
|
||||
Add AV_DISPOSITION_MULTILAYER
|
||||
|
||||
2024-07-02 - d822146f4fc - lavu 59.28.100 - hwcontext_d3d12va.h
|
||||
Add AVD3D12VAFramesContext.flags
|
||||
|
||||
2024-06-28 - 8af0919cc66 - lavu 59.27.100 - stereo3d.h
|
||||
Add AV_STEREO3D_UNSPEC and AV_STEREO3D_VIEW_UNSPEC.
|
||||
|
||||
2024-06-25 - e6baf4f3841 - lavu 59.26.100 - stereo3d.h
|
||||
Add av_stereo3d_alloc_size().
|
||||
|
||||
2024-06-19 - cc587e69c6f - lavu 59.25.100 - dovi_meta.h
|
||||
Add AVDOVIRpuDataHeader.ext_mapping_idc_0_4 and ext_mapping_idc_5_7.
|
||||
|
||||
2024-06-18 - cf2436a0b4d - lavu 59.24.100 - stereo3d.h
|
||||
Add primary_eye, baseline, horizontal_disparity_adjustment, and
|
||||
horizontal_field_of_view fields to AVStereo3D.
|
||||
Add AVStereo3DPrimaryEye.
|
||||
Add av_stereo3d_view_name.
|
||||
Add av_stereo3d_view_from_name.
|
||||
Add av_stereo3d_primary_eye_name.
|
||||
Add av_stereo3d_primary_eye_from_name.
|
||||
|
||||
2024-06-18 - 57bfba35d6b - lavu 59.23.100 - spherical.h
|
||||
Add AV_SPHERICAL_HALF_EQUIRECTANGULAR, AV_SPHERICAL_RECTILINEAR, and
|
||||
AV_SPHERICAL_FISHEYE values to AVSphericalProjection, and initialize
|
||||
to AV_SPHERICAL_RECTILINEAR on alloc.
|
||||
|
||||
2024-06-13 - 39c90d6466a - lavu 59.22.100 - common.h
|
||||
Deprecate av_mod_uintp2[_c]() and replace it with av_zero_extend[_c]().
|
||||
|
||||
2024-06-08 - 91fd6ca000c - lavc 61.7.100 - defs.h
|
||||
Add AV_PROFILE_AAC_USAC.
|
||||
|
||||
2024-06-02 - 63e166d8028 - lavu 59.21.100 - channel_layout.h
|
||||
Add AV_CHAN_SIDE_SURROUND_RIGHT and AV_CH_SIDE_SURROUND_LEFT.
|
||||
Add AV_CHAN_SIDE_SURROUND_RIGHT and AV_CH_SIDE_SURROUND_RIGHT.
|
||||
Add AV_CHAN_TOP_SURROUND_LEFT and AV_CH_TOP_SURROUND_LEFT.
|
||||
Add AV_CHAN_TOP_SURROUND_RIGHT and AV_CH_TOP_SURROUND_RIGHT.
|
||||
|
||||
2024-05-23 - 8c974494822 - lavu 59.20.100 - channel_layout.h
|
||||
Add av_channel_layout_ambisonic_order().
|
||||
|
||||
2024-05-20 - 4c0bb7d4a91 - lavu 59.19.100 - hwcontext_qsv.h
|
||||
Add AVQSVFramesContext.info
|
||||
|
||||
2024-05-10 - 01c5f4ad9fa - lavu 59.18.100 - cpu.h
|
||||
Add AV_CPU_FLAG_RV_ZVBB.
|
||||
|
||||
2024-05-04 - d053290d8dd - lavu 59.17.100 - opt.h
|
||||
Add AV_OPT_TYPE_UINT and av_opt_eval_uint().
|
||||
|
||||
2024-04-24 - 8616cfe0890 - lavu 59.16.100 - opt.h
|
||||
Add AV_OPT_SERIALIZE_SEARCH_CHILDREN.
|
||||
|
||||
2024-04-11 - 6d0c89980c7 - lavc 61.5.102 - avcodec.h
|
||||
AVCodecContext.decoded_side_data may now be set by libavcodec after
|
||||
calling avcodec_open2().
|
||||
|
||||
2024-04-11 - 6d760c666d5 - lavu 59.15.100 - frame.h
|
||||
Add av_mastering_display_metadata_alloc_size().
|
||||
|
||||
2024-04-11 - adb67bba064 - lavu 59.14.100 - frame.h
|
||||
Add av_frame_side_data_add() and av_frame_side_data_remove().
|
||||
Add AV_FRAME_SIDE_DATA_FLAG_REPLACE.
|
||||
|
||||
2024-04-03 - 29561c8e2d4 - lavu 59.13.100 - pixfmt.h
|
||||
Add AVCOL_SPC_IPT_C2, AVCOL_SPC_YCGCO_RE and AVCOL_SPC_YCGCO_RO
|
||||
to map new matrix coefficients defined by H.273 v3.
|
||||
|
||||
2024-04-03 - 4f55e16f2bc - lavu 59.12.100 - dovi_meta.h
|
||||
Add AVDOVIMetadata.ext_block_{offset,size}, AVDOVIMetadata.num_ext_blocks,
|
||||
AVDOVIDmData and AVDOVIDmLevel{1..6,8..11,254..255}, av_dovi_get_ext()
|
||||
and av_dovi_find_level().
|
||||
|
||||
2024-04-03 - 78076ede296 - lavu 59.11.100 - dovi_meta.h
|
||||
Add AVDOVIDataMapping.nlq_pivots.
|
||||
|
||||
2024-03-29 - ed9363052f4 - lavf 61.3.100 - avformat.h
|
||||
Add AVFormatContext.duration_probesize.
|
||||
|
||||
2024-03-27 - 2621be35397 - lavu 59.10.100 - frame.h
|
||||
Add AVSideDataDescriptor, enum AVSideDataProps, and
|
||||
av_frame_side_data_desc().
|
||||
|
||||
-------- 8< --------- FFmpeg 7.0 was cut here -------- 8< ---------
|
||||
|
||||
2024-03-25 - 5df901ffa56 - lavu 59.7.100 - timestamp.h
|
||||
|
||||
+1
-1
@@ -38,7 +38,7 @@ PROJECT_NAME = FFmpeg
|
||||
# could be handy for archiving the generated documentation or if some version
|
||||
# control system is used.
|
||||
|
||||
PROJECT_NUMBER =
|
||||
PROJECT_NUMBER = 7.0
|
||||
|
||||
# Using the PROJECT_BRIEF tag one can provide an optional one line description
|
||||
# for a project that appears at the top of each page and should give viewer a
|
||||
|
||||
+1
-1
@@ -60,7 +60,7 @@ GENTEXI := $(GENTEXI:%=doc/avoptions_%.texi)
|
||||
|
||||
$(GENTEXI): TAG = GENTEXI
|
||||
$(GENTEXI): doc/avoptions_%.texi: doc/print_options$(HOSTEXESUF)
|
||||
$(M)doc/print_options$(HOSTEXESUF) $* > $@
|
||||
$(M)doc/print_options $* > $@
|
||||
|
||||
doc/%.html: TAG = HTML
|
||||
doc/%-all.html: TAG = HTML
|
||||
|
||||
@@ -101,29 +101,6 @@ Remove zero padding at the end of a packet.
|
||||
Extract the core from a DCA/DTS stream, dropping extensions such as
|
||||
DTS-HD.
|
||||
|
||||
@section dovi_rpu
|
||||
|
||||
Manipulate Dolby Vision metadata in a HEVC/AV1 bitstream, optionally enabling
|
||||
metadata compression.
|
||||
|
||||
@table @option
|
||||
@item strip
|
||||
If enabled, strip all Dolby Vision metadata (configuration record + RPU data
|
||||
blocks) from the stream.
|
||||
@item compression
|
||||
Which compression level to enable.
|
||||
@table @samp
|
||||
@item none
|
||||
No metadata compression.
|
||||
@item limited
|
||||
Limited metadata compression scheme. Should be compatible with most devices.
|
||||
This is the default.
|
||||
@item extended
|
||||
Extended metadata compression. Devices are not required to support this. Note
|
||||
that this level currently behaves the same as @samp{limited} in libavcodec.
|
||||
@end table
|
||||
@end table
|
||||
|
||||
@section dump_extra
|
||||
|
||||
Add extradata to the beginning of the filtered packets except when
|
||||
@@ -479,10 +456,6 @@ will replace the current ones if the stream is already cropped.
|
||||
These fields are set in pixels. Note that some sizes may not be
|
||||
representable if the chroma is subsampled (H.265 section 7.4.3.2.1).
|
||||
|
||||
@item width
|
||||
@item height
|
||||
Set width and height after crop.
|
||||
|
||||
@item level
|
||||
Set the level in the VPS and SPS. See H.265 section A.4 and tables
|
||||
A.6 and A.7.
|
||||
|
||||
+2
-7
@@ -82,6 +82,8 @@ The TC has 2 modes of operation: a RFC one and an internal one.
|
||||
|
||||
If the TC thinks it needs the input from the larger community, the TC can call for a RFC. Else, it can decide by itself.
|
||||
|
||||
If the disagreement involves a member of the TC, that member should recuse themselves from the decision.
|
||||
|
||||
The decision to use a RFC process or an internal discussion is a discretionary decision of the TC.
|
||||
|
||||
The TC can also reject a seizure for a few reasons such as: the matter was not discussed enough previously; it lacks expertise to reach a beneficial decision on the matter; or the matter is too trivial.
|
||||
@@ -121,13 +123,6 @@ The decisions from the TC will be sent on the mailing list, with the [TC] tag.
|
||||
|
||||
Internally, the TC should take decisions with a majority, or using ranked-choice voting.
|
||||
|
||||
Each TC member must vote on such decision according to what is, in their view, best for the project.
|
||||
|
||||
If a TC member feels they are affected by a conflict of interest with regards to the case, they should announce it and recuse themselves from the TC
|
||||
discussion and vote.
|
||||
|
||||
A conflict of interest is presumed to occur when a TC member has a personal interest (e.g. financial) in a specific outcome of the case.
|
||||
|
||||
The decision from the TC should be published with a summary of the reasons that lead to this decision.
|
||||
|
||||
The decisions from the TC are final, until the matters are reopened after no less than one year.
|
||||
|
||||
+1
-46
@@ -38,51 +38,6 @@ Select an operating point of a scalable AV1 bitstream (0 - 31). Default is 0.
|
||||
|
||||
@end table
|
||||
|
||||
@section hevc
|
||||
HEVC (AKA ITU-T H.265 or ISO/IEC 23008-2) decoder.
|
||||
|
||||
The decoder supports MV-HEVC multiview streams with at most two views. Views to
|
||||
be output are selected by supplying a list of view IDs to the decoder (the
|
||||
@option{view_ids} option). This option may be set either statically before
|
||||
decoder init, or from the @code{get_format()} callback - useful for the case
|
||||
when the view count or IDs change dynamically during decoding.
|
||||
|
||||
Only the base layer is decoded by default.
|
||||
|
||||
Note that if you are using the @code{ffmpeg} CLI tool, you should be using view
|
||||
specifiers as documented in its manual, rather than the options documented here.
|
||||
|
||||
@subsection Options
|
||||
|
||||
@table @option
|
||||
|
||||
@item view_ids (MV-HEVC)
|
||||
Specify a list of view IDs that should be output. This option can also be set to
|
||||
a single '-1', which will cause all views defined in the VPS to be decoded and
|
||||
output.
|
||||
|
||||
@item view_ids_available (MV-HEVC)
|
||||
This option may be read by the caller to retrieve an array of view IDs available
|
||||
in the active VPS. The array is empty for single-layer video.
|
||||
|
||||
The value of this option is guaranteed to be accurate when read from the
|
||||
@code{get_format()} callback. It may also be set at other times (e.g. after
|
||||
opening the decoder), but the value is informational only and may be incorrect
|
||||
(e.g. when the stream contains multiple distinct VPS NALUs).
|
||||
|
||||
@item view_pos_available (MV-HEVC)
|
||||
This option may be read by the caller to retrieve an array of view positions
|
||||
(left, right, or unspecified) available in the active VPS, as
|
||||
@code{AVStereo3DView} values. When the array is available, its elements apply to
|
||||
the corresponding elements of @option{view_ids_available}, i.e.
|
||||
@code{view_pos_available[i]} contains the position of view with ID
|
||||
@code{view_ids_available[i]}.
|
||||
|
||||
Same validity restrictions as for @option{view_ids_available} apply to
|
||||
this option.
|
||||
|
||||
@end table
|
||||
|
||||
@section rawvideo
|
||||
|
||||
Raw video decoder.
|
||||
@@ -202,7 +157,7 @@ Force to use a specific number of threads
|
||||
@section QSV Decoders
|
||||
|
||||
The family of Intel QuickSync Video decoders (VC1, MPEG-2, H.264, HEVC,
|
||||
JPEG/MJPEG, VP8, VP9, AV1, VVC).
|
||||
JPEG/MJPEG, VP8, VP9, AV1).
|
||||
|
||||
@subsection Common Options
|
||||
|
||||
|
||||
@@ -1038,36 +1038,6 @@ the command:
|
||||
ffplay -f rawvideo -pixel_format rgb24 -video_size 320x240 -framerate 10 input.raw
|
||||
@end example
|
||||
|
||||
@anchor{rcwtdec}
|
||||
@section rcwt
|
||||
|
||||
RCWT (Raw Captions With Time) is a format native to ccextractor, a commonly
|
||||
used open source tool for processing 608/708 Closed Captions (CC) sources.
|
||||
For more information on the format, see @ref{rcwtenc,,,ffmpeg-formats}.
|
||||
|
||||
This demuxer implements the specification as of March 2024, which has
|
||||
been stable and unchanged since April 2014.
|
||||
|
||||
@subsection Examples
|
||||
|
||||
@itemize
|
||||
@item
|
||||
Render CC to ASS using the built-in decoder:
|
||||
@example
|
||||
ffmpeg -i CC.rcwt.bin CC.ass
|
||||
@end example
|
||||
Note that if your output appears to be empty, you may have to manually
|
||||
set the decoder's @option{data_field} option to pick the desired CC substream.
|
||||
|
||||
@item
|
||||
Convert an RCWT backup to Scenarist (SCC) format:
|
||||
@example
|
||||
ffmpeg -i CC.rcwt.bin -c:s copy CC.scc
|
||||
@end example
|
||||
Note that the SCC format does not support all of the possible CC extensions
|
||||
that can be stored in RCWT (such as EIA-708).
|
||||
@end itemize
|
||||
|
||||
@section sbg
|
||||
|
||||
SBaGen script demuxer.
|
||||
|
||||
+2
-7
@@ -638,11 +638,6 @@ patch is inline or attached per mail.
|
||||
You can check @url{https://patchwork.ffmpeg.org}, if your patch does not show up, its mime type
|
||||
likely was wrong.
|
||||
|
||||
@subheading How to setup git send-email?
|
||||
|
||||
Please see @url{https://git-send-email.io/}.
|
||||
For gmail additionally see @url{https://shallowsky.com/blog/tech/email/gmail-app-passwds.html}.
|
||||
|
||||
@subheading Sending patches from email clients
|
||||
Using @code{git send-email} might not be desirable for everyone. The
|
||||
following trick allows to send patches via email clients in a safe
|
||||
@@ -687,7 +682,7 @@ number) in @file{libavcodec/version.h} or @file{libavformat/version.h}?
|
||||
Did you register it in @file{allcodecs.c} or @file{allformats.c}?
|
||||
|
||||
@item
|
||||
Did you add the AVCodecID to @file{codec_id.h}?
|
||||
Did you add the AVCodecID to @file{avcodec.h}?
|
||||
When adding new codec IDs, also add an entry to the codec descriptor
|
||||
list in @file{libavcodec/codec_desc.c}.
|
||||
|
||||
@@ -702,7 +697,7 @@ already being compiled by some other rule, like a raw demuxer.
|
||||
|
||||
@item
|
||||
Did you add an entry to the table of supported formats or codecs in
|
||||
@file{doc/general_contents.texi}?
|
||||
@file{doc/general.texi}?
|
||||
|
||||
@item
|
||||
Did you add an entry in the Changelog?
|
||||
|
||||
+7
-151
@@ -144,7 +144,8 @@ If this option is unspecified it is set to @samp{aac_low}.
|
||||
|
||||
AC-3 audio encoders.
|
||||
|
||||
These encoders implement part of ATSC A/52:2010 and ETSI TS 102 366.
|
||||
These encoders implement part of ATSC A/52:2010 and ETSI TS 102 366, as well as
|
||||
the undocumented RealAudio 3 (a.k.a. dnet).
|
||||
|
||||
The @var{ac3} encoder uses floating-point math, while the @var{ac3_fixed}
|
||||
encoder only uses fixed-point integer math. This does not mean that one is
|
||||
@@ -813,63 +814,6 @@ ffmpeg -i input.wav -c:a libfdk_aac -profile:a aac_he -b:a 64k output.m4a
|
||||
@end example
|
||||
@end itemize
|
||||
|
||||
@anchor{liblc3-enc}
|
||||
@section liblc3
|
||||
|
||||
liblc3 LC3 (Low Complexity Communication Codec) encoder wrapper.
|
||||
|
||||
Requires the presence of the liblc3 headers and library during configuration.
|
||||
You need to explicitly configure the build with @code{--enable-liblc3}.
|
||||
|
||||
This encoder has support for the Bluetooth SIG LC3 codec for the LE Audio
|
||||
protocol, and the following features of LC3plus:
|
||||
@itemize
|
||||
@item
|
||||
Frame duration of 2.5 and 5ms.
|
||||
@item
|
||||
High-Resolution mode, 48 KHz, and 96 kHz sampling rates.
|
||||
@end itemize
|
||||
|
||||
For more information see the liblc3 project at
|
||||
@url{https://github.com/google/liblc3}.
|
||||
|
||||
@subsection Options
|
||||
|
||||
The following options are mapped on the shared FFmpeg codec options.
|
||||
|
||||
@table @option
|
||||
@item b @var{bitrate}
|
||||
Set the bit rate in bits/s. This will determine the fixed size of the encoded
|
||||
frames, for a selected frame duration.
|
||||
|
||||
@item ar @var{frequency}
|
||||
Set the audio sampling rate (in Hz).
|
||||
|
||||
@item channels
|
||||
Set the number of audio channels.
|
||||
|
||||
@item frame_duration
|
||||
Set the audio frame duration in milliseconds. Default value is 10ms.
|
||||
Allowed frame durations are 2.5ms, 5ms, 7.5ms and 10ms.
|
||||
LC3 (Bluetooth LE Audio), allows 7.5ms and 10ms; and LC3plus 2.5ms, 5ms
|
||||
and 10ms.
|
||||
|
||||
The 10ms frame duration is available in LC3 and LC3 plus standard.
|
||||
In this mode, the produced bitstream can be referenced either as LC3 or LC3plus.
|
||||
|
||||
@item high_resolution @var{boolean}
|
||||
Enable the high-resolution mode if set to 1. The high-resolution mode is
|
||||
available with all LC3plus frame durations and for a sampling rate of 48 KHz,
|
||||
and 96 KHz.
|
||||
|
||||
The encoder automatically turns off this mode at lower sampling rates and
|
||||
activates it at 96 KHz.
|
||||
|
||||
This mode should be preferred at high bitrates. In this mode, the audio
|
||||
bandwidth is always up to the Nyquist frequency, compared to LC3 at 48 KHz,
|
||||
which limits the bandwidth to 20 KHz.
|
||||
@end table
|
||||
|
||||
@anchor{libmp3lame}
|
||||
@section libmp3lame
|
||||
|
||||
@@ -2378,70 +2322,6 @@ Indicates frame duration
|
||||
For more information about libvpx see:
|
||||
@url{http://www.webmproject.org/}
|
||||
|
||||
@section libvvenc
|
||||
|
||||
VVenC H.266/VVC encoder wrapper.
|
||||
|
||||
This encoder requires the presence of the libvvenc headers and library
|
||||
during configuration. You need to explicitly configure the build with
|
||||
@option{--enable-libvvenc}.
|
||||
|
||||
The VVenC project website is at
|
||||
@url{https://github.com/fraunhoferhhi/vvenc}.
|
||||
|
||||
@subsection Supported Pixel Formats
|
||||
|
||||
VVenC supports only 10-bit color spaces as input. But the internal (encoded)
|
||||
bit depth can be set to 8-bit or 10-bit at runtime.
|
||||
|
||||
@subsection Options
|
||||
|
||||
@table @option
|
||||
@item b
|
||||
Sets target video bitrate.
|
||||
|
||||
@item g
|
||||
Set the GOP size. Currently support for g=1 (Intra only) or default.
|
||||
|
||||
@item preset
|
||||
Set the VVenC preset.
|
||||
|
||||
@item levelidc
|
||||
Set level idc.
|
||||
|
||||
@item tier
|
||||
Set vvc tier.
|
||||
|
||||
@item qp
|
||||
Set constant quantization parameter.
|
||||
|
||||
@item subopt @var{boolean}
|
||||
Set subjective (perceptually motivated) optimization. Default is 1 (on).
|
||||
|
||||
@item bitdepth8 @var{boolean}
|
||||
Set 8bit coding mode instead of using 10bit. Default is 0 (off).
|
||||
|
||||
@item period
|
||||
set (intra) refresh period in seconds.
|
||||
|
||||
@item vvenc-params
|
||||
Set vvenc options using a list of @var{key}=@var{value} couples separated
|
||||
by ":". See @command{vvencapp --fullhelp} or @command{vvencFFapp --fullhelp} for a list of options.
|
||||
|
||||
For example, the options might be provided as:
|
||||
|
||||
@example
|
||||
intraperiod=64:decodingrefreshtype=idr:poc0idr=1:internalbitdepth=8
|
||||
@end example
|
||||
|
||||
For example the encoding options might be provided with @option{-vvenc-params}:
|
||||
|
||||
@example
|
||||
ffmpeg -i input -c:v libvvenc -b 1M -vvenc-params intraperiod=64:decodingrefreshtype=idr:poc0idr=1:internalbitdepth=8 output.mp4
|
||||
@end example
|
||||
|
||||
@end table
|
||||
|
||||
@section libwebp
|
||||
|
||||
libwebp WebP Image encoder wrapper
|
||||
@@ -3165,6 +3045,9 @@ Enable high quality AC prediction.
|
||||
@item gray
|
||||
Only encode grayscale.
|
||||
|
||||
@item gmc
|
||||
Enable the use of global motion compensation (GMC).
|
||||
|
||||
@item qpel
|
||||
Enable quarter-pixel motion compensation.
|
||||
|
||||
@@ -3176,9 +3059,7 @@ Place global headers in extradata instead of every keyframe.
|
||||
|
||||
@end table
|
||||
|
||||
@item gmc
|
||||
Enable the use of global motion compensation (GMC). Default is 0
|
||||
(disabled).
|
||||
@item trellis
|
||||
|
||||
@item me_quality
|
||||
Set motion estimation quality level. Possible values in decreasing order of
|
||||
@@ -3233,9 +3114,6 @@ be better than any of the two specified individually. In other
|
||||
words, the resulting quality will be the worse one of the two
|
||||
effects.
|
||||
|
||||
@item trellis
|
||||
Set rate-distortion optimal quantization.
|
||||
|
||||
@item ssim
|
||||
Set structural similarity (SSIM) displaying method. Possible values:
|
||||
|
||||
@@ -3610,20 +3488,6 @@ Change these value to reset qsv codec's bitrate control configuration.
|
||||
@item @var{pic_timing_sei}
|
||||
Supported in h264_qsv and hevc_qsv.
|
||||
Change this value to reset qsv codec's pic_timing_sei configuration.
|
||||
|
||||
@item @var{qsv_params}
|
||||
Set QSV encoder parameters as a colon-separated list of key-value pairs.
|
||||
|
||||
The @option{qsv_params} should be formatted as @code{key1=value1:key2=value2:...}.
|
||||
|
||||
These parameters are passed directly to the underlying Intel Quick Sync Video (QSV) encoder using the MFXSetParameter function.
|
||||
|
||||
Example:
|
||||
@example
|
||||
ffmpeg -i input.mp4 -c:v h264_qsv -qsv_params "CodingOption1=1:CodingOption2=2" output.mp4
|
||||
@end example
|
||||
|
||||
This option allows fine-grained control over various encoder-specific settings provided by the QSV encoder.
|
||||
@end table
|
||||
|
||||
@subsection H264 options
|
||||
@@ -4105,18 +3969,10 @@ Setting this flag turns on or off LowDelayBRC feautre in qsv plugin, which provi
|
||||
more accurate bitrate control to minimize the variance of bitstream size frame
|
||||
by frame. Value: -1-default 0-off 1-on
|
||||
|
||||
@item @var{max_frame_size}
|
||||
@item max_frame_size
|
||||
Set the allowed max size in bytes for each frame. If the frame size exceeds
|
||||
the limitation, encoder will adjust the QP value to control the frame size.
|
||||
Invalid in CQP rate control mode.
|
||||
|
||||
@item @var{max_frame_size_i}
|
||||
Maximum encoded frame size for I frames in bytes. If this value is set as larger
|
||||
than zero, then for I frames the value set by max_frame_size is ignored.
|
||||
|
||||
@item @var{max_frame_size_p}
|
||||
Maximum encoded frame size for P frames in bytes. If this value is set as larger
|
||||
than zero, then for P frames the value set by max_frame_size is ignored.
|
||||
@end table
|
||||
|
||||
@section snow
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libavformat/avio.h>
|
||||
#include <libavutil/file.h>
|
||||
#include <libavutil/mem.h>
|
||||
|
||||
struct buffer_data {
|
||||
uint8_t *ptr;
|
||||
|
||||
@@ -37,7 +37,6 @@
|
||||
#include <libavfilter/buffersink.h>
|
||||
#include <libavfilter/buffersrc.h>
|
||||
#include <libavutil/channel_layout.h>
|
||||
#include <libavutil/mem.h>
|
||||
#include <libavutil/opt.h>
|
||||
|
||||
static const char *filter_descr = "aresample=8000,aformat=sample_fmts=s16:channel_layouts=mono";
|
||||
@@ -280,25 +279,6 @@ int main(int argc, char **argv)
|
||||
}
|
||||
av_packet_unref(packet);
|
||||
}
|
||||
if (ret == AVERROR_EOF) {
|
||||
/* signal EOF to the filtergraph */
|
||||
if (av_buffersrc_add_frame_flags(buffersrc_ctx, NULL, 0) < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Error while closing the filtergraph\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* pull remaining frames from the filtergraph */
|
||||
while (1) {
|
||||
ret = av_buffersink_get_frame(buffersink_ctx, filt_frame);
|
||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
|
||||
break;
|
||||
if (ret < 0)
|
||||
goto end;
|
||||
print_frame(filt_frame);
|
||||
av_frame_unref(filt_frame);
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
avfilter_graph_free(&filter_graph);
|
||||
avcodec_free_context(&dec_ctx);
|
||||
|
||||
@@ -36,7 +36,6 @@
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libavfilter/buffersink.h>
|
||||
#include <libavfilter/buffersrc.h>
|
||||
#include <libavutil/mem.h>
|
||||
#include <libavutil/opt.h>
|
||||
|
||||
const char *filter_descr = "scale=78:24,transpose=cclock";
|
||||
@@ -277,25 +276,6 @@ int main(int argc, char **argv)
|
||||
}
|
||||
av_packet_unref(packet);
|
||||
}
|
||||
if (ret == AVERROR_EOF) {
|
||||
/* signal EOF to the filtergraph */
|
||||
if (av_buffersrc_add_frame_flags(buffersrc_ctx, NULL, 0) < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Error while closing the filtergraph\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* pull remaining frames from the filtergraph */
|
||||
while (1) {
|
||||
ret = av_buffersink_get_frame(buffersink_ctx, filt_frame);
|
||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
|
||||
break;
|
||||
if (ret < 0)
|
||||
goto end;
|
||||
display_frame(filt_frame, buffersink_ctx->inputs[0]->time_base);
|
||||
av_frame_unref(filt_frame);
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
avfilter_graph_free(&filter_graph);
|
||||
avcodec_free_context(&dec_ctx);
|
||||
|
||||
@@ -138,9 +138,11 @@ static int decode_packet(AVCodecContext *dec, const AVPacket *pkt)
|
||||
ret = output_audio_frame(frame);
|
||||
|
||||
av_frame_unref(frame);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int open_codec_context(int *stream_idx,
|
||||
|
||||
@@ -41,15 +41,15 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <libavutil/channel_layout.h>
|
||||
#include <libavutil/md5.h>
|
||||
#include <libavutil/mem.h>
|
||||
#include <libavutil/opt.h>
|
||||
#include <libavutil/samplefmt.h>
|
||||
#include "libavutil/channel_layout.h"
|
||||
#include "libavutil/md5.h"
|
||||
#include "libavutil/mem.h"
|
||||
#include "libavutil/opt.h"
|
||||
#include "libavutil/samplefmt.h"
|
||||
|
||||
#include <libavfilter/avfilter.h>
|
||||
#include <libavfilter/buffersink.h>
|
||||
#include <libavfilter/buffersrc.h>
|
||||
#include "libavfilter/avfilter.h"
|
||||
#include "libavfilter/buffersink.h"
|
||||
#include "libavfilter/buffersrc.h"
|
||||
|
||||
#define INPUT_SAMPLERATE 48000
|
||||
#define INPUT_FORMAT AV_SAMPLE_FMT_FLTP
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libavutil/mem.h>
|
||||
#include <libavutil/pixdesc.h>
|
||||
#include <libavutil/hwcontext.h>
|
||||
#include <libavutil/opt.h>
|
||||
|
||||
+2
-1
@@ -347,7 +347,8 @@ static int write_audio_frame(AVFormatContext *oc, OutputStream *ost)
|
||||
if (frame) {
|
||||
/* convert samples from native format to destination codec format, using the resampler */
|
||||
/* compute destination number of samples */
|
||||
dst_nb_samples = swr_get_delay(ost->swr_ctx, c->sample_rate) + frame->nb_samples;
|
||||
dst_nb_samples = av_rescale_rnd(swr_get_delay(ost->swr_ctx, c->sample_rate) + frame->nb_samples,
|
||||
c->sample_rate, c->sample_rate, AV_ROUND_UP);
|
||||
av_assert0(dst_nb_samples == frame->nb_samples);
|
||||
|
||||
/* when we pass a frame to the encoder, it may keep a reference to it
|
||||
|
||||
@@ -30,16 +30,16 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libavformat/avio.h>
|
||||
#include "libavformat/avformat.h"
|
||||
#include "libavformat/avio.h"
|
||||
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include "libavcodec/avcodec.h"
|
||||
|
||||
#include <libavutil/buffer.h>
|
||||
#include <libavutil/error.h>
|
||||
#include <libavutil/hwcontext.h>
|
||||
#include <libavutil/hwcontext_qsv.h>
|
||||
#include <libavutil/mem.h>
|
||||
#include "libavutil/buffer.h"
|
||||
#include "libavutil/error.h"
|
||||
#include "libavutil/hwcontext.h"
|
||||
#include "libavutil/hwcontext_qsv.h"
|
||||
#include "libavutil/mem.h"
|
||||
|
||||
static int get_format(AVCodecContext *avctx, const enum AVPixelFormat *pix_fmts)
|
||||
{
|
||||
|
||||
@@ -38,7 +38,6 @@
|
||||
#include <errno.h>
|
||||
|
||||
#include <libavutil/hwcontext.h>
|
||||
#include <libavutil/mem.h>
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libavutil/opt.h>
|
||||
@@ -76,7 +75,8 @@ static int str_to_dict(char* optstr, AVDictionary **opt)
|
||||
if (value == NULL)
|
||||
return AVERROR(EINVAL);
|
||||
av_dict_set(opt, key, value, 0);
|
||||
} while(1);
|
||||
} while(key != NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dynamic_set_parameter(AVCodecContext *avctx)
|
||||
@@ -334,15 +334,17 @@ static int dec_enc(AVPacket *pkt, const AVCodec *enc_codec, char *optstr)
|
||||
|
||||
fail:
|
||||
av_frame_free(&frame);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const AVCodec *enc_codec;
|
||||
int ret = 0;
|
||||
AVPacket *dec_pkt = NULL;
|
||||
AVPacket *dec_pkt;
|
||||
|
||||
if (argc < 5 || (argc - 5) % 2) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Usage: %s <input file> <encoder> <output file>"
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
* input to the output without transcoding.
|
||||
*/
|
||||
|
||||
#include <libavutil/mem.h>
|
||||
#include <libavutil/timestamp.h>
|
||||
#include <libavformat/avformat.h>
|
||||
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
#include <libavfilter/buffersink.h>
|
||||
#include <libavfilter/buffersrc.h>
|
||||
#include <libavutil/channel_layout.h>
|
||||
#include <libavutil/mem.h>
|
||||
#include <libavutil/opt.h>
|
||||
#include <libavutil/pixdesc.h>
|
||||
|
||||
|
||||
@@ -29,20 +29,19 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <libavutil/mem.h>
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libavformat/avio.h>
|
||||
#include "libavformat/avformat.h"
|
||||
#include "libavformat/avio.h"
|
||||
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include "libavcodec/avcodec.h"
|
||||
|
||||
#include <libavutil/audio_fifo.h>
|
||||
#include <libavutil/avassert.h>
|
||||
#include <libavutil/avstring.h>
|
||||
#include <libavutil/channel_layout.h>
|
||||
#include <libavutil/frame.h>
|
||||
#include <libavutil/opt.h>
|
||||
#include "libavutil/audio_fifo.h"
|
||||
#include "libavutil/avassert.h"
|
||||
#include "libavutil/avstring.h"
|
||||
#include "libavutil/channel_layout.h"
|
||||
#include "libavutil/frame.h"
|
||||
#include "libavutil/opt.h"
|
||||
|
||||
#include <libswresample/swresample.h>
|
||||
#include "libswresample/swresample.h"
|
||||
|
||||
/* The output bit rate in bit/s */
|
||||
#define OUTPUT_BIT_RATE 96000
|
||||
|
||||
@@ -88,10 +88,6 @@ static int encode_write(AVCodecContext *avctx, AVFrame *frame, FILE *fout)
|
||||
enc_pkt->stream_index = 0;
|
||||
ret = fwrite(enc_pkt->data, enc_pkt->size, 1, fout);
|
||||
av_packet_unref(enc_pkt);
|
||||
if (ret != enc_pkt->size) {
|
||||
ret = AVERROR(errno);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
|
||||
@@ -215,8 +215,10 @@ static int dec_enc(AVPacket *pkt, const AVCodec *enc_codec)
|
||||
|
||||
fail:
|
||||
av_frame_free(&frame);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
|
||||
+16
-149
@@ -229,16 +229,12 @@ successive integers starting at zero. These indices should then be used to refer
|
||||
to loopback decoders in complex filtergraph link labels, as described in the
|
||||
documentation for @option{-filter_complex}.
|
||||
|
||||
Decoding AVOptions can be passed to loopback decoders by placing them before
|
||||
@code{-dec}, analogously to input/output options.
|
||||
|
||||
E.g. the following example:
|
||||
|
||||
@example
|
||||
ffmpeg -i INPUT \
|
||||
-map 0:v:0 -c:v libx264 -crf 45 -f null - \
|
||||
-threads 3 -dec 0:0 \
|
||||
-filter_complex '[0:v][dec:0]hstack[stack]' \
|
||||
-dec 0:0 -filter_complex '[0:v][dec:0]hstack[stack]' \
|
||||
-map '[stack]' -c:v ffv1 OUTPUT
|
||||
@end example
|
||||
|
||||
@@ -248,13 +244,11 @@ reads an input video and
|
||||
(line 2) encodes it with @code{libx264} at low quality;
|
||||
|
||||
@item
|
||||
(line 3) decodes this encoded stream using 3 threads;
|
||||
(line 3) decodes this encoded stream and places it side by side with the
|
||||
original input video;
|
||||
|
||||
@item
|
||||
(line 4) places decoded video side by side with the original input video;
|
||||
|
||||
@item
|
||||
(line 5) combined video is then losslessly encoded and written into
|
||||
(line 4) combined video is then losslessly encoded and written into
|
||||
@file{OUTPUT}.
|
||||
|
||||
@end itemize
|
||||
@@ -663,11 +657,10 @@ Not all muxers support embedded thumbnails, and those who do, only support a few
|
||||
Creates a program with the specified @var{title}, @var{program_num} and adds the specified
|
||||
@var{stream}(s) to it.
|
||||
|
||||
@item -stream_group [map=@var{input_file_id}=@var{stream_group}][type=@var{type}:]st=@var{stream}[:st=@var{stream}][:stg=@var{stream_group}][:id=@var{stream_group_id}...] (@emph{output})
|
||||
@item -stream_group type=@var{type}:st=@var{stream}[:st=@var{stream}][:stg=@var{stream_group}][:id=@var{stream_group_id}...] (@emph{output})
|
||||
|
||||
Creates a stream group of the specified @var{type} and @var{stream_group_id}, or by
|
||||
@var{map}ping an input group, adding the specified @var{stream}(s) and/or previously
|
||||
defined @var{stream_group}(s) to it.
|
||||
Creates a stream group of the specified @var{type}, @var{stream_group_id} and adds the specified
|
||||
@var{stream}(s) and/or previously defined @var{stream_group}(s) to it.
|
||||
|
||||
@var{type} can be one of the following:
|
||||
@table @option
|
||||
@@ -864,27 +857,6 @@ all sub-mix element's @var{annotations}s
|
||||
|
||||
@end table
|
||||
|
||||
E.g. to create an scalable 5.1 IAMF file from several WAV input files
|
||||
@example
|
||||
ffmpeg -i front.wav -i back.wav -i center.wav -i lfe.wav
|
||||
-map 0:0 -map 1:0 -map 2:0 -map 3:0 -c:a opus
|
||||
-stream_group type=iamf_audio_element:id=1:st=0:st=1:st=2:st=3,
|
||||
demixing=parameter_id=998,
|
||||
recon_gain=parameter_id=101,
|
||||
layer=ch_layout=stereo,
|
||||
layer=ch_layout=5.1,
|
||||
-stream_group type=iamf_mix_presentation:id=2:stg=0:annotations=en-us=Mix_Presentation,
|
||||
submix=parameter_id=100:parameter_rate=48000|element=stg=0:parameter_id=100:annotations=en-us=Scalable_Submix|layout=sound_system=stereo|layout=sound_system=5.1
|
||||
-streamid 0:0 -streamid 1:1 -streamid 2:2 -streamid 3:3 output.iamf
|
||||
@end example
|
||||
|
||||
To copy the two stream groups (Audio Element and Mix Presentation) from an input IAMF file with four
|
||||
streams into an mp4 output
|
||||
@example
|
||||
ffmpeg -i input.iamf -c:a copy -stream_group map=0=0:st=0:st=1:st=2:st=3 -stream_group map=0=1:stg=0
|
||||
-streamid 0:0 -streamid 1:1 -streamid 2:2 -streamid 3:3 output.mp4
|
||||
@end example
|
||||
|
||||
@item -target @var{type} (@emph{output})
|
||||
Specify target file type (@code{vcd}, @code{svcd}, @code{dvd}, @code{dv},
|
||||
@code{dv50}). @var{type} may be prefixed with @code{pal-}, @code{ntsc-} or
|
||||
@@ -1379,21 +1351,6 @@ Note that forcing too many keyframes is very harmful for the lookahead
|
||||
algorithms of certain encoders: using fixed-GOP options or similar
|
||||
would be more efficient.
|
||||
|
||||
@item -apply_cropping[:@var{stream_specifier}] @var{source} (@emph{input,per-stream})
|
||||
Automatically crop the video after decoding according to file metadata.
|
||||
Default is @emph{all}.
|
||||
|
||||
@table @option
|
||||
@item none (0)
|
||||
Don't apply any cropping metadata.
|
||||
@item all (1)
|
||||
Apply both codec and container level croppping. This is the default mode.
|
||||
@item codec (2)
|
||||
Apply codec level croppping.
|
||||
@item container (3)
|
||||
Apply container level croppping.
|
||||
@end table
|
||||
|
||||
@item -copyinkf[:@var{stream_specifier}] (@emph{output,per-stream})
|
||||
When doing stream copy, copy also non-key frames found at the
|
||||
beginning.
|
||||
@@ -1458,11 +1415,6 @@ The following options are recognized:
|
||||
When @var{device} is not specified, use this option to specify the name of the kernel
|
||||
driver associated with the desired device. This option is available only when
|
||||
the hardware acceleration method @emph{drm} and @emph{vaapi} are enabled.
|
||||
@item vendor_id
|
||||
When @var{device} and @var{kernel_driver} are not specified, use this option to specify
|
||||
the vendor id associated with the desired device. This option is available only when the
|
||||
hardware acceleration method @emph{drm} and @emph{vaapi} are enabled and @emph{kernel_driver}
|
||||
is not specified.
|
||||
@end table
|
||||
|
||||
Examples:
|
||||
@@ -1478,9 +1430,6 @@ Create a vaapi device on DirectX adapter 1.
|
||||
|
||||
@item -init_hw_device vaapi:,kernel_driver=i915
|
||||
Create a vaapi device on a device associated with kernel driver @samp{i915}.
|
||||
|
||||
@item -init_hw_device vaapi:,vendor_id=0x8086
|
||||
Create a vaapi device on a device associated with vendor id @samp{0x8086}.
|
||||
@end table
|
||||
|
||||
@item vdpau
|
||||
@@ -1742,21 +1691,12 @@ This is an alias for @code{-filter:a}, see the @ref{filter_option,,-filter optio
|
||||
@table @option
|
||||
@item -atag @var{fourcc/tag} (@emph{output})
|
||||
Force audio tag/fourcc. This is an alias for @code{-tag:a}.
|
||||
@item -ch_layout[:@var{stream_specifier}] @var{layout} (@emph{input/output,per-stream})
|
||||
Alias for @code{-channel_layout}.
|
||||
@item -channel_layout[:@var{stream_specifier}] @var{layout} (@emph{input/output,per-stream})
|
||||
Set the audio channel layout. For output streams it is set by default to the
|
||||
input channel layout. For input streams it overrides the channel layout of the
|
||||
input. Not all decoders respect the overridden channel layout. This option
|
||||
also sets the channel layout for audio grabbing devices and raw demuxers
|
||||
and is mapped to the corresponding demuxer option.
|
||||
@item -guess_layout_max @var{channels} (@emph{input,per-stream})
|
||||
If some input channel layout is not known, try to guess only if it
|
||||
corresponds to at most the specified number of channels. For example, 2
|
||||
tells to @command{ffmpeg} to recognize 1 channel as mono and 2 channels as
|
||||
stereo but not 6 channels as 5.1. The default is to always try to guess. Use
|
||||
0 to disable all guessing. Using the @code{-channel_layout} option to
|
||||
explicitly specify an input layout also disables guessing.
|
||||
0 to disable all guessing.
|
||||
@end table
|
||||
|
||||
@section Subtitle options
|
||||
@@ -1799,7 +1739,7 @@ Set the size of the canvas used to render subtitles.
|
||||
@section Advanced options
|
||||
|
||||
@table @option
|
||||
@item -map [-]@var{input_file_id}[:@var{stream_specifier}][:@var{view_specifier}][?] | @var{[linklabel]} (@emph{output})
|
||||
@item -map [-]@var{input_file_id}[:@var{stream_specifier}][?] | @var{[linklabel]} (@emph{output})
|
||||
|
||||
Create one or more streams in the output file. This option has two forms for
|
||||
specifying the data source(s): the first selects one or more streams from some
|
||||
@@ -1814,26 +1754,6 @@ only those streams that match the specifier are used (see the
|
||||
A @code{-} character before the stream identifier creates a "negative" mapping.
|
||||
It disables matching streams from already created mappings.
|
||||
|
||||
An optional @var{view_specifier} may be given after the stream specifier, which
|
||||
for multiview video specifies the view to be used. The view specifier may have
|
||||
one of the following formats:
|
||||
@table @option
|
||||
@item view:@var{view_id}
|
||||
select a view by its ID; @var{view_id} may be set to 'all' to use all the views
|
||||
interleaved into one stream;
|
||||
|
||||
@item vidx:@var{view_idx}
|
||||
select a view by its index; i.e. 0 is the base view, 1 is the first non-base
|
||||
view, etc.
|
||||
|
||||
@item vpos:@var{position}
|
||||
select a view by its display position; @var{position} may be @code{left} or
|
||||
@code{right}
|
||||
@end table
|
||||
The default for transcoding is to only use the base view, i.e. the equivalent of
|
||||
@code{vidx:0}. For streamcopy, view specifiers are not supported and all views
|
||||
are always copied.
|
||||
|
||||
A trailing @code{?} after the stream index will allow the map to be
|
||||
optional: if the map matches no streams the map will be ignored instead
|
||||
of failing. Note the map will still fail if an invalid input file index
|
||||
@@ -2217,68 +2137,15 @@ Define a complex filtergraph, i.e. one with arbitrary number of inputs and/or
|
||||
outputs. For simple graphs -- those with one input and one output of the same
|
||||
type -- see the @option{-filter} options. @var{filtergraph} is a description of
|
||||
the filtergraph, as described in the ``Filtergraph syntax'' section of the
|
||||
ffmpeg-filters manual. This option may be specified multiple times - each use
|
||||
creates a new complex filtergraph.
|
||||
ffmpeg-filters manual.
|
||||
|
||||
Inputs to a complex filtergraph may come from different source types,
|
||||
distinguished by the format of the corresponding link label:
|
||||
@itemize
|
||||
@item
|
||||
To connect an input stream, use @code{[file_index:stream_specifier]} (i.e. the
|
||||
same syntax as @option{-map}). If @var{stream_specifier} matches multiple
|
||||
streams, the first one will be used. For multiview video, the stream specifier
|
||||
may be followed by the view specifier, see documentation for the @option{-map}
|
||||
option for its syntax.
|
||||
Input link labels must refer to either input streams or loopback decoders. For
|
||||
input streams, use the @code{[file_index:stream_specifier]} syntax (i.e. the
|
||||
same as @option{-map} uses). If @var{stream_specifier} matches multiple streams,
|
||||
the first one will be used.
|
||||
|
||||
@item
|
||||
To connect a loopback decoder use [dec:@var{dec_idx}], where @var{dec_idx} is
|
||||
the index of the loopback decoder to be connected to given input. For multiview
|
||||
video, the decoder index may be followed by the view specifier, see
|
||||
documentation for the @option{-map} option for its syntax.
|
||||
|
||||
@item
|
||||
To connect an output from another complex filtergraph, use its link label. E.g
|
||||
the following example:
|
||||
|
||||
@example
|
||||
ffmpeg -i input.mkv \
|
||||
-filter_complex '[0:v]scale=size=hd1080,split=outputs=2[for_enc][orig_scaled]' \
|
||||
-c:v libx264 -map '[for_enc]' output.mkv \
|
||||
-dec 0:0 \
|
||||
-filter_complex '[dec:0][orig_scaled]hstack[stacked]' \
|
||||
-map '[stacked]' -c:v ffv1 comparison.mkv
|
||||
@end example
|
||||
|
||||
reads an input video and
|
||||
@itemize
|
||||
@item
|
||||
(line 2) uses a complex filtergraph with one input and two outputs
|
||||
to scale the video to 1920x1080 and duplicate the result to both
|
||||
outputs;
|
||||
|
||||
@item
|
||||
(line 3) encodes one scaled output with @code{libx264} and writes the result to
|
||||
@file{output.mkv};
|
||||
|
||||
@item
|
||||
(line 4) decodes this encoded stream with a loopback decoder;
|
||||
|
||||
@item
|
||||
(line 5) places the output of the loopback decoder (i.e. the
|
||||
@code{libx264}-encoded video) side by side with the scaled original input;
|
||||
|
||||
@item
|
||||
(line 6) combined video is then losslessly encoded and written into
|
||||
@file{comparison.mkv}.
|
||||
|
||||
@end itemize
|
||||
|
||||
Note that the two filtergraphs cannot be combined into one, because then there
|
||||
would be a cycle in the transcoding pipeline (filtergraph output goes to
|
||||
encoding, from there to decoding, then back to the same graph), and such cycles
|
||||
are not allowed.
|
||||
|
||||
@end itemize
|
||||
For decoders, the link label must be [dec:@var{dec_idx}], where @var{dec_idx} is
|
||||
the index of the loopback decoder to be connected to given input.
|
||||
|
||||
An unlabeled input will be connected to the first unused input stream of the
|
||||
matching type.
|
||||
|
||||
@@ -255,7 +255,6 @@
|
||||
<xsd:attribute name="metadata" type="xsd:int" use="required" />
|
||||
<xsd:attribute name="dependent" type="xsd:int" use="required" />
|
||||
<xsd:attribute name="still_image" type="xsd:int" use="required" />
|
||||
<xsd:attribute name="multilayer" type="xsd:int" use="required" />
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:complexType name="streamType">
|
||||
|
||||
@@ -79,10 +79,6 @@ Match the stream by stream id (e.g. PID in MPEG-TS container).
|
||||
Matches streams with the metadata tag @var{key} having the specified value. If
|
||||
@var{value} is not given, matches streams that contain the given tag with any
|
||||
value.
|
||||
@item disp:@var{dispositions}[:@var{additional_stream_specifier}]
|
||||
Matches streams with the given disposition(s). @var{dispositions} is a list of
|
||||
one or more dispositions (as printed by the @option{-dispositions} option)
|
||||
joined with '+'.
|
||||
@item u
|
||||
Matches streams with usable configuration, the codec must be defined and the
|
||||
essential information such as video dimension or audio sample rate must be present.
|
||||
|
||||
+100
-463
@@ -11092,8 +11092,8 @@ By default, a component curve is defined by the two points @var{(0;0)} and
|
||||
"adjusted" to its own value, which means no change to the image.
|
||||
|
||||
The filter allows you to redefine these two points and add some more. A new
|
||||
curve will be defined to pass smoothly through all these new coordinates. The
|
||||
new defined points need to be strictly increasing over the x-axis, and their
|
||||
curve will be define to pass smoothly through all these new coordinates. The
|
||||
new defined points needs to be strictly increasing over the x-axis, and their
|
||||
@var{x} and @var{y} values must be in the @var{[0;1]} interval. The curve is
|
||||
formed by using a natural or monotonic cubic spline interpolation, depending
|
||||
on the @var{interp} option (default: @code{natural}). The @code{natural}
|
||||
@@ -17071,8 +17071,8 @@ ffmpeg \
|
||||
-hwaccel cuda -hwaccel_output_format cuda -codec:v av1_cuvid -i dis.obu \
|
||||
-hwaccel cuda -hwaccel_output_format cuda -codec:v av1_cuvid -i ref.obu \
|
||||
-filter_complex "
|
||||
[0:v]scale_cuda=format=yuv420p[dis]; \
|
||||
[1:v]scale_cuda=format=yuv420p[ref]; \
|
||||
[0:v]scale_cuda=format=yuv420p[ref]; \
|
||||
[1:v]scale_cuda=format=yuv420p[dis]; \
|
||||
[dis][ref]libvmaf_cuda=log_fmt=json:log_path=output.json
|
||||
" \
|
||||
-f null -
|
||||
@@ -17290,9 +17290,6 @@ The command accepts the same syntax of the corresponding option.
|
||||
If the specified expression is not valid, it is kept at its current
|
||||
value.
|
||||
|
||||
@anchor{lutrgb}
|
||||
@anchor{lutyuv}
|
||||
@anchor{lut}
|
||||
@section lut, lutrgb, lutyuv
|
||||
|
||||
Compute a look-up table for binding each pixel component input value
|
||||
@@ -19944,7 +19941,6 @@ pseudocolor="'if(between(val,ymax,amax),lerp(ymin,ymax,(val-ymax)/(amax-ymax)),-
|
||||
@end example
|
||||
@end itemize
|
||||
|
||||
@anchor{psnr}
|
||||
@section psnr
|
||||
|
||||
Obtain the average, maximum and minimum PSNR (Peak Signal to Noise
|
||||
@@ -20993,8 +20989,8 @@ the next filter, the scale filter will convert the input to the
|
||||
requested format.
|
||||
|
||||
@subsection Options
|
||||
The filter accepts the following options, any of the options supported
|
||||
by the libswscale scaler, as well as any of the @ref{framesync} options.
|
||||
The filter accepts the following options, or any of the options
|
||||
supported by the libswscale scaler.
|
||||
|
||||
See @ref{scaler_options,,the ffmpeg-scaler manual,ffmpeg-scaler} for
|
||||
the complete list of scaler options.
|
||||
@@ -21138,21 +21134,6 @@ Set full range (0-255 in case of 8-bit luma).
|
||||
Set "MPEG" range (16-235 in case of 8-bit luma).
|
||||
@end table
|
||||
|
||||
@item in_chroma_loc
|
||||
@item out_chroma_loc
|
||||
Set in/output chroma sample location. If not specified, center-sited chroma
|
||||
is used by default. Possible values:
|
||||
|
||||
@table @samp
|
||||
@item auto, unknown
|
||||
@item left
|
||||
@item center
|
||||
@item topleft
|
||||
@item top
|
||||
@item bottomleft
|
||||
@item bottom
|
||||
@end table
|
||||
|
||||
@item force_original_aspect_ratio
|
||||
Enable decreasing or increasing output video width or height if necessary to
|
||||
keep the original aspect ratio. Possible values:
|
||||
@@ -21247,16 +21228,6 @@ The position (byte offset) of the frame in the input stream, or NaN if
|
||||
this information is unavailable and/or meaningless (for example in case of synthetic video).
|
||||
Only available with @code{eval=frame}.
|
||||
Deprecated, do not use.
|
||||
|
||||
@item ref_w, rw
|
||||
@item ref_h, rh
|
||||
@item ref_a
|
||||
@item ref_dar, rdar
|
||||
@item ref_n
|
||||
@item ref_t
|
||||
@item ref_pos
|
||||
Eqvuialent to the above, but for a second reference input. If any of these
|
||||
variables are present, this filter accepts two inputs.
|
||||
@end table
|
||||
|
||||
@subsection Examples
|
||||
@@ -21358,20 +21329,6 @@ making sure the resulting resolution is even (required by some codecs):
|
||||
@example
|
||||
scale='trunc(ih*dar/2)*2:trunc(ih/2)*2',setsar=1/1
|
||||
@end example
|
||||
|
||||
@item
|
||||
Scale a subtitle stream (sub) to match the main video (main) in size before
|
||||
overlaying. ("scale2ref")
|
||||
@example
|
||||
'[main]split[a][b]; [ref][a]scale=rw:rh[c]; [b][c]overlay'
|
||||
@end example
|
||||
|
||||
@item
|
||||
Scale a logo to 1/10th the height of a video, while preserving its display
|
||||
aspect ratio.
|
||||
@example
|
||||
[logo-in][video-in]scale=w=oh*dar:h=rh/10[logo-out]
|
||||
@end example
|
||||
@end itemize
|
||||
|
||||
@subsection Commands
|
||||
@@ -21607,6 +21564,79 @@ Only available with @code{eval=frame}.
|
||||
Deprecated, do not use.
|
||||
@end table
|
||||
|
||||
@section scale2ref
|
||||
|
||||
Scale (resize) the input video, based on a reference video.
|
||||
|
||||
See the scale filter for available options, scale2ref supports the same but
|
||||
uses the reference video instead of the main input as basis. scale2ref also
|
||||
supports the following additional constants for the @option{w} and
|
||||
@option{h} options:
|
||||
|
||||
@table @var
|
||||
@item main_w
|
||||
@item main_h
|
||||
The main input video's width and height
|
||||
|
||||
@item main_a
|
||||
The same as @var{main_w} / @var{main_h}
|
||||
|
||||
@item main_sar
|
||||
The main input video's sample aspect ratio
|
||||
|
||||
@item main_dar, mdar
|
||||
The main input video's display aspect ratio. Calculated from
|
||||
@code{(main_w / main_h) * main_sar}.
|
||||
|
||||
@item main_hsub
|
||||
@item main_vsub
|
||||
The main input video's horizontal and vertical chroma subsample values.
|
||||
For example for the pixel format "yuv422p" @var{hsub} is 2 and @var{vsub}
|
||||
is 1.
|
||||
|
||||
@item main_n
|
||||
The (sequential) number of the main input frame, starting from 0.
|
||||
Only available with @code{eval=frame}.
|
||||
|
||||
@item main_t
|
||||
The presentation timestamp of the main input frame, expressed as a number of
|
||||
seconds. Only available with @code{eval=frame}.
|
||||
|
||||
@item main_pos
|
||||
The position (byte offset) of the frame in the main input stream, or NaN if
|
||||
this information is unavailable and/or meaningless (for example in case of synthetic video).
|
||||
Only available with @code{eval=frame}.
|
||||
@end table
|
||||
|
||||
@subsection Examples
|
||||
|
||||
@itemize
|
||||
@item
|
||||
Scale a subtitle stream (b) to match the main video (a) in size before overlaying
|
||||
@example
|
||||
'scale2ref[b][a];[a][b]overlay'
|
||||
@end example
|
||||
|
||||
@item
|
||||
Scale a logo to 1/10th the height of a video, while preserving its display aspect ratio.
|
||||
@example
|
||||
[logo-in][video-in]scale2ref=w=oh*mdar:h=ih/10[logo-out][video-out]
|
||||
@end example
|
||||
@end itemize
|
||||
|
||||
@subsection Commands
|
||||
|
||||
This filter supports the following commands:
|
||||
@table @option
|
||||
@item width, w
|
||||
@item height, h
|
||||
Set the output video dimension expression.
|
||||
The command accepts the same syntax of the corresponding option.
|
||||
|
||||
If the specified expression is not valid, it is kept at its current
|
||||
value.
|
||||
@end table
|
||||
|
||||
@section scale2ref_npp
|
||||
|
||||
Use the NVIDIA Performance Primitives (libnpp) to scale (resize) the input
|
||||
@@ -22089,23 +22119,6 @@ Keep the same colorspace property (default).
|
||||
@item chroma-derived-c
|
||||
@item ictcp
|
||||
@end table
|
||||
|
||||
@item chroma_location
|
||||
Set the chroma sample location.
|
||||
Available values are:
|
||||
|
||||
@table @samp
|
||||
@item auto
|
||||
Keep the same chroma location (default).
|
||||
|
||||
@item unspecified, unknown
|
||||
@item left
|
||||
@item center
|
||||
@item topleft
|
||||
@item top
|
||||
@item bottomleft
|
||||
@item bottom
|
||||
@end table
|
||||
@end table
|
||||
|
||||
@section sharpen_npp
|
||||
@@ -22689,27 +22702,9 @@ whether a pixel should be blurred or not. The option value must be an
|
||||
integer in the range [-30,30]. A value of 0 will filter all the image,
|
||||
a value included in [0,30] will filter flat areas and a value included
|
||||
in [-30,0] will filter edges. Default value is @option{luma_threshold}.
|
||||
|
||||
@item alpha_radius, ar
|
||||
Set the alpha radius. The option value must be a float number in
|
||||
the range [0.1,5.0] that specifies the variance of the gaussian filter
|
||||
used to blur the image (slower if larger). Default value is @option{luma_radius}.
|
||||
|
||||
@item alpha_strength, as
|
||||
Set the alpha strength. The option value must be a float number
|
||||
in the range [-1.0,1.0] that configures the blurring. A value included
|
||||
in [0.0,1.0] will blur the image whereas a value included in
|
||||
[-1.0,0.0] will sharpen the image. Default value is @option{luma_strength}.
|
||||
|
||||
@item alpha_threshold, at
|
||||
Set the alpha threshold used as a coefficient to determine
|
||||
whether a pixel should be blurred or not. The option value must be an
|
||||
integer in the range [-30,30]. A value of 0 will filter all the image,
|
||||
a value included in [0,30] will filter flat areas and a value included
|
||||
in [-30,0] will filter edges. Default value is @option{luma_threshold}.
|
||||
@end table
|
||||
|
||||
If a chroma or alpha option is not explicitly set, the corresponding luma value
|
||||
If a chroma option is not explicitly set, the corresponding luma value
|
||||
is set.
|
||||
|
||||
@section sobel
|
||||
@@ -23579,13 +23574,12 @@ tile=3x2:nb_frames=5:padding=7:margin=2
|
||||
@end itemize
|
||||
|
||||
@section tiltandshift
|
||||
Apply tilt-and-shift effect.
|
||||
|
||||
What happens when you invert time and space?
|
||||
|
||||
Normally a video is composed of several frames that represent a different
|
||||
instant of time and shows a scene that evolves in the space captured by the
|
||||
frame. This filter is the antipode of that concept, taking inspiration from
|
||||
instant of time and shows a scence that evolves in the space captured by the
|
||||
frame. This filter is the antipode of that concept, taking inspiration by
|
||||
tilt and shift photography.
|
||||
|
||||
A filtered frame contains the whole timeline of events composing the sequence,
|
||||
@@ -23593,13 +23587,13 @@ and this is obtained by placing a slice of pixels from each frame into a single
|
||||
one. However, since there are no infinite-width frames, this is done up the
|
||||
width of the input frame, and a video is recomposed by shifting away one
|
||||
column for each subsequent frame. In order to map space to time, the filter
|
||||
tilts each input frame as well, so that motion is preserved. This is accomplished
|
||||
tilts each input frame as well, so that motion is preseved. This is accomplished
|
||||
by progressively selecting a different column from each input frame.
|
||||
|
||||
The end result is a sort of inverted parallax, so that far away objects move
|
||||
The end result is a sort of inverted parralax, so that far away objects move
|
||||
much faster that the ones in the front. The ideal conditions for this video
|
||||
effect are when there is either very little motion and the backgroud is static,
|
||||
or when there is a lot of motion and a very wide depth of field (e.g. wide
|
||||
or when there is a lot of motion and a very wide depth of field (eg. wide
|
||||
panorama, while moving on a train).
|
||||
|
||||
The filter accepts the following parameters:
|
||||
@@ -23624,7 +23618,7 @@ How many columns should be inserted before end of filtering.
|
||||
|
||||
@end table
|
||||
|
||||
Normally the filter shifts and tilts from the very first frame, and stops when
|
||||
Normally the filter shifts and tils from the very first frame, and stops when
|
||||
the last one is received. However, before filtering starts, normal video may
|
||||
be preseved, so that the effect is slowly shifted in its place. Similarly,
|
||||
the last video frame may be reconstructed at the end. Alternatively it is
|
||||
@@ -23632,7 +23626,7 @@ possible to just start and end with black.
|
||||
|
||||
@table @samp
|
||||
@item none
|
||||
Filtering starts immediately and ends when the last frame is received.
|
||||
Filtering is starts immediately and ends when the last frame is received.
|
||||
|
||||
@item frame
|
||||
The first frames or the very last frame are kept intact during processing.
|
||||
@@ -24464,7 +24458,7 @@ The way this differs from the behavior of spp is that uspp actually encodes &
|
||||
decodes each case with libavcodec Snow, whereas spp uses a simplified intra only 8x8
|
||||
DCT similar to MJPEG.
|
||||
|
||||
This filter is not available in ffmpeg versions between 5.0 and 6.0.
|
||||
This filter is only available in ffmpeg version 4.4 or earlier.
|
||||
|
||||
The filter accepts the following options:
|
||||
|
||||
@@ -26065,73 +26059,6 @@ minimum values, and @code{1} maximum values.
|
||||
|
||||
This filter supports all above options as @ref{commands}, excluding option @code{inputs}.
|
||||
|
||||
@anchor{xpsnr}
|
||||
@section xpsnr
|
||||
|
||||
Obtain the average (across all input frames) and minimum (across all color plane averages)
|
||||
eXtended Perceptually weighted peak Signal-to-Noise Ratio (XPSNR) between two input videos.
|
||||
|
||||
The XPSNR is a low-complexity psychovisually motivated distortion measurement algorithm for
|
||||
assessing the difference between two video streams or images. This is especially useful for
|
||||
objectively quantifying the distortions caused by video and image codecs, as an alternative
|
||||
to a formal subjective test. The logarithmic XPSNR output values are in a similar range as
|
||||
those of traditional @ref{psnr} assessments but better reflect human impressions of visual
|
||||
coding quality. More details on the XPSNR measure, which essentially represents a blockwise
|
||||
weighted variant of the PSNR measure, can be found in the following freely available papers:
|
||||
|
||||
@itemize
|
||||
@item
|
||||
C. R. Helmrich, M. Siekmann, S. Becker, S. Bosse, D. Marpe, and T. Wiegand, "XPSNR: A
|
||||
Low-Complexity Extension of the Perceptually Weighted Peak Signal-to-Noise Ratio for
|
||||
High-Resolution Video Quality Assessment," in Proc. IEEE Int. Conf. Acoustics, Speech,
|
||||
Sig. Process. (ICASSP), virt./online, May 2020. @url{www.ecodis.de/xpsnr.htm}
|
||||
|
||||
@item
|
||||
C. R. Helmrich, S. Bosse, H. Schwarz, D. Marpe, and T. Wiegand, "A Study of the
|
||||
Extended Perceptually Weighted Peak Signal-to-Noise Ratio (XPSNR) for Video Compression
|
||||
with Different Resolutions and Bit Depths," ITU Journal: ICT Discoveries, vol. 3, no.
|
||||
1, pp. 65 - 72, May 2020. @url{http://handle.itu.int/11.1002/pub/8153d78b-en}
|
||||
@end itemize
|
||||
|
||||
When publishing the results of XPSNR assessments obtained using, e.g., this FFmpeg filter, a
|
||||
reference to the above papers as a means of documentation is strongly encouraged. The filter
|
||||
requires two input videos. The first input is considered a (usually not distorted) reference
|
||||
source and is passed unchanged to the output, whereas the second input is a (distorted) test
|
||||
signal. Except for the bit depth, these two video inputs must have the same pixel format. In
|
||||
addition, for best performance, both compared input videos should be in YCbCr color format.
|
||||
|
||||
The obtained overall XPSNR values mentioned above are printed through the logging system. In
|
||||
case of input with multiple color planes, we suggest reporting of the minimum XPSNR average.
|
||||
|
||||
The following parameter, which behaves like the one for the @ref{psnr} filter, is accepted:
|
||||
|
||||
@table @option
|
||||
@item stats_file, f
|
||||
If specified, the filter will use the named file to save the XPSNR value of each individual
|
||||
frame and color plane. When the file name equals "-", that data is sent to standard output.
|
||||
@end table
|
||||
|
||||
This filter also supports the @ref{framesync} options.
|
||||
|
||||
@subsection Examples
|
||||
@itemize
|
||||
@item
|
||||
XPSNR analysis of two 1080p HD videos, ref_source.yuv and test_video.yuv, both at 24 frames
|
||||
per second, with color format 4:2:0, bit depth 8, and output of a logfile named "xpsnr.log":
|
||||
@example
|
||||
ffmpeg -s 1920x1080 -framerate 24 -pix_fmt yuv420p -i ref_source.yuv -s 1920x1080 -framerate
|
||||
24 -pix_fmt yuv420p -i test_video.yuv -lavfi xpsnr="stats_file=xpsnr.log" -f null -
|
||||
@end example
|
||||
|
||||
@item
|
||||
XPSNR analysis of two 2160p UHD videos, ref_source.yuv with bit depth 8 and test_video.yuv
|
||||
with bit depth 10, both at 60 frames per second with color format 4:2:0, no logfile output:
|
||||
@example
|
||||
ffmpeg -s 3840x2160 -framerate 60 -pix_fmt yuv420p -i ref_source.yuv -s 3840x2160 -framerate
|
||||
60 -pix_fmt yuv420p10le -i test_video.yuv -lavfi xpsnr="stats_file=-" -f null -
|
||||
@end example
|
||||
@end itemize
|
||||
|
||||
@anchor{xstack}
|
||||
@section xstack
|
||||
Stack video inputs into custom layout.
|
||||
@@ -27905,7 +27832,8 @@ The inputs have same memory layout for color channels, the overlay has additiona
|
||||
|
||||
@section tonemap_vaapi
|
||||
|
||||
Perform HDR-to-SDR or HDR-to-HDR tone-mapping.
|
||||
Perform HDR(High Dynamic Range) to SDR(Standard Dynamic Range) conversion with tone-mapping.
|
||||
It maps the dynamic range of HDR10 content to the SDR content.
|
||||
It currently only accepts HDR10 as input.
|
||||
|
||||
It accepts the following parameters:
|
||||
@@ -27914,42 +27842,28 @@ It accepts the following parameters:
|
||||
@item format
|
||||
Specify the output pixel format.
|
||||
|
||||
Default is nv12 for HDR-to-SDR tone-mapping and p010 for HDR-to-HDR
|
||||
tone-mapping.
|
||||
Currently supported formats are:
|
||||
@table @var
|
||||
@item p010
|
||||
@item nv12
|
||||
@end table
|
||||
|
||||
Default is nv12.
|
||||
|
||||
@item primaries, p
|
||||
Set the output color primaries.
|
||||
|
||||
Default is bt709 for HDR-to-SDR tone-mapping and same as input for HDR-to-HDR
|
||||
tone-mapping.
|
||||
Default is same as input.
|
||||
|
||||
@item transfer, t
|
||||
Set the output transfer characteristics.
|
||||
|
||||
Default is bt709 for HDR-to-SDR tone-mapping and same as input for HDR-to-HDR
|
||||
tone-mapping.
|
||||
Default is bt709.
|
||||
|
||||
@item matrix, m
|
||||
Set the output colorspace matrix.
|
||||
|
||||
Default is bt709 for HDR-to-SDR tone-mapping and same as input for HDR-to-HDR
|
||||
tone-mapping.
|
||||
|
||||
@item display
|
||||
Set the output mastering display colour volume. It is given by a '|'-separated
|
||||
list of two values, two values are space separated. It set display primaries
|
||||
x & y in G, B, R order, then white point x & y, the nominal minimum & maximum
|
||||
display luminances.
|
||||
|
||||
HDR-to-HDR tone-mapping will be performed when this option is set.
|
||||
|
||||
@item light
|
||||
Set the output content light level information. It accepts 2 space-separated
|
||||
values, the first input is the maximum light level and the second input is
|
||||
the maximum average light level.
|
||||
|
||||
It is ignored for HDR-to-SDR tone-mapping, and optional for HDR-to-HDR
|
||||
tone-mapping.
|
||||
Default is same as input.
|
||||
|
||||
@end table
|
||||
|
||||
@@ -27961,11 +27875,6 @@ Convert HDR(HDR10) video to bt2020-transfer-characteristic p010 format
|
||||
@example
|
||||
tonemap_vaapi=format=p010:t=bt2020-10
|
||||
@end example
|
||||
@item
|
||||
Convert HDR video to HDR video
|
||||
@example
|
||||
tonemap_vaapi=display=7500\ 3000|34000\ 16000|13250\ 34500|15635\ 16450|500\ 10000000
|
||||
@end example
|
||||
@end itemize
|
||||
|
||||
@section hstack_vaapi
|
||||
@@ -28046,168 +27955,6 @@ first input stream. For the syntax of this option, check the
|
||||
See @ref{xstack}.
|
||||
@end table
|
||||
|
||||
@section pad_vaapi
|
||||
|
||||
Add paddings to the input image, and place the original input at the
|
||||
provided @var{x}, @var{y} coordinates.
|
||||
|
||||
It accepts the following options:
|
||||
|
||||
@table @option
|
||||
@item width, w
|
||||
@item height, h
|
||||
Specify an expression for the size of the output image with the
|
||||
paddings added. If the value for @var{width} or @var{height} is 0, the
|
||||
corresponding input size is used for the output.
|
||||
|
||||
The @var{width} expression can reference the value set by the
|
||||
@var{height} expression, and vice versa.
|
||||
|
||||
The default value of @var{width} and @var{height} is 0.
|
||||
|
||||
@item x
|
||||
@item y
|
||||
Specify the offsets to place the input image at within the padded area,
|
||||
with respect to the top/left border of the output image.
|
||||
|
||||
The @var{x} expression can reference the value set by the @var{y}
|
||||
expression, and vice versa.
|
||||
|
||||
The default value of @var{x} and @var{y} is 0.
|
||||
|
||||
If @var{x} or @var{y} evaluate to a negative number, they'll be changed
|
||||
so the input image is centered on the padded area.
|
||||
|
||||
@item color
|
||||
Specify the color of the padded area. For the syntax of this option,
|
||||
check the @ref{color syntax,,"Color" section in the ffmpeg-utils
|
||||
manual,ffmpeg-utils}.
|
||||
|
||||
@item aspect
|
||||
Pad to an aspect instead to a resolution.
|
||||
@end table
|
||||
|
||||
The value for the @var{width}, @var{height}, @var{x}, and @var{y}
|
||||
options are expressions containing the following constants:
|
||||
|
||||
@table @option
|
||||
@item in_w
|
||||
@item in_h
|
||||
The input video width and height.
|
||||
|
||||
@item iw
|
||||
@item ih
|
||||
These are the same as @var{in_w} and @var{in_h}.
|
||||
|
||||
@item out_w
|
||||
@item out_h
|
||||
The output width and height (the size of the padded area), as
|
||||
specified by the @var{width} and @var{height} expressions.
|
||||
|
||||
@item ow
|
||||
@item oh
|
||||
These are the same as @var{out_w} and @var{out_h}.
|
||||
|
||||
@item x
|
||||
@item y
|
||||
The x and y offsets as specified by the @var{x} and @var{y}
|
||||
expressions, or NAN if not yet specified.
|
||||
|
||||
@item a
|
||||
same as @var{iw} / @var{ih}
|
||||
|
||||
@item sar
|
||||
input sample aspect ratio
|
||||
|
||||
@item dar
|
||||
input display aspect ratio, it is the same as (@var{iw} / @var{ih}) * @var{sar}
|
||||
@end table
|
||||
|
||||
@section drawbox_vaapi
|
||||
|
||||
Draw a colored box on the input image.
|
||||
|
||||
It accepts the following parameters:
|
||||
|
||||
@table @option
|
||||
@item x
|
||||
@item y
|
||||
The expressions which specify the top left corner coordinates of the box. It defaults to 0.
|
||||
|
||||
@item width, w
|
||||
@item height, h
|
||||
The expressions which specify the width and height of the box; if 0 they are interpreted as
|
||||
the input width and height. It defaults to 0.
|
||||
|
||||
@item color, c
|
||||
Specify the color of the box to write. For the general syntax of this option,
|
||||
check the @ref{color syntax,,"Color" section in the ffmpeg-utils manual,ffmpeg-utils}.
|
||||
|
||||
@item thickness, t
|
||||
The expression which sets the thickness of the box edge.
|
||||
A value of @code{fill} will create a filled box. Default value is @code{3}.
|
||||
|
||||
See below for the list of accepted constants.
|
||||
|
||||
@item replace
|
||||
With value @code{1}, the pixels of the painted box will overwrite the video's color and alpha pixels.
|
||||
Default is @code{0}, which composites the box onto the input video.
|
||||
@end table
|
||||
|
||||
The parameters for @var{x}, @var{y}, @var{w} and @var{h} and @var{t} are expressions containing the
|
||||
following constants:
|
||||
|
||||
@table @option
|
||||
@item in_h, ih
|
||||
@item in_w, iw
|
||||
The input width and height.
|
||||
|
||||
@item x
|
||||
@item y
|
||||
The x and y offset coordinates where the box is drawn.
|
||||
|
||||
@item w
|
||||
@item h
|
||||
The width and height of the drawn box.
|
||||
|
||||
@item t
|
||||
The thickness of the drawn box.
|
||||
|
||||
@end table
|
||||
|
||||
@subsection Examples
|
||||
|
||||
@itemize
|
||||
@item
|
||||
Draw a black box around the edge of the input image:
|
||||
@example
|
||||
drawbox
|
||||
@end example
|
||||
|
||||
@item
|
||||
Draw a box with color red and an opacity of 50%:
|
||||
@example
|
||||
drawbox=10:20:200:60:red@@0.5
|
||||
@end example
|
||||
|
||||
The previous example can be specified as:
|
||||
@example
|
||||
drawbox=x=10:y=20:w=200:h=60:color=red@@0.5
|
||||
@end example
|
||||
|
||||
@item
|
||||
Fill the box with pink color:
|
||||
@example
|
||||
drawbox=x=10:y=10:w=100:h=100:color=pink@@0.5:t=fill
|
||||
@end example
|
||||
|
||||
@item
|
||||
Draw a 2-pixel red 2.40:1 mask:
|
||||
@example
|
||||
drawbox=x=-t:y=0.5*(ih-iw/2.4)-t:w=iw+t*2:h=iw/2.4+t*2:t=2:c=red
|
||||
@end example
|
||||
@end itemize
|
||||
|
||||
@c man end VAAPI VIDEO FILTERS
|
||||
|
||||
@chapter Vulkan Video Filters
|
||||
@@ -29384,107 +29131,6 @@ ffplay -f lavfi life=s=300x200:mold=10:r=60:ratio=0.1:death_color=#C83232:life_c
|
||||
@end example
|
||||
@end itemize
|
||||
|
||||
@section perlin
|
||||
Generate Perlin noise.
|
||||
|
||||
Perlin noise is a kind of noise with local continuity in space. This
|
||||
can be used to generate patterns with continuity in space and time,
|
||||
e.g. to simulate smoke, fluids, or terrain.
|
||||
|
||||
In case more than one octave is specified through the @option{octaves}
|
||||
option, Perlin noise is generated as a sum of components, each one
|
||||
with doubled frequency. In this case the @option{persistence} option
|
||||
specify the ratio of the amplitude with respect to the previous
|
||||
component. More octave components enable to specify more high
|
||||
frequency details in the generated noise (e.g. small size variations
|
||||
due to boulders in a generated terrain).
|
||||
|
||||
@subsection Options
|
||||
@table @option
|
||||
|
||||
@item size, s
|
||||
Specify the size (width and height) of the buffered video frames. For the
|
||||
syntax of this option, check the
|
||||
@ref{video size syntax,,"Video size" section in the ffmpeg-utils manual,ffmpeg-utils}.
|
||||
Default value is @code{320x240}.
|
||||
|
||||
@item rate, r
|
||||
Specify the frame rate expected for the video stream, expressed as a
|
||||
number of frames per second. Default value is @code{25}.
|
||||
|
||||
@item octaves
|
||||
Specify the total number of components making up the noise, each one
|
||||
with doubled frequency. Default value is @code{1}.
|
||||
|
||||
@item persistence
|
||||
Set the ratio used to compute the amplitude of the next octave
|
||||
component with respect to the previous component amplitude. Default
|
||||
value is @code{1}.
|
||||
|
||||
@item xscale
|
||||
@item yscale
|
||||
Define a scale factor used to multiple the x, y coordinates. This can
|
||||
be useful to define an effect with a pattern stretched along the x or
|
||||
y axis. Default value is @code{1}.
|
||||
|
||||
@item tscale
|
||||
Define a scale factor used to multiple the time coordinate. This can
|
||||
be useful to change the time variation speed. Default value is @code{1}.
|
||||
|
||||
@item random_mode
|
||||
Set random mode used to compute initial pattern.
|
||||
|
||||
Supported values are:
|
||||
@table @option
|
||||
@item random
|
||||
Compute and use random seed.
|
||||
|
||||
@item ken
|
||||
Use the predefined initial pattern defined by Ken Perlin in the
|
||||
original article, can be useful to compare the output with other
|
||||
sources.
|
||||
|
||||
@item seed
|
||||
Use the value specified by @option{random_seed} option.
|
||||
@end table
|
||||
|
||||
Default value is @code{random}.
|
||||
|
||||
@item random_seed, seed
|
||||
When @option{random_mode} is set to @var{random_seed}, use this value
|
||||
to compute the initial pattern. Default value is @code{0}.
|
||||
@end table
|
||||
|
||||
@subsection Examples
|
||||
@itemize
|
||||
@item
|
||||
Generate single component:
|
||||
@example
|
||||
perlin
|
||||
@end example
|
||||
|
||||
@item
|
||||
Use Perlin noise with 7 components, each one with a halved contribution
|
||||
to total amplitude:
|
||||
@example
|
||||
perlin=octaves=7:persistence=0.5
|
||||
@end example
|
||||
|
||||
@item
|
||||
Chain Perlin noise with the @ref{lutyuv} to generate a black&white
|
||||
effect:
|
||||
@example
|
||||
perlin=octaves=3:tscale=0.3,lutyuv=y='if(lt(val\,128)\,255\,0)'
|
||||
@end example
|
||||
|
||||
@item
|
||||
Stretch noise along the y axis, and convert gray level to red-only
|
||||
signal:
|
||||
@example
|
||||
perlin=octaves=7:tscale=0.4:yscale=0.3,lutrgb=r=val:b=0:g=0
|
||||
@end example
|
||||
@end itemize
|
||||
|
||||
@section qrencodesrc
|
||||
|
||||
Generate a QR code using the libqrencode library (see
|
||||
@@ -31105,15 +30751,6 @@ missing.
|
||||
That basically means that an input frame is selected if its pts is within the
|
||||
interval set by the concat demuxer.
|
||||
|
||||
@item iw @emph{(video only)}
|
||||
Represents the width of the input video frame.
|
||||
|
||||
@item ih @emph{(video only)}
|
||||
Represents the height of the input video frame.
|
||||
|
||||
@item view @emph{(video only)}
|
||||
View ID for multi-view video.
|
||||
|
||||
@end table
|
||||
|
||||
The default value of the select expression is "1".
|
||||
|
||||
+1
-18
@@ -225,26 +225,9 @@ Specifies the maximum number of streams. This can be used to reject files that
|
||||
would require too many resources due to a large number of streams.
|
||||
|
||||
@item skip_estimate_duration_from_pts @var{bool} (@emph{input})
|
||||
Skip estimation of input duration if it requires an additional probing for PTS at end of file.
|
||||
Skip estimation of input duration when calculated using PTS.
|
||||
At present, applicable for MPEG-PS and MPEG-TS.
|
||||
|
||||
@item duration_probesize @var{integer} (@emph{input})
|
||||
Set probing size, in bytes, for input duration estimation when it actually requires
|
||||
an additional probing for PTS at end of file (at present: MPEG-PS and MPEG-TS).
|
||||
It is aimed at users interested in better durations probing for itself, or indirectly
|
||||
because using the concat demuxer, for example.
|
||||
The typical use case is an MPEG-TS CBR with a high bitrate, high video buffering and
|
||||
ending cleaning with similar PTS for video and audio: in such a scenario, the large
|
||||
physical gap between the last video packet and the last audio packet makes it necessary
|
||||
to read many bytes in order to get the video stream duration.
|
||||
Another use case is where the default probing behaviour only reaches a single video frame which is
|
||||
not the last one of the stream due to frame reordering, so the duration is not accurate.
|
||||
Setting this option has a performance impact even for small files because the probing
|
||||
size is fixed.
|
||||
Default behaviour is a general purpose trade-off, largely adaptive, but the probing size
|
||||
will not be extended to get streams durations at all costs.
|
||||
Must be an integer not lesser than 1, or 0 for default behaviour.
|
||||
|
||||
@item strict, f_strict @var{integer} (@emph{input/output})
|
||||
Specify how strictly to follow the standards. @code{f_strict} is deprecated and
|
||||
should be used only via the @command{ffmpeg} tool.
|
||||
|
||||
@@ -160,19 +160,6 @@ Go to @url{http://lame.sourceforge.net/} and follow the
|
||||
instructions for installing the library.
|
||||
Then pass @code{--enable-libmp3lame} to configure to enable it.
|
||||
|
||||
@section LCEVCdec
|
||||
|
||||
FFmpeg can make use of the liblcevc_dec library for LCEVC enhacement layer
|
||||
decoding on supported bitstreams.
|
||||
|
||||
Go to @url{https://github.com/v-novaltd/LCEVCdec} and follow the instructions
|
||||
for installing the library. Then pass @code{--enable-liblcevc-dec} to configure to
|
||||
enable it.
|
||||
|
||||
@float NOTE
|
||||
LCEVCdec is under the BSD-3-Clause-Clear License.
|
||||
@end float
|
||||
|
||||
@section libilbc
|
||||
|
||||
iLBC is a narrowband speech codec that has been made freely available
|
||||
@@ -250,14 +237,6 @@ Go to @url{http://sourceforge.net/projects/opencore-amr/} and follow the
|
||||
instructions for installing the library.
|
||||
Then pass @code{--enable-libfdk-aac} to configure to enable it.
|
||||
|
||||
@subsection LC3 library
|
||||
|
||||
FFmpeg can make use of the Google LC3 library for LC3 decoding & encoding.
|
||||
|
||||
Go to @url{https://github.com/google/liblc3/} and follow the instructions for
|
||||
installing the library.
|
||||
Then pass @code{--enable-liblc3} to configure to enable it.
|
||||
|
||||
@section OpenH264
|
||||
|
||||
FFmpeg can make use of the OpenH264 library for H.264 decoding and encoding.
|
||||
@@ -1036,8 +1015,6 @@ following image formats are supported:
|
||||
@item Kega Game Video (KGV1) @tab @tab X
|
||||
@tab Kega emulator screen capture codec.
|
||||
@item Lagarith @tab @tab X
|
||||
@item LCEVC / MPEG-5 LCEVC / MPEG-5 Part 2 @tab @tab E
|
||||
@tab decoding supported through external library liblcevc-dec
|
||||
@item LCL (LossLess Codec Library) MSZH @tab @tab X
|
||||
@item LCL (LossLess Codec Library) ZLIB @tab E @tab E
|
||||
@item LEAD MCMP @tab @tab X
|
||||
@@ -1323,8 +1300,7 @@ following image formats are supported:
|
||||
@tab encoding and decoding supported through external library libilbc
|
||||
@item IMC (Intel Music Coder) @tab @tab X
|
||||
@item Interplay ACM @tab @tab X
|
||||
@item LC3 @tab E @tab E
|
||||
@tab supported through external library liblc3
|
||||
@item MACE (Macintosh Audio Compression/Expansion) 3:1 @tab @tab X
|
||||
@item MACE (Macintosh Audio Compression/Expansion) 6:1 @tab @tab X
|
||||
@item Marian's A-pac audio @tab @tab X
|
||||
@item MI-SC4 (Micronas SC-4 Audio) @tab @tab X
|
||||
|
||||
+2
-18
@@ -396,22 +396,6 @@ Defaults to @samp{audio}.
|
||||
@item draw_bars
|
||||
If set to @samp{true}, color bars are drawn in the event of a signal loss.
|
||||
Defaults to @samp{true}.
|
||||
This option is deprecated, please use the @code{signal_loss_action} option.
|
||||
|
||||
@item signal_loss_action
|
||||
Sets the action to take in the event of a signal loss. Accepts one of the
|
||||
following values:
|
||||
|
||||
@table @option
|
||||
@item 1, none
|
||||
Do nothing on signal loss. This usually results in black frames.
|
||||
@item 2, bars
|
||||
Draw color bars on signal loss. Only supported for 8-bit input signals.
|
||||
@item 3, repeat
|
||||
Repeat the last video frame on signal loss.
|
||||
@end table
|
||||
|
||||
Defaults to @samp{bars}.
|
||||
|
||||
@item queue_size
|
||||
Sets maximum input buffer size in bytes. If the buffering reaches this value,
|
||||
@@ -1085,9 +1069,9 @@ ffplay -f lavfi "movie=test.avi[out0];amovie=test.wav[out1]"
|
||||
@end example
|
||||
|
||||
@item
|
||||
Dump decoded frames to images and Closed Captions to an RCWT backup:
|
||||
Dump decoded frames to images and closed captions to a file (experimental):
|
||||
@example
|
||||
ffmpeg -f lavfi -i "movie=test.ts[out0+subcc]" -map v frame%08d.png -map s -c copy -f rcwt subcc.bin
|
||||
ffmpeg -f lavfi -i "movie=test.ts[out0+subcc]" -map v frame%08d.png -map s -c copy -f rawvideo subcc.bin
|
||||
@end example
|
||||
|
||||
@end itemize
|
||||
|
||||
@@ -157,6 +157,9 @@ Perform a site search using your favorite search engine. Example:
|
||||
|
||||
You can ask for help in the official @t{#ffmpeg} IRC channel on Libera Chat.
|
||||
|
||||
Some users prefer the third-party @url{http://www.ffmpeg-archive.org/, Nabble}
|
||||
interface which presents the mailing lists in a typical forum layout.
|
||||
|
||||
There are also numerous third-party help sites such as
|
||||
@url{https://superuser.com/tags/ffmpeg, Super User} and
|
||||
@url{https://www.reddit.com/r/ffmpeg/, r/ffmpeg on reddit}.
|
||||
|
||||
@@ -49,6 +49,11 @@ Files that have MIPS copyright notice in them:
|
||||
libm_mips.h
|
||||
softfloat_tables.h
|
||||
* libavcodec/mips/
|
||||
aacdec_fixed.c
|
||||
aacsbr_fixed.c
|
||||
aacsbr_template.c
|
||||
aaccoder_mips.c
|
||||
aacpsy_mips.h
|
||||
ac3dsp_mips.c
|
||||
acelp_filters_mips.c
|
||||
acelp_vectors_mips.c
|
||||
@@ -59,6 +64,7 @@ Files that have MIPS copyright notice in them:
|
||||
compute_antialias_fixed.h
|
||||
compute_antialias_float.h
|
||||
lsp_mips.h
|
||||
dsputil_mips.c
|
||||
fmtconvert_mips.c
|
||||
iirfilter_mips.c
|
||||
mpegaudiodsp_mips_fixed.c
|
||||
|
||||
@@ -36,9 +36,9 @@ Frame threading -
|
||||
* Codecs similar to ffv1, whose streams don't reset across frames,
|
||||
will not work because their bitstreams cannot be decoded in parallel.
|
||||
|
||||
* The contents of buffers must not be read before ff_progress_frame_await()
|
||||
* The contents of buffers must not be read before ff_thread_await_progress()
|
||||
has been called on them. reget_buffer() and buffer age optimizations no longer work.
|
||||
* The contents of buffers must not be written to after ff_progress_frame_report()
|
||||
* The contents of buffers must not be written to after ff_thread_report_progress()
|
||||
has been called on them. This includes draw_edges().
|
||||
|
||||
Porting codecs to frame threading
|
||||
@@ -53,13 +53,14 @@ thread.
|
||||
Add AV_CODEC_CAP_FRAME_THREADS to the codec capabilities. There will be very little
|
||||
speed gain at this point but it should work.
|
||||
|
||||
Use ff_thread_get_buffer() (or ff_progress_frame_get_buffer()
|
||||
in case you have inter-frame dependencies and use the ProgressFrame API)
|
||||
to allocate frame buffers.
|
||||
If there are inter-frame dependencies, so the codec calls
|
||||
ff_thread_report/await_progress(), set FF_CODEC_CAP_ALLOCATE_PROGRESS in
|
||||
FFCodec.caps_internal and use ff_thread_get_buffer() to allocate frames.
|
||||
Otherwise decode directly into the user-supplied frames.
|
||||
|
||||
Call ff_progress_frame_report() after some part of the current picture has decoded.
|
||||
Call ff_thread_report_progress() after some part of the current picture has decoded.
|
||||
A good place to put this is where draw_horiz_band() is called - add this if it isn't
|
||||
called anywhere, as it's useful too and the implementation is trivial when you're
|
||||
doing this. Note that draw_edges() needs to be called before reporting progress.
|
||||
|
||||
Before accessing a reference frame or its MVs, call ff_progress_frame_await().
|
||||
Before accessing a reference frame or its MVs, call ff_thread_await_progress().
|
||||
|
||||
+233
-437
File diff suppressed because it is too large
Load Diff
+55
-88
@@ -442,6 +442,9 @@ value is -1.
|
||||
@item chunked_post
|
||||
If set to 1 use chunked Transfer-Encoding for posts, default is 1.
|
||||
|
||||
@item content_type
|
||||
Set a specific content type for the POST messages or for listen mode.
|
||||
|
||||
@item http_proxy
|
||||
set HTTP proxy to tunnel through e.g. http://example.com:1234
|
||||
|
||||
@@ -449,33 +452,42 @@ set HTTP proxy to tunnel through e.g. http://example.com:1234
|
||||
Set custom HTTP headers, can override built in default headers. The
|
||||
value must be a string encoding the headers.
|
||||
|
||||
@item content_type
|
||||
Set a specific content type for the POST messages or for listen mode.
|
||||
|
||||
@item user_agent
|
||||
Override the User-Agent header. If not specified the protocol will use a
|
||||
string describing the libavformat build. ("Lavf/<version>")
|
||||
|
||||
@item referer
|
||||
Set the Referer header. Include 'Referer: URL' header in HTTP request.
|
||||
|
||||
@item multiple_requests
|
||||
Use persistent connections if set to 1, default is 0.
|
||||
|
||||
@item post_data
|
||||
Set custom HTTP post data.
|
||||
|
||||
@item referer
|
||||
Set the Referer header. Include 'Referer: URL' header in HTTP request.
|
||||
|
||||
@item user_agent
|
||||
Override the User-Agent header. If not specified the protocol will use a
|
||||
string describing the libavformat build. ("Lavf/<version>")
|
||||
|
||||
@item reconnect_at_eof
|
||||
If set then eof is treated like an error and causes reconnection, this is useful
|
||||
for live / endless streams.
|
||||
|
||||
@item reconnect_streamed
|
||||
If set then even streamed/non seekable streams will be reconnected on errors.
|
||||
|
||||
@item reconnect_on_network_error
|
||||
Reconnect automatically in case of TCP/TLS errors during connect.
|
||||
|
||||
@item reconnect_on_http_error
|
||||
A comma separated list of HTTP status codes to reconnect on. The list can
|
||||
include specific status codes (e.g. '503') or the strings '4xx' / '5xx'.
|
||||
|
||||
@item reconnect_delay_max
|
||||
Sets the maximum delay in seconds after which to give up reconnecting
|
||||
|
||||
@item mime_type
|
||||
Export the MIME type.
|
||||
|
||||
@item http_version
|
||||
Exports the HTTP response version number. Usually "1.0" or "1.1".
|
||||
|
||||
@item cookies
|
||||
Set the cookies to be sent in future requests. The format of each cookie is the
|
||||
same as the value of a Set-Cookie HTTP response field. Multiple cookies can be
|
||||
delimited by a newline character.
|
||||
|
||||
@item icy
|
||||
If set to 1 request ICY (SHOUTcast) metadata from the server. If the server
|
||||
supports this, the metadata has to be retrieved by the application by reading
|
||||
@@ -492,40 +504,10 @@ contains the last non-empty metadata packet sent by the server. It should be
|
||||
polled in regular intervals by applications interested in mid-stream metadata
|
||||
updates.
|
||||
|
||||
@item metadata
|
||||
Set an exported dictionary containing Icecast metadata from the bitstream, if present.
|
||||
Only useful with the C API.
|
||||
|
||||
@item auth_type
|
||||
|
||||
Set HTTP authentication type. No option for Digest, since this method requires
|
||||
getting nonce parameters from the server first and can't be used straight away like
|
||||
Basic.
|
||||
|
||||
@table @option
|
||||
@item none
|
||||
Choose the HTTP authentication type automatically. This is the default.
|
||||
@item basic
|
||||
|
||||
Choose the HTTP basic authentication.
|
||||
|
||||
Basic authentication sends a Base64-encoded string that contains a user name and password
|
||||
for the client. Base64 is not a form of encryption and should be considered the same as
|
||||
sending the user name and password in clear text (Base64 is a reversible encoding).
|
||||
If a resource needs to be protected, strongly consider using an authentication scheme
|
||||
other than basic authentication. HTTPS/TLS should be used with basic authentication.
|
||||
Without these additional security enhancements, basic authentication should not be used
|
||||
to protect sensitive or valuable information.
|
||||
@end table
|
||||
|
||||
@item send_expect_100
|
||||
Send an Expect: 100-continue header for POST. If set to 1 it will send, if set
|
||||
to 0 it won't, if set to -1 it will try to send if it is applicable. Default
|
||||
value is -1.
|
||||
|
||||
@item location
|
||||
An exported dictionary containing the content location. Only useful with the C
|
||||
API.
|
||||
@item cookies
|
||||
Set the cookies to be sent in future requests. The format of each cookie is the
|
||||
same as the value of a Set-Cookie HTTP response field. Multiple cookies can be
|
||||
delimited by a newline character.
|
||||
|
||||
@item offset
|
||||
Set initial byte offset.
|
||||
@@ -543,37 +525,6 @@ be given a Bad Request response.
|
||||
When unset the HTTP method is not checked for now. This will be replaced by
|
||||
autodetection in the future.
|
||||
|
||||
@item reconnect
|
||||
Reconnect automatically when disconnected before EOF is hit.
|
||||
|
||||
@item reconnect_at_eof
|
||||
If set then eof is treated like an error and causes reconnection, this is useful
|
||||
for live / endless streams.
|
||||
|
||||
@item reconnect_on_network_error
|
||||
Reconnect automatically in case of TCP/TLS errors during connect.
|
||||
|
||||
@item reconnect_on_http_error
|
||||
A comma separated list of HTTP status codes to reconnect on. The list can
|
||||
include specific status codes (e.g. '503') or the strings '4xx' / '5xx'.
|
||||
|
||||
@item reconnect_streamed
|
||||
If set then even streamed/non seekable streams will be reconnected on errors.
|
||||
|
||||
@item reconnect_delay_max
|
||||
Set the maximum delay in seconds after which to give up reconnecting.
|
||||
|
||||
@item reconnect_max_retries
|
||||
Set the maximum number of times to retry a connection. Default unset.
|
||||
|
||||
@item reconnect_delay_total_max
|
||||
Set the maximum total delay in seconds after which to give up reconnecting.
|
||||
|
||||
@item respect_retry_after
|
||||
If enabled, and a Retry-After header is encountered, its requested reconnection
|
||||
delay will be honored, rather than using exponential backoff. Useful for 429 and
|
||||
503 errors. Default enabled.
|
||||
|
||||
@item listen
|
||||
If set to 1 enables experimental HTTP server. This can be used to send data when
|
||||
used as an output option, or read data from a client with HTTP POST when used as
|
||||
@@ -600,16 +551,32 @@ ffmpeg -i somefile.ogg -chunked_post 0 -c copy -f ogg http://@var{server}:@var{p
|
||||
wget --post-file=somefile.ogg http://@var{server}:@var{port}
|
||||
@end example
|
||||
|
||||
@item resource
|
||||
The resource requested by a client, when the experimental HTTP server is in use.
|
||||
@item send_expect_100
|
||||
Send an Expect: 100-continue header for POST. If set to 1 it will send, if set
|
||||
to 0 it won't, if set to -1 it will try to send if it is applicable. Default
|
||||
value is -1.
|
||||
|
||||
@item reply_code
|
||||
The HTTP code returned to the client, when the experimental HTTP server is in use.
|
||||
@item auth_type
|
||||
|
||||
@item short_seek_size
|
||||
Set the threshold, in bytes, for when a readahead should be prefered over a seek and
|
||||
new HTTP request. This is useful, for example, to make sure the same connection
|
||||
is used for reading large video packets with small audio packets in between.
|
||||
Set HTTP authentication type. No option for Digest, since this method requires
|
||||
getting nonce parameters from the server first and can't be used straight away like
|
||||
Basic.
|
||||
|
||||
@table @option
|
||||
@item none
|
||||
Choose the HTTP authentication type automatically. This is the default.
|
||||
@item basic
|
||||
|
||||
Choose the HTTP basic authentication.
|
||||
|
||||
Basic authentication sends a Base64-encoded string that contains a user name and password
|
||||
for the client. Base64 is not a form of encryption and should be considered the same as
|
||||
sending the user name and password in clear text (Base64 is a reversible encoding).
|
||||
If a resource needs to be protected, strongly consider using an authentication scheme
|
||||
other than basic authentication. HTTPS/TLS should be used with basic authentication.
|
||||
Without these additional security enhancements, basic authentication should not be used
|
||||
to protect sensitive or valuable information.
|
||||
@end table
|
||||
|
||||
@end table
|
||||
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env perl
|
||||
#! /usr/bin/env perl
|
||||
|
||||
# This script will print the dependency of a Texinfo file to stdout.
|
||||
# texidep.pl <src-path> <input.texi> <output.ext>
|
||||
|
||||
+27
-45
@@ -801,11 +801,6 @@ The following binary operators are available: @code{+}, @code{-},
|
||||
|
||||
The following unary operators are available: @code{+}, @code{-}.
|
||||
|
||||
Some internal variables can be used to store and load intermediary
|
||||
results. They can be accessed using the @code{ld} and @code{st}
|
||||
functions with an index argument varying from 0 to 9 to specify which
|
||||
internal variable to access.
|
||||
|
||||
The following functions are available:
|
||||
@table @option
|
||||
@item abs(x)
|
||||
@@ -903,9 +898,9 @@ Return 1.0 if @var{x} is +/-INFINITY, 0.0 otherwise.
|
||||
@item isnan(x)
|
||||
Return 1.0 if @var{x} is NAN, 0.0 otherwise.
|
||||
|
||||
@item ld(idx)
|
||||
Load the value of the internal variable with index @var{idx}, which was
|
||||
previously stored with st(@var{idx}, @var{expr}).
|
||||
@item ld(var)
|
||||
Load the value of the internal variable with number
|
||||
@var{var}, which was previously stored with st(@var{var}, @var{expr}).
|
||||
The function returns the loaded value.
|
||||
|
||||
@item lerp(x, y, z)
|
||||
@@ -938,31 +933,21 @@ Compute the power of @var{x} elevated @var{y}, it is equivalent to
|
||||
|
||||
@item print(t)
|
||||
@item print(t, l)
|
||||
Print the value of expression @var{t} with loglevel @var{l}. If @var{l} is not
|
||||
specified then a default log level is used.
|
||||
Return the value of the expression printed.
|
||||
Print the value of expression @var{t} with loglevel @var{l}. If
|
||||
@var{l} is not specified then a default log level is used.
|
||||
Returns the value of the expression printed.
|
||||
|
||||
Prints t with loglevel l
|
||||
|
||||
@item random(idx)
|
||||
Return a pseudo random value between 0.0 and 1.0. @var{idx} is the
|
||||
index of the internal variable used to save the seed/state, which can be
|
||||
previously stored with @code{st(idx)}.
|
||||
|
||||
To initialize the seed, you need to store the seed value as a 64-bit
|
||||
unsigned integer in the internal variable with index @var{idx}.
|
||||
|
||||
For example, to store the seed with value @code{42} in the internal
|
||||
variable with index @code{0} and print a few random values:
|
||||
@example
|
||||
st(0,42); print(random(0)); print(random(0)); print(random(0))
|
||||
@end example
|
||||
index of the internal variable which will be used to save the
|
||||
seed/state.
|
||||
|
||||
@item randomi(idx, min, max)
|
||||
Return a pseudo random value in the interval between @var{min} and
|
||||
@var{max}. @var{idx} is the index of the internal variable which will be used to
|
||||
save the seed/state, which can be previously stored with @code{st(idx)}.
|
||||
|
||||
To initialize the seed, you need to store the seed value as a 64-bit
|
||||
unsigned integer in the internal variable with index @var{idx}.
|
||||
@var{max}. @var{idx} is the index of the internal variable which will
|
||||
be used to save the seed/state.
|
||||
|
||||
@item root(expr, max)
|
||||
Find an input value for which the function represented by @var{expr}
|
||||
@@ -971,14 +956,14 @@ with argument @var{ld(0)} is 0 in the interval 0..@var{max}.
|
||||
The expression in @var{expr} must denote a continuous function or the
|
||||
result is undefined.
|
||||
|
||||
@var{ld(0)} is used to represent the function input value, which means that the
|
||||
given expression will be evaluated multiple times with various input values that
|
||||
the expression can access through @code{ld(0)}. When the expression evaluates to
|
||||
0 then the corresponding input value will be returned.
|
||||
@var{ld(0)} is used to represent the function input value, which means
|
||||
that the given expression will be evaluated multiple times with
|
||||
various input values that the expression can access through
|
||||
@code{ld(0)}. When the expression evaluates to 0 then the
|
||||
corresponding input value will be returned.
|
||||
|
||||
@item round(expr)
|
||||
Round the value of expression @var{expr} to the nearest integer. For example,
|
||||
"round(1.5)" is "2.0".
|
||||
Round the value of expression @var{expr} to the nearest integer. For example, "round(1.5)" is "2.0".
|
||||
|
||||
@item sgn(x)
|
||||
Compute sign of @var{x}.
|
||||
@@ -996,15 +981,12 @@ Compute the square root of @var{expr}. This is equivalent to
|
||||
@item squish(x)
|
||||
Compute expression @code{1/(1 + exp(4*x))}.
|
||||
|
||||
@item st(idx, expr)
|
||||
@item st(var, expr)
|
||||
Store the value of the expression @var{expr} in an internal
|
||||
variable. @var{idx} specifies the index of the variable where to store
|
||||
the value, and it is a value ranging from 0 to 9. The function returns
|
||||
the value stored in the internal variable.
|
||||
|
||||
The stored value can be retrieved with @code{ld(var)}.
|
||||
|
||||
Note: variables are currently not shared between expressions.
|
||||
variable. @var{var} specifies the number of the variable where to
|
||||
store the value, and it is a value ranging from 0 to 9. The function
|
||||
returns the value stored in the internal variable.
|
||||
Note, Variables are currently not shared between expressions.
|
||||
|
||||
@item tan(x)
|
||||
Compute tangent of @var{x}.
|
||||
@@ -1013,16 +995,16 @@ Compute tangent of @var{x}.
|
||||
Compute hyperbolic tangent of @var{x}.
|
||||
|
||||
@item taylor(expr, x)
|
||||
@item taylor(expr, x, idx)
|
||||
@item taylor(expr, x, id)
|
||||
Evaluate a Taylor series at @var{x}, given an expression representing
|
||||
the @code{ld(idx)}-th derivative of a function at 0.
|
||||
the @code{ld(id)}-th derivative of a function at 0.
|
||||
|
||||
When the series does not converge the result is undefined.
|
||||
|
||||
@var{ld(idx)} is used to represent the derivative order in @var{expr},
|
||||
@var{ld(id)} is used to represent the derivative order in @var{expr},
|
||||
which means that the given expression will be evaluated multiple times
|
||||
with various input values that the expression can access through
|
||||
@code{ld(idx)}. If @var{idx} is not specified then 0 is assumed.
|
||||
@code{ld(id)}. If @var{id} is not specified then 0 is assumed.
|
||||
|
||||
Note, when you have the derivatives at y instead of 0,
|
||||
@code{taylor(expr, x-y)} can be used.
|
||||
|
||||
@@ -17,7 +17,6 @@ OBJS-$(HAVE_VSX) += $(VSX-OBJS) $(VSX-OBJS-yes)
|
||||
|
||||
OBJS-$(HAVE_RV) += $(RV-OBJS) $(RV-OBJS-yes)
|
||||
OBJS-$(HAVE_RVV) += $(RVV-OBJS) $(RVV-OBJS-yes)
|
||||
OBJS-$(HAVE_RV_ZVBB) += $(RVVB-OBJS) $(RVVB-OBJS-yes)
|
||||
|
||||
OBJS-$(HAVE_MMX) += $(MMX-OBJS) $(MMX-OBJS-yes)
|
||||
OBJS-$(HAVE_X86ASM) += $(X86ASM-OBJS) $(X86ASM-OBJS-yes)
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#!/bin/sh
|
||||
toupper(){
|
||||
echo "$@" | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ
|
||||
}
|
||||
|
||||
+21
-402
@@ -33,14 +33,17 @@
|
||||
#include "compat/va_copy.h"
|
||||
#include "libavformat/avformat.h"
|
||||
#include "libswscale/swscale.h"
|
||||
#include "libswscale/version.h"
|
||||
#include "libswresample/swresample.h"
|
||||
#include "libavutil/avassert.h"
|
||||
#include "libavutil/avstring.h"
|
||||
#include "libavutil/bprint.h"
|
||||
#include "libavutil/channel_layout.h"
|
||||
#include "libavutil/display.h"
|
||||
#include "libavutil/getenv_utf8.h"
|
||||
#include "libavutil/mathematics.h"
|
||||
#include "libavutil/imgutils.h"
|
||||
#include "libavutil/libm.h"
|
||||
#include "libavutil/mem.h"
|
||||
#include "libavutil/parseutils.h"
|
||||
#include "libavutil/eval.h"
|
||||
#include "libavutil/dict.h"
|
||||
@@ -246,8 +249,6 @@ static int write_option(void *optctx, const OptionDef *po, const char *opt,
|
||||
(uint8_t *)optctx + po->u.off : po->u.dst_ptr;
|
||||
char *arg_allocated = NULL;
|
||||
|
||||
enum OptionType so_type = po->type;
|
||||
|
||||
SpecifierOptList *sol = NULL;
|
||||
double num;
|
||||
int ret = 0;
|
||||
@@ -288,14 +289,6 @@ static int write_option(void *optctx, const OptionDef *po, const char *opt,
|
||||
goto finish;
|
||||
}
|
||||
sol->opt[sol->nb_opt - 1].specifier = str;
|
||||
|
||||
if (po->flags & OPT_FLAG_PERSTREAM) {
|
||||
ret = stream_specifier_parse(&sol->opt[sol->nb_opt - 1].stream_spec,
|
||||
str, 0, NULL);
|
||||
if (ret < 0)
|
||||
goto finish;
|
||||
}
|
||||
|
||||
dst = &sol->opt[sol->nb_opt - 1].u;
|
||||
}
|
||||
|
||||
@@ -320,9 +313,8 @@ static int write_option(void *optctx, const OptionDef *po, const char *opt,
|
||||
goto finish;
|
||||
|
||||
*(int *)dst = num;
|
||||
so_type = OPT_TYPE_INT;
|
||||
} else if (po->type == OPT_TYPE_INT64) {
|
||||
ret = parse_number(opt, arg, OPT_TYPE_INT64, INT64_MIN, (double)INT64_MAX, &num);
|
||||
ret = parse_number(opt, arg, OPT_TYPE_INT64, INT64_MIN, INT64_MAX, &num);
|
||||
if (ret < 0)
|
||||
goto finish;
|
||||
|
||||
@@ -334,7 +326,6 @@ static int write_option(void *optctx, const OptionDef *po, const char *opt,
|
||||
opt, arg);
|
||||
goto finish;
|
||||
}
|
||||
so_type = OPT_TYPE_INT64;
|
||||
} else if (po->type == OPT_TYPE_FLOAT) {
|
||||
ret = parse_number(opt, arg, OPT_TYPE_FLOAT, -INFINITY, INFINITY, &num);
|
||||
if (ret < 0)
|
||||
@@ -364,7 +355,7 @@ static int write_option(void *optctx, const OptionDef *po, const char *opt,
|
||||
}
|
||||
|
||||
if (sol) {
|
||||
sol->type = so_type;
|
||||
sol->type = po->type;
|
||||
sol->opt_canon = (po->flags & OPT_HAS_CANON) ?
|
||||
find_option(defs, po->u1.name_canon) : po;
|
||||
}
|
||||
@@ -590,7 +581,7 @@ static const AVOption *opt_find(void *obj, const char *name, const char *unit,
|
||||
return o;
|
||||
}
|
||||
|
||||
#define FLAGS ((o->type == AV_OPT_TYPE_FLAGS && (arg[0]=='-' || arg[0]=='+')) ? AV_DICT_APPEND : 0)
|
||||
#define FLAGS (o->type == AV_OPT_TYPE_FLAGS && (arg[0]=='-' || arg[0]=='+')) ? AV_DICT_APPEND : 0
|
||||
int opt_default(void *optctx, const char *opt, const char *arg)
|
||||
{
|
||||
const AVOption *o;
|
||||
@@ -802,7 +793,7 @@ int split_commandline(OptionParseContext *octx, int argc, char *argv[],
|
||||
while (optindex < argc) {
|
||||
const char *opt = argv[optindex++], *arg;
|
||||
const OptionDef *po;
|
||||
int group_idx;
|
||||
int ret, group_idx;
|
||||
|
||||
av_log(NULL, AV_LOG_DEBUG, "Reading option '%s' ...", opt);
|
||||
|
||||
@@ -988,366 +979,17 @@ FILE *get_preset_file(char *filename, size_t filename_size,
|
||||
return f;
|
||||
}
|
||||
|
||||
int cmdutils_isalnum(char c)
|
||||
{
|
||||
return (c >= '0' && c <= '9') ||
|
||||
(c >= 'A' && c <= 'Z') ||
|
||||
(c >= 'a' && c <= 'z');
|
||||
}
|
||||
|
||||
void stream_specifier_uninit(StreamSpecifier *ss)
|
||||
{
|
||||
av_freep(&ss->meta_key);
|
||||
av_freep(&ss->meta_val);
|
||||
av_freep(&ss->remainder);
|
||||
|
||||
memset(ss, 0, sizeof(*ss));
|
||||
}
|
||||
|
||||
int stream_specifier_parse(StreamSpecifier *ss, const char *spec,
|
||||
int allow_remainder, void *logctx)
|
||||
{
|
||||
char *endptr;
|
||||
int ret;
|
||||
|
||||
memset(ss, 0, sizeof(*ss));
|
||||
|
||||
ss->idx = -1;
|
||||
ss->media_type = AVMEDIA_TYPE_UNKNOWN;
|
||||
ss->stream_list = STREAM_LIST_ALL;
|
||||
|
||||
av_log(logctx, AV_LOG_TRACE, "Parsing stream specifier: %s\n", spec);
|
||||
|
||||
while (*spec) {
|
||||
if (*spec <= '9' && *spec >= '0') { /* opt:index */
|
||||
ss->idx = strtol(spec, &endptr, 0);
|
||||
|
||||
av_assert0(endptr > spec);
|
||||
spec = endptr;
|
||||
|
||||
av_log(logctx, AV_LOG_TRACE,
|
||||
"Parsed index: %d; remainder: %s\n", ss->idx, spec);
|
||||
|
||||
// this terminates the specifier
|
||||
break;
|
||||
} else if ((*spec == 'v' || *spec == 'a' || *spec == 's' ||
|
||||
*spec == 'd' || *spec == 't' || *spec == 'V') &&
|
||||
!cmdutils_isalnum(*(spec + 1))) { /* opt:[vasdtV] */
|
||||
if (ss->media_type != AVMEDIA_TYPE_UNKNOWN) {
|
||||
av_log(logctx, AV_LOG_ERROR, "Stream type specified multiple times\n");
|
||||
ret = AVERROR(EINVAL);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
switch (*spec++) {
|
||||
case 'v': ss->media_type = AVMEDIA_TYPE_VIDEO; break;
|
||||
case 'a': ss->media_type = AVMEDIA_TYPE_AUDIO; break;
|
||||
case 's': ss->media_type = AVMEDIA_TYPE_SUBTITLE; break;
|
||||
case 'd': ss->media_type = AVMEDIA_TYPE_DATA; break;
|
||||
case 't': ss->media_type = AVMEDIA_TYPE_ATTACHMENT; break;
|
||||
case 'V': ss->media_type = AVMEDIA_TYPE_VIDEO;
|
||||
ss->no_apic = 1; break;
|
||||
default: av_assert0(0);
|
||||
}
|
||||
|
||||
av_log(logctx, AV_LOG_TRACE, "Parsed media type: %s; remainder: %s\n",
|
||||
av_get_media_type_string(ss->media_type), spec);
|
||||
} else if (*spec == 'g' && *(spec + 1) == ':') {
|
||||
if (ss->stream_list != STREAM_LIST_ALL)
|
||||
goto multiple_stream_lists;
|
||||
|
||||
spec += 2;
|
||||
if (*spec == '#' || (*spec == 'i' && *(spec + 1) == ':')) {
|
||||
ss->stream_list = STREAM_LIST_GROUP_ID;
|
||||
|
||||
spec += 1 + (*spec == 'i');
|
||||
} else
|
||||
ss->stream_list = STREAM_LIST_GROUP_IDX;
|
||||
|
||||
ss->list_id = strtol(spec, &endptr, 0);
|
||||
if (spec == endptr) {
|
||||
av_log(logctx, AV_LOG_ERROR, "Expected stream group idx/ID, got: %s\n", spec);
|
||||
ret = AVERROR(EINVAL);
|
||||
goto fail;
|
||||
}
|
||||
spec = endptr;
|
||||
|
||||
av_log(logctx, AV_LOG_TRACE, "Parsed stream group %s: %"PRId64"; remainder: %s\n",
|
||||
ss->stream_list == STREAM_LIST_GROUP_ID ? "ID" : "index", ss->list_id, spec);
|
||||
} else if (*spec == 'p' && *(spec + 1) == ':') {
|
||||
if (ss->stream_list != STREAM_LIST_ALL)
|
||||
goto multiple_stream_lists;
|
||||
|
||||
ss->stream_list = STREAM_LIST_PROGRAM;
|
||||
|
||||
spec += 2;
|
||||
ss->list_id = strtol(spec, &endptr, 0);
|
||||
if (spec == endptr) {
|
||||
av_log(logctx, AV_LOG_ERROR, "Expected program ID, got: %s\n", spec);
|
||||
ret = AVERROR(EINVAL);
|
||||
goto fail;
|
||||
}
|
||||
spec = endptr;
|
||||
|
||||
av_log(logctx, AV_LOG_TRACE,
|
||||
"Parsed program ID: %"PRId64"; remainder: %s\n", ss->list_id, spec);
|
||||
} else if (!strncmp(spec, "disp:", 5)) {
|
||||
const AVClass *st_class = av_stream_get_class();
|
||||
const AVOption *o = av_opt_find(&st_class, "disposition", NULL, 0, AV_OPT_SEARCH_FAKE_OBJ);
|
||||
char *disp = NULL;
|
||||
size_t len;
|
||||
|
||||
av_assert0(o);
|
||||
|
||||
if (ss->disposition) {
|
||||
av_log(logctx, AV_LOG_ERROR, "Multiple disposition specifiers\n");
|
||||
ret = AVERROR(EINVAL);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
spec += 5;
|
||||
|
||||
for (len = 0; cmdutils_isalnum(spec[len]) ||
|
||||
spec[len] == '_' || spec[len] == '+'; len++)
|
||||
continue;
|
||||
|
||||
disp = av_strndup(spec, len);
|
||||
if (!disp) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = av_opt_eval_flags(&st_class, o, disp, &ss->disposition);
|
||||
av_freep(&disp);
|
||||
if (ret < 0) {
|
||||
av_log(logctx, AV_LOG_ERROR, "Invalid disposition specifier\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
spec += len;
|
||||
|
||||
av_log(logctx, AV_LOG_TRACE,
|
||||
"Parsed disposition: 0x%x; remainder: %s\n", ss->disposition, spec);
|
||||
} else if (*spec == '#' ||
|
||||
(*spec == 'i' && *(spec + 1) == ':')) {
|
||||
if (ss->stream_list != STREAM_LIST_ALL)
|
||||
goto multiple_stream_lists;
|
||||
|
||||
ss->stream_list = STREAM_LIST_STREAM_ID;
|
||||
|
||||
spec += 1 + (*spec == 'i');
|
||||
ss->list_id = strtol(spec, &endptr, 0);
|
||||
if (spec == endptr) {
|
||||
av_log(logctx, AV_LOG_ERROR, "Expected stream ID, got: %s\n", spec);
|
||||
ret = AVERROR(EINVAL);
|
||||
goto fail;
|
||||
}
|
||||
spec = endptr;
|
||||
|
||||
av_log(logctx, AV_LOG_TRACE,
|
||||
"Parsed stream ID: %"PRId64"; remainder: %s\n", ss->list_id, spec);
|
||||
|
||||
// this terminates the specifier
|
||||
break;
|
||||
} else if (*spec == 'm' && *(spec + 1) == ':') {
|
||||
av_assert0(!ss->meta_key && !ss->meta_val);
|
||||
|
||||
spec += 2;
|
||||
ss->meta_key = av_get_token(&spec, ":");
|
||||
if (!ss->meta_key) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto fail;
|
||||
}
|
||||
if (*spec == ':') {
|
||||
spec++;
|
||||
ss->meta_val = av_get_token(&spec, ":");
|
||||
if (!ss->meta_val) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
av_log(logctx, AV_LOG_TRACE,
|
||||
"Parsed metadata: %s:%s; remainder: %s", ss->meta_key,
|
||||
ss->meta_val ? ss->meta_val : "<any value>", spec);
|
||||
|
||||
// this terminates the specifier
|
||||
break;
|
||||
} else if (*spec == 'u' && (*(spec + 1) == '\0' || *(spec + 1) == ':')) {
|
||||
ss->usable_only = 1;
|
||||
spec++;
|
||||
av_log(logctx, AV_LOG_ERROR, "Parsed 'usable only'\n");
|
||||
|
||||
// this terminates the specifier
|
||||
break;
|
||||
} else
|
||||
break;
|
||||
|
||||
if (*spec == ':')
|
||||
spec++;
|
||||
}
|
||||
|
||||
if (*spec) {
|
||||
if (!allow_remainder) {
|
||||
av_log(logctx, AV_LOG_ERROR,
|
||||
"Trailing garbage at the end of a stream specifier: %s\n",
|
||||
spec);
|
||||
ret = AVERROR(EINVAL);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (*spec == ':')
|
||||
spec++;
|
||||
|
||||
ss->remainder = av_strdup(spec);
|
||||
if (!ss->remainder) {
|
||||
ret = AVERROR(EINVAL);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
multiple_stream_lists:
|
||||
av_log(logctx, AV_LOG_ERROR,
|
||||
"Cannot combine multiple program/group designators in a "
|
||||
"single stream specifier");
|
||||
ret = AVERROR(EINVAL);
|
||||
|
||||
fail:
|
||||
stream_specifier_uninit(ss);
|
||||
return ret;
|
||||
}
|
||||
|
||||
unsigned stream_specifier_match(const StreamSpecifier *ss,
|
||||
const AVFormatContext *s, const AVStream *st,
|
||||
void *logctx)
|
||||
{
|
||||
const AVStreamGroup *g = NULL;
|
||||
const AVProgram *p = NULL;
|
||||
int start_stream = 0, nb_streams;
|
||||
int nb_matched = 0;
|
||||
|
||||
switch (ss->stream_list) {
|
||||
case STREAM_LIST_STREAM_ID:
|
||||
// <n-th> stream with given ID makes no sense and should be impossible to request
|
||||
av_assert0(ss->idx < 0);
|
||||
// return early if we know for sure the stream does not match
|
||||
if (st->id != ss->list_id)
|
||||
return 0;
|
||||
start_stream = st->index;
|
||||
nb_streams = st->index + 1;
|
||||
break;
|
||||
case STREAM_LIST_ALL:
|
||||
start_stream = ss->idx >= 0 ? 0 : st->index;
|
||||
nb_streams = st->index + 1;
|
||||
break;
|
||||
case STREAM_LIST_PROGRAM:
|
||||
for (unsigned i = 0; i < s->nb_programs; i++) {
|
||||
if (s->programs[i]->id == ss->list_id) {
|
||||
p = s->programs[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!p) {
|
||||
av_log(logctx, AV_LOG_WARNING, "No program with ID %"PRId64" exists,"
|
||||
" stream specifier can never match\n", ss->list_id);
|
||||
return 0;
|
||||
}
|
||||
nb_streams = p->nb_stream_indexes;
|
||||
break;
|
||||
case STREAM_LIST_GROUP_ID:
|
||||
for (unsigned i = 0; i < s->nb_stream_groups; i++) {
|
||||
if (ss->list_id == s->stream_groups[i]->id) {
|
||||
g = s->stream_groups[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
// fall-through
|
||||
case STREAM_LIST_GROUP_IDX:
|
||||
if (ss->stream_list == STREAM_LIST_GROUP_IDX &&
|
||||
ss->list_id >= 0 && ss->list_id < s->nb_stream_groups)
|
||||
g = s->stream_groups[ss->list_id];
|
||||
|
||||
if (!g) {
|
||||
av_log(logctx, AV_LOG_WARNING, "No stream group with group %s %"
|
||||
PRId64" exists, stream specifier can never match\n",
|
||||
ss->stream_list == STREAM_LIST_GROUP_ID ? "ID" : "index",
|
||||
ss->list_id);
|
||||
return 0;
|
||||
}
|
||||
nb_streams = g->nb_streams;
|
||||
break;
|
||||
default: av_assert0(0);
|
||||
}
|
||||
|
||||
for (int i = start_stream; i < nb_streams; i++) {
|
||||
const AVStream *candidate = s->streams[g ? g->streams[i]->index :
|
||||
p ? p->stream_index[i] : i];
|
||||
|
||||
if (ss->media_type != AVMEDIA_TYPE_UNKNOWN &&
|
||||
(ss->media_type != candidate->codecpar->codec_type ||
|
||||
(ss->no_apic && (candidate->disposition & AV_DISPOSITION_ATTACHED_PIC))))
|
||||
continue;
|
||||
|
||||
if (ss->meta_key) {
|
||||
const AVDictionaryEntry *tag = av_dict_get(candidate->metadata,
|
||||
ss->meta_key, NULL, 0);
|
||||
|
||||
if (!tag)
|
||||
continue;
|
||||
if (ss->meta_val && strcmp(tag->value, ss->meta_val))
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ss->usable_only) {
|
||||
const AVCodecParameters *par = candidate->codecpar;
|
||||
|
||||
switch (par->codec_type) {
|
||||
case AVMEDIA_TYPE_AUDIO:
|
||||
if (!par->sample_rate || !par->ch_layout.nb_channels ||
|
||||
par->format == AV_SAMPLE_FMT_NONE)
|
||||
continue;
|
||||
break;
|
||||
case AVMEDIA_TYPE_VIDEO:
|
||||
if (!par->width || !par->height || par->format == AV_PIX_FMT_NONE)
|
||||
continue;
|
||||
break;
|
||||
case AVMEDIA_TYPE_UNKNOWN:
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (ss->disposition &&
|
||||
(candidate->disposition & ss->disposition) != ss->disposition)
|
||||
continue;
|
||||
|
||||
if (st == candidate)
|
||||
return ss->idx < 0 || ss->idx == nb_matched;
|
||||
|
||||
nb_matched++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int check_stream_specifier(AVFormatContext *s, AVStream *st, const char *spec)
|
||||
{
|
||||
StreamSpecifier ss;
|
||||
int ret;
|
||||
|
||||
ret = stream_specifier_parse(&ss, spec, 0, NULL);
|
||||
int ret = avformat_match_stream_specifier(s, st, spec);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = stream_specifier_match(&ss, s, st, NULL);
|
||||
stream_specifier_uninit(&ss);
|
||||
av_log(s, AV_LOG_ERROR, "Invalid stream specifier: %s.\n", spec);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int filter_codec_opts(const AVDictionary *opts, enum AVCodecID codec_id,
|
||||
AVFormatContext *s, AVStream *st, const AVCodec *codec,
|
||||
AVDictionary **dst, AVDictionary **opts_used)
|
||||
AVDictionary **dst)
|
||||
{
|
||||
AVDictionary *ret = NULL;
|
||||
const AVDictionaryEntry *t = NULL;
|
||||
@@ -1356,6 +998,10 @@ int filter_codec_opts(const AVDictionary *opts, enum AVCodecID codec_id,
|
||||
char prefix = 0;
|
||||
const AVClass *cc = avcodec_get_class();
|
||||
|
||||
if (!codec)
|
||||
codec = s->oformat ? avcodec_find_encoder(codec_id)
|
||||
: avcodec_find_decoder(codec_id);
|
||||
|
||||
switch (st->codecpar->codec_type) {
|
||||
case AVMEDIA_TYPE_VIDEO:
|
||||
prefix = 'v';
|
||||
@@ -1374,7 +1020,6 @@ int filter_codec_opts(const AVDictionary *opts, enum AVCodecID codec_id,
|
||||
while (t = av_dict_iterate(opts, t)) {
|
||||
const AVClass *priv_class;
|
||||
char *p = strchr(t->key, ':');
|
||||
int used = 0;
|
||||
|
||||
/* check stream specification in opt name */
|
||||
if (p) {
|
||||
@@ -1392,21 +1037,15 @@ int filter_codec_opts(const AVDictionary *opts, enum AVCodecID codec_id,
|
||||
!codec ||
|
||||
((priv_class = codec->priv_class) &&
|
||||
av_opt_find(&priv_class, t->key, NULL, flags,
|
||||
AV_OPT_SEARCH_FAKE_OBJ))) {
|
||||
AV_OPT_SEARCH_FAKE_OBJ)))
|
||||
av_dict_set(&ret, t->key, t->value, 0);
|
||||
used = 1;
|
||||
} else if (t->key[0] == prefix &&
|
||||
else if (t->key[0] == prefix &&
|
||||
av_opt_find(&cc, t->key + 1, NULL, flags,
|
||||
AV_OPT_SEARCH_FAKE_OBJ)) {
|
||||
AV_OPT_SEARCH_FAKE_OBJ))
|
||||
av_dict_set(&ret, t->key + 1, t->value, 0);
|
||||
used = 1;
|
||||
}
|
||||
|
||||
if (p)
|
||||
*p = ':';
|
||||
|
||||
if (used && opts_used)
|
||||
av_dict_set(opts_used, t->key, "", 0);
|
||||
}
|
||||
|
||||
*dst = ret;
|
||||
@@ -1414,7 +1053,7 @@ int filter_codec_opts(const AVDictionary *opts, enum AVCodecID codec_id,
|
||||
}
|
||||
|
||||
int setup_find_stream_info_opts(AVFormatContext *s,
|
||||
AVDictionary *local_codec_opts,
|
||||
AVDictionary *codec_opts,
|
||||
AVDictionary ***dst)
|
||||
{
|
||||
int ret;
|
||||
@@ -1430,8 +1069,8 @@ int setup_find_stream_info_opts(AVFormatContext *s,
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
for (int i = 0; i < s->nb_streams; i++) {
|
||||
ret = filter_codec_opts(local_codec_opts, s->streams[i]->codecpar->codec_id,
|
||||
s, s->streams[i], NULL, &opts[i], NULL);
|
||||
ret = filter_codec_opts(codec_opts, s->streams[i]->codecpar->codec_id,
|
||||
s, s->streams[i], NULL, &opts[i]);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
}
|
||||
@@ -1514,23 +1153,3 @@ char *file_read(const char *filename)
|
||||
return NULL;
|
||||
return str;
|
||||
}
|
||||
|
||||
void remove_avoptions(AVDictionary **a, AVDictionary *b)
|
||||
{
|
||||
const AVDictionaryEntry *t = NULL;
|
||||
|
||||
while ((t = av_dict_iterate(b, t))) {
|
||||
av_dict_set(a, t->key, NULL, AV_DICT_MATCH_CASE);
|
||||
}
|
||||
}
|
||||
|
||||
int check_avoptions(AVDictionary *m)
|
||||
{
|
||||
const AVDictionaryEntry *t = av_dict_iterate(m, NULL);
|
||||
if (t) {
|
||||
av_log(NULL, AV_LOG_FATAL, "Option %s not found.\n", t->key);
|
||||
return AVERROR_OPTION_NOT_FOUND;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+15
-77
@@ -102,70 +102,8 @@ enum OptionType {
|
||||
int parse_number(const char *context, const char *numstr, enum OptionType type,
|
||||
double min, double max, double *dst);
|
||||
|
||||
enum StreamList {
|
||||
STREAM_LIST_ALL,
|
||||
STREAM_LIST_STREAM_ID,
|
||||
STREAM_LIST_PROGRAM,
|
||||
STREAM_LIST_GROUP_ID,
|
||||
STREAM_LIST_GROUP_IDX,
|
||||
};
|
||||
|
||||
typedef struct StreamSpecifier {
|
||||
// trailing stream index - pick idx-th stream that matches
|
||||
// all the other constraints; -1 when not present
|
||||
int idx;
|
||||
|
||||
// which stream list to consider
|
||||
enum StreamList stream_list;
|
||||
|
||||
// STREAM_LIST_STREAM_ID: stream ID
|
||||
// STREAM_LIST_GROUP_IDX: group index
|
||||
// STREAM_LIST_GROUP_ID: group ID
|
||||
// STREAM_LIST_PROGRAM: program ID
|
||||
int64_t list_id;
|
||||
|
||||
// when not AVMEDIA_TYPE_UNKNOWN, consider only streams of this type
|
||||
enum AVMediaType media_type;
|
||||
uint8_t no_apic;
|
||||
|
||||
uint8_t usable_only;
|
||||
|
||||
int disposition;
|
||||
|
||||
char *meta_key;
|
||||
char *meta_val;
|
||||
|
||||
char *remainder;
|
||||
} StreamSpecifier;
|
||||
|
||||
/**
|
||||
* Parse a stream specifier string into a form suitable for matching.
|
||||
*
|
||||
* @param ss Parsed specifier will be stored here; must be uninitialized
|
||||
* with stream_specifier_uninit() when no longer needed.
|
||||
* @param spec String containing the stream specifier to be parsed.
|
||||
* @param allow_remainder When 1, the part of spec that is left after parsing
|
||||
* the stream specifier is stored into ss->remainder.
|
||||
* When 0, any remainder will cause parsing to fail.
|
||||
*/
|
||||
int stream_specifier_parse(StreamSpecifier *ss, const char *spec,
|
||||
int allow_remainder, void *logctx);
|
||||
|
||||
/**
|
||||
* @return 1 if st matches the parsed specifier, 0 if it does not
|
||||
*/
|
||||
unsigned stream_specifier_match(const StreamSpecifier *ss,
|
||||
const AVFormatContext *s, const AVStream *st,
|
||||
void *logctx);
|
||||
|
||||
void stream_specifier_uninit(StreamSpecifier *ss);
|
||||
|
||||
typedef struct SpecifierOpt {
|
||||
// original specifier or empty string
|
||||
char *specifier;
|
||||
// parsed specifier for OPT_FLAG_PERSTREAM options
|
||||
StreamSpecifier stream_spec;
|
||||
|
||||
char *specifier; /**< stream/chapter/program/... specifier */
|
||||
union {
|
||||
uint8_t *str;
|
||||
int i;
|
||||
@@ -182,9 +120,6 @@ typedef struct SpecifierOptList {
|
||||
|
||||
/* Canonical option definition that was parsed into this list. */
|
||||
const struct OptionDef *opt_canon;
|
||||
/* Type corresponding to the field that should be used from SpecifierOpt.u.
|
||||
* May not match the option type, e.g. OPT_TYPE_BOOL options are stored as
|
||||
* int, so this field would be OPT_TYPE_INT for them */
|
||||
enum OptionType type;
|
||||
} SpecifierOptList;
|
||||
|
||||
@@ -436,13 +371,11 @@ int check_stream_specifier(AVFormatContext *s, AVStream *st, const char *spec);
|
||||
* @param codec The particular codec for which the options should be filtered.
|
||||
* If null, the default one is looked up according to the codec id.
|
||||
* @param dst a pointer to the created dictionary
|
||||
* @param opts_used if non-NULL, every option stored in dst is also stored here,
|
||||
* with specifiers preserved
|
||||
* @return a non-negative number on success, a negative error code on failure
|
||||
*/
|
||||
int filter_codec_opts(const AVDictionary *opts, enum AVCodecID codec_id,
|
||||
AVFormatContext *s, AVStream *st, const AVCodec *codec,
|
||||
AVDictionary **dst, AVDictionary **opts_used);
|
||||
AVDictionary **dst);
|
||||
|
||||
/**
|
||||
* Setup AVCodecContext options for avformat_find_stream_info().
|
||||
@@ -532,17 +465,22 @@ void *allocate_array_elem(void *array, size_t elem_size, int *nb_elems);
|
||||
#define GROW_ARRAY(array, nb_elems)\
|
||||
grow_array((void**)&array, sizeof(*array), &nb_elems, nb_elems + 1)
|
||||
|
||||
#define GET_PIX_FMT_NAME(pix_fmt)\
|
||||
const char *name = av_get_pix_fmt_name(pix_fmt);
|
||||
|
||||
#define GET_CODEC_NAME(id)\
|
||||
const char *name = avcodec_descriptor_get(id)->name;
|
||||
|
||||
#define GET_SAMPLE_FMT_NAME(sample_fmt)\
|
||||
const char *name = av_get_sample_fmt_name(sample_fmt)
|
||||
|
||||
#define GET_SAMPLE_RATE_NAME(rate)\
|
||||
char name[16];\
|
||||
snprintf(name, sizeof(name), "%d", rate);
|
||||
|
||||
double get_rotation(const int32_t *displaymatrix);
|
||||
|
||||
/* read file contents into a string */
|
||||
char *file_read(const char *filename);
|
||||
|
||||
/* Remove keys in dictionary b from dictionary a */
|
||||
void remove_avoptions(AVDictionary **a, AVDictionary *b);
|
||||
|
||||
/* Check if any keys exist in dictionary m */
|
||||
int check_avoptions(AVDictionary *m);
|
||||
|
||||
int cmdutils_isalnum(char c);
|
||||
|
||||
#endif /* FFTOOLS_CMDUTILS_H */
|
||||
|
||||
+42
-59
@@ -68,19 +68,40 @@
|
||||
#include <conio.h>
|
||||
#endif
|
||||
|
||||
#include "libavutil/avassert.h"
|
||||
#include "libavutil/avstring.h"
|
||||
#include "libavutil/bprint.h"
|
||||
#include "libavutil/channel_layout.h"
|
||||
#include "libavutil/dict.h"
|
||||
#include "libavutil/mem.h"
|
||||
#include "libavutil/display.h"
|
||||
#include "libavutil/fifo.h"
|
||||
#include "libavutil/hwcontext.h"
|
||||
#include "libavutil/imgutils.h"
|
||||
#include "libavutil/intreadwrite.h"
|
||||
#include "libavutil/libm.h"
|
||||
#include "libavutil/mathematics.h"
|
||||
#include "libavutil/opt.h"
|
||||
#include "libavutil/parseutils.h"
|
||||
#include "libavutil/pixdesc.h"
|
||||
#include "libavutil/samplefmt.h"
|
||||
#include "libavutil/thread.h"
|
||||
#include "libavutil/threadmessage.h"
|
||||
#include "libavutil/time.h"
|
||||
#include "libavutil/timestamp.h"
|
||||
|
||||
#include "libavcodec/version.h"
|
||||
|
||||
#include "libavformat/avformat.h"
|
||||
|
||||
#include "libavdevice/avdevice.h"
|
||||
|
||||
#include "libswresample/swresample.h"
|
||||
|
||||
#include "cmdutils.h"
|
||||
#include "ffmpeg.h"
|
||||
#include "ffmpeg_sched.h"
|
||||
#include "ffmpeg_utils.h"
|
||||
#include "sync_queue.h"
|
||||
|
||||
const char program_name[] = "ffmpeg";
|
||||
const int program_birth_year = 2000;
|
||||
@@ -136,7 +157,7 @@ void term_exit(void)
|
||||
|
||||
static volatile int received_sigterm = 0;
|
||||
static volatile int received_nb_signals = 0;
|
||||
static atomic_int transcode_init_done = 0;
|
||||
static atomic_int transcode_init_done = ATOMIC_VAR_INIT(0);
|
||||
static volatile int ffmpeg_exited = 0;
|
||||
static int64_t copy_ts_first_pts = AV_NOPTS_VALUE;
|
||||
|
||||
@@ -285,9 +306,8 @@ static int read_key(void)
|
||||
}
|
||||
//Read it
|
||||
if(nchars != 0) {
|
||||
if (read(0, &ch, 1) == 1)
|
||||
return ch;
|
||||
return 0;
|
||||
read(0, &ch, 1);
|
||||
return ch;
|
||||
}else{
|
||||
return -1;
|
||||
}
|
||||
@@ -309,8 +329,8 @@ const AVIOInterruptCB int_cb = { decode_interrupt_cb, NULL };
|
||||
static void ffmpeg_cleanup(int ret)
|
||||
{
|
||||
if (do_benchmark) {
|
||||
int64_t maxrss = getmaxrss() / 1024;
|
||||
av_log(NULL, AV_LOG_INFO, "bench: maxrss=%"PRId64"KiB\n", maxrss);
|
||||
int maxrss = getmaxrss() / 1024;
|
||||
av_log(NULL, AV_LOG_INFO, "bench: maxrss=%iKiB\n", maxrss);
|
||||
}
|
||||
|
||||
for (int i = 0; i < nb_filtergraphs; i++)
|
||||
@@ -474,51 +494,21 @@ const FrameData *packet_data_c(AVPacket *pkt)
|
||||
return ret < 0 ? NULL : (const FrameData*)pkt->opaque_ref->data;
|
||||
}
|
||||
|
||||
int check_avoptions_used(const AVDictionary *opts, const AVDictionary *opts_used,
|
||||
void *logctx, int decode)
|
||||
void remove_avoptions(AVDictionary **a, AVDictionary *b)
|
||||
{
|
||||
const AVClass *class = avcodec_get_class();
|
||||
const AVClass *fclass = avformat_get_class();
|
||||
const AVDictionaryEntry *t = NULL;
|
||||
|
||||
const int flag = decode ? AV_OPT_FLAG_DECODING_PARAM :
|
||||
AV_OPT_FLAG_ENCODING_PARAM;
|
||||
const AVDictionaryEntry *e = NULL;
|
||||
while ((t = av_dict_iterate(b, t))) {
|
||||
av_dict_set(a, t->key, NULL, AV_DICT_MATCH_CASE);
|
||||
}
|
||||
}
|
||||
|
||||
while ((e = av_dict_iterate(opts, e))) {
|
||||
const AVOption *option, *foption;
|
||||
char *optname, *p;
|
||||
|
||||
if (av_dict_get(opts_used, e->key, NULL, 0))
|
||||
continue;
|
||||
|
||||
optname = av_strdup(e->key);
|
||||
if (!optname)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
p = strchr(optname, ':');
|
||||
if (p)
|
||||
*p = 0;
|
||||
|
||||
option = av_opt_find(&class, optname, NULL, 0,
|
||||
AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
|
||||
foption = av_opt_find(&fclass, optname, NULL, 0,
|
||||
AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
|
||||
av_freep(&optname);
|
||||
if (!option || foption)
|
||||
continue;
|
||||
|
||||
if (!(option->flags & flag)) {
|
||||
av_log(logctx, AV_LOG_ERROR, "Codec AVOption %s (%s) is not a %s "
|
||||
"option.\n", e->key, option->help ? option->help : "",
|
||||
decode ? "decoding" : "encoding");
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
av_log(logctx, AV_LOG_WARNING, "Codec AVOption %s (%s) has not been used "
|
||||
"for any stream. The most likely reason is either wrong type "
|
||||
"(e.g. a video option with no video streams) or that it is a "
|
||||
"private option of some decoder which was not actually used "
|
||||
"for any stream.\n", e->key, option->help ? option->help : "");
|
||||
int check_avoptions(AVDictionary *m)
|
||||
{
|
||||
const AVDictionaryEntry *t;
|
||||
if ((t = av_dict_get(m, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
|
||||
av_log(NULL, AV_LOG_FATAL, "Option %s not found.\n", t->key);
|
||||
return AVERROR_OPTION_NOT_FOUND;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -587,7 +577,7 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti
|
||||
av_bprintf(&buf_script, "stream_%d_%d_q=%.1f\n",
|
||||
ost->file->index, ost->index, q);
|
||||
}
|
||||
if (!vid && ost->type == AVMEDIA_TYPE_VIDEO) {
|
||||
if (!vid && ost->type == AVMEDIA_TYPE_VIDEO && ost->filter) {
|
||||
float fps;
|
||||
uint64_t frame_number = atomic_load(&ost->packets_written);
|
||||
|
||||
@@ -601,10 +591,8 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti
|
||||
if (is_last_report)
|
||||
av_bprintf(&buf, "L");
|
||||
|
||||
if (ost->filter) {
|
||||
nb_frames_dup = atomic_load(&ost->filter->nb_frames_dup);
|
||||
nb_frames_drop = atomic_load(&ost->filter->nb_frames_drop);
|
||||
}
|
||||
nb_frames_dup = atomic_load(&ost->filter->nb_frames_dup);
|
||||
nb_frames_drop = atomic_load(&ost->filter->nb_frames_drop);
|
||||
|
||||
vid = 1;
|
||||
}
|
||||
@@ -820,11 +808,6 @@ static int check_keyboard_interaction(int64_t cur_time)
|
||||
(n = sscanf(buf, "%63[^ ] %lf %255[^ ] %255[^\n]", target, &time, command, arg)) >= 3) {
|
||||
av_log(NULL, AV_LOG_DEBUG, "Processing command target:%s time:%f command:%s arg:%s",
|
||||
target, time, command, arg);
|
||||
for (OutputStream *ost = ost_iter(NULL); ost; ost = ost_iter(ost)) {
|
||||
if (ost->fg_simple)
|
||||
fg_send_command(ost->fg_simple, time, target, command, arg,
|
||||
key == 'C');
|
||||
}
|
||||
for (i = 0; i < nb_filtergraphs; i++)
|
||||
fg_send_command(filtergraphs[i], time, target, command, arg,
|
||||
key == 'C');
|
||||
|
||||
+64
-133
@@ -112,32 +112,12 @@ typedef struct HWDevice {
|
||||
AVBufferRef *device_ref;
|
||||
} HWDevice;
|
||||
|
||||
enum ViewSpecifierType {
|
||||
// no specifier given
|
||||
VIEW_SPECIFIER_TYPE_NONE = 0,
|
||||
// val is view index
|
||||
VIEW_SPECIFIER_TYPE_IDX,
|
||||
// val is view ID
|
||||
VIEW_SPECIFIER_TYPE_ID,
|
||||
// specify view by its position, val is AV_STEREO3D_VIEW_LEFT/RIGHT
|
||||
VIEW_SPECIFIER_TYPE_POS,
|
||||
// use all views, val is ignored
|
||||
VIEW_SPECIFIER_TYPE_ALL,
|
||||
};
|
||||
|
||||
typedef struct ViewSpecifier {
|
||||
enum ViewSpecifierType type;
|
||||
unsigned val;
|
||||
} ViewSpecifier;
|
||||
|
||||
/* select an input stream for an output stream */
|
||||
typedef struct StreamMap {
|
||||
int disabled; /* 1 is this mapping is disabled by a negative map */
|
||||
int file_index;
|
||||
int stream_index;
|
||||
char *linklabel; /* name of an output link, for mapping lavfi outputs */
|
||||
|
||||
ViewSpecifier vs;
|
||||
} StreamMap;
|
||||
|
||||
typedef struct OptionsContext {
|
||||
@@ -175,7 +155,6 @@ typedef struct OptionsContext {
|
||||
SpecifierOptList hwaccel_devices;
|
||||
SpecifierOptList hwaccel_output_formats;
|
||||
SpecifierOptList autorotate;
|
||||
SpecifierOptList apply_cropping;
|
||||
|
||||
/* output options */
|
||||
StreamMap *stream_maps;
|
||||
@@ -260,7 +239,6 @@ enum IFilterFlags {
|
||||
IFILTER_FLAG_AUTOROTATE = (1 << 0),
|
||||
IFILTER_FLAG_REINIT = (1 << 1),
|
||||
IFILTER_FLAG_CFR = (1 << 2),
|
||||
IFILTER_FLAG_CROP = (1 << 3),
|
||||
};
|
||||
|
||||
typedef struct InputFilterOptions {
|
||||
@@ -276,11 +254,6 @@ typedef struct InputFilterOptions {
|
||||
* accurate */
|
||||
AVRational framerate;
|
||||
|
||||
unsigned crop_top;
|
||||
unsigned crop_bottom;
|
||||
unsigned crop_left;
|
||||
unsigned crop_right;
|
||||
|
||||
int sub2video_width;
|
||||
int sub2video_height;
|
||||
|
||||
@@ -290,78 +263,20 @@ typedef struct InputFilterOptions {
|
||||
AVFrame *fallback;
|
||||
} InputFilterOptions;
|
||||
|
||||
enum OFilterFlags {
|
||||
OFILTER_FLAG_DISABLE_CONVERT = (1 << 0),
|
||||
// produce 24-bit audio
|
||||
OFILTER_FLAG_AUDIO_24BIT = (1 << 1),
|
||||
OFILTER_FLAG_AUTOSCALE = (1 << 2),
|
||||
};
|
||||
|
||||
typedef struct OutputFilterOptions {
|
||||
// Caller-provided name for this output
|
||||
char *name;
|
||||
|
||||
// Codec used for encoding, may be NULL
|
||||
const AVCodec *enc;
|
||||
|
||||
int64_t trim_start_us;
|
||||
int64_t trim_duration_us;
|
||||
int64_t ts_offset;
|
||||
|
||||
/* Desired output timebase.
|
||||
* Numerator can be one of EncTimeBase values, or 0 when no preference.
|
||||
*/
|
||||
AVRational output_tb;
|
||||
|
||||
AVDictionary *sws_opts;
|
||||
AVDictionary *swr_opts;
|
||||
|
||||
const char *nb_threads;
|
||||
|
||||
// A combination of OFilterFlags.
|
||||
unsigned flags;
|
||||
|
||||
int format;
|
||||
int width;
|
||||
int height;
|
||||
enum AVColorSpace color_space;
|
||||
enum AVColorRange color_range;
|
||||
|
||||
enum VideoSyncMethod vsync_method;
|
||||
|
||||
int sample_rate;
|
||||
AVChannelLayout ch_layout;
|
||||
|
||||
const int *formats;
|
||||
const int *sample_rates;
|
||||
const AVChannelLayout *ch_layouts;
|
||||
const AVRational *frame_rates;
|
||||
const enum AVColorSpace *color_spaces;
|
||||
const enum AVColorRange *color_ranges;
|
||||
|
||||
// for simple filtergraphs only, view specifier passed
|
||||
// along to the decoder
|
||||
const ViewSpecifier *vs;
|
||||
} OutputFilterOptions;
|
||||
|
||||
typedef struct InputFilter {
|
||||
struct FilterGraph *graph;
|
||||
uint8_t *name;
|
||||
} InputFilter;
|
||||
|
||||
typedef struct OutputFilter {
|
||||
const AVClass *class;
|
||||
|
||||
struct OutputStream *ost;
|
||||
struct FilterGraph *graph;
|
||||
uint8_t *name;
|
||||
|
||||
/* for filters that are not yet bound to an output stream,
|
||||
* this stores the output linklabel, if any */
|
||||
int bound;
|
||||
uint8_t *linklabel;
|
||||
|
||||
char *apad;
|
||||
|
||||
enum AVMediaType type;
|
||||
|
||||
atomic_uint_least64_t nb_frames_dup;
|
||||
@@ -389,8 +304,6 @@ enum DecoderFlags {
|
||||
DECODER_FLAG_TOP_FIELD_FIRST = (1 << 3),
|
||||
#endif
|
||||
DECODER_FLAG_SEND_END_TS = (1 << 4),
|
||||
// force bitexact decoding
|
||||
DECODER_FLAG_BITEXACT = (1 << 5),
|
||||
};
|
||||
|
||||
typedef struct DecoderOpts {
|
||||
@@ -455,6 +368,8 @@ typedef struct InputStream {
|
||||
int top_field_first;
|
||||
#endif
|
||||
|
||||
int autorotate;
|
||||
|
||||
int fix_sub_duration;
|
||||
|
||||
/* decoded data from this stream goes into all those filters
|
||||
@@ -577,13 +492,6 @@ typedef struct KeyframeForceCtx {
|
||||
|
||||
typedef struct Encoder Encoder;
|
||||
|
||||
enum CroppingType {
|
||||
CROP_DISABLED = 0,
|
||||
CROP_ALL,
|
||||
CROP_CODEC,
|
||||
CROP_CONTAINER,
|
||||
};
|
||||
|
||||
typedef struct OutputStream {
|
||||
const AVClass *class;
|
||||
|
||||
@@ -607,16 +515,21 @@ typedef struct OutputStream {
|
||||
|
||||
AVStream *st; /* stream in the output file */
|
||||
|
||||
AVRational enc_timebase;
|
||||
|
||||
Encoder *enc;
|
||||
AVCodecContext *enc_ctx;
|
||||
|
||||
/* video only */
|
||||
AVRational frame_rate;
|
||||
AVRational max_frame_rate;
|
||||
enum VideoSyncMethod vsync_method;
|
||||
int is_cfr;
|
||||
int force_fps;
|
||||
#if FFMPEG_OPT_TOP
|
||||
int top_field_first;
|
||||
#endif
|
||||
int autoscale;
|
||||
int bitexact;
|
||||
int bits_per_raw_sample;
|
||||
|
||||
@@ -624,15 +537,20 @@ typedef struct OutputStream {
|
||||
|
||||
KeyframeForceCtx kf;
|
||||
|
||||
const char *logfile_prefix;
|
||||
char *logfile_prefix;
|
||||
FILE *logfile;
|
||||
|
||||
// simple filtergraph feeding this stream, if any
|
||||
FilterGraph *fg_simple;
|
||||
OutputFilter *filter;
|
||||
|
||||
AVDictionary *encoder_opts;
|
||||
AVDictionary *sws_dict;
|
||||
AVDictionary *swr_opts;
|
||||
char *apad;
|
||||
|
||||
char *attachment_filename;
|
||||
|
||||
int keep_pix_fmt;
|
||||
|
||||
/* stats */
|
||||
// number of packets send to the muxer
|
||||
atomic_uint_least64_t packets_written;
|
||||
@@ -658,6 +576,7 @@ typedef struct OutputFile {
|
||||
|
||||
int index;
|
||||
|
||||
const AVOutputFormat *format;
|
||||
const char *url;
|
||||
|
||||
OutputStream **streams;
|
||||
@@ -666,6 +585,7 @@ typedef struct OutputFile {
|
||||
int64_t recording_time; ///< desired length of the resulting file in microseconds == AV_TIME_BASE units
|
||||
int64_t start_time; ///< start time in microseconds == AV_TIME_BASE units
|
||||
|
||||
int shortest;
|
||||
int bitexact;
|
||||
} OutputFile;
|
||||
|
||||
@@ -698,7 +618,6 @@ extern int nb_input_files;
|
||||
extern OutputFile **output_files;
|
||||
extern int nb_output_files;
|
||||
|
||||
// complex filtergraphs
|
||||
extern FilterGraph **filtergraphs;
|
||||
extern int nb_filtergraphs;
|
||||
|
||||
@@ -753,10 +672,11 @@ void term_exit(void);
|
||||
|
||||
void show_usage(void);
|
||||
|
||||
int check_avoptions_used(const AVDictionary *opts, const AVDictionary *opts_used,
|
||||
void *logctx, int decode);
|
||||
void remove_avoptions(AVDictionary **a, AVDictionary *b);
|
||||
int check_avoptions(AVDictionary *m);
|
||||
|
||||
int assert_file_overwrite(const char *filename);
|
||||
AVDictionary *strip_specifiers(const AVDictionary *dict);
|
||||
int find_codec(void *logctx, const char *name,
|
||||
enum AVMediaType type, int encoder, const AVCodec **codec);
|
||||
int parse_and_set_vsync(const char *arg, int *vsync_var, int file_idx, int st_idx, int is_global);
|
||||
@@ -764,9 +684,8 @@ int parse_and_set_vsync(const char *arg, int *vsync_var, int file_idx, int st_id
|
||||
int filtergraph_is_simple(const FilterGraph *fg);
|
||||
int init_simple_filtergraph(InputStream *ist, OutputStream *ost,
|
||||
char *graph_desc,
|
||||
Scheduler *sch, unsigned sch_idx_enc,
|
||||
const OutputFilterOptions *opts);
|
||||
int fg_finalise_bindings(void);
|
||||
Scheduler *sch, unsigned sch_idx_enc);
|
||||
int fg_finalise_bindings(FilterGraph *fg);
|
||||
|
||||
/**
|
||||
* Get our axiliary frame data attached to the frame, allocating it
|
||||
@@ -780,8 +699,7 @@ FrameData *packet_data (AVPacket *pkt);
|
||||
const FrameData *packet_data_c(AVPacket *pkt);
|
||||
|
||||
int ofilter_bind_ost(OutputFilter *ofilter, OutputStream *ost,
|
||||
unsigned sched_idx_enc,
|
||||
const OutputFilterOptions *opts);
|
||||
unsigned sched_idx_enc);
|
||||
|
||||
/**
|
||||
* Create a new filtergraph in the global filtergraph list.
|
||||
@@ -841,21 +759,7 @@ void dec_free(Decoder **pdec);
|
||||
*
|
||||
* @param opts filtergraph input options, to be filled by this function
|
||||
*/
|
||||
int dec_filter_add(Decoder *dec, InputFilter *ifilter, InputFilterOptions *opts,
|
||||
const ViewSpecifier *vs, SchedulerNode *src);
|
||||
|
||||
/*
|
||||
* For multiview video, request output of the view(s) determined by vs.
|
||||
* May be called multiple times.
|
||||
*
|
||||
* If this function is never called, only the base view is output. If it is
|
||||
* called at least once, only the views requested are output.
|
||||
*
|
||||
* @param src scheduler node from which the frames corresponding vs
|
||||
* will originate
|
||||
*/
|
||||
int dec_request_view(Decoder *dec, const ViewSpecifier *vs,
|
||||
SchedulerNode *src);
|
||||
int dec_filter_add(Decoder *dec, InputFilter *ifilter, InputFilterOptions *opts);
|
||||
|
||||
int enc_alloc(Encoder **penc, const AVCodec *codec,
|
||||
Scheduler *sch, unsigned sch_idx);
|
||||
@@ -885,8 +789,7 @@ void ifile_close(InputFile **f);
|
||||
|
||||
int ist_output_add(InputStream *ist, OutputStream *ost);
|
||||
int ist_filter_add(InputStream *ist, InputFilter *ifilter, int is_simple,
|
||||
const ViewSpecifier *vs, InputFilterOptions *opts,
|
||||
SchedulerNode *src);
|
||||
InputFilterOptions *opts);
|
||||
|
||||
/**
|
||||
* Find an unused input stream of given type.
|
||||
@@ -903,18 +806,46 @@ OutputStream *ost_iter(OutputStream *prev);
|
||||
|
||||
void update_benchmark(const char *fmt, ...);
|
||||
|
||||
#define SPECIFIER_OPT_FMT_str "%s"
|
||||
#define SPECIFIER_OPT_FMT_i "%i"
|
||||
#define SPECIFIER_OPT_FMT_i64 "%"PRId64
|
||||
#define SPECIFIER_OPT_FMT_ui64 "%"PRIu64
|
||||
#define SPECIFIER_OPT_FMT_f "%f"
|
||||
#define SPECIFIER_OPT_FMT_dbl "%lf"
|
||||
|
||||
#define WARN_MULTIPLE_OPT_USAGE(optname, type, idx, st)\
|
||||
{\
|
||||
char namestr[128] = "";\
|
||||
const SpecifierOpt *so = &o->optname.opt[idx];\
|
||||
const char *spec = so->specifier && so->specifier[0] ? so->specifier : "";\
|
||||
snprintf(namestr, sizeof(namestr), "-%s", o->optname.opt_canon->name);\
|
||||
if (o->optname.opt_canon->flags & OPT_HAS_ALT) {\
|
||||
const char * const *names_alt = o->optname.opt_canon->u1.names_alt;\
|
||||
for (int _i = 0; names_alt[_i]; _i++)\
|
||||
av_strlcatf(namestr, sizeof(namestr), "/-%s", names_alt[_i]);\
|
||||
}\
|
||||
av_log(NULL, AV_LOG_WARNING, "Multiple %s options specified for stream %d, only the last option '-%s%s%s "SPECIFIER_OPT_FMT_##type"' will be used.\n",\
|
||||
namestr, st->index, o->optname.opt_canon->name, spec[0] ? ":" : "", spec, so->u.type);\
|
||||
}
|
||||
|
||||
#define MATCH_PER_STREAM_OPT(name, type, outvar, fmtctx, st)\
|
||||
{\
|
||||
int _ret, _matches = 0, _match_idx;\
|
||||
for (int _i = 0; _i < o->name.nb_opt; _i++) {\
|
||||
char *spec = o->name.opt[_i].specifier;\
|
||||
if ((_ret = check_stream_specifier(fmtctx, st, spec)) > 0) {\
|
||||
outvar = o->name.opt[_i].u.type;\
|
||||
_match_idx = _i;\
|
||||
_matches++;\
|
||||
} else if (_ret < 0)\
|
||||
return _ret;\
|
||||
}\
|
||||
if (_matches > 1 && o->name.opt_canon)\
|
||||
WARN_MULTIPLE_OPT_USAGE(name, type, _match_idx, st);\
|
||||
}
|
||||
|
||||
const char *opt_match_per_type_str(const SpecifierOptList *sol,
|
||||
char mediatype);
|
||||
void opt_match_per_stream_str(void *logctx, const SpecifierOptList *sol,
|
||||
AVFormatContext *fc, AVStream *st, const char **out);
|
||||
void opt_match_per_stream_int(void *logctx, const SpecifierOptList *sol,
|
||||
AVFormatContext *fc, AVStream *st, int *out);
|
||||
void opt_match_per_stream_int64(void *logctx, const SpecifierOptList *sol,
|
||||
AVFormatContext *fc, AVStream *st, int64_t *out);
|
||||
void opt_match_per_stream_dbl(void *logctx, const SpecifierOptList *sol,
|
||||
AVFormatContext *fc, AVStream *st, double *out);
|
||||
|
||||
int view_specifier_parse(const char **pspec, ViewSpecifier *vs);
|
||||
|
||||
int muxer_thread(void *arg);
|
||||
int encoder_thread(void *arg);
|
||||
|
||||
+27
-426
@@ -16,25 +16,24 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <stdbit.h>
|
||||
|
||||
#include "libavutil/avassert.h"
|
||||
#include "libavutil/avstring.h"
|
||||
#include "libavutil/dict.h"
|
||||
#include "libavutil/error.h"
|
||||
#include "libavutil/log.h"
|
||||
#include "libavutil/mem.h"
|
||||
#include "libavutil/opt.h"
|
||||
#include "libavutil/pixdesc.h"
|
||||
#include "libavutil/pixfmt.h"
|
||||
#include "libavutil/stereo3d.h"
|
||||
#include "libavutil/time.h"
|
||||
#include "libavutil/timestamp.h"
|
||||
|
||||
#include "libavcodec/avcodec.h"
|
||||
#include "libavcodec/codec.h"
|
||||
|
||||
#include "libavfilter/buffersrc.h"
|
||||
|
||||
#include "ffmpeg.h"
|
||||
#include "ffmpeg_utils.h"
|
||||
#include "thread_queue.h"
|
||||
|
||||
typedef struct DecoderPriv {
|
||||
Decoder dec;
|
||||
@@ -42,7 +41,6 @@ typedef struct DecoderPriv {
|
||||
AVCodecContext *dec_ctx;
|
||||
|
||||
AVFrame *frame;
|
||||
AVFrame *frame_tmp_ref;
|
||||
AVPacket *pkt;
|
||||
|
||||
// override output video sample aspect ratio with this value
|
||||
@@ -52,7 +50,6 @@ typedef struct DecoderPriv {
|
||||
|
||||
// a combination of DECODER_FLAG_*, provided to dec_open()
|
||||
int flags;
|
||||
int apply_cropping;
|
||||
|
||||
enum AVPixelFormat hwaccel_pix_fmt;
|
||||
enum HWAccelID hwaccel_id;
|
||||
@@ -81,23 +78,6 @@ typedef struct DecoderPriv {
|
||||
char log_name[32];
|
||||
char *parent_name;
|
||||
|
||||
// user specified decoder multiview options manually
|
||||
int multiview_user_config;
|
||||
|
||||
struct {
|
||||
ViewSpecifier vs;
|
||||
unsigned out_idx;
|
||||
} *views_requested;
|
||||
int nb_views_requested;
|
||||
|
||||
/* A map of view ID to decoder outputs.
|
||||
* MUST NOT be accessed outside of get_format()/get_buffer() */
|
||||
struct {
|
||||
unsigned id;
|
||||
uintptr_t out_mask;
|
||||
} *view_map;
|
||||
int nb_view_map;
|
||||
|
||||
struct {
|
||||
AVDictionary *opts;
|
||||
const AVCodec *codec;
|
||||
@@ -127,7 +107,6 @@ void dec_free(Decoder **pdec)
|
||||
avcodec_free_context(&dp->dec_ctx);
|
||||
|
||||
av_frame_free(&dp->frame);
|
||||
av_frame_free(&dp->frame_tmp_ref);
|
||||
av_packet_free(&dp->pkt);
|
||||
|
||||
av_dict_free(&dp->standalone_init.opts);
|
||||
@@ -138,9 +117,6 @@ void dec_free(Decoder **pdec)
|
||||
|
||||
av_freep(&dp->parent_name);
|
||||
|
||||
av_freep(&dp->views_requested);
|
||||
av_freep(&dp->view_map);
|
||||
|
||||
av_freep(pdec);
|
||||
}
|
||||
|
||||
@@ -285,10 +261,6 @@ static int64_t video_duration_estimate(const DecoderPriv *dp, const AVFrame *fra
|
||||
const int ts_unreliable = dp->flags & DECODER_FLAG_TS_UNRELIABLE;
|
||||
const int fr_forced = dp->flags & DECODER_FLAG_FRAMERATE_FORCED;
|
||||
int64_t codec_duration = 0;
|
||||
// difference between this and last frame's timestamps
|
||||
const int64_t ts_diff =
|
||||
(frame->pts != AV_NOPTS_VALUE && dp->last_frame_pts != AV_NOPTS_VALUE) ?
|
||||
frame->pts - dp->last_frame_pts : -1;
|
||||
|
||||
// XXX lavf currently makes up frame durations when they are not provided by
|
||||
// the container. As there is no way to reliably distinguish real container
|
||||
@@ -296,13 +268,8 @@ static int64_t video_duration_estimate(const DecoderPriv *dp, const AVFrame *fra
|
||||
// the container has timestamps. Eventually lavf should stop making up
|
||||
// durations, then this should be simplified.
|
||||
|
||||
// frame duration is unreliable (typically guessed by lavf) when it is equal
|
||||
// to 1 and the actual duration of the last frame is more than 2x larger
|
||||
const int duration_unreliable = frame->duration == 1 && ts_diff > 2 * frame->duration;
|
||||
|
||||
// prefer frame duration for containers with timestamps
|
||||
if (fr_forced ||
|
||||
(frame->duration > 0 && !ts_unreliable && !duration_unreliable))
|
||||
if (frame->duration > 0 && (!ts_unreliable || fr_forced))
|
||||
return frame->duration;
|
||||
|
||||
if (dp->dec_ctx->framerate.den && dp->dec_ctx->framerate.num) {
|
||||
@@ -319,8 +286,9 @@ static int64_t video_duration_estimate(const DecoderPriv *dp, const AVFrame *fra
|
||||
|
||||
// when timestamps are available, repeat last frame's actual duration
|
||||
// (i.e. pts difference between this and last frame)
|
||||
if (ts_diff > 0)
|
||||
return ts_diff;
|
||||
if (frame->pts != AV_NOPTS_VALUE && dp->last_frame_pts != AV_NOPTS_VALUE &&
|
||||
frame->pts > dp->last_frame_pts)
|
||||
return frame->pts - dp->last_frame_pts;
|
||||
|
||||
// try frame/codec duration
|
||||
if (frame->duration > 0)
|
||||
@@ -382,8 +350,7 @@ fail:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int video_frame_process(DecoderPriv *dp, AVFrame *frame,
|
||||
unsigned *outputs_mask)
|
||||
static int video_frame_process(DecoderPriv *dp, AVFrame *frame)
|
||||
{
|
||||
#if FFMPEG_OPT_TOP
|
||||
if (dp->flags & DECODER_FLAG_TOP_FIELD_FIRST) {
|
||||
@@ -436,18 +403,6 @@ static int video_frame_process(DecoderPriv *dp, AVFrame *frame,
|
||||
if (dp->sar_override.num)
|
||||
frame->sample_aspect_ratio = dp->sar_override;
|
||||
|
||||
if (dp->apply_cropping) {
|
||||
// lavfi does not require aligned frame data
|
||||
int ret = av_frame_apply_cropping(frame, AV_FRAME_CROP_UNALIGNED);
|
||||
if (ret < 0) {
|
||||
av_log(dp, AV_LOG_ERROR, "Error applying decoder cropping\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (frame->opaque)
|
||||
*outputs_mask = (uintptr_t)frame->opaque;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -607,7 +562,7 @@ static int process_subtitle(DecoderPriv *dp, AVFrame *frame)
|
||||
if (!subtitle)
|
||||
return 0;
|
||||
|
||||
ret = sch_dec_send(dp->sch, dp->sch_idx, 0, frame);
|
||||
ret = sch_dec_send(dp->sch, dp->sch_idx, frame);
|
||||
if (ret < 0)
|
||||
av_frame_unref(frame);
|
||||
|
||||
@@ -649,7 +604,7 @@ static int transcode_subtitles(DecoderPriv *dp, const AVPacket *pkt,
|
||||
frame->time_base = pkt->time_base;
|
||||
frame->opaque = (void*)(intptr_t)FRAME_OPAQUE_SUB_HEARTBEAT;
|
||||
|
||||
ret = sch_dec_send(dp->sch, dp->sch_idx, 0, frame);
|
||||
ret = sch_dec_send(dp->sch, dp->sch_idx, frame);
|
||||
return ret == AVERROR_EOF ? AVERROR_EXIT : ret;
|
||||
} else if (pkt && (intptr_t)pkt->opaque == PKT_OPAQUE_FIX_SUB_DURATION) {
|
||||
return fix_sub_duration_heartbeat(dp, av_rescale_q(pkt->pts, pkt->time_base,
|
||||
@@ -744,7 +699,6 @@ static int packet_decode(DecoderPriv *dp, AVPacket *pkt, AVFrame *frame)
|
||||
|
||||
while (1) {
|
||||
FrameData *fd;
|
||||
unsigned outputs_mask = 1;
|
||||
|
||||
av_frame_unref(frame);
|
||||
|
||||
@@ -793,7 +747,7 @@ static int packet_decode(DecoderPriv *dp, AVPacket *pkt, AVFrame *frame)
|
||||
|
||||
audio_ts_process(dp, frame);
|
||||
} else {
|
||||
ret = video_frame_process(dp, frame, &outputs_mask);
|
||||
ret = video_frame_process(dp, frame);
|
||||
if (ret < 0) {
|
||||
av_log(dp, AV_LOG_FATAL,
|
||||
"Error while processing the decoded data\n");
|
||||
@@ -803,28 +757,10 @@ static int packet_decode(DecoderPriv *dp, AVPacket *pkt, AVFrame *frame)
|
||||
|
||||
dp->dec.frames_decoded++;
|
||||
|
||||
for (int i = 0; i < stdc_count_ones(outputs_mask); i++) {
|
||||
AVFrame *to_send = frame;
|
||||
int pos;
|
||||
|
||||
av_assert0(outputs_mask);
|
||||
pos = stdc_trailing_zeros(outputs_mask);
|
||||
outputs_mask &= ~(1U << pos);
|
||||
|
||||
// this is not the last output and sch_dec_send() consumes the frame
|
||||
// given to it, so make a temporary reference
|
||||
if (outputs_mask) {
|
||||
to_send = dp->frame_tmp_ref;
|
||||
ret = av_frame_ref(to_send, frame);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = sch_dec_send(dp->sch, dp->sch_idx, pos, to_send);
|
||||
if (ret < 0) {
|
||||
av_frame_unref(to_send);
|
||||
return ret == AVERROR_EOF ? AVERROR_EXIT : ret;
|
||||
}
|
||||
ret = sch_dec_send(dp->sch, dp->sch_idx, frame);
|
||||
if (ret < 0) {
|
||||
av_frame_unref(frame);
|
||||
return ret == AVERROR_EOF ? AVERROR_EXIT : ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -999,7 +935,7 @@ static int decoder_thread(void *arg)
|
||||
dp->last_frame_pts + dp->last_frame_duration_est;
|
||||
dt.frame->time_base = dp->last_frame_tb;
|
||||
|
||||
ret = sch_dec_send(dp->sch, dp->sch_idx, 0, dt.frame);
|
||||
ret = sch_dec_send(dp->sch, dp->sch_idx, dt.frame);
|
||||
if (ret < 0 && ret != AVERROR_EOF) {
|
||||
av_log(dp, AV_LOG_FATAL,
|
||||
"Error signalling EOF timestamp: %s\n", av_err2str(ret));
|
||||
@@ -1023,307 +959,10 @@ finish:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int dec_request_view(Decoder *d, const ViewSpecifier *vs,
|
||||
SchedulerNode *src)
|
||||
{
|
||||
DecoderPriv *dp = dp_from_dec(d);
|
||||
unsigned out_idx = 0;
|
||||
int ret;
|
||||
|
||||
if (dp->multiview_user_config) {
|
||||
if (!vs || vs->type == VIEW_SPECIFIER_TYPE_NONE) {
|
||||
*src = SCH_DEC_OUT(dp->sch_idx, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
av_log(dp, AV_LOG_ERROR,
|
||||
"Manually selecting views with -view_ids cannot be combined "
|
||||
"with view selection via stream specifiers. It is strongly "
|
||||
"recommended you always use stream specifiers only.\n");
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
// when multiview_user_config is not set, NONE specifier is treated
|
||||
// as requesting the base view
|
||||
vs = (vs && vs->type != VIEW_SPECIFIER_TYPE_NONE) ? vs :
|
||||
&(ViewSpecifier){ .type = VIEW_SPECIFIER_TYPE_IDX, .val = 0 };
|
||||
|
||||
// check if the specifier matches an already-existing one
|
||||
for (int i = 0; i < dp->nb_views_requested; i++) {
|
||||
const ViewSpecifier *vs1 = &dp->views_requested[i].vs;
|
||||
|
||||
if (vs->type == vs1->type &&
|
||||
(vs->type == VIEW_SPECIFIER_TYPE_ALL || vs->val == vs1->val)) {
|
||||
*src = SCH_DEC_OUT(dp->sch_idx, dp->views_requested[i].out_idx);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// we use a bitmask to map view IDs to decoder outputs, which
|
||||
// limits the number of outputs allowed
|
||||
if (dp->nb_views_requested >= sizeof(dp->view_map[0].out_mask) * 8) {
|
||||
av_log(dp, AV_LOG_ERROR, "Too many view specifiers\n");
|
||||
return AVERROR(ENOSYS);
|
||||
}
|
||||
|
||||
ret = GROW_ARRAY(dp->views_requested, dp->nb_views_requested);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (dp->nb_views_requested > 1) {
|
||||
ret = sch_add_dec_output(dp->sch, dp->sch_idx);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
out_idx = ret;
|
||||
}
|
||||
|
||||
dp->views_requested[dp->nb_views_requested - 1].out_idx = out_idx;
|
||||
dp->views_requested[dp->nb_views_requested - 1].vs = *vs;
|
||||
|
||||
*src = SCH_DEC_OUT(dp->sch_idx,
|
||||
dp->views_requested[dp->nb_views_requested - 1].out_idx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int multiview_setup(DecoderPriv *dp, AVCodecContext *dec_ctx)
|
||||
{
|
||||
unsigned views_wanted = 0;
|
||||
|
||||
unsigned nb_view_ids_av, nb_view_ids;
|
||||
unsigned *view_ids_av = NULL, *view_pos_av = NULL;
|
||||
int *view_ids = NULL;
|
||||
int ret;
|
||||
|
||||
// no views/only base view were requested - do nothing
|
||||
if (!dp->nb_views_requested ||
|
||||
(dp->nb_views_requested == 1 &&
|
||||
dp->views_requested[0].vs.type == VIEW_SPECIFIER_TYPE_IDX &&
|
||||
dp->views_requested[0].vs.val == 0))
|
||||
return 0;
|
||||
|
||||
av_freep(&dp->view_map);
|
||||
dp->nb_view_map = 0;
|
||||
|
||||
// retrieve views available in current CVS
|
||||
ret = av_opt_get_array_size(dec_ctx, "view_ids_available",
|
||||
AV_OPT_SEARCH_CHILDREN, &nb_view_ids_av);
|
||||
if (ret < 0) {
|
||||
av_log(dp, AV_LOG_ERROR,
|
||||
"Multiview decoding requested, but decoder '%s' does not "
|
||||
"support it\n", dec_ctx->codec->name);
|
||||
return AVERROR(ENOSYS);
|
||||
}
|
||||
|
||||
if (nb_view_ids_av) {
|
||||
unsigned nb_view_pos_av;
|
||||
|
||||
if (nb_view_ids_av >= sizeof(views_wanted) * 8) {
|
||||
av_log(dp, AV_LOG_ERROR, "Too many views in video: %u\n", nb_view_ids_av);
|
||||
ret = AVERROR(ENOSYS);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
view_ids_av = av_calloc(nb_view_ids_av, sizeof(*view_ids_av));
|
||||
if (!view_ids_av) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = av_opt_get_array(dec_ctx, "view_ids_available",
|
||||
AV_OPT_SEARCH_CHILDREN, 0, nb_view_ids_av,
|
||||
AV_OPT_TYPE_UINT, view_ids_av);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
|
||||
ret = av_opt_get_array_size(dec_ctx, "view_pos_available",
|
||||
AV_OPT_SEARCH_CHILDREN, &nb_view_pos_av);
|
||||
if (ret >= 0 && nb_view_pos_av == nb_view_ids_av) {
|
||||
view_pos_av = av_calloc(nb_view_ids_av, sizeof(*view_pos_av));
|
||||
if (!view_pos_av) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = av_opt_get_array(dec_ctx, "view_pos_available",
|
||||
AV_OPT_SEARCH_CHILDREN, 0, nb_view_ids_av,
|
||||
AV_OPT_TYPE_UINT, view_pos_av);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
}
|
||||
} else {
|
||||
// assume there is a single view with ID=0
|
||||
nb_view_ids_av = 1;
|
||||
view_ids_av = av_calloc(nb_view_ids_av, sizeof(*view_ids_av));
|
||||
view_pos_av = av_calloc(nb_view_ids_av, sizeof(*view_pos_av));
|
||||
if (!view_ids_av || !view_pos_av) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto fail;
|
||||
}
|
||||
view_pos_av[0] = AV_STEREO3D_VIEW_UNSPEC;
|
||||
}
|
||||
|
||||
dp->view_map = av_calloc(nb_view_ids_av, sizeof(*dp->view_map));
|
||||
if (!dp->view_map) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto fail;
|
||||
}
|
||||
dp->nb_view_map = nb_view_ids_av;
|
||||
|
||||
for (int i = 0; i < dp->nb_view_map; i++)
|
||||
dp->view_map[i].id = view_ids_av[i];
|
||||
|
||||
// figure out which views should go to which output
|
||||
for (int i = 0; i < dp->nb_views_requested; i++) {
|
||||
const ViewSpecifier *vs = &dp->views_requested[i].vs;
|
||||
|
||||
switch (vs->type) {
|
||||
case VIEW_SPECIFIER_TYPE_IDX:
|
||||
if (vs->val >= nb_view_ids_av) {
|
||||
av_log(dp, exit_on_error ? AV_LOG_ERROR : AV_LOG_WARNING,
|
||||
"View with index %u requested, but only %u views available "
|
||||
"in current video sequence (more views may or may not be "
|
||||
"available in later sequences).\n",
|
||||
vs->val, nb_view_ids_av);
|
||||
if (exit_on_error) {
|
||||
ret = AVERROR(EINVAL);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
views_wanted |= 1U << vs->val;
|
||||
dp->view_map[vs->val].out_mask |= 1ULL << i;
|
||||
|
||||
break;
|
||||
case VIEW_SPECIFIER_TYPE_ID: {
|
||||
int view_idx = -1;
|
||||
|
||||
for (unsigned j = 0; j < nb_view_ids_av; j++) {
|
||||
if (view_ids_av[j] == vs->val) {
|
||||
view_idx = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (view_idx < 0) {
|
||||
av_log(dp, exit_on_error ? AV_LOG_ERROR : AV_LOG_WARNING,
|
||||
"View with ID %u requested, but is not available "
|
||||
"in the video sequence\n", vs->val);
|
||||
if (exit_on_error) {
|
||||
ret = AVERROR(EINVAL);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
views_wanted |= 1U << view_idx;
|
||||
dp->view_map[view_idx].out_mask |= 1ULL << i;
|
||||
|
||||
break;
|
||||
}
|
||||
case VIEW_SPECIFIER_TYPE_POS: {
|
||||
int view_idx = -1;
|
||||
|
||||
for (unsigned j = 0; view_pos_av && j < nb_view_ids_av; j++) {
|
||||
if (view_pos_av[j] == vs->val) {
|
||||
view_idx = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (view_idx < 0) {
|
||||
av_log(dp, exit_on_error ? AV_LOG_ERROR : AV_LOG_WARNING,
|
||||
"View position '%s' requested, but is not available "
|
||||
"in the video sequence\n", av_stereo3d_view_name(vs->val));
|
||||
if (exit_on_error) {
|
||||
ret = AVERROR(EINVAL);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
views_wanted |= 1U << view_idx;
|
||||
dp->view_map[view_idx].out_mask |= 1ULL << i;
|
||||
|
||||
break;
|
||||
}
|
||||
case VIEW_SPECIFIER_TYPE_ALL:
|
||||
views_wanted |= (1U << nb_view_ids_av) - 1;
|
||||
|
||||
for (int j = 0; j < dp->nb_view_map; j++)
|
||||
dp->view_map[j].out_mask |= 1ULL << i;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!views_wanted) {
|
||||
av_log(dp, AV_LOG_ERROR, "No views were selected for decoding\n");
|
||||
ret = AVERROR(EINVAL);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
// signal to decoder which views we want
|
||||
nb_view_ids = stdc_count_ones(views_wanted);
|
||||
view_ids = av_malloc_array(nb_view_ids, sizeof(*view_ids));
|
||||
if (!view_ids) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < nb_view_ids; i++) {
|
||||
int pos;
|
||||
|
||||
av_assert0(views_wanted);
|
||||
pos = stdc_trailing_zeros(views_wanted);
|
||||
views_wanted &= ~(1U << pos);
|
||||
|
||||
view_ids[i] = view_ids_av[pos];
|
||||
}
|
||||
|
||||
// unset view_ids in case we set it earlier
|
||||
av_opt_set(dec_ctx, "view_ids", NULL, AV_OPT_SEARCH_CHILDREN);
|
||||
|
||||
ret = av_opt_set_array(dec_ctx, "view_ids", AV_OPT_SEARCH_CHILDREN,
|
||||
0, nb_view_ids, AV_OPT_TYPE_INT, view_ids);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
|
||||
if (!dp->frame_tmp_ref) {
|
||||
dp->frame_tmp_ref = av_frame_alloc();
|
||||
if (!dp->frame_tmp_ref) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
fail:
|
||||
av_freep(&view_ids_av);
|
||||
av_freep(&view_pos_av);
|
||||
av_freep(&view_ids);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void multiview_check_manual(DecoderPriv *dp, const AVDictionary *dec_opts)
|
||||
{
|
||||
if (av_dict_get(dec_opts, "view_ids", NULL, 0)) {
|
||||
av_log(dp, AV_LOG_WARNING, "Manually selecting views with -view_ids "
|
||||
"is not recommended, use view specifiers instead\n");
|
||||
dp->multiview_user_config = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static enum AVPixelFormat get_format(AVCodecContext *s, const enum AVPixelFormat *pix_fmts)
|
||||
{
|
||||
DecoderPriv *dp = s->opaque;
|
||||
const enum AVPixelFormat *p;
|
||||
int ret;
|
||||
|
||||
ret = multiview_setup(dp, s);
|
||||
if (ret < 0) {
|
||||
av_log(dp, AV_LOG_ERROR, "Error setting up multiview decoding: %s\n",
|
||||
av_err2str(ret));
|
||||
return AV_PIX_FMT_NONE;
|
||||
}
|
||||
|
||||
for (p = pix_fmts; *p != AV_PIX_FMT_NONE; p++) {
|
||||
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(*p);
|
||||
@@ -1354,26 +993,6 @@ static enum AVPixelFormat get_format(AVCodecContext *s, const enum AVPixelFormat
|
||||
return *p;
|
||||
}
|
||||
|
||||
static int get_buffer(AVCodecContext *dec_ctx, AVFrame *frame, int flags)
|
||||
{
|
||||
DecoderPriv *dp = dec_ctx->opaque;
|
||||
|
||||
// for multiview video, store the output mask in frame opaque
|
||||
if (dp->nb_view_map) {
|
||||
const AVFrameSideData *sd = av_frame_get_side_data(frame, AV_FRAME_DATA_VIEW_ID);
|
||||
int view_id = sd ? *(int*)sd->data : 0;
|
||||
|
||||
for (int i = 0; i < dp->nb_view_map; i++) {
|
||||
if (dp->view_map[i].id == view_id) {
|
||||
frame->opaque = (void*)dp->view_map[i].out_mask;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return avcodec_default_get_buffer2(dec_ctx, frame, flags);
|
||||
}
|
||||
|
||||
static HWDevice *hw_device_match_by_codec(const AVCodec *codec)
|
||||
{
|
||||
const AVCodecHWConfig *config;
|
||||
@@ -1567,12 +1186,13 @@ static int dec_open(DecoderPriv *dp, AVDictionary **dec_opts,
|
||||
|
||||
dp->dec_ctx->opaque = dp;
|
||||
dp->dec_ctx->get_format = get_format;
|
||||
dp->dec_ctx->get_buffer2 = get_buffer;
|
||||
dp->dec_ctx->pkt_timebase = o->time_base;
|
||||
|
||||
if (!av_dict_get(*dec_opts, "threads", NULL, 0))
|
||||
av_dict_set(dec_opts, "threads", "auto", 0);
|
||||
|
||||
av_dict_set(dec_opts, "flags", "+copy_opaque", AV_DICT_MULTIKEY);
|
||||
|
||||
ret = hw_device_setup_for_decode(dp, codec, o->hwaccel_device);
|
||||
if (ret < 0) {
|
||||
av_log(dp, AV_LOG_ERROR,
|
||||
@@ -1581,25 +1201,7 @@ static int dec_open(DecoderPriv *dp, AVDictionary **dec_opts,
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = av_opt_set_dict2(dp->dec_ctx, dec_opts, AV_OPT_SEARCH_CHILDREN);
|
||||
if (ret < 0) {
|
||||
av_log(dp, AV_LOG_ERROR, "Error applying decoder options: %s\n",
|
||||
av_err2str(ret));
|
||||
return ret;
|
||||
}
|
||||
ret = check_avoptions(*dec_opts);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
dp->dec_ctx->flags |= AV_CODEC_FLAG_COPY_OPAQUE;
|
||||
if (o->flags & DECODER_FLAG_BITEXACT)
|
||||
dp->dec_ctx->flags |= AV_CODEC_FLAG_BITEXACT;
|
||||
|
||||
// we apply cropping outselves
|
||||
dp->apply_cropping = dp->dec_ctx->apply_cropping;
|
||||
dp->dec_ctx->apply_cropping = 0;
|
||||
|
||||
if ((ret = avcodec_open2(dp->dec_ctx, codec, NULL)) < 0) {
|
||||
if ((ret = avcodec_open2(dp->dec_ctx, codec, dec_opts)) < 0) {
|
||||
av_log(dp, AV_LOG_ERROR, "Error while opening decoder: %s\n",
|
||||
av_err2str(ret));
|
||||
return ret;
|
||||
@@ -1618,6 +1220,10 @@ static int dec_open(DecoderPriv *dp, AVDictionary **dec_opts,
|
||||
dp->dec_ctx->extra_hw_frames = extra_frames;
|
||||
}
|
||||
|
||||
ret = check_avoptions(*dec_opts);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
dp->dec.subtitle_header = dp->dec_ctx->subtitle_header;
|
||||
dp->dec.subtitle_header_size = dp->dec_ctx->subtitle_header_size;
|
||||
|
||||
@@ -1657,8 +1263,6 @@ int dec_init(Decoder **pdec, Scheduler *sch,
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
multiview_check_manual(dp, *dec_opts);
|
||||
|
||||
ret = dec_open(dp, dec_opts, o, param_out);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
@@ -1723,7 +1327,7 @@ int dec_create(const OptionsContext *o, const char *arg, Scheduler *sch)
|
||||
return ret;
|
||||
enc_idx = ret;
|
||||
|
||||
ret = sch_connect(sch, SCH_ENC(enc_idx), SCH_DEC_IN(dp->sch_idx));
|
||||
ret = sch_connect(sch, SCH_ENC(enc_idx), SCH_DEC(dp->sch_idx));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@@ -1731,8 +1335,6 @@ int dec_create(const OptionsContext *o, const char *arg, Scheduler *sch)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
multiview_check_manual(dp, dp->standalone_init.opts);
|
||||
|
||||
if (o->codec_names.nb_opt) {
|
||||
const char *name = o->codec_names.opt[o->codec_names.nb_opt - 1].u.str;
|
||||
dp->standalone_init.codec = avcodec_find_decoder_by_name(name);
|
||||
@@ -1745,8 +1347,7 @@ int dec_create(const OptionsContext *o, const char *arg, Scheduler *sch)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dec_filter_add(Decoder *d, InputFilter *ifilter, InputFilterOptions *opts,
|
||||
const ViewSpecifier *vs, SchedulerNode *src)
|
||||
int dec_filter_add(Decoder *d, InputFilter *ifilter, InputFilterOptions *opts)
|
||||
{
|
||||
DecoderPriv *dp = dp_from_dec(d);
|
||||
char name[16];
|
||||
@@ -1756,5 +1357,5 @@ int dec_filter_add(Decoder *d, InputFilter *ifilter, InputFilterOptions *opts,
|
||||
if (!opts->name)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
return dec_request_view(d, vs, src);
|
||||
return dp->sch_idx;
|
||||
}
|
||||
|
||||
+96
-151
@@ -28,7 +28,6 @@
|
||||
#include "libavutil/display.h"
|
||||
#include "libavutil/error.h"
|
||||
#include "libavutil/intreadwrite.h"
|
||||
#include "libavutil/mem.h"
|
||||
#include "libavutil/opt.h"
|
||||
#include "libavutil/parseutils.h"
|
||||
#include "libavutil/pixdesc.h"
|
||||
@@ -65,9 +64,6 @@ typedef struct DemuxStream {
|
||||
int streamcopy_needed;
|
||||
int have_sub2video;
|
||||
int reinit_filters;
|
||||
int autorotate;
|
||||
int apply_cropping;
|
||||
|
||||
|
||||
int wrap_correction_done;
|
||||
int saw_first_ts;
|
||||
@@ -874,8 +870,7 @@ void ifile_close(InputFile **pf)
|
||||
av_freep(pf);
|
||||
}
|
||||
|
||||
static int ist_use(InputStream *ist, int decoding_needed,
|
||||
const ViewSpecifier *vs, SchedulerNode *src)
|
||||
static int ist_use(InputStream *ist, int decoding_needed)
|
||||
{
|
||||
Demuxer *d = demuxer_from_ifile(ist->file);
|
||||
DemuxStream *ds = ds_from_ist(ist);
|
||||
@@ -913,11 +908,11 @@ static int ist_use(InputStream *ist, int decoding_needed,
|
||||
if (decoding_needed && ds->sch_idx_dec < 0) {
|
||||
int is_audio = ist->st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO;
|
||||
|
||||
ds->dec_opts.flags |= (!!ist->fix_sub_duration * DECODER_FLAG_FIX_SUB_DURATION) |
|
||||
(!!(d->f.ctx->iformat->flags & AVFMT_NOTIMESTAMPS) * DECODER_FLAG_TS_UNRELIABLE) |
|
||||
(!!(d->loop && is_audio) * DECODER_FLAG_SEND_END_TS)
|
||||
ds->dec_opts.flags = (!!ist->fix_sub_duration * DECODER_FLAG_FIX_SUB_DURATION) |
|
||||
(!!(d->f.ctx->iformat->flags & AVFMT_NOTIMESTAMPS) * DECODER_FLAG_TS_UNRELIABLE) |
|
||||
(!!(d->loop && is_audio) * DECODER_FLAG_SEND_END_TS)
|
||||
#if FFMPEG_OPT_TOP
|
||||
| ((ist->top_field_first >= 0) * DECODER_FLAG_TOP_FIELD_FIRST)
|
||||
| ((ist->top_field_first >= 0) * DECODER_FLAG_TOP_FIELD_FIRST)
|
||||
#endif
|
||||
;
|
||||
|
||||
@@ -955,33 +950,22 @@ static int ist_use(InputStream *ist, int decoding_needed,
|
||||
ds->sch_idx_dec = ret;
|
||||
|
||||
ret = sch_connect(d->sch, SCH_DSTREAM(d->f.index, ds->sch_idx_stream),
|
||||
SCH_DEC_IN(ds->sch_idx_dec));
|
||||
SCH_DEC(ds->sch_idx_dec));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
d->have_audio_dec |= is_audio;
|
||||
}
|
||||
|
||||
if (decoding_needed && ist->par->codec_type == AVMEDIA_TYPE_VIDEO) {
|
||||
ret = dec_request_view(ist->decoder, vs, src);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
} else {
|
||||
*src = decoding_needed ?
|
||||
SCH_DEC_OUT(ds->sch_idx_dec, 0) :
|
||||
SCH_DSTREAM(d->f.index, ds->sch_idx_stream);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ist_output_add(InputStream *ist, OutputStream *ost)
|
||||
{
|
||||
DemuxStream *ds = ds_from_ist(ist);
|
||||
SchedulerNode src;
|
||||
int ret;
|
||||
|
||||
ret = ist_use(ist, ost->enc ? DECODING_FOR_OST : 0, NULL, &src);
|
||||
ret = ist_use(ist, ost->enc ? DECODING_FOR_OST : 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@@ -995,16 +979,14 @@ int ist_output_add(InputStream *ist, OutputStream *ost)
|
||||
}
|
||||
|
||||
int ist_filter_add(InputStream *ist, InputFilter *ifilter, int is_simple,
|
||||
const ViewSpecifier *vs, InputFilterOptions *opts,
|
||||
SchedulerNode *src)
|
||||
InputFilterOptions *opts)
|
||||
{
|
||||
Demuxer *d = demuxer_from_ifile(ist->file);
|
||||
DemuxStream *ds = ds_from_ist(ist);
|
||||
int64_t tsoffset = 0;
|
||||
int ret;
|
||||
|
||||
ret = ist_use(ist, is_simple ? DECODING_FOR_OST : DECODING_FOR_FILTER,
|
||||
vs, src);
|
||||
ret = ist_use(ist, is_simple ? DECODING_FOR_OST : DECODING_FOR_FILTER);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
@@ -1015,23 +997,11 @@ int ist_filter_add(InputStream *ist, InputFilter *ifilter, int is_simple,
|
||||
ist->filters[ist->nb_filters - 1] = ifilter;
|
||||
|
||||
if (ist->par->codec_type == AVMEDIA_TYPE_VIDEO) {
|
||||
const AVPacketSideData *sd = av_packet_side_data_get(ist->par->coded_side_data,
|
||||
ist->par->nb_coded_side_data,
|
||||
AV_PKT_DATA_FRAME_CROPPING);
|
||||
if (ist->framerate.num > 0 && ist->framerate.den > 0) {
|
||||
opts->framerate = ist->framerate;
|
||||
opts->flags |= IFILTER_FLAG_CFR;
|
||||
} else
|
||||
opts->framerate = av_guess_frame_rate(d->f.ctx, ist->st, NULL);
|
||||
if (sd && sd->size >= sizeof(uint32_t) * 4) {
|
||||
opts->crop_top = AV_RL32(sd->data + 0);
|
||||
opts->crop_bottom = AV_RL32(sd->data + 4);
|
||||
opts->crop_left = AV_RL32(sd->data + 8);
|
||||
opts->crop_right = AV_RL32(sd->data + 12);
|
||||
if (ds->apply_cropping && ds->apply_cropping != CROP_CODEC &&
|
||||
(opts->crop_top | opts->crop_bottom | opts->crop_left | opts->crop_right))
|
||||
opts->flags |= IFILTER_FLAG_CROP;
|
||||
}
|
||||
} else if (ist->par->codec_type == AVMEDIA_TYPE_SUBTITLE) {
|
||||
/* Compute the size of the canvas for the subtitles stream.
|
||||
If the subtitles codecpar has set a size, use it. Otherwise use the
|
||||
@@ -1085,21 +1055,20 @@ int ist_filter_add(InputStream *ist, InputFilter *ifilter, int is_simple,
|
||||
if (!opts->name)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
opts->flags |= IFILTER_FLAG_AUTOROTATE * !!(ds->autorotate) |
|
||||
opts->flags |= IFILTER_FLAG_AUTOROTATE * !!(ist->autorotate) |
|
||||
IFILTER_FLAG_REINIT * !!(ds->reinit_filters);
|
||||
|
||||
return 0;
|
||||
return ds->sch_idx_dec;
|
||||
}
|
||||
|
||||
static int choose_decoder(const OptionsContext *o, void *logctx,
|
||||
AVFormatContext *s, AVStream *st,
|
||||
static int choose_decoder(const OptionsContext *o, AVFormatContext *s, AVStream *st,
|
||||
enum HWAccelID hwaccel_id, enum AVHWDeviceType hwaccel_device_type,
|
||||
const AVCodec **pcodec)
|
||||
|
||||
{
|
||||
const char *codec_name = NULL;
|
||||
char *codec_name = NULL;
|
||||
|
||||
opt_match_per_stream_str(logctx, &o->codec_names, s, st, &codec_name);
|
||||
MATCH_PER_STREAM_OPT(codec_names, str, codec_name, s, st);
|
||||
if (codec_name) {
|
||||
int ret = find_codec(NULL, codec_name, st->codecpar->codec_type, 0, pcodec);
|
||||
if (ret < 0)
|
||||
@@ -1165,9 +1134,9 @@ static int add_display_matrix_to_stream(const OptionsContext *o,
|
||||
int hflip_set = 0, vflip_set = 0, rotation_set = 0;
|
||||
int32_t *buf;
|
||||
|
||||
opt_match_per_stream_dbl(ist, &o->display_rotations, ctx, st, &rotation);
|
||||
opt_match_per_stream_int(ist, &o->display_hflips, ctx, st, &hflip);
|
||||
opt_match_per_stream_int(ist, &o->display_vflips, ctx, st, &vflip);
|
||||
MATCH_PER_STREAM_OPT(display_rotations, dbl, rotation, ctx, st);
|
||||
MATCH_PER_STREAM_OPT(display_hflips, i, hflip, ctx, st);
|
||||
MATCH_PER_STREAM_OPT(display_vflips, i, vflip, ctx, st);
|
||||
|
||||
rotation_set = rotation != DBL_MAX;
|
||||
hflip_set = hflip != -1;
|
||||
@@ -1235,20 +1204,19 @@ static DemuxStream *demux_stream_alloc(Demuxer *d, AVStream *st)
|
||||
return ds;
|
||||
}
|
||||
|
||||
static int ist_add(const OptionsContext *o, Demuxer *d, AVStream *st, AVDictionary **opts_used)
|
||||
static int ist_add(const OptionsContext *o, Demuxer *d, AVStream *st)
|
||||
{
|
||||
AVFormatContext *ic = d->f.ctx;
|
||||
AVCodecParameters *par = st->codecpar;
|
||||
DemuxStream *ds;
|
||||
InputStream *ist;
|
||||
const char *framerate = NULL, *hwaccel_device = NULL;
|
||||
char *framerate = NULL, *hwaccel_device = NULL;
|
||||
const char *hwaccel = NULL;
|
||||
const char *apply_cropping = NULL;
|
||||
const char *hwaccel_output_format = NULL;
|
||||
const char *codec_tag = NULL;
|
||||
const char *bsfs = NULL;
|
||||
char *hwaccel_output_format = NULL;
|
||||
char *codec_tag = NULL;
|
||||
char *bsfs = NULL;
|
||||
char *next;
|
||||
const char *discard_str = NULL;
|
||||
char *discard_str = NULL;
|
||||
int ret;
|
||||
|
||||
ds = demux_stream_alloc(d, st);
|
||||
@@ -1265,39 +1233,12 @@ static int ist_add(const OptionsContext *o, Demuxer *d, AVStream *st, AVDictiona
|
||||
ds->dec_opts.time_base = st->time_base;
|
||||
|
||||
ds->ts_scale = 1.0;
|
||||
opt_match_per_stream_dbl(ist, &o->ts_scale, ic, st, &ds->ts_scale);
|
||||
MATCH_PER_STREAM_OPT(ts_scale, dbl, ds->ts_scale, ic, st);
|
||||
|
||||
ds->autorotate = 1;
|
||||
opt_match_per_stream_int(ist, &o->autorotate, ic, st, &ds->autorotate);
|
||||
ist->autorotate = 1;
|
||||
MATCH_PER_STREAM_OPT(autorotate, i, ist->autorotate, ic, st);
|
||||
|
||||
ds->apply_cropping = CROP_ALL;
|
||||
opt_match_per_stream_str(ist, &o->apply_cropping, ic, st, &apply_cropping);
|
||||
if (apply_cropping) {
|
||||
const AVOption opts[] = {
|
||||
{ "apply_cropping", NULL, 0, AV_OPT_TYPE_INT,
|
||||
{ .i64 = CROP_ALL }, CROP_DISABLED, CROP_CONTAINER, AV_OPT_FLAG_DECODING_PARAM, .unit = "apply_cropping" },
|
||||
{ "none", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CROP_DISABLED }, .unit = "apply_cropping" },
|
||||
{ "all", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CROP_ALL }, .unit = "apply_cropping" },
|
||||
{ "codec", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CROP_CODEC }, .unit = "apply_cropping" },
|
||||
{ "container", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = CROP_CONTAINER }, .unit = "apply_cropping" },
|
||||
{ NULL },
|
||||
};
|
||||
const AVClass class = {
|
||||
.class_name = "apply_cropping",
|
||||
.item_name = av_default_item_name,
|
||||
.option = opts,
|
||||
.version = LIBAVUTIL_VERSION_INT,
|
||||
};
|
||||
const AVClass *pclass = &class;
|
||||
|
||||
ret = av_opt_eval_int(&pclass, opts, apply_cropping, &ds->apply_cropping);
|
||||
if (ret < 0) {
|
||||
av_log(ist, AV_LOG_ERROR, "Invalid apply_cropping value '%s'.\n", apply_cropping);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
opt_match_per_stream_str(ist, &o->codec_tags, ic, st, &codec_tag);
|
||||
MATCH_PER_STREAM_OPT(codec_tags, str, codec_tag, ic, st);
|
||||
if (codec_tag) {
|
||||
uint32_t tag = strtol(codec_tag, &next, 0);
|
||||
if (*next) {
|
||||
@@ -1314,9 +1255,10 @@ static int ist_add(const OptionsContext *o, Demuxer *d, AVStream *st, AVDictiona
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
opt_match_per_stream_str(ist, &o->hwaccels, ic, st, &hwaccel);
|
||||
opt_match_per_stream_str(ist, &o->hwaccel_output_formats, ic, st,
|
||||
&hwaccel_output_format);
|
||||
MATCH_PER_STREAM_OPT(hwaccels, str, hwaccel, ic, st);
|
||||
MATCH_PER_STREAM_OPT(hwaccel_output_formats, str,
|
||||
hwaccel_output_format, ic, st);
|
||||
|
||||
if (!hwaccel_output_format && hwaccel && !strcmp(hwaccel, "cuvid")) {
|
||||
av_log(ist, AV_LOG_WARNING,
|
||||
"WARNING: defaulting hwaccel_output_format to cuda for compatibility "
|
||||
@@ -1374,7 +1316,7 @@ static int ist_add(const OptionsContext *o, Demuxer *d, AVStream *st, AVDictiona
|
||||
}
|
||||
}
|
||||
|
||||
opt_match_per_stream_str(ist, &o->hwaccel_devices, ic, st, &hwaccel_device);
|
||||
MATCH_PER_STREAM_OPT(hwaccel_devices, str, hwaccel_device, ic, st);
|
||||
if (hwaccel_device) {
|
||||
ds->dec_opts.hwaccel_device = av_strdup(hwaccel_device);
|
||||
if (!ds->dec_opts.hwaccel_device)
|
||||
@@ -1382,20 +1324,18 @@ static int ist_add(const OptionsContext *o, Demuxer *d, AVStream *st, AVDictiona
|
||||
}
|
||||
}
|
||||
|
||||
ret = choose_decoder(o, ist, ic, st, ds->dec_opts.hwaccel_id,
|
||||
ret = choose_decoder(o, ic, st, ds->dec_opts.hwaccel_id,
|
||||
ds->dec_opts.hwaccel_device_type, &ist->dec);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (ist->dec) {
|
||||
ret = filter_codec_opts(o->g->codec_opts, ist->st->codecpar->codec_id,
|
||||
ic, st, ist->dec, &ds->decoder_opts, opts_used);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
ret = filter_codec_opts(o->g->codec_opts, ist->st->codecpar->codec_id,
|
||||
ic, st, ist->dec, &ds->decoder_opts);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ds->reinit_filters = -1;
|
||||
opt_match_per_stream_int(ist, &o->reinit_filters, ic, st, &ds->reinit_filters);
|
||||
MATCH_PER_STREAM_OPT(reinit_filters, i, ds->reinit_filters, ic, st);
|
||||
|
||||
ist->user_set_discard = AVDISCARD_NONE;
|
||||
|
||||
@@ -1405,7 +1345,7 @@ static int ist_add(const OptionsContext *o, Demuxer *d, AVStream *st, AVDictiona
|
||||
(o->data_disable && ist->st->codecpar->codec_type == AVMEDIA_TYPE_DATA))
|
||||
ist->user_set_discard = AVDISCARD_ALL;
|
||||
|
||||
opt_match_per_stream_str(ist, &o->discard, ic, st, &discard_str);
|
||||
MATCH_PER_STREAM_OPT(discard, str, discard_str, ic, st);
|
||||
if (discard_str) {
|
||||
ret = av_opt_set(ist->st, "discard", discard_str, 0);
|
||||
if (ret < 0) {
|
||||
@@ -1415,10 +1355,8 @@ static int ist_add(const OptionsContext *o, Demuxer *d, AVStream *st, AVDictiona
|
||||
ist->user_set_discard = ist->st->discard;
|
||||
}
|
||||
|
||||
ds->dec_opts.flags |= DECODER_FLAG_BITEXACT * !!o->bitexact;
|
||||
|
||||
av_dict_set_int(&ds->decoder_opts, "apply_cropping",
|
||||
ds->apply_cropping && ds->apply_cropping != CROP_CONTAINER, 0);
|
||||
if (o->bitexact)
|
||||
av_dict_set(&ds->decoder_opts, "flags", "+bitexact", AV_DICT_MULTIKEY);
|
||||
|
||||
/* Attached pics are sparse, therefore we would not want to delay their decoding
|
||||
* till EOF. */
|
||||
@@ -1427,7 +1365,7 @@ static int ist_add(const OptionsContext *o, Demuxer *d, AVStream *st, AVDictiona
|
||||
|
||||
switch (par->codec_type) {
|
||||
case AVMEDIA_TYPE_VIDEO:
|
||||
opt_match_per_stream_str(ist, &o->frame_rates, ic, st, &framerate);
|
||||
MATCH_PER_STREAM_OPT(frame_rates, str, framerate, ic, st);
|
||||
if (framerate) {
|
||||
ret = av_parse_video_rate(&ist->framerate, framerate);
|
||||
if (ret < 0) {
|
||||
@@ -1439,44 +1377,21 @@ static int ist_add(const OptionsContext *o, Demuxer *d, AVStream *st, AVDictiona
|
||||
|
||||
#if FFMPEG_OPT_TOP
|
||||
ist->top_field_first = -1;
|
||||
opt_match_per_stream_int(ist, &o->top_field_first, ic, st, &ist->top_field_first);
|
||||
MATCH_PER_STREAM_OPT(top_field_first, i, ist->top_field_first, ic, st);
|
||||
#endif
|
||||
|
||||
break;
|
||||
case AVMEDIA_TYPE_AUDIO: {
|
||||
const char *ch_layout_str = NULL;
|
||||
|
||||
opt_match_per_stream_str(ist, &o->audio_ch_layouts, ic, st, &ch_layout_str);
|
||||
if (ch_layout_str) {
|
||||
AVChannelLayout ch_layout;
|
||||
ret = av_channel_layout_from_string(&ch_layout, ch_layout_str);
|
||||
if (ret < 0) {
|
||||
av_log(ist, AV_LOG_ERROR, "Error parsing channel layout %s.\n", ch_layout_str);
|
||||
return ret;
|
||||
}
|
||||
if (par->ch_layout.nb_channels <= 0 || par->ch_layout.nb_channels == ch_layout.nb_channels) {
|
||||
av_channel_layout_uninit(&par->ch_layout);
|
||||
par->ch_layout = ch_layout;
|
||||
} else {
|
||||
av_log(ist, AV_LOG_ERROR,
|
||||
"Specified channel layout '%s' has %d channels, but input has %d channels.\n",
|
||||
ch_layout_str, ch_layout.nb_channels, par->ch_layout.nb_channels);
|
||||
av_channel_layout_uninit(&ch_layout);
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
} else {
|
||||
int guess_layout_max = INT_MAX;
|
||||
opt_match_per_stream_int(ist, &o->guess_layout_max, ic, st, &guess_layout_max);
|
||||
guess_input_channel_layout(ist, par, guess_layout_max);
|
||||
}
|
||||
int guess_layout_max = INT_MAX;
|
||||
MATCH_PER_STREAM_OPT(guess_layout_max, i, guess_layout_max, ic, st);
|
||||
guess_input_channel_layout(ist, par, guess_layout_max);
|
||||
break;
|
||||
}
|
||||
case AVMEDIA_TYPE_DATA:
|
||||
case AVMEDIA_TYPE_SUBTITLE: {
|
||||
const char *canvas_size = NULL;
|
||||
|
||||
opt_match_per_stream_int(ist, &o->fix_sub_duration, ic, st, &ist->fix_sub_duration);
|
||||
opt_match_per_stream_str(ist, &o->canvas_sizes, ic, st, &canvas_size);
|
||||
char *canvas_size = NULL;
|
||||
MATCH_PER_STREAM_OPT(fix_sub_duration, i, ist->fix_sub_duration, ic, st);
|
||||
MATCH_PER_STREAM_OPT(canvas_sizes, str, canvas_size, ic, st);
|
||||
if (canvas_size) {
|
||||
ret = av_parse_video_size(&par->width, &par->height,
|
||||
canvas_size);
|
||||
@@ -1506,7 +1421,7 @@ static int ist_add(const OptionsContext *o, Demuxer *d, AVStream *st, AVDictiona
|
||||
if (ist->st->sample_aspect_ratio.num)
|
||||
ist->par->sample_aspect_ratio = ist->st->sample_aspect_ratio;
|
||||
|
||||
opt_match_per_stream_str(ist, &o->bitstream_filters, ic, st, &bsfs);
|
||||
MATCH_PER_STREAM_OPT(bitstream_filters, str, bsfs, ic, st);
|
||||
if (bsfs) {
|
||||
ret = av_bsf_list_parse_str(bsfs, &ds->bsf);
|
||||
if (ret < 0) {
|
||||
@@ -1611,9 +1526,10 @@ int ifile_open(const OptionsContext *o, const char *filename, Scheduler *sch)
|
||||
InputFile *f;
|
||||
AVFormatContext *ic;
|
||||
const AVInputFormat *file_iformat = NULL;
|
||||
int err, ret = 0;
|
||||
int err, i, ret = 0;
|
||||
int64_t timestamp;
|
||||
AVDictionary *opts_used = NULL;
|
||||
AVDictionary *unused_opts = NULL;
|
||||
const AVDictionaryEntry *e = NULL;
|
||||
const char* video_codec_name = NULL;
|
||||
const char* audio_codec_name = NULL;
|
||||
const char* subtitle_codec_name = NULL;
|
||||
@@ -1766,9 +1682,9 @@ int ifile_open(const OptionsContext *o, const char *filename, Scheduler *sch)
|
||||
return ret;
|
||||
|
||||
/* apply forced codec ids */
|
||||
for (int i = 0; i < ic->nb_streams; i++) {
|
||||
for (i = 0; i < ic->nb_streams; i++) {
|
||||
const AVCodec *dummy;
|
||||
ret = choose_decoder(o, f, ic, ic->streams[i], HWACCEL_NONE, AV_HWDEVICE_TYPE_NONE,
|
||||
ret = choose_decoder(o, ic, ic->streams[i], HWACCEL_NONE, AV_HWDEVICE_TYPE_NONE,
|
||||
&dummy);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
@@ -1786,7 +1702,7 @@ int ifile_open(const OptionsContext *o, const char *filename, Scheduler *sch)
|
||||
first frames to get it. (used in mpeg case for example) */
|
||||
ret = avformat_find_stream_info(ic, opts);
|
||||
|
||||
for (int i = 0; i < orig_nb_streams; i++)
|
||||
for (i = 0; i < orig_nb_streams; i++)
|
||||
av_dict_free(&opts[i]);
|
||||
av_freep(&opts);
|
||||
|
||||
@@ -1827,7 +1743,7 @@ int ifile_open(const OptionsContext *o, const char *filename, Scheduler *sch)
|
||||
|
||||
if (!(ic->iformat->flags & AVFMT_SEEK_TO_PTS)) {
|
||||
int dts_heuristic = 0;
|
||||
for (int i = 0; i < ic->nb_streams; i++) {
|
||||
for (i=0; i<ic->nb_streams; i++) {
|
||||
const AVCodecParameters *par = ic->streams[i]->codecpar;
|
||||
if (par->video_delay) {
|
||||
dts_heuristic = 1;
|
||||
@@ -1885,24 +1801,53 @@ int ifile_open(const OptionsContext *o, const char *filename, Scheduler *sch)
|
||||
|
||||
/* Add all the streams from the given input file to the demuxer */
|
||||
for (int i = 0; i < ic->nb_streams; i++) {
|
||||
ret = ist_add(o, d, ic->streams[i], &opts_used);
|
||||
if (ret < 0) {
|
||||
av_dict_free(&opts_used);
|
||||
ret = ist_add(o, d, ic->streams[i]);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* dump the file content */
|
||||
av_dump_format(ic, f->index, filename, 0);
|
||||
|
||||
/* check if all codec options have been used */
|
||||
ret = check_avoptions_used(o->g->codec_opts, opts_used, d, 1);
|
||||
av_dict_free(&opts_used);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
unused_opts = strip_specifiers(o->g->codec_opts);
|
||||
for (i = 0; i < f->nb_streams; i++) {
|
||||
DemuxStream *ds = ds_from_ist(f->streams[i]);
|
||||
e = NULL;
|
||||
while ((e = av_dict_iterate(ds->decoder_opts, e)))
|
||||
av_dict_set(&unused_opts, e->key, NULL, 0);
|
||||
}
|
||||
|
||||
for (int i = 0; i < o->dump_attachment.nb_opt; i++) {
|
||||
for (int j = 0; j < f->nb_streams; j++) {
|
||||
e = NULL;
|
||||
while ((e = av_dict_iterate(unused_opts, e))) {
|
||||
const AVClass *class = avcodec_get_class();
|
||||
const AVOption *option = av_opt_find(&class, e->key, NULL, 0,
|
||||
AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
|
||||
const AVClass *fclass = avformat_get_class();
|
||||
const AVOption *foption = av_opt_find(&fclass, e->key, NULL, 0,
|
||||
AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ);
|
||||
if (!option || foption)
|
||||
continue;
|
||||
|
||||
|
||||
if (!(option->flags & AV_OPT_FLAG_DECODING_PARAM)) {
|
||||
av_log(d, AV_LOG_ERROR, "Codec AVOption %s (%s) is not a decoding "
|
||||
"option.\n", e->key, option->help ? option->help : "");
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
av_log(d, AV_LOG_WARNING, "Codec AVOption %s (%s) has not been used "
|
||||
"for any stream. The most likely reason is either wrong type "
|
||||
"(e.g. a video option with no video streams) or that it is a "
|
||||
"private option of some decoder which was not actually used "
|
||||
"for any stream.\n", e->key, option->help ? option->help : "");
|
||||
}
|
||||
av_dict_free(&unused_opts);
|
||||
|
||||
for (i = 0; i < o->dump_attachment.nb_opt; i++) {
|
||||
int j;
|
||||
|
||||
for (j = 0; j < f->nb_streams; j++) {
|
||||
InputStream *ist = f->streams[j];
|
||||
|
||||
if (check_stream_specifier(ic, ist->st, o->dump_attachment.opt[i].specifier) == 1) {
|
||||
|
||||
+62
-22
@@ -20,6 +20,8 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "ffmpeg.h"
|
||||
#include "ffmpeg_utils.h"
|
||||
#include "thread_queue.h"
|
||||
|
||||
#include "libavutil/avassert.h"
|
||||
#include "libavutil/avstring.h"
|
||||
@@ -30,7 +32,6 @@
|
||||
#include "libavutil/frame.h"
|
||||
#include "libavutil/intreadwrite.h"
|
||||
#include "libavutil/log.h"
|
||||
#include "libavutil/mem.h"
|
||||
#include "libavutil/pixdesc.h"
|
||||
#include "libavutil/rational.h"
|
||||
#include "libavutil/time.h"
|
||||
@@ -38,6 +39,8 @@
|
||||
|
||||
#include "libavcodec/avcodec.h"
|
||||
|
||||
#include "libavformat/avformat.h"
|
||||
|
||||
struct Encoder {
|
||||
// combined size of all the packets received from the encoder
|
||||
uint64_t data_size;
|
||||
@@ -168,7 +171,7 @@ int enc_open(void *opaque, const AVFrame *frame)
|
||||
InputStream *ist = ost->ist;
|
||||
Encoder *e = ost->enc;
|
||||
AVCodecContext *enc_ctx = ost->enc_ctx;
|
||||
Decoder *dec = NULL;
|
||||
Decoder *dec;
|
||||
const AVCodec *enc = enc_ctx->codec;
|
||||
OutputFile *of = ost->file;
|
||||
FrameData *fd;
|
||||
@@ -184,20 +187,6 @@ int enc_open(void *opaque, const AVFrame *frame)
|
||||
if (frame) {
|
||||
av_assert0(frame->opaque_ref);
|
||||
fd = (FrameData*)frame->opaque_ref->data;
|
||||
|
||||
for (int i = 0; i < frame->nb_side_data; i++) {
|
||||
const AVSideDataDescriptor *desc = av_frame_side_data_desc(frame->side_data[i]->type);
|
||||
|
||||
if (!(desc->props & AV_SIDE_DATA_PROP_GLOBAL))
|
||||
continue;
|
||||
|
||||
ret = av_frame_side_data_clone(&enc_ctx->decoded_side_data,
|
||||
&enc_ctx->nb_decoded_side_data,
|
||||
frame->side_data[i],
|
||||
AV_FRAME_SIDE_DATA_FLAG_UNIQUE);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
ret = set_encoder_id(of, ost);
|
||||
@@ -257,6 +246,21 @@ int enc_open(void *opaque, const AVFrame *frame)
|
||||
enc_ctx->colorspace = frame->colorspace;
|
||||
enc_ctx->chroma_sample_location = frame->chroma_location;
|
||||
|
||||
for (int i = 0; i < frame->nb_side_data; i++) {
|
||||
ret = av_frame_side_data_clone(
|
||||
&enc_ctx->decoded_side_data, &enc_ctx->nb_decoded_side_data,
|
||||
frame->side_data[i], AV_FRAME_SIDE_DATA_FLAG_UNIQUE);
|
||||
if (ret < 0) {
|
||||
av_frame_side_data_free(
|
||||
&enc_ctx->decoded_side_data,
|
||||
&enc_ctx->nb_decoded_side_data);
|
||||
av_log(NULL, AV_LOG_ERROR,
|
||||
"failed to configure video encoder: %s!\n",
|
||||
av_err2str(ret));
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (enc_ctx->flags & (AV_CODEC_FLAG_INTERLACED_DCT | AV_CODEC_FLAG_INTERLACED_ME) ||
|
||||
(frame->flags & AV_FRAME_FLAG_INTERLACED)
|
||||
#if FFMPEG_OPT_TOP
|
||||
@@ -280,6 +284,9 @@ int enc_open(void *opaque, const AVFrame *frame)
|
||||
break;
|
||||
}
|
||||
case AVMEDIA_TYPE_SUBTITLE:
|
||||
if (ost->enc_timebase.num)
|
||||
av_log(ost, AV_LOG_WARNING,
|
||||
"-enc_time_base not supported for subtitles, ignoring\n");
|
||||
enc_ctx->time_base = AV_TIME_BASE_Q;
|
||||
|
||||
if (!enc_ctx->width) {
|
||||
@@ -307,10 +314,16 @@ int enc_open(void *opaque, const AVFrame *frame)
|
||||
if (ost->bitexact)
|
||||
enc_ctx->flags |= AV_CODEC_FLAG_BITEXACT;
|
||||
|
||||
if (enc->capabilities & AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE)
|
||||
enc_ctx->flags |= AV_CODEC_FLAG_COPY_OPAQUE;
|
||||
if (!av_dict_get(ost->encoder_opts, "threads", NULL, 0))
|
||||
av_dict_set(&ost->encoder_opts, "threads", "auto", 0);
|
||||
|
||||
enc_ctx->flags |= AV_CODEC_FLAG_FRAME_DURATION;
|
||||
if (enc->capabilities & AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE) {
|
||||
ret = av_dict_set(&ost->encoder_opts, "flags", "+copy_opaque", AV_DICT_MULTIKEY);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
av_dict_set(&ost->encoder_opts, "flags", "+frame_duration", AV_DICT_MULTIKEY);
|
||||
|
||||
ret = hw_device_setup_for_encode(ost, frame ? frame->hw_frames_ctx : NULL);
|
||||
if (ret < 0) {
|
||||
@@ -319,7 +332,7 @@ int enc_open(void *opaque, const AVFrame *frame)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((ret = avcodec_open2(ost->enc_ctx, enc, NULL)) < 0) {
|
||||
if ((ret = avcodec_open2(ost->enc_ctx, enc, &ost->encoder_opts)) < 0) {
|
||||
if (ret != AVERROR_EXPERIMENTAL)
|
||||
av_log(ost, AV_LOG_ERROR, "Error while opening encoder - maybe "
|
||||
"incorrect parameters such as bit_rate, rate, width or height.\n");
|
||||
@@ -331,6 +344,10 @@ int enc_open(void *opaque, const AVFrame *frame)
|
||||
if (ost->enc_ctx->frame_size)
|
||||
frame_samples = ost->enc_ctx->frame_size;
|
||||
|
||||
ret = check_avoptions(ost->encoder_opts);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (ost->enc_ctx->bit_rate && ost->enc_ctx->bit_rate < 1000 &&
|
||||
ost->enc_ctx->codec_id != AV_CODEC_ID_CODEC2 /* don't complain about 700 bit/s modes */)
|
||||
av_log(ost, AV_LOG_WARNING, "The bitrate parameter is set too low."
|
||||
@@ -343,6 +360,29 @@ int enc_open(void *opaque, const AVFrame *frame)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add global input side data. For now this is naive, and copies it
|
||||
* from the input stream's global side data. All side data should
|
||||
* really be funneled over AVFrame and libavfilter, then added back to
|
||||
* packet side data, and then potentially using the first packet for
|
||||
* global side data.
|
||||
*/
|
||||
if (ist) {
|
||||
for (int i = 0; i < ist->st->codecpar->nb_coded_side_data; i++) {
|
||||
AVPacketSideData *sd_src = &ist->st->codecpar->coded_side_data[i];
|
||||
if (sd_src->type != AV_PKT_DATA_CPB_PROPERTIES) {
|
||||
AVPacketSideData *sd_dst = av_packet_side_data_new(&ost->par_in->coded_side_data,
|
||||
&ost->par_in->nb_coded_side_data,
|
||||
sd_src->type, sd_src->size, 0);
|
||||
if (!sd_dst)
|
||||
return AVERROR(ENOMEM);
|
||||
memcpy(sd_dst->data, sd_src->data, sd_src->size);
|
||||
if (ist->autorotate && sd_src->type == AV_PKT_DATA_DISPLAYMATRIX)
|
||||
av_display_rotation_set((int32_t *)sd_dst->data, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// copy timebase while removing common factors
|
||||
if (ost->st->time_base.num <= 0 || ost->st->time_base.den <= 0)
|
||||
ost->st->time_base = av_add_q(ost->enc_ctx->time_base, (AVRational){0, 1});
|
||||
@@ -464,9 +504,9 @@ void enc_stats_write(OutputStream *ost, EncStats *es,
|
||||
AVRational tbi = (AVRational){ 0, 1};
|
||||
int64_t ptsi = INT64_MAX;
|
||||
|
||||
const FrameData *fd = NULL;
|
||||
const FrameData *fd;
|
||||
|
||||
if (frame ? frame->opaque_ref : pkt->opaque_ref) {
|
||||
if ((frame && frame->opaque_ref) || (pkt && pkt->opaque_ref)) {
|
||||
fd = (const FrameData*)(frame ? frame->opaque_ref->data : pkt->opaque_ref->data);
|
||||
tbi = fd->dec.tb;
|
||||
ptsi = fd->dec.pts;
|
||||
|
||||
+219
-410
File diff suppressed because it is too large
Load Diff
+3
-1
@@ -18,7 +18,9 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "libavutil/mem.h"
|
||||
#include "libavutil/avstring.h"
|
||||
#include "libavutil/pixdesc.h"
|
||||
#include "libavfilter/buffersink.h"
|
||||
|
||||
#include "ffmpeg.h"
|
||||
|
||||
|
||||
+14
-13
@@ -140,7 +140,7 @@ static int mux_fixup_ts(Muxer *mux, MuxStream *ms, AVPacket *pkt)
|
||||
OutputStream *ost = &ms->ost;
|
||||
|
||||
#if FFMPEG_OPT_VSYNC_DROP
|
||||
if (ost->type == AVMEDIA_TYPE_VIDEO && ms->ts_drop)
|
||||
if (ost->type == AVMEDIA_TYPE_VIDEO && ost->vsync_method == VSYNC_DROP)
|
||||
pkt->pts = pkt->dts = AV_NOPTS_VALUE;
|
||||
#endif
|
||||
|
||||
@@ -290,7 +290,7 @@ static int mux_packet_filter(Muxer *mux, MuxThreadContext *mt,
|
||||
{
|
||||
MuxStream *ms = ms_from_ost(ost);
|
||||
const char *err_msg;
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
if (pkt && !ost->enc) {
|
||||
ret = of_streamcopy(&mux->of, ost, pkt);
|
||||
@@ -299,6 +299,7 @@ static int mux_packet_filter(Muxer *mux, MuxThreadContext *mt,
|
||||
else if (ret == AVERROR_EOF) {
|
||||
av_packet_unref(pkt);
|
||||
pkt = NULL;
|
||||
ret = 0;
|
||||
*stream_eof = 1;
|
||||
} else if (ret < 0)
|
||||
goto fail;
|
||||
@@ -369,11 +370,10 @@ fail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void thread_set_name(Muxer *mux)
|
||||
static void thread_set_name(OutputFile *of)
|
||||
{
|
||||
char name[16];
|
||||
snprintf(name, sizeof(name), "mux%d:%s",
|
||||
mux->of.index, mux->fc->oformat->name);
|
||||
snprintf(name, sizeof(name), "mux%d:%s", of->index, of->format->name);
|
||||
ff_thread_setname(name);
|
||||
}
|
||||
|
||||
@@ -417,7 +417,7 @@ int muxer_thread(void *arg)
|
||||
if (ret < 0)
|
||||
goto finish;
|
||||
|
||||
thread_set_name(mux);
|
||||
thread_set_name(of);
|
||||
|
||||
while (1) {
|
||||
OutputStream *ost;
|
||||
@@ -515,10 +515,8 @@ int print_sdp(const char *filename)
|
||||
if (!avc)
|
||||
return AVERROR(ENOMEM);
|
||||
for (int i = 0; i < nb_output_files; i++) {
|
||||
Muxer *mux = mux_from_of(output_files[i]);
|
||||
|
||||
if (!strcmp(mux->fc->oformat->name, "rtp")) {
|
||||
avc[j] = mux->fc;
|
||||
if (!strcmp(output_files[i]->format->name, "rtp")) {
|
||||
avc[j] = mux_from_of(output_files[i])->fc;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
@@ -758,7 +756,7 @@ int of_write_trailer(OutputFile *of)
|
||||
|
||||
mux->last_filesize = filesize(fc->pb);
|
||||
|
||||
if (!(fc->oformat->flags & AVFMT_NOFILE)) {
|
||||
if (!(of->format->flags & AVFMT_NOFILE)) {
|
||||
ret = avio_closep(&fc->pb);
|
||||
if (ret < 0) {
|
||||
av_log(mux, AV_LOG_ERROR, "Error closing file: %s\n", av_err2str(ret));
|
||||
@@ -796,7 +794,6 @@ static void ost_free(OutputStream **post)
|
||||
ms = ms_from_ost(ost);
|
||||
|
||||
enc_free(&ost->enc);
|
||||
fg_free(&ost->fg_simple);
|
||||
|
||||
if (ost->logfile) {
|
||||
if (fclose(ost->logfile))
|
||||
@@ -812,14 +809,19 @@ static void ost_free(OutputStream **post)
|
||||
av_packet_free(&ms->bsf_pkt);
|
||||
|
||||
av_packet_free(&ms->pkt);
|
||||
av_dict_free(&ost->encoder_opts);
|
||||
|
||||
av_freep(&ost->kf.pts);
|
||||
av_expr_free(ost->kf.pexpr);
|
||||
|
||||
av_freep(&ost->logfile_prefix);
|
||||
av_freep(&ost->apad);
|
||||
|
||||
av_freep(&ost->attachment_filename);
|
||||
|
||||
av_dict_free(&ost->sws_dict);
|
||||
av_dict_free(&ost->swr_opts);
|
||||
|
||||
if (ost->enc_ctx)
|
||||
av_freep(&ost->enc_ctx->stats_in);
|
||||
avcodec_free_context(&ost->enc_ctx);
|
||||
@@ -863,7 +865,6 @@ void of_free(OutputFile **pof)
|
||||
av_freep(&mux->sch_stream_idx);
|
||||
|
||||
av_dict_free(&mux->opts);
|
||||
av_dict_free(&mux->enc_opts_used);
|
||||
|
||||
av_packet_free(&mux->sq_pkt);
|
||||
|
||||
|
||||
@@ -75,11 +75,6 @@ typedef struct MuxStream {
|
||||
int copy_initial_nonkeyframes;
|
||||
int copy_prior_start;
|
||||
int streamcopy_started;
|
||||
#if FFMPEG_OPT_VSYNC_DROP
|
||||
int ts_drop;
|
||||
#endif
|
||||
|
||||
const char *apad;
|
||||
} MuxStream;
|
||||
|
||||
typedef struct Muxer {
|
||||
@@ -99,9 +94,6 @@ typedef struct Muxer {
|
||||
|
||||
AVDictionary *opts;
|
||||
|
||||
// used to validate that all encoder avoptions have been actually used
|
||||
AVDictionary *enc_opts_used;
|
||||
|
||||
/* filesize limit expressed in bytes */
|
||||
int64_t limit_filesize;
|
||||
atomic_int_least64_t last_filesize;
|
||||
|
||||
+246
-534
File diff suppressed because it is too large
Load Diff
+59
-181
@@ -31,6 +31,7 @@
|
||||
#include "ffmpeg_sched.h"
|
||||
#include "cmdutils.h"
|
||||
#include "opt_common.h"
|
||||
#include "sync_queue.h"
|
||||
|
||||
#include "libavformat/avformat.h"
|
||||
|
||||
@@ -42,11 +43,16 @@
|
||||
#include "libavutil/avassert.h"
|
||||
#include "libavutil/avstring.h"
|
||||
#include "libavutil/avutil.h"
|
||||
#include "libavutil/bprint.h"
|
||||
#include "libavutil/channel_layout.h"
|
||||
#include "libavutil/display.h"
|
||||
#include "libavutil/intreadwrite.h"
|
||||
#include "libavutil/fifo.h"
|
||||
#include "libavutil/mathematics.h"
|
||||
#include "libavutil/mem.h"
|
||||
#include "libavutil/opt.h"
|
||||
#include "libavutil/parseutils.h"
|
||||
#include "libavutil/stereo3d.h"
|
||||
#include "libavutil/pixdesc.h"
|
||||
#include "libavutil/pixfmt.h"
|
||||
|
||||
HWDevice *filter_hw_device;
|
||||
|
||||
@@ -88,6 +94,8 @@ int recast_media = 0;
|
||||
|
||||
static void uninit_options(OptionsContext *o)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* all OPT_SPEC and OPT_TYPE_STRING can be freed in generic way */
|
||||
for (const OptionDef *po = options; po->name; po++) {
|
||||
void *dst;
|
||||
@@ -100,8 +108,6 @@ static void uninit_options(OptionsContext *o)
|
||||
SpecifierOptList *so = dst;
|
||||
for (int i = 0; i < so->nb_opt; i++) {
|
||||
av_freep(&so->opt[i].specifier);
|
||||
if (po->flags & OPT_FLAG_PERSTREAM)
|
||||
stream_specifier_uninit(&so->opt[i].stream_spec);
|
||||
if (po->type == OPT_TYPE_STRING)
|
||||
av_freep(&so->opt[i].u.str);
|
||||
}
|
||||
@@ -111,11 +117,11 @@ static void uninit_options(OptionsContext *o)
|
||||
av_freep(dst);
|
||||
}
|
||||
|
||||
for (int i = 0; i < o->nb_stream_maps; i++)
|
||||
for (i = 0; i < o->nb_stream_maps; i++)
|
||||
av_freep(&o->stream_maps[i].linklabel);
|
||||
av_freep(&o->stream_maps);
|
||||
|
||||
for (int i = 0; i < o->nb_attachments; i++)
|
||||
for (i = 0; i < o->nb_attachments; i++)
|
||||
av_freep(&o->attachments[i]);
|
||||
av_freep(&o->attachments);
|
||||
|
||||
@@ -152,6 +158,24 @@ static int show_hwaccels(void *optctx, const char *opt, const char *arg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* return a copy of the input with the stream specifiers removed from the keys */
|
||||
AVDictionary *strip_specifiers(const AVDictionary *dict)
|
||||
{
|
||||
const AVDictionaryEntry *e = NULL;
|
||||
AVDictionary *ret = NULL;
|
||||
|
||||
while ((e = av_dict_iterate(dict, e))) {
|
||||
char *p = strchr(e->key, ':');
|
||||
|
||||
if (p)
|
||||
*p = 0;
|
||||
av_dict_set(&ret, e->key, e->value, 0);
|
||||
if (p)
|
||||
*p = ':';
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
const char *opt_match_per_type_str(const SpecifierOptList *sol,
|
||||
char mediatype)
|
||||
{
|
||||
@@ -165,123 +189,6 @@ const char *opt_match_per_type_str(const SpecifierOptList *sol,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static unsigned opt_match_per_stream(void *logctx, enum OptionType type,
|
||||
const SpecifierOptList *sol,
|
||||
AVFormatContext *fc, AVStream *st)
|
||||
{
|
||||
int matches = 0, match_idx = -1;
|
||||
|
||||
av_assert0((type == sol->type) || !sol->nb_opt);
|
||||
|
||||
for (int i = 0; i < sol->nb_opt; i++) {
|
||||
const StreamSpecifier *ss = &sol->opt[i].stream_spec;
|
||||
|
||||
if (stream_specifier_match(ss, fc, st, logctx)) {
|
||||
match_idx = i;
|
||||
matches++;
|
||||
}
|
||||
}
|
||||
|
||||
if (matches > 1 && sol->opt_canon) {
|
||||
const SpecifierOpt *so = &sol->opt[match_idx];
|
||||
const char *spec = so->specifier && so->specifier[0] ? so->specifier : "";
|
||||
|
||||
char namestr[128] = "";
|
||||
char optval_buf[32];
|
||||
const char *optval = optval_buf;
|
||||
|
||||
snprintf(namestr, sizeof(namestr), "-%s", sol->opt_canon->name);
|
||||
if (sol->opt_canon->flags & OPT_HAS_ALT) {
|
||||
const char * const *names_alt = sol->opt_canon->u1.names_alt;
|
||||
for (int i = 0; names_alt[i]; i++)
|
||||
av_strlcatf(namestr, sizeof(namestr), "/-%s", names_alt[i]);
|
||||
}
|
||||
|
||||
switch (sol->type) {
|
||||
case OPT_TYPE_STRING: optval = so->u.str; break;
|
||||
case OPT_TYPE_INT: snprintf(optval_buf, sizeof(optval_buf), "%d", so->u.i); break;
|
||||
case OPT_TYPE_INT64: snprintf(optval_buf, sizeof(optval_buf), "%"PRId64, so->u.i64); break;
|
||||
case OPT_TYPE_FLOAT: snprintf(optval_buf, sizeof(optval_buf), "%f", so->u.f); break;
|
||||
case OPT_TYPE_DOUBLE: snprintf(optval_buf, sizeof(optval_buf), "%f", so->u.dbl); break;
|
||||
default: av_assert0(0);
|
||||
}
|
||||
|
||||
av_log(logctx, AV_LOG_WARNING, "Multiple %s options specified for "
|
||||
"stream %d, only the last option '-%s%s%s %s' will be used.\n",
|
||||
namestr, st->index, sol->opt_canon->name, spec[0] ? ":" : "",
|
||||
spec, optval);
|
||||
}
|
||||
|
||||
return match_idx + 1;
|
||||
}
|
||||
|
||||
#define OPT_MATCH_PER_STREAM(name, type, opt_type, m) \
|
||||
void opt_match_per_stream_ ## name(void *logctx, const SpecifierOptList *sol, \
|
||||
AVFormatContext *fc, AVStream *st, type *out) \
|
||||
{ \
|
||||
unsigned ret = opt_match_per_stream(logctx, opt_type, sol, fc, st); \
|
||||
if (ret > 0) \
|
||||
*out = sol->opt[ret - 1].u.m; \
|
||||
}
|
||||
|
||||
OPT_MATCH_PER_STREAM(str, const char *, OPT_TYPE_STRING, str);
|
||||
OPT_MATCH_PER_STREAM(int, int, OPT_TYPE_INT, i);
|
||||
OPT_MATCH_PER_STREAM(int64, int64_t, OPT_TYPE_INT64, i64);
|
||||
OPT_MATCH_PER_STREAM(dbl, double, OPT_TYPE_DOUBLE, dbl);
|
||||
|
||||
int view_specifier_parse(const char **pspec, ViewSpecifier *vs)
|
||||
{
|
||||
const char *spec = *pspec;
|
||||
char *endptr;
|
||||
|
||||
vs->type = VIEW_SPECIFIER_TYPE_NONE;
|
||||
|
||||
if (!strncmp(spec, "view:", 5)) {
|
||||
spec += 5;
|
||||
|
||||
if (!strncmp(spec, "all", 3)) {
|
||||
spec += 3;
|
||||
vs->type = VIEW_SPECIFIER_TYPE_ALL;
|
||||
} else {
|
||||
vs->type = VIEW_SPECIFIER_TYPE_ID;
|
||||
vs->val = strtoul(spec, &endptr, 0);
|
||||
if (endptr == spec) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Invalid view ID: %s\n", spec);
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
spec = endptr;
|
||||
}
|
||||
} else if (!strncmp(spec, "vidx:", 5)) {
|
||||
spec += 5;
|
||||
vs->type = VIEW_SPECIFIER_TYPE_IDX;
|
||||
vs->val = strtoul(spec, &endptr, 0);
|
||||
if (endptr == spec) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Invalid view index: %s\n", spec);
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
spec = endptr;
|
||||
} else if (!strncmp(spec, "vpos:", 5)) {
|
||||
spec += 5;
|
||||
vs->type = VIEW_SPECIFIER_TYPE_POS;
|
||||
|
||||
if (!strncmp(spec, "left", 4) && !cmdutils_isalnum(spec[4])) {
|
||||
spec += 4;
|
||||
vs->val = AV_STEREO3D_VIEW_LEFT;
|
||||
} else if (!strncmp(spec, "right", 5) && !cmdutils_isalnum(spec[5])) {
|
||||
spec += 5;
|
||||
vs->val = AV_STEREO3D_VIEW_RIGHT;
|
||||
} else {
|
||||
av_log(NULL, AV_LOG_ERROR, "Invalid view position: %s\n", spec);
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
} else
|
||||
return 0;
|
||||
|
||||
*pspec = spec;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int parse_and_set_vsync(const char *arg, int *vsync_var, int file_idx, int st_idx, int is_global)
|
||||
{
|
||||
if (!av_strcasecmp(arg, "cfr")) *vsync_var = VSYNC_CFR;
|
||||
@@ -417,7 +324,7 @@ static int opt_filter_threads(void *optctx, const char *opt, const char *arg)
|
||||
static int opt_abort_on(void *optctx, const char *opt, const char *arg)
|
||||
{
|
||||
static const AVOption opts[] = {
|
||||
{ "abort_on" , NULL, 0, AV_OPT_TYPE_FLAGS, { .i64 = 0 }, INT64_MIN, (double)INT64_MAX, .unit = "flags" },
|
||||
{ "abort_on" , NULL, 0, AV_OPT_TYPE_FLAGS, { .i64 = 0 }, INT64_MIN, INT64_MAX, .unit = "flags" },
|
||||
{ "empty_output" , NULL, 0, AV_OPT_TYPE_CONST, { .i64 = ABORT_ON_FLAG_EMPTY_OUTPUT }, .unit = "flags" },
|
||||
{ "empty_output_stream", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = ABORT_ON_FLAG_EMPTY_OUTPUT_STREAM }, .unit = "flags" },
|
||||
{ NULL },
|
||||
@@ -479,20 +386,22 @@ static int opt_map(void *optctx, const char *opt, const char *arg)
|
||||
{
|
||||
OptionsContext *o = optctx;
|
||||
StreamMap *m = NULL;
|
||||
StreamSpecifier ss;
|
||||
int i, negative = 0, file_idx, disabled = 0;
|
||||
int ret, allow_unused = 0;
|
||||
|
||||
memset(&ss, 0, sizeof(ss));
|
||||
int ret;
|
||||
char *map, *p;
|
||||
char *allow_unused;
|
||||
|
||||
if (*arg == '-') {
|
||||
negative = 1;
|
||||
arg++;
|
||||
}
|
||||
map = av_strdup(arg);
|
||||
if (!map)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
if (arg[0] == '[') {
|
||||
if (map[0] == '[') {
|
||||
/* this mapping refers to lavfi output */
|
||||
const char *c = arg + 1;
|
||||
const char *c = map + 1;
|
||||
|
||||
ret = GROW_ARRAY(o->stream_maps, o->nb_stream_maps);
|
||||
if (ret < 0)
|
||||
@@ -501,62 +410,33 @@ static int opt_map(void *optctx, const char *opt, const char *arg)
|
||||
m = &o->stream_maps[o->nb_stream_maps - 1];
|
||||
m->linklabel = av_get_token(&c, "]");
|
||||
if (!m->linklabel) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Invalid output link label: %s.\n", arg);
|
||||
av_log(NULL, AV_LOG_ERROR, "Invalid output link label: %s.\n", map);
|
||||
ret = AVERROR(EINVAL);
|
||||
goto fail;
|
||||
}
|
||||
} else {
|
||||
ViewSpecifier vs;
|
||||
char *endptr;
|
||||
|
||||
file_idx = strtol(arg, &endptr, 0);
|
||||
if (allow_unused = strchr(map, '?'))
|
||||
*allow_unused = 0;
|
||||
file_idx = strtol(map, &p, 0);
|
||||
if (file_idx >= nb_input_files || file_idx < 0) {
|
||||
av_log(NULL, AV_LOG_FATAL, "Invalid input file index: %d.\n", file_idx);
|
||||
ret = AVERROR(EINVAL);
|
||||
goto fail;
|
||||
}
|
||||
arg = endptr;
|
||||
|
||||
ret = stream_specifier_parse(&ss, *arg == ':' ? arg + 1 : arg, 1, NULL);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Invalid stream specifier: %s\n", arg);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
arg = ss.remainder ? ss.remainder : "";
|
||||
|
||||
ret = view_specifier_parse(&arg, &vs);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
|
||||
if (*arg) {
|
||||
if (!strcmp(arg, "?"))
|
||||
allow_unused = 1;
|
||||
else {
|
||||
av_log(NULL, AV_LOG_ERROR,
|
||||
"Trailing garbage after stream specifier: %s\n", arg);
|
||||
ret = AVERROR(EINVAL);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
if (negative)
|
||||
/* disable some already defined maps */
|
||||
for (i = 0; i < o->nb_stream_maps; i++) {
|
||||
m = &o->stream_maps[i];
|
||||
if (file_idx == m->file_index &&
|
||||
stream_specifier_match(&ss,
|
||||
input_files[m->file_index]->ctx,
|
||||
check_stream_specifier(input_files[m->file_index]->ctx,
|
||||
input_files[m->file_index]->ctx->streams[m->stream_index],
|
||||
NULL))
|
||||
*p == ':' ? p + 1 : p) > 0)
|
||||
m->disabled = 1;
|
||||
}
|
||||
else
|
||||
for (i = 0; i < input_files[file_idx]->nb_streams; i++) {
|
||||
if (!stream_specifier_match(&ss,
|
||||
input_files[file_idx]->ctx,
|
||||
input_files[file_idx]->ctx->streams[i],
|
||||
NULL))
|
||||
if (check_stream_specifier(input_files[file_idx]->ctx, input_files[file_idx]->ctx->streams[i],
|
||||
*p == ':' ? p + 1 : p) <= 0)
|
||||
continue;
|
||||
if (input_files[file_idx]->streams[i]->user_set_discard == AVDISCARD_ALL) {
|
||||
disabled = 1;
|
||||
@@ -570,7 +450,6 @@ static int opt_map(void *optctx, const char *opt, const char *arg)
|
||||
|
||||
m->file_index = file_idx;
|
||||
m->stream_index = i;
|
||||
m->vs = vs;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -591,7 +470,7 @@ static int opt_map(void *optctx, const char *opt, const char *arg)
|
||||
}
|
||||
ret = 0;
|
||||
fail:
|
||||
stream_specifier_uninit(&ss);
|
||||
av_freep(&map);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1392,10 +1271,12 @@ int ffmpeg_parse_options(int argc, char **argv, Scheduler *sch)
|
||||
}
|
||||
|
||||
// bind unbound filtegraph inputs/outputs and check consistency
|
||||
ret = fg_finalise_bindings();
|
||||
if (ret < 0) {
|
||||
errmsg = "binding filtergraph inputs/outputs";
|
||||
goto fail;
|
||||
for (int i = 0; i < nb_filtergraphs; i++) {
|
||||
ret = fg_finalise_bindings(filtergraphs[i]);
|
||||
if (ret < 0) {
|
||||
errmsg = "binding filtergraph inputs/outputs";
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
correct_input_start_times();
|
||||
@@ -1623,6 +1504,9 @@ const OptionDef options[] = {
|
||||
{ "bitexact", OPT_TYPE_BOOL, OPT_EXPERT | OPT_OFFSET | OPT_OUTPUT | OPT_INPUT,
|
||||
{ .off = OFFSET(bitexact) },
|
||||
"bitexact mode" },
|
||||
{ "apad", OPT_TYPE_STRING, OPT_PERSTREAM | OPT_EXPERT | OPT_OUTPUT,
|
||||
{ .off = OFFSET(apad) },
|
||||
"audio pad", "" },
|
||||
{ "dts_delta_threshold", OPT_TYPE_FLOAT, OPT_EXPERT,
|
||||
{ &dts_delta_threshold },
|
||||
"timestamp discontinuity delta threshold", "threshold" },
|
||||
@@ -1851,15 +1735,12 @@ const OptionDef options[] = {
|
||||
{ "hwaccels", OPT_TYPE_FUNC, OPT_EXIT | OPT_EXPERT,
|
||||
{ .func_arg = show_hwaccels },
|
||||
"show available HW acceleration methods" },
|
||||
{ "autorotate", OPT_TYPE_BOOL, OPT_VIDEO | OPT_PERSTREAM | OPT_EXPERT | OPT_INPUT,
|
||||
{ "autorotate", OPT_TYPE_BOOL, OPT_PERSTREAM | OPT_EXPERT | OPT_INPUT,
|
||||
{ .off = OFFSET(autorotate) },
|
||||
"automatically insert correct rotate filters" },
|
||||
{ "autoscale", OPT_TYPE_BOOL, OPT_VIDEO | OPT_PERSTREAM | OPT_EXPERT | OPT_OUTPUT,
|
||||
{ "autoscale", OPT_TYPE_BOOL, OPT_PERSTREAM | OPT_EXPERT | OPT_OUTPUT,
|
||||
{ .off = OFFSET(autoscale) },
|
||||
"automatically insert a scale filter at the end of the filter graph" },
|
||||
{ "apply_cropping", OPT_TYPE_STRING, OPT_VIDEO | OPT_PERSTREAM | OPT_EXPERT | OPT_INPUT,
|
||||
{ .off = OFFSET(apply_cropping) },
|
||||
"select the cropping to apply" },
|
||||
{ "fix_sub_duration_heartbeat", OPT_TYPE_BOOL, OPT_VIDEO | OPT_EXPERT | OPT_PERSTREAM | OPT_OUTPUT,
|
||||
{ .off = OFFSET(fix_sub_duration_heartbeat) },
|
||||
"set this video output stream to be a heartbeat stream for "
|
||||
@@ -1890,9 +1771,6 @@ const OptionDef options[] = {
|
||||
{ "ab", OPT_TYPE_FUNC, OPT_AUDIO | OPT_FUNC_ARG | OPT_PERFILE | OPT_OUTPUT,
|
||||
{ .func_arg = opt_bitrate },
|
||||
"alias for -b:a (select bitrate for audio streams)", "bitrate" },
|
||||
{ "apad", OPT_TYPE_STRING, OPT_AUDIO | OPT_PERSTREAM | OPT_EXPERT | OPT_OUTPUT,
|
||||
{ .off = OFFSET(apad) },
|
||||
"audio pad", "" },
|
||||
{ "atag", OPT_TYPE_FUNC, OPT_AUDIO | OPT_FUNC_ARG | OPT_EXPERT | OPT_PERFILE | OPT_OUTPUT | OPT_HAS_CANON,
|
||||
{ .func_arg = opt_old2new },
|
||||
"force audio tag/fourcc", "fourcc/tag",
|
||||
|
||||
+69
-136
@@ -71,19 +71,13 @@ typedef struct SchTask {
|
||||
int thread_running;
|
||||
} SchTask;
|
||||
|
||||
typedef struct SchDecOutput {
|
||||
SchedulerNode *dst;
|
||||
uint8_t *dst_finished;
|
||||
unsigned nb_dst;
|
||||
} SchDecOutput;
|
||||
|
||||
typedef struct SchDec {
|
||||
const AVClass *class;
|
||||
|
||||
SchedulerNode src;
|
||||
|
||||
SchDecOutput *outputs;
|
||||
unsigned nb_outputs;
|
||||
SchedulerNode *dst;
|
||||
uint8_t *dst_finished;
|
||||
unsigned nb_dst;
|
||||
|
||||
SchTask task;
|
||||
// Queue for receiving input packets, one stream.
|
||||
@@ -519,14 +513,8 @@ void sch_free(Scheduler **psch)
|
||||
|
||||
av_thread_message_queue_free(&dec->queue_end_ts);
|
||||
|
||||
for (unsigned j = 0; j < dec->nb_outputs; j++) {
|
||||
SchDecOutput *o = &dec->outputs[j];
|
||||
|
||||
av_freep(&o->dst);
|
||||
av_freep(&o->dst_finished);
|
||||
}
|
||||
|
||||
av_freep(&dec->outputs);
|
||||
av_freep(&dec->dst);
|
||||
av_freep(&dec->dst_finished);
|
||||
|
||||
av_frame_free(&dec->send_frame);
|
||||
}
|
||||
@@ -724,28 +712,14 @@ int sch_add_demux_stream(Scheduler *sch, unsigned demux_idx)
|
||||
return ret < 0 ? ret : d->nb_streams - 1;
|
||||
}
|
||||
|
||||
int sch_add_dec_output(Scheduler *sch, unsigned dec_idx)
|
||||
{
|
||||
SchDec *dec;
|
||||
int ret;
|
||||
|
||||
av_assert0(dec_idx < sch->nb_dec);
|
||||
dec = &sch->dec[dec_idx];
|
||||
|
||||
ret = GROW_ARRAY(dec->outputs, dec->nb_outputs);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return dec->nb_outputs - 1;
|
||||
}
|
||||
|
||||
static const AVClass sch_dec_class = {
|
||||
.class_name = "SchDec",
|
||||
.version = LIBAVUTIL_VERSION_INT,
|
||||
.parent_log_context_offset = offsetof(SchDec, task.func_arg),
|
||||
};
|
||||
|
||||
int sch_add_dec(Scheduler *sch, SchThreadFunc func, void *ctx, int send_end_ts)
|
||||
int sch_add_dec(Scheduler *sch, SchThreadFunc func, void *ctx,
|
||||
int send_end_ts)
|
||||
{
|
||||
const unsigned idx = sch->nb_dec;
|
||||
|
||||
@@ -765,10 +739,6 @@ int sch_add_dec(Scheduler *sch, SchThreadFunc func, void *ctx, int send_end_ts)
|
||||
if (!dec->send_frame)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
ret = sch_add_dec_output(sch, idx);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ret = queue_alloc(&dec->queue, 1, 0, QUEUE_PACKETS);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
@@ -973,19 +943,15 @@ int sch_connect(Scheduler *sch, SchedulerNode src, SchedulerNode dst)
|
||||
}
|
||||
case SCH_NODE_TYPE_DEC: {
|
||||
SchDec *dec;
|
||||
SchDecOutput *o;
|
||||
|
||||
av_assert0(src.idx < sch->nb_dec);
|
||||
dec = &sch->dec[src.idx];
|
||||
|
||||
av_assert0(src.idx_stream < dec->nb_outputs);
|
||||
o = &dec->outputs[src.idx_stream];
|
||||
|
||||
ret = GROW_ARRAY(o->dst, o->nb_dst);
|
||||
ret = GROW_ARRAY(dec->dst, dec->nb_dst);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
o->dst[o->nb_dst - 1] = dst;
|
||||
dec->dst[dec->nb_dst - 1] = dst;
|
||||
|
||||
// decoded frames go to filters or encoding
|
||||
switch (dst.type) {
|
||||
@@ -1017,40 +983,20 @@ int sch_connect(Scheduler *sch, SchedulerNode src, SchedulerNode dst)
|
||||
}
|
||||
case SCH_NODE_TYPE_FILTER_OUT: {
|
||||
SchFilterOut *fo;
|
||||
SchEnc *enc;
|
||||
|
||||
av_assert0(src.idx < sch->nb_filters &&
|
||||
src.idx_stream < sch->filters[src.idx].nb_outputs);
|
||||
fo = &sch->filters[src.idx].outputs[src.idx_stream];
|
||||
// filtered frames go to encoding
|
||||
av_assert0(dst.type == SCH_NODE_TYPE_ENC &&
|
||||
dst.idx < sch->nb_enc);
|
||||
|
||||
av_assert0(!fo->dst.type);
|
||||
fo->dst = dst;
|
||||
|
||||
// filtered frames go to encoding or another filtergraph
|
||||
switch (dst.type) {
|
||||
case SCH_NODE_TYPE_ENC: {
|
||||
SchEnc *enc;
|
||||
|
||||
av_assert0(dst.idx < sch->nb_enc);
|
||||
enc = &sch->enc[dst.idx];
|
||||
|
||||
av_assert0(!enc->src.type);
|
||||
enc->src = src;
|
||||
break;
|
||||
}
|
||||
case SCH_NODE_TYPE_FILTER_IN: {
|
||||
SchFilterIn *fi;
|
||||
|
||||
av_assert0(dst.idx < sch->nb_filters &&
|
||||
dst.idx_stream < sch->filters[dst.idx].nb_inputs);
|
||||
fi = &sch->filters[dst.idx].inputs[dst.idx_stream];
|
||||
|
||||
av_assert0(!fi->src.type);
|
||||
fi->src = src;
|
||||
break;
|
||||
}
|
||||
default: av_assert0(0);
|
||||
}
|
||||
fo = &sch->filters[src.idx].outputs[src.idx_stream];
|
||||
enc = &sch->enc[dst.idx];
|
||||
|
||||
av_assert0(!fo->dst.type && !enc->src.type);
|
||||
fo->dst = dst;
|
||||
enc->src = src;
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -1405,13 +1351,24 @@ static int check_acyclic(Scheduler *sch)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
// trace the transcoding graph upstream from every filtegraph
|
||||
for (unsigned i = 0; i < sch->nb_filters; i++) {
|
||||
ret = check_acyclic_for_output(sch, (SchedulerNode){ .idx = i },
|
||||
filters_visited, filters_stack);
|
||||
if (ret < 0) {
|
||||
av_log(&sch->filters[i], AV_LOG_ERROR, "Transcoding graph has a cycle\n");
|
||||
goto fail;
|
||||
// trace the transcoding graph upstream from every output stream
|
||||
// fed by a filtergraph
|
||||
for (unsigned i = 0; i < sch->nb_mux; i++) {
|
||||
SchMux *mux = &sch->mux[i];
|
||||
|
||||
for (unsigned j = 0; j < mux->nb_streams; j++) {
|
||||
SchMuxStream *ms = &mux->streams[j];
|
||||
SchedulerNode src = ms->src_sched;
|
||||
|
||||
if (src.type != SCH_NODE_TYPE_FILTER_OUT)
|
||||
continue;
|
||||
src.idx_stream = 0;
|
||||
|
||||
ret = check_acyclic_for_output(sch, src, filters_visited, filters_stack);
|
||||
if (ret < 0) {
|
||||
av_log(mux, AV_LOG_ERROR, "Transcoding graph has a cycle\n");
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1451,20 +1408,15 @@ static int start_prepare(Scheduler *sch)
|
||||
"Decoder not connected to a source\n");
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
for (unsigned j = 0; j < dec->nb_outputs; j++) {
|
||||
SchDecOutput *o = &dec->outputs[j];
|
||||
|
||||
if (!o->nb_dst) {
|
||||
av_log(dec, AV_LOG_ERROR,
|
||||
"Decoder output %u not connected to any sink\n", j);
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
o->dst_finished = av_calloc(o->nb_dst, sizeof(*o->dst_finished));
|
||||
if (!o->dst_finished)
|
||||
return AVERROR(ENOMEM);
|
||||
if (!dec->nb_dst) {
|
||||
av_log(dec, AV_LOG_ERROR,
|
||||
"Decoder not connected to any sink\n");
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
dec->dst_finished = av_calloc(dec->nb_dst, sizeof(*dec->dst_finished));
|
||||
if (!dec->dst_finished)
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < sch->nb_enc; i++) {
|
||||
@@ -1532,18 +1484,13 @@ static int start_prepare(Scheduler *sch)
|
||||
"Filtergraph input %u not connected to a source\n", j);
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
av_assert0(fi->src.type == SCH_NODE_TYPE_DEC);
|
||||
dec = &sch->dec[fi->src.idx];
|
||||
|
||||
if (fi->src.type == SCH_NODE_TYPE_FILTER_OUT)
|
||||
fi->src_sched = fi->src;
|
||||
else {
|
||||
av_assert0(fi->src.type == SCH_NODE_TYPE_DEC);
|
||||
dec = &sch->dec[fi->src.idx];
|
||||
|
||||
switch (dec->src.type) {
|
||||
case SCH_NODE_TYPE_DEMUX: fi->src_sched = dec->src; break;
|
||||
case SCH_NODE_TYPE_ENC: fi->src_sched = sch->enc[dec->src.idx].src; break;
|
||||
default: av_assert0(0);
|
||||
}
|
||||
switch (dec->src.type) {
|
||||
case SCH_NODE_TYPE_DEMUX: fi->src_sched = dec->src; break;
|
||||
case SCH_NODE_TYPE_ENC: fi->src_sched = sch->enc[dec->src.idx].src; break;
|
||||
default: av_assert0(0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2210,26 +2157,21 @@ finish:
|
||||
return AVERROR_EOF;
|
||||
}
|
||||
|
||||
int sch_dec_send(Scheduler *sch, unsigned dec_idx,
|
||||
unsigned out_idx, AVFrame *frame)
|
||||
int sch_dec_send(Scheduler *sch, unsigned dec_idx, AVFrame *frame)
|
||||
{
|
||||
SchDec *dec;
|
||||
SchDecOutput *o;
|
||||
int ret;
|
||||
int ret = 0;
|
||||
unsigned nb_done = 0;
|
||||
|
||||
av_assert0(dec_idx < sch->nb_dec);
|
||||
dec = &sch->dec[dec_idx];
|
||||
|
||||
av_assert0(out_idx < dec->nb_outputs);
|
||||
o = &dec->outputs[out_idx];
|
||||
|
||||
for (unsigned i = 0; i < o->nb_dst; i++) {
|
||||
uint8_t *finished = &o->dst_finished[i];
|
||||
for (unsigned i = 0; i < dec->nb_dst; i++) {
|
||||
uint8_t *finished = &dec->dst_finished[i];
|
||||
AVFrame *to_send = frame;
|
||||
|
||||
// sending a frame consumes it, so make a temporary reference if needed
|
||||
if (i < o->nb_dst - 1) {
|
||||
if (i < dec->nb_dst - 1) {
|
||||
to_send = dec->send_frame;
|
||||
|
||||
// frame may sometimes contain props only,
|
||||
@@ -2240,18 +2182,19 @@ int sch_dec_send(Scheduler *sch, unsigned dec_idx,
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = dec_send_to_dst(sch, o->dst[i], finished, to_send);
|
||||
ret = dec_send_to_dst(sch, dec->dst[i], finished, to_send);
|
||||
if (ret < 0) {
|
||||
av_frame_unref(to_send);
|
||||
if (ret == AVERROR_EOF) {
|
||||
nb_done++;
|
||||
ret = 0;
|
||||
continue;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return (nb_done == o->nb_dst) ? AVERROR_EOF : 0;
|
||||
return (nb_done == dec->nb_dst) ? AVERROR_EOF : 0;
|
||||
}
|
||||
|
||||
static int dec_done(Scheduler *sch, unsigned dec_idx)
|
||||
@@ -2266,14 +2209,10 @@ static int dec_done(Scheduler *sch, unsigned dec_idx)
|
||||
if (dec->queue_end_ts)
|
||||
av_thread_message_queue_set_err_recv(dec->queue_end_ts, AVERROR_EOF);
|
||||
|
||||
for (unsigned i = 0; i < dec->nb_outputs; i++) {
|
||||
SchDecOutput *o = &dec->outputs[i];
|
||||
|
||||
for (unsigned j = 0; j < o->nb_dst; j++) {
|
||||
int err = dec_send_to_dst(sch, o->dst[j], &o->dst_finished[j], NULL);
|
||||
if (err < 0 && err != AVERROR_EOF)
|
||||
ret = err_merge(ret, err);
|
||||
}
|
||||
for (unsigned i = 0; i < dec->nb_dst; i++) {
|
||||
int err = dec_send_to_dst(sch, dec->dst[i], &dec->dst_finished[i], NULL);
|
||||
if (err < 0 && err != AVERROR_EOF)
|
||||
ret = err_merge(ret, err);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -2347,13 +2286,15 @@ int sch_enc_send(Scheduler *sch, unsigned enc_idx, AVPacket *pkt)
|
||||
ret = enc_send_to_dst(sch, enc->dst[i], finished, to_send);
|
||||
if (ret < 0) {
|
||||
av_packet_unref(to_send);
|
||||
if (ret == AVERROR_EOF)
|
||||
if (ret == AVERROR_EOF) {
|
||||
ret = 0;
|
||||
continue;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int enc_done(Scheduler *sch, unsigned enc_idx)
|
||||
@@ -2440,17 +2381,12 @@ void sch_filter_receive_finish(Scheduler *sch, unsigned fg_idx, unsigned in_idx)
|
||||
int sch_filter_send(Scheduler *sch, unsigned fg_idx, unsigned out_idx, AVFrame *frame)
|
||||
{
|
||||
SchFilterGraph *fg;
|
||||
SchedulerNode dst;
|
||||
|
||||
av_assert0(fg_idx < sch->nb_filters);
|
||||
fg = &sch->filters[fg_idx];
|
||||
|
||||
av_assert0(out_idx < fg->nb_outputs);
|
||||
dst = fg->outputs[out_idx].dst;
|
||||
|
||||
return (dst.type == SCH_NODE_TYPE_ENC) ?
|
||||
send_to_enc (sch, &sch->enc[dst.idx], frame) :
|
||||
send_to_filter(sch, &sch->filters[dst.idx], dst.idx_stream, frame);
|
||||
return send_to_enc(sch, &sch->enc[fg->outputs[out_idx].dst.idx], frame);
|
||||
}
|
||||
|
||||
static int filter_done(Scheduler *sch, unsigned fg_idx)
|
||||
@@ -2462,11 +2398,8 @@ static int filter_done(Scheduler *sch, unsigned fg_idx)
|
||||
tq_receive_finish(fg->queue, i);
|
||||
|
||||
for (unsigned i = 0; i < fg->nb_outputs; i++) {
|
||||
SchedulerNode dst = fg->outputs[i].dst;
|
||||
int err = (dst.type == SCH_NODE_TYPE_ENC) ?
|
||||
send_to_enc (sch, &sch->enc[dst.idx], NULL) :
|
||||
send_to_filter(sch, &sch->filters[dst.idx], dst.idx_stream, NULL);
|
||||
|
||||
SchEnc *enc = &sch->enc[fg->outputs[i].dst.idx];
|
||||
int err = send_to_enc(sch, enc, NULL);
|
||||
if (err < 0 && err != AVERROR_EOF)
|
||||
ret = err_merge(ret, err);
|
||||
}
|
||||
|
||||
+6
-21
@@ -41,8 +41,7 @@
|
||||
* - filtergraphs, each containing zero or more inputs (0 in case the
|
||||
* filtergraph contains a lavfi source filter), and one or more outputs; the
|
||||
* inputs and outputs need not have matching media types;
|
||||
* each filtergraph input receives decoded frames from some decoder or another
|
||||
* filtergraph output;
|
||||
* each filtergraph input receives decoded frames from some decoder;
|
||||
* filtered frames from each output are sent to some encoder;
|
||||
* - encoders, which receive decoded frames from some decoder (subtitles) or
|
||||
* some filtergraph output (audio/video), encode them, and send encoded
|
||||
@@ -52,9 +51,6 @@
|
||||
* encoder (transcoding); those packets are interleaved and written out by the
|
||||
* muxer.
|
||||
*
|
||||
* The structure formed by the above components is a directed acyclic graph
|
||||
* (absence of cycles is checked at startup).
|
||||
*
|
||||
* There must be at least one muxer instance, otherwise the transcode produces
|
||||
* no output and is meaningless. Otherwise, in a generic transcoding scenario
|
||||
* there may be arbitrary number of instances of any of the above components,
|
||||
@@ -114,12 +110,9 @@ typedef int (*SchThreadFunc)(void *arg);
|
||||
#define SCH_MSTREAM(file, stream) \
|
||||
(SchedulerNode){ .type = SCH_NODE_TYPE_MUX, \
|
||||
.idx = file, .idx_stream = stream }
|
||||
#define SCH_DEC_IN(decoder) \
|
||||
#define SCH_DEC(decoder) \
|
||||
(SchedulerNode){ .type = SCH_NODE_TYPE_DEC, \
|
||||
.idx = decoder }
|
||||
#define SCH_DEC_OUT(decoder, out_idx) \
|
||||
(SchedulerNode){ .type = SCH_NODE_TYPE_DEC, \
|
||||
.idx = decoder, .idx_stream = out_idx }
|
||||
.idx = decoder }
|
||||
#define SCH_ENC(encoder) \
|
||||
(SchedulerNode){ .type = SCH_NODE_TYPE_ENC, \
|
||||
.idx = encoder }
|
||||
@@ -181,15 +174,8 @@ int sch_add_demux_stream(Scheduler *sch, unsigned demux_idx);
|
||||
* @retval ">=0" Index of the newly-created decoder.
|
||||
* @retval "<0" Error code.
|
||||
*/
|
||||
int sch_add_dec(Scheduler *sch, SchThreadFunc func, void *ctx, int send_end_ts);
|
||||
|
||||
/**
|
||||
* Add another output to decoder (e.g. for multiview video).
|
||||
*
|
||||
* @retval ">=0" Index of the newly-added decoder output.
|
||||
* @retval "<0" Error code.
|
||||
*/
|
||||
int sch_add_dec_output(Scheduler *sch, unsigned dec_idx);
|
||||
int sch_add_dec(Scheduler *sch, SchThreadFunc func, void *ctx,
|
||||
int send_end_ts);
|
||||
|
||||
/**
|
||||
* Add a filtergraph to the scheduler.
|
||||
@@ -389,8 +375,7 @@ int sch_dec_receive(Scheduler *sch, unsigned dec_idx, struct AVPacket *pkt);
|
||||
* @retval AVERROR_EOF all consumers are done, should terminate decoding
|
||||
* @retval "another negative error code" other failure
|
||||
*/
|
||||
int sch_dec_send(Scheduler *sch, unsigned dec_idx,
|
||||
unsigned out_idx, struct AVFrame *frame);
|
||||
int sch_dec_send(Scheduler *sch, unsigned dec_idx, struct AVFrame *frame);
|
||||
|
||||
/**
|
||||
* Called by filtergraph tasks to obtain frames for filtering. Will wait for a
|
||||
|
||||
@@ -35,12 +35,11 @@ typedef struct Timestamp {
|
||||
/**
|
||||
* Merge two return codes - return one of the error codes if at least one of
|
||||
* them was negative, 0 otherwise.
|
||||
* Currently just picks the first one, eventually we might want to do something
|
||||
* more sophisticated, like sorting them by priority.
|
||||
*/
|
||||
static inline int err_merge(int err0, int err1)
|
||||
{
|
||||
// prefer "real" errors over EOF
|
||||
if ((err0 >= 0 || err0 == AVERROR_EOF) && err1 < 0)
|
||||
return err1;
|
||||
return (err0 < 0) ? err0 : FFMIN(err1, 0);
|
||||
}
|
||||
|
||||
|
||||
+22
-26
@@ -25,6 +25,7 @@
|
||||
|
||||
#include "config.h"
|
||||
#include "config_components.h"
|
||||
#include <inttypes.h>
|
||||
#include <math.h>
|
||||
#include <limits.h>
|
||||
#include <signal.h>
|
||||
@@ -32,11 +33,13 @@
|
||||
|
||||
#include "libavutil/avstring.h"
|
||||
#include "libavutil/channel_layout.h"
|
||||
#include "libavutil/eval.h"
|
||||
#include "libavutil/mathematics.h"
|
||||
#include "libavutil/mem.h"
|
||||
#include "libavutil/pixdesc.h"
|
||||
#include "libavutil/imgutils.h"
|
||||
#include "libavutil/dict.h"
|
||||
#include "libavutil/fifo.h"
|
||||
#include "libavutil/parseutils.h"
|
||||
#include "libavutil/samplefmt.h"
|
||||
#include "libavutil/time.h"
|
||||
#include "libavutil/bprint.h"
|
||||
@@ -1963,21 +1966,16 @@ static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const c
|
||||
theta = get_rotation(displaymatrix);
|
||||
|
||||
if (fabs(theta - 90) < 1.0) {
|
||||
INSERT_FILT("transpose", displaymatrix[3] > 0 ? "cclock_flip" : "clock");
|
||||
INSERT_FILT("transpose", "clock");
|
||||
} else if (fabs(theta - 180) < 1.0) {
|
||||
if (displaymatrix[0] < 0)
|
||||
INSERT_FILT("hflip", NULL);
|
||||
if (displaymatrix[4] < 0)
|
||||
INSERT_FILT("vflip", NULL);
|
||||
INSERT_FILT("hflip", NULL);
|
||||
INSERT_FILT("vflip", NULL);
|
||||
} else if (fabs(theta - 270) < 1.0) {
|
||||
INSERT_FILT("transpose", displaymatrix[3] < 0 ? "clock_flip" : "cclock");
|
||||
INSERT_FILT("transpose", "cclock");
|
||||
} else if (fabs(theta) > 1.0) {
|
||||
char rotate_buf[64];
|
||||
snprintf(rotate_buf, sizeof(rotate_buf), "%f*PI/180", theta);
|
||||
INSERT_FILT("rotate", rotate_buf);
|
||||
} else {
|
||||
if (displaymatrix && displaymatrix[4] < 0)
|
||||
INSERT_FILT("vflip", NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2396,13 +2394,12 @@ static int audio_decode_frame(VideoState *is)
|
||||
av_channel_layout_compare(&af->frame->ch_layout, &is->audio_src.ch_layout) ||
|
||||
af->frame->sample_rate != is->audio_src.freq ||
|
||||
(wanted_nb_samples != af->frame->nb_samples && !is->swr_ctx)) {
|
||||
int ret;
|
||||
swr_free(&is->swr_ctx);
|
||||
ret = swr_alloc_set_opts2(&is->swr_ctx,
|
||||
swr_alloc_set_opts2(&is->swr_ctx,
|
||||
&is->audio_tgt.ch_layout, is->audio_tgt.fmt, is->audio_tgt.freq,
|
||||
&af->frame->ch_layout, af->frame->format, af->frame->sample_rate,
|
||||
0, NULL);
|
||||
if (ret < 0 || swr_init(is->swr_ctx) < 0) {
|
||||
if (!is->swr_ctx || swr_init(is->swr_ctx) < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR,
|
||||
"Cannot create sample rate converter for conversion of %d Hz %s %d channels to %d Hz %s %d channels!\n",
|
||||
af->frame->sample_rate, av_get_sample_fmt_name(af->frame->format), af->frame->ch_layout.nb_channels,
|
||||
@@ -2631,6 +2628,7 @@ static int stream_component_open(VideoState *is, int stream_index)
|
||||
const AVCodec *codec;
|
||||
const char *forced_codec_name = NULL;
|
||||
AVDictionary *opts = NULL;
|
||||
const AVDictionaryEntry *t = NULL;
|
||||
int sample_rate;
|
||||
AVChannelLayout ch_layout = { 0 };
|
||||
int ret = 0;
|
||||
@@ -2678,7 +2676,7 @@ static int stream_component_open(VideoState *is, int stream_index)
|
||||
avctx->flags2 |= AV_CODEC_FLAG2_FAST;
|
||||
|
||||
ret = filter_codec_opts(codec_opts, avctx->codec_id, ic,
|
||||
ic->streams[stream_index], codec, &opts, NULL);
|
||||
ic->streams[stream_index], codec, &opts);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
|
||||
@@ -2698,9 +2696,11 @@ static int stream_component_open(VideoState *is, int stream_index)
|
||||
if ((ret = avcodec_open2(avctx, codec, &opts)) < 0) {
|
||||
goto fail;
|
||||
}
|
||||
ret = check_avoptions(opts);
|
||||
if (ret < 0)
|
||||
if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
|
||||
ret = AVERROR_OPTION_NOT_FOUND;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
is->eof = 0;
|
||||
ic->streams[stream_index]->discard = AVDISCARD_DEFAULT;
|
||||
@@ -2863,11 +2863,12 @@ static int read_thread(void *arg)
|
||||
}
|
||||
if (scan_all_pmts_set)
|
||||
av_dict_set(&format_opts, "scan_all_pmts", NULL, AV_DICT_MATCH_CASE);
|
||||
remove_avoptions(&format_opts, codec_opts);
|
||||
|
||||
ret = check_avoptions(format_opts);
|
||||
if (ret < 0)
|
||||
if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key);
|
||||
ret = AVERROR_OPTION_NOT_FOUND;
|
||||
goto fail;
|
||||
}
|
||||
is->ic = ic;
|
||||
|
||||
if (genpts)
|
||||
@@ -3841,13 +3842,8 @@ int main(int argc, char **argv)
|
||||
if (vk_renderer) {
|
||||
AVDictionary *dict = NULL;
|
||||
|
||||
if (vulkan_params) {
|
||||
int ret = av_dict_parse_string(&dict, vulkan_params, "=", ":", 0);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_FATAL, "Failed to parse, %s\n", vulkan_params);
|
||||
do_exit(NULL);
|
||||
}
|
||||
}
|
||||
if (vulkan_params)
|
||||
av_dict_parse_string(&dict, vulkan_params, "=", ":", 0);
|
||||
ret = vk_renderer_create(vk_renderer, window, dict);
|
||||
av_dict_free(&dict);
|
||||
if (ret < 0) {
|
||||
|
||||
@@ -42,7 +42,6 @@
|
||||
#include <SDL_vulkan.h>
|
||||
|
||||
#include "libavutil/bprint.h"
|
||||
#include "libavutil/mem.h"
|
||||
|
||||
#endif
|
||||
|
||||
@@ -766,7 +765,7 @@ static void destroy(VkRenderer *renderer)
|
||||
vkDestroySurfaceKHR = (PFN_vkDestroySurfaceKHR)
|
||||
ctx->get_proc_addr(ctx->inst, "vkDestroySurfaceKHR");
|
||||
vkDestroySurfaceKHR(ctx->inst, ctx->vk_surface, NULL);
|
||||
ctx->vk_surface = VK_NULL_HANDLE;
|
||||
ctx->vk_surface = NULL;
|
||||
}
|
||||
|
||||
av_buffer_unref(&ctx->hw_device_ref);
|
||||
|
||||
+4
-26
@@ -46,7 +46,6 @@
|
||||
#include "libavutil/mastering_display_metadata.h"
|
||||
#include "libavutil/hdr_dynamic_vivid_metadata.h"
|
||||
#include "libavutil/dovi_meta.h"
|
||||
#include "libavutil/mem.h"
|
||||
#include "libavutil/opt.h"
|
||||
#include "libavutil/pixdesc.h"
|
||||
#include "libavutil/spherical.h"
|
||||
@@ -2544,11 +2543,6 @@ static void print_pkt_side_data(WriterContext *w,
|
||||
const AVStereo3D *stereo = (AVStereo3D *)sd->data;
|
||||
print_str("type", av_stereo3d_type_name(stereo->type));
|
||||
print_int("inverted", !!(stereo->flags & AV_STEREO3D_FLAG_INVERT));
|
||||
print_str("view", av_stereo3d_view_name(stereo->view));
|
||||
print_str("primary_eye", av_stereo3d_primary_eye_name(stereo->primary_eye));
|
||||
print_int("baseline", stereo->baseline);
|
||||
print_q("horizontal_disparity_adjustment", stereo->horizontal_disparity_adjustment, '/');
|
||||
print_q("horizontal_field_of_view", stereo->horizontal_field_of_view, '/');
|
||||
} else if (sd->type == AV_PKT_DATA_SPHERICAL) {
|
||||
const AVSphericalMapping *spherical = (AVSphericalMapping *)sd->data;
|
||||
print_str("projection", av_spherical_projection_name(spherical->projection));
|
||||
@@ -2603,7 +2597,6 @@ static void print_pkt_side_data(WriterContext *w,
|
||||
print_dynamic_hdr10_plus(w, metadata);
|
||||
} else if (sd->type == AV_PKT_DATA_DOVI_CONF) {
|
||||
AVDOVIDecoderConfigurationRecord *dovi = (AVDOVIDecoderConfigurationRecord *)sd->data;
|
||||
const char *comp = "unknown";
|
||||
print_int("dv_version_major", dovi->dv_version_major);
|
||||
print_int("dv_version_minor", dovi->dv_version_minor);
|
||||
print_int("dv_profile", dovi->dv_profile);
|
||||
@@ -2612,14 +2605,6 @@ static void print_pkt_side_data(WriterContext *w,
|
||||
print_int("el_present_flag", dovi->el_present_flag);
|
||||
print_int("bl_present_flag", dovi->bl_present_flag);
|
||||
print_int("dv_bl_signal_compatibility_id", dovi->dv_bl_signal_compatibility_id);
|
||||
switch (dovi->dv_md_compression)
|
||||
{
|
||||
case AV_DOVI_COMPRESSION_NONE: comp = "none"; break;
|
||||
case AV_DOVI_COMPRESSION_LIMITED: comp = "limited"; break;
|
||||
case AV_DOVI_COMPRESSION_RESERVED: comp = "reserved"; break;
|
||||
case AV_DOVI_COMPRESSION_EXTENDED: comp = "extended"; break;
|
||||
}
|
||||
print_str("dv_md_compression", comp);
|
||||
} else if (sd->type == AV_PKT_DATA_AUDIO_SERVICE_TYPE) {
|
||||
enum AVAudioServiceType *t = (enum AVAudioServiceType *)sd->data;
|
||||
print_int("service_type", *t);
|
||||
@@ -2637,11 +2622,6 @@ static void print_pkt_side_data(WriterContext *w,
|
||||
if (do_show_data)
|
||||
writer_print_data(w, "data", sd->data, sd->size);
|
||||
writer_print_data_hash(w, "data_hash", sd->data, sd->size);
|
||||
} else if (sd->type == AV_PKT_DATA_FRAME_CROPPING && sd->size >= sizeof(uint32_t) * 4) {
|
||||
print_int("crop_top", AV_RL32(sd->data));
|
||||
print_int("crop_bottom", AV_RL32(sd->data + 4));
|
||||
print_int("crop_left", AV_RL32(sd->data + 8));
|
||||
print_int("crop_right", AV_RL32(sd->data + 12));
|
||||
} else if (sd->type == AV_PKT_DATA_AFD && sd->size > 0) {
|
||||
print_int("active_format", *sd->data);
|
||||
}
|
||||
@@ -2920,8 +2900,6 @@ static void print_frame_side_data(WriterContext *w,
|
||||
} else if (sd->type == AV_FRAME_DATA_FILM_GRAIN_PARAMS) {
|
||||
AVFilmGrainParams *fgp = (AVFilmGrainParams *)sd->data;
|
||||
print_film_grain_params(w, fgp);
|
||||
} else if (sd->type == AV_FRAME_DATA_VIEW_ID) {
|
||||
print_int("view_id", *(int*)sd->data);
|
||||
}
|
||||
writer_print_section_footer(w);
|
||||
}
|
||||
@@ -3345,8 +3323,8 @@ static int show_stream(WriterContext *w, AVFormatContext *fmt_ctx, int stream_id
|
||||
if (sar.num) {
|
||||
print_q("sample_aspect_ratio", sar, ':');
|
||||
av_reduce(&dar.num, &dar.den,
|
||||
(int64_t) par->width * sar.num,
|
||||
(int64_t) par->height * sar.den,
|
||||
par->width * sar.num,
|
||||
par->height * sar.den,
|
||||
1024*1024);
|
||||
print_q("display_aspect_ratio", dar, ':');
|
||||
} else {
|
||||
@@ -3943,7 +3921,7 @@ static int open_input_file(InputFile *ifile, const char *filename,
|
||||
AVDictionary *opts;
|
||||
|
||||
err = filter_codec_opts(codec_opts, stream->codecpar->codec_id,
|
||||
fmt_ctx, stream, codec, &opts, NULL);
|
||||
fmt_ctx, stream, codec, &opts);
|
||||
if (err < 0)
|
||||
exit(1);
|
||||
|
||||
@@ -3972,7 +3950,7 @@ static int open_input_file(InputFile *ifile, const char *filename,
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ((t = av_dict_iterate(opts, NULL))) {
|
||||
if ((t = av_dict_get(opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Option %s for input stream %d not found\n",
|
||||
t->key, stream->index);
|
||||
return AVERROR_OPTION_NOT_FOUND;
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
* CRT, and FILE* handles can't be shared across them.) */
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "libavutil/mem.h"
|
||||
#include "libavutil/wchar_filename.h"
|
||||
|
||||
static inline FILE *fopen_utf8(const char *path_utf8, const char *mode)
|
||||
|
||||
+48
-56
@@ -262,36 +262,22 @@ int show_buildconf(void *optctx, const char *opt, const char *arg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define PRINT_CODEC_SUPPORTED(codec, config, type, name, elem, fmt, ...) \
|
||||
do { \
|
||||
int num = 0; \
|
||||
const type *elem = NULL; \
|
||||
avcodec_get_supported_config(NULL, codec, config, 0, \
|
||||
(const void **) &elem, &num); \
|
||||
if (elem) { \
|
||||
printf(" Supported " name ":"); \
|
||||
for (int i = 0; i < num; i++) { \
|
||||
printf(" " fmt, __VA_ARGS__); \
|
||||
elem++; \
|
||||
} \
|
||||
printf("\n"); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static const char *get_channel_layout_desc(const AVChannelLayout *layout, AVBPrint *bp)
|
||||
{
|
||||
int ret;
|
||||
av_bprint_clear(bp);
|
||||
ret = av_channel_layout_describe_bprint(layout, bp);
|
||||
if (!av_bprint_is_complete(bp) || ret < 0)
|
||||
return "unknown/invalid";
|
||||
return bp->str;
|
||||
}
|
||||
#define PRINT_CODEC_SUPPORTED(codec, field, type, list_name, term, get_name) \
|
||||
if (codec->field) { \
|
||||
const type *p = codec->field; \
|
||||
\
|
||||
printf(" Supported " list_name ":"); \
|
||||
while (*p != term) { \
|
||||
get_name(*p); \
|
||||
printf(" %s", name); \
|
||||
p++; \
|
||||
} \
|
||||
printf("\n"); \
|
||||
} \
|
||||
|
||||
static void print_codec(const AVCodec *c)
|
||||
{
|
||||
int encoder = av_codec_is_encoder(c);
|
||||
AVBPrint desc;
|
||||
|
||||
printf("%s %s [%s]:\n", encoder ? "Encoder" : "Decoder", c->name,
|
||||
c->long_name ? c->long_name : "");
|
||||
@@ -357,20 +343,35 @@ static void print_codec(const AVCodec *c)
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
PRINT_CODEC_SUPPORTED(c, AV_CODEC_CONFIG_FRAME_RATE, AVRational, "framerates",
|
||||
fps, "%d/%d", fps->num, fps->den);
|
||||
PRINT_CODEC_SUPPORTED(c, AV_CODEC_CONFIG_PIX_FORMAT, enum AVPixelFormat,
|
||||
"pixel formats", fmt, "%s", av_get_pix_fmt_name(*fmt));
|
||||
PRINT_CODEC_SUPPORTED(c, AV_CODEC_CONFIG_SAMPLE_RATE, int, "sample rates",
|
||||
rate, "%d", *rate);
|
||||
PRINT_CODEC_SUPPORTED(c, AV_CODEC_CONFIG_SAMPLE_FORMAT, enum AVSampleFormat,
|
||||
"sample formats", fmt, "%s", av_get_sample_fmt_name(*fmt));
|
||||
if (c->supported_framerates) {
|
||||
const AVRational *fps = c->supported_framerates;
|
||||
|
||||
av_bprint_init(&desc, 0, AV_BPRINT_SIZE_AUTOMATIC);
|
||||
PRINT_CODEC_SUPPORTED(c, AV_CODEC_CONFIG_CHANNEL_LAYOUT, AVChannelLayout,
|
||||
"channel layouts", layout, "%s",
|
||||
get_channel_layout_desc(layout, &desc));
|
||||
av_bprint_finalize(&desc, NULL);
|
||||
printf(" Supported framerates:");
|
||||
while (fps->num) {
|
||||
printf(" %d/%d", fps->num, fps->den);
|
||||
fps++;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
PRINT_CODEC_SUPPORTED(c, pix_fmts, enum AVPixelFormat, "pixel formats",
|
||||
AV_PIX_FMT_NONE, GET_PIX_FMT_NAME);
|
||||
PRINT_CODEC_SUPPORTED(c, supported_samplerates, int, "sample rates", 0,
|
||||
GET_SAMPLE_RATE_NAME);
|
||||
PRINT_CODEC_SUPPORTED(c, sample_fmts, enum AVSampleFormat, "sample formats",
|
||||
AV_SAMPLE_FMT_NONE, GET_SAMPLE_FMT_NAME);
|
||||
|
||||
if (c->ch_layouts) {
|
||||
const AVChannelLayout *p = c->ch_layouts;
|
||||
|
||||
printf(" Supported channel layouts:");
|
||||
while (p->nb_channels) {
|
||||
char name[128];
|
||||
av_channel_layout_describe(p, name, sizeof(name));
|
||||
printf(" %s", name);
|
||||
p++;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
if (c->priv_class) {
|
||||
show_help_children(c->priv_class,
|
||||
@@ -565,15 +566,8 @@ static void show_help_bsf(const char *name)
|
||||
}
|
||||
|
||||
printf("Bit stream filter %s\n", bsf->name);
|
||||
if (bsf->codec_ids) {
|
||||
const enum AVCodecID *id = bsf->codec_ids;
|
||||
printf(" Supported codecs:");
|
||||
while (*id != AV_CODEC_ID_NONE) {
|
||||
printf(" %s", avcodec_descriptor_get(*id)->name);
|
||||
id++;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
PRINT_CODEC_SUPPORTED(bsf, codec_ids, enum AVCodecID, "codecs",
|
||||
AV_CODEC_ID_NONE, GET_CODEC_NAME);
|
||||
if (bsf->priv_class)
|
||||
show_help_children(bsf->priv_class, AV_OPT_FLAG_BSF_PARAM);
|
||||
}
|
||||
@@ -730,13 +724,10 @@ int show_codecs(void *optctx, const char *opt, const char *arg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int print_codecs(int encoder)
|
||||
static void print_codecs(int encoder)
|
||||
{
|
||||
const AVCodecDescriptor **codecs;
|
||||
int i, nb_codecs = get_codecs_sorted(&codecs);
|
||||
|
||||
if (nb_codecs < 0)
|
||||
return nb_codecs;
|
||||
unsigned i, nb_codecs = get_codecs_sorted(&codecs);
|
||||
|
||||
printf("%s:\n"
|
||||
" V..... = Video\n"
|
||||
@@ -771,17 +762,18 @@ static int print_codecs(int encoder)
|
||||
}
|
||||
}
|
||||
av_free(codecs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int show_decoders(void *optctx, const char *opt, const char *arg)
|
||||
{
|
||||
return print_codecs(0);
|
||||
print_codecs(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int show_encoders(void *optctx, const char *opt, const char *arg)
|
||||
{
|
||||
return print_codecs(1);
|
||||
print_codecs(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int show_bsfs(void *optctx, const char *opt, const char *arg)
|
||||
|
||||
@@ -64,6 +64,9 @@ static int zero12v_decode_frame(AVCodecContext *avctx, AVFrame *pic,
|
||||
if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
|
||||
return ret;
|
||||
|
||||
pic->pict_type = AV_PICTURE_TYPE_I;
|
||||
pic->flags |= AV_FRAME_FLAG_KEY;
|
||||
|
||||
line_end = avpkt->data + stride;
|
||||
for (line = 0; line < avctx->height; line++) {
|
||||
uint16_t y_temp[6] = {0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000};
|
||||
|
||||
@@ -30,7 +30,6 @@
|
||||
#include "libavutil/frame.h"
|
||||
#include "libavutil/imgutils.h"
|
||||
#include "libavutil/intreadwrite.h"
|
||||
#include "libavutil/mem.h"
|
||||
#include "libavutil/mem_internal.h"
|
||||
#include "libavutil/thread.h"
|
||||
#include "avcodec.h"
|
||||
|
||||
@@ -40,7 +40,6 @@
|
||||
#include "config_components.h"
|
||||
|
||||
#include "libavutil/avassert.h"
|
||||
#include "libavutil/mem.h"
|
||||
#include "avcodec.h"
|
||||
#include "codec_internal.h"
|
||||
#include "decode.h"
|
||||
|
||||
+35
-44
@@ -32,7 +32,7 @@ OBJS = ac3_parser.o \
|
||||
avcodec.o \
|
||||
avdct.o \
|
||||
avfft.o \
|
||||
packet.o \
|
||||
avpacket.o \
|
||||
bitstream.o \
|
||||
bitstream_filters.o \
|
||||
bsf.o \
|
||||
@@ -46,7 +46,6 @@ OBJS = ac3_parser.o \
|
||||
get_buffer.o \
|
||||
imgconvert.o \
|
||||
jni.o \
|
||||
lcevcdec.o \
|
||||
mathtables.o \
|
||||
mediacodec.o \
|
||||
mpeg12framerate.o \
|
||||
@@ -57,7 +56,6 @@ OBJS = ac3_parser.o \
|
||||
qsv_api.o \
|
||||
raw.o \
|
||||
refstruct.o \
|
||||
threadprogress.o \
|
||||
utils.o \
|
||||
version.o \
|
||||
vlc.o \
|
||||
@@ -65,9 +63,6 @@ OBJS = ac3_parser.o \
|
||||
xiph.o \
|
||||
|
||||
# subsystems
|
||||
include $(SRC_PATH)/libavcodec/aac/Makefile
|
||||
include $(SRC_PATH)/libavcodec/hevc/Makefile
|
||||
include $(SRC_PATH)/libavcodec/opus/Makefile
|
||||
include $(SRC_PATH)/libavcodec/vvc/Makefile
|
||||
-include $(SRC_PATH)/libavcodec/$(ARCH)/vvc/Makefile
|
||||
OBJS-$(CONFIG_AANDCTTABLES) += aandcttab.o
|
||||
@@ -89,10 +84,8 @@ OBJS-$(CONFIG_CBS_JPEG) += cbs_jpeg.o
|
||||
OBJS-$(CONFIG_CBS_MPEG2) += cbs_mpeg2.o
|
||||
OBJS-$(CONFIG_CBS_VP8) += cbs_vp8.o vp8data.o
|
||||
OBJS-$(CONFIG_CBS_VP9) += cbs_vp9.o
|
||||
OBJS-$(CONFIG_D3D12VA_ENCODE) += d3d12va_encode.o hw_base_encode.o
|
||||
OBJS-$(CONFIG_DEFLATE_WRAPPER) += zlib_wrapper.o
|
||||
OBJS-$(CONFIG_DOVI_RPUDEC) += dovi_rpu.o dovi_rpudec.o
|
||||
OBJS-$(CONFIG_DOVI_RPUENC) += dovi_rpu.o dovi_rpuenc.o
|
||||
OBJS-$(CONFIG_DOVI_RPU) += dovi_rpu.o
|
||||
OBJS-$(CONFIG_ERROR_RESILIENCE) += error_resilience.o
|
||||
OBJS-$(CONFIG_EVCPARSE) += evc_parse.o evc_ps.o
|
||||
OBJS-$(CONFIG_EXIF) += exif.o tiff_common.o
|
||||
@@ -104,14 +97,15 @@ OBJS-$(CONFIG_GOLOMB) += golomb.o
|
||||
OBJS-$(CONFIG_H263DSP) += h263dsp.o
|
||||
OBJS-$(CONFIG_H264CHROMA) += h264chroma.o
|
||||
OBJS-$(CONFIG_H264DSP) += h264dsp.o h264idct.o
|
||||
OBJS-$(CONFIG_H264PARSE) += h264_parse.o h264_ps.o h264data.o \
|
||||
h2645data.o h2645_parse.o h2645_vui.o
|
||||
OBJS-$(CONFIG_H264PARSE) += h264_parse.o h264_ps.o h2645data.o \
|
||||
h2645_parse.o h2645_vui.o
|
||||
OBJS-$(CONFIG_H264PRED) += h264pred.o
|
||||
OBJS-$(CONFIG_H264QPEL) += h264qpel.o
|
||||
OBJS-$(CONFIG_H264_SEI) += h264_sei.o h2645_sei.o
|
||||
OBJS-$(CONFIG_HEVCPARSE) += h2645data.o h2645_parse.o h2645_vui.o
|
||||
OBJS-$(CONFIG_HEVC_SEI) += h2645_sei.o aom_film_grain.o \
|
||||
dynamic_hdr_vivid.o
|
||||
OBJS-$(CONFIG_HEVCPARSE) += hevc_parse.o hevc_ps.o hevc_data.o \
|
||||
h2645data.o h2645_parse.o h2645_vui.o
|
||||
OBJS-$(CONFIG_HEVC_SEI) += hevc_sei.o h2645_sei.o \
|
||||
dynamic_hdr_vivid.o aom_film_grain.o
|
||||
OBJS-$(CONFIG_HPELDSP) += hpeldsp.o
|
||||
OBJS-$(CONFIG_HUFFMAN) += huffman.o
|
||||
OBJS-$(CONFIG_HUFFYUVDSP) += huffyuvdsp.o
|
||||
@@ -119,7 +113,7 @@ OBJS-$(CONFIG_HUFFYUVENCDSP) += huffyuvencdsp.o
|
||||
OBJS-$(CONFIG_IDCTDSP) += idctdsp.o simple_idct.o jrevdct.o
|
||||
OBJS-$(CONFIG_IIRFILTER) += iirfilter.o
|
||||
OBJS-$(CONFIG_INFLATE_WRAPPER) += zlib_wrapper.o
|
||||
OBJS-$(CONFIG_INTRAX8) += intrax8.o intrax8dsp.o msmpeg4_vc1_data.o
|
||||
OBJS-$(CONFIG_INTRAX8) += intrax8.o intrax8dsp.o msmpeg4data.o
|
||||
OBJS-$(CONFIG_IVIDSP) += ivi_dsp.o
|
||||
OBJS-$(CONFIG_JNI) += ffjni.o jni.o
|
||||
OBJS-$(CONFIG_JPEGTABLES) += jpegtables.o
|
||||
@@ -168,7 +162,7 @@ OBJS-$(CONFIG_STARTCODE) += startcode.o
|
||||
OBJS-$(CONFIG_TEXTUREDSP) += texturedsp.o
|
||||
OBJS-$(CONFIG_TEXTUREDSPENC) += texturedspenc.o
|
||||
OBJS-$(CONFIG_TPELDSP) += tpeldsp.o
|
||||
OBJS-$(CONFIG_VAAPI_ENCODE) += vaapi_encode.o hw_base_encode.o
|
||||
OBJS-$(CONFIG_VAAPI_ENCODE) += vaapi_encode.o
|
||||
OBJS-$(CONFIG_AV1_AMF_ENCODER) += amfenc_av1.o
|
||||
OBJS-$(CONFIG_VC1DSP) += vc1dsp.o
|
||||
OBJS-$(CONFIG_VIDEODSP) += videodsp.o
|
||||
@@ -183,11 +177,11 @@ OBJS-$(CONFIG_WMV2DSP) += wmv2dsp.o
|
||||
OBJS-$(CONFIG_ZERO12V_DECODER) += 012v.o
|
||||
OBJS-$(CONFIG_A64MULTI_ENCODER) += a64multienc.o elbg.o
|
||||
OBJS-$(CONFIG_A64MULTI5_ENCODER) += a64multienc.o elbg.o
|
||||
OBJS-$(CONFIG_AAC_DECODER) += aactab.o \
|
||||
OBJS-$(CONFIG_AAC_DECODER) += aacdec.o aacdec_common.o aactab.o \
|
||||
aacsbr.o aacps_common.o aacps_float.o \
|
||||
kbdwin.o \
|
||||
sbrdsp.o aacpsdsp_float.o cbrt_data.o
|
||||
OBJS-$(CONFIG_AAC_FIXED_DECODER) += aactab.o \
|
||||
OBJS-$(CONFIG_AAC_FIXED_DECODER) += aacdec_fixed.o aacdec_common.o aactab.o \
|
||||
aacsbr_fixed.o aacps_common.o aacps_fixed.o \
|
||||
kbdwin.o \
|
||||
sbrdsp_fixed.o aacpsdsp_fixed.o cbrt_data_fixed.o
|
||||
@@ -199,7 +193,6 @@ OBJS-$(CONFIG_AAC_ENCODER) += aacenc.o aaccoder.o aacenctab.o \
|
||||
aacenc_pred.o \
|
||||
psymodel.o kbdwin.o \
|
||||
mpeg4audio_sample_rates.o
|
||||
OBJS-$(CONFIG_AAC_MEDIACODEC_DECODER) += mediacodecdec.o
|
||||
OBJS-$(CONFIG_AAC_MF_ENCODER) += mfenc.o mf_utils.o
|
||||
OBJS-$(CONFIG_AASC_DECODER) += aasc.o msrledec.o
|
||||
OBJS-$(CONFIG_AC3_DECODER) += ac3dec_float.o ac3dec_data.o ac3.o \
|
||||
@@ -226,8 +219,6 @@ OBJS-$(CONFIG_AMRWB_DECODER) += amrwbdec.o celp_filters.o \
|
||||
celp_math.o acelp_filters.o \
|
||||
acelp_vectors.o \
|
||||
acelp_pitch_delay.o
|
||||
OBJS-$(CONFIG_AMRNB_MEDIACODEC_DECODER) += mediacodecdec.o
|
||||
OBJS-$(CONFIG_AMRWB_MEDIACODEC_DECODER) += mediacodecdec.o
|
||||
OBJS-$(CONFIG_AMV_ENCODER) += mjpegenc.o mjpegenc_common.o
|
||||
OBJS-$(CONFIG_ANM_DECODER) += anm.o
|
||||
OBJS-$(CONFIG_ANULL_DECODER) += null.o
|
||||
@@ -274,6 +265,8 @@ OBJS-$(CONFIG_AVRP_ENCODER) += r210enc.o
|
||||
OBJS-$(CONFIG_AVS_DECODER) += avs.o
|
||||
OBJS-$(CONFIG_AVUI_DECODER) += avuidec.o
|
||||
OBJS-$(CONFIG_AVUI_ENCODER) += avuienc.o
|
||||
OBJS-$(CONFIG_AYUV_DECODER) += v408dec.o
|
||||
OBJS-$(CONFIG_AYUV_ENCODER) += v408enc.o
|
||||
OBJS-$(CONFIG_BETHSOFTVID_DECODER) += bethsoftvideo.o
|
||||
OBJS-$(CONFIG_BFI_DECODER) += bfi.o
|
||||
OBJS-$(CONFIG_BINK_DECODER) += bink.o binkdsp.o
|
||||
@@ -291,7 +284,7 @@ OBJS-$(CONFIG_BRENDER_PIX_DECODER) += brenderpix.o
|
||||
OBJS-$(CONFIG_C93_DECODER) += c93.o
|
||||
OBJS-$(CONFIG_CAVS_DECODER) += cavs.o cavsdec.o cavsdsp.o \
|
||||
cavsdata.o
|
||||
OBJS-$(CONFIG_CBD2_DPCM_DECODER) += dpcm.o
|
||||
OBJS-$(CONFIG_CBD2_DECODER) += dpcm.o
|
||||
OBJS-$(CONFIG_CCAPTION_DECODER) += ccaption_dec.o ass.o
|
||||
OBJS-$(CONFIG_CDGRAPHICS_DECODER) += cdgraphics.o
|
||||
OBJS-$(CONFIG_CDTOONS_DECODER) += cdtoons.o
|
||||
@@ -426,10 +419,7 @@ OBJS-$(CONFIG_H264_QSV_DECODER) += qsvdec.o
|
||||
OBJS-$(CONFIG_H264_QSV_ENCODER) += qsvenc_h264.o
|
||||
OBJS-$(CONFIG_H264_RKMPP_DECODER) += rkmppdec.o
|
||||
OBJS-$(CONFIG_H264_VAAPI_ENCODER) += vaapi_encode_h264.o h264_levels.o \
|
||||
h2645data.o hw_base_encode_h264.o
|
||||
OBJS-$(CONFIG_H264_VULKAN_ENCODER) += vulkan_encode.o vulkan_encode_h264.o \
|
||||
hw_base_encode.o hw_base_encode_h264.o \
|
||||
h264_levels.o h2645data.o
|
||||
h2645data.o
|
||||
OBJS-$(CONFIG_H264_VIDEOTOOLBOX_ENCODER) += videotoolboxenc.o
|
||||
OBJS-$(CONFIG_H264_V4L2M2M_DECODER) += v4l2_m2m_dec.o
|
||||
OBJS-$(CONFIG_H264_V4L2M2M_ENCODER) += v4l2_m2m_enc.o
|
||||
@@ -439,23 +429,22 @@ OBJS-$(CONFIG_HCA_DECODER) += hcadec.o
|
||||
OBJS-$(CONFIG_HCOM_DECODER) += hcom.o
|
||||
OBJS-$(CONFIG_HDR_DECODER) += hdrdec.o
|
||||
OBJS-$(CONFIG_HDR_ENCODER) += hdrenc.o
|
||||
OBJS-$(CONFIG_HEVC_DECODER) += aom_film_grain.o h274.o container_fifo.o
|
||||
OBJS-$(CONFIG_HEVC_DECODER) += hevcdec.o hevc_mvs.o \
|
||||
hevc_cabac.o hevc_refs.o hevcpred.o \
|
||||
hevcdsp.o hevc_filter.o hevc_data.o \
|
||||
h274.o aom_film_grain.o
|
||||
OBJS-$(CONFIG_HEVC_AMF_ENCODER) += amfenc_hevc.o
|
||||
OBJS-$(CONFIG_HEVC_CUVID_DECODER) += cuviddec.o
|
||||
OBJS-$(CONFIG_HEVC_D3D12VA_ENCODER) += d3d12va_encode_hevc.o h265_profile_level.o \
|
||||
h2645data.o
|
||||
OBJS-$(CONFIG_HEVC_MEDIACODEC_DECODER) += mediacodecdec.o
|
||||
OBJS-$(CONFIG_HEVC_MEDIACODEC_ENCODER) += mediacodecenc.o
|
||||
OBJS-$(CONFIG_HEVC_MF_ENCODER) += mfenc.o mf_utils.o
|
||||
OBJS-$(CONFIG_HEVC_NVENC_ENCODER) += nvenc_hevc.o nvenc.o
|
||||
OBJS-$(CONFIG_HEVC_QSV_DECODER) += qsvdec.o
|
||||
OBJS-$(CONFIG_HEVC_QSV_ENCODER) += qsvenc_hevc.o hevc/ps_enc.o
|
||||
OBJS-$(CONFIG_HEVC_QSV_ENCODER) += qsvenc_hevc.o hevc_ps_enc.o \
|
||||
hevc_data.o
|
||||
OBJS-$(CONFIG_HEVC_RKMPP_DECODER) += rkmppdec.o
|
||||
OBJS-$(CONFIG_HEVC_VAAPI_ENCODER) += vaapi_encode_h265.o h265_profile_level.o \
|
||||
h2645data.o hw_base_encode_h265.o
|
||||
OBJS-$(CONFIG_HEVC_VULKAN_ENCODER) += vulkan_encode.o vulkan_encode_h265.o \
|
||||
hw_base_encode.o hw_base_encode_h265.o \
|
||||
h265_profile_level.o h2645data.o
|
||||
h2645data.o
|
||||
OBJS-$(CONFIG_HEVC_V4L2M2M_DECODER) += v4l2_m2m_dec.o
|
||||
OBJS-$(CONFIG_HEVC_V4L2M2M_ENCODER) += v4l2_m2m_enc.o
|
||||
OBJS-$(CONFIG_HEVC_VIDEOTOOLBOX_ENCODER) += videotoolboxenc.o
|
||||
@@ -532,7 +521,6 @@ OBJS-$(CONFIG_MP2FIXED_ENCODER) += mpegaudioenc_fixed.o mpegaudio.o \
|
||||
mpegaudiotabs.o
|
||||
OBJS-$(CONFIG_MP2FLOAT_DECODER) += mpegaudiodec_float.o
|
||||
OBJS-$(CONFIG_MP3_DECODER) += mpegaudiodec_fixed.o
|
||||
OBJS-$(CONFIG_MP3_MEDIACODEC_DECODER) += mediacodecdec.o
|
||||
OBJS-$(CONFIG_MP3_MF_ENCODER) += mfenc.o mf_utils.o
|
||||
OBJS-$(CONFIG_MP3ADU_DECODER) += mpegaudiodec_fixed.o
|
||||
OBJS-$(CONFIG_MP3ADUFLOAT_DECODER) += mpegaudiodec_float.o
|
||||
@@ -588,7 +576,11 @@ OBJS-$(CONFIG_NELLYMOSER_ENCODER) += nellymoserenc.o nellymoser.o
|
||||
OBJS-$(CONFIG_NOTCHLC_DECODER) += notchlc.o
|
||||
OBJS-$(CONFIG_NUV_DECODER) += nuv.o rtjpeg.o jpegquanttables.o
|
||||
OBJS-$(CONFIG_ON2AVC_DECODER) += on2avc.o on2avcdata.o
|
||||
OBJS-$(CONFIG_OPUS_DECODER) += vorbis_data.o
|
||||
OBJS-$(CONFIG_OPUS_DECODER) += opusdec.o opusdec_celt.o opus_celt.o \
|
||||
opus_pvq.o opus_silk.o opustab.o vorbis_data.o \
|
||||
opusdsp.o opus_parse.o opus_rc.o
|
||||
OBJS-$(CONFIG_OPUS_ENCODER) += opusenc.o opusenc_psy.o opus_celt.o \
|
||||
opus_pvq.o opus_rc.o opustab.o
|
||||
OBJS-$(CONFIG_OSQ_DECODER) += osq.o
|
||||
OBJS-$(CONFIG_PAF_AUDIO_DECODER) += pafaudio.o
|
||||
OBJS-$(CONFIG_PAF_VIDEO_DECODER) += pafvideo.o
|
||||
@@ -617,7 +609,7 @@ OBJS-$(CONFIG_PNG_DECODER) += png.o pngdec.o pngdsp.o
|
||||
OBJS-$(CONFIG_PNG_ENCODER) += png.o pngenc.o
|
||||
OBJS-$(CONFIG_PPM_DECODER) += pnmdec.o pnm.o
|
||||
OBJS-$(CONFIG_PPM_ENCODER) += pnmenc.o
|
||||
OBJS-$(CONFIG_PRORES_DECODER) += proresdec.o proresdsp.o proresdata.o
|
||||
OBJS-$(CONFIG_PRORES_DECODER) += proresdec2.o proresdsp.o proresdata.o
|
||||
OBJS-$(CONFIG_PRORES_ENCODER) += proresenc_anatoliy.o proresdata.o
|
||||
OBJS-$(CONFIG_PRORES_AW_ENCODER) += proresenc_anatoliy.o proresdata.o
|
||||
OBJS-$(CONFIG_PRORES_KS_ENCODER) += proresenc_kostya.o proresdata.o
|
||||
@@ -1132,8 +1124,6 @@ OBJS-$(CONFIG_LIBILBC_ENCODER) += libilbc.o
|
||||
OBJS-$(CONFIG_LIBJXL_DECODER) += libjxldec.o libjxl.o
|
||||
OBJS-$(CONFIG_LIBJXL_ENCODER) += libjxlenc.o libjxl.o
|
||||
OBJS-$(CONFIG_LIBKVAZAAR_ENCODER) += libkvazaar.o
|
||||
OBJS-$(CONFIG_LIBLC3_ENCODER) += liblc3enc.o
|
||||
OBJS-$(CONFIG_LIBLC3_DECODER) += liblc3dec.o
|
||||
OBJS-$(CONFIG_LIBMP3LAME_ENCODER) += libmp3lame.o
|
||||
OBJS-$(CONFIG_LIBOPENCORE_AMRNB_DECODER) += libopencore-amr.o
|
||||
OBJS-$(CONFIG_LIBOPENCORE_AMRNB_ENCODER) += libopencore-amr.o
|
||||
@@ -1161,7 +1151,6 @@ OBJS-$(CONFIG_LIBVPX_VP8_DECODER) += libvpxdec.o
|
||||
OBJS-$(CONFIG_LIBVPX_VP8_ENCODER) += libvpxenc.o
|
||||
OBJS-$(CONFIG_LIBVPX_VP9_DECODER) += libvpxdec.o
|
||||
OBJS-$(CONFIG_LIBVPX_VP9_ENCODER) += libvpxenc.o
|
||||
OBJS-$(CONFIG_LIBVVENC_ENCODER) += libvvenc.o
|
||||
OBJS-$(CONFIG_LIBWEBP_ENCODER) += libwebpenc_common.o libwebpenc.o
|
||||
OBJS-$(CONFIG_LIBWEBP_ANIM_ENCODER) += libwebpenc_common.o libwebpenc_animencoder.o
|
||||
OBJS-$(CONFIG_LIBX262_ENCODER) += libx264.o
|
||||
@@ -1208,6 +1197,7 @@ OBJS-$(CONFIG_GSM_PARSER) += gsm_parser.o
|
||||
OBJS-$(CONFIG_H261_PARSER) += h261_parser.o
|
||||
OBJS-$(CONFIG_H263_PARSER) += h263_parser.o
|
||||
OBJS-$(CONFIG_H264_PARSER) += h264_parser.o h264data.o
|
||||
OBJS-$(CONFIG_HEVC_PARSER) += hevc_parser.o hevc_data.o
|
||||
OBJS-$(CONFIG_HDR_PARSER) += hdr_parser.o
|
||||
OBJS-$(CONFIG_IPU_PARSER) += ipu_parser.o
|
||||
OBJS-$(CONFIG_JPEG2000_PARSER) += jpeg2000_parser.o
|
||||
@@ -1221,7 +1211,8 @@ OBJS-$(CONFIG_MPEG4VIDEO_PARSER) += mpeg4video_parser.o h263.o \
|
||||
OBJS-$(CONFIG_MPEGAUDIO_PARSER) += mpegaudio_parser.o
|
||||
OBJS-$(CONFIG_MPEGVIDEO_PARSER) += mpegvideo_parser.o \
|
||||
mpeg12.o mpeg12data.o
|
||||
OBJS-$(CONFIG_OPUS_PARSER) += vorbis_data.o
|
||||
OBJS-$(CONFIG_OPUS_PARSER) += opus_parser.o opus_parse.o \
|
||||
vorbis_data.o
|
||||
OBJS-$(CONFIG_PNG_PARSER) += png_parser.o
|
||||
OBJS-$(CONFIG_PNM_PARSER) += pnm_parser.o pnm.o
|
||||
OBJS-$(CONFIG_QOI_PARSER) += qoi_parser.o
|
||||
@@ -1272,7 +1263,7 @@ SKIPHEADERS += %_tablegen.h \
|
||||
|
||||
SKIPHEADERS-$(CONFIG_AMF) += amfenc.h
|
||||
SKIPHEADERS-$(CONFIG_D3D11VA) += d3d11va.h dxva2_internal.h
|
||||
SKIPHEADERS-$(CONFIG_D3D12VA) += d3d12va_decode.h d3d12va_encode.h
|
||||
SKIPHEADERS-$(CONFIG_D3D12VA) += d3d12va_decode.h
|
||||
SKIPHEADERS-$(CONFIG_DXVA2) += dxva2.h dxva2_internal.h
|
||||
SKIPHEADERS-$(CONFIG_JNI) += ffjni.h
|
||||
SKIPHEADERS-$(CONFIG_LCMS2) += fflcms2.h
|
||||
@@ -1289,7 +1280,7 @@ SKIPHEADERS-$(CONFIG_QSVENC) += qsvenc.h
|
||||
SKIPHEADERS-$(CONFIG_VAAPI) += vaapi_decode.h vaapi_hevc.h vaapi_encode.h
|
||||
SKIPHEADERS-$(CONFIG_VDPAU) += vdpau.h vdpau_internal.h
|
||||
SKIPHEADERS-$(CONFIG_VIDEOTOOLBOX) += videotoolbox.h vt_internal.h
|
||||
SKIPHEADERS-$(CONFIG_VULKAN) += vulkan.h vulkan_video.h vulkan_encode.h vulkan_decode.h
|
||||
SKIPHEADERS-$(CONFIG_VULKAN) += vulkan.h vulkan_video.h vulkan_decode.h
|
||||
SKIPHEADERS-$(CONFIG_V4L2_M2M) += v4l2_buffers.h v4l2_context.h v4l2_m2m.h
|
||||
SKIPHEADERS-$(CONFIG_ZLIB) += zlib_wrapper.h
|
||||
|
||||
@@ -1357,7 +1348,7 @@ $(GEN_HEADERS): $(SUBDIR)%_tables.h: $(SUBDIR)%_tablegen$(HOSTEXESUF)
|
||||
ifdef CONFIG_HARDCODED_TABLES
|
||||
$(SUBDIR)cbrt_data.o: $(SUBDIR)cbrt_tables.h
|
||||
$(SUBDIR)cbrt_data_fixed.o: $(SUBDIR)cbrt_fixed_tables.h
|
||||
$(SUBDIR)aac/aacdec_fixed.o: $(SUBDIR)sinewin_fixed_tables.h
|
||||
$(SUBDIR)aacdec_fixed.o: $(SUBDIR)sinewin_fixed_tables.h
|
||||
$(SUBDIR)aacps_float.o: $(SUBDIR)aacps_tables.h
|
||||
$(SUBDIR)aacps_fixed.o: $(SUBDIR)aacps_fixed_tables.h
|
||||
$(SUBDIR)dvenc.o: $(SUBDIR)dv_tables.h
|
||||
|
||||
@@ -32,8 +32,8 @@
|
||||
#include "elbg.h"
|
||||
#include "encode.h"
|
||||
#include "libavutil/avassert.h"
|
||||
#include "libavutil/common.h"
|
||||
#include "libavutil/intreadwrite.h"
|
||||
#include "libavutil/mem.h"
|
||||
|
||||
#define DITHERSTEPS 8
|
||||
#define CHARSET_CHARS 256
|
||||
|
||||
+18
-17
@@ -30,8 +30,11 @@
|
||||
#ifndef AVCODEC_AAC_H
|
||||
#define AVCODEC_AAC_H
|
||||
|
||||
|
||||
#include "aac_defines.h"
|
||||
|
||||
#define MAX_CHANNELS 64
|
||||
#define MAX_ELEM_ID 64
|
||||
#define MAX_ELEM_ID 16
|
||||
|
||||
#define TNS_MAX_ORDER 20
|
||||
#define MAX_LTP_LONG_SFB 40
|
||||
@@ -82,6 +85,20 @@ enum ChannelPosition {
|
||||
AAC_CHANNEL_CC = 5,
|
||||
};
|
||||
|
||||
/**
|
||||
* Predictor State
|
||||
*/
|
||||
typedef struct PredictorState {
|
||||
AAC_FLOAT cor0;
|
||||
AAC_FLOAT cor1;
|
||||
AAC_FLOAT var0;
|
||||
AAC_FLOAT var1;
|
||||
AAC_FLOAT r0;
|
||||
AAC_FLOAT r1;
|
||||
AAC_FLOAT k1;
|
||||
AAC_FLOAT x_est;
|
||||
} PredictorState;
|
||||
|
||||
#define MAX_PREDICTORS 672
|
||||
|
||||
#define SCALE_DIV_512 36 ///< scalefactor difference that corresponds to scale difference in 512 times
|
||||
@@ -103,20 +120,4 @@ typedef struct Pulse {
|
||||
int amp[4];
|
||||
} Pulse;
|
||||
|
||||
static inline int ff_aac_sample_rate_idx(int rate)
|
||||
{
|
||||
if (92017 <= rate) return 0;
|
||||
else if (75132 <= rate) return 1;
|
||||
else if (55426 <= rate) return 2;
|
||||
else if (46009 <= rate) return 3;
|
||||
else if (37566 <= rate) return 4;
|
||||
else if (27713 <= rate) return 5;
|
||||
else if (23004 <= rate) return 6;
|
||||
else if (18783 <= rate) return 7;
|
||||
else if (13856 <= rate) return 8;
|
||||
else if (11502 <= rate) return 9;
|
||||
else if (9391 <= rate) return 10;
|
||||
else return 11;
|
||||
}
|
||||
|
||||
#endif /* AVCODEC_AAC_H */
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
clean::
|
||||
$(RM) $(CLEANSUFFIXES:%=libavcodec/aac/%)
|
||||
|
||||
OBJS-$(CONFIG_AAC_DECODER) += aac/aacdec.o aac/aacdec_tab.o \
|
||||
aac/aacdec_float.o aac/aacdec_usac.o \
|
||||
aac/aacdec_ac.o aac/aacdec_lpd.o
|
||||
OBJS-$(CONFIG_AAC_FIXED_DECODER) += aac/aacdec.o aac/aacdec_tab.o \
|
||||
aac/aacdec_fixed.o
|
||||
@@ -1,562 +0,0 @@
|
||||
/*
|
||||
* AAC decoder definitions and structures
|
||||
* Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org )
|
||||
* Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov gmail com )
|
||||
*
|
||||
* 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
|
||||
* AAC decoder definitions and structures
|
||||
* @author Oded Shimon ( ods15 ods15 dyndns org )
|
||||
* @author Maxim Gavrilov ( maxim.gavrilov gmail com )
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_AAC_AACDEC_H
|
||||
#define AVCODEC_AAC_AACDEC_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "libavutil/channel_layout.h"
|
||||
#include "libavutil/float_dsp.h"
|
||||
#include "libavutil/fixed_dsp.h"
|
||||
#include "libavutil/mem_internal.h"
|
||||
#include "libavutil/tx.h"
|
||||
|
||||
#include "libavcodec/aac.h"
|
||||
#include "libavcodec/avcodec.h"
|
||||
#include "libavcodec/mpeg4audio.h"
|
||||
|
||||
#include "aacdec_ac.h"
|
||||
|
||||
typedef struct AACDecContext AACDecContext;
|
||||
|
||||
/**
|
||||
* Output configuration status
|
||||
*/
|
||||
enum OCStatus {
|
||||
OC_NONE, ///< Output unconfigured
|
||||
OC_TRIAL_PCE, ///< Output configuration under trial specified by an inband PCE
|
||||
OC_TRIAL_FRAME, ///< Output configuration under trial specified by a frame header
|
||||
OC_GLOBAL_HDR, ///< Output configuration set in a global header but not yet locked
|
||||
OC_LOCKED, ///< Output configuration locked in place
|
||||
};
|
||||
|
||||
enum AACOutputChannelOrder {
|
||||
CHANNEL_ORDER_DEFAULT,
|
||||
CHANNEL_ORDER_CODED,
|
||||
};
|
||||
|
||||
/**
|
||||
* The point during decoding at which channel coupling is applied.
|
||||
*/
|
||||
enum CouplingPoint {
|
||||
BEFORE_TNS,
|
||||
BETWEEN_TNS_AND_IMDCT,
|
||||
AFTER_IMDCT = 3,
|
||||
};
|
||||
|
||||
enum AACUsacElem {
|
||||
ID_USAC_SCE = 0,
|
||||
ID_USAC_CPE = 1,
|
||||
ID_USAC_LFE = 2,
|
||||
ID_USAC_EXT = 3,
|
||||
};
|
||||
|
||||
enum ExtensionHeaderType {
|
||||
ID_CONFIG_EXT_FILL = 0,
|
||||
ID_CONFIG_EXT_LOUDNESS_INFO = 2,
|
||||
ID_CONFIG_EXT_STREAM_ID = 7,
|
||||
};
|
||||
|
||||
enum AACUsacExtension {
|
||||
ID_EXT_ELE_FILL,
|
||||
ID_EXT_ELE_MPEGS,
|
||||
ID_EXT_ELE_SAOC,
|
||||
ID_EXT_ELE_AUDIOPREROLL,
|
||||
ID_EXT_ELE_UNI_DRC,
|
||||
};
|
||||
|
||||
enum AACUSACLoudnessExt {
|
||||
UNIDRCLOUDEXT_TERM = 0x0,
|
||||
UNIDRCLOUDEXT_EQ = 0x1,
|
||||
};
|
||||
|
||||
// Supposed to be equal to AAC_RENAME() in case of USE_FIXED.
|
||||
#define RENAME_FIXED(name) name ## _fixed
|
||||
|
||||
#define INTFLOAT_UNION(name, elems) \
|
||||
union { \
|
||||
int RENAME_FIXED(name) elems; \
|
||||
float name elems; \
|
||||
}
|
||||
|
||||
#define INTFLOAT_ALIGNED_UNION(alignment, name, nb_elems) \
|
||||
union { \
|
||||
DECLARE_ALIGNED(alignment, int, RENAME_FIXED(name))[nb_elems]; \
|
||||
DECLARE_ALIGNED(alignment, float, name)[nb_elems]; \
|
||||
}
|
||||
/**
|
||||
* Long Term Prediction
|
||||
*/
|
||||
typedef struct LongTermPrediction {
|
||||
int8_t present;
|
||||
int16_t lag;
|
||||
INTFLOAT_UNION(coef,);
|
||||
int8_t used[MAX_LTP_LONG_SFB];
|
||||
} LongTermPrediction;
|
||||
|
||||
/* Per channel core mode */
|
||||
typedef struct AACUsacElemData {
|
||||
uint8_t core_mode;
|
||||
uint8_t scale_factor_grouping;
|
||||
uint8_t tns_data_present;
|
||||
|
||||
/* Timewarping ratio */
|
||||
#define NUM_TW_NODES 16
|
||||
uint8_t tw_ratio[NUM_TW_NODES];
|
||||
|
||||
struct {
|
||||
uint8_t acelp_core_mode : 3;
|
||||
uint8_t lpd_mode : 5;
|
||||
|
||||
uint8_t bpf_control_info : 1;
|
||||
uint8_t core_mode_last : 1;
|
||||
uint8_t fac_data_present : 1;
|
||||
|
||||
int last_lpd_mode;
|
||||
} ldp;
|
||||
|
||||
struct {
|
||||
unsigned int seed;
|
||||
uint8_t level : 3;
|
||||
uint8_t offset : 5;
|
||||
} noise;
|
||||
|
||||
struct {
|
||||
uint8_t gain;
|
||||
uint32_t kv[8 /* (1024 / 16) / 8 */][8];
|
||||
} fac;
|
||||
|
||||
AACArithState ac;
|
||||
} AACUsacElemData;
|
||||
|
||||
/**
|
||||
* Individual Channel Stream
|
||||
*/
|
||||
typedef struct IndividualChannelStream {
|
||||
uint8_t max_sfb; ///< number of scalefactor bands per group
|
||||
enum WindowSequence window_sequence[2];
|
||||
uint8_t use_kb_window[2]; ///< If set, use Kaiser-Bessel window, otherwise use a sine window.
|
||||
int num_window_groups;
|
||||
int prev_num_window_groups; ///< Previous frame's number of window groups
|
||||
uint8_t group_len[8];
|
||||
LongTermPrediction ltp;
|
||||
const uint16_t *swb_offset; ///< table of offsets to the lowest spectral coefficient of a scalefactor band, sfb, for a particular window
|
||||
int num_swb; ///< number of scalefactor window bands
|
||||
int num_windows;
|
||||
int tns_max_bands;
|
||||
int predictor_present;
|
||||
int predictor_initialized;
|
||||
int predictor_reset_group;
|
||||
uint8_t prediction_used[41];
|
||||
uint8_t window_clipping[8]; ///< set if a certain window is near clipping
|
||||
} IndividualChannelStream;
|
||||
|
||||
/**
|
||||
* Temporal Noise Shaping
|
||||
*/
|
||||
typedef struct TemporalNoiseShaping {
|
||||
int present;
|
||||
int n_filt[8];
|
||||
int length[8][4];
|
||||
int direction[8][4];
|
||||
int order[8][4];
|
||||
INTFLOAT_UNION(coef, [8][4][TNS_MAX_ORDER]);
|
||||
} TemporalNoiseShaping;
|
||||
|
||||
/**
|
||||
* coupling parameters
|
||||
*/
|
||||
typedef struct ChannelCoupling {
|
||||
enum CouplingPoint coupling_point; ///< The point during decoding at which coupling is applied.
|
||||
int num_coupled; ///< number of target elements
|
||||
enum RawDataBlockType type[8]; ///< Type of channel element to be coupled - SCE or CPE.
|
||||
int id_select[8]; ///< element id
|
||||
int ch_select[8]; /**< [0] shared list of gains; [1] list of gains for right channel;
|
||||
* [2] list of gains for left channel; [3] lists of gains for both channels
|
||||
*/
|
||||
INTFLOAT_UNION(gain, [16][120]);
|
||||
} ChannelCoupling;
|
||||
|
||||
/**
|
||||
* Single Channel Element - used for both SCE and LFE elements.
|
||||
*/
|
||||
typedef struct SingleChannelElement {
|
||||
IndividualChannelStream ics;
|
||||
AACUsacElemData ue; ///< USAC element data
|
||||
TemporalNoiseShaping tns;
|
||||
enum BandType band_type[128]; ///< band types
|
||||
int sfo[128]; ///< scalefactor offsets
|
||||
INTFLOAT_UNION(sf, [128]); ///< scalefactors (8 windows * 16 sfb max)
|
||||
INTFLOAT_ALIGNED_UNION(32, coeffs, 1024); ///< coefficients for IMDCT, maybe processed
|
||||
INTFLOAT_ALIGNED_UNION(32, prev_coeffs, 1024); ///< unscaled previous contents of coeffs[] for USAC
|
||||
INTFLOAT_ALIGNED_UNION(32, saved, 1536); ///< overlap
|
||||
INTFLOAT_ALIGNED_UNION(32, ret_buf, 2048); ///< PCM output buffer
|
||||
INTFLOAT_ALIGNED_UNION(16, ltp_state, 3072); ///< time signal for LTP
|
||||
union {
|
||||
struct PredictorStateFixed *RENAME_FIXED(predictor_state);
|
||||
struct PredictorState *predictor_state;
|
||||
};
|
||||
union {
|
||||
float *output; ///< PCM output
|
||||
int *RENAME_FIXED(output); ///< PCM output
|
||||
};
|
||||
} SingleChannelElement;
|
||||
|
||||
typedef struct AACUsacStereo {
|
||||
uint8_t common_window;
|
||||
uint8_t common_tw;
|
||||
uint8_t tns_on_lr; ///< Apply TNS before M/S and stereo prediction
|
||||
|
||||
uint8_t ms_mask_mode;
|
||||
uint8_t config_idx;
|
||||
|
||||
/* Complex prediction */
|
||||
uint8_t use_prev_frame;
|
||||
uint8_t pred_dir;
|
||||
uint8_t complex_coef;
|
||||
|
||||
uint8_t pred_used[128];
|
||||
|
||||
INTFLOAT_ALIGNED_UNION(32, alpha_q_re, 1024);
|
||||
INTFLOAT_ALIGNED_UNION(32, alpha_q_im, 1024);
|
||||
INTFLOAT_ALIGNED_UNION(32, prev_alpha_q_re, 1024);
|
||||
INTFLOAT_ALIGNED_UNION(32, prev_alpha_q_im, 1024);
|
||||
|
||||
INTFLOAT_ALIGNED_UNION(32, dmix_re, 1024);
|
||||
INTFLOAT_ALIGNED_UNION(32, prev_dmix_re, 1024); /* Recalculated on every frame */
|
||||
INTFLOAT_ALIGNED_UNION(32, dmix_im, 1024); /* Final prediction data */
|
||||
} AACUsacStereo;
|
||||
|
||||
/**
|
||||
* channel element - generic struct for SCE/CPE/CCE/LFE
|
||||
*/
|
||||
typedef struct ChannelElement {
|
||||
int present;
|
||||
// CPE specific
|
||||
uint8_t max_sfb_ste; ///< (USAC) Maximum of both max_sfb values
|
||||
uint8_t ms_mask[128]; ///< Set if mid/side stereo is used for each scalefactor window band
|
||||
// shared
|
||||
SingleChannelElement ch[2];
|
||||
// CCE specific
|
||||
ChannelCoupling coup;
|
||||
// USAC stereo coupling data
|
||||
AACUsacStereo us;
|
||||
} ChannelElement;
|
||||
|
||||
typedef struct AACUSACLoudnessInfo {
|
||||
uint8_t drc_set_id : 6;
|
||||
uint8_t downmix_id : 7;
|
||||
struct {
|
||||
uint16_t lvl : 12;
|
||||
uint8_t present : 1;
|
||||
} sample_peak;
|
||||
|
||||
struct {
|
||||
uint16_t lvl : 12;
|
||||
uint8_t measurement : 4;
|
||||
uint8_t reliability : 2;
|
||||
uint8_t present : 1;
|
||||
} true_peak;
|
||||
|
||||
uint8_t nb_measurements : 4;
|
||||
struct {
|
||||
uint8_t method_def : 4;
|
||||
uint8_t method_val;
|
||||
uint8_t measurement : 4;
|
||||
uint8_t reliability : 2;
|
||||
} measurements[16];
|
||||
} AACUSACLoudnessInfo;
|
||||
|
||||
typedef struct AACUsacElemConfig {
|
||||
enum AACUsacElem type;
|
||||
|
||||
uint8_t tw_mdct : 1;
|
||||
uint8_t noise_fill : 1;
|
||||
|
||||
uint8_t stereo_config_index;
|
||||
|
||||
struct {
|
||||
int ratio;
|
||||
|
||||
uint8_t harmonic_sbr : 1; /* harmonicSBR */
|
||||
uint8_t bs_intertes : 1; /* bs_interTes */
|
||||
uint8_t bs_pvc : 1; /* bs_pvc */
|
||||
|
||||
struct {
|
||||
uint8_t start_freq; /* dflt_start_freq */
|
||||
uint8_t stop_freq; /* dflt_stop_freq */
|
||||
|
||||
uint8_t freq_scale; /* dflt_freq_scale */
|
||||
uint8_t alter_scale : 1; /* dflt_alter_scale */
|
||||
uint8_t noise_bands; /* dflt_noise_bands */
|
||||
|
||||
uint8_t limiter_bands; /* dflt_limiter_bands */
|
||||
uint8_t limiter_gains; /* dflt_limiter_gains */
|
||||
uint8_t interpol_freq : 1; /* dflt_interpol_freq */
|
||||
uint8_t smoothing_mode : 1; /* dflt_smoothing_mode */
|
||||
} dflt;
|
||||
} sbr;
|
||||
|
||||
struct {
|
||||
uint8_t freq_res; /* bsFreqRes */
|
||||
uint8_t fixed_gain; /* bsFixedGainDMX */
|
||||
uint8_t temp_shape_config; /* bsTempShapeConfig */
|
||||
uint8_t decorr_config; /* bsDecorrConfig */
|
||||
uint8_t high_rate_mode : 1; /* bsHighRateMode */
|
||||
uint8_t phase_coding : 1; /* bsPhaseCoding */
|
||||
|
||||
uint8_t otts_bands_phase; /* bsOttBandsPhase */
|
||||
uint8_t residual_coding; /* bsResidualCoding */
|
||||
uint8_t residual_bands; /* bsResidualBands */
|
||||
uint8_t pseudo_lr : 1; /* bsPseudoLr */
|
||||
uint8_t env_quant_mode : 1; /* bsEnvQuantMode */
|
||||
} mps;
|
||||
|
||||
struct {
|
||||
enum AACUsacExtension type;
|
||||
uint8_t payload_frag;
|
||||
uint32_t default_len;
|
||||
uint32_t pl_data_offset;
|
||||
uint8_t *pl_data;
|
||||
} ext;
|
||||
} AACUsacElemConfig;
|
||||
|
||||
typedef struct AACUSACConfig {
|
||||
uint8_t core_sbr_frame_len_idx; /* coreSbrFrameLengthIndex */
|
||||
uint16_t core_frame_len;
|
||||
uint16_t stream_identifier;
|
||||
|
||||
AACUsacElemConfig elems[64];
|
||||
int nb_elems;
|
||||
|
||||
struct {
|
||||
uint8_t nb_album;
|
||||
AACUSACLoudnessInfo album_info[64];
|
||||
uint8_t nb_info;
|
||||
AACUSACLoudnessInfo info[64];
|
||||
} loudness;
|
||||
} AACUSACConfig;
|
||||
|
||||
typedef struct OutputConfiguration {
|
||||
MPEG4AudioConfig m4ac;
|
||||
uint8_t layout_map[MAX_ELEM_ID*4][3];
|
||||
int layout_map_tags;
|
||||
AVChannelLayout ch_layout;
|
||||
enum OCStatus status;
|
||||
AACUSACConfig usac;
|
||||
} OutputConfiguration;
|
||||
|
||||
/**
|
||||
* Dynamic Range Control - decoded from the bitstream but not processed further.
|
||||
*/
|
||||
typedef struct DynamicRangeControl {
|
||||
int pce_instance_tag; ///< Indicates with which program the DRC info is associated.
|
||||
int dyn_rng_sgn[17]; ///< DRC sign information; 0 - positive, 1 - negative
|
||||
int dyn_rng_ctl[17]; ///< DRC magnitude information
|
||||
int exclude_mask[MAX_CHANNELS]; ///< Channels to be excluded from DRC processing.
|
||||
int band_incr; ///< Number of DRC bands greater than 1 having DRC info.
|
||||
int interpolation_scheme; ///< Indicates the interpolation scheme used in the SBR QMF domain.
|
||||
int band_top[17]; ///< Indicates the top of the i-th DRC band in units of 4 spectral lines.
|
||||
int prog_ref_level; /**< A reference level for the long-term program audio level for all
|
||||
* channels combined.
|
||||
*/
|
||||
} DynamicRangeControl;
|
||||
|
||||
/**
|
||||
* Decode-specific primitives
|
||||
*/
|
||||
typedef struct AACDecProc {
|
||||
int (*decode_spectrum_and_dequant)(AACDecContext *ac,
|
||||
GetBitContext *gb,
|
||||
const Pulse *pulse,
|
||||
SingleChannelElement *sce);
|
||||
|
||||
int (*decode_cce)(AACDecContext *ac, GetBitContext *gb, ChannelElement *che);
|
||||
|
||||
int (*sbr_ctx_alloc_init)(AACDecContext *ac, ChannelElement **che, int id_aac);
|
||||
int (*sbr_decode_extension)(AACDecContext *ac, ChannelElement *che,
|
||||
GetBitContext *gb, int crc, int cnt, int id_aac);
|
||||
void (*sbr_apply)(AACDecContext *ac, ChannelElement *che,
|
||||
int id_aac, void /* INTFLOAT */ *L, void /* INTFLOAT */ *R);
|
||||
void (*sbr_ctx_close)(ChannelElement *che);
|
||||
} AACDecProc;
|
||||
|
||||
/**
|
||||
* DSP-specific primitives
|
||||
*/
|
||||
typedef struct AACDecDSP {
|
||||
void (*dequant_scalefactors)(SingleChannelElement *sce);
|
||||
|
||||
void (*apply_mid_side_stereo)(AACDecContext *ac, ChannelElement *cpe);
|
||||
void (*apply_intensity_stereo)(AACDecContext *ac, ChannelElement *cpe,
|
||||
int ms_present);
|
||||
|
||||
void (*apply_tns)(void *_coef_param, TemporalNoiseShaping *tns,
|
||||
IndividualChannelStream *ics, int decode);
|
||||
|
||||
void (*apply_ltp)(AACDecContext *ac, SingleChannelElement *sce);
|
||||
void (*update_ltp)(AACDecContext *ac, SingleChannelElement *sce);
|
||||
|
||||
void (*apply_prediction)(AACDecContext *ac, SingleChannelElement *sce);
|
||||
|
||||
void (*apply_dependent_coupling)(AACDecContext *ac,
|
||||
SingleChannelElement *target,
|
||||
ChannelElement *cce, int index);
|
||||
void (*apply_independent_coupling)(AACDecContext *ac,
|
||||
SingleChannelElement *target,
|
||||
ChannelElement *cce, int index);
|
||||
|
||||
void (*imdct_and_windowing)(AACDecContext *ac, SingleChannelElement *sce);
|
||||
void (*imdct_and_windowing_768)(AACDecContext *ac, SingleChannelElement *sce);
|
||||
void (*imdct_and_windowing_960)(AACDecContext *ac, SingleChannelElement *sce);
|
||||
void (*imdct_and_windowing_ld)(AACDecContext *ac, SingleChannelElement *sce);
|
||||
void (*imdct_and_windowing_eld)(AACDecContext *ac, SingleChannelElement *sce);
|
||||
|
||||
void (*clip_output)(AACDecContext *ac, ChannelElement *che, int type, int samples);
|
||||
} AACDecDSP;
|
||||
|
||||
/**
|
||||
* main AAC decoding context
|
||||
*/
|
||||
struct AACDecContext {
|
||||
const struct AVClass *class;
|
||||
struct AVCodecContext *avctx;
|
||||
|
||||
AACDecDSP dsp;
|
||||
AACDecProc proc;
|
||||
|
||||
struct AVFrame *frame;
|
||||
|
||||
int is_saved; ///< Set if elements have stored overlap from previous frame.
|
||||
DynamicRangeControl che_drc;
|
||||
|
||||
/**
|
||||
* @name Channel element related data
|
||||
* @{
|
||||
*/
|
||||
ChannelElement *che[4][MAX_ELEM_ID];
|
||||
ChannelElement *tag_che_map[4][MAX_ELEM_ID];
|
||||
int tags_mapped;
|
||||
int warned_remapping_once;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name temporary aligned temporary buffers
|
||||
* (We do not want to have these on the stack.)
|
||||
* @{
|
||||
*/
|
||||
INTFLOAT_ALIGNED_UNION(32, buf_mdct, 1024);
|
||||
INTFLOAT_ALIGNED_UNION(32, temp, 128);
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Computed / set up during initialization
|
||||
* @{
|
||||
*/
|
||||
AVTXContext *mdct96;
|
||||
AVTXContext *mdct120;
|
||||
AVTXContext *mdct128;
|
||||
AVTXContext *mdct480;
|
||||
AVTXContext *mdct512;
|
||||
AVTXContext *mdct768;
|
||||
AVTXContext *mdct960;
|
||||
AVTXContext *mdct1024;
|
||||
AVTXContext *mdct_ltp;
|
||||
|
||||
av_tx_fn mdct96_fn;
|
||||
av_tx_fn mdct120_fn;
|
||||
av_tx_fn mdct128_fn;
|
||||
av_tx_fn mdct480_fn;
|
||||
av_tx_fn mdct512_fn;
|
||||
av_tx_fn mdct768_fn;
|
||||
av_tx_fn mdct960_fn;
|
||||
av_tx_fn mdct1024_fn;
|
||||
av_tx_fn mdct_ltp_fn;
|
||||
union {
|
||||
AVFixedDSPContext *RENAME_FIXED(fdsp);
|
||||
AVFloatDSPContext *fdsp;
|
||||
};
|
||||
int random_state;
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Members used for output
|
||||
* @{
|
||||
*/
|
||||
SingleChannelElement *output_element[MAX_CHANNELS]; ///< Points to each SingleChannelElement
|
||||
/** @} */
|
||||
|
||||
|
||||
/**
|
||||
* @name Japanese DTV specific extension
|
||||
* @{
|
||||
*/
|
||||
int force_dmono_mode;///< 0->not dmono, 1->use first channel, 2->use second channel
|
||||
int dmono_mode; ///< 0->not dmono, 1->use first channel, 2->use second channel
|
||||
/** @} */
|
||||
|
||||
enum AACOutputChannelOrder output_channel_order;
|
||||
|
||||
OutputConfiguration oc[2];
|
||||
int warned_num_aac_frames;
|
||||
int warned_960_sbr;
|
||||
unsigned warned_71_wide;
|
||||
int warned_gain_control;
|
||||
int warned_he_aac_mono;
|
||||
|
||||
int is_fixed;
|
||||
};
|
||||
|
||||
#if defined(USE_FIXED) && USE_FIXED
|
||||
#define fdsp RENAME_FIXED(fdsp)
|
||||
#endif
|
||||
|
||||
int ff_aac_decode_init(AVCodecContext *avctx);
|
||||
int ff_aac_decode_init_float(AVCodecContext *avctx);
|
||||
int ff_aac_decode_init_fixed(AVCodecContext *avctx);
|
||||
|
||||
int ff_aac_decode_ics(AACDecContext *ac, SingleChannelElement *sce,
|
||||
GetBitContext *gb, int common_window, int scale_flag);
|
||||
|
||||
int ff_aac_decode_tns(AACDecContext *ac, TemporalNoiseShaping *tns,
|
||||
GetBitContext *gb, const IndividualChannelStream *ics);
|
||||
|
||||
int ff_aac_set_default_channel_config(AACDecContext *ac, AVCodecContext *avctx,
|
||||
uint8_t (*layout_map)[3],
|
||||
int *tags,
|
||||
int channel_config);
|
||||
|
||||
int ff_aac_output_configure(AACDecContext *ac,
|
||||
uint8_t layout_map[MAX_ELEM_ID * 4][3], int tags,
|
||||
enum OCStatus oc_type, int get_new_frame);
|
||||
|
||||
ChannelElement *ff_aac_get_che(AACDecContext *ac, int type, int elem_id);
|
||||
|
||||
#endif /* AVCODEC_AAC_AACDEC_H */
|
||||
@@ -1,208 +0,0 @@
|
||||
/*
|
||||
* AAC definitions and structures
|
||||
* Copyright (c) 2024 Lynne
|
||||
*
|
||||
* 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 "libavcodec/aactab.h"
|
||||
#include "aacdec_ac.h"
|
||||
|
||||
uint32_t ff_aac_ac_map_process(AACArithState *state, int reset, int N)
|
||||
{
|
||||
float ratio;
|
||||
if (reset) {
|
||||
memset(state->last, 0, sizeof(state->last));
|
||||
state->last_len = N;
|
||||
} else if (state->last_len != N) {
|
||||
int i;
|
||||
uint8_t last[512 /* 2048 / 4 */];
|
||||
memcpy(last, state->last, sizeof(last));
|
||||
|
||||
ratio = state->last_len / (float)N;
|
||||
for (i = 0; i < N/2; i++) {
|
||||
int k = (int)(i * ratio);
|
||||
state->last[i] = last[k];
|
||||
}
|
||||
|
||||
for (; i < FF_ARRAY_ELEMS(state->last); i++)
|
||||
state->last[i] = 0;
|
||||
|
||||
state->last_len = N;
|
||||
}
|
||||
|
||||
state->cur[3] = 0;
|
||||
state->cur[2] = 0;
|
||||
state->cur[1] = 0;
|
||||
state->cur[0] = 1;
|
||||
|
||||
state->state_pre = state->last[0] << 12;
|
||||
return state->last[0] << 12;
|
||||
}
|
||||
|
||||
uint32_t ff_aac_ac_get_context(AACArithState *state, uint32_t c, int i, int N)
|
||||
{
|
||||
c = state->state_pre >> 8;
|
||||
c = c + (state->last[i + 1] << 8);
|
||||
c = (c << 4);
|
||||
c += state->cur[1];
|
||||
|
||||
state->state_pre = c;
|
||||
|
||||
if (i > 3 &&
|
||||
((state->cur[3] + state->cur[2] + state->cur[1]) < 5))
|
||||
return c + 0x10000;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
uint32_t ff_aac_ac_get_pk(uint32_t c)
|
||||
{
|
||||
int i_min = -1;
|
||||
int i, j;
|
||||
int i_max = FF_ARRAY_ELEMS(ff_aac_ac_lookup_m) - 1;
|
||||
while ((i_max - i_min) > 1) {
|
||||
i = i_min + ((i_max - i_min) / 2);
|
||||
j = ff_aac_ac_hash_m[i];
|
||||
if (c < (j >> 8))
|
||||
i_max = i;
|
||||
else if (c > (j >> 8))
|
||||
i_min = i;
|
||||
else
|
||||
return (j & 0xFF);
|
||||
}
|
||||
return ff_aac_ac_lookup_m[i_max];
|
||||
}
|
||||
|
||||
void ff_aac_ac_update_context(AACArithState *state, int idx,
|
||||
uint16_t a, uint16_t b)
|
||||
{
|
||||
state->cur[0] = a + b + 1;
|
||||
if (state->cur[0] > 0xF)
|
||||
state->cur[0] = 0xF;
|
||||
|
||||
state->cur[3] = state->cur[2];
|
||||
state->cur[2] = state->cur[1];
|
||||
state->cur[1] = state->cur[0];
|
||||
|
||||
state->last[idx] = state->cur[0];
|
||||
}
|
||||
|
||||
/* Initialize AC */
|
||||
void ff_aac_ac_init(AACArith *ac, GetBitContext *gb)
|
||||
{
|
||||
ac->low = 0;
|
||||
ac->high = UINT16_MAX;
|
||||
ac->val = get_bits(gb, 16);
|
||||
}
|
||||
|
||||
uint16_t ff_aac_ac_decode(AACArith *ac, GetBitContext *gb,
|
||||
const uint16_t *cdf, uint16_t cdf_len)
|
||||
{
|
||||
int val = ac->val;
|
||||
int low = ac->low;
|
||||
int high = ac->high;
|
||||
|
||||
int sym;
|
||||
int rng = high - low + 1;
|
||||
int c = ((((int)(val - low + 1)) << 14) - ((int)1));
|
||||
|
||||
const uint16_t *p = cdf - 1;
|
||||
|
||||
/* One for each possible CDF length in the spec */
|
||||
switch (cdf_len) {
|
||||
case 2:
|
||||
if ((p[1] * rng) > c)
|
||||
p += 1;
|
||||
break;
|
||||
case 4:
|
||||
if ((p[2] * rng) > c)
|
||||
p += 2;
|
||||
if ((p[1] * rng) > c)
|
||||
p += 1;
|
||||
break;
|
||||
case 17:
|
||||
/* First check if the current probability is even met at all */
|
||||
if ((p[1] * rng) <= c)
|
||||
break;
|
||||
p += 1;
|
||||
for (int i = 8; i >= 1; i >>= 1)
|
||||
if ((p[i] * rng) > c)
|
||||
p += i;
|
||||
break;
|
||||
case 27:
|
||||
if ((p[16] * rng) > c)
|
||||
p += 16;
|
||||
if ((p[8] * rng) > c)
|
||||
p += 8;
|
||||
if (p != (cdf - 1 + 24))
|
||||
if ((p[4] * rng) > c)
|
||||
p += 4;
|
||||
if ((p[2] * rng) > c)
|
||||
p += 2;
|
||||
|
||||
if (p != (cdf - 1 + 24 + 2))
|
||||
if ((p[1] * rng) > c)
|
||||
p += 1;
|
||||
break;
|
||||
default:
|
||||
/* This should never happen */
|
||||
av_assert2(0);
|
||||
}
|
||||
|
||||
sym = (int)((ptrdiff_t)(p - cdf)) + 1;
|
||||
if (sym)
|
||||
high = low + ((rng * cdf[sym - 1]) >> 14) - 1;
|
||||
low += (rng * cdf[sym]) >> 14;
|
||||
|
||||
/* This loop could be done faster */
|
||||
while (1) {
|
||||
if (high < 32768) {
|
||||
;
|
||||
} else if (low >= 32768) {
|
||||
val -= 32768;
|
||||
low -= 32768;
|
||||
high -= 32768;
|
||||
} else if (low >= 16384 && high < 49152) {
|
||||
val -= 16384;
|
||||
low -= 16384;
|
||||
high -= 16384;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
low += low;
|
||||
high += high + 1;
|
||||
val = (val << 1) | get_bits1(gb);
|
||||
};
|
||||
|
||||
ac->low = low;
|
||||
ac->high = high;
|
||||
ac->val = val;
|
||||
|
||||
return sym;
|
||||
}
|
||||
|
||||
void ff_aac_ac_finish(AACArithState *state, int offset, int N)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = offset; i < N/2; i++)
|
||||
state->last[i] = 1;
|
||||
|
||||
for (; i < FF_ARRAY_ELEMS(state->last); i++)
|
||||
state->last[i] = 0;
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
* AAC definitions and structures
|
||||
* Copyright (c) 2024 Lynne
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_AAC_AACDEC_AC_H
|
||||
#define AVCODEC_AAC_AACDEC_AC_H
|
||||
|
||||
#include "libavcodec/get_bits.h"
|
||||
|
||||
typedef struct AACArithState {
|
||||
uint8_t last[512 /* 2048 / 4 */ + 1];
|
||||
int last_len;
|
||||
uint8_t cur[4];
|
||||
uint16_t state_pre;
|
||||
} AACArithState;
|
||||
|
||||
typedef struct AACArith {
|
||||
uint16_t low;
|
||||
uint16_t high;
|
||||
uint16_t val;
|
||||
} AACArith;
|
||||
|
||||
#define FF_AAC_AC_ESCAPE 16
|
||||
|
||||
uint32_t ff_aac_ac_map_process(AACArithState *state, int reset, int len);
|
||||
uint32_t ff_aac_ac_get_context(AACArithState *state, uint32_t old_c, int idx, int len);
|
||||
uint32_t ff_aac_ac_get_pk(uint32_t c);
|
||||
|
||||
void ff_aac_ac_update_context(AACArithState *state, int idx, uint16_t a, uint16_t b);
|
||||
void ff_aac_ac_init(AACArith *ac, GetBitContext *gb);
|
||||
|
||||
uint16_t ff_aac_ac_decode(AACArith *ac, GetBitContext *gb,
|
||||
const uint16_t *cdf, uint16_t cdf_len);
|
||||
|
||||
void ff_aac_ac_finish(AACArithState *state, int offset, int nb);
|
||||
|
||||
#endif /* AVCODEC_AACDEC_AC_H */
|
||||
@@ -1,688 +0,0 @@
|
||||
/*
|
||||
* AAC decoder
|
||||
* Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org )
|
||||
* Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov gmail com )
|
||||
* Copyright (c) 2008-2013 Alex Converse <alex.converse@gmail.com>
|
||||
*
|
||||
* AAC LATM decoder
|
||||
* Copyright (c) 2008-2010 Paul Kendall <paul@kcbbs.gen.nz>
|
||||
* Copyright (c) 2010 Janne Grunau <janne-libav@jannau.net>
|
||||
*
|
||||
* AAC decoder fixed-point implementation
|
||||
* Copyright (c) 2013
|
||||
* MIPS Technologies, Inc., California.
|
||||
*
|
||||
* 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 "aacdec.h"
|
||||
#include "libavcodec/lpc_functions.h"
|
||||
|
||||
#include "libavcodec/aactab.h"
|
||||
|
||||
/**
|
||||
* Convert integer scalefactors to the decoder's native expected
|
||||
* scalefactor values.
|
||||
*/
|
||||
static void AAC_RENAME(dequant_scalefactors)(SingleChannelElement *sce)
|
||||
{
|
||||
IndividualChannelStream *ics = &sce->ics;
|
||||
const int *sfo = sce->sfo;
|
||||
INTFLOAT *sf = sce->AAC_RENAME(sf);
|
||||
|
||||
int idx = 0;
|
||||
for (int g = 0; g < ics->num_window_groups; g++) {
|
||||
for (int sfb = 0; sfb < ics->max_sfb; sfb++, idx++) {
|
||||
switch (sce->band_type[g*ics->max_sfb + sfb]) {
|
||||
case ZERO_BT:
|
||||
sf[idx] = FIXR(0.);
|
||||
break;
|
||||
case INTENSITY_BT: /* fallthrough */
|
||||
case INTENSITY_BT2:
|
||||
#if USE_FIXED
|
||||
sf[idx] = 100 - (sfo[idx] + 100);
|
||||
#else
|
||||
sf[idx] = ff_aac_pow2sf_tab[-sfo[idx] - 100 + POW_SF2_ZERO];
|
||||
#endif /* USE_FIXED */
|
||||
break;
|
||||
case NOISE_BT:
|
||||
#if USE_FIXED
|
||||
sf[idx] = -(100 + sfo[idx]);
|
||||
#else
|
||||
sf[idx] = -ff_aac_pow2sf_tab[sfo[idx] + POW_SF2_ZERO];
|
||||
#endif /* USE_FIXED */
|
||||
break;
|
||||
default:
|
||||
#if USE_FIXED
|
||||
sf[idx] = -sfo[idx] - 100;
|
||||
#else
|
||||
sf[idx] = -ff_aac_pow2sf_tab[sfo[idx] + POW_SF2_ZERO];
|
||||
#endif /* USE_FIXED */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mid/Side stereo decoding; reference: 4.6.8.1.3.
|
||||
*/
|
||||
static void AAC_RENAME(apply_mid_side_stereo)(AACDecContext *ac, ChannelElement *cpe)
|
||||
{
|
||||
const IndividualChannelStream *ics = &cpe->ch[0].ics;
|
||||
INTFLOAT *ch0 = cpe->ch[0].AAC_RENAME(coeffs);
|
||||
INTFLOAT *ch1 = cpe->ch[1].AAC_RENAME(coeffs);
|
||||
const uint16_t *offsets = ics->swb_offset;
|
||||
for (int g = 0; g < ics->num_window_groups; g++) {
|
||||
for (int sfb = 0; sfb < cpe->max_sfb_ste; sfb++) {
|
||||
const int idx = g*cpe->max_sfb_ste + sfb;
|
||||
if (cpe->ms_mask[idx] &&
|
||||
cpe->ch[0].band_type[idx] < NOISE_BT &&
|
||||
cpe->ch[1].band_type[idx] < NOISE_BT) {
|
||||
for (int group = 0; group < ics->group_len[g]; group++)
|
||||
#if USE_FIXED
|
||||
ac->fdsp->butterflies_fixed(ch0 + group * 128 + offsets[sfb],
|
||||
ch1 + group * 128 + offsets[sfb],
|
||||
offsets[sfb+1] - offsets[sfb]);
|
||||
#else
|
||||
ac->fdsp->butterflies_float(ch0 + group * 128 + offsets[sfb],
|
||||
ch1 + group * 128 + offsets[sfb],
|
||||
offsets[sfb+1] - offsets[sfb]);
|
||||
#endif /* USE_FIXED */
|
||||
}
|
||||
}
|
||||
ch0 += ics->group_len[g] * 128;
|
||||
ch1 += ics->group_len[g] * 128;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* intensity stereo decoding; reference: 4.6.8.2.3
|
||||
*
|
||||
* @param ms_present Indicates mid/side stereo presence. [0] mask is all 0s;
|
||||
* [1] mask is decoded from bitstream; [2] mask is all 1s;
|
||||
* [3] reserved for scalable AAC
|
||||
*/
|
||||
static void AAC_RENAME(apply_intensity_stereo)(AACDecContext *ac,
|
||||
ChannelElement *cpe, int ms_present)
|
||||
{
|
||||
const IndividualChannelStream *ics = &cpe->ch[1].ics;
|
||||
SingleChannelElement *sce1 = &cpe->ch[1];
|
||||
INTFLOAT *coef0 = cpe->ch[0].AAC_RENAME(coeffs), *coef1 = cpe->ch[1].AAC_RENAME(coeffs);
|
||||
const uint16_t *offsets = ics->swb_offset;
|
||||
int c;
|
||||
INTFLOAT scale;
|
||||
for (int g = 0; g < ics->num_window_groups; g++) {
|
||||
for (int sfb = 0; sfb < ics->max_sfb; sfb++) {
|
||||
const int idx = g*ics->max_sfb + sfb;
|
||||
if (sce1->band_type[idx] == INTENSITY_BT ||
|
||||
sce1->band_type[idx] == INTENSITY_BT2) {
|
||||
c = -1 + 2 * (sce1->band_type[idx] - 14);
|
||||
if (ms_present)
|
||||
c *= 1 - 2 * cpe->ms_mask[idx];
|
||||
scale = c * sce1->AAC_RENAME(sf)[idx];
|
||||
for (int group = 0; group < ics->group_len[g]; group++)
|
||||
#if USE_FIXED
|
||||
subband_scale(coef1 + group * 128 + offsets[sfb],
|
||||
coef0 + group * 128 + offsets[sfb],
|
||||
scale,
|
||||
23,
|
||||
offsets[sfb + 1] - offsets[sfb], ac->avctx);
|
||||
#else
|
||||
ac->fdsp->vector_fmul_scalar(coef1 + group * 128 + offsets[sfb],
|
||||
coef0 + group * 128 + offsets[sfb],
|
||||
scale,
|
||||
offsets[sfb + 1] - offsets[sfb]);
|
||||
#endif /* USE_FIXED */
|
||||
}
|
||||
}
|
||||
coef0 += ics->group_len[g] * 128;
|
||||
coef1 += ics->group_len[g] * 128;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode Temporal Noise Shaping filter coefficients and apply all-pole filters; reference: 4.6.9.3.
|
||||
*
|
||||
* @param decode 1 if tool is used normally, 0 if tool is used in LTP.
|
||||
* @param coef spectral coefficients
|
||||
*/
|
||||
static void AAC_RENAME(apply_tns)(void *_coef_param, TemporalNoiseShaping *tns,
|
||||
IndividualChannelStream *ics, int decode)
|
||||
{
|
||||
const int mmm = FFMIN(ics->tns_max_bands, ics->max_sfb);
|
||||
int w, filt, m, i;
|
||||
int bottom, top, order, start, end, size, inc;
|
||||
INTFLOAT *coef_param = _coef_param;
|
||||
INTFLOAT lpc[TNS_MAX_ORDER];
|
||||
INTFLOAT tmp[TNS_MAX_ORDER+1];
|
||||
UINTFLOAT *coef = coef_param;
|
||||
|
||||
if(!mmm)
|
||||
return;
|
||||
|
||||
for (w = 0; w < ics->num_windows; w++) {
|
||||
bottom = ics->num_swb;
|
||||
for (filt = 0; filt < tns->n_filt[w]; filt++) {
|
||||
top = bottom;
|
||||
bottom = FFMAX(0, top - tns->length[w][filt]);
|
||||
order = tns->order[w][filt];
|
||||
if (order == 0)
|
||||
continue;
|
||||
|
||||
// tns_decode_coef
|
||||
compute_lpc_coefs(tns->AAC_RENAME(coef)[w][filt], order, lpc, 0, 0, 0);
|
||||
|
||||
start = ics->swb_offset[FFMIN(bottom, mmm)];
|
||||
end = ics->swb_offset[FFMIN( top, mmm)];
|
||||
if ((size = end - start) <= 0)
|
||||
continue;
|
||||
if (tns->direction[w][filt]) {
|
||||
inc = -1;
|
||||
start = end - 1;
|
||||
} else {
|
||||
inc = 1;
|
||||
}
|
||||
start += w * 128;
|
||||
|
||||
if (decode) {
|
||||
// ar filter
|
||||
for (m = 0; m < size; m++, start += inc)
|
||||
for (i = 1; i <= FFMIN(m, order); i++)
|
||||
coef[start] -= AAC_MUL26((INTFLOAT)coef[start - i * inc], lpc[i - 1]);
|
||||
} else {
|
||||
// ma filter
|
||||
for (m = 0; m < size; m++, start += inc) {
|
||||
tmp[0] = coef[start];
|
||||
for (i = 1; i <= FFMIN(m, order); i++)
|
||||
coef[start] += AAC_MUL26(tmp[i], lpc[i - 1]);
|
||||
for (i = order; i > 0; i--)
|
||||
tmp[i] = tmp[i - 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply windowing and MDCT to obtain the spectral
|
||||
* coefficient from the predicted sample by LTP.
|
||||
*/
|
||||
static inline void AAC_RENAME(windowing_and_mdct_ltp)(AACDecContext *ac,
|
||||
INTFLOAT *out, INTFLOAT *in,
|
||||
IndividualChannelStream *ics)
|
||||
{
|
||||
const INTFLOAT *lwindow = ics->use_kb_window[0] ? AAC_RENAME2(aac_kbd_long_1024) : AAC_RENAME2(sine_1024);
|
||||
const INTFLOAT *swindow = ics->use_kb_window[0] ? AAC_RENAME2(aac_kbd_short_128) : AAC_RENAME2(sine_128);
|
||||
const INTFLOAT *lwindow_prev = ics->use_kb_window[1] ? AAC_RENAME2(aac_kbd_long_1024) : AAC_RENAME2(sine_1024);
|
||||
const INTFLOAT *swindow_prev = ics->use_kb_window[1] ? AAC_RENAME2(aac_kbd_short_128) : AAC_RENAME2(sine_128);
|
||||
|
||||
if (ics->window_sequence[0] != LONG_STOP_SEQUENCE) {
|
||||
ac->fdsp->vector_fmul(in, in, lwindow_prev, 1024);
|
||||
} else {
|
||||
memset(in, 0, 448 * sizeof(*in));
|
||||
ac->fdsp->vector_fmul(in + 448, in + 448, swindow_prev, 128);
|
||||
}
|
||||
if (ics->window_sequence[0] != LONG_START_SEQUENCE) {
|
||||
ac->fdsp->vector_fmul_reverse(in + 1024, in + 1024, lwindow, 1024);
|
||||
} else {
|
||||
ac->fdsp->vector_fmul_reverse(in + 1024 + 448, in + 1024 + 448, swindow, 128);
|
||||
memset(in + 1024 + 576, 0, 448 * sizeof(*in));
|
||||
}
|
||||
ac->mdct_ltp_fn(ac->mdct_ltp, out, in, sizeof(INTFLOAT));
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the long term prediction
|
||||
*/
|
||||
static void AAC_RENAME(apply_ltp)(AACDecContext *ac, SingleChannelElement *sce)
|
||||
{
|
||||
const LongTermPrediction *ltp = &sce->ics.ltp;
|
||||
const uint16_t *offsets = sce->ics.swb_offset;
|
||||
int i, sfb;
|
||||
|
||||
if (sce->ics.window_sequence[0] != EIGHT_SHORT_SEQUENCE) {
|
||||
INTFLOAT *predTime = sce->AAC_RENAME(output);
|
||||
INTFLOAT *predFreq = ac->AAC_RENAME(buf_mdct);
|
||||
int16_t num_samples = 2048;
|
||||
|
||||
if (ltp->lag < 1024)
|
||||
num_samples = ltp->lag + 1024;
|
||||
for (i = 0; i < num_samples; i++)
|
||||
predTime[i] = AAC_MUL30(sce->AAC_RENAME(ltp_state)[i + 2048 - ltp->lag], ltp->AAC_RENAME(coef));
|
||||
memset(&predTime[i], 0, (2048 - i) * sizeof(*predTime));
|
||||
|
||||
AAC_RENAME(windowing_and_mdct_ltp)(ac, predFreq, predTime, &sce->ics);
|
||||
|
||||
if (sce->tns.present)
|
||||
AAC_RENAME(apply_tns)(predFreq, &sce->tns, &sce->ics, 0);
|
||||
|
||||
for (sfb = 0; sfb < FFMIN(sce->ics.max_sfb, MAX_LTP_LONG_SFB); sfb++)
|
||||
if (ltp->used[sfb])
|
||||
for (i = offsets[sfb]; i < offsets[sfb + 1]; i++)
|
||||
sce->AAC_RENAME(coeffs)[i] += (UINTFLOAT)predFreq[i];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the LTP buffer for next frame
|
||||
*/
|
||||
static void AAC_RENAME(update_ltp)(AACDecContext *ac, SingleChannelElement *sce)
|
||||
{
|
||||
IndividualChannelStream *ics = &sce->ics;
|
||||
INTFLOAT *saved = sce->AAC_RENAME(saved);
|
||||
INTFLOAT *saved_ltp = sce->AAC_RENAME(coeffs);
|
||||
const INTFLOAT *lwindow = ics->use_kb_window[0] ? AAC_RENAME2(aac_kbd_long_1024) : AAC_RENAME2(sine_1024);
|
||||
const INTFLOAT *swindow = ics->use_kb_window[0] ? AAC_RENAME2(aac_kbd_short_128) : AAC_RENAME2(sine_128);
|
||||
int i;
|
||||
|
||||
if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
|
||||
memcpy(saved_ltp, saved, 512 * sizeof(*saved_ltp));
|
||||
memset(saved_ltp + 576, 0, 448 * sizeof(*saved_ltp));
|
||||
ac->fdsp->vector_fmul_reverse(saved_ltp + 448, ac->AAC_RENAME(buf_mdct) + 960, &swindow[64], 64);
|
||||
|
||||
for (i = 0; i < 64; i++)
|
||||
saved_ltp[i + 512] = AAC_MUL31(ac->AAC_RENAME(buf_mdct)[1023 - i], swindow[63 - i]);
|
||||
} else if (1 && ics->window_sequence[0] == LONG_START_SEQUENCE) {
|
||||
memcpy(saved_ltp, ac->AAC_RENAME(buf_mdct) + 512, 448 * sizeof(*saved_ltp));
|
||||
memset(saved_ltp + 576, 0, 448 * sizeof(*saved_ltp));
|
||||
ac->fdsp->vector_fmul_reverse(saved_ltp + 448, ac->AAC_RENAME(buf_mdct) + 960, &swindow[64], 64);
|
||||
|
||||
for (i = 0; i < 64; i++)
|
||||
saved_ltp[i + 512] = AAC_MUL31(ac->AAC_RENAME(buf_mdct)[1023 - i], swindow[63 - i]);
|
||||
} else if (1) { // LONG_STOP or ONLY_LONG
|
||||
ac->fdsp->vector_fmul_reverse(saved_ltp, ac->AAC_RENAME(buf_mdct) + 512, &lwindow[512], 512);
|
||||
|
||||
for (i = 0; i < 512; i++)
|
||||
saved_ltp[i + 512] = AAC_MUL31(ac->AAC_RENAME(buf_mdct)[1023 - i], lwindow[511 - i]);
|
||||
}
|
||||
|
||||
memcpy(sce->AAC_RENAME(ltp_state), sce->AAC_RENAME(ltp_state)+1024,
|
||||
1024 * sizeof(*sce->AAC_RENAME(ltp_state)));
|
||||
memcpy(sce->AAC_RENAME(ltp_state) + 1024, sce->AAC_RENAME(output),
|
||||
1024 * sizeof(*sce->AAC_RENAME(ltp_state)));
|
||||
memcpy(sce->AAC_RENAME(ltp_state) + 2048, saved_ltp,
|
||||
1024 * sizeof(*sce->AAC_RENAME(ltp_state)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Conduct IMDCT and windowing.
|
||||
*/
|
||||
static void AAC_RENAME(imdct_and_windowing)(AACDecContext *ac, SingleChannelElement *sce)
|
||||
{
|
||||
IndividualChannelStream *ics = &sce->ics;
|
||||
INTFLOAT *in = sce->AAC_RENAME(coeffs);
|
||||
INTFLOAT *out = sce->AAC_RENAME(output);
|
||||
INTFLOAT *saved = sce->AAC_RENAME(saved);
|
||||
const INTFLOAT *swindow = ics->use_kb_window[0] ? AAC_RENAME2(aac_kbd_short_128) : AAC_RENAME2(sine_128);
|
||||
const INTFLOAT *lwindow_prev = ics->use_kb_window[1] ? AAC_RENAME2(aac_kbd_long_1024) : AAC_RENAME2(sine_1024);
|
||||
const INTFLOAT *swindow_prev = ics->use_kb_window[1] ? AAC_RENAME2(aac_kbd_short_128) : AAC_RENAME2(sine_128);
|
||||
INTFLOAT *buf = ac->AAC_RENAME(buf_mdct);
|
||||
INTFLOAT *temp = ac->AAC_RENAME(temp);
|
||||
int i;
|
||||
|
||||
// imdct
|
||||
if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
|
||||
for (i = 0; i < 1024; i += 128)
|
||||
ac->mdct128_fn(ac->mdct128, buf + i, in + i, sizeof(INTFLOAT));
|
||||
} else {
|
||||
ac->mdct1024_fn(ac->mdct1024, buf, in, sizeof(INTFLOAT));
|
||||
}
|
||||
|
||||
/* window overlapping
|
||||
* NOTE: To simplify the overlapping code, all 'meaningless' short to long
|
||||
* and long to short transitions are considered to be short to short
|
||||
* transitions. This leaves just two cases (long to long and short to short)
|
||||
* with a little special sauce for EIGHT_SHORT_SEQUENCE.
|
||||
*/
|
||||
if ((ics->window_sequence[1] == ONLY_LONG_SEQUENCE || ics->window_sequence[1] == LONG_STOP_SEQUENCE) &&
|
||||
(ics->window_sequence[0] == ONLY_LONG_SEQUENCE || ics->window_sequence[0] == LONG_START_SEQUENCE)) {
|
||||
ac->fdsp->vector_fmul_window( out, saved, buf, lwindow_prev, 512);
|
||||
} else {
|
||||
memcpy( out, saved, 448 * sizeof(*out));
|
||||
|
||||
if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
|
||||
ac->fdsp->vector_fmul_window(out + 448 + 0*128, saved + 448, buf + 0*128, swindow_prev, 64);
|
||||
ac->fdsp->vector_fmul_window(out + 448 + 1*128, buf + 0*128 + 64, buf + 1*128, swindow, 64);
|
||||
ac->fdsp->vector_fmul_window(out + 448 + 2*128, buf + 1*128 + 64, buf + 2*128, swindow, 64);
|
||||
ac->fdsp->vector_fmul_window(out + 448 + 3*128, buf + 2*128 + 64, buf + 3*128, swindow, 64);
|
||||
ac->fdsp->vector_fmul_window(temp, buf + 3*128 + 64, buf + 4*128, swindow, 64);
|
||||
memcpy( out + 448 + 4*128, temp, 64 * sizeof(*out));
|
||||
} else {
|
||||
ac->fdsp->vector_fmul_window(out + 448, saved + 448, buf, swindow_prev, 64);
|
||||
memcpy( out + 576, buf + 64, 448 * sizeof(*out));
|
||||
}
|
||||
}
|
||||
|
||||
// buffer update
|
||||
if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
|
||||
memcpy( saved, temp + 64, 64 * sizeof(*saved));
|
||||
ac->fdsp->vector_fmul_window(saved + 64, buf + 4*128 + 64, buf + 5*128, swindow, 64);
|
||||
ac->fdsp->vector_fmul_window(saved + 192, buf + 5*128 + 64, buf + 6*128, swindow, 64);
|
||||
ac->fdsp->vector_fmul_window(saved + 320, buf + 6*128 + 64, buf + 7*128, swindow, 64);
|
||||
memcpy( saved + 448, buf + 7*128 + 64, 64 * sizeof(*saved));
|
||||
} else if (ics->window_sequence[0] == LONG_START_SEQUENCE) {
|
||||
memcpy( saved, buf + 512, 448 * sizeof(*saved));
|
||||
memcpy( saved + 448, buf + 7*128 + 64, 64 * sizeof(*saved));
|
||||
} else { // LONG_STOP or ONLY_LONG
|
||||
memcpy( saved, buf + 512, 512 * sizeof(*saved));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Conduct IMDCT and windowing for 768-point frames.
|
||||
*/
|
||||
static void AAC_RENAME(imdct_and_windowing_768)(AACDecContext *ac, SingleChannelElement *sce)
|
||||
{
|
||||
IndividualChannelStream *ics = &sce->ics;
|
||||
INTFLOAT *in = sce->AAC_RENAME(coeffs);
|
||||
INTFLOAT *out = sce->AAC_RENAME(output);
|
||||
INTFLOAT *saved = sce->AAC_RENAME(saved);
|
||||
const INTFLOAT *swindow = ics->use_kb_window[0] ? AAC_RENAME(aac_kbd_short_96) : AAC_RENAME(sine_96);
|
||||
const INTFLOAT *lwindow_prev = ics->use_kb_window[1] ? AAC_RENAME(aac_kbd_long_768) : AAC_RENAME(sine_768);
|
||||
const INTFLOAT *swindow_prev = ics->use_kb_window[1] ? AAC_RENAME(aac_kbd_short_96) : AAC_RENAME(sine_96);
|
||||
INTFLOAT *buf = ac->AAC_RENAME(buf_mdct);
|
||||
INTFLOAT *temp = ac->AAC_RENAME(temp);
|
||||
int i;
|
||||
|
||||
// imdct
|
||||
if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
|
||||
for (i = 0; i < 8; i++)
|
||||
ac->mdct96_fn(ac->mdct96, buf + i * 96, in + i * 96, sizeof(INTFLOAT));
|
||||
} else {
|
||||
ac->mdct768_fn(ac->mdct768, buf, in, sizeof(INTFLOAT));
|
||||
}
|
||||
|
||||
/* window overlapping
|
||||
* NOTE: To simplify the overlapping code, all 'meaningless' short to long
|
||||
* and long to short transitions are considered to be short to short
|
||||
* transitions. This leaves just two cases (long to long and short to short)
|
||||
* with a little special sauce for EIGHT_SHORT_SEQUENCE.
|
||||
*/
|
||||
|
||||
if ((ics->window_sequence[1] == ONLY_LONG_SEQUENCE || ics->window_sequence[1] == LONG_STOP_SEQUENCE) &&
|
||||
(ics->window_sequence[0] == ONLY_LONG_SEQUENCE || ics->window_sequence[0] == LONG_START_SEQUENCE)) {
|
||||
ac->fdsp->vector_fmul_window( out, saved, buf, lwindow_prev, 384);
|
||||
} else {
|
||||
memcpy( out, saved, 336 * sizeof(*out));
|
||||
|
||||
if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
|
||||
ac->fdsp->vector_fmul_window(out + 336 + 0*96, saved + 336, buf + 0*96, swindow_prev, 48);
|
||||
ac->fdsp->vector_fmul_window(out + 336 + 1*96, buf + 0*96 + 48, buf + 1*96, swindow, 48);
|
||||
ac->fdsp->vector_fmul_window(out + 336 + 2*96, buf + 1*96 + 48, buf + 2*96, swindow, 48);
|
||||
ac->fdsp->vector_fmul_window(out + 336 + 3*96, buf + 2*96 + 48, buf + 3*96, swindow, 48);
|
||||
ac->fdsp->vector_fmul_window(temp, buf + 3*96 + 48, buf + 4*96, swindow, 48);
|
||||
memcpy( out + 336 + 4*96, temp, 48 * sizeof(*out));
|
||||
} else {
|
||||
ac->fdsp->vector_fmul_window(out + 336, saved + 336, buf, swindow_prev, 48);
|
||||
memcpy( out + 432, buf + 48, 336 * sizeof(*out));
|
||||
}
|
||||
}
|
||||
|
||||
// buffer update
|
||||
if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
|
||||
memcpy( saved, temp + 48, 48 * sizeof(*saved));
|
||||
ac->fdsp->vector_fmul_window(saved + 48, buf + 4*96 + 48, buf + 5*96, swindow, 48);
|
||||
ac->fdsp->vector_fmul_window(saved + 144, buf + 5*96 + 48, buf + 6*96, swindow, 48);
|
||||
ac->fdsp->vector_fmul_window(saved + 240, buf + 6*96 + 48, buf + 7*96, swindow, 48);
|
||||
memcpy( saved + 336, buf + 7*96 + 48, 48 * sizeof(*saved));
|
||||
} else if (ics->window_sequence[0] == LONG_START_SEQUENCE) {
|
||||
memcpy( saved, buf + 384, 336 * sizeof(*saved));
|
||||
memcpy( saved + 336, buf + 7*96 + 48, 48 * sizeof(*saved));
|
||||
} else { // LONG_STOP or ONLY_LONG
|
||||
memcpy( saved, buf + 384, 384 * sizeof(*saved));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Conduct IMDCT and windowing.
|
||||
*/
|
||||
static void AAC_RENAME(imdct_and_windowing_960)(AACDecContext *ac, SingleChannelElement *sce)
|
||||
{
|
||||
IndividualChannelStream *ics = &sce->ics;
|
||||
INTFLOAT *in = sce->AAC_RENAME(coeffs);
|
||||
INTFLOAT *out = sce->AAC_RENAME(output);
|
||||
INTFLOAT *saved = sce->AAC_RENAME(saved);
|
||||
const INTFLOAT *swindow = ics->use_kb_window[0] ? AAC_RENAME(aac_kbd_short_120) : AAC_RENAME(sine_120);
|
||||
const INTFLOAT *lwindow_prev = ics->use_kb_window[1] ? AAC_RENAME(aac_kbd_long_960) : AAC_RENAME(sine_960);
|
||||
const INTFLOAT *swindow_prev = ics->use_kb_window[1] ? AAC_RENAME(aac_kbd_short_120) : AAC_RENAME(sine_120);
|
||||
INTFLOAT *buf = ac->AAC_RENAME(buf_mdct);
|
||||
INTFLOAT *temp = ac->AAC_RENAME(temp);
|
||||
int i;
|
||||
|
||||
// imdct
|
||||
if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
|
||||
for (i = 0; i < 8; i++)
|
||||
ac->mdct120_fn(ac->mdct120, buf + i * 120, in + i * 128, sizeof(INTFLOAT));
|
||||
} else {
|
||||
ac->mdct960_fn(ac->mdct960, buf, in, sizeof(INTFLOAT));
|
||||
}
|
||||
|
||||
/* window overlapping
|
||||
* NOTE: To simplify the overlapping code, all 'meaningless' short to long
|
||||
* and long to short transitions are considered to be short to short
|
||||
* transitions. This leaves just two cases (long to long and short to short)
|
||||
* with a little special sauce for EIGHT_SHORT_SEQUENCE.
|
||||
*/
|
||||
|
||||
if ((ics->window_sequence[1] == ONLY_LONG_SEQUENCE || ics->window_sequence[1] == LONG_STOP_SEQUENCE) &&
|
||||
(ics->window_sequence[0] == ONLY_LONG_SEQUENCE || ics->window_sequence[0] == LONG_START_SEQUENCE)) {
|
||||
ac->fdsp->vector_fmul_window( out, saved, buf, lwindow_prev, 480);
|
||||
} else {
|
||||
memcpy( out, saved, 420 * sizeof(*out));
|
||||
|
||||
if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
|
||||
ac->fdsp->vector_fmul_window(out + 420 + 0*120, saved + 420, buf + 0*120, swindow_prev, 60);
|
||||
ac->fdsp->vector_fmul_window(out + 420 + 1*120, buf + 0*120 + 60, buf + 1*120, swindow, 60);
|
||||
ac->fdsp->vector_fmul_window(out + 420 + 2*120, buf + 1*120 + 60, buf + 2*120, swindow, 60);
|
||||
ac->fdsp->vector_fmul_window(out + 420 + 3*120, buf + 2*120 + 60, buf + 3*120, swindow, 60);
|
||||
ac->fdsp->vector_fmul_window(temp, buf + 3*120 + 60, buf + 4*120, swindow, 60);
|
||||
memcpy( out + 420 + 4*120, temp, 60 * sizeof(*out));
|
||||
} else {
|
||||
ac->fdsp->vector_fmul_window(out + 420, saved + 420, buf, swindow_prev, 60);
|
||||
memcpy( out + 540, buf + 60, 420 * sizeof(*out));
|
||||
}
|
||||
}
|
||||
|
||||
// buffer update
|
||||
if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
|
||||
memcpy( saved, temp + 60, 60 * sizeof(*saved));
|
||||
ac->fdsp->vector_fmul_window(saved + 60, buf + 4*120 + 60, buf + 5*120, swindow, 60);
|
||||
ac->fdsp->vector_fmul_window(saved + 180, buf + 5*120 + 60, buf + 6*120, swindow, 60);
|
||||
ac->fdsp->vector_fmul_window(saved + 300, buf + 6*120 + 60, buf + 7*120, swindow, 60);
|
||||
memcpy( saved + 420, buf + 7*120 + 60, 60 * sizeof(*saved));
|
||||
} else if (ics->window_sequence[0] == LONG_START_SEQUENCE) {
|
||||
memcpy( saved, buf + 480, 420 * sizeof(*saved));
|
||||
memcpy( saved + 420, buf + 7*120 + 60, 60 * sizeof(*saved));
|
||||
} else { // LONG_STOP or ONLY_LONG
|
||||
memcpy( saved, buf + 480, 480 * sizeof(*saved));
|
||||
}
|
||||
}
|
||||
|
||||
static void AAC_RENAME(imdct_and_windowing_ld)(AACDecContext *ac, SingleChannelElement *sce)
|
||||
{
|
||||
IndividualChannelStream *ics = &sce->ics;
|
||||
INTFLOAT *in = sce->AAC_RENAME(coeffs);
|
||||
INTFLOAT *out = sce->AAC_RENAME(output);
|
||||
INTFLOAT *saved = sce->AAC_RENAME(saved);
|
||||
INTFLOAT *buf = ac->AAC_RENAME(buf_mdct);
|
||||
|
||||
// imdct
|
||||
ac->mdct512_fn(ac->mdct512, buf, in, sizeof(INTFLOAT));
|
||||
|
||||
// window overlapping
|
||||
if (ics->use_kb_window[1]) {
|
||||
// AAC LD uses a low overlap sine window instead of a KBD window
|
||||
memcpy(out, saved, 192 * sizeof(*out));
|
||||
ac->fdsp->vector_fmul_window(out + 192, saved + 192, buf, AAC_RENAME2(sine_128), 64);
|
||||
memcpy( out + 320, buf + 64, 192 * sizeof(*out));
|
||||
} else {
|
||||
ac->fdsp->vector_fmul_window(out, saved, buf, AAC_RENAME2(sine_512), 256);
|
||||
}
|
||||
|
||||
// buffer update
|
||||
memcpy(saved, buf + 256, 256 * sizeof(*saved));
|
||||
}
|
||||
|
||||
static void AAC_RENAME(imdct_and_windowing_eld)(AACDecContext *ac, SingleChannelElement *sce)
|
||||
{
|
||||
UINTFLOAT *in = sce->AAC_RENAME(coeffs);
|
||||
INTFLOAT *out = sce->AAC_RENAME(output);
|
||||
INTFLOAT *saved = sce->AAC_RENAME(saved);
|
||||
INTFLOAT *buf = ac->AAC_RENAME(buf_mdct);
|
||||
int i;
|
||||
const int n = ac->oc[1].m4ac.frame_length_short ? 480 : 512;
|
||||
const int n2 = n >> 1;
|
||||
const int n4 = n >> 2;
|
||||
const INTFLOAT *const window = n == 480 ? AAC_RENAME(ff_aac_eld_window_480) :
|
||||
AAC_RENAME(ff_aac_eld_window_512);
|
||||
|
||||
// Inverse transform, mapped to the conventional IMDCT by
|
||||
// Chivukula, R.K.; Reznik, Y.A.; Devarajan, V.,
|
||||
// "Efficient algorithms for MPEG-4 AAC-ELD, AAC-LD and AAC-LC filterbanks,"
|
||||
// International Conference on Audio, Language and Image Processing, ICALIP 2008.
|
||||
// URL: http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=4590245&isnumber=4589950
|
||||
for (i = 0; i < n2; i+=2) {
|
||||
INTFLOAT temp;
|
||||
temp = in[i ]; in[i ] = -in[n - 1 - i]; in[n - 1 - i] = temp;
|
||||
temp = -in[i + 1]; in[i + 1] = in[n - 2 - i]; in[n - 2 - i] = temp;
|
||||
}
|
||||
|
||||
if (n == 480)
|
||||
ac->mdct480_fn(ac->mdct480, buf, in, sizeof(INTFLOAT));
|
||||
else
|
||||
ac->mdct512_fn(ac->mdct512, buf, in, sizeof(INTFLOAT));
|
||||
|
||||
for (i = 0; i < n; i+=2) {
|
||||
buf[i + 0] = -(UINTFLOAT)(USE_FIXED + 1)*buf[i + 0];
|
||||
buf[i + 1] = (UINTFLOAT)(USE_FIXED + 1)*buf[i + 1];
|
||||
}
|
||||
// Like with the regular IMDCT at this point we still have the middle half
|
||||
// of a transform but with even symmetry on the left and odd symmetry on
|
||||
// the right
|
||||
|
||||
// window overlapping
|
||||
// The spec says to use samples [0..511] but the reference decoder uses
|
||||
// samples [128..639].
|
||||
for (i = n4; i < n2; i ++) {
|
||||
out[i - n4] = AAC_MUL31( buf[ n2 - 1 - i] , window[i - n4]) +
|
||||
AAC_MUL31( saved[ i + n2] , window[i + n - n4]) +
|
||||
AAC_MUL31(-saved[n + n2 - 1 - i] , window[i + 2*n - n4]) +
|
||||
AAC_MUL31(-saved[ 2*n + n2 + i] , window[i + 3*n - n4]);
|
||||
}
|
||||
for (i = 0; i < n2; i ++) {
|
||||
out[n4 + i] = AAC_MUL31( buf[ i] , window[i + n2 - n4]) +
|
||||
AAC_MUL31(-saved[ n - 1 - i] , window[i + n2 + n - n4]) +
|
||||
AAC_MUL31(-saved[ n + i] , window[i + n2 + 2*n - n4]) +
|
||||
AAC_MUL31( saved[2*n + n - 1 - i] , window[i + n2 + 3*n - n4]);
|
||||
}
|
||||
for (i = 0; i < n4; i ++) {
|
||||
out[n2 + n4 + i] = AAC_MUL31( buf[ i + n2] , window[i + n - n4]) +
|
||||
AAC_MUL31(-saved[n2 - 1 - i] , window[i + 2*n - n4]) +
|
||||
AAC_MUL31(-saved[n + n2 + i] , window[i + 3*n - n4]);
|
||||
}
|
||||
|
||||
// buffer update
|
||||
memmove(saved + n, saved, 2 * n * sizeof(*saved));
|
||||
memcpy( saved, buf, n * sizeof(*saved));
|
||||
}
|
||||
|
||||
static void AAC_RENAME(clip_output)(AACDecContext *ac, ChannelElement *che,
|
||||
int type, int samples)
|
||||
{
|
||||
#if USE_FIXED
|
||||
/* preparation for resampler */
|
||||
for (int j = 0; j < samples; j++){
|
||||
che->ch[0].output_fixed[j] = (int32_t)av_clip64((int64_t)che->ch[0].output_fixed[j]*128,
|
||||
INT32_MIN, INT32_MAX-0x8000)+0x8000;
|
||||
if (type == TYPE_CPE || (type == TYPE_SCE && ac->oc[1].m4ac.ps == 1))
|
||||
che->ch[1].output_fixed[j] = (int32_t)av_clip64((int64_t)che->ch[1].output_fixed[j]*128,
|
||||
INT32_MIN, INT32_MAX-0x8000)+0x8000;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void reset_all_predictors(PredictorState *ps)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < MAX_PREDICTORS; i++)
|
||||
reset_predict_state(&ps[i]);
|
||||
}
|
||||
|
||||
static inline void reset_predictor_group(PredictorState *ps, int group_num)
|
||||
{
|
||||
int i;
|
||||
for (i = group_num - 1; i < MAX_PREDICTORS; i += 30)
|
||||
reset_predict_state(&ps[i]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply AAC-Main style frequency domain prediction.
|
||||
*/
|
||||
static void AAC_RENAME(apply_prediction)(AACDecContext *ac, SingleChannelElement *sce)
|
||||
{
|
||||
int sfb, k;
|
||||
|
||||
if (!sce->ics.predictor_initialized) {
|
||||
reset_all_predictors(sce->AAC_RENAME(predictor_state));
|
||||
sce->ics.predictor_initialized = 1;
|
||||
}
|
||||
|
||||
if (sce->ics.window_sequence[0] != EIGHT_SHORT_SEQUENCE) {
|
||||
for (sfb = 0;
|
||||
sfb < ff_aac_pred_sfb_max[ac->oc[1].m4ac.sampling_index];
|
||||
sfb++) {
|
||||
for (k = sce->ics.swb_offset[sfb];
|
||||
k < sce->ics.swb_offset[sfb + 1];
|
||||
k++) {
|
||||
predict(&sce->AAC_RENAME(predictor_state)[k],
|
||||
&sce->AAC_RENAME(coeffs)[k],
|
||||
sce->ics.predictor_present &&
|
||||
sce->ics.prediction_used[sfb]);
|
||||
}
|
||||
}
|
||||
if (sce->ics.predictor_reset_group)
|
||||
reset_predictor_group(sce->AAC_RENAME(predictor_state),
|
||||
sce->ics.predictor_reset_group);
|
||||
} else
|
||||
reset_all_predictors(sce->AAC_RENAME(predictor_state));
|
||||
}
|
||||
|
||||
static av_cold void AAC_RENAME(aac_dsp_init)(AACDecDSP *aac_dsp)
|
||||
{
|
||||
#define SET(member) aac_dsp->member = AAC_RENAME(member)
|
||||
SET(dequant_scalefactors);
|
||||
SET(apply_mid_side_stereo);
|
||||
SET(apply_intensity_stereo);
|
||||
SET(apply_tns);
|
||||
SET(apply_ltp);
|
||||
SET(update_ltp);
|
||||
|
||||
SET(apply_prediction);
|
||||
|
||||
SET(imdct_and_windowing);
|
||||
SET(imdct_and_windowing_768);
|
||||
SET(imdct_and_windowing_960);
|
||||
SET(imdct_and_windowing_ld);
|
||||
SET(imdct_and_windowing_eld);
|
||||
|
||||
SET(apply_dependent_coupling);
|
||||
SET(apply_independent_coupling);
|
||||
|
||||
SET(clip_output);
|
||||
#undef SET
|
||||
}
|
||||
@@ -1,105 +0,0 @@
|
||||
/*
|
||||
* AAC decoder
|
||||
* Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org )
|
||||
* Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov gmail com )
|
||||
* Copyright (c) 2008-2013 Alex Converse <alex.converse@gmail.com>
|
||||
*
|
||||
* AAC LATM decoder
|
||||
* Copyright (c) 2008-2010 Paul Kendall <paul@kcbbs.gen.nz>
|
||||
* Copyright (c) 2010 Janne Grunau <janne-libav@jannau.net>
|
||||
*
|
||||
* AAC decoder fixed-point implementation
|
||||
* Copyright (c) 2013
|
||||
* MIPS Technologies, Inc., California.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#define USE_FIXED 1
|
||||
|
||||
#include "libavutil/thread.h"
|
||||
|
||||
#include "libavcodec/aac_defines.h"
|
||||
|
||||
#include "libavcodec/avcodec.h"
|
||||
#include "aacdec.h"
|
||||
#include "libavcodec/aactab.h"
|
||||
#include "libavcodec/sinewin_fixed_tablegen.h"
|
||||
#include "libavcodec/kbdwin.h"
|
||||
#include "libavcodec/cbrt_data.h"
|
||||
#include "libavcodec/aacsbr.h"
|
||||
|
||||
DECLARE_ALIGNED(32, static int, aac_kbd_long_1024_fixed)[1024];
|
||||
DECLARE_ALIGNED(32, static int, aac_kbd_short_128_fixed)[128];
|
||||
DECLARE_ALIGNED(32, static int, aac_kbd_long_960_fixed)[960];
|
||||
DECLARE_ALIGNED(32, static int, aac_kbd_short_120_fixed)[120];
|
||||
DECLARE_ALIGNED(32, static int, aac_kbd_long_768_fixed)[768];
|
||||
DECLARE_ALIGNED(32, static int, aac_kbd_short_96_fixed)[96];
|
||||
|
||||
static void init_tables_fixed_fn(void)
|
||||
{
|
||||
ff_cbrt_tableinit_fixed();
|
||||
|
||||
ff_kbd_window_init_fixed(aac_kbd_long_1024_fixed, 4.0, 1024);
|
||||
ff_kbd_window_init_fixed(aac_kbd_short_128_fixed, 6.0, 128);
|
||||
|
||||
ff_kbd_window_init_fixed(aac_kbd_long_960_fixed, 4.0, 960);
|
||||
ff_kbd_window_init_fixed(aac_kbd_short_120_fixed, 6.0, 120);
|
||||
|
||||
ff_aac_sbr_init_fixed();
|
||||
|
||||
init_sine_windows_fixed();
|
||||
}
|
||||
|
||||
static const int cce_scale_fixed[8] = {
|
||||
Q30(1.0), //2^(0/8)
|
||||
Q30(1.0905077327), //2^(1/8)
|
||||
Q30(1.1892071150), //2^(2/8)
|
||||
Q30(1.2968395547), //2^(3/8)
|
||||
Q30(1.4142135624), //2^(4/8)
|
||||
Q30(1.5422108254), //2^(5/8)
|
||||
Q30(1.6817928305), //2^(6/8)
|
||||
Q30(1.8340080864), //2^(7/8)
|
||||
};
|
||||
|
||||
/** Dequantization-related */
|
||||
#include "aacdec_fixed_dequant.h"
|
||||
|
||||
#include "aacdec_fixed_coupling.h"
|
||||
#include "aacdec_fixed_prediction.h"
|
||||
#include "aacdec_dsp_template.c"
|
||||
#include "aacdec_proc_template.c"
|
||||
|
||||
av_cold int ff_aac_decode_init_fixed(AVCodecContext *avctx)
|
||||
{
|
||||
static AVOnce init_fixed_once = AV_ONCE_INIT;
|
||||
AACDecContext *ac = avctx->priv_data;
|
||||
|
||||
ac->is_fixed = 1;
|
||||
avctx->sample_fmt = AV_SAMPLE_FMT_S32P;
|
||||
|
||||
aac_dsp_init_fixed(&ac->dsp);
|
||||
aac_proc_init_fixed(&ac->proc);
|
||||
|
||||
ac->fdsp = avpriv_alloc_fixed_dsp(avctx->flags & AV_CODEC_FLAG_BITEXACT);
|
||||
if (!ac->fdsp)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
ff_thread_once(&init_fixed_once, init_tables_fixed_fn);
|
||||
|
||||
return ff_aac_decode_init(avctx);
|
||||
}
|
||||
@@ -1,137 +0,0 @@
|
||||
/*
|
||||
* AAC decoder
|
||||
* Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org )
|
||||
* Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov gmail com )
|
||||
* Copyright (c) 2008-2013 Alex Converse <alex.converse@gmail.com>
|
||||
*
|
||||
* AAC LATM decoder
|
||||
* Copyright (c) 2008-2010 Paul Kendall <paul@kcbbs.gen.nz>
|
||||
* Copyright (c) 2010 Janne Grunau <janne-libav@jannau.net>
|
||||
*
|
||||
* AAC decoder fixed-point implementation
|
||||
* Copyright (c) 2013
|
||||
* MIPS Technologies, Inc., California.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_AAC_AACDEC_FIXED_COUPLING_H
|
||||
#define AVCODEC_AAC_AACDEC_FIXED_COUPLING_H
|
||||
|
||||
#include "aacdec.h"
|
||||
|
||||
/**
|
||||
* Apply dependent channel coupling (applied before IMDCT).
|
||||
*
|
||||
* @param index index into coupling gain array
|
||||
*/
|
||||
static void AAC_RENAME(apply_dependent_coupling)(AACDecContext *ac,
|
||||
SingleChannelElement *target,
|
||||
ChannelElement *cce, int index)
|
||||
{
|
||||
IndividualChannelStream *ics = &cce->ch[0].ics;
|
||||
const uint16_t *offsets = ics->swb_offset;
|
||||
int *dest = target->coeffs_fixed;
|
||||
const int *src = cce->ch[0].coeffs_fixed;
|
||||
int g, i, group, k, idx = 0;
|
||||
if (ac->oc[1].m4ac.object_type == AOT_AAC_LTP) {
|
||||
av_log(ac->avctx, AV_LOG_ERROR,
|
||||
"Dependent coupling is not supported together with LTP\n");
|
||||
return;
|
||||
}
|
||||
for (g = 0; g < ics->num_window_groups; g++) {
|
||||
for (i = 0; i < ics->max_sfb; i++, idx++) {
|
||||
if (cce->ch[0].band_type[idx] != ZERO_BT) {
|
||||
const int gain = cce->coup.gain[index][idx];
|
||||
int shift, round, c, tmp;
|
||||
|
||||
if (gain < 0) {
|
||||
c = -cce_scale_fixed[-gain & 7];
|
||||
shift = (-gain-1024) >> 3;
|
||||
}
|
||||
else {
|
||||
c = cce_scale_fixed[gain & 7];
|
||||
shift = (gain-1024) >> 3;
|
||||
}
|
||||
|
||||
if (shift < -31) {
|
||||
// Nothing to do
|
||||
} else if (shift < 0) {
|
||||
shift = -shift;
|
||||
round = 1 << (shift - 1);
|
||||
|
||||
for (group = 0; group < ics->group_len[g]; group++) {
|
||||
for (k = offsets[i]; k < offsets[i + 1]; k++) {
|
||||
tmp = (int)(((int64_t)src[group * 128 + k] * c + \
|
||||
(int64_t)0x1000000000) >> 37);
|
||||
dest[group * 128 + k] += (tmp + (int64_t)round) >> shift;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (group = 0; group < ics->group_len[g]; group++) {
|
||||
for (k = offsets[i]; k < offsets[i + 1]; k++) {
|
||||
tmp = (int)(((int64_t)src[group * 128 + k] * c + \
|
||||
(int64_t)0x1000000000) >> 37);
|
||||
dest[group * 128 + k] += tmp * (1U << shift);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
dest += ics->group_len[g] * 128;
|
||||
src += ics->group_len[g] * 128;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply independent channel coupling (applied after IMDCT).
|
||||
*
|
||||
* @param index index into coupling gain array
|
||||
*/
|
||||
static void AAC_RENAME(apply_independent_coupling)(AACDecContext *ac,
|
||||
SingleChannelElement *target,
|
||||
ChannelElement *cce, int index)
|
||||
{
|
||||
int i, c, shift, round, tmp;
|
||||
const int gain = cce->coup.gain[index][0];
|
||||
const int *src = cce->ch[0].output_fixed;
|
||||
unsigned int *dest = target->output_fixed;
|
||||
const int len = 1024 << (ac->oc[1].m4ac.sbr == 1);
|
||||
|
||||
c = cce_scale_fixed[gain & 7];
|
||||
shift = (gain-1024) >> 3;
|
||||
if (shift < -31) {
|
||||
return;
|
||||
} else if (shift < 0) {
|
||||
shift = -shift;
|
||||
round = 1 << (shift - 1);
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
tmp = (int)(((int64_t)src[i] * c + (int64_t)0x1000000000) >> 37);
|
||||
dest[i] += (tmp + round) >> shift;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i = 0; i < len; i++) {
|
||||
tmp = (int)(((int64_t)src[i] * c + (int64_t)0x1000000000) >> 37);
|
||||
dest[i] += tmp * (1U << shift);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* AVCODEC_AAC_AACDEC_FIXED_COUPLING_H */
|
||||
@@ -1,174 +0,0 @@
|
||||
/*
|
||||
* AAC decoder
|
||||
* Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org )
|
||||
* Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov gmail com )
|
||||
* Copyright (c) 2008-2013 Alex Converse <alex.converse@gmail.com>
|
||||
*
|
||||
* AAC LATM decoder
|
||||
* Copyright (c) 2008-2010 Paul Kendall <paul@kcbbs.gen.nz>
|
||||
* Copyright (c) 2010 Janne Grunau <janne-libav@jannau.net>
|
||||
*
|
||||
* AAC decoder fixed-point implementation
|
||||
* Copyright (c) 2013
|
||||
* MIPS Technologies, Inc., California.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_AAC_AACDEC_FIXED_DEQUANT_H
|
||||
#define AVCODEC_AAC_AACDEC_FIXED_DEQUANT_H
|
||||
|
||||
#include "aacdec_tab.h"
|
||||
|
||||
static void inline vector_pow43(int *coefs, int len)
|
||||
{
|
||||
int i, coef;
|
||||
|
||||
for (i=0; i<len; i++) {
|
||||
coef = coefs[i];
|
||||
if (coef < 0)
|
||||
coef = -(int)ff_cbrt_tab_fixed[(-coef) & 8191];
|
||||
else
|
||||
coef = (int)ff_cbrt_tab_fixed[ coef & 8191];
|
||||
coefs[i] = coef;
|
||||
}
|
||||
}
|
||||
|
||||
/* 2^0, 2^0.25, 2^0.5, 2^0.75 */
|
||||
static const int exp2tab[4] = {
|
||||
Q31(1.0000000000/2), Q31(1.1892071150/2),
|
||||
Q31(1.4142135624/2), Q31(1.6817928305/2)
|
||||
};
|
||||
|
||||
static void inline subband_scale(int *dst, int *src, int scale,
|
||||
int offset, int len, void *log_context)
|
||||
{
|
||||
int ssign = scale < 0 ? -1 : 1;
|
||||
int s = FFABS(scale);
|
||||
unsigned int round;
|
||||
int i, out, c = exp2tab[s & 3];
|
||||
|
||||
s = offset - (s >> 2);
|
||||
|
||||
if (s > 31) {
|
||||
for (i=0; i<len; i++) {
|
||||
dst[i] = 0;
|
||||
}
|
||||
} else if (s > 0) {
|
||||
round = 1 << (s-1);
|
||||
for (i=0; i<len; i++) {
|
||||
out = (int)(((int64_t)src[i] * c) >> 32);
|
||||
dst[i] = ((int)(out+round) >> s) * ssign;
|
||||
}
|
||||
} else if (s > -32) {
|
||||
s = s + 32;
|
||||
round = 1U << (s-1);
|
||||
for (i=0; i<len; i++) {
|
||||
out = (int)((int64_t)((int64_t)src[i] * c + round) >> s);
|
||||
dst[i] = out * (unsigned)ssign;
|
||||
}
|
||||
} else {
|
||||
av_log(log_context, AV_LOG_ERROR, "Overflow in subband_scale()\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void noise_scale(int *coefs, int scale, int band_energy, int len)
|
||||
{
|
||||
int s = -scale;
|
||||
unsigned int round;
|
||||
int i, out, c = exp2tab[s & 3];
|
||||
int nlz = 0;
|
||||
|
||||
av_assert0(s >= 0);
|
||||
while (band_energy > 0x7fff) {
|
||||
band_energy >>= 1;
|
||||
nlz++;
|
||||
}
|
||||
c /= band_energy;
|
||||
s = 21 + nlz - (s >> 2);
|
||||
|
||||
if (s > 31) {
|
||||
for (i=0; i<len; i++) {
|
||||
coefs[i] = 0;
|
||||
}
|
||||
} else if (s >= 0) {
|
||||
round = s ? 1 << (s-1) : 0;
|
||||
for (i=0; i<len; i++) {
|
||||
out = (int)(((int64_t)coefs[i] * c) >> 32);
|
||||
coefs[i] = -((int)(out+round) >> s);
|
||||
}
|
||||
}
|
||||
else {
|
||||
s = s + 32;
|
||||
if (s > 0) {
|
||||
round = 1 << (s-1);
|
||||
for (i=0; i<len; i++) {
|
||||
out = (int)((int64_t)((int64_t)coefs[i] * c + round) >> s);
|
||||
coefs[i] = -out;
|
||||
}
|
||||
} else {
|
||||
for (i=0; i<len; i++)
|
||||
coefs[i] = -(int64_t)coefs[i] * c * (1 << -s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline int *DEC_SPAIR(int *dst, unsigned idx)
|
||||
{
|
||||
dst[0] = (idx & 15) - 4;
|
||||
dst[1] = (idx >> 4 & 15) - 4;
|
||||
|
||||
return dst + 2;
|
||||
}
|
||||
|
||||
static inline int *DEC_SQUAD(int *dst, unsigned idx)
|
||||
{
|
||||
dst[0] = (idx & 3) - 1;
|
||||
dst[1] = (idx >> 2 & 3) - 1;
|
||||
dst[2] = (idx >> 4 & 3) - 1;
|
||||
dst[3] = (idx >> 6 & 3) - 1;
|
||||
|
||||
return dst + 4;
|
||||
}
|
||||
|
||||
static inline int *DEC_UPAIR(int *dst, unsigned idx, unsigned sign)
|
||||
{
|
||||
dst[0] = (idx & 15) * (1 - (sign & 0xFFFFFFFE));
|
||||
dst[1] = (idx >> 4 & 15) * (1 - ((sign & 1) * 2));
|
||||
|
||||
return dst + 2;
|
||||
}
|
||||
|
||||
static inline int *DEC_UQUAD(int *dst, unsigned idx, unsigned sign)
|
||||
{
|
||||
unsigned nz = idx >> 12;
|
||||
|
||||
dst[0] = (idx & 3) * (1 + (((int)sign >> 31) * 2));
|
||||
sign <<= nz & 1;
|
||||
nz >>= 1;
|
||||
dst[1] = (idx >> 2 & 3) * (1 + (((int)sign >> 31) * 2));
|
||||
sign <<= nz & 1;
|
||||
nz >>= 1;
|
||||
dst[2] = (idx >> 4 & 3) * (1 + (((int)sign >> 31) * 2));
|
||||
sign <<= nz & 1;
|
||||
nz >>= 1;
|
||||
dst[3] = (idx >> 6 & 3) * (1 + (((int)sign >> 31) * 2));
|
||||
|
||||
return dst + 4;
|
||||
}
|
||||
|
||||
#endif /* AVCODEC_AAC_AACDEC_FIXED_DEQUANT_H */
|
||||
@@ -1,151 +0,0 @@
|
||||
/*
|
||||
* AAC decoder
|
||||
* Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org )
|
||||
* Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov gmail com )
|
||||
* Copyright (c) 2008-2013 Alex Converse <alex.converse@gmail.com>
|
||||
*
|
||||
* AAC LATM decoder
|
||||
* Copyright (c) 2008-2010 Paul Kendall <paul@kcbbs.gen.nz>
|
||||
* Copyright (c) 2010 Janne Grunau <janne-libav@jannau.net>
|
||||
*
|
||||
* AAC decoder fixed-point implementation
|
||||
* Copyright (c) 2013
|
||||
* MIPS Technologies, Inc., California.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_AAC_AACDEC_FIXED_PREDICTION_H
|
||||
#define AVCODEC_AAC_AACDEC_FIXED_PREDICTION_H
|
||||
|
||||
static av_always_inline SoftFloat flt16_round(SoftFloat pf)
|
||||
{
|
||||
SoftFloat tmp;
|
||||
int s;
|
||||
|
||||
tmp.exp = pf.exp;
|
||||
s = pf.mant >> 31;
|
||||
tmp.mant = (pf.mant ^ s) - s;
|
||||
tmp.mant = (tmp.mant + 0x00200000U) & 0xFFC00000U;
|
||||
tmp.mant = (tmp.mant ^ s) - s;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static av_always_inline SoftFloat flt16_even(SoftFloat pf)
|
||||
{
|
||||
SoftFloat tmp;
|
||||
int s;
|
||||
|
||||
tmp.exp = pf.exp;
|
||||
s = pf.mant >> 31;
|
||||
tmp.mant = (pf.mant ^ s) - s;
|
||||
tmp.mant = (tmp.mant + 0x001FFFFFU + (tmp.mant & 0x00400000U >> 16)) & 0xFFC00000U;
|
||||
tmp.mant = (tmp.mant ^ s) - s;
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static av_always_inline SoftFloat flt16_trunc(SoftFloat pf)
|
||||
{
|
||||
SoftFloat pun;
|
||||
int s;
|
||||
|
||||
pun.exp = pf.exp;
|
||||
s = pf.mant >> 31;
|
||||
pun.mant = (pf.mant ^ s) - s;
|
||||
pun.mant = pun.mant & 0xFFC00000U;
|
||||
pun.mant = (pun.mant ^ s) - s;
|
||||
|
||||
return pun;
|
||||
}
|
||||
|
||||
static av_always_inline void predict(PredictorState *ps, int *coef,
|
||||
int output_enable)
|
||||
{
|
||||
const SoftFloat a = { 1023410176, 0 }; // 61.0 / 64
|
||||
const SoftFloat alpha = { 973078528, 0 }; // 29.0 / 32
|
||||
SoftFloat e0, e1;
|
||||
SoftFloat pv;
|
||||
SoftFloat k1, k2;
|
||||
SoftFloat r0 = ps->r0, r1 = ps->r1;
|
||||
SoftFloat cor0 = ps->cor0, cor1 = ps->cor1;
|
||||
SoftFloat var0 = ps->var0, var1 = ps->var1;
|
||||
SoftFloat tmp;
|
||||
|
||||
if (var0.exp > 1 || (var0.exp == 1 && var0.mant > 0x20000000)) {
|
||||
k1 = av_mul_sf(cor0, flt16_even(av_div_sf(a, var0)));
|
||||
}
|
||||
else {
|
||||
k1.mant = 0;
|
||||
k1.exp = 0;
|
||||
}
|
||||
|
||||
if (var1.exp > 1 || (var1.exp == 1 && var1.mant > 0x20000000)) {
|
||||
k2 = av_mul_sf(cor1, flt16_even(av_div_sf(a, var1)));
|
||||
}
|
||||
else {
|
||||
k2.mant = 0;
|
||||
k2.exp = 0;
|
||||
}
|
||||
|
||||
tmp = av_mul_sf(k1, r0);
|
||||
pv = flt16_round(av_add_sf(tmp, av_mul_sf(k2, r1)));
|
||||
if (output_enable) {
|
||||
int shift = 28 - pv.exp;
|
||||
|
||||
if (shift < 31) {
|
||||
if (shift > 0) {
|
||||
*coef += (unsigned)((pv.mant + (1 << (shift - 1))) >> shift);
|
||||
} else
|
||||
*coef += (unsigned)pv.mant << -shift;
|
||||
}
|
||||
}
|
||||
|
||||
e0 = av_int2sf(*coef, 2);
|
||||
e1 = av_sub_sf(e0, tmp);
|
||||
|
||||
ps->cor1 = flt16_trunc(av_add_sf(av_mul_sf(alpha, cor1), av_mul_sf(r1, e1)));
|
||||
tmp = av_add_sf(av_mul_sf(r1, r1), av_mul_sf(e1, e1));
|
||||
tmp.exp--;
|
||||
ps->var1 = flt16_trunc(av_add_sf(av_mul_sf(alpha, var1), tmp));
|
||||
ps->cor0 = flt16_trunc(av_add_sf(av_mul_sf(alpha, cor0), av_mul_sf(r0, e0)));
|
||||
tmp = av_add_sf(av_mul_sf(r0, r0), av_mul_sf(e0, e0));
|
||||
tmp.exp--;
|
||||
ps->var0 = flt16_trunc(av_add_sf(av_mul_sf(alpha, var0), tmp));
|
||||
|
||||
ps->r1 = flt16_trunc(av_mul_sf(a, av_sub_sf(r0, av_mul_sf(k1, e0))));
|
||||
ps->r0 = flt16_trunc(av_mul_sf(a, e0));
|
||||
}
|
||||
|
||||
static av_always_inline void reset_predict_state(PredictorState *ps)
|
||||
{
|
||||
ps->r0.mant = 0;
|
||||
ps->r0.exp = 0;
|
||||
ps->r1.mant = 0;
|
||||
ps->r1.exp = 0;
|
||||
ps->cor0.mant = 0;
|
||||
ps->cor0.exp = 0;
|
||||
ps->cor1.mant = 0;
|
||||
ps->cor1.exp = 0;
|
||||
ps->var0.mant = 0x20000000;
|
||||
ps->var0.exp = 1;
|
||||
ps->var1.mant = 0x20000000;
|
||||
ps->var1.exp = 1;
|
||||
}
|
||||
|
||||
#endif /* AVCODEC_AAC_AACDEC_FIXED_PREDICTION_H */
|
||||
@@ -1,182 +0,0 @@
|
||||
/*
|
||||
* AAC decoder
|
||||
* Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org )
|
||||
* Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov gmail com )
|
||||
* Copyright (c) 2008-2013 Alex Converse <alex.converse@gmail.com>
|
||||
*
|
||||
* AAC LATM decoder
|
||||
* Copyright (c) 2008-2010 Paul Kendall <paul@kcbbs.gen.nz>
|
||||
* Copyright (c) 2010 Janne Grunau <janne-libav@jannau.net>
|
||||
*
|
||||
* AAC decoder fixed-point implementation
|
||||
* Copyright (c) 2013
|
||||
* MIPS Technologies, Inc., California.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#define USE_FIXED 0
|
||||
|
||||
#include "libavutil/thread.h"
|
||||
|
||||
#include "libavcodec/aac_defines.h"
|
||||
|
||||
#include "libavcodec/avcodec.h"
|
||||
#include "aacdec.h"
|
||||
#include "libavcodec/aactab.h"
|
||||
#include "libavcodec/sinewin.h"
|
||||
#include "libavcodec/kbdwin.h"
|
||||
#include "libavcodec/cbrt_data.h"
|
||||
#include "libavutil/mathematics.h"
|
||||
#include "libavcodec/aacsbr.h"
|
||||
|
||||
DECLARE_ALIGNED(32, static float, sine_96)[96];
|
||||
DECLARE_ALIGNED(32, static float, sine_120)[120];
|
||||
DECLARE_ALIGNED(32, static float, sine_768)[768];
|
||||
DECLARE_ALIGNED(32, static float, sine_960)[960];
|
||||
DECLARE_ALIGNED(32, static float, aac_kbd_long_960)[960];
|
||||
DECLARE_ALIGNED(32, static float, aac_kbd_short_120)[120];
|
||||
DECLARE_ALIGNED(32, static float, aac_kbd_long_768)[768];
|
||||
DECLARE_ALIGNED(32, static float, aac_kbd_short_96)[96];
|
||||
|
||||
static void init_tables_float_fn(void)
|
||||
{
|
||||
ff_cbrt_tableinit();
|
||||
|
||||
ff_kbd_window_init(ff_aac_kbd_long_1024, 4.0, 1024);
|
||||
ff_kbd_window_init(ff_aac_kbd_short_128, 6.0, 128);
|
||||
|
||||
ff_kbd_window_init(aac_kbd_long_960, 4.0, 960);
|
||||
ff_kbd_window_init(aac_kbd_short_120, 6.0, 120);
|
||||
|
||||
ff_sine_window_init(sine_960, 960);
|
||||
ff_sine_window_init(sine_120, 120);
|
||||
ff_init_ff_sine_windows(9);
|
||||
|
||||
ff_aac_sbr_init();
|
||||
|
||||
ff_aac_float_common_init();
|
||||
}
|
||||
|
||||
static const float cce_scale[] = {
|
||||
1.09050773266525765921, //2^(1/8)
|
||||
1.18920711500272106672, //2^(1/4)
|
||||
M_SQRT2,
|
||||
2,
|
||||
};
|
||||
|
||||
/** Dequantization-related **/
|
||||
#include "aacdec_tab.h"
|
||||
#include "libavutil/intfloat.h"
|
||||
|
||||
#include "config.h"
|
||||
#if ARCH_ARM
|
||||
#include "libavcodec/arm/aac.h"
|
||||
#endif
|
||||
|
||||
#ifndef VMUL2
|
||||
static inline float *VMUL2(float *dst, const float *v, unsigned idx,
|
||||
const float *scale)
|
||||
{
|
||||
float s = *scale;
|
||||
*dst++ = v[idx & 15] * s;
|
||||
*dst++ = v[idx>>4 & 15] * s;
|
||||
return dst;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef VMUL4
|
||||
static inline float *VMUL4(float *dst, const float *v, unsigned idx,
|
||||
const float *scale)
|
||||
{
|
||||
float s = *scale;
|
||||
*dst++ = v[idx & 3] * s;
|
||||
*dst++ = v[idx>>2 & 3] * s;
|
||||
*dst++ = v[idx>>4 & 3] * s;
|
||||
*dst++ = v[idx>>6 & 3] * s;
|
||||
return dst;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef VMUL2S
|
||||
static inline float *VMUL2S(float *dst, const float *v, unsigned idx,
|
||||
unsigned sign, const float *scale)
|
||||
{
|
||||
union av_intfloat32 s0, s1;
|
||||
|
||||
s0.f = s1.f = *scale;
|
||||
s0.i ^= sign >> 1 << 31;
|
||||
s1.i ^= sign << 31;
|
||||
|
||||
*dst++ = v[idx & 15] * s0.f;
|
||||
*dst++ = v[idx>>4 & 15] * s1.f;
|
||||
|
||||
return dst;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef VMUL4S
|
||||
static inline float *VMUL4S(float *dst, const float *v, unsigned idx,
|
||||
unsigned sign, const float *scale)
|
||||
{
|
||||
unsigned nz = idx >> 12;
|
||||
union av_intfloat32 s = { .f = *scale };
|
||||
union av_intfloat32 t;
|
||||
|
||||
t.i = s.i ^ (sign & 1U<<31);
|
||||
*dst++ = v[idx & 3] * t.f;
|
||||
|
||||
sign <<= nz & 1; nz >>= 1;
|
||||
t.i = s.i ^ (sign & 1U<<31);
|
||||
*dst++ = v[idx>>2 & 3] * t.f;
|
||||
|
||||
sign <<= nz & 1; nz >>= 1;
|
||||
t.i = s.i ^ (sign & 1U<<31);
|
||||
*dst++ = v[idx>>4 & 3] * t.f;
|
||||
|
||||
sign <<= nz & 1;
|
||||
t.i = s.i ^ (sign & 1U<<31);
|
||||
*dst++ = v[idx>>6 & 3] * t.f;
|
||||
|
||||
return dst;
|
||||
}
|
||||
#endif
|
||||
|
||||
#include "aacdec_float_coupling.h"
|
||||
#include "aacdec_float_prediction.h"
|
||||
#include "aacdec_dsp_template.c"
|
||||
#include "aacdec_proc_template.c"
|
||||
|
||||
av_cold int ff_aac_decode_init_float(AVCodecContext *avctx)
|
||||
{
|
||||
static AVOnce init_float_once = AV_ONCE_INIT;
|
||||
AACDecContext *ac = avctx->priv_data;
|
||||
|
||||
ac->is_fixed = 0;
|
||||
avctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
|
||||
|
||||
aac_dsp_init(&ac->dsp);
|
||||
aac_proc_init(&ac->proc);
|
||||
|
||||
ac->fdsp = avpriv_float_dsp_alloc(avctx->flags & AV_CODEC_FLAG_BITEXACT);
|
||||
if (!ac->fdsp)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
ff_thread_once(&init_float_once, init_tables_float_fn);
|
||||
|
||||
return ff_aac_decode_init(avctx);
|
||||
}
|
||||
@@ -1,90 +0,0 @@
|
||||
/*
|
||||
* AAC decoder
|
||||
* Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org )
|
||||
* Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov gmail com )
|
||||
* Copyright (c) 2008-2013 Alex Converse <alex.converse@gmail.com>
|
||||
*
|
||||
* AAC LATM decoder
|
||||
* Copyright (c) 2008-2010 Paul Kendall <paul@kcbbs.gen.nz>
|
||||
* Copyright (c) 2010 Janne Grunau <janne-libav@jannau.net>
|
||||
*
|
||||
* AAC decoder fixed-point implementation
|
||||
* Copyright (c) 2013
|
||||
* MIPS Technologies, Inc., California.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_AAC_AACDEC_FLOAT_COUPLING_H
|
||||
#define AVCODEC_AAC_AACDEC_FLOAT_COUPLING_H
|
||||
|
||||
#include "aacdec.h"
|
||||
|
||||
/**
|
||||
* Apply dependent channel coupling (applied before IMDCT).
|
||||
*
|
||||
* @param index index into coupling gain array
|
||||
*/
|
||||
static void AAC_RENAME(apply_dependent_coupling)(AACDecContext *ac,
|
||||
SingleChannelElement *target,
|
||||
ChannelElement *cce, int index)
|
||||
{
|
||||
IndividualChannelStream *ics = &cce->ch[0].ics;
|
||||
const uint16_t *offsets = ics->swb_offset;
|
||||
float *dest = target->coeffs;
|
||||
const float *src = cce->ch[0].coeffs;
|
||||
int g, i, group, k, idx = 0;
|
||||
if (ac->oc[1].m4ac.object_type == AOT_AAC_LTP) {
|
||||
av_log(ac->avctx, AV_LOG_ERROR,
|
||||
"Dependent coupling is not supported together with LTP\n");
|
||||
return;
|
||||
}
|
||||
for (g = 0; g < ics->num_window_groups; g++) {
|
||||
for (i = 0; i < ics->max_sfb; i++, idx++) {
|
||||
if (cce->ch[0].band_type[idx] != ZERO_BT) {
|
||||
const float gain = cce->coup.gain[index][idx];
|
||||
for (group = 0; group < ics->group_len[g]; group++) {
|
||||
for (k = offsets[i]; k < offsets[i + 1]; k++) {
|
||||
// FIXME: SIMDify
|
||||
dest[group * 128 + k] += gain * src[group * 128 + k];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
dest += ics->group_len[g] * 128;
|
||||
src += ics->group_len[g] * 128;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply independent channel coupling (applied after IMDCT).
|
||||
*
|
||||
* @param index index into coupling gain array
|
||||
*/
|
||||
static void AAC_RENAME(apply_independent_coupling)(AACDecContext *ac,
|
||||
SingleChannelElement *target,
|
||||
ChannelElement *cce, int index)
|
||||
{
|
||||
const float gain = cce->coup.gain[index][0];
|
||||
const float *src = cce->ch[0].output;
|
||||
float *dest = target->output;
|
||||
const int len = 1024 << (ac->oc[1].m4ac.sbr == 1);
|
||||
|
||||
ac->fdsp->vector_fmac_scalar(dest, src, gain, len);
|
||||
}
|
||||
|
||||
#endif /* AVCODEC_AAC_AACDEC_FLOAT_COUPLING_H */
|
||||
@@ -1,100 +0,0 @@
|
||||
/*
|
||||
* AAC decoder
|
||||
* Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org )
|
||||
* Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov gmail com )
|
||||
* Copyright (c) 2008-2013 Alex Converse <alex.converse@gmail.com>
|
||||
*
|
||||
* AAC LATM decoder
|
||||
* Copyright (c) 2008-2010 Paul Kendall <paul@kcbbs.gen.nz>
|
||||
* Copyright (c) 2010 Janne Grunau <janne-libav@jannau.net>
|
||||
*
|
||||
* AAC decoder fixed-point implementation
|
||||
* Copyright (c) 2013
|
||||
* MIPS Technologies, Inc., California.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_AAC_AACDEC_FLOAT_PREDICTION_H
|
||||
#define AVCODEC_AAC_AACDEC_FLOAT_PREDICTION_H
|
||||
|
||||
static av_always_inline float flt16_round(float pf)
|
||||
{
|
||||
union av_intfloat32 tmp;
|
||||
tmp.f = pf;
|
||||
tmp.i = (tmp.i + 0x00008000U) & 0xFFFF0000U;
|
||||
return tmp.f;
|
||||
}
|
||||
|
||||
static av_always_inline float flt16_even(float pf)
|
||||
{
|
||||
union av_intfloat32 tmp;
|
||||
tmp.f = pf;
|
||||
tmp.i = (tmp.i + 0x00007FFFU + (tmp.i & 0x00010000U >> 16)) & 0xFFFF0000U;
|
||||
return tmp.f;
|
||||
}
|
||||
|
||||
static av_always_inline float flt16_trunc(float pf)
|
||||
{
|
||||
union av_intfloat32 pun;
|
||||
pun.f = pf;
|
||||
pun.i &= 0xFFFF0000U;
|
||||
return pun.f;
|
||||
}
|
||||
|
||||
static av_always_inline void predict(PredictorState *ps, float *coef,
|
||||
int output_enable)
|
||||
{
|
||||
const float a = 0.953125; // 61.0 / 64
|
||||
const float alpha = 0.90625; // 29.0 / 32
|
||||
float e0, e1;
|
||||
float pv;
|
||||
float k1, k2;
|
||||
float r0 = ps->r0, r1 = ps->r1;
|
||||
float cor0 = ps->cor0, cor1 = ps->cor1;
|
||||
float var0 = ps->var0, var1 = ps->var1;
|
||||
|
||||
k1 = var0 > 1 ? cor0 * flt16_even(a / var0) : 0;
|
||||
k2 = var1 > 1 ? cor1 * flt16_even(a / var1) : 0;
|
||||
|
||||
pv = flt16_round(k1 * r0 + k2 * r1);
|
||||
if (output_enable)
|
||||
*coef += pv;
|
||||
|
||||
e0 = *coef;
|
||||
e1 = e0 - k1 * r0;
|
||||
|
||||
ps->cor1 = flt16_trunc(alpha * cor1 + r1 * e1);
|
||||
ps->var1 = flt16_trunc(alpha * var1 + 0.5f * (r1 * r1 + e1 * e1));
|
||||
ps->cor0 = flt16_trunc(alpha * cor0 + r0 * e0);
|
||||
ps->var0 = flt16_trunc(alpha * var0 + 0.5f * (r0 * r0 + e0 * e0));
|
||||
|
||||
ps->r1 = flt16_trunc(a * (r0 - k1 * e0));
|
||||
ps->r0 = flt16_trunc(a * e0);
|
||||
}
|
||||
|
||||
static av_always_inline void reset_predict_state(PredictorState *ps)
|
||||
{
|
||||
ps->r0 = 0.0f;
|
||||
ps->r1 = 0.0f;
|
||||
ps->cor0 = 0.0f;
|
||||
ps->cor1 = 0.0f;
|
||||
ps->var0 = 1.0f;
|
||||
ps->var1 = 1.0f;
|
||||
}
|
||||
|
||||
#endif /* AVCODEC_AAC_AACDEC_FLOAT_PREDICTION_H */
|
||||
@@ -1,198 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Lynne <dev@lynne.ee>
|
||||
*
|
||||
* 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 "aacdec_lpd.h"
|
||||
#include "aacdec_usac.h"
|
||||
#include "libavcodec/unary.h"
|
||||
|
||||
const uint8_t ff_aac_lpd_mode_tab[32][4] = {
|
||||
{ 0, 0, 0, 0 },
|
||||
{ 1, 0, 0, 0 },
|
||||
{ 0, 1, 0, 0 },
|
||||
{ 1, 1, 0, 0 },
|
||||
{ 0, 0, 1, 0 },
|
||||
{ 1, 0, 1, 0 },
|
||||
{ 0, 1, 1, 0 },
|
||||
{ 1, 1, 1, 0 },
|
||||
{ 0, 0, 0, 1 },
|
||||
{ 1, 0, 0, 1 },
|
||||
{ 0, 1, 0, 1 },
|
||||
{ 1, 1, 0, 1 },
|
||||
{ 0, 0, 1, 1 },
|
||||
{ 1, 0, 1, 1 },
|
||||
{ 0, 1, 1, 1 },
|
||||
{ 1, 1, 1, 1 },
|
||||
{ 2, 2, 0, 0 },
|
||||
{ 2, 2, 1, 0 },
|
||||
{ 2, 2, 0, 1 },
|
||||
{ 2, 2, 1, 1 },
|
||||
{ 0, 0, 2, 2 },
|
||||
{ 1, 0, 2, 2 },
|
||||
{ 0, 1, 2, 2 },
|
||||
{ 1, 1, 2, 2 },
|
||||
{ 2, 2, 2, 2 },
|
||||
{ 3, 3, 3, 3 },
|
||||
/* Larger values are reserved, but permit them for resilience */
|
||||
{ 0, 0, 0, 0 },
|
||||
{ 0, 0, 0, 0 },
|
||||
{ 0, 0, 0, 0 },
|
||||
{ 0, 0, 0, 0 },
|
||||
{ 0, 0, 0, 0 },
|
||||
{ 0, 0, 0, 0 },
|
||||
};
|
||||
|
||||
static void parse_qn(GetBitContext *gb, int *qn, int nk_mode, int no_qn)
|
||||
{
|
||||
if (nk_mode == 1) {
|
||||
for (int k = 0; k < no_qn; k++) {
|
||||
qn[k] = get_unary(gb, 0, INT32_MAX); // TODO: find proper ranges
|
||||
if (qn[k])
|
||||
qn[k]++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
for (int k = 0; k < no_qn; k++)
|
||||
qn[k] = get_bits(gb, 2) + 2;
|
||||
|
||||
if (nk_mode == 2) {
|
||||
for (int k = 0; k < no_qn; k++) {
|
||||
if (qn[k] > 4) {
|
||||
qn[k] = get_unary(gb, 0, INT32_MAX);;
|
||||
if (qn[k])
|
||||
qn[k] += 4;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
for (int k = 0; k < no_qn; k++) {
|
||||
if (qn[k] > 4) {
|
||||
int qn_ext = get_unary(gb, 0, INT32_MAX);;
|
||||
switch (qn_ext) {
|
||||
case 0: qn[k] = 5; break;
|
||||
case 1: qn[k] = 6; break;
|
||||
case 2: qn[k] = 0; break;
|
||||
default: qn[k] = qn_ext + 4; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int parse_codebook_idx(GetBitContext *gb, uint32_t *kv,
|
||||
int nk_mode, int no_qn)
|
||||
{
|
||||
int n, nk;
|
||||
|
||||
int qn[2];
|
||||
parse_qn(gb, qn, nk_mode, no_qn);
|
||||
|
||||
for (int k = 0; k < no_qn; k++) {
|
||||
if (qn[k] > 4) {
|
||||
nk = (qn[k] - 3) / 2;
|
||||
n = qn[k] - nk*2;
|
||||
} else {
|
||||
nk = 0;
|
||||
n = qn[k];
|
||||
}
|
||||
}
|
||||
|
||||
skip_bits(gb, 4*n);
|
||||
|
||||
if (nk > 0)
|
||||
for (int i = 0; i < 8; i++)
|
||||
kv[i] = get_bits(gb, nk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ff_aac_parse_fac_data(AACUsacElemData *ce, GetBitContext *gb,
|
||||
int use_gain, int len)
|
||||
{
|
||||
int ret;
|
||||
if (use_gain)
|
||||
ce->fac.gain = get_bits(gb, 7);
|
||||
|
||||
if (len/8 > 8)
|
||||
return AVERROR_PATCHWELCOME;
|
||||
|
||||
for (int i = 0; i < len/8; i++) {
|
||||
ret = parse_codebook_idx(gb, ce->fac.kv[i], 1, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ff_aac_ldp_parse_channel_stream(AACDecContext *ac, AACUSACConfig *usac,
|
||||
AACUsacElemData *ce, GetBitContext *gb)
|
||||
{
|
||||
int k;
|
||||
const uint8_t *mod;
|
||||
int first_ldp_flag;
|
||||
|
||||
ce->ldp.acelp_core_mode = get_bits(gb, 3);
|
||||
ce->ldp.lpd_mode = get_bits(gb, 5);
|
||||
|
||||
ce->ldp.bpf_control_info = get_bits1(gb);
|
||||
ce->ldp.core_mode_last = get_bits1(gb);
|
||||
ce->ldp.fac_data_present = get_bits1(gb);
|
||||
|
||||
mod = ff_aac_lpd_mode_tab[ce->ldp.lpd_mode];
|
||||
|
||||
first_ldp_flag = !ce->ldp.core_mode_last;
|
||||
if (first_ldp_flag)
|
||||
ce->ldp.last_lpd_mode = -1; /* last_ldp_mode is a **STATEFUL** value */
|
||||
|
||||
k = 0;
|
||||
while (k < 0) {
|
||||
if (!k) {
|
||||
if (ce->ldp.core_mode_last && ce->ldp.fac_data_present)
|
||||
ff_aac_parse_fac_data(ce, gb, 0, usac->core_frame_len/8);
|
||||
} else {
|
||||
if (!ce->ldp.last_lpd_mode && mod[k] > 0 ||
|
||||
ce->ldp.last_lpd_mode && !mod[k])
|
||||
ff_aac_parse_fac_data(ce, gb, 0, usac->core_frame_len/8);
|
||||
}
|
||||
if (!mod[k]) {
|
||||
// parse_acelp_coding();
|
||||
ce->ldp.last_lpd_mode = 0;
|
||||
k++;
|
||||
} else {
|
||||
// parse_tcx_coding();
|
||||
ce->ldp.last_lpd_mode = mod[k];
|
||||
k += (1 << (mod[k] - 1));
|
||||
}
|
||||
}
|
||||
|
||||
// parse_lpc_data(first_lpd_flag);
|
||||
|
||||
if (!ce->ldp.core_mode_last && ce->ldp.fac_data_present) {
|
||||
uint16_t len_8 = usac->core_frame_len / 8;
|
||||
uint16_t len_16 = usac->core_frame_len / 16;
|
||||
uint16_t fac_len = get_bits1(gb) /* short_fac_flag */ ? len_8 : len_16;
|
||||
int ret = ff_aac_parse_fac_data(ce, gb, 1, fac_len);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Lynne <dev@lynne.ee>
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_AAC_AACDEC_LPD_H
|
||||
#define AVCODEC_AAC_AACDEC_LPD_H
|
||||
|
||||
#include "aacdec.h"
|
||||
#include "libavcodec/get_bits.h"
|
||||
|
||||
int ff_aac_parse_fac_data(AACUsacElemData *ce, GetBitContext *gb,
|
||||
int use_gain, int len);
|
||||
|
||||
int ff_aac_ldp_parse_channel_stream(AACDecContext *ac, AACUSACConfig *usac,
|
||||
AACUsacElemData *ce, GetBitContext *gb);
|
||||
|
||||
#endif /* AVCODEC_AAC_AACDEC_LPD_H */
|
||||
@@ -1,448 +0,0 @@
|
||||
/*
|
||||
* AAC decoder
|
||||
* Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org )
|
||||
* Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov gmail com )
|
||||
* Copyright (c) 2008-2013 Alex Converse <alex.converse@gmail.com>
|
||||
*
|
||||
* AAC LATM decoder
|
||||
* Copyright (c) 2008-2010 Paul Kendall <paul@kcbbs.gen.nz>
|
||||
* Copyright (c) 2010 Janne Grunau <janne-libav@jannau.net>
|
||||
*
|
||||
* AAC decoder fixed-point implementation
|
||||
* Copyright (c) 2013
|
||||
* MIPS Technologies, Inc., California.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/**
|
||||
* linear congruential pseudorandom number generator
|
||||
*
|
||||
* @param previous_val pointer to the current state of the generator
|
||||
*
|
||||
* @return Returns a 32-bit pseudorandom integer
|
||||
*/
|
||||
static av_always_inline int lcg_random(unsigned previous_val)
|
||||
{
|
||||
union { unsigned u; int s; } v = { previous_val * 1664525u + 1013904223 };
|
||||
return v.s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode spectral data; reference: table 4.50.
|
||||
* Dequantize and scale spectral data; reference: 4.6.3.3.
|
||||
*
|
||||
* @param coef array of dequantized, scaled spectral data
|
||||
* @param sf array of scalefactors or intensity stereo positions
|
||||
* @param pulse_present set if pulses are present
|
||||
* @param pulse pointer to pulse data struct
|
||||
* @param band_type array of the used band type
|
||||
*
|
||||
* @return Returns error status. 0 - OK, !0 - error
|
||||
*/
|
||||
static int AAC_RENAME(decode_spectrum_and_dequant)(AACDecContext *ac,
|
||||
GetBitContext *gb,
|
||||
const Pulse *pulse,
|
||||
SingleChannelElement *sce)
|
||||
{
|
||||
int i, k, g, idx = 0;
|
||||
INTFLOAT *coef = sce->AAC_RENAME(coeffs);
|
||||
IndividualChannelStream *ics = &sce->ics;
|
||||
const int c = 1024 / ics->num_windows;
|
||||
const uint16_t *offsets = ics->swb_offset;
|
||||
const INTFLOAT *sf = sce->AAC_RENAME(sf);
|
||||
const enum BandType *band_type = sce->band_type;
|
||||
INTFLOAT *coef_base = coef;
|
||||
|
||||
for (g = 0; g < ics->num_windows; g++)
|
||||
memset(coef + g * 128 + offsets[ics->max_sfb], 0,
|
||||
sizeof(INTFLOAT) * (c - offsets[ics->max_sfb]));
|
||||
|
||||
for (g = 0; g < ics->num_window_groups; g++) {
|
||||
unsigned g_len = ics->group_len[g];
|
||||
|
||||
for (i = 0; i < ics->max_sfb; i++, idx++) {
|
||||
const unsigned cbt_m1 = band_type[idx] - 1;
|
||||
INTFLOAT *cfo = coef + offsets[i];
|
||||
int off_len = offsets[i + 1] - offsets[i];
|
||||
int group;
|
||||
|
||||
if (cbt_m1 >= INTENSITY_BT2 - 1) {
|
||||
for (group = 0; group < (AAC_SIGNE)g_len; group++, cfo+=128) {
|
||||
memset(cfo, 0, off_len * sizeof(*cfo));
|
||||
}
|
||||
} else if (cbt_m1 == NOISE_BT - 1) {
|
||||
for (group = 0; group < (AAC_SIGNE)g_len; group++, cfo+=128) {
|
||||
INTFLOAT band_energy;
|
||||
#if USE_FIXED
|
||||
for (k = 0; k < off_len; k++) {
|
||||
ac->random_state = lcg_random(ac->random_state);
|
||||
cfo[k] = ac->random_state >> 3;
|
||||
}
|
||||
|
||||
band_energy = ac->fdsp->scalarproduct_fixed(cfo, cfo, off_len);
|
||||
band_energy = fixed_sqrt(band_energy, 31);
|
||||
noise_scale(cfo, sf[idx], band_energy, off_len);
|
||||
#else
|
||||
float scale;
|
||||
|
||||
for (k = 0; k < off_len; k++) {
|
||||
ac->random_state = lcg_random(ac->random_state);
|
||||
cfo[k] = ac->random_state;
|
||||
}
|
||||
|
||||
band_energy = ac->fdsp->scalarproduct_float(cfo, cfo, off_len);
|
||||
scale = sf[idx] / sqrtf(band_energy);
|
||||
ac->fdsp->vector_fmul_scalar(cfo, cfo, scale, off_len);
|
||||
#endif /* USE_FIXED */
|
||||
}
|
||||
} else {
|
||||
#if !USE_FIXED
|
||||
const float *vq = ff_aac_codebook_vector_vals[cbt_m1];
|
||||
#endif /* !USE_FIXED */
|
||||
const VLCElem *vlc_tab = ff_vlc_spectral[cbt_m1];
|
||||
OPEN_READER(re, gb);
|
||||
|
||||
switch (cbt_m1 >> 1) {
|
||||
case 0:
|
||||
for (group = 0; group < (AAC_SIGNE)g_len; group++, cfo+=128) {
|
||||
INTFLOAT *cf = cfo;
|
||||
int len = off_len;
|
||||
|
||||
do {
|
||||
int code;
|
||||
unsigned cb_idx;
|
||||
|
||||
UPDATE_CACHE(re, gb);
|
||||
GET_VLC(code, re, gb, vlc_tab, 8, 2);
|
||||
cb_idx = code;
|
||||
#if USE_FIXED
|
||||
cf = DEC_SQUAD(cf, cb_idx);
|
||||
#else
|
||||
cf = VMUL4(cf, vq, cb_idx, sf + idx);
|
||||
#endif /* USE_FIXED */
|
||||
} while (len -= 4);
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
for (group = 0; group < (AAC_SIGNE)g_len; group++, cfo+=128) {
|
||||
INTFLOAT *cf = cfo;
|
||||
int len = off_len;
|
||||
|
||||
do {
|
||||
int code;
|
||||
unsigned nnz;
|
||||
unsigned cb_idx;
|
||||
uint32_t bits;
|
||||
|
||||
UPDATE_CACHE(re, gb);
|
||||
GET_VLC(code, re, gb, vlc_tab, 8, 2);
|
||||
cb_idx = code;
|
||||
nnz = cb_idx >> 8 & 15;
|
||||
bits = nnz ? GET_CACHE(re, gb) : 0;
|
||||
LAST_SKIP_BITS(re, gb, nnz);
|
||||
#if USE_FIXED
|
||||
cf = DEC_UQUAD(cf, cb_idx, bits);
|
||||
#else
|
||||
cf = VMUL4S(cf, vq, cb_idx, bits, sf + idx);
|
||||
#endif /* USE_FIXED */
|
||||
} while (len -= 4);
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
for (group = 0; group < (AAC_SIGNE)g_len; group++, cfo+=128) {
|
||||
INTFLOAT *cf = cfo;
|
||||
int len = off_len;
|
||||
|
||||
do {
|
||||
int code;
|
||||
unsigned cb_idx;
|
||||
|
||||
UPDATE_CACHE(re, gb);
|
||||
GET_VLC(code, re, gb, vlc_tab, 8, 2);
|
||||
cb_idx = code;
|
||||
#if USE_FIXED
|
||||
cf = DEC_SPAIR(cf, cb_idx);
|
||||
#else
|
||||
cf = VMUL2(cf, vq, cb_idx, sf + idx);
|
||||
#endif /* USE_FIXED */
|
||||
} while (len -= 2);
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
case 4:
|
||||
for (group = 0; group < (AAC_SIGNE)g_len; group++, cfo+=128) {
|
||||
INTFLOAT *cf = cfo;
|
||||
int len = off_len;
|
||||
|
||||
do {
|
||||
int code;
|
||||
unsigned nnz;
|
||||
unsigned cb_idx;
|
||||
unsigned sign;
|
||||
|
||||
UPDATE_CACHE(re, gb);
|
||||
GET_VLC(code, re, gb, vlc_tab, 8, 2);
|
||||
cb_idx = code;
|
||||
nnz = cb_idx >> 8 & 15;
|
||||
sign = nnz ? SHOW_UBITS(re, gb, nnz) << (cb_idx >> 12) : 0;
|
||||
LAST_SKIP_BITS(re, gb, nnz);
|
||||
#if USE_FIXED
|
||||
cf = DEC_UPAIR(cf, cb_idx, sign);
|
||||
#else
|
||||
cf = VMUL2S(cf, vq, cb_idx, sign, sf + idx);
|
||||
#endif /* USE_FIXED */
|
||||
} while (len -= 2);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
for (group = 0; group < (AAC_SIGNE)g_len; group++, cfo+=128) {
|
||||
#if USE_FIXED
|
||||
int *icf = cfo;
|
||||
int v;
|
||||
#else
|
||||
float *cf = cfo;
|
||||
uint32_t *icf = (uint32_t *) cf;
|
||||
#endif /* USE_FIXED */
|
||||
int len = off_len;
|
||||
|
||||
do {
|
||||
int code;
|
||||
unsigned nzt, nnz;
|
||||
unsigned cb_idx;
|
||||
uint32_t bits;
|
||||
int j;
|
||||
|
||||
UPDATE_CACHE(re, gb);
|
||||
GET_VLC(code, re, gb, vlc_tab, 8, 2);
|
||||
cb_idx = code;
|
||||
|
||||
if (cb_idx == 0x0000) {
|
||||
*icf++ = 0;
|
||||
*icf++ = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
nnz = cb_idx >> 12;
|
||||
nzt = cb_idx >> 8;
|
||||
bits = SHOW_UBITS(re, gb, nnz) << (32-nnz);
|
||||
LAST_SKIP_BITS(re, gb, nnz);
|
||||
|
||||
for (j = 0; j < 2; j++) {
|
||||
if (nzt & 1<<j) {
|
||||
uint32_t b;
|
||||
int n;
|
||||
/* The total length of escape_sequence must be < 22 bits according
|
||||
to the specification (i.e. max is 111111110xxxxxxxxxxxx). */
|
||||
UPDATE_CACHE(re, gb);
|
||||
b = GET_CACHE(re, gb);
|
||||
b = 31 - av_log2(~b);
|
||||
|
||||
if (b > 8) {
|
||||
av_log(ac->avctx, AV_LOG_ERROR, "error in spectral data, ESC overflow\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
SKIP_BITS(re, gb, b + 1);
|
||||
b += 4;
|
||||
n = (1 << b) + SHOW_UBITS(re, gb, b);
|
||||
LAST_SKIP_BITS(re, gb, b);
|
||||
#if USE_FIXED
|
||||
v = n;
|
||||
if (bits & 1U<<31)
|
||||
v = -v;
|
||||
*icf++ = v;
|
||||
#else
|
||||
*icf++ = ff_cbrt_tab[n] | (bits & 1U<<31);
|
||||
#endif /* USE_FIXED */
|
||||
bits <<= 1;
|
||||
} else {
|
||||
#if USE_FIXED
|
||||
v = cb_idx & 15;
|
||||
if (bits & 1U<<31)
|
||||
v = -v;
|
||||
*icf++ = v;
|
||||
#else
|
||||
unsigned v = ((const uint32_t*)vq)[cb_idx & 15];
|
||||
*icf++ = (bits & 1U<<31) | v;
|
||||
#endif /* USE_FIXED */
|
||||
bits <<= !!v;
|
||||
}
|
||||
cb_idx >>= 4;
|
||||
}
|
||||
} while (len -= 2);
|
||||
#if !USE_FIXED
|
||||
ac->fdsp->vector_fmul_scalar(cfo, cfo, sf[idx], off_len);
|
||||
#endif /* !USE_FIXED */
|
||||
}
|
||||
}
|
||||
|
||||
CLOSE_READER(re, gb);
|
||||
}
|
||||
}
|
||||
coef += g_len << 7;
|
||||
}
|
||||
|
||||
if (pulse) {
|
||||
idx = 0;
|
||||
for (i = 0; i < pulse->num_pulse; i++) {
|
||||
INTFLOAT co = coef_base[ pulse->pos[i] ];
|
||||
while (offsets[idx + 1] <= pulse->pos[i])
|
||||
idx++;
|
||||
if (band_type[idx] != NOISE_BT && sf[idx]) {
|
||||
INTFLOAT ico = -pulse->amp[i];
|
||||
#if USE_FIXED
|
||||
if (co) {
|
||||
ico = co + (co > 0 ? -ico : ico);
|
||||
}
|
||||
coef_base[ pulse->pos[i] ] = ico;
|
||||
#else
|
||||
if (co) {
|
||||
co /= sf[idx];
|
||||
ico = co / sqrtf(sqrtf(fabsf(co))) + (co > 0 ? -ico : ico);
|
||||
}
|
||||
coef_base[ pulse->pos[i] ] = cbrtf(fabsf(ico)) * ico * sf[idx];
|
||||
#endif /* USE_FIXED */
|
||||
}
|
||||
}
|
||||
}
|
||||
#if USE_FIXED
|
||||
coef = coef_base;
|
||||
idx = 0;
|
||||
for (g = 0; g < ics->num_window_groups; g++) {
|
||||
unsigned g_len = ics->group_len[g];
|
||||
|
||||
for (i = 0; i < ics->max_sfb; i++, idx++) {
|
||||
const unsigned cbt_m1 = band_type[idx] - 1;
|
||||
int *cfo = coef + offsets[i];
|
||||
int off_len = offsets[i + 1] - offsets[i];
|
||||
int group;
|
||||
|
||||
if (cbt_m1 < NOISE_BT - 1) {
|
||||
for (group = 0; group < (int)g_len; group++, cfo+=128) {
|
||||
vector_pow43(cfo, off_len);
|
||||
subband_scale(cfo, cfo, sf[idx], 34, off_len, ac->avctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
coef += g_len << 7;
|
||||
}
|
||||
#endif /* USE_FIXED */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode coupling_channel_element; reference: table 4.8.
|
||||
*
|
||||
* @return Returns error status. 0 - OK, !0 - error
|
||||
*/
|
||||
static int AAC_RENAME(decode_cce)(AACDecContext *ac, GetBitContext *gb, ChannelElement *che)
|
||||
{
|
||||
int num_gain = 0;
|
||||
int c, g, sfb, ret;
|
||||
int sign;
|
||||
INTFLOAT scale;
|
||||
SingleChannelElement *sce = &che->ch[0];
|
||||
ChannelCoupling *coup = &che->coup;
|
||||
|
||||
coup->coupling_point = 2 * get_bits1(gb);
|
||||
coup->num_coupled = get_bits(gb, 3);
|
||||
for (c = 0; c <= coup->num_coupled; c++) {
|
||||
num_gain++;
|
||||
coup->type[c] = get_bits1(gb) ? TYPE_CPE : TYPE_SCE;
|
||||
coup->id_select[c] = get_bits(gb, 4);
|
||||
if (coup->type[c] == TYPE_CPE) {
|
||||
coup->ch_select[c] = get_bits(gb, 2);
|
||||
if (coup->ch_select[c] == 3)
|
||||
num_gain++;
|
||||
} else
|
||||
coup->ch_select[c] = 2;
|
||||
}
|
||||
coup->coupling_point += get_bits1(gb) || (coup->coupling_point >> 1);
|
||||
|
||||
sign = get_bits(gb, 1);
|
||||
#if USE_FIXED
|
||||
scale = get_bits(gb, 2);
|
||||
#else
|
||||
scale = cce_scale[get_bits(gb, 2)];
|
||||
#endif
|
||||
|
||||
if ((ret = ff_aac_decode_ics(ac, sce, gb, 0, 0)))
|
||||
return ret;
|
||||
|
||||
for (c = 0; c < num_gain; c++) {
|
||||
int idx = 0;
|
||||
int cge = 1;
|
||||
int gain = 0;
|
||||
INTFLOAT gain_cache = FIXR10(1.);
|
||||
if (c) {
|
||||
cge = coup->coupling_point == AFTER_IMDCT ? 1 : get_bits1(gb);
|
||||
gain = cge ? get_vlc2(gb, ff_vlc_scalefactors, 7, 3) - 60: 0;
|
||||
gain_cache = GET_GAIN(scale, gain);
|
||||
#if USE_FIXED
|
||||
if ((abs(gain_cache)-1024) >> 3 > 30)
|
||||
return AVERROR(ERANGE);
|
||||
#endif
|
||||
}
|
||||
if (coup->coupling_point == AFTER_IMDCT) {
|
||||
coup->gain[c][0] = gain_cache;
|
||||
} else {
|
||||
for (g = 0; g < sce->ics.num_window_groups; g++) {
|
||||
for (sfb = 0; sfb < sce->ics.max_sfb; sfb++, idx++) {
|
||||
if (sce->band_type[idx] != ZERO_BT) {
|
||||
if (!cge) {
|
||||
int t = get_vlc2(gb, ff_vlc_scalefactors, 7, 3) - 60;
|
||||
if (t) {
|
||||
int s = 1;
|
||||
t = gain += t;
|
||||
if (sign) {
|
||||
s -= 2 * (t & 0x1);
|
||||
t >>= 1;
|
||||
}
|
||||
gain_cache = GET_GAIN(scale, t) * s;
|
||||
#if USE_FIXED
|
||||
if ((abs(gain_cache)-1024) >> 3 > 30)
|
||||
return AVERROR(ERANGE);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
coup->gain[c][idx] = gain_cache;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static av_cold void AAC_RENAME(aac_proc_init)(AACDecProc *aac_proc)
|
||||
{
|
||||
#define SET(member) aac_proc->member = AAC_RENAME(member)
|
||||
SET(decode_spectrum_and_dequant);
|
||||
SET(decode_cce);
|
||||
#undef SET
|
||||
#define SET(member) aac_proc->member = AV_JOIN(ff_aac_, AAC_RENAME(member));
|
||||
SET(sbr_ctx_alloc_init);
|
||||
SET(sbr_decode_extension);
|
||||
SET(sbr_apply);
|
||||
SET(sbr_ctx_close);
|
||||
#undef SET
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -144,9 +144,10 @@ get_next:
|
||||
#endif
|
||||
} else {
|
||||
#if CONFIG_AAC_PARSER
|
||||
AACADTSHeaderInfo hdr;
|
||||
if (buf_size < AV_AAC_ADTS_HEADER_SIZE ||
|
||||
ff_adts_header_parse_buf(buf, &hdr) < 0)
|
||||
AACADTSHeaderInfo hdr, *phrd = &hdr;
|
||||
int ret = avpriv_adts_header_parse(&phrd, buf, buf_size);
|
||||
|
||||
if (ret < 0)
|
||||
return i;
|
||||
|
||||
bit_rate = hdr.bit_rate;
|
||||
|
||||
@@ -28,6 +28,16 @@
|
||||
#include "avcodec.h"
|
||||
#include "parser.h"
|
||||
|
||||
typedef enum {
|
||||
AAC_AC3_PARSE_ERROR_SYNC = -0x1030c0a,
|
||||
AAC_AC3_PARSE_ERROR_BSID = -0x2030c0a,
|
||||
AAC_AC3_PARSE_ERROR_SAMPLE_RATE = -0x3030c0a,
|
||||
AAC_AC3_PARSE_ERROR_FRAME_SIZE = -0x4030c0a,
|
||||
AAC_AC3_PARSE_ERROR_FRAME_TYPE = -0x5030c0a,
|
||||
AAC_AC3_PARSE_ERROR_CRC = -0x6030c0a,
|
||||
AAC_AC3_PARSE_ERROR_CHANNEL_CFG = -0x7030c0a,
|
||||
} AACAC3ParseError;
|
||||
|
||||
typedef struct AACAC3ParseContext {
|
||||
ParseContext pc;
|
||||
int header_size;
|
||||
|
||||
@@ -42,6 +42,7 @@ typedef int AAC_SIGNE;
|
||||
#define Q23(a) (int)((a) * 8388608.0 + 0.5)
|
||||
#define Q30(x) (int)((x)*1073741824.0 + 0.5)
|
||||
#define Q31(x) (int)((x)*2147483648.0 + 0.5)
|
||||
#define TX_SCALE(x) ((x) * 128.0f)
|
||||
#define GET_GAIN(x, y) (-(y) * (1 << (x))) + 1024
|
||||
#define AAC_MUL16(x, y) (int)(((int64_t)(x) * (y) + 0x8000) >> 16)
|
||||
#define AAC_MUL26(x, y) (int)(((int64_t)(x) * (y) + 0x2000000) >> 26)
|
||||
@@ -71,20 +72,6 @@ typedef int AAC_SIGNE;
|
||||
0x40000000) >> 31)
|
||||
#define AAC_HALF_SUM(x, y) (((x) >> 1) + ((y) >> 1))
|
||||
|
||||
/**
|
||||
* Predictor State
|
||||
*/
|
||||
typedef struct PredictorStateFixed {
|
||||
SoftFloat cor0;
|
||||
SoftFloat cor1;
|
||||
SoftFloat var0;
|
||||
SoftFloat var1;
|
||||
SoftFloat r0;
|
||||
SoftFloat r1;
|
||||
SoftFloat k1;
|
||||
SoftFloat x_est;
|
||||
} PredictorState;
|
||||
|
||||
#ifdef LPC_USE_FIXED
|
||||
#error aac_defines.h must be included before lpc_functions.h for fixed point decoder
|
||||
#endif
|
||||
@@ -109,6 +96,7 @@ typedef unsigned AAC_SIGNE;
|
||||
#define Q23(x) ((float)(x))
|
||||
#define Q30(x) ((float)(x))
|
||||
#define Q31(x) ((float)(x))
|
||||
#define TX_SCALE(x) ((x) / 32768.0f)
|
||||
#define GET_GAIN(x, y) powf((x), -(y))
|
||||
#define AAC_MUL16(x, y) ((x) * (y))
|
||||
#define AAC_MUL26(x, y) ((x) * (y))
|
||||
@@ -124,20 +112,6 @@ typedef unsigned AAC_SIGNE;
|
||||
#define AAC_MSUB31_V3(x, y, z) ((x) - (y)) * (z)
|
||||
#define AAC_HALF_SUM(x, y) ((x) + (y)) * 0.5f
|
||||
|
||||
/**
|
||||
* Predictor State
|
||||
*/
|
||||
typedef struct PredictorState {
|
||||
float cor0;
|
||||
float cor1;
|
||||
float var0;
|
||||
float var1;
|
||||
float r0;
|
||||
float r1;
|
||||
float k1;
|
||||
float x_est;
|
||||
} PredictorState;
|
||||
|
||||
#endif /* USE_FIXED */
|
||||
|
||||
#endif /* AVCODEC_AAC_DEFINES_H */
|
||||
|
||||
+11
-5
@@ -24,18 +24,24 @@
|
||||
#include "aac_ac3_parser.h"
|
||||
#include "adts_header.h"
|
||||
#include "adts_parser.h"
|
||||
#include "libavutil/intreadwrite.h"
|
||||
#include "get_bits.h"
|
||||
#include "mpeg4audio.h"
|
||||
|
||||
static int aac_sync(uint64_t state, int *need_next_header, int *new_frame_start)
|
||||
{
|
||||
uint8_t tmp[8 + AV_INPUT_BUFFER_PADDING_SIZE];
|
||||
GetBitContext bits;
|
||||
AACADTSHeaderInfo hdr;
|
||||
int size;
|
||||
union {
|
||||
uint64_t u64;
|
||||
uint8_t u8[8 + AV_INPUT_BUFFER_PADDING_SIZE];
|
||||
} tmp;
|
||||
|
||||
AV_WB64(tmp, state);
|
||||
tmp.u64 = av_be2ne64(state);
|
||||
init_get_bits(&bits, tmp.u8 + 8 - AV_AAC_ADTS_HEADER_SIZE,
|
||||
AV_AAC_ADTS_HEADER_SIZE * 8);
|
||||
|
||||
size = ff_adts_header_parse_buf(tmp + 8 - AV_AAC_ADTS_HEADER_SIZE, &hdr);
|
||||
if (size < 0)
|
||||
if ((size = ff_adts_header_parse(&bits, &hdr)) < 0)
|
||||
return 0;
|
||||
*need_next_header = 0;
|
||||
*new_frame_start = 1;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user