mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2025-12-06 23:10:00 +01:00
Compare commits
239 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1014e20492 | ||
|
|
431cf16963 | ||
|
|
e85296beae | ||
|
|
62c4739348 | ||
|
|
7efa13b4b4 | ||
|
|
a5e0afe3c9 | ||
|
|
42f0a66968 | ||
|
|
f1c9dbe40b | ||
|
|
b945f558c7 | ||
|
|
90a4a46747 | ||
|
|
6d6254ba9f | ||
|
|
ae24b5ce3a | ||
|
|
c9c7db0af2 | ||
|
|
e1a2bcbec8 | ||
|
|
d32ea79ea2 | ||
|
|
6b156c4563 | ||
|
|
57eb787ed3 | ||
|
|
dbe7e209df | ||
|
|
cfb9b47a1e | ||
|
|
b26c1a8b7e | ||
|
|
ccd2ca0246 | ||
|
|
92b964969b | ||
|
|
ca87ec53e9 | ||
|
|
bd071de29a | ||
|
|
8ddc0b491d | ||
|
|
94aacaf508 | ||
|
|
8d68083298 | ||
|
|
e28bb18fdc | ||
|
|
a62779d986 | ||
|
|
201fcfb894 | ||
|
|
8856c4c5c9 | ||
|
|
0f7bf1786e | ||
|
|
b99366faef | ||
|
|
da0900e8bb | ||
|
|
d5551d7884 | ||
|
|
35f1888585 | ||
|
|
7cd7461ec8 | ||
|
|
23f622de60 | ||
|
|
19a99b6e6b | ||
|
|
117e04cdfa | ||
|
|
5d6fe49ac9 | ||
|
|
9f28eede5e | ||
|
|
6f70111e81 | ||
|
|
4492523938 | ||
|
|
a97e82c487 | ||
|
|
f79f3a946f | ||
|
|
5394cdf775 | ||
|
|
7f163e5a87 | ||
|
|
23999c45bc | ||
|
|
14fae6eab0 | ||
|
|
f5a8c4242e | ||
|
|
1edc513bcf | ||
|
|
9864518544 | ||
|
|
4ccb8f5b7b | ||
|
|
01b9a6e447 | ||
|
|
34d2fe6860 | ||
|
|
e7746f834a | ||
|
|
973bdafe05 | ||
|
|
f4a5a730d8 | ||
|
|
603a282f8f | ||
|
|
36c196bca4 | ||
|
|
7b733e4b7f | ||
|
|
e07086d8ae | ||
|
|
d2411412f1 | ||
|
|
0facc63ff6 | ||
|
|
5ed9457260 | ||
|
|
002e6d185c | ||
|
|
81d5ceff04 | ||
|
|
86849f0976 | ||
|
|
84fce203bd | ||
|
|
572e94bc51 | ||
|
|
7487d53d01 | ||
|
|
21ad6e08e4 | ||
|
|
feca20021c | ||
|
|
394c3e78d5 | ||
|
|
2fc39af1de | ||
|
|
973d752dfb | ||
|
|
3cc3f351a6 | ||
|
|
222d18ab20 | ||
|
|
7a6bba627d | ||
|
|
9f95d7aab3 | ||
|
|
fe4a355805 | ||
|
|
88ea7ca627 | ||
|
|
03ef9828b5 | ||
|
|
2ad6e14457 | ||
|
|
39c8434bce | ||
|
|
701dd6eab0 | ||
|
|
f5d14a92cb | ||
|
|
b5c3b18bfc | ||
|
|
8539ea3265 | ||
|
|
9848e1be2d | ||
|
|
66ebf37c73 | ||
|
|
036fefebb9 | ||
|
|
1916656641 | ||
|
|
ace432f62c | ||
|
|
f8969f8ea9 | ||
|
|
36f3244ec8 | ||
|
|
553ae88b2e | ||
|
|
9b919571e5 | ||
|
|
99d3772ef4 | ||
|
|
15cfc6c97d | ||
|
|
b4eafa8b04 | ||
|
|
2b2856bac2 | ||
|
|
52f9b632b5 | ||
|
|
79e0cbae33 | ||
|
|
7fc5bffb54 | ||
|
|
4940d1c0ae | ||
|
|
b0f8fdc411 | ||
|
|
ba1927dda9 | ||
|
|
dda2062c31 | ||
|
|
5d01cd8429 | ||
|
|
f9bf2a4ab1 | ||
|
|
cf69619141 | ||
|
|
2d782b9646 | ||
|
|
5e3d023702 | ||
|
|
4ac56bf7dc | ||
|
|
a38489c0d8 | ||
|
|
a5200fac2c | ||
|
|
32b0876fb5 | ||
|
|
e33f58af5a | ||
|
|
540c6cca6e | ||
|
|
08f5b2464d | ||
|
|
79a16f0cac | ||
|
|
9ad774ff33 | ||
|
|
84149812a6 | ||
|
|
d41187cb9e | ||
|
|
094e849f32 | ||
|
|
ba90f93852 | ||
|
|
93883b0c39 | ||
|
|
61eb165514 | ||
|
|
9d1213912f | ||
|
|
edf5072fea | ||
|
|
32fa7cecd7 | ||
|
|
b9ebd7dc7d | ||
|
|
55b6e09e5e | ||
|
|
aa48d9e64c | ||
|
|
d7e98ea6ac | ||
|
|
8182bcae90 | ||
|
|
522f1861ca | ||
|
|
44f91788a5 | ||
|
|
03b47bb8d7 | ||
|
|
05b4e4fe49 | ||
|
|
3229bf8573 | ||
|
|
db06ddf8c6 | ||
|
|
eb4b8b96fc | ||
|
|
373010971e | ||
|
|
c3cd8890fe | ||
|
|
20d4a1f020 | ||
|
|
e5880b3f24 | ||
|
|
4b51239df3 | ||
|
|
4979362ae4 | ||
|
|
0546386dff | ||
|
|
70ea5176a5 | ||
|
|
661092004f | ||
|
|
f7f9f18f83 | ||
|
|
55291e37f5 | ||
|
|
1f1d2fa75c | ||
|
|
2a546cecbf | ||
|
|
8f3504c3ca | ||
|
|
bf20d5e4bb | ||
|
|
3fa19f6828 | ||
|
|
4e62a67389 | ||
|
|
46ac6315fd | ||
|
|
9052b5b73b | ||
|
|
9181adff9c | ||
|
|
8261cce1f0 | ||
|
|
df62b0d9f5 | ||
|
|
e63d03e7e2 | ||
|
|
7920dc8802 | ||
|
|
057287c9cd | ||
|
|
1746657479 | ||
|
|
0ff244dea2 | ||
|
|
0078216f07 | ||
|
|
12ca60ec15 | ||
|
|
2c3439b008 | ||
|
|
cdfe333493 | ||
|
|
5f1a8c5e80 | ||
|
|
b5afece607 | ||
|
|
6ae05f541a | ||
|
|
9d3bb3501d | ||
|
|
0b374e40b1 | ||
|
|
a2a26d108b | ||
|
|
49aa53f2d7 | ||
|
|
fb2fc3a4f0 | ||
|
|
36edfb558b | ||
|
|
4a7c99d6f3 | ||
|
|
327afd42b4 | ||
|
|
a22222dadb | ||
|
|
28631e9393 | ||
|
|
f8a6c707a5 | ||
|
|
c9b841c2b1 | ||
|
|
15b20ef6f9 | ||
|
|
1dea5cfbb0 | ||
|
|
d48539fb85 | ||
|
|
a14f86aac7 | ||
|
|
6438cb834c | ||
|
|
ed2b1f80fa | ||
|
|
3d24c2ce02 | ||
|
|
7d8b893b7e | ||
|
|
e6ef35bc22 | ||
|
|
3588e6b7c5 | ||
|
|
34a0dee17e | ||
|
|
b9a35435a5 | ||
|
|
85ed859e6b | ||
|
|
fcaba83909 | ||
|
|
daf864016d | ||
|
|
7454142424 | ||
|
|
a7216204eb | ||
|
|
cff1f85c3f | ||
|
|
dd92ff49c9 | ||
|
|
b12045c8c7 | ||
|
|
a70e7cc928 | ||
|
|
6f8fbbf8d7 | ||
|
|
b68d9df427 | ||
|
|
26fe0ec7d6 | ||
|
|
7590718414 | ||
|
|
37a0852009 | ||
|
|
b50601e882 | ||
|
|
d1026ab506 | ||
|
|
08a441d4ad | ||
|
|
369e37e900 | ||
|
|
40630a90ed | ||
|
|
dc04fb36d7 | ||
|
|
8740ed496c | ||
|
|
77a023f422 | ||
|
|
ba9cecf5e5 | ||
|
|
8ab1409a59 | ||
|
|
3589ac6334 | ||
|
|
dd68bb3cab | ||
|
|
50dab63690 | ||
|
|
da8e4f5f79 | ||
|
|
e0e0283778 | ||
|
|
1673bf86d6 | ||
|
|
0db6f6cfed | ||
|
|
9d08b20fea | ||
|
|
a03dcb9682 | ||
|
|
26899578f1 | ||
|
|
eb9df4ac33 | ||
|
|
64c2076bfc |
@@ -1,93 +0,0 @@
|
||||
# This file describes the expected reviewers for a PR based on the changed
|
||||
# files. Unlike what the name of the file suggests they don't own the code, but
|
||||
# merely have a good understanding of that area of the codebase and therefore
|
||||
# are usually suited as a reviewer.
|
||||
|
||||
# Lines in this file match changed paths via Go-Style regular expressions:
|
||||
# https://pkg.go.dev/regexp/syntax
|
||||
|
||||
# Mind the alphabetical order
|
||||
|
||||
# avcodec
|
||||
# =======
|
||||
libavcodec/.*aac.* @lynne
|
||||
libavcodec/.*ac3.* @lynne
|
||||
libavcodec/.*atrac9.* @lynne
|
||||
libavcodec/.*bitpacked.* @lynne
|
||||
libavcodec/.*d3d12va.* @jianhuaw
|
||||
libavcodec/.*dirac.* @lynne
|
||||
libavcodec/.*ffv1.* @lynne @michaelni
|
||||
libavcodec/golomb.* @michaelni
|
||||
libavcodec/.*h266.* @frankplow @NuoMi @jianhuaw
|
||||
libavcodec/h26x/.* @frankplow @NuoMi @jianhuaw
|
||||
libavcodec/.*jpegxl.* @lynne
|
||||
libavcodec/.*jxl.* @lynne
|
||||
libavcodec/.*opus.* @lynne
|
||||
libavcodec/.*prores.* @lynne
|
||||
libavcodec/rangecoder.* @michaelni
|
||||
libavcodec/ratecontrol.* @michaelni
|
||||
libavcodec/.*siren.* @lynne
|
||||
libavcodec/.*vc2.* @lynne
|
||||
libavcodec/.*vvc.* @frankplow @NuoMi @jianhuaw
|
||||
|
||||
libavcodec/aarch64/.* @lynne @mstorsjo
|
||||
libavcodec/arm/.* @mstorsjo
|
||||
libavcodec/ppc/.* @sean_mcg
|
||||
libavcodec/x86/.* @lynne
|
||||
|
||||
# avfilter
|
||||
# =======
|
||||
libavfilter/aarch64/.* @mstorsjo
|
||||
libavfilter/af_whisper.* @vpalmisano
|
||||
libavfilter/vf_yadif.* @michaelni
|
||||
libavfilter/vsrc_mandelbrot.* @michaelni
|
||||
|
||||
# avformat
|
||||
# =======
|
||||
libavformat/iamf.* @jamrial
|
||||
|
||||
# avutil
|
||||
# ======
|
||||
libavutil/.*crc.* @lynne @michaelni
|
||||
libavutil/.*d3d12va.* @jianhuaw
|
||||
libavutil/eval.* @michaelni
|
||||
libavutil/iamf.* @jamrial
|
||||
libavutil/integer.* @michaelni
|
||||
libavutil/lfg.* @michaelni
|
||||
libavutil/lls.* @michaelni
|
||||
libavutil/md5.* @michaelni
|
||||
libavutil/mathematics.* @michaelni
|
||||
libavutil/mem.* @michaelni
|
||||
libavutil/qsort.* @michaelni
|
||||
libavutil/random_seed.* @michaelni
|
||||
libavutil/rational.* @michaelni
|
||||
libavutil/sfc.* @michaelni
|
||||
libavutil/softfloat.* @michaelni
|
||||
libavutil/tree.* @michaelni
|
||||
libavutil/tx.* @lynne
|
||||
|
||||
libavutil/aarch64/.* @lynne @mstorsjo
|
||||
libavutil/arm/.* @mstorsjo
|
||||
libavutil/ppc/.* @sean_mcg
|
||||
libavutil/x86/.* @lynne
|
||||
|
||||
# swresample
|
||||
# =======
|
||||
libswresample/aarch64/.* @mstorsjo
|
||||
libswresample/arm/.* @mstorsjo
|
||||
libswresample/.* @michaelni
|
||||
|
||||
# swscale
|
||||
# =======
|
||||
libswscale/aarch64/.* @mstorsjo
|
||||
libswscale/arm/.* @mstorsjo
|
||||
libswscale/ppc/.* @sean_mcg
|
||||
|
||||
# doc
|
||||
# ===
|
||||
doc/.* @GyanD
|
||||
|
||||
# Frameworks
|
||||
# ==========
|
||||
.*d3d12va.* @jianhuaw
|
||||
.*vulkan.* @lynne
|
||||
@@ -1,9 +0,0 @@
|
||||
# Summary of the bug
|
||||
|
||||
Briefly describe the issue you're experiencing. Include any error messages, unexpected behavior, or relevant observations.
|
||||
|
||||
# Steps to reproduce
|
||||
|
||||
List the steps required to trigger the bug.
|
||||
Include the exact CLI command used, if any.
|
||||
Provide sample input files, logs, or scripts if available.
|
||||
@@ -1,36 +0,0 @@
|
||||
module.exports = async ({github, context}) => {
|
||||
const title = (context.payload.pull_request?.title || context.payload.issue?.title || '').toLowerCase();
|
||||
const labels = [];
|
||||
|
||||
const kwmap = {
|
||||
'avcodec': 'avcodec',
|
||||
'avdevice': 'avdevice',
|
||||
'avfilter': 'avfilter',
|
||||
'avformat': 'avformat',
|
||||
'avutil': 'avutil',
|
||||
'swresample': 'swresample',
|
||||
'swscale': 'swscale',
|
||||
'fftools': 'CLI'
|
||||
};
|
||||
|
||||
if (context.payload.action === 'opened') {
|
||||
labels.push('new');
|
||||
console.log('Detected label: new');
|
||||
}
|
||||
|
||||
for (const [kw, label] of Object.entries(kwmap)) {
|
||||
if (title.includes(kw)) {
|
||||
labels.push(label);
|
||||
console.log('Detected label: ' + label);
|
||||
}
|
||||
}
|
||||
|
||||
if (labels.length > 0) {
|
||||
await github.rest.issues.addLabels({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: context.payload.pull_request?.number || context.payload.issue?.number,
|
||||
labels: labels,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
avcodec:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: libavcodec/**
|
||||
|
||||
avdevice:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: libavdevice/**
|
||||
|
||||
avfilter:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: libavfilter/**
|
||||
|
||||
avformat:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: libavformat/**
|
||||
|
||||
avutil:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: libavutil/**
|
||||
|
||||
swresample:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: libswresample/**
|
||||
|
||||
swscale:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: libswscale/**
|
||||
|
||||
CLI:
|
||||
- changed-files:
|
||||
- any-glob-to-any-file: fftools/**
|
||||
@@ -1,28 +0,0 @@
|
||||
exclude: ^tests/ref/
|
||||
|
||||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v5.0.0
|
||||
hooks:
|
||||
- id: check-case-conflict
|
||||
- id: check-executables-have-shebangs
|
||||
- id: check-illegal-windows-names
|
||||
- id: check-shebang-scripts-are-executable
|
||||
- id: check-yaml
|
||||
- id: end-of-file-fixer
|
||||
- id: file-contents-sorter
|
||||
files:
|
||||
.forgejo/pre-commit/ignored-words.txt
|
||||
args:
|
||||
- --ignore-case
|
||||
- id: fix-byte-order-marker
|
||||
- id: mixed-line-ending
|
||||
- id: trailing-whitespace
|
||||
- repo: https://github.com/codespell-project/codespell
|
||||
rev: v2.4.1
|
||||
hooks:
|
||||
- id: codespell
|
||||
args:
|
||||
- --ignore-words=.forgejo/pre-commit/ignored-words.txt
|
||||
- --ignore-multiline-regex=codespell:off.*?(codespell:on|\Z)
|
||||
exclude: ^tools/(patcheck|clean-diff)$
|
||||
@@ -1,119 +0,0 @@
|
||||
abl
|
||||
ACN
|
||||
acount
|
||||
addin
|
||||
alis
|
||||
alls
|
||||
ALOG
|
||||
ALS
|
||||
als
|
||||
ANC
|
||||
anc
|
||||
ANS
|
||||
ans
|
||||
anull
|
||||
basf
|
||||
bloc
|
||||
brane
|
||||
BREIF
|
||||
BU
|
||||
bu
|
||||
bufer
|
||||
CAF
|
||||
caf
|
||||
clen
|
||||
clens
|
||||
Collet
|
||||
compre
|
||||
dum
|
||||
endin
|
||||
erro
|
||||
FIEL
|
||||
fiel
|
||||
filp
|
||||
fils
|
||||
FILTERD
|
||||
filterd
|
||||
fle
|
||||
fo
|
||||
FPR
|
||||
fro
|
||||
Hald
|
||||
indx
|
||||
ine
|
||||
inh
|
||||
inout
|
||||
inouts
|
||||
inport
|
||||
ist
|
||||
LAF
|
||||
laf
|
||||
lastr
|
||||
LinS
|
||||
mapp
|
||||
mis
|
||||
mot
|
||||
nd
|
||||
nIn
|
||||
offsetp
|
||||
orderd
|
||||
ot
|
||||
outout
|
||||
padd
|
||||
PAETH
|
||||
paeth
|
||||
PARM
|
||||
parm
|
||||
parms
|
||||
pEvents
|
||||
PixelX
|
||||
Psot
|
||||
quater
|
||||
readd
|
||||
recuse
|
||||
redY
|
||||
Reencode
|
||||
reencode
|
||||
remaind
|
||||
renderD
|
||||
rin
|
||||
SAV
|
||||
SEH
|
||||
SER
|
||||
ser
|
||||
setts
|
||||
shft
|
||||
SIZ
|
||||
siz
|
||||
skipd
|
||||
sme
|
||||
som
|
||||
sover
|
||||
STAP
|
||||
startd
|
||||
statics
|
||||
struc
|
||||
suble
|
||||
TE
|
||||
tE
|
||||
te
|
||||
tha
|
||||
tne
|
||||
tolen
|
||||
tpye
|
||||
tre
|
||||
TRUN
|
||||
trun
|
||||
truns
|
||||
Tung
|
||||
TYE
|
||||
ue
|
||||
UES
|
||||
ues
|
||||
vai
|
||||
vas
|
||||
vie
|
||||
VILL
|
||||
vor
|
||||
wel
|
||||
wih
|
||||
@@ -1,25 +0,0 @@
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [opened, edited, synchronize]
|
||||
issues:
|
||||
types: [opened, edited]
|
||||
|
||||
jobs:
|
||||
pr_labeler:
|
||||
runs-on: utilities
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Label by file-changes
|
||||
uses: https://github.com/actions/labeler@v5
|
||||
if: ${{ forge.event_name == 'pull_request_target' }}
|
||||
with:
|
||||
configuration-path: .forgejo/labeler/labeler.yml
|
||||
repo-token: ${{ secrets.AUTOLABELER_TOKEN }}
|
||||
- name: Label by title-match
|
||||
uses: https://github.com/actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const script = require('.forgejo/labeler/labeler.js')
|
||||
await script({github, context})
|
||||
github-token: ${{ secrets.AUTOLABELER_TOKEN }}
|
||||
@@ -1,26 +0,0 @@
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: utilities
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Install pre-commit CI
|
||||
id: install
|
||||
run: |
|
||||
python3 -m venv ~/pre-commit
|
||||
~/pre-commit/bin/pip install --upgrade pip setuptools
|
||||
~/pre-commit/bin/pip install pre-commit
|
||||
echo "envhash=$({ python3 --version && cat .forgejo/pre-commit/config.yaml; } | sha256sum | cut -d' ' -f1)" >> $FORGEJO_OUTPUT
|
||||
- name: Cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.cache/pre-commit
|
||||
key: pre-commit-${{ steps.install.outputs.envhash }}
|
||||
- name: Run pre-commit CI
|
||||
run: ~/pre-commit/bin/pre-commit run -c .forgejo/pre-commit/config.yaml --show-diff-on-failure --color=always --all-files
|
||||
@@ -1,59 +0,0 @@
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
run_fate:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
runner: [linux-amd64,linux-aarch64]
|
||||
runs-on: ${{ matrix.runner }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Configure
|
||||
run: ./configure --enable-gpl --enable-nonfree --enable-memory-poisoning --assert-level=2
|
||||
- name: Build
|
||||
run: make -j$(nproc)
|
||||
- name: Restore Cached Fate-Suite
|
||||
id: cache
|
||||
uses: actions/cache/restore@v4
|
||||
with:
|
||||
path: fate-suite
|
||||
key: fate-suite
|
||||
restore-keys: |
|
||||
fate-suite-
|
||||
- name: Sync Fate-Suite
|
||||
id: fate
|
||||
run: |
|
||||
make fate-rsync SAMPLES=$PWD/fate-suite
|
||||
echo "hash=$(find fate-suite -type f | sort | sha256sum | cut -d' ' -f1)" >> $FORGEJO_OUTPUT
|
||||
- name: Cache Fate-Suite
|
||||
uses: actions/cache/save@v4
|
||||
if: ${{ format('fate-suite-{0}', steps.fate.outputs.hash) != steps.cache.outputs.cache-matched-key }}
|
||||
with:
|
||||
path: fate-suite
|
||||
key: fate-suite-${{ steps.fate.outputs.hash }}
|
||||
- name: Run Fate
|
||||
run: make fate SAMPLES=$PWD/fate-suite -j$(nproc)
|
||||
compile_only:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
image: ["ghcr.io/btbn/ffmpeg-builds/win64-gpl:latest"]
|
||||
runs-on: linux-amd64
|
||||
container: ${{ matrix.image }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Configure
|
||||
run: |
|
||||
./configure --pkg-config-flags="--static" $FFBUILD_TARGET_FLAGS $FF_CONFIGURE \
|
||||
--cc="$CC" --cxx="$CXX" --ar="$AR" --ranlib="$RANLIB" --nm="$NM" \
|
||||
--extra-cflags="$FF_CFLAGS" --extra-cxxflags="$FF_CXXFLAGS" \
|
||||
--extra-libs="$FF_LIBS" --extra-ldflags="$FF_LDFLAGS" --extra-ldexeflags="$FF_LDEXEFLAGS"
|
||||
- name: Build
|
||||
run: make -j$(nproc)
|
||||
2
.gitattributes
vendored
2
.gitattributes
vendored
@@ -1,2 +0,0 @@
|
||||
*.pnm -diff -text
|
||||
Changelog merge=union
|
||||
85
.gitignore
vendored
85
.gitignore
vendored
@@ -1,48 +1,45 @@
|
||||
*.a
|
||||
.config
|
||||
.version
|
||||
*.o
|
||||
*.objs
|
||||
*.o.*
|
||||
*.d
|
||||
*.def
|
||||
*.dll
|
||||
*.dylib
|
||||
*.exe
|
||||
*.exp
|
||||
*.gcda
|
||||
*.gcno
|
||||
*.h.c
|
||||
*.ilk
|
||||
*.lib
|
||||
*.pc
|
||||
*.pdb
|
||||
*.so
|
||||
*.so.*
|
||||
*.swp
|
||||
*.ver
|
||||
*.version
|
||||
*.metal.air
|
||||
*.metallib
|
||||
*.metallib.c
|
||||
*.ptx
|
||||
*.ptx.c
|
||||
*.ptx.gz
|
||||
*.ho
|
||||
*-example
|
||||
*-test
|
||||
*_g
|
||||
\#*
|
||||
.\#*
|
||||
/.config
|
||||
/.version
|
||||
/ffmpeg
|
||||
/ffplay
|
||||
/ffprobe
|
||||
/config.asm
|
||||
/config.h
|
||||
/config_components.h
|
||||
/coverage.info
|
||||
/lcov/
|
||||
/src
|
||||
/mapfile
|
||||
/tools/python/__pycache__/
|
||||
/libavcodec/vulkan/*.c
|
||||
/libavfilter/vulkan/*.c
|
||||
/.*/
|
||||
!/.forgejo/
|
||||
config.*
|
||||
doc/*.1
|
||||
doc/*.html
|
||||
doc/*.pod
|
||||
doxy
|
||||
ffmpeg
|
||||
ffplay
|
||||
ffprobe
|
||||
ffserver
|
||||
libavcodec/libavcodec*
|
||||
libavcore/libavcore*
|
||||
libavdevice/libavdevice*
|
||||
libavfilter/libavfilter*
|
||||
libavformat/libavformat*
|
||||
libavutil/avconfig.h
|
||||
libavutil/libavutil*
|
||||
libpostproc/libpostproc*
|
||||
libswscale/libswscale*
|
||||
tests/audiogen
|
||||
tests/base64
|
||||
tests/data
|
||||
tests/rotozoom
|
||||
tests/seek_test
|
||||
tests/tiny_psnr
|
||||
tests/videogen
|
||||
tests/vsynth1
|
||||
tests/vsynth2
|
||||
tools/cws2fws
|
||||
tools/graph2dot
|
||||
tools/lavfi-showfiltfmts
|
||||
tools/pktdumper
|
||||
tools/probetest
|
||||
tools/qt-faststart
|
||||
tools/trasher
|
||||
tools/trasher*.d
|
||||
version.h
|
||||
|
||||
30
.mailmap
30
.mailmap
@@ -1,30 +0,0 @@
|
||||
<jeebjp@gmail.com> <jan.ekstrom@aminocom.com>
|
||||
<sw@jkqxz.net> <mrt@jkqxz.net>
|
||||
<u@pkh.me> <cboesch@gopro.com>
|
||||
<quinkblack@foxmail.com> <wantlamy@gmail.com>
|
||||
<quinkblack@foxmail.com> <zhilizhao@tencent.com>
|
||||
<modmaker@google.com> <modmaker-at-google.com@ffmpeg.org>
|
||||
<stebbins@jetheaddev.com> <jstebbins@jetheaddev.com>
|
||||
<barryjzhao@tencent.com> <mypopydev@gmail.com>
|
||||
<barryjzhao@tencent.com> <jun.zhao@intel.com>
|
||||
<josh@itanimul.li> <joshdk@obe.tv>
|
||||
<michael@niedermayer.cc> <michaelni@gmx.at>
|
||||
<linjie.justin.fu@gmail.com> <linjie.fu@intel.com>
|
||||
<linjie.justin.fu@gmail.com> <fulinjie@zju.edu.cn>
|
||||
<ceffmpeg@gmail.com> <cehoyos@ag.or.at>
|
||||
<ceffmpeg@gmail.com> <cehoyos@rainbow.studorg.tuwien.ac.at>
|
||||
<ffmpeg@gyani.pro> <gyandoshi@gmail.com>
|
||||
<atomnuker@gmail.com> <rpehlivanov@obe.tv>
|
||||
<lizhong1008@gmail.com> <zhong.li@intel.com>
|
||||
<lizhong1008@gmail.com> <zhongli_dev@126.com>
|
||||
<andreas.rheinhardt@outlook.com> <andreas.rheinhardt@gmail.com>
|
||||
<andreas.rheinhardt@outlook.com> <andreas.rheinhardt@googlemail.com>
|
||||
rcombs <rcombs@rcombs.me> <rodger.combs@gmail.com>
|
||||
<thilo.borgmann@mail.de> <thilo.borgmann@googlemail.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>
|
||||
<toqsxw@outlook.com> <jianhua.wu-at-intel.com@ffmpeg.org>
|
||||
<toqsxw@outlook.com> <jianhua.wu@intel.com>
|
||||
@@ -1,4 +0,0 @@
|
||||
# Note to Github users
|
||||
Patches should be submitted to the [ffmpeg-devel mailing list](https://ffmpeg.org/mailman/listinfo/ffmpeg-devel) using `git format-patch` or `git send-email`. Github pull requests should be avoided because they are not part of our review process and **will be ignored**.
|
||||
|
||||
See [https://ffmpeg.org/developer.html#Contributing](https://ffmpeg.org/developer.html#Contributing) for more information.
|
||||
@@ -55,7 +55,7 @@ modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
@@ -111,7 +111,7 @@ modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
@@ -158,7 +158,7 @@ Library.
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
@@ -216,7 +216,7 @@ instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
@@ -267,7 +267,7 @@ Library will still fall under Section 6.)
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
@@ -329,7 +329,7 @@ restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
@@ -370,7 +370,7 @@ subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
@@ -422,7 +422,7 @@ conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
@@ -456,7 +456,7 @@ SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
@@ -500,3 +500,5 @@ necessary. Here is a sample; alter the names:
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
|
||||
|
||||
|
||||
57
CREDITS
57
CREDITS
@@ -1,6 +1,53 @@
|
||||
See the Git history of the project (https://git.ffmpeg.org/ffmpeg) to
|
||||
get the names of people who have contributed to FFmpeg.
|
||||
This file contains the name of the people who have contributed to
|
||||
FFmpeg. The names are sorted alphabetically by last name.
|
||||
|
||||
To check the log, you can type the command "git log" in the FFmpeg
|
||||
source directory, or browse the online repository at
|
||||
https://git.ffmpeg.org/ffmpeg
|
||||
Dénes Balatoni
|
||||
Michel Bardiaux
|
||||
Fabrice Bellard
|
||||
Patrice Bensoussan
|
||||
Alex Beregszaszi
|
||||
BERO
|
||||
Thilo Borgmann
|
||||
Mario Brito
|
||||
Ronald Bultje
|
||||
Alex Converse
|
||||
Maarten Daniels
|
||||
Reimar Doeffinger
|
||||
Tim Ferguson
|
||||
Brian Foley
|
||||
Arpad Gereoffy
|
||||
Philip Gladstone
|
||||
Vladimir Gneushev
|
||||
Roine Gustafsson
|
||||
David Hammerton
|
||||
Wolfgang Hesseler
|
||||
Marc Hoffman
|
||||
Falk Hueffner
|
||||
Aurélien Jacobs
|
||||
Steven Johnson
|
||||
Zdenek Kabelac
|
||||
Robin Kay
|
||||
Todd Kirby
|
||||
Nick Kurshev
|
||||
Benjamin Larsson
|
||||
Loïc Le Loarer
|
||||
Daniel Maas
|
||||
Mike Melanson
|
||||
Loren Merritt
|
||||
Jeff Muizelaar
|
||||
Michael Niedermayer
|
||||
François Revol
|
||||
Peter Ross
|
||||
Måns Rullgård
|
||||
Stefano Sabatini
|
||||
Roman Shaposhnik
|
||||
Oded Shimon
|
||||
Dieter Shirley
|
||||
Konstantin Shishkov
|
||||
Juan J. Sierralta
|
||||
Ewald Snel
|
||||
Sascha Sommer
|
||||
Leon van Stuivenberg
|
||||
Roberto Togni
|
||||
Lionel Ulmer
|
||||
Reynaldo Verdejo
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"drips": {
|
||||
"ethereum": {
|
||||
"ownedBy": "0x2f3900e7064eE63D30d749971265858612AA7139"
|
||||
}
|
||||
}
|
||||
}
|
||||
11
INSTALL
Normal file
11
INSTALL
Normal file
@@ -0,0 +1,11 @@
|
||||
|
||||
1) Type './configure' to create the configuration. A list of configure
|
||||
options is printed by running 'configure --help'.
|
||||
|
||||
'configure' can be launched from a directory different from the FFmpeg
|
||||
sources to build the objects out of tree. To do this, use an absolute
|
||||
path when launching 'configure', e.g. '/ffmpegdir/ffmpeg/configure'.
|
||||
|
||||
2) Then type 'make' to build FFmpeg. GNU Make 3.81 or later is required.
|
||||
|
||||
3) Type 'make install' to install all binaries and libraries you built.
|
||||
28
INSTALL.md
28
INSTALL.md
@@ -1,28 +0,0 @@
|
||||
## Installing FFmpeg
|
||||
|
||||
0. If you like to include source plugins, merge them before configure
|
||||
for example run tools/merge-all-source-plugins
|
||||
|
||||
1. Type `./configure` to create the configuration. A list of configure
|
||||
options is printed by running `configure --help`.
|
||||
|
||||
`configure` can be launched from a directory different from the FFmpeg
|
||||
sources to build the objects out of tree. To do this, use an absolute
|
||||
path when launching `configure`, e.g. `/ffmpegdir/ffmpeg/configure`.
|
||||
|
||||
2. Then type `make` to build FFmpeg. GNU Make 3.81 or later is required.
|
||||
|
||||
3. Type `make install` to install all binaries and libraries you built.
|
||||
|
||||
NOTICE
|
||||
------
|
||||
|
||||
- Non system dependencies (e.g. libx264, libvpx) are disabled by default.
|
||||
|
||||
NOTICE for Package Maintainers
|
||||
------------------------------
|
||||
|
||||
- It is recommended to build FFmpeg twice, first with minimal external dependencies so
|
||||
that 3rd party packages, which depend on FFmpegs libavutil/libavfilter/libavcodec/libavformat
|
||||
can then be built. And last build FFmpeg with full dependencies (which may in turn depend on
|
||||
some of these 3rd party packages). This avoids circular dependencies during build.
|
||||
50
LICENSE
Normal file
50
LICENSE
Normal file
@@ -0,0 +1,50 @@
|
||||
FFmpeg:
|
||||
-------
|
||||
|
||||
Most files in FFmpeg are under the GNU Lesser General Public License version 2.1
|
||||
or later (LGPL v2.1+). Read the file COPYING.LGPLv2.1 for details. Some other
|
||||
files have MIT/X11/BSD-style licenses. In combination the LGPL v2.1+ applies to
|
||||
FFmpeg.
|
||||
|
||||
Some optional parts of FFmpeg are licensed under the GNU General Public License
|
||||
version 2 or later (GPL v2+). See the file COPYING.GPLv2 for details. None of
|
||||
these parts are used by default, you have to explicitly pass --enable-gpl to
|
||||
configure to activate them. In this case, FFmpeg's license changes to GPL v2+.
|
||||
|
||||
Specifically, the GPL parts of FFmpeg are
|
||||
|
||||
- libpostproc
|
||||
- optional MMX optimizations for YUV to RGB colorspace conversion in
|
||||
libswscale/x86/yuv2rgb_template.c
|
||||
- optional x86 optimizations in the files
|
||||
libavcodec/x86/h264_deblock_sse2.asm
|
||||
libavcodec/x86/h264_idct_sse2.asm
|
||||
libavcodec/x86/idct_mmx.c
|
||||
- the X11 grabber in libavdevice/x11grab.c
|
||||
|
||||
There are a handful of files under other licensing terms, namely:
|
||||
|
||||
* The files libavcodec/jfdctfst.c, libavcodec/jfdctint.c, libavcodec/jrevdct.c
|
||||
are taken from libjpeg, see the top of the files for licensing details.
|
||||
|
||||
Should you, for whatever reason, prefer to use version 3 of the (L)GPL, then
|
||||
the configure parameter --enable-version3 will activate this licensing option
|
||||
for you. Read the file COPYING.LGPLv3 or, if you have enabled GPL parts,
|
||||
COPYING.GPLv3 to learn the exact legal terms that apply in this case.
|
||||
|
||||
|
||||
external libraries:
|
||||
-------------------
|
||||
|
||||
Some external libraries, e.g. libx264, are under GPL and can be used in
|
||||
conjunction with FFmpeg. They require --enable-gpl to be passed to configure
|
||||
as well.
|
||||
|
||||
The OpenCORE external libraries are under the Apache License 2.0. That license
|
||||
is incompatible with the LGPL v2.1 and the GPL v2, but not with version 3 of
|
||||
those licenses. So to combine the OpenCORE libraries with FFmpeg, the license
|
||||
version needs to be upgraded by passing --enable-version3 to configure.
|
||||
|
||||
The nonfree external library libfaac can be hooked up in FFmpeg. You need to
|
||||
pass --enable-nonfree to configure to enable it. Employ this option with care
|
||||
as FFmpeg then becomes nonfree and unredistributable.
|
||||
127
LICENSE.md
127
LICENSE.md
@@ -1,127 +0,0 @@
|
||||
# License
|
||||
|
||||
Most files in FFmpeg are under the GNU Lesser General Public License version 2.1
|
||||
or later (LGPL v2.1+). Read the file `COPYING.LGPLv2.1` for details. Some other
|
||||
files have MIT/X11/BSD-style licenses. In combination the LGPL v2.1+ applies to
|
||||
FFmpeg.
|
||||
|
||||
Some optional parts of FFmpeg are licensed under the GNU General Public License
|
||||
version 2 or later (GPL v2+). See the file `COPYING.GPLv2` for details. None of
|
||||
these parts are used by default, you have to explicitly pass `--enable-gpl` to
|
||||
configure to activate them. In this case, FFmpeg's license changes to GPL v2+.
|
||||
|
||||
Specifically, the GPL parts of FFmpeg are:
|
||||
|
||||
- optional x86 optimization in the files
|
||||
- `libavcodec/x86/flac_dsp_gpl.asm`
|
||||
- `libavcodec/x86/idct_mmx.c`
|
||||
- `libavfilter/x86/vf_removegrain.asm`
|
||||
- the following building and testing tools
|
||||
- `compat/solaris/make_sunver.pl`
|
||||
- `doc/t2h.pm`
|
||||
- `doc/texi2pod.pl`
|
||||
- `libswresample/tests/swresample.c`
|
||||
- `tests/checkasm/*`
|
||||
- `tests/tiny_ssim.c`
|
||||
- the following filters in libavfilter:
|
||||
- `signature_lookup.c`
|
||||
- `vf_blackframe.c`
|
||||
- `vf_boxblur.c`
|
||||
- `vf_colormatrix.c`
|
||||
- `vf_cover_rect.c`
|
||||
- `vf_cropdetect.c`
|
||||
- `vf_delogo.c`
|
||||
- `vf_eq.c`
|
||||
- `vf_find_rect.c`
|
||||
- `vf_fspp.c`
|
||||
- `vf_histeq.c`
|
||||
- `vf_hqdn3d.c`
|
||||
- `vf_kerndeint.c`
|
||||
- `vf_lensfun.c` (GPL version 3 or later)
|
||||
- `vf_mcdeint.c`
|
||||
- `vf_mpdecimate.c`
|
||||
- `vf_nnedi.c`
|
||||
- `vf_owdenoise.c`
|
||||
- `vf_perspective.c`
|
||||
- `vf_phase.c`
|
||||
- `vf_pp7.c`
|
||||
- `vf_pullup.c`
|
||||
- `vf_repeatfields.c`
|
||||
- `vf_sab.c`
|
||||
- `vf_signature.c`
|
||||
- `vf_smartblur.c`
|
||||
- `vf_spp.c`
|
||||
- `vf_stereo3d.c`
|
||||
- `vf_super2xsai.c`
|
||||
- `vf_tinterlace.c`
|
||||
- `vf_uspp.c`
|
||||
- `vf_vaguedenoiser.c`
|
||||
- `vsrc_mptestsrc.c`
|
||||
|
||||
Should you, for whatever reason, prefer to use version 3 of the (L)GPL, then
|
||||
the configure parameter `--enable-version3` will activate this licensing option
|
||||
for you. Read the file `COPYING.LGPLv3` or, if you have enabled GPL parts,
|
||||
`COPYING.GPLv3` to learn the exact legal terms that apply in this case.
|
||||
|
||||
There are a handful of files under other licensing terms, namely:
|
||||
|
||||
* The files `libavcodec/jfdctfst.c`, `libavcodec/jfdctint_template.c` and
|
||||
`libavcodec/jrevdct.c` are taken from libjpeg, see the top of the files for
|
||||
licensing details. Specifically note that you must credit the IJG in the
|
||||
documentation accompanying your program if you only distribute executables.
|
||||
You must also indicate any changes including additions and deletions to
|
||||
those three files in the documentation.
|
||||
* `tests/reference.pnm` is under the expat license.
|
||||
|
||||
|
||||
## External libraries
|
||||
|
||||
FFmpeg can be combined with a number of external libraries, which sometimes
|
||||
affect the licensing of binaries resulting from the combination.
|
||||
|
||||
### Compatible libraries
|
||||
|
||||
The following libraries are under GPL version 2:
|
||||
- avisynth
|
||||
- frei0r
|
||||
- libcdio
|
||||
- libdavs2
|
||||
- librubberband
|
||||
- libvidstab
|
||||
- libx264
|
||||
- libx265
|
||||
- libxavs
|
||||
- libxavs2
|
||||
- libxvid
|
||||
|
||||
When combining them with FFmpeg, FFmpeg needs to be licensed as GPL as well by
|
||||
passing `--enable-gpl` to configure.
|
||||
|
||||
The following libraries are under LGPL version 3:
|
||||
- gmp
|
||||
- libaribb24
|
||||
- liblensfun
|
||||
|
||||
When combining them with FFmpeg, use the configure option `--enable-version3` to
|
||||
upgrade FFmpeg to the LGPL v3.
|
||||
|
||||
The VMAF, mbedTLS, RK MPI, OpenCORE and VisualOn libraries are under the Apache License
|
||||
2.0. That license is incompatible with the LGPL v2.1 and the GPL v2, but not with
|
||||
version 3 of those licenses. So to combine these libraries with FFmpeg, the
|
||||
license version needs to be upgraded by passing `--enable-version3` to configure.
|
||||
|
||||
The smbclient library is under the GPL v3, to combine it with FFmpeg,
|
||||
the options `--enable-gpl` and `--enable-version3` have to be passed to
|
||||
configure to upgrade FFmpeg to the GPL v3.
|
||||
|
||||
### Incompatible libraries
|
||||
|
||||
There are certain libraries you can combine with FFmpeg whose licenses are not
|
||||
compatible with the GPL and/or the LGPL. If you wish to enable these
|
||||
libraries, even in circumstances that their license may be incompatible, pass
|
||||
`--enable-nonfree` to configure. This will cause the resulting binary to be
|
||||
unredistributable.
|
||||
|
||||
The Fraunhofer FDK AAC and OpenSSL libraries are under licenses which are
|
||||
incompatible with the GPLv2 and v3. To the best of our knowledge, they are
|
||||
compatible with the LGPL.
|
||||
537
MAINTAINERS
537
MAINTAINERS
@@ -4,40 +4,25 @@ FFmpeg maintainers
|
||||
Below is a list of the people maintaining different parts of the
|
||||
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.
|
||||
Project Leader
|
||||
==============
|
||||
|
||||
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
|
||||
Michael Niedermayer
|
||||
final design decisions
|
||||
|
||||
|
||||
Applications
|
||||
============
|
||||
|
||||
ffmpeg:
|
||||
ffmpeg.c Michael Niedermayer, Anton Khirnov
|
||||
ffmpeg.c Michael Niedermayer
|
||||
|
||||
ffplay:
|
||||
ffplay.c [2] Marton Balint
|
||||
ffplay.c Michael Niedermayer
|
||||
|
||||
ffprobe:
|
||||
ffprobe.c [2] Stefano Sabatini
|
||||
ffserver:
|
||||
ffserver.c, ffserver.h Baptiste Coudurier
|
||||
|
||||
Commandline utility code:
|
||||
cmdutils.c, cmdutils.h Michael Niedermayer
|
||||
@@ -45,32 +30,18 @@ Commandline utility code:
|
||||
QuickTime faststart:
|
||||
tools/qt-faststart.c Baptiste Coudurier
|
||||
|
||||
Execution Graph Printing
|
||||
fftools/graph, fftools/resources [2] softworkz
|
||||
|
||||
Miscellaneous Areas
|
||||
===================
|
||||
|
||||
documentation Stefano Sabatini, Mike Melanson, Timothy Gu, Gyan Doshi
|
||||
project server day to day operations (L: root@ffmpeg.org) Michael Niedermayer, Reimar Doeffinger, Alexander Strasser, Nikolay Aleksandrov, Timo Rothenpieler
|
||||
project server emergencies (L: root@ffmpeg.org) Reimar Doeffinger, Alexander Strasser, Nikolay Aleksandrov, Timo Rothenpieler
|
||||
presets [0]
|
||||
documentation Mike Melanson, Diego Biurrun
|
||||
website Robert Swain
|
||||
build system (configure,Makefiles) Diego Biurrun, Mans Rullgard
|
||||
project server Diego Biurrun, Mans Rullgard
|
||||
mailinglists Michael Niedermayer, Baptiste Coudurier
|
||||
presets Robert Swain
|
||||
metadata subsystem Aurelien Jacobs
|
||||
release management Michael Niedermayer
|
||||
API tests [0]
|
||||
samples-request [2] Thilo Borgmann, James Almer, Ben Littler
|
||||
|
||||
|
||||
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
|
||||
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
|
||||
release management Diego Biurrun, Reinhard Tartler
|
||||
|
||||
|
||||
libavutil
|
||||
@@ -82,29 +53,11 @@ Internal Interfaces:
|
||||
libavutil/common.h Michael Niedermayer
|
||||
|
||||
Other:
|
||||
aes_ctr.c, aes_ctr.h Eran Kornblau
|
||||
bprint Nicolas George
|
||||
bswap.h
|
||||
csp.c, csp.h Leo Izen, Ronald S. Bultje
|
||||
des Reimar Doeffinger
|
||||
dynarray.h Nicolas George
|
||||
eval.c, eval.h [2] Michael Niedermayer
|
||||
float_dsp Loren Merritt
|
||||
hash Reimar Doeffinger
|
||||
hwcontext_cuda* Timo Rothenpieler
|
||||
hwcontext_d3d12va* Wu Jianhua
|
||||
hwcontext_vulkan* [2] Lynne
|
||||
intfloat* Michael Niedermayer
|
||||
rational.c, rational.h Michael Niedermayer
|
||||
mathematics.c, mathematics.h 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
|
||||
opencl.c, opencl.h Wei Gao
|
||||
opt.c, opt.h Michael Niedermayer
|
||||
rational.c, rational.h [2] Michael Niedermayer
|
||||
rc4 Reimar Doeffinger
|
||||
ripemd.c, ripemd.h James Almer
|
||||
tx* [2] Lynne
|
||||
bswap.h
|
||||
|
||||
|
||||
libavcodec
|
||||
@@ -115,131 +68,112 @@ Generic Parts:
|
||||
avcodec.h Michael Niedermayer
|
||||
utility code:
|
||||
utils.c Michael Niedermayer
|
||||
mem.c Michael Niedermayer
|
||||
opt.c, opt.h Michael Niedermayer
|
||||
arithmetic expression evaluator:
|
||||
eval.c Michael Niedermayer
|
||||
audio and video frame extraction:
|
||||
parser.c Michael Niedermayer
|
||||
bitstream reading:
|
||||
bitstream.c, bitstream.h Michael Niedermayer
|
||||
CABAC:
|
||||
cabac.h, cabac.c Michael Niedermayer
|
||||
codec names:
|
||||
codec_names.sh Nicolas George
|
||||
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
|
||||
LPC:
|
||||
lpc.c, lpc.h Justin Ruggles
|
||||
motion estimation:
|
||||
motion* Michael Niedermayer
|
||||
rate control:
|
||||
ratecontrol.c [2] Michael Niedermayer
|
||||
ratecontrol.c Michael Niedermayer
|
||||
libxvid_rc.c Michael Niedermayer
|
||||
simple IDCT:
|
||||
simple_idct.c, simple_idct.h [2] Michael Niedermayer
|
||||
table generation:
|
||||
tableprint.c, tableprint.h Reimar Doeffinger
|
||||
fixed point FFT:
|
||||
fft* Zeljko Lukac
|
||||
Text Subtitles Clément Bœsch
|
||||
simple_idct.c, simple_idct.h Michael Niedermayer
|
||||
postprocessing:
|
||||
libpostproc/* Michael Niedermayer
|
||||
|
||||
Codecs:
|
||||
4xm.c [2] Michael Niedermayer
|
||||
4xm.c Michael Niedermayer
|
||||
8bps.c Roberto Togni
|
||||
8svx.c Jaikrishnan Menon
|
||||
aacenc*, aaccoder.c Rostislav Pehlivanov
|
||||
adpcm.c Zane van Iperen
|
||||
aasc.c Kostya Shishkov
|
||||
aac*, sbr.h Alex Converse
|
||||
ac3* Justin Ruggles
|
||||
alacenc.c Jaikrishnan Menon
|
||||
alsdec.c Thilo Borgmann, Umair Khan
|
||||
amfenc* Dmitrii Ovchinnikov
|
||||
aptx.c Aurelien Jacobs
|
||||
ass* Aurelien Jacobs
|
||||
alsdec.c Thilo Borgmann
|
||||
apedec.c Kostya Shishkov
|
||||
asv* Michael Niedermayer
|
||||
atrac3plus* Maxim Poliakovski
|
||||
audiotoolbox* rcombs
|
||||
avs2* Huiwen Ren
|
||||
atrac3* Benjamin Larsson
|
||||
bgmc.c, bgmc.h Thilo Borgmann
|
||||
bink.c Kostya Shishkov
|
||||
binkaudio.c Peter Ross
|
||||
bmp.c Mans Rullgard, Kostya Shishkov
|
||||
cavs* Stefan Gehrer
|
||||
celp_filters.* Vitor Sessak
|
||||
cinepak.c Roberto Togni
|
||||
cinepakenc.c Rl / Aetey G.T. AB
|
||||
ccaption_dec.c Anshul Maheshwari, Aman Gupta
|
||||
cljr Alex Beregszaszi
|
||||
cpia.c Stephan Hilb
|
||||
cook.c, cookdata.h Benjamin Larsson
|
||||
cscd.c Reimar Doeffinger
|
||||
cuviddec.c Timo Rothenpieler
|
||||
dca* foo86
|
||||
dfpwm* Jack Bruienne
|
||||
dirac* Rostislav Pehlivanov
|
||||
dca.c Kostya Shishkov, Benjamin Larsson
|
||||
dnxhd* Baptiste Coudurier
|
||||
dolby_e* foo86
|
||||
dpcm.c Mike Melanson
|
||||
dss_sp.c Oleksij Rempel
|
||||
dxa.c Kostya Shishkov
|
||||
dv.c Roman Shaposhnik
|
||||
dvbsubdec.c Anshul Maheshwari
|
||||
dxv.*, dxvenc.* Emma Worley
|
||||
eacmv*, eaidct*, eat* Peter Ross
|
||||
exif.c, exif.h Thilo Borgmann
|
||||
ffv1* [2] Michael Niedermayer
|
||||
ffwavesynth.c Nicolas George
|
||||
fifo.c Jan Sebechlebsky
|
||||
ffv1.c Michael Niedermayer
|
||||
flac* Justin Ruggles
|
||||
flashsv* Benjamin Larsson
|
||||
flicvideo.c Mike Melanson
|
||||
g722.c Martin Storsjo
|
||||
g726.c Roman Shaposhnik
|
||||
gifdec.c Baptiste Coudurier
|
||||
h264* Loren Merritt, Michael Niedermayer
|
||||
h261* Michael Niedermayer
|
||||
h263* Michael Niedermayer
|
||||
h264* Loren Merritt, Michael Niedermayer
|
||||
hap* Tom Butterworth
|
||||
hevc/* Anton Khirnov
|
||||
huffyuv* Michael Niedermayer
|
||||
huffyuv.c Michael Niedermayer
|
||||
idcinvideo.c Mike Melanson
|
||||
imc* Benjamin Larsson
|
||||
indeo2* Kostya Shishkov
|
||||
indeo5* Kostya Shishkov
|
||||
interplayvideo.c Mike Melanson
|
||||
jni*, ffjni* Matthieu Bouron
|
||||
jpeg2000* Nicolas Bertrand
|
||||
jpegxl* Leo Izen
|
||||
jvdec.c Peter Ross
|
||||
ivi* Kostya Shishkov
|
||||
jpeg_ls.c Kostya Shishkov
|
||||
kmvc.c Kostya Shishkov
|
||||
lcl*.c Roberto Togni, Reimar Doeffinger
|
||||
libcelt_dec.c Nicolas George
|
||||
libcodec2.c Tomas Härdin
|
||||
libdirac* David Conrad
|
||||
libdavs2.c Huiwen Ren
|
||||
libjxl*.c, libjxl.h Leo Izen
|
||||
libgsm.c Michel Bardiaux
|
||||
libkvazaar.c Arttu Ylä-Outinen
|
||||
libopenh264enc.c Martin Storsjo, Linjie Fu
|
||||
libopenjpegenc.c Michael Bradshaw
|
||||
libdirac* David Conrad
|
||||
libopenjpeg.c Jaikrishnan Menon
|
||||
libschroedinger* David Conrad
|
||||
libspeexdec.c Justin Ruggles
|
||||
libtheoraenc.c David Conrad
|
||||
libvorbis.c David Conrad
|
||||
libvpx* James Zern
|
||||
libxavs.c Stefan Gehrer
|
||||
libxavs2.c Huiwen Ren
|
||||
libzvbi-teletextdec.c Marton Balint
|
||||
libx264.c Mans Rullgard, Jason Garrett-Glaser
|
||||
loco.c Kostya Shishkov
|
||||
lzo.h, lzo.c Reimar Doeffinger
|
||||
mdec.c Michael Niedermayer
|
||||
mimic.c Ramiro Polla
|
||||
mjpeg*.c Michael Niedermayer
|
||||
mlp* Ramiro Polla, Jai Luthra
|
||||
mjpeg.c Michael Niedermayer
|
||||
mlp* Ramiro Polla
|
||||
mmvideo.c Peter Ross
|
||||
mpc* Kostya Shishkov
|
||||
mpeg12.c, mpeg12data.h Michael Niedermayer
|
||||
mpegvideo.c, mpegvideo.h Michael Niedermayer
|
||||
mqc* Nicolas Bertrand
|
||||
msmpeg4.c, msmpeg4data.h Michael Niedermayer
|
||||
msrle.c Mike Melanson
|
||||
msrleenc.c Tomas Härdin
|
||||
msvideo1.c Mike Melanson
|
||||
nellymoserdec.c Benjamin Larsson
|
||||
nuv.c Reimar Doeffinger
|
||||
nvdec*, nvenc* Timo Rothenpieler
|
||||
omx.c Martin Storsjo, Aman Gupta
|
||||
opus* Rostislav Pehlivanov
|
||||
pcx.c Ivo van Poorten
|
||||
pgssubdec.c Reimar Doeffinger
|
||||
ptx.c Ivo van Poorten
|
||||
qcelp* Reynaldo H. Verdejo Pinochet
|
||||
qdm2.c, qdm2data.h Roberto Togni
|
||||
qsv* Mark Thompson, Zhong Li, Haihao Xiang
|
||||
qdm2.c, qdm2data.h Roberto Togni, Benjamin Larsson
|
||||
qdrw.c Kostya Shishkov
|
||||
qpeg.c Kostya Shishkov
|
||||
qtrle.c Mike Melanson
|
||||
ra144.c, ra144.h, ra288.c, ra288.h Roberto Togni
|
||||
resample2.c Michael Niedermayer
|
||||
@@ -247,46 +181,48 @@ Codecs:
|
||||
rpza.c Roberto Togni
|
||||
rtjpeg.c, rtjpeg.h Reimar Doeffinger
|
||||
rv10.c Michael Niedermayer
|
||||
sanm.c Manuel Lauss
|
||||
rv3* Kostya Shishkov
|
||||
rv4* Kostya Shishkov
|
||||
s3tc* Ivo van Poorten
|
||||
smacker.c Kostya Shishkov
|
||||
smc.c Mike Melanson
|
||||
snow* Michael Niedermayer, Loren Merritt
|
||||
snow.c Michael Niedermayer, Loren Merritt
|
||||
sonic.c Alex Beregszaszi
|
||||
speedhq.c Steinar H. Gunderson
|
||||
srt* Aurelien Jacobs
|
||||
sunrast.c Ivo van Poorten
|
||||
svq3.c Michael Niedermayer
|
||||
targa.c Kostya Shishkov
|
||||
tiff.c Kostya Shishkov
|
||||
truemotion1* Mike Melanson
|
||||
truemotion2* Kostya Shishkov
|
||||
truespeech.c Kostya Shishkov
|
||||
tscc.c Kostya Shishkov
|
||||
tta.c Alex Beregszaszi, Jaikrishnan Menon
|
||||
txd.c Ivo van Poorten
|
||||
v4l2_* Jorge Ramirez-Ortiz
|
||||
vc2* Rostislav Pehlivanov
|
||||
ulti* Kostya Shishkov
|
||||
vb.c Kostya Shishkov
|
||||
vc1* Kostya Shishkov
|
||||
vcr1.c Michael Niedermayer
|
||||
videotoolboxenc.c Rick Kern, Aman Gupta
|
||||
vorbisdec.c Denes Balatoni, David Conrad
|
||||
vorbisenc.c Oded Shimon
|
||||
vmnc.c Kostya Shishkov
|
||||
vorbis_enc.c Oded Shimon
|
||||
vorbis_dec.c Denes Balatoni
|
||||
vp3* Mike Melanson
|
||||
vp5 Aurelien Jacobs
|
||||
vp6 Aurelien Jacobs
|
||||
vp8 David Conrad, Ronald Bultje
|
||||
vp9 Ronald Bultje
|
||||
vqavideo.c Mike Melanson
|
||||
vvc [2] Nuo Mi, Wu Jianhua, Frank Plowman
|
||||
wavpack.c Kostya Shishkov
|
||||
wmaprodec.c Sascha Sommer
|
||||
wmavoice.c Ronald S. Bultje
|
||||
wmv2.c Michael Niedermayer
|
||||
wnv1.c Kostya Shishkov
|
||||
xan.c Mike Melanson
|
||||
xface Stefano Sabatini
|
||||
xl.c Kostya Shishkov
|
||||
xvmc.c Ivan Kalvachev
|
||||
zmbv* Kostya Shishkov
|
||||
|
||||
Hardware acceleration:
|
||||
dxva2* Hendrik Leppkes, Laurent Aimar, Steve Lhomme
|
||||
d3d11va* Steve Lhomme
|
||||
d3d12va* Wu Jianhua
|
||||
d3d12va_encode* Tong Wu
|
||||
mediacodec* Matthieu Bouron, Aman Gupta, Zhao Zhili
|
||||
vaapi* Haihao Xiang
|
||||
vaapi_encode* Mark Thompson, Haihao Xiang
|
||||
vdpau* Philip Langdale, Carl Eugen Hoyos
|
||||
videotoolbox* Rick Kern, Aman Gupta, Zhao Zhili
|
||||
dxva2* Laurent Aimar
|
||||
vaapi* Gwenole Beauchesne
|
||||
vdpau* Carl Eugen Hoyos
|
||||
|
||||
|
||||
libavdevice
|
||||
@@ -295,66 +231,10 @@ libavdevice
|
||||
libavdevice/avdevice.h
|
||||
|
||||
|
||||
avfoundation.m Thilo Borgmann
|
||||
android_camera.c Felix Matouschek
|
||||
decklink* Marton Balint
|
||||
dshow.c Roger Pack (CC rogerdpack@gmail.com)
|
||||
fbdev_enc.c Lukasz Marek
|
||||
gdigrab.c Roger Pack (CC rogerdpack@gmail.com)
|
||||
iec61883.c Georg Lippitsch
|
||||
lavfi Stefano Sabatini
|
||||
libdc1394.c Roman Shaposhnik
|
||||
opengl_enc.c Lukasz Marek
|
||||
pulse_audio_enc.c Lukasz Marek
|
||||
sdl Stefano Sabatini
|
||||
sdl2.c Josh de Kock
|
||||
v4l2.c Giorgio Vazzana
|
||||
v4l2.c Luca Abeni
|
||||
vfwcap.c Ramiro Polla
|
||||
xv.c Lukasz Marek
|
||||
|
||||
libavfilter
|
||||
===========
|
||||
|
||||
Generic parts:
|
||||
graphdump.c Nicolas George
|
||||
|
||||
motion_estimation.c Davinder Singh
|
||||
|
||||
Filters:
|
||||
af_amerge.c Nicolas George
|
||||
af_aresample.c Michael Niedermayer
|
||||
af_atempo.c Pavel Koshevoy
|
||||
af_firequalizer.c Muhammad Faiz
|
||||
af_hdcd.c Burt P.
|
||||
af_loudnorm.c Kyle Swanson
|
||||
af_pan.c Nicolas George
|
||||
avf_showcqt.c Muhammad Faiz
|
||||
vf_bwdif Thomas Mundt (CC <thomas.mundt@hr.de>)
|
||||
vf_chromakey.c Timo Rothenpieler
|
||||
vf_colorconstancy.c Mina Sami (CC <minas.gorgy@gmail.com>)
|
||||
vf_colorkey.c Timo Rothenpieler
|
||||
vf_coreimage.m Thilo Borgmann
|
||||
vf_dejudder.c Nicholas Robbins
|
||||
vf_delogo.c Jean Delvare (CC <jdelvare@suse.com>)
|
||||
vf_drawbox.c/drawgrid Andrey Utkin
|
||||
vf_fsync.c Thilo Borgmann
|
||||
vf_hqx.c Clément Bœsch
|
||||
vf_idet.c Pascal Massimino
|
||||
vf_(t)interlace Thomas Mundt (CC <thomas.mundt@hr.de>)
|
||||
vf_lenscorrection.c Daniel Oberhoff
|
||||
vf_libplacebo.c Niklas Haas
|
||||
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_tonemap_opencl.c Ruiling Song
|
||||
vf_yadif.c [2] Michael Niedermayer
|
||||
vf_xfade_vulkan.c [2] Marvin Scholz (CC <epirat07@gmail.com>)
|
||||
|
||||
Sources:
|
||||
vsrc_mandelbrot.c [2] Michael Niedermayer
|
||||
|
||||
dnn Yejun Guo
|
||||
|
||||
libavformat
|
||||
===========
|
||||
@@ -364,265 +244,116 @@ Generic parts:
|
||||
libavformat/avformat.h Michael Niedermayer
|
||||
Utility Code:
|
||||
libavformat/utils.c Michael Niedermayer
|
||||
Text Subtitles Clément Bœsch
|
||||
|
||||
|
||||
Muxers/Demuxers:
|
||||
4xm.c Mike Melanson
|
||||
aadec.c Vesselin Bontchev (vesselin.bontchev at yandex dot com)
|
||||
adtsenc.c [0]
|
||||
aiffdec.c Baptiste Coudurier, Matthieu Bouron
|
||||
aiffenc.c Baptiste Coudurier, Matthieu Bouron
|
||||
alp.c Zane van Iperen
|
||||
amvenc.c Zane van Iperen
|
||||
apm.c Zane van Iperen
|
||||
apngdec.c Benoit Fouet
|
||||
argo_asf.c Zane van Iperen
|
||||
argo_brp.c Zane van Iperen
|
||||
argo_cvg.c Zane van Iperen
|
||||
ass* Aurelien Jacobs
|
||||
astenc.c James Almer
|
||||
adtsenc.c Robert Swain
|
||||
aiff.c Baptiste Coudurier
|
||||
ape.c Kostya Shishkov
|
||||
avi* Michael Niedermayer
|
||||
avisynth.c Stephen Hutchinson
|
||||
bink.c Peter Ross
|
||||
boadec.c Michael Niedermayer
|
||||
caf* Peter Ross
|
||||
codec2.c Tomas Härdin
|
||||
crc.c Michael Niedermayer
|
||||
dashdec.c Steven Liu
|
||||
dashenc.c Karthick Jeyapal
|
||||
daud.c Reimar Doeffinger
|
||||
dfpwmdec.c Jack Bruienne
|
||||
dss.c Oleksij Rempel
|
||||
dtsdec.c foo86
|
||||
dv.c Roman Shaposhnik
|
||||
dvdvideodec.c [2] Marth64
|
||||
dxa.c Kostya Shishkov
|
||||
electronicarts.c Peter Ross
|
||||
evc* Samsung (Dawid Kozinski)
|
||||
ffm* Baptiste Coudurier
|
||||
flac* Justin Ruggles
|
||||
flic.c Mike Melanson
|
||||
flvdec.c Michael Niedermayer
|
||||
flvenc.c Michael Niedermayer, Steven Liu
|
||||
flvdec.c, flvenc.c Michael Niedermayer
|
||||
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
|
||||
idroq.c Mike Melanson
|
||||
iff.c Jaikrishnan Menon
|
||||
imf* Pierre-Anthony Lemieux
|
||||
img2*.c Michael Niedermayer
|
||||
ipmovie.c Mike Melanson
|
||||
img2.c Michael Niedermayer
|
||||
iss.c Stefan Gehrer
|
||||
jpegxl* Leo Izen
|
||||
jvdec.c Peter Ross
|
||||
kvag.c Zane van Iperen
|
||||
libmodplug.c Clément Bœsch
|
||||
libopenmpt.c Josh de Kock
|
||||
libnut.c Oded Shimon
|
||||
lmlm4.c Ivo van Poorten
|
||||
lxfdec.c Tomas Härdin
|
||||
matroska.c Andreas Rheinhardt
|
||||
matroskadec.c Andreas Rheinhardt
|
||||
matroskaenc.c Andreas Rheinhardt
|
||||
matroska subtitles (matroskaenc.c) John Peebles
|
||||
matroska.c Aurelien Jacobs
|
||||
matroskadec.c Aurelien Jacobs
|
||||
matroskaenc.c David Conrad
|
||||
metadata* Aurelien Jacobs
|
||||
microdvd* Aurelien Jacobs
|
||||
mm.c Peter Ross
|
||||
mov.c Baptiste Coudurier
|
||||
movenc.c Baptiste Coudurier, Matthieu Bouron
|
||||
movenccenc.c Eran Kornblau
|
||||
mov.c Michael Niedermayer, Baptiste Coudurier
|
||||
movenc.c Michael Niedermayer, Baptiste Coudurier
|
||||
mpc.c Kostya Shishkov
|
||||
mpeg.c Michael Niedermayer
|
||||
mpegenc.c Michael Niedermayer
|
||||
mpegts.c Marton Balint
|
||||
mpegtsenc.c Baptiste Coudurier
|
||||
mpegts* Baptiste Coudurier
|
||||
msnwc_tcp.c Ramiro Polla
|
||||
mtv.c Reynaldo H. Verdejo Pinochet
|
||||
mxf* Baptiste Coudurier, Tomas Härdin
|
||||
mxf* Baptiste Coudurier
|
||||
nsvdec.c Francois Revol
|
||||
nut* Michael Niedermayer
|
||||
nut.c Michael Niedermayer
|
||||
nuv.c Reimar Doeffinger
|
||||
oggdec.c, oggdec.h David Conrad
|
||||
oggenc.c Baptiste Coudurier
|
||||
oggparse*.c David Conrad
|
||||
oma.c Maxim Poliakovski
|
||||
pp_bnk.c Zane van Iperen
|
||||
psxstr.c Mike Melanson
|
||||
pva.c Ivo van Poorten
|
||||
r3d.c Baptiste Coudurier
|
||||
raw.c Michael Niedermayer
|
||||
rcwtdec.c [2] Marth64
|
||||
rcwtenc.c [2] Marth64
|
||||
rdt.c Ronald S. Bultje
|
||||
rl2.c Sascha Sommer
|
||||
rmdec.c, rmenc.c Ronald S. Bultje
|
||||
rtp.c, rtpenc.c Martin Storsjo
|
||||
rtpdec_ac3.* Gilles Chanteperdrix
|
||||
rtpdec_dv.* Thomas Volkert
|
||||
rtpdec_h261.*, rtpenc_h261.* Thomas Volkert
|
||||
rtpdec_hevc.*, rtpenc_hevc.* Thomas Volkert
|
||||
rtpdec_mpa_robust.* Gilles Chanteperdrix
|
||||
rtpdec_asf.* Ronald S. Bultje
|
||||
rtpdec_vc2hq.*, rtpenc_vc2hq.* Thomas Volkert
|
||||
rtpdec_vp9.c Thomas Volkert
|
||||
rtpenc_mpv.*, rtpenc_aac.* Martin Storsjo
|
||||
s337m.c foo86
|
||||
sbgdec.c Nicolas George
|
||||
sdp.c Martin Storsjo
|
||||
rmdec.c, rmenc.c Ronald S. Bultje, Kostya Shishkov
|
||||
rtmp* Kostya Shishkov
|
||||
rtp.c, rtpenc.c Luca Abeni
|
||||
rtp_asf.* Ronald S. Bultje
|
||||
rtp_mpv.*, rtp_aac.* Luca Abeni
|
||||
rtsp.c Luca Barbato
|
||||
sdp.c Luca Abeni
|
||||
segafilm.c Mike Melanson
|
||||
segment.c Stefano Sabatini
|
||||
smush.c Manuel Lauss
|
||||
spdif* Anssi Hannula
|
||||
srtdec.c Aurelien Jacobs
|
||||
siff.c Kostya Shishkov
|
||||
smacker.c Kostya Shishkov
|
||||
swf.c Baptiste Coudurier
|
||||
tta.c Alex Beregszaszi
|
||||
txd.c Ivo van Poorten
|
||||
voc.c Aurelien Jacobs
|
||||
wav.c Michael Niedermayer
|
||||
wc3movie.c Mike Melanson
|
||||
webm dash (matroskaenc.c) Vignesh Venkatasubramanian
|
||||
webvtt* Matthew J Heaney
|
||||
westwood.c Mike Melanson
|
||||
wtv.c Peter Ross
|
||||
wv.c Kostya Shishkov
|
||||
|
||||
Protocols:
|
||||
async.c Zhang Rui
|
||||
bluray.c Petri Hintukainen
|
||||
ftp.c Lukasz Marek
|
||||
http.c Ronald S. Bultje
|
||||
libsrt.c Zhao Zhili
|
||||
libssh.c Lukasz Marek
|
||||
libzmq.c Andriy Gelman
|
||||
mms*.c Ronald S. Bultje
|
||||
udp.c Luca Abeni
|
||||
icecast.c [2] Marvin Scholz (CC <epirat07@gmail.com>)
|
||||
|
||||
|
||||
libswresample
|
||||
=============
|
||||
|
||||
Generic parts:
|
||||
audioconvert.c [2] Michael Niedermayer
|
||||
dither.c [2] Michael Niedermayer
|
||||
rematrix*.c [2] Michael Niedermayer
|
||||
swresample*.c [2] Michael Niedermayer
|
||||
|
||||
Resamplers:
|
||||
resample*.c [2] Michael Niedermayer
|
||||
soxr_resample.c Rob Sykes
|
||||
|
||||
|
||||
Operating systems / CPU architectures
|
||||
=====================================
|
||||
|
||||
*BSD [2] Brad Smith
|
||||
Alpha [0]
|
||||
MIPS Manojkumar Bhosale, Shiyou Yin
|
||||
LoongArch [2] Shiyou Yin
|
||||
Darwin (macOS, iOS) [2] Marvin Scholz
|
||||
Mac OS X / PowerPC [0]
|
||||
Alpha Mans Rullgard, Falk Hueffner
|
||||
ARM Mans Rullgard
|
||||
AVR32 Mans Rullgard
|
||||
MIPS Mans Rullgard
|
||||
BeOS Francois Revol
|
||||
Mac OS X / PowerPC Romain Dolbeau, Guillaume Poirier
|
||||
Amiga / PowerPC Colin Ward
|
||||
Linux / PowerPC [1] Lauri Kasanen
|
||||
RISC-V [2] Rémi Denis-Courmont
|
||||
Linux / PowerPC Luca Barbato
|
||||
Windows MinGW Alex Beregszaszi, Ramiro Polla
|
||||
Windows Cygwin Victor Paesa
|
||||
Windows MSVC Hendrik Leppkes
|
||||
ADI/Blackfin DSP Marc Hoffman
|
||||
Sparc Roman Shaposhnik
|
||||
OS/2 KO Myung-Hun
|
||||
x86 Michael Niedermayer
|
||||
|
||||
|
||||
Developers with git write access who are currently not maintaining any specific part
|
||||
====================================================================================
|
||||
Alex Converse
|
||||
Andreas Cadhalpun
|
||||
Anuradha Suraparaju
|
||||
Ben Littler
|
||||
Benjamin Larsson
|
||||
Bobby Bingham
|
||||
Daniel Verkamp
|
||||
Derek Buitenhuis
|
||||
Fei Wang
|
||||
Ganesh Ajjanagadde
|
||||
Henrik Gramner
|
||||
Ivan Uskov
|
||||
James Darnley
|
||||
Jan Ekström
|
||||
Joakim Plate
|
||||
Jun Zhao
|
||||
Kacper Michajłow
|
||||
Kieran Kunhya
|
||||
Kirill Gavrilov
|
||||
Limin Wang
|
||||
Martin Storsjö
|
||||
Panagiotis Issaris
|
||||
Pedro Arthur
|
||||
Sebastien Zwickert
|
||||
Vittorio Giovara
|
||||
wm4
|
||||
(this list is incomplete)
|
||||
GnuPG Fingerprints of maintainers and others who have svn write access
|
||||
======================================================================
|
||||
|
||||
|
||||
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
|
||||
|
||||
If you want to maintain an older release, please contact us
|
||||
|
||||
|
||||
GnuPG Fingerprints and IRC nicknames of maintainers and contributors
|
||||
====================================================================
|
||||
|
||||
IRC nicknames are in parentheses. These apply
|
||||
to the IRC channels listed on the website.
|
||||
|
||||
Alexander Strasser 1C96 78B7 83CB 8AA7 9AF5 D1EB A7D8 A57B A876 E58F
|
||||
Anssi Hannula 1A92 FF42 2DD9 8D2E 8AF7 65A9 4278 C520 513D F3CB
|
||||
Ash Hughes 694D 43D2 D180 C7C7 6421 ABD3 A641 D0B7 623D 6029
|
||||
Attila Kinali 11F0 F9A6 A1D2 11F6 C745 D10C 6520 BCDD F2DF E765
|
||||
Baptiste Coudurier 8D77 134D 20CC 9220 201F C5DB 0AC9 325C 5C1A BAAA
|
||||
Ben Littler 3EE3 3723 E560 3214 A8CD 4DEB 2CDB FCE7 768C 8D2C
|
||||
Benoit Fouet B22A 4F4F 43EF 636B BB66 FCDC 0023 AE1E 2985 49C8
|
||||
Clément Bœsch 52D0 3A82 D445 F194 DB8B 2B16 87EE 2CB8 F4B8 FCF9
|
||||
Daniel Verkamp 78A6 07ED 782C 653E C628 B8B9 F0EB 8DD8 2F0E 21C7
|
||||
FFmpeg release signing key FCF9 86EA 15E6 E293 A564 4F10 B432 2F04 D676 58D8
|
||||
Frank Plowman 34E2 48D6 B7DF 4769 70C7 3304 03A8 4C6A 098F 2C6B
|
||||
Ganesh Ajjanagadde C96A 848E 97C3 CEA2 AB72 5CE4 45F9 6A2D 3C36 FB1B
|
||||
Gwenole Beauchesne 2E63 B3A6 3E44 37E2 017D 2704 53C7 6266 B153 99C4
|
||||
Haihao Xiang (haihao) 1F0C 31E8 B4FE F7A4 4DC1 DC99 E0F5 76D4 76FC 437F
|
||||
Diego Biurrun 8227 1E31 B6D9 4994 7427 E220 9CAE D6CC 4757 FCC5
|
||||
Jaikrishnan Menon 61A1 F09F 01C9 2D45 78E1 C862 25DC 8831 AF70 D368
|
||||
James Almer 7751 2E8C FD94 A169 57E6 9A7A 1463 01AD 7376 59E0
|
||||
Jean Delvare 7CA6 9F44 60F1 BDC4 1FD2 C858 A552 6B9B B3CD 4E6A
|
||||
Leo Izen (Traneptora) B6FD 3CFC 7ACF 83FC 9137 6945 5A71 C331 FD2F A19A
|
||||
Leo Izen (Traneptora) 1D83 0A0B CE46 709E 203B 26FC 764E 48EA 4822 1833
|
||||
Loren Merritt ABD9 08F4 C920 3F65 D8BE 35D7 1540 DAA7 060F 56DE
|
||||
Lynne FE50 139C 6805 72CA FD52 1F8D A2FE A5F0 3F03 4464
|
||||
Michael Niedermayer 9FF2 128B 147E F673 0BAD F133 611E C787 040B 0FAB
|
||||
DD1E C9E8 DE08 5C62 9B3E 1846 B18E 8928 B394 8D64
|
||||
Nicolas George 24CE 01CE 9ACC 5CEB 74D8 8D9D B063 D997 36E5 4C93
|
||||
Niklas Haas (haasn) 1DDB 8076 B14D 5B48 32FC 99D9 EB52 DA9C 02BA 6FB4
|
||||
Nikolay Aleksandrov 8978 1D8C FB71 588E 4B27 EAA8 C4F0 B5FC E011 13B1
|
||||
Panagiotis Issaris 6571 13A3 33D9 3726 F728 AA98 F643 B12E ECF3 E029
|
||||
Panagiotis Issaris 515C E262 10A8 FDCE 5481 7B9C 3AD7 D9A5 071D B3A9
|
||||
Peter Ross A907 E02F A6E5 0CD2 34CD 20D2 6760 79C5 AC40 DD6B
|
||||
Philip Langdale 5DC5 8D66 5FBA 3A43 18EC 045E F8D6 B194 6A75 682E
|
||||
Pierre-Anthony Lemieux (pal) F4B3 9492 E6F2 E4AF AEC8 46CB 698F A1F0 F8D4 EED4
|
||||
Ramiro Polla 7859 C65B 751B 1179 792E DAE8 8E95 8B2F 9B6C 5700
|
||||
Reimar Doeffinger C61D 16E5 9E2C D10C 8958 38A4 0899 A2B9 06D4 D9C7
|
||||
Reimar Döffinger C61D 16E5 9E2C D10C 8958 38A4 0899 A2B9 06D4 D9C7
|
||||
Reinhard Tartler 9300 5DC2 7E87 6C37 ED7B CA9A 9808 3544 9453 48A4
|
||||
Reynaldo H. Verdejo Pinochet 6E27 CD34 170C C78E 4D4F 5F40 C18E 077F 3114 452A
|
||||
Robert Swain EE7A 56EA 4A81 A7B5 2001 A521 67FA 362D A2FC 3E71
|
||||
Sascha Sommer 38A0 F88B 868E 9D3A 97D4 D6A0 E823 706F 1E07 0D3C
|
||||
Stefano Sabatini 0D0B AD6B 5330 BBAD D3D6 6A0C 719C 2839 FC43 2D5F
|
||||
Steinar H. Gunderson C2E9 004F F028 C18E 4EAD DB83 7F61 7561 7797 8F76
|
||||
Stephan Hilb 4F38 0B3A 5F39 B99B F505 E562 8D5C 5554 4E17 8863
|
||||
Thilo Borgmann (thilo) CE1D B7F4 4D20 FC3A DD9F FE5A 257C 5B8F 1D20 B92F
|
||||
Tiancheng "Timothy" Gu 9456 AFC0 814A 8139 E994 8351 7FE6 B095 B582 B0D4
|
||||
Tim Nicholson 38CF DB09 3ED0 F607 8B67 6CED 0C0B FC44 8B0B FC83
|
||||
Tomas Härdin (thardin) A79D 4E3D F38F 763F 91F5 8B33 A01E 8AE0 41BB 2551
|
||||
Wei Gao 4269 7741 857A 0E60 9EC5 08D2 4744 4EFA 62C1 87B9
|
||||
Zane van Iperen (zane) 61AE D40F 368B 6F26 9DAE 3892 6861 6B2D 8AC4 DCC5
|
||||
|
||||
448
Makefile
448
Makefile
@@ -1,116 +1,62 @@
|
||||
MAIN_MAKEFILE=1
|
||||
include ffbuild/config.mak
|
||||
include config.mak
|
||||
|
||||
vpath %.c $(SRC_PATH)
|
||||
vpath %.cpp $(SRC_PATH)
|
||||
vpath %.h $(SRC_PATH)
|
||||
vpath %.inc $(SRC_PATH)
|
||||
vpath %.m $(SRC_PATH)
|
||||
vpath %.S $(SRC_PATH)
|
||||
vpath %.asm $(SRC_PATH)
|
||||
vpath %.rc $(SRC_PATH)
|
||||
vpath %.v $(SRC_PATH)
|
||||
vpath %.texi $(SRC_PATH)
|
||||
vpath %.cu $(SRC_PATH)
|
||||
vpath %.ptx $(SRC_PATH)
|
||||
vpath %.metal $(SRC_PATH)
|
||||
vpath %/fate_config.sh.template $(SRC_PATH)
|
||||
SRC_DIR = $(SRC_PATH_BARE)
|
||||
|
||||
TESTTOOLS = audiogen videogen rotozoom tiny_psnr tiny_ssim base64 audiomatch
|
||||
HOSTPROGS := $(TESTTOOLS:%=tests/%) doc/print_options
|
||||
vpath %.texi $(SRC_PATH_BARE)
|
||||
|
||||
ALLFFLIBS = \
|
||||
avcodec \
|
||||
avdevice \
|
||||
avfilter \
|
||||
avformat \
|
||||
avutil \
|
||||
swscale \
|
||||
swresample \
|
||||
PROGS-$(CONFIG_FFMPEG) += ffmpeg
|
||||
PROGS-$(CONFIG_FFPLAY) += ffplay
|
||||
PROGS-$(CONFIG_FFPROBE) += ffprobe
|
||||
PROGS-$(CONFIG_FFSERVER) += ffserver
|
||||
|
||||
# $(FFLIBS-yes) needs to be in linking order
|
||||
FFLIBS-$(CONFIG_AVDEVICE) += avdevice
|
||||
FFLIBS-$(CONFIG_AVFILTER) += avfilter
|
||||
FFLIBS-$(CONFIG_AVFORMAT) += avformat
|
||||
FFLIBS-$(CONFIG_AVCODEC) += avcodec
|
||||
FFLIBS-$(CONFIG_SWRESAMPLE) += swresample
|
||||
FFLIBS-$(CONFIG_SWSCALE) += swscale
|
||||
PROGS := $(addsuffix $(EXESUF), $(PROGS-yes))
|
||||
PROGS_G = $(addsuffix _g$(EXESUF), $(PROGS-yes))
|
||||
OBJS = $(addsuffix .o, $(PROGS-yes)) cmdutils.o
|
||||
MANPAGES = $(addprefix doc/, $(addsuffix .1, $(PROGS-yes)))
|
||||
TOOLS = $(addprefix tools/, $(addsuffix $(EXESUF), cws2fws pktdumper probetest qt-faststart trasher))
|
||||
HOSTPROGS = $(addprefix tests/, audiogen videogen rotozoom tiny_psnr)
|
||||
|
||||
BASENAMES = ffmpeg ffplay ffprobe ffserver
|
||||
ALLPROGS = $(addsuffix $(EXESUF), $(BASENAMES))
|
||||
ALLPROGS_G = $(addsuffix _g$(EXESUF), $(BASENAMES))
|
||||
ALLMANPAGES = $(addsuffix .1, $(BASENAMES))
|
||||
|
||||
FFLIBS-$(CONFIG_AVDEVICE) += avdevice
|
||||
FFLIBS-$(CONFIG_AVFILTER) += avfilter
|
||||
FFLIBS-$(CONFIG_AVFORMAT) += avformat
|
||||
FFLIBS-$(CONFIG_AVCODEC) += avcodec
|
||||
FFLIBS-$(CONFIG_POSTPROC) += postproc
|
||||
FFLIBS-$(CONFIG_SWSCALE) += swscale
|
||||
|
||||
FFLIBS := avutil
|
||||
|
||||
DATA_FILES := $(wildcard $(SRC_PATH)/presets/*.ffpreset) $(SRC_PATH)/doc/ffprobe.xsd
|
||||
DATA_FILES := $(wildcard $(SRC_DIR)/ffpresets/*.ffpreset)
|
||||
|
||||
SKIPHEADERS = compat/w32pthreads.h
|
||||
SKIPHEADERS = cmdutils_common_opts.h
|
||||
|
||||
# first so "all" becomes default target
|
||||
all: all-yes
|
||||
|
||||
include $(SRC_PATH)/tools/Makefile
|
||||
include $(SRC_PATH)/ffbuild/common.mak
|
||||
include common.mak
|
||||
|
||||
FF_LDFLAGS := $(FFLDFLAGS)
|
||||
FF_EXTRALIBS := $(FFEXTRALIBS)
|
||||
FF_DEP_LIBS := $(DEP_LIBS)
|
||||
FF_STATIC_DEP_LIBS := $(STATIC_DEP_LIBS)
|
||||
|
||||
$(TOOLS): %$(EXESUF): %.o
|
||||
$(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $(filter-out $(FF_DEP_LIBS), $^) $(EXTRALIBS-$(*F)) $(EXTRALIBS) $(ELIBS)
|
||||
ALL_TARGETS-$(CONFIG_DOC) += documentation
|
||||
|
||||
target_dec_%_fuzzer$(EXESUF): target_dec_%_fuzzer.o $(FF_DEP_LIBS)
|
||||
$(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $^ $(ELIBS) $(FF_EXTRALIBS) $(LIBFUZZER_PATH)
|
||||
ifdef PROGS
|
||||
INSTALL_TARGETS-yes += install-progs install-data
|
||||
INSTALL_TARGETS-$(CONFIG_DOC) += install-man
|
||||
endif
|
||||
INSTALL_PROGS_TARGETS-$(CONFIG_SHARED) = install-libs
|
||||
|
||||
target_enc_%_fuzzer$(EXESUF): target_enc_%_fuzzer.o $(FF_DEP_LIBS)
|
||||
$(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $^ $(ELIBS) $(FF_EXTRALIBS) $(LIBFUZZER_PATH)
|
||||
all: $(FF_DEP_LIBS) $(PROGS) $(ALL_TARGETS-yes)
|
||||
|
||||
tools/target_bsf_%_fuzzer$(EXESUF): tools/target_bsf_%_fuzzer.o $(FF_DEP_LIBS)
|
||||
$(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $^ $(ELIBS) $(FF_EXTRALIBS) $(LIBFUZZER_PATH)
|
||||
$(PROGS): %$(EXESUF): %_g$(EXESUF)
|
||||
$(CP) $< $@
|
||||
$(STRIP) $@
|
||||
|
||||
target_dem_%_fuzzer$(EXESUF): target_dem_%_fuzzer.o $(FF_DEP_LIBS)
|
||||
$(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $^ $(ELIBS) $(FF_EXTRALIBS) $(LIBFUZZER_PATH)
|
||||
|
||||
tools/target_dem_fuzzer$(EXESUF): tools/target_dem_fuzzer.o $(FF_DEP_LIBS)
|
||||
$(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $^ $(ELIBS) $(FF_EXTRALIBS) $(LIBFUZZER_PATH)
|
||||
|
||||
tools/target_io_dem_fuzzer$(EXESUF): tools/target_io_dem_fuzzer.o $(FF_DEP_LIBS)
|
||||
$(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $^ $(ELIBS) $(FF_EXTRALIBS) $(LIBFUZZER_PATH)
|
||||
|
||||
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)
|
||||
tools/enc_recon_frame_test$(EXESUF): $(FF_DEP_LIBS)
|
||||
tools/enc_recon_frame_test$(EXESUF): ELIBS = $(FF_EXTRALIBS)
|
||||
tools/scale_slice_test$(EXESUF): $(FF_DEP_LIBS)
|
||||
tools/scale_slice_test$(EXESUF): ELIBS = $(FF_EXTRALIBS)
|
||||
tools/sofa2wavs$(EXESUF): ELIBS = $(FF_EXTRALIBS)
|
||||
tools/uncoded_frame$(EXESUF): $(FF_DEP_LIBS)
|
||||
tools/uncoded_frame$(EXESUF): ELIBS = $(FF_EXTRALIBS)
|
||||
tools/target_dec_%_fuzzer$(EXESUF): $(FF_DEP_LIBS)
|
||||
tools/target_dem_%_fuzzer$(EXESUF): $(FF_DEP_LIBS)
|
||||
|
||||
CONFIGURABLE_COMPONENTS = \
|
||||
$(wildcard $(FFLIBS:%=$(SRC_PATH)/lib%/all*.c)) \
|
||||
$(SRC_PATH)/libavcodec/bitstream_filters.c \
|
||||
$(SRC_PATH)/libavcodec/hwaccels.h \
|
||||
$(SRC_PATH)/libavcodec/parsers.c \
|
||||
$(SRC_PATH)/libavformat/protocols.c \
|
||||
|
||||
config_components.h: ffbuild/.config
|
||||
ffbuild/.config: $(CONFIGURABLE_COMPONENTS)
|
||||
@-tput bold 2>/dev/null
|
||||
@-printf '\nWARNING: $(?) newer than config_components.h, rerun configure\n\n'
|
||||
@-tput sgr0 2>/dev/null
|
||||
|
||||
SUBDIR_VARS := CLEANFILES FFLIBS HOSTPROGS TESTPROGS TOOLS \
|
||||
HEADERS ARCH_HEADERS BUILT_HEADERS SKIPHEADERS \
|
||||
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 \
|
||||
OBJS SHLIBOBJS STLIBOBJS HOSTOBJS TESTOBJS SIMD128-OBJS
|
||||
SUBDIR_VARS := OBJS FFLIBS CLEANFILES DIRS TESTPROGS EXAMPLES SKIPHEADERS \
|
||||
ALTIVEC-OBJS MMX-OBJS NEON-OBJS X86-OBJS YASM-OBJS-FFT YASM-OBJS \
|
||||
HOSTPROGS BUILT_HEADERS TESTOBJS ARCH_HEADERS
|
||||
|
||||
define RESET
|
||||
$(1) :=
|
||||
@@ -120,100 +66,288 @@ endef
|
||||
define DOSUBDIR
|
||||
$(foreach V,$(SUBDIR_VARS),$(eval $(call RESET,$(V))))
|
||||
SUBDIR := $(1)/
|
||||
include $(SRC_PATH)/$(1)/Makefile
|
||||
-include $(SRC_PATH)/$(1)/$(ARCH)/Makefile
|
||||
-include $(SRC_PATH)/$(1)/$(INTRINSICS)/Makefile
|
||||
include $(SRC_PATH)/ffbuild/library.mak
|
||||
include $(1)/Makefile
|
||||
endef
|
||||
|
||||
$(foreach D,$(FFLIBS),$(eval $(call DOSUBDIR,lib$(D))))
|
||||
|
||||
include $(SRC_PATH)/fftools/Makefile
|
||||
include $(SRC_PATH)/doc/Makefile
|
||||
include $(SRC_PATH)/doc/examples/Makefile
|
||||
ffplay_g$(EXESUF): FF_EXTRALIBS += $(SDL_LIBS)
|
||||
ffserver_g$(EXESUF): FF_LDFLAGS += $(FFSERVERLDFLAGS)
|
||||
|
||||
$(ALLFFLIBS:%=lib%/version.o): libavutil/ffversion.h
|
||||
%_g$(EXESUF): %.o cmdutils.o $(FF_DEP_LIBS)
|
||||
$(LD) $(FF_LDFLAGS) -o $@ $< cmdutils.o $(FF_EXTRALIBS)
|
||||
|
||||
$(PROGS): %$(PROGSSUF)$(EXESUF): %$(PROGSSUF)_g$(EXESUF)
|
||||
ifeq ($(STRIPTYPE),direct)
|
||||
$(STRIP) -o $@ $<
|
||||
else
|
||||
$(RM) $@
|
||||
$(CP) $< $@
|
||||
$(STRIP) $@
|
||||
endif
|
||||
tools/%$(EXESUF): tools/%.o
|
||||
$(LD) $(FF_LDFLAGS) -o $@ $< $(FF_EXTRALIBS)
|
||||
|
||||
%$(PROGSSUF)_g$(EXESUF): $(FF_DEP_LIBS)
|
||||
$(LD) $(LDFLAGS) $(LDEXEFLAGS) $(LD_O) $(OBJS-$*) $(FF_EXTRALIBS)
|
||||
tools/%.o: tools/%.c
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) $(CC_O) $<
|
||||
|
||||
VERSION_SH = $(SRC_PATH)/ffbuild/version.sh
|
||||
ifeq ($(VERSION_TRACKING),yes)
|
||||
GIT_LOG = $(SRC_PATH)/.git/logs/HEAD
|
||||
endif
|
||||
ffplay.o ffplay.d: CFLAGS += $(SDL_CFLAGS)
|
||||
|
||||
.version: $(wildcard $(GIT_LOG)) $(VERSION_SH) ffbuild/config.mak
|
||||
VERSION_SH = $(SRC_PATH_BARE)/version.sh
|
||||
GIT_LOG = $(SRC_PATH_BARE)/.git/logs/HEAD
|
||||
SVN_ENTRIES = $(SRC_PATH_BARE)/.svn/entries
|
||||
|
||||
.version: $(wildcard $(GIT_LOG) $(SVN_ENTRIES)) $(VERSION_SH) config.mak
|
||||
.version: M=@
|
||||
|
||||
ifneq ($(VERSION_TRACKING),yes)
|
||||
libavutil/ffversion.h .version: REVISION=unknown
|
||||
endif
|
||||
libavutil/ffversion.h .version:
|
||||
$(M)revision=$(REVISION) $(VERSION_SH) $(SRC_PATH) libavutil/ffversion.h $(EXTRA_VERSION)
|
||||
version.h .version:
|
||||
$(M)$(VERSION_SH) $(SRC_PATH) version.h $(EXTRA_VERSION)
|
||||
$(Q)touch .version
|
||||
|
||||
# force version.sh to run whenever version might have changed
|
||||
-include .version
|
||||
|
||||
install: install-libs install-headers
|
||||
alltools: $(TOOLS)
|
||||
|
||||
install-libs: install-libs-yes
|
||||
documentation: $(addprefix doc/, developer.html faq.html ffmpeg-doc.html \
|
||||
ffplay-doc.html ffprobe-doc.html ffserver-doc.html \
|
||||
general.html libavfilter.html $(ALLMANPAGES))
|
||||
|
||||
doc/%.html: TAG = HTML
|
||||
doc/%.html: doc/%.texi
|
||||
$(M)cd doc && texi2html -monolithic -number $(<:doc/%=%)
|
||||
|
||||
doc/%.pod: TAG = POD
|
||||
doc/%.pod: doc/%-doc.texi
|
||||
$(M)doc/texi2pod.pl $< $@
|
||||
|
||||
doc/%.1: TAG = MAN
|
||||
doc/%.1: doc/%.pod
|
||||
$(M)pod2man --section=1 --center=" " --release=" " $< > $@
|
||||
|
||||
install: $(INSTALL_TARGETS-yes)
|
||||
|
||||
install-progs: $(PROGS) $(INSTALL_PROGS_TARGETS-yes)
|
||||
$(Q)mkdir -p "$(BINDIR)"
|
||||
$(INSTALL) -c -m 755 $(PROGS) "$(BINDIR)"
|
||||
|
||||
install-data: $(DATA_FILES)
|
||||
$(Q)mkdir -p "$(DATADIR)"
|
||||
$(INSTALL) -m 644 $(DATA_FILES) "$(DATADIR)"
|
||||
|
||||
uninstall: uninstall-data uninstall-headers uninstall-libs uninstall-pkgconfig
|
||||
install-man: $(MANPAGES)
|
||||
$(Q)mkdir -p "$(MANDIR)/man1"
|
||||
$(INSTALL) -m 644 $(MANPAGES) "$(MANDIR)/man1"
|
||||
|
||||
uninstall: uninstall-progs uninstall-data uninstall-man
|
||||
|
||||
uninstall-progs:
|
||||
$(RM) $(addprefix "$(BINDIR)/", $(ALLPROGS))
|
||||
|
||||
uninstall-data:
|
||||
$(RM) -r "$(DATADIR)"
|
||||
|
||||
clean::
|
||||
$(RM) $(CLEANSUFFIXES)
|
||||
$(RM) $(addprefix compat/,$(CLEANSUFFIXES)) $(addprefix compat/*/,$(CLEANSUFFIXES)) $(addprefix compat/*/*/,$(CLEANSUFFIXES))
|
||||
$(RM) -r coverage-html
|
||||
$(RM) -rf coverage.info coverage.info.in lcov
|
||||
uninstall-man:
|
||||
$(RM) $(addprefix "$(MANDIR)/man1/",$(ALLMANPAGES))
|
||||
|
||||
distclean:: clean
|
||||
$(RM) .version config.asm config.h config_components.h mapfile \
|
||||
ffbuild/.config ffbuild/config.* libavutil/avconfig.h \
|
||||
version.h libavutil/ffversion.h libavcodec/codec_names.h \
|
||||
libavcodec/bsf_list.c libavformat/protocol_list.c \
|
||||
libavcodec/codec_list.c libavcodec/parser_list.c \
|
||||
libavfilter/filter_list.c libavdevice/indev_list.c libavdevice/outdev_list.c \
|
||||
libavformat/muxer_list.c libavformat/demuxer_list.c
|
||||
ifeq ($(SRC_LINK),src)
|
||||
$(RM) src
|
||||
endif
|
||||
$(RM) -rf doc/examples/pc-uninstalled
|
||||
testclean:
|
||||
$(RM) -r tests/vsynth1 tests/vsynth2 tests/data
|
||||
$(RM) $(addprefix tests/,$(CLEANSUFFIXES))
|
||||
$(RM) tests/seek_test$(EXESUF) tests/seek_test.o
|
||||
$(RM) $(addprefix tests/,$(addsuffix $(HOSTEXESUF),audiogen videogen rotozoom tiny_psnr))
|
||||
|
||||
clean:: testclean
|
||||
$(RM) $(ALLPROGS) $(ALLPROGS_G)
|
||||
$(RM) $(CLEANSUFFIXES)
|
||||
$(RM) doc/*.html doc/*.pod doc/*.1
|
||||
$(RM) $(TOOLS)
|
||||
|
||||
distclean::
|
||||
$(RM) $(DISTCLEANSUFFIXES)
|
||||
$(RM) version.h config.* libavutil/avconfig.h
|
||||
|
||||
config:
|
||||
$(SRC_PATH)/configure $(value FFMPEG_CONFIGURATION)
|
||||
|
||||
build: all alltools examples testprogs
|
||||
check: all alltools examples testprogs fate
|
||||
# regression tests
|
||||
|
||||
include $(SRC_PATH)/tests/Makefile
|
||||
check: test checkheaders
|
||||
|
||||
$(sort $(OUTDIRS)):
|
||||
$(Q)mkdir -p $@
|
||||
fulltest test: codectest lavftest seektest
|
||||
|
||||
# Dummy rule to stop make trying to rebuild removed or renamed headers
|
||||
%.h:
|
||||
@:
|
||||
FFSERVER_REFFILE = $(SRC_PATH)/tests/ffserver.regression.ref
|
||||
SEEK_REFFILE = $(SRC_PATH)/tests/seek.regression.ref
|
||||
|
||||
# Disable suffix rules. Most of the builtin rules are suffix rules,
|
||||
# so this saves some time on slow systems.
|
||||
.SUFFIXES:
|
||||
ENCDEC = $(and $(CONFIG_$(1)_ENCODER),$(CONFIG_$(1)_DECODER))
|
||||
MUXDEM = $(and $(CONFIG_$(1)_MUXER),$(CONFIG_$(or $(2),$(1))_DEMUXER))
|
||||
|
||||
.PHONY: all all-yes alltools build check config testprogs
|
||||
.PHONY: *clean install* uninstall*
|
||||
VCODEC_TESTS =
|
||||
VCODEC_TESTS-$(call ENCDEC,ASV1) += asv1
|
||||
VCODEC_TESTS-$(call ENCDEC,ASV2) += asv2
|
||||
VCODEC_TESTS-$(call ENCDEC,DNXHD) += dnxhd_1080i dnxhd_720p dnxhd_720p_rd
|
||||
VCODEC_TESTS-$(call ENCDEC,DVVIDEO) += dv dv50
|
||||
VCODEC_TESTS-$(call ENCDEC,FFV1) += ffv1
|
||||
VCODEC_TESTS-$(call ENCDEC,FLASHSV) += flashsv
|
||||
VCODEC_TESTS-$(call ENCDEC,FLV) += flv
|
||||
VCODEC_TESTS-$(call ENCDEC,H261) += h261
|
||||
VCODEC_TESTS-$(call ENCDEC,H263) += h263 h263p
|
||||
VCODEC_TESTS-$(call ENCDEC,HUFFYUV) += huffyuv
|
||||
VCODEC_TESTS-$(call ENCDEC,JPEGLS) += jpegls
|
||||
VCODEC_TESTS-$(call ENCDEC,MJPEG) += mjpeg ljpeg
|
||||
VCODEC_TESTS-$(call ENCDEC,MPEG1VIDEO) += mpeg mpeg1b
|
||||
VCODEC_TESTS-$(call ENCDEC,MPEG2VIDEO) += mpeg2 mpeg2thread
|
||||
VCODEC_TESTS-$(call ENCDEC,MPEG4) += mpeg4 mpeg4adv mpeg4nr mpeg4thread error rc
|
||||
VCODEC_TESTS-$(call ENCDEC,MSMPEG4V1) += msmpeg4
|
||||
VCODEC_TESTS-$(call ENCDEC,MSMPEG4V2) += msmpeg4v2
|
||||
VCODEC_TESTS-$(call ENCDEC,ROQ) += roq
|
||||
VCODEC_TESTS-$(call ENCDEC,RV10) += rv10
|
||||
VCODEC_TESTS-$(call ENCDEC,RV20) += rv20
|
||||
VCODEC_TESTS-$(call ENCDEC,SNOW) += snow snowll
|
||||
VCODEC_TESTS-$(call ENCDEC,SVQ1) += svq1
|
||||
VCODEC_TESTS-$(call ENCDEC,WMV1) += wmv1
|
||||
VCODEC_TESTS-$(call ENCDEC,WMV2) += wmv2
|
||||
|
||||
ACODEC_TESTS =
|
||||
ACODEC_TESTS-$(call ENCDEC,AC3) += ac3
|
||||
ACODEC_TESTS-$(call ENCDEC,ADPCM_G726) += g726
|
||||
ACODEC_TESTS-$(call ENCDEC,ADPCM_IMA_QT) += adpcm_ima_qt
|
||||
ACODEC_TESTS-$(call ENCDEC,ADPCM_IMA_WAV) += adpcm_ima_wav
|
||||
ACODEC_TESTS-$(call ENCDEC,ADPCM_MS) += adpcm_ms
|
||||
ACODEC_TESTS-$(call ENCDEC,ADPCM_SWF) += adpcm_swf
|
||||
ACODEC_TESTS-$(call ENCDEC,ADPCM_YAMAHA) += adpcm_yam
|
||||
ACODEC_TESTS-$(call ENCDEC,ALAC) += alac
|
||||
ACODEC_TESTS-$(call ENCDEC,FLAC) += flac
|
||||
ACODEC_TESTS-$(call ENCDEC,MP2) += mp2
|
||||
ACODEC_TESTS-$(call ENCDEC,PCM_S16LE) += pcm # fixme
|
||||
ACODEC_TESTS-$(call ENCDEC,WMAV1) += wmav1
|
||||
ACODEC_TESTS-$(call ENCDEC,WMAV1) += wmav2
|
||||
|
||||
LAVF_TESTS =
|
||||
LAVF_TESTS-$(call MUXDEM,AIFF) += aiff
|
||||
LAVF_TESTS-$(call MUXDEM,PCM_ALAW) += alaw
|
||||
LAVF_TESTS-$(call MUXDEM,ASF) += asf
|
||||
LAVF_TESTS-$(call MUXDEM,AU) += au
|
||||
LAVF_TESTS-$(call MUXDEM,AVI) += avi
|
||||
LAVF_TESTS-$(call ENCDEC,BMP) += bmp
|
||||
LAVF_TESTS-$(call MUXDEM,DV) += dv_fmt
|
||||
LAVF_TESTS-$(call MUXDEM,FFM) += ffm
|
||||
LAVF_TESTS-$(call MUXDEM,FLV) += flv_fmt
|
||||
LAVF_TESTS-$(call ENCDEC,GIF) += gif
|
||||
LAVF_TESTS-$(call MUXDEM,GXF) += gxf
|
||||
LAVF_TESTS-$(call ENCDEC,MJPEG) += jpg
|
||||
LAVF_TESTS-$(call MUXDEM,MATROSKA) += mkv
|
||||
LAVF_TESTS-$(call MUXDEM,MMF) += mmf
|
||||
LAVF_TESTS-$(call MUXDEM,MOV) += mov
|
||||
LAVF_TESTS-$(call MUXDEM,MPEG1SYSTEM,MPEGPS) += mpg
|
||||
LAVF_TESTS-$(call MUXDEM,PCM_MULAW) += mulaw
|
||||
LAVF_TESTS-$(call MUXDEM,MXF) += mxf
|
||||
LAVF_TESTS-$(call MUXDEM,NUT) += nut
|
||||
LAVF_TESTS-$(call MUXDEM,OGG) += ogg
|
||||
LAVF_TESTS-$(call ENCDEC,PBM) += pbmpipe
|
||||
LAVF_TESTS-$(call ENCDEC,PCX) += pcx
|
||||
LAVF_TESTS-$(call ENCDEC,PGM) += pgm pgmpipe
|
||||
LAVF_TESTS-$(call MUXDEM,RAWVIDEO) += pixfmt
|
||||
LAVF_TESTS-$(call ENCDEC,PPM) += ppm ppmpipe
|
||||
LAVF_TESTS-$(call MUXDEM,RM) += rm
|
||||
LAVF_TESTS-$(call ENCDEC,SGI) += sgi
|
||||
LAVF_TESTS-$(call MUXDEM,SWF) += swf
|
||||
LAVF_TESTS-$(call ENCDEC,TARGA) += tga
|
||||
LAVF_TESTS-$(call ENCDEC,TIFF) += tiff
|
||||
LAVF_TESTS-$(call MUXDEM,MPEGTS) += ts
|
||||
LAVF_TESTS-$(call MUXDEM,VOC) += voc
|
||||
LAVF_TESTS-$(call MUXDEM,WAV) += wav
|
||||
LAVF_TESTS-$(call MUXDEM,YUV4MPEGPIPE) += yuv4mpeg
|
||||
|
||||
LAVFI_TESTS = \
|
||||
crop \
|
||||
crop_scale \
|
||||
crop_scale_vflip \
|
||||
crop_vflip \
|
||||
null \
|
||||
scale200 \
|
||||
scale500 \
|
||||
vflip \
|
||||
vflip_crop \
|
||||
vflip_vflip \
|
||||
|
||||
ACODEC_TESTS := $(addprefix regtest-, $(ACODEC_TESTS) $(ACODEC_TESTS-yes))
|
||||
VCODEC_TESTS := $(addprefix regtest-, $(VCODEC_TESTS) $(VCODEC_TESTS-yes))
|
||||
LAVF_TESTS := $(addprefix regtest-, $(LAVF_TESTS) $(LAVF_TESTS-yes))
|
||||
LAVFI_TESTS := $(addprefix regtest-, $(LAVFI_TESTS) $(LAVFI_TESTS-yes))
|
||||
|
||||
CODEC_TESTS = $(VCODEC_TESTS) $(ACODEC_TESTS)
|
||||
|
||||
codectest: $(CODEC_TESTS)
|
||||
lavftest: $(LAVF_TESTS)
|
||||
lavfitest: $(LAVFI_TESTS)
|
||||
|
||||
$(ACODEC_TESTS): regtest-aref
|
||||
$(VCODEC_TESTS): regtest-vref
|
||||
$(LAVF_TESTS) $(LAVFI_TESTS): regtest-ref
|
||||
|
||||
REFFILE = $(SRC_PATH)/tests/ref/$(1)/$(2:regtest-%=%)
|
||||
RESFILE = tests/data/$(2:regtest-%=%).$(1).regression
|
||||
|
||||
define CODECTEST_CMD
|
||||
$(SRC_PATH)/tests/codec-regression.sh $@ vsynth1 tests/vsynth1 "$(TARGET_EXEC)" "$(TARGET_PATH)"
|
||||
$(SRC_PATH)/tests/codec-regression.sh $@ vsynth2 tests/vsynth2 "$(TARGET_EXEC)" "$(TARGET_PATH)"
|
||||
endef
|
||||
|
||||
regtest-ref: regtest-aref regtest-vref
|
||||
|
||||
regtest-vref: ffmpeg$(EXESUF) tests/vsynth1/00.pgm tests/vsynth2/00.pgm
|
||||
$(CODECTEST_CMD)
|
||||
|
||||
regtest-aref: ffmpeg$(EXESUF) tests/data/asynth1.sw
|
||||
@$(SRC_PATH)/tests/codec-regression.sh $@ acodec tests/acodec "$(TARGET_EXEC)" "$(TARGET_PATH)"
|
||||
|
||||
$(VCODEC_TESTS): tests/tiny_psnr$(HOSTEXESUF)
|
||||
@echo "TEST VCODEC $(@:regtest-%=%)"
|
||||
@$(CODECTEST_CMD)
|
||||
@diff -u -w $(call REFFILE,vsynth1,$@) $(call RESFILE,vsynth1,$@)
|
||||
@diff -u -w $(call REFFILE,vsynth2,$@) $(call RESFILE,vsynth2,$@)
|
||||
|
||||
$(ACODEC_TESTS): tests/tiny_psnr$(HOSTEXESUF)
|
||||
@echo "TEST ACODEC $(@:regtest-%=%)"
|
||||
@$(SRC_PATH)/tests/codec-regression.sh $@ acodec tests/acodec "$(TARGET_EXEC)" "$(TARGET_PATH)"
|
||||
@diff -u -w $(call REFFILE,acodec,$@) $(call RESFILE,acodec,$@)
|
||||
|
||||
$(LAVF_TESTS):
|
||||
@echo "TEST LAVF $(@:regtest-%=%)"
|
||||
@$(SRC_PATH)/tests/lavf-regression.sh $@ lavf tests/vsynth1 "$(TARGET_EXEC)" "$(TARGET_PATH)"
|
||||
@diff -u -w $(call REFFILE,lavf,$@) $(call RESFILE,lavf,$@)
|
||||
|
||||
$(LAVFI_TESTS):
|
||||
@echo "TEST LAVFI $(@:regtest-%=%)"
|
||||
@$(SRC_PATH)/tests/lavfi-regression.sh $@ lavfi tests/vsynth1 "$(TARGET_EXEC)" "$(TARGET_PATH)"
|
||||
@diff -u -w $(call REFFILE,lavfi,$@) $(call RESFILE,lavfi,$@)
|
||||
|
||||
seektest: codectest lavftest tests/seek_test$(EXESUF)
|
||||
$(SRC_PATH)/tests/seek-regression.sh $(SRC_PATH) "$(TARGET_EXEC)" "$(TARGET_PATH)"
|
||||
|
||||
ffservertest: ffserver$(EXESUF) tests/vsynth1/00.pgm tests/data/asynth1.sw
|
||||
@echo
|
||||
@echo "Unfortunately ffserver is broken and therefore its regression"
|
||||
@echo "test fails randomly. Treat the results accordingly."
|
||||
@echo
|
||||
$(SRC_PATH)/tests/ffserver-regression.sh $(FFSERVER_REFFILE) $(SRC_PATH)/tests/ffserver.conf
|
||||
|
||||
tests/vsynth1/00.pgm: tests/videogen$(HOSTEXESUF)
|
||||
mkdir -p tests/vsynth1
|
||||
$(BUILD_ROOT)/$< 'tests/vsynth1/'
|
||||
|
||||
tests/vsynth2/00.pgm: tests/rotozoom$(HOSTEXESUF)
|
||||
mkdir -p tests/vsynth2
|
||||
$(BUILD_ROOT)/$< 'tests/vsynth2/' $(SRC_PATH)/tests/lena.pnm
|
||||
|
||||
tests/data/asynth1.sw: tests/audiogen$(HOSTEXESUF)
|
||||
mkdir -p tests/data
|
||||
$(BUILD_ROOT)/$< $@
|
||||
|
||||
tests/seek_test$(EXESUF): tests/seek_test.o $(FF_DEP_LIBS)
|
||||
$(LD) $(FF_LDFLAGS) -o $@ $< $(FF_EXTRALIBS)
|
||||
|
||||
ifdef SAMPLES
|
||||
include $(SRC_PATH_BARE)/tests/fate.mak
|
||||
fate: $(FATE_TESTS)
|
||||
$(FATE_TESTS): ffmpeg$(EXESUF)
|
||||
@echo "TEST FATE $(@:fate-%=%)"
|
||||
@$(SRC_PATH)/tests/fate-run.sh $@ "$(SAMPLES)" "$(TARGET_EXEC)" "$(TARGET_PATH)" '$(CMD)'
|
||||
else
|
||||
fate:
|
||||
@echo "SAMPLES not specified, cannot run FATE"
|
||||
endif
|
||||
|
||||
.PHONY: documentation *test regtest-* zlib-error alltools check config
|
||||
|
||||
12
README
Normal file
12
README
Normal file
@@ -0,0 +1,12 @@
|
||||
FFmpeg README
|
||||
-------------
|
||||
|
||||
1) Documentation
|
||||
----------------
|
||||
|
||||
* Read the documentation in the doc/ directory.
|
||||
|
||||
2) Licensing
|
||||
------------
|
||||
|
||||
* See the LICENSE file.
|
||||
46
README.md
46
README.md
@@ -1,46 +0,0 @@
|
||||
FFmpeg README
|
||||
=============
|
||||
|
||||
FFmpeg is a collection of libraries and tools to process multimedia content
|
||||
such as audio, video, subtitles and related metadata.
|
||||
|
||||
## Libraries
|
||||
|
||||
* `libavcodec` provides implementation of a wider range of codecs.
|
||||
* `libavformat` implements streaming protocols, container formats and basic I/O access.
|
||||
* `libavutil` includes hashers, decompressors and miscellaneous utility functions.
|
||||
* `libavfilter` provides means to alter decoded audio and video through a directed graph of connected filters.
|
||||
* `libavdevice` provides an abstraction to access capture and playback devices.
|
||||
* `libswresample` implements audio mixing and resampling routines.
|
||||
* `libswscale` implements color conversion and scaling routines.
|
||||
|
||||
## Tools
|
||||
|
||||
* [ffmpeg](https://ffmpeg.org/ffmpeg.html) is a command line toolbox to
|
||||
manipulate, convert and stream multimedia content.
|
||||
* [ffplay](https://ffmpeg.org/ffplay.html) is a minimalistic multimedia player.
|
||||
* [ffprobe](https://ffmpeg.org/ffprobe.html) is a simple analysis tool to inspect
|
||||
multimedia content.
|
||||
* Additional small tools such as `aviocat`, `ismindex` and `qt-faststart`.
|
||||
|
||||
## Documentation
|
||||
|
||||
The offline documentation is available in the **doc/** directory.
|
||||
|
||||
The online documentation is available in the main [website](https://ffmpeg.org)
|
||||
and in the [wiki](https://trac.ffmpeg.org).
|
||||
|
||||
### Examples
|
||||
|
||||
Coding examples are available in the **doc/examples** directory.
|
||||
|
||||
## License
|
||||
|
||||
FFmpeg codebase is mainly LGPL-licensed with optional components licensed under
|
||||
GPL. Please refer to the LICENSE file for detailed information.
|
||||
|
||||
## Contributing
|
||||
|
||||
Patches should be submitted to the ffmpeg-devel mailing list using
|
||||
`git format-patch` or `git send-email`. Github pull requests should be
|
||||
avoided because they are not part of our review process and will be ignored.
|
||||
195
RELEASE
195
RELEASE
@@ -1 +1,194 @@
|
||||
8.0.1
|
||||
Release Notes
|
||||
=============
|
||||
|
||||
* 0.6 "Works with HTML5" June, 2010
|
||||
|
||||
General notes
|
||||
-------------
|
||||
|
||||
This release focuses on improvements for the new multimedia elements in HTML5.
|
||||
The H.264 and Theora decoders are now significantly faster, the Vorbis decoder
|
||||
has seen important updates and this release supports Google's newly released
|
||||
libvpx library for the VP8 codec and WebM container.
|
||||
|
||||
Other important changes are additions of decoders including, but not limited to,
|
||||
Intel Indeo 5, WMA Pro, WMA Voice and HE-AAC.
|
||||
|
||||
See the Changelog file for a list of significant changes.
|
||||
|
||||
Please note that our policy on bug reports has not changed. We still only accept
|
||||
bug reports against HEAD of the FFmpeg trunk repository. If you are experiencing
|
||||
any issues with any formally released version of FFmpeg, please try a current
|
||||
version of the development code to check if the issue still exists. If it does,
|
||||
make your report against the development code following the usual bug reporting
|
||||
guidelines.
|
||||
|
||||
|
||||
API and other notable Changes
|
||||
-----------------------------
|
||||
|
||||
Please see the file doc/APIchanges for programmer-centric information.
|
||||
|
||||
Notable changes:
|
||||
- deprecated vhook subsystem removed
|
||||
- deprecated old scaler removed
|
||||
- nonfree libamr support for AMR-NB/WB decoding/encoding removed
|
||||
- RTMP support in libavformat
|
||||
- -formats option split into -formats, -codecs, -bsfs, and -protocols
|
||||
- ffprobe tool
|
||||
- RTMP/RTMPT/RTMPS/RTMPE/RTMPTE protocol support via librtmp
|
||||
- CODEC_CAP_EXPERIMENTAL added
|
||||
|
||||
|
||||
Added Codecs:
|
||||
-------------
|
||||
|
||||
- VQF demuxer
|
||||
- PCX encoder
|
||||
- CorePNG decoding support
|
||||
- 8088flex TMV demuxer and decoder
|
||||
- enable symbol versioning by default for linkers that support it
|
||||
- V210 decoder and encoder
|
||||
- QCP demuxer
|
||||
- SoX native format muxer and demuxer
|
||||
- AMR-NB decoding/encoding, AMR-WB decoding via OpenCORE libraries
|
||||
- DPX image decoder
|
||||
- Electronic Arts Madcow decoder
|
||||
- DivX (XSUB) subtitle encoder
|
||||
- experimental AAC encoder
|
||||
- Wave64 demuxer
|
||||
- IEC-61937 compatible Muxer
|
||||
- TwinVQ decoder
|
||||
- Bluray (PGS) subtitle decoder
|
||||
- LPCM support in MPEG-TS (HDMV RID as found on Blu-ray disks)
|
||||
- WMA Pro decoder
|
||||
- Core Audio Format demuxer
|
||||
- Atrac1 decoder
|
||||
- MD STUDIO audio demuxer
|
||||
- RF64 support in WAV demuxer
|
||||
- MPEG-4 Audio Lossless Coding (ALS) decoder
|
||||
- IV8 demuxer
|
||||
- CDG demuxer and decoder
|
||||
- R210 decoder
|
||||
- Auravision Aura 1 and 2 decoders
|
||||
- Deluxe Paint Animation playback system
|
||||
- SIPR decoder
|
||||
- Adobe Filmstrip muxer and demuxer
|
||||
- RTP packetization and depacketization of H.263 and AMR
|
||||
- Bink demuxer and audio/video decoders
|
||||
- IFF PBM/ILBM bitmap decoder
|
||||
- Indeo 5 decoder
|
||||
- WMA Voice decoder
|
||||
- AMR-NB decoder
|
||||
- RTSP muxer
|
||||
- HE-AAC v1 decoder
|
||||
- Kega Game Video (KGV1) decoder
|
||||
- Psygnosis YOP demuxer and video decoder
|
||||
- RTP hinting in the mov/3gp/mp4 muxer
|
||||
- VP8 decoding via libvpx
|
||||
|
||||
|
||||
Notable license related changes
|
||||
-------------------------------
|
||||
|
||||
- remaining GPL parts in AC-3 decoder converted to LGPL
|
||||
- libswscale can now be compiled in LGPL mode
|
||||
|
||||
|
||||
|
||||
* 0.6.1
|
||||
|
||||
General notes
|
||||
-------------
|
||||
|
||||
This point release includes some updates to make the 0.6 release series usable
|
||||
for users that need to retain the existing behavior as closely as possible.
|
||||
The changes follow below:
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- fix autodetection of E-AC-3 substream samples
|
||||
- performance fix for seekable HTTP
|
||||
- add missing VP80 fourcc code for the VP8 codec
|
||||
- small documentation fixes
|
||||
- fix several potentially exploitable issues in the FLIC decoder
|
||||
(addresses CVE-2010-3429)
|
||||
|
||||
|
||||
HE-AAC v2 backport
|
||||
------------------
|
||||
|
||||
This release includes a backport of the AAC decoder from trunk, which
|
||||
enables proper playback of HE-AAC v2 media.
|
||||
|
||||
|
||||
* 0.6.2
|
||||
|
||||
General notes
|
||||
-------------
|
||||
|
||||
This is a maintenance-only release that addresses a small number of security
|
||||
and portability issues. Distributors and system integrators are encouraged
|
||||
to update and share their patches against this branch.
|
||||
|
||||
Security fixes
|
||||
--------------
|
||||
|
||||
Programming errors in container and codec implementations may lead to
|
||||
denial of service or the execution of arbitrary code if the user is
|
||||
tricked into opening a malformed media file or stream.
|
||||
|
||||
Affected and updated have been the implementations of the following
|
||||
codecs and container formats:
|
||||
|
||||
- VC1 decoder (Change related to CVE-2011-0723)
|
||||
- APE decoder (cf. http://packetstorm.linuxsecurity.com/1103-exploits/vlc105-dos.txt)
|
||||
|
||||
|
||||
* 0.6.3
|
||||
|
||||
General notes
|
||||
-------------
|
||||
|
||||
This is a mostly maintenance-only release that addresses a small number
|
||||
of bugs such as security and compilation issues. Moreover, this release
|
||||
has been updated to work with gcc-4.6 and the VisualOn AAC encoder has
|
||||
been backported from the Libav 0.7.2 release. Distributors and system
|
||||
integrators are encouraged to update and share their patches against
|
||||
this branch.
|
||||
For a full list of changes please see the Changelog file.
|
||||
|
||||
|
||||
* 0.6.4
|
||||
|
||||
General notes
|
||||
-------------
|
||||
|
||||
This mostly maintenance-only release that addresses a number a number of
|
||||
bugs such as security and compilation issues that have been brought to
|
||||
our attention. Among other (rather minor) fixes, this release features
|
||||
fixes for the QDM2 decoder (CVE-2011-4351), vp3 decoder (CVE-2011-4352),
|
||||
DoS in the VP5/VP6 decoders (CVE-2011-4353), a buffer overflow in the
|
||||
Sierra VMD decoder CVE-2011-4364, and a safety fix in the svq1 decoder
|
||||
(CVE-2011-4579).
|
||||
|
||||
Distributors and system integrators are encouraged
|
||||
to update and share their patches against this branch. For a full list
|
||||
of changes please see the Changelog file.
|
||||
|
||||
|
||||
* 0.6.5
|
||||
|
||||
General notes
|
||||
-------------
|
||||
|
||||
This mostly maintenance-only release that addresses a number a number of
|
||||
bugs such as security and compilation issues that have been brought to
|
||||
our attention. Among other (rather minor) fixes, this release features
|
||||
fixes for the VP3 decoder (CVE-2011-3892), vorbis decoder, and matroska
|
||||
demuxer (CVE-2011-3893 and CVE-2011-3895).
|
||||
|
||||
Distributors and system integrators are encouraged
|
||||
to update and share their patches against this branch. For a full list
|
||||
of changes please see the Changelog file.
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
|
||||
┌────────────────────────────────────────┐
|
||||
│ RELEASE NOTES for FFmpeg 8.0 "Huffman" │
|
||||
└────────────────────────────────────────┘
|
||||
|
||||
The FFmpeg Project proudly presents FFmpeg 8.0 "Huffman", about 11
|
||||
months after the release of FFmpeg 7.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.
|
||||
664
cmdutils.c
Normal file
664
cmdutils.c
Normal file
@@ -0,0 +1,664 @@
|
||||
/*
|
||||
* Various utilities for command line tools
|
||||
* Copyright (c) 2000-2003 Fabrice Bellard
|
||||
*
|
||||
* 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 <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <math.h>
|
||||
|
||||
/* Include only the enabled headers since some compilers (namely, Sun
|
||||
Studio) will not omit unused inline functions and create undefined
|
||||
references to libraries that are not being built. */
|
||||
|
||||
#include "config.h"
|
||||
#include "libavformat/avformat.h"
|
||||
#include "libavfilter/avfilter.h"
|
||||
#include "libavdevice/avdevice.h"
|
||||
#include "libswscale/swscale.h"
|
||||
#include "libpostproc/postprocess.h"
|
||||
#include "libavutil/avstring.h"
|
||||
#include "libavutil/pixdesc.h"
|
||||
#include "libavcodec/opt.h"
|
||||
#include "cmdutils.h"
|
||||
#include "version.h"
|
||||
#if CONFIG_NETWORK
|
||||
#include "libavformat/network.h"
|
||||
#endif
|
||||
#if HAVE_SYS_RESOURCE_H
|
||||
#include <sys/resource.h>
|
||||
#endif
|
||||
|
||||
const char **opt_names;
|
||||
static int opt_name_count;
|
||||
AVCodecContext *avcodec_opts[AVMEDIA_TYPE_NB];
|
||||
AVFormatContext *avformat_opts;
|
||||
struct SwsContext *sws_opts;
|
||||
|
||||
const int this_year = 2010;
|
||||
|
||||
double parse_number_or_die(const char *context, const char *numstr, int type, double min, double max)
|
||||
{
|
||||
char *tail;
|
||||
const char *error;
|
||||
double d = strtod(numstr, &tail);
|
||||
if (*tail)
|
||||
error= "Expected number for %s but found: %s\n";
|
||||
else if (d < min || d > max)
|
||||
error= "The value for %s was %s which is not within %f - %f\n";
|
||||
else if(type == OPT_INT64 && (int64_t)d != d)
|
||||
error= "Expected int64 for %s but found %s\n";
|
||||
else
|
||||
return d;
|
||||
fprintf(stderr, error, context, numstr, min, max);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int64_t parse_time_or_die(const char *context, const char *timestr, int is_duration)
|
||||
{
|
||||
int64_t us = parse_date(timestr, is_duration);
|
||||
if (us == INT64_MIN) {
|
||||
fprintf(stderr, "Invalid %s specification for %s: %s\n",
|
||||
is_duration ? "duration" : "date", context, timestr);
|
||||
exit(1);
|
||||
}
|
||||
return us;
|
||||
}
|
||||
|
||||
void show_help_options(const OptionDef *options, const char *msg, int mask, int value)
|
||||
{
|
||||
const OptionDef *po;
|
||||
int first;
|
||||
|
||||
first = 1;
|
||||
for(po = options; po->name != NULL; po++) {
|
||||
char buf[64];
|
||||
if ((po->flags & mask) == value) {
|
||||
if (first) {
|
||||
printf("%s", msg);
|
||||
first = 0;
|
||||
}
|
||||
av_strlcpy(buf, po->name, sizeof(buf));
|
||||
if (po->flags & HAS_ARG) {
|
||||
av_strlcat(buf, " ", sizeof(buf));
|
||||
av_strlcat(buf, po->argname, sizeof(buf));
|
||||
}
|
||||
printf("-%-17s %s\n", buf, po->help);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const OptionDef* find_option(const OptionDef *po, const char *name){
|
||||
while (po->name != NULL) {
|
||||
if (!strcmp(name, po->name))
|
||||
break;
|
||||
po++;
|
||||
}
|
||||
return po;
|
||||
}
|
||||
|
||||
void parse_options(int argc, char **argv, const OptionDef *options,
|
||||
void (* parse_arg_function)(const char*))
|
||||
{
|
||||
const char *opt, *arg;
|
||||
int optindex, handleoptions=1;
|
||||
const OptionDef *po;
|
||||
|
||||
/* parse options */
|
||||
optindex = 1;
|
||||
while (optindex < argc) {
|
||||
opt = argv[optindex++];
|
||||
|
||||
if (handleoptions && opt[0] == '-' && opt[1] != '\0') {
|
||||
int bool_val = 1;
|
||||
if (opt[1] == '-' && opt[2] == '\0') {
|
||||
handleoptions = 0;
|
||||
continue;
|
||||
}
|
||||
opt++;
|
||||
po= find_option(options, opt);
|
||||
if (!po->name && opt[0] == 'n' && opt[1] == 'o') {
|
||||
/* handle 'no' bool option */
|
||||
po = find_option(options, opt + 2);
|
||||
if (!(po->name && (po->flags & OPT_BOOL)))
|
||||
goto unknown_opt;
|
||||
bool_val = 0;
|
||||
}
|
||||
if (!po->name)
|
||||
po= find_option(options, "default");
|
||||
if (!po->name) {
|
||||
unknown_opt:
|
||||
fprintf(stderr, "%s: unrecognized option '%s'\n", argv[0], opt);
|
||||
exit(1);
|
||||
}
|
||||
arg = NULL;
|
||||
if (po->flags & HAS_ARG) {
|
||||
arg = argv[optindex++];
|
||||
if (!arg) {
|
||||
fprintf(stderr, "%s: missing argument for option '%s'\n", argv[0], opt);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
if (po->flags & OPT_STRING) {
|
||||
char *str;
|
||||
str = av_strdup(arg);
|
||||
*po->u.str_arg = str;
|
||||
} else if (po->flags & OPT_BOOL) {
|
||||
*po->u.int_arg = bool_val;
|
||||
} else if (po->flags & OPT_INT) {
|
||||
*po->u.int_arg = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX);
|
||||
} else if (po->flags & OPT_INT64) {
|
||||
*po->u.int64_arg = parse_number_or_die(opt, arg, OPT_INT64, INT64_MIN, INT64_MAX);
|
||||
} else if (po->flags & OPT_FLOAT) {
|
||||
*po->u.float_arg = parse_number_or_die(opt, arg, OPT_FLOAT, -1.0/0.0, 1.0/0.0);
|
||||
} else if (po->flags & OPT_FUNC2) {
|
||||
if (po->u.func2_arg(opt, arg) < 0) {
|
||||
fprintf(stderr, "%s: failed to set value '%s' for option '%s'\n", argv[0], arg, opt);
|
||||
exit(1);
|
||||
}
|
||||
} else {
|
||||
po->u.func_arg(arg);
|
||||
}
|
||||
if(po->flags & OPT_EXIT)
|
||||
exit(0);
|
||||
} else {
|
||||
if (parse_arg_function)
|
||||
parse_arg_function(opt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int opt_default(const char *opt, const char *arg){
|
||||
int type;
|
||||
int ret= 0;
|
||||
const AVOption *o= NULL;
|
||||
int opt_types[]={AV_OPT_FLAG_VIDEO_PARAM, AV_OPT_FLAG_AUDIO_PARAM, 0, AV_OPT_FLAG_SUBTITLE_PARAM, 0};
|
||||
|
||||
for(type=0; type<AVMEDIA_TYPE_NB && ret>= 0; type++){
|
||||
const AVOption *o2 = av_find_opt(avcodec_opts[0], opt, NULL, opt_types[type], opt_types[type]);
|
||||
if(o2)
|
||||
ret = av_set_string3(avcodec_opts[type], opt, arg, 1, &o);
|
||||
}
|
||||
if(!o)
|
||||
ret = av_set_string3(avformat_opts, opt, arg, 1, &o);
|
||||
if(!o && sws_opts)
|
||||
ret = av_set_string3(sws_opts, opt, arg, 1, &o);
|
||||
if(!o){
|
||||
if(opt[0] == 'a')
|
||||
ret = av_set_string3(avcodec_opts[AVMEDIA_TYPE_AUDIO], opt+1, arg, 1, &o);
|
||||
else if(opt[0] == 'v')
|
||||
ret = av_set_string3(avcodec_opts[AVMEDIA_TYPE_VIDEO], opt+1, arg, 1, &o);
|
||||
else if(opt[0] == 's')
|
||||
ret = av_set_string3(avcodec_opts[AVMEDIA_TYPE_SUBTITLE], opt+1, arg, 1, &o);
|
||||
}
|
||||
if (o && ret < 0) {
|
||||
fprintf(stderr, "Invalid value '%s' for option '%s'\n", arg, opt);
|
||||
exit(1);
|
||||
}
|
||||
if (!o) {
|
||||
fprintf(stderr, "Unrecognized option '%s'\n", opt);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// av_log(NULL, AV_LOG_ERROR, "%s:%s: %f 0x%0X\n", opt, arg, av_get_double(avcodec_opts, opt, NULL), (int)av_get_int(avcodec_opts, opt, NULL));
|
||||
|
||||
//FIXME we should always use avcodec_opts, ... for storing options so there will not be any need to keep track of what i set over this
|
||||
opt_names= av_realloc(opt_names, sizeof(void*)*(opt_name_count+1));
|
||||
opt_names[opt_name_count++]= o->name;
|
||||
|
||||
if(avcodec_opts[0]->debug || avformat_opts->debug)
|
||||
av_log_set_level(AV_LOG_DEBUG);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int opt_loglevel(const char *opt, const char *arg)
|
||||
{
|
||||
const struct { const char *name; int level; } log_levels[] = {
|
||||
{ "quiet" , AV_LOG_QUIET },
|
||||
{ "panic" , AV_LOG_PANIC },
|
||||
{ "fatal" , AV_LOG_FATAL },
|
||||
{ "error" , AV_LOG_ERROR },
|
||||
{ "warning", AV_LOG_WARNING },
|
||||
{ "info" , AV_LOG_INFO },
|
||||
{ "verbose", AV_LOG_VERBOSE },
|
||||
{ "debug" , AV_LOG_DEBUG },
|
||||
};
|
||||
char *tail;
|
||||
int level;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++) {
|
||||
if (!strcmp(log_levels[i].name, arg)) {
|
||||
av_log_set_level(log_levels[i].level);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
level = strtol(arg, &tail, 10);
|
||||
if (*tail) {
|
||||
fprintf(stderr, "Invalid loglevel \"%s\". "
|
||||
"Possible levels are numbers or:\n", arg);
|
||||
for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++)
|
||||
fprintf(stderr, "\"%s\"\n", log_levels[i].name);
|
||||
exit(1);
|
||||
}
|
||||
av_log_set_level(level);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int opt_timelimit(const char *opt, const char *arg)
|
||||
{
|
||||
#if HAVE_SETRLIMIT
|
||||
int lim = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
|
||||
struct rlimit rl = { lim, lim + 1 };
|
||||
if (setrlimit(RLIMIT_CPU, &rl))
|
||||
perror("setrlimit");
|
||||
#else
|
||||
fprintf(stderr, "Warning: -%s not implemented on this OS\n", opt);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
void set_context_opts(void *ctx, void *opts_ctx, int flags)
|
||||
{
|
||||
int i;
|
||||
for(i=0; i<opt_name_count; i++){
|
||||
char buf[256];
|
||||
const AVOption *opt;
|
||||
const char *str= av_get_string(opts_ctx, opt_names[i], &opt, buf, sizeof(buf));
|
||||
/* if an option with name opt_names[i] is present in opts_ctx then str is non-NULL */
|
||||
if(str && ((opt->flags & flags) == flags))
|
||||
av_set_string3(ctx, opt_names[i], str, 1, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void print_error(const char *filename, int err)
|
||||
{
|
||||
char errbuf[128];
|
||||
const char *errbuf_ptr = errbuf;
|
||||
|
||||
if (av_strerror(err, errbuf, sizeof(errbuf)) < 0)
|
||||
errbuf_ptr = strerror(AVUNERROR(err));
|
||||
fprintf(stderr, "%s: %s\n", filename, errbuf_ptr);
|
||||
}
|
||||
|
||||
#define PRINT_LIB_VERSION(outstream,libname,LIBNAME,indent) \
|
||||
if (CONFIG_##LIBNAME) { \
|
||||
unsigned int version = libname##_version(); \
|
||||
fprintf(outstream, "%slib%-10s %2d.%2d.%2d / %2d.%2d.%2d\n", \
|
||||
indent? " " : "", #libname, \
|
||||
LIB##LIBNAME##_VERSION_MAJOR, \
|
||||
LIB##LIBNAME##_VERSION_MINOR, \
|
||||
LIB##LIBNAME##_VERSION_MICRO, \
|
||||
version >> 16, version >> 8 & 0xff, version & 0xff); \
|
||||
}
|
||||
|
||||
static void print_all_lib_versions(FILE* outstream, int indent)
|
||||
{
|
||||
PRINT_LIB_VERSION(outstream, avutil, AVUTIL, indent);
|
||||
PRINT_LIB_VERSION(outstream, avcodec, AVCODEC, indent);
|
||||
PRINT_LIB_VERSION(outstream, avformat, AVFORMAT, indent);
|
||||
PRINT_LIB_VERSION(outstream, avdevice, AVDEVICE, indent);
|
||||
PRINT_LIB_VERSION(outstream, avfilter, AVFILTER, indent);
|
||||
PRINT_LIB_VERSION(outstream, swscale, SWSCALE, indent);
|
||||
PRINT_LIB_VERSION(outstream, postproc, POSTPROC, indent);
|
||||
}
|
||||
|
||||
static void maybe_print_config(const char *lib, const char *cfg)
|
||||
{
|
||||
static int warned_cfg;
|
||||
|
||||
if (strcmp(FFMPEG_CONFIGURATION, cfg)) {
|
||||
if (!warned_cfg) {
|
||||
fprintf(stderr, " WARNING: library configuration mismatch\n");
|
||||
warned_cfg = 1;
|
||||
}
|
||||
fprintf(stderr, " %-11s configuration: %s\n", lib, cfg);
|
||||
}
|
||||
}
|
||||
|
||||
#define PRINT_LIB_CONFIG(lib, tag, cfg) do { \
|
||||
if (CONFIG_##lib) \
|
||||
maybe_print_config(tag, cfg); \
|
||||
} while (0)
|
||||
|
||||
void show_banner(void)
|
||||
{
|
||||
fprintf(stderr, "%s version " FFMPEG_VERSION ", Copyright (c) %d-%d the FFmpeg developers\n",
|
||||
program_name, program_birth_year, this_year);
|
||||
fprintf(stderr, " built on %s %s with %s %s\n",
|
||||
__DATE__, __TIME__, CC_TYPE, CC_VERSION);
|
||||
fprintf(stderr, " configuration: " FFMPEG_CONFIGURATION "\n");
|
||||
PRINT_LIB_CONFIG(AVUTIL, "libavutil", avutil_configuration());
|
||||
PRINT_LIB_CONFIG(AVCODEC, "libavcodec", avcodec_configuration());
|
||||
PRINT_LIB_CONFIG(AVFORMAT, "libavformat", avformat_configuration());
|
||||
PRINT_LIB_CONFIG(AVDEVICE, "libavdevice", avdevice_configuration());
|
||||
PRINT_LIB_CONFIG(AVFILTER, "libavfilter", avfilter_configuration());
|
||||
PRINT_LIB_CONFIG(SWSCALE, "libswscale", swscale_configuration());
|
||||
PRINT_LIB_CONFIG(POSTPROC, "libpostproc", postproc_configuration());
|
||||
print_all_lib_versions(stderr, 1);
|
||||
}
|
||||
|
||||
void show_version(void) {
|
||||
printf("%s " FFMPEG_VERSION "\n", program_name);
|
||||
print_all_lib_versions(stdout, 0);
|
||||
}
|
||||
|
||||
void show_license(void)
|
||||
{
|
||||
printf(
|
||||
#if CONFIG_NONFREE
|
||||
"This version of %s has nonfree parts compiled in.\n"
|
||||
"Therefore it is not legally redistributable.\n",
|
||||
program_name
|
||||
#elif CONFIG_GPLV3
|
||||
"%s is free software; you can redistribute it and/or modify\n"
|
||||
"it under the terms of the GNU General Public License as published by\n"
|
||||
"the Free Software Foundation; either version 3 of the License, or\n"
|
||||
"(at your option) any later version.\n"
|
||||
"\n"
|
||||
"%s is distributed in the hope that it will be useful,\n"
|
||||
"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
|
||||
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
|
||||
"GNU General Public License for more details.\n"
|
||||
"\n"
|
||||
"You should have received a copy of the GNU General Public License\n"
|
||||
"along with %s. If not, see <http://www.gnu.org/licenses/>.\n",
|
||||
program_name, program_name, program_name
|
||||
#elif CONFIG_GPL
|
||||
"%s is free software; you can redistribute it and/or modify\n"
|
||||
"it under the terms of the GNU General Public License as published by\n"
|
||||
"the Free Software Foundation; either version 2 of the License, or\n"
|
||||
"(at your option) any later version.\n"
|
||||
"\n"
|
||||
"%s is distributed in the hope that it will be useful,\n"
|
||||
"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
|
||||
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
|
||||
"GNU General Public License for more details.\n"
|
||||
"\n"
|
||||
"You should have received a copy of the GNU General Public License\n"
|
||||
"along with %s; if not, write to the Free Software\n"
|
||||
"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
|
||||
program_name, program_name, program_name
|
||||
#elif CONFIG_LGPLV3
|
||||
"%s is free software; you can redistribute it and/or modify\n"
|
||||
"it under the terms of the GNU Lesser General Public License as published by\n"
|
||||
"the Free Software Foundation; either version 3 of the License, or\n"
|
||||
"(at your option) any later version.\n"
|
||||
"\n"
|
||||
"%s is distributed in the hope that it will be useful,\n"
|
||||
"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
|
||||
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
|
||||
"GNU Lesser General Public License for more details.\n"
|
||||
"\n"
|
||||
"You should have received a copy of the GNU Lesser General Public License\n"
|
||||
"along with %s. If not, see <http://www.gnu.org/licenses/>.\n",
|
||||
program_name, program_name, program_name
|
||||
#else
|
||||
"%s is free software; you can redistribute it and/or\n"
|
||||
"modify it under the terms of the GNU Lesser General Public\n"
|
||||
"License as published by the Free Software Foundation; either\n"
|
||||
"version 2.1 of the License, or (at your option) any later version.\n"
|
||||
"\n"
|
||||
"%s is distributed in the hope that it will be useful,\n"
|
||||
"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
|
||||
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n"
|
||||
"Lesser General Public License for more details.\n"
|
||||
"\n"
|
||||
"You should have received a copy of the GNU Lesser General Public\n"
|
||||
"License along with %s; if not, write to the Free Software\n"
|
||||
"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
|
||||
program_name, program_name, program_name
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
void list_fmts(void (*get_fmt_string)(char *buf, int buf_size, int fmt), int nb_fmts)
|
||||
{
|
||||
int i;
|
||||
char fmt_str[128];
|
||||
for (i=-1; i < nb_fmts; i++) {
|
||||
get_fmt_string (fmt_str, sizeof(fmt_str), i);
|
||||
fprintf(stdout, "%s\n", fmt_str);
|
||||
}
|
||||
}
|
||||
|
||||
void show_formats(void)
|
||||
{
|
||||
AVInputFormat *ifmt=NULL;
|
||||
AVOutputFormat *ofmt=NULL;
|
||||
const char *last_name;
|
||||
|
||||
printf(
|
||||
"File formats:\n"
|
||||
" D. = Demuxing supported\n"
|
||||
" .E = Muxing supported\n"
|
||||
" --\n");
|
||||
last_name= "000";
|
||||
for(;;){
|
||||
int decode=0;
|
||||
int encode=0;
|
||||
const char *name=NULL;
|
||||
const char *long_name=NULL;
|
||||
|
||||
while((ofmt= av_oformat_next(ofmt))) {
|
||||
if((name == NULL || strcmp(ofmt->name, name)<0) &&
|
||||
strcmp(ofmt->name, last_name)>0){
|
||||
name= ofmt->name;
|
||||
long_name= ofmt->long_name;
|
||||
encode=1;
|
||||
}
|
||||
}
|
||||
while((ifmt= av_iformat_next(ifmt))) {
|
||||
if((name == NULL || strcmp(ifmt->name, name)<0) &&
|
||||
strcmp(ifmt->name, last_name)>0){
|
||||
name= ifmt->name;
|
||||
long_name= ifmt->long_name;
|
||||
encode=0;
|
||||
}
|
||||
if(name && strcmp(ifmt->name, name)==0)
|
||||
decode=1;
|
||||
}
|
||||
if(name==NULL)
|
||||
break;
|
||||
last_name= name;
|
||||
|
||||
printf(
|
||||
" %s%s %-15s %s\n",
|
||||
decode ? "D":" ",
|
||||
encode ? "E":" ",
|
||||
name,
|
||||
long_name ? long_name:" ");
|
||||
}
|
||||
}
|
||||
|
||||
void show_codecs(void)
|
||||
{
|
||||
AVCodec *p=NULL, *p2;
|
||||
const char *last_name;
|
||||
printf(
|
||||
"Codecs:\n"
|
||||
" D..... = Decoding supported\n"
|
||||
" .E.... = Encoding supported\n"
|
||||
" ..V... = Video codec\n"
|
||||
" ..A... = Audio codec\n"
|
||||
" ..S... = Subtitle codec\n"
|
||||
" ...S.. = Supports draw_horiz_band\n"
|
||||
" ....D. = Supports direct rendering method 1\n"
|
||||
" .....T = Supports weird frame truncation\n"
|
||||
" ------\n");
|
||||
last_name= "000";
|
||||
for(;;){
|
||||
int decode=0;
|
||||
int encode=0;
|
||||
int cap=0;
|
||||
const char *type_str;
|
||||
|
||||
p2=NULL;
|
||||
while((p= av_codec_next(p))) {
|
||||
if((p2==NULL || strcmp(p->name, p2->name)<0) &&
|
||||
strcmp(p->name, last_name)>0){
|
||||
p2= p;
|
||||
decode= encode= cap=0;
|
||||
}
|
||||
if(p2 && strcmp(p->name, p2->name)==0){
|
||||
if(p->decode) decode=1;
|
||||
if(p->encode) encode=1;
|
||||
cap |= p->capabilities;
|
||||
}
|
||||
}
|
||||
if(p2==NULL)
|
||||
break;
|
||||
last_name= p2->name;
|
||||
|
||||
switch(p2->type) {
|
||||
case AVMEDIA_TYPE_VIDEO:
|
||||
type_str = "V";
|
||||
break;
|
||||
case AVMEDIA_TYPE_AUDIO:
|
||||
type_str = "A";
|
||||
break;
|
||||
case AVMEDIA_TYPE_SUBTITLE:
|
||||
type_str = "S";
|
||||
break;
|
||||
default:
|
||||
type_str = "?";
|
||||
break;
|
||||
}
|
||||
printf(
|
||||
" %s%s%s%s%s%s %-15s %s",
|
||||
decode ? "D": (/*p2->decoder ? "d":*/" "),
|
||||
encode ? "E":" ",
|
||||
type_str,
|
||||
cap & CODEC_CAP_DRAW_HORIZ_BAND ? "S":" ",
|
||||
cap & CODEC_CAP_DR1 ? "D":" ",
|
||||
cap & CODEC_CAP_TRUNCATED ? "T":" ",
|
||||
p2->name,
|
||||
p2->long_name ? p2->long_name : "");
|
||||
/* if(p2->decoder && decode==0)
|
||||
printf(" use %s for decoding", p2->decoder->name);*/
|
||||
printf("\n");
|
||||
}
|
||||
printf("\n");
|
||||
printf(
|
||||
"Note, the names of encoders and decoders do not always match, so there are\n"
|
||||
"several cases where the above table shows encoder only or decoder only entries\n"
|
||||
"even though both encoding and decoding are supported. For example, the h263\n"
|
||||
"decoder corresponds to the h263 and h263p encoders, for file formats it is even\n"
|
||||
"worse.\n");
|
||||
}
|
||||
|
||||
void show_bsfs(void)
|
||||
{
|
||||
AVBitStreamFilter *bsf=NULL;
|
||||
|
||||
printf("Bitstream filters:\n");
|
||||
while((bsf = av_bitstream_filter_next(bsf)))
|
||||
printf("%s\n", bsf->name);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void show_protocols(void)
|
||||
{
|
||||
URLProtocol *up=NULL;
|
||||
|
||||
printf("Supported file protocols:\n");
|
||||
while((up = av_protocol_next(up)))
|
||||
printf("%s\n", up->name);
|
||||
}
|
||||
|
||||
void show_filters(void)
|
||||
{
|
||||
AVFilter av_unused(**filter) = NULL;
|
||||
|
||||
printf("Filters:\n");
|
||||
#if CONFIG_AVFILTER
|
||||
while ((filter = av_filter_next(filter)) && *filter)
|
||||
printf("%-16s %s\n", (*filter)->name, (*filter)->description);
|
||||
#endif
|
||||
}
|
||||
|
||||
void show_pix_fmts(void)
|
||||
{
|
||||
enum PixelFormat pix_fmt;
|
||||
|
||||
printf(
|
||||
"Pixel formats:\n"
|
||||
"I.... = Supported Input format for conversion\n"
|
||||
".O... = Supported Output format for conversion\n"
|
||||
"..H.. = Hardware accelerated format\n"
|
||||
"...P. = Paletted format\n"
|
||||
"....B = Bitstream format\n"
|
||||
"FLAGS NAME NB_COMPONENTS BITS_PER_PIXEL\n"
|
||||
"-----\n");
|
||||
|
||||
#if !CONFIG_SWSCALE
|
||||
# define sws_isSupportedInput(x) 0
|
||||
# define sws_isSupportedOutput(x) 0
|
||||
#endif
|
||||
|
||||
for (pix_fmt = 0; pix_fmt < PIX_FMT_NB; pix_fmt++) {
|
||||
const AVPixFmtDescriptor *pix_desc = &av_pix_fmt_descriptors[pix_fmt];
|
||||
printf("%c%c%c%c%c %-16s %d %2d\n",
|
||||
sws_isSupportedInput (pix_fmt) ? 'I' : '.',
|
||||
sws_isSupportedOutput(pix_fmt) ? 'O' : '.',
|
||||
pix_desc->flags & PIX_FMT_HWACCEL ? 'H' : '.',
|
||||
pix_desc->flags & PIX_FMT_PAL ? 'P' : '.',
|
||||
pix_desc->flags & PIX_FMT_BITSTREAM ? 'B' : '.',
|
||||
pix_desc->name,
|
||||
pix_desc->nb_components,
|
||||
av_get_bits_per_pixel(pix_desc));
|
||||
}
|
||||
}
|
||||
|
||||
int read_yesno(void)
|
||||
{
|
||||
int c = getchar();
|
||||
int yesno = (toupper(c) == 'Y');
|
||||
|
||||
while (c != '\n' && c != EOF)
|
||||
c = getchar();
|
||||
|
||||
return yesno;
|
||||
}
|
||||
|
||||
int read_file(const char *filename, char **bufptr, size_t *size)
|
||||
{
|
||||
FILE *f = fopen(filename, "rb");
|
||||
|
||||
if (!f) {
|
||||
fprintf(stderr, "Cannot read file '%s': %s\n", filename, strerror(errno));
|
||||
return AVERROR(errno);
|
||||
}
|
||||
fseek(f, 0, SEEK_END);
|
||||
*size = ftell(f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
*bufptr = av_malloc(*size + 1);
|
||||
if (!*bufptr) {
|
||||
fprintf(stderr, "Could not allocate file buffer\n");
|
||||
fclose(f);
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
fread(*bufptr, 1, *size, f);
|
||||
(*bufptr)[*size++] = '\0';
|
||||
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
223
cmdutils.h
Normal file
223
cmdutils.h
Normal file
@@ -0,0 +1,223 @@
|
||||
/*
|
||||
* Various utilities for command line tools
|
||||
* copyright (c) 2003 Fabrice Bellard
|
||||
*
|
||||
* 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 FFMPEG_CMDUTILS_H
|
||||
#define FFMPEG_CMDUTILS_H
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "libavcodec/avcodec.h"
|
||||
#include "libavformat/avformat.h"
|
||||
#include "libswscale/swscale.h"
|
||||
|
||||
/**
|
||||
* program name, defined by the program for show_version().
|
||||
*/
|
||||
extern const char program_name[];
|
||||
|
||||
/**
|
||||
* program birth year, defined by the program for show_banner()
|
||||
*/
|
||||
extern const int program_birth_year;
|
||||
|
||||
extern const int this_year;
|
||||
|
||||
extern const char **opt_names;
|
||||
extern AVCodecContext *avcodec_opts[AVMEDIA_TYPE_NB];
|
||||
extern AVFormatContext *avformat_opts;
|
||||
extern struct SwsContext *sws_opts;
|
||||
|
||||
/**
|
||||
* Fallback for options that are not explicitly handled, these will be
|
||||
* parsed through AVOptions.
|
||||
*/
|
||||
int opt_default(const char *opt, const char *arg);
|
||||
|
||||
/**
|
||||
* Sets the libav* libraries log level.
|
||||
*/
|
||||
int opt_loglevel(const char *opt, const char *arg);
|
||||
|
||||
/**
|
||||
* Limit the execution time.
|
||||
*/
|
||||
int opt_timelimit(const char *opt, const char *arg);
|
||||
|
||||
/**
|
||||
* Parses a string and returns its corresponding value as a double.
|
||||
* Exits from the application if the string cannot be correctly
|
||||
* parsed or the corresponding value is invalid.
|
||||
*
|
||||
* @param context the context of the value to be set (e.g. the
|
||||
* corresponding commandline option name)
|
||||
* @param numstr the string to be parsed
|
||||
* @param type the type (OPT_INT64 or OPT_FLOAT) as which the
|
||||
* string should be parsed
|
||||
* @param min the minimum valid accepted value
|
||||
* @param max the maximum valid accepted value
|
||||
*/
|
||||
double parse_number_or_die(const char *context, const char *numstr, int type, double min, double max);
|
||||
|
||||
/**
|
||||
* Parses a string specifying a time and returns its corresponding
|
||||
* value as a number of microseconds. Exits from the application if
|
||||
* the string cannot be correctly parsed.
|
||||
*
|
||||
* @param context the context of the value to be set (e.g. the
|
||||
* corresponding commandline option name)
|
||||
* @param timestr the string to be parsed
|
||||
* @param is_duration a flag which tells how to interpret timestr, if
|
||||
* not zero timestr is interpreted as a duration, otherwise as a
|
||||
* date
|
||||
*
|
||||
* @see parse_date()
|
||||
*/
|
||||
int64_t parse_time_or_die(const char *context, const char *timestr, int is_duration);
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
int flags;
|
||||
#define HAS_ARG 0x0001
|
||||
#define OPT_BOOL 0x0002
|
||||
#define OPT_EXPERT 0x0004
|
||||
#define OPT_STRING 0x0008
|
||||
#define OPT_VIDEO 0x0010
|
||||
#define OPT_AUDIO 0x0020
|
||||
#define OPT_GRAB 0x0040
|
||||
#define OPT_INT 0x0080
|
||||
#define OPT_FLOAT 0x0100
|
||||
#define OPT_SUBTITLE 0x0200
|
||||
#define OPT_FUNC2 0x0400
|
||||
#define OPT_INT64 0x0800
|
||||
#define OPT_EXIT 0x1000
|
||||
union {
|
||||
void (*func_arg)(const char *); //FIXME passing error code as int return would be nicer then exit() in the func
|
||||
int *int_arg;
|
||||
char **str_arg;
|
||||
float *float_arg;
|
||||
int (*func2_arg)(const char *, const char *);
|
||||
int64_t *int64_arg;
|
||||
} u;
|
||||
const char *help;
|
||||
const char *argname;
|
||||
} OptionDef;
|
||||
|
||||
void show_help_options(const OptionDef *options, const char *msg, int mask, int value);
|
||||
|
||||
/**
|
||||
* Parses the command line arguments.
|
||||
* @param options Array with the definitions required to interpret every
|
||||
* option of the form: -<option_name> [<argument>]
|
||||
* @param parse_arg_function Name of the function called to process every
|
||||
* argument without a leading option name flag. NULL if such arguments do
|
||||
* not have to be processed.
|
||||
*/
|
||||
void parse_options(int argc, char **argv, const OptionDef *options,
|
||||
void (* parse_arg_function)(const char*));
|
||||
|
||||
void set_context_opts(void *ctx, void *opts_ctx, int flags);
|
||||
|
||||
/**
|
||||
* Prints an error message to stderr, indicating filename and a human
|
||||
* readable description of the error code err.
|
||||
*
|
||||
* If strerror_r() is not available the use of this function in a
|
||||
* multithreaded application may be unsafe.
|
||||
*
|
||||
* @see av_strerror()
|
||||
*/
|
||||
void print_error(const char *filename, int err);
|
||||
|
||||
void list_fmts(void (*get_fmt_string)(char *buf, int buf_size, int fmt), int nb_fmts);
|
||||
|
||||
/**
|
||||
* Prints the program banner to stderr. The banner contents depend on the
|
||||
* current version of the repository and of the libav* libraries used by
|
||||
* the program.
|
||||
*/
|
||||
void show_banner(void);
|
||||
|
||||
/**
|
||||
* Prints the version of the program to stdout. The version message
|
||||
* depends on the current versions of the repository and of the libav*
|
||||
* libraries.
|
||||
*/
|
||||
void show_version(void);
|
||||
|
||||
/**
|
||||
* Prints the license of the program to stdout. The license depends on
|
||||
* the license of the libraries compiled into the program.
|
||||
*/
|
||||
void show_license(void);
|
||||
|
||||
/**
|
||||
* Prints a listing containing all the formats supported by the
|
||||
* program.
|
||||
*/
|
||||
void show_formats(void);
|
||||
|
||||
/**
|
||||
* Prints a listing containing all the codecs supported by the
|
||||
* program.
|
||||
*/
|
||||
void show_codecs(void);
|
||||
|
||||
/**
|
||||
* Prints a listing containing all the filters supported by the
|
||||
* program.
|
||||
*/
|
||||
void show_filters(void);
|
||||
|
||||
/**
|
||||
* Prints a listing containing all the bit stream filters supported by the
|
||||
* program.
|
||||
*/
|
||||
void show_bsfs(void);
|
||||
|
||||
/**
|
||||
* Prints a listing containing all the protocols supported by the
|
||||
* program.
|
||||
*/
|
||||
void show_protocols(void);
|
||||
|
||||
/**
|
||||
* Prints a listing containing all the pixel formats supported by the
|
||||
* program.
|
||||
*/
|
||||
void show_pix_fmts(void);
|
||||
|
||||
/**
|
||||
* Returns a positive value if reads from standard input a line
|
||||
* starting with [yY], otherwise returns 0.
|
||||
*/
|
||||
int read_yesno(void);
|
||||
|
||||
/**
|
||||
* Reads the file with name filename, and puts its content in a newly
|
||||
* allocated 0-terminated buffer.
|
||||
*
|
||||
* @param bufptr puts here the pointer to the newly allocated buffer
|
||||
* @param size puts here the size of the newly allocated buffer
|
||||
* @return 0 in case of success, a negative value corresponding to an
|
||||
* AVERROR error code in case of failure.
|
||||
*/
|
||||
int read_file(const char *filename, char **bufptr, size_t *size);
|
||||
|
||||
#endif /* FFMPEG_CMDUTILS_H */
|
||||
13
cmdutils_common_opts.h
Normal file
13
cmdutils_common_opts.h
Normal file
@@ -0,0 +1,13 @@
|
||||
{ "L", OPT_EXIT, {(void*)show_license}, "show license" },
|
||||
{ "h", OPT_EXIT, {(void*)show_help}, "show help" },
|
||||
{ "?", OPT_EXIT, {(void*)show_help}, "show help" },
|
||||
{ "help", OPT_EXIT, {(void*)show_help}, "show help" },
|
||||
{ "-help", OPT_EXIT, {(void*)show_help}, "show help" },
|
||||
{ "version", OPT_EXIT, {(void*)show_version}, "show version" },
|
||||
{ "formats" , OPT_EXIT, {(void*)show_formats }, "show available formats" },
|
||||
{ "codecs" , OPT_EXIT, {(void*)show_codecs }, "show available codecs" },
|
||||
{ "bsfs" , OPT_EXIT, {(void*)show_bsfs }, "show available bit stream filters" },
|
||||
{ "protocols", OPT_EXIT, {(void*)show_protocols}, "show available protocols" },
|
||||
{ "filters", OPT_EXIT, {(void*)show_filters }, "show available filters" },
|
||||
{ "pix_fmts" , OPT_EXIT, {(void*)show_pix_fmts }, "show available pixel formats" },
|
||||
{ "loglevel", HAS_ARG | OPT_FUNC2, {(void*)opt_loglevel}, "set libav* logging level", "loglevel" },
|
||||
109
common.mak
Normal file
109
common.mak
Normal file
@@ -0,0 +1,109 @@
|
||||
#
|
||||
# common bits used by all libraries
|
||||
#
|
||||
|
||||
# first so "all" becomes default target
|
||||
all: all-yes
|
||||
|
||||
ifndef SUBDIR
|
||||
vpath %.c $(SRC_DIR)
|
||||
vpath %.h $(SRC_DIR)
|
||||
vpath %.S $(SRC_DIR)
|
||||
vpath %.asm $(SRC_DIR)
|
||||
vpath %.v $(SRC_DIR)
|
||||
|
||||
ifeq ($(SRC_DIR),$(SRC_PATH_BARE))
|
||||
BUILD_ROOT_REL = .
|
||||
else
|
||||
BUILD_ROOT_REL = ..
|
||||
endif
|
||||
|
||||
ifndef V
|
||||
Q = @
|
||||
ECHO = printf "$(1)\t%s\n" $(2)
|
||||
BRIEF = CC AS YASM AR LD HOSTCC STRIP CP
|
||||
SILENT = DEPCC YASMDEP RM RANLIB
|
||||
MSG = $@
|
||||
M = @$(call ECHO,$(TAG),$@);
|
||||
$(foreach VAR,$(BRIEF), \
|
||||
$(eval $(VAR) = @$$(call ECHO,$(VAR),$$(MSG)); $($(VAR))))
|
||||
$(foreach VAR,$(SILENT),$(eval $(VAR) = @$($(VAR))))
|
||||
$(eval INSTALL = @$(call ECHO,INSTALL,$$(^:$(SRC_DIR)/%=%)); $(INSTALL))
|
||||
endif
|
||||
|
||||
ALLFFLIBS = avcodec avdevice avfilter avformat avutil postproc swscale
|
||||
|
||||
CPPFLAGS := -I$(BUILD_ROOT_REL) -I$(SRC_PATH) $(CPPFLAGS)
|
||||
CFLAGS += $(ECFLAGS)
|
||||
|
||||
%.o: %.c
|
||||
$(CCDEP)
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) $(CC_DEPFLAGS) -c $(CC_O) $<
|
||||
|
||||
%.o: %.S
|
||||
$(ASDEP)
|
||||
$(AS) $(CPPFLAGS) $(ASFLAGS) $(AS_DEPFLAGS) -c -o $@ $<
|
||||
|
||||
%.ho: %.h
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) -Wno-unused -c -o $@ -x c $<
|
||||
|
||||
%$(EXESUF): %.c
|
||||
|
||||
%.ver: %.v
|
||||
$(Q)sed 's/$$MAJOR/$($(basename $(@F))_VERSION_MAJOR)/' $^ > $@
|
||||
|
||||
%.c %.h: TAG = GEN
|
||||
|
||||
install: install-libs install-headers
|
||||
install-libs: install-libs-yes
|
||||
|
||||
uninstall: uninstall-libs uninstall-headers
|
||||
|
||||
.PHONY: all depend dep *clean install* uninstall* examples testprogs
|
||||
|
||||
# Disable suffix rules. Most of the builtin rules are suffix rules,
|
||||
# so this saves some time on slow systems.
|
||||
.SUFFIXES:
|
||||
|
||||
# Do not delete intermediate files from chains of implicit rules
|
||||
$(OBJS):
|
||||
endif
|
||||
|
||||
OBJS-$(HAVE_MMX) += $(MMX-OBJS-yes)
|
||||
|
||||
CFLAGS += $(CFLAGS-yes)
|
||||
OBJS += $(OBJS-yes)
|
||||
FFLIBS := $(FFLIBS-yes) $(FFLIBS)
|
||||
TESTPROGS += $(TESTPROGS-yes)
|
||||
|
||||
FFEXTRALIBS := $(addprefix -l,$(addsuffix $(BUILDSUF),$(FFLIBS))) $(EXTRALIBS)
|
||||
FFLDFLAGS := $(addprefix -L$(BUILD_ROOT)/lib,$(ALLFFLIBS)) $(LDFLAGS)
|
||||
|
||||
EXAMPLES := $(addprefix $(SUBDIR),$(addsuffix -example$(EXESUF),$(EXAMPLES)))
|
||||
OBJS := $(addprefix $(SUBDIR),$(sort $(OBJS)))
|
||||
TESTOBJS := $(addprefix $(SUBDIR),$(TESTOBJS))
|
||||
TESTPROGS := $(addprefix $(SUBDIR),$(addsuffix -test$(EXESUF),$(TESTPROGS)))
|
||||
HOSTOBJS := $(addprefix $(SUBDIR),$(addsuffix .o,$(HOSTPROGS)))
|
||||
HOSTPROGS := $(addprefix $(SUBDIR),$(addsuffix $(HOSTEXESUF),$(HOSTPROGS)))
|
||||
|
||||
DEP_LIBS := $(foreach NAME,$(FFLIBS),$(BUILD_ROOT_REL)/lib$(NAME)/$($(CONFIG_SHARED:yes=S)LIBNAME))
|
||||
|
||||
ALLHEADERS := $(subst $(SRC_DIR)/,$(SUBDIR),$(wildcard $(SRC_DIR)/*.h $(SRC_DIR)/$(ARCH)/*.h))
|
||||
SKIPHEADERS += $(addprefix $(ARCH)/,$(ARCH_HEADERS))
|
||||
SKIPHEADERS := $(addprefix $(SUBDIR),$(SKIPHEADERS-) $(SKIPHEADERS))
|
||||
checkheaders: $(filter-out $(SKIPHEADERS:.h=.ho),$(ALLHEADERS:.h=.ho))
|
||||
|
||||
$(HOSTOBJS): %.o: %.c
|
||||
$(HOSTCC) $(HOSTCFLAGS) -c -o $@ $<
|
||||
|
||||
$(HOSTPROGS): %$(HOSTEXESUF): %.o
|
||||
$(HOSTCC) $(HOSTLDFLAGS) -o $@ $< $(HOSTLIBS)
|
||||
|
||||
DEPS := $(OBJS:.o=.d)
|
||||
depend dep: $(DEPS)
|
||||
|
||||
CLEANSUFFIXES = *.d *.o *~ *.ho *.map *.ver
|
||||
DISTCLEANSUFFIXES = *.pc
|
||||
LIBSUFFIXES = *.a *.lib *.so *.so.* *.dylib *.dll *.def *.dll.a *.exp
|
||||
|
||||
-include $(wildcard $(DEPS))
|
||||
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Work around the class() function in AIX math.h clashing with
|
||||
* identifiers named "class".
|
||||
*
|
||||
* 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_AIX_MATH_H
|
||||
#define COMPAT_AIX_MATH_H
|
||||
|
||||
#define class class_in_math_h_causes_problems
|
||||
|
||||
#include_next <math.h>
|
||||
|
||||
#undef class
|
||||
|
||||
#endif /* COMPAT_AIX_MATH_H */
|
||||
@@ -1,176 +0,0 @@
|
||||
/*
|
||||
* 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_DUMMY_STDATOMIC_H
|
||||
#define COMPAT_ATOMICS_DUMMY_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_thread_fence(order) \
|
||||
((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;
|
||||
|
||||
#define atomic_store(object, desired) \
|
||||
do { \
|
||||
*(object) = (desired); \
|
||||
} while (0)
|
||||
|
||||
#define atomic_store_explicit(object, desired, order) \
|
||||
atomic_store(object, desired)
|
||||
|
||||
#define atomic_load(object) \
|
||||
(*(object))
|
||||
|
||||
#define atomic_load_explicit(object, order) \
|
||||
atomic_load(object)
|
||||
|
||||
static inline intptr_t atomic_exchange(intptr_t *object, intptr_t desired)
|
||||
{
|
||||
intptr_t ret = *object;
|
||||
*object = desired;
|
||||
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;
|
||||
if (*object == *expected) {
|
||||
*object = desired;
|
||||
ret = 1;
|
||||
} else {
|
||||
*expected = *object;
|
||||
ret = 0;
|
||||
}
|
||||
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; \
|
||||
ret = *object; \
|
||||
*object = *object op operand; \
|
||||
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_DUMMY_STDATOMIC_H */
|
||||
@@ -1,180 +0,0 @@
|
||||
/*
|
||||
* 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_WIN32_STDATOMIC_H
|
||||
#define COMPAT_ATOMICS_WIN32_STDATOMIC_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <windows.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) \
|
||||
MemoryBarrier();
|
||||
|
||||
#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;
|
||||
|
||||
#define atomic_store(object, desired) \
|
||||
do { \
|
||||
*(object) = (desired); \
|
||||
MemoryBarrier(); \
|
||||
} while (0)
|
||||
|
||||
#define atomic_store_explicit(object, desired, order) \
|
||||
atomic_store(object, desired)
|
||||
|
||||
#define atomic_load(object) \
|
||||
(MemoryBarrier(), *(object))
|
||||
|
||||
#define atomic_load_explicit(object, order) \
|
||||
atomic_load(object)
|
||||
|
||||
#define atomic_exchange(object, desired) \
|
||||
InterlockedExchangePointer((PVOID volatile *)object, (PVOID)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)InterlockedCompareExchangePointer(
|
||||
(PVOID *)object, (PVOID)desired, (PVOID)old);
|
||||
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)
|
||||
|
||||
#ifdef _WIN64
|
||||
#define atomic_fetch_add(object, operand) \
|
||||
InterlockedExchangeAdd64(object, operand)
|
||||
|
||||
#define atomic_fetch_sub(object, operand) \
|
||||
InterlockedExchangeAdd64(object, -(operand))
|
||||
|
||||
#define atomic_fetch_or(object, operand) \
|
||||
InterlockedOr64(object, operand)
|
||||
|
||||
#define atomic_fetch_xor(object, operand) \
|
||||
InterlockedXor64(object, operand)
|
||||
|
||||
#define atomic_fetch_and(object, operand) \
|
||||
InterlockedAnd64(object, operand)
|
||||
#else
|
||||
#define atomic_fetch_add(object, operand) \
|
||||
InterlockedExchangeAdd(object, operand)
|
||||
|
||||
#define atomic_fetch_sub(object, operand) \
|
||||
InterlockedExchangeAdd(object, -(operand))
|
||||
|
||||
#define atomic_fetch_or(object, operand) \
|
||||
InterlockedOr(object, operand)
|
||||
|
||||
#define atomic_fetch_xor(object, operand) \
|
||||
InterlockedXor(object, operand)
|
||||
|
||||
#define atomic_fetch_and(object, operand) \
|
||||
InterlockedAnd(object, operand)
|
||||
#endif /* _WIN64 */
|
||||
|
||||
#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_WIN32_STDATOMIC_H */
|
||||
@@ -1,195 +0,0 @@
|
||||
/*
|
||||
* Minimum CUDA compatibility definitions header
|
||||
*
|
||||
* Copyright (c) 2019 rcombs
|
||||
*
|
||||
* 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_CUDA_CUDA_RUNTIME_H
|
||||
#define COMPAT_CUDA_CUDA_RUNTIME_H
|
||||
|
||||
// Common macros
|
||||
#define __global__ __attribute__((global))
|
||||
#define __device__ __attribute__((device))
|
||||
#define __device_builtin__ __attribute__((device_builtin))
|
||||
#define __align__(N) __attribute__((aligned(N)))
|
||||
#define __inline__ __inline__ __attribute__((always_inline))
|
||||
|
||||
#define max(a, b) ((a) > (b) ? (a) : (b))
|
||||
#define min(a, b) ((a) < (b) ? (a) : (b))
|
||||
#define abs(x) ((x) < 0 ? -(x) : (x))
|
||||
|
||||
#define atomicAdd(a, b) (__atomic_fetch_add(a, b, __ATOMIC_SEQ_CST))
|
||||
|
||||
// Basic typedefs
|
||||
typedef __device_builtin__ unsigned long long cudaTextureObject_t;
|
||||
|
||||
typedef struct __device_builtin__ __align__(2) uchar2
|
||||
{
|
||||
unsigned char x, y;
|
||||
} uchar2;
|
||||
|
||||
typedef struct __device_builtin__ __align__(4) ushort2
|
||||
{
|
||||
unsigned short x, y;
|
||||
} ushort2;
|
||||
|
||||
typedef struct __device_builtin__ __align__(8) float2
|
||||
{
|
||||
float x, y;
|
||||
} float2;
|
||||
|
||||
typedef struct __device_builtin__ __align__(8) int2
|
||||
{
|
||||
int x, y;
|
||||
} int2;
|
||||
|
||||
typedef struct __device_builtin__ uint3
|
||||
{
|
||||
unsigned int x, y, z;
|
||||
} uint3;
|
||||
|
||||
typedef struct uint3 dim3;
|
||||
|
||||
typedef struct __device_builtin__ __align__(4) uchar4
|
||||
{
|
||||
unsigned char x, y, z, w;
|
||||
} uchar4;
|
||||
|
||||
typedef struct __device_builtin__ __align__(8) ushort4
|
||||
{
|
||||
unsigned short x, y, z, w;
|
||||
} ushort4;
|
||||
|
||||
typedef struct __device_builtin__ __align__(16) int4
|
||||
{
|
||||
int x, y, z, w;
|
||||
} int4;
|
||||
|
||||
typedef struct __device_builtin__ __align__(16) float4
|
||||
{
|
||||
float x, y, z, w;
|
||||
} float4;
|
||||
|
||||
// Accessors for special registers
|
||||
#define GETCOMP(reg, comp) \
|
||||
asm("mov.u32 %0, %%" #reg "." #comp ";" : "=r"(tmp)); \
|
||||
ret.comp = tmp;
|
||||
|
||||
#define GET(name, reg) static inline __device__ uint3 name() {\
|
||||
uint3 ret; \
|
||||
unsigned tmp; \
|
||||
GETCOMP(reg, x) \
|
||||
GETCOMP(reg, y) \
|
||||
GETCOMP(reg, z) \
|
||||
return ret; \
|
||||
}
|
||||
|
||||
GET(getBlockIdx, ctaid)
|
||||
GET(getBlockDim, ntid)
|
||||
GET(getThreadIdx, tid)
|
||||
|
||||
// Instead of externs for these registers, we turn access to them into calls into trivial ASM
|
||||
#define blockIdx (getBlockIdx())
|
||||
#define blockDim (getBlockDim())
|
||||
#define threadIdx (getThreadIdx())
|
||||
|
||||
// Basic initializers (simple macros rather than inline functions)
|
||||
#define make_int2(a, b) ((int2){.x = a, .y = b})
|
||||
#define make_uchar2(a, b) ((uchar2){.x = a, .y = b})
|
||||
#define make_ushort2(a, b) ((ushort2){.x = a, .y = b})
|
||||
#define make_float2(a, b) ((float2){.x = a, .y = b})
|
||||
#define make_int4(a, b, c, d) ((int4){.x = a, .y = b, .z = c, .w = d})
|
||||
#define make_uchar4(a, b, c, d) ((uchar4){.x = a, .y = b, .z = c, .w = d})
|
||||
#define make_ushort4(a, b, c, d) ((ushort4){.x = a, .y = b, .z = c, .w = d})
|
||||
#define make_float4(a, b, c, d) ((float4){.x = a, .y = b, .z = c, .w = d})
|
||||
|
||||
// Conversions from the tex instruction's 4-register output to various types
|
||||
#define TEX2D(type, ret) static inline __device__ void conv(type* out, unsigned a, unsigned b, unsigned c, unsigned d) {*out = (ret);}
|
||||
|
||||
TEX2D(unsigned char, a & 0xFF)
|
||||
TEX2D(unsigned short, a & 0xFFFF)
|
||||
TEX2D(float, a)
|
||||
TEX2D(uchar2, make_uchar2(a & 0xFF, b & 0xFF))
|
||||
TEX2D(ushort2, make_ushort2(a & 0xFFFF, b & 0xFFFF))
|
||||
TEX2D(float2, make_float2(a, b))
|
||||
TEX2D(uchar4, make_uchar4(a & 0xFF, b & 0xFF, c & 0xFF, d & 0xFF))
|
||||
TEX2D(ushort4, make_ushort4(a & 0xFFFF, b & 0xFFFF, c & 0xFFFF, d & 0xFFFF))
|
||||
TEX2D(float4, make_float4(a, b, c, d))
|
||||
|
||||
// Template calling tex instruction and converting the output to the selected type
|
||||
template<typename T>
|
||||
inline __device__ T tex2D(cudaTextureObject_t texObject, float x, float y)
|
||||
{
|
||||
T ret;
|
||||
unsigned ret1, ret2, ret3, ret4;
|
||||
asm("tex.2d.v4.u32.f32 {%0, %1, %2, %3}, [%4, {%5, %6}];" :
|
||||
"=r"(ret1), "=r"(ret2), "=r"(ret3), "=r"(ret4) :
|
||||
"l"(texObject), "f"(x), "f"(y));
|
||||
conv(&ret, ret1, ret2, ret3, ret4);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline __device__ float4 tex2D<float4>(cudaTextureObject_t texObject, float x, float y)
|
||||
{
|
||||
float4 ret;
|
||||
asm("tex.2d.v4.f32.f32 {%0, %1, %2, %3}, [%4, {%5, %6}];" :
|
||||
"=r"(ret.x), "=r"(ret.y), "=r"(ret.z), "=r"(ret.w) :
|
||||
"l"(texObject), "f"(x), "f"(y));
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline __device__ float tex2D<float>(cudaTextureObject_t texObject, float x, float y)
|
||||
{
|
||||
return tex2D<float4>(texObject, x, y).x;
|
||||
}
|
||||
|
||||
template<>
|
||||
inline __device__ float2 tex2D<float2>(cudaTextureObject_t texObject, float x, float y)
|
||||
{
|
||||
float4 ret = tex2D<float4>(texObject, x, y);
|
||||
return make_float2(ret.x, ret.y);
|
||||
}
|
||||
|
||||
// Math helper functions
|
||||
static inline __device__ float floorf(float a) { return __builtin_floorf(a); }
|
||||
static inline __device__ float floor(float a) { return __builtin_floorf(a); }
|
||||
static inline __device__ double floor(double a) { return __builtin_floor(a); }
|
||||
static inline __device__ float ceilf(float a) { return __builtin_ceilf(a); }
|
||||
static inline __device__ float ceil(float a) { return __builtin_ceilf(a); }
|
||||
static inline __device__ double ceil(double a) { return __builtin_ceil(a); }
|
||||
static inline __device__ float truncf(float a) { return __builtin_truncf(a); }
|
||||
static inline __device__ float trunc(float a) { return __builtin_truncf(a); }
|
||||
static inline __device__ double trunc(double a) { return __builtin_trunc(a); }
|
||||
static inline __device__ float fabsf(float a) { return __builtin_fabsf(a); }
|
||||
static inline __device__ float fabs(float a) { return __builtin_fabsf(a); }
|
||||
static inline __device__ double fabs(double a) { return __builtin_fabs(a); }
|
||||
static inline __device__ float sqrtf(float a) { return __builtin_sqrtf(a); }
|
||||
|
||||
static inline __device__ float __saturatef(float a) { return __nvvm_saturate_f(a); }
|
||||
static inline __device__ float __sinf(float a) { return __nvvm_sin_approx_f(a); }
|
||||
static inline __device__ float __cosf(float a) { return __nvvm_cos_approx_f(a); }
|
||||
static inline __device__ float __expf(float a) { return __nvvm_ex2_approx_f(a * (float)__builtin_log2(__builtin_exp(1))); }
|
||||
static inline __device__ float __powf(float a, float b) { return __nvvm_ex2_approx_f(__nvvm_lg2_approx_f(a) * b); }
|
||||
|
||||
// Misc helper functions
|
||||
extern "C" __device__ int printf(const char*, ...);
|
||||
|
||||
#endif /* COMPAT_CUDA_CUDA_RUNTIME_H */
|
||||
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* 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_CUDA_DYNLINK_LOADER_H
|
||||
#define COMPAT_CUDA_DYNLINK_LOADER_H
|
||||
|
||||
#include "libavutil/log.h"
|
||||
#include "compat/w32dlfcn.h"
|
||||
|
||||
#define FFNV_LOAD_FUNC(path) dlopen((path), RTLD_LAZY)
|
||||
#define FFNV_SYM_FUNC(lib, sym) dlsym((lib), (sym))
|
||||
#define FFNV_FREE_FUNC(lib) dlclose(lib)
|
||||
#define FFNV_LOG_FUNC(logctx, msg, ...) av_log(logctx, AV_LOG_ERROR, msg, __VA_ARGS__)
|
||||
#define FFNV_DEBUG_LOG_FUNC(logctx, msg, ...) av_log(logctx, AV_LOG_DEBUG, msg, __VA_ARGS__)
|
||||
|
||||
#include <ffnvcodec/dynlink_loader.h>
|
||||
|
||||
#endif /* COMPAT_CUDA_DYNLINK_LOADER_H */
|
||||
@@ -1,42 +0,0 @@
|
||||
/*
|
||||
* 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_DISPATCH_SEMAPHORE_SEMAPHORE_H
|
||||
#define COMPAT_DISPATCH_SEMAPHORE_SEMAPHORE_H
|
||||
|
||||
#include <dispatch/dispatch.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define sem_t dispatch_semaphore_t
|
||||
#define sem_post(psem) dispatch_semaphore_signal(*psem)
|
||||
#define sem_wait(psem) dispatch_semaphore_wait(*psem, DISPATCH_TIME_FOREVER)
|
||||
#define sem_timedwait(psem, val) dispatch_semaphore_wait(*psem, dispatch_walltime(val, 0))
|
||||
#define sem_destroy(psem) dispatch_release(*psem)
|
||||
|
||||
static inline int compat_sem_init(dispatch_semaphore_t *psem,
|
||||
int unused, int val)
|
||||
{
|
||||
int ret = !!(*psem = dispatch_semaphore_create(val)) - 1;
|
||||
if (ret < 0)
|
||||
errno = ENOMEM;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define sem_init compat_sem_init
|
||||
|
||||
#endif /* COMPAT_DISPATCH_SEMAPHORE_SEMAPHORE_H */
|
||||
@@ -1,47 +0,0 @@
|
||||
/*
|
||||
* 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 <math.h>
|
||||
|
||||
#define FUN(name, type, op) \
|
||||
type name(type x, type y) \
|
||||
{ \
|
||||
if (fpclassify(x) == FP_NAN) return y; \
|
||||
if (fpclassify(y) == FP_NAN) return x; \
|
||||
return x op y ? x : y; \
|
||||
}
|
||||
|
||||
FUN(fmin, double, <)
|
||||
FUN(fmax, double, >)
|
||||
FUN(fminf, float, <)
|
||||
FUN(fmaxf, float, >)
|
||||
|
||||
long double fmodl(long double x, long double y)
|
||||
{
|
||||
return fmod(x, y);
|
||||
}
|
||||
|
||||
long double scalbnl(long double x, int exp)
|
||||
{
|
||||
return scalbn(x, exp);
|
||||
}
|
||||
|
||||
long double copysignl(long double x, long double y)
|
||||
{
|
||||
return copysign(x, y);
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
double fmin(double, double);
|
||||
double fmax(double, double);
|
||||
float fminf(float, float);
|
||||
float fmaxf(float, float);
|
||||
long double fmodl(long double, long double);
|
||||
long double scalbnl(long double, int);
|
||||
long double copysignl(long double, long double);
|
||||
@@ -1,35 +0,0 @@
|
||||
/*
|
||||
* Work around broken floating point limits on some systems.
|
||||
*
|
||||
* 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_next <float.h>
|
||||
|
||||
#ifdef FLT_MAX
|
||||
#undef FLT_MAX
|
||||
#define FLT_MAX 3.40282346638528859812e+38F
|
||||
|
||||
#undef FLT_MIN
|
||||
#define FLT_MIN 1.17549435082228750797e-38F
|
||||
|
||||
#undef DBL_MAX
|
||||
#define DBL_MAX ((double)1.79769313486231570815e+308L)
|
||||
|
||||
#undef DBL_MIN
|
||||
#define DBL_MIN ((double)2.22507385850720138309e-308L)
|
||||
#endif
|
||||
@@ -1,22 +0,0 @@
|
||||
/*
|
||||
* Work around broken floating point limits on some systems.
|
||||
*
|
||||
* 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_next <limits.h>
|
||||
#include <float.h>
|
||||
@@ -1,84 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file was copied from the following newsgroup posting:
|
||||
*
|
||||
* Newsgroups: mod.std.unix
|
||||
* Subject: public domain AT&T getopt source
|
||||
* Date: 3 Nov 85 19:34:15 GMT
|
||||
*
|
||||
* Here's something you've all been waiting for: the AT&T public domain
|
||||
* source for getopt(3). It is the code which was given out at the 1985
|
||||
* UNIFORUM conference in Dallas. I obtained it by electronic mail
|
||||
* directly from AT&T. The people there assure me that it is indeed
|
||||
* in the public domain.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
static int opterr = 1;
|
||||
static int optind = 1;
|
||||
static int optopt;
|
||||
static char *optarg;
|
||||
|
||||
static int getopt(int argc, char *argv[], char *opts)
|
||||
{
|
||||
static int sp = 1;
|
||||
int c;
|
||||
char *cp;
|
||||
|
||||
if (sp == 1) {
|
||||
if (optind >= argc ||
|
||||
argv[optind][0] != '-' || argv[optind][1] == '\0')
|
||||
return EOF;
|
||||
else if (!strcmp(argv[optind], "--")) {
|
||||
optind++;
|
||||
return EOF;
|
||||
}
|
||||
}
|
||||
optopt = c = argv[optind][sp];
|
||||
if (c == ':' || !(cp = strchr(opts, c))) {
|
||||
fprintf(stderr, ": illegal option -- %c\n", c);
|
||||
if (argv[optind][++sp] == '\0') {
|
||||
optind++;
|
||||
sp = 1;
|
||||
}
|
||||
return '?';
|
||||
}
|
||||
if (*++cp == ':') {
|
||||
if (argv[optind][sp+1] != '\0')
|
||||
optarg = &argv[optind++][sp+1];
|
||||
else if(++optind >= argc) {
|
||||
fprintf(stderr, ": option requires an argument -- %c\n", c);
|
||||
sp = 1;
|
||||
return '?';
|
||||
} else
|
||||
optarg = argv[optind++];
|
||||
sp = 1;
|
||||
} else {
|
||||
if (argv[optind][++sp] == '\0') {
|
||||
sp = 1;
|
||||
optind++;
|
||||
}
|
||||
optarg = NULL;
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
* C99-compatible snprintf() and vsnprintf() implementations
|
||||
* Copyright (c) 2012 Ronald S. Bultje <rsbultje@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
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "compat/va_copy.h"
|
||||
#include "libavutil/error.h"
|
||||
|
||||
#if defined(__MINGW32__)
|
||||
#define EOVERFLOW EFBIG
|
||||
#endif
|
||||
|
||||
int avpriv_snprintf(char *s, size_t n, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int ret;
|
||||
|
||||
va_start(ap, fmt);
|
||||
ret = avpriv_vsnprintf(s, n, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int avpriv_vsnprintf(char *s, size_t n, const char *fmt,
|
||||
va_list ap)
|
||||
{
|
||||
int ret;
|
||||
va_list ap_copy;
|
||||
|
||||
if (n == 0)
|
||||
return _vscprintf(fmt, ap);
|
||||
else if (n > INT_MAX)
|
||||
return AVERROR(EOVERFLOW);
|
||||
|
||||
/* we use n - 1 here because if the buffer is not big enough, the MS
|
||||
* runtime libraries don't add a terminating zero at the end. MSDN
|
||||
* recommends to provide _snprintf/_vsnprintf() a buffer size that
|
||||
* is one less than the actual buffer, and zero it before calling
|
||||
* _snprintf/_vsnprintf() to workaround this problem.
|
||||
* See https://web.archive.org/web/20151214111935/http://msdn.microsoft.com/en-us/library/1kt27hek(v=vs.80).aspx */
|
||||
memset(s, 0, n);
|
||||
va_copy(ap_copy, ap);
|
||||
ret = _vsnprintf(s, n - 1, fmt, ap_copy);
|
||||
va_end(ap_copy);
|
||||
if (ret == -1)
|
||||
ret = _vscprintf(fmt, ap);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
/*
|
||||
* C99-compatible snprintf() and vsnprintf() implementations
|
||||
* Copyright (c) 2012 Ronald S. Bultje <rsbultje@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
|
||||
*/
|
||||
|
||||
#ifndef COMPAT_MSVCRT_SNPRINTF_H
|
||||
#define COMPAT_MSVCRT_SNPRINTF_H
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int avpriv_snprintf(char *s, size_t n, const char *fmt, ...);
|
||||
int avpriv_vsnprintf(char *s, size_t n, const char *fmt, va_list ap);
|
||||
|
||||
#undef snprintf
|
||||
#undef _snprintf
|
||||
#undef vsnprintf
|
||||
#define snprintf avpriv_snprintf
|
||||
#define _snprintf avpriv_snprintf
|
||||
#define vsnprintf avpriv_vsnprintf
|
||||
|
||||
#endif /* COMPAT_MSVCRT_SNPRINTF_H */
|
||||
@@ -1,229 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011-2017 KO Myung-Hun <komh@chollian.net>
|
||||
*
|
||||
* 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
|
||||
* os2threads to pthreads wrapper
|
||||
*/
|
||||
|
||||
#ifndef COMPAT_OS2THREADS_H
|
||||
#define COMPAT_OS2THREADS_H
|
||||
|
||||
#define INCL_DOS
|
||||
#define INCL_DOSERRORS
|
||||
#include <os2.h>
|
||||
|
||||
#undef __STRICT_ANSI__ /* for _beginthread() */
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <sys/builtin.h>
|
||||
#include <sys/fmutex.h>
|
||||
|
||||
#include "libavutil/attributes.h"
|
||||
#include "libavutil/common.h"
|
||||
#include "libavutil/time.h"
|
||||
|
||||
typedef struct {
|
||||
TID tid;
|
||||
void *(*start_routine)(void *);
|
||||
void *arg;
|
||||
void *result;
|
||||
} pthread_t;
|
||||
|
||||
typedef void pthread_attr_t;
|
||||
|
||||
typedef _fmutex pthread_mutex_t;
|
||||
typedef void pthread_mutexattr_t;
|
||||
|
||||
#define PTHREAD_MUTEX_INITIALIZER _FMUTEX_INITIALIZER
|
||||
|
||||
typedef struct {
|
||||
HEV event_sem;
|
||||
HEV ack_sem;
|
||||
volatile unsigned wait_count;
|
||||
} pthread_cond_t;
|
||||
|
||||
typedef void pthread_condattr_t;
|
||||
|
||||
typedef struct {
|
||||
volatile int done;
|
||||
_fmutex mtx;
|
||||
} pthread_once_t;
|
||||
|
||||
#define PTHREAD_ONCE_INIT {0, _FMUTEX_INITIALIZER}
|
||||
|
||||
static void thread_entry(void *arg)
|
||||
{
|
||||
pthread_t *thread = arg;
|
||||
|
||||
thread->result = thread->start_routine(thread->arg);
|
||||
}
|
||||
|
||||
static av_always_inline int pthread_create(pthread_t *thread,
|
||||
const pthread_attr_t *attr,
|
||||
void *(*start_routine)(void*),
|
||||
void *arg)
|
||||
{
|
||||
thread->start_routine = start_routine;
|
||||
thread->arg = arg;
|
||||
thread->result = NULL;
|
||||
|
||||
thread->tid = _beginthread(thread_entry, NULL, 1024 * 1024, thread);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static av_always_inline int pthread_join(pthread_t thread, void **value_ptr)
|
||||
{
|
||||
DosWaitThread(&thread.tid, DCWW_WAIT);
|
||||
|
||||
if (value_ptr)
|
||||
*value_ptr = thread.result;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static av_always_inline int pthread_mutex_init(pthread_mutex_t *mutex,
|
||||
const pthread_mutexattr_t *attr)
|
||||
{
|
||||
_fmutex_create(mutex, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static av_always_inline int pthread_mutex_destroy(pthread_mutex_t *mutex)
|
||||
{
|
||||
_fmutex_close(mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static av_always_inline int pthread_mutex_lock(pthread_mutex_t *mutex)
|
||||
{
|
||||
_fmutex_request(mutex, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static av_always_inline int pthread_mutex_unlock(pthread_mutex_t *mutex)
|
||||
{
|
||||
_fmutex_release(mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static av_always_inline int pthread_cond_init(pthread_cond_t *cond,
|
||||
const pthread_condattr_t *attr)
|
||||
{
|
||||
DosCreateEventSem(NULL, &cond->event_sem, DCE_POSTONE, FALSE);
|
||||
DosCreateEventSem(NULL, &cond->ack_sem, DCE_POSTONE, FALSE);
|
||||
|
||||
cond->wait_count = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static av_always_inline int pthread_cond_destroy(pthread_cond_t *cond)
|
||||
{
|
||||
DosCloseEventSem(cond->event_sem);
|
||||
DosCloseEventSem(cond->ack_sem);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static av_always_inline int pthread_cond_signal(pthread_cond_t *cond)
|
||||
{
|
||||
if (!__atomic_cmpxchg32(&cond->wait_count, 0, 0)) {
|
||||
DosPostEventSem(cond->event_sem);
|
||||
DosWaitEventSem(cond->ack_sem, SEM_INDEFINITE_WAIT);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static av_always_inline int pthread_cond_broadcast(pthread_cond_t *cond)
|
||||
{
|
||||
while (!__atomic_cmpxchg32(&cond->wait_count, 0, 0))
|
||||
pthread_cond_signal(cond);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static av_always_inline int pthread_cond_timedwait(pthread_cond_t *cond,
|
||||
pthread_mutex_t *mutex,
|
||||
const struct timespec *abstime)
|
||||
{
|
||||
int64_t abs_milli = abstime->tv_sec * 1000LL + abstime->tv_nsec / 1000000;
|
||||
ULONG t = av_clip64(abs_milli - av_gettime() / 1000, 0, ULONG_MAX);
|
||||
|
||||
__atomic_increment(&cond->wait_count);
|
||||
|
||||
pthread_mutex_unlock(mutex);
|
||||
|
||||
APIRET ret = DosWaitEventSem(cond->event_sem, t);
|
||||
|
||||
__atomic_decrement(&cond->wait_count);
|
||||
|
||||
DosPostEventSem(cond->ack_sem);
|
||||
|
||||
pthread_mutex_lock(mutex);
|
||||
|
||||
return (ret == ERROR_TIMEOUT) ? ETIMEDOUT : 0;
|
||||
}
|
||||
|
||||
static av_always_inline int pthread_cond_wait(pthread_cond_t *cond,
|
||||
pthread_mutex_t *mutex)
|
||||
{
|
||||
__atomic_increment(&cond->wait_count);
|
||||
|
||||
pthread_mutex_unlock(mutex);
|
||||
|
||||
DosWaitEventSem(cond->event_sem, SEM_INDEFINITE_WAIT);
|
||||
|
||||
__atomic_decrement(&cond->wait_count);
|
||||
|
||||
DosPostEventSem(cond->ack_sem);
|
||||
|
||||
pthread_mutex_lock(mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static av_always_inline int pthread_once(pthread_once_t *once_control,
|
||||
void (*init_routine)(void))
|
||||
{
|
||||
if (!once_control->done)
|
||||
{
|
||||
_fmutex_request(&once_control->mtx, 0);
|
||||
|
||||
if (!once_control->done)
|
||||
{
|
||||
init_routine();
|
||||
|
||||
once_control->done = 1;
|
||||
}
|
||||
|
||||
_fmutex_release(&once_control->mtx);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* COMPAT_OS2THREADS_H */
|
||||
@@ -1,352 +0,0 @@
|
||||
#!/usr/bin/env perl
|
||||
|
||||
# make_sunver.pl
|
||||
#
|
||||
# Copyright (C) 2010, 2011, 2012, 2013
|
||||
# Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 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
|
||||
# General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; see the file COPYING.GPLv3. If not see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
|
||||
# This script takes at least two arguments, a GNU style version script and
|
||||
# a list of object and archive files, and generates a corresponding Sun
|
||||
# style version script as follows:
|
||||
#
|
||||
# Each glob pattern, C++ mangled pattern or literal in the input script is
|
||||
# matched against all global symbols in the input objects, emitting those
|
||||
# that matched (or nothing if no match was found).
|
||||
# A comment with the original pattern and its type is left in the output
|
||||
# file to make it easy to understand the matches.
|
||||
#
|
||||
# It uses elfdump when present (native), GNU readelf otherwise.
|
||||
# It depends on the GNU version of c++filt, since it must understand the
|
||||
# GNU mangling style.
|
||||
|
||||
use FileHandle;
|
||||
use IPC::Open2;
|
||||
|
||||
# Enforce C locale.
|
||||
$ENV{'LC_ALL'} = "C";
|
||||
$ENV{'LANG'} = "C";
|
||||
|
||||
# Input version script, GNU style.
|
||||
my $symvers = shift;
|
||||
|
||||
##########
|
||||
# Get all the symbols from the library, match them, and add them to a hash.
|
||||
|
||||
my %sym_hash = ();
|
||||
|
||||
# List of objects and archives to process.
|
||||
my @OBJECTS = ();
|
||||
|
||||
# List of shared objects to omit from processing.
|
||||
my @SHAREDOBJS = ();
|
||||
|
||||
# Filter out those input archives that have corresponding shared objects to
|
||||
# avoid adding all symbols matched in the archive to the output map.
|
||||
foreach $file (@ARGV) {
|
||||
if (($so = $file) =~ s/\.a$/.so/ && -e $so) {
|
||||
printf STDERR "omitted $file -> $so\n";
|
||||
push (@SHAREDOBJS, $so);
|
||||
} else {
|
||||
push (@OBJECTS, $file);
|
||||
}
|
||||
}
|
||||
|
||||
# We need to detect and ignore hidden symbols. Solaris nm can only detect
|
||||
# this in the harder to parse default output format, and GNU nm not at all,
|
||||
# so use elfdump -s in the native case and GNU readelf -s otherwise.
|
||||
# GNU objdump -t cannot be used since it produces a variable number of
|
||||
# columns.
|
||||
|
||||
# The path to elfdump.
|
||||
my $elfdump = "/usr/ccs/bin/elfdump";
|
||||
|
||||
if (-f $elfdump) {
|
||||
open ELFDUMP,$elfdump.' -s '.(join ' ',@OBJECTS).'|' or die $!;
|
||||
my $skip_arsym = 0;
|
||||
|
||||
while (<ELFDUMP>) {
|
||||
chomp;
|
||||
|
||||
# Ignore empty lines.
|
||||
if (/^$/) {
|
||||
# End of archive symbol table, stop skipping.
|
||||
$skip_arsym = 0 if $skip_arsym;
|
||||
next;
|
||||
}
|
||||
|
||||
# Keep skipping until end of archive symbol table.
|
||||
next if ($skip_arsym);
|
||||
|
||||
# Ignore object name header for individual objects and archives.
|
||||
next if (/:$/);
|
||||
|
||||
# Ignore table header lines.
|
||||
next if (/^Symbol Table Section:/);
|
||||
next if (/index.*value.*size/);
|
||||
|
||||
# Start of archive symbol table: start skipping.
|
||||
if (/^Symbol Table: \(archive/) {
|
||||
$skip_arsym = 1;
|
||||
next;
|
||||
}
|
||||
|
||||
# Split table.
|
||||
(undef, undef, undef, undef, $bind, $oth, undef, $shndx, $name) = split;
|
||||
|
||||
# Error out for unknown input.
|
||||
die "unknown input line:\n$_" unless defined($bind);
|
||||
|
||||
# Ignore local symbols.
|
||||
next if ($bind eq "LOCL");
|
||||
# Ignore hidden symbols.
|
||||
next if ($oth eq "H");
|
||||
# Ignore undefined symbols.
|
||||
next if ($shndx eq "UNDEF");
|
||||
# Error out for unhandled cases.
|
||||
if ($bind !~ /^(GLOB|WEAK)/ or $oth ne "D") {
|
||||
die "unhandled symbol:\n$_";
|
||||
}
|
||||
|
||||
# Remember symbol.
|
||||
$sym_hash{$name}++;
|
||||
}
|
||||
close ELFDUMP or die "$elfdump error";
|
||||
} else {
|
||||
open READELF, 'readelf -s -W '.(join ' ',@OBJECTS).'|' or die $!;
|
||||
# Process each symbol.
|
||||
while (<READELF>) {
|
||||
chomp;
|
||||
|
||||
# Ignore empty lines.
|
||||
next if (/^$/);
|
||||
|
||||
# Ignore object name header.
|
||||
next if (/^File: .*$/);
|
||||
|
||||
# Ignore table header lines.
|
||||
next if (/^Symbol table.*contains.*:/);
|
||||
next if (/Num:.*Value.*Size/);
|
||||
|
||||
# Split table.
|
||||
(undef, undef, undef, undef, $bind, $vis, $ndx, $name) = split;
|
||||
|
||||
# Error out for unknown input.
|
||||
die "unknown input line:\n$_" unless defined($bind);
|
||||
|
||||
# Ignore local symbols.
|
||||
next if ($bind eq "LOCAL");
|
||||
# Ignore hidden symbols.
|
||||
next if ($vis eq "HIDDEN");
|
||||
# Ignore undefined symbols.
|
||||
next if ($ndx eq "UND");
|
||||
# Error out for unhandled cases.
|
||||
if ($bind !~ /^(GLOBAL|WEAK)/ or $vis ne "DEFAULT") {
|
||||
die "unhandled symbol:\n$_";
|
||||
}
|
||||
|
||||
# Remember symbol.
|
||||
$sym_hash{$name}++;
|
||||
}
|
||||
close READELF or die "readelf error";
|
||||
}
|
||||
|
||||
##########
|
||||
# The various types of glob patterns.
|
||||
#
|
||||
# A glob pattern that is to be applied to the demangled name: 'cxx'.
|
||||
# A glob patterns that applies directly to the name in the .o files: 'glob'.
|
||||
# This pattern is ignored; used for local variables (usually just '*'): 'ign'.
|
||||
|
||||
# The type of the current pattern.
|
||||
my $glob = 'glob';
|
||||
|
||||
# We're currently inside `extern "C++"', which Sun ld doesn't understand.
|
||||
my $in_extern = 0;
|
||||
|
||||
# The c++filt command to use. This *must* be GNU c++filt; the Sun Studio
|
||||
# c++filt doesn't handle the GNU mangling style.
|
||||
my $cxxfilt = $ENV{'CXXFILT'} || "c++filt";
|
||||
|
||||
# The current version name.
|
||||
my $current_version = "";
|
||||
|
||||
# Was there any attempt to match a symbol to this version?
|
||||
my $matches_attempted;
|
||||
|
||||
# The number of versions which matched this symbol.
|
||||
my $matched_symbols;
|
||||
|
||||
open F,$symvers or die $!;
|
||||
|
||||
# Print information about generating this file
|
||||
print "# This file was generated by make_sunver.pl. DO NOT EDIT!\n";
|
||||
print "# It was generated by:\n";
|
||||
printf "# %s %s %s\n", $0, $symvers, (join ' ',@ARGV);
|
||||
printf "# Omitted archives with corresponding shared libraries: %s\n",
|
||||
(join ' ', @SHAREDOBJS) if $#SHAREDOBJS >= 0;
|
||||
print "#\n\n";
|
||||
|
||||
print "\$mapfile_version 2\n";
|
||||
|
||||
while (<F>) {
|
||||
# Lines of the form '};'
|
||||
if (/^([ \t]*)(\}[ \t]*;[ \t]*)$/) {
|
||||
$glob = 'glob';
|
||||
if ($in_extern) {
|
||||
$in_extern--;
|
||||
print "$1##$2\n";
|
||||
} else {
|
||||
print;
|
||||
}
|
||||
next;
|
||||
}
|
||||
|
||||
# Lines of the form '} SOME_VERSION_NAME_1.0;'
|
||||
if (/^[ \t]*\}[ \tA-Z0-9_.a-z]+;[ \t]*$/) {
|
||||
$glob = 'glob';
|
||||
# We tried to match symbols against this version, but none matched.
|
||||
# Emit dummy hidden symbol to avoid marking this version WEAK.
|
||||
if ($matches_attempted && $matched_symbols == 0) {
|
||||
print " hidden:\n";
|
||||
print " .force_WEAK_off_$current_version = DATA S0x0 V0x0;\n";
|
||||
}
|
||||
print; next;
|
||||
}
|
||||
|
||||
# Comment and blank lines
|
||||
if (/^[ \t]*\#/) { print; next; }
|
||||
if (/^[ \t]*$/) { print; next; }
|
||||
|
||||
# Lines of the form '{'
|
||||
if (/^([ \t]*){$/) {
|
||||
if ($in_extern) {
|
||||
print "$1##{\n";
|
||||
} else {
|
||||
print;
|
||||
}
|
||||
next;
|
||||
}
|
||||
|
||||
# Lines of the form 'SOME_VERSION_NAME_1.1 {'
|
||||
if (/^([A-Z0-9_.]+)[ \t]+{$/) {
|
||||
# Record version name.
|
||||
$current_version = $1;
|
||||
# Reset match attempts, #matched symbols for this version.
|
||||
$matches_attempted = 0;
|
||||
$matched_symbols = 0;
|
||||
print "SYMBOL_VERSION $1 {\n";
|
||||
next;
|
||||
}
|
||||
|
||||
# Ignore 'global:'
|
||||
if (/^[ \t]*global:$/) { print; next; }
|
||||
|
||||
# After 'local:', globs should be ignored, they won't be exported.
|
||||
if (/^[ \t]*local:$/) {
|
||||
$glob = 'ign';
|
||||
print;
|
||||
next;
|
||||
}
|
||||
|
||||
# After 'extern "C++"', globs are C++ patterns
|
||||
if (/^([ \t]*)(extern \"C\+\+\"[ \t]*)$/) {
|
||||
$in_extern++;
|
||||
$glob = 'cxx';
|
||||
# Need to comment, Sun ld cannot handle this.
|
||||
print "$1##$2\n"; next;
|
||||
}
|
||||
|
||||
# Chomp newline now we're done with passing through the input file.
|
||||
chomp;
|
||||
|
||||
# Catch globs. Note that '{}' is not allowed in globs by this script,
|
||||
# so only '*' and '[]' are available.
|
||||
if (/^([ \t]*)([^ \t;{}#]+);?[ \t]*$/) {
|
||||
my $ws = $1;
|
||||
my $ptn = $2;
|
||||
# Turn the glob into a regex by replacing '*' with '.*', '?' with '.'.
|
||||
# Keep $ptn so we can still print the original form.
|
||||
($pattern = $ptn) =~ s/\*/\.\*/g;
|
||||
$pattern =~ s/\?/\./g;
|
||||
|
||||
if ($glob eq 'ign') {
|
||||
# We're in a local: * section; just continue.
|
||||
print "$_\n";
|
||||
next;
|
||||
}
|
||||
|
||||
# Print the glob commented for human readers.
|
||||
print "$ws##$ptn ($glob)\n";
|
||||
# We tried to match a symbol to this version.
|
||||
$matches_attempted++;
|
||||
|
||||
if ($glob eq 'glob') {
|
||||
my %ptn_syms = ();
|
||||
|
||||
# Match ptn against symbols in %sym_hash.
|
||||
foreach my $sym (keys %sym_hash) {
|
||||
# Maybe it matches one of the patterns based on the symbol in
|
||||
# the .o file.
|
||||
$ptn_syms{$sym}++ if ($sym =~ /^$pattern$/);
|
||||
}
|
||||
|
||||
foreach my $sym (sort keys(%ptn_syms)) {
|
||||
$matched_symbols++;
|
||||
print "$ws$sym;\n";
|
||||
}
|
||||
} elsif ($glob eq 'cxx') {
|
||||
my %dem_syms = ();
|
||||
|
||||
# Verify that we're actually using GNU c++filt. Other versions
|
||||
# most likely cannot handle GNU style symbol mangling.
|
||||
my $cxxout = `$cxxfilt --version 2>&1`;
|
||||
$cxxout =~ m/GNU/ or die "$0 requires GNU c++filt to function";
|
||||
|
||||
# Talk to c++filt through a pair of file descriptors.
|
||||
# Need to start a fresh instance per pattern, otherwise the
|
||||
# process grows to 500+ MB.
|
||||
my $pid = open2(*FILTIN, *FILTOUT, $cxxfilt) or die $!;
|
||||
|
||||
# Match ptn against symbols in %sym_hash.
|
||||
foreach my $sym (keys %sym_hash) {
|
||||
# No? Well, maybe its demangled form matches one of those
|
||||
# patterns.
|
||||
printf FILTOUT "%s\n",$sym;
|
||||
my $dem = <FILTIN>;
|
||||
chomp $dem;
|
||||
$dem_syms{$sym}++ if ($dem =~ /^$pattern$/);
|
||||
}
|
||||
|
||||
close FILTOUT or die "c++filt error";
|
||||
close FILTIN or die "c++filt error";
|
||||
# Need to wait for the c++filt process to avoid lots of zombies.
|
||||
waitpid $pid, 0;
|
||||
|
||||
foreach my $sym (sort keys(%dem_syms)) {
|
||||
$matched_symbols++;
|
||||
print "$ws$sym;\n";
|
||||
}
|
||||
} else {
|
||||
# No? Well, then ignore it.
|
||||
}
|
||||
next;
|
||||
}
|
||||
# Important sanity check. This script can't handle lots of formats
|
||||
# that GNU ld can, so be sure to error out if one is seen!
|
||||
die "strange line `$_'";
|
||||
}
|
||||
close F;
|
||||
@@ -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__ */
|
||||
@@ -1,93 +0,0 @@
|
||||
/*
|
||||
* C99-compatible strtod() implementation
|
||||
* Copyright (c) 2012 Ronald S. Bultje <rsbultje@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
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "libavutil/avstring.h"
|
||||
#include "libavutil/mathematics.h"
|
||||
|
||||
static const char *check_nan_suffix(const char *s)
|
||||
{
|
||||
const char *start = s;
|
||||
|
||||
if (*s++ != '(')
|
||||
return start;
|
||||
|
||||
while ((*s >= 'a' && *s <= 'z') || (*s >= 'A' && *s <= 'Z') ||
|
||||
(*s >= '0' && *s <= '9') || *s == '_')
|
||||
s++;
|
||||
|
||||
return *s == ')' ? s + 1 : start;
|
||||
}
|
||||
|
||||
#undef strtod
|
||||
double strtod(const char *, char **);
|
||||
|
||||
double avpriv_strtod(const char *nptr, char **endptr)
|
||||
{
|
||||
const char *end;
|
||||
double res;
|
||||
|
||||
/* Skip leading spaces */
|
||||
while (av_isspace(*nptr))
|
||||
nptr++;
|
||||
|
||||
if (!av_strncasecmp(nptr, "infinity", 8)) {
|
||||
end = nptr + 8;
|
||||
res = INFINITY;
|
||||
} else if (!av_strncasecmp(nptr, "inf", 3)) {
|
||||
end = nptr + 3;
|
||||
res = INFINITY;
|
||||
} else if (!av_strncasecmp(nptr, "+infinity", 9)) {
|
||||
end = nptr + 9;
|
||||
res = INFINITY;
|
||||
} else if (!av_strncasecmp(nptr, "+inf", 4)) {
|
||||
end = nptr + 4;
|
||||
res = INFINITY;
|
||||
} else if (!av_strncasecmp(nptr, "-infinity", 9)) {
|
||||
end = nptr + 9;
|
||||
res = -INFINITY;
|
||||
} else if (!av_strncasecmp(nptr, "-inf", 4)) {
|
||||
end = nptr + 4;
|
||||
res = -INFINITY;
|
||||
} else if (!av_strncasecmp(nptr, "nan", 3)) {
|
||||
end = check_nan_suffix(nptr + 3);
|
||||
res = NAN;
|
||||
} else if (!av_strncasecmp(nptr, "+nan", 4) ||
|
||||
!av_strncasecmp(nptr, "-nan", 4)) {
|
||||
end = check_nan_suffix(nptr + 4);
|
||||
res = NAN;
|
||||
} else if (!av_strncasecmp(nptr, "0x", 2) ||
|
||||
!av_strncasecmp(nptr, "-0x", 3) ||
|
||||
!av_strncasecmp(nptr, "+0x", 3)) {
|
||||
/* FIXME this doesn't handle exponents, non-integers (float/double)
|
||||
* and numbers too large for long long */
|
||||
res = strtoll(nptr, (char **)&end, 16);
|
||||
} else {
|
||||
res = strtod(nptr, (char **)&end);
|
||||
}
|
||||
|
||||
if (endptr)
|
||||
*endptr = (char *)end;
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* MSVC Compatible va_copy macro
|
||||
* Copyright (c) 2012 Derek Buitenhuis
|
||||
*
|
||||
* 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_VA_COPY_H
|
||||
#define COMPAT_VA_COPY_H
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#if !defined(va_copy) && defined(_MSC_VER)
|
||||
#define va_copy(dst, src) ((dst) = (src))
|
||||
#endif
|
||||
#if !defined(va_copy) && defined(__GNUC__) && __GNUC__ < 3
|
||||
#define va_copy(dst, src) __va_copy(dst, src)
|
||||
#endif
|
||||
|
||||
#endif /* COMPAT_VA_COPY_H */
|
||||
@@ -1,151 +0,0 @@
|
||||
/*
|
||||
* 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_W32DLFCN_H
|
||||
#define COMPAT_W32DLFCN_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <stdint.h>
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#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)
|
||||
{
|
||||
wchar_t *path = NULL, *new_path;
|
||||
DWORD path_size = 0, path_len;
|
||||
|
||||
do {
|
||||
path_size = path_size ? FFMIN(2 * path_size, INT16_MAX + 1) : MAX_PATH;
|
||||
new_path = av_realloc_array(path, path_size, sizeof *path);
|
||||
if (!new_path) {
|
||||
av_free(path);
|
||||
return NULL;
|
||||
}
|
||||
path = new_path;
|
||||
// Returns path_size in case of insufficient buffer.
|
||||
// Whether the error is set or not and whether the output
|
||||
// is null-terminated or not depends on the version of Windows.
|
||||
path_len = GetModuleFileNameW(module, path, path_size);
|
||||
} while (path_len && path_size <= INT16_MAX && path_size <= path_len);
|
||||
|
||||
if (!path_len) {
|
||||
av_free(path);
|
||||
return NULL;
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Safe function used to open dynamic libs. This attempts to improve program security
|
||||
* by removing the current directory from the dll search path. Only dll's found in the
|
||||
* executable or system directory are allowed to be loaded.
|
||||
* @param name The dynamic lib name.
|
||||
* @return A handle to the opened lib.
|
||||
*/
|
||||
static inline HMODULE win32_dlopen(const char *name)
|
||||
{
|
||||
wchar_t *name_w;
|
||||
HMODULE module = NULL;
|
||||
if (utf8towchar(name, &name_w))
|
||||
name_w = NULL;
|
||||
#if _WIN32_WINNT < 0x0602
|
||||
// On Win7 and earlier we check if KB2533623 is available
|
||||
if (!GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "SetDefaultDllDirectories")) {
|
||||
wchar_t *path = NULL, *new_path;
|
||||
DWORD pathlen, pathsize, namelen;
|
||||
if (!name_w)
|
||||
goto exit;
|
||||
namelen = wcslen(name_w);
|
||||
// Try local directory first
|
||||
path = get_module_filename(NULL);
|
||||
if (!path)
|
||||
goto exit;
|
||||
new_path = wcsrchr(path, '\\');
|
||||
if (!new_path)
|
||||
goto exit;
|
||||
pathlen = new_path - path;
|
||||
pathsize = pathlen + namelen + 2;
|
||||
new_path = av_realloc_array(path, pathsize, sizeof *path);
|
||||
if (!new_path)
|
||||
goto exit;
|
||||
path = new_path;
|
||||
wcscpy(path + pathlen + 1, name_w);
|
||||
module = LoadLibraryExW(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
|
||||
if (module == NULL) {
|
||||
// Next try System32 directory
|
||||
pathlen = GetSystemDirectoryW(path, pathsize);
|
||||
if (!pathlen)
|
||||
goto exit;
|
||||
// Buffer is not enough in two cases:
|
||||
// 1. system directory + \ + module name
|
||||
// 2. system directory even without the module name.
|
||||
if (pathlen + namelen + 2 > pathsize) {
|
||||
pathsize = pathlen + namelen + 2;
|
||||
new_path = av_realloc_array(path, pathsize, sizeof *path);
|
||||
if (!new_path)
|
||||
goto exit;
|
||||
path = new_path;
|
||||
// Query again to handle the case #2.
|
||||
pathlen = GetSystemDirectoryW(path, pathsize);
|
||||
if (!pathlen)
|
||||
goto exit;
|
||||
}
|
||||
path[pathlen] = L'\\';
|
||||
wcscpy(path + pathlen + 1, name_w);
|
||||
module = LoadLibraryExW(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
|
||||
}
|
||||
exit:
|
||||
av_free(path);
|
||||
av_free(name_w);
|
||||
return module;
|
||||
}
|
||||
#endif
|
||||
#ifndef LOAD_LIBRARY_SEARCH_APPLICATION_DIR
|
||||
# define LOAD_LIBRARY_SEARCH_APPLICATION_DIR 0x00000200
|
||||
#endif
|
||||
#ifndef LOAD_LIBRARY_SEARCH_SYSTEM32
|
||||
# define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000800
|
||||
#endif
|
||||
#if HAVE_WINRT
|
||||
if (!name_w)
|
||||
return NULL;
|
||||
module = LoadPackagedLibrary(name_w, 0);
|
||||
#else
|
||||
#define LOAD_FLAGS (LOAD_LIBRARY_SEARCH_APPLICATION_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32)
|
||||
/* filename may be be in CP_ACP */
|
||||
if (!name_w)
|
||||
return LoadLibraryExA(name, NULL, LOAD_FLAGS);
|
||||
module = LoadLibraryExW(name_w, NULL, LOAD_FLAGS);
|
||||
#undef LOAD_FLAGS
|
||||
#endif
|
||||
av_free(name_w);
|
||||
return module;
|
||||
}
|
||||
#define dlopen(name, flags) win32_dlopen(name)
|
||||
#define dlclose FreeLibrary
|
||||
#define dlsym GetProcAddress
|
||||
#else
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
#endif /* COMPAT_W32DLFCN_H */
|
||||
@@ -1,212 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2011 x264 project
|
||||
*
|
||||
* Authors: Steven Walters <kemuri9@gmail.com>
|
||||
* Pegasys Inc. <http://www.pegasys-inc.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
|
||||
* w32threads to pthreads wrapper
|
||||
*/
|
||||
|
||||
#ifndef COMPAT_W32PTHREADS_H
|
||||
#define COMPAT_W32PTHREADS_H
|
||||
|
||||
/* Build up a pthread-like API using underlying Windows API. Have only static
|
||||
* methods so as to not conflict with a potentially linked in pthread-win32
|
||||
* library.
|
||||
* As most functions here are used without checking return values,
|
||||
* only implement return values as necessary. */
|
||||
|
||||
#include <windows.h>
|
||||
#include <process.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "libavutil/attributes.h"
|
||||
#include "libavutil/common.h"
|
||||
#include "libavutil/internal.h"
|
||||
#include "libavutil/mem.h"
|
||||
#include "libavutil/time.h"
|
||||
|
||||
typedef struct pthread_t {
|
||||
void *handle;
|
||||
void *(*func)(void* arg);
|
||||
void *arg;
|
||||
void *ret;
|
||||
} *pthread_t;
|
||||
|
||||
/* use light weight mutex/condition variable API for Windows Vista and later */
|
||||
typedef SRWLOCK pthread_mutex_t;
|
||||
typedef CONDITION_VARIABLE pthread_cond_t;
|
||||
|
||||
#define PTHREAD_MUTEX_INITIALIZER SRWLOCK_INIT
|
||||
#define PTHREAD_COND_INITIALIZER CONDITION_VARIABLE_INIT
|
||||
|
||||
#define InitializeCriticalSection(x) InitializeCriticalSectionEx(x, 0, 0)
|
||||
#define WaitForSingleObject(a, b) WaitForSingleObjectEx(a, b, FALSE)
|
||||
|
||||
#define PTHREAD_CANCEL_ENABLE 1
|
||||
#define PTHREAD_CANCEL_DISABLE 0
|
||||
|
||||
#if HAVE_WINRT
|
||||
#define THREADFUNC_RETTYPE DWORD
|
||||
#else
|
||||
#define THREADFUNC_RETTYPE unsigned
|
||||
#endif
|
||||
|
||||
static av_unused THREADFUNC_RETTYPE
|
||||
__stdcall attribute_align_arg win32thread_worker(void *arg)
|
||||
{
|
||||
pthread_t h = (pthread_t)arg;
|
||||
h->ret = h->func(h->arg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static av_unused int pthread_create(pthread_t *thread, const void *unused_attr,
|
||||
void *(*start_routine)(void*), void *arg)
|
||||
{
|
||||
pthread_t ret;
|
||||
|
||||
ret = av_mallocz(sizeof(*ret));
|
||||
if (!ret)
|
||||
return EAGAIN;
|
||||
|
||||
ret->func = start_routine;
|
||||
ret->arg = arg;
|
||||
#if HAVE_WINRT
|
||||
ret->handle = (void*)CreateThread(NULL, 0, win32thread_worker, ret,
|
||||
0, NULL);
|
||||
#else
|
||||
ret->handle = (void*)_beginthreadex(NULL, 0, win32thread_worker, ret,
|
||||
0, NULL);
|
||||
#endif
|
||||
|
||||
if (!ret->handle) {
|
||||
av_free(ret);
|
||||
return EAGAIN;
|
||||
}
|
||||
|
||||
*thread = ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static av_unused int pthread_join(pthread_t thread, void **value_ptr)
|
||||
{
|
||||
DWORD ret = WaitForSingleObject(thread->handle, INFINITE);
|
||||
if (ret != WAIT_OBJECT_0) {
|
||||
if (ret == WAIT_ABANDONED)
|
||||
return EINVAL;
|
||||
else
|
||||
return EDEADLK;
|
||||
}
|
||||
if (value_ptr)
|
||||
*value_ptr = thread->ret;
|
||||
CloseHandle(thread->handle);
|
||||
av_free(thread);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int pthread_mutex_init(pthread_mutex_t *m, void* attr)
|
||||
{
|
||||
InitializeSRWLock(m);
|
||||
return 0;
|
||||
}
|
||||
static inline int pthread_mutex_destroy(pthread_mutex_t *m)
|
||||
{
|
||||
/* Unlocked SWR locks use no resources */
|
||||
return 0;
|
||||
}
|
||||
static inline int pthread_mutex_lock(pthread_mutex_t *m)
|
||||
{
|
||||
AcquireSRWLockExclusive(m);
|
||||
return 0;
|
||||
}
|
||||
static inline int pthread_mutex_unlock(pthread_mutex_t *m)
|
||||
{
|
||||
ReleaseSRWLockExclusive(m);
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef INIT_ONCE pthread_once_t;
|
||||
#define PTHREAD_ONCE_INIT INIT_ONCE_STATIC_INIT
|
||||
|
||||
static av_unused int pthread_once(pthread_once_t *once_control, void (*init_routine)(void))
|
||||
{
|
||||
BOOL pending = FALSE;
|
||||
InitOnceBeginInitialize(once_control, 0, &pending, NULL);
|
||||
if (pending)
|
||||
init_routine();
|
||||
InitOnceComplete(once_control, 0, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int pthread_cond_init(pthread_cond_t *cond, const void *unused_attr)
|
||||
{
|
||||
InitializeConditionVariable(cond);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* native condition variables do not destroy */
|
||||
static inline int pthread_cond_destroy(pthread_cond_t *cond)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int pthread_cond_broadcast(pthread_cond_t *cond)
|
||||
{
|
||||
WakeAllConditionVariable(cond);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
|
||||
{
|
||||
SleepConditionVariableSRW(cond, mutex, INFINITE, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
|
||||
const struct timespec *abstime)
|
||||
{
|
||||
int64_t abs_milli = abstime->tv_sec * 1000LL + abstime->tv_nsec / 1000000;
|
||||
DWORD t = av_clip64(abs_milli - av_gettime() / 1000, 0, UINT32_MAX);
|
||||
|
||||
if (!SleepConditionVariableSRW(cond, mutex, t, 0)) {
|
||||
DWORD err = GetLastError();
|
||||
if (err == ERROR_TIMEOUT)
|
||||
return ETIMEDOUT;
|
||||
else
|
||||
return EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int pthread_cond_signal(pthread_cond_t *cond)
|
||||
{
|
||||
WakeConditionVariable(cond);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int pthread_setcancelstate(int state, int *oldstate)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* COMPAT_W32PTHREADS_H */
|
||||
@@ -1,129 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Copyright (c) 2013, Derek Buitenhuis
|
||||
#
|
||||
# Permission to use, copy, modify, and/or distribute this software for any
|
||||
# purpose with or without fee is hereby granted, provided that the above
|
||||
# copyright notice and this permission notice appear in all copies.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
# mktemp isn't POSIX, so supply an implementation
|
||||
mktemp() {
|
||||
echo "${2%%XXX*}.${HOSTNAME}.${UID}.$$"
|
||||
}
|
||||
|
||||
if [ $# -lt 2 ]; then
|
||||
echo "Usage: makedef <version_script> <objects>" >&2
|
||||
exit 0
|
||||
fi
|
||||
|
||||
vscript=$1
|
||||
shift
|
||||
|
||||
if [ ! -f "$vscript" ]; then
|
||||
echo "Version script does not exist" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for object in "$@"; do
|
||||
if [ ! -f "$object" ]; then
|
||||
echo "Object does not exist: ${object}" >&2
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
# Create a lib temporarily to dump symbols from.
|
||||
# It's just much easier to do it this way
|
||||
libname=$(mktemp -u "library").lib
|
||||
|
||||
trap 'rm -f -- $libname' EXIT
|
||||
|
||||
if [ -n "$AR" ]; then
|
||||
$AR rcs ${libname} $@ >/dev/null
|
||||
else
|
||||
lib.exe -out:${libname} $@ >/dev/null
|
||||
fi
|
||||
if [ $? != 0 ]; then
|
||||
echo "Could not create temporary library." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
IFS='
|
||||
'
|
||||
|
||||
prefix="$EXTERN_PREFIX"
|
||||
|
||||
started=0
|
||||
regex="none"
|
||||
|
||||
for line in $(cat ${vscript} | tr '\t' ' '); do
|
||||
# We only care about global symbols
|
||||
echo "${line}" | grep -q '^ \+global:'
|
||||
if [ $? = 0 ]; then
|
||||
started=1
|
||||
line=$(echo "${line}" | sed -e 's/^ \{1,\}global: *//')
|
||||
else
|
||||
echo "${line}" | grep -q '^ \+local:'
|
||||
if [ $? = 0 ]; then
|
||||
started=0
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ${started} = 0 ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
# Handle multiple symbols on one line
|
||||
IFS=';'
|
||||
|
||||
# Work around stupid expansion to filenames
|
||||
line=$(echo "${line}" | sed -e 's/\*/.\\+/g')
|
||||
for exp in ${line}; do
|
||||
# Remove leading and trailing whitespace
|
||||
exp=$(echo "${exp}" | sed -e 's/^ *//' -e 's/ *$//')
|
||||
|
||||
if [ "${regex}" = "none" ]; then
|
||||
regex="${exp}"
|
||||
else
|
||||
regex="${regex};${exp}"
|
||||
fi
|
||||
done
|
||||
|
||||
IFS='
|
||||
'
|
||||
done
|
||||
|
||||
if [ -n "$NM" ]; then
|
||||
# Use eval, since NM="nm -g"
|
||||
dump=$(eval "$NM --defined-only -g ${libname}" |
|
||||
grep -v : |
|
||||
grep -v ^$ |
|
||||
cut -d' ' -f3 |
|
||||
sed -e "s/^${prefix}//")
|
||||
else
|
||||
dump=$(dumpbin.exe -linkermember:1 ${libname} |
|
||||
sed -e '/public symbols/,$!d' -e '/^ \{1,\}Summary/,$d' -e "s/ \{1,\}${prefix}/ /" -e 's/ \{1,\}/ /g' |
|
||||
tail -n +2 |
|
||||
cut -d' ' -f3)
|
||||
fi
|
||||
|
||||
rm ${libname}
|
||||
|
||||
IFS=';'
|
||||
list=""
|
||||
for exp in ${regex}; do
|
||||
list="${list}"'
|
||||
'$(echo "${dump}" |
|
||||
grep "^${exp}" |
|
||||
sed -e 's/^/ /')
|
||||
done
|
||||
|
||||
echo "EXPORTS"
|
||||
echo "${list}" | sort | uniq | tail -n +2
|
||||
@@ -1,9 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
LINK_EXE_PATH=$(dirname "$(command -v cl)")/link
|
||||
if [ -x "$LINK_EXE_PATH" ]; then
|
||||
"$LINK_EXE_PATH" $@
|
||||
else
|
||||
link.exe $@
|
||||
fi
|
||||
exit $?
|
||||
@@ -1,32 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ "$1" = "--version" ]; then
|
||||
rc.exe -?
|
||||
exit $?
|
||||
fi
|
||||
|
||||
if [ $# -lt 2 ]; then
|
||||
echo "Usage: mswindres [-I/include/path ...] [-DSOME_DEFINE ...] [-o output.o] input.rc [output.o]" >&2
|
||||
exit 0
|
||||
fi
|
||||
|
||||
EXTRA_OPTS="-nologo"
|
||||
|
||||
while [ $# -gt 2 ]; do
|
||||
case $1 in
|
||||
-D*) EXTRA_OPTS="$EXTRA_OPTS -d$(echo $1 | sed -e "s/^..//" -e "s/ /\\\\ /g")" ;;
|
||||
-I*) EXTRA_OPTS="$EXTRA_OPTS -i$(echo $1 | sed -e "s/^..//" -e "s/ /\\\\ /g")" ;;
|
||||
-o) OPT_OUT="$2"; shift ;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
IN="$1"
|
||||
if [ -z "$OPT_OUT" ]; then
|
||||
OUT="$2"
|
||||
else
|
||||
OUT="$OPT_OUT"
|
||||
fi
|
||||
|
||||
eval set -- $EXTRA_OPTS
|
||||
rc.exe "$@" -fo "$OUT" "$IN"
|
||||
9
doc/.gitignore
vendored
9
doc/.gitignore
vendored
@@ -1,9 +0,0 @@
|
||||
/*.1
|
||||
/*.3
|
||||
/*.html
|
||||
/*.pod
|
||||
/config.texi
|
||||
/avoptions_codec.texi
|
||||
/avoptions_format.texi
|
||||
/fate.txt
|
||||
/print_options
|
||||
4350
doc/APIchanges
4350
doc/APIchanges
File diff suppressed because it is too large
Load Diff
2360
doc/Doxyfile
2360
doc/Doxyfile
File diff suppressed because it is too large
Load Diff
158
doc/Makefile
158
doc/Makefile
@@ -1,158 +0,0 @@
|
||||
LIBRARIES-$(CONFIG_AVUTIL) += libavutil
|
||||
LIBRARIES-$(CONFIG_SWSCALE) += libswscale
|
||||
LIBRARIES-$(CONFIG_SWRESAMPLE) += libswresample
|
||||
LIBRARIES-$(CONFIG_AVCODEC) += libavcodec
|
||||
LIBRARIES-$(CONFIG_AVFORMAT) += libavformat
|
||||
LIBRARIES-$(CONFIG_AVDEVICE) += libavdevice
|
||||
LIBRARIES-$(CONFIG_AVFILTER) += libavfilter
|
||||
|
||||
COMPONENTS-$(CONFIG_AVUTIL) += ffmpeg-utils
|
||||
COMPONENTS-$(CONFIG_SWSCALE) += ffmpeg-scaler
|
||||
COMPONENTS-$(CONFIG_SWRESAMPLE) += ffmpeg-resampler
|
||||
COMPONENTS-$(CONFIG_AVCODEC) += ffmpeg-codecs ffmpeg-bitstream-filters
|
||||
COMPONENTS-$(CONFIG_AVFORMAT) += ffmpeg-formats ffmpeg-protocols
|
||||
COMPONENTS-$(CONFIG_AVDEVICE) += ffmpeg-devices
|
||||
COMPONENTS-$(CONFIG_AVFILTER) += ffmpeg-filters
|
||||
|
||||
MANPAGES1 = $(AVPROGS-yes:%=doc/%.1) $(AVPROGS-yes:%=doc/%-all.1) $(COMPONENTS-yes:%=doc/%.1)
|
||||
MANPAGES3 = $(LIBRARIES-yes:%=doc/%.3)
|
||||
MANPAGES = $(MANPAGES1) $(MANPAGES3)
|
||||
PODPAGES = $(AVPROGS-yes:%=doc/%.pod) $(AVPROGS-yes:%=doc/%-all.pod) $(COMPONENTS-yes:%=doc/%.pod) $(LIBRARIES-yes:%=doc/%.pod)
|
||||
HTMLPAGES = $(AVPROGS-yes:%=doc/%.html) $(AVPROGS-yes:%=doc/%-all.html) $(COMPONENTS-yes:%=doc/%.html) $(LIBRARIES-yes:%=doc/%.html) \
|
||||
doc/community.html \
|
||||
doc/developer.html \
|
||||
doc/faq.html \
|
||||
doc/fate.html \
|
||||
doc/general.html \
|
||||
doc/git-howto.html \
|
||||
doc/mailing-list-faq.html \
|
||||
doc/nut.html \
|
||||
doc/platform.html \
|
||||
$(SRC_PATH)/doc/bootstrap.min.css \
|
||||
$(SRC_PATH)/doc/style.min.css \
|
||||
$(SRC_PATH)/doc/default.css \
|
||||
|
||||
TXTPAGES = doc/fate.txt \
|
||||
|
||||
|
||||
DOCS-$(CONFIG_HTMLPAGES) += $(HTMLPAGES)
|
||||
DOCS-$(CONFIG_PODPAGES) += $(PODPAGES)
|
||||
DOCS-$(CONFIG_MANPAGES) += $(MANPAGES)
|
||||
DOCS-$(CONFIG_TXTPAGES) += $(TXTPAGES)
|
||||
DOCS = $(DOCS-yes)
|
||||
|
||||
all-$(CONFIG_DOC): doc
|
||||
|
||||
doc: documentation
|
||||
|
||||
apidoc: doc/doxy/html
|
||||
documentation: $(DOCS)
|
||||
|
||||
TEXIDEP = perl $(SRC_PATH)/doc/texidep.pl $(SRC_PATH) $< $@ >$(@:%=%.d)
|
||||
|
||||
doc/%.txt: TAG = TXT
|
||||
doc/%.txt: doc/%.texi
|
||||
$(Q)$(TEXIDEP)
|
||||
$(M)makeinfo --force --no-headers -o $@ $< 2>/dev/null
|
||||
|
||||
GENTEXI = format codec
|
||||
GENTEXI := $(GENTEXI:%=doc/avoptions_%.texi)
|
||||
|
||||
$(GENTEXI): TAG = GENTEXI
|
||||
$(GENTEXI): doc/avoptions_%.texi: doc/print_options$(HOSTEXESUF)
|
||||
$(M)doc/print_options$(HOSTEXESUF) $* > $@
|
||||
|
||||
doc/%.html: TAG = HTML
|
||||
doc/%-all.html: TAG = HTML
|
||||
|
||||
ifdef HAVE_MAKEINFO_HTML
|
||||
doc/%.html: doc/%.texi $(SRC_PATH)/doc/t2h.pm $(GENTEXI)
|
||||
$(Q)$(TEXIDEP)
|
||||
$(M)makeinfo --html -I doc --no-split -D config-not-all --init-file=$(SRC_PATH)/doc/t2h.pm --output $@ $<
|
||||
|
||||
doc/%-all.html: doc/%.texi $(SRC_PATH)/doc/t2h.pm $(GENTEXI)
|
||||
$(Q)$(TEXIDEP)
|
||||
$(M)makeinfo --html -I doc --no-split -D config-all --init-file=$(SRC_PATH)/doc/t2h.pm --output $@ $<
|
||||
else
|
||||
doc/%.html: doc/%.texi $(SRC_PATH)/doc/t2h.init $(GENTEXI)
|
||||
$(Q)$(TEXIDEP)
|
||||
$(M)texi2html -I doc -monolithic --D=config-not-all --init-file $(SRC_PATH)/doc/t2h.init --output $@ $<
|
||||
|
||||
doc/%-all.html: doc/%.texi $(SRC_PATH)/doc/t2h.init $(GENTEXI)
|
||||
$(Q)$(TEXIDEP)
|
||||
$(M)texi2html -I doc -monolithic --D=config-all --init-file $(SRC_PATH)/doc/t2h.init --output $@ $<
|
||||
endif
|
||||
|
||||
doc/%.pod: TAG = POD
|
||||
doc/%.pod: doc/%.texi $(SRC_PATH)/doc/texi2pod.pl $(GENTEXI)
|
||||
$(Q)$(TEXIDEP)
|
||||
$(M)perl $(SRC_PATH)/doc/texi2pod.pl -Dconfig-not-all=yes -Idoc $< $@
|
||||
|
||||
doc/%-all.pod: TAG = POD
|
||||
doc/%-all.pod: doc/%.texi $(SRC_PATH)/doc/texi2pod.pl $(GENTEXI)
|
||||
$(Q)$(TEXIDEP)
|
||||
$(M)perl $(SRC_PATH)/doc/texi2pod.pl -Dconfig-all=yes -Idoc $< $@
|
||||
|
||||
doc/%.1 doc/%.3: TAG = MAN
|
||||
doc/%.1: doc/%.pod $(GENTEXI)
|
||||
$(M)pod2man --section=1 --center=" " --release=" " --date=" " $< > $@
|
||||
doc/%.3: doc/%.pod $(GENTEXI)
|
||||
$(M)pod2man --section=3 --center=" " --release=" " --date=" " $< > $@
|
||||
|
||||
$(DOCS) doc/doxy/html: | doc/
|
||||
|
||||
DOXY_INPUT = $(INSTHEADERS)
|
||||
DOXY_INPUT_DEPS = $(addprefix $(SRC_PATH)/, $(DOXY_INPUT)) ffbuild/config.mak
|
||||
|
||||
doc/doxy/html: TAG = DOXY
|
||||
doc/doxy/html: $(SRC_PATH)/doc/Doxyfile $(SRC_PATH)/doc/doxy-wrapper.sh $(DOXY_INPUT_DEPS)
|
||||
$(M)$(SRC_PATH)/doc/doxy-wrapper.sh $$PWD/doc/doxy $(SRC_PATH) doc/Doxyfile $(DOXYGEN) $(DOXY_INPUT);
|
||||
|
||||
install-doc: install-html install-man
|
||||
|
||||
install-html:
|
||||
|
||||
install-man:
|
||||
|
||||
ifdef CONFIG_HTMLPAGES
|
||||
install-progs-$(CONFIG_DOC): install-html
|
||||
|
||||
install-html: $(HTMLPAGES)
|
||||
$(Q)mkdir -p "$(DOCDIR)"
|
||||
$(INSTALL) -m 644 $(HTMLPAGES) "$(DOCDIR)"
|
||||
endif
|
||||
|
||||
ifdef CONFIG_MANPAGES
|
||||
install-progs-$(CONFIG_DOC): install-man
|
||||
|
||||
install-man: $(MANPAGES)
|
||||
$(Q)mkdir -p "$(MANDIR)/man1"
|
||||
$(INSTALL) -m 644 $(MANPAGES1) "$(MANDIR)/man1"
|
||||
$(Q)mkdir -p "$(MANDIR)/man3"
|
||||
$(INSTALL) -m 644 $(MANPAGES3) "$(MANDIR)/man3"
|
||||
endif
|
||||
|
||||
uninstall: uninstall-doc
|
||||
|
||||
uninstall-doc: uninstall-html uninstall-man
|
||||
|
||||
uninstall-html:
|
||||
$(RM) -r "$(DOCDIR)"
|
||||
|
||||
uninstall-man:
|
||||
$(RM) $(addprefix "$(MANDIR)/man1/",$(AVPROGS-yes:%=%.1) $(AVPROGS-yes:%=%-all.1) $(COMPONENTS-yes:%=%.1))
|
||||
$(RM) $(addprefix "$(MANDIR)/man3/",$(LIBRARIES-yes:%=%.3))
|
||||
|
||||
clean:: docclean
|
||||
|
||||
distclean:: docclean
|
||||
$(RM) doc/config.texi
|
||||
|
||||
docclean::
|
||||
$(RM) $(CLEANSUFFIXES:%=doc/%)
|
||||
$(RM) $(TXTPAGES) doc/*.html doc/*.pod doc/*.1 doc/*.3 doc/avoptions_*.texi
|
||||
$(RM) -r doc/doxy/html
|
||||
|
||||
-include $(wildcard $(DOCS:%=%.d))
|
||||
|
||||
.PHONY: apidoc doc documentation
|
||||
90
doc/TODO
Normal file
90
doc/TODO
Normal file
@@ -0,0 +1,90 @@
|
||||
ffmpeg TODO list:
|
||||
----------------
|
||||
|
||||
Fabrice's TODO list: (unordered)
|
||||
-------------------
|
||||
Short term:
|
||||
|
||||
- use AVFMTCTX_DISCARD_PKT in ffplay so that DV has a chance to work
|
||||
- add RTSP regression test (both client and server)
|
||||
- make ffserver allocate AVFormatContext
|
||||
- clean up (incompatible change, for 0.5.0):
|
||||
* AVStream -> AVComponent
|
||||
* AVFormatContext -> AVInputStream/AVOutputStream
|
||||
* suppress rate_emu from AVCodecContext
|
||||
- add new float/integer audio filterting and conversion : suppress
|
||||
CODEC_ID_PCM_xxc and use CODEC_ID_RAWAUDIO.
|
||||
- fix telecine and frame rate conversion
|
||||
|
||||
Long term (ask me if you want to help):
|
||||
|
||||
- commit new imgconvert API and new PIX_FMT_xxx alpha formats
|
||||
- commit new LGPL'ed float and integer-only AC3 decoder
|
||||
- add WMA integer-only decoder
|
||||
- add new MPEG4-AAC audio decoder (both integer-only and float version)
|
||||
|
||||
Michael's TODO list: (unordered) (if anyone wanna help with sth, just ask)
|
||||
-------------------
|
||||
- optimize H264 CABAC
|
||||
- more optimizations
|
||||
- simper rate control
|
||||
|
||||
Francois' TODO list: (unordered, without any timeframe)
|
||||
-------------------
|
||||
- test MACE decoder against the openquicktime one as suggested by A'rpi
|
||||
- BeOS audio input grabbing backend
|
||||
- BeOS video input grabbing backend
|
||||
- publish my BeOS libposix on BeBits so I can officially support ffserver :)
|
||||
- check the whole code for thread-safety (global and init stuff)
|
||||
|
||||
Philip'a TODO list: (alphabetically ordered) (please help)
|
||||
------------------
|
||||
- Add a multi-ffm filetype so that feeds can be recorded into multiple files rather
|
||||
than one big file.
|
||||
- Authenticated users support -- where the authentication is in the URL
|
||||
- Change ASF files so that the embedded timestamp in the frames is right rather
|
||||
than being an offset from the start of the stream
|
||||
- Make ffm files more resilient to changes in the codec structures so that you
|
||||
can play old ffm files.
|
||||
|
||||
Baptiste's TODO list:
|
||||
-----------------
|
||||
- mov edit list support (AVEditList)
|
||||
- YUV 10 bit per component support "2vuy"
|
||||
- mxf muxer
|
||||
- mpeg2 non linear quantizer
|
||||
|
||||
unassigned TODO: (unordered)
|
||||
---------------
|
||||
- use AVFrame for audio codecs too
|
||||
- rework aviobuf.c buffering strategy and fix url_fskip
|
||||
- generate optimal huffman tables for mjpeg encoding
|
||||
- fix ffserver regression tests
|
||||
- support xvids motion estimation
|
||||
- support x264s motion estimation
|
||||
- support x264s rate control
|
||||
- SNOW: non translational motion compensation
|
||||
- SNOW: more optimal quantization
|
||||
- SNOW: 4x4 block support
|
||||
- SNOW: 1/8 pel motion compensation support
|
||||
- SNOW: iterative motion estimation based on subsampled images
|
||||
- SNOW: try B frames and MCTF and see how their PSNR/bitrate/complexity behaves
|
||||
- SNOW: try to use the wavelet transformed MC-ed reference frame as context for the entropy coder
|
||||
- SNOW: think about/analyize how to make snow use multiple cpus/threads
|
||||
- SNOW: finish spec
|
||||
- FLAC: lossy encoding (viterbi and naive scalar quantization)
|
||||
- libavfilter
|
||||
- JPEG2000 decoder & encoder
|
||||
- MPEG4 GMC encoding support
|
||||
- macroblock based pixel format (better cache locality, somewhat complex, one paper claimed it faster for high res)
|
||||
- regression tests for codecs which do not have an encoder (I+P-frame bitstream in svn)
|
||||
- add support for using mplayers video filters to ffmpeg
|
||||
- H264 encoder
|
||||
- per MB ratecontrol (so VCD and such do work better)
|
||||
- write a script which iteratively changes all functions between always_inline and noinline and benchmarks the result to find the best set of inlined functions
|
||||
- convert all the non SIMD asm into small asm vs. C testcases and submit them to the gcc devels so they can improve gcc
|
||||
- generic audio mixing API
|
||||
- extract PES packetizer from PS muxer and use it for new TS muxer
|
||||
- implement automatic AVBistreamFilter activation
|
||||
- make cabac encoder use bytestream (see http://trac.videolan.org/x264/changeset/?format=diff&new=651)
|
||||
- merge imdct and windowing, the current code does considerable amounts of redundant work
|
||||
@@ -1,11 +0,0 @@
|
||||
@chapter Authors
|
||||
|
||||
The FFmpeg developers.
|
||||
|
||||
For details about the authorship, see the Git history of the project
|
||||
(https://git.ffmpeg.org/ffmpeg), e.g. by typing the command
|
||||
@command{git log} in the FFmpeg source directory, or browsing the
|
||||
online repository at @url{https://git.ffmpeg.org/ffmpeg}.
|
||||
|
||||
Maintainers for the specific components are listed in the file
|
||||
@file{MAINTAINERS} in the source code tree.
|
||||
37
doc/avutil.txt
Normal file
37
doc/avutil.txt
Normal file
@@ -0,0 +1,37 @@
|
||||
AVUtil
|
||||
======
|
||||
libavutil is a small lightweight library of generally useful functions.
|
||||
It is not a library for code needed by both libavcodec and libavformat.
|
||||
|
||||
|
||||
Overview:
|
||||
=========
|
||||
adler32.c adler32 checksum
|
||||
aes.c AES encryption and decryption
|
||||
fifo.c resizeable first in first out buffer
|
||||
intfloat_readwrite.c portable reading and writing of floating point values
|
||||
log.c "printf" with context and level
|
||||
md5.c MD5 Message-Digest Algorithm
|
||||
rational.c code to perform exact calculations with rational numbers
|
||||
tree.c generic AVL tree
|
||||
crc.c generic CRC checksumming code
|
||||
integer.c 128bit integer math
|
||||
lls.c
|
||||
mathematics.c greatest common divisor, integer sqrt, integer log2, ...
|
||||
mem.c memory allocation routines with guaranteed alignment
|
||||
softfloat.c
|
||||
|
||||
Headers:
|
||||
bswap.h big/little/native-endian conversion code
|
||||
x86_cpu.h a few useful macros for unifying x86-64 and x86-32 code
|
||||
avutil.h
|
||||
common.h
|
||||
intreadwrite.h reading and writing of unaligned big/little/native-endian integers
|
||||
|
||||
|
||||
Goals:
|
||||
======
|
||||
* Modular (few interdependencies and the possibility of disabling individual parts during ./configure)
|
||||
* Small (source and object)
|
||||
* Efficient (low CPU and memory usage)
|
||||
* Useful (avoid useless features almost no one needs)
|
||||
File diff suppressed because it is too large
Load Diff
5
doc/bootstrap.min.css
vendored
5
doc/bootstrap.min.css
vendored
File diff suppressed because one or more lines are too long
@@ -1,72 +0,0 @@
|
||||
FFmpeg currently uses a custom build system, this text attempts to document
|
||||
some of its obscure features and options.
|
||||
|
||||
Makefile variables:
|
||||
|
||||
V
|
||||
Disable the default terse mode, the full command issued by make and its
|
||||
output will be shown on the screen.
|
||||
|
||||
DBG
|
||||
Preprocess x86 external assembler files to a .dbg.asm file in the object
|
||||
directory, which then gets compiled. Helps in developing those assembler
|
||||
files.
|
||||
|
||||
DESTDIR
|
||||
Destination directory for the install targets, useful to prepare packages
|
||||
or install FFmpeg in cross-environments.
|
||||
|
||||
GEN
|
||||
Set to ‘1’ to generate the missing or mismatched references.
|
||||
|
||||
Makefile targets:
|
||||
|
||||
all
|
||||
Default target, builds all the libraries and the executables.
|
||||
|
||||
fate
|
||||
Run the fate test suite, note that you must have installed it.
|
||||
|
||||
fate-list
|
||||
List all fate/regression test targets.
|
||||
|
||||
fate-list-failing
|
||||
List the fate tests that failed the last time they were executed.
|
||||
|
||||
fate-clear-reports
|
||||
Remove the test reports from previous test executions (getting rid of
|
||||
potentially stale results from fate-list-failing).
|
||||
|
||||
install
|
||||
Install headers, libraries and programs.
|
||||
|
||||
examples
|
||||
Build all examples located in doc/examples.
|
||||
|
||||
checkheaders
|
||||
Check headers dependencies.
|
||||
|
||||
alltools
|
||||
Build all tools in tools directory.
|
||||
|
||||
config
|
||||
Reconfigure the project with the current configuration.
|
||||
|
||||
tools/target_dec_<decoder>_fuzzer
|
||||
Build fuzzer to fuzz the specified decoder.
|
||||
|
||||
tools/target_bsf_<filter>_fuzzer
|
||||
Build fuzzer to fuzz the specified bitstream filter.
|
||||
|
||||
Useful standard make commands:
|
||||
make -t <target>
|
||||
Touch all files that otherwise would be built, this is useful to reduce
|
||||
unneeded rebuilding when changing headers, but note that you must force rebuilds
|
||||
of files that actually need it by hand then.
|
||||
|
||||
make -j<num>
|
||||
Rebuild with multiple jobs at the same time. Faster on multi processor systems.
|
||||
|
||||
make -k
|
||||
Continue build in case of errors, this is useful for the regression tests
|
||||
sometimes but note that it will still not run all reg tests.
|
||||
1033
doc/codecs.texi
1033
doc/codecs.texi
File diff suppressed because it is too large
Load Diff
@@ -1,182 +0,0 @@
|
||||
\input texinfo @c -*- texinfo -*-
|
||||
@documentencoding UTF-8
|
||||
|
||||
@settitle Community
|
||||
@titlepage
|
||||
@center @titlefont{Community}
|
||||
@end titlepage
|
||||
|
||||
@top
|
||||
|
||||
@contents
|
||||
|
||||
@anchor{Organisation}
|
||||
@chapter Organisation
|
||||
|
||||
The FFmpeg project is organized through a community working on global consensus.
|
||||
|
||||
Decisions are taken by the ensemble of active members, through voting and are aided by two committees.
|
||||
|
||||
@anchor{General Assembly}
|
||||
@chapter General Assembly
|
||||
|
||||
The ensemble of active members is called the General Assembly (GA).
|
||||
|
||||
The General Assembly is sovereign and legitimate for all its decisions regarding the FFmpeg project.
|
||||
|
||||
The General Assembly is made up of active contributors.
|
||||
|
||||
Contributors are considered "active contributors" if they have authored more than 20 patches in the last 36 months in the main FFmpeg repository, or if they have been voted in by the GA.
|
||||
|
||||
The list of active contributors is updated twice each year, on 1st January and 1st July, 0:00 UTC.
|
||||
|
||||
Additional members are added to the General Assembly through a vote after proposal by a member of the General Assembly. They are part of the GA for two years, after which they need a confirmation by the GA.
|
||||
|
||||
A script to generate the current members of the general assembly (minus members voted in) can be found in `tools/general_assembly.pl`.
|
||||
|
||||
@anchor{Voting}
|
||||
@chapter Voting
|
||||
|
||||
Voting is done using a ranked voting system, currently running on https://vote.ffmpeg.org/ .
|
||||
|
||||
Majority vote means more than 50% of the expressed ballots.
|
||||
|
||||
@anchor{Technical Committee}
|
||||
@chapter Technical Committee
|
||||
|
||||
The Technical Committee (TC) is here to arbitrate and make decisions when technical conflicts occur in the project. They will consider the merits of all the positions, judge them and make a decision.
|
||||
|
||||
The TC resolves technical conflicts but is not a technical steering committee.
|
||||
|
||||
Decisions by the TC are binding for all the contributors.
|
||||
|
||||
Decisions made by the TC can be re-opened after 1 year or by a majority vote of the General Assembly, requested by one of the member of the GA.
|
||||
|
||||
The TC is elected by the General Assembly for a duration of 1 year, and is composed of 5 members. Members can be re-elected if they wish. A majority vote in the General Assembly can trigger a new election of the TC.
|
||||
|
||||
The members of the TC can be elected from outside of the GA. Candidates for election can either be suggested or self-nominated.
|
||||
|
||||
The conflict resolution process is detailed in the resolution process document.
|
||||
|
||||
The TC can be contacted at <tc@@ffmpeg>.
|
||||
|
||||
@anchor{Resolution Process}
|
||||
@section Resolution Process
|
||||
|
||||
The Technical Committee (TC) is here to arbitrate and make decisions when technical conflicts occur in the project.
|
||||
|
||||
The TC main role is to resolve technical conflicts. It is therefore not a technical steering committee, but it is understood that some decisions might impact the future of the project.
|
||||
|
||||
@subsection Seizing
|
||||
|
||||
The TC can take possession of any technical matter that it sees fit.
|
||||
|
||||
To involve the TC in a matter, email tc@ or CC them on an ongoing discussion.
|
||||
|
||||
As members of TC are developers, they also can email tc@ to raise an issue.
|
||||
@subsection Announcement
|
||||
|
||||
The TC, once seized, must announce itself on the main mailing list, with a [TC] tag.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
@subsection RFC call
|
||||
|
||||
In the RFC mode, one person from the TC posts on the mailing list the technical question and will request input from the community.
|
||||
|
||||
The mail will have the following specification:
|
||||
|
||||
a precise title
|
||||
a specific tag [TC RFC]
|
||||
a top-level email
|
||||
contain a precise question that does not exceed 100 words and that is answerable by developers
|
||||
may have an extra description, or a link to a previous discussion, if deemed necessary,
|
||||
contain a precise end date for the answers.
|
||||
|
||||
The answers from the community must be on the main mailing list and must have the following specification:
|
||||
|
||||
keep the tag and the title unchanged
|
||||
limited to 400 words
|
||||
a first-level, answering directly to the main email
|
||||
answering to the question.
|
||||
|
||||
Further replies to answers are permitted, as long as they conform to the community standards of politeness, they are limited to 100 words, and are not nested more than once. (max-depth=2)
|
||||
|
||||
After the end-date, mails on the thread will be ignored.
|
||||
|
||||
Violations of those rules will be escalated through the Community Committee.
|
||||
|
||||
After all the emails are in, the TC has 96 hours to give its final decision. Exceptionally, the TC can request an extra delay, that will be notified on the mailing list.
|
||||
@subsection Within TC
|
||||
|
||||
In the internal case, the TC has 96 hours to give its final decision. Exceptionally, the TC can request an extra delay.
|
||||
@subsection Decisions
|
||||
|
||||
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.
|
||||
|
||||
@anchor{Community Committee}
|
||||
@chapter Community Committee
|
||||
|
||||
The Community Committee (CC) is here to arbitrage and make decisions when inter-personal conflicts occur in the project. It will decide quickly and take actions, for the sake of the project.
|
||||
|
||||
The CC can remove privileges of offending members, including removal of commit access and temporary ban from the community.
|
||||
|
||||
Decisions made by the CC can be re-opened after 1 year or by a majority vote of the General Assembly. Indefinite bans from the community must be confirmed by the General Assembly, in a majority vote.
|
||||
|
||||
The CC is elected by the General Assembly for a duration of 1 year, and is composed of 5 members. Members can be re-elected if they wish. A majority vote in the General Assembly can trigger a new election of the CC.
|
||||
|
||||
The members of the CC can be elected from outside of the GA. Candidates for election can either be suggested or self-nominated.
|
||||
|
||||
The CC is governed by and responsible for enforcing the Code of Conduct.
|
||||
|
||||
The CC can be contacted at <cc@@ffmpeg>.
|
||||
|
||||
@anchor{Code of Conduct}
|
||||
@chapter Code of Conduct
|
||||
|
||||
Be friendly and respectful towards others and third parties.
|
||||
Treat others the way you yourself want to be treated.
|
||||
|
||||
Be considerate. Not everyone shares the same viewpoint and priorities as you do.
|
||||
Different opinions and interpretations help the project.
|
||||
Looking at issues from a different perspective assists development.
|
||||
|
||||
Do not assume malice for things that can be attributed to incompetence. Even if
|
||||
it is malice, it's rarely good to start with that as initial assumption.
|
||||
|
||||
Stay friendly even if someone acts contrarily. Everyone has a bad day
|
||||
once in a while.
|
||||
If you yourself have a bad day or are angry then try to take a break and reply
|
||||
once you are calm and without anger if you have to.
|
||||
|
||||
Try to help other team members and cooperate if you can.
|
||||
|
||||
The goal of software development is to create technical excellence, not for any
|
||||
individual to be better and "win" against the others. Large software projects
|
||||
are only possible and successful through teamwork.
|
||||
|
||||
If someone struggles do not put them down. Give them a helping hand
|
||||
instead and point them in the right direction.
|
||||
|
||||
Finally, keep in mind the immortal words of Bill and Ted,
|
||||
"Be excellent to each other."
|
||||
|
||||
@bye
|
||||
@@ -1,699 +0,0 @@
|
||||
@chapter Decoders
|
||||
@c man begin DECODERS
|
||||
|
||||
Decoders are configured elements in FFmpeg which allow the decoding of
|
||||
multimedia streams.
|
||||
|
||||
When you configure your FFmpeg build, all the supported native decoders
|
||||
are enabled by default. Decoders requiring an external library must be enabled
|
||||
manually via the corresponding @code{--enable-lib} option. You can list all
|
||||
available decoders using the configure option @code{--list-decoders}.
|
||||
|
||||
You can disable all the decoders with the configure option
|
||||
@code{--disable-decoders} and selectively enable / disable single decoders
|
||||
with the options @code{--enable-decoder=@var{DECODER}} /
|
||||
@code{--disable-decoder=@var{DECODER}}.
|
||||
|
||||
The option @code{-decoders} of the ff* tools will display the list of
|
||||
enabled decoders.
|
||||
|
||||
@c man end DECODERS
|
||||
|
||||
@chapter Video Decoders
|
||||
@c man begin VIDEO DECODERS
|
||||
|
||||
A description of some of the currently available video decoders
|
||||
follows.
|
||||
|
||||
@section av1
|
||||
|
||||
AOMedia Video 1 (AV1) decoder.
|
||||
|
||||
@subsection Options
|
||||
|
||||
@table @option
|
||||
|
||||
@item operating_point
|
||||
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.
|
||||
|
||||
This decoder decodes rawvideo streams.
|
||||
|
||||
@subsection Options
|
||||
|
||||
@table @option
|
||||
@item top @var{top_field_first}
|
||||
Specify the assumed field type of the input video.
|
||||
@table @option
|
||||
@item -1
|
||||
the video is assumed to be progressive (default)
|
||||
@item 0
|
||||
bottom-field-first is assumed
|
||||
@item 1
|
||||
top-field-first is assumed
|
||||
@end table
|
||||
|
||||
@end table
|
||||
|
||||
@section libdav1d
|
||||
|
||||
dav1d AV1 decoder.
|
||||
|
||||
libdav1d allows libavcodec to decode the AOMedia Video 1 (AV1) codec.
|
||||
Requires the presence of the libdav1d headers and library during configuration.
|
||||
You need to explicitly configure the build with @code{--enable-libdav1d}.
|
||||
|
||||
@subsection Options
|
||||
|
||||
The following options are supported by the libdav1d wrapper.
|
||||
|
||||
@table @option
|
||||
|
||||
@item framethreads
|
||||
Set amount of frame threads to use during decoding. The default value is 0 (autodetect).
|
||||
This option is deprecated for libdav1d >= 1.0 and will be removed in the future. Use the
|
||||
option @code{max_frame_delay} and the global option @code{threads} instead.
|
||||
|
||||
@item tilethreads
|
||||
Set amount of tile threads to use during decoding. The default value is 0 (autodetect).
|
||||
This option is deprecated for libdav1d >= 1.0 and will be removed in the future. Use the
|
||||
global option @code{threads} instead.
|
||||
|
||||
@item max_frame_delay
|
||||
Set max amount of frames the decoder may buffer internally. The default value is 0
|
||||
(autodetect).
|
||||
|
||||
@item filmgrain
|
||||
Apply film grain to the decoded video if present in the bitstream. Defaults to the
|
||||
internal default of the library.
|
||||
This option is deprecated and will be removed in the future. See the global option
|
||||
@code{export_side_data} to export Film Grain parameters instead of applying it.
|
||||
|
||||
@item oppoint
|
||||
Select an operating point of a scalable AV1 bitstream (0 - 31). Defaults to the
|
||||
internal default of the library.
|
||||
|
||||
@item alllayers
|
||||
Output all spatial layers of a scalable AV1 bitstream. The default value is false.
|
||||
|
||||
@end table
|
||||
|
||||
@section libdavs2
|
||||
|
||||
AVS2-P2/IEEE1857.4 video decoder wrapper.
|
||||
|
||||
This decoder allows libavcodec to decode AVS2 streams with davs2 library.
|
||||
|
||||
@c man end VIDEO DECODERS
|
||||
|
||||
@section libuavs3d
|
||||
|
||||
AVS3-P2/IEEE1857.10 video decoder.
|
||||
|
||||
libuavs3d allows libavcodec to decode AVS3 streams.
|
||||
Requires the presence of the libuavs3d headers and library during configuration.
|
||||
You need to explicitly configure the build with @code{--enable-libuavs3d}.
|
||||
|
||||
@subsection Options
|
||||
|
||||
The following option is supported by the libuavs3d wrapper.
|
||||
|
||||
@table @option
|
||||
|
||||
@item frame_threads
|
||||
Set amount of frame threads to use during decoding. The default value is 0 (autodetect).
|
||||
|
||||
@end table
|
||||
|
||||
@section libxevd
|
||||
|
||||
eXtra-fast Essential Video Decoder (XEVD) MPEG-5 EVC decoder wrapper.
|
||||
|
||||
This decoder requires the presence of the libxevd headers and library
|
||||
during configuration. You need to explicitly configure the build with
|
||||
@option{--enable-libxevd}.
|
||||
|
||||
The xevd project website is at @url{https://github.com/mpeg5/xevd}.
|
||||
|
||||
@subsection Options
|
||||
|
||||
The following options are supported by the libxevd wrapper.
|
||||
The xevd-equivalent options or values are listed in parentheses for easy migration.
|
||||
|
||||
To get a more accurate and extensive documentation of the libxevd options,
|
||||
invoke the command @code{xevd_app --help} or consult the libxevd documentation.
|
||||
|
||||
@table @option
|
||||
@item threads (@emph{threads})
|
||||
Force to use a specific number of threads
|
||||
|
||||
@end table
|
||||
|
||||
@section QSV Decoders
|
||||
|
||||
The family of Intel QuickSync Video decoders (VC1, MPEG-2, H.264, HEVC,
|
||||
JPEG/MJPEG, VP8, VP9, AV1, VVC).
|
||||
|
||||
@subsection Common Options
|
||||
|
||||
The following options are supported by all qsv decoders.
|
||||
|
||||
@table @option
|
||||
|
||||
@item @var{async_depth}
|
||||
Internal parallelization depth, the higher the value the higher the latency.
|
||||
|
||||
@item @var{gpu_copy}
|
||||
A GPU-accelerated copy between video and system memory
|
||||
@table @samp
|
||||
@item default
|
||||
@item on
|
||||
@item off
|
||||
@end table
|
||||
|
||||
@end table
|
||||
|
||||
@subsection HEVC Options
|
||||
Extra options for hevc_qsv.
|
||||
|
||||
@table @option
|
||||
|
||||
@item @var{load_plugin}
|
||||
A user plugin to load in an internal session
|
||||
@table @samp
|
||||
@item none
|
||||
@item hevc_sw
|
||||
@item hevc_hw
|
||||
@end table
|
||||
|
||||
@item @var{load_plugins}
|
||||
A :-separate list of hexadecimal plugin UIDs to load in an internal session
|
||||
|
||||
@end table
|
||||
|
||||
@section v210
|
||||
|
||||
Uncompressed 4:2:2 10-bit decoder.
|
||||
|
||||
@subsection Options
|
||||
|
||||
@table @option
|
||||
|
||||
@item custom_stride
|
||||
Set the line size of the v210 data in bytes. The default value is 0
|
||||
(autodetect). You can use the special -1 value for a strideless v210 as seen in
|
||||
BOXX files.
|
||||
|
||||
@end table
|
||||
|
||||
@c man end VIDEO DECODERS
|
||||
|
||||
@chapter Audio Decoders
|
||||
@c man begin AUDIO DECODERS
|
||||
|
||||
A description of some of the currently available audio decoders
|
||||
follows.
|
||||
|
||||
@section ac3
|
||||
|
||||
AC-3 audio decoder.
|
||||
|
||||
This decoder implements part of ATSC A/52:2010 and ETSI TS 102 366, as well as
|
||||
the undocumented RealAudio 3 (a.k.a. dnet).
|
||||
|
||||
@subsection AC-3 Decoder Options
|
||||
|
||||
@table @option
|
||||
|
||||
@item -drc_scale @var{value}
|
||||
Dynamic Range Scale Factor. The factor to apply to dynamic range values
|
||||
from the AC-3 stream. This factor is applied exponentially. The default value is 1.
|
||||
There are 3 notable scale factor ranges:
|
||||
@table @option
|
||||
@item drc_scale == 0
|
||||
DRC disabled. Produces full range audio.
|
||||
@item 0 < drc_scale <= 1
|
||||
DRC enabled. Applies a fraction of the stream DRC value.
|
||||
Audio reproduction is between full range and full compression.
|
||||
@item drc_scale > 1
|
||||
DRC enabled. Applies drc_scale asymmetrically.
|
||||
Loud sounds are fully compressed. Soft sounds are enhanced.
|
||||
@end table
|
||||
|
||||
@end table
|
||||
|
||||
@section flac
|
||||
|
||||
FLAC audio decoder.
|
||||
|
||||
This decoder aims to implement the complete FLAC specification from Xiph.
|
||||
|
||||
@subsection FLAC Decoder options
|
||||
|
||||
@table @option
|
||||
|
||||
@item -use_buggy_lpc
|
||||
The lavc FLAC encoder used to produce buggy streams with high lpc values
|
||||
(like the default value). This option makes it possible to decode such streams
|
||||
correctly by using lavc's old buggy lpc logic for decoding.
|
||||
|
||||
@end table
|
||||
|
||||
@section ffwavesynth
|
||||
|
||||
Internal wave synthesizer.
|
||||
|
||||
This decoder generates wave patterns according to predefined sequences. Its
|
||||
use is purely internal and the format of the data it accepts is not publicly
|
||||
documented.
|
||||
|
||||
@section libcelt
|
||||
|
||||
libcelt decoder wrapper.
|
||||
|
||||
libcelt allows libavcodec to decode the Xiph CELT ultra-low delay audio codec.
|
||||
Requires the presence of the libcelt headers and library during configuration.
|
||||
You need to explicitly configure the build with @code{--enable-libcelt}.
|
||||
|
||||
@section libgsm
|
||||
|
||||
libgsm decoder wrapper.
|
||||
|
||||
libgsm allows libavcodec to decode the GSM full rate audio codec. Requires
|
||||
the presence of the libgsm headers and library during configuration. You need
|
||||
to explicitly configure the build with @code{--enable-libgsm}.
|
||||
|
||||
This decoder supports both the ordinary GSM and the Microsoft variant.
|
||||
|
||||
@section libilbc
|
||||
|
||||
libilbc decoder wrapper.
|
||||
|
||||
libilbc allows libavcodec to decode the Internet Low Bitrate Codec (iLBC)
|
||||
audio codec. Requires the presence of the libilbc headers and library during
|
||||
configuration. You need to explicitly configure the build with
|
||||
@code{--enable-libilbc}.
|
||||
|
||||
@subsection Options
|
||||
|
||||
The following option is supported by the libilbc wrapper.
|
||||
|
||||
@table @option
|
||||
@item enhance
|
||||
|
||||
Enable the enhancement of the decoded audio when set to 1. The default
|
||||
value is 0 (disabled).
|
||||
|
||||
@end table
|
||||
|
||||
@section libopencore-amrnb
|
||||
|
||||
libopencore-amrnb decoder wrapper.
|
||||
|
||||
libopencore-amrnb allows libavcodec to decode the Adaptive Multi-Rate
|
||||
Narrowband audio codec. Using it requires the presence of the
|
||||
libopencore-amrnb headers and library during configuration. You need to
|
||||
explicitly configure the build with @code{--enable-libopencore-amrnb}.
|
||||
|
||||
An FFmpeg native decoder for AMR-NB exists, so users can decode AMR-NB
|
||||
without this library.
|
||||
|
||||
@section libopencore-amrwb
|
||||
|
||||
libopencore-amrwb decoder wrapper.
|
||||
|
||||
libopencore-amrwb allows libavcodec to decode the Adaptive Multi-Rate
|
||||
Wideband audio codec. Using it requires the presence of the
|
||||
libopencore-amrwb headers and library during configuration. You need to
|
||||
explicitly configure the build with @code{--enable-libopencore-amrwb}.
|
||||
|
||||
An FFmpeg native decoder for AMR-WB exists, so users can decode AMR-WB
|
||||
without this library.
|
||||
|
||||
@section libopus
|
||||
|
||||
libopus decoder wrapper.
|
||||
|
||||
libopus allows libavcodec to decode the Opus Interactive Audio Codec.
|
||||
Requires the presence of the libopus headers and library during
|
||||
configuration. You need to explicitly configure the build with
|
||||
@code{--enable-libopus}.
|
||||
|
||||
An FFmpeg native decoder for Opus exists, so users can decode Opus
|
||||
without this library.
|
||||
|
||||
@c man end AUDIO DECODERS
|
||||
|
||||
@chapter Subtitles Decoders
|
||||
@c man begin SUBTITLES DECODERS
|
||||
|
||||
@section libaribb24
|
||||
|
||||
ARIB STD-B24 caption decoder.
|
||||
|
||||
Implements profiles A and C of the ARIB STD-B24 standard.
|
||||
|
||||
@subsection libaribb24 Decoder Options
|
||||
|
||||
@table @option
|
||||
|
||||
@item -aribb24-base-path @var{path}
|
||||
Sets the base path for the libaribb24 library. This is utilized for reading of
|
||||
configuration files (for custom unicode conversions), and for dumping of
|
||||
non-text symbols as images under that location.
|
||||
|
||||
Unset by default.
|
||||
|
||||
@item -aribb24-skip-ruby-text @var{boolean}
|
||||
Tells the decoder wrapper to skip text blocks that contain half-height ruby
|
||||
text.
|
||||
|
||||
Enabled by default.
|
||||
|
||||
@end table
|
||||
|
||||
@section libaribcaption
|
||||
|
||||
Yet another ARIB STD-B24 caption decoder using external @dfn{libaribcaption}
|
||||
library.
|
||||
|
||||
Implements profiles A and C of the Japanese ARIB STD-B24 standard,
|
||||
Brazilian ABNT NBR 15606-1, and Philippines version of ISDB-T.
|
||||
|
||||
Requires the presence of the libaribcaption headers and library
|
||||
(@url{https://github.com/xqq/libaribcaption}) during configuration.
|
||||
You need to explicitly configure the build with @code{--enable-libaribcaption}.
|
||||
If both @dfn{libaribb24} and @dfn{libaribcaption} are enabled, @dfn{libaribcaption}
|
||||
decoder precedes.
|
||||
|
||||
@subsection libaribcaption Decoder Options
|
||||
|
||||
@table @option
|
||||
|
||||
@item -sub_type @var{subtitle_type}
|
||||
Specifies the format of the decoded subtitles.
|
||||
|
||||
@table @samp
|
||||
@item bitmap
|
||||
Graphical image.
|
||||
@item ass
|
||||
ASS formatted text.
|
||||
@item text
|
||||
Simple text based output without formatting.
|
||||
@end table
|
||||
|
||||
The default is @dfn{ass} as same as @dfn{libaribb24} decoder.
|
||||
Some present players (e.g., @dfn{mpv}) expect ASS format for ARIB caption.
|
||||
|
||||
@item -caption_encoding @var{encoding_scheme}
|
||||
Specifies the encoding scheme of input subtitle text.
|
||||
|
||||
@table @samp
|
||||
@item auto
|
||||
Automatically detect text encoding (default).
|
||||
@item jis
|
||||
8bit-char JIS encoding defined in ARIB STD B24.
|
||||
This encoding used in Japan for ISDB captions.
|
||||
@item utf8
|
||||
UTF-8 encoding defined in ARIB STD B24.
|
||||
This encoding is used in Philippines for ISDB-T captions.
|
||||
@item latin
|
||||
Latin character encoding defined in ABNT NBR 15606-1.
|
||||
This encoding is used in South America for SBTVD / ISDB-Tb captions.
|
||||
@end table
|
||||
|
||||
@item -font @var{font_name[,font_name2,...]}
|
||||
Specify comma-separated list of font family names to be used for @dfn{bitmap}
|
||||
or @dfn{ass} type subtitle rendering.
|
||||
Only first font name is used for @dfn{ass} type subtitle.
|
||||
|
||||
If not specified, use internally defined default font family.
|
||||
|
||||
@item -ass_single_rect @var{boolean}
|
||||
ARIB STD-B24 specifies that some captions may be displayed at different
|
||||
positions at a time (multi-rectangle subtitle).
|
||||
Since some players (e.g., old @dfn{mpv}) can't handle multiple ASS rectangles
|
||||
in a single AVSubtitle, or multiple ASS rectangles of indeterminate duration
|
||||
with the same start timestamp, this option can change the behavior so that
|
||||
all the texts are displayed in a single ASS rectangle.
|
||||
|
||||
The default is @var{false}.
|
||||
|
||||
If your player cannot handle AVSubtitles with multiple ASS rectangles properly,
|
||||
set this option to @var{true} or define @env{ASS_SINGLE_RECT=1} to change
|
||||
default behavior at compilation.
|
||||
|
||||
@item -force_outline_text @var{boolean}
|
||||
Specify whether always render outline text for all characters regardless of
|
||||
the indication by character style.
|
||||
|
||||
The default is @var{false}.
|
||||
|
||||
@item -outline_width @var{number} (0.0 - 3.0)
|
||||
Specify width for outline text, in dots (relative).
|
||||
|
||||
The default is @var{1.5}.
|
||||
|
||||
@item -ignore_background @var{boolean}
|
||||
Specify whether to ignore background color rendering.
|
||||
|
||||
The default is @var{false}.
|
||||
|
||||
@item -ignore_ruby @var{boolean}
|
||||
Specify whether to ignore rendering for ruby-like (furigana) characters.
|
||||
|
||||
The default is @var{false}.
|
||||
|
||||
@item -replace_drcs @var{boolean}
|
||||
Specify whether to render replaced DRCS characters as Unicode characters.
|
||||
|
||||
The default is @var{true}.
|
||||
|
||||
@item -replace_msz_ascii @var{boolean}
|
||||
Specify whether to replace MSZ (Middle Size; half width) fullwidth
|
||||
alphanumerics with halfwidth alphanumerics.
|
||||
|
||||
The default is @var{true}.
|
||||
|
||||
@item -replace_msz_japanese @var{boolean}
|
||||
Specify whether to replace some MSZ (Middle Size; half width) fullwidth
|
||||
japanese special characters with halfwidth ones.
|
||||
|
||||
The default is @var{true}.
|
||||
|
||||
@item -replace_msz_glyph @var{boolean}
|
||||
Specify whether to replace MSZ (Middle Size; half width) characters
|
||||
with halfwidth glyphs if the fonts supports it.
|
||||
This option works under FreeType or DirectWrite renderer
|
||||
with Adobe-Japan1 compliant fonts.
|
||||
e.g., IBM Plex Sans JP, Morisawa BIZ UDGothic, Morisawa BIZ UDMincho,
|
||||
Yu Gothic, Yu Mincho, and Meiryo.
|
||||
|
||||
The default is @var{true}.
|
||||
|
||||
@item -canvas_size @var{image_size}
|
||||
Specify the resolution of the canvas to render subtitles to; usually, this
|
||||
should be frame size of input video.
|
||||
This only applies when @code{-subtitle_type} is set to @var{bitmap}.
|
||||
|
||||
The libaribcaption decoder assumes input frame size for bitmap rendering as below:
|
||||
@enumerate
|
||||
@item
|
||||
PROFILE_A : 1440 x 1080 with SAR (PAR) 4:3
|
||||
@item
|
||||
PROFILE_C : 320 x 180 with SAR (PAR) 1:1
|
||||
@end enumerate
|
||||
|
||||
If actual frame size of input video does not match above assumption,
|
||||
the rendered captions may be distorted.
|
||||
To make the captions undistorted, add @code{-canvas_size} option to specify
|
||||
actual input video size.
|
||||
|
||||
Note that the @code{-canvas_size} option is not required for video with
|
||||
different size but same aspect ratio.
|
||||
In such cases, the caption will be stretched or shrunk to actual video size
|
||||
if @code{-canvas_size} option is not specified.
|
||||
If @code{-canvas_size} option is specified with different size,
|
||||
the caption will be stretched or shrunk as specified size with calculated SAR.
|
||||
|
||||
@end table
|
||||
|
||||
@subsection libaribcaption decoder usage examples
|
||||
|
||||
Display MPEG-TS file with ARIB subtitle by @code{ffplay} tool:
|
||||
@example
|
||||
ffplay -sub_type bitmap MPEG.TS
|
||||
@end example
|
||||
|
||||
Display MPEG-TS file with input frame size 1920x1080 by @code{ffplay} tool:
|
||||
@example
|
||||
ffplay -sub_type bitmap -canvas_size 1920x1080 MPEG.TS
|
||||
@end example
|
||||
|
||||
Embed ARIB subtitle in transcoded video:
|
||||
@example
|
||||
ffmpeg -sub_type bitmap -i src.m2t -filter_complex "[0:v][0:s]overlay" -vcodec h264 dest.mp4
|
||||
@end example
|
||||
|
||||
@section dvbsub
|
||||
|
||||
@subsection Options
|
||||
|
||||
@table @option
|
||||
@item compute_clut
|
||||
@table @option
|
||||
@item -2
|
||||
Compute clut once if no matching CLUT is in the stream.
|
||||
@item -1
|
||||
Compute clut if no matching CLUT is in the stream.
|
||||
@item 0
|
||||
Never compute CLUT
|
||||
@item 1
|
||||
Always compute CLUT and override the one provided in the stream.
|
||||
@end table
|
||||
@item dvb_substream
|
||||
Selects the dvb substream, or all substreams if -1 which is default.
|
||||
|
||||
@end table
|
||||
|
||||
@section dvdsub
|
||||
|
||||
This codec decodes the bitmap subtitles used in DVDs; the same subtitles can
|
||||
also be found in VobSub file pairs and in some Matroska files.
|
||||
|
||||
@subsection Options
|
||||
|
||||
@table @option
|
||||
@item palette
|
||||
Specify the global palette used by the bitmaps. When stored in VobSub, the
|
||||
palette is normally specified in the index file; in Matroska, the palette is
|
||||
stored in the codec extra-data in the same format as in VobSub. In DVDs, the
|
||||
palette is stored in the IFO file, and therefore not available when reading
|
||||
from dumped VOB files.
|
||||
|
||||
The format for this option is a string containing 16 24-bits hexadecimal
|
||||
numbers (without 0x prefix) separated by commas, for example @code{0d00ee,
|
||||
ee450d, 101010, eaeaea, 0ce60b, ec14ed, ebff0b, 0d617a, 7b7b7b, d1d1d1,
|
||||
7b2a0e, 0d950c, 0f007b, cf0dec, cfa80c, 7c127b}.
|
||||
|
||||
@item ifo_palette
|
||||
Specify the IFO file from which the global palette is obtained.
|
||||
(experimental)
|
||||
|
||||
@item forced_subs_only
|
||||
Only decode subtitle entries marked as forced. Some titles have forced
|
||||
and non-forced subtitles in the same track. Setting this flag to @code{1}
|
||||
will only keep the forced subtitles. Default value is @code{0}.
|
||||
@end table
|
||||
|
||||
@section libzvbi-teletext
|
||||
|
||||
Libzvbi allows libavcodec to decode DVB teletext pages and DVB teletext
|
||||
subtitles. Requires the presence of the libzvbi headers and library during
|
||||
configuration. You need to explicitly configure the build with
|
||||
@code{--enable-libzvbi}.
|
||||
|
||||
@subsection Options
|
||||
|
||||
@table @option
|
||||
@item txt_page
|
||||
List of teletext page numbers to decode. Pages that do not match the specified
|
||||
list are dropped. You may use the special @code{*} string to match all pages,
|
||||
or @code{subtitle} to match all subtitle pages.
|
||||
Default value is *.
|
||||
@item txt_default_region
|
||||
Set default character set used for decoding, a value between 0 and 87 (see
|
||||
ETS 300 706, Section 15, Table 32). Default value is -1, which does not
|
||||
override the libzvbi default. This option is needed for some legacy level 1.0
|
||||
transmissions which cannot signal the proper charset.
|
||||
@item txt_chop_top
|
||||
Discards the top teletext line. Default value is 1.
|
||||
@item txt_format
|
||||
Specifies the format of the decoded subtitles.
|
||||
@table @option
|
||||
@item bitmap
|
||||
The default format, you should use this for teletext pages, because certain
|
||||
graphics and colors cannot be expressed in simple text or even ASS.
|
||||
@item text
|
||||
Simple text based output without formatting.
|
||||
@item ass
|
||||
Formatted ASS output, subtitle pages and teletext pages are returned in
|
||||
different styles, subtitle pages are stripped down to text, but an effort is
|
||||
made to keep the text alignment and the formatting.
|
||||
@end table
|
||||
@item txt_left
|
||||
X offset of generated bitmaps, default is 0.
|
||||
@item txt_top
|
||||
Y offset of generated bitmaps, default is 0.
|
||||
@item txt_chop_spaces
|
||||
Chops leading and trailing spaces and removes empty lines from the generated
|
||||
text. This option is useful for teletext based subtitles where empty spaces may
|
||||
be present at the start or at the end of the lines or empty lines may be
|
||||
present between the subtitle lines because of double-sized teletext characters.
|
||||
Default value is 1.
|
||||
@item txt_duration
|
||||
Sets the display duration of the decoded teletext pages or subtitles in
|
||||
milliseconds. Default value is -1 which means infinity or until the next
|
||||
subtitle event comes.
|
||||
@item txt_transparent
|
||||
Force transparent background of the generated teletext bitmaps. Default value
|
||||
is 0 which means an opaque background.
|
||||
@item txt_opacity
|
||||
Sets the opacity (0-255) of the teletext background. If
|
||||
@option{txt_transparent} is not set, it only affects characters between a start
|
||||
box and an end box, typically subtitles. Default value is 0 if
|
||||
@option{txt_transparent} is set, 255 otherwise.
|
||||
|
||||
@end table
|
||||
|
||||
@c man end SUBTITLES DECODERS
|
||||
165
doc/default.css
165
doc/default.css
@@ -1,165 +0,0 @@
|
||||
a.summary-letter {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #2D6198;
|
||||
}
|
||||
|
||||
a:visited {
|
||||
color: #884488;
|
||||
}
|
||||
|
||||
#banner {
|
||||
background-color: white;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#banner img {
|
||||
margin-bottom: 1px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
#body {
|
||||
margin-left: 1em;
|
||||
margin-right: 1em;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: #313131;
|
||||
margin: 0;
|
||||
text-align: justify;
|
||||
}
|
||||
|
||||
.center {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#container {
|
||||
background-color: white;
|
||||
color: #202020;
|
||||
margin-left: 1em;
|
||||
margin-right: 1em;
|
||||
}
|
||||
|
||||
#footer {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
h1 a, h2 a, h3 a, h4 a {
|
||||
text-decoration: inherit;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4 {
|
||||
padding-left: 0.4em;
|
||||
border-radius: 4px;
|
||||
padding-bottom: 0.25em;
|
||||
padding-top: 0.25em;
|
||||
border: 1px solid #6A996A;
|
||||
}
|
||||
|
||||
h1 {
|
||||
background-color: #7BB37B;
|
||||
color: #151515;
|
||||
font-size: 1.2em;
|
||||
padding-bottom: 0.3em;
|
||||
padding-top: 0.3em;
|
||||
}
|
||||
|
||||
h2 {
|
||||
color: #313131;
|
||||
font-size: 1.0em;
|
||||
background-color: #ABE3AB;
|
||||
}
|
||||
|
||||
h3 {
|
||||
color: #313131;
|
||||
font-size: 0.9em;
|
||||
margin-bottom: -6px;
|
||||
background-color: #BBF3BB;
|
||||
}
|
||||
|
||||
h4 {
|
||||
color: #313131;
|
||||
font-size: 0.8em;
|
||||
margin-bottom: -8px;
|
||||
background-color: #D1FDD1;
|
||||
}
|
||||
|
||||
img {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
#navbar {
|
||||
background-color: #738073;
|
||||
border-bottom: 1px solid #5C665C;
|
||||
border-top: 1px solid #5C665C;
|
||||
margin-top: 12px;
|
||||
padding: 0.3em;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#navbar a, #navbar_secondary a {
|
||||
color: white;
|
||||
padding: 0.3em;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
#navbar a:hover, #navbar_secondary a:hover {
|
||||
background-color: #313131;
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
#navbar_secondary {
|
||||
background-color: #738073;
|
||||
border-bottom: 1px solid #5C665C;
|
||||
border-left: 1px solid #5C665C;
|
||||
border-right: 1px solid #5C665C;
|
||||
padding: 0.3em;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-left: 1em;
|
||||
margin-right: 1em;
|
||||
}
|
||||
|
||||
pre {
|
||||
margin-left: 3em;
|
||||
margin-right: 3em;
|
||||
padding: 0.3em;
|
||||
border: 1px solid #bbb;
|
||||
background-color: #f7f7f7;
|
||||
}
|
||||
|
||||
dl dt {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#proj_desc {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
#repos {
|
||||
margin-left: 1em;
|
||||
margin-right: 1em;
|
||||
border-collapse: collapse;
|
||||
border: solid 1px #6A996A;
|
||||
}
|
||||
|
||||
#repos th {
|
||||
background-color: #7BB37B;
|
||||
border: solid 1px #6A996A;
|
||||
}
|
||||
|
||||
#repos td {
|
||||
padding: 0.2em;
|
||||
border: solid 1px #6A996A;
|
||||
}
|
||||
1191
doc/demuxers.texi
1191
doc/demuxers.texi
File diff suppressed because it is too large
Load Diff
1223
doc/developer.texi
1223
doc/developer.texi
File diff suppressed because it is too large
Load Diff
@@ -1,25 +0,0 @@
|
||||
@chapter Device Options
|
||||
@c man begin DEVICE OPTIONS
|
||||
|
||||
The libavdevice library provides the same interface as
|
||||
libavformat. Namely, an input device is considered like a demuxer, and
|
||||
an output device like a muxer, and the interface and generic device
|
||||
options are the same provided by libavformat (see the ffmpeg-formats
|
||||
manual).
|
||||
|
||||
In addition each input or output device may support so-called private
|
||||
options, which are specific for that component.
|
||||
|
||||
Options may be set by specifying -@var{option} @var{value} in the
|
||||
FFmpeg tools, or by setting the value explicitly in the device
|
||||
@code{AVFormatContext} options or using the @file{libavutil/opt.h} API
|
||||
for programmatic use.
|
||||
|
||||
@c man end DEVICE OPTIONS
|
||||
|
||||
@ifclear config-writeonly
|
||||
@include indevs.texi
|
||||
@end ifclear
|
||||
@ifclear config-readonly
|
||||
@include outdevs.texi
|
||||
@end ifclear
|
||||
@@ -1,24 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
OUT_DIR="${1}"
|
||||
SRC_DIR="${2}"
|
||||
DOXYFILE="${3}"
|
||||
DOXYGEN="${4}"
|
||||
|
||||
shift 4
|
||||
|
||||
cd ${SRC_DIR}
|
||||
|
||||
if [ -e "VERSION" ]; then
|
||||
VERSION=`cat "VERSION"`
|
||||
else
|
||||
VERSION=`git describe`
|
||||
fi
|
||||
|
||||
$DOXYGEN - <<EOF
|
||||
@INCLUDE = ${DOXYFILE}
|
||||
INPUT = $@
|
||||
HTML_TIMESTAMP = NO
|
||||
PROJECT_NUMBER = $VERSION
|
||||
OUTPUT_DIRECTORY = $OUT_DIR
|
||||
EOF
|
||||
1
doc/doxy/.gitignore
vendored
1
doc/doxy/.gitignore
vendored
@@ -1 +0,0 @@
|
||||
/html/
|
||||
4665
doc/encoders.texi
4665
doc/encoders.texi
File diff suppressed because it is too large
Load Diff
174
doc/errno.txt
174
doc/errno.txt
@@ -1,174 +0,0 @@
|
||||
The following table lists most error codes found in various operating
|
||||
systems supported by FFmpeg.
|
||||
|
||||
OS
|
||||
Code Std F LBMWwb Text (YMMV)
|
||||
|
||||
E2BIG POSIX ++++++ Argument list too long
|
||||
EACCES POSIX ++++++ Permission denied
|
||||
EADDRINUSE POSIX +++..+ Address in use
|
||||
EADDRNOTAVAIL POSIX +++..+ Cannot assign requested address
|
||||
EADV +..... Advertise error
|
||||
EAFNOSUPPORT POSIX +++..+ Address family not supported
|
||||
EAGAIN POSIX + ++++++ Resource temporarily unavailable
|
||||
EALREADY POSIX +++..+ Operation already in progress
|
||||
EAUTH .++... Authentication error
|
||||
EBADARCH ..+... Bad CPU type in executable
|
||||
EBADE +..... Invalid exchange
|
||||
EBADEXEC ..+... Bad executable
|
||||
EBADF POSIX ++++++ Bad file descriptor
|
||||
EBADFD +..... File descriptor in bad state
|
||||
EBADMACHO ..+... Malformed Macho file
|
||||
EBADMSG POSIX ++4... Bad message
|
||||
EBADR +..... Invalid request descriptor
|
||||
EBADRPC .++... RPC struct is bad
|
||||
EBADRQC +..... Invalid request code
|
||||
EBADSLT +..... Invalid slot
|
||||
EBFONT +..... Bad font file format
|
||||
EBUSY POSIX - ++++++ Device or resource busy
|
||||
ECANCELED POSIX +++... Operation canceled
|
||||
ECHILD POSIX ++++++ No child processes
|
||||
ECHRNG +..... Channel number out of range
|
||||
ECOMM +..... Communication error on send
|
||||
ECONNABORTED POSIX +++..+ Software caused connection abort
|
||||
ECONNREFUSED POSIX - +++ss+ Connection refused
|
||||
ECONNRESET POSIX +++..+ Connection reset
|
||||
EDEADLK POSIX ++++++ Resource deadlock avoided
|
||||
EDEADLOCK +..++. File locking deadlock error
|
||||
EDESTADDRREQ POSIX +++... Destination address required
|
||||
EDEVERR ..+... Device error
|
||||
EDOM C89 - ++++++ Numerical argument out of domain
|
||||
EDOOFUS .F.... Programming error
|
||||
EDOTDOT +..... RFS specific error
|
||||
EDQUOT POSIX +++... Disc quota exceeded
|
||||
EEXIST POSIX ++++++ File exists
|
||||
EFAULT POSIX - ++++++ Bad address
|
||||
EFBIG POSIX - ++++++ File too large
|
||||
EFTYPE .++... Inappropriate file type or format
|
||||
EHOSTDOWN +++... Host is down
|
||||
EHOSTUNREACH POSIX +++..+ No route to host
|
||||
EHWPOISON +..... Memory page has hardware error
|
||||
EIDRM POSIX +++... Identifier removed
|
||||
EILSEQ C99 ++++++ Illegal byte sequence
|
||||
EINPROGRESS POSIX - +++ss+ Operation in progress
|
||||
EINTR POSIX - ++++++ Interrupted system call
|
||||
EINVAL POSIX + ++++++ Invalid argument
|
||||
EIO POSIX + ++++++ I/O error
|
||||
EISCONN POSIX +++..+ Socket is already connected
|
||||
EISDIR POSIX ++++++ Is a directory
|
||||
EISNAM +..... Is a named type file
|
||||
EKEYEXPIRED +..... Key has expired
|
||||
EKEYREJECTED +..... Key was rejected by service
|
||||
EKEYREVOKED +..... Key has been revoked
|
||||
EL2HLT +..... Level 2 halted
|
||||
EL2NSYNC +..... Level 2 not synchronized
|
||||
EL3HLT +..... Level 3 halted
|
||||
EL3RST +..... Level 3 reset
|
||||
ELIBACC +..... Can not access a needed shared library
|
||||
ELIBBAD +..... Accessing a corrupted shared library
|
||||
ELIBEXEC +..... Cannot exec a shared library directly
|
||||
ELIBMAX +..... Too many shared libraries
|
||||
ELIBSCN +..... .lib section in a.out corrupted
|
||||
ELNRNG +..... Link number out of range
|
||||
ELOOP POSIX +++..+ Too many levels of symbolic links
|
||||
EMEDIUMTYPE +..... Wrong medium type
|
||||
EMFILE POSIX ++++++ Too many open files
|
||||
EMLINK POSIX ++++++ Too many links
|
||||
EMSGSIZE POSIX +++..+ Message too long
|
||||
EMULTIHOP POSIX ++4... Multihop attempted
|
||||
ENAMETOOLONG POSIX - ++++++ File name too long
|
||||
ENAVAIL +..... No XENIX semaphores available
|
||||
ENEEDAUTH .++... Need authenticator
|
||||
ENETDOWN POSIX +++..+ Network is down
|
||||
ENETRESET SUSv3 +++..+ Network dropped connection on reset
|
||||
ENETUNREACH POSIX +++..+ Network unreachable
|
||||
ENFILE POSIX ++++++ Too many open files in system
|
||||
ENOANO +..... No anode
|
||||
ENOATTR .++... Attribute not found
|
||||
ENOBUFS POSIX - +++..+ No buffer space available
|
||||
ENOCSI +..... No CSI structure available
|
||||
ENODATA XSR +N4... No message available
|
||||
ENODEV POSIX - ++++++ No such device
|
||||
ENOENT POSIX - ++++++ No such file or directory
|
||||
ENOEXEC POSIX ++++++ Exec format error
|
||||
ENOFILE ...++. No such file or directory
|
||||
ENOKEY +..... Required key not available
|
||||
ENOLCK POSIX ++++++ No locks available
|
||||
ENOLINK POSIX ++4... Link has been severed
|
||||
ENOMEDIUM +..... No medium found
|
||||
ENOMEM POSIX ++++++ Not enough space
|
||||
ENOMSG POSIX +++..+ No message of desired type
|
||||
ENONET +..... Machine is not on the network
|
||||
ENOPKG +..... Package not installed
|
||||
ENOPROTOOPT POSIX +++..+ Protocol not available
|
||||
ENOSPC POSIX ++++++ No space left on device
|
||||
ENOSR XSR +N4... No STREAM resources
|
||||
ENOSTR XSR +N4... Not a STREAM
|
||||
ENOSYS POSIX + ++++++ Function not implemented
|
||||
ENOTBLK +++... Block device required
|
||||
ENOTCONN POSIX +++..+ Socket is not connected
|
||||
ENOTDIR POSIX ++++++ Not a directory
|
||||
ENOTEMPTY POSIX ++++++ Directory not empty
|
||||
ENOTNAM +..... Not a XENIX named type file
|
||||
ENOTRECOVERABLE SUSv4 - +..... State not recoverable
|
||||
ENOTSOCK POSIX +++..+ Socket operation on non-socket
|
||||
ENOTSUP POSIX +++... Operation not supported
|
||||
ENOTTY POSIX ++++++ Inappropriate I/O control operation
|
||||
ENOTUNIQ +..... Name not unique on network
|
||||
ENXIO POSIX ++++++ No such device or address
|
||||
EOPNOTSUPP POSIX +++..+ Operation not supported (on socket)
|
||||
EOVERFLOW POSIX +++..+ Value too large to be stored in data type
|
||||
EOWNERDEAD SUSv4 +..... Owner died
|
||||
EPERM POSIX - ++++++ Operation not permitted
|
||||
EPFNOSUPPORT +++..+ Protocol family not supported
|
||||
EPIPE POSIX - ++++++ Broken pipe
|
||||
EPROCLIM .++... Too many processes
|
||||
EPROCUNAVAIL .++... Bad procedure for program
|
||||
EPROGMISMATCH .++... Program version wrong
|
||||
EPROGUNAVAIL .++... RPC prog. not avail
|
||||
EPROTO POSIX ++4... Protocol error
|
||||
EPROTONOSUPPORT POSIX - +++ss+ Protocol not supported
|
||||
EPROTOTYPE POSIX +++..+ Protocol wrong type for socket
|
||||
EPWROFF ..+... Device power is off
|
||||
ERANGE C89 - ++++++ Result too large
|
||||
EREMCHG +..... Remote address changed
|
||||
EREMOTE +++... Object is remote
|
||||
EREMOTEIO +..... Remote I/O error
|
||||
ERESTART +..... Interrupted system call should be restarted
|
||||
ERFKILL +..... Operation not possible due to RF-kill
|
||||
EROFS POSIX ++++++ Read-only file system
|
||||
ERPCMISMATCH .++... RPC version wrong
|
||||
ESHLIBVERS ..+... Shared library version mismatch
|
||||
ESHUTDOWN +++..+ Cannot send after socket shutdown
|
||||
ESOCKTNOSUPPORT +++... Socket type not supported
|
||||
ESPIPE POSIX ++++++ Illegal seek
|
||||
ESRCH POSIX ++++++ No such process
|
||||
ESRMNT +..... Srmount error
|
||||
ESTALE POSIX +++..+ Stale NFS file handle
|
||||
ESTRPIPE +..... Streams pipe error
|
||||
ETIME XSR +N4... Stream ioctl timeout
|
||||
ETIMEDOUT POSIX - +++ss+ Connection timed out
|
||||
ETOOMANYREFS +++... Too many references: cannot splice
|
||||
ETXTBSY POSIX +++... Text file busy
|
||||
EUCLEAN +..... Structure needs cleaning
|
||||
EUNATCH +..... Protocol driver not attached
|
||||
EUSERS +++... Too many users
|
||||
EWOULDBLOCK POSIX +++..+ Operation would block
|
||||
EXDEV POSIX ++++++ Cross-device link
|
||||
EXFULL +..... Exchange full
|
||||
|
||||
Notations:
|
||||
|
||||
F: used in FFmpeg (-: a few times, +: a lot)
|
||||
|
||||
SUSv3: Single Unix Specification, version 3
|
||||
SUSv4: Single Unix Specification, version 4
|
||||
XSR: XSI STREAMS (obsolete)
|
||||
|
||||
OS: availability on some supported operating systems
|
||||
L: GNU/Linux
|
||||
B: BSD (F: FreeBSD, N: NetBSD)
|
||||
M: MacOS X
|
||||
W: Microsoft Windows (s: emulated with winsock, see libavformat/network.h)
|
||||
w: Mingw32 (3.17) and Mingw64 (2.0.1)
|
||||
b: BeOS
|
||||
25
doc/examples/.gitignore
vendored
25
doc/examples/.gitignore
vendored
@@ -1,25 +0,0 @@
|
||||
/avio_list_dir
|
||||
/avio_reading
|
||||
/decode_audio
|
||||
/decode_video
|
||||
/demuxing_decoding
|
||||
/encode_audio
|
||||
/encode_video
|
||||
/extract_mvs
|
||||
/filter_audio
|
||||
/filtering_audio
|
||||
/filtering_video
|
||||
/http_multiclient
|
||||
/hw_decode
|
||||
/metadata
|
||||
/muxing
|
||||
/pc-uninstalled
|
||||
/qsvdec
|
||||
/remuxing
|
||||
/resampling_audio
|
||||
/scaling_video
|
||||
/transcode_aac
|
||||
/transcoding
|
||||
/vaapi_encode
|
||||
/vaapi_transcode
|
||||
/qsv_transcode
|
||||
@@ -1,65 +0,0 @@
|
||||
EXAMPLES-$(CONFIG_AVIO_HTTP_SERVE_FILES) += avio_http_serve_files
|
||||
EXAMPLES-$(CONFIG_AVIO_LIST_DIR_EXAMPLE) += avio_list_dir
|
||||
EXAMPLES-$(CONFIG_AVIO_READ_CALLBACK_EXAMPLE) += avio_read_callback
|
||||
EXAMPLES-$(CONFIG_DECODE_AUDIO_EXAMPLE) += decode_audio
|
||||
EXAMPLES-$(CONFIG_DECODE_FILTER_AUDIO_EXAMPLE) += decode_filter_audio
|
||||
EXAMPLES-$(CONFIG_DECODE_FILTER_VIDEO_EXAMPLE) += decode_filter_video
|
||||
EXAMPLES-$(CONFIG_DECODE_VIDEO_EXAMPLE) += decode_video
|
||||
EXAMPLES-$(CONFIG_DEMUX_DECODE_EXAMPLE) += demux_decode
|
||||
EXAMPLES-$(CONFIG_ENCODE_AUDIO_EXAMPLE) += encode_audio
|
||||
EXAMPLES-$(CONFIG_ENCODE_VIDEO_EXAMPLE) += encode_video
|
||||
EXAMPLES-$(CONFIG_EXTRACT_MVS_EXAMPLE) += extract_mvs
|
||||
EXAMPLES-$(CONFIG_FILTER_AUDIO_EXAMPLE) += filter_audio
|
||||
EXAMPLES-$(CONFIG_HW_DECODE_EXAMPLE) += hw_decode
|
||||
EXAMPLES-$(CONFIG_MUX_EXAMPLE) += mux
|
||||
EXAMPLES-$(CONFIG_QSV_DECODE_EXAMPLE) += qsv_decode
|
||||
EXAMPLES-$(CONFIG_REMUX_EXAMPLE) += remux
|
||||
EXAMPLES-$(CONFIG_RESAMPLE_AUDIO_EXAMPLE) += resample_audio
|
||||
EXAMPLES-$(CONFIG_SCALE_VIDEO_EXAMPLE) += scale_video
|
||||
EXAMPLES-$(CONFIG_SHOW_METADATA_EXAMPLE) += show_metadata
|
||||
EXAMPLES-$(CONFIG_TRANSCODE_AAC_EXAMPLE) += transcode_aac
|
||||
EXAMPLES-$(CONFIG_TRANSCODE_EXAMPLE) += transcode
|
||||
EXAMPLES-$(CONFIG_VAAPI_ENCODE_EXAMPLE) += vaapi_encode
|
||||
EXAMPLES-$(CONFIG_VAAPI_TRANSCODE_EXAMPLE) += vaapi_transcode
|
||||
EXAMPLES-$(CONFIG_QSV_TRANSCODE_EXAMPLE) += qsv_transcode
|
||||
|
||||
EXAMPLES := $(EXAMPLES-yes:%=doc/examples/%$(PROGSSUF)$(EXESUF))
|
||||
EXAMPLES_G := $(EXAMPLES-yes:%=doc/examples/%$(PROGSSUF)_g$(EXESUF))
|
||||
ALL_EXAMPLES := $(EXAMPLES) $(EXAMPLES-:%=doc/examples/%$(PROGSSUF)$(EXESUF))
|
||||
ALL_EXAMPLES_G := $(EXAMPLES_G) $(EXAMPLES-:%=doc/examples/%$(PROGSSUF)_g$(EXESUF))
|
||||
PROGS += $(EXAMPLES)
|
||||
|
||||
EXAMPLE_MAKEFILE := $(SRC_PATH)/doc/examples/Makefile
|
||||
EXAMPLES_FILES := $(wildcard $(SRC_PATH)/doc/examples/*.c) $(SRC_PATH)/doc/examples/README $(EXAMPLE_MAKEFILE)
|
||||
|
||||
$(foreach P,$(EXAMPLES),$(eval OBJS-$(P:%$(PROGSSUF)$(EXESUF)=%) = $(P:%$(PROGSSUF)$(EXESUF)=%).o))
|
||||
$(EXAMPLES_G): %$(PROGSSUF)_g$(EXESUF): %.o
|
||||
|
||||
examples: $(EXAMPLES)
|
||||
|
||||
$(EXAMPLES:%$(PROGSSUF)$(EXESUF)=%.o): | doc/examples
|
||||
OUTDIRS += doc/examples
|
||||
|
||||
DOXY_INPUT += $(EXAMPLES:%$(PROGSSUF)$(EXESUF)=%.c)
|
||||
|
||||
install: install-examples
|
||||
|
||||
install-examples: $(EXAMPLES_FILES)
|
||||
$(Q)mkdir -p "$(DATADIR)/examples"
|
||||
$(INSTALL) -m 644 $(EXAMPLES_FILES) "$(DATADIR)/examples"
|
||||
$(INSTALL) -m 644 $(EXAMPLE_MAKEFILE:%=%.example) "$(DATADIR)/examples/Makefile"
|
||||
|
||||
uninstall: uninstall-examples
|
||||
|
||||
uninstall-examples:
|
||||
$(RM) -r "$(DATADIR)/examples"
|
||||
|
||||
examplesclean:
|
||||
$(RM) $(ALL_EXAMPLES) $(ALL_EXAMPLES_G)
|
||||
$(RM) $(CLEANSUFFIXES:%=doc/examples/%)
|
||||
|
||||
docclean:: examplesclean
|
||||
|
||||
-include $(wildcard $(EXAMPLES:%$(PROGSSUF)$(EXESUF)=%.d))
|
||||
|
||||
.PHONY: examples
|
||||
@@ -1,57 +0,0 @@
|
||||
# use pkg-config for getting CFLAGS and LDLIBS
|
||||
FFMPEG_LIBS= libavdevice \
|
||||
libavformat \
|
||||
libavfilter \
|
||||
libavcodec \
|
||||
libswresample \
|
||||
libswscale \
|
||||
libavutil \
|
||||
|
||||
CFLAGS += -Wall -g
|
||||
CFLAGS := $(shell pkg-config --cflags $(FFMPEG_LIBS)) $(CFLAGS)
|
||||
LDLIBS := $(shell pkg-config --libs $(FFMPEG_LIBS)) $(LDLIBS)
|
||||
|
||||
# missing the following targets, since they need special options in the FFmpeg build:
|
||||
# qsv_decode
|
||||
# qsv_transcode
|
||||
# vaapi_encode
|
||||
# vaapi_transcode
|
||||
|
||||
EXAMPLES=\
|
||||
avio_http_serve_files \
|
||||
avio_list_dir \
|
||||
avio_read_callback \
|
||||
decode_audio \
|
||||
decode_filter_audio \
|
||||
decode_filter_video \
|
||||
decode_video \
|
||||
demux_decode \
|
||||
encode_audio \
|
||||
encode_video \
|
||||
extract_mvs \
|
||||
hw_decode \
|
||||
mux \
|
||||
remux \
|
||||
resample_audio \
|
||||
scale_video \
|
||||
show_metadata \
|
||||
transcode_aac \
|
||||
transcode
|
||||
|
||||
OBJS=$(addsuffix .o,$(EXAMPLES))
|
||||
|
||||
# the following examples make explicit use of the math library
|
||||
avcodec: LDLIBS += -lm
|
||||
encode_audio: LDLIBS += -lm
|
||||
mux: LDLIBS += -lm
|
||||
resample_audio: LDLIBS += -lm
|
||||
|
||||
.phony: all clean-test clean
|
||||
|
||||
all: $(OBJS) $(EXAMPLES)
|
||||
|
||||
clean-test:
|
||||
$(RM) test*.pgm test.h264 test.mp2 test.sw test.mpg
|
||||
|
||||
clean: clean-test
|
||||
$(RM) $(EXAMPLES) $(OBJS)
|
||||
@@ -1,25 +0,0 @@
|
||||
FFmpeg examples README
|
||||
----------------------
|
||||
|
||||
Both following use cases rely on pkg-config and make, thus make sure
|
||||
that you have them installed and working on your system.
|
||||
|
||||
|
||||
Method 1: build the installed examples in a generic read/write user directory
|
||||
|
||||
Copy to a read/write user directory and run:
|
||||
make -f Makefile.example
|
||||
|
||||
It will link to the libraries on your system, assuming the PKG_CONFIG_PATH is
|
||||
correctly configured.
|
||||
|
||||
Method 2: build the examples in-tree
|
||||
|
||||
Assuming you are in the source FFmpeg checkout directory, you need to build
|
||||
FFmpeg (no need to make install in any prefix). Then just run "make examples".
|
||||
This will build the examples using the FFmpeg build system. You can clean those
|
||||
examples using "make examplesclean"
|
||||
|
||||
If you want to try the dedicated Makefile examples (to emulate the first
|
||||
method), go into doc/examples and run a command such as
|
||||
PKG_CONFIG_PATH=pc-uninstalled make -f Makefile.example
|
||||
@@ -1,155 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2015 Stephan Holljes
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file libavformat multi-client network API usage example
|
||||
* @example avio_http_serve_files.c
|
||||
*
|
||||
* Serve a file without decoding or demuxing it over the HTTP protocol. Multiple
|
||||
* clients can connect and will receive the same file.
|
||||
*/
|
||||
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libavutil/opt.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static void process_client(AVIOContext *client, const char *in_uri)
|
||||
{
|
||||
AVIOContext *input = NULL;
|
||||
uint8_t buf[1024];
|
||||
int ret, n, reply_code;
|
||||
uint8_t *resource = NULL;
|
||||
while ((ret = avio_handshake(client)) > 0) {
|
||||
av_opt_get(client, "resource", AV_OPT_SEARCH_CHILDREN, &resource);
|
||||
// check for strlen(resource) is necessary, because av_opt_get()
|
||||
// may return empty string.
|
||||
if (resource && strlen(resource))
|
||||
break;
|
||||
av_freep(&resource);
|
||||
}
|
||||
if (ret < 0)
|
||||
goto end;
|
||||
av_log(client, AV_LOG_TRACE, "resource=%p\n", resource);
|
||||
if (resource && resource[0] == '/' && !strcmp((resource + 1), in_uri)) {
|
||||
reply_code = 200;
|
||||
} else {
|
||||
reply_code = AVERROR_HTTP_NOT_FOUND;
|
||||
}
|
||||
if ((ret = av_opt_set_int(client, "reply_code", reply_code, AV_OPT_SEARCH_CHILDREN)) < 0) {
|
||||
av_log(client, AV_LOG_ERROR, "Failed to set reply_code: %s.\n", av_err2str(ret));
|
||||
goto end;
|
||||
}
|
||||
av_log(client, AV_LOG_TRACE, "Set reply code to %d\n", reply_code);
|
||||
|
||||
while ((ret = avio_handshake(client)) > 0);
|
||||
|
||||
if (ret < 0)
|
||||
goto end;
|
||||
|
||||
fprintf(stderr, "Handshake performed.\n");
|
||||
if (reply_code != 200)
|
||||
goto end;
|
||||
fprintf(stderr, "Opening input file.\n");
|
||||
if ((ret = avio_open2(&input, in_uri, AVIO_FLAG_READ, NULL, NULL)) < 0) {
|
||||
av_log(input, AV_LOG_ERROR, "Failed to open input: %s: %s.\n", in_uri,
|
||||
av_err2str(ret));
|
||||
goto end;
|
||||
}
|
||||
for(;;) {
|
||||
n = avio_read(input, buf, sizeof(buf));
|
||||
if (n < 0) {
|
||||
if (n == AVERROR_EOF)
|
||||
break;
|
||||
av_log(input, AV_LOG_ERROR, "Error reading from input: %s.\n",
|
||||
av_err2str(n));
|
||||
break;
|
||||
}
|
||||
avio_write(client, buf, n);
|
||||
avio_flush(client);
|
||||
}
|
||||
end:
|
||||
fprintf(stderr, "Flushing client\n");
|
||||
avio_flush(client);
|
||||
fprintf(stderr, "Closing client\n");
|
||||
avio_close(client);
|
||||
fprintf(stderr, "Closing input\n");
|
||||
avio_close(input);
|
||||
av_freep(&resource);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
AVDictionary *options = NULL;
|
||||
AVIOContext *client = NULL, *server = NULL;
|
||||
const char *in_uri, *out_uri;
|
||||
int ret, pid;
|
||||
av_log_set_level(AV_LOG_TRACE);
|
||||
if (argc < 3) {
|
||||
printf("usage: %s input http://hostname[:port]\n"
|
||||
"API example program to serve http to multiple clients.\n"
|
||||
"\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
in_uri = argv[1];
|
||||
out_uri = argv[2];
|
||||
|
||||
avformat_network_init();
|
||||
|
||||
if ((ret = av_dict_set(&options, "listen", "2", 0)) < 0) {
|
||||
fprintf(stderr, "Failed to set listen mode for server: %s\n", av_err2str(ret));
|
||||
return ret;
|
||||
}
|
||||
if ((ret = avio_open2(&server, out_uri, AVIO_FLAG_WRITE, NULL, &options)) < 0) {
|
||||
fprintf(stderr, "Failed to open server: %s\n", av_err2str(ret));
|
||||
return ret;
|
||||
}
|
||||
fprintf(stderr, "Entering main loop.\n");
|
||||
for(;;) {
|
||||
if ((ret = avio_accept(server, &client)) < 0)
|
||||
goto end;
|
||||
fprintf(stderr, "Accepted client, forking process.\n");
|
||||
// XXX: Since we don't reap our children and don't ignore signals
|
||||
// this produces zombie processes.
|
||||
pid = fork();
|
||||
if (pid < 0) {
|
||||
perror("Fork failed");
|
||||
ret = AVERROR(errno);
|
||||
goto end;
|
||||
}
|
||||
if (pid == 0) {
|
||||
fprintf(stderr, "In child.\n");
|
||||
process_client(client, in_uri);
|
||||
avio_close(server);
|
||||
exit(0);
|
||||
}
|
||||
if (pid > 0)
|
||||
avio_close(client);
|
||||
}
|
||||
end:
|
||||
avio_close(server);
|
||||
if (ret < 0 && ret != AVERROR_EOF) {
|
||||
fprintf(stderr, "Some errors occurred: %s\n", av_err2str(ret));
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1,137 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Lukasz Marek
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file libavformat AVIOContext list directory API usage example
|
||||
* @example avio_list_dir.c
|
||||
*
|
||||
* Show how to list directories through the libavformat AVIOContext API.
|
||||
*/
|
||||
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libavformat/avio.h>
|
||||
|
||||
static const char *type_string(int type)
|
||||
{
|
||||
switch (type) {
|
||||
case AVIO_ENTRY_DIRECTORY:
|
||||
return "<DIR>";
|
||||
case AVIO_ENTRY_FILE:
|
||||
return "<FILE>";
|
||||
case AVIO_ENTRY_BLOCK_DEVICE:
|
||||
return "<BLOCK DEVICE>";
|
||||
case AVIO_ENTRY_CHARACTER_DEVICE:
|
||||
return "<CHARACTER DEVICE>";
|
||||
case AVIO_ENTRY_NAMED_PIPE:
|
||||
return "<PIPE>";
|
||||
case AVIO_ENTRY_SYMBOLIC_LINK:
|
||||
return "<LINK>";
|
||||
case AVIO_ENTRY_SOCKET:
|
||||
return "<SOCKET>";
|
||||
case AVIO_ENTRY_SERVER:
|
||||
return "<SERVER>";
|
||||
case AVIO_ENTRY_SHARE:
|
||||
return "<SHARE>";
|
||||
case AVIO_ENTRY_WORKGROUP:
|
||||
return "<WORKGROUP>";
|
||||
case AVIO_ENTRY_UNKNOWN:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return "<UNKNOWN>";
|
||||
}
|
||||
|
||||
static int list_op(const char *input_dir)
|
||||
{
|
||||
AVIODirEntry *entry = NULL;
|
||||
AVIODirContext *ctx = NULL;
|
||||
int cnt, ret;
|
||||
char filemode[4], uid_and_gid[20];
|
||||
|
||||
if ((ret = avio_open_dir(&ctx, input_dir, NULL)) < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot open directory: %s.\n", av_err2str(ret));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
cnt = 0;
|
||||
for (;;) {
|
||||
if ((ret = avio_read_dir(ctx, &entry)) < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot list directory: %s.\n", av_err2str(ret));
|
||||
goto fail;
|
||||
}
|
||||
if (!entry)
|
||||
break;
|
||||
if (entry->filemode == -1) {
|
||||
snprintf(filemode, 4, "???");
|
||||
} else {
|
||||
snprintf(filemode, 4, "%3"PRIo64, entry->filemode);
|
||||
}
|
||||
snprintf(uid_and_gid, 20, "%"PRId64"(%"PRId64")", entry->user_id, entry->group_id);
|
||||
if (cnt == 0)
|
||||
av_log(NULL, AV_LOG_INFO, "%-9s %12s %30s %10s %s %16s %16s %16s\n",
|
||||
"TYPE", "SIZE", "NAME", "UID(GID)", "UGO", "MODIFIED",
|
||||
"ACCESSED", "STATUS_CHANGED");
|
||||
av_log(NULL, AV_LOG_INFO, "%-9s %12"PRId64" %30s %10s %s %16"PRId64" %16"PRId64" %16"PRId64"\n",
|
||||
type_string(entry->type),
|
||||
entry->size,
|
||||
entry->name,
|
||||
uid_and_gid,
|
||||
filemode,
|
||||
entry->modification_timestamp,
|
||||
entry->access_timestamp,
|
||||
entry->status_change_timestamp);
|
||||
avio_free_directory_entry(&entry);
|
||||
cnt++;
|
||||
};
|
||||
|
||||
fail:
|
||||
avio_close_dir(&ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void usage(const char *program_name)
|
||||
{
|
||||
fprintf(stderr, "usage: %s input_dir\n"
|
||||
"API example program to show how to list files in directory "
|
||||
"accessed through AVIOContext.\n", program_name);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int ret;
|
||||
|
||||
av_log_set_level(AV_LOG_DEBUG);
|
||||
|
||||
if (argc < 2) {
|
||||
usage(argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
avformat_network_init();
|
||||
|
||||
ret = list_op(argv[1]);
|
||||
|
||||
avformat_network_deinit();
|
||||
|
||||
return ret < 0 ? 1 : 0;
|
||||
}
|
||||
@@ -1,135 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Stefano Sabatini
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file libavformat AVIOContext read callback API usage example
|
||||
* @example avio_read_callback.c
|
||||
*
|
||||
* Make libavformat demuxer access media content through a custom
|
||||
* AVIOContext read callback.
|
||||
*/
|
||||
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libavformat/avio.h>
|
||||
#include <libavutil/file.h>
|
||||
#include <libavutil/mem.h>
|
||||
|
||||
struct buffer_data {
|
||||
uint8_t *ptr;
|
||||
size_t size; ///< size left in the buffer
|
||||
};
|
||||
|
||||
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
|
||||
{
|
||||
struct buffer_data *bd = (struct buffer_data *)opaque;
|
||||
buf_size = FFMIN(buf_size, bd->size);
|
||||
|
||||
if (!buf_size)
|
||||
return AVERROR_EOF;
|
||||
printf("ptr:%p size:%zu\n", bd->ptr, bd->size);
|
||||
|
||||
/* copy internal buffer data to buf */
|
||||
memcpy(buf, bd->ptr, buf_size);
|
||||
bd->ptr += buf_size;
|
||||
bd->size -= buf_size;
|
||||
|
||||
return buf_size;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
AVFormatContext *fmt_ctx = NULL;
|
||||
AVIOContext *avio_ctx = NULL;
|
||||
uint8_t *buffer = NULL, *avio_ctx_buffer = NULL;
|
||||
size_t buffer_size, avio_ctx_buffer_size = 4096;
|
||||
char *input_filename = NULL;
|
||||
int ret = 0;
|
||||
struct buffer_data bd = { 0 };
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "usage: %s input_file\n"
|
||||
"API example program to show how to read from a custom buffer "
|
||||
"accessed through AVIOContext.\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
input_filename = argv[1];
|
||||
|
||||
/* slurp file content into buffer */
|
||||
ret = av_file_map(input_filename, &buffer, &buffer_size, 0, NULL);
|
||||
if (ret < 0)
|
||||
goto end;
|
||||
|
||||
/* fill opaque structure used by the AVIOContext read callback */
|
||||
bd.ptr = buffer;
|
||||
bd.size = buffer_size;
|
||||
|
||||
if (!(fmt_ctx = avformat_alloc_context())) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto end;
|
||||
}
|
||||
|
||||
avio_ctx_buffer = av_malloc(avio_ctx_buffer_size);
|
||||
if (!avio_ctx_buffer) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto end;
|
||||
}
|
||||
avio_ctx = avio_alloc_context(avio_ctx_buffer, avio_ctx_buffer_size,
|
||||
0, &bd, &read_packet, NULL, NULL);
|
||||
if (!avio_ctx) {
|
||||
av_freep(&avio_ctx_buffer);
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto end;
|
||||
}
|
||||
fmt_ctx->pb = avio_ctx;
|
||||
|
||||
ret = avformat_open_input(&fmt_ctx, NULL, NULL, NULL);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Could not open input\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = avformat_find_stream_info(fmt_ctx, NULL);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Could not find stream information\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
av_dump_format(fmt_ctx, 0, input_filename, 0);
|
||||
|
||||
end:
|
||||
avformat_close_input(&fmt_ctx);
|
||||
|
||||
/* note: the internal buffer could have changed, and be != avio_ctx_buffer */
|
||||
if (avio_ctx)
|
||||
av_freep(&avio_ctx->buffer);
|
||||
avio_context_free(&avio_ctx);
|
||||
|
||||
av_file_unmap(buffer, buffer_size);
|
||||
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error occurred: %s\n", av_err2str(ret));
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,241 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2001 Fabrice Bellard
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file libavcodec audio decoding API usage example
|
||||
* @example decode_audio.c
|
||||
*
|
||||
* Decode data from an MP2 input file and generate a raw audio file to
|
||||
* be played with ffplay.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <libavutil/frame.h>
|
||||
#include <libavutil/mem.h>
|
||||
|
||||
#include <libavcodec/avcodec.h>
|
||||
|
||||
#define AUDIO_INBUF_SIZE 20480
|
||||
#define AUDIO_REFILL_THRESH 4096
|
||||
|
||||
static int get_format_from_sample_fmt(const char **fmt,
|
||||
enum AVSampleFormat sample_fmt)
|
||||
{
|
||||
int i;
|
||||
struct sample_fmt_entry {
|
||||
enum AVSampleFormat sample_fmt; const char *fmt_be, *fmt_le;
|
||||
} sample_fmt_entries[] = {
|
||||
{ AV_SAMPLE_FMT_U8, "u8", "u8" },
|
||||
{ AV_SAMPLE_FMT_S16, "s16be", "s16le" },
|
||||
{ AV_SAMPLE_FMT_S32, "s32be", "s32le" },
|
||||
{ AV_SAMPLE_FMT_FLT, "f32be", "f32le" },
|
||||
{ AV_SAMPLE_FMT_DBL, "f64be", "f64le" },
|
||||
};
|
||||
*fmt = NULL;
|
||||
|
||||
for (i = 0; i < FF_ARRAY_ELEMS(sample_fmt_entries); i++) {
|
||||
struct sample_fmt_entry *entry = &sample_fmt_entries[i];
|
||||
if (sample_fmt == entry->sample_fmt) {
|
||||
*fmt = AV_NE(entry->fmt_be, entry->fmt_le);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr,
|
||||
"sample format %s is not supported as output format\n",
|
||||
av_get_sample_fmt_name(sample_fmt));
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame,
|
||||
FILE *outfile)
|
||||
{
|
||||
int i, ch;
|
||||
int ret, data_size;
|
||||
|
||||
/* send the packet with the compressed data to the decoder */
|
||||
ret = avcodec_send_packet(dec_ctx, pkt);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error submitting the packet to the decoder\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* read all the output frames (in general there may be any number of them */
|
||||
while (ret >= 0) {
|
||||
ret = avcodec_receive_frame(dec_ctx, frame);
|
||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
|
||||
return;
|
||||
else if (ret < 0) {
|
||||
fprintf(stderr, "Error during decoding\n");
|
||||
exit(1);
|
||||
}
|
||||
data_size = av_get_bytes_per_sample(dec_ctx->sample_fmt);
|
||||
if (data_size < 0) {
|
||||
/* This should not occur, checking just for paranoia */
|
||||
fprintf(stderr, "Failed to calculate data size\n");
|
||||
exit(1);
|
||||
}
|
||||
for (i = 0; i < frame->nb_samples; i++)
|
||||
for (ch = 0; ch < dec_ctx->ch_layout.nb_channels; ch++)
|
||||
fwrite(frame->data[ch] + data_size*i, 1, data_size, outfile);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *outfilename, *filename;
|
||||
const AVCodec *codec;
|
||||
AVCodecContext *c= NULL;
|
||||
AVCodecParserContext *parser = NULL;
|
||||
int len, ret;
|
||||
FILE *f, *outfile;
|
||||
uint8_t inbuf[AUDIO_INBUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
|
||||
uint8_t *data;
|
||||
size_t data_size;
|
||||
AVPacket *pkt;
|
||||
AVFrame *decoded_frame = NULL;
|
||||
enum AVSampleFormat sfmt;
|
||||
int n_channels = 0;
|
||||
const char *fmt;
|
||||
|
||||
if (argc <= 2) {
|
||||
fprintf(stderr, "Usage: %s <input file> <output file>\n", argv[0]);
|
||||
exit(0);
|
||||
}
|
||||
filename = argv[1];
|
||||
outfilename = argv[2];
|
||||
|
||||
pkt = av_packet_alloc();
|
||||
if (!pkt) {
|
||||
fprintf(stderr, "Could not allocate AVPacket\n");
|
||||
exit(1); /* or proper cleanup and returning */
|
||||
}
|
||||
|
||||
/* find the MPEG audio decoder */
|
||||
codec = avcodec_find_decoder(AV_CODEC_ID_MP2);
|
||||
if (!codec) {
|
||||
fprintf(stderr, "Codec not found\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
parser = av_parser_init(codec->id);
|
||||
if (!parser) {
|
||||
fprintf(stderr, "Parser not found\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
c = avcodec_alloc_context3(codec);
|
||||
if (!c) {
|
||||
fprintf(stderr, "Could not allocate audio codec context\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* open it */
|
||||
if (avcodec_open2(c, codec, NULL) < 0) {
|
||||
fprintf(stderr, "Could not open codec\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
f = fopen(filename, "rb");
|
||||
if (!f) {
|
||||
fprintf(stderr, "Could not open %s\n", filename);
|
||||
exit(1);
|
||||
}
|
||||
outfile = fopen(outfilename, "wb");
|
||||
if (!outfile) {
|
||||
fprintf(stderr, "Could not open %s\n", outfilename);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* decode until eof */
|
||||
data = inbuf;
|
||||
data_size = fread(inbuf, 1, AUDIO_INBUF_SIZE, f);
|
||||
|
||||
while (data_size > 0) {
|
||||
if (!decoded_frame) {
|
||||
if (!(decoded_frame = av_frame_alloc())) {
|
||||
fprintf(stderr, "Could not allocate audio frame\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
ret = av_parser_parse2(parser, c, &pkt->data, &pkt->size,
|
||||
data, data_size,
|
||||
AV_NOPTS_VALUE, AV_NOPTS_VALUE, 0);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error while parsing\n");
|
||||
exit(1);
|
||||
}
|
||||
data += ret;
|
||||
data_size -= ret;
|
||||
|
||||
if (pkt->size)
|
||||
decode(c, pkt, decoded_frame, outfile);
|
||||
|
||||
if (data_size < AUDIO_REFILL_THRESH) {
|
||||
memmove(inbuf, data, data_size);
|
||||
data = inbuf;
|
||||
len = fread(data + data_size, 1,
|
||||
AUDIO_INBUF_SIZE - data_size, f);
|
||||
if (len > 0)
|
||||
data_size += len;
|
||||
}
|
||||
}
|
||||
|
||||
/* flush the decoder */
|
||||
pkt->data = NULL;
|
||||
pkt->size = 0;
|
||||
decode(c, pkt, decoded_frame, outfile);
|
||||
|
||||
/* print output pcm infomations, because there have no metadata of pcm */
|
||||
sfmt = c->sample_fmt;
|
||||
|
||||
if (av_sample_fmt_is_planar(sfmt)) {
|
||||
const char *packed = av_get_sample_fmt_name(sfmt);
|
||||
printf("Warning: the sample format the decoder produced is planar "
|
||||
"(%s). This example will output the first channel only.\n",
|
||||
packed ? packed : "?");
|
||||
sfmt = av_get_packed_sample_fmt(sfmt);
|
||||
}
|
||||
|
||||
n_channels = c->ch_layout.nb_channels;
|
||||
if ((ret = get_format_from_sample_fmt(&fmt, sfmt)) < 0)
|
||||
goto end;
|
||||
|
||||
printf("Play the output audio file with the command:\n"
|
||||
"ffplay -f %s -ac %d -ar %d %s\n",
|
||||
fmt, n_channels, c->sample_rate,
|
||||
outfilename);
|
||||
end:
|
||||
fclose(outfile);
|
||||
fclose(f);
|
||||
|
||||
avcodec_free_context(&c);
|
||||
av_parser_close(parser);
|
||||
av_frame_free(&decoded_frame);
|
||||
av_packet_free(&pkt);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,321 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Nicolas George
|
||||
* Copyright (c) 2011 Stefano Sabatini
|
||||
* Copyright (c) 2012 Clément Bœsch
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file audio decoding and filtering usage example
|
||||
* @example decode_filter_audio.c
|
||||
*
|
||||
* Demux, decode and filter audio input file, generate a raw audio
|
||||
* file to be played with ffplay.
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavformat/avformat.h>
|
||||
#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";
|
||||
static const char *player = "ffplay -f s16le -ar 8000 -ac 1 -";
|
||||
|
||||
static AVFormatContext *fmt_ctx;
|
||||
static AVCodecContext *dec_ctx;
|
||||
AVFilterContext *buffersink_ctx;
|
||||
AVFilterContext *buffersrc_ctx;
|
||||
AVFilterGraph *filter_graph;
|
||||
static int audio_stream_index = -1;
|
||||
|
||||
static int open_input_file(const char *filename)
|
||||
{
|
||||
const AVCodec *dec;
|
||||
int ret;
|
||||
|
||||
if ((ret = avformat_open_input(&fmt_ctx, filename, NULL, NULL)) < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot open input file\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((ret = avformat_find_stream_info(fmt_ctx, NULL)) < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot find stream information\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* select the audio stream */
|
||||
ret = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_AUDIO, -1, -1, &dec, 0);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot find an audio stream in the input file\n");
|
||||
return ret;
|
||||
}
|
||||
audio_stream_index = ret;
|
||||
|
||||
/* create decoding context */
|
||||
dec_ctx = avcodec_alloc_context3(dec);
|
||||
if (!dec_ctx)
|
||||
return AVERROR(ENOMEM);
|
||||
avcodec_parameters_to_context(dec_ctx, fmt_ctx->streams[audio_stream_index]->codecpar);
|
||||
|
||||
/* init the audio decoder */
|
||||
if ((ret = avcodec_open2(dec_ctx, dec, NULL)) < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot open audio decoder\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int init_filters(const char *filters_descr)
|
||||
{
|
||||
char args[512];
|
||||
int ret = 0;
|
||||
const AVFilter *abuffersrc = avfilter_get_by_name("abuffer");
|
||||
const AVFilter *abuffersink = avfilter_get_by_name("abuffersink");
|
||||
AVFilterInOut *outputs = avfilter_inout_alloc();
|
||||
AVFilterInOut *inputs = avfilter_inout_alloc();
|
||||
static const int out_sample_rate = 8000;
|
||||
const AVFilterLink *outlink;
|
||||
AVRational time_base = fmt_ctx->streams[audio_stream_index]->time_base;
|
||||
|
||||
filter_graph = avfilter_graph_alloc();
|
||||
if (!outputs || !inputs || !filter_graph) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* buffer audio source: the decoded frames from the decoder will be inserted here. */
|
||||
if (dec_ctx->ch_layout.order == AV_CHANNEL_ORDER_UNSPEC)
|
||||
av_channel_layout_default(&dec_ctx->ch_layout, dec_ctx->ch_layout.nb_channels);
|
||||
ret = snprintf(args, sizeof(args),
|
||||
"time_base=%d/%d:sample_rate=%d:sample_fmt=%s:channel_layout=",
|
||||
time_base.num, time_base.den, dec_ctx->sample_rate,
|
||||
av_get_sample_fmt_name(dec_ctx->sample_fmt));
|
||||
av_channel_layout_describe(&dec_ctx->ch_layout, args + ret, sizeof(args) - ret);
|
||||
ret = avfilter_graph_create_filter(&buffersrc_ctx, abuffersrc, "in",
|
||||
args, NULL, filter_graph);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot create audio buffer source\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* buffer audio sink: to terminate the filter chain. */
|
||||
buffersink_ctx = avfilter_graph_alloc_filter(filter_graph, abuffersink, "out");
|
||||
if (!buffersink_ctx) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot create audio buffer sink\n");
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = av_opt_set(buffersink_ctx, "sample_formats", "s16",
|
||||
AV_OPT_SEARCH_CHILDREN);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot set output sample format\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = av_opt_set(buffersink_ctx, "channel_layouts", "mono",
|
||||
AV_OPT_SEARCH_CHILDREN);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot set output channel layout\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = av_opt_set_array(buffersink_ctx, "samplerates", AV_OPT_SEARCH_CHILDREN,
|
||||
0, 1, AV_OPT_TYPE_INT, &out_sample_rate);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot set output sample rate\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = avfilter_init_dict(buffersink_ctx, NULL);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot initialize audio buffer sink\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the endpoints for the filter graph. The filter_graph will
|
||||
* be linked to the graph described by filters_descr.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The buffer source output must be connected to the input pad of
|
||||
* the first filter described by filters_descr; since the first
|
||||
* filter input label is not specified, it is set to "in" by
|
||||
* default.
|
||||
*/
|
||||
outputs->name = av_strdup("in");
|
||||
outputs->filter_ctx = buffersrc_ctx;
|
||||
outputs->pad_idx = 0;
|
||||
outputs->next = NULL;
|
||||
|
||||
/*
|
||||
* The buffer sink input must be connected to the output pad of
|
||||
* the last filter described by filters_descr; since the last
|
||||
* filter output label is not specified, it is set to "out" by
|
||||
* default.
|
||||
*/
|
||||
inputs->name = av_strdup("out");
|
||||
inputs->filter_ctx = buffersink_ctx;
|
||||
inputs->pad_idx = 0;
|
||||
inputs->next = NULL;
|
||||
|
||||
if ((ret = avfilter_graph_parse_ptr(filter_graph, filters_descr,
|
||||
&inputs, &outputs, NULL)) < 0)
|
||||
goto end;
|
||||
|
||||
if ((ret = avfilter_graph_config(filter_graph, NULL)) < 0)
|
||||
goto end;
|
||||
|
||||
/* Print summary of the sink buffer
|
||||
* Note: args buffer is reused to store channel layout string */
|
||||
outlink = buffersink_ctx->inputs[0];
|
||||
av_channel_layout_describe(&outlink->ch_layout, args, sizeof(args));
|
||||
av_log(NULL, AV_LOG_INFO, "Output: srate:%dHz fmt:%s chlayout:%s\n",
|
||||
(int)outlink->sample_rate,
|
||||
(char *)av_x_if_null(av_get_sample_fmt_name(outlink->format), "?"),
|
||||
args);
|
||||
|
||||
end:
|
||||
avfilter_inout_free(&inputs);
|
||||
avfilter_inout_free(&outputs);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void print_frame(const AVFrame *frame)
|
||||
{
|
||||
const int n = frame->nb_samples * frame->ch_layout.nb_channels;
|
||||
const uint16_t *p = (uint16_t*)frame->data[0];
|
||||
const uint16_t *p_end = p + n;
|
||||
|
||||
while (p < p_end) {
|
||||
fputc(*p & 0xff, stdout);
|
||||
fputc(*p>>8 & 0xff, stdout);
|
||||
p++;
|
||||
}
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int ret;
|
||||
AVPacket *packet = av_packet_alloc();
|
||||
AVFrame *frame = av_frame_alloc();
|
||||
AVFrame *filt_frame = av_frame_alloc();
|
||||
|
||||
if (!packet || !frame || !filt_frame) {
|
||||
fprintf(stderr, "Could not allocate frame or packet\n");
|
||||
exit(1);
|
||||
}
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "Usage: %s file | %s\n", argv[0], player);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ((ret = open_input_file(argv[1])) < 0)
|
||||
goto end;
|
||||
if ((ret = init_filters(filter_descr)) < 0)
|
||||
goto end;
|
||||
|
||||
/* read all packets */
|
||||
while (1) {
|
||||
if ((ret = av_read_frame(fmt_ctx, packet)) < 0)
|
||||
break;
|
||||
|
||||
if (packet->stream_index == audio_stream_index) {
|
||||
ret = avcodec_send_packet(dec_ctx, packet);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Error while sending a packet to the decoder\n");
|
||||
break;
|
||||
}
|
||||
|
||||
while (ret >= 0) {
|
||||
ret = avcodec_receive_frame(dec_ctx, frame);
|
||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
|
||||
break;
|
||||
} else if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Error while receiving a frame from the decoder\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (ret >= 0) {
|
||||
/* push the audio data from decoded frame into the filtergraph */
|
||||
if (av_buffersrc_add_frame_flags(buffersrc_ctx, frame, AV_BUFFERSRC_FLAG_KEEP_REF) < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Error while feeding the audio filtergraph\n");
|
||||
break;
|
||||
}
|
||||
|
||||
/* pull filtered audio 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);
|
||||
}
|
||||
av_frame_unref(frame);
|
||||
}
|
||||
}
|
||||
}
|
||||
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);
|
||||
avformat_close_input(&fmt_ctx);
|
||||
av_packet_free(&packet);
|
||||
av_frame_free(&frame);
|
||||
av_frame_free(&filt_frame);
|
||||
|
||||
if (ret < 0 && ret != AVERROR_EOF) {
|
||||
fprintf(stderr, "Error occurred: %s\n", av_err2str(ret));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
exit(0);
|
||||
}
|
||||
@@ -1,318 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Nicolas George
|
||||
* Copyright (c) 2011 Stefano Sabatini
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* API example for decoding and filtering
|
||||
* @example decode_filter_video.c
|
||||
*/
|
||||
|
||||
#define _XOPEN_SOURCE 600 /* for usleep */
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <libavcodec/avcodec.h>
|
||||
#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";
|
||||
/* other way:
|
||||
scale=78:24 [scl]; [scl] transpose=cclock // assumes "[in]" and "[out]" to be input output pads respectively
|
||||
*/
|
||||
|
||||
static AVFormatContext *fmt_ctx;
|
||||
static AVCodecContext *dec_ctx;
|
||||
AVFilterContext *buffersink_ctx;
|
||||
AVFilterContext *buffersrc_ctx;
|
||||
AVFilterGraph *filter_graph;
|
||||
static int video_stream_index = -1;
|
||||
static int64_t last_pts = AV_NOPTS_VALUE;
|
||||
|
||||
static int open_input_file(const char *filename)
|
||||
{
|
||||
const AVCodec *dec;
|
||||
int ret;
|
||||
|
||||
if ((ret = avformat_open_input(&fmt_ctx, filename, NULL, NULL)) < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot open input file\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((ret = avformat_find_stream_info(fmt_ctx, NULL)) < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot find stream information\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* select the video stream */
|
||||
ret = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, &dec, 0);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot find a video stream in the input file\n");
|
||||
return ret;
|
||||
}
|
||||
video_stream_index = ret;
|
||||
|
||||
/* create decoding context */
|
||||
dec_ctx = avcodec_alloc_context3(dec);
|
||||
if (!dec_ctx)
|
||||
return AVERROR(ENOMEM);
|
||||
avcodec_parameters_to_context(dec_ctx, fmt_ctx->streams[video_stream_index]->codecpar);
|
||||
|
||||
/* init the video decoder */
|
||||
if ((ret = avcodec_open2(dec_ctx, dec, NULL)) < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot open video decoder\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int init_filters(const char *filters_descr)
|
||||
{
|
||||
char args[512];
|
||||
int ret = 0;
|
||||
const AVFilter *buffersrc = avfilter_get_by_name("buffer");
|
||||
const AVFilter *buffersink = avfilter_get_by_name("buffersink");
|
||||
AVFilterInOut *outputs = avfilter_inout_alloc();
|
||||
AVFilterInOut *inputs = avfilter_inout_alloc();
|
||||
AVRational time_base = fmt_ctx->streams[video_stream_index]->time_base;
|
||||
|
||||
filter_graph = avfilter_graph_alloc();
|
||||
if (!outputs || !inputs || !filter_graph) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* buffer video source: the decoded frames from the decoder will be inserted here. */
|
||||
snprintf(args, sizeof(args),
|
||||
"video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
|
||||
dec_ctx->width, dec_ctx->height, dec_ctx->pix_fmt,
|
||||
time_base.num, time_base.den,
|
||||
dec_ctx->sample_aspect_ratio.num, dec_ctx->sample_aspect_ratio.den);
|
||||
|
||||
ret = avfilter_graph_create_filter(&buffersrc_ctx, buffersrc, "in",
|
||||
args, NULL, filter_graph);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot create buffer source\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* buffer video sink: to terminate the filter chain. */
|
||||
buffersink_ctx = avfilter_graph_alloc_filter(filter_graph, buffersink, "out");
|
||||
if (!buffersink_ctx) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot create buffer sink\n");
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = av_opt_set(buffersink_ctx, "pixel_formats", "gray8",
|
||||
AV_OPT_SEARCH_CHILDREN);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot set output pixel format\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = avfilter_init_dict(buffersink_ctx, NULL);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Cannot initialize buffer sink\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the endpoints for the filter graph. The filter_graph will
|
||||
* be linked to the graph described by filters_descr.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The buffer source output must be connected to the input pad of
|
||||
* the first filter described by filters_descr; since the first
|
||||
* filter input label is not specified, it is set to "in" by
|
||||
* default.
|
||||
*/
|
||||
outputs->name = av_strdup("in");
|
||||
outputs->filter_ctx = buffersrc_ctx;
|
||||
outputs->pad_idx = 0;
|
||||
outputs->next = NULL;
|
||||
|
||||
/*
|
||||
* The buffer sink input must be connected to the output pad of
|
||||
* the last filter described by filters_descr; since the last
|
||||
* filter output label is not specified, it is set to "out" by
|
||||
* default.
|
||||
*/
|
||||
inputs->name = av_strdup("out");
|
||||
inputs->filter_ctx = buffersink_ctx;
|
||||
inputs->pad_idx = 0;
|
||||
inputs->next = NULL;
|
||||
|
||||
if ((ret = avfilter_graph_parse_ptr(filter_graph, filters_descr,
|
||||
&inputs, &outputs, NULL)) < 0)
|
||||
goto end;
|
||||
|
||||
if ((ret = avfilter_graph_config(filter_graph, NULL)) < 0)
|
||||
goto end;
|
||||
|
||||
end:
|
||||
avfilter_inout_free(&inputs);
|
||||
avfilter_inout_free(&outputs);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void display_frame(const AVFrame *frame, AVRational time_base)
|
||||
{
|
||||
int x, y;
|
||||
uint8_t *p0, *p;
|
||||
int64_t delay;
|
||||
|
||||
if (frame->pts != AV_NOPTS_VALUE) {
|
||||
if (last_pts != AV_NOPTS_VALUE) {
|
||||
/* sleep roughly the right amount of time;
|
||||
* usleep is in microseconds, just like AV_TIME_BASE. */
|
||||
delay = av_rescale_q(frame->pts - last_pts,
|
||||
time_base, AV_TIME_BASE_Q);
|
||||
if (delay > 0 && delay < 1000000)
|
||||
usleep(delay);
|
||||
}
|
||||
last_pts = frame->pts;
|
||||
}
|
||||
|
||||
/* Trivial ASCII grayscale display. */
|
||||
p0 = frame->data[0];
|
||||
puts("\033c");
|
||||
for (y = 0; y < frame->height; y++) {
|
||||
p = p0;
|
||||
for (x = 0; x < frame->width; x++)
|
||||
putchar(" .-+#"[*(p++) / 52]);
|
||||
putchar('\n');
|
||||
p0 += frame->linesize[0];
|
||||
}
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int ret;
|
||||
AVPacket *packet;
|
||||
AVFrame *frame;
|
||||
AVFrame *filt_frame;
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "Usage: %s file\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
frame = av_frame_alloc();
|
||||
filt_frame = av_frame_alloc();
|
||||
packet = av_packet_alloc();
|
||||
if (!frame || !filt_frame || !packet) {
|
||||
fprintf(stderr, "Could not allocate frame or packet\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ((ret = open_input_file(argv[1])) < 0)
|
||||
goto end;
|
||||
if ((ret = init_filters(filter_descr)) < 0)
|
||||
goto end;
|
||||
|
||||
/* read all packets */
|
||||
while (1) {
|
||||
if ((ret = av_read_frame(fmt_ctx, packet)) < 0)
|
||||
break;
|
||||
|
||||
if (packet->stream_index == video_stream_index) {
|
||||
ret = avcodec_send_packet(dec_ctx, packet);
|
||||
if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Error while sending a packet to the decoder\n");
|
||||
break;
|
||||
}
|
||||
|
||||
while (ret >= 0) {
|
||||
ret = avcodec_receive_frame(dec_ctx, frame);
|
||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
|
||||
break;
|
||||
} else if (ret < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Error while receiving a frame from the decoder\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
frame->pts = frame->best_effort_timestamp;
|
||||
|
||||
/* push the decoded frame into the filtergraph */
|
||||
if (av_buffersrc_add_frame_flags(buffersrc_ctx, frame, AV_BUFFERSRC_FLAG_KEEP_REF) < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Error while feeding the filtergraph\n");
|
||||
break;
|
||||
}
|
||||
|
||||
/* pull filtered 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);
|
||||
}
|
||||
av_frame_unref(frame);
|
||||
}
|
||||
}
|
||||
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);
|
||||
avformat_close_input(&fmt_ctx);
|
||||
av_frame_free(&frame);
|
||||
av_frame_free(&filt_frame);
|
||||
av_packet_free(&packet);
|
||||
|
||||
if (ret < 0 && ret != AVERROR_EOF) {
|
||||
fprintf(stderr, "Error occurred: %s\n", av_err2str(ret));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
exit(0);
|
||||
}
|
||||
@@ -1,192 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2001 Fabrice Bellard
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file libavcodec video decoding API usage example
|
||||
* @example decode_video.c *
|
||||
*
|
||||
* Read from an MPEG1 video file, decode frames, and generate PGM images as
|
||||
* output.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <libavcodec/avcodec.h>
|
||||
|
||||
#define INBUF_SIZE 4096
|
||||
|
||||
static void pgm_save(unsigned char *buf, int wrap, int xsize, int ysize,
|
||||
char *filename)
|
||||
{
|
||||
FILE *f;
|
||||
int i;
|
||||
|
||||
f = fopen(filename,"wb");
|
||||
fprintf(f, "P5\n%d %d\n%d\n", xsize, ysize, 255);
|
||||
for (i = 0; i < ysize; i++)
|
||||
fwrite(buf + i * wrap, 1, xsize, f);
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
static void decode(AVCodecContext *dec_ctx, AVFrame *frame, AVPacket *pkt,
|
||||
const char *filename)
|
||||
{
|
||||
char buf[1024];
|
||||
int ret;
|
||||
|
||||
ret = avcodec_send_packet(dec_ctx, pkt);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error sending a packet for decoding\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
while (ret >= 0) {
|
||||
ret = avcodec_receive_frame(dec_ctx, frame);
|
||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
|
||||
return;
|
||||
else if (ret < 0) {
|
||||
fprintf(stderr, "Error during decoding\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("saving frame %3"PRId64"\n", dec_ctx->frame_num);
|
||||
fflush(stdout);
|
||||
|
||||
/* the picture is allocated by the decoder. no need to
|
||||
free it */
|
||||
snprintf(buf, sizeof(buf), "%s-%"PRId64, filename, dec_ctx->frame_num);
|
||||
pgm_save(frame->data[0], frame->linesize[0],
|
||||
frame->width, frame->height, buf);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *filename, *outfilename;
|
||||
const AVCodec *codec;
|
||||
AVCodecParserContext *parser;
|
||||
AVCodecContext *c= NULL;
|
||||
FILE *f;
|
||||
AVFrame *frame;
|
||||
uint8_t inbuf[INBUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
|
||||
uint8_t *data;
|
||||
size_t data_size;
|
||||
int ret;
|
||||
int eof;
|
||||
AVPacket *pkt;
|
||||
|
||||
if (argc <= 2) {
|
||||
fprintf(stderr, "Usage: %s <input file> <output file>\n"
|
||||
"And check your input file is encoded by mpeg1video please.\n", argv[0]);
|
||||
exit(0);
|
||||
}
|
||||
filename = argv[1];
|
||||
outfilename = argv[2];
|
||||
|
||||
pkt = av_packet_alloc();
|
||||
if (!pkt)
|
||||
exit(1);
|
||||
|
||||
/* set end of buffer to 0 (this ensures that no overreading happens for damaged MPEG streams) */
|
||||
memset(inbuf + INBUF_SIZE, 0, AV_INPUT_BUFFER_PADDING_SIZE);
|
||||
|
||||
/* find the MPEG-1 video decoder */
|
||||
codec = avcodec_find_decoder(AV_CODEC_ID_MPEG1VIDEO);
|
||||
if (!codec) {
|
||||
fprintf(stderr, "Codec not found\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
parser = av_parser_init(codec->id);
|
||||
if (!parser) {
|
||||
fprintf(stderr, "parser not found\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
c = avcodec_alloc_context3(codec);
|
||||
if (!c) {
|
||||
fprintf(stderr, "Could not allocate video codec context\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* For some codecs, such as msmpeg4 and mpeg4, width and height
|
||||
MUST be initialized there because this information is not
|
||||
available in the bitstream. */
|
||||
|
||||
/* open it */
|
||||
if (avcodec_open2(c, codec, NULL) < 0) {
|
||||
fprintf(stderr, "Could not open codec\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
f = fopen(filename, "rb");
|
||||
if (!f) {
|
||||
fprintf(stderr, "Could not open %s\n", filename);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
frame = av_frame_alloc();
|
||||
if (!frame) {
|
||||
fprintf(stderr, "Could not allocate video frame\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
do {
|
||||
/* read raw data from the input file */
|
||||
data_size = fread(inbuf, 1, INBUF_SIZE, f);
|
||||
if (ferror(f))
|
||||
break;
|
||||
eof = !data_size;
|
||||
|
||||
/* use the parser to split the data into frames */
|
||||
data = inbuf;
|
||||
while (data_size > 0 || eof) {
|
||||
ret = av_parser_parse2(parser, c, &pkt->data, &pkt->size,
|
||||
data, data_size, AV_NOPTS_VALUE, AV_NOPTS_VALUE, 0);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error while parsing\n");
|
||||
exit(1);
|
||||
}
|
||||
data += ret;
|
||||
data_size -= ret;
|
||||
|
||||
if (pkt->size)
|
||||
decode(c, frame, pkt, outfilename);
|
||||
else if (eof)
|
||||
break;
|
||||
}
|
||||
} while (!eof);
|
||||
|
||||
/* flush the decoder */
|
||||
decode(c, frame, NULL, outfilename);
|
||||
|
||||
fclose(f);
|
||||
|
||||
av_parser_close(parser);
|
||||
avcodec_free_context(&c);
|
||||
av_frame_free(&frame);
|
||||
av_packet_free(&pkt);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,380 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Stefano Sabatini
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file libavformat and libavcodec demuxing and decoding API usage example
|
||||
* @example demux_decode.c
|
||||
*
|
||||
* Show how to use the libavformat and libavcodec API to demux and decode audio
|
||||
* and video data. Write the output as raw audio and input files to be played by
|
||||
* ffplay.
|
||||
*/
|
||||
|
||||
#include <libavutil/imgutils.h>
|
||||
#include <libavutil/samplefmt.h>
|
||||
#include <libavutil/timestamp.h>
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavformat/avformat.h>
|
||||
|
||||
static AVFormatContext *fmt_ctx = NULL;
|
||||
static AVCodecContext *video_dec_ctx = NULL, *audio_dec_ctx;
|
||||
static int width, height;
|
||||
static enum AVPixelFormat pix_fmt;
|
||||
static AVStream *video_stream = NULL, *audio_stream = NULL;
|
||||
static const char *src_filename = NULL;
|
||||
static const char *video_dst_filename = NULL;
|
||||
static const char *audio_dst_filename = NULL;
|
||||
static FILE *video_dst_file = NULL;
|
||||
static FILE *audio_dst_file = NULL;
|
||||
|
||||
static uint8_t *video_dst_data[4] = {NULL};
|
||||
static int video_dst_linesize[4];
|
||||
static int video_dst_bufsize;
|
||||
|
||||
static int video_stream_idx = -1, audio_stream_idx = -1;
|
||||
static AVFrame *frame = NULL;
|
||||
static AVPacket *pkt = NULL;
|
||||
static int video_frame_count = 0;
|
||||
static int audio_frame_count = 0;
|
||||
|
||||
static int output_video_frame(AVFrame *frame)
|
||||
{
|
||||
if (frame->width != width || frame->height != height ||
|
||||
frame->format != pix_fmt) {
|
||||
/* To handle this change, one could call av_image_alloc again and
|
||||
* decode the following frames into another rawvideo file. */
|
||||
fprintf(stderr, "Error: Width, height and pixel format have to be "
|
||||
"constant in a rawvideo file, but the width, height or "
|
||||
"pixel format of the input video changed:\n"
|
||||
"old: width = %d, height = %d, format = %s\n"
|
||||
"new: width = %d, height = %d, format = %s\n",
|
||||
width, height, av_get_pix_fmt_name(pix_fmt),
|
||||
frame->width, frame->height,
|
||||
av_get_pix_fmt_name(frame->format));
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("video_frame n:%d\n",
|
||||
video_frame_count++);
|
||||
|
||||
/* copy decoded frame to destination buffer:
|
||||
* this is required since rawvideo expects non aligned data */
|
||||
av_image_copy2(video_dst_data, video_dst_linesize,
|
||||
frame->data, frame->linesize,
|
||||
pix_fmt, width, height);
|
||||
|
||||
/* write to rawvideo file */
|
||||
fwrite(video_dst_data[0], 1, video_dst_bufsize, video_dst_file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int output_audio_frame(AVFrame *frame)
|
||||
{
|
||||
size_t unpadded_linesize = frame->nb_samples * av_get_bytes_per_sample(frame->format);
|
||||
printf("audio_frame n:%d nb_samples:%d pts:%s\n",
|
||||
audio_frame_count++, frame->nb_samples,
|
||||
av_ts2timestr(frame->pts, &audio_dec_ctx->time_base));
|
||||
|
||||
/* Write the raw audio data samples of the first plane. This works
|
||||
* fine for packed formats (e.g. AV_SAMPLE_FMT_S16). However,
|
||||
* most audio decoders output planar audio, which uses a separate
|
||||
* plane of audio samples for each channel (e.g. AV_SAMPLE_FMT_S16P).
|
||||
* In other words, this code will write only the first audio channel
|
||||
* in these cases.
|
||||
* You should use libswresample or libavfilter to convert the frame
|
||||
* to packed data. */
|
||||
fwrite(frame->extended_data[0], 1, unpadded_linesize, audio_dst_file);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int decode_packet(AVCodecContext *dec, const AVPacket *pkt)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
// submit the packet to the decoder
|
||||
ret = avcodec_send_packet(dec, pkt);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error submitting a packet for decoding (%s)\n", av_err2str(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
// get all the available frames from the decoder
|
||||
while (ret >= 0) {
|
||||
ret = avcodec_receive_frame(dec, frame);
|
||||
if (ret < 0) {
|
||||
// those two return values are special and mean there is no output
|
||||
// frame available, but there were no errors during decoding
|
||||
if (ret == AVERROR_EOF || ret == AVERROR(EAGAIN))
|
||||
return 0;
|
||||
|
||||
fprintf(stderr, "Error during decoding (%s)\n", av_err2str(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
// write the frame data to output file
|
||||
if (dec->codec->type == AVMEDIA_TYPE_VIDEO)
|
||||
ret = output_video_frame(frame);
|
||||
else
|
||||
ret = output_audio_frame(frame);
|
||||
|
||||
av_frame_unref(frame);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int open_codec_context(int *stream_idx,
|
||||
AVCodecContext **dec_ctx, AVFormatContext *fmt_ctx, enum AVMediaType type)
|
||||
{
|
||||
int ret, stream_index;
|
||||
AVStream *st;
|
||||
const AVCodec *dec = NULL;
|
||||
|
||||
ret = av_find_best_stream(fmt_ctx, type, -1, -1, NULL, 0);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Could not find %s stream in input file '%s'\n",
|
||||
av_get_media_type_string(type), src_filename);
|
||||
return ret;
|
||||
} else {
|
||||
stream_index = ret;
|
||||
st = fmt_ctx->streams[stream_index];
|
||||
|
||||
/* find decoder for the stream */
|
||||
dec = avcodec_find_decoder(st->codecpar->codec_id);
|
||||
if (!dec) {
|
||||
fprintf(stderr, "Failed to find %s codec\n",
|
||||
av_get_media_type_string(type));
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
/* Allocate a codec context for the decoder */
|
||||
*dec_ctx = avcodec_alloc_context3(dec);
|
||||
if (!*dec_ctx) {
|
||||
fprintf(stderr, "Failed to allocate the %s codec context\n",
|
||||
av_get_media_type_string(type));
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
/* Copy codec parameters from input stream to output codec context */
|
||||
if ((ret = avcodec_parameters_to_context(*dec_ctx, st->codecpar)) < 0) {
|
||||
fprintf(stderr, "Failed to copy %s codec parameters to decoder context\n",
|
||||
av_get_media_type_string(type));
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Init the decoders */
|
||||
if ((ret = avcodec_open2(*dec_ctx, dec, NULL)) < 0) {
|
||||
fprintf(stderr, "Failed to open %s codec\n",
|
||||
av_get_media_type_string(type));
|
||||
return ret;
|
||||
}
|
||||
*stream_idx = stream_index;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_format_from_sample_fmt(const char **fmt,
|
||||
enum AVSampleFormat sample_fmt)
|
||||
{
|
||||
int i;
|
||||
struct sample_fmt_entry {
|
||||
enum AVSampleFormat sample_fmt; const char *fmt_be, *fmt_le;
|
||||
} sample_fmt_entries[] = {
|
||||
{ AV_SAMPLE_FMT_U8, "u8", "u8" },
|
||||
{ AV_SAMPLE_FMT_S16, "s16be", "s16le" },
|
||||
{ AV_SAMPLE_FMT_S32, "s32be", "s32le" },
|
||||
{ AV_SAMPLE_FMT_FLT, "f32be", "f32le" },
|
||||
{ AV_SAMPLE_FMT_DBL, "f64be", "f64le" },
|
||||
};
|
||||
*fmt = NULL;
|
||||
|
||||
for (i = 0; i < FF_ARRAY_ELEMS(sample_fmt_entries); i++) {
|
||||
struct sample_fmt_entry *entry = &sample_fmt_entries[i];
|
||||
if (sample_fmt == entry->sample_fmt) {
|
||||
*fmt = AV_NE(entry->fmt_be, entry->fmt_le);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr,
|
||||
"sample format %s is not supported as output format\n",
|
||||
av_get_sample_fmt_name(sample_fmt));
|
||||
return -1;
|
||||
}
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (argc != 4) {
|
||||
fprintf(stderr, "usage: %s input_file video_output_file audio_output_file\n"
|
||||
"API example program to show how to read frames from an input file.\n"
|
||||
"This program reads frames from a file, decodes them, and writes decoded\n"
|
||||
"video frames to a rawvideo file named video_output_file, and decoded\n"
|
||||
"audio frames to a rawaudio file named audio_output_file.\n",
|
||||
argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
src_filename = argv[1];
|
||||
video_dst_filename = argv[2];
|
||||
audio_dst_filename = argv[3];
|
||||
|
||||
/* open input file, and allocate format context */
|
||||
if (avformat_open_input(&fmt_ctx, src_filename, NULL, NULL) < 0) {
|
||||
fprintf(stderr, "Could not open source file %s\n", src_filename);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* retrieve stream information */
|
||||
if (avformat_find_stream_info(fmt_ctx, NULL) < 0) {
|
||||
fprintf(stderr, "Could not find stream information\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (open_codec_context(&video_stream_idx, &video_dec_ctx, fmt_ctx, AVMEDIA_TYPE_VIDEO) >= 0) {
|
||||
video_stream = fmt_ctx->streams[video_stream_idx];
|
||||
|
||||
video_dst_file = fopen(video_dst_filename, "wb");
|
||||
if (!video_dst_file) {
|
||||
fprintf(stderr, "Could not open destination file %s\n", video_dst_filename);
|
||||
ret = 1;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* allocate image where the decoded image will be put */
|
||||
width = video_dec_ctx->width;
|
||||
height = video_dec_ctx->height;
|
||||
pix_fmt = video_dec_ctx->pix_fmt;
|
||||
ret = av_image_alloc(video_dst_data, video_dst_linesize,
|
||||
width, height, pix_fmt, 1);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Could not allocate raw video buffer\n");
|
||||
goto end;
|
||||
}
|
||||
video_dst_bufsize = ret;
|
||||
}
|
||||
|
||||
if (open_codec_context(&audio_stream_idx, &audio_dec_ctx, fmt_ctx, AVMEDIA_TYPE_AUDIO) >= 0) {
|
||||
audio_stream = fmt_ctx->streams[audio_stream_idx];
|
||||
audio_dst_file = fopen(audio_dst_filename, "wb");
|
||||
if (!audio_dst_file) {
|
||||
fprintf(stderr, "Could not open destination file %s\n", audio_dst_filename);
|
||||
ret = 1;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
/* dump input information to stderr */
|
||||
av_dump_format(fmt_ctx, 0, src_filename, 0);
|
||||
|
||||
if (!audio_stream && !video_stream) {
|
||||
fprintf(stderr, "Could not find audio or video stream in the input, aborting\n");
|
||||
ret = 1;
|
||||
goto end;
|
||||
}
|
||||
|
||||
frame = av_frame_alloc();
|
||||
if (!frame) {
|
||||
fprintf(stderr, "Could not allocate frame\n");
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto end;
|
||||
}
|
||||
|
||||
pkt = av_packet_alloc();
|
||||
if (!pkt) {
|
||||
fprintf(stderr, "Could not allocate packet\n");
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (video_stream)
|
||||
printf("Demuxing video from file '%s' into '%s'\n", src_filename, video_dst_filename);
|
||||
if (audio_stream)
|
||||
printf("Demuxing audio from file '%s' into '%s'\n", src_filename, audio_dst_filename);
|
||||
|
||||
/* read frames from the file */
|
||||
while (av_read_frame(fmt_ctx, pkt) >= 0) {
|
||||
// check if the packet belongs to a stream we are interested in, otherwise
|
||||
// skip it
|
||||
if (pkt->stream_index == video_stream_idx)
|
||||
ret = decode_packet(video_dec_ctx, pkt);
|
||||
else if (pkt->stream_index == audio_stream_idx)
|
||||
ret = decode_packet(audio_dec_ctx, pkt);
|
||||
av_packet_unref(pkt);
|
||||
if (ret < 0)
|
||||
break;
|
||||
}
|
||||
|
||||
/* flush the decoders */
|
||||
if (video_dec_ctx)
|
||||
decode_packet(video_dec_ctx, NULL);
|
||||
if (audio_dec_ctx)
|
||||
decode_packet(audio_dec_ctx, NULL);
|
||||
|
||||
printf("Demuxing succeeded.\n");
|
||||
|
||||
if (video_stream) {
|
||||
printf("Play the output video file with the command:\n"
|
||||
"ffplay -f rawvideo -pix_fmt %s -video_size %dx%d %s\n",
|
||||
av_get_pix_fmt_name(pix_fmt), width, height,
|
||||
video_dst_filename);
|
||||
}
|
||||
|
||||
if (audio_stream) {
|
||||
enum AVSampleFormat sfmt = audio_dec_ctx->sample_fmt;
|
||||
int n_channels = audio_dec_ctx->ch_layout.nb_channels;
|
||||
const char *fmt;
|
||||
|
||||
if (av_sample_fmt_is_planar(sfmt)) {
|
||||
const char *packed = av_get_sample_fmt_name(sfmt);
|
||||
printf("Warning: the sample format the decoder produced is planar "
|
||||
"(%s). This example will output the first channel only.\n",
|
||||
packed ? packed : "?");
|
||||
sfmt = av_get_packed_sample_fmt(sfmt);
|
||||
n_channels = 1;
|
||||
}
|
||||
|
||||
if ((ret = get_format_from_sample_fmt(&fmt, sfmt)) < 0)
|
||||
goto end;
|
||||
|
||||
printf("Play the output audio file with the command:\n"
|
||||
"ffplay -f %s -ac %d -ar %d %s\n",
|
||||
fmt, n_channels, audio_dec_ctx->sample_rate,
|
||||
audio_dst_filename);
|
||||
}
|
||||
|
||||
end:
|
||||
avcodec_free_context(&video_dec_ctx);
|
||||
avcodec_free_context(&audio_dec_ctx);
|
||||
avformat_close_input(&fmt_ctx);
|
||||
if (video_dst_file)
|
||||
fclose(video_dst_file);
|
||||
if (audio_dst_file)
|
||||
fclose(audio_dst_file);
|
||||
av_packet_free(&pkt);
|
||||
av_frame_free(&frame);
|
||||
av_free(video_dst_data[0]);
|
||||
|
||||
return ret < 0;
|
||||
}
|
||||
@@ -1,240 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2001 Fabrice Bellard
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file libavcodec encoding audio API usage examples
|
||||
* @example encode_audio.c
|
||||
*
|
||||
* Generate a synthetic audio signal and encode it to an output MP2 file.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <libavcodec/avcodec.h>
|
||||
|
||||
#include <libavutil/channel_layout.h>
|
||||
#include <libavutil/common.h>
|
||||
#include <libavutil/frame.h>
|
||||
#include <libavutil/samplefmt.h>
|
||||
|
||||
/* check that a given sample format is supported by the encoder */
|
||||
static int check_sample_fmt(const AVCodec *codec, enum AVSampleFormat sample_fmt)
|
||||
{
|
||||
const enum AVSampleFormat *p = codec->sample_fmts;
|
||||
|
||||
while (*p != AV_SAMPLE_FMT_NONE) {
|
||||
if (*p == sample_fmt)
|
||||
return 1;
|
||||
p++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* just pick the highest supported samplerate */
|
||||
static int select_sample_rate(const AVCodec *codec)
|
||||
{
|
||||
const int *p;
|
||||
int best_samplerate = 0;
|
||||
|
||||
if (!codec->supported_samplerates)
|
||||
return 44100;
|
||||
|
||||
p = codec->supported_samplerates;
|
||||
while (*p) {
|
||||
if (!best_samplerate || abs(44100 - *p) < abs(44100 - best_samplerate))
|
||||
best_samplerate = *p;
|
||||
p++;
|
||||
}
|
||||
return best_samplerate;
|
||||
}
|
||||
|
||||
/* select layout with the highest channel count */
|
||||
static int select_channel_layout(const AVCodec *codec, AVChannelLayout *dst)
|
||||
{
|
||||
const AVChannelLayout *p, *best_ch_layout;
|
||||
int best_nb_channels = 0;
|
||||
|
||||
if (!codec->ch_layouts)
|
||||
return av_channel_layout_copy(dst, &(AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO);
|
||||
|
||||
p = codec->ch_layouts;
|
||||
while (p->nb_channels) {
|
||||
int nb_channels = p->nb_channels;
|
||||
|
||||
if (nb_channels > best_nb_channels) {
|
||||
best_ch_layout = p;
|
||||
best_nb_channels = nb_channels;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
return av_channel_layout_copy(dst, best_ch_layout);
|
||||
}
|
||||
|
||||
static void encode(AVCodecContext *ctx, AVFrame *frame, AVPacket *pkt,
|
||||
FILE *output)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* send the frame for encoding */
|
||||
ret = avcodec_send_frame(ctx, frame);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error sending the frame to the encoder\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* read all the available output packets (in general there may be any
|
||||
* number of them */
|
||||
while (ret >= 0) {
|
||||
ret = avcodec_receive_packet(ctx, pkt);
|
||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
|
||||
return;
|
||||
else if (ret < 0) {
|
||||
fprintf(stderr, "Error encoding audio frame\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fwrite(pkt->data, 1, pkt->size, output);
|
||||
av_packet_unref(pkt);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *filename;
|
||||
const AVCodec *codec;
|
||||
AVCodecContext *c= NULL;
|
||||
AVFrame *frame;
|
||||
AVPacket *pkt;
|
||||
int i, j, k, ret;
|
||||
FILE *f;
|
||||
uint16_t *samples;
|
||||
float t, tincr;
|
||||
|
||||
if (argc <= 1) {
|
||||
fprintf(stderr, "Usage: %s <output file>\n", argv[0]);
|
||||
return 0;
|
||||
}
|
||||
filename = argv[1];
|
||||
|
||||
/* find the MP2 encoder */
|
||||
codec = avcodec_find_encoder(AV_CODEC_ID_MP2);
|
||||
if (!codec) {
|
||||
fprintf(stderr, "Codec not found\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
c = avcodec_alloc_context3(codec);
|
||||
if (!c) {
|
||||
fprintf(stderr, "Could not allocate audio codec context\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* put sample parameters */
|
||||
c->bit_rate = 64000;
|
||||
|
||||
/* check that the encoder supports s16 pcm input */
|
||||
c->sample_fmt = AV_SAMPLE_FMT_S16;
|
||||
if (!check_sample_fmt(codec, c->sample_fmt)) {
|
||||
fprintf(stderr, "Encoder does not support sample format %s",
|
||||
av_get_sample_fmt_name(c->sample_fmt));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* select other audio parameters supported by the encoder */
|
||||
c->sample_rate = select_sample_rate(codec);
|
||||
ret = select_channel_layout(codec, &c->ch_layout);
|
||||
if (ret < 0)
|
||||
exit(1);
|
||||
|
||||
/* open it */
|
||||
if (avcodec_open2(c, codec, NULL) < 0) {
|
||||
fprintf(stderr, "Could not open codec\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
f = fopen(filename, "wb");
|
||||
if (!f) {
|
||||
fprintf(stderr, "Could not open %s\n", filename);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* packet for holding encoded output */
|
||||
pkt = av_packet_alloc();
|
||||
if (!pkt) {
|
||||
fprintf(stderr, "could not allocate the packet\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* frame containing input raw audio */
|
||||
frame = av_frame_alloc();
|
||||
if (!frame) {
|
||||
fprintf(stderr, "Could not allocate audio frame\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
frame->nb_samples = c->frame_size;
|
||||
frame->format = c->sample_fmt;
|
||||
ret = av_channel_layout_copy(&frame->ch_layout, &c->ch_layout);
|
||||
if (ret < 0)
|
||||
exit(1);
|
||||
|
||||
/* allocate the data buffers */
|
||||
ret = av_frame_get_buffer(frame, 0);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Could not allocate audio data buffers\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* encode a single tone sound */
|
||||
t = 0;
|
||||
tincr = 2 * M_PI * 440.0 / c->sample_rate;
|
||||
for (i = 0; i < 200; i++) {
|
||||
/* make sure the frame is writable -- makes a copy if the encoder
|
||||
* kept a reference internally */
|
||||
ret = av_frame_make_writable(frame);
|
||||
if (ret < 0)
|
||||
exit(1);
|
||||
samples = (uint16_t*)frame->data[0];
|
||||
|
||||
for (j = 0; j < c->frame_size; j++) {
|
||||
samples[2*j] = (int)(sin(t) * 10000);
|
||||
|
||||
for (k = 1; k < c->ch_layout.nb_channels; k++)
|
||||
samples[2*j + k] = samples[2*j];
|
||||
t += tincr;
|
||||
}
|
||||
encode(c, frame, pkt, f);
|
||||
}
|
||||
|
||||
/* flush the encoder */
|
||||
encode(c, NULL, pkt, f);
|
||||
|
||||
fclose(f);
|
||||
|
||||
av_frame_free(&frame);
|
||||
av_packet_free(&pkt);
|
||||
avcodec_free_context(&c);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,216 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2001 Fabrice Bellard
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file libavcodec encoding video API usage example
|
||||
* @example encode_video.c
|
||||
*
|
||||
* Generate synthetic video data and encode it to an output file.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <libavcodec/avcodec.h>
|
||||
|
||||
#include <libavutil/opt.h>
|
||||
#include <libavutil/imgutils.h>
|
||||
|
||||
static void encode(AVCodecContext *enc_ctx, AVFrame *frame, AVPacket *pkt,
|
||||
FILE *outfile)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* send the frame to the encoder */
|
||||
if (frame)
|
||||
printf("Send frame %3"PRId64"\n", frame->pts);
|
||||
|
||||
ret = avcodec_send_frame(enc_ctx, frame);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error sending a frame for encoding\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
while (ret >= 0) {
|
||||
ret = avcodec_receive_packet(enc_ctx, pkt);
|
||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
|
||||
return;
|
||||
else if (ret < 0) {
|
||||
fprintf(stderr, "Error during encoding\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("Write packet %3"PRId64" (size=%5d)\n", pkt->pts, pkt->size);
|
||||
fwrite(pkt->data, 1, pkt->size, outfile);
|
||||
av_packet_unref(pkt);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *filename, *codec_name;
|
||||
const AVCodec *codec;
|
||||
AVCodecContext *c= NULL;
|
||||
int i, ret, x, y;
|
||||
FILE *f;
|
||||
AVFrame *frame;
|
||||
AVPacket *pkt;
|
||||
uint8_t endcode[] = { 0, 0, 1, 0xb7 };
|
||||
|
||||
if (argc <= 2) {
|
||||
fprintf(stderr, "Usage: %s <output file> <codec name>\n", argv[0]);
|
||||
exit(0);
|
||||
}
|
||||
filename = argv[1];
|
||||
codec_name = argv[2];
|
||||
|
||||
/* find the mpeg1video encoder */
|
||||
codec = avcodec_find_encoder_by_name(codec_name);
|
||||
if (!codec) {
|
||||
fprintf(stderr, "Codec '%s' not found\n", codec_name);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
c = avcodec_alloc_context3(codec);
|
||||
if (!c) {
|
||||
fprintf(stderr, "Could not allocate video codec context\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
pkt = av_packet_alloc();
|
||||
if (!pkt)
|
||||
exit(1);
|
||||
|
||||
/* put sample parameters */
|
||||
c->bit_rate = 400000;
|
||||
/* resolution must be a multiple of two */
|
||||
c->width = 352;
|
||||
c->height = 288;
|
||||
/* frames per second */
|
||||
c->time_base = (AVRational){1, 25};
|
||||
c->framerate = (AVRational){25, 1};
|
||||
|
||||
/* emit one intra frame every ten frames
|
||||
* check frame pict_type before passing frame
|
||||
* to encoder, if frame->pict_type is AV_PICTURE_TYPE_I
|
||||
* then gop_size is ignored and the output of encoder
|
||||
* will always be I frame irrespective to gop_size
|
||||
*/
|
||||
c->gop_size = 10;
|
||||
c->max_b_frames = 1;
|
||||
c->pix_fmt = AV_PIX_FMT_YUV420P;
|
||||
|
||||
if (codec->id == AV_CODEC_ID_H264)
|
||||
av_opt_set(c->priv_data, "preset", "slow", 0);
|
||||
|
||||
/* open it */
|
||||
ret = avcodec_open2(c, codec, NULL);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Could not open codec: %s\n", av_err2str(ret));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
f = fopen(filename, "wb");
|
||||
if (!f) {
|
||||
fprintf(stderr, "Could not open %s\n", filename);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
frame = av_frame_alloc();
|
||||
if (!frame) {
|
||||
fprintf(stderr, "Could not allocate video frame\n");
|
||||
exit(1);
|
||||
}
|
||||
frame->format = c->pix_fmt;
|
||||
frame->width = c->width;
|
||||
frame->height = c->height;
|
||||
|
||||
ret = av_frame_get_buffer(frame, 0);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Could not allocate the video frame data\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* encode 1 second of video */
|
||||
for (i = 0; i < 25; i++) {
|
||||
fflush(stdout);
|
||||
|
||||
/* Make sure the frame data is writable.
|
||||
On the first round, the frame is fresh from av_frame_get_buffer()
|
||||
and therefore we know it is writable.
|
||||
But on the next rounds, encode() will have called
|
||||
avcodec_send_frame(), and the codec may have kept a reference to
|
||||
the frame in its internal structures, that makes the frame
|
||||
unwritable.
|
||||
av_frame_make_writable() checks that and allocates a new buffer
|
||||
for the frame only if necessary.
|
||||
*/
|
||||
ret = av_frame_make_writable(frame);
|
||||
if (ret < 0)
|
||||
exit(1);
|
||||
|
||||
/* Prepare a dummy image.
|
||||
In real code, this is where you would have your own logic for
|
||||
filling the frame. FFmpeg does not care what you put in the
|
||||
frame.
|
||||
*/
|
||||
/* Y */
|
||||
for (y = 0; y < c->height; y++) {
|
||||
for (x = 0; x < c->width; x++) {
|
||||
frame->data[0][y * frame->linesize[0] + x] = x + y + i * 3;
|
||||
}
|
||||
}
|
||||
|
||||
/* Cb and Cr */
|
||||
for (y = 0; y < c->height/2; y++) {
|
||||
for (x = 0; x < c->width/2; x++) {
|
||||
frame->data[1][y * frame->linesize[1] + x] = 128 + y + i * 2;
|
||||
frame->data[2][y * frame->linesize[2] + x] = 64 + x + i * 5;
|
||||
}
|
||||
}
|
||||
|
||||
frame->pts = i;
|
||||
|
||||
/* encode the image */
|
||||
encode(c, frame, pkt, f);
|
||||
}
|
||||
|
||||
/* flush the encoder */
|
||||
encode(c, NULL, pkt, f);
|
||||
|
||||
/* Add sequence end code to have a real MPEG file.
|
||||
It makes only sense because this tiny examples writes packets
|
||||
directly. This is called "elementary stream" and only works for some
|
||||
codecs. To create a valid file, you usually need to write packets
|
||||
into a proper file format or protocol; see mux.c.
|
||||
*/
|
||||
if (codec->id == AV_CODEC_ID_MPEG1VIDEO || codec->id == AV_CODEC_ID_MPEG2VIDEO)
|
||||
fwrite(endcode, 1, sizeof(endcode), f);
|
||||
fclose(f);
|
||||
|
||||
avcodec_free_context(&c);
|
||||
av_frame_free(&frame);
|
||||
av_packet_free(&pkt);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,198 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Stefano Sabatini
|
||||
* Copyright (c) 2014 Clément Bœsch
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file libavcodec motion vectors extraction API usage example
|
||||
* @example extract_mvs.c
|
||||
*
|
||||
* Read from input file, decode video stream and print a motion vectors
|
||||
* representation to stdout.
|
||||
*/
|
||||
|
||||
#include <libavutil/motion_vector.h>
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavformat/avformat.h>
|
||||
|
||||
static AVFormatContext *fmt_ctx = NULL;
|
||||
static AVCodecContext *video_dec_ctx = NULL;
|
||||
static AVStream *video_stream = NULL;
|
||||
static const char *src_filename = NULL;
|
||||
|
||||
static int video_stream_idx = -1;
|
||||
static AVFrame *frame = NULL;
|
||||
static int video_frame_count = 0;
|
||||
|
||||
static int decode_packet(const AVPacket *pkt)
|
||||
{
|
||||
int ret = avcodec_send_packet(video_dec_ctx, pkt);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error while sending a packet to the decoder: %s\n", av_err2str(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
while (ret >= 0) {
|
||||
ret = avcodec_receive_frame(video_dec_ctx, frame);
|
||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
|
||||
break;
|
||||
} else if (ret < 0) {
|
||||
fprintf(stderr, "Error while receiving a frame from the decoder: %s\n", av_err2str(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (ret >= 0) {
|
||||
int i;
|
||||
AVFrameSideData *sd;
|
||||
|
||||
video_frame_count++;
|
||||
sd = av_frame_get_side_data(frame, AV_FRAME_DATA_MOTION_VECTORS);
|
||||
if (sd) {
|
||||
const AVMotionVector *mvs = (const AVMotionVector *)sd->data;
|
||||
for (i = 0; i < sd->size / sizeof(*mvs); i++) {
|
||||
const AVMotionVector *mv = &mvs[i];
|
||||
printf("%d,%2d,%2d,%2d,%4d,%4d,%4d,%4d,0x%"PRIx64",%4d,%4d,%4d\n",
|
||||
video_frame_count, mv->source,
|
||||
mv->w, mv->h, mv->src_x, mv->src_y,
|
||||
mv->dst_x, mv->dst_y, mv->flags,
|
||||
mv->motion_x, mv->motion_y, mv->motion_scale);
|
||||
}
|
||||
}
|
||||
av_frame_unref(frame);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int open_codec_context(AVFormatContext *fmt_ctx, enum AVMediaType type)
|
||||
{
|
||||
int ret;
|
||||
AVStream *st;
|
||||
AVCodecContext *dec_ctx = NULL;
|
||||
const AVCodec *dec = NULL;
|
||||
AVDictionary *opts = NULL;
|
||||
|
||||
ret = av_find_best_stream(fmt_ctx, type, -1, -1, &dec, 0);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Could not find %s stream in input file '%s'\n",
|
||||
av_get_media_type_string(type), src_filename);
|
||||
return ret;
|
||||
} else {
|
||||
int stream_idx = ret;
|
||||
st = fmt_ctx->streams[stream_idx];
|
||||
|
||||
dec_ctx = avcodec_alloc_context3(dec);
|
||||
if (!dec_ctx) {
|
||||
fprintf(stderr, "Failed to allocate codec\n");
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
ret = avcodec_parameters_to_context(dec_ctx, st->codecpar);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Failed to copy codec parameters to codec context\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Init the video decoder */
|
||||
av_dict_set(&opts, "flags2", "+export_mvs", 0);
|
||||
ret = avcodec_open2(dec_ctx, dec, &opts);
|
||||
av_dict_free(&opts);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Failed to open %s codec\n",
|
||||
av_get_media_type_string(type));
|
||||
return ret;
|
||||
}
|
||||
|
||||
video_stream_idx = stream_idx;
|
||||
video_stream = fmt_ctx->streams[video_stream_idx];
|
||||
video_dec_ctx = dec_ctx;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int ret = 0;
|
||||
AVPacket *pkt = NULL;
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "Usage: %s <video>\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
src_filename = argv[1];
|
||||
|
||||
if (avformat_open_input(&fmt_ctx, src_filename, NULL, NULL) < 0) {
|
||||
fprintf(stderr, "Could not open source file %s\n", src_filename);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (avformat_find_stream_info(fmt_ctx, NULL) < 0) {
|
||||
fprintf(stderr, "Could not find stream information\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
open_codec_context(fmt_ctx, AVMEDIA_TYPE_VIDEO);
|
||||
|
||||
av_dump_format(fmt_ctx, 0, src_filename, 0);
|
||||
|
||||
if (!video_stream) {
|
||||
fprintf(stderr, "Could not find video stream in the input, aborting\n");
|
||||
ret = 1;
|
||||
goto end;
|
||||
}
|
||||
|
||||
frame = av_frame_alloc();
|
||||
if (!frame) {
|
||||
fprintf(stderr, "Could not allocate frame\n");
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto end;
|
||||
}
|
||||
|
||||
pkt = av_packet_alloc();
|
||||
if (!pkt) {
|
||||
fprintf(stderr, "Could not allocate AVPacket\n");
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto end;
|
||||
}
|
||||
|
||||
printf("framenum,source,blockw,blockh,srcx,srcy,dstx,dsty,flags,motion_x,motion_y,motion_scale\n");
|
||||
|
||||
/* read frames from the file */
|
||||
while (av_read_frame(fmt_ctx, pkt) >= 0) {
|
||||
if (pkt->stream_index == video_stream_idx)
|
||||
ret = decode_packet(pkt);
|
||||
av_packet_unref(pkt);
|
||||
if (ret < 0)
|
||||
break;
|
||||
}
|
||||
|
||||
/* flush cached frames */
|
||||
decode_packet(NULL);
|
||||
|
||||
end:
|
||||
avcodec_free_context(&video_dec_ctx);
|
||||
avformat_close_input(&fmt_ctx);
|
||||
av_frame_free(&frame);
|
||||
av_packet_free(&pkt);
|
||||
return ret < 0;
|
||||
}
|
||||
@@ -1,365 +0,0 @@
|
||||
/*
|
||||
* copyright (c) 2013 Andrew Kelley
|
||||
*
|
||||
* 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 libavfilter audio filtering API usage example
|
||||
* @example filter_audio.c
|
||||
*
|
||||
* This example will generate a sine wave audio, pass it through a simple filter
|
||||
* chain, and then compute the MD5 checksum of the output data.
|
||||
*
|
||||
* The filter chain it uses is:
|
||||
* (input) -> abuffer -> volume -> aformat -> abuffersink -> (output)
|
||||
*
|
||||
* abuffer: This provides the endpoint where you can feed the decoded samples.
|
||||
* volume: In this example we hardcode it to 0.90.
|
||||
* aformat: This converts the samples to the samplefreq, channel layout,
|
||||
* and sample format required by the audio device.
|
||||
* abuffersink: This provides the endpoint where you can read the samples after
|
||||
* they have passed through the filter chain.
|
||||
*/
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <math.h>
|
||||
#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 <libavfilter/avfilter.h>
|
||||
#include <libavfilter/buffersink.h>
|
||||
#include <libavfilter/buffersrc.h>
|
||||
|
||||
#define INPUT_SAMPLERATE 48000
|
||||
#define INPUT_FORMAT AV_SAMPLE_FMT_FLTP
|
||||
#define INPUT_CHANNEL_LAYOUT (AVChannelLayout)AV_CHANNEL_LAYOUT_5POINT0
|
||||
|
||||
#define VOLUME_VAL 0.90
|
||||
|
||||
static int init_filter_graph(AVFilterGraph **graph, AVFilterContext **src,
|
||||
AVFilterContext **sink)
|
||||
{
|
||||
AVFilterGraph *filter_graph;
|
||||
AVFilterContext *abuffer_ctx;
|
||||
const AVFilter *abuffer;
|
||||
AVFilterContext *volume_ctx;
|
||||
const AVFilter *volume;
|
||||
AVFilterContext *aformat_ctx;
|
||||
const AVFilter *aformat;
|
||||
AVFilterContext *abuffersink_ctx;
|
||||
const AVFilter *abuffersink;
|
||||
|
||||
AVDictionary *options_dict = NULL;
|
||||
uint8_t options_str[1024];
|
||||
uint8_t ch_layout[64];
|
||||
|
||||
int err;
|
||||
|
||||
/* Create a new filtergraph, which will contain all the filters. */
|
||||
filter_graph = avfilter_graph_alloc();
|
||||
if (!filter_graph) {
|
||||
fprintf(stderr, "Unable to create filter graph.\n");
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
/* Create the abuffer filter;
|
||||
* it will be used for feeding the data into the graph. */
|
||||
abuffer = avfilter_get_by_name("abuffer");
|
||||
if (!abuffer) {
|
||||
fprintf(stderr, "Could not find the abuffer filter.\n");
|
||||
return AVERROR_FILTER_NOT_FOUND;
|
||||
}
|
||||
|
||||
abuffer_ctx = avfilter_graph_alloc_filter(filter_graph, abuffer, "src");
|
||||
if (!abuffer_ctx) {
|
||||
fprintf(stderr, "Could not allocate the abuffer instance.\n");
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
/* Set the filter options through the AVOptions API. */
|
||||
av_channel_layout_describe(&INPUT_CHANNEL_LAYOUT, ch_layout, sizeof(ch_layout));
|
||||
av_opt_set (abuffer_ctx, "channel_layout", ch_layout, AV_OPT_SEARCH_CHILDREN);
|
||||
av_opt_set (abuffer_ctx, "sample_fmt", av_get_sample_fmt_name(INPUT_FORMAT), AV_OPT_SEARCH_CHILDREN);
|
||||
av_opt_set_q (abuffer_ctx, "time_base", (AVRational){ 1, INPUT_SAMPLERATE }, AV_OPT_SEARCH_CHILDREN);
|
||||
av_opt_set_int(abuffer_ctx, "sample_rate", INPUT_SAMPLERATE, AV_OPT_SEARCH_CHILDREN);
|
||||
|
||||
/* Now initialize the filter; we pass NULL options, since we have already
|
||||
* set all the options above. */
|
||||
err = avfilter_init_str(abuffer_ctx, NULL);
|
||||
if (err < 0) {
|
||||
fprintf(stderr, "Could not initialize the abuffer filter.\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Create volume filter. */
|
||||
volume = avfilter_get_by_name("volume");
|
||||
if (!volume) {
|
||||
fprintf(stderr, "Could not find the volume filter.\n");
|
||||
return AVERROR_FILTER_NOT_FOUND;
|
||||
}
|
||||
|
||||
volume_ctx = avfilter_graph_alloc_filter(filter_graph, volume, "volume");
|
||||
if (!volume_ctx) {
|
||||
fprintf(stderr, "Could not allocate the volume instance.\n");
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
/* A different way of passing the options is as key/value pairs in a
|
||||
* dictionary. */
|
||||
av_dict_set(&options_dict, "volume", AV_STRINGIFY(VOLUME_VAL), 0);
|
||||
err = avfilter_init_dict(volume_ctx, &options_dict);
|
||||
av_dict_free(&options_dict);
|
||||
if (err < 0) {
|
||||
fprintf(stderr, "Could not initialize the volume filter.\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Create the aformat filter;
|
||||
* it ensures that the output is of the format we want. */
|
||||
aformat = avfilter_get_by_name("aformat");
|
||||
if (!aformat) {
|
||||
fprintf(stderr, "Could not find the aformat filter.\n");
|
||||
return AVERROR_FILTER_NOT_FOUND;
|
||||
}
|
||||
|
||||
aformat_ctx = avfilter_graph_alloc_filter(filter_graph, aformat, "aformat");
|
||||
if (!aformat_ctx) {
|
||||
fprintf(stderr, "Could not allocate the aformat instance.\n");
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
/* A third way of passing the options is in a string of the form
|
||||
* key1=value1:key2=value2.... */
|
||||
snprintf(options_str, sizeof(options_str),
|
||||
"sample_fmts=%s:sample_rates=%d:channel_layouts=stereo",
|
||||
av_get_sample_fmt_name(AV_SAMPLE_FMT_S16), 44100);
|
||||
err = avfilter_init_str(aformat_ctx, options_str);
|
||||
if (err < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Could not initialize the aformat filter.\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Finally create the abuffersink filter;
|
||||
* it will be used to get the filtered data out of the graph. */
|
||||
abuffersink = avfilter_get_by_name("abuffersink");
|
||||
if (!abuffersink) {
|
||||
fprintf(stderr, "Could not find the abuffersink filter.\n");
|
||||
return AVERROR_FILTER_NOT_FOUND;
|
||||
}
|
||||
|
||||
abuffersink_ctx = avfilter_graph_alloc_filter(filter_graph, abuffersink, "sink");
|
||||
if (!abuffersink_ctx) {
|
||||
fprintf(stderr, "Could not allocate the abuffersink instance.\n");
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
/* This filter takes no options. */
|
||||
err = avfilter_init_str(abuffersink_ctx, NULL);
|
||||
if (err < 0) {
|
||||
fprintf(stderr, "Could not initialize the abuffersink instance.\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Connect the filters;
|
||||
* in this simple case the filters just form a linear chain. */
|
||||
err = avfilter_link(abuffer_ctx, 0, volume_ctx, 0);
|
||||
if (err >= 0)
|
||||
err = avfilter_link(volume_ctx, 0, aformat_ctx, 0);
|
||||
if (err >= 0)
|
||||
err = avfilter_link(aformat_ctx, 0, abuffersink_ctx, 0);
|
||||
if (err < 0) {
|
||||
fprintf(stderr, "Error connecting filters\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Configure the graph. */
|
||||
err = avfilter_graph_config(filter_graph, NULL);
|
||||
if (err < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Error configuring the filter graph\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
*graph = filter_graph;
|
||||
*src = abuffer_ctx;
|
||||
*sink = abuffersink_ctx;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Do something useful with the filtered data: this simple
|
||||
* example just prints the MD5 checksum of each plane to stdout. */
|
||||
static int process_output(struct AVMD5 *md5, AVFrame *frame)
|
||||
{
|
||||
int planar = av_sample_fmt_is_planar(frame->format);
|
||||
int channels = frame->ch_layout.nb_channels;
|
||||
int planes = planar ? channels : 1;
|
||||
int bps = av_get_bytes_per_sample(frame->format);
|
||||
int plane_size = bps * frame->nb_samples * (planar ? 1 : channels);
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < planes; i++) {
|
||||
uint8_t checksum[16];
|
||||
|
||||
av_md5_init(md5);
|
||||
av_md5_sum(checksum, frame->extended_data[i], plane_size);
|
||||
|
||||
fprintf(stdout, "plane %d: 0x", i);
|
||||
for (j = 0; j < sizeof(checksum); j++)
|
||||
fprintf(stdout, "%02X", checksum[j]);
|
||||
fprintf(stdout, "\n");
|
||||
}
|
||||
fprintf(stdout, "\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Construct a frame of audio data to be filtered;
|
||||
* this simple example just synthesizes a sine wave. */
|
||||
static int get_input(AVFrame *frame, int frame_num)
|
||||
{
|
||||
int err, i, j;
|
||||
|
||||
#define FRAME_SIZE 1024
|
||||
|
||||
/* Set up the frame properties and allocate the buffer for the data. */
|
||||
frame->sample_rate = INPUT_SAMPLERATE;
|
||||
frame->format = INPUT_FORMAT;
|
||||
av_channel_layout_copy(&frame->ch_layout, &INPUT_CHANNEL_LAYOUT);
|
||||
frame->nb_samples = FRAME_SIZE;
|
||||
frame->pts = frame_num * FRAME_SIZE;
|
||||
|
||||
err = av_frame_get_buffer(frame, 0);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
/* Fill the data for each channel. */
|
||||
for (i = 0; i < 5; i++) {
|
||||
float *data = (float*)frame->extended_data[i];
|
||||
|
||||
for (j = 0; j < frame->nb_samples; j++)
|
||||
data[j] = sin(2 * M_PI * (frame_num + j) * (i + 1) / FRAME_SIZE);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
struct AVMD5 *md5;
|
||||
AVFilterGraph *graph;
|
||||
AVFilterContext *src, *sink;
|
||||
AVFrame *frame;
|
||||
float duration;
|
||||
int err, nb_frames, i;
|
||||
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "Usage: %s <duration>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
duration = atof(argv[1]);
|
||||
nb_frames = duration * INPUT_SAMPLERATE / FRAME_SIZE;
|
||||
if (nb_frames <= 0) {
|
||||
fprintf(stderr, "Invalid duration: %s\n", argv[1]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Allocate the frame we will be using to store the data. */
|
||||
frame = av_frame_alloc();
|
||||
if (!frame) {
|
||||
fprintf(stderr, "Error allocating the frame\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
md5 = av_md5_alloc();
|
||||
if (!md5) {
|
||||
av_frame_free(&frame);
|
||||
fprintf(stderr, "Error allocating the MD5 context\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Set up the filtergraph. */
|
||||
err = init_filter_graph(&graph, &src, &sink);
|
||||
if (err < 0) {
|
||||
av_frame_free(&frame);
|
||||
av_freep(&md5);
|
||||
fprintf(stderr, "Unable to init filter graph:");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* the main filtering loop */
|
||||
for (i = 0; i < nb_frames; i++) {
|
||||
/* get an input frame to be filtered */
|
||||
err = get_input(frame, i);
|
||||
if (err < 0) {
|
||||
fprintf(stderr, "Error generating input frame:");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Send the frame to the input of the filtergraph. */
|
||||
err = av_buffersrc_add_frame(src, frame);
|
||||
if (err < 0) {
|
||||
av_frame_unref(frame);
|
||||
fprintf(stderr, "Error submitting the frame to the filtergraph:");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Get all the filtered output that is available. */
|
||||
while ((err = av_buffersink_get_frame(sink, frame)) >= 0) {
|
||||
/* now do something with our filtered frame */
|
||||
err = process_output(md5, frame);
|
||||
if (err < 0) {
|
||||
fprintf(stderr, "Error processing the filtered frame:");
|
||||
goto fail;
|
||||
}
|
||||
av_frame_unref(frame);
|
||||
}
|
||||
|
||||
if (err == AVERROR(EAGAIN)) {
|
||||
/* Need to feed more frames in. */
|
||||
continue;
|
||||
} else if (err == AVERROR_EOF) {
|
||||
/* Nothing more to do, finish. */
|
||||
break;
|
||||
} else if (err < 0) {
|
||||
/* An error occurred. */
|
||||
fprintf(stderr, "Error filtering the data:");
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
avfilter_graph_free(&graph);
|
||||
av_frame_free(&frame);
|
||||
av_freep(&md5);
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
avfilter_graph_free(&graph);
|
||||
av_frame_free(&frame);
|
||||
av_freep(&md5);
|
||||
|
||||
fprintf(stderr, "%s\n", av_err2str(err));
|
||||
return 1;
|
||||
}
|
||||
@@ -1,256 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Jun Zhao
|
||||
* Copyright (c) 2017 Kaixuan Liu
|
||||
*
|
||||
* HW Acceleration API (video decoding) decode sample
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file HW-accelerated decoding API usage.example
|
||||
* @example hw_decode.c
|
||||
*
|
||||
* Perform HW-accelerated decoding with output frames from HW video
|
||||
* surfaces.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libavutil/mem.h>
|
||||
#include <libavutil/pixdesc.h>
|
||||
#include <libavutil/hwcontext.h>
|
||||
#include <libavutil/opt.h>
|
||||
#include <libavutil/avassert.h>
|
||||
#include <libavutil/imgutils.h>
|
||||
|
||||
static AVBufferRef *hw_device_ctx = NULL;
|
||||
static enum AVPixelFormat hw_pix_fmt;
|
||||
static FILE *output_file = NULL;
|
||||
|
||||
static int hw_decoder_init(AVCodecContext *ctx, const enum AVHWDeviceType type)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
if ((err = av_hwdevice_ctx_create(&hw_device_ctx, type,
|
||||
NULL, NULL, 0)) < 0) {
|
||||
fprintf(stderr, "Failed to create specified HW device.\n");
|
||||
return err;
|
||||
}
|
||||
ctx->hw_device_ctx = av_buffer_ref(hw_device_ctx);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static enum AVPixelFormat get_hw_format(AVCodecContext *ctx,
|
||||
const enum AVPixelFormat *pix_fmts)
|
||||
{
|
||||
const enum AVPixelFormat *p;
|
||||
|
||||
for (p = pix_fmts; *p != -1; p++) {
|
||||
if (*p == hw_pix_fmt)
|
||||
return *p;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Failed to get HW surface format.\n");
|
||||
return AV_PIX_FMT_NONE;
|
||||
}
|
||||
|
||||
static int decode_write(AVCodecContext *avctx, AVPacket *packet)
|
||||
{
|
||||
AVFrame *frame = NULL, *sw_frame = NULL;
|
||||
AVFrame *tmp_frame = NULL;
|
||||
uint8_t *buffer = NULL;
|
||||
int size;
|
||||
int ret = 0;
|
||||
|
||||
ret = avcodec_send_packet(avctx, packet);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error during decoding\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
if (!(frame = av_frame_alloc()) || !(sw_frame = av_frame_alloc())) {
|
||||
fprintf(stderr, "Can not alloc frame\n");
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = avcodec_receive_frame(avctx, frame);
|
||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
|
||||
av_frame_free(&frame);
|
||||
av_frame_free(&sw_frame);
|
||||
return 0;
|
||||
} else if (ret < 0) {
|
||||
fprintf(stderr, "Error while decoding\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (frame->format == hw_pix_fmt) {
|
||||
/* retrieve data from GPU to CPU */
|
||||
if ((ret = av_hwframe_transfer_data(sw_frame, frame, 0)) < 0) {
|
||||
fprintf(stderr, "Error transferring the data to system memory\n");
|
||||
goto fail;
|
||||
}
|
||||
tmp_frame = sw_frame;
|
||||
} else
|
||||
tmp_frame = frame;
|
||||
|
||||
size = av_image_get_buffer_size(tmp_frame->format, tmp_frame->width,
|
||||
tmp_frame->height, 1);
|
||||
buffer = av_malloc(size);
|
||||
if (!buffer) {
|
||||
fprintf(stderr, "Can not alloc buffer\n");
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto fail;
|
||||
}
|
||||
ret = av_image_copy_to_buffer(buffer, size,
|
||||
(const uint8_t * const *)tmp_frame->data,
|
||||
(const int *)tmp_frame->linesize, tmp_frame->format,
|
||||
tmp_frame->width, tmp_frame->height, 1);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Can not copy image to buffer\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if ((ret = fwrite(buffer, 1, size, output_file)) < 0) {
|
||||
fprintf(stderr, "Failed to dump raw data.\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
fail:
|
||||
av_frame_free(&frame);
|
||||
av_frame_free(&sw_frame);
|
||||
av_freep(&buffer);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
AVFormatContext *input_ctx = NULL;
|
||||
int video_stream, ret;
|
||||
AVStream *video = NULL;
|
||||
AVCodecContext *decoder_ctx = NULL;
|
||||
const AVCodec *decoder = NULL;
|
||||
AVPacket *packet = NULL;
|
||||
enum AVHWDeviceType type;
|
||||
int i;
|
||||
|
||||
if (argc < 4) {
|
||||
fprintf(stderr, "Usage: %s <device type> <input file> <output file>\n", argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
type = av_hwdevice_find_type_by_name(argv[1]);
|
||||
if (type == AV_HWDEVICE_TYPE_NONE) {
|
||||
fprintf(stderr, "Device type %s is not supported.\n", argv[1]);
|
||||
fprintf(stderr, "Available device types:");
|
||||
while((type = av_hwdevice_iterate_types(type)) != AV_HWDEVICE_TYPE_NONE)
|
||||
fprintf(stderr, " %s", av_hwdevice_get_type_name(type));
|
||||
fprintf(stderr, "\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
packet = av_packet_alloc();
|
||||
if (!packet) {
|
||||
fprintf(stderr, "Failed to allocate AVPacket\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* open the input file */
|
||||
if (avformat_open_input(&input_ctx, argv[2], NULL, NULL) != 0) {
|
||||
fprintf(stderr, "Cannot open input file '%s'\n", argv[2]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (avformat_find_stream_info(input_ctx, NULL) < 0) {
|
||||
fprintf(stderr, "Cannot find input stream information.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* find the video stream information */
|
||||
ret = av_find_best_stream(input_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, &decoder, 0);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Cannot find a video stream in the input file\n");
|
||||
return -1;
|
||||
}
|
||||
video_stream = ret;
|
||||
|
||||
for (i = 0;; i++) {
|
||||
const AVCodecHWConfig *config = avcodec_get_hw_config(decoder, i);
|
||||
if (!config) {
|
||||
fprintf(stderr, "Decoder %s does not support device type %s.\n",
|
||||
decoder->name, av_hwdevice_get_type_name(type));
|
||||
return -1;
|
||||
}
|
||||
if (config->methods & AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX &&
|
||||
config->device_type == type) {
|
||||
hw_pix_fmt = config->pix_fmt;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(decoder_ctx = avcodec_alloc_context3(decoder)))
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
video = input_ctx->streams[video_stream];
|
||||
if (avcodec_parameters_to_context(decoder_ctx, video->codecpar) < 0)
|
||||
return -1;
|
||||
|
||||
decoder_ctx->get_format = get_hw_format;
|
||||
|
||||
if (hw_decoder_init(decoder_ctx, type) < 0)
|
||||
return -1;
|
||||
|
||||
if ((ret = avcodec_open2(decoder_ctx, decoder, NULL)) < 0) {
|
||||
fprintf(stderr, "Failed to open codec for stream #%u\n", video_stream);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* open the file to dump raw data */
|
||||
output_file = fopen(argv[3], "w+b");
|
||||
|
||||
/* actual decoding and dump the raw data */
|
||||
while (ret >= 0) {
|
||||
if ((ret = av_read_frame(input_ctx, packet)) < 0)
|
||||
break;
|
||||
|
||||
if (video_stream == packet->stream_index)
|
||||
ret = decode_write(decoder_ctx, packet);
|
||||
|
||||
av_packet_unref(packet);
|
||||
}
|
||||
|
||||
/* flush the decoder */
|
||||
ret = decode_write(decoder_ctx, NULL);
|
||||
|
||||
if (output_file)
|
||||
fclose(output_file);
|
||||
av_packet_free(&packet);
|
||||
avcodec_free_context(&decoder_ctx);
|
||||
avformat_close_input(&input_ctx);
|
||||
av_buffer_unref(&hw_device_ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,643 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2003 Fabrice Bellard
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file libavformat muxing API usage example
|
||||
* @example mux.c
|
||||
*
|
||||
* Generate a synthetic audio and video signal and mux them to a media file in
|
||||
* any supported libavformat format. The default codecs are used.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <libavutil/avassert.h>
|
||||
#include <libavutil/channel_layout.h>
|
||||
#include <libavutil/opt.h>
|
||||
#include <libavutil/mathematics.h>
|
||||
#include <libavutil/timestamp.h>
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libswscale/swscale.h>
|
||||
#include <libswresample/swresample.h>
|
||||
|
||||
#define STREAM_DURATION 10.0
|
||||
#define STREAM_FRAME_RATE 25 /* 25 images/s */
|
||||
#define STREAM_PIX_FMT AV_PIX_FMT_YUV420P /* default pix_fmt */
|
||||
|
||||
#define SCALE_FLAGS SWS_BICUBIC
|
||||
|
||||
// a wrapper around a single output AVStream
|
||||
typedef struct OutputStream {
|
||||
AVStream *st;
|
||||
AVCodecContext *enc;
|
||||
|
||||
/* pts of the next frame that will be generated */
|
||||
int64_t next_pts;
|
||||
int samples_count;
|
||||
|
||||
AVFrame *frame;
|
||||
AVFrame *tmp_frame;
|
||||
|
||||
AVPacket *tmp_pkt;
|
||||
|
||||
float t, tincr, tincr2;
|
||||
|
||||
struct SwsContext *sws_ctx;
|
||||
struct SwrContext *swr_ctx;
|
||||
} OutputStream;
|
||||
|
||||
static void log_packet(const AVFormatContext *fmt_ctx, const AVPacket *pkt)
|
||||
{
|
||||
AVRational *time_base = &fmt_ctx->streams[pkt->stream_index]->time_base;
|
||||
|
||||
printf("pts:%s pts_time:%s dts:%s dts_time:%s duration:%s duration_time:%s stream_index:%d\n",
|
||||
av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, time_base),
|
||||
av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, time_base),
|
||||
av_ts2str(pkt->duration), av_ts2timestr(pkt->duration, time_base),
|
||||
pkt->stream_index);
|
||||
}
|
||||
|
||||
static int write_frame(AVFormatContext *fmt_ctx, AVCodecContext *c,
|
||||
AVStream *st, AVFrame *frame, AVPacket *pkt)
|
||||
{
|
||||
int ret;
|
||||
|
||||
// send the frame to the encoder
|
||||
ret = avcodec_send_frame(c, frame);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error sending a frame to the encoder: %s\n",
|
||||
av_err2str(ret));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
while (ret >= 0) {
|
||||
ret = avcodec_receive_packet(c, pkt);
|
||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
|
||||
break;
|
||||
else if (ret < 0) {
|
||||
fprintf(stderr, "Error encoding a frame: %s\n", av_err2str(ret));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* rescale output packet timestamp values from codec to stream timebase */
|
||||
av_packet_rescale_ts(pkt, c->time_base, st->time_base);
|
||||
pkt->stream_index = st->index;
|
||||
|
||||
/* Write the compressed frame to the media file. */
|
||||
log_packet(fmt_ctx, pkt);
|
||||
ret = av_interleaved_write_frame(fmt_ctx, pkt);
|
||||
/* pkt is now blank (av_interleaved_write_frame() takes ownership of
|
||||
* its contents and resets pkt), so that no unreferencing is necessary.
|
||||
* This would be different if one used av_write_frame(). */
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error while writing output packet: %s\n", av_err2str(ret));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
return ret == AVERROR_EOF ? 1 : 0;
|
||||
}
|
||||
|
||||
/* Add an output stream. */
|
||||
static void add_stream(OutputStream *ost, AVFormatContext *oc,
|
||||
const AVCodec **codec,
|
||||
enum AVCodecID codec_id)
|
||||
{
|
||||
AVCodecContext *c;
|
||||
int i;
|
||||
|
||||
/* find the encoder */
|
||||
*codec = avcodec_find_encoder(codec_id);
|
||||
if (!(*codec)) {
|
||||
fprintf(stderr, "Could not find encoder for '%s'\n",
|
||||
avcodec_get_name(codec_id));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ost->tmp_pkt = av_packet_alloc();
|
||||
if (!ost->tmp_pkt) {
|
||||
fprintf(stderr, "Could not allocate AVPacket\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ost->st = avformat_new_stream(oc, NULL);
|
||||
if (!ost->st) {
|
||||
fprintf(stderr, "Could not allocate stream\n");
|
||||
exit(1);
|
||||
}
|
||||
ost->st->id = oc->nb_streams-1;
|
||||
c = avcodec_alloc_context3(*codec);
|
||||
if (!c) {
|
||||
fprintf(stderr, "Could not alloc an encoding context\n");
|
||||
exit(1);
|
||||
}
|
||||
ost->enc = c;
|
||||
|
||||
switch ((*codec)->type) {
|
||||
case AVMEDIA_TYPE_AUDIO:
|
||||
c->sample_fmt = (*codec)->sample_fmts ?
|
||||
(*codec)->sample_fmts[0] : AV_SAMPLE_FMT_FLTP;
|
||||
c->bit_rate = 64000;
|
||||
c->sample_rate = 44100;
|
||||
if ((*codec)->supported_samplerates) {
|
||||
c->sample_rate = (*codec)->supported_samplerates[0];
|
||||
for (i = 0; (*codec)->supported_samplerates[i]; i++) {
|
||||
if ((*codec)->supported_samplerates[i] == 44100)
|
||||
c->sample_rate = 44100;
|
||||
}
|
||||
}
|
||||
av_channel_layout_copy(&c->ch_layout, &(AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO);
|
||||
ost->st->time_base = (AVRational){ 1, c->sample_rate };
|
||||
break;
|
||||
|
||||
case AVMEDIA_TYPE_VIDEO:
|
||||
c->codec_id = codec_id;
|
||||
|
||||
c->bit_rate = 400000;
|
||||
/* Resolution must be a multiple of two. */
|
||||
c->width = 352;
|
||||
c->height = 288;
|
||||
/* timebase: This is the fundamental unit of time (in seconds) in terms
|
||||
* of which frame timestamps are represented. For fixed-fps content,
|
||||
* timebase should be 1/framerate and timestamp increments should be
|
||||
* identical to 1. */
|
||||
ost->st->time_base = (AVRational){ 1, STREAM_FRAME_RATE };
|
||||
c->time_base = ost->st->time_base;
|
||||
|
||||
c->gop_size = 12; /* emit one intra frame every twelve frames at most */
|
||||
c->pix_fmt = STREAM_PIX_FMT;
|
||||
if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
|
||||
/* just for testing, we also add B-frames */
|
||||
c->max_b_frames = 2;
|
||||
}
|
||||
if (c->codec_id == AV_CODEC_ID_MPEG1VIDEO) {
|
||||
/* Needed to avoid using macroblocks in which some coeffs overflow.
|
||||
* This does not happen with normal video, it just happens here as
|
||||
* the motion of the chroma plane does not match the luma plane. */
|
||||
c->mb_decision = 2;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Some formats want stream headers to be separate. */
|
||||
if (oc->oformat->flags & AVFMT_GLOBALHEADER)
|
||||
c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
|
||||
}
|
||||
|
||||
/**************************************************************/
|
||||
/* audio output */
|
||||
|
||||
static AVFrame *alloc_audio_frame(enum AVSampleFormat sample_fmt,
|
||||
const AVChannelLayout *channel_layout,
|
||||
int sample_rate, int nb_samples)
|
||||
{
|
||||
AVFrame *frame = av_frame_alloc();
|
||||
if (!frame) {
|
||||
fprintf(stderr, "Error allocating an audio frame\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
frame->format = sample_fmt;
|
||||
av_channel_layout_copy(&frame->ch_layout, channel_layout);
|
||||
frame->sample_rate = sample_rate;
|
||||
frame->nb_samples = nb_samples;
|
||||
|
||||
if (nb_samples) {
|
||||
if (av_frame_get_buffer(frame, 0) < 0) {
|
||||
fprintf(stderr, "Error allocating an audio buffer\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
static void open_audio(AVFormatContext *oc, const AVCodec *codec,
|
||||
OutputStream *ost, AVDictionary *opt_arg)
|
||||
{
|
||||
AVCodecContext *c;
|
||||
int nb_samples;
|
||||
int ret;
|
||||
AVDictionary *opt = NULL;
|
||||
|
||||
c = ost->enc;
|
||||
|
||||
/* open it */
|
||||
av_dict_copy(&opt, opt_arg, 0);
|
||||
ret = avcodec_open2(c, codec, &opt);
|
||||
av_dict_free(&opt);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Could not open audio codec: %s\n", av_err2str(ret));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* init signal generator */
|
||||
ost->t = 0;
|
||||
ost->tincr = 2 * M_PI * 110.0 / c->sample_rate;
|
||||
/* increment frequency by 110 Hz per second */
|
||||
ost->tincr2 = 2 * M_PI * 110.0 / c->sample_rate / c->sample_rate;
|
||||
|
||||
if (c->codec->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE)
|
||||
nb_samples = 10000;
|
||||
else
|
||||
nb_samples = c->frame_size;
|
||||
|
||||
ost->frame = alloc_audio_frame(c->sample_fmt, &c->ch_layout,
|
||||
c->sample_rate, nb_samples);
|
||||
ost->tmp_frame = alloc_audio_frame(AV_SAMPLE_FMT_S16, &c->ch_layout,
|
||||
c->sample_rate, nb_samples);
|
||||
|
||||
/* copy the stream parameters to the muxer */
|
||||
ret = avcodec_parameters_from_context(ost->st->codecpar, c);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Could not copy the stream parameters\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* create resampler context */
|
||||
ost->swr_ctx = swr_alloc();
|
||||
if (!ost->swr_ctx) {
|
||||
fprintf(stderr, "Could not allocate resampler context\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* set options */
|
||||
av_opt_set_chlayout (ost->swr_ctx, "in_chlayout", &c->ch_layout, 0);
|
||||
av_opt_set_int (ost->swr_ctx, "in_sample_rate", c->sample_rate, 0);
|
||||
av_opt_set_sample_fmt(ost->swr_ctx, "in_sample_fmt", AV_SAMPLE_FMT_S16, 0);
|
||||
av_opt_set_chlayout (ost->swr_ctx, "out_chlayout", &c->ch_layout, 0);
|
||||
av_opt_set_int (ost->swr_ctx, "out_sample_rate", c->sample_rate, 0);
|
||||
av_opt_set_sample_fmt(ost->swr_ctx, "out_sample_fmt", c->sample_fmt, 0);
|
||||
|
||||
/* initialize the resampling context */
|
||||
if ((ret = swr_init(ost->swr_ctx)) < 0) {
|
||||
fprintf(stderr, "Failed to initialize the resampling context\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Prepare a 16 bit dummy audio frame of 'frame_size' samples and
|
||||
* 'nb_channels' channels. */
|
||||
static AVFrame *get_audio_frame(OutputStream *ost)
|
||||
{
|
||||
AVFrame *frame = ost->tmp_frame;
|
||||
int j, i, v;
|
||||
int16_t *q = (int16_t*)frame->data[0];
|
||||
|
||||
/* check if we want to generate more frames */
|
||||
if (av_compare_ts(ost->next_pts, ost->enc->time_base,
|
||||
STREAM_DURATION, (AVRational){ 1, 1 }) > 0)
|
||||
return NULL;
|
||||
|
||||
for (j = 0; j <frame->nb_samples; j++) {
|
||||
v = (int)(sin(ost->t) * 10000);
|
||||
for (i = 0; i < ost->enc->ch_layout.nb_channels; i++)
|
||||
*q++ = v;
|
||||
ost->t += ost->tincr;
|
||||
ost->tincr += ost->tincr2;
|
||||
}
|
||||
|
||||
frame->pts = ost->next_pts;
|
||||
ost->next_pts += frame->nb_samples;
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
/*
|
||||
* encode one audio frame and send it to the muxer
|
||||
* return 1 when encoding is finished, 0 otherwise
|
||||
*/
|
||||
static int write_audio_frame(AVFormatContext *oc, OutputStream *ost)
|
||||
{
|
||||
AVCodecContext *c;
|
||||
AVFrame *frame;
|
||||
int ret;
|
||||
int dst_nb_samples;
|
||||
|
||||
c = ost->enc;
|
||||
|
||||
frame = get_audio_frame(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;
|
||||
av_assert0(dst_nb_samples == frame->nb_samples);
|
||||
|
||||
/* when we pass a frame to the encoder, it may keep a reference to it
|
||||
* internally;
|
||||
* make sure we do not overwrite it here
|
||||
*/
|
||||
ret = av_frame_make_writable(ost->frame);
|
||||
if (ret < 0)
|
||||
exit(1);
|
||||
|
||||
/* convert to destination format */
|
||||
ret = swr_convert(ost->swr_ctx,
|
||||
ost->frame->data, dst_nb_samples,
|
||||
(const uint8_t **)frame->data, frame->nb_samples);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error while converting\n");
|
||||
exit(1);
|
||||
}
|
||||
frame = ost->frame;
|
||||
|
||||
frame->pts = av_rescale_q(ost->samples_count, (AVRational){1, c->sample_rate}, c->time_base);
|
||||
ost->samples_count += dst_nb_samples;
|
||||
}
|
||||
|
||||
return write_frame(oc, c, ost->st, frame, ost->tmp_pkt);
|
||||
}
|
||||
|
||||
/**************************************************************/
|
||||
/* video output */
|
||||
|
||||
static AVFrame *alloc_frame(enum AVPixelFormat pix_fmt, int width, int height)
|
||||
{
|
||||
AVFrame *frame;
|
||||
int ret;
|
||||
|
||||
frame = av_frame_alloc();
|
||||
if (!frame)
|
||||
return NULL;
|
||||
|
||||
frame->format = pix_fmt;
|
||||
frame->width = width;
|
||||
frame->height = height;
|
||||
|
||||
/* allocate the buffers for the frame data */
|
||||
ret = av_frame_get_buffer(frame, 0);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Could not allocate frame data.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
static void open_video(AVFormatContext *oc, const AVCodec *codec,
|
||||
OutputStream *ost, AVDictionary *opt_arg)
|
||||
{
|
||||
int ret;
|
||||
AVCodecContext *c = ost->enc;
|
||||
AVDictionary *opt = NULL;
|
||||
|
||||
av_dict_copy(&opt, opt_arg, 0);
|
||||
|
||||
/* open the codec */
|
||||
ret = avcodec_open2(c, codec, &opt);
|
||||
av_dict_free(&opt);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Could not open video codec: %s\n", av_err2str(ret));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* allocate and init a reusable frame */
|
||||
ost->frame = alloc_frame(c->pix_fmt, c->width, c->height);
|
||||
if (!ost->frame) {
|
||||
fprintf(stderr, "Could not allocate video frame\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* If the output format is not YUV420P, then a temporary YUV420P
|
||||
* picture is needed too. It is then converted to the required
|
||||
* output format. */
|
||||
ost->tmp_frame = NULL;
|
||||
if (c->pix_fmt != AV_PIX_FMT_YUV420P) {
|
||||
ost->tmp_frame = alloc_frame(AV_PIX_FMT_YUV420P, c->width, c->height);
|
||||
if (!ost->tmp_frame) {
|
||||
fprintf(stderr, "Could not allocate temporary video frame\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* copy the stream parameters to the muxer */
|
||||
ret = avcodec_parameters_from_context(ost->st->codecpar, c);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Could not copy the stream parameters\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Prepare a dummy image. */
|
||||
static void fill_yuv_image(AVFrame *pict, int frame_index,
|
||||
int width, int height)
|
||||
{
|
||||
int x, y, i;
|
||||
|
||||
i = frame_index;
|
||||
|
||||
/* Y */
|
||||
for (y = 0; y < height; y++)
|
||||
for (x = 0; x < width; x++)
|
||||
pict->data[0][y * pict->linesize[0] + x] = x + y + i * 3;
|
||||
|
||||
/* Cb and Cr */
|
||||
for (y = 0; y < height / 2; y++) {
|
||||
for (x = 0; x < width / 2; x++) {
|
||||
pict->data[1][y * pict->linesize[1] + x] = 128 + y + i * 2;
|
||||
pict->data[2][y * pict->linesize[2] + x] = 64 + x + i * 5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static AVFrame *get_video_frame(OutputStream *ost)
|
||||
{
|
||||
AVCodecContext *c = ost->enc;
|
||||
|
||||
/* check if we want to generate more frames */
|
||||
if (av_compare_ts(ost->next_pts, c->time_base,
|
||||
STREAM_DURATION, (AVRational){ 1, 1 }) > 0)
|
||||
return NULL;
|
||||
|
||||
/* when we pass a frame to the encoder, it may keep a reference to it
|
||||
* internally; make sure we do not overwrite it here */
|
||||
if (av_frame_make_writable(ost->frame) < 0)
|
||||
exit(1);
|
||||
|
||||
if (c->pix_fmt != AV_PIX_FMT_YUV420P) {
|
||||
/* as we only generate a YUV420P picture, we must convert it
|
||||
* to the codec pixel format if needed */
|
||||
if (!ost->sws_ctx) {
|
||||
ost->sws_ctx = sws_getContext(c->width, c->height,
|
||||
AV_PIX_FMT_YUV420P,
|
||||
c->width, c->height,
|
||||
c->pix_fmt,
|
||||
SCALE_FLAGS, NULL, NULL, NULL);
|
||||
if (!ost->sws_ctx) {
|
||||
fprintf(stderr,
|
||||
"Could not initialize the conversion context\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
fill_yuv_image(ost->tmp_frame, ost->next_pts, c->width, c->height);
|
||||
sws_scale(ost->sws_ctx, (const uint8_t * const *) ost->tmp_frame->data,
|
||||
ost->tmp_frame->linesize, 0, c->height, ost->frame->data,
|
||||
ost->frame->linesize);
|
||||
} else {
|
||||
fill_yuv_image(ost->frame, ost->next_pts, c->width, c->height);
|
||||
}
|
||||
|
||||
ost->frame->pts = ost->next_pts++;
|
||||
|
||||
return ost->frame;
|
||||
}
|
||||
|
||||
/*
|
||||
* encode one video frame and send it to the muxer
|
||||
* return 1 when encoding is finished, 0 otherwise
|
||||
*/
|
||||
static int write_video_frame(AVFormatContext *oc, OutputStream *ost)
|
||||
{
|
||||
return write_frame(oc, ost->enc, ost->st, get_video_frame(ost), ost->tmp_pkt);
|
||||
}
|
||||
|
||||
static void close_stream(AVFormatContext *oc, OutputStream *ost)
|
||||
{
|
||||
avcodec_free_context(&ost->enc);
|
||||
av_frame_free(&ost->frame);
|
||||
av_frame_free(&ost->tmp_frame);
|
||||
av_packet_free(&ost->tmp_pkt);
|
||||
sws_freeContext(ost->sws_ctx);
|
||||
swr_free(&ost->swr_ctx);
|
||||
}
|
||||
|
||||
/**************************************************************/
|
||||
/* media file output */
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
OutputStream video_st = { 0 }, audio_st = { 0 };
|
||||
const AVOutputFormat *fmt;
|
||||
const char *filename;
|
||||
AVFormatContext *oc;
|
||||
const AVCodec *audio_codec, *video_codec;
|
||||
int ret;
|
||||
int have_video = 0, have_audio = 0;
|
||||
int encode_video = 0, encode_audio = 0;
|
||||
AVDictionary *opt = NULL;
|
||||
int i;
|
||||
|
||||
if (argc < 2) {
|
||||
printf("usage: %s output_file\n"
|
||||
"API example program to output a media file with libavformat.\n"
|
||||
"This program generates a synthetic audio and video stream, encodes and\n"
|
||||
"muxes them into a file named output_file.\n"
|
||||
"The output format is automatically guessed according to the file extension.\n"
|
||||
"Raw images can also be output by using '%%d' in the filename.\n"
|
||||
"\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
filename = argv[1];
|
||||
for (i = 2; i+1 < argc; i+=2) {
|
||||
if (!strcmp(argv[i], "-flags") || !strcmp(argv[i], "-fflags"))
|
||||
av_dict_set(&opt, argv[i]+1, argv[i+1], 0);
|
||||
}
|
||||
|
||||
/* allocate the output media context */
|
||||
avformat_alloc_output_context2(&oc, NULL, NULL, filename);
|
||||
if (!oc) {
|
||||
printf("Could not deduce output format from file extension: using MPEG.\n");
|
||||
avformat_alloc_output_context2(&oc, NULL, "mpeg", filename);
|
||||
}
|
||||
if (!oc)
|
||||
return 1;
|
||||
|
||||
fmt = oc->oformat;
|
||||
|
||||
/* Add the audio and video streams using the default format codecs
|
||||
* and initialize the codecs. */
|
||||
if (fmt->video_codec != AV_CODEC_ID_NONE) {
|
||||
add_stream(&video_st, oc, &video_codec, fmt->video_codec);
|
||||
have_video = 1;
|
||||
encode_video = 1;
|
||||
}
|
||||
if (fmt->audio_codec != AV_CODEC_ID_NONE) {
|
||||
add_stream(&audio_st, oc, &audio_codec, fmt->audio_codec);
|
||||
have_audio = 1;
|
||||
encode_audio = 1;
|
||||
}
|
||||
|
||||
/* Now that all the parameters are set, we can open the audio and
|
||||
* video codecs and allocate the necessary encode buffers. */
|
||||
if (have_video)
|
||||
open_video(oc, video_codec, &video_st, opt);
|
||||
|
||||
if (have_audio)
|
||||
open_audio(oc, audio_codec, &audio_st, opt);
|
||||
|
||||
av_dump_format(oc, 0, filename, 1);
|
||||
|
||||
/* open the output file, if needed */
|
||||
if (!(fmt->flags & AVFMT_NOFILE)) {
|
||||
ret = avio_open(&oc->pb, filename, AVIO_FLAG_WRITE);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Could not open '%s': %s\n", filename,
|
||||
av_err2str(ret));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Write the stream header, if any. */
|
||||
ret = avformat_write_header(oc, &opt);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error occurred when opening output file: %s\n",
|
||||
av_err2str(ret));
|
||||
return 1;
|
||||
}
|
||||
|
||||
while (encode_video || encode_audio) {
|
||||
/* select the stream to encode */
|
||||
if (encode_video &&
|
||||
(!encode_audio || av_compare_ts(video_st.next_pts, video_st.enc->time_base,
|
||||
audio_st.next_pts, audio_st.enc->time_base) <= 0)) {
|
||||
encode_video = !write_video_frame(oc, &video_st);
|
||||
} else {
|
||||
encode_audio = !write_audio_frame(oc, &audio_st);
|
||||
}
|
||||
}
|
||||
|
||||
av_write_trailer(oc);
|
||||
|
||||
/* Close each codec. */
|
||||
if (have_video)
|
||||
close_stream(oc, &video_st);
|
||||
if (have_audio)
|
||||
close_stream(oc, &audio_st);
|
||||
|
||||
if (!(fmt->flags & AVFMT_NOFILE))
|
||||
/* Close the output file. */
|
||||
avio_closep(&oc->pb);
|
||||
|
||||
/* free the stream */
|
||||
avformat_free_context(oc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,238 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2015 Anton Khirnov
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file Intel QSV-accelerated H.264 decoding API usage example
|
||||
* @example qsv_decode.c
|
||||
*
|
||||
* Perform QSV-accelerated H.264 decoding with output frames in the
|
||||
* GPU video surfaces, write the decoded frames to an output file.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libavformat/avio.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>
|
||||
|
||||
static int get_format(AVCodecContext *avctx, const enum AVPixelFormat *pix_fmts)
|
||||
{
|
||||
while (*pix_fmts != AV_PIX_FMT_NONE) {
|
||||
if (*pix_fmts == AV_PIX_FMT_QSV) {
|
||||
return AV_PIX_FMT_QSV;
|
||||
}
|
||||
|
||||
pix_fmts++;
|
||||
}
|
||||
|
||||
fprintf(stderr, "The QSV pixel format not offered in get_format()\n");
|
||||
|
||||
return AV_PIX_FMT_NONE;
|
||||
}
|
||||
|
||||
static int decode_packet(AVCodecContext *decoder_ctx,
|
||||
AVFrame *frame, AVFrame *sw_frame,
|
||||
AVPacket *pkt, AVIOContext *output_ctx)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = avcodec_send_packet(decoder_ctx, pkt);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error during decoding\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
while (ret >= 0) {
|
||||
int i, j;
|
||||
|
||||
ret = avcodec_receive_frame(decoder_ctx, frame);
|
||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
|
||||
break;
|
||||
else if (ret < 0) {
|
||||
fprintf(stderr, "Error during decoding\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* A real program would do something useful with the decoded frame here.
|
||||
* We just retrieve the raw data and write it to a file, which is rather
|
||||
* useless but pedagogic. */
|
||||
ret = av_hwframe_transfer_data(sw_frame, frame, 0);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error transferring the data to system memory\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
for (i = 0; i < FF_ARRAY_ELEMS(sw_frame->data) && sw_frame->data[i]; i++)
|
||||
for (j = 0; j < (sw_frame->height >> (i > 0)); j++)
|
||||
avio_write(output_ctx, sw_frame->data[i] + j * sw_frame->linesize[i], sw_frame->width);
|
||||
|
||||
fail:
|
||||
av_frame_unref(sw_frame);
|
||||
av_frame_unref(frame);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
AVFormatContext *input_ctx = NULL;
|
||||
AVStream *video_st = NULL;
|
||||
AVCodecContext *decoder_ctx = NULL;
|
||||
const AVCodec *decoder;
|
||||
|
||||
AVPacket *pkt = NULL;
|
||||
AVFrame *frame = NULL, *sw_frame = NULL;
|
||||
|
||||
AVIOContext *output_ctx = NULL;
|
||||
|
||||
int ret, i;
|
||||
|
||||
AVBufferRef *device_ref = NULL;
|
||||
|
||||
if (argc < 3) {
|
||||
fprintf(stderr, "Usage: %s <input file> <output file>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* open the input file */
|
||||
ret = avformat_open_input(&input_ctx, argv[1], NULL, NULL);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Cannot open input file '%s': ", argv[1]);
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* find the first H.264 video stream */
|
||||
for (i = 0; i < input_ctx->nb_streams; i++) {
|
||||
AVStream *st = input_ctx->streams[i];
|
||||
|
||||
if (st->codecpar->codec_id == AV_CODEC_ID_H264 && !video_st)
|
||||
video_st = st;
|
||||
else
|
||||
st->discard = AVDISCARD_ALL;
|
||||
}
|
||||
if (!video_st) {
|
||||
fprintf(stderr, "No H.264 video stream in the input file\n");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* open the hardware device */
|
||||
ret = av_hwdevice_ctx_create(&device_ref, AV_HWDEVICE_TYPE_QSV,
|
||||
"auto", NULL, 0);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Cannot open the hardware device\n");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* initialize the decoder */
|
||||
decoder = avcodec_find_decoder_by_name("h264_qsv");
|
||||
if (!decoder) {
|
||||
fprintf(stderr, "The QSV decoder is not present in libavcodec\n");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
decoder_ctx = avcodec_alloc_context3(decoder);
|
||||
if (!decoder_ctx) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto finish;
|
||||
}
|
||||
decoder_ctx->codec_id = AV_CODEC_ID_H264;
|
||||
if (video_st->codecpar->extradata_size) {
|
||||
decoder_ctx->extradata = av_mallocz(video_st->codecpar->extradata_size +
|
||||
AV_INPUT_BUFFER_PADDING_SIZE);
|
||||
if (!decoder_ctx->extradata) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto finish;
|
||||
}
|
||||
memcpy(decoder_ctx->extradata, video_st->codecpar->extradata,
|
||||
video_st->codecpar->extradata_size);
|
||||
decoder_ctx->extradata_size = video_st->codecpar->extradata_size;
|
||||
}
|
||||
|
||||
|
||||
decoder_ctx->hw_device_ctx = av_buffer_ref(device_ref);
|
||||
decoder_ctx->get_format = get_format;
|
||||
|
||||
ret = avcodec_open2(decoder_ctx, NULL, NULL);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error opening the decoder: ");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* open the output stream */
|
||||
ret = avio_open(&output_ctx, argv[2], AVIO_FLAG_WRITE);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error opening the output context: ");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
frame = av_frame_alloc();
|
||||
sw_frame = av_frame_alloc();
|
||||
pkt = av_packet_alloc();
|
||||
if (!frame || !sw_frame || !pkt) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* actual decoding */
|
||||
while (ret >= 0) {
|
||||
ret = av_read_frame(input_ctx, pkt);
|
||||
if (ret < 0)
|
||||
break;
|
||||
|
||||
if (pkt->stream_index == video_st->index)
|
||||
ret = decode_packet(decoder_ctx, frame, sw_frame, pkt, output_ctx);
|
||||
|
||||
av_packet_unref(pkt);
|
||||
}
|
||||
|
||||
/* flush the decoder */
|
||||
ret = decode_packet(decoder_ctx, frame, sw_frame, NULL, output_ctx);
|
||||
|
||||
finish:
|
||||
if (ret < 0)
|
||||
fprintf(stderr, "%s\n", av_err2str(ret));
|
||||
|
||||
avformat_close_input(&input_ctx);
|
||||
|
||||
av_frame_free(&frame);
|
||||
av_frame_free(&sw_frame);
|
||||
av_packet_free(&pkt);
|
||||
|
||||
avcodec_free_context(&decoder_ctx);
|
||||
|
||||
av_buffer_unref(&device_ref);
|
||||
|
||||
avio_close(output_ctx);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1,436 +0,0 @@
|
||||
/*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file Intel QSV-accelerated video transcoding API usage example
|
||||
* @example qsv_transcode.c
|
||||
*
|
||||
* Perform QSV-accelerated transcoding and show to dynamically change
|
||||
* encoder's options.
|
||||
*
|
||||
* Usage: qsv_transcode input_stream codec output_stream initial option
|
||||
* { frame_number new_option }
|
||||
* e.g: - qsv_transcode input.mp4 h264_qsv output_h264.mp4 "g 60"
|
||||
* - qsv_transcode input.mp4 hevc_qsv output_hevc.mp4 "g 60 async_depth 1"
|
||||
* 100 "g 120"
|
||||
* (initialize codec with gop_size 60 and change it to 120 after 100
|
||||
* frames)
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <libavutil/hwcontext.h>
|
||||
#include <libavutil/mem.h>
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libavutil/opt.h>
|
||||
|
||||
static AVFormatContext *ifmt_ctx = NULL, *ofmt_ctx = NULL;
|
||||
static AVBufferRef *hw_device_ctx = NULL;
|
||||
static AVCodecContext *decoder_ctx = NULL, *encoder_ctx = NULL;
|
||||
static int video_stream = -1;
|
||||
|
||||
typedef struct DynamicSetting {
|
||||
int frame_number;
|
||||
char* optstr;
|
||||
} DynamicSetting;
|
||||
static DynamicSetting *dynamic_setting;
|
||||
static int setting_number;
|
||||
static int current_setting_number;
|
||||
|
||||
static int str_to_dict(char* optstr, AVDictionary **opt)
|
||||
{
|
||||
char *key, *value;
|
||||
if (strlen(optstr) == 0)
|
||||
return 0;
|
||||
key = strtok(optstr, " ");
|
||||
if (key == NULL)
|
||||
return AVERROR(EINVAL);
|
||||
value = strtok(NULL, " ");
|
||||
if (value == NULL)
|
||||
return AVERROR(EINVAL);
|
||||
av_dict_set(opt, key, value, 0);
|
||||
do {
|
||||
key = strtok(NULL, " ");
|
||||
if (key == NULL)
|
||||
return 0;
|
||||
value = strtok(NULL, " ");
|
||||
if (value == NULL)
|
||||
return AVERROR(EINVAL);
|
||||
av_dict_set(opt, key, value, 0);
|
||||
} while(1);
|
||||
}
|
||||
|
||||
static int dynamic_set_parameter(AVCodecContext *avctx)
|
||||
{
|
||||
AVDictionary *opts = NULL;
|
||||
int ret = 0;
|
||||
static int frame_number = 0;
|
||||
frame_number++;
|
||||
if (current_setting_number < setting_number &&
|
||||
frame_number == dynamic_setting[current_setting_number].frame_number) {
|
||||
AVDictionaryEntry *e = NULL;
|
||||
ret = str_to_dict(dynamic_setting[current_setting_number++].optstr, &opts);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "The dynamic parameter is wrong\n");
|
||||
goto fail;
|
||||
}
|
||||
/* Set common option. The dictionary will be freed and replaced
|
||||
* by a new one containing all options not found in common option list.
|
||||
* Then this new dictionary is used to set private option. */
|
||||
if ((ret = av_opt_set_dict(avctx, &opts)) < 0)
|
||||
goto fail;
|
||||
/* Set codec specific option */
|
||||
if ((ret = av_opt_set_dict(avctx->priv_data, &opts)) < 0)
|
||||
goto fail;
|
||||
/* There is no "framerate" option in common option list. Use "-r" to set
|
||||
* framerate, which is compatible with ffmpeg commandline. The video is
|
||||
* assumed to be average frame rate, so set time_base to 1/framerate. */
|
||||
e = av_dict_get(opts, "r", NULL, 0);
|
||||
if (e) {
|
||||
avctx->framerate = av_d2q(atof(e->value), INT_MAX);
|
||||
encoder_ctx->time_base = av_inv_q(encoder_ctx->framerate);
|
||||
}
|
||||
}
|
||||
fail:
|
||||
av_dict_free(&opts);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int get_format(AVCodecContext *avctx, const enum AVPixelFormat *pix_fmts)
|
||||
{
|
||||
while (*pix_fmts != AV_PIX_FMT_NONE) {
|
||||
if (*pix_fmts == AV_PIX_FMT_QSV) {
|
||||
return AV_PIX_FMT_QSV;
|
||||
}
|
||||
|
||||
pix_fmts++;
|
||||
}
|
||||
|
||||
fprintf(stderr, "The QSV pixel format not offered in get_format()\n");
|
||||
|
||||
return AV_PIX_FMT_NONE;
|
||||
}
|
||||
|
||||
static int open_input_file(char *filename)
|
||||
{
|
||||
int ret;
|
||||
const AVCodec *decoder = NULL;
|
||||
AVStream *video = NULL;
|
||||
|
||||
if ((ret = avformat_open_input(&ifmt_ctx, filename, NULL, NULL)) < 0) {
|
||||
fprintf(stderr, "Cannot open input file '%s', Error code: %s\n",
|
||||
filename, av_err2str(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
if ((ret = avformat_find_stream_info(ifmt_ctx, NULL)) < 0) {
|
||||
fprintf(stderr, "Cannot find input stream information. Error code: %s\n",
|
||||
av_err2str(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = av_find_best_stream(ifmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Cannot find a video stream in the input file. "
|
||||
"Error code: %s\n", av_err2str(ret));
|
||||
return ret;
|
||||
}
|
||||
video_stream = ret;
|
||||
video = ifmt_ctx->streams[video_stream];
|
||||
|
||||
switch(video->codecpar->codec_id) {
|
||||
case AV_CODEC_ID_H264:
|
||||
decoder = avcodec_find_decoder_by_name("h264_qsv");
|
||||
break;
|
||||
case AV_CODEC_ID_HEVC:
|
||||
decoder = avcodec_find_decoder_by_name("hevc_qsv");
|
||||
break;
|
||||
case AV_CODEC_ID_VP9:
|
||||
decoder = avcodec_find_decoder_by_name("vp9_qsv");
|
||||
break;
|
||||
case AV_CODEC_ID_VP8:
|
||||
decoder = avcodec_find_decoder_by_name("vp8_qsv");
|
||||
break;
|
||||
case AV_CODEC_ID_AV1:
|
||||
decoder = avcodec_find_decoder_by_name("av1_qsv");
|
||||
break;
|
||||
case AV_CODEC_ID_MPEG2VIDEO:
|
||||
decoder = avcodec_find_decoder_by_name("mpeg2_qsv");
|
||||
break;
|
||||
case AV_CODEC_ID_MJPEG:
|
||||
decoder = avcodec_find_decoder_by_name("mjpeg_qsv");
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Codec is not supported by qsv\n");
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
if (!(decoder_ctx = avcodec_alloc_context3(decoder)))
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
if ((ret = avcodec_parameters_to_context(decoder_ctx, video->codecpar)) < 0) {
|
||||
fprintf(stderr, "avcodec_parameters_to_context error. Error code: %s\n",
|
||||
av_err2str(ret));
|
||||
return ret;
|
||||
}
|
||||
decoder_ctx->framerate = av_guess_frame_rate(ifmt_ctx, video, NULL);
|
||||
|
||||
decoder_ctx->hw_device_ctx = av_buffer_ref(hw_device_ctx);
|
||||
if (!decoder_ctx->hw_device_ctx) {
|
||||
fprintf(stderr, "A hardware device reference create failed.\n");
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
decoder_ctx->get_format = get_format;
|
||||
decoder_ctx->pkt_timebase = video->time_base;
|
||||
if ((ret = avcodec_open2(decoder_ctx, decoder, NULL)) < 0)
|
||||
fprintf(stderr, "Failed to open codec for decoding. Error code: %s\n",
|
||||
av_err2str(ret));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int encode_write(AVPacket *enc_pkt, AVFrame *frame)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
av_packet_unref(enc_pkt);
|
||||
|
||||
if((ret = dynamic_set_parameter(encoder_ctx)) < 0) {
|
||||
fprintf(stderr, "Failed to set dynamic parameter. Error code: %s\n",
|
||||
av_err2str(ret));
|
||||
goto end;
|
||||
}
|
||||
|
||||
if ((ret = avcodec_send_frame(encoder_ctx, frame)) < 0) {
|
||||
fprintf(stderr, "Error during encoding. Error code: %s\n", av_err2str(ret));
|
||||
goto end;
|
||||
}
|
||||
while (1) {
|
||||
if (ret = avcodec_receive_packet(encoder_ctx, enc_pkt))
|
||||
break;
|
||||
enc_pkt->stream_index = 0;
|
||||
av_packet_rescale_ts(enc_pkt, encoder_ctx->time_base,
|
||||
ofmt_ctx->streams[0]->time_base);
|
||||
if ((ret = av_interleaved_write_frame(ofmt_ctx, enc_pkt)) < 0) {
|
||||
fprintf(stderr, "Error during writing data to output file. "
|
||||
"Error code: %s\n", av_err2str(ret));
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
if (ret == AVERROR_EOF)
|
||||
return 0;
|
||||
ret = ((ret == AVERROR(EAGAIN)) ? 0:-1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int dec_enc(AVPacket *pkt, const AVCodec *enc_codec, char *optstr)
|
||||
{
|
||||
AVFrame *frame;
|
||||
int ret = 0;
|
||||
|
||||
ret = avcodec_send_packet(decoder_ctx, pkt);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error during decoding. Error code: %s\n", av_err2str(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
while (ret >= 0) {
|
||||
if (!(frame = av_frame_alloc()))
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
ret = avcodec_receive_frame(decoder_ctx, frame);
|
||||
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
|
||||
av_frame_free(&frame);
|
||||
return 0;
|
||||
} else if (ret < 0) {
|
||||
fprintf(stderr, "Error while decoding. Error code: %s\n", av_err2str(ret));
|
||||
goto fail;
|
||||
}
|
||||
if (!encoder_ctx->hw_frames_ctx) {
|
||||
AVDictionaryEntry *e = NULL;
|
||||
AVDictionary *opts = NULL;
|
||||
AVStream *ost;
|
||||
/* we need to ref hw_frames_ctx of decoder to initialize encoder's codec.
|
||||
Only after we get a decoded frame, can we obtain its hw_frames_ctx */
|
||||
encoder_ctx->hw_frames_ctx = av_buffer_ref(decoder_ctx->hw_frames_ctx);
|
||||
if (!encoder_ctx->hw_frames_ctx) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto fail;
|
||||
}
|
||||
/* set AVCodecContext Parameters for encoder, here we keep them stay
|
||||
* the same as decoder.
|
||||
*/
|
||||
encoder_ctx->time_base = av_inv_q(decoder_ctx->framerate);
|
||||
encoder_ctx->pix_fmt = AV_PIX_FMT_QSV;
|
||||
encoder_ctx->width = decoder_ctx->width;
|
||||
encoder_ctx->height = decoder_ctx->height;
|
||||
if ((ret = str_to_dict(optstr, &opts)) < 0) {
|
||||
fprintf(stderr, "Failed to set encoding parameter.\n");
|
||||
goto fail;
|
||||
}
|
||||
/* There is no "framerate" option in common option list. Use "-r" to
|
||||
* set framerate, which is compatible with ffmpeg commandline. The
|
||||
* video is assumed to be average frame rate, so set time_base to
|
||||
* 1/framerate. */
|
||||
e = av_dict_get(opts, "r", NULL, 0);
|
||||
if (e) {
|
||||
encoder_ctx->framerate = av_d2q(atof(e->value), INT_MAX);
|
||||
encoder_ctx->time_base = av_inv_q(encoder_ctx->framerate);
|
||||
}
|
||||
if ((ret = avcodec_open2(encoder_ctx, enc_codec, &opts)) < 0) {
|
||||
fprintf(stderr, "Failed to open encode codec. Error code: %s\n",
|
||||
av_err2str(ret));
|
||||
av_dict_free(&opts);
|
||||
goto fail;
|
||||
}
|
||||
av_dict_free(&opts);
|
||||
|
||||
if (!(ost = avformat_new_stream(ofmt_ctx, enc_codec))) {
|
||||
fprintf(stderr, "Failed to allocate stream for output format.\n");
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ost->time_base = encoder_ctx->time_base;
|
||||
ret = avcodec_parameters_from_context(ost->codecpar, encoder_ctx);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Failed to copy the stream parameters. "
|
||||
"Error code: %s\n", av_err2str(ret));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* write the stream header */
|
||||
if ((ret = avformat_write_header(ofmt_ctx, NULL)) < 0) {
|
||||
fprintf(stderr, "Error while writing stream header. "
|
||||
"Error code: %s\n", av_err2str(ret));
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
frame->pts = av_rescale_q(frame->pts, decoder_ctx->pkt_timebase,
|
||||
encoder_ctx->time_base);
|
||||
if ((ret = encode_write(pkt, frame)) < 0)
|
||||
fprintf(stderr, "Error during encoding and writing.\n");
|
||||
|
||||
fail:
|
||||
av_frame_free(&frame);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const AVCodec *enc_codec;
|
||||
int ret = 0;
|
||||
AVPacket *dec_pkt = NULL;
|
||||
|
||||
if (argc < 5 || (argc - 5) % 2) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Usage: %s <input file> <encoder> <output file>"
|
||||
" <\"encoding option set 0\"> [<frame_number> <\"encoding options set 1\">]...\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
setting_number = (argc - 5) / 2;
|
||||
dynamic_setting = av_malloc(setting_number * sizeof(*dynamic_setting));
|
||||
current_setting_number = 0;
|
||||
for (int i = 0; i < setting_number; i++) {
|
||||
dynamic_setting[i].frame_number = atoi(argv[i*2 + 5]);
|
||||
dynamic_setting[i].optstr = argv[i*2 + 6];
|
||||
}
|
||||
|
||||
ret = av_hwdevice_ctx_create(&hw_device_ctx, AV_HWDEVICE_TYPE_QSV, NULL, NULL, 0);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Failed to create a QSV device. Error code: %s\n", av_err2str(ret));
|
||||
goto end;
|
||||
}
|
||||
|
||||
dec_pkt = av_packet_alloc();
|
||||
if (!dec_pkt) {
|
||||
fprintf(stderr, "Failed to allocate decode packet\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if ((ret = open_input_file(argv[1])) < 0)
|
||||
goto end;
|
||||
|
||||
if (!(enc_codec = avcodec_find_encoder_by_name(argv[2]))) {
|
||||
fprintf(stderr, "Could not find encoder '%s'\n", argv[2]);
|
||||
ret = -1;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if ((ret = (avformat_alloc_output_context2(&ofmt_ctx, NULL, NULL, argv[3]))) < 0) {
|
||||
fprintf(stderr, "Failed to deduce output format from file extension. Error code: "
|
||||
"%s\n", av_err2str(ret));
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (!(encoder_ctx = avcodec_alloc_context3(enc_codec))) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = avio_open(&ofmt_ctx->pb, argv[3], AVIO_FLAG_WRITE);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Cannot open output file. "
|
||||
"Error code: %s\n", av_err2str(ret));
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* read all packets and only transcoding video */
|
||||
while (ret >= 0) {
|
||||
if ((ret = av_read_frame(ifmt_ctx, dec_pkt)) < 0)
|
||||
break;
|
||||
|
||||
if (video_stream == dec_pkt->stream_index)
|
||||
ret = dec_enc(dec_pkt, enc_codec, argv[4]);
|
||||
|
||||
av_packet_unref(dec_pkt);
|
||||
}
|
||||
|
||||
/* flush decoder */
|
||||
av_packet_unref(dec_pkt);
|
||||
if ((ret = dec_enc(dec_pkt, enc_codec, argv[4])) < 0) {
|
||||
fprintf(stderr, "Failed to flush decoder %s\n", av_err2str(ret));
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* flush encoder */
|
||||
if ((ret = encode_write(dec_pkt, NULL)) < 0) {
|
||||
fprintf(stderr, "Failed to flush encoder %s\n", av_err2str(ret));
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* write the trailer for output stream */
|
||||
if ((ret = av_write_trailer(ofmt_ctx)) < 0)
|
||||
fprintf(stderr, "Failed to write trailer %s\n", av_err2str(ret));
|
||||
|
||||
end:
|
||||
avformat_close_input(&ifmt_ctx);
|
||||
avformat_close_input(&ofmt_ctx);
|
||||
avcodec_free_context(&decoder_ctx);
|
||||
avcodec_free_context(&encoder_ctx);
|
||||
av_buffer_unref(&hw_device_ctx);
|
||||
av_packet_free(&dec_pkt);
|
||||
av_freep(&dynamic_setting);
|
||||
return ret;
|
||||
}
|
||||
@@ -1,199 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013 Stefano Sabatini
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file libavformat/libavcodec demuxing and muxing API usage example
|
||||
* @example remux.c
|
||||
*
|
||||
* Remux streams from one container format to another. Data is copied from the
|
||||
* input to the output without transcoding.
|
||||
*/
|
||||
|
||||
#include <libavutil/mem.h>
|
||||
#include <libavutil/timestamp.h>
|
||||
#include <libavformat/avformat.h>
|
||||
|
||||
static void log_packet(const AVFormatContext *fmt_ctx, const AVPacket *pkt, const char *tag)
|
||||
{
|
||||
AVRational *time_base = &fmt_ctx->streams[pkt->stream_index]->time_base;
|
||||
|
||||
printf("%s: pts:%s pts_time:%s dts:%s dts_time:%s duration:%s duration_time:%s stream_index:%d\n",
|
||||
tag,
|
||||
av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, time_base),
|
||||
av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, time_base),
|
||||
av_ts2str(pkt->duration), av_ts2timestr(pkt->duration, time_base),
|
||||
pkt->stream_index);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const AVOutputFormat *ofmt = NULL;
|
||||
AVFormatContext *ifmt_ctx = NULL, *ofmt_ctx = NULL;
|
||||
AVPacket *pkt = NULL;
|
||||
const char *in_filename, *out_filename;
|
||||
int ret, i;
|
||||
int stream_index = 0;
|
||||
int *stream_mapping = NULL;
|
||||
int stream_mapping_size = 0;
|
||||
|
||||
if (argc < 3) {
|
||||
printf("usage: %s input output\n"
|
||||
"API example program to remux a media file with libavformat and libavcodec.\n"
|
||||
"The output format is guessed according to the file extension.\n"
|
||||
"\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
in_filename = argv[1];
|
||||
out_filename = argv[2];
|
||||
|
||||
pkt = av_packet_alloc();
|
||||
if (!pkt) {
|
||||
fprintf(stderr, "Could not allocate AVPacket\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((ret = avformat_open_input(&ifmt_ctx, in_filename, 0, 0)) < 0) {
|
||||
fprintf(stderr, "Could not open input file '%s'", in_filename);
|
||||
goto end;
|
||||
}
|
||||
|
||||
if ((ret = avformat_find_stream_info(ifmt_ctx, 0)) < 0) {
|
||||
fprintf(stderr, "Failed to retrieve input stream information");
|
||||
goto end;
|
||||
}
|
||||
|
||||
av_dump_format(ifmt_ctx, 0, in_filename, 0);
|
||||
|
||||
avformat_alloc_output_context2(&ofmt_ctx, NULL, NULL, out_filename);
|
||||
if (!ofmt_ctx) {
|
||||
fprintf(stderr, "Could not create output context\n");
|
||||
ret = AVERROR_UNKNOWN;
|
||||
goto end;
|
||||
}
|
||||
|
||||
stream_mapping_size = ifmt_ctx->nb_streams;
|
||||
stream_mapping = av_calloc(stream_mapping_size, sizeof(*stream_mapping));
|
||||
if (!stream_mapping) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto end;
|
||||
}
|
||||
|
||||
ofmt = ofmt_ctx->oformat;
|
||||
|
||||
for (i = 0; i < ifmt_ctx->nb_streams; i++) {
|
||||
AVStream *out_stream;
|
||||
AVStream *in_stream = ifmt_ctx->streams[i];
|
||||
AVCodecParameters *in_codecpar = in_stream->codecpar;
|
||||
|
||||
if (in_codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
|
||||
in_codecpar->codec_type != AVMEDIA_TYPE_VIDEO &&
|
||||
in_codecpar->codec_type != AVMEDIA_TYPE_SUBTITLE) {
|
||||
stream_mapping[i] = -1;
|
||||
continue;
|
||||
}
|
||||
|
||||
stream_mapping[i] = stream_index++;
|
||||
|
||||
out_stream = avformat_new_stream(ofmt_ctx, NULL);
|
||||
if (!out_stream) {
|
||||
fprintf(stderr, "Failed allocating output stream\n");
|
||||
ret = AVERROR_UNKNOWN;
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = avcodec_parameters_copy(out_stream->codecpar, in_codecpar);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Failed to copy codec parameters\n");
|
||||
goto end;
|
||||
}
|
||||
out_stream->codecpar->codec_tag = 0;
|
||||
}
|
||||
av_dump_format(ofmt_ctx, 0, out_filename, 1);
|
||||
|
||||
if (!(ofmt->flags & AVFMT_NOFILE)) {
|
||||
ret = avio_open(&ofmt_ctx->pb, out_filename, AVIO_FLAG_WRITE);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Could not open output file '%s'", out_filename);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
ret = avformat_write_header(ofmt_ctx, NULL);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error occurred when opening output file\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
AVStream *in_stream, *out_stream;
|
||||
|
||||
ret = av_read_frame(ifmt_ctx, pkt);
|
||||
if (ret < 0)
|
||||
break;
|
||||
|
||||
in_stream = ifmt_ctx->streams[pkt->stream_index];
|
||||
if (pkt->stream_index >= stream_mapping_size ||
|
||||
stream_mapping[pkt->stream_index] < 0) {
|
||||
av_packet_unref(pkt);
|
||||
continue;
|
||||
}
|
||||
|
||||
pkt->stream_index = stream_mapping[pkt->stream_index];
|
||||
out_stream = ofmt_ctx->streams[pkt->stream_index];
|
||||
log_packet(ifmt_ctx, pkt, "in");
|
||||
|
||||
/* copy packet */
|
||||
av_packet_rescale_ts(pkt, in_stream->time_base, out_stream->time_base);
|
||||
pkt->pos = -1;
|
||||
log_packet(ofmt_ctx, pkt, "out");
|
||||
|
||||
ret = av_interleaved_write_frame(ofmt_ctx, pkt);
|
||||
/* pkt is now blank (av_interleaved_write_frame() takes ownership of
|
||||
* its contents and resets pkt), so that no unreferencing is necessary.
|
||||
* This would be different if one used av_write_frame(). */
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error muxing packet\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
av_write_trailer(ofmt_ctx);
|
||||
end:
|
||||
av_packet_free(&pkt);
|
||||
|
||||
avformat_close_input(&ifmt_ctx);
|
||||
|
||||
/* close output */
|
||||
if (ofmt_ctx && !(ofmt->flags & AVFMT_NOFILE))
|
||||
avio_closep(&ofmt_ctx->pb);
|
||||
avformat_free_context(ofmt_ctx);
|
||||
|
||||
av_freep(&stream_mapping);
|
||||
|
||||
if (ret < 0 && ret != AVERROR_EOF) {
|
||||
fprintf(stderr, "Error occurred: %s\n", av_err2str(ret));
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,220 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Stefano Sabatini
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file audio resampling API usage example
|
||||
* @example resample_audio.c
|
||||
*
|
||||
* Generate a synthetic audio signal, and Use libswresample API to perform audio
|
||||
* resampling. The output is written to a raw audio file to be played with
|
||||
* ffplay.
|
||||
*/
|
||||
|
||||
#include <libavutil/opt.h>
|
||||
#include <libavutil/channel_layout.h>
|
||||
#include <libavutil/samplefmt.h>
|
||||
#include <libswresample/swresample.h>
|
||||
|
||||
static int get_format_from_sample_fmt(const char **fmt,
|
||||
enum AVSampleFormat sample_fmt)
|
||||
{
|
||||
int i;
|
||||
struct sample_fmt_entry {
|
||||
enum AVSampleFormat sample_fmt; const char *fmt_be, *fmt_le;
|
||||
} sample_fmt_entries[] = {
|
||||
{ AV_SAMPLE_FMT_U8, "u8", "u8" },
|
||||
{ AV_SAMPLE_FMT_S16, "s16be", "s16le" },
|
||||
{ AV_SAMPLE_FMT_S32, "s32be", "s32le" },
|
||||
{ AV_SAMPLE_FMT_FLT, "f32be", "f32le" },
|
||||
{ AV_SAMPLE_FMT_DBL, "f64be", "f64le" },
|
||||
};
|
||||
*fmt = NULL;
|
||||
|
||||
for (i = 0; i < FF_ARRAY_ELEMS(sample_fmt_entries); i++) {
|
||||
struct sample_fmt_entry *entry = &sample_fmt_entries[i];
|
||||
if (sample_fmt == entry->sample_fmt) {
|
||||
*fmt = AV_NE(entry->fmt_be, entry->fmt_le);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr,
|
||||
"Sample format %s not supported as output format\n",
|
||||
av_get_sample_fmt_name(sample_fmt));
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill dst buffer with nb_samples, generated starting from t.
|
||||
*/
|
||||
static void fill_samples(double *dst, int nb_samples, int nb_channels, int sample_rate, double *t)
|
||||
{
|
||||
int i, j;
|
||||
double tincr = 1.0 / sample_rate, *dstp = dst;
|
||||
const double c = 2 * M_PI * 440.0;
|
||||
|
||||
/* generate sin tone with 440Hz frequency and duplicated channels */
|
||||
for (i = 0; i < nb_samples; i++) {
|
||||
*dstp = sin(c * *t);
|
||||
for (j = 1; j < nb_channels; j++)
|
||||
dstp[j] = dstp[0];
|
||||
dstp += nb_channels;
|
||||
*t += tincr;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
AVChannelLayout src_ch_layout = AV_CHANNEL_LAYOUT_STEREO, dst_ch_layout = AV_CHANNEL_LAYOUT_SURROUND;
|
||||
int src_rate = 48000, dst_rate = 44100;
|
||||
uint8_t **src_data = NULL, **dst_data = NULL;
|
||||
int src_nb_channels = 0, dst_nb_channels = 0;
|
||||
int src_linesize, dst_linesize;
|
||||
int src_nb_samples = 1024, dst_nb_samples, max_dst_nb_samples;
|
||||
enum AVSampleFormat src_sample_fmt = AV_SAMPLE_FMT_DBL, dst_sample_fmt = AV_SAMPLE_FMT_S16;
|
||||
const char *dst_filename = NULL;
|
||||
FILE *dst_file;
|
||||
int dst_bufsize;
|
||||
const char *fmt;
|
||||
struct SwrContext *swr_ctx;
|
||||
char buf[64];
|
||||
double t;
|
||||
int ret;
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "Usage: %s output_file\n"
|
||||
"API example program to show how to resample an audio stream with libswresample.\n"
|
||||
"This program generates a series of audio frames, resamples them to a specified "
|
||||
"output format and rate and saves them to an output file named output_file.\n",
|
||||
argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
dst_filename = argv[1];
|
||||
|
||||
dst_file = fopen(dst_filename, "wb");
|
||||
if (!dst_file) {
|
||||
fprintf(stderr, "Could not open destination file %s\n", dst_filename);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* create resampler context */
|
||||
swr_ctx = swr_alloc();
|
||||
if (!swr_ctx) {
|
||||
fprintf(stderr, "Could not allocate resampler context\n");
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* set options */
|
||||
av_opt_set_chlayout(swr_ctx, "in_chlayout", &src_ch_layout, 0);
|
||||
av_opt_set_int(swr_ctx, "in_sample_rate", src_rate, 0);
|
||||
av_opt_set_sample_fmt(swr_ctx, "in_sample_fmt", src_sample_fmt, 0);
|
||||
|
||||
av_opt_set_chlayout(swr_ctx, "out_chlayout", &dst_ch_layout, 0);
|
||||
av_opt_set_int(swr_ctx, "out_sample_rate", dst_rate, 0);
|
||||
av_opt_set_sample_fmt(swr_ctx, "out_sample_fmt", dst_sample_fmt, 0);
|
||||
|
||||
/* initialize the resampling context */
|
||||
if ((ret = swr_init(swr_ctx)) < 0) {
|
||||
fprintf(stderr, "Failed to initialize the resampling context\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* allocate source and destination samples buffers */
|
||||
|
||||
src_nb_channels = src_ch_layout.nb_channels;
|
||||
ret = av_samples_alloc_array_and_samples(&src_data, &src_linesize, src_nb_channels,
|
||||
src_nb_samples, src_sample_fmt, 0);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Could not allocate source samples\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* compute the number of converted samples: buffering is avoided
|
||||
* ensuring that the output buffer will contain at least all the
|
||||
* converted input samples */
|
||||
max_dst_nb_samples = dst_nb_samples =
|
||||
av_rescale_rnd(src_nb_samples, dst_rate, src_rate, AV_ROUND_UP);
|
||||
|
||||
/* buffer is going to be directly written to a rawaudio file, no alignment */
|
||||
dst_nb_channels = dst_ch_layout.nb_channels;
|
||||
ret = av_samples_alloc_array_and_samples(&dst_data, &dst_linesize, dst_nb_channels,
|
||||
dst_nb_samples, dst_sample_fmt, 0);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Could not allocate destination samples\n");
|
||||
goto end;
|
||||
}
|
||||
|
||||
t = 0;
|
||||
do {
|
||||
/* generate synthetic audio */
|
||||
fill_samples((double *)src_data[0], src_nb_samples, src_nb_channels, src_rate, &t);
|
||||
|
||||
/* compute destination number of samples */
|
||||
dst_nb_samples = av_rescale_rnd(swr_get_delay(swr_ctx, src_rate) +
|
||||
src_nb_samples, dst_rate, src_rate, AV_ROUND_UP);
|
||||
if (dst_nb_samples > max_dst_nb_samples) {
|
||||
av_freep(&dst_data[0]);
|
||||
ret = av_samples_alloc(dst_data, &dst_linesize, dst_nb_channels,
|
||||
dst_nb_samples, dst_sample_fmt, 1);
|
||||
if (ret < 0)
|
||||
break;
|
||||
max_dst_nb_samples = dst_nb_samples;
|
||||
}
|
||||
|
||||
/* convert to destination format */
|
||||
ret = swr_convert(swr_ctx, dst_data, dst_nb_samples, (const uint8_t **)src_data, src_nb_samples);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error while converting\n");
|
||||
goto end;
|
||||
}
|
||||
dst_bufsize = av_samples_get_buffer_size(&dst_linesize, dst_nb_channels,
|
||||
ret, dst_sample_fmt, 1);
|
||||
if (dst_bufsize < 0) {
|
||||
fprintf(stderr, "Could not get sample buffer size\n");
|
||||
goto end;
|
||||
}
|
||||
printf("t:%f in:%d out:%d\n", t, src_nb_samples, ret);
|
||||
fwrite(dst_data[0], 1, dst_bufsize, dst_file);
|
||||
} while (t < 10);
|
||||
|
||||
if ((ret = get_format_from_sample_fmt(&fmt, dst_sample_fmt)) < 0)
|
||||
goto end;
|
||||
av_channel_layout_describe(&dst_ch_layout, buf, sizeof(buf));
|
||||
fprintf(stderr, "Resampling succeeded. Play the output file with the command:\n"
|
||||
"ffplay -f %s -channel_layout %s -channels %d -ar %d %s\n",
|
||||
fmt, buf, dst_nb_channels, dst_rate, dst_filename);
|
||||
|
||||
end:
|
||||
fclose(dst_file);
|
||||
|
||||
if (src_data)
|
||||
av_freep(&src_data[0]);
|
||||
av_freep(&src_data);
|
||||
|
||||
if (dst_data)
|
||||
av_freep(&dst_data[0]);
|
||||
av_freep(&dst_data);
|
||||
|
||||
swr_free(&swr_ctx);
|
||||
return ret < 0;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user