Merge pull request #583 from arthenica/development

Merge v5.1 to main
pull/584/head
Taner Sener 3 years ago committed by GitHub
commit da12d00c15
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 10
      .github/ISSUE_TEMPLATE/bug_report.md
  2. 2
      .github/pull_request_template.md
  3. 40
      .github/workflows/android-build-scripts.yml
  4. 31
      .github/workflows/ios-build-scripts.yml
  5. 97
      .github/workflows/linux-build-scripts.yml
  6. 31
      .github/workflows/macos-build-scripts.yml
  7. 16
      .github/workflows/periodic-builds-android.yml
  8. 24
      .github/workflows/periodic-builds-apple.yml
  9. 31
      .github/workflows/tvos-build-scripts.yml
  10. 59
      CODE_OF_CONDUCT.md
  11. 63
      CONTRIBUTING.md
  12. 0
      LICENSE
  13. 113
      README.md
  14. 18
      android.sh
  15. 8
      android/README.md
  16. 2
      android/build.gradle
  17. 2
      android/ffmpeg-kit-android-lib/Doxyfile
  18. 26
      android/ffmpeg-kit-android-lib/build.gradle
  19. 7
      android/ffmpeg-kit-android-lib/consumer-rules.pro
  20. 4
      android/ffmpeg-kit-android-lib/src/main/AndroidManifest.xml
  21. 8
      android/ffmpeg-kit-android-lib/src/main/cpp/ffmpegkit.c
  22. 2
      android/ffmpeg-kit-android-lib/src/main/cpp/ffmpegkit.h
  23. 3
      android/ffmpeg-kit-android-lib/src/main/cpp/ffprobekit.c
  24. 1557
      android/ffmpeg-kit-android-lib/src/main/cpp/fftools_cmdutils.c
  25. 228
      android/ffmpeg-kit-android-lib/src/main/cpp/fftools_cmdutils.h
  26. 1308
      android/ffmpeg-kit-android-lib/src/main/cpp/fftools_ffmpeg.c
  27. 211
      android/ffmpeg-kit-android-lib/src/main/cpp/fftools_ffmpeg.h
  28. 304
      android/ffmpeg-kit-android-lib/src/main/cpp/fftools_ffmpeg_filter.c
  29. 51
      android/ffmpeg-kit-android-lib/src/main/cpp/fftools_ffmpeg_hw.c
  30. 331
      android/ffmpeg-kit-android-lib/src/main/cpp/fftools_ffmpeg_mux.c
  31. 667
      android/ffmpeg-kit-android-lib/src/main/cpp/fftools_ffmpeg_opt.c
  32. 583
      android/ffmpeg-kit-android-lib/src/main/cpp/fftools_ffprobe.c
  33. 79
      android/ffmpeg-kit-android-lib/src/main/cpp/fftools_fopen_utf8.h
  34. 1492
      android/ffmpeg-kit-android-lib/src/main/cpp/fftools_opt_common.c
  35. 202
      android/ffmpeg-kit-android-lib/src/main/cpp/fftools_opt_common.h
  36. 2
      android/ffmpeg-kit-android-lib/src/main/java/com/arthenica/ffmpegkit/AbstractSession.java
  37. 34
      android/ffmpeg-kit-android-lib/src/main/java/com/arthenica/ffmpegkit/Chapter.java
  38. 14
      android/ffmpeg-kit-android-lib/src/main/java/com/arthenica/ffmpegkit/FFmpegKit.java
  39. 39
      android/ffmpeg-kit-android-lib/src/main/java/com/arthenica/ffmpegkit/FFmpegKitConfig.java
  40. 35
      android/ffmpeg-kit-android-lib/src/main/java/com/arthenica/ffmpegkit/FFmpegSession.java
  41. 30
      android/ffmpeg-kit-android-lib/src/main/java/com/arthenica/ffmpegkit/FFprobeKit.java
  42. 35
      android/ffmpeg-kit-android-lib/src/main/java/com/arthenica/ffmpegkit/FFprobeSession.java
  43. 123
      android/ffmpeg-kit-android-lib/src/main/java/com/arthenica/ffmpegkit/MediaInformation.java
  44. 24
      android/ffmpeg-kit-android-lib/src/main/java/com/arthenica/ffmpegkit/MediaInformationSession.java
  45. 4
      android/ffmpeg-kit-android-lib/src/main/java/com/arthenica/ffmpegkit/NativeLoader.java
  46. 34
      android/ffmpeg-kit-android-lib/src/main/java/com/arthenica/ffmpegkit/StreamInformation.java
  47. 20
      android/ffmpeg-kit-android-lib/src/test/java/com/arthenica/ffmpegkit/FFmpegKitConfigTest.java
  48. 28
      android/ffmpeg-kit-android-lib/src/test/java/com/arthenica/ffmpegkit/FFmpegSessionTest.java
  49. 26
      android/ffmpeg-kit-android-lib/src/test/java/com/arthenica/ffmpegkit/FFprobeSessionTest.java
  50. 2
      android/gradle/wrapper/gradle-wrapper.properties
  51. 8
      android/jni/Android.mk
  52. 1
      apple.sh
  53. 5
      apple/.gitignore
  54. 2
      apple/Doxyfile
  55. 807
      apple/Makefile.in
  56. 10
      apple/README.md
  57. 16948
      apple/configure
  58. 13
      apple/configure.ac
  59. 11642
      apple/libtool
  60. 11147
      apple/ltmain.sh
  61. 8364
      apple/m4/libtool.m4
  62. 437
      apple/m4/ltoptions.m4
  63. 124
      apple/m4/ltsugar.m4
  64. 23
      apple/m4/ltversion.m4
  65. 99
      apple/m4/lt~obsolete.m4
  66. 4
      apple/src/AbstractSession.m
  67. 8
      apple/src/Chapter.h
  68. 10
      apple/src/Chapter.m
  69. 24
      apple/src/FFmpegKit.m
  70. 44
      apple/src/FFmpegKitConfig.m
  71. 14
      apple/src/FFmpegSession.h
  72. 44
      apple/src/FFmpegSession.m
  73. 40
      apple/src/FFprobeKit.m
  74. 14
      apple/src/FFprobeSession.h
  75. 37
      apple/src/FFprobeSession.m
  76. 12
      apple/src/Makefile.am
  77. 89
      apple/src/Makefile.in
  78. 45
      apple/src/MediaInformation.h
  79. 69
      apple/src/MediaInformation.m
  80. 8
      apple/src/MediaInformationJsonParser.h
  81. 23
      apple/src/MediaInformationJsonParser.m
  82. 11
      apple/src/MediaInformationSession.h
  83. 26
      apple/src/MediaInformationSession.m
  84. 3
      apple/src/Packages.m
  85. 8
      apple/src/StreamInformation.h
  86. 12
      apple/src/StreamInformation.m
  87. 1556
      apple/src/fftools_cmdutils.c
  88. 228
      apple/src/fftools_cmdutils.h
  89. 1307
      apple/src/fftools_ffmpeg.c
  90. 211
      apple/src/fftools_ffmpeg.h
  91. 310
      apple/src/fftools_ffmpeg_filter.c
  92. 51
      apple/src/fftools_ffmpeg_hw.c
  93. 332
      apple/src/fftools_ffmpeg_mux.c
  94. 666
      apple/src/fftools_ffmpeg_opt.c
  95. 177
      apple/src/fftools_ffmpeg_videotoolbox.c
  96. 583
      apple/src/fftools_ffprobe.c
  97. 79
      apple/src/fftools_fopen_utf8.h
  98. 1492
      apple/src/fftools_opt_common.c
  99. 202
      apple/src/fftools_opt_common.h
  100. 4
      docs/_config.yml
  101. Some files were not shown because too many files have changed in this diff Show More

@ -27,14 +27,14 @@ Post logs here or paste them to [Ghostbin](https://ghostbin.co) and insert the l
**Environment**
- Platform: `Android`/`Flutter`/`iOS`/`macOS`/`ReactNative`/`tvOS`
- Platform: `Android`/`Flutter`/`iOS`/`Linux`/`macOS`/`ReactNative`/`tvOS`
- Architecture: `arm-v7a`, `arm-v7a-neon`, `arm64-v8a`, `x86`, `x86_64`, `armv7`, `armv7s`, `arm64`, `arm64-mac-catalyst`, `arm64-simulator`, `arm64e`, `i386`, `x86-64`, `x86-64-mac-catalyst`
- Version: `v4.5`/`v4.5.LTS`
- Version: `v5.1`/`v5.1.LTS`
- Source branch: `main`, `development`
- Xcode version: `12.4.1`
- Cocoapods version: `1.10.1`
- Xcode version: `13.4.1`
- Cocoapods version: `1.10.3`
- Android Studio version: `4.0`
- Android NDK version: `r22b`
- Android NDK version: `r25b`
- flutter doctor: ` `
- react-native info: ` `

@ -8,7 +8,7 @@ Please also include the context and motivation about the changes introduced.
- Documentation
## Checks
- [ ] Changes support all platforms (`Android`, `iOS`, `macOS`, `tvOS`)
- [ ] Changes support all platforms (`Android`, `iOS`, `Linux`, macOS`, `tvOS`)
- [ ] Breaks existing functionality
- [ ] Implementation is completed, not half-done
- [ ] Is there another PR already created for this feature/bug fix

@ -8,6 +8,7 @@ on:
paths:
- '.github/workflows/android-build-scripts.yml'
- 'android/**'
- '!android/README.md'
- 'scripts/**'
- 'tools/**'
- 'android.sh'
@ -18,6 +19,7 @@ on:
paths:
- '.github/workflows/android-build-scripts.yml'
- 'android/**'
- '!android/README.md'
- 'scripts/**'
- 'tools/**'
- 'android.sh'
@ -28,24 +30,24 @@ jobs:
runs-on: ubuntu-20.04
strategy:
matrix:
ndk-version: [ 'r22b-linux-x86_64', 'r23b-linux' ]
ndk-version: [ 'r22b-linux-x86_64', 'r23b-linux', 'r24-linux', 'r25b-linux' ]
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@v2
- name: set up adopt jdk 8
uses: actions/setup-java@v2.2.0
- name: set up adopt jdk 11
uses: actions/setup-java@v3
with:
distribution: 'adopt'
java-version: '8'
java-version: '11'
- name: set up android ndk
run: |
curl -s "https://dl.google.com/android/repository/android-ndk-${{ matrix.ndk-version }}.zip" -o ndk.zip
unzip -q -o ndk.zip -d .ndk
echo "ANDROID_NDK_ROOT=$PWD/.ndk/$(ls .ndk)" >> $GITHUB_ENV
- name: run the build script
run: ./android.sh -d --enable-android-media-codec --enable-android-zlib
run: ./android.sh -d --enable-android-media-codec --enable-android-zlib --disable-arm-v7a
- name: print build logs
if: ${{ always() }}
run: cat build.log
@ -63,11 +65,11 @@ jobs:
shell: bash
steps:
- uses: actions/checkout@v2
- name: set up adopt jdk 8
uses: actions/setup-java@v2.2.0
- name: set up adopt jdk 11
uses: actions/setup-java@v3
with:
distribution: 'adopt'
java-version: '8'
java-version: '11'
- name: set up android ndk
run: |
curl -s "https://dl.google.com/android/repository/android-ndk-${{ matrix.ndk-version }}.zip" -o ndk.zip
@ -86,24 +88,24 @@ jobs:
runs-on: macos-10.15
strategy:
matrix:
ndk-version: [ 'r22b-darwin-x86_64', 'r23b-darwin' ]
ndk-version: [ 'r22b-darwin-x86_64', 'r23b-darwin', 'r24-darwin', 'r25b-darwin' ]
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@v2
- name: set up adopt jdk 8
uses: actions/setup-java@v2.2.0
- name: set up adopt jdk 11
uses: actions/setup-java@v3
with:
distribution: 'adopt'
java-version: '8'
java-version: '11'
- name: set up android ndk
run: |
curl -s "https://dl.google.com/android/repository/android-ndk-${{ matrix.ndk-version }}.zip" -o ndk.zip
unzip -q -o ndk.zip -d .ndk
echo "ANDROID_NDK_ROOT=$PWD/.ndk/$(ls .ndk)" >> $GITHUB_ENV
- name: run the build script
run: ./android.sh -d --enable-android-media-codec --enable-android-zlib
run: ./android.sh -d --enable-android-media-codec --enable-android-zlib --disable-arm-v7a
- name: print build logs
if: ${{ always() }}
run: cat build.log
@ -121,11 +123,11 @@ jobs:
shell: bash
steps:
- uses: actions/checkout@v2
- name: set up adopt jdk 8
uses: actions/setup-java@v2.2.0
- name: set up adopt jdk 11
uses: actions/setup-java@v3
with:
distribution: 'adopt'
java-version: '8'
java-version: '11'
- name: set up android ndk
run: |
curl -s "https://dl.google.com/android/repository/android-ndk-${{ matrix.ndk-version }}.zip" -o ndk.zip
@ -150,11 +152,11 @@ jobs:
shell: bash
steps:
- uses: actions/checkout@v2
- name: set up adopt jdk 8
uses: actions/setup-java@v2.2.0
- name: set up adopt jdk 11
uses: actions/setup-java@v3
with:
distribution: 'adopt'
java-version: '8'
java-version: '11'
- name: set up android ndk
run: |
curl -s "https://dl.google.com/android/repository/android-ndk-${{ matrix.ndk-version }}.zip" -o ndk.zip

@ -8,6 +8,7 @@ on:
paths:
- '.github/workflows/ios-build-scripts.yml'
- 'apple/**'
- '!apple/README.md'
- 'scripts/**'
- 'tools/**'
- 'apple.sh'
@ -19,12 +20,36 @@ on:
paths:
- '.github/workflows/ios-build-scripts.yml'
- 'apple/**'
- '!apple/README.md'
- 'scripts/**'
- 'tools/**'
- 'apple.sh'
- 'ios.sh'
jobs:
build-main-on-macos-monterey:
name: ios main on monterey
runs-on: macos-12
strategy:
matrix:
xcode: [ '13.4.1', '14.0.1' ]
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@v2
- name: prerequisites
run: brew install autoconf automake libtool pkg-config curl git cmake nasm
- name: set up xcode
run: echo "export DEVELOPER_DIR=/Applications/Xcode_${{ matrix.xcode }}.app/Contents/Developer" > ~/.xcode.for.ffmpeg.kit.sh
- name: run the build script
run: ./ios.sh --xcframework --enable-ios-audiotoolbox --enable-ios-avfoundation --enable-ios-bzip2 --enable-ios-libiconv --enable-ios-videotoolbox --enable-ios-zlib
- name: print build logs
if: ${{ always() }}
run: cat build.log
- name: print ffbuild logs
if: ${{ failure() }}
run: '[[ -f ./src/ffmpeg/ffbuild/config.log ]] && tail -50 ./src/ffmpeg/ffbuild/config.log'
build-main-on-macos-bigsur:
name: ios main on big sur
runs-on: macos-11
@ -36,6 +61,8 @@ jobs:
shell: bash
steps:
- uses: actions/checkout@v2
- name: prerequisites
run: brew install autoconf automake libtool pkg-config curl git cmake nasm
- name: set up xcode
run: echo "export DEVELOPER_DIR=/Applications/Xcode_${{ matrix.xcode }}.app/Contents/Developer" > ~/.xcode.for.ffmpeg.kit.sh
- name: run the build script
@ -57,6 +84,8 @@ jobs:
shell: bash
steps:
- uses: actions/checkout@v2
- name: prerequisites
run: brew install autoconf automake libtool pkg-config curl git cmake nasm
- name: set up xcode
run: echo "export DEVELOPER_DIR=/Applications/Xcode_${{ matrix.xcode }}.app/Contents/Developer" > ~/.xcode.for.ffmpeg.kit.sh
- name: run the build script
@ -78,6 +107,8 @@ jobs:
shell: bash
steps:
- uses: actions/checkout@v2
- name: prerequisites
run: brew install autoconf automake libtool pkg-config curl git cmake nasm
- name: set up xcode
run: echo "export DEVELOPER_DIR=/Applications/Xcode_${{ matrix.xcode }}.app/Contents/Developer" > ~/.xcode.for.ffmpeg.kit.sh
- name: run the build script

@ -0,0 +1,97 @@
name: linux build scripts
on:
push:
branches:
- development
- main
paths:
- '.github/workflows/linux-build-scripts.yml'
- 'linux/**'
- 'scripts/**'
- 'tools/**'
- 'linux.sh'
pull_request:
branches:
- development
- main
paths:
- '.github/workflows/linux-build-scripts.yml'
- 'linux/**'
- 'scripts/**'
- 'tools/**'
- 'linux.sh'
jobs:
build-main-on-ubuntu-2204:
name: linux main on ubuntu-22.04
runs-on: ubuntu-22.04
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@v2
- name: prerequisites
run: sudo apt-get install clang llvm lld libclang-11-dev libstdc++6 nasm autoconf automake libtool pkg-config curl git doxygen rapidjson-dev
- name: run the build script
run: ./linux.sh -d
- name: print build logs
if: ${{ always() }}
run: cat build.log
- name: print ffbuild logs
if: ${{ failure() }}
run: '[[ -f ./src/ffmpeg/ffbuild/config.log ]] && tail -50 ./src/ffmpeg/ffbuild/config.log'
build-lts-on-ubuntu-2204:
name: linux lts on ubuntu 22.04
runs-on: ubuntu-22.04
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@v2
- name: prerequisites
run: sudo apt-get install clang llvm lld libclang-11-dev libstdc++6 nasm autoconf automake libtool pkg-config curl git doxygen rapidjson-dev
- name: run the build script
run: ./linux.sh -d --lts
- name: print build logs
if: ${{ always() }}
run: cat build.log
- name: print ffbuild logs
if: ${{ failure() }}
run: '[[ -f ./src/ffmpeg/ffbuild/config.log ]] && tail -50 ./src/ffmpeg/ffbuild/config.log'
build-main-on-ubuntu-2004:
name: linux main on ubuntu-20.04
runs-on: ubuntu-20.04
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@v2
- name: prerequisites
run: sudo apt-get install clang llvm lld libclang-11-dev libstdc++6 nasm autoconf automake libtool pkg-config curl git doxygen rapidjson-dev
- name: run the build script
run: ./linux.sh -d
- name: print build logs
if: ${{ always() }}
run: cat build.log
- name: print ffbuild logs
if: ${{ failure() }}
run: '[[ -f ./src/ffmpeg/ffbuild/config.log ]] && tail -50 ./src/ffmpeg/ffbuild/config.log'
build-lts-on-ubuntu-2004:
name: linux lts on ubuntu 20.04
runs-on: ubuntu-20.04
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@v2
- name: prerequisites
run: sudo apt-get install clang llvm lld libclang-11-dev libstdc++6 nasm autoconf automake libtool pkg-config curl git doxygen rapidjson-dev
- name: run the build script
run: ./linux.sh -d --lts
- name: print build logs
if: ${{ always() }}
run: cat build.log
- name: print ffbuild logs
if: ${{ failure() }}
run: '[[ -f ./src/ffmpeg/ffbuild/config.log ]] && tail -50 ./src/ffmpeg/ffbuild/config.log'

@ -8,6 +8,7 @@ on:
paths:
- '.github/workflows/macos-build-scripts.yml'
- 'apple/**'
- '!apple/README.md'
- 'scripts/**'
- 'tools/**'
- 'apple.sh'
@ -19,12 +20,36 @@ on:
paths:
- '.github/workflows/macos-build-scripts.yml'
- 'apple/**'
- '!apple/README.md'
- 'scripts/**'
- 'tools/**'
- 'apple.sh'
- 'macos.sh'
jobs:
build-main-on-macos-monterey:
name: macos main on monterey
runs-on: macos-12
strategy:
matrix:
xcode: [ '13.4.1', '14.0.1' ]
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@v2
- name: prerequisites
run: brew install autoconf automake libtool pkg-config curl git cmake nasm
- name: set up xcode
run: echo "export DEVELOPER_DIR=/Applications/Xcode_${{ matrix.xcode }}.app/Contents/Developer" > ~/.xcode.for.ffmpeg.kit.sh
- name: run the build script
run: ./macos.sh --xcframework --enable-macos-audiotoolbox --enable-macos-avfoundation --enable-macos-bzip2 --enable-macos-coreimage --enable-macos-libiconv --enable-macos-opencl --enable-macos-opengl --enable-macos-videotoolbox --enable-macos-zlib
- name: print build logs
if: ${{ always() }}
run: cat build.log
- name: print ffbuild logs
if: ${{ failure() }}
run: '[[ -f ./src/ffmpeg/ffbuild/config.log ]] && tail -50 ./src/ffmpeg/ffbuild/config.log'
build-main-on-macos-bigsur:
name: macos main on big sur
runs-on: macos-11
@ -36,6 +61,8 @@ jobs:
shell: bash
steps:
- uses: actions/checkout@v2
- name: prerequisites
run: brew install autoconf automake libtool pkg-config curl git cmake nasm
- name: set up xcode
run: echo "export DEVELOPER_DIR=/Applications/Xcode_${{ matrix.xcode }}.app/Contents/Developer" > ~/.xcode.for.ffmpeg.kit.sh
- name: run the build script
@ -57,6 +84,8 @@ jobs:
shell: bash
steps:
- uses: actions/checkout@v2
- name: prerequisites
run: brew install autoconf automake libtool pkg-config curl git cmake nasm
- name: set up xcode
run: echo "export DEVELOPER_DIR=/Applications/Xcode_${{ matrix.xcode }}.app/Contents/Developer" > ~/.xcode.for.ffmpeg.kit.sh
- name: run the build script
@ -78,6 +107,8 @@ jobs:
shell: bash
steps:
- uses: actions/checkout@v2
- name: prerequisites
run: brew install autoconf automake libtool pkg-config curl git cmake nasm
- name: set up xcode
run: echo "export DEVELOPER_DIR=/Applications/Xcode_${{ matrix.xcode }}.app/Contents/Developer" > ~/.xcode.for.ffmpeg.kit.sh
- name: run the build script

@ -10,7 +10,7 @@ jobs:
runs-on: ubuntu-20.04
strategy:
matrix:
ndk-version: [ 'r22b-linux-x86_64', 'r23b-linux' ]
ndk-version: [ 'r22b-linux-x86_64', 'r23b-linux', 'r24-linux', 'r25b-linux' ]
branches: [ 'main', 'development' ]
defaults:
run:
@ -19,11 +19,11 @@ jobs:
- uses: actions/checkout@v2
with:
ref: ${{ matrix.branches }}
- name: set up adopt jdk 8
uses: actions/setup-java@v2.2.0
- name: set up adopt jdk 11
uses: actions/setup-java@v3
with:
distribution: 'adopt'
java-version: '8'
java-version: '11'
- name: prerequisites
run: sudo apt-get install autoconf automake libtool pkg-config curl git cmake gcc gperf texinfo yasm nasm bison autogen wget autopoint meson ninja-build ragel
- name: upgrade meson
@ -34,7 +34,7 @@ jobs:
unzip -q -o ndk.zip -d .ndk
echo "ANDROID_NDK_ROOT=$PWD/.ndk/$(ls .ndk)" >> $GITHUB_ENV
- name: run the build script
run: ./android.sh --full --enable-gpl --disable-lib-srt
run: ./android.sh --full --enable-gpl --disable-lib-srt --disable-arm-v7a
- name: print build logs
if: ${{ always() }}
run: cat build.log
@ -55,11 +55,11 @@ jobs:
- uses: actions/checkout@v2
with:
ref: ${{ matrix.branches }}
- name: set up adopt jdk 8
uses: actions/setup-java@v2.2.0
- name: set up adopt jdk 11
uses: actions/setup-java@v3
with:
distribution: 'adopt'
java-version: '8'
java-version: '11'
- name: prerequisites
run: sudo apt-get install autoconf automake libtool pkg-config curl git cmake gcc gperf texinfo yasm nasm bison autogen wget autopoint meson ninja-build ragel
- name: upgrade meson

@ -5,12 +5,12 @@ on:
- cron: '0 1 * * 0'
jobs:
build-ios-main-on-macos-bigsur:
name: ios main on big sur
runs-on: macos-11
build-ios-main-on-macos-monterey:
name: ios main on monterey
runs-on: macos-12
strategy:
matrix:
xcode: [ '13.2.1' ]
xcode: [ '13.4.1' ]
branches: [ 'main', 'development' ]
defaults:
run:
@ -57,12 +57,12 @@ jobs:
- name: print ffbuild logs
if: ${{ failure() }}
run: '[[ -f ./src/ffmpeg/ffbuild/config.log ]] && tail -50 ./src/ffmpeg/ffbuild/config.log'
build-macos-main-on-macos-bigsur:
name: macos main on big sur
runs-on: macos-11
build-macos-main-on-macos-monterey:
name: macos main on monterey
runs-on: macos-12
strategy:
matrix:
xcode: [ '13.2.1' ]
xcode: [ '13.4.1' ]
branches: [ 'main', 'development' ]
defaults:
run:
@ -109,12 +109,12 @@ jobs:
- name: print ffbuild logs
if: ${{ failure() }}
run: '[[ -f ./src/ffmpeg/ffbuild/config.log ]] && tail -50 ./src/ffmpeg/ffbuild/config.log'
build-tvos-main-on-macos-bigsur:
name: tvos main on big sur
runs-on: macos-11
build-tvos-main-on-macos-monterey:
name: tvos main on monterey
runs-on: macos-12
strategy:
matrix:
xcode: [ '13.2.1' ]
xcode: [ '13.4.1' ]
branches: [ 'main', 'development' ]
defaults:
run:

@ -8,6 +8,7 @@ on:
paths:
- '.github/workflows/tvos-build-scripts.yml'
- 'apple/**'
- '!apple/README.md'
- 'scripts/**'
- 'tools/**'
- 'apple.sh'
@ -19,12 +20,36 @@ on:
paths:
- '.github/workflows/tvos-build-scripts.yml'
- 'apple/**'
- '!apple/README.md'
- 'scripts/**'
- 'tools/**'
- 'apple.sh'
- 'tvos.sh'
jobs:
build-main-on-macos-monterey:
name: tvos main on monterey
runs-on: macos-12
strategy:
matrix:
xcode: [ '13.4.1', '14.0.1' ]
defaults:
run:
shell: bash
steps:
- uses: actions/checkout@v2
- name: prerequisites
run: brew install autoconf automake libtool pkg-config curl git cmake nasm
- name: set up xcode
run: echo "export DEVELOPER_DIR=/Applications/Xcode_${{ matrix.xcode }}.app/Contents/Developer" > ~/.xcode.for.ffmpeg.kit.sh
- name: run the build script
run: ./tvos.sh --xcframework --enable-tvos-bzip2 --enable-tvos-audiotoolbox --enable-tvos-libiconv --enable-tvos-videotoolbox --enable-tvos-zlib
- name: print build logs
if: ${{ always() }}
run: cat build.log
- name: print ffbuild logs
if: ${{ failure() }}
run: '[[ -f ./src/ffmpeg/ffbuild/config.log ]] && tail -50 ./src/ffmpeg/ffbuild/config.log'
build-main-on-macos-bigsur:
name: tvos main on big sur
runs-on: macos-11
@ -36,6 +61,8 @@ jobs:
shell: bash
steps:
- uses: actions/checkout@v2
- name: prerequisites
run: brew install autoconf automake libtool pkg-config curl git cmake nasm
- name: set up xcode
run: echo "export DEVELOPER_DIR=/Applications/Xcode_${{ matrix.xcode }}.app/Contents/Developer" > ~/.xcode.for.ffmpeg.kit.sh
- name: run the build script
@ -57,6 +84,8 @@ jobs:
shell: bash
steps:
- uses: actions/checkout@v2
- name: prerequisites
run: brew install autoconf automake libtool pkg-config curl git cmake nasm
- name: set up xcode
run: echo "export DEVELOPER_DIR=/Applications/Xcode_${{ matrix.xcode }}.app/Contents/Developer" > ~/.xcode.for.ffmpeg.kit.sh
- name: run the build script
@ -78,6 +107,8 @@ jobs:
shell: bash
steps:
- uses: actions/checkout@v2
- name: prerequisites
run: brew install autoconf automake libtool pkg-config curl git cmake nasm
- name: set up xcode
run: echo "export DEVELOPER_DIR=/Applications/Xcode_${{ matrix.xcode }}.app/Contents/Developer" > ~/.xcode.for.ffmpeg.kit.sh
- name: run the build script

@ -0,0 +1,59 @@
# Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to make
participation in our project and our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance,
race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take
appropriate and fair corrective action in response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits,
issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any
contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the
project or its community. Examples of representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed representative at an online or
offline event. Representation of a project may be further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at
`open-source@arthenica.com`. All complaints will be reviewed and investigated and will result in a response that is
deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with
regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at
[https://contributor-covenant.org/version/1/4][version].
[homepage]: https://contributor-covenant.org
[version]: https://contributor-covenant.org/version/1/4/

@ -0,0 +1,63 @@
# How to contribute
Thanks for taking the time to contribute! :heart:
The following is a set of guidelines for contributing to `FFmpegKit`!
## Project Resources
* [Wiki](https://github.com/arthenica/ffmpeg-kit/wiki) includes most detailed documentation we have
* [FFmpegKit Feature Roadmap](https://github.com/orgs/arthenica/projects/1) shows our long term plans for the project
* [How To Get Help](https://github.com/arthenica/ffmpeg-kit/issues/215) details what you need to do if you need help
* [Discussions](https://github.com/arthenica/ffmpeg-kit/discussions) is where we expect you to ask questions
* [Issues](https://github.com/arthenica/ffmpeg-kit/issues) is for bugs and issues
## Reporting Bugs
Bugs are tracked as [GitHub issues](https://github.com/arthenica/ffmpeg-kit/issues). We have a `Bug report` issue
template which includes all the fields we need to see to confirm a bug and work on it. Try to fill out all template
fields, especially the logs field and steps to reproduce the bug. Reproducing a bug is crucial to be able to fix it.
### FFmpeg Bugs
`FFmpegKit` does not modify the original `FFmpeg` source code. Therefore, if an `FFmpeg` feature or component is not
working as expected, most probably that problem comes from `FFmpeg`. If you encounter those kind of errors, we expect
you to install the desktop version of `FFmpeg` and test that feature or component there. If it fails on desktop too
then it must be reported to [FFmpeg bug tracker](https://trac.ffmpeg.org/). If not, then it is an `FFmpegKit` bug.
Create an issue and state that this bug doesn't exist on the `desktop` version of the same `FFmpeg` version.
## Feature Requests
Before creating a feature request, please check our long term plan for the project, which is visible under the
[FFmpegKit Feature Roadmap](https://github.com/orgs/arthenica/projects/1). Then create an issue and fill out the
`Feature request` issue template and provide as many details as possible.
### External Library Requests
`FFmpeg` supports a long list of `external` libraries. In `FFmpegKit` we did our best to support most of them.
However, there are still many libraries that cannot be used within `FFmpegKit`.
Unfortunately, cross compilation is a challenging process. Because of that, we don't take new external library
requests. Though, we are open to PRs. If someone wants to contribute we'll be happy to review their changes that
enables another external library in `FFmpeg`.
## Pull Requests
Although it is not mandatory, our suggestion is to first discuss the change you wish to make via an issue or a
discussion. `FFmpegKit` is a complex project. There are many things that must be considered when implementing a
feature.
`FFmpegKit` has a unified API, which means we provide the same functionality on all platforms. Therefore, we expect
the same from the pull requests as well. A feature must be implemented for all platforms unless it is a platform specific
feature.
Ensure that your changes rely on official documented methods and test your changes using the test applications we have
under the [ffmpeg-kit-test](https://github.com/arthenica/ffmpeg-kit-test) repository.
`main` branch of `FFmpegKit` includes only the latest released source code. Therefore, please open your pull requests
against the development branches (`development` for native platforms, `development-react-native` for
`react-native`, `development-flutter` for `flutter`).
Note that PRs about styling and cosmetic changes will not be accepted.
Thanks!

@ -1,20 +1,20 @@
# FFmpegKit ![GitHub release](https://img.shields.io/badge/release-v4.5.1-blue.svg) ![Maven Central](https://img.shields.io/maven-central/v/com.arthenica/ffmpeg-kit-min) ![CocoaPods](https://img.shields.io/cocoapods/v/ffmpeg-kit-ios-min) ![pub](https://img.shields.io/pub/v/ffmpeg_kit_flutter.svg) ![npm](https://img.shields.io/npm/v/ffmpeg-kit-react-native.svg)
# FFmpegKit ![GitHub release](https://img.shields.io/badge/release-v5.1-blue.svg) ![Maven Central](https://img.shields.io/maven-central/v/com.arthenica/ffmpeg-kit-min) ![CocoaPods](https://img.shields.io/cocoapods/v/ffmpeg-kit-ios-min) ![pub](https://img.shields.io/pub/v/ffmpeg_kit_flutter.svg) ![npm](https://img.shields.io/npm/v/ffmpeg-kit-react-native.svg)
<img src="https://github.com/tanersener/ffmpeg-kit/blob/main/docs/assets/ffmpeg-kit-icon-v9.png" width="240">
<img src="https://github.com/arthenica/ffmpeg-kit/blob/main/docs/assets/ffmpeg-kit-icon-v9.png" width="240">
`FFmpegKit` is a collection of tools to use `FFmpeg` in `Android`, `iOS`, `macOS`, `tvOS`, `Flutter` and `React Native` applications.
`FFmpegKit` is a collection of tools to use `FFmpeg` in `Android`, `iOS`, `Linux`, `macOS`, `tvOS`, `Flutter` and `React Native` applications.
It includes scripts to build `FFmpeg` native libraries, a wrapper library to run `FFmpeg`/`FFprobe` commands in
applications and 8 prebuilt binary packages available at [Github](https://github.com/tanersener/ffmpeg-kit/releases),
applications and 8 prebuilt binary packages available at [Github](https://github.com/arthenica/ffmpeg-kit/releases),
[Maven Central](https://search.maven.org), [CocoaPods](https://cocoapods.org), [pub](https://pub.dev) and [npm](https://www.npmjs.com).
### 1. Features
- Scripts to build FFmpeg native libraries
- `FFmpegKit` wrapper library to run `FFmpeg`/`FFprobe` commands in applications
- Supports native platforms: Android, iOS, macOS and tvOS
- Supports native platforms: Android, iOS, Linux, macOS and tvOS
- Supports hybrid platforms: Flutter, React Native
- Based on FFmpeg `v4.5-dev` with optional system and external libraries
- 8 prebuilt binary packages available at [Github](https://github.com/tanersener/ffmpeg-kit/releases), [Maven Central](https://search.maven.org), [CocoaPods](https://cocoapods.org), [pub](https://pub.dev) and [npm](https://www.npmjs.com)
- Based on FFmpeg `v4.5-dev` or later with optional system and external libraries
- 8 prebuilt binary packages available at [Github](https://github.com/arthenica/ffmpeg-kit/releases), [Maven Central](https://search.maven.org), [CocoaPods](https://cocoapods.org), [pub](https://pub.dev) and [npm](https://www.npmjs.com)
- Licensed under `LGPL 3.0`, or `GPL v3.0` if GPL licensed libraries are enabled
### 2. Android
@ -29,31 +29,35 @@ See [Apple](apple) to use `FFmpegKit` on `Apple` platforms (`iOS`, `macOS`, `tvO
See [Flutter](flutter/flutter) to learn more about `FFmpegKit` for `Flutter`.
### 5. React Native
### 5. Linux
See [Linux](linux) to learn more about `FFmpegKit` for `Linux`.
### 6. React Native
See [React Native](react-native) to learn more about `FFmpegKit` for `React Native`.
### 6. Build Scripts
### 7. Build Scripts
Use `android.sh`, `ios.sh`, `macos.sh` and `tvos.sh` to build `FFmpegKit` for each native platform.
Use `android.sh`, `ios.sh`, `linux.sh`, `macos.sh` and `tvos.sh` to build `FFmpegKit` for each native platform.
All scripts support additional options to enable optional libraries and disable platform architectures. See
[Building](https://github.com/tanersener/ffmpeg-kit/wiki/Building) wiki page for the details.
[Building](https://github.com/arthenica/ffmpeg-kit/wiki/Building) wiki page for the details.
### 7. FFmpegKit Library
### 8. FFmpegKit Library
`FFmpegKit` is a wrapper library that allows you to easily run `FFmpeg`/`FFprobe` commands in applications. It
provides additional features on top of `FFmpeg` to enable platform specific resources, control how commands are
executed and how the results are handled.
`Android` library of `FFmpegKit` has a `Java` API, `Apple` libraries (`iOS`, `macOS`, `tvOS`) have an `Objective-C`
API, `Flutter`library comes with a `Dart` API and `React Native` library provides a `JavaScript` API, which are
identical in terms of features and capabilities.
API, `Flutter` library comes with a `Dart` API, `Linux` library has a `C++` API and `React Native` library provides
a `JavaScript` API with `Typescript` definitions, which are identical in terms of features and capabilities.
### 8. Packages
### 9. Packages
There are eight different `ffmpeg-kit` packages distributed on
[Github](https://github.com/tanersener/ffmpeg-kit/releases),
[Github](https://github.com/arthenica/ffmpeg-kit/releases),
[Maven Central](https://search.maven.org), [CocoaPods](https://cocoapods.org), [pub](https://pub.dev) and
[npm](https://www.npmjs.com).
Below you can see which system libraries and external libraries are enabled in each one of them.
@ -111,26 +115,30 @@ include them.
- `VideoToolbox` is not available on LTS releases of `iOS` and `tvOS`
- `zimg` is supported since `v4.5.1`
### 9. Versions
### 10. Versions
`FFmpegKit` binaries generated use the same major and minor version numbers as the upstream `FFmpeg` project.
`FFmpegKit` binaries generated use the same major and minor version numbers as the upstream `FFmpeg` project. The
third and last number in the version string, if exists, is specific to `FFmpegKit`. It shows different releases from
the same `FFmpeg` release branch.
The exact version number of `FFmpeg` is obtained using `git describe --tags`. `dev` part in the version string
indicates that `FFmpeg` source code is cloned from the `FFmpeg` `master` branch.
`dev` part in the version string indicates that `FFmpeg` source code is cloned from the `FFmpeg` `master` branch and
the exact version number of `FFmpeg` is obtained using the `git describe --tags` command.
| Platforms | FFmpegKit Version | FFmpeg Version | Release Date |
|:----------------:|:----------------------------------------------------------------------------------:| :------------: |:------------:|
| React Native | [4.5.2](https://github.com/tanersener/ffmpeg-kit/releases/tag/react.native.v4.5.2) | 4.5-dev-3393 | May 25, 2022 |
| Flutter | [4.5.1](https://github.com/tanersener/ffmpeg-kit/releases/tag/flutter.v4.5.1) | 4.5-dev-3393 | Jan 02, 2022 |
| React Native | [4.5.1](https://github.com/tanersener/ffmpeg-kit/releases/tag/react.native.v4.5.1) | 4.5-dev-3393 | Jan 02, 2022 |
| Android | [4.5.1](https://github.com/tanersener/ffmpeg-kit/releases/tag/v4.5.1) | 4.5-dev-3393 | Jan 01, 2022 |
| Apple | [4.5.1](https://github.com/tanersener/ffmpeg-kit/releases/tag/v4.5.1) | 4.5-dev-3393 | Dec 30, 2021 |
| Flutter | [4.5.0](https://github.com/tanersener/ffmpeg-kit/releases/tag/flutter.v4.5.0) | 4.5-dev-2008 | Oct 05, 2021 |
| React Native | [4.5.0](https://github.com/tanersener/ffmpeg-kit/releases/tag/react.native.v4.5.0) | 4.5-dev-2008 | Oct 01, 2021 |
| Android<br>Apple | [4.5](https://github.com/tanersener/ffmpeg-kit/releases/tag/v4.5) | 4.5-dev-2008 | Sep 18, 2021 |
| Android<br>Apple | [4.4](https://github.com/tanersener/ffmpeg-kit/releases/tag/v4.4) | 4.4-dev-3015 | Mar 03, 2021 |
### 10. LTS Releases
|:----------------:|:----------------------------------------------------------------------------------:|:--------------:|:------------:|
| Android | [5.1](https://github.com/arthenica/ffmpeg-kit/releases/tag/v5.1) | 5.1.2 | Sep 29, 2022 |
| Apple | [5.1](https://github.com/arthenica/ffmpeg-kit/releases/tag/v5.1) | 5.1.2 | Sep 29, 2022 |
| React Native | [4.5.2](https://github.com/arthenica/ffmpeg-kit/releases/tag/react.native.v4.5.2) | 4.5-dev-3393 | May 25, 2022 |
| Flutter | [4.5.1](https://github.com/arthenica/ffmpeg-kit/releases/tag/flutter.v4.5.1) | 4.5-dev-3393 | Jan 02, 2022 |
| React Native | [4.5.1](https://github.com/arthenica/ffmpeg-kit/releases/tag/react.native.v4.5.1) | 4.5-dev-3393 | Jan 02, 2022 |
| Android | [4.5.1](https://github.com/arthenica/ffmpeg-kit/releases/tag/v4.5.1) | 4.5-dev-3393 | Jan 01, 2022 |
| Apple | [4.5.1](https://github.com/arthenica/ffmpeg-kit/releases/tag/v4.5.1) | 4.5-dev-3393 | Dec 30, 2021 |
| Flutter | [4.5.0](https://github.com/arthenica/ffmpeg-kit/releases/tag/flutter.v4.5.0) | 4.5-dev-2008 | Oct 05, 2021 |
| React Native | [4.5.0](https://github.com/arthenica/ffmpeg-kit/releases/tag/react.native.v4.5.0) | 4.5-dev-2008 | Oct 01, 2021 |
| Android<br>Apple | [4.5](https://github.com/arthenica/ffmpeg-kit/releases/tag/v4.5) | 4.5-dev-2008 | Sep 18, 2021 |
| Android<br>Apple | [4.4](https://github.com/arthenica/ffmpeg-kit/releases/tag/v4.4) | 4.4-dev-3015 | Mar 03, 2021 |
### 11. LTS Releases
`FFmpegKit` binaries are published in two release variants: `Main Release` and `LTS Release`.
@ -160,26 +168,38 @@ This table shows the differences between two variants.
| tvOS Architectures | arm64<br/>x86-64<br/>arm64-simulator | arm64<br/>x86-64 |
| tvOS Bundle Format | XCFrameworks | Frameworks |
### 11. Documentation
### 12. Documentation
A more detailed documentation is available under [Wiki](https://github.com/tanersener/ffmpeg-kit/wiki).
A more detailed documentation is available under [Wiki](https://github.com/arthenica/ffmpeg-kit/wiki).
### 12. Test Applications
### 13. Test Applications
You can see how `FFmpegKit` is used inside an application by running test applications created under
[FFmpegKit Test](https://github.com/tanersener/ffmpeg-kit-test) project.
[FFmpegKit Test](https://github.com/arthenica/ffmpeg-kit-test) project.
All applications are identical and supports command execution, video encoding, accessing https urls, encoding audio,
burning subtitles, video stabilisation, pipe operations and concurrent command execution.
### 13. License
### 14. License
`FFmpegKit` library alone is licensed under the `LGPL v3.0`.
`FFmpegKit` is licensed under the `LGPL v3.0`. However, if source code is built using the optional `--enable-gpl` flag
or prebuilt binaries with `-gpl` postfix are used, then `FFmpegKit` is subject to the `GPL v3.0` license.
`FFmpegKit` bundles (`.aar` archives, `frameworks`, `xcframeworks`), which include both `FFmpegKit` and `FFmpeg`
libraries, are also licensed under the `LGPL v3.0`. However, if the source code is built using the optional
`--enable-gpl` flag or prebuilt binaries with `-gpl` postfix are used, then `FFmpegKit` bundles become subject to the
`GPL v3.0`. Because, `FFmpeg` is licensed under the `GPL v3.0` in those bundles. And that makes the whole bundle
effectively subject to the `GPL v3.0`.
See the [License](https://github.com/tanersener/ffmpeg-kit/wiki/License) wiki page for the details.
`FFmpegKit` build scripts always configure `FFmpeg` with `--enable-version3` option. And never enable non-free
libraries. Thus, `FFmpeg` libraries created by `FFmpegKit` are licensed under the `LGPL v3.0` by default. Only when
`--enable-gpl` is provided they become subject to `GPL v3.0`. That is how prebuilt binaries with `-gpl` postfix are
compiled.
### 14. Patents
Refer to [Licenses](https://github.com/arthenica/ffmpeg-kit/wiki/Licenses) to see the licenses of all libraries.
[Trademark](https://github.com/arthenica/ffmpeg-kit/wiki/Trademark) lists the trademarks used in the `FFmpegKit`
documentation.
### 15. Patents
It is not clearly explained in their documentation, but it is believed that `FFmpeg`, `kvazaar`, `x264` and `x265`
include algorithms which are subject to software patents. If you live in a country where software algorithms are
@ -190,16 +210,11 @@ that you seek legal advice first. See [FFmpeg Patent Mini-FAQ](https://ffmpeg.or
distribute that library, then you are subject to pay MPEG LA licensing fees. Refer to
[OpenH264 FAQ](https://www.openh264.org/faq.html) page for the details.
### 15. Contributing
Feel free to submit issues or pull requests.
### 16. Contributing
Please note that `main` includes only the latest released source code. Changes planned for the next release are
developed under the `development` branches (`development` for native platforms, `development-react-native` for
`react-native`, `development-flutter` for `flutter`). Therefore, if you want to create a pull request, please open it
against them.
See our [CONTRIBUTING](CONTRIBUTING.md) guide.
### 16. See Also
### 17. See Also
- [FFmpeg API Documentation](https://ffmpeg.org/doxygen/4.0/index.html)
- [FFmpeg Wiki](https://trac.ffmpeg.org/wiki/WikiStart)

@ -28,7 +28,7 @@ echo -e "\nINFO: Using Android NDK v${DETECTED_NDK_VERSION} provided at ${ANDROI
echo -e "INFO: Build options: $*\n" 1>>"${BASEDIR}"/build.log 2>&1
# SET DEFAULT BUILD OPTIONS
GPL_ENABLED="no"
export GPL_ENABLED="no"
DISPLAY_HELP=""
BUILD_FULL=""
BUILD_TYPE_ID=""
@ -36,13 +36,13 @@ BUILD_VERSION=$(git describe --tags --always 2>>"${BASEDIR}"/build.log)
# PROCESS LTS BUILD OPTION FIRST AND SET BUILD TYPE: MAIN OR LTS
rm -f "${BASEDIR}"/android/ffmpeg-kit-android-lib/build.gradle 1>>"${BASEDIR}"/build.log 2>&1
cp "${BASEDIR}"/tools/release/android/build.gradle "${BASEDIR}"/android/ffmpeg-kit-android-lib/build.gradle 1>>"${BASEDIR}"/build.log 2>&1
cp "${BASEDIR}"/tools/android/build.gradle "${BASEDIR}"/android/ffmpeg-kit-android-lib/build.gradle 1>>"${BASEDIR}"/build.log 2>&1
for argument in "$@"; do
if [[ "$argument" == "-l" ]] || [[ "$argument" == "--lts" ]]; then
enable_lts_build
BUILD_TYPE_ID+="LTS "
rm -f "${BASEDIR}"/android/ffmpeg-kit-android-lib/build.gradle 1>>"${BASEDIR}"/build.log 2>&1
cp "${BASEDIR}"/tools/release/android/build.lts.gradle "${BASEDIR}"/android/ffmpeg-kit-android-lib/build.gradle 1>>"${BASEDIR}"/build.log 2>&1
cp "${BASEDIR}"/tools/android/build.lts.gradle "${BASEDIR}"/android/ffmpeg-kit-android-lib/build.gradle 1>>"${BASEDIR}"/build.log 2>&1
fi
done
@ -105,7 +105,7 @@ while [ ! $# -eq 0 ]; do
BUILD_FULL="1"
;;
--enable-gpl)
GPL_ENABLED="yes"
export GPL_ENABLED="yes"
;;
--enable-custom-library-*)
CUSTOM_LIBRARY_OPTION_KEY=$(echo $1 | sed -e 's/^--enable-custom-//g;s/=.*$//g')
@ -289,7 +289,7 @@ if [[ -n ${ANDROID_ARCHITECTURES} ]]; then
cd "${BASEDIR}"/android 1>>"${BASEDIR}"/build.log 2>&1 || exit 1
# COPY LIBRARY LICENSES
# COPY EXTERNAL LIBRARY LICENSES
LICENSE_BASEDIR="${BASEDIR}"/android/ffmpeg-kit-android-lib/src/main/res/raw
rm -f "${LICENSE_BASEDIR}"/*.txt 1>>"${BASEDIR}"/build.log 2>&1 || exit 1
for library in {0..49}; do
@ -331,13 +331,17 @@ if [[ -n ${ANDROID_ARCHITECTURES} ]]; then
# COPY LIBRARY LICENSES
if [[ ${GPL_ENABLED} == "yes" ]]; then
cp "${BASEDIR}"/LICENSE.GPLv3 "${LICENSE_BASEDIR}"/license.txt 1>>"${BASEDIR}"/build.log 2>&1
cp "${BASEDIR}"/tools/license/LICENSE.GPLv3 "${LICENSE_BASEDIR}"/license.txt 1>>"${BASEDIR}"/build.log 2>&1 || exit 1
else
cp "${BASEDIR}"/LICENSE.LGPLv3 "${LICENSE_BASEDIR}"/license.txt 1>>"${BASEDIR}"/build.log 2>&1
cp "${BASEDIR}"/LICENSE "${LICENSE_BASEDIR}"/license.txt 1>>"${BASEDIR}"/build.log 2>&1 || exit 1
fi
echo -e "DEBUG: Copied the ffmpeg-kit license successfully\n" 1>>"${BASEDIR}"/build.log 2>&1
overwrite_file "${BASEDIR}"/tools/source/SOURCE "${LICENSE_BASEDIR}"/source.txt 1>>"${BASEDIR}"/build.log 2>&1 || exit 1
echo -e "DEBUG: Copied source.txt successfully\n" 1>>"${BASEDIR}"/build.log 2>&1
# BUILD NATIVE LIBRARY
if [[ ${SKIP_ffmpeg_kit} -ne 1 ]]; then
if [ "$(is_darwin_arm64)" == "1" ]; then

@ -22,7 +22,7 @@ external libraries enabled.
##### 2.1.1 Android Tools
- Android SDK Build Tools
- Android NDK r22b or later with LLDB and CMake (See [#292](https://github.com/tanersener/ffmpeg-kit/issues/292) if you want to use NDK r23b)
- Android NDK r22b or later with LLDB and CMake (See [#292](https://github.com/arthenica/ffmpeg-kit/issues/292) if you want to use NDK r23b)
##### 2.1.2 Packages
@ -69,7 +69,7 @@ All libraries created by `android.sh` can be found under the `prebuilt` director
1. Declare `mavenCentral` repository and add `FFmpegKit` dependency to your `build.gradle` in
`ffmpeg-kit-<package name>` pattern. Use one of the `FFmpegKit` package names given in the
project [README](https://github.com/tanersener/ffmpeg-kit).
project [README](https://github.com/arthenica/ffmpeg-kit).
```yaml
repositories {
@ -77,7 +77,7 @@ All libraries created by `android.sh` can be found under the `prebuilt` director
}
dependencies {
implementation 'com.arthenica:ffmpeg-kit-full:4.5.1-1'
implementation 'com.arthenica:ffmpeg-kit-full:5.1'
}
```
@ -328,4 +328,4 @@ All libraries created by `android.sh` can be found under the `prebuilt` director
### 4. Test Application
You can see how `FFmpegKit` is used inside an application by running `Android` test applications developed under the
[FFmpegKit Test](https://github.com/tanersener/ffmpeg-kit-test) project.
[FFmpegKit Test](https://github.com/arthenica/ffmpeg-kit-test) project.

@ -4,7 +4,7 @@ buildscript {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.2.2'
classpath 'com.android.tools.build:gradle:7.3.0'
}
}

@ -38,7 +38,7 @@ PROJECT_NAME = "FFmpegKit Android API"
# could be handy for archiving the generated documentation or if some version
# control system is used.
PROJECT_NUMBER = 4.5.1
PROJECT_NUMBER = 5.1
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a

@ -1,25 +1,31 @@
apply plugin: 'com.android.library'
android {
compileSdkVersion 30
namespace 'com.arthenica.ffmpegkit'
compileSdk 31
ndkVersion "22.1.7171670"
defaultConfig {
minSdkVersion 24
targetSdkVersion 30
versionCode 240451
versionName "4.5.1"
minSdk 24
targetSdk 31
versionCode 240510
versionName "5.1"
project.archivesBaseName = "ffmpeg-kit"
consumerProguardFiles 'proguard-rules.pro'
consumerProguardFiles "consumer-rules.pro"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
}
sourceSets {
main {
jniLibs.srcDirs = ["../libs"]
@ -44,11 +50,11 @@ task javadoc(type: Javadoc) {
}
dependencies {
implementation 'com.arthenica:smart-exception-java:0.1.1'
api 'com.arthenica:smart-exception-java:0.2.1'
testImplementation "androidx.test.ext:junit:1.1.3"
testImplementation "org.json:json:20201115"
testImplementation 'org.json:json:20220320'
}
if (System.properties.containsKey('releaseFFmpegKit')) {
apply from: "${rootProject.projectDir}/../tools/release/android/release.template.gradle"
apply from: "${rootProject.projectDir}/../tools/android/release.template.gradle"
}

@ -1,10 +1,3 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
-keep class com.arthenica.ffmpegkit.FFmpegKitConfig {
native <methods>;
void log(long, int, byte[]);

@ -1 +1,3 @@
<manifest package="com.arthenica.ffmpegkit" />
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
</manifest>

@ -106,7 +106,7 @@ volatile int handleSIGXCPU = 1;
volatile int handleSIGPIPE = 1;
/** Holds the id of the current session */
__thread volatile long globalSessionId = 0;
__thread long globalSessionId = 0;
/** Holds the default log level */
int configuredLogLevel = AV_LOG_INFO;
@ -621,19 +621,19 @@ jint JNI_OnLoad(JavaVM *vm, void *reserved) {
}
statisticsMethod = (*env)->GetStaticMethodID(env, localConfigClass, "statistics", "(JIFFJIDD)V");
if (logMethod == NULL) {
if (statisticsMethod == NULL) {
LOGE("OnLoad thread failed to GetStaticMethodID for %s.\n", "statistics");
return JNI_FALSE;
}
safOpenMethod = (*env)->GetStaticMethodID(env, localConfigClass, "safOpen", "(I)I");
if (logMethod == NULL) {
if (safOpenMethod == NULL) {
LOGE("OnLoad thread failed to GetStaticMethodID for %s.\n", "safOpen");
return JNI_FALSE;
}
safCloseMethod = (*env)->GetStaticMethodID(env, localConfigClass, "safClose", "(I)I");
if (logMethod == NULL) {
if (safCloseMethod == NULL) {
LOGE("OnLoad thread failed to GetStaticMethodID for %s.\n", "safClose");
return JNI_FALSE;
}

@ -27,7 +27,7 @@
#include "libavutil/ffversion.h"
/** Library version string */
#define FFMPEG_KIT_VERSION "4.5.1"
#define FFMPEG_KIT_VERSION "5.1"
/** Defines tag used for Android logging. */
#define LIB_NAME "ffmpeg-kit"

@ -24,13 +24,14 @@
#include "config.h"
#include "libavcodec/jni.h"
#include "libavutil/bprint.h"
#include "libavutil/mem.h"
#include "ffmpegkit.h"
/** Forward declaration for function defined in fftools_ffprobe.c */
int ffprobe_execute(int argc, char **argv);
extern int configuredLogLevel;
extern __thread volatile long globalSessionId;
extern __thread long globalSessionId;
extern void addSession(long sessionId);
extern void removeSession(long sessionId);
extern void resetMessagesInTransmit(long sessionId);

@ -1,6 +1,7 @@
/*
* Various utilities for command line tools
* copyright (c) 2003 Fabrice Bellard
* copyright (c) 2018 Taner Sener ( tanersener gmail com )
*
* This file is part of FFmpeg.
*
@ -20,25 +21,37 @@
*/
/*
* CHANGES 01.2020
* - ffprobe support changes
* - AV_LOG_STDERR introduced
* This file is the modified version of cmdutils.h file living in ffmpeg source code under the fftools folder. We
* manually update it each time we depend on a new ffmpeg version. Below you can see the list of changes applied
* by us to develop mobile-ffmpeg and later ffmpeg-kit libraries.
*
* CHANGES 12.2019
* - Concurrent execution support
* mobile-ffmpeg / ffmpeg-kit changes by Taner Sener
*
* CHANGES 03.2019
* 09.2022
* --------------------------------------------------------
* - config.h include added back
*
* 01.2020
* --------------------------------------------------------
* - ffprobe support added (variables used by ffprobe marked with "__thread" specifier)
* - AV_LOG_STDERR log level added
*
* 12.2019
* --------------------------------------------------------
* - concurrent execution support ("__thread" specifier added to variables used by multiple threads)
*
* 03.2019
* --------------------------------------------------------
* - config.h include removed
*
* CHANGES 08.2018
* 08.2018
* --------------------------------------------------------
* - fftools_ prefix added to file name and include guards
*
* CHANGES 07.2018
* 07.2018
* --------------------------------------------------------
* - Include guards renamed
* - Unused headers removed
* - include guards renamed
* - unused headers removed
*/
#ifndef FFTOOLS_CMDUTILS_H
@ -46,6 +59,7 @@
#include <stdint.h>
#include "config.h"
#include "libavcodec/avcodec.h"
#include "libavfilter/avfilter.h"
#include "libavformat/avformat.h"
@ -70,11 +84,9 @@ extern __thread char *program_name;
*/
extern __thread int program_birth_year;
extern __thread AVCodecContext *avcodec_opts[AVMEDIA_TYPE_NB];
extern __thread AVFormatContext *avformat_opts;
extern __thread AVDictionary *sws_dict;
extern __thread AVDictionary *swr_opts;
extern __thread AVDictionary *format_opts, *codec_opts, *resample_opts;
extern __thread AVDictionary *format_opts, *codec_opts;
extern __thread int hide_banner;
extern __thread int find_stream_info;
@ -93,11 +105,6 @@ void exit_program(int ret) av_noreturn;
*/
void init_dynload(void);
/**
* Initialize the cmdutils option system, in particular
* allocate the *_opts contexts.
*/
void init_opts(void);
/**
* Uninitialize the cmdutils option system, in particular
* free the *_opts contexts and their contents.
@ -110,33 +117,12 @@ void uninit_opts(void);
*/
void log_callback_help(void* ptr, int level, const char* fmt, va_list vl);
/**
* Override the cpuflags.
*/
int opt_cpuflags(void *optctx, const char *opt, const char *arg);
/**
* Override the cpucount.
*/
int opt_cpucount(void *optctx, const char *opt, const char *arg);
/**
* Fallback for options that are not explicitly handled, these will be
* parsed through AVOptions.
*/
int opt_default(void *optctx, const char *opt, const char *arg);
/**
* Set the libav* libraries log level.
*/
int opt_loglevel(void *optctx, const char *opt, const char *arg);
int opt_report(void *optctx, const char *opt, const char *arg);
int opt_max_alloc(void *optctx, const char *opt, const char *arg);
int opt_codec_debug(void *optctx, const char *opt, const char *arg);
/**
* Limit the execution time.
*/
@ -237,7 +223,7 @@ void show_help_options(const OptionDef *options, const char *msg, int req_flags,
* Show help for all options with given flags in class and all its
* children.
*/
void show_help_children(const AVClass *class, int flags);
void show_help_children(const AVClass *clazz, int flags);
/**
* Per-fftool specific help handler. Implemented in each
@ -309,7 +295,6 @@ typedef struct OptionGroup {
AVDictionary *codec_opts;
AVDictionary *format_opts;
AVDictionary *resample_opts;
AVDictionary *sws_dict;
AVDictionary *swr_opts;
} OptionGroup;
@ -417,8 +402,8 @@ AVDictionary *filter_codec_opts(AVDictionary *opts, enum AVCodecID codec_id,
* Each dictionary will contain the options from codec_opts which can
* be applied to the corresponding stream codec context.
*
* @return pointer to the created array of dictionaries, NULL if it
* cannot be created
* @return pointer to the created array of dictionaries.
* Calls exit() on failure.
*/
AVDictionary **setup_find_stream_info_opts(AVFormatContext *s,
AVDictionary *codec_opts);
@ -441,136 +426,6 @@ void print_error(const char *filename, int err);
*/
void show_banner(int argc, char **argv, const OptionDef *options);
/**
* Print the version of the program to stdout. The version message
* depends on the current versions of the repository and of the libav*
* libraries.
* This option processing function does not utilize the arguments.
*/
int show_version(void *optctx, const char *opt, const char *arg);
/**
* Print the build configuration of the program to stdout. The contents
* depend on the definition of FFMPEG_CONFIGURATION.
* This option processing function does not utilize the arguments.
*/
int show_buildconf(void *optctx, const char *opt, const char *arg);
/**
* Print the license of the program to stdout. The license depends on
* the license of the libraries compiled into the program.
* This option processing function does not utilize the arguments.
*/
int show_license(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the formats supported by the
* program (including devices).
* This option processing function does not utilize the arguments.
*/
int show_formats(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the muxers supported by the
* program (including devices).
* This option processing function does not utilize the arguments.
*/
int show_muxers(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the demuxer supported by the
* program (including devices).
* This option processing function does not utilize the arguments.
*/
int show_demuxers(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the devices supported by the
* program.
* This option processing function does not utilize the arguments.
*/
int show_devices(void *optctx, const char *opt, const char *arg);
#if CONFIG_AVDEVICE
/**
* Print a listing containing autodetected sinks of the output device.
* Device name with options may be passed as an argument to limit results.
*/
int show_sinks(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing autodetected sources of the input device.
* Device name with options may be passed as an argument to limit results.
*/
int show_sources(void *optctx, const char *opt, const char *arg);
#endif
/**
* Print a listing containing all the codecs supported by the
* program.
* This option processing function does not utilize the arguments.
*/
int show_codecs(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the decoders supported by the
* program.
*/
int show_decoders(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the encoders supported by the
* program.
*/
int show_encoders(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the filters supported by the
* program.
* This option processing function does not utilize the arguments.
*/
int show_filters(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the bit stream filters supported by the
* program.
* This option processing function does not utilize the arguments.
*/
int show_bsfs(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the protocols supported by the
* program.
* This option processing function does not utilize the arguments.
*/
int show_protocols(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the pixel formats supported by the
* program.
* This option processing function does not utilize the arguments.
*/
int show_pix_fmts(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the standard channel layouts supported by
* the program.
* This option processing function does not utilize the arguments.
*/
int show_layouts(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the sample formats supported by the
* program.
*/
int show_sample_fmts(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the color names and values recognized
* by the program.
*/
int show_colors(void *optctx, const char *opt, const char *arg);
/**
* Return a positive value if a line read from standard input
* starts with [yY], otherwise return 0.
@ -610,11 +465,26 @@ FILE *get_preset_file(char *filename, size_t filename_size,
*/
void *grow_array(void *array, int elem_size, int *size, int new_size);
#define media_type_string av_get_media_type_string
/**
* Atomically add a new element to an array of pointers, i.e. allocate
* a new entry, reallocate the array of pointers and make the new last
* member of this array point to the newly allocated buffer.
* Calls exit() on failure.
*
* @param array array of pointers to reallocate
* @param elem_size size of the new element to allocate
* @param nb_elems pointer to the number of elements of the array array;
* *nb_elems will be incremented by one by this function.
* @return pointer to the newly allocated entry
*/
void *allocate_array_elem(void *array, size_t elem_size, int *nb_elems);
#define GROW_ARRAY(array, nb_elems)\
array = grow_array(array, sizeof(*array), &nb_elems, nb_elems + 1)
#define ALLOC_ARRAY_ELEM(array, nb_elems)\
allocate_array_elem(&array, sizeof(*array[0]), &nb_elems)
#define GET_PIX_FMT_NAME(pix_fmt)\
const char *name = av_get_pix_fmt_name(pix_fmt);
@ -628,14 +498,6 @@ void *grow_array(void *array, int elem_size, int *size, int new_size);
char name[16];\
snprintf(name, sizeof(name), "%d", rate);
#define GET_CH_LAYOUT_NAME(ch_layout)\
char name[16];\
snprintf(name, sizeof(name), "0x%"PRIx64, ch_layout);
#define GET_CH_LAYOUT_DESC(ch_layout)\
char name[128];\
av_get_channel_layout_string(name, sizeof(name), 0, ch_layout);
double get_rotation(AVStream *st);
double get_rotation(int32_t *displaymatrix);
#endif /* FFTOOLS_CMDUTILS_H */

File diff suppressed because it is too large Load Diff

@ -1,5 +1,6 @@
/*
* This file is part of FFmpeg.
* Copyright (c) 2018 Taner Sener ( tanersener gmail com )
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -17,33 +18,47 @@
*/
/*
* CHANGES 06.2020
* - cancel_operation() method signature updated with id
* This file is the modified version of ffmpeg.h file living in ffmpeg source code under the fftools folder. We
* manually update it each time we depend on a new ffmpeg version. Below you can see the list of changes applied
* by us to develop mobile-ffmpeg and later ffmpeg-kit libraries.
*
* mobile-ffmpeg / ffmpeg-kit changes by Taner Sener
*
* 09.2022
* --------------------------------------------------------
* - config.h include added back
* - volatile dropped from thread local variables
* - dropped signatures of ffmpeg_opt.c methods called by both ffmpeg and ffprobe
*
* CHANGES 01.2020
* - ffprobe support changes
* 06.2020
* --------------------------------------------------------
* - cancel_operation() method signature updated with id
*
* CHANGES 12.2019
* - Concurrent execution support
* 12.2019
* --------------------------------------------------------
* - concurrent execution support ("__thread" specifier added to variables used by multiple threads,
* signatures of ffmpeg_opt.c methods called by both ffmpeg and ffprobe added)
*
* CHANGES 03.2019
* 03.2019
* --------------------------------------------------------
* - config.h include removed
*
* CHANGES 08.2018
* 08.2018
* --------------------------------------------------------
* - fftools_ prefix added to file name and include guards
* - set_report_callback() method declared
* - cancel_operation() method declared
*
* CHANGES 07.2018
* 07.2018
* --------------------------------------------------------
* - Include guards renamed
* - include guards renamed
*/
#ifndef FFTOOLS_FFMPEG_H
#define FFTOOLS_FFMPEG_H
#include "config.h"
#include <stdint.h>
#include <stdio.h>
#include <signal.h>
@ -70,12 +85,14 @@
#include "libswresample/swresample.h"
#define VSYNC_AUTO -1
#define VSYNC_PASSTHROUGH 0
#define VSYNC_CFR 1
#define VSYNC_VFR 2
#define VSYNC_VSCFR 0xfe
#define VSYNC_DROP 0xff
enum VideoSyncMethod {
VSYNC_AUTO = -1,
VSYNC_PASSTHROUGH,
VSYNC_CFR,
VSYNC_VFR,
VSYNC_VSCFR,
VSYNC_DROP,
};
#define MAX_STREAMS 1024 /* arbitrary sanity check value */
@ -83,16 +100,8 @@ enum HWAccelID {
HWACCEL_NONE = 0,
HWACCEL_AUTO,
HWACCEL_GENERIC,
HWACCEL_VIDEOTOOLBOX,
};
typedef struct HWAccel {
const char *name;
int (*init)(AVCodecContext *s);
enum HWAccelID id;
enum AVPixelFormat pix_fmt;
} HWAccel;
typedef struct HWDevice {
const char *name;
enum AVHWDeviceType type;
@ -125,6 +134,8 @@ typedef struct OptionsContext {
SpecifierOpt *codec_names;
int nb_codec_names;
SpecifierOpt *audio_ch_layouts;
int nb_audio_ch_layouts;
SpecifierOpt *audio_channels;
int nb_audio_channels;
SpecifierOpt *audio_sample_rate;
@ -145,6 +156,7 @@ typedef struct OptionsContext {
float readrate;
int accurate_seek;
int thread_queue_size;
int input_sync_ref;
SpecifierOpt *ts_scale;
int nb_ts_scale;
@ -203,6 +215,8 @@ typedef struct OptionsContext {
int nb_qscale;
SpecifierOpt *forced_key_frames;
int nb_forced_key_frames;
SpecifierOpt *fps_mode;
int nb_fps_mode;
SpecifierOpt *force_fps;
int nb_force_fps;
SpecifierOpt *frame_aspect_ratios;
@ -259,6 +273,8 @@ typedef struct OptionsContext {
int nb_enc_time_bases;
SpecifierOpt *autoscale;
int nb_autoscale;
SpecifierOpt *bits_per_raw_sample;
int nb_bits_per_raw_sample;
} OptionsContext;
typedef struct InputFilter {
@ -268,7 +284,7 @@ typedef struct InputFilter {
uint8_t *name;
enum AVMediaType type; // AVMEDIA_TYPE_SUBTITLE for sub2video
AVFifoBuffer *frame_queue;
AVFifo *frame_queue;
// parameters configured for this input
int format;
@ -277,10 +293,10 @@ typedef struct InputFilter {
AVRational sample_aspect_ratio;
int sample_rate;
int channels;
uint64_t channel_layout;
AVChannelLayout ch_layout;
AVBufferRef *hw_frames_ctx;
int32_t *displaymatrix;
int eof;
} InputFilter;
@ -300,12 +316,13 @@ typedef struct OutputFilter {
AVRational frame_rate;
int format;
int sample_rate;
uint64_t channel_layout;
AVChannelLayout ch_layout;
// those are only set if no format is specified and the encoder gives us multiple options
int *formats;
uint64_t *channel_layouts;
int *sample_rates;
// They point directly to the relevant lists of the encoder.
const int *formats;
const AVChannelLayout *ch_layouts;
const int *sample_rates;
} OutputFilter;
typedef struct FilterGraph {
@ -314,6 +331,9 @@ typedef struct FilterGraph {
AVFilterGraph *graph;
int reconfiguration;
// true when the filtergraph contains only meta filters
// that do not modify the frame data
int is_meta;
InputFilter **inputs;
int nb_inputs;
@ -329,13 +349,14 @@ typedef struct InputStream {
int decoding_needed; /* non zero if the packets must be decoded in 'raw_fifo', see DECODING_FOR_* */
#define DECODING_FOR_OST 1
#define DECODING_FOR_FILTER 2
int processing_needed; /* non zero if the packets must be processed */
AVCodecContext *dec_ctx;
const AVCodec *dec;
AVFrame *decoded_frame;
AVFrame *filter_frame; /* a ref of decoded_frame, to be sent to filters */
AVPacket *pkt;
int64_t prev_pkt_pts;
int64_t start; /* time when read started */
/* predicted dts of the next packet read for this stream or (when there are
* several frames in a packet) of the next frame in current packet (in AV_TIME_BASE units) */
@ -377,14 +398,12 @@ typedef struct InputStream {
struct sub2video {
int64_t last_pts;
int64_t end_pts;
AVFifoBuffer *sub_queue; ///< queue of AVSubtitle* before filter init
AVFifo *sub_queue; ///< queue of AVSubtitle* before filter init
AVFrame *frame;
int w, h;
unsigned int initialize; ///< marks if sub2video_update should force an initialization
} sub2video;
int dr1;
/* decoded data from this stream goes into all those filters
* currently video and audio only */
InputFilter **filters;
@ -401,11 +420,9 @@ typedef struct InputStream {
/* hwaccel context */
void *hwaccel_ctx;
void (*hwaccel_uninit)(AVCodecContext *s);
int (*hwaccel_get_buffer)(AVCodecContext *s, AVFrame *frame, int flags);
int (*hwaccel_retrieve_data)(AVCodecContext *s, AVFrame *frame);
enum AVPixelFormat hwaccel_pix_fmt;
enum AVPixelFormat hwaccel_retrieved_pix_fmt;
AVBufferRef *hw_frames_ctx;
/* stats */
// combined size of all the packets read
@ -432,11 +449,11 @@ typedef struct InputFile {
at the moment when looping happens */
AVRational time_base; /* time base of the duration */
int64_t input_ts_offset;
int input_sync_ref;
int64_t ts_offset;
int64_t last_ts;
int64_t start_time; /* user-specified start time in AV_TIME_BASE or AV_NOPTS_VALUE */
int seek_timestamp;
int64_t recording_time;
int nb_streams; /* number of stream that ffmpeg is aware of; may be different
from ctx.nb_streams if new streams appear during av_read_frame() */
@ -481,7 +498,7 @@ typedef struct OutputStream {
int source_index; /* InputStream index */
AVStream *st; /* stream in the output file */
int encoding_needed; /* true if encoding needed for this stream */
int frame_number;
int64_t frame_number;
/* input pts and corresponding output pts
for A/V sync */
struct InputStream *sync_ist; /* input stream to sync against */
@ -504,19 +521,22 @@ typedef struct OutputStream {
AVFrame *filtered_frame;
AVFrame *last_frame;
AVPacket *pkt;
int last_dropped;
int last_nb0_frames[3];
int64_t last_dropped;
int64_t last_nb0_frames[3];
void *hwaccel_ctx;
/* video only */
AVRational frame_rate;
AVRational max_frame_rate;
enum VideoSyncMethod vsync_method;
int is_cfr;
const char *fps_mode;
int force_fps;
int top_field_first;
int rotate_overridden;
int autoscale;
int bits_per_raw_sample;
double rotate_override_value;
AVRational frame_aspect_ratio;
@ -546,7 +566,6 @@ typedef struct OutputStream {
AVDictionary *encoder_opts;
AVDictionary *sws_dict;
AVDictionary *swr_opts;
AVDictionary *resample_opts;
char *apad;
OSTFinished finished; /* no more packets should be written for this stream */
int unavailable; /* true if the steram is unavailable (possibly temporarily) */
@ -560,6 +579,7 @@ typedef struct OutputStream {
int inputs_done;
const char *attachment_filename;
int streamcopy_started;
int copy_initial_nonkeyframes;
int copy_prior_start;
char *disposition;
@ -574,6 +594,8 @@ typedef struct OutputStream {
// number of frames/samples sent to the encoder
uint64_t frames_encoded;
uint64_t samples_encoded;
// number of packets received from the encoder
uint64_t packets_encoded;
/* packet quality factor */
int quality;
@ -581,7 +603,7 @@ typedef struct OutputStream {
int max_muxing_queue_size;
/* the packets are buffered here until the muxer is ready to be initialized */
AVFifoBuffer *muxing_queue;
AVFifo *muxing_queue;
/*
* The size of the AVPackets' buffers in queue.
@ -600,6 +622,10 @@ typedef struct OutputStream {
} OutputStream;
typedef struct OutputFile {
int index;
const AVOutputFormat *format;
AVFormatContext *ctx;
AVDictionary *opts;
int ost_index; /* index of the first stream in output_streams */
@ -634,7 +660,7 @@ extern __thread float dts_error_threshold;
extern __thread int audio_volume;
extern __thread int audio_sync_method;
extern __thread int video_sync_method;
extern __thread enum VideoSyncMethod video_sync_method;
extern __thread float frame_drop_threshold;
extern __thread int do_benchmark;
extern __thread int do_benchmark_all;
@ -654,41 +680,35 @@ extern __thread int stdin_interaction;
extern __thread int frame_bits_per_raw_sample;
extern __thread AVIOContext *progress_avio;
extern __thread float max_error_rate;
extern __thread char *videotoolbox_pixfmt;
extern __thread int filter_nbthreads;
extern __thread char *filter_nbthreads;
extern __thread int filter_complex_nbthreads;
extern __thread int vstats_version;
extern __thread int auto_conversion_filters;
extern __thread const AVIOInterruptCB int_cb;
extern const HWAccel hwaccels[];
#if CONFIG_QSV
extern __thread char *qsv_device;
#endif
extern __thread HWDevice *filter_hw_device;
extern __thread int want_sdp;
extern __thread unsigned nb_output_dumped;
extern __thread int main_ffmpeg_return_code;
void term_init(void);
void term_exit(void);
void reset_options(OptionsContext *o, int is_input);
void show_usage(void);
void opt_output_file(void *optctx, const char *filename);
void remove_avoptions(AVDictionary **a, AVDictionary *b);
void assert_avoptions(AVDictionary *m);
int guess_input_channel_layout(InputStream *ist);
enum AVPixelFormat choose_pixel_fmt(AVStream *st, AVCodecContext *avctx, const AVCodec *codec, enum AVPixelFormat target);
void choose_sample_fmt(AVStream *st, const AVCodec *codec);
int configure_filtergraph(FilterGraph *fg);
int configure_output_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out);
void check_filter_outputs(void);
int ist_in_filtergraph(FilterGraph *fg, InputStream *ist);
int filtergraph_is_simple(FilterGraph *fg);
int init_simple_filtergraph(InputStream *ist, OutputStream *ost);
int init_complex_filtergraph(FilterGraph *fg);
@ -712,80 +732,15 @@ int hw_device_setup_for_filter(FilterGraph *fg);
int hwaccel_decode_init(AVCodecContext *avctx);
void set_report_callback(void (*callback)(int, float, float, int64_t, int, double, double));
/* open the muxer when all the streams are initialized */
int of_check_init(OutputFile *of);
int of_write_trailer(OutputFile *of);
void of_close(OutputFile **pof);
void cancel_operation(long id);
void of_write_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost,
int unqueue);
int opt_map(void *optctx, const char *opt, const char *arg);
int opt_map_channel(void *optctx, const char *opt, const char *arg);
int opt_recording_timestamp(void *optctx, const char *opt, const char *arg);
int opt_data_frames(void *optctx, const char *opt, const char *arg);
int opt_progress(void *optctx, const char *opt, const char *arg);
int opt_target(void *optctx, const char *opt, const char *arg);
int opt_vsync(void *optctx, const char *opt, const char *arg);
int opt_abort_on(void *optctx, const char *opt, const char *arg);
int opt_stats_period(void *optctx, const char *opt, const char *arg);
int opt_qscale(void *optctx, const char *opt, const char *arg);
int opt_profile(void *optctx, const char *opt, const char *arg);
int opt_filter_complex(void *optctx, const char *opt, const char *arg);
int opt_filter_complex_script(void *optctx, const char *opt, const char *arg);
int opt_attach(void *optctx, const char *opt, const char *arg);
int opt_video_frames(void *optctx, const char *opt, const char *arg);
int opt_video_codec(void *optctx, const char *opt, const char *arg);
int opt_sameq(void *optctx, const char *opt, const char *arg);
int opt_timecode(void *optctx, const char *opt, const char *arg);
int opt_vstats_file(void *optctx, const char *opt, const char *arg);
int opt_vstats(void *optctx, const char *opt, const char *arg);
int opt_video_frames(void *optctx, const char *opt, const char *arg);
int opt_old2new(void *optctx, const char *opt, const char *arg);
int opt_streamid(void *optctx, const char *opt, const char *arg);
int opt_bitrate(void *optctx, const char *opt, const char *arg);
int show_hwaccels(void *optctx, const char *opt, const char *arg);
int opt_video_filters(void *optctx, const char *opt, const char *arg);
int opt_audio_frames(void *optctx, const char *opt, const char *arg);
int opt_audio_qscale(void *optctx, const char *opt, const char *arg);
int opt_audio_codec(void *optctx, const char *opt, const char *arg);
int opt_channel_layout(void *optctx, const char *opt, const char *arg);
int opt_preset(void *optctx, const char *opt, const char *arg);
int opt_audio_filters(void *optctx, const char *opt, const char *arg);
int opt_subtitle_codec(void *optctx, const char *opt, const char *arg);
int opt_video_channel(void *optctx, const char *opt, const char *arg);
int opt_video_standard(void *optctx, const char *opt, const char *arg);
int opt_sdp_file(void *optctx, const char *opt, const char *arg);
int opt_data_codec(void *optctx, const char *opt, const char *arg);
int opt_init_hw_device(void *optctx, const char *opt, const char *arg);
int opt_filter_hw_device(void *optctx, const char *opt, const char *arg);
void add_input_streams(OptionsContext *o, AVFormatContext *ic);
void assert_file_overwrite(const char *filename);
void dump_attachment(AVStream *st, const char *filename);
uint8_t *get_line(AVIOContext *s);
void uninit_options(OptionsContext *o);
void init_options(OptionsContext *o);
AVDictionary *strip_specifiers(AVDictionary *dict);
void parse_meta_type(char *arg, char *type, int *index, const char **stream_spec);
int fftools_copy_metadata(char *outspec, char *inspec, AVFormatContext *oc, AVFormatContext *ic, OptionsContext *o);
const AVCodec *find_codec_or_die(const char *name, enum AVMediaType type, int encoder);
const AVCodec *choose_decoder(OptionsContext *o, AVFormatContext *s, AVStream *st);
int open_input_file(OptionsContext *o, const char *filename);
int get_preset_file_2(const char *preset_name, const char *codec_name, AVIOContext **s);
int choose_encoder(OptionsContext *o, AVFormatContext *s, OutputStream *ost);
OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, enum AVMediaType type, int source_index);
void parse_matrix_coeffs(uint16_t *dest, const char *str);
uint8_t *fftools_read_file(const char *filename);
char *get_ost_filters(OptionsContext *o, AVFormatContext *oc, OutputStream *ost);
void check_streamcopy_filters(OptionsContext *o, AVFormatContext *oc, const OutputStream *ost, enum AVMediaType type);
OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc, int source_index);
OutputStream *new_audio_stream(OptionsContext *o, AVFormatContext *oc, int source_index);
OutputStream *new_data_stream(OptionsContext *o, AVFormatContext *oc, int source_index);
OutputStream *new_unknown_stream(OptionsContext *o, AVFormatContext *oc, int source_index);
OutputStream *new_attachment_stream(OptionsContext *o, AVFormatContext *oc, int source_index);
OutputStream *new_subtitle_stream(OptionsContext *o, AVFormatContext *oc, int source_index);
int copy_chapters(InputFile *ifile, OutputFile *ofile, int copy_metadata);
void init_output_filter(OutputFilter *ofilter, OptionsContext *o, AVFormatContext *oc);
int init_complex_filters(void);
int open_output_file(OptionsContext *o, const char *filename);
int opt_default_new(OptionsContext *o, const char *opt, const char *arg);
int open_files(OptionGroupList *l, const char *inout, int (*open_file)(OptionsContext*, const char*));
void set_report_callback(void (*callback)(int, float, float, int64_t, int, double, double));
void cancel_operation(long id);
#endif /* FFTOOLS_FFMPEG_H */

@ -1,5 +1,6 @@
/*
* ffmpeg filter configuration
* copyright (c) 2018 Taner Sener ( tanersener gmail com )
*
* This file is part of FFmpeg.
*
@ -19,13 +20,19 @@
*/
/*
* CHANGES 08.2018
* This file is the modified version of ffmpeg_filter.c file living in ffmpeg source code under the fftools folder.
* We manually update it each time we depend on a new ffmpeg version. Below you can see the list of changes applied
* by us to develop mobile-ffmpeg and later ffmpeg-kit libraries.
*
* mobile-ffmpeg / ffmpeg-kit changes by Taner Sener
*
* 08.2018
* --------------------------------------------------------
* - fftools_ prefix added to file name and parent header
*
* CHANGES 07.2018
* 07.2018
* --------------------------------------------------------
* - Unused headers removed
* - unused headers removed
*/
#include <stdint.h>
@ -53,7 +60,7 @@ static const enum AVPixelFormat *get_compliance_normal_pix_fmts(const AVCodec *c
{
static const enum AVPixelFormat mjpeg_formats[] =
{ AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ444P,
AV_PIX_FMT_NONE};
AV_PIX_FMT_NONE };
if (!strcmp(codec->name, "mjpeg")) {
return mjpeg_formats;
@ -93,10 +100,13 @@ enum AVPixelFormat choose_pixel_fmt(AVStream *st, AVCodecContext *enc_ctx,
return target;
}
static char *choose_pix_fmts(OutputFilter *ofilter)
/* May return NULL (no pixel format found), a static string or a string
* backed by the bprint. Nothing has been written to the AVBPrint in case
* NULL is returned. The AVBPrint provided should be clean. */
static const char *choose_pix_fmts(OutputFilter *ofilter, AVBPrint *bprint)
{
OutputStream *ost = ofilter->ost;
AVDictionaryEntry *strict_dict = av_dict_get(ost->encoder_opts, "strict", NULL, 0);
const AVDictionaryEntry *strict_dict = av_dict_get(ost->encoder_opts, "strict", NULL, 0);
if (strict_dict)
// used by choose_pixel_fmt() and below
av_opt_set(ost->enc_ctx, "strict", strict_dict->value, 0);
@ -106,18 +116,12 @@ static char *choose_pix_fmts(OutputFilter *ofilter)
AVFILTER_AUTO_CONVERT_NONE);
if (ost->enc_ctx->pix_fmt == AV_PIX_FMT_NONE)
return NULL;
return av_strdup(av_get_pix_fmt_name(ost->enc_ctx->pix_fmt));
return av_get_pix_fmt_name(ost->enc_ctx->pix_fmt);
}
if (ost->enc_ctx->pix_fmt != AV_PIX_FMT_NONE) {
return av_strdup(av_get_pix_fmt_name(choose_pixel_fmt(ost->st, ost->enc_ctx, ost->enc, ost->enc_ctx->pix_fmt)));
return av_get_pix_fmt_name(choose_pixel_fmt(ost->st, ost->enc_ctx, ost->enc, ost->enc_ctx->pix_fmt));
} else if (ost->enc && ost->enc->pix_fmts) {
const enum AVPixelFormat *p;
AVIOContext *s = NULL;
uint8_t *ret;
int len;
if (avio_open_dyn_buf(&s) < 0)
exit_program(1);
p = ost->enc->pix_fmts;
if (ost->enc_ctx->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL) {
@ -126,11 +130,11 @@ static char *choose_pix_fmts(OutputFilter *ofilter)
for (; *p != AV_PIX_FMT_NONE; p++) {
const char *name = av_get_pix_fmt_name(*p);
avio_printf(s, "%s|", name);
av_bprintf(bprint, "%s%c", name, p[1] == AV_PIX_FMT_NONE ? '\0' : '|');
}
len = avio_close_dyn_buf(s, &ret);
ret[len - 1] = 0;
return ret;
if (!av_bprint_is_complete(bprint))
exit_program(1);
return bprint->str;
} else
return NULL;
}
@ -166,39 +170,54 @@ DEF_CHOOSE_FORMAT(sample_fmts, enum AVSampleFormat, format, formats,
DEF_CHOOSE_FORMAT(sample_rates, int, sample_rate, sample_rates, 0,
"%d", )
DEF_CHOOSE_FORMAT(channel_layouts, uint64_t, channel_layout, channel_layouts, 0,
"0x%"PRIx64, )
static void choose_channel_layouts(OutputFilter *ofilter, AVBPrint *bprint)
{
if (av_channel_layout_check(&ofilter->ch_layout)) {
av_bprintf(bprint, "channel_layouts=");
av_channel_layout_describe_bprint(&ofilter->ch_layout, bprint);
} else if (ofilter->ch_layouts) {
const AVChannelLayout *p;
av_bprintf(bprint, "channel_layouts=");
for (p = ofilter->ch_layouts; p->nb_channels; p++) {
av_channel_layout_describe_bprint(p, bprint);
av_bprintf(bprint, "|");
}
if (bprint->len > 0)
bprint->str[--bprint->len] = '\0';
} else
return;
av_bprint_chars(bprint, ':', 1);
}
int init_simple_filtergraph(InputStream *ist, OutputStream *ost)
{
FilterGraph *fg = av_mallocz(sizeof(*fg));
OutputFilter *ofilter;
InputFilter *ifilter;
if (!fg)
exit_program(1);
fg->index = nb_filtergraphs;
GROW_ARRAY(fg->outputs, fg->nb_outputs);
if (!(fg->outputs[0] = av_mallocz(sizeof(*fg->outputs[0]))))
exit_program(1);
fg->outputs[0]->ost = ost;
fg->outputs[0]->graph = fg;
fg->outputs[0]->format = -1;
ofilter = ALLOC_ARRAY_ELEM(fg->outputs, fg->nb_outputs);
ofilter->ost = ost;
ofilter->graph = fg;
ofilter->format = -1;
ost->filter = fg->outputs[0];
ost->filter = ofilter;
GROW_ARRAY(fg->inputs, fg->nb_inputs);
if (!(fg->inputs[0] = av_mallocz(sizeof(*fg->inputs[0]))))
exit_program(1);
fg->inputs[0]->ist = ist;
fg->inputs[0]->graph = fg;
fg->inputs[0]->format = -1;
ifilter = ALLOC_ARRAY_ELEM(fg->inputs, fg->nb_inputs);
ifilter->ist = ist;
ifilter->graph = fg;
ifilter->format = -1;
fg->inputs[0]->frame_queue = av_fifo_alloc(8 * sizeof(AVFrame*));
if (!fg->inputs[0]->frame_queue)
ifilter->frame_queue = av_fifo_alloc2(8, sizeof(AVFrame*), AV_FIFO_FLAG_AUTO_GROW);
if (!ifilter->frame_queue)
exit_program(1);
GROW_ARRAY(ist->filters, ist->nb_filters);
ist->filters[ist->nb_filters - 1] = fg->inputs[0];
ist->filters[ist->nb_filters - 1] = ifilter;
GROW_ARRAY(filtergraphs, nb_filtergraphs);
filtergraphs[nb_filtergraphs - 1] = fg;
@ -211,17 +230,15 @@ static char *describe_filter_link(FilterGraph *fg, AVFilterInOut *inout, int in)
AVFilterContext *ctx = inout->filter_ctx;
AVFilterPad *pads = in ? ctx->input_pads : ctx->output_pads;
int nb_pads = in ? ctx->nb_inputs : ctx->nb_outputs;
AVIOContext *pb;
uint8_t *res = NULL;
char *res;
if (avio_open_dyn_buf(&pb) < 0)
exit_program(1);
avio_printf(pb, "%s", ctx->filter->name);
if (nb_pads > 1)
avio_printf(pb, ":%s", avfilter_pad_get_name(pads, inout->pad_idx));
avio_w8(pb, 0);
avio_close_dyn_buf(pb, &res);
res = av_strdup(ctx->filter->name);
else
res = av_asprintf("%s:%s", ctx->filter->name,
avfilter_pad_get_name(pads, inout->pad_idx));
if (!res)
exit_program(1);
return res;
}
@ -229,6 +246,7 @@ static void init_input_filter(FilterGraph *fg, AVFilterInOut *in)
{
InputStream *ist = NULL;
enum AVMediaType type = avfilter_pad_get_type(in->filter_ctx->input_pads, in->pad_idx);
InputFilter *ifilter;
int i;
// TODO: support other filter types
@ -293,23 +311,22 @@ static void init_input_filter(FilterGraph *fg, AVFilterInOut *in)
ist->discard = 0;
ist->decoding_needed |= DECODING_FOR_FILTER;
ist->processing_needed = 1;
ist->st->discard = AVDISCARD_NONE;
GROW_ARRAY(fg->inputs, fg->nb_inputs);
if (!(fg->inputs[fg->nb_inputs - 1] = av_mallocz(sizeof(*fg->inputs[0]))))
exit_program(1);
fg->inputs[fg->nb_inputs - 1]->ist = ist;
fg->inputs[fg->nb_inputs - 1]->graph = fg;
fg->inputs[fg->nb_inputs - 1]->format = -1;
fg->inputs[fg->nb_inputs - 1]->type = ist->st->codecpar->codec_type;
fg->inputs[fg->nb_inputs - 1]->name = describe_filter_link(fg, in, 1);
fg->inputs[fg->nb_inputs - 1]->frame_queue = av_fifo_alloc(8 * sizeof(AVFrame*));
if (!fg->inputs[fg->nb_inputs - 1]->frame_queue)
ifilter = ALLOC_ARRAY_ELEM(fg->inputs, fg->nb_inputs);
ifilter->ist = ist;
ifilter->graph = fg;
ifilter->format = -1;
ifilter->type = ist->st->codecpar->codec_type;
ifilter->name = describe_filter_link(fg, in, 1);
ifilter->frame_queue = av_fifo_alloc2(8, sizeof(AVFrame*), AV_FIFO_FLAG_AUTO_GROW);
if (!ifilter->frame_queue)
exit_program(1);
GROW_ARRAY(ist->filters, ist->nb_filters);
ist->filters[ist->nb_filters - 1] = fg->inputs[fg->nb_inputs - 1];
ist->filters[ist->nb_filters - 1] = ifilter;
}
int init_complex_filtergraph(FilterGraph *fg)
@ -333,18 +350,15 @@ int init_complex_filtergraph(FilterGraph *fg)
init_input_filter(fg, cur);
for (cur = outputs; cur;) {
GROW_ARRAY(fg->outputs, fg->nb_outputs);
fg->outputs[fg->nb_outputs - 1] = av_mallocz(sizeof(*fg->outputs[0]));
if (!fg->outputs[fg->nb_outputs - 1])
exit_program(1);
OutputFilter *const ofilter = ALLOC_ARRAY_ELEM(fg->outputs, fg->nb_outputs);
fg->outputs[fg->nb_outputs - 1]->graph = fg;
fg->outputs[fg->nb_outputs - 1]->out_tmp = cur;
fg->outputs[fg->nb_outputs - 1]->type = avfilter_pad_get_type(cur->filter_ctx->output_pads,
ofilter->graph = fg;
ofilter->out_tmp = cur;
ofilter->type = avfilter_pad_get_type(cur->filter_ctx->output_pads,
cur->pad_idx);
fg->outputs[fg->nb_outputs - 1]->name = describe_filter_link(fg, cur, 0);
ofilter->name = describe_filter_link(fg, cur, 0);
cur = cur->next;
fg->outputs[fg->nb_outputs - 1]->out_tmp->next = NULL;
ofilter->out_tmp->next = NULL;
}
fail:
@ -428,12 +442,13 @@ static int insert_filter(AVFilterContext **last_filter, int *pad_idx,
static int configure_output_video_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out)
{
char *pix_fmts;
OutputStream *ost = ofilter->ost;
OutputFile *of = output_files[ost->file_index];
AVFilterContext *last_filter = out->filter_ctx;
AVBPrint bprint;
int pad_idx = out->pad_idx;
int ret;
const char *pix_fmts;
char name[255];
snprintf(name, sizeof(name), "out_%d_%d", ost->file_index, ost->index);
@ -447,7 +462,7 @@ static int configure_output_video_filter(FilterGraph *fg, OutputFilter *ofilter,
if ((ofilter->width || ofilter->height) && ofilter->ost->autoscale) {
char args[255];
AVFilterContext *filter;
AVDictionaryEntry *e = NULL;
const AVDictionaryEntry *e = NULL;
snprintf(args, sizeof(args), "%d:%d",
ofilter->width, ofilter->height);
@ -469,13 +484,14 @@ static int configure_output_video_filter(FilterGraph *fg, OutputFilter *ofilter,
pad_idx = 0;
}
if ((pix_fmts = choose_pix_fmts(ofilter))) {
av_bprint_init(&bprint, 0, AV_BPRINT_SIZE_UNLIMITED);
if ((pix_fmts = choose_pix_fmts(ofilter, &bprint))) {
AVFilterContext *filter;
ret = avfilter_graph_create_filter(&filter,
avfilter_get_by_name("format"),
"format", pix_fmts, NULL, fg->graph);
av_freep(&pix_fmts);
av_bprint_finalize(&bprint, NULL);
if (ret < 0)
return ret;
if ((ret = avfilter_link(last_filter, pad_idx, filter, 0)) < 0)
@ -560,9 +576,10 @@ static int configure_output_audio_filter(FilterGraph *fg, OutputFilter *ofilter,
} while (0)
av_bprint_init(&args, 0, AV_BPRINT_SIZE_UNLIMITED);
if (ost->audio_channels_mapped) {
AVChannelLayout mapped_layout = { 0 };
int i;
av_bprintf(&args, "0x%"PRIx64,
av_get_default_channel_layout(ost->audio_channels_mapped));
av_channel_layout_default(&mapped_layout, ost->audio_channels_mapped);
av_channel_layout_describe_bprint(&mapped_layout, &args);
for (i = 0; i < ost->audio_channels_mapped; i++)
if (ost->audio_channels_map[i] != -1)
av_bprintf(&args, "|c%d=c%d", i, ost->audio_channels_map[i]);
@ -571,8 +588,8 @@ static int configure_output_audio_filter(FilterGraph *fg, OutputFilter *ofilter,
av_bprint_clear(&args);
}
if (codec->channels && !codec->channel_layout)
codec->channel_layout = av_get_default_channel_layout(codec->channels);
if (codec->ch_layout.order == AV_CHANNEL_ORDER_UNSPEC)
av_channel_layout_default(&codec->ch_layout, codec->ch_layout.nb_channels);
choose_sample_fmts(ofilter, &args);
choose_sample_rates(ofilter, &args);
@ -709,6 +726,7 @@ static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter,
{
AVFilterContext *last_filter;
const AVFilter *buffer_filt = avfilter_get_by_name("buffer");
const AVPixFmtDescriptor *desc;
InputStream *ist = ifilter->ist;
InputFile *f = input_files[ist->file_index];
AVRational tb = ist->framerate.num ? av_inv_q(ist->framerate) :
@ -766,42 +784,44 @@ static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter,
av_freep(&par);
last_filter = ifilter->filter;
if (ist->autorotate) {
double theta = get_rotation(ist->st);
desc = av_pix_fmt_desc_get(ifilter->format);
av_assert0(desc);
// TODO: insert hwaccel enabled filters like transpose_vaapi into the graph
if (ist->autorotate && !(desc->flags & AV_PIX_FMT_FLAG_HWACCEL)) {
int32_t *displaymatrix = ifilter->displaymatrix;
double theta;
if (!displaymatrix)
displaymatrix = (int32_t *)av_stream_get_side_data(ist->st, AV_PKT_DATA_DISPLAYMATRIX, NULL);
theta = get_rotation(displaymatrix);
if (fabs(theta - 90) < 1.0) {
ret = insert_filter(&last_filter, &pad_idx, "transpose", "clock");
ret = insert_filter(&last_filter, &pad_idx, "transpose",
displaymatrix[3] > 0 ? "cclock_flip" : "clock");
} else if (fabs(theta - 180) < 1.0) {
if (displaymatrix[0] < 0) {
ret = insert_filter(&last_filter, &pad_idx, "hflip", NULL);
if (ret < 0)
return ret;
}
if (displaymatrix[4] < 0) {
ret = insert_filter(&last_filter, &pad_idx, "vflip", NULL);
}
} else if (fabs(theta - 270) < 1.0) {
ret = insert_filter(&last_filter, &pad_idx, "transpose", "cclock");
ret = insert_filter(&last_filter, &pad_idx, "transpose",
displaymatrix[3] < 0 ? "clock_flip" : "cclock");
} else if (fabs(theta) > 1.0) {
char rotate_buf[64];
snprintf(rotate_buf, sizeof(rotate_buf), "%f*PI/180", theta);
ret = insert_filter(&last_filter, &pad_idx, "rotate", rotate_buf);
} else if (fabs(theta) < 1.0) {
if (displaymatrix && displaymatrix[4] < 0) {
ret = insert_filter(&last_filter, &pad_idx, "vflip", NULL);
}
if (ret < 0)
return ret;
}
if (do_deinterlace) {
AVFilterContext *yadif;
snprintf(name, sizeof(name), "deinterlace_in_%d_%d",
ist->file_index, ist->st->index);
if ((ret = avfilter_graph_create_filter(&yadif,
avfilter_get_by_name("yadif"),
name, "", NULL,
fg->graph)) < 0)
return ret;
if ((ret = avfilter_link(last_filter, 0, yadif, 0)) < 0)
if (ret < 0)
return ret;
last_filter = yadif;
}
snprintf(name, sizeof(name), "trim_in_%d_%d",
@ -848,11 +868,12 @@ static int configure_input_audio_filter(FilterGraph *fg, InputFilter *ifilter,
1, ifilter->sample_rate,
ifilter->sample_rate,
av_get_sample_fmt_name(ifilter->format));
if (ifilter->channel_layout)
av_bprintf(&args, ":channel_layout=0x%"PRIx64,
ifilter->channel_layout);
else
av_bprintf(&args, ":channels=%d", ifilter->channels);
if (av_channel_layout_check(&ifilter->ch_layout) &&
ifilter->ch_layout.order != AV_CHANNEL_ORDER_UNSPEC) {
av_bprintf(&args, ":channel_layout=");
av_channel_layout_describe_bprint(&ifilter->ch_layout, &args);
} else
av_bprintf(&args, ":channels=%d", ifilter->ch_layout.nb_channels);
snprintf(name, sizeof(name), "graph_%d_in_%d_%d", fg->index,
ist->file_index, ist->st->index);
@ -962,6 +983,30 @@ static void cleanup_filtergraph(FilterGraph *fg)
avfilter_graph_free(&fg->graph);
}
static int filter_is_buffersrc(const AVFilterContext *f)
{
return f->nb_inputs == 0 &&
(!strcmp(f->filter->name, "buffer") ||
!strcmp(f->filter->name, "abuffer"));
}
static int graph_is_meta(AVFilterGraph *graph)
{
for (unsigned i = 0; i < graph->nb_filters; i++) {
const AVFilterContext *f = graph->filters[i];
/* in addition to filters flagged as meta, also
* disregard sinks and buffersources (but not other sources,
* since they introduce data we are not aware of)
*/
if (!((f->filter->flags & AVFILTER_FLAG_METADATA_ONLY) ||
f->nb_outputs == 0 ||
filter_is_buffersrc(f)))
return 0;
}
return 1;
}
int configure_filtergraph(FilterGraph *fg)
{
AVFilterInOut *inputs, *outputs, *cur;
@ -976,24 +1021,31 @@ int configure_filtergraph(FilterGraph *fg)
if (simple) {
OutputStream *ost = fg->outputs[0]->ost;
char args[512];
AVDictionaryEntry *e = NULL;
const AVDictionaryEntry *e = NULL;
fg->graph->nb_threads = filter_nbthreads;
if (filter_nbthreads) {
ret = av_opt_set(fg->graph, "threads", filter_nbthreads, 0);
if (ret < 0)
goto fail;
} else {
e = av_dict_get(ost->encoder_opts, "threads", NULL, 0);
if (e)
av_opt_set(fg->graph, "threads", e->value, 0);
}
args[0] = 0;
e = NULL;
while ((e = av_dict_get(ost->sws_dict, "", e,
AV_DICT_IGNORE_SUFFIX))) {
av_strlcatf(args, sizeof(args), "%s=%s:", e->key, e->value);
}
if (strlen(args))
if (strlen(args)) {
args[strlen(args)-1] = 0;
if (!strncmp(args, "sws_flags=", 10)) {
// keep the 'flags=' part
fg->graph->scale_sws_opts = av_strdup(args+4);
fg->graph->scale_sws_opts = av_strdup(args);
}
args[0] = 0;
e = NULL;
while ((e = av_dict_get(ost->swr_opts, "", e,
AV_DICT_IGNORE_SUFFIX))) {
av_strlcatf(args, sizeof(args), "%s=%s:", e->key, e->value);
@ -1001,18 +1053,6 @@ int configure_filtergraph(FilterGraph *fg)
if (strlen(args))
args[strlen(args)-1] = 0;
av_opt_set(fg->graph, "aresample_swr_opts", args, 0);
args[0] = '\0';
while ((e = av_dict_get(fg->outputs[0]->ost->resample_opts, "", e,
AV_DICT_IGNORE_SUFFIX))) {
av_strlcatf(args, sizeof(args), "%s=%s:", e->key, e->value);
}
if (strlen(args))
args[strlen(args) - 1] = '\0';
e = av_dict_get(ost->encoder_opts, "threads", NULL, 0);
if (e)
av_opt_set(fg->graph, "threads", e->value, 0);
} else {
fg->graph->nb_threads = filter_complex_nbthreads;
}
@ -1067,6 +1107,8 @@ int configure_filtergraph(FilterGraph *fg)
if ((ret = avfilter_graph_config(fg->graph, NULL)) < 0)
goto fail;
fg->is_meta = graph_is_meta(fg->graph);
/* limit the lists of allowed formats to the ones selected, to
* make sure they stay the same if the filtergraph is reconfigured later */
for (i = 0; i < fg->nb_outputs; i++) {
@ -1079,7 +1121,10 @@ int configure_filtergraph(FilterGraph *fg)
ofilter->height = av_buffersink_get_h(sink);
ofilter->sample_rate = av_buffersink_get_sample_rate(sink);
ofilter->channel_layout = av_buffersink_get_channel_layout(sink);
av_channel_layout_uninit(&ofilter->ch_layout);
ret = av_buffersink_get_ch_layout(sink, &ofilter->ch_layout);
if (ret < 0)
goto fail;
}
fg->reconfiguration = 1;
@ -1101,9 +1146,8 @@ int configure_filtergraph(FilterGraph *fg)
}
for (i = 0; i < fg->nb_inputs; i++) {
while (av_fifo_size(fg->inputs[i]->frame_queue)) {
AVFrame *tmp;
av_fifo_generic_read(fg->inputs[i]->frame_queue, &tmp, sizeof(tmp), NULL);
while (av_fifo_read(fg->inputs[i]->frame_queue, &tmp, 1) >= 0) {
ret = av_buffersrc_add_frame(fg->inputs[i]->filter, tmp);
av_frame_free(&tmp);
if (ret < 0)
@ -1124,9 +1168,8 @@ int configure_filtergraph(FilterGraph *fg)
for (i = 0; i < fg->nb_inputs; i++) {
InputStream *ist = fg->inputs[i]->ist;
if (ist->sub2video.sub_queue && ist->sub2video.frame) {
while (av_fifo_size(ist->sub2video.sub_queue)) {
AVSubtitle tmp;
av_fifo_generic_read(ist->sub2video.sub_queue, &tmp, sizeof(tmp), NULL);
while (av_fifo_read(ist->sub2video.sub_queue, &tmp, 1) >= 0) {
sub2video_update(ist, INT64_MIN, &tmp);
avsubtitle_free(&tmp);
}
@ -1142,6 +1185,9 @@ fail:
int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *frame)
{
AVFrameSideData *sd;
int ret;
av_buffer_unref(&ifilter->hw_frames_ctx);
ifilter->format = frame->format;
@ -1151,8 +1197,14 @@ int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *frame)
ifilter->sample_aspect_ratio = frame->sample_aspect_ratio;
ifilter->sample_rate = frame->sample_rate;
ifilter->channels = frame->channels;
ifilter->channel_layout = frame->channel_layout;
ret = av_channel_layout_copy(&ifilter->ch_layout, &frame->ch_layout);
if (ret < 0)
return ret;
av_freep(&ifilter->displaymatrix);
sd = av_frame_get_side_data(frame, AV_FRAME_DATA_DISPLAYMATRIX);
if (sd)
ifilter->displaymatrix = av_memdup(sd->data, sizeof(int32_t) * 9);
if (frame->hw_frames_ctx) {
ifilter->hw_frames_ctx = av_buffer_ref(frame->hw_frames_ctx);

@ -1,4 +1,6 @@
/*
* copyright (c) 2018 Taner Sener ( tanersener gmail com )
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
@ -17,10 +19,17 @@
*/
/*
* CHANGES 12.2019
* - Concurrent execution support
* This file is the modified version of ffmpeg_hw.c file living in ffmpeg source code under the fftools folder. We
* manually update it each time we depend on a new ffmpeg version. Below you can see the list of changes applied
* by us to develop mobile-ffmpeg and later ffmpeg-kit libraries.
*
* mobile-ffmpeg / ffmpeg-kit changes by Taner Sener
*
* 12.2019
* --------------------------------------------------------
* - concurrent execution support ("__thread" specifier added to variables used by multiple threads)
*
* CHANGES 08.2018
* 08.2018
* --------------------------------------------------------
* - fftools_ prefix added to file name and parent header
*/
@ -102,6 +111,8 @@ static char *hw_device_default_name(enum AVHWDeviceType type)
int hw_device_init_from_string(const char *arg, HWDevice **dev_out)
{
// "type=name"
// "type=name,key=value,key2=value2"
// "type=name:device,key=value,key2=value2"
// "type:device,key=value,key2=value2"
// -> av_hwdevice_ctx_create()
@ -133,7 +144,7 @@ int hw_device_init_from_string(const char *arg, HWDevice **dev_out)
}
if (*p == '=') {
k = strcspn(p + 1, ":@");
k = strcspn(p + 1, ":@,");
name = av_strndup(p + 1, k);
if (!name) {
@ -199,6 +210,18 @@ int hw_device_init_from_string(const char *arg, HWDevice **dev_out)
src->device_ref, 0);
if (err < 0)
goto fail;
} else if (*p == ',') {
err = av_dict_parse_string(&options, p + 1, "=", ",", 0);
if (err < 0) {
errmsg = "failed to parse options";
goto invalid;
}
err = av_hwdevice_ctx_create(&device_ref, type,
NULL, options, 0);
if (err < 0)
goto fail;
} else {
errmsg = "parse error";
goto invalid;
@ -548,15 +571,21 @@ int hw_device_setup_for_filter(FilterGraph *fg)
HWDevice *dev;
int i;
// If the user has supplied exactly one hardware device then just
// give it straight to every filter for convenience. If more than
// one device is available then the user needs to pick one explcitly
// with the filter_hw_device option.
// Pick the last hardware device if the user doesn't pick the device for
// filters explicitly with the filter_hw_device option.
if (filter_hw_device)
dev = filter_hw_device;
else if (nb_hw_devices == 1)
dev = hw_devices[0];
else
else if (nb_hw_devices > 0) {
dev = hw_devices[nb_hw_devices - 1];
if (nb_hw_devices > 1)
av_log(NULL, AV_LOG_WARNING, "There are %d hardware devices. device "
"%s of type %s is picked for filters by default. Set hardware "
"device explicitly with the filter_hw_device option if device "
"%s is not usable for filters.\n",
nb_hw_devices, dev->name,
av_hwdevice_get_type_name(dev->type), dev->name);
} else
dev = NULL;
if (dev) {

@ -0,0 +1,331 @@
/*
* This file is part of FFmpeg.
* copyright (c) 2022 Taner Sener ( tanersener gmail com )
*
* 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 is the modified version of ffmpeg_mux.c file living in ffmpeg source code under the fftools folder. We
* manually update it each time we depend on a new ffmpeg version. Below you can see the list of changes applied
* by us to develop the ffmpeg-kit library.
*
* ffmpeg-kit changes by Taner Sener
*
* 09.2022
* --------------------------------------------------------
* - fftools_ prefix added to fftools headers
* - using main_ffmpeg_return_code instead of main_return_code
*/
#include <stdio.h>
#include <string.h>
#include "fftools_ffmpeg.h"
#include "libavutil/fifo.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/log.h"
#include "libavutil/mem.h"
#include "libavutil/timestamp.h"
#include "libavcodec/packet.h"
#include "libavformat/avformat.h"
#include "libavformat/avio.h"
static void close_all_output_streams(OutputStream *ost, OSTFinished this_stream, OSTFinished others)
{
int i;
for (i = 0; i < nb_output_streams; i++) {
OutputStream *ost2 = output_streams[i];
ost2->finished |= ost == ost2 ? this_stream : others;
}
}
void of_write_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost,
int unqueue)
{
AVFormatContext *s = of->ctx;
AVStream *st = ost->st;
int ret;
/*
* Audio encoders may split the packets -- #frames in != #packets out.
* But there is no reordering, so we can limit the number of output packets
* by simply dropping them here.
* Counting encoded video frames needs to be done separately because of
* reordering, see do_video_out().
* Do not count the packet when unqueued because it has been counted when queued.
*/
if (!(st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && ost->encoding_needed) && !unqueue) {
if (ost->frame_number >= ost->max_frames) {
av_packet_unref(pkt);
return;
}
ost->frame_number++;
}
if (!of->header_written) {
AVPacket *tmp_pkt;
/* the muxer is not initialized yet, buffer the packet */
if (!av_fifo_can_write(ost->muxing_queue)) {
size_t cur_size = av_fifo_can_read(ost->muxing_queue);
unsigned int are_we_over_size =
(ost->muxing_queue_data_size + pkt->size) > ost->muxing_queue_data_threshold;
size_t limit = are_we_over_size ? ost->max_muxing_queue_size : SIZE_MAX;
size_t new_size = FFMIN(2 * cur_size, limit);
if (new_size <= cur_size) {
av_log(NULL, AV_LOG_ERROR,
"Too many packets buffered for output stream %d:%d.\n",
ost->file_index, ost->st->index);
exit_program(1);
}
ret = av_fifo_grow2(ost->muxing_queue, new_size - cur_size);
if (ret < 0)
exit_program(1);
}
ret = av_packet_make_refcounted(pkt);
if (ret < 0)
exit_program(1);
tmp_pkt = av_packet_alloc();
if (!tmp_pkt)
exit_program(1);
av_packet_move_ref(tmp_pkt, pkt);
ost->muxing_queue_data_size += tmp_pkt->size;
av_fifo_write(ost->muxing_queue, &tmp_pkt, 1);
return;
}
if ((st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && ost->vsync_method == VSYNC_DROP) ||
(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && audio_sync_method < 0))
pkt->pts = pkt->dts = AV_NOPTS_VALUE;
if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
if (ost->frame_rate.num && ost->is_cfr) {
if (pkt->duration > 0)
av_log(NULL, AV_LOG_WARNING, "Overriding packet duration by frame rate, this should not happen\n");
pkt->duration = av_rescale_q(1, av_inv_q(ost->frame_rate),
ost->mux_timebase);
}
}
av_packet_rescale_ts(pkt, ost->mux_timebase, ost->st->time_base);
if (!(s->oformat->flags & AVFMT_NOTIMESTAMPS)) {
if (pkt->dts != AV_NOPTS_VALUE &&
pkt->pts != AV_NOPTS_VALUE &&
pkt->dts > pkt->pts) {
av_log(s, AV_LOG_WARNING, "Invalid DTS: %"PRId64" PTS: %"PRId64" in output stream %d:%d, replacing by guess\n",
pkt->dts, pkt->pts,
ost->file_index, ost->st->index);
pkt->pts =
pkt->dts = pkt->pts + pkt->dts + ost->last_mux_dts + 1
- FFMIN3(pkt->pts, pkt->dts, ost->last_mux_dts + 1)
- FFMAX3(pkt->pts, pkt->dts, ost->last_mux_dts + 1);
}
if ((st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO || st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) &&
pkt->dts != AV_NOPTS_VALUE &&
ost->last_mux_dts != AV_NOPTS_VALUE) {
int64_t max = ost->last_mux_dts + !(s->oformat->flags & AVFMT_TS_NONSTRICT);
if (pkt->dts < max) {
int loglevel = max - pkt->dts > 2 || st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO ? AV_LOG_WARNING : AV_LOG_DEBUG;
if (exit_on_error)
loglevel = AV_LOG_ERROR;
av_log(s, loglevel, "Non-monotonous DTS in output stream "
"%d:%d; previous: %"PRId64", current: %"PRId64"; ",
ost->file_index, ost->st->index, ost->last_mux_dts, pkt->dts);
if (exit_on_error) {
av_log(NULL, AV_LOG_FATAL, "aborting.\n");
exit_program(1);
}
av_log(s, loglevel, "changing to %"PRId64". This may result "
"in incorrect timestamps in the output file.\n",
max);
if (pkt->pts >= pkt->dts)
pkt->pts = FFMAX(pkt->pts, max);
pkt->dts = max;
}
}
}
ost->last_mux_dts = pkt->dts;
ost->data_size += pkt->size;
ost->packets_written++;
pkt->stream_index = ost->index;
if (debug_ts) {
av_log(NULL, AV_LOG_INFO, "muxer <- type:%s "
"pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s duration:%s duration_time:%s size:%d\n",
av_get_media_type_string(ost->enc_ctx->codec_type),
av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &ost->st->time_base),
av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &ost->st->time_base),
av_ts2str(pkt->duration), av_ts2timestr(pkt->duration, &ost->st->time_base),
pkt->size
);
}
ret = av_interleaved_write_frame(s, pkt);
if (ret < 0) {
print_error("av_interleaved_write_frame()", ret);
main_ffmpeg_return_code = 1;
close_all_output_streams(ost, MUXER_FINISHED | ENCODER_FINISHED, ENCODER_FINISHED);
}
}
static int print_sdp(void)
{
char sdp[16384];
int i;
int j, ret;
AVIOContext *sdp_pb;
AVFormatContext **avc;
for (i = 0; i < nb_output_files; i++) {
if (!output_files[i]->header_written)
return 0;
}
avc = av_malloc_array(nb_output_files, sizeof(*avc));
if (!avc)
exit_program(1);
for (i = 0, j = 0; i < nb_output_files; i++) {
if (!strcmp(output_files[i]->ctx->oformat->name, "rtp")) {
avc[j] = output_files[i]->ctx;
j++;
}
}
if (!j) {
av_log(NULL, AV_LOG_ERROR, "No output streams in the SDP.\n");
ret = AVERROR(EINVAL);
goto fail;
}
ret = av_sdp_create(avc, j, sdp, sizeof(sdp));
if (ret < 0)
goto fail;
if (!sdp_filename) {
printf("SDP:\n%s\n", sdp);
fflush(stdout);
} else {
ret = avio_open2(&sdp_pb, sdp_filename, AVIO_FLAG_WRITE, &int_cb, NULL);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Failed to open sdp file '%s'\n", sdp_filename);
goto fail;
}
avio_print(sdp_pb, sdp);
avio_closep(&sdp_pb);
av_freep(&sdp_filename);
}
fail:
av_freep(&avc);
return ret;
}
/* open the muxer when all the streams are initialized */
int of_check_init(OutputFile *of)
{
int ret, i;
for (i = 0; i < of->ctx->nb_streams; i++) {
OutputStream *ost = output_streams[of->ost_index + i];
if (!ost->initialized)
return 0;
}
ret = avformat_write_header(of->ctx, &of->opts);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR,
"Could not write header for output file #%d "
"(incorrect codec parameters ?): %s\n",
of->index, av_err2str(ret));
return ret;
}
//assert_avoptions(of->opts);
of->header_written = 1;
av_dump_format(of->ctx, of->index, of->ctx->url, 1);
nb_output_dumped++;
if (sdp_filename || want_sdp) {
ret = print_sdp();
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Error writing the SDP.\n");
return ret;
}
}
/* flush the muxing queues */
for (i = 0; i < of->ctx->nb_streams; i++) {
OutputStream *ost = output_streams[of->ost_index + i];
AVPacket *pkt;
/* try to improve muxing time_base (only possible if nothing has been written yet) */
if (!av_fifo_can_read(ost->muxing_queue))
ost->mux_timebase = ost->st->time_base;
while (av_fifo_read(ost->muxing_queue, &pkt, 1) >= 0) {
ost->muxing_queue_data_size -= pkt->size;
of_write_packet(of, pkt, ost, 1);
av_packet_free(&pkt);
}
}
return 0;
}
int of_write_trailer(OutputFile *of)
{
int ret;
if (!of->header_written) {
av_log(NULL, AV_LOG_ERROR,
"Nothing was written into output file %d (%s), because "
"at least one of its streams received no packets.\n",
of->index, of->ctx->url);
return AVERROR(EINVAL);
}
ret = av_write_trailer(of->ctx);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Error writing trailer of %s: %s\n", of->ctx->url, av_err2str(ret));
return ret;
}
return 0;
}
void of_close(OutputFile **pof)
{
OutputFile *of = *pof;
AVFormatContext *s;
if (!of)
return;
s = of->ctx;
if (s && s->oformat && !(s->oformat->flags & AVFMT_NOFILE))
avio_closep(&s->pb);
avformat_free_context(s);
av_dict_free(&of->opts);
av_freep(pof);
}

@ -0,0 +1,79 @@
/*
* 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 is the modified version of fopen_utf8.h file living in ffmpeg source code under the fftools folder. We
* manually update it each time we depend on a new ffmpeg version. Below you can see the list of changes applied
* by us to develop the ffmpeg-kit library.
*
* ffmpeg-kit changes by Taner Sener
*/
#ifndef FFTOOLS_FOPEN_UTF8_H
#define FFTOOLS_FOPEN_UTF8_H
#include <stdio.h>
/* The fopen_utf8 function here is essentially equivalent to avpriv_fopen_utf8,
* except that it doesn't set O_CLOEXEC, and that it isn't exported
* from a different library. (On Windows, each DLL might use a different
* CRT, and FILE* handles can't be shared across them.) */
#ifdef _WIN32
#include "libavutil/wchar_filename.h"
static inline FILE *fopen_utf8(const char *path_utf8, const char *mode)
{
wchar_t *path_w, *mode_w;
FILE *f;
/* convert UTF-8 to wide chars */
if (get_extended_win32_path(path_utf8, &path_w)) /* This sets errno on error. */
return NULL;
if (!path_w)
goto fallback;
if (utf8towchar(mode, &mode_w))
return NULL;
if (!mode_w) {
/* If failing to interpret the mode string as utf8, it is an invalid
* parameter. */
av_freep(&path_w);
errno = EINVAL;
return NULL;
}
f = _wfopen(path_w, mode_w);
av_freep(&path_w);
av_freep(&mode_w);
return f;
fallback:
/* path may be in CP_ACP */
return fopen(path_utf8, mode);
}
#else
static inline FILE *fopen_utf8(const char *path, const char *mode)
{
return fopen(path, mode);
}
#endif
#endif /* FFTOOLS_FOPEN_UTF8_H */

@ -0,0 +1,202 @@
/*
* Option handlers shared between the tools.
* copyright (c) 2022 Taner Sener ( tanersener 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
*/
/*
* This file is the modified version of opt_common.h file living in ffmpeg source code under the fftools folder. We
* manually update it each time we depend on a new ffmpeg version. Below you can see the list of changes applied
* by us to develop the ffmpeg-kit library.
*
* ffmpeg-kit changes by Taner Sener
*
* 09.2022
* --------------------------------------------------------
* - CMDUTILS_COMMON_OPTIONS and CMDUTILS_COMMON_OPTIONS_AVDEVICE defines dropped
* - fftools_ prefix added to fftools headers
*/
#ifndef FFTOOLS_OPT_COMMON_H
#define FFTOOLS_OPT_COMMON_H
#include "config.h"
#include "fftools_cmdutils.h"
#if CONFIG_AVDEVICE
/**
* Print a listing containing autodetected sinks of the output device.
* Device name with options may be passed as an argument to limit results.
*/
int show_sinks(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing autodetected sources of the input device.
* Device name with options may be passed as an argument to limit results.
*/
int show_sources(void *optctx, const char *opt, const char *arg);
#endif
/**
* Print the license of the program to stdout. The license depends on
* the license of the libraries compiled into the program.
* This option processing function does not utilize the arguments.
*/
int show_license(void *optctx, const char *opt, const char *arg);
/**
* Generic -h handler common to all fftools.
*/
int show_help(void *optctx, const char *opt, const char *arg);
/**
* Print the version of the program to stdout. The version message
* depends on the current versions of the repository and of the libav*
* libraries.
* This option processing function does not utilize the arguments.
*/
int show_version(void *optctx, const char *opt, const char *arg);
/**
* Print the build configuration of the program to stdout. The contents
* depend on the definition of FFMPEG_CONFIGURATION.
* This option processing function does not utilize the arguments.
*/
int show_buildconf(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the formats supported by the
* program (including devices).
* This option processing function does not utilize the arguments.
*/
int show_formats(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the muxers supported by the
* program (including devices).
* This option processing function does not utilize the arguments.
*/
int show_muxers(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the demuxer supported by the
* program (including devices).
* This option processing function does not utilize the arguments.
*/
int show_demuxers(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the devices supported by the
* program.
* This option processing function does not utilize the arguments.
*/
int show_devices(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the codecs supported by the
* program.
* This option processing function does not utilize the arguments.
*/
int show_codecs(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the decoders supported by the
* program.
*/
int show_decoders(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the encoders supported by the
* program.
*/
int show_encoders(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the bit stream filters supported by the
* program.
* This option processing function does not utilize the arguments.
*/
int show_bsfs(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the protocols supported by the
* program.
* This option processing function does not utilize the arguments.
*/
int show_protocols(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the filters supported by the
* program.
* This option processing function does not utilize the arguments.
*/
int show_filters(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the pixel formats supported by the
* program.
* This option processing function does not utilize the arguments.
*/
int show_pix_fmts(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the standard channel layouts supported by
* the program.
* This option processing function does not utilize the arguments.
*/
int show_layouts(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the sample formats supported by the
* program.
*/
int show_sample_fmts(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all supported stream dispositions.
*/
int show_dispositions(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the color names and values recognized
* by the program.
*/
int show_colors(void *optctx, const char *opt, const char *arg);
/**
* Set the libav* libraries log level.
*/
int opt_loglevel(void *optctx, const char *opt, const char *arg);
int opt_report(void *optctx, const char *opt, const char *arg);
int init_report(const char *env, FILE **file);
int opt_max_alloc(void *optctx, const char *opt, const char *arg);
/**
* Override the cpuflags.
*/
int opt_cpuflags(void *optctx, const char *opt, const char *arg);
/**
* Override the cpucount.
*/
int opt_cpucount(void *optctx, const char *opt, const char *arg);
#endif /* FFTOOLS_OPT_COMMON_H */

@ -115,7 +115,7 @@ public abstract class AbstractSession implements Session {
* @param logCallback session specific log callback
* @param logRedirectionStrategy session specific log redirection strategy
*/
public AbstractSession(final String[] arguments,
protected AbstractSession(final String[] arguments,
final LogCallback logCallback,
final LogRedirectionStrategy logRedirectionStrategy) {
this.sessionId = sessionIdGenerator.getAndIncrement();

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Taner Sener
* Copyright (c) 2021-2022 Taner Sener
*
* This file is part of FFmpegKit.
*
@ -63,7 +63,7 @@ public class Chapter {
}
public JSONObject getTags() {
return getProperties(KEY_TAGS);
return getProperty(KEY_TAGS);
}
/**
@ -73,13 +73,13 @@ public class Chapter {
* @return chapter property as string or null if the key is not found
*/
public String getStringProperty(final String key) {
JSONObject chapterProperties = getAllProperties();
if (chapterProperties == null) {
JSONObject allProperties = getAllProperties();
if (allProperties == null) {
return null;
}
if (chapterProperties.has(key)) {
return chapterProperties.optString(key);
if (allProperties.has(key)) {
return allProperties.optString(key);
} else {
return null;
}
@ -92,31 +92,31 @@ public class Chapter {
* @return chapter property as Long or null if the key is not found
*/
public Long getNumberProperty(String key) {
JSONObject chapterProperties = getAllProperties();
if (chapterProperties == null) {
JSONObject allProperties = getAllProperties();
if (allProperties == null) {
return null;
}
if (chapterProperties.has(key)) {
return chapterProperties.optLong(key);
if (allProperties.has(key)) {
return allProperties.optLong(key);
} else {
return null;
}
}
/**
* Returns the chapter properties associated with the key.
* Returns the chapter property associated with the key.
*
* @param key properties key
* @return chapter properties as a JSONObject or null if the key is not found
* @param key property key
* @return chapter property as a JSONObject or null if the key is not found
*/
public JSONObject getProperties(String key) {
JSONObject chapterProperties = getAllProperties();
if (chapterProperties == null) {
public JSONObject getProperty(String key) {
JSONObject allProperties = getAllProperties();
if (allProperties == null) {
return null;
}
return chapterProperties.optJSONObject(key);
return allProperties.optJSONObject(key);
}
/**

@ -55,7 +55,7 @@ public class FFmpegKit {
* @return FFmpeg session created for this execution
*/
public static FFmpegSession executeWithArguments(final String[] arguments) {
final FFmpegSession session = new FFmpegSession(arguments);
final FFmpegSession session = FFmpegSession.create(arguments);
FFmpegKitConfig.ffmpegExecute(session);
@ -75,7 +75,7 @@ public class FFmpegKit {
*/
public static FFmpegSession executeWithArgumentsAsync(final String[] arguments,
final FFmpegSessionCompleteCallback completeCallback) {
final FFmpegSession session = new FFmpegSession(arguments, completeCallback);
final FFmpegSession session = FFmpegSession.create(arguments, completeCallback);
FFmpegKitConfig.asyncFFmpegExecute(session);
@ -99,7 +99,7 @@ public class FFmpegKit {
final FFmpegSessionCompleteCallback completeCallback,
final LogCallback logCallback,
final StatisticsCallback statisticsCallback) {
final FFmpegSession session = new FFmpegSession(arguments, completeCallback, logCallback, statisticsCallback);
final FFmpegSession session = FFmpegSession.create(arguments, completeCallback, logCallback, statisticsCallback);
FFmpegKitConfig.asyncFFmpegExecute(session);
@ -121,7 +121,7 @@ public class FFmpegKit {
public static FFmpegSession executeWithArgumentsAsync(final String[] arguments,
final FFmpegSessionCompleteCallback completeCallback,
final ExecutorService executorService) {
final FFmpegSession session = new FFmpegSession(arguments, completeCallback);
final FFmpegSession session = FFmpegSession.create(arguments, completeCallback);
FFmpegKitConfig.asyncFFmpegExecute(session, executorService);
@ -148,7 +148,7 @@ public class FFmpegKit {
final LogCallback logCallback,
final StatisticsCallback statisticsCallback,
final ExecutorService executorService) {
final FFmpegSession session = new FFmpegSession(arguments, completeCallback, logCallback, statisticsCallback);
final FFmpegSession session = FFmpegSession.create(arguments, completeCallback, logCallback, statisticsCallback);
FFmpegKitConfig.asyncFFmpegExecute(session, executorService);
@ -224,7 +224,7 @@ public class FFmpegKit {
public static FFmpegSession executeAsync(final String command,
final FFmpegSessionCompleteCallback completeCallback,
final ExecutorService executorService) {
final FFmpegSession session = new FFmpegSession(FFmpegKitConfig.parseArguments(command), completeCallback);
final FFmpegSession session = FFmpegSession.create(FFmpegKitConfig.parseArguments(command), completeCallback);
FFmpegKitConfig.asyncFFmpegExecute(session, executorService);
@ -252,7 +252,7 @@ public class FFmpegKit {
final LogCallback logCallback,
final StatisticsCallback statisticsCallback,
final ExecutorService executorService) {
final FFmpegSession session = new FFmpegSession(FFmpegKitConfig.parseArguments(command), completeCallback, logCallback, statisticsCallback);
final FFmpegSession session = FFmpegSession.create(FFmpegKitConfig.parseArguments(command), completeCallback, logCallback, statisticsCallback);
FFmpegKitConfig.asyncFFmpegExecute(session, executorService);

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2021 Taner Sener
* Copyright (c) 2018-2022 Taner Sener
*
* This file is part of FFmpegKit.
*
@ -455,7 +455,7 @@ public class FFmpegKitConfig {
fontConfigBuilder.append("</dir>\n");
}
fontConfigBuilder.append(fontNameMappingBlock);
fontConfigBuilder.append("</fontconfig>");
fontConfigBuilder.append("</fontconfig>\n");
final AtomicReference<FileOutputStream> reference = new AtomicReference<>();
try {
@ -696,7 +696,15 @@ public class FFmpegKitConfig {
final ReturnCode returnCode = new ReturnCode(returnCodeValue);
mediaInformationSession.complete(returnCode);
if (returnCode.isValueSuccess()) {
MediaInformation mediaInformation = MediaInformationJsonParser.fromWithError(mediaInformationSession.getAllLogsAsString(waitTimeout));
List<Log> allLogs = mediaInformationSession.getAllLogs(waitTimeout);
final StringBuilder ffprobeJsonOutput = new StringBuilder();
for (int i = 0, allLogsSize = allLogs.size(); i < allLogsSize; i++) {
Log log = allLogs.get(i);
if (log.getLevel() == Level.AV_LOG_STDERR) {
ffprobeJsonOutput.append(log.getMessage());
}
}
MediaInformation mediaInformation = MediaInformationJsonParser.fromWithError(ffprobeJsonOutput.toString());
mediaInformationSession.setMediaInformation(mediaInformation);
}
} catch (final Exception e) {
@ -1086,6 +1094,22 @@ public class FFmpegKitConfig {
throw new IllegalArgumentException("Session history size must not exceed the hard limit!");
} else if (sessionHistorySize > 0) {
FFmpegKitConfig.sessionHistorySize = sessionHistorySize;
deleteExpiredSessions();
}
}
/**
* Deletes expired sessions.
*/
private static void deleteExpiredSessions() {
while (sessionHistoryList.size() > sessionHistorySize) {
try {
Session expiredSession = sessionHistoryList.remove(0);
if (expiredSession != null) {
sessionHistoryMap.remove(expiredSession.getSessionId());
}
} catch (final IndexOutOfBoundsException ignored) {
}
}
}
@ -1099,18 +1123,13 @@ public class FFmpegKitConfig {
/*
* ASYNC SESSIONS CALL THIS METHOD TWICE
* THIS CHECK PREVENTS ADDING THE SAME SESSION TWICE
* THIS CHECK PREVENTS ADDING THE SAME SESSION AGAIN
*/
final boolean sessionAlreadyAdded = sessionHistoryMap.containsKey(session.getSessionId());
if (!sessionAlreadyAdded) {
sessionHistoryMap.put(session.getSessionId(), session);
sessionHistoryList.add(session);
if (sessionHistoryList.size() > sessionHistorySize) {
try {
sessionHistoryList.remove(0);
} catch (final IndexOutOfBoundsException ignored) {
}
}
deleteExpiredSessions();
}
}
}

@ -51,9 +51,10 @@ public class FFmpegSession extends AbstractSession implements Session {
* Builds a new FFmpeg session.
*
* @param arguments command arguments
* @return created session
*/
public FFmpegSession(final String[] arguments) {
this(arguments, null);
public static FFmpegSession create(final String[] arguments) {
return new FFmpegSession(arguments, null, null, null, FFmpegKitConfig.getLogRedirectionStrategy());
}
/**
@ -61,9 +62,10 @@ public class FFmpegSession extends AbstractSession implements Session {
*
* @param arguments command arguments
* @param completeCallback session specific complete callback
* @return created session
*/
public FFmpegSession(final String[] arguments, final FFmpegSessionCompleteCallback completeCallback) {
this(arguments, completeCallback, null, null);
public static FFmpegSession create(final String[] arguments, final FFmpegSessionCompleteCallback completeCallback) {
return new FFmpegSession(arguments, completeCallback, null, null, FFmpegKitConfig.getLogRedirectionStrategy());
}
/**
@ -73,12 +75,13 @@ public class FFmpegSession extends AbstractSession implements Session {
* @param completeCallback session specific complete callback
* @param logCallback session specific log callback
* @param statisticsCallback session specific statistics callback
* @return created session
*/
public FFmpegSession(final String[] arguments,
public static FFmpegSession create(final String[] arguments,
final FFmpegSessionCompleteCallback completeCallback,
final LogCallback logCallback,
final StatisticsCallback statisticsCallback) {
this(arguments, completeCallback, logCallback, statisticsCallback, FFmpegKitConfig.getLogRedirectionStrategy());
return new FFmpegSession(arguments, completeCallback, logCallback, statisticsCallback, FFmpegKitConfig.getLogRedirectionStrategy());
}
/**
@ -89,8 +92,26 @@ public class FFmpegSession extends AbstractSession implements Session {
* @param logCallback session specific log callback
* @param statisticsCallback session specific statistics callback
* @param logRedirectionStrategy session specific log redirection strategy
* @return created session
*/
public FFmpegSession(final String[] arguments,
public static FFmpegSession create(final String[] arguments,
final FFmpegSessionCompleteCallback completeCallback,
final LogCallback logCallback,
final StatisticsCallback statisticsCallback,
final LogRedirectionStrategy logRedirectionStrategy) {
return new FFmpegSession(arguments, completeCallback, logCallback, statisticsCallback, logRedirectionStrategy);
}
/**
* Builds a new FFmpeg session.
*
* @param arguments command arguments
* @param completeCallback session specific complete callback
* @param logCallback session specific log callback
* @param statisticsCallback session specific statistics callback
* @param logRedirectionStrategy session specific log redirection strategy
*/
private FFmpegSession(final String[] arguments,
final FFmpegSessionCompleteCallback completeCallback,
final LogCallback logCallback,
final StatisticsCallback statisticsCallback,

@ -69,7 +69,7 @@ public class FFprobeKit {
* @return FFprobe session created for this execution
*/
public static FFprobeSession executeWithArguments(final String[] arguments) {
final FFprobeSession session = new FFprobeSession(arguments);
final FFprobeSession session = FFprobeSession.create(arguments);
FFmpegKitConfig.ffprobeExecute(session);
@ -89,7 +89,7 @@ public class FFprobeKit {
*/
public static FFprobeSession executeWithArgumentsAsync(final String[] arguments,
final FFprobeSessionCompleteCallback completeCallback) {
final FFprobeSession session = new FFprobeSession(arguments, completeCallback);
final FFprobeSession session = FFprobeSession.create(arguments, completeCallback);
FFmpegKitConfig.asyncFFprobeExecute(session);
@ -111,7 +111,7 @@ public class FFprobeKit {
public static FFprobeSession executeWithArgumentsAsync(final String[] arguments,
final FFprobeSessionCompleteCallback completeCallback,
final LogCallback logCallback) {
final FFprobeSession session = new FFprobeSession(arguments, completeCallback, logCallback);
final FFprobeSession session = FFprobeSession.create(arguments, completeCallback, logCallback);
FFmpegKitConfig.asyncFFprobeExecute(session);
@ -133,7 +133,7 @@ public class FFprobeKit {
public static FFprobeSession executeWithArgumentsAsync(final String[] arguments,
final FFprobeSessionCompleteCallback completeCallback,
final ExecutorService executorService) {
final FFprobeSession session = new FFprobeSession(arguments, completeCallback);
final FFprobeSession session = FFprobeSession.create(arguments, completeCallback);
FFmpegKitConfig.asyncFFprobeExecute(session, executorService);
@ -157,7 +157,7 @@ public class FFprobeKit {
final FFprobeSessionCompleteCallback completeCallback,
final LogCallback logCallback,
final ExecutorService executorService) {
final FFprobeSession session = new FFprobeSession(arguments, completeCallback, logCallback);
final FFprobeSession session = FFprobeSession.create(arguments, completeCallback, logCallback);
FFmpegKitConfig.asyncFFprobeExecute(session, executorService);
@ -231,7 +231,7 @@ public class FFprobeKit {
public static FFprobeSession executeAsync(final String command,
final FFprobeSessionCompleteCallback completeCallback,
final ExecutorService executorService) {
final FFprobeSession session = new FFprobeSession(FFmpegKitConfig.parseArguments(command), completeCallback);
final FFprobeSession session = FFprobeSession.create(FFmpegKitConfig.parseArguments(command), completeCallback);
FFmpegKitConfig.asyncFFprobeExecute(session, executorService);
@ -257,7 +257,7 @@ public class FFprobeKit {
final FFprobeSessionCompleteCallback completeCallback,
final LogCallback logCallback,
final ExecutorService executorService) {
final FFprobeSession session = new FFprobeSession(FFmpegKitConfig.parseArguments(command), completeCallback, logCallback);
final FFprobeSession session = FFprobeSession.create(FFmpegKitConfig.parseArguments(command), completeCallback, logCallback);
FFmpegKitConfig.asyncFFprobeExecute(session, executorService);
@ -271,7 +271,7 @@ public class FFprobeKit {
* @return media information session created for this execution
*/
public static MediaInformationSession getMediaInformation(final String path) {
final MediaInformationSession session = new MediaInformationSession(defaultGetMediaInformationCommandArguments(path));
final MediaInformationSession session = MediaInformationSession.create(defaultGetMediaInformationCommandArguments(path));
FFmpegKitConfig.getMediaInformationExecute(session, AbstractSession.DEFAULT_TIMEOUT_FOR_ASYNCHRONOUS_MESSAGES_IN_TRANSMIT);
@ -287,7 +287,7 @@ public class FFprobeKit {
*/
public static MediaInformationSession getMediaInformation(final String path,
final int waitTimeout) {
final MediaInformationSession session = new MediaInformationSession(defaultGetMediaInformationCommandArguments(path));
final MediaInformationSession session = MediaInformationSession.create(defaultGetMediaInformationCommandArguments(path));
FFmpegKitConfig.getMediaInformationExecute(session, waitTimeout);
@ -308,7 +308,7 @@ public class FFprobeKit {
*/
public static MediaInformationSession getMediaInformationAsync(final String path,
final MediaInformationSessionCompleteCallback completeCallback) {
final MediaInformationSession session = new MediaInformationSession(defaultGetMediaInformationCommandArguments(path), completeCallback);
final MediaInformationSession session = MediaInformationSession.create(defaultGetMediaInformationCommandArguments(path), completeCallback);
FFmpegKitConfig.asyncGetMediaInformationExecute(session, AbstractSession.DEFAULT_TIMEOUT_FOR_ASYNCHRONOUS_MESSAGES_IN_TRANSMIT);
@ -333,7 +333,7 @@ public class FFprobeKit {
final MediaInformationSessionCompleteCallback completeCallback,
final LogCallback logCallback,
final int waitTimeout) {
final MediaInformationSession session = new MediaInformationSession(defaultGetMediaInformationCommandArguments(path), completeCallback, logCallback);
final MediaInformationSession session = MediaInformationSession.create(defaultGetMediaInformationCommandArguments(path), completeCallback, logCallback);
FFmpegKitConfig.asyncGetMediaInformationExecute(session, waitTimeout);
@ -356,7 +356,7 @@ public class FFprobeKit {
public static MediaInformationSession getMediaInformationAsync(final String path,
final MediaInformationSessionCompleteCallback completeCallback,
final ExecutorService executorService) {
final MediaInformationSession session = new MediaInformationSession(defaultGetMediaInformationCommandArguments(path), completeCallback);
final MediaInformationSession session = MediaInformationSession.create(defaultGetMediaInformationCommandArguments(path), completeCallback);
FFmpegKitConfig.asyncGetMediaInformationExecute(session, executorService, AbstractSession.DEFAULT_TIMEOUT_FOR_ASYNCHRONOUS_MESSAGES_IN_TRANSMIT);
@ -383,7 +383,7 @@ public class FFprobeKit {
final LogCallback logCallback,
final ExecutorService executorService,
final int waitTimeout) {
final MediaInformationSession session = new MediaInformationSession(defaultGetMediaInformationCommandArguments(path), completeCallback, logCallback);
final MediaInformationSession session = MediaInformationSession.create(defaultGetMediaInformationCommandArguments(path), completeCallback, logCallback);
FFmpegKitConfig.asyncGetMediaInformationExecute(session, executorService, waitTimeout);
@ -397,7 +397,7 @@ public class FFprobeKit {
* @return media information session created for this execution
*/
public static MediaInformationSession getMediaInformationFromCommand(final String command) {
final MediaInformationSession session = new MediaInformationSession(FFmpegKitConfig.parseArguments(command));
final MediaInformationSession session = MediaInformationSession.create(FFmpegKitConfig.parseArguments(command));
FFmpegKitConfig.getMediaInformationExecute(session, AbstractSession.DEFAULT_TIMEOUT_FOR_ASYNCHRONOUS_MESSAGES_IN_TRANSMIT);
@ -447,7 +447,7 @@ public class FFprobeKit {
final MediaInformationSessionCompleteCallback completeCallback,
final LogCallback logCallback,
final int waitTimeout) {
final MediaInformationSession session = new MediaInformationSession(arguments, completeCallback, logCallback);
final MediaInformationSession session = MediaInformationSession.create(arguments, completeCallback, logCallback);
FFmpegKitConfig.asyncGetMediaInformationExecute(session, waitTimeout);

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020-2021 Taner Sener
* Copyright (c) 2020-2022 Taner Sener
*
* This file is part of FFmpegKit.
*
@ -33,9 +33,10 @@ public class FFprobeSession extends AbstractSession implements Session {
* Builds a new FFprobe session.
*
* @param arguments command arguments
* @return created session
*/
public FFprobeSession(final String[] arguments) {
this(arguments, null);
public static FFprobeSession create(final String[] arguments) {
return new FFprobeSession(arguments, null, null, FFmpegKitConfig.getLogRedirectionStrategy());
}
/**
@ -43,9 +44,10 @@ public class FFprobeSession extends AbstractSession implements Session {
*
* @param arguments command arguments
* @param completeCallback session specific complete callback
* @return created session
*/
public FFprobeSession(final String[] arguments, final FFprobeSessionCompleteCallback completeCallback) {
this(arguments, completeCallback, null);
public static FFprobeSession create(final String[] arguments, final FFprobeSessionCompleteCallback completeCallback) {
return new FFprobeSession(arguments, completeCallback, null, FFmpegKitConfig.getLogRedirectionStrategy());
}
/**
@ -54,11 +56,12 @@ public class FFprobeSession extends AbstractSession implements Session {
* @param arguments command arguments
* @param completeCallback session specific complete callback
* @param logCallback session specific log callback
* @return created session
*/
public FFprobeSession(final String[] arguments,
public static FFprobeSession create(final String[] arguments,
final FFprobeSessionCompleteCallback completeCallback,
final LogCallback logCallback) {
this(arguments, completeCallback, logCallback, FFmpegKitConfig.getLogRedirectionStrategy());
return new FFprobeSession(arguments, completeCallback, logCallback, FFmpegKitConfig.getLogRedirectionStrategy());
}
/**
@ -68,8 +71,24 @@ public class FFprobeSession extends AbstractSession implements Session {
* @param completeCallback session specific complete callback
* @param logCallback session specific log callback
* @param logRedirectionStrategy session specific log redirection strategy
* @return created session
*/
public FFprobeSession(final String[] arguments,
public static FFprobeSession create(final String[] arguments,
final FFprobeSessionCompleteCallback completeCallback,
final LogCallback logCallback,
final LogRedirectionStrategy logRedirectionStrategy) {
return new FFprobeSession(arguments, completeCallback, logCallback, logRedirectionStrategy);
}
/**
* Builds a new FFprobe session.
*
* @param arguments command arguments
* @param completeCallback session specific complete callback
* @param logCallback session specific log callback
* @param logRedirectionStrategy session specific log redirection strategy
*/
private FFprobeSession(final String[] arguments,
final FFprobeSessionCompleteCallback completeCallback,
final LogCallback logCallback,
final LogRedirectionStrategy logRedirectionStrategy) {

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2021 Taner Sener
* Copyright (c) 2018-2022 Taner Sener
*
* This file is part of FFmpegKit.
*
@ -29,7 +29,7 @@ import java.util.List;
public class MediaInformation {
/* COMMON KEYS */
public static final String KEY_MEDIA_PROPERTIES = "format";
public static final String KEY_FORMAT_PROPERTIES = "format";
public static final String KEY_FILENAME = "filename";
public static final String KEY_FORMAT = "format_name";
public static final String KEY_FORMAT_LONG = "format_long_name";
@ -66,7 +66,7 @@ public class MediaInformation {
* @return media file name
*/
public String getFilename() {
return getStringProperty(KEY_FILENAME);
return getStringFormatProperty(KEY_FILENAME);
}
/**
@ -75,7 +75,7 @@ public class MediaInformation {
* @return media format
*/
public String getFormat() {
return getStringProperty(KEY_FORMAT);
return getStringFormatProperty(KEY_FORMAT);
}
/**
@ -84,16 +84,16 @@ public class MediaInformation {
* @return media long format
*/
public String getLongFormat() {
return getStringProperty(KEY_FORMAT_LONG);
return getStringFormatProperty(KEY_FORMAT_LONG);
}
/**
* Returns duration.
*
* @return media duration in milliseconds
* @return media duration in "seconds.microseconds" format
*/
public String getDuration() {
return getStringProperty(KEY_DURATION);
return getStringFormatProperty(KEY_DURATION);
}
/**
@ -102,7 +102,7 @@ public class MediaInformation {
* @return media start time in milliseconds
*/
public String getStartTime() {
return getStringProperty(KEY_START_TIME);
return getStringFormatProperty(KEY_START_TIME);
}
/**
@ -111,7 +111,7 @@ public class MediaInformation {
* @return media size in bytes
*/
public String getSize() {
return getStringProperty(KEY_SIZE);
return getStringFormatProperty(KEY_SIZE);
}
/**
@ -120,16 +120,16 @@ public class MediaInformation {
* @return media bitrate in kb/s
*/
public String getBitrate() {
return getStringProperty(KEY_BIT_RATE);
return getStringFormatProperty(KEY_BIT_RATE);
}
/**
* Returns all tags.
*
* @return tags dictionary
* @return tags as a JSONObject
*/
public JSONObject getTags() {
return getProperties(KEY_TAGS);
return getFormatProperty(KEY_TAGS);
}
/**
@ -151,65 +151,118 @@ public class MediaInformation {
}
/**
* Returns the media property associated with the key.
* Returns the property associated with the key.
*
* @param key property key
* @return media property as string or null if the key is not found
* @return property as string or null if the key is not found
*/
public String getStringProperty(final String key) {
JSONObject mediaProperties = getMediaProperties();
if (mediaProperties == null) {
JSONObject allProperties = getAllProperties();
if (allProperties == null) {
return null;
}
if (mediaProperties.has(key)) {
return mediaProperties.optString(key);
if (allProperties.has(key)) {
return allProperties.optString(key);
} else {
return null;
}
}
/**
* Returns the media property associated with the key.
* Returns the property associated with the key.
*
* @param key property key
* @return media property as Long or null if the key is not found
* @return property as Long or null if the key is not found
*/
public Long getNumberProperty(String key) {
JSONObject mediaProperties = getMediaProperties();
if (mediaProperties == null) {
JSONObject allProperties = getAllProperties();
if (allProperties == null) {
return null;
}
if (mediaProperties.has(key)) {
return mediaProperties.optLong(key);
if (allProperties.has(key)) {
return allProperties.optLong(key);
} else {
return null;
}
}
/**
* Returns the media properties associated with the key.
* Returns the property associated with the key.
*
* @param key properties key
* @return media properties as a JSONObject or null if the key is not found
* @param key property key
* @return property as a JSONObject or null if the key is not found
*/
public JSONObject getProperty(String key) {
JSONObject allProperties = getAllProperties();
if (allProperties == null) {
return null;
}
return allProperties.optJSONObject(key);
}
/**
* Returns the format property associated with the key.
*
* @param key property key
* @return format property as string or null if the key is not found
*/
public String getStringFormatProperty(final String key) {
JSONObject formatProperties = getFormatProperties();
if (formatProperties == null) {
return null;
}
if (formatProperties.has(key)) {
return formatProperties.optString(key);
} else {
return null;
}
}
/**
* Returns the format property associated with the key.
*
* @param key property key
* @return format property as Long or null if the key is not found
*/
public Long getNumberFormatProperty(String key) {
JSONObject formatProperties = getFormatProperties();
if (formatProperties == null) {
return null;
}
if (formatProperties.has(key)) {
return formatProperties.optLong(key);
} else {
return null;
}
}
/**
* Returns the format property associated with the key.
*
* @param key property key
* @return format property as a JSONObject or null if the key is not found
*/
public JSONObject getProperties(String key) {
JSONObject mediaProperties = getMediaProperties();
if (mediaProperties == null) {
public JSONObject getFormatProperty(String key) {
JSONObject formatProperties = getFormatProperties();
if (formatProperties == null) {
return null;
}
return mediaProperties.optJSONObject(key);
return formatProperties.optJSONObject(key);
}
/**
* Returns all media properties.
* Returns all format properties defined.
*
* @return all media properties as a JSONObject or null if no media properties are defined
* @return all format properties as a JSONObject or null if no format properties are defined
*/
public JSONObject getMediaProperties() {
return jsonObject.optJSONObject(KEY_MEDIA_PROPERTIES);
public JSONObject getFormatProperties() {
return jsonObject.optJSONObject(KEY_FORMAT_PROPERTIES);
}
/**

@ -39,9 +39,10 @@ public class MediaInformationSession extends AbstractSession implements Session
* Creates a new media information session.
*
* @param arguments command arguments
* @return created session
*/
public MediaInformationSession(final String[] arguments) {
this(arguments, null);
public static MediaInformationSession create(final String[] arguments) {
return new MediaInformationSession(arguments, null, null);
}
/**
@ -49,9 +50,10 @@ public class MediaInformationSession extends AbstractSession implements Session
*
* @param arguments command arguments
* @param completeCallback session specific complete callback
* @return created session
*/
public MediaInformationSession(final String[] arguments, final MediaInformationSessionCompleteCallback completeCallback) {
this(arguments, completeCallback, null);
public static MediaInformationSession create(final String[] arguments, final MediaInformationSessionCompleteCallback completeCallback) {
return new MediaInformationSession(arguments, completeCallback, null);
}
/**
@ -60,8 +62,20 @@ public class MediaInformationSession extends AbstractSession implements Session
* @param arguments command arguments
* @param completeCallback session specific complete callback
* @param logCallback session specific log callback
* @return created session
*/
public MediaInformationSession(final String[] arguments, final MediaInformationSessionCompleteCallback completeCallback, final LogCallback logCallback) {
public static MediaInformationSession create(final String[] arguments, final MediaInformationSessionCompleteCallback completeCallback, final LogCallback logCallback) {
return new MediaInformationSession(arguments, completeCallback, logCallback);
}
/**
* Creates a new media information session.
*
* @param arguments command arguments
* @param completeCallback session specific complete callback
* @param logCallback session specific log callback
*/
private MediaInformationSession(final String[] arguments, final MediaInformationSessionCompleteCallback completeCallback, final LogCallback logCallback) {
super(arguments, logCallback, LogRedirectionStrategy.NEVER_PRINT_LOGS);
this.completeCallback = completeCallback;

@ -36,7 +36,7 @@ public class NativeLoader {
static final String[] FFMPEG_LIBRARIES = {"avutil", "swscale", "swresample", "avcodec", "avformat", "avfilter", "avdevice"};
static final String[] LIBRARIES_LINKED_WITH_CXX = {"openh264", "rubberband", "snappy", "srt", "tesseract", "x265", "zimg"};
static final String[] LIBRARIES_LINKED_WITH_CXX = {"chromaprint", "openh264", "rubberband", "snappy", "srt", "tesseract", "x265", "zimg"};
static boolean isTestModeDisabled() {
return (System.getProperty("enable.ffmpeg.kit.test.mode") == null);
@ -85,7 +85,7 @@ public class NativeLoader {
}
static String loadVersion() {
final String version = "4.5.1";
final String version = "5.1";
if (isTestModeDisabled()) {
return FFmpegKitConfig.getVersion();

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2021 Taner Sener
* Copyright (c) 2018-2022 Taner Sener
*
* This file is part of FFmpegKit.
*
@ -214,7 +214,7 @@ public class StreamInformation {
* @return tags object
*/
public JSONObject getTags() {
return getProperties(KEY_TAGS);
return getProperty(KEY_TAGS);
}
/**
@ -224,13 +224,13 @@ public class StreamInformation {
* @return stream property as string or null if the key is not found
*/
public String getStringProperty(final String key) {
JSONObject mediaProperties = getAllProperties();
if (mediaProperties == null) {
JSONObject allProperties = getAllProperties();
if (allProperties == null) {
return null;
}
if (mediaProperties.has(key)) {
return mediaProperties.optString(key);
if (allProperties.has(key)) {
return allProperties.optString(key);
} else {
return null;
}
@ -243,31 +243,31 @@ public class StreamInformation {
* @return stream property as Long or null if the key is not found
*/
public Long getNumberProperty(String key) {
JSONObject mediaProperties = getAllProperties();
if (mediaProperties == null) {
JSONObject allProperties = getAllProperties();
if (allProperties == null) {
return null;
}
if (mediaProperties.has(key)) {
return mediaProperties.optLong(key);
if (allProperties.has(key)) {
return allProperties.optLong(key);
} else {
return null;
}
}
/**
* Returns the stream properties associated with the key.
* Returns the stream property associated with the key.
*
* @param key properties key
* @return stream properties as a JSONObject or null if the key is not found
* @param key property key
* @return stream property as a JSONObject or null if the key is not found
*/
public JSONObject getProperties(String key) {
JSONObject mediaProperties = getAllProperties();
if (mediaProperties == null) {
public JSONObject getProperty(String key) {
JSONObject allProperties = getAllProperties();
if (allProperties == null) {
return null;
}
return mediaProperties.optJSONObject(key);
return allProperties.optJSONObject(key);
}
/**

@ -19,6 +19,8 @@
package com.arthenica.ffmpegkit;
import static com.arthenica.ffmpegkit.FFmpegSessionTest.TEST_ARGUMENTS;
import org.junit.Assert;
import org.junit.Test;
@ -167,6 +169,24 @@ public class FFmpegKitConfigTest {
Assert.assertEquals("mp4", extension);
}
@Test
public void setSessionHistorySize() {
int newSize = 15;
FFmpegKitConfig.setSessionHistorySize(newSize);
for (int i = 1; i <= (newSize + 5); i++) {
FFmpegSession.create(TEST_ARGUMENTS);
Assert.assertTrue(FFmpegKitConfig.getSessions().size() <= newSize);
}
newSize = 3;
FFmpegKitConfig.setSessionHistorySize(newSize);
for (int i = 1; i <= (newSize + 5); i++) {
FFmpegSession.create(TEST_ARGUMENTS);
Assert.assertTrue(FFmpegKitConfig.getSessions().size() <= newSize);
}
}
private String listToPackageName(final List<String> externalLibraryList) {
boolean speex = externalLibraryList.contains("speex");
boolean fribidi = externalLibraryList.contains("fribidi");

@ -26,11 +26,11 @@ import java.util.List;
public class FFmpegSessionTest {
private static final String[] TEST_ARGUMENTS = new String[]{"argument1", "argument2"};
static final String[] TEST_ARGUMENTS = new String[]{"argument1", "argument2"};
@Test
public void constructorTest() {
FFmpegSession ffmpegSession = new FFmpegSession(TEST_ARGUMENTS);
FFmpegSession ffmpegSession = FFmpegSession.create(TEST_ARGUMENTS);
// 1. getCompleteCallback
Assert.assertNull(ffmpegSession.getCompleteCallback());
@ -100,7 +100,7 @@ public class FFmpegSessionTest {
}
};
FFmpegSession ffmpegSession = new FFmpegSession(TEST_ARGUMENTS, completeCallback);
FFmpegSession ffmpegSession = FFmpegSession.create(TEST_ARGUMENTS, completeCallback);
// 1. getCompleteCallback
Assert.assertEquals(ffmpegSession.getCompleteCallback(), completeCallback);
@ -184,7 +184,7 @@ public class FFmpegSessionTest {
}
};
FFmpegSession ffmpegSession = new FFmpegSession(TEST_ARGUMENTS, completeCallback, logCallback, statisticsCallback);
FFmpegSession ffmpegSession = FFmpegSession.create(TEST_ARGUMENTS, completeCallback, logCallback, statisticsCallback);
// 1. getCompleteCallback
Assert.assertEquals(ffmpegSession.getCompleteCallback(), completeCallback);
@ -247,9 +247,9 @@ public class FFmpegSessionTest {
@Test
public void getSessionIdTest() {
FFmpegSession ffmpegSession1 = new FFmpegSession(TEST_ARGUMENTS);
FFmpegSession ffmpegSession2 = new FFmpegSession(TEST_ARGUMENTS);
FFmpegSession ffmpegSession3 = new FFmpegSession(TEST_ARGUMENTS);
FFmpegSession ffmpegSession1 = FFmpegSession.create(TEST_ARGUMENTS);
FFmpegSession ffmpegSession2 = FFmpegSession.create(TEST_ARGUMENTS);
FFmpegSession ffmpegSession3 = FFmpegSession.create(TEST_ARGUMENTS);
Assert.assertTrue(ffmpegSession3.getSessionId() > ffmpegSession2.getSessionId());
Assert.assertTrue(ffmpegSession3.getSessionId() > ffmpegSession1.getSessionId());
@ -262,7 +262,7 @@ public class FFmpegSessionTest {
@Test
public void getLogs() {
final FFmpegSession ffmpegSession = new FFmpegSession(TEST_ARGUMENTS);
final FFmpegSession ffmpegSession = FFmpegSession.create(TEST_ARGUMENTS);
String logMessage1 = "i am log one";
String logMessage2 = "i am log two";
@ -279,7 +279,7 @@ public class FFmpegSessionTest {
@Test
public void getLogsAsStringTest() {
final FFmpegSession ffmpegSession = new FFmpegSession(TEST_ARGUMENTS);
final FFmpegSession ffmpegSession = FFmpegSession.create(TEST_ARGUMENTS);
String logMessage1 = "i am log one";
String logMessage2 = "i am log two";
@ -296,18 +296,18 @@ public class FFmpegSessionTest {
public void getLogRedirectionStrategy() {
FFmpegKitConfig.setLogRedirectionStrategy(LogRedirectionStrategy.NEVER_PRINT_LOGS);
final FFmpegSession ffmpegSession1 = new FFmpegSession(TEST_ARGUMENTS);
final FFmpegSession ffmpegSession1 = FFmpegSession.create(TEST_ARGUMENTS);
Assert.assertEquals(FFmpegKitConfig.getLogRedirectionStrategy(), ffmpegSession1.getLogRedirectionStrategy());
FFmpegKitConfig.setLogRedirectionStrategy(LogRedirectionStrategy.PRINT_LOGS_WHEN_SESSION_CALLBACK_NOT_DEFINED);
final FFmpegSession ffmpegSession2 = new FFmpegSession(TEST_ARGUMENTS);
final FFmpegSession ffmpegSession2 = FFmpegSession.create(TEST_ARGUMENTS);
Assert.assertEquals(FFmpegKitConfig.getLogRedirectionStrategy(), ffmpegSession2.getLogRedirectionStrategy());
}
@Test
public void startRunningTest() {
FFmpegSession ffmpegSession = new FFmpegSession(TEST_ARGUMENTS);
FFmpegSession ffmpegSession = FFmpegSession.create(TEST_ARGUMENTS);
ffmpegSession.startRunning();
@ -318,7 +318,7 @@ public class FFmpegSessionTest {
@Test
public void completeTest() {
FFmpegSession ffmpegSession = new FFmpegSession(TEST_ARGUMENTS);
FFmpegSession ffmpegSession = FFmpegSession.create(TEST_ARGUMENTS);
ffmpegSession.startRunning();
ffmpegSession.complete(new ReturnCode(100));
@ -331,7 +331,7 @@ public class FFmpegSessionTest {
@Test
public void failTest() {
FFmpegSession ffmpegSession = new FFmpegSession(TEST_ARGUMENTS);
FFmpegSession ffmpegSession = FFmpegSession.create(TEST_ARGUMENTS);
ffmpegSession.startRunning();
ffmpegSession.fail(new Exception(""));

@ -30,7 +30,7 @@ public class FFprobeSessionTest {
@Test
public void constructorTest() {
FFprobeSession ffprobeSession = new FFprobeSession(TEST_ARGUMENTS);
FFprobeSession ffprobeSession = FFprobeSession.create(TEST_ARGUMENTS);
// 1. getCompleteCallback
Assert.assertNull(ffprobeSession.getCompleteCallback());
@ -97,7 +97,7 @@ public class FFprobeSessionTest {
}
};
FFprobeSession ffprobeSession = new FFprobeSession(TEST_ARGUMENTS, completeCallback);
FFprobeSession ffprobeSession = FFprobeSession.create(TEST_ARGUMENTS, completeCallback);
// 1. getCompleteCallback
Assert.assertEquals(ffprobeSession.getCompleteCallback(), completeCallback);
@ -171,7 +171,7 @@ public class FFprobeSessionTest {
}
};
FFprobeSession ffprobeSession = new FFprobeSession(TEST_ARGUMENTS, completeCallback, logCallback);
FFprobeSession ffprobeSession = FFprobeSession.create(TEST_ARGUMENTS, completeCallback, logCallback);
// 1. getCompleteCallback
Assert.assertEquals(ffprobeSession.getCompleteCallback(), completeCallback);
@ -231,9 +231,9 @@ public class FFprobeSessionTest {
@Test
public void getSessionIdTest() {
FFprobeSession ffprobeSession1 = new FFprobeSession(TEST_ARGUMENTS);
FFprobeSession ffprobeSession2 = new FFprobeSession(TEST_ARGUMENTS);
FFprobeSession ffprobeSession3 = new FFprobeSession(TEST_ARGUMENTS);
FFprobeSession ffprobeSession1 = FFprobeSession.create(TEST_ARGUMENTS);
FFprobeSession ffprobeSession2 = FFprobeSession.create(TEST_ARGUMENTS);
FFprobeSession ffprobeSession3 = FFprobeSession.create(TEST_ARGUMENTS);
Assert.assertTrue(ffprobeSession3.getSessionId() > ffprobeSession2.getSessionId());
Assert.assertTrue(ffprobeSession3.getSessionId() > ffprobeSession1.getSessionId());
@ -246,7 +246,7 @@ public class FFprobeSessionTest {
@Test
public void getLogs() {
final FFprobeSession ffprobeSession = new FFprobeSession(TEST_ARGUMENTS);
final FFprobeSession ffprobeSession = FFprobeSession.create(TEST_ARGUMENTS);
String logMessage1 = "i am log one";
String logMessage2 = "i am log two";
@ -263,7 +263,7 @@ public class FFprobeSessionTest {
@Test
public void getLogsAsStringTest() {
final FFprobeSession ffprobeSession = new FFprobeSession(TEST_ARGUMENTS);
final FFprobeSession ffprobeSession = FFprobeSession.create(TEST_ARGUMENTS);
String logMessage1 = "i am log one";
String logMessage2 = "i am log two";
@ -280,18 +280,18 @@ public class FFprobeSessionTest {
public void getLogRedirectionStrategy() {
FFmpegKitConfig.setLogRedirectionStrategy(LogRedirectionStrategy.NEVER_PRINT_LOGS);
final FFprobeSession ffprobeSession1 = new FFprobeSession(TEST_ARGUMENTS);
final FFprobeSession ffprobeSession1 = FFprobeSession.create(TEST_ARGUMENTS);
Assert.assertEquals(FFmpegKitConfig.getLogRedirectionStrategy(), ffprobeSession1.getLogRedirectionStrategy());
FFmpegKitConfig.setLogRedirectionStrategy(LogRedirectionStrategy.PRINT_LOGS_WHEN_SESSION_CALLBACK_NOT_DEFINED);
final FFprobeSession ffprobeSession2 = new FFprobeSession(TEST_ARGUMENTS);
final FFprobeSession ffprobeSession2 = FFprobeSession.create(TEST_ARGUMENTS);
Assert.assertEquals(FFmpegKitConfig.getLogRedirectionStrategy(), ffprobeSession2.getLogRedirectionStrategy());
}
@Test
public void startRunningTest() {
FFprobeSession ffprobeSession = new FFprobeSession(TEST_ARGUMENTS);
FFprobeSession ffprobeSession = FFprobeSession.create(TEST_ARGUMENTS);
ffprobeSession.startRunning();
@ -302,7 +302,7 @@ public class FFprobeSessionTest {
@Test
public void completeTest() {
FFprobeSession ffprobeSession = new FFprobeSession(TEST_ARGUMENTS);
FFprobeSession ffprobeSession = FFprobeSession.create(TEST_ARGUMENTS);
ffprobeSession.startRunning();
ffprobeSession.complete(new ReturnCode(100));
@ -315,7 +315,7 @@ public class FFprobeSessionTest {
@Test
public void failTest() {
FFprobeSession ffprobeSession = new FFprobeSession(TEST_ARGUMENTS);
FFprobeSession ffprobeSession = FFprobeSession.create(TEST_ARGUMENTS);
ffprobeSession.startRunning();
ffprobeSession.fail(new Exception(""));

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

@ -37,7 +37,11 @@ LOCAL_PATH := $(MY_LOCAL_PATH)/../ffmpeg-kit-android-lib/src/main/cpp
# DEFINE ARCH FLAGS
ifeq ($(TARGET_ARCH_ABI), armeabi-v7a)
MY_ARCH_FLAGS := ARM_V7A
ifeq ("$(shell test -e $(MY_LOCAL_PATH)/../build/.lts && echo lts)","lts")
MY_ARM_NEON := false
else
MY_ARM_NEON := true
endif
endif
ifeq ($(TARGET_ARCH_ABI), arm64-v8a)
MY_ARCH_FLAGS := ARM64_V8A
@ -45,9 +49,11 @@ ifeq ($(TARGET_ARCH_ABI), arm64-v8a)
endif
ifeq ($(TARGET_ARCH_ABI), x86)
MY_ARCH_FLAGS := X86
MY_ARM_NEON := true
endif
ifeq ($(TARGET_ARCH_ABI), x86_64)
MY_ARCH_FLAGS := X86_64
MY_ARM_NEON := true
endif
include $(CLEAR_VARS)
@ -63,7 +69,7 @@ include $(BUILD_SHARED_LIBRARY)
$(call import-module, cpu-features)
MY_SRC_FILES := ffmpegkit.c ffprobekit.c ffmpegkit_exception.c fftools_cmdutils.c fftools_ffmpeg.c fftools_ffprobe.c fftools_ffmpeg_opt.c fftools_ffmpeg_hw.c fftools_ffmpeg_filter.c
MY_SRC_FILES := ffmpegkit.c ffprobekit.c ffmpegkit_exception.c fftools_cmdutils.c fftools_ffmpeg.c fftools_ffprobe.c fftools_ffmpeg_mux.c fftools_ffmpeg_opt.c fftools_opt_common.c fftools_ffmpeg_hw.c fftools_ffmpeg_filter.c
ifeq ($(TARGET_PLATFORM),android-16)
MY_SRC_FILES += android_lts_support.c

@ -141,7 +141,6 @@ echo -e "INFO: Using iOS SDK: ${DETECTED_IOS_SDK_VERSION}, tvOS SDK: ${DETECTED_
echo -e "INFO: Build options: $*\n" 1>>"${BASEDIR}"/build.log 2>&1
# SET DEFAULT BUILD OPTIONS
GPL_ENABLED="no"
DISPLAY_HELP=""
BUILD_TYPE_ID=""
BUILD_FULL=""

5
apple/.gitignore vendored

@ -10,3 +10,8 @@
/test-driver
/config.log
/*.tmp
/m4/
/configure
/libtool
/ltmain.sh
/Makefile.in

@ -38,7 +38,7 @@ PROJECT_NAME = "FFmpegKit iOS / macOS / tvOS API"
# could be handy for archiving the generated documentation or if some version
# control system is used.
PROJECT_NUMBER = 4.5.1
PROJECT_NUMBER = 5.1
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a

@ -1,807 +0,0 @@
# Makefile.in generated by automake 1.16.5 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2021 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
am__is_gnu_make = { \
if test -z '$(MAKELEVEL)'; then \
false; \
elif test -n '$(MAKE_HOST)'; then \
true; \
elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
true; \
else \
false; \
fi; \
}
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
*) echo "am__make_running_with_option: internal error: invalid" \
"target option '$${target_option-}' specified" >&2; \
exit 1;; \
esac; \
has_opt=no; \
sane_makeflags=$$MAKEFLAGS; \
if $(am__is_gnu_make); then \
sane_makeflags=$$MFLAGS; \
else \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
bs=\\; \
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
esac; \
fi; \
skip_next=no; \
strip_trailopt () \
{ \
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
}; \
for flg in $$sane_makeflags; do \
test $$skip_next = yes && { skip_next=no; continue; }; \
case $$flg in \
*=*|--*) continue;; \
-*I) strip_trailopt 'I'; skip_next=yes;; \
-*I?*) strip_trailopt 'I';; \
-*O) strip_trailopt 'O'; skip_next=yes;; \
-*O?*) strip_trailopt 'O';; \
-*l) strip_trailopt 'l'; skip_next=yes;; \
-*l?*) strip_trailopt 'l';; \
-[dEDm]) skip_next=yes;; \
-[JT]) skip_next=yes;; \
esac; \
case $$flg in \
*$$target_option*) has_opt=yes; break;; \
esac; \
done; \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
subdir = .
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \
$(am__configure_deps) $(am__DIST_COMMON)
am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
configure.lineno config.status.lineno
mkinstalldirs = $(install_sh) -d
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
SOURCES =
DIST_SOURCES =
RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \
ctags-recursive dvi-recursive html-recursive info-recursive \
install-data-recursive install-dvi-recursive \
install-exec-recursive install-html-recursive \
install-info-recursive install-pdf-recursive \
install-ps-recursive install-recursive installcheck-recursive \
installdirs-recursive pdf-recursive ps-recursive \
tags-recursive uninstall-recursive
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
distclean-recursive maintainer-clean-recursive
am__recursive_targets = \
$(RECURSIVE_TARGETS) \
$(RECURSIVE_CLEAN_TARGETS) \
$(am__extra_recursive_targets)
AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \
cscope distdir distdir-am dist dist-all distcheck
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates. Input order is
# *not* preserved.
am__uniquify_input = $(AWK) '\
BEGIN { nonempty = 0; } \
{ items[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in items) print i; }; } \
'
# Make sure the list of sources is unique. This is necessary because,
# e.g., the same source file might be shared among _SOURCES variables
# for different programs/libraries.
am__define_uniq_tagged_files = \
list='$(am__tagged_files)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
DIST_SUBDIRS = $(SUBDIRS)
am__DIST_COMMON = $(srcdir)/Makefile.in README.md ar-lib compile \
config.guess config.sub install-sh ltmain.sh missing
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
distdir = $(PACKAGE)-$(VERSION)
top_distdir = $(distdir)
am__remove_distdir = \
if test -d "$(distdir)"; then \
find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
&& rm -rf "$(distdir)" \
|| { sleep 5 && rm -rf "$(distdir)"; }; \
else :; fi
am__post_remove_distdir = $(am__remove_distdir)
am__relativize = \
dir0=`pwd`; \
sed_first='s,^\([^/]*\)/.*$$,\1,'; \
sed_rest='s,^[^/]*/*,,'; \
sed_last='s,^.*/\([^/]*\)$$,\1,'; \
sed_butlast='s,/*[^/]*$$,,'; \
while test -n "$$dir1"; do \
first=`echo "$$dir1" | sed -e "$$sed_first"`; \
if test "$$first" != "."; then \
if test "$$first" = ".."; then \
dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
else \
first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
if test "$$first2" = "$$first"; then \
dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
else \
dir2="../$$dir2"; \
fi; \
dir0="$$dir0"/"$$first"; \
fi; \
fi; \
dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
done; \
reldir="$$dir2"
DIST_ARCHIVES = $(distdir).tar.gz
GZIP_ENV = --best
DIST_TARGETS = dist-gzip
# Exists only to be overridden by the user if desired.
AM_DISTCHECK_DVI_TARGET = dvi
distuninstallcheck_listfiles = find . -type f -print
am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
| sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
distcleancheck_listfiles = find . -type f -print
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPPFLAGS = @CPPFLAGS@
CSCOPE = @CSCOPE@
CTAGS = @CTAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
ETAGS = @ETAGS@
EXEEXT = @EXEEXT@
FFMPEG_FRAMEWORKS = @FFMPEG_FRAMEWORKS@
FGREP = @FGREP@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJC = @OBJC@
OBJCDEPMODE = @OBJCDEPMODE@
OBJCFLAGS = @OBJCFLAGS@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
ac_ct_OBJC = @ac_ct_OBJC@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
ACLOCAL_AMFLAGS = -I m4
SUBDIRS = src
all: all-recursive
.SUFFIXES:
am--refresh: Makefile
@:
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \
$(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
echo ' $(SHELL) ./config.status'; \
$(SHELL) ./config.status;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles)'; \
cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
$(SHELL) ./config.status --recheck
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
$(am__cd) $(srcdir) && $(AUTOCONF)
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
$(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
$(am__aclocal_m4_deps):
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
-rm -f libtool config.lt
# This directory's subdirectories are mostly independent; you can cd
# into them and run 'make' without going through this Makefile.
# To change the values of 'make' variables: instead of editing Makefiles,
# (1) if the variable is set in 'config.status', edit 'config.status'
# (which will cause the Makefiles to be regenerated when you run 'make');
# (2) otherwise, pass the desired values on the 'make' command line.
$(am__recursive_targets):
@fail=; \
if $(am__make_keepgoing); then \
failcom='fail=yes'; \
else \
failcom='exit 1'; \
fi; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
case "$@" in \
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
*) list='$(SUBDIRS)' ;; \
esac; \
for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| eval $$failcom; \
done; \
if test "$$dot_seen" = "no"; then \
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
fi; test -z "$$fail"
ID: $(am__tagged_files)
$(am__define_uniq_tagged_files); mkid -fID $$unique
tags: tags-recursive
TAGS: tags
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
set x; \
here=`pwd`; \
if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
include_option=--etags-include; \
empty_fix=.; \
else \
include_option=--include; \
empty_fix=; \
fi; \
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test ! -f $$subdir/TAGS || \
set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
fi; \
done; \
$(am__define_uniq_tagged_files); \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: ctags-recursive
CTAGS: ctags
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
$(am__define_uniq_tagged_files); \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
cscope: cscope.files
test ! -s cscope.files \
|| $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS)
clean-cscope:
-rm -f cscope.files
cscope.files: clean-cscope cscopelist
cscopelist: cscopelist-recursive
cscopelist-am: $(am__tagged_files)
list='$(am__tagged_files)'; \
case "$(srcdir)" in \
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
*) sdir=$(subdir)/$(srcdir) ;; \
esac; \
for i in $$list; do \
if test -f "$$i"; then \
echo "$(subdir)/$$i"; \
else \
echo "$$sdir/$$i"; \
fi; \
done >> $(top_builddir)/cscope.files
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-rm -f cscope.out cscope.in.out cscope.po.out cscope.files
distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am
distdir-am: $(DISTFILES)
$(am__remove_distdir)
test -d "$(distdir)" || mkdir "$(distdir)"
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
$(am__make_dryrun) \
|| test -d "$(distdir)/$$subdir" \
|| $(MKDIR_P) "$(distdir)/$$subdir" \
|| exit 1; \
dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
$(am__relativize); \
new_distdir=$$reldir; \
dir1=$$subdir; dir2="$(top_distdir)"; \
$(am__relativize); \
new_top_distdir=$$reldir; \
echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
($(am__cd) $$subdir && \
$(MAKE) $(AM_MAKEFLAGS) \
top_distdir="$$new_top_distdir" \
distdir="$$new_distdir" \
am__remove_distdir=: \
am__skip_length_check=: \
am__skip_mode_fix=: \
distdir) \
|| exit 1; \
fi; \
done
-test -n "$(am__skip_mode_fix)" \
|| find "$(distdir)" -type d ! -perm -755 \
-exec chmod u+rwx,go+rx {} \; -o \
! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
! -type d ! -perm -400 -exec chmod a+r {} \; -o \
! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
|| chmod -R a+r "$(distdir)"
dist-gzip: distdir
tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz
$(am__post_remove_distdir)
dist-bzip2: distdir
tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
$(am__post_remove_distdir)
dist-lzip: distdir
tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz
$(am__post_remove_distdir)
dist-xz: distdir
tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
$(am__post_remove_distdir)
dist-zstd: distdir
tardir=$(distdir) && $(am__tar) | zstd -c $${ZSTD_CLEVEL-$${ZSTD_OPT--19}} >$(distdir).tar.zst
$(am__post_remove_distdir)
dist-tarZ: distdir
@echo WARNING: "Support for distribution archives compressed with" \
"legacy program 'compress' is deprecated." >&2
@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
$(am__post_remove_distdir)
dist-shar: distdir
@echo WARNING: "Support for shar distribution archives is" \
"deprecated." >&2
@echo WARNING: "It will be removed altogether in Automake 2.0" >&2
shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz
$(am__post_remove_distdir)
dist-zip: distdir
-rm -f $(distdir).zip
zip -rq $(distdir).zip $(distdir)
$(am__post_remove_distdir)
dist dist-all:
$(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:'
$(am__post_remove_distdir)
# This target untars the dist file and tries a VPATH configuration. Then
# it guarantees that the distribution is self-contained by making another
# tarfile.
distcheck: dist
case '$(DIST_ARCHIVES)' in \
*.tar.gz*) \
eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\
*.tar.bz2*) \
bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
*.tar.lz*) \
lzip -dc $(distdir).tar.lz | $(am__untar) ;;\
*.tar.xz*) \
xz -dc $(distdir).tar.xz | $(am__untar) ;;\
*.tar.Z*) \
uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
*.shar.gz*) \
eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\
*.zip*) \
unzip $(distdir).zip ;;\
*.tar.zst*) \
zstd -dc $(distdir).tar.zst | $(am__untar) ;;\
esac
chmod -R a-w $(distdir)
chmod u+w $(distdir)
mkdir $(distdir)/_build $(distdir)/_build/sub $(distdir)/_inst
chmod a-w $(distdir)
test -d $(distdir)/_build || exit 0; \
dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
&& dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
&& am__cwd=`pwd` \
&& $(am__cd) $(distdir)/_build/sub \
&& ../../configure \
$(AM_DISTCHECK_CONFIGURE_FLAGS) \
$(DISTCHECK_CONFIGURE_FLAGS) \
--srcdir=../.. --prefix="$$dc_install_base" \
&& $(MAKE) $(AM_MAKEFLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) $(AM_DISTCHECK_DVI_TARGET) \
&& $(MAKE) $(AM_MAKEFLAGS) check \
&& $(MAKE) $(AM_MAKEFLAGS) install \
&& $(MAKE) $(AM_MAKEFLAGS) installcheck \
&& $(MAKE) $(AM_MAKEFLAGS) uninstall \
&& $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
distuninstallcheck \
&& chmod -R a-w "$$dc_install_base" \
&& ({ \
(cd ../.. && umask 077 && mkdir "$$dc_destdir") \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
} || { rm -rf "$$dc_destdir"; exit 1; }) \
&& rm -rf "$$dc_destdir" \
&& $(MAKE) $(AM_MAKEFLAGS) dist \
&& rm -rf $(DIST_ARCHIVES) \
&& $(MAKE) $(AM_MAKEFLAGS) distcleancheck \
&& cd "$$am__cwd" \
|| exit 1
$(am__post_remove_distdir)
@(echo "$(distdir) archives ready for distribution: "; \
list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
distuninstallcheck:
@test -n '$(distuninstallcheck_dir)' || { \
echo 'ERROR: trying to run $@ with an empty' \
'$$(distuninstallcheck_dir)' >&2; \
exit 1; \
}; \
$(am__cd) '$(distuninstallcheck_dir)' || { \
echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \
exit 1; \
}; \
test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \
|| { echo "ERROR: files left after uninstall:" ; \
if test -n "$(DESTDIR)"; then \
echo " (check DESTDIR support)"; \
fi ; \
$(distuninstallcheck_listfiles) ; \
exit 1; } >&2
distcleancheck: distclean
@if test '$(srcdir)' = . ; then \
echo "ERROR: distcleancheck can only run from a VPATH build" ; \
exit 1 ; \
fi
@test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
|| { echo "ERROR: files left in build directory after distclean:" ; \
$(distcleancheck_listfiles) ; \
exit 1; } >&2
check-am: all-am
check: check-recursive
all-am: Makefile
installdirs: installdirs-recursive
installdirs-am:
install: install-recursive
install-exec: install-exec-recursive
install-data: install-data-recursive
uninstall: uninstall-recursive
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-recursive
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-recursive
clean-am: clean-generic clean-libtool mostlyclean-am
distclean: distclean-recursive
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-rm -f Makefile
distclean-am: clean-am distclean-generic distclean-libtool \
distclean-tags
dvi: dvi-recursive
dvi-am:
html: html-recursive
html-am:
info: info-recursive
info-am:
install-data-am:
install-dvi: install-dvi-recursive
install-dvi-am:
install-exec-am:
install-html: install-html-recursive
install-html-am:
install-info: install-info-recursive
install-info-am:
install-man:
install-pdf: install-pdf-recursive
install-pdf-am:
install-ps: install-ps-recursive
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-recursive
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-rm -rf $(top_srcdir)/autom4te.cache
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-recursive
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
pdf: pdf-recursive
pdf-am:
ps: ps-recursive
ps-am:
uninstall-am:
.MAKE: $(am__recursive_targets) install-am install-strip
.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \
am--refresh check check-am clean clean-cscope clean-generic \
clean-libtool cscope cscopelist-am ctags ctags-am dist \
dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \
dist-xz dist-zip dist-zstd distcheck distclean \
distclean-generic distclean-libtool distclean-tags \
distcleancheck distdir distuninstallcheck dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-dvi install-dvi-am install-exec \
install-exec-am install-html install-html-am install-info \
install-info-am install-man install-pdf install-pdf-am \
install-ps install-ps-am install-strip installcheck \
installcheck-am installdirs installdirs-am maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-generic \
mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \
uninstall-am
.PRECIOUS: Makefile
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

@ -107,21 +107,21 @@ All libraries created can be found under the `prebuilt` directory.
#### 3.1 Objective API
1. Add `FFmpegKit` dependency to your `Podfile` in `ffmpeg-kit-<platform>-<package name>` pattern. Use one of the
`FFmpegKit` package names given in the project [README](https://github.com/tanersener/ffmpeg-kit).
`FFmpegKit` package names given in the project [README](https://github.com/arthenica/ffmpeg-kit).
- iOS
```yaml
pod 'ffmpeg-kit-ios-full', '~> 4.5.1'
pod 'ffmpeg-kit-ios-full', '~> 5.1'
```
- macOS
```yaml
pod 'ffmpeg-kit-macos-full', '~> 4.5.1'
pod 'ffmpeg-kit-macos-full', '~> 5.1'
```
- tvOS
```yaml
pod 'ffmpeg-kit-tvos-full', '~> 4.5.1'
pod 'ffmpeg-kit-tvos-full', '~> 5.1'
```
2. Execute synchronous `FFmpeg` commands.
@ -312,4 +312,4 @@ All libraries created can be found under the `prebuilt` directory.
### 4. Test Application
You can see how `FFmpegKit` is used inside an application by running `iOS`, `macOS` and `tvOS` test applications
developed under the [FFmpegKit Test](https://github.com/tanersener/ffmpeg-kit-test) project.
developed under the [FFmpegKit Test](https://github.com/arthenica/ffmpeg-kit-test) project.

16948
apple/configure vendored

File diff suppressed because it is too large Load Diff

@ -1,6 +1,6 @@
# ffmpeg-kit 4.5.1 configure.ac
# ffmpeg-kit 5.1 configure.ac
AC_INIT([ffmpeg-kit], [4.5.1], [https://github.com/tanersener/ffmpeg-kit/issues/new])
AC_INIT([ffmpeg-kit], [5.1], [https://github.com/arthenica/ffmpeg-kit/issues/new])
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_SRCDIR([src/FFmpegKit.m])
@ -35,15 +35,6 @@ AC_CHECK_HEADERS([libavformat/avformat.h libavcodec/avcodec.h libavfilter/avfilt
])
AC_CHECK_HEADERS([fcntl.h limits.h stdint.h stdlib.h string.h sys/ioctl.h sys/time.h termios.h unistd.h])
AC_ARG_ENABLE([videotoolbox],
[ --enable-videotoolbox enable videotoolbox support],
[case "${enableval}" in
yes) videotoolbox=true ;;
no) videotoolbox=false ;;
*) AC_MSG_ERROR([bad value ${enableval} for --enable-videotoolbox]) ;;
esac],[videotoolbox=false])
AM_CONDITIONAL([FFMPEGKIT_VIDEOTOOLBOX], [test x$videotoolbox = xtrue])
# Checks for typedefs, structures, and compiler characteristics.
AC_C_INLINE
AC_TYPE_INT32_T

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

8364
apple/m4/libtool.m4 vendored

File diff suppressed because it is too large Load Diff

@ -1,437 +0,0 @@
# Helper functions for option handling. -*- Autoconf -*-
#
# Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software
# Foundation, Inc.
# Written by Gary V. Vaughan, 2004
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
# serial 8 ltoptions.m4
# This is to help aclocal find these macros, as it can't see m4_define.
AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])
# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME)
# ------------------------------------------
m4_define([_LT_MANGLE_OPTION],
[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])])
# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME)
# ---------------------------------------
# Set option OPTION-NAME for macro MACRO-NAME, and if there is a
# matching handler defined, dispatch to it. Other OPTION-NAMEs are
# saved as a flag.
m4_define([_LT_SET_OPTION],
[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl
m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]),
_LT_MANGLE_DEFUN([$1], [$2]),
[m4_warning([Unknown $1 option '$2'])])[]dnl
])
# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET])
# ------------------------------------------------------------
# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
m4_define([_LT_IF_OPTION],
[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])])
# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET)
# -------------------------------------------------------
# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME
# are set.
m4_define([_LT_UNLESS_OPTIONS],
[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
[m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option),
[m4_define([$0_found])])])[]dnl
m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3
])[]dnl
])
# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST)
# ----------------------------------------
# OPTION-LIST is a space-separated list of Libtool options associated
# with MACRO-NAME. If any OPTION has a matching handler declared with
# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about
# the unknown option and exit.
m4_defun([_LT_SET_OPTIONS],
[# Set options
m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
[_LT_SET_OPTION([$1], _LT_Option)])
m4_if([$1],[LT_INIT],[
dnl
dnl Simply set some default values (i.e off) if boolean options were not
dnl specified:
_LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no
])
_LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no
])
dnl
dnl If no reference was made to various pairs of opposing options, then
dnl we run the default mode handler for the pair. For example, if neither
dnl 'shared' nor 'disable-shared' was passed, we enable building of shared
dnl archives by default:
_LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED])
_LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC])
_LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC])
_LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install],
[_LT_ENABLE_FAST_INSTALL])
_LT_UNLESS_OPTIONS([LT_INIT], [aix-soname=aix aix-soname=both aix-soname=svr4],
[_LT_WITH_AIX_SONAME([aix])])
])
])# _LT_SET_OPTIONS
## --------------------------------- ##
## Macros to handle LT_INIT options. ##
## --------------------------------- ##
# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME)
# -----------------------------------------
m4_define([_LT_MANGLE_DEFUN],
[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])])
# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE)
# -----------------------------------------------
m4_define([LT_OPTION_DEFINE],
[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl
])# LT_OPTION_DEFINE
# dlopen
# ------
LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes
])
AU_DEFUN([AC_LIBTOOL_DLOPEN],
[_LT_SET_OPTION([LT_INIT], [dlopen])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you
put the 'dlopen' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], [])
# win32-dll
# ---------
# Declare package support for building win32 dll's.
LT_OPTION_DEFINE([LT_INIT], [win32-dll],
[enable_win32_dll=yes
case $host in
*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*)
AC_CHECK_TOOL(AS, as, false)
AC_CHECK_TOOL(DLLTOOL, dlltool, false)
AC_CHECK_TOOL(OBJDUMP, objdump, false)
;;
esac
test -z "$AS" && AS=as
_LT_DECL([], [AS], [1], [Assembler program])dnl
test -z "$DLLTOOL" && DLLTOOL=dlltool
_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl
test -z "$OBJDUMP" && OBJDUMP=objdump
_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl
])# win32-dll
AU_DEFUN([AC_LIBTOOL_WIN32_DLL],
[AC_REQUIRE([AC_CANONICAL_HOST])dnl
_LT_SET_OPTION([LT_INIT], [win32-dll])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you
put the 'win32-dll' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [])
# _LT_ENABLE_SHARED([DEFAULT])
# ----------------------------
# implement the --enable-shared flag, and supports the 'shared' and
# 'disable-shared' LT_INIT options.
# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'.
m4_define([_LT_ENABLE_SHARED],
[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl
AC_ARG_ENABLE([shared],
[AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@],
[build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])],
[p=${PACKAGE-default}
case $enableval in
yes) enable_shared=yes ;;
no) enable_shared=no ;;
*)
enable_shared=no
# Look at the argument we got. We use all the common list separators.
lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
for pkg in $enableval; do
IFS=$lt_save_ifs
if test "X$pkg" = "X$p"; then
enable_shared=yes
fi
done
IFS=$lt_save_ifs
;;
esac],
[enable_shared=]_LT_ENABLE_SHARED_DEFAULT)
_LT_DECL([build_libtool_libs], [enable_shared], [0],
[Whether or not to build shared libraries])
])# _LT_ENABLE_SHARED
LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])])
LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])])
# Old names:
AC_DEFUN([AC_ENABLE_SHARED],
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared])
])
AC_DEFUN([AC_DISABLE_SHARED],
[_LT_SET_OPTION([LT_INIT], [disable-shared])
])
AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)])
AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AM_ENABLE_SHARED], [])
dnl AC_DEFUN([AM_DISABLE_SHARED], [])
# _LT_ENABLE_STATIC([DEFAULT])
# ----------------------------
# implement the --enable-static flag, and support the 'static' and
# 'disable-static' LT_INIT options.
# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'.
m4_define([_LT_ENABLE_STATIC],
[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl
AC_ARG_ENABLE([static],
[AS_HELP_STRING([--enable-static@<:@=PKGS@:>@],
[build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])],
[p=${PACKAGE-default}
case $enableval in
yes) enable_static=yes ;;
no) enable_static=no ;;
*)
enable_static=no
# Look at the argument we got. We use all the common list separators.
lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
for pkg in $enableval; do
IFS=$lt_save_ifs
if test "X$pkg" = "X$p"; then
enable_static=yes
fi
done
IFS=$lt_save_ifs
;;
esac],
[enable_static=]_LT_ENABLE_STATIC_DEFAULT)
_LT_DECL([build_old_libs], [enable_static], [0],
[Whether or not to build static libraries])
])# _LT_ENABLE_STATIC
LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])])
LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])])
# Old names:
AC_DEFUN([AC_ENABLE_STATIC],
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static])
])
AC_DEFUN([AC_DISABLE_STATIC],
[_LT_SET_OPTION([LT_INIT], [disable-static])
])
AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)])
AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AM_ENABLE_STATIC], [])
dnl AC_DEFUN([AM_DISABLE_STATIC], [])
# _LT_ENABLE_FAST_INSTALL([DEFAULT])
# ----------------------------------
# implement the --enable-fast-install flag, and support the 'fast-install'
# and 'disable-fast-install' LT_INIT options.
# DEFAULT is either 'yes' or 'no'. If omitted, it defaults to 'yes'.
m4_define([_LT_ENABLE_FAST_INSTALL],
[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl
AC_ARG_ENABLE([fast-install],
[AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@],
[optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])],
[p=${PACKAGE-default}
case $enableval in
yes) enable_fast_install=yes ;;
no) enable_fast_install=no ;;
*)
enable_fast_install=no
# Look at the argument we got. We use all the common list separators.
lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
for pkg in $enableval; do
IFS=$lt_save_ifs
if test "X$pkg" = "X$p"; then
enable_fast_install=yes
fi
done
IFS=$lt_save_ifs
;;
esac],
[enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT)
_LT_DECL([fast_install], [enable_fast_install], [0],
[Whether or not to optimize for fast installation])dnl
])# _LT_ENABLE_FAST_INSTALL
LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])])
LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])])
# Old names:
AU_DEFUN([AC_ENABLE_FAST_INSTALL],
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you put
the 'fast-install' option into LT_INIT's first parameter.])
])
AU_DEFUN([AC_DISABLE_FAST_INSTALL],
[_LT_SET_OPTION([LT_INIT], [disable-fast-install])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you put
the 'disable-fast-install' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], [])
dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])
# _LT_WITH_AIX_SONAME([DEFAULT])
# ----------------------------------
# implement the --with-aix-soname flag, and support the `aix-soname=aix'
# and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT
# is either `aix', `both' or `svr4'. If omitted, it defaults to `aix'.
m4_define([_LT_WITH_AIX_SONAME],
[m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl
shared_archive_member_spec=
case $host,$enable_shared in
power*-*-aix[[5-9]]*,yes)
AC_MSG_CHECKING([which variant of shared library versioning to provide])
AC_ARG_WITH([aix-soname],
[AS_HELP_STRING([--with-aix-soname=aix|svr4|both],
[shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])],
[case $withval in
aix|svr4|both)
;;
*)
AC_MSG_ERROR([Unknown argument to --with-aix-soname])
;;
esac
lt_cv_with_aix_soname=$with_aix_soname],
[AC_CACHE_VAL([lt_cv_with_aix_soname],
[lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT)
with_aix_soname=$lt_cv_with_aix_soname])
AC_MSG_RESULT([$with_aix_soname])
if test aix != "$with_aix_soname"; then
# For the AIX way of multilib, we name the shared archive member
# based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o',
# and 'shr.imp' or 'shr_64.imp', respectively, for the Import File.
# Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag,
# the AIX toolchain works better with OBJECT_MODE set (default 32).
if test 64 = "${OBJECT_MODE-32}"; then
shared_archive_member_spec=shr_64
else
shared_archive_member_spec=shr
fi
fi
;;
*)
with_aix_soname=aix
;;
esac
_LT_DECL([], [shared_archive_member_spec], [0],
[Shared archive member basename, for filename based shared library versioning on AIX])dnl
])# _LT_WITH_AIX_SONAME
LT_OPTION_DEFINE([LT_INIT], [aix-soname=aix], [_LT_WITH_AIX_SONAME([aix])])
LT_OPTION_DEFINE([LT_INIT], [aix-soname=both], [_LT_WITH_AIX_SONAME([both])])
LT_OPTION_DEFINE([LT_INIT], [aix-soname=svr4], [_LT_WITH_AIX_SONAME([svr4])])
# _LT_WITH_PIC([MODE])
# --------------------
# implement the --with-pic flag, and support the 'pic-only' and 'no-pic'
# LT_INIT options.
# MODE is either 'yes' or 'no'. If omitted, it defaults to 'both'.
m4_define([_LT_WITH_PIC],
[AC_ARG_WITH([pic],
[AS_HELP_STRING([--with-pic@<:@=PKGS@:>@],
[try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
[lt_p=${PACKAGE-default}
case $withval in
yes|no) pic_mode=$withval ;;
*)
pic_mode=default
# Look at the argument we got. We use all the common list separators.
lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR,
for lt_pkg in $withval; do
IFS=$lt_save_ifs
if test "X$lt_pkg" = "X$lt_p"; then
pic_mode=yes
fi
done
IFS=$lt_save_ifs
;;
esac],
[pic_mode=m4_default([$1], [default])])
_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl
])# _LT_WITH_PIC
LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])])
LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])])
# Old name:
AU_DEFUN([AC_LIBTOOL_PICMODE],
[_LT_SET_OPTION([LT_INIT], [pic-only])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you
put the 'pic-only' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_LIBTOOL_PICMODE], [])
## ----------------- ##
## LTDL_INIT Options ##
## ----------------- ##
m4_define([_LTDL_MODE], [])
LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive],
[m4_define([_LTDL_MODE], [nonrecursive])])
LT_OPTION_DEFINE([LTDL_INIT], [recursive],
[m4_define([_LTDL_MODE], [recursive])])
LT_OPTION_DEFINE([LTDL_INIT], [subproject],
[m4_define([_LTDL_MODE], [subproject])])
m4_define([_LTDL_TYPE], [])
LT_OPTION_DEFINE([LTDL_INIT], [installable],
[m4_define([_LTDL_TYPE], [installable])])
LT_OPTION_DEFINE([LTDL_INIT], [convenience],
[m4_define([_LTDL_TYPE], [convenience])])

124
apple/m4/ltsugar.m4 vendored

@ -1,124 +0,0 @@
# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*-
#
# Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software
# Foundation, Inc.
# Written by Gary V. Vaughan, 2004
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
# serial 6 ltsugar.m4
# This is to help aclocal find these macros, as it can't see m4_define.
AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])])
# lt_join(SEP, ARG1, [ARG2...])
# -----------------------------
# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their
# associated separator.
# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier
# versions in m4sugar had bugs.
m4_define([lt_join],
[m4_if([$#], [1], [],
[$#], [2], [[$2]],
[m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])])
m4_define([_lt_join],
[m4_if([$#$2], [2], [],
[m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])])
# lt_car(LIST)
# lt_cdr(LIST)
# ------------
# Manipulate m4 lists.
# These macros are necessary as long as will still need to support
# Autoconf-2.59, which quotes differently.
m4_define([lt_car], [[$1]])
m4_define([lt_cdr],
[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])],
[$#], 1, [],
[m4_dquote(m4_shift($@))])])
m4_define([lt_unquote], $1)
# lt_append(MACRO-NAME, STRING, [SEPARATOR])
# ------------------------------------------
# Redefine MACRO-NAME to hold its former content plus 'SEPARATOR''STRING'.
# Note that neither SEPARATOR nor STRING are expanded; they are appended
# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked).
# No SEPARATOR is output if MACRO-NAME was previously undefined (different
# than defined and empty).
#
# This macro is needed until we can rely on Autoconf 2.62, since earlier
# versions of m4sugar mistakenly expanded SEPARATOR but not STRING.
m4_define([lt_append],
[m4_define([$1],
m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])])
# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...])
# ----------------------------------------------------------
# Produce a SEP delimited list of all paired combinations of elements of
# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list
# has the form PREFIXmINFIXSUFFIXn.
# Needed until we can rely on m4_combine added in Autoconf 2.62.
m4_define([lt_combine],
[m4_if(m4_eval([$# > 3]), [1],
[m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl
[[m4_foreach([_Lt_prefix], [$2],
[m4_foreach([_Lt_suffix],
]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[,
[_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])])
# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ])
# -----------------------------------------------------------------------
# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited
# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ.
m4_define([lt_if_append_uniq],
[m4_ifdef([$1],
[m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1],
[lt_append([$1], [$2], [$3])$4],
[$5])],
[lt_append([$1], [$2], [$3])$4])])
# lt_dict_add(DICT, KEY, VALUE)
# -----------------------------
m4_define([lt_dict_add],
[m4_define([$1($2)], [$3])])
# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE)
# --------------------------------------------
m4_define([lt_dict_add_subkey],
[m4_define([$1($2:$3)], [$4])])
# lt_dict_fetch(DICT, KEY, [SUBKEY])
# ----------------------------------
m4_define([lt_dict_fetch],
[m4_ifval([$3],
m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]),
m4_ifdef([$1($2)], [m4_defn([$1($2)])]))])
# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE])
# -----------------------------------------------------------------
m4_define([lt_if_dict_fetch],
[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4],
[$5],
[$6])])
# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...])
# --------------------------------------------------------------
m4_define([lt_dict_filter],
[m4_if([$5], [], [],
[lt_join(m4_quote(m4_default([$4], [[, ]])),
lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]),
[lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl
])

@ -1,23 +0,0 @@
# ltversion.m4 -- version numbers -*- Autoconf -*-
#
# Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc.
# Written by Scott James Remnant, 2004
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
# @configure_input@
# serial 4179 ltversion.m4
# This file is part of GNU Libtool
m4_define([LT_PACKAGE_VERSION], [2.4.6])
m4_define([LT_PACKAGE_REVISION], [2.4.6])
AC_DEFUN([LTVERSION_VERSION],
[macro_version='2.4.6'
macro_revision='2.4.6'
_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
_LT_DECL(, macro_revision, 0)
])

@ -1,99 +0,0 @@
# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*-
#
# Copyright (C) 2004-2005, 2007, 2009, 2011-2015 Free Software
# Foundation, Inc.
# Written by Scott James Remnant, 2004.
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
# serial 5 lt~obsolete.m4
# These exist entirely to fool aclocal when bootstrapping libtool.
#
# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN),
# which have later been changed to m4_define as they aren't part of the
# exported API, or moved to Autoconf or Automake where they belong.
#
# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN
# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us
# using a macro with the same name in our local m4/libtool.m4 it'll
# pull the old libtool.m4 in (it doesn't see our shiny new m4_define
# and doesn't know about Autoconf macros at all.)
#
# So we provide this file, which has a silly filename so it's always
# included after everything else. This provides aclocal with the
# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything
# because those macros already exist, or will be overwritten later.
# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6.
#
# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here.
# Yes, that means every name once taken will need to remain here until
# we give up compatibility with versions before 1.7, at which point
# we need to keep only those names which we still refer to.
# This is to help aclocal find these macros, as it can't see m4_define.
AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])])
m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])])
m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])])
m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])])
m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])])
m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])])
m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])])
m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])])
m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])])
m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])])
m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])])
m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])])
m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])])
m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])])
m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])])
m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])])
m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])])
m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])])
m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])])
m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])])
m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])])
m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])])
m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])])
m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])])
m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])])
m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])])
m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])])
m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])])
m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])])
m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])])
m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])])
m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])])
m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])])
m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])])
m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])])
m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])])
m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])])
m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])])
m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])])
m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])])
m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])])
m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])])
m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])])
m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])])
m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])])
m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])])
m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])])
m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])])
m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])])
m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])])
m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])])
m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])])
m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])])
m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])])
m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])])
m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])])
m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])])
m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])])
m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])])
m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])])
m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])])
m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])])

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Taner Sener
* Copyright (c) 2021-2022 Taner Sener
*
* This file is part of FFmpegKit.
*
@ -208,7 +208,7 @@ extern void addSessionToSessionHistory(id<Session> session);
}
- (void)fail:(NSException*)exception {
_failStackTrace = [NSString stringWithFormat:@"%@", [exception callStackSymbols]];
_failStackTrace = [NSString stringWithFormat:@"%@\n%@", [exception userInfo], [exception callStackSymbols]];
_state = SessionStateFailed;
_endTime = [NSDate date];
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Taner Sener
* Copyright (c) 2021-2022 Taner Sener
*
* This file is part of FFmpegKit.
*
@ -66,11 +66,11 @@ extern NSString* const ChapterKeyTags;
- (NSNumber*)getNumberProperty:(NSString*)key;
/**
* Returns the chapter properties associated with the key.
* Returns the chapter property associated with the key.
*
* @return chapter properties in a dictionary or nil if the key is not found
* @return chapter property as id or nil if the key is not found
*/
- (NSDictionary*)getProperties:(NSString*)key;
- (id)getProperty:(NSString*)key;
/**
* Returns all chapter properties defined.

@ -70,7 +70,7 @@ NSString* const ChapterKeyTags = @"tags";
}
- (NSDictionary*)getTags {
return [self getProperties:ChapterKeyTags];
return [self getProperty:ChapterKeyTags];
}
- (NSString*)getStringProperty:(NSString*)key {
@ -83,15 +83,15 @@ NSString* const ChapterKeyTags = @"tags";
}
- (NSNumber*)getNumberProperty:(NSString*)key {
NSDictionary* mediaProperties = [self getAllProperties];
if (mediaProperties == nil) {
NSDictionary* allProperties = [self getAllProperties];
if (allProperties == nil) {
return nil;
}
return mediaProperties[key];
return allProperties[key];
}
- (NSDictionary*)getProperties:(NSString*)key {
- (id)getProperty:(NSString*)key {
NSDictionary* allProperties = [self getAllProperties];
if (allProperties == nil) {
return nil;

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2021 Taner Sener
* Copyright (c) 2018-2022 Taner Sener
*
* This file is part of FFmpegKit.
*
@ -31,65 +31,65 @@
[FFmpegKitConfig class];
NSLog(@"Loaded ffmpeg-kit-%@-%@-%@-%@\n", [Packages getPackageName], [ArchDetect getArch], [FFmpegKitConfig getVersion], [FFmpegKitConfig getBuildDate]);
NSLog(@"Loaded ffmpeg-kit-%@-%@-%@-%@.\n", [Packages getPackageName], [ArchDetect getArch], [FFmpegKitConfig getVersion], [FFmpegKitConfig getBuildDate]);
}
+ (FFmpegSession*)executeWithArguments:(NSArray*)arguments {
FFmpegSession* session = [[FFmpegSession alloc] init:arguments];
FFmpegSession* session = [FFmpegSession create:arguments];
[FFmpegKitConfig ffmpegExecute:session];
return session;
}
+ (FFmpegSession*)executeWithArgumentsAsync:(NSArray*)arguments withCompleteCallback:(FFmpegSessionCompleteCallback)completeCallback {
FFmpegSession* session = [[FFmpegSession alloc] init:arguments withCompleteCallback:completeCallback];
FFmpegSession* session = [FFmpegSession create:arguments withCompleteCallback:completeCallback];
[FFmpegKitConfig asyncFFmpegExecute:session];
return session;
}
+ (FFmpegSession*)executeWithArgumentsAsync:(NSArray*)arguments withCompleteCallback:(FFmpegSessionCompleteCallback)completeCallback withLogCallback:(LogCallback)logCallback withStatisticsCallback:(StatisticsCallback)statisticsCallback {
FFmpegSession* session = [[FFmpegSession alloc] init:arguments withCompleteCallback:completeCallback withLogCallback:logCallback withStatisticsCallback:statisticsCallback];
FFmpegSession* session = [FFmpegSession create:arguments withCompleteCallback:completeCallback withLogCallback:logCallback withStatisticsCallback:statisticsCallback];
[FFmpegKitConfig asyncFFmpegExecute:session];
return session;
}
+ (FFmpegSession*)executeWithArgumentsAsync:(NSArray*)arguments withCompleteCallback:(FFmpegSessionCompleteCallback)completeCallback onDispatchQueue:(dispatch_queue_t)queue {
FFmpegSession* session = [[FFmpegSession alloc] init:arguments withCompleteCallback:completeCallback];
FFmpegSession* session = [FFmpegSession create:arguments withCompleteCallback:completeCallback];
[FFmpegKitConfig asyncFFmpegExecute:session onDispatchQueue:queue];
return session;
}
+ (FFmpegSession*)executeWithArgumentsAsync:(NSArray*)arguments withCompleteCallback:(FFmpegSessionCompleteCallback)completeCallback withLogCallback:(LogCallback)logCallback withStatisticsCallback:(StatisticsCallback)statisticsCallback onDispatchQueue:(dispatch_queue_t)queue {
FFmpegSession* session = [[FFmpegSession alloc] init:arguments withCompleteCallback:completeCallback withLogCallback:logCallback withStatisticsCallback:statisticsCallback];
FFmpegSession* session = [FFmpegSession create:arguments withCompleteCallback:completeCallback withLogCallback:logCallback withStatisticsCallback:statisticsCallback];
[FFmpegKitConfig asyncFFmpegExecute:session onDispatchQueue:queue];
return session;
}
+ (FFmpegSession*)execute:(NSString*)command {
FFmpegSession* session = [[FFmpegSession alloc] init:[FFmpegKitConfig parseArguments:command]];
FFmpegSession* session = [FFmpegSession create:[FFmpegKitConfig parseArguments:command]];
[FFmpegKitConfig ffmpegExecute:session];
return session;
}
+ (FFmpegSession*)executeAsync:(NSString*)command withCompleteCallback:(FFmpegSessionCompleteCallback)completeCallback {
FFmpegSession* session = [[FFmpegSession alloc] init:[FFmpegKitConfig parseArguments:command] withCompleteCallback:completeCallback];
FFmpegSession* session = [FFmpegSession create:[FFmpegKitConfig parseArguments:command] withCompleteCallback:completeCallback];
[FFmpegKitConfig asyncFFmpegExecute:session];
return session;
}
+ (FFmpegSession*)executeAsync:(NSString*)command withCompleteCallback:(FFmpegSessionCompleteCallback)completeCallback withLogCallback:(LogCallback)logCallback withStatisticsCallback:(StatisticsCallback)statisticsCallback {
FFmpegSession* session = [[FFmpegSession alloc] init:[FFmpegKitConfig parseArguments:command] withCompleteCallback:completeCallback withLogCallback:logCallback withStatisticsCallback:statisticsCallback];
FFmpegSession* session = [FFmpegSession create:[FFmpegKitConfig parseArguments:command] withCompleteCallback:completeCallback withLogCallback:logCallback withStatisticsCallback:statisticsCallback];
[FFmpegKitConfig asyncFFmpegExecute:session];
return session;
}
+ (FFmpegSession*)executeAsync:(NSString*)command withCompleteCallback:(FFmpegSessionCompleteCallback)completeCallback onDispatchQueue:(dispatch_queue_t)queue {
FFmpegSession* session = [[FFmpegSession alloc] init:[FFmpegKitConfig parseArguments:command] withCompleteCallback:completeCallback];
FFmpegSession* session = [FFmpegSession create:[FFmpegKitConfig parseArguments:command] withCompleteCallback:completeCallback];
[FFmpegKitConfig asyncFFmpegExecute:session onDispatchQueue:queue];
return session;
}
+ (FFmpegSession*)executeAsync:(NSString*)command withCompleteCallback:(FFmpegSessionCompleteCallback)completeCallback withLogCallback:(LogCallback)logCallback withStatisticsCallback:(StatisticsCallback)statisticsCallback onDispatchQueue:(dispatch_queue_t)queue {
FFmpegSession* session = [[FFmpegSession alloc] init:[FFmpegKitConfig parseArguments:command] withCompleteCallback:completeCallback withLogCallback:logCallback withStatisticsCallback:statisticsCallback];
FFmpegSession* session = [FFmpegSession create:[FFmpegKitConfig parseArguments:command] withCompleteCallback:completeCallback withLogCallback:logCallback withStatisticsCallback:statisticsCallback];
[FFmpegKitConfig asyncFFmpegExecute:session onDispatchQueue:queue];
return session;
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2021 Taner Sener
* Copyright (c) 2018-2022 Taner Sener
*
* This file is part of FFmpegKit.
*
@ -36,7 +36,7 @@
#import "SessionState.h"
/** Global library version */
NSString* const FFmpegKitVersion = @"4.5.1";
NSString* const FFmpegKitVersion = @"5.1";
/**
* Prefix of named pipes created by ffmpeg-kit.
@ -88,7 +88,7 @@ volatile int handleSIGXCPU = 1;
volatile int handleSIGPIPE = 1;
/** Holds the id of the current execution */
__thread volatile long globalSessionId = 0;
__thread long globalSessionId = 0;
/** Holds the default log level */
int configuredLogLevel = LevelAVLogInfo;
@ -104,6 +104,16 @@ typedef NS_ENUM(NSUInteger, CallbackType) {
StatisticsType
};
void deleteExpiredSessions() {
while ([sessionHistoryList count] > sessionHistorySize) {
id<Session> first = [sessionHistoryList firstObject];
if (first != nil) {
[sessionHistoryList removeObjectAtIndex:0];
[sessionHistoryMap removeObjectForKey:[NSNumber numberWithLong:[first getSessionId]]];
}
}
}
void addSessionToSessionHistory(id<Session> session) {
NSNumber* sessionIdNumber = [NSNumber numberWithLong:[session getSessionId]];
@ -111,19 +121,12 @@ void addSessionToSessionHistory(id<Session> session) {
/*
* ASYNC SESSIONS CALL THIS METHOD TWICE
* THIS CHECK PREVENTS ADDING THE SAME SESSION TWICE
* THIS CHECK PREVENTS ADDING THE SAME SESSION AGAIN
*/
if ([sessionHistoryMap objectForKey:sessionIdNumber] == nil) {
[sessionHistoryMap setObject:session forKey:sessionIdNumber];
[sessionHistoryList addObject:session];
if ([sessionHistoryList count] > sessionHistorySize) {
id<Session> first = [sessionHistoryList firstObject];
if (first != nil) {
NSNumber* key = [NSNumber numberWithLong:[first getSessionId]];
[sessionHistoryList removeObject:key];
[sessionHistoryMap removeObjectForKey:key];
}
}
deleteExpiredSessions();
}
[sessionHistoryLock unlock];
@ -862,10 +865,10 @@ int executeFFprobe(long sessionId, NSArray* arguments) {
NSString *fontDirectoryPath = [fontDirectoryArray objectAtIndex:i];
[fontConfiguration appendString: @" <dir>"];
[fontConfiguration appendString: fontDirectoryPath];
[fontConfiguration appendString: @"</dir>"];
[fontConfiguration appendString: @"</dir>\n"];
}
[fontConfiguration appendString:fontNameMappingBlock];
[fontConfiguration appendString:@"</fontconfig>"];
[fontConfiguration appendString:@"</fontconfig>\n"];
if (![fontConfiguration writeToFile:fontConfigurationFile atomically:YES encoding:NSUTF8StringEncoding error:&error]) {
NSLog(@"Failed to set font directory. Error received while saving font configuration: %@.", error);
@ -995,12 +998,20 @@ int executeFFprobe(long sessionId, NSArray* arguments) {
ReturnCode* returnCode = [[ReturnCode alloc] init:returnCodeValue];
[mediaInformationSession complete:returnCode];
if ([returnCode isValueSuccess]) {
MediaInformation* mediaInformation = [MediaInformationJsonParser from:[mediaInformationSession getAllLogsAsStringWithTimeout:waitTimeout]];
NSArray* allLogs = [mediaInformationSession getAllLogsWithTimeout:waitTimeout];
NSMutableString* ffprobeJsonOutput = [[NSMutableString alloc] init];
for (int i=0; i < [allLogs count]; i++) {
Log* log = [allLogs objectAtIndex:i];
if ([log getLevel] == LevelAVLogStdErr) {
[ffprobeJsonOutput appendString:[log getMessage]];
}
}
MediaInformation* mediaInformation = [MediaInformationJsonParser fromWithError:ffprobeJsonOutput];
[mediaInformationSession setMediaInformation:mediaInformation];
}
} @catch (NSException *exception) {
[mediaInformationSession fail:exception];
NSLog(@"Get media information execute failed: %@.%@", [FFmpegKitConfig argumentsToString:[mediaInformationSession getArguments]], [NSString stringWithFormat:@"%@", [exception callStackSymbols]]);
NSLog(@"Get media information execute failed: %@.%@", [FFmpegKitConfig argumentsToString:[mediaInformationSession getArguments]], [NSString stringWithFormat:@"\n%@\n%@", [exception userInfo], [exception callStackSymbols]]);
}
}
@ -1169,6 +1180,7 @@ int executeFFprobe(long sessionId, NSArray* arguments) {
@throw([NSException exceptionWithName:NSInvalidArgumentException reason:@"Session history size must not exceed the hard limit!" userInfo:nil]);
} else if (pSessionHistorySize > 0) {
sessionHistorySize = pSessionHistorySize;
deleteExpiredSessions();
}
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Taner Sener
* Copyright (c) 2021-2022 Taner Sener
*
* This file is part of FFmpegKit.
*
@ -34,16 +34,18 @@
* Builds a new FFmpeg session.
*
* @param arguments command arguments
* @return created session
*/
- (instancetype)init:(NSArray*)arguments;
+ (instancetype)create:(NSArray*)arguments;
/**
* Builds a new FFmpeg session.
*
* @param arguments command arguments
* @param completeCallback session specific complete callback
* @return created session
*/
- (instancetype)init:(NSArray*)arguments withCompleteCallback:(FFmpegSessionCompleteCallback)completeCallback;
+ (instancetype)create:(NSArray*)arguments withCompleteCallback:(FFmpegSessionCompleteCallback)completeCallback;
/**
* Builds a new FFmpeg session.
@ -52,8 +54,9 @@
* @param completeCallback session specific complete callback
* @param logCallback session specific log callback
* @param statisticsCallback session specific statistics callback
* @return created session
*/
- (instancetype)init:(NSArray*)arguments withCompleteCallback:(FFmpegSessionCompleteCallback)completeCallback withLogCallback:(LogCallback)logCallback withStatisticsCallback:(StatisticsCallback)statisticsCallback;
+ (instancetype)create:(NSArray*)arguments withCompleteCallback:(FFmpegSessionCompleteCallback)completeCallback withLogCallback:(LogCallback)logCallback withStatisticsCallback:(StatisticsCallback)statisticsCallback;
/**
* Builds a new FFmpeg session.
@ -63,8 +66,9 @@
* @param logCallback session specific log callback
* @param statisticsCallback session specific statistics callback
* @param logRedirectionStrategy session specific log redirection strategy
* @return created session
*/
- (instancetype)init:(NSArray*)arguments withCompleteCallback:(FFmpegSessionCompleteCallback)completeCallback withLogCallback:(LogCallback)logCallback withStatisticsCallback:(StatisticsCallback)statisticsCallback withLogRedirectionStrategy:(LogRedirectionStrategy)logRedirectionStrategy;
+ (instancetype)create:(NSArray*)arguments withCompleteCallback:(FFmpegSessionCompleteCallback)completeCallback withLogCallback:(LogCallback)logCallback withStatisticsCallback:(StatisticsCallback)statisticsCallback withLogRedirectionStrategy:(LogRedirectionStrategy)logRedirectionStrategy;
/**
* Returns the session specific statistics callback.

@ -33,46 +33,20 @@
// EMPTY INITIALIZE
}
- (instancetype)init:(NSArray*)arguments {
self = [super init:arguments withLogCallback:nil withLogRedirectionStrategy:[FFmpegKitConfig getLogRedirectionStrategy]];
if (self) {
_statisticsCallback = nil;
_completeCallback = nil;
_statistics = [[NSMutableArray alloc] init];
_statisticsLock = [[NSRecursiveLock alloc] init];
}
return self;
+ (instancetype)create:(NSArray*)arguments {
return [[self alloc] init:arguments withCompleteCallback:nil withLogCallback:nil withStatisticsCallback:nil withLogRedirectionStrategy:[FFmpegKitConfig getLogRedirectionStrategy]];
}
- (instancetype)init:(NSArray*)arguments withCompleteCallback:(FFmpegSessionCompleteCallback)completeCallback {
self = [super init:arguments withLogCallback:nil withLogRedirectionStrategy:[FFmpegKitConfig getLogRedirectionStrategy]];
if (self) {
_statisticsCallback = nil;
_completeCallback = completeCallback;
_statistics = [[NSMutableArray alloc] init];
_statisticsLock = [[NSRecursiveLock alloc] init];
}
return self;
+ (instancetype)create:(NSArray*)arguments withCompleteCallback:(FFmpegSessionCompleteCallback)completeCallback {
return [[self alloc] init:arguments withCompleteCallback:completeCallback withLogCallback:nil withStatisticsCallback:nil withLogRedirectionStrategy:[FFmpegKitConfig getLogRedirectionStrategy]];
}
- (instancetype)init:(NSArray*)arguments withCompleteCallback:(FFmpegSessionCompleteCallback)completeCallback withLogCallback:(LogCallback)logCallback withStatisticsCallback:(StatisticsCallback)statisticsCallback {
self = [super init:arguments withLogCallback:logCallback withLogRedirectionStrategy:[FFmpegKitConfig getLogRedirectionStrategy]];
if (self) {
_statisticsCallback = statisticsCallback;
_completeCallback = completeCallback;
_statistics = [[NSMutableArray alloc] init];
_statisticsLock = [[NSRecursiveLock alloc] init];
}
+ (instancetype)create:(NSArray*)arguments withCompleteCallback:(FFmpegSessionCompleteCallback)completeCallback withLogCallback:(LogCallback)logCallback withStatisticsCallback:(StatisticsCallback)statisticsCallback {
return [[self alloc] init:arguments withCompleteCallback:completeCallback withLogCallback:logCallback withStatisticsCallback:statisticsCallback withLogRedirectionStrategy:[FFmpegKitConfig getLogRedirectionStrategy]];
}
return self;
+ (instancetype)create:(NSArray*)arguments withCompleteCallback:(FFmpegSessionCompleteCallback)completeCallback withLogCallback:(LogCallback)logCallback withStatisticsCallback:(StatisticsCallback)statisticsCallback withLogRedirectionStrategy:(LogRedirectionStrategy)logRedirectionStrategy {
return [[self alloc] init:arguments withCompleteCallback:completeCallback withLogCallback:logCallback withStatisticsCallback:statisticsCallback withLogRedirectionStrategy:logRedirectionStrategy];
}
- (instancetype)init:(NSArray*)arguments withCompleteCallback:(FFmpegSessionCompleteCallback)completeCallback withLogCallback:(LogCallback)logCallback withStatisticsCallback:(StatisticsCallback)statisticsCallback withLogRedirectionStrategy:(LogRedirectionStrategy)logRedirectionStrategy {

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020-2021 Taner Sener
* Copyright (c) 2020-2022 Taner Sener
*
* This file is part of FFmpegKit.
*
@ -33,121 +33,121 @@
}
+ (FFprobeSession*)executeWithArguments:(NSArray*)arguments {
FFprobeSession* session = [[FFprobeSession alloc] init:arguments];
FFprobeSession* session = [FFprobeSession create:arguments];
[FFmpegKitConfig ffprobeExecute:session];
return session;
}
+ (FFprobeSession*)executeWithArgumentsAsync:(NSArray*)arguments withCompleteCallback:(FFprobeSessionCompleteCallback)completeCallback {
FFprobeSession* session = [[FFprobeSession alloc] init:arguments withCompleteCallback:completeCallback];
FFprobeSession* session = [FFprobeSession create:arguments withCompleteCallback:completeCallback];
[FFmpegKitConfig asyncFFprobeExecute:session];
return session;
}
+ (FFprobeSession*)executeWithArgumentsAsync:(NSArray*)arguments withCompleteCallback:(FFprobeSessionCompleteCallback)completeCallback withLogCallback:(LogCallback)logCallback {
FFprobeSession* session = [[FFprobeSession alloc] init:arguments withCompleteCallback:completeCallback withLogCallback:logCallback];
FFprobeSession* session = [FFprobeSession create:arguments withCompleteCallback:completeCallback withLogCallback:logCallback];
[FFmpegKitConfig asyncFFprobeExecute:session];
return session;
}
+ (FFprobeSession*)executeWithArgumentsAsync:(NSArray*)arguments withCompleteCallback:(FFprobeSessionCompleteCallback)completeCallback onDispatchQueue:(dispatch_queue_t)queue {
FFprobeSession* session = [[FFprobeSession alloc] init:arguments withCompleteCallback:completeCallback];
FFprobeSession* session = [FFprobeSession create:arguments withCompleteCallback:completeCallback];
[FFmpegKitConfig asyncFFprobeExecute:session onDispatchQueue:queue];
return session;
}
+ (FFprobeSession*)executeWithArgumentsAsync:(NSArray*)arguments withCompleteCallback:(FFprobeSessionCompleteCallback)completeCallback withLogCallback:(LogCallback)logCallback onDispatchQueue:(dispatch_queue_t)queue {
FFprobeSession* session = [[FFprobeSession alloc] init:arguments withCompleteCallback:completeCallback withLogCallback:logCallback];
FFprobeSession* session = [FFprobeSession create:arguments withCompleteCallback:completeCallback withLogCallback:logCallback];
[FFmpegKitConfig asyncFFprobeExecute:session onDispatchQueue:queue];
return session;
}
+ (FFprobeSession*)execute:(NSString*)command {
FFprobeSession* session = [[FFprobeSession alloc] init:[FFmpegKitConfig parseArguments:command]];
FFprobeSession* session = [FFprobeSession create:[FFmpegKitConfig parseArguments:command]];
[FFmpegKitConfig ffprobeExecute:session];
return session;
}
+ (FFprobeSession*)executeAsync:(NSString*)command withCompleteCallback:(FFprobeSessionCompleteCallback)completeCallback {
FFprobeSession* session = [[FFprobeSession alloc] init:[FFmpegKitConfig parseArguments:command] withCompleteCallback:completeCallback];
FFprobeSession* session = [FFprobeSession create:[FFmpegKitConfig parseArguments:command] withCompleteCallback:completeCallback];
[FFmpegKitConfig asyncFFprobeExecute:session];
return session;
}
+ (FFprobeSession*)executeAsync:(NSString*)command withCompleteCallback:(FFprobeSessionCompleteCallback)completeCallback withLogCallback:(LogCallback)logCallback {
FFprobeSession* session = [[FFprobeSession alloc] init:[FFmpegKitConfig parseArguments:command] withCompleteCallback:completeCallback withLogCallback:logCallback];
FFprobeSession* session = [FFprobeSession create:[FFmpegKitConfig parseArguments:command] withCompleteCallback:completeCallback withLogCallback:logCallback];
[FFmpegKitConfig asyncFFprobeExecute:session];
return session;
}
+ (FFprobeSession*)executeAsync:(NSString*)command withCompleteCallback:(FFprobeSessionCompleteCallback)completeCallback onDispatchQueue:(dispatch_queue_t)queue {
FFprobeSession* session = [[FFprobeSession alloc] init:[FFmpegKitConfig parseArguments:command] withCompleteCallback:completeCallback];
FFprobeSession* session = [FFprobeSession create:[FFmpegKitConfig parseArguments:command] withCompleteCallback:completeCallback];
[FFmpegKitConfig asyncFFprobeExecute:session onDispatchQueue:queue];
return session;
}
+ (FFprobeSession*)executeAsync:(NSString*)command withCompleteCallback:(FFprobeSessionCompleteCallback)completeCallback withLogCallback:(LogCallback)logCallback onDispatchQueue:(dispatch_queue_t)queue {
FFprobeSession* session = [[FFprobeSession alloc] init:[FFmpegKitConfig parseArguments:command] withCompleteCallback:completeCallback withLogCallback:logCallback];
FFprobeSession* session = [FFprobeSession create:[FFmpegKitConfig parseArguments:command] withCompleteCallback:completeCallback withLogCallback:logCallback];
[FFmpegKitConfig asyncFFprobeExecute:session onDispatchQueue:queue];
return session;
}
+ (MediaInformationSession*)getMediaInformation:(NSString*)path {
NSArray* arguments = [FFprobeKit defaultGetMediaInformationCommandArguments:path];
MediaInformationSession* session = [[MediaInformationSession alloc] init:arguments];
MediaInformationSession* session = [MediaInformationSession create:arguments];
[FFmpegKitConfig getMediaInformationExecute:session withTimeout:AbstractSessionDefaultTimeoutForAsynchronousMessagesInTransmit];
return session;
}
+ (MediaInformationSession*)getMediaInformation:(NSString*)path withTimeout:(int)waitTimeout {
NSArray* arguments = [FFprobeKit defaultGetMediaInformationCommandArguments:path];
MediaInformationSession* session = [[MediaInformationSession alloc] init:arguments];
MediaInformationSession* session = [MediaInformationSession create:arguments];
[FFmpegKitConfig getMediaInformationExecute:session withTimeout:waitTimeout];
return session;
}
+ (MediaInformationSession*)getMediaInformationAsync:(NSString*)path withCompleteCallback:(MediaInformationSessionCompleteCallback)completeCallback {
NSArray* arguments = [FFprobeKit defaultGetMediaInformationCommandArguments:path];
MediaInformationSession* session = [[MediaInformationSession alloc] init:arguments withCompleteCallback:completeCallback];
MediaInformationSession* session = [MediaInformationSession create:arguments withCompleteCallback:completeCallback];
[FFmpegKitConfig asyncGetMediaInformationExecute:session withTimeout:AbstractSessionDefaultTimeoutForAsynchronousMessagesInTransmit];
return session;
}
+ (MediaInformationSession*)getMediaInformationAsync:(NSString*)path withCompleteCallback:(MediaInformationSessionCompleteCallback)completeCallback withLogCallback:(LogCallback)logCallback withTimeout:(int)waitTimeout {
NSArray* arguments = [FFprobeKit defaultGetMediaInformationCommandArguments:path];
MediaInformationSession* session = [[MediaInformationSession alloc] init:arguments withCompleteCallback:completeCallback withLogCallback:logCallback];
MediaInformationSession* session = [MediaInformationSession create:arguments withCompleteCallback:completeCallback withLogCallback:logCallback];
[FFmpegKitConfig asyncGetMediaInformationExecute:session withTimeout:waitTimeout];
return session;
}
+ (MediaInformationSession*)getMediaInformationAsync:(NSString*)path withCompleteCallback:(MediaInformationSessionCompleteCallback)completeCallback onDispatchQueue:(dispatch_queue_t)queue {
NSArray* arguments = [FFprobeKit defaultGetMediaInformationCommandArguments:path];
MediaInformationSession* session = [[MediaInformationSession alloc] init:arguments withCompleteCallback:completeCallback];
MediaInformationSession* session = [MediaInformationSession create:arguments withCompleteCallback:completeCallback];
[FFmpegKitConfig asyncGetMediaInformationExecute:session onDispatchQueue:queue withTimeout:AbstractSessionDefaultTimeoutForAsynchronousMessagesInTransmit];
return session;
}
+ (MediaInformationSession*)getMediaInformationAsync:(NSString*)path withCompleteCallback:(MediaInformationSessionCompleteCallback)completeCallback withLogCallback:(LogCallback)logCallback onDispatchQueue:(dispatch_queue_t)queue withTimeout:(int)waitTimeout {
NSArray* arguments = [FFprobeKit defaultGetMediaInformationCommandArguments:path];
MediaInformationSession* session = [[MediaInformationSession alloc] init:arguments withCompleteCallback:completeCallback];
MediaInformationSession* session = [MediaInformationSession create:arguments withCompleteCallback:completeCallback];
[FFmpegKitConfig asyncGetMediaInformationExecute:session onDispatchQueue:queue withTimeout:waitTimeout];
return session;
}
+ (MediaInformationSession*)getMediaInformationFromCommand:(NSString*)command {
MediaInformationSession* session = [[MediaInformationSession alloc] init:[FFmpegKitConfig parseArguments:command]];
MediaInformationSession* session = [MediaInformationSession create:[FFmpegKitConfig parseArguments:command]];
[FFmpegKitConfig getMediaInformationExecute:session withTimeout:AbstractSessionDefaultTimeoutForAsynchronousMessagesInTransmit];
return session;
}
+ (MediaInformationSession*)getMediaInformationFromCommandAsync:(NSString*)command withCompleteCallback:(MediaInformationSessionCompleteCallback)completeCallback withLogCallback:(LogCallback)logCallback onDispatchQueue:(dispatch_queue_t)queue withTimeout:(int)waitTimeout {
MediaInformationSession* session = [[MediaInformationSession alloc] init:[FFmpegKitConfig parseArguments:command] withCompleteCallback:completeCallback withLogCallback:logCallback];
MediaInformationSession* session = [MediaInformationSession create:[FFmpegKitConfig parseArguments:command] withCompleteCallback:completeCallback withLogCallback:logCallback];
[FFmpegKitConfig asyncGetMediaInformationExecute:session onDispatchQueue:queue withTimeout:waitTimeout];
return session;
}
+ (MediaInformationSession*)getMediaInformationFromCommandArgumentsAsync:(NSArray*)arguments withCompleteCallback:(MediaInformationSessionCompleteCallback)completeCallback withLogCallback:(LogCallback)logCallback onDispatchQueue:(dispatch_queue_t)queue withTimeout:(int)waitTimeout {
MediaInformationSession* session = [[MediaInformationSession alloc] init:arguments withCompleteCallback:completeCallback withLogCallback:logCallback];
MediaInformationSession* session = [MediaInformationSession create:arguments withCompleteCallback:completeCallback withLogCallback:logCallback];
[FFmpegKitConfig asyncGetMediaInformationExecute:session onDispatchQueue:queue withTimeout:waitTimeout];
return session;
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Taner Sener
* Copyright (c) 2021-2022 Taner Sener
*
* This file is part of FFmpegKit.
*
@ -33,16 +33,18 @@
* Builds a new FFprobe session.
*
* @param arguments command arguments
* @return created session
*/
- (instancetype)init:(NSArray*)arguments;
+ (instancetype)create:(NSArray*)arguments;
/**
* Builds a new FFprobe session.
*
* @param arguments command arguments
* @param completeCallback session specific complete callback
* @return created session
*/
- (instancetype)init:(NSArray*)arguments withCompleteCallback:(FFprobeSessionCompleteCallback)completeCallback;
+ (instancetype)create:(NSArray*)arguments withCompleteCallback:(FFprobeSessionCompleteCallback)completeCallback;
/**
* Builds a new FFprobe session.
@ -50,8 +52,9 @@
* @param arguments command arguments
* @param completeCallback session specific complete callback
* @param logCallback session specific log callback
* @return created session
*/
- (instancetype)init:(NSArray*)arguments withCompleteCallback:(FFprobeSessionCompleteCallback)completeCallback withLogCallback:(LogCallback)logCallback;
+ (instancetype)create:(NSArray*)arguments withCompleteCallback:(FFprobeSessionCompleteCallback)completeCallback withLogCallback:(LogCallback)logCallback;
/**
* Builds a new FFprobe session.
@ -60,8 +63,9 @@
* @param completeCallback session specific complete callback
* @param logCallback session specific log callback
* @param logRedirectionStrategy session specific log redirection strategy
* @return created session
*/
- (instancetype)init:(NSArray*)arguments withCompleteCallback:(FFprobeSessionCompleteCallback)completeCallback withLogCallback:(LogCallback)logCallback withLogRedirectionStrategy:(LogRedirectionStrategy)logRedirectionStrategy;
+ (instancetype)create:(NSArray*)arguments withCompleteCallback:(FFprobeSessionCompleteCallback)completeCallback withLogCallback:(LogCallback)logCallback withLogRedirectionStrategy:(LogRedirectionStrategy)logRedirectionStrategy;
/**
* Returns the session specific complete callback.

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Taner Sener
* Copyright (c) 2021-2022 Taner Sener
*
* This file is part of FFmpegKit.
*
@ -29,37 +29,20 @@
// EMPTY INITIALIZE
}
- (instancetype)init:(NSArray*)arguments {
self = [super init:arguments withLogCallback:nil withLogRedirectionStrategy:[FFmpegKitConfig getLogRedirectionStrategy]];
if (self) {
_completeCallback = nil;
}
return self;
+ (instancetype)create:(NSArray*)arguments {
return [[self alloc] init:arguments withCompleteCallback:nil withLogCallback:nil withLogRedirectionStrategy:[FFmpegKitConfig getLogRedirectionStrategy]];
}
- (instancetype)init:(NSArray*)arguments withCompleteCallback:(FFprobeSessionCompleteCallback)completeCallback {
self = [super init:arguments withLogCallback:nil withLogRedirectionStrategy:[FFmpegKitConfig getLogRedirectionStrategy]];
if (self) {
_completeCallback = completeCallback;
}
return self;
+ (instancetype)create:(NSArray*)arguments withCompleteCallback:(FFprobeSessionCompleteCallback)completeCallback {
return [[self alloc] init:arguments withCompleteCallback:completeCallback withLogCallback:nil withLogRedirectionStrategy:[FFmpegKitConfig getLogRedirectionStrategy]];
}
- (instancetype)init:(NSArray*)arguments withCompleteCallback:(FFprobeSessionCompleteCallback)completeCallback withLogCallback:(LogCallback)logCallback {
self = [super init:arguments withLogCallback:logCallback withLogRedirectionStrategy:[FFmpegKitConfig getLogRedirectionStrategy]];
if (self) {
_completeCallback = completeCallback;
}
+ (instancetype)create:(NSArray*)arguments withCompleteCallback:(FFprobeSessionCompleteCallback)completeCallback withLogCallback:(LogCallback)logCallback {
return [[self alloc] init:arguments withCompleteCallback:completeCallback withLogCallback:logCallback withLogRedirectionStrategy:[FFmpegKitConfig getLogRedirectionStrategy]];
}
return self;
+ (instancetype)create:(NSArray*)arguments withCompleteCallback:(FFprobeSessionCompleteCallback)completeCallback withLogCallback:(LogCallback)logCallback withLogRedirectionStrategy:(LogRedirectionStrategy)logRedirectionStrategy {
return [[self alloc] init:arguments withCompleteCallback:completeCallback withLogCallback:logCallback withLogRedirectionStrategy:logRedirectionStrategy];
}
- (instancetype)init:(NSArray*)arguments withCompleteCallback:(FFprobeSessionCompleteCallback)completeCallback withLogCallback:(LogCallback)logCallback withLogRedirectionStrategy:(LogRedirectionStrategy)logRedirectionStrategy {

@ -25,12 +25,10 @@ libffmpegkit_la_SOURCES = \
fftools_ffmpeg.c \
fftools_ffmpeg_filter.c \
fftools_ffmpeg_hw.c \
fftools_ffmpeg_mux.c \
fftools_ffmpeg_opt.c \
fftools_ffprobe.c
if FFMPEGKIT_VIDEOTOOLBOX
libffmpegkit_la_SOURCES += fftools_ffmpeg_videotoolbox.c
endif
fftools_ffprobe.c \
fftools_opt_common.c
include_HEADERS = \
AbstractSession.h \
@ -61,7 +59,9 @@ include_HEADERS = \
StreamInformation.h \
ffmpegkit_exception.h \
fftools_cmdutils.h \
fftools_ffmpeg.h
fftools_ffmpeg.h \
fftools_fopen_utf8.h \
fftools_opt_common.h
libffmpegkit_la_CFLAGS = $(CFLAGS)
libffmpegkit_la_OBJCFLAGS = $(CFLAGS)

@ -89,7 +89,6 @@ PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
@FFMPEGKIT_VIDEOTOOLBOX_TRUE@am__append_1 = fftools_ffmpeg_videotoolbox.c
subdir = src
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
@ -133,16 +132,6 @@ am__uninstall_files_from_dir = { \
am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)"
LTLIBRARIES = $(lib_LTLIBRARIES)
libffmpegkit_la_DEPENDENCIES =
am__libffmpegkit_la_SOURCES_DIST = AbstractSession.m ArchDetect.m \
AtomicLong.m Chapter.m FFmpegKit.m FFmpegKitConfig.m \
FFmpegSession.m FFprobeKit.m FFprobeSession.m Log.m \
MediaInformation.m MediaInformationJsonParser.m \
MediaInformationSession.m Packages.m ReturnCode.m Statistics.m \
StreamInformation.m ffmpegkit_exception.m fftools_cmdutils.c \
fftools_ffmpeg.c fftools_ffmpeg_filter.c fftools_ffmpeg_hw.c \
fftools_ffmpeg_opt.c fftools_ffprobe.c \
fftools_ffmpeg_videotoolbox.c
@FFMPEGKIT_VIDEOTOOLBOX_TRUE@am__objects_1 = libffmpegkit_la-fftools_ffmpeg_videotoolbox.lo
am_libffmpegkit_la_OBJECTS = libffmpegkit_la-AbstractSession.lo \
libffmpegkit_la-ArchDetect.lo libffmpegkit_la-AtomicLong.lo \
libffmpegkit_la-Chapter.lo libffmpegkit_la-FFmpegKit.lo \
@ -160,8 +149,10 @@ am_libffmpegkit_la_OBJECTS = libffmpegkit_la-AbstractSession.lo \
libffmpegkit_la-fftools_ffmpeg.lo \
libffmpegkit_la-fftools_ffmpeg_filter.lo \
libffmpegkit_la-fftools_ffmpeg_hw.lo \
libffmpegkit_la-fftools_ffmpeg_mux.lo \
libffmpegkit_la-fftools_ffmpeg_opt.lo \
libffmpegkit_la-fftools_ffprobe.lo $(am__objects_1)
libffmpegkit_la-fftools_ffprobe.lo \
libffmpegkit_la-fftools_opt_common.lo
libffmpegkit_la_OBJECTS = $(am_libffmpegkit_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
@ -208,9 +199,10 @@ am__depfiles_remade = ./$(DEPDIR)/libffmpegkit_la-AbstractSession.Plo \
./$(DEPDIR)/libffmpegkit_la-fftools_ffmpeg.Plo \
./$(DEPDIR)/libffmpegkit_la-fftools_ffmpeg_filter.Plo \
./$(DEPDIR)/libffmpegkit_la-fftools_ffmpeg_hw.Plo \
./$(DEPDIR)/libffmpegkit_la-fftools_ffmpeg_mux.Plo \
./$(DEPDIR)/libffmpegkit_la-fftools_ffmpeg_opt.Plo \
./$(DEPDIR)/libffmpegkit_la-fftools_ffmpeg_videotoolbox.Plo \
./$(DEPDIR)/libffmpegkit_la-fftools_ffprobe.Plo
./$(DEPDIR)/libffmpegkit_la-fftools_ffprobe.Plo \
./$(DEPDIR)/libffmpegkit_la-fftools_opt_common.Plo
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
@ -249,7 +241,7 @@ am__v_OBJCLD_ = $(am__v_OBJCLD_@AM_DEFAULT_V@)
am__v_OBJCLD_0 = @echo " OBJCLD " $@;
am__v_OBJCLD_1 =
SOURCES = $(libffmpegkit_la_SOURCES)
DIST_SOURCES = $(am__libffmpegkit_la_SOURCES_DIST)
DIST_SOURCES = $(libffmpegkit_la_SOURCES)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
@ -303,6 +295,7 @@ ETAGS = @ETAGS@
EXEEXT = @EXEEXT@
FFMPEG_FRAMEWORKS = @FFMPEG_FRAMEWORKS@
FGREP = @FGREP@
FILECMD = @FILECMD@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
@ -401,14 +394,34 @@ top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
lib_LTLIBRARIES = libffmpegkit.la
libffmpegkit_la_LIBADD = @FFMPEG_FRAMEWORKS@
libffmpegkit_la_SOURCES = AbstractSession.m ArchDetect.m AtomicLong.m \
Chapter.m FFmpegKit.m FFmpegKitConfig.m FFmpegSession.m \
FFprobeKit.m FFprobeSession.m Log.m MediaInformation.m \
MediaInformationJsonParser.m MediaInformationSession.m \
Packages.m ReturnCode.m Statistics.m StreamInformation.m \
ffmpegkit_exception.m fftools_cmdutils.c fftools_ffmpeg.c \
fftools_ffmpeg_filter.c fftools_ffmpeg_hw.c \
fftools_ffmpeg_opt.c fftools_ffprobe.c $(am__append_1)
libffmpegkit_la_SOURCES = \
AbstractSession.m \
ArchDetect.m \
AtomicLong.m \
Chapter.m \
FFmpegKit.m \
FFmpegKitConfig.m \
FFmpegSession.m \
FFprobeKit.m \
FFprobeSession.m \
Log.m \
MediaInformation.m \
MediaInformationJsonParser.m \
MediaInformationSession.m \
Packages.m \
ReturnCode.m \
Statistics.m \
StreamInformation.m \
ffmpegkit_exception.m \
fftools_cmdutils.c \
fftools_ffmpeg.c \
fftools_ffmpeg_filter.c \
fftools_ffmpeg_hw.c \
fftools_ffmpeg_mux.c \
fftools_ffmpeg_opt.c \
fftools_ffprobe.c \
fftools_opt_common.c
include_HEADERS = \
AbstractSession.h \
ArchDetect.h \
@ -438,7 +451,9 @@ include_HEADERS = \
StreamInformation.h \
ffmpegkit_exception.h \
fftools_cmdutils.h \
fftools_ffmpeg.h
fftools_ffmpeg.h \
fftools_fopen_utf8.h \
fftools_opt_common.h
libffmpegkit_la_CFLAGS = $(CFLAGS)
libffmpegkit_la_OBJCFLAGS = $(CFLAGS)
@ -544,9 +559,10 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libffmpegkit_la-fftools_ffmpeg.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libffmpegkit_la-fftools_ffmpeg_filter.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libffmpegkit_la-fftools_ffmpeg_hw.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libffmpegkit_la-fftools_ffmpeg_mux.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libffmpegkit_la-fftools_ffmpeg_opt.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libffmpegkit_la-fftools_ffmpeg_videotoolbox.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libffmpegkit_la-fftools_ffprobe.Plo@am__quote@ # am--include-marker
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libffmpegkit_la-fftools_opt_common.Plo@am__quote@ # am--include-marker
$(am__depfiles_remade):
@$(MKDIR_P) $(@D)
@ -606,6 +622,13 @@ libffmpegkit_la-fftools_ffmpeg_hw.lo: fftools_ffmpeg_hw.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libffmpegkit_la_CFLAGS) $(CFLAGS) -c -o libffmpegkit_la-fftools_ffmpeg_hw.lo `test -f 'fftools_ffmpeg_hw.c' || echo '$(srcdir)/'`fftools_ffmpeg_hw.c
libffmpegkit_la-fftools_ffmpeg_mux.lo: fftools_ffmpeg_mux.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libffmpegkit_la_CFLAGS) $(CFLAGS) -MT libffmpegkit_la-fftools_ffmpeg_mux.lo -MD -MP -MF $(DEPDIR)/libffmpegkit_la-fftools_ffmpeg_mux.Tpo -c -o libffmpegkit_la-fftools_ffmpeg_mux.lo `test -f 'fftools_ffmpeg_mux.c' || echo '$(srcdir)/'`fftools_ffmpeg_mux.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libffmpegkit_la-fftools_ffmpeg_mux.Tpo $(DEPDIR)/libffmpegkit_la-fftools_ffmpeg_mux.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fftools_ffmpeg_mux.c' object='libffmpegkit_la-fftools_ffmpeg_mux.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libffmpegkit_la_CFLAGS) $(CFLAGS) -c -o libffmpegkit_la-fftools_ffmpeg_mux.lo `test -f 'fftools_ffmpeg_mux.c' || echo '$(srcdir)/'`fftools_ffmpeg_mux.c
libffmpegkit_la-fftools_ffmpeg_opt.lo: fftools_ffmpeg_opt.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libffmpegkit_la_CFLAGS) $(CFLAGS) -MT libffmpegkit_la-fftools_ffmpeg_opt.lo -MD -MP -MF $(DEPDIR)/libffmpegkit_la-fftools_ffmpeg_opt.Tpo -c -o libffmpegkit_la-fftools_ffmpeg_opt.lo `test -f 'fftools_ffmpeg_opt.c' || echo '$(srcdir)/'`fftools_ffmpeg_opt.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libffmpegkit_la-fftools_ffmpeg_opt.Tpo $(DEPDIR)/libffmpegkit_la-fftools_ffmpeg_opt.Plo
@ -620,12 +643,12 @@ libffmpegkit_la-fftools_ffprobe.lo: fftools_ffprobe.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libffmpegkit_la_CFLAGS) $(CFLAGS) -c -o libffmpegkit_la-fftools_ffprobe.lo `test -f 'fftools_ffprobe.c' || echo '$(srcdir)/'`fftools_ffprobe.c
libffmpegkit_la-fftools_ffmpeg_videotoolbox.lo: fftools_ffmpeg_videotoolbox.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libffmpegkit_la_CFLAGS) $(CFLAGS) -MT libffmpegkit_la-fftools_ffmpeg_videotoolbox.lo -MD -MP -MF $(DEPDIR)/libffmpegkit_la-fftools_ffmpeg_videotoolbox.Tpo -c -o libffmpegkit_la-fftools_ffmpeg_videotoolbox.lo `test -f 'fftools_ffmpeg_videotoolbox.c' || echo '$(srcdir)/'`fftools_ffmpeg_videotoolbox.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libffmpegkit_la-fftools_ffmpeg_videotoolbox.Tpo $(DEPDIR)/libffmpegkit_la-fftools_ffmpeg_videotoolbox.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fftools_ffmpeg_videotoolbox.c' object='libffmpegkit_la-fftools_ffmpeg_videotoolbox.lo' libtool=yes @AMDEPBACKSLASH@
libffmpegkit_la-fftools_opt_common.lo: fftools_opt_common.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libffmpegkit_la_CFLAGS) $(CFLAGS) -MT libffmpegkit_la-fftools_opt_common.lo -MD -MP -MF $(DEPDIR)/libffmpegkit_la-fftools_opt_common.Tpo -c -o libffmpegkit_la-fftools_opt_common.lo `test -f 'fftools_opt_common.c' || echo '$(srcdir)/'`fftools_opt_common.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libffmpegkit_la-fftools_opt_common.Tpo $(DEPDIR)/libffmpegkit_la-fftools_opt_common.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='fftools_opt_common.c' object='libffmpegkit_la-fftools_opt_common.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libffmpegkit_la_CFLAGS) $(CFLAGS) -c -o libffmpegkit_la-fftools_ffmpeg_videotoolbox.lo `test -f 'fftools_ffmpeg_videotoolbox.c' || echo '$(srcdir)/'`fftools_ffmpeg_videotoolbox.c
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libffmpegkit_la_CFLAGS) $(CFLAGS) -c -o libffmpegkit_la-fftools_opt_common.lo `test -f 'fftools_opt_common.c' || echo '$(srcdir)/'`fftools_opt_common.c
.m.o:
@am__fastdepOBJC_TRUE@ $(AM_V_OBJC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
@ -953,9 +976,10 @@ distclean: distclean-am
-rm -f ./$(DEPDIR)/libffmpegkit_la-fftools_ffmpeg.Plo
-rm -f ./$(DEPDIR)/libffmpegkit_la-fftools_ffmpeg_filter.Plo
-rm -f ./$(DEPDIR)/libffmpegkit_la-fftools_ffmpeg_hw.Plo
-rm -f ./$(DEPDIR)/libffmpegkit_la-fftools_ffmpeg_mux.Plo
-rm -f ./$(DEPDIR)/libffmpegkit_la-fftools_ffmpeg_opt.Plo
-rm -f ./$(DEPDIR)/libffmpegkit_la-fftools_ffmpeg_videotoolbox.Plo
-rm -f ./$(DEPDIR)/libffmpegkit_la-fftools_ffprobe.Plo
-rm -f ./$(DEPDIR)/libffmpegkit_la-fftools_opt_common.Plo
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
@ -1023,9 +1047,10 @@ maintainer-clean: maintainer-clean-am
-rm -f ./$(DEPDIR)/libffmpegkit_la-fftools_ffmpeg.Plo
-rm -f ./$(DEPDIR)/libffmpegkit_la-fftools_ffmpeg_filter.Plo
-rm -f ./$(DEPDIR)/libffmpegkit_la-fftools_ffmpeg_hw.Plo
-rm -f ./$(DEPDIR)/libffmpegkit_la-fftools_ffmpeg_mux.Plo
-rm -f ./$(DEPDIR)/libffmpegkit_la-fftools_ffmpeg_opt.Plo
-rm -f ./$(DEPDIR)/libffmpegkit_la-fftools_ffmpeg_videotoolbox.Plo
-rm -f ./$(DEPDIR)/libffmpegkit_la-fftools_ffprobe.Plo
-rm -f ./$(DEPDIR)/libffmpegkit_la-fftools_opt_common.Plo
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2021 Taner Sener
* Copyright (c) 2018-2022 Taner Sener
*
* This file is part of FFmpegKit.
*
@ -65,7 +65,7 @@ extern NSString* const MediaKeyTags;
/**
* Returns duration.
*
* @return media duration in milliseconds
* @return media duration in "seconds.microseconds" format
*/
- (NSString*)getDuration;
@ -112,32 +112,53 @@ extern NSString* const MediaKeyTags;
- (NSArray*)getChapters;
/**
* Returns the media property associated with the key.
* Returns the property associated with the key.
*
* @return media property as string or nil if the key is not found
* @return property as string or nil if the key is not found
*/
- (NSString*)getStringProperty:(NSString*)key;
/**
* Returns the media property associated with the key.
* Returns the property associated with the key.
*
* @return media property as number or nil if the key is not found
* @return property as number or nil if the key is not found
*/
- (NSNumber*)getNumberProperty:(NSString*)key;
/**
* Returns the media properties associated with the key.
* Returns the property associated with the key.
*
* @return media properties in a dictionary or nil if the key is not found
* @return property as id or nil if the key is not found
*/
- (NSDictionary*)getProperties:(NSString*)key;
- (id)getProperty:(NSString*)key;
/**
* Returns all media properties.
* Returns the format property associated with the key.
*
* @return all media properties in a dictionary or nil if no media properties are defined
* @return format property as string or nil if the key is not found
*/
- (NSString*)getStringFormatProperty:(NSString*)key;
/**
* Returns the format property associated with the key.
*
* @return format property as number or nil if the key is not found
*/
- (NSNumber*)getNumberFormatProperty:(NSString*)key;
/**
* Returns the format property associated with the key.
*
* @return format property as id or nil if the key is not found
*/
- (id)getFormatProperty:(NSString*)key;
/**
* Returns all format properties defined.
*
* @return all format properties in a dictionary or nil if no format properties are defined
*/
- (NSDictionary*)getMediaProperties;
- (NSDictionary*)getFormatProperties;
/**
* Returns all properties defined.

@ -19,7 +19,7 @@
#import "MediaInformation.h"
NSString* const MediaKeyMediaProperties = @"format";
NSString* const MediaKeyFormatProperties = @"format";
NSString* const MediaKeyFilename = @"filename";
NSString* const MediaKeyFormat = @"format_name";
NSString* const MediaKeyFormatLong = @"format_long_name";
@ -60,35 +60,35 @@ NSString* const MediaKeyTags = @"tags";
}
- (NSString*)getFilename {
return [self getStringProperty:MediaKeyFilename];
return [self getStringFormatProperty:MediaKeyFilename];
}
- (NSString*)getFormat {
return [self getStringProperty:MediaKeyFormat];
return [self getStringFormatProperty:MediaKeyFormat];
}
- (NSString*)getLongFormat {
return [self getStringProperty:MediaKeyFormatLong];
return [self getStringFormatProperty:MediaKeyFormatLong];
}
- (NSString*)getStartTime {
return [self getStringProperty:MediaKeyStartTime];
return [self getStringFormatProperty:MediaKeyStartTime];
}
- (NSString*)getDuration {
return [self getStringProperty:MediaKeyDuration];
return [self getStringFormatProperty:MediaKeyDuration];
}
- (NSString*)getSize {
return [self getStringProperty:MediaKeySize];
return [self getStringFormatProperty:MediaKeySize];
}
- (NSString*)getBitrate {
return [self getStringProperty:MediaKeyBitRate];
return [self getStringFormatProperty:MediaKeyBitRate];
}
- (NSDictionary*)getTags {
return [self getProperties:MediaKeyTags];
return [self getFormatProperty:MediaKeyTags];
}
- (NSArray*)getStreams {
@ -100,34 +100,61 @@ NSString* const MediaKeyTags = @"tags";
}
- (NSString*)getStringProperty:(NSString*)key {
NSDictionary* mediaProperties = [self getMediaProperties];
if (mediaProperties == nil) {
NSDictionary* allProperties = [self getAllProperties];
if (allProperties == nil) {
return nil;
}
return mediaProperties[key];
return allProperties[key];
}
- (NSNumber*)getNumberProperty:(NSString*)key {
NSDictionary* mediaProperties = [self getMediaProperties];
if (mediaProperties == nil) {
NSDictionary* allProperties = [self getAllProperties];
if (allProperties == nil) {
return nil;
}
return mediaProperties[key];
return allProperties[key];
}
- (NSDictionary*)getProperties:(NSString*)key {
NSDictionary* mediaProperties = [self getMediaProperties];
if (mediaProperties == nil) {
- (id)getProperty:(NSString*)key {
NSDictionary* allProperties = [self getAllProperties];
if (allProperties == nil) {
return nil;
}
return mediaProperties[key];
return allProperties[key];
}
- (NSDictionary*)getMediaProperties {
return dictionary[MediaKeyMediaProperties];
- (NSString*)getStringFormatProperty:(NSString*)key {
NSDictionary* formatProperties = [self getFormatProperties];
if (formatProperties == nil) {
return nil;
}
return formatProperties[key];
}
- (NSNumber*)getNumberFormatProperty:(NSString*)key {
NSDictionary* formatProperties = [self getFormatProperties];
if (formatProperties == nil) {
return nil;
}
return formatProperties[key];
}
- (id)getFormatProperty:(NSString*)key {
NSDictionary* formatProperties = [self getFormatProperties];
if (formatProperties == nil) {
return nil;
}
return formatProperties[key];
}
- (NSDictionary*)getFormatProperties {
return dictionary[MediaKeyFormatProperties];
}
- (NSDictionary*)getAllProperties {

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2021 Taner Sener
* Copyright (c) 2018-2022 Taner Sener
*
* This file is part of FFmpegKit.
*
@ -37,13 +37,13 @@
+ (MediaInformation*)from:(NSString*)ffprobeJsonOutput;
/**
* Extracts <code>MediaInformation</code> from the given FFprobe json output.
* Extracts <code>MediaInformation</code> from the given FFprobe json output. If a parsing error occurs an NSException
* is thrown.
*
* @param ffprobeJsonOutput FFprobe json output
* @param error error to save the parsing error if a parsing error occurs
* @return created MediaInformation instance
*/
+ (MediaInformation*)from:(NSString*)ffprobeJsonOutput with:(NSError*)error;
+ (MediaInformation*)fromWithError:(NSString*)ffprobeJsonOutput;
@end

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2021 Taner Sener
* Copyright (c) 2018-2022 Taner Sener
*
* This file is part of FFmpegKit.
*
@ -25,21 +25,22 @@ NSString* const MediaInformationJsonParserKeyChapters = @"chapters";
@implementation MediaInformationJsonParser
+ (MediaInformation*)from:(NSString*)ffprobeJsonOutput {
NSError *error;
MediaInformation* mediaInformation = [self from: ffprobeJsonOutput with: error];
if (error != nil) {
NSLog(@"MediaInformation parsing failed: %@.\n", error);
@try {
return [self fromWithError:ffprobeJsonOutput];
} @catch (NSException *exception) {
NSLog(@"MediaInformation parsing failed: %@.\n", [NSString stringWithFormat:@"%@\n%@", [exception userInfo], [exception callStackSymbols]]);
return nil;
}
return mediaInformation;
}
+ (MediaInformation*)from:(NSString*)ffprobeJsonOutput with:(NSError*)error {
+ (MediaInformation*)fromWithError:(NSString*)ffprobeJsonOutput {
NSError* error = nil;
NSData *jsonData = [ffprobeJsonOutput dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *jsonDictionary = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:&error];
if (error != nil || jsonDictionary == nil) {
if (error != nil) {
@throw [NSException exceptionWithName:@"ParsingException" reason:[NSString stringWithFormat:@"%ld",(long)[error code]] userInfo:[error userInfo]];
}
if (jsonDictionary == nil) {
return nil;
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Taner Sener
* Copyright (c) 2021-2022 Taner Sener
*
* This file is part of FFmpegKit.
*
@ -35,16 +35,18 @@
* Creates a new media information session.
*
* @param arguments command arguments
* @return created session
*/
- (instancetype)init:(NSArray*)arguments;
+ (instancetype)create:(NSArray*)arguments;
/**
* Creates a new media information session.
*
* @param arguments command arguments
* @param completeCallback session specific complete callback
* @return created session
*/
- (instancetype)init:(NSArray*)arguments withCompleteCallback:(MediaInformationSessionCompleteCallback)completeCallback;
+ (instancetype)create:(NSArray*)arguments withCompleteCallback:(MediaInformationSessionCompleteCallback)completeCallback;
/**
* Creates a new media information session.
@ -52,8 +54,9 @@
* @param arguments command arguments
* @param completeCallback session specific complete callback
* @param logCallback session specific log callback
* @return created session
*/
- (instancetype)init:(NSArray*)arguments withCompleteCallback:(MediaInformationSessionCompleteCallback)completeCallback withLogCallback:(LogCallback)logCallback;
+ (instancetype)create:(NSArray*)arguments withCompleteCallback:(MediaInformationSessionCompleteCallback)completeCallback withLogCallback:(LogCallback)logCallback;
/**
* Returns the media information extracted in this session.

@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Taner Sener
* Copyright (c) 2021-2022 Taner Sener
*
* This file is part of FFmpegKit.
*
@ -30,26 +30,16 @@
// EMPTY INITIALIZE
}
- (instancetype)init:(NSArray*)arguments {
self = [super init:arguments withLogCallback:nil withLogRedirectionStrategy:LogRedirectionStrategyNeverPrintLogs];
if (self) {
_completeCallback = nil;
}
return self;
+ (instancetype)create:(NSArray*)arguments {
return [[self alloc] init:arguments withCompleteCallback:nil withLogCallback:nil];
}
- (instancetype)init:(NSArray*)arguments withCompleteCallback:(MediaInformationSessionCompleteCallback)completeCallback {
self = [super init:arguments withLogCallback:nil withLogRedirectionStrategy:LogRedirectionStrategyNeverPrintLogs];
if (self) {
_completeCallback = completeCallback;
}
+ (instancetype)create:(NSArray*)arguments withCompleteCallback:(MediaInformationSessionCompleteCallback)completeCallback {
return [[self alloc] init:arguments withCompleteCallback:completeCallback withLogCallback:nil];
}
return self;
+ (instancetype)create:(NSArray*)arguments withCompleteCallback:(MediaInformationSessionCompleteCallback)completeCallback withLogCallback:(LogCallback)logCallback {
return [[self alloc] init:arguments withCompleteCallback:completeCallback withLogCallback:logCallback];
}
- (instancetype)init:(NSArray*)arguments withCompleteCallback:(MediaInformationSessionCompleteCallback)completeCallback withLogCallback:(LogCallback)logCallback {

@ -73,7 +73,6 @@ static NSMutableArray *supportedExternalLibraries;
Boolean gnutls = [enabledLibraryArray containsObject:@"gnutls"];
Boolean xvid = [enabledLibraryArray containsObject:@"xvid"];
Boolean min = false;
Boolean minGpl = false;
Boolean https = false;
Boolean httpsGpl = false;
@ -101,8 +100,6 @@ static NSMutableArray *supportedExternalLibraries;
} else {
if (gnutls) {
https = true;
} else {
min = true;
}
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2021 Taner Sener
* Copyright (c) 2018-2022 Taner Sener
*
* This file is part of FFmpegKit.
*
@ -189,11 +189,11 @@ extern NSString* const StreamKeyTags;
- (NSNumber*)getNumberProperty:(NSString*)key;
/**
* Returns the stream properties associated with the key.
* Returns the stream property associated with the key.
*
* @return stream properties in a dictionary or nil if the key is not found
* @return stream property as id or nil if the key is not found
*/
- (NSDictionary*)getProperties:(NSString*)key;
- (id)getProperty:(NSString*)key;
/**
* Returns all stream properties defined.

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018-2021 Taner Sener
* Copyright (c) 2018-2022 Taner Sener
*
* This file is part of FFmpegKit.
*
@ -125,7 +125,7 @@ NSString* const StreamKeyTags = @"tags";
}
- (NSDictionary*)getTags {
return [self getProperties:StreamKeyTags];
return [self getProperty:StreamKeyTags];
}
- (NSString*)getStringProperty:(NSString*)key {
@ -138,15 +138,15 @@ NSString* const StreamKeyTags = @"tags";
}
- (NSNumber*)getNumberProperty:(NSString*)key {
NSDictionary* mediaProperties = [self getAllProperties];
if (mediaProperties == nil) {
NSDictionary* allProperties = [self getAllProperties];
if (allProperties == nil) {
return nil;
}
return mediaProperties[key];
return allProperties[key];
}
- (NSDictionary*)getProperties:(NSString*)key {
- (id)getProperty:(NSString*)key {
NSDictionary* allProperties = [self getAllProperties];
if (allProperties == nil) {
return nil;

File diff suppressed because it is too large Load Diff

@ -1,6 +1,7 @@
/*
* Various utilities for command line tools
* copyright (c) 2003 Fabrice Bellard
* copyright (c) 2018 Taner Sener ( tanersener gmail com )
*
* This file is part of FFmpeg.
*
@ -20,25 +21,37 @@
*/
/*
* CHANGES 01.2020
* - ffprobe support changes
* - AV_LOG_STDERR introduced
* This file is the modified version of cmdutils.h file living in ffmpeg source code under the fftools folder. We
* manually update it each time we depend on a new ffmpeg version. Below you can see the list of changes applied
* by us to develop mobile-ffmpeg and later ffmpeg-kit libraries.
*
* CHANGES 12.2019
* - Concurrent execution support
* mobile-ffmpeg / ffmpeg-kit changes by Taner Sener
*
* CHANGES 03.2019
* 09.2022
* --------------------------------------------------------
* - config.h include added back
*
* 01.2020
* --------------------------------------------------------
* - ffprobe support added (variables used by ffprobe marked with "__thread" specifier)
* - AV_LOG_STDERR log level added
*
* 12.2019
* --------------------------------------------------------
* - concurrent execution support ("__thread" specifier added to variables used by multiple threads)
*
* 03.2019
* --------------------------------------------------------
* - config.h include removed
*
* CHANGES 08.2018
* 08.2018
* --------------------------------------------------------
* - fftools_ prefix added to file name and include guards
*
* CHANGES 07.2018
* 07.2018
* --------------------------------------------------------
* - Include guards renamed
* - Unused headers removed
* - include guards renamed
* - unused headers removed
*/
#ifndef FFTOOLS_CMDUTILS_H
@ -46,6 +59,7 @@
#include <stdint.h>
#include "config.h"
#include "libavcodec/avcodec.h"
#include "libavfilter/avfilter.h"
#include "libavformat/avformat.h"
@ -70,11 +84,9 @@ extern __thread char *program_name;
*/
extern __thread int program_birth_year;
extern __thread AVCodecContext *avcodec_opts[AVMEDIA_TYPE_NB];
extern __thread AVFormatContext *avformat_opts;
extern __thread AVDictionary *sws_dict;
extern __thread AVDictionary *swr_opts;
extern __thread AVDictionary *format_opts, *codec_opts, *resample_opts;
extern __thread AVDictionary *format_opts, *codec_opts;
extern __thread int hide_banner;
extern __thread int find_stream_info;
@ -93,11 +105,6 @@ void exit_program(int ret) av_noreturn;
*/
void init_dynload(void);
/**
* Initialize the cmdutils option system, in particular
* allocate the *_opts contexts.
*/
void init_opts(void);
/**
* Uninitialize the cmdutils option system, in particular
* free the *_opts contexts and their contents.
@ -110,33 +117,12 @@ void uninit_opts(void);
*/
void log_callback_help(void* ptr, int level, const char* fmt, va_list vl);
/**
* Override the cpuflags.
*/
int opt_cpuflags(void *optctx, const char *opt, const char *arg);
/**
* Override the cpucount.
*/
int opt_cpucount(void *optctx, const char *opt, const char *arg);
/**
* Fallback for options that are not explicitly handled, these will be
* parsed through AVOptions.
*/
int opt_default(void *optctx, const char *opt, const char *arg);
/**
* Set the libav* libraries log level.
*/
int opt_loglevel(void *optctx, const char *opt, const char *arg);
int opt_report(void *optctx, const char *opt, const char *arg);
int opt_max_alloc(void *optctx, const char *opt, const char *arg);
int opt_codec_debug(void *optctx, const char *opt, const char *arg);
/**
* Limit the execution time.
*/
@ -237,7 +223,7 @@ void show_help_options(const OptionDef *options, const char *msg, int req_flags,
* Show help for all options with given flags in class and all its
* children.
*/
void show_help_children(const AVClass *class, int flags);
void show_help_children(const AVClass *clazz, int flags);
/**
* Per-fftool specific help handler. Implemented in each
@ -309,7 +295,6 @@ typedef struct OptionGroup {
AVDictionary *codec_opts;
AVDictionary *format_opts;
AVDictionary *resample_opts;
AVDictionary *sws_dict;
AVDictionary *swr_opts;
} OptionGroup;
@ -417,8 +402,8 @@ AVDictionary *filter_codec_opts(AVDictionary *opts, enum AVCodecID codec_id,
* Each dictionary will contain the options from codec_opts which can
* be applied to the corresponding stream codec context.
*
* @return pointer to the created array of dictionaries, NULL if it
* cannot be created
* @return pointer to the created array of dictionaries.
* Calls exit() on failure.
*/
AVDictionary **setup_find_stream_info_opts(AVFormatContext *s,
AVDictionary *codec_opts);
@ -441,136 +426,6 @@ void print_error(const char *filename, int err);
*/
void show_banner(int argc, char **argv, const OptionDef *options);
/**
* Print the version of the program to stdout. The version message
* depends on the current versions of the repository and of the libav*
* libraries.
* This option processing function does not utilize the arguments.
*/
int show_version(void *optctx, const char *opt, const char *arg);
/**
* Print the build configuration of the program to stdout. The contents
* depend on the definition of FFMPEG_CONFIGURATION.
* This option processing function does not utilize the arguments.
*/
int show_buildconf(void *optctx, const char *opt, const char *arg);
/**
* Print the license of the program to stdout. The license depends on
* the license of the libraries compiled into the program.
* This option processing function does not utilize the arguments.
*/
int show_license(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the formats supported by the
* program (including devices).
* This option processing function does not utilize the arguments.
*/
int show_formats(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the muxers supported by the
* program (including devices).
* This option processing function does not utilize the arguments.
*/
int show_muxers(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the demuxer supported by the
* program (including devices).
* This option processing function does not utilize the arguments.
*/
int show_demuxers(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the devices supported by the
* program.
* This option processing function does not utilize the arguments.
*/
int show_devices(void *optctx, const char *opt, const char *arg);
#if CONFIG_AVDEVICE
/**
* Print a listing containing autodetected sinks of the output device.
* Device name with options may be passed as an argument to limit results.
*/
int show_sinks(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing autodetected sources of the input device.
* Device name with options may be passed as an argument to limit results.
*/
int show_sources(void *optctx, const char *opt, const char *arg);
#endif
/**
* Print a listing containing all the codecs supported by the
* program.
* This option processing function does not utilize the arguments.
*/
int show_codecs(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the decoders supported by the
* program.
*/
int show_decoders(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the encoders supported by the
* program.
*/
int show_encoders(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the filters supported by the
* program.
* This option processing function does not utilize the arguments.
*/
int show_filters(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the bit stream filters supported by the
* program.
* This option processing function does not utilize the arguments.
*/
int show_bsfs(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the protocols supported by the
* program.
* This option processing function does not utilize the arguments.
*/
int show_protocols(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the pixel formats supported by the
* program.
* This option processing function does not utilize the arguments.
*/
int show_pix_fmts(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the standard channel layouts supported by
* the program.
* This option processing function does not utilize the arguments.
*/
int show_layouts(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the sample formats supported by the
* program.
*/
int show_sample_fmts(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the color names and values recognized
* by the program.
*/
int show_colors(void *optctx, const char *opt, const char *arg);
/**
* Return a positive value if a line read from standard input
* starts with [yY], otherwise return 0.
@ -610,11 +465,26 @@ FILE *get_preset_file(char *filename, size_t filename_size,
*/
void *grow_array(void *array, int elem_size, int *size, int new_size);
#define media_type_string av_get_media_type_string
/**
* Atomically add a new element to an array of pointers, i.e. allocate
* a new entry, reallocate the array of pointers and make the new last
* member of this array point to the newly allocated buffer.
* Calls exit() on failure.
*
* @param array array of pointers to reallocate
* @param elem_size size of the new element to allocate
* @param nb_elems pointer to the number of elements of the array array;
* *nb_elems will be incremented by one by this function.
* @return pointer to the newly allocated entry
*/
void *allocate_array_elem(void *array, size_t elem_size, int *nb_elems);
#define GROW_ARRAY(array, nb_elems)\
array = grow_array(array, sizeof(*array), &nb_elems, nb_elems + 1)
#define ALLOC_ARRAY_ELEM(array, nb_elems)\
allocate_array_elem(&array, sizeof(*array[0]), &nb_elems)
#define GET_PIX_FMT_NAME(pix_fmt)\
const char *name = av_get_pix_fmt_name(pix_fmt);
@ -628,14 +498,6 @@ void *grow_array(void *array, int elem_size, int *size, int new_size);
char name[16];\
snprintf(name, sizeof(name), "%d", rate);
#define GET_CH_LAYOUT_NAME(ch_layout)\
char name[16];\
snprintf(name, sizeof(name), "0x%"PRIx64, ch_layout);
#define GET_CH_LAYOUT_DESC(ch_layout)\
char name[128];\
av_get_channel_layout_string(name, sizeof(name), 0, ch_layout);
double get_rotation(AVStream *st);
double get_rotation(int32_t *displaymatrix);
#endif /* FFTOOLS_CMDUTILS_H */

File diff suppressed because it is too large Load Diff

@ -1,5 +1,6 @@
/*
* This file is part of FFmpeg.
* Copyright (c) 2018 Taner Sener ( tanersener gmail com )
*
* FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -17,33 +18,47 @@
*/
/*
* CHANGES 06.2020
* - cancel_operation() method signature updated with id
* This file is the modified version of ffmpeg.h file living in ffmpeg source code under the fftools folder. We
* manually update it each time we depend on a new ffmpeg version. Below you can see the list of changes applied
* by us to develop mobile-ffmpeg and later ffmpeg-kit libraries.
*
* mobile-ffmpeg / ffmpeg-kit changes by Taner Sener
*
* 09.2022
* --------------------------------------------------------
* - config.h include added back
* - volatile dropped from thread local variables
* - dropped signatures of ffmpeg_opt.c methods called by both ffmpeg and ffprobe
*
* CHANGES 01.2020
* - ffprobe support changes
* 06.2020
* --------------------------------------------------------
* - cancel_operation() method signature updated with id
*
* CHANGES 12.2019
* - Concurrent execution support
* 12.2019
* --------------------------------------------------------
* - concurrent execution support ("__thread" specifier added to variables used by multiple threads,
* signatures of ffmpeg_opt.c methods called by both ffmpeg and ffprobe added)
*
* CHANGES 03.2019
* 03.2019
* --------------------------------------------------------
* - config.h include removed
*
* CHANGES 08.2018
* 08.2018
* --------------------------------------------------------
* - fftools_ prefix added to file name and include guards
* - set_report_callback() method declared
* - cancel_operation() method declared
*
* CHANGES 07.2018
* 07.2018
* --------------------------------------------------------
* - Include guards renamed
* - include guards renamed
*/
#ifndef FFTOOLS_FFMPEG_H
#define FFTOOLS_FFMPEG_H
#include "config.h"
#include <stdint.h>
#include <stdio.h>
#include <signal.h>
@ -70,12 +85,14 @@
#include "libswresample/swresample.h"
#define VSYNC_AUTO -1
#define VSYNC_PASSTHROUGH 0
#define VSYNC_CFR 1
#define VSYNC_VFR 2
#define VSYNC_VSCFR 0xfe
#define VSYNC_DROP 0xff
enum VideoSyncMethod {
VSYNC_AUTO = -1,
VSYNC_PASSTHROUGH,
VSYNC_CFR,
VSYNC_VFR,
VSYNC_VSCFR,
VSYNC_DROP,
};
#define MAX_STREAMS 1024 /* arbitrary sanity check value */
@ -83,16 +100,8 @@ enum HWAccelID {
HWACCEL_NONE = 0,
HWACCEL_AUTO,
HWACCEL_GENERIC,
HWACCEL_VIDEOTOOLBOX,
};
typedef struct HWAccel {
const char *name;
int (*init)(AVCodecContext *s);
enum HWAccelID id;
enum AVPixelFormat pix_fmt;
} HWAccel;
typedef struct HWDevice {
const char *name;
enum AVHWDeviceType type;
@ -125,6 +134,8 @@ typedef struct OptionsContext {
SpecifierOpt *codec_names;
int nb_codec_names;
SpecifierOpt *audio_ch_layouts;
int nb_audio_ch_layouts;
SpecifierOpt *audio_channels;
int nb_audio_channels;
SpecifierOpt *audio_sample_rate;
@ -145,6 +156,7 @@ typedef struct OptionsContext {
float readrate;
int accurate_seek;
int thread_queue_size;
int input_sync_ref;
SpecifierOpt *ts_scale;
int nb_ts_scale;
@ -203,6 +215,8 @@ typedef struct OptionsContext {
int nb_qscale;
SpecifierOpt *forced_key_frames;
int nb_forced_key_frames;
SpecifierOpt *fps_mode;
int nb_fps_mode;
SpecifierOpt *force_fps;
int nb_force_fps;
SpecifierOpt *frame_aspect_ratios;
@ -259,6 +273,8 @@ typedef struct OptionsContext {
int nb_enc_time_bases;
SpecifierOpt *autoscale;
int nb_autoscale;
SpecifierOpt *bits_per_raw_sample;
int nb_bits_per_raw_sample;
} OptionsContext;
typedef struct InputFilter {
@ -268,7 +284,7 @@ typedef struct InputFilter {
uint8_t *name;
enum AVMediaType type; // AVMEDIA_TYPE_SUBTITLE for sub2video
AVFifoBuffer *frame_queue;
AVFifo *frame_queue;
// parameters configured for this input
int format;
@ -277,10 +293,10 @@ typedef struct InputFilter {
AVRational sample_aspect_ratio;
int sample_rate;
int channels;
uint64_t channel_layout;
AVChannelLayout ch_layout;
AVBufferRef *hw_frames_ctx;
int32_t *displaymatrix;
int eof;
} InputFilter;
@ -300,12 +316,13 @@ typedef struct OutputFilter {
AVRational frame_rate;
int format;
int sample_rate;
uint64_t channel_layout;
AVChannelLayout ch_layout;
// those are only set if no format is specified and the encoder gives us multiple options
int *formats;
uint64_t *channel_layouts;
int *sample_rates;
// They point directly to the relevant lists of the encoder.
const int *formats;
const AVChannelLayout *ch_layouts;
const int *sample_rates;
} OutputFilter;
typedef struct FilterGraph {
@ -314,6 +331,9 @@ typedef struct FilterGraph {
AVFilterGraph *graph;
int reconfiguration;
// true when the filtergraph contains only meta filters
// that do not modify the frame data
int is_meta;
InputFilter **inputs;
int nb_inputs;
@ -329,13 +349,14 @@ typedef struct InputStream {
int decoding_needed; /* non zero if the packets must be decoded in 'raw_fifo', see DECODING_FOR_* */
#define DECODING_FOR_OST 1
#define DECODING_FOR_FILTER 2
int processing_needed; /* non zero if the packets must be processed */
AVCodecContext *dec_ctx;
const AVCodec *dec;
AVFrame *decoded_frame;
AVFrame *filter_frame; /* a ref of decoded_frame, to be sent to filters */
AVPacket *pkt;
int64_t prev_pkt_pts;
int64_t start; /* time when read started */
/* predicted dts of the next packet read for this stream or (when there are
* several frames in a packet) of the next frame in current packet (in AV_TIME_BASE units) */
@ -377,14 +398,12 @@ typedef struct InputStream {
struct sub2video {
int64_t last_pts;
int64_t end_pts;
AVFifoBuffer *sub_queue; ///< queue of AVSubtitle* before filter init
AVFifo *sub_queue; ///< queue of AVSubtitle* before filter init
AVFrame *frame;
int w, h;
unsigned int initialize; ///< marks if sub2video_update should force an initialization
} sub2video;
int dr1;
/* decoded data from this stream goes into all those filters
* currently video and audio only */
InputFilter **filters;
@ -401,11 +420,9 @@ typedef struct InputStream {
/* hwaccel context */
void *hwaccel_ctx;
void (*hwaccel_uninit)(AVCodecContext *s);
int (*hwaccel_get_buffer)(AVCodecContext *s, AVFrame *frame, int flags);
int (*hwaccel_retrieve_data)(AVCodecContext *s, AVFrame *frame);
enum AVPixelFormat hwaccel_pix_fmt;
enum AVPixelFormat hwaccel_retrieved_pix_fmt;
AVBufferRef *hw_frames_ctx;
/* stats */
// combined size of all the packets read
@ -432,11 +449,11 @@ typedef struct InputFile {
at the moment when looping happens */
AVRational time_base; /* time base of the duration */
int64_t input_ts_offset;
int input_sync_ref;
int64_t ts_offset;
int64_t last_ts;
int64_t start_time; /* user-specified start time in AV_TIME_BASE or AV_NOPTS_VALUE */
int seek_timestamp;
int64_t recording_time;
int nb_streams; /* number of stream that ffmpeg is aware of; may be different
from ctx.nb_streams if new streams appear during av_read_frame() */
@ -481,7 +498,7 @@ typedef struct OutputStream {
int source_index; /* InputStream index */
AVStream *st; /* stream in the output file */
int encoding_needed; /* true if encoding needed for this stream */
int frame_number;
int64_t frame_number;
/* input pts and corresponding output pts
for A/V sync */
struct InputStream *sync_ist; /* input stream to sync against */
@ -504,19 +521,22 @@ typedef struct OutputStream {
AVFrame *filtered_frame;
AVFrame *last_frame;
AVPacket *pkt;
int last_dropped;
int last_nb0_frames[3];
int64_t last_dropped;
int64_t last_nb0_frames[3];
void *hwaccel_ctx;
/* video only */
AVRational frame_rate;
AVRational max_frame_rate;
enum VideoSyncMethod vsync_method;
int is_cfr;
const char *fps_mode;
int force_fps;
int top_field_first;
int rotate_overridden;
int autoscale;
int bits_per_raw_sample;
double rotate_override_value;
AVRational frame_aspect_ratio;
@ -546,7 +566,6 @@ typedef struct OutputStream {
AVDictionary *encoder_opts;
AVDictionary *sws_dict;
AVDictionary *swr_opts;
AVDictionary *resample_opts;
char *apad;
OSTFinished finished; /* no more packets should be written for this stream */
int unavailable; /* true if the steram is unavailable (possibly temporarily) */
@ -560,6 +579,7 @@ typedef struct OutputStream {
int inputs_done;
const char *attachment_filename;
int streamcopy_started;
int copy_initial_nonkeyframes;
int copy_prior_start;
char *disposition;
@ -574,6 +594,8 @@ typedef struct OutputStream {
// number of frames/samples sent to the encoder
uint64_t frames_encoded;
uint64_t samples_encoded;
// number of packets received from the encoder
uint64_t packets_encoded;
/* packet quality factor */
int quality;
@ -581,7 +603,7 @@ typedef struct OutputStream {
int max_muxing_queue_size;
/* the packets are buffered here until the muxer is ready to be initialized */
AVFifoBuffer *muxing_queue;
AVFifo *muxing_queue;
/*
* The size of the AVPackets' buffers in queue.
@ -600,6 +622,10 @@ typedef struct OutputStream {
} OutputStream;
typedef struct OutputFile {
int index;
const AVOutputFormat *format;
AVFormatContext *ctx;
AVDictionary *opts;
int ost_index; /* index of the first stream in output_streams */
@ -634,7 +660,7 @@ extern __thread float dts_error_threshold;
extern __thread int audio_volume;
extern __thread int audio_sync_method;
extern __thread int video_sync_method;
extern __thread enum VideoSyncMethod video_sync_method;
extern __thread float frame_drop_threshold;
extern __thread int do_benchmark;
extern __thread int do_benchmark_all;
@ -654,41 +680,35 @@ extern __thread int stdin_interaction;
extern __thread int frame_bits_per_raw_sample;
extern __thread AVIOContext *progress_avio;
extern __thread float max_error_rate;
extern __thread char *videotoolbox_pixfmt;
extern __thread int filter_nbthreads;
extern __thread char *filter_nbthreads;
extern __thread int filter_complex_nbthreads;
extern __thread int vstats_version;
extern __thread int auto_conversion_filters;
extern __thread const AVIOInterruptCB int_cb;
extern const HWAccel hwaccels[];
#if CONFIG_QSV
extern __thread char *qsv_device;
#endif
extern __thread HWDevice *filter_hw_device;
extern __thread int want_sdp;
extern __thread unsigned nb_output_dumped;
extern __thread int main_ffmpeg_return_code;
void term_init(void);
void term_exit(void);
void reset_options(OptionsContext *o, int is_input);
void show_usage(void);
void opt_output_file(void *optctx, const char *filename);
void remove_avoptions(AVDictionary **a, AVDictionary *b);
void assert_avoptions(AVDictionary *m);
int guess_input_channel_layout(InputStream *ist);
enum AVPixelFormat choose_pixel_fmt(AVStream *st, AVCodecContext *avctx, const AVCodec *codec, enum AVPixelFormat target);
void choose_sample_fmt(AVStream *st, const AVCodec *codec);
int configure_filtergraph(FilterGraph *fg);
int configure_output_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out);
void check_filter_outputs(void);
int ist_in_filtergraph(FilterGraph *fg, InputStream *ist);
int filtergraph_is_simple(FilterGraph *fg);
int init_simple_filtergraph(InputStream *ist, OutputStream *ost);
int init_complex_filtergraph(FilterGraph *fg);
@ -712,80 +732,15 @@ int hw_device_setup_for_filter(FilterGraph *fg);
int hwaccel_decode_init(AVCodecContext *avctx);
void set_report_callback(void (*callback)(int, float, float, int64_t, int, double, double));
/* open the muxer when all the streams are initialized */
int of_check_init(OutputFile *of);
int of_write_trailer(OutputFile *of);
void of_close(OutputFile **pof);
void cancel_operation(long id);
void of_write_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost,
int unqueue);
int opt_map(void *optctx, const char *opt, const char *arg);
int opt_map_channel(void *optctx, const char *opt, const char *arg);
int opt_recording_timestamp(void *optctx, const char *opt, const char *arg);
int opt_data_frames(void *optctx, const char *opt, const char *arg);
int opt_progress(void *optctx, const char *opt, const char *arg);
int opt_target(void *optctx, const char *opt, const char *arg);
int opt_vsync(void *optctx, const char *opt, const char *arg);
int opt_abort_on(void *optctx, const char *opt, const char *arg);
int opt_stats_period(void *optctx, const char *opt, const char *arg);
int opt_qscale(void *optctx, const char *opt, const char *arg);
int opt_profile(void *optctx, const char *opt, const char *arg);
int opt_filter_complex(void *optctx, const char *opt, const char *arg);
int opt_filter_complex_script(void *optctx, const char *opt, const char *arg);
int opt_attach(void *optctx, const char *opt, const char *arg);
int opt_video_frames(void *optctx, const char *opt, const char *arg);
int opt_video_codec(void *optctx, const char *opt, const char *arg);
int opt_sameq(void *optctx, const char *opt, const char *arg);
int opt_timecode(void *optctx, const char *opt, const char *arg);
int opt_vstats_file(void *optctx, const char *opt, const char *arg);
int opt_vstats(void *optctx, const char *opt, const char *arg);
int opt_video_frames(void *optctx, const char *opt, const char *arg);
int opt_old2new(void *optctx, const char *opt, const char *arg);
int opt_streamid(void *optctx, const char *opt, const char *arg);
int opt_bitrate(void *optctx, const char *opt, const char *arg);
int show_hwaccels(void *optctx, const char *opt, const char *arg);
int opt_video_filters(void *optctx, const char *opt, const char *arg);
int opt_audio_frames(void *optctx, const char *opt, const char *arg);
int opt_audio_qscale(void *optctx, const char *opt, const char *arg);
int opt_audio_codec(void *optctx, const char *opt, const char *arg);
int opt_channel_layout(void *optctx, const char *opt, const char *arg);
int opt_preset(void *optctx, const char *opt, const char *arg);
int opt_audio_filters(void *optctx, const char *opt, const char *arg);
int opt_subtitle_codec(void *optctx, const char *opt, const char *arg);
int opt_video_channel(void *optctx, const char *opt, const char *arg);
int opt_video_standard(void *optctx, const char *opt, const char *arg);
int opt_sdp_file(void *optctx, const char *opt, const char *arg);
int opt_data_codec(void *optctx, const char *opt, const char *arg);
int opt_init_hw_device(void *optctx, const char *opt, const char *arg);
int opt_filter_hw_device(void *optctx, const char *opt, const char *arg);
void add_input_streams(OptionsContext *o, AVFormatContext *ic);
void assert_file_overwrite(const char *filename);
void dump_attachment(AVStream *st, const char *filename);
uint8_t *get_line(AVIOContext *s);
void uninit_options(OptionsContext *o);
void init_options(OptionsContext *o);
AVDictionary *strip_specifiers(AVDictionary *dict);
void parse_meta_type(char *arg, char *type, int *index, const char **stream_spec);
int fftools_copy_metadata(char *outspec, char *inspec, AVFormatContext *oc, AVFormatContext *ic, OptionsContext *o);
const AVCodec *find_codec_or_die(const char *name, enum AVMediaType type, int encoder);
const AVCodec *choose_decoder(OptionsContext *o, AVFormatContext *s, AVStream *st);
int open_input_file(OptionsContext *o, const char *filename);
int get_preset_file_2(const char *preset_name, const char *codec_name, AVIOContext **s);
int choose_encoder(OptionsContext *o, AVFormatContext *s, OutputStream *ost);
OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, enum AVMediaType type, int source_index);
void parse_matrix_coeffs(uint16_t *dest, const char *str);
uint8_t *fftools_read_file(const char *filename);
char *get_ost_filters(OptionsContext *o, AVFormatContext *oc, OutputStream *ost);
void check_streamcopy_filters(OptionsContext *o, AVFormatContext *oc, const OutputStream *ost, enum AVMediaType type);
OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc, int source_index);
OutputStream *new_audio_stream(OptionsContext *o, AVFormatContext *oc, int source_index);
OutputStream *new_data_stream(OptionsContext *o, AVFormatContext *oc, int source_index);
OutputStream *new_unknown_stream(OptionsContext *o, AVFormatContext *oc, int source_index);
OutputStream *new_attachment_stream(OptionsContext *o, AVFormatContext *oc, int source_index);
OutputStream *new_subtitle_stream(OptionsContext *o, AVFormatContext *oc, int source_index);
int copy_chapters(InputFile *ifile, OutputFile *ofile, int copy_metadata);
void init_output_filter(OutputFilter *ofilter, OptionsContext *o, AVFormatContext *oc);
int init_complex_filters(void);
int open_output_file(OptionsContext *o, const char *filename);
int opt_default_new(OptionsContext *o, const char *opt, const char *arg);
int open_files(OptionGroupList *l, const char *inout, int (*open_file)(OptionsContext*, const char*));
void set_report_callback(void (*callback)(int, float, float, int64_t, int, double, double));
void cancel_operation(long id);
#endif /* FFTOOLS_FFMPEG_H */

@ -1,5 +1,6 @@
/*
* ffmpeg filter configuration
* copyright (c) 2018 Taner Sener ( tanersener gmail com )
*
* This file is part of FFmpeg.
*
@ -19,13 +20,19 @@
*/
/*
* CHANGES 08.2018
* This file is the modified version of ffmpeg_filter.c file living in ffmpeg source code under the fftools folder.
* We manually update it each time we depend on a new ffmpeg version. Below you can see the list of changes applied
* by us to develop mobile-ffmpeg and later ffmpeg-kit libraries.
*
* mobile-ffmpeg / ffmpeg-kit changes by Taner Sener
*
* 08.2018
* --------------------------------------------------------
* - fftools_ prefix added to file name and parent header
*
* CHANGES 07.2018
* 07.2018
* --------------------------------------------------------
* - Unused headers removed
* - unused headers removed
*/
#include <stdint.h>
@ -53,7 +60,7 @@ static const enum AVPixelFormat *get_compliance_normal_pix_fmts(const AVCodec *c
{
static const enum AVPixelFormat mjpeg_formats[] =
{ AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ444P,
AV_PIX_FMT_NONE};
AV_PIX_FMT_NONE };
if (!strcmp(codec->name, "mjpeg")) {
return mjpeg_formats;
@ -62,7 +69,8 @@ static const enum AVPixelFormat *get_compliance_normal_pix_fmts(const AVCodec *c
}
}
enum AVPixelFormat choose_pixel_fmt(AVStream *st, AVCodecContext *enc_ctx, const AVCodec *codec, enum AVPixelFormat target)
enum AVPixelFormat choose_pixel_fmt(AVStream *st, AVCodecContext *enc_ctx,
const AVCodec *codec, enum AVPixelFormat target)
{
if (codec && codec->pix_fmts) {
const enum AVPixelFormat *p = codec->pix_fmts;
@ -92,10 +100,13 @@ enum AVPixelFormat choose_pixel_fmt(AVStream *st, AVCodecContext *enc_ctx, const
return target;
}
static char *choose_pix_fmts(OutputFilter *ofilter)
/* May return NULL (no pixel format found), a static string or a string
* backed by the bprint. Nothing has been written to the AVBPrint in case
* NULL is returned. The AVBPrint provided should be clean. */
static const char *choose_pix_fmts(OutputFilter *ofilter, AVBPrint *bprint)
{
OutputStream *ost = ofilter->ost;
AVDictionaryEntry *strict_dict = av_dict_get(ost->encoder_opts, "strict", NULL, 0);
const AVDictionaryEntry *strict_dict = av_dict_get(ost->encoder_opts, "strict", NULL, 0);
if (strict_dict)
// used by choose_pixel_fmt() and below
av_opt_set(ost->enc_ctx, "strict", strict_dict->value, 0);
@ -105,18 +116,12 @@ static char *choose_pix_fmts(OutputFilter *ofilter)
AVFILTER_AUTO_CONVERT_NONE);
if (ost->enc_ctx->pix_fmt == AV_PIX_FMT_NONE)
return NULL;
return av_strdup(av_get_pix_fmt_name(ost->enc_ctx->pix_fmt));
return av_get_pix_fmt_name(ost->enc_ctx->pix_fmt);
}
if (ost->enc_ctx->pix_fmt != AV_PIX_FMT_NONE) {
return av_strdup(av_get_pix_fmt_name(choose_pixel_fmt(ost->st, ost->enc_ctx, ost->enc, ost->enc_ctx->pix_fmt)));
return av_get_pix_fmt_name(choose_pixel_fmt(ost->st, ost->enc_ctx, ost->enc, ost->enc_ctx->pix_fmt));
} else if (ost->enc && ost->enc->pix_fmts) {
const enum AVPixelFormat *p;
AVIOContext *s = NULL;
uint8_t *ret;
int len;
if (avio_open_dyn_buf(&s) < 0)
exit_program(1);
p = ost->enc->pix_fmts;
if (ost->enc_ctx->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL) {
@ -125,11 +130,11 @@ static char *choose_pix_fmts(OutputFilter *ofilter)
for (; *p != AV_PIX_FMT_NONE; p++) {
const char *name = av_get_pix_fmt_name(*p);
avio_printf(s, "%s|", name);
av_bprintf(bprint, "%s%c", name, p[1] == AV_PIX_FMT_NONE ? '\0' : '|');
}
len = avio_close_dyn_buf(s, &ret);
ret[len - 1] = 0;
return ret;
if (!av_bprint_is_complete(bprint))
exit_program(1);
return bprint->str;
} else
return NULL;
}
@ -165,39 +170,54 @@ DEF_CHOOSE_FORMAT(sample_fmts, enum AVSampleFormat, format, formats,
DEF_CHOOSE_FORMAT(sample_rates, int, sample_rate, sample_rates, 0,
"%d", )
DEF_CHOOSE_FORMAT(channel_layouts, uint64_t, channel_layout, channel_layouts, 0,
"0x%"PRIx64, )
static void choose_channel_layouts(OutputFilter *ofilter, AVBPrint *bprint)
{
if (av_channel_layout_check(&ofilter->ch_layout)) {
av_bprintf(bprint, "channel_layouts=");
av_channel_layout_describe_bprint(&ofilter->ch_layout, bprint);
} else if (ofilter->ch_layouts) {
const AVChannelLayout *p;
av_bprintf(bprint, "channel_layouts=");
for (p = ofilter->ch_layouts; p->nb_channels; p++) {
av_channel_layout_describe_bprint(p, bprint);
av_bprintf(bprint, "|");
}
if (bprint->len > 0)
bprint->str[--bprint->len] = '\0';
} else
return;
av_bprint_chars(bprint, ':', 1);
}
int init_simple_filtergraph(InputStream *ist, OutputStream *ost)
{
FilterGraph *fg = av_mallocz(sizeof(*fg));
OutputFilter *ofilter;
InputFilter *ifilter;
if (!fg)
exit_program(1);
fg->index = nb_filtergraphs;
GROW_ARRAY(fg->outputs, fg->nb_outputs);
if (!(fg->outputs[0] = av_mallocz(sizeof(*fg->outputs[0]))))
exit_program(1);
fg->outputs[0]->ost = ost;
fg->outputs[0]->graph = fg;
fg->outputs[0]->format = -1;
ofilter = ALLOC_ARRAY_ELEM(fg->outputs, fg->nb_outputs);
ofilter->ost = ost;
ofilter->graph = fg;
ofilter->format = -1;
ost->filter = fg->outputs[0];
ost->filter = ofilter;
GROW_ARRAY(fg->inputs, fg->nb_inputs);
if (!(fg->inputs[0] = av_mallocz(sizeof(*fg->inputs[0]))))
exit_program(1);
fg->inputs[0]->ist = ist;
fg->inputs[0]->graph = fg;
fg->inputs[0]->format = -1;
ifilter = ALLOC_ARRAY_ELEM(fg->inputs, fg->nb_inputs);
ifilter->ist = ist;
ifilter->graph = fg;
ifilter->format = -1;
fg->inputs[0]->frame_queue = av_fifo_alloc(8 * sizeof(AVFrame*));
if (!fg->inputs[0]->frame_queue)
ifilter->frame_queue = av_fifo_alloc2(8, sizeof(AVFrame*), AV_FIFO_FLAG_AUTO_GROW);
if (!ifilter->frame_queue)
exit_program(1);
GROW_ARRAY(ist->filters, ist->nb_filters);
ist->filters[ist->nb_filters - 1] = fg->inputs[0];
ist->filters[ist->nb_filters - 1] = ifilter;
GROW_ARRAY(filtergraphs, nb_filtergraphs);
filtergraphs[nb_filtergraphs - 1] = fg;
@ -210,17 +230,15 @@ static char *describe_filter_link(FilterGraph *fg, AVFilterInOut *inout, int in)
AVFilterContext *ctx = inout->filter_ctx;
AVFilterPad *pads = in ? ctx->input_pads : ctx->output_pads;
int nb_pads = in ? ctx->nb_inputs : ctx->nb_outputs;
AVIOContext *pb;
uint8_t *res = NULL;
char *res;
if (avio_open_dyn_buf(&pb) < 0)
exit_program(1);
avio_printf(pb, "%s", ctx->filter->name);
if (nb_pads > 1)
avio_printf(pb, ":%s", avfilter_pad_get_name(pads, inout->pad_idx));
avio_w8(pb, 0);
avio_close_dyn_buf(pb, &res);
res = av_strdup(ctx->filter->name);
else
res = av_asprintf("%s:%s", ctx->filter->name,
avfilter_pad_get_name(pads, inout->pad_idx));
if (!res)
exit_program(1);
return res;
}
@ -228,6 +246,7 @@ static void init_input_filter(FilterGraph *fg, AVFilterInOut *in)
{
InputStream *ist = NULL;
enum AVMediaType type = avfilter_pad_get_type(in->filter_ctx->input_pads, in->pad_idx);
InputFilter *ifilter;
int i;
// TODO: support other filter types
@ -292,23 +311,22 @@ static void init_input_filter(FilterGraph *fg, AVFilterInOut *in)
ist->discard = 0;
ist->decoding_needed |= DECODING_FOR_FILTER;
ist->processing_needed = 1;
ist->st->discard = AVDISCARD_NONE;
GROW_ARRAY(fg->inputs, fg->nb_inputs);
if (!(fg->inputs[fg->nb_inputs - 1] = av_mallocz(sizeof(*fg->inputs[0]))))
exit_program(1);
fg->inputs[fg->nb_inputs - 1]->ist = ist;
fg->inputs[fg->nb_inputs - 1]->graph = fg;
fg->inputs[fg->nb_inputs - 1]->format = -1;
fg->inputs[fg->nb_inputs - 1]->type = ist->st->codecpar->codec_type;
fg->inputs[fg->nb_inputs - 1]->name = describe_filter_link(fg, in, 1);
fg->inputs[fg->nb_inputs - 1]->frame_queue = av_fifo_alloc(8 * sizeof(AVFrame*));
if (!fg->inputs[fg->nb_inputs - 1]->frame_queue)
ifilter = ALLOC_ARRAY_ELEM(fg->inputs, fg->nb_inputs);
ifilter->ist = ist;
ifilter->graph = fg;
ifilter->format = -1;
ifilter->type = ist->st->codecpar->codec_type;
ifilter->name = describe_filter_link(fg, in, 1);
ifilter->frame_queue = av_fifo_alloc2(8, sizeof(AVFrame*), AV_FIFO_FLAG_AUTO_GROW);
if (!ifilter->frame_queue)
exit_program(1);
GROW_ARRAY(ist->filters, ist->nb_filters);
ist->filters[ist->nb_filters - 1] = fg->inputs[fg->nb_inputs - 1];
ist->filters[ist->nb_filters - 1] = ifilter;
}
int init_complex_filtergraph(FilterGraph *fg)
@ -332,18 +350,15 @@ int init_complex_filtergraph(FilterGraph *fg)
init_input_filter(fg, cur);
for (cur = outputs; cur;) {
GROW_ARRAY(fg->outputs, fg->nb_outputs);
fg->outputs[fg->nb_outputs - 1] = av_mallocz(sizeof(*fg->outputs[0]));
if (!fg->outputs[fg->nb_outputs - 1])
exit_program(1);
OutputFilter *const ofilter = ALLOC_ARRAY_ELEM(fg->outputs, fg->nb_outputs);
fg->outputs[fg->nb_outputs - 1]->graph = fg;
fg->outputs[fg->nb_outputs - 1]->out_tmp = cur;
fg->outputs[fg->nb_outputs - 1]->type = avfilter_pad_get_type(cur->filter_ctx->output_pads,
ofilter->graph = fg;
ofilter->out_tmp = cur;
ofilter->type = avfilter_pad_get_type(cur->filter_ctx->output_pads,
cur->pad_idx);
fg->outputs[fg->nb_outputs - 1]->name = describe_filter_link(fg, cur, 0);
ofilter->name = describe_filter_link(fg, cur, 0);
cur = cur->next;
fg->outputs[fg->nb_outputs - 1]->out_tmp->next = NULL;
ofilter->out_tmp->next = NULL;
}
fail:
@ -427,12 +442,13 @@ static int insert_filter(AVFilterContext **last_filter, int *pad_idx,
static int configure_output_video_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out)
{
char *pix_fmts;
OutputStream *ost = ofilter->ost;
OutputFile *of = output_files[ost->file_index];
AVFilterContext *last_filter = out->filter_ctx;
AVBPrint bprint;
int pad_idx = out->pad_idx;
int ret;
const char *pix_fmts;
char name[255];
snprintf(name, sizeof(name), "out_%d_%d", ost->file_index, ost->index);
@ -446,7 +462,7 @@ static int configure_output_video_filter(FilterGraph *fg, OutputFilter *ofilter,
if ((ofilter->width || ofilter->height) && ofilter->ost->autoscale) {
char args[255];
AVFilterContext *filter;
AVDictionaryEntry *e = NULL;
const AVDictionaryEntry *e = NULL;
snprintf(args, sizeof(args), "%d:%d",
ofilter->width, ofilter->height);
@ -468,13 +484,14 @@ static int configure_output_video_filter(FilterGraph *fg, OutputFilter *ofilter,
pad_idx = 0;
}
if ((pix_fmts = choose_pix_fmts(ofilter))) {
av_bprint_init(&bprint, 0, AV_BPRINT_SIZE_UNLIMITED);
if ((pix_fmts = choose_pix_fmts(ofilter, &bprint))) {
AVFilterContext *filter;
ret = avfilter_graph_create_filter(&filter,
avfilter_get_by_name("format"),
"format", pix_fmts, NULL, fg->graph);
av_freep(&pix_fmts);
av_bprint_finalize(&bprint, NULL);
if (ret < 0)
return ret;
if ((ret = avfilter_link(last_filter, pad_idx, filter, 0)) < 0)
@ -559,9 +576,10 @@ static int configure_output_audio_filter(FilterGraph *fg, OutputFilter *ofilter,
} while (0)
av_bprint_init(&args, 0, AV_BPRINT_SIZE_UNLIMITED);
if (ost->audio_channels_mapped) {
AVChannelLayout mapped_layout = { 0 };
int i;
av_bprintf(&args, "0x%"PRIx64,
av_get_default_channel_layout(ost->audio_channels_mapped));
av_channel_layout_default(&mapped_layout, ost->audio_channels_mapped);
av_channel_layout_describe_bprint(&mapped_layout, &args);
for (i = 0; i < ost->audio_channels_mapped; i++)
if (ost->audio_channels_map[i] != -1)
av_bprintf(&args, "|c%d=c%d", i, ost->audio_channels_map[i]);
@ -570,8 +588,8 @@ static int configure_output_audio_filter(FilterGraph *fg, OutputFilter *ofilter,
av_bprint_clear(&args);
}
if (codec->channels && !codec->channel_layout)
codec->channel_layout = av_get_default_channel_layout(codec->channels);
if (codec->ch_layout.order == AV_CHANNEL_ORDER_UNSPEC)
av_channel_layout_default(&codec->ch_layout, codec->ch_layout.nb_channels);
choose_sample_fmts(ofilter, &args);
choose_sample_rates(ofilter, &args);
@ -626,7 +644,8 @@ fail:
return ret;
}
int configure_output_filter(FilterGraph *fg, OutputFilter *ofilter, AVFilterInOut *out)
int configure_output_filter(FilterGraph *fg, OutputFilter *ofilter,
AVFilterInOut *out)
{
if (!ofilter->ost) {
av_log(NULL, AV_LOG_FATAL, "Filter %s has an unconnected output\n", ofilter->name);
@ -707,6 +726,7 @@ static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter,
{
AVFilterContext *last_filter;
const AVFilter *buffer_filt = avfilter_get_by_name("buffer");
const AVPixFmtDescriptor *desc;
InputStream *ist = ifilter->ist;
InputFile *f = input_files[ist->file_index];
AVRational tb = ist->framerate.num ? av_inv_q(ist->framerate) :
@ -764,42 +784,44 @@ static int configure_input_video_filter(FilterGraph *fg, InputFilter *ifilter,
av_freep(&par);
last_filter = ifilter->filter;
if (ist->autorotate) {
double theta = get_rotation(ist->st);
desc = av_pix_fmt_desc_get(ifilter->format);
av_assert0(desc);
// TODO: insert hwaccel enabled filters like transpose_vaapi into the graph
if (ist->autorotate && !(desc->flags & AV_PIX_FMT_FLAG_HWACCEL)) {
int32_t *displaymatrix = ifilter->displaymatrix;
double theta;
if (!displaymatrix)
displaymatrix = (int32_t *)av_stream_get_side_data(ist->st, AV_PKT_DATA_DISPLAYMATRIX, NULL);
theta = get_rotation(displaymatrix);
if (fabs(theta - 90) < 1.0) {
ret = insert_filter(&last_filter, &pad_idx, "transpose", "clock");
ret = insert_filter(&last_filter, &pad_idx, "transpose",
displaymatrix[3] > 0 ? "cclock_flip" : "clock");
} else if (fabs(theta - 180) < 1.0) {
if (displaymatrix[0] < 0) {
ret = insert_filter(&last_filter, &pad_idx, "hflip", NULL);
if (ret < 0)
return ret;
}
if (displaymatrix[4] < 0) {
ret = insert_filter(&last_filter, &pad_idx, "vflip", NULL);
}
} else if (fabs(theta - 270) < 1.0) {
ret = insert_filter(&last_filter, &pad_idx, "transpose", "cclock");
ret = insert_filter(&last_filter, &pad_idx, "transpose",
displaymatrix[3] < 0 ? "clock_flip" : "cclock");
} else if (fabs(theta) > 1.0) {
char rotate_buf[64];
snprintf(rotate_buf, sizeof(rotate_buf), "%f*PI/180", theta);
ret = insert_filter(&last_filter, &pad_idx, "rotate", rotate_buf);
} else if (fabs(theta) < 1.0) {
if (displaymatrix && displaymatrix[4] < 0) {
ret = insert_filter(&last_filter, &pad_idx, "vflip", NULL);
}
if (ret < 0)
return ret;
}
if (do_deinterlace) {
AVFilterContext *yadif;
snprintf(name, sizeof(name), "deinterlace_in_%d_%d",
ist->file_index, ist->st->index);
if ((ret = avfilter_graph_create_filter(&yadif,
avfilter_get_by_name("yadif"),
name, "", NULL,
fg->graph)) < 0)
return ret;
if ((ret = avfilter_link(last_filter, 0, yadif, 0)) < 0)
if (ret < 0)
return ret;
last_filter = yadif;
}
snprintf(name, sizeof(name), "trim_in_%d_%d",
@ -846,11 +868,12 @@ static int configure_input_audio_filter(FilterGraph *fg, InputFilter *ifilter,
1, ifilter->sample_rate,
ifilter->sample_rate,
av_get_sample_fmt_name(ifilter->format));
if (ifilter->channel_layout)
av_bprintf(&args, ":channel_layout=0x%"PRIx64,
ifilter->channel_layout);
else
av_bprintf(&args, ":channels=%d", ifilter->channels);
if (av_channel_layout_check(&ifilter->ch_layout) &&
ifilter->ch_layout.order != AV_CHANNEL_ORDER_UNSPEC) {
av_bprintf(&args, ":channel_layout=");
av_channel_layout_describe_bprint(&ifilter->ch_layout, &args);
} else
av_bprintf(&args, ":channels=%d", ifilter->ch_layout.nb_channels);
snprintf(name, sizeof(name), "graph_%d_in_%d_%d", fg->index,
ist->file_index, ist->st->index);
@ -960,6 +983,30 @@ static void cleanup_filtergraph(FilterGraph *fg)
avfilter_graph_free(&fg->graph);
}
static int filter_is_buffersrc(const AVFilterContext *f)
{
return f->nb_inputs == 0 &&
(!strcmp(f->filter->name, "buffer") ||
!strcmp(f->filter->name, "abuffer"));
}
static int graph_is_meta(AVFilterGraph *graph)
{
for (unsigned i = 0; i < graph->nb_filters; i++) {
const AVFilterContext *f = graph->filters[i];
/* in addition to filters flagged as meta, also
* disregard sinks and buffersources (but not other sources,
* since they introduce data we are not aware of)
*/
if (!((f->filter->flags & AVFILTER_FLAG_METADATA_ONLY) ||
f->nb_outputs == 0 ||
filter_is_buffersrc(f)))
return 0;
}
return 1;
}
int configure_filtergraph(FilterGraph *fg)
{
AVFilterInOut *inputs, *outputs, *cur;
@ -974,24 +1021,31 @@ int configure_filtergraph(FilterGraph *fg)
if (simple) {
OutputStream *ost = fg->outputs[0]->ost;
char args[512];
AVDictionaryEntry *e = NULL;
const AVDictionaryEntry *e = NULL;
fg->graph->nb_threads = filter_nbthreads;
if (filter_nbthreads) {
ret = av_opt_set(fg->graph, "threads", filter_nbthreads, 0);
if (ret < 0)
goto fail;
} else {
e = av_dict_get(ost->encoder_opts, "threads", NULL, 0);
if (e)
av_opt_set(fg->graph, "threads", e->value, 0);
}
args[0] = 0;
e = NULL;
while ((e = av_dict_get(ost->sws_dict, "", e,
AV_DICT_IGNORE_SUFFIX))) {
av_strlcatf(args, sizeof(args), "%s=%s:", e->key, e->value);
}
if (strlen(args))
if (strlen(args)) {
args[strlen(args)-1] = 0;
if (!strncmp(args, "sws_flags=", 10)) {
// keep the 'flags=' part
fg->graph->scale_sws_opts = av_strdup(args+4);
fg->graph->scale_sws_opts = av_strdup(args);
}
args[0] = 0;
e = NULL;
while ((e = av_dict_get(ost->swr_opts, "", e,
AV_DICT_IGNORE_SUFFIX))) {
av_strlcatf(args, sizeof(args), "%s=%s:", e->key, e->value);
@ -999,18 +1053,6 @@ int configure_filtergraph(FilterGraph *fg)
if (strlen(args))
args[strlen(args)-1] = 0;
av_opt_set(fg->graph, "aresample_swr_opts", args, 0);
args[0] = '\0';
while ((e = av_dict_get(fg->outputs[0]->ost->resample_opts, "", e,
AV_DICT_IGNORE_SUFFIX))) {
av_strlcatf(args, sizeof(args), "%s=%s:", e->key, e->value);
}
if (strlen(args))
args[strlen(args) - 1] = '\0';
e = av_dict_get(ost->encoder_opts, "threads", NULL, 0);
if (e)
av_opt_set(fg->graph, "threads", e->value, 0);
} else {
fg->graph->nb_threads = filter_complex_nbthreads;
}
@ -1065,6 +1107,8 @@ int configure_filtergraph(FilterGraph *fg)
if ((ret = avfilter_graph_config(fg->graph, NULL)) < 0)
goto fail;
fg->is_meta = graph_is_meta(fg->graph);
/* limit the lists of allowed formats to the ones selected, to
* make sure they stay the same if the filtergraph is reconfigured later */
for (i = 0; i < fg->nb_outputs; i++) {
@ -1077,7 +1121,10 @@ int configure_filtergraph(FilterGraph *fg)
ofilter->height = av_buffersink_get_h(sink);
ofilter->sample_rate = av_buffersink_get_sample_rate(sink);
ofilter->channel_layout = av_buffersink_get_channel_layout(sink);
av_channel_layout_uninit(&ofilter->ch_layout);
ret = av_buffersink_get_ch_layout(sink, &ofilter->ch_layout);
if (ret < 0)
goto fail;
}
fg->reconfiguration = 1;
@ -1099,9 +1146,8 @@ int configure_filtergraph(FilterGraph *fg)
}
for (i = 0; i < fg->nb_inputs; i++) {
while (av_fifo_size(fg->inputs[i]->frame_queue)) {
AVFrame *tmp;
av_fifo_generic_read(fg->inputs[i]->frame_queue, &tmp, sizeof(tmp), NULL);
while (av_fifo_read(fg->inputs[i]->frame_queue, &tmp, 1) >= 0) {
ret = av_buffersrc_add_frame(fg->inputs[i]->filter, tmp);
av_frame_free(&tmp);
if (ret < 0)
@ -1122,9 +1168,8 @@ int configure_filtergraph(FilterGraph *fg)
for (i = 0; i < fg->nb_inputs; i++) {
InputStream *ist = fg->inputs[i]->ist;
if (ist->sub2video.sub_queue && ist->sub2video.frame) {
while (av_fifo_size(ist->sub2video.sub_queue)) {
AVSubtitle tmp;
av_fifo_generic_read(ist->sub2video.sub_queue, &tmp, sizeof(tmp), NULL);
while (av_fifo_read(ist->sub2video.sub_queue, &tmp, 1) >= 0) {
sub2video_update(ist, INT64_MIN, &tmp);
avsubtitle_free(&tmp);
}
@ -1140,6 +1185,9 @@ fail:
int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *frame)
{
AVFrameSideData *sd;
int ret;
av_buffer_unref(&ifilter->hw_frames_ctx);
ifilter->format = frame->format;
@ -1149,8 +1197,14 @@ int ifilter_parameters_from_frame(InputFilter *ifilter, const AVFrame *frame)
ifilter->sample_aspect_ratio = frame->sample_aspect_ratio;
ifilter->sample_rate = frame->sample_rate;
ifilter->channels = frame->channels;
ifilter->channel_layout = frame->channel_layout;
ret = av_channel_layout_copy(&ifilter->ch_layout, &frame->ch_layout);
if (ret < 0)
return ret;
av_freep(&ifilter->displaymatrix);
sd = av_frame_get_side_data(frame, AV_FRAME_DATA_DISPLAYMATRIX);
if (sd)
ifilter->displaymatrix = av_memdup(sd->data, sizeof(int32_t) * 9);
if (frame->hw_frames_ctx) {
ifilter->hw_frames_ctx = av_buffer_ref(frame->hw_frames_ctx);

@ -1,4 +1,6 @@
/*
* copyright (c) 2018 Taner Sener ( tanersener gmail com )
*
* This file is part of FFmpeg.
*
* FFmpeg is free software; you can redistribute it and/or
@ -17,10 +19,17 @@
*/
/*
* CHANGES 12.2019
* - Concurrent execution support
* This file is the modified version of ffmpeg_hw.c file living in ffmpeg source code under the fftools folder. We
* manually update it each time we depend on a new ffmpeg version. Below you can see the list of changes applied
* by us to develop mobile-ffmpeg and later ffmpeg-kit libraries.
*
* mobile-ffmpeg / ffmpeg-kit changes by Taner Sener
*
* 12.2019
* --------------------------------------------------------
* - concurrent execution support ("__thread" specifier added to variables used by multiple threads)
*
* CHANGES 08.2018
* 08.2018
* --------------------------------------------------------
* - fftools_ prefix added to file name and parent header
*/
@ -102,6 +111,8 @@ static char *hw_device_default_name(enum AVHWDeviceType type)
int hw_device_init_from_string(const char *arg, HWDevice **dev_out)
{
// "type=name"
// "type=name,key=value,key2=value2"
// "type=name:device,key=value,key2=value2"
// "type:device,key=value,key2=value2"
// -> av_hwdevice_ctx_create()
@ -133,7 +144,7 @@ int hw_device_init_from_string(const char *arg, HWDevice **dev_out)
}
if (*p == '=') {
k = strcspn(p + 1, ":@");
k = strcspn(p + 1, ":@,");
name = av_strndup(p + 1, k);
if (!name) {
@ -199,6 +210,18 @@ int hw_device_init_from_string(const char *arg, HWDevice **dev_out)
src->device_ref, 0);
if (err < 0)
goto fail;
} else if (*p == ',') {
err = av_dict_parse_string(&options, p + 1, "=", ",", 0);
if (err < 0) {
errmsg = "failed to parse options";
goto invalid;
}
err = av_hwdevice_ctx_create(&device_ref, type,
NULL, options, 0);
if (err < 0)
goto fail;
} else {
errmsg = "parse error";
goto invalid;
@ -548,15 +571,21 @@ int hw_device_setup_for_filter(FilterGraph *fg)
HWDevice *dev;
int i;
// If the user has supplied exactly one hardware device then just
// give it straight to every filter for convenience. If more than
// one device is available then the user needs to pick one explcitly
// with the filter_hw_device option.
// Pick the last hardware device if the user doesn't pick the device for
// filters explicitly with the filter_hw_device option.
if (filter_hw_device)
dev = filter_hw_device;
else if (nb_hw_devices == 1)
dev = hw_devices[0];
else
else if (nb_hw_devices > 0) {
dev = hw_devices[nb_hw_devices - 1];
if (nb_hw_devices > 1)
av_log(NULL, AV_LOG_WARNING, "There are %d hardware devices. device "
"%s of type %s is picked for filters by default. Set hardware "
"device explicitly with the filter_hw_device option if device "
"%s is not usable for filters.\n",
nb_hw_devices, dev->name,
av_hwdevice_get_type_name(dev->type), dev->name);
} else
dev = NULL;
if (dev) {

@ -0,0 +1,332 @@
/*
* This file is part of FFmpeg.
* copyright (c) 2022 Taner Sener ( tanersener gmail com )
*
* 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 is the modified version of ffmpeg_mux.c file living in ffmpeg source code under the fftools folder. We
* manually update it each time we depend on a new ffmpeg version. Below you can see the list of changes applied
* by us to develop the ffmpeg-kit library.
*
* ffmpeg-kit changes by Taner Sener
*
* 09.2022
* --------------------------------------------------------
* - fftools_ prefix added to fftools headers
* - using main_ffmpeg_return_code instead of main_return_code
* - printf replaced with av_log statements
*/
#include <stdio.h>
#include <string.h>
#include "fftools_ffmpeg.h"
#include "libavutil/fifo.h"
#include "libavutil/intreadwrite.h"
#include "libavutil/log.h"
#include "libavutil/mem.h"
#include "libavutil/timestamp.h"
#include "libavcodec/packet.h"
#include "libavformat/avformat.h"
#include "libavformat/avio.h"
static void close_all_output_streams(OutputStream *ost, OSTFinished this_stream, OSTFinished others)
{
int i;
for (i = 0; i < nb_output_streams; i++) {
OutputStream *ost2 = output_streams[i];
ost2->finished |= ost == ost2 ? this_stream : others;
}
}
void of_write_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost,
int unqueue)
{
AVFormatContext *s = of->ctx;
AVStream *st = ost->st;
int ret;
/*
* Audio encoders may split the packets -- #frames in != #packets out.
* But there is no reordering, so we can limit the number of output packets
* by simply dropping them here.
* Counting encoded video frames needs to be done separately because of
* reordering, see do_video_out().
* Do not count the packet when unqueued because it has been counted when queued.
*/
if (!(st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && ost->encoding_needed) && !unqueue) {
if (ost->frame_number >= ost->max_frames) {
av_packet_unref(pkt);
return;
}
ost->frame_number++;
}
if (!of->header_written) {
AVPacket *tmp_pkt;
/* the muxer is not initialized yet, buffer the packet */
if (!av_fifo_can_write(ost->muxing_queue)) {
size_t cur_size = av_fifo_can_read(ost->muxing_queue);
unsigned int are_we_over_size =
(ost->muxing_queue_data_size + pkt->size) > ost->muxing_queue_data_threshold;
size_t limit = are_we_over_size ? ost->max_muxing_queue_size : SIZE_MAX;
size_t new_size = FFMIN(2 * cur_size, limit);
if (new_size <= cur_size) {
av_log(NULL, AV_LOG_ERROR,
"Too many packets buffered for output stream %d:%d.\n",
ost->file_index, ost->st->index);
exit_program(1);
}
ret = av_fifo_grow2(ost->muxing_queue, new_size - cur_size);
if (ret < 0)
exit_program(1);
}
ret = av_packet_make_refcounted(pkt);
if (ret < 0)
exit_program(1);
tmp_pkt = av_packet_alloc();
if (!tmp_pkt)
exit_program(1);
av_packet_move_ref(tmp_pkt, pkt);
ost->muxing_queue_data_size += tmp_pkt->size;
av_fifo_write(ost->muxing_queue, &tmp_pkt, 1);
return;
}
if ((st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && ost->vsync_method == VSYNC_DROP) ||
(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && audio_sync_method < 0))
pkt->pts = pkt->dts = AV_NOPTS_VALUE;
if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
if (ost->frame_rate.num && ost->is_cfr) {
if (pkt->duration > 0)
av_log(NULL, AV_LOG_WARNING, "Overriding packet duration by frame rate, this should not happen\n");
pkt->duration = av_rescale_q(1, av_inv_q(ost->frame_rate),
ost->mux_timebase);
}
}
av_packet_rescale_ts(pkt, ost->mux_timebase, ost->st->time_base);
if (!(s->oformat->flags & AVFMT_NOTIMESTAMPS)) {
if (pkt->dts != AV_NOPTS_VALUE &&
pkt->pts != AV_NOPTS_VALUE &&
pkt->dts > pkt->pts) {
av_log(s, AV_LOG_WARNING, "Invalid DTS: %"PRId64" PTS: %"PRId64" in output stream %d:%d, replacing by guess\n",
pkt->dts, pkt->pts,
ost->file_index, ost->st->index);
pkt->pts =
pkt->dts = pkt->pts + pkt->dts + ost->last_mux_dts + 1
- FFMIN3(pkt->pts, pkt->dts, ost->last_mux_dts + 1)
- FFMAX3(pkt->pts, pkt->dts, ost->last_mux_dts + 1);
}
if ((st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO || st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO || st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) &&
pkt->dts != AV_NOPTS_VALUE &&
ost->last_mux_dts != AV_NOPTS_VALUE) {
int64_t max = ost->last_mux_dts + !(s->oformat->flags & AVFMT_TS_NONSTRICT);
if (pkt->dts < max) {
int loglevel = max - pkt->dts > 2 || st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO ? AV_LOG_WARNING : AV_LOG_DEBUG;
if (exit_on_error)
loglevel = AV_LOG_ERROR;
av_log(s, loglevel, "Non-monotonous DTS in output stream "
"%d:%d; previous: %"PRId64", current: %"PRId64"; ",
ost->file_index, ost->st->index, ost->last_mux_dts, pkt->dts);
if (exit_on_error) {
av_log(NULL, AV_LOG_FATAL, "aborting.\n");
exit_program(1);
}
av_log(s, loglevel, "changing to %"PRId64". This may result "
"in incorrect timestamps in the output file.\n",
max);
if (pkt->pts >= pkt->dts)
pkt->pts = FFMAX(pkt->pts, max);
pkt->dts = max;
}
}
}
ost->last_mux_dts = pkt->dts;
ost->data_size += pkt->size;
ost->packets_written++;
pkt->stream_index = ost->index;
if (debug_ts) {
av_log(NULL, AV_LOG_INFO, "muxer <- type:%s "
"pkt_pts:%s pkt_pts_time:%s pkt_dts:%s pkt_dts_time:%s duration:%s duration_time:%s size:%d\n",
av_get_media_type_string(ost->enc_ctx->codec_type),
av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &ost->st->time_base),
av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &ost->st->time_base),
av_ts2str(pkt->duration), av_ts2timestr(pkt->duration, &ost->st->time_base),
pkt->size
);
}
ret = av_interleaved_write_frame(s, pkt);
if (ret < 0) {
print_error("av_interleaved_write_frame()", ret);
main_ffmpeg_return_code = 1;
close_all_output_streams(ost, MUXER_FINISHED | ENCODER_FINISHED, ENCODER_FINISHED);
}
}
static int print_sdp(void)
{
char sdp[16384];
int i;
int j, ret;
AVIOContext *sdp_pb;
AVFormatContext **avc;
for (i = 0; i < nb_output_files; i++) {
if (!output_files[i]->header_written)
return 0;
}
avc = av_malloc_array(nb_output_files, sizeof(*avc));
if (!avc)
exit_program(1);
for (i = 0, j = 0; i < nb_output_files; i++) {
if (!strcmp(output_files[i]->ctx->oformat->name, "rtp")) {
avc[j] = output_files[i]->ctx;
j++;
}
}
if (!j) {
av_log(NULL, AV_LOG_ERROR, "No output streams in the SDP.\n");
ret = AVERROR(EINVAL);
goto fail;
}
ret = av_sdp_create(avc, j, sdp, sizeof(sdp));
if (ret < 0)
goto fail;
if (!sdp_filename) {
av_log(NULL, AV_LOG_ERROR, "SDP:\n%s\n", sdp);
fflush(stdout);
} else {
ret = avio_open2(&sdp_pb, sdp_filename, AVIO_FLAG_WRITE, &int_cb, NULL);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Failed to open sdp file '%s'\n", sdp_filename);
goto fail;
}
avio_print(sdp_pb, sdp);
avio_closep(&sdp_pb);
av_freep(&sdp_filename);
}
fail:
av_freep(&avc);
return ret;
}
/* open the muxer when all the streams are initialized */
int of_check_init(OutputFile *of)
{
int ret, i;
for (i = 0; i < of->ctx->nb_streams; i++) {
OutputStream *ost = output_streams[of->ost_index + i];
if (!ost->initialized)
return 0;
}
ret = avformat_write_header(of->ctx, &of->opts);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR,
"Could not write header for output file #%d "
"(incorrect codec parameters ?): %s\n",
of->index, av_err2str(ret));
return ret;
}
//assert_avoptions(of->opts);
of->header_written = 1;
av_dump_format(of->ctx, of->index, of->ctx->url, 1);
nb_output_dumped++;
if (sdp_filename || want_sdp) {
ret = print_sdp();
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Error writing the SDP.\n");
return ret;
}
}
/* flush the muxing queues */
for (i = 0; i < of->ctx->nb_streams; i++) {
OutputStream *ost = output_streams[of->ost_index + i];
AVPacket *pkt;
/* try to improve muxing time_base (only possible if nothing has been written yet) */
if (!av_fifo_can_read(ost->muxing_queue))
ost->mux_timebase = ost->st->time_base;
while (av_fifo_read(ost->muxing_queue, &pkt, 1) >= 0) {
ost->muxing_queue_data_size -= pkt->size;
of_write_packet(of, pkt, ost, 1);
av_packet_free(&pkt);
}
}
return 0;
}
int of_write_trailer(OutputFile *of)
{
int ret;
if (!of->header_written) {
av_log(NULL, AV_LOG_ERROR,
"Nothing was written into output file %d (%s), because "
"at least one of its streams received no packets.\n",
of->index, of->ctx->url);
return AVERROR(EINVAL);
}
ret = av_write_trailer(of->ctx);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Error writing trailer of %s: %s\n", of->ctx->url, av_err2str(ret));
return ret;
}
return 0;
}
void of_close(OutputFile **pof)
{
OutputFile *of = *pof;
AVFormatContext *s;
if (!of)
return;
s = of->ctx;
if (s && s->oformat && !(s->oformat->flags & AVFMT_NOFILE))
avio_closep(&s->pb);
avformat_free_context(s);
av_dict_free(&of->opts);
av_freep(pof);
}

File diff suppressed because it is too large Load Diff

@ -1,177 +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 "config.h"
#if HAVE_UTGETOSTYPEFROMSTRING
#include <CoreServices/CoreServices.h>
#endif
#include "libavcodec/avcodec.h"
#include "libavcodec/videotoolbox.h"
#include "libavutil/imgutils.h"
#include "fftools_ffmpeg.h"
typedef struct VTContext {
AVFrame *tmp_frame;
int log_once;
} VTContext;
__thread char *videotoolbox_pixfmt;
static int videotoolbox_retrieve_data(AVCodecContext *s, AVFrame *frame)
{
InputStream *ist = s->opaque;
VTContext *vt = ist->hwaccel_ctx;
CVPixelBufferRef pixbuf = (CVPixelBufferRef)frame->data[3];
OSType pixel_format = CVPixelBufferGetPixelFormatType(pixbuf);
CVReturn err;
uint8_t *data[4] = { 0 };
int linesize[4] = { 0 };
int planes, ret, i;
if (frame->format == ist->hwaccel_output_format) {
av_log_once(s, AV_LOG_INFO, AV_LOG_TRACE, &vt->log_once,
"There is no video filter for videotoolbox pix_fmt now, remove the "
"-hwaccel_output_format option if video filter doesn't work\n");
return 0;
}
av_frame_unref(vt->tmp_frame);
switch (pixel_format) {
case kCVPixelFormatType_420YpCbCr8Planar: vt->tmp_frame->format = AV_PIX_FMT_YUV420P; break;
case kCVPixelFormatType_422YpCbCr8: vt->tmp_frame->format = AV_PIX_FMT_UYVY422; break;
case kCVPixelFormatType_32BGRA: vt->tmp_frame->format = AV_PIX_FMT_BGRA; break;
#ifdef kCFCoreFoundationVersionNumber10_7
case kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange:
case kCVPixelFormatType_420YpCbCr8BiPlanarFullRange: vt->tmp_frame->format = AV_PIX_FMT_NV12; break;
#endif
#if HAVE_KCVPIXELFORMATTYPE_420YPCBCR10BIPLANARVIDEORANGE
case kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange:
case kCVPixelFormatType_420YpCbCr10BiPlanarFullRange: vt->tmp_frame->format = AV_PIX_FMT_P010; break;
#endif
default:
av_log(NULL, AV_LOG_ERROR,
"%s: Unsupported pixel format: %s\n",
av_fourcc2str(s->codec_tag), videotoolbox_pixfmt);
return AVERROR(ENOSYS);
}
vt->tmp_frame->width = frame->width;
vt->tmp_frame->height = frame->height;
ret = av_frame_get_buffer(vt->tmp_frame, 0);
if (ret < 0)
return ret;
err = CVPixelBufferLockBaseAddress(pixbuf, kCVPixelBufferLock_ReadOnly);
if (err != kCVReturnSuccess) {
av_log(NULL, AV_LOG_ERROR, "Error locking the pixel buffer.\n");
return AVERROR_UNKNOWN;
}
if (CVPixelBufferIsPlanar(pixbuf)) {
planes = CVPixelBufferGetPlaneCount(pixbuf);
for (i = 0; i < planes; i++) {
data[i] = CVPixelBufferGetBaseAddressOfPlane(pixbuf, i);
linesize[i] = CVPixelBufferGetBytesPerRowOfPlane(pixbuf, i);
}
} else {
data[0] = CVPixelBufferGetBaseAddress(pixbuf);
linesize[0] = CVPixelBufferGetBytesPerRow(pixbuf);
}
av_image_copy(vt->tmp_frame->data, vt->tmp_frame->linesize,
(const uint8_t **)data, linesize, vt->tmp_frame->format,
frame->width, frame->height);
ret = av_frame_copy_props(vt->tmp_frame, frame);
CVPixelBufferUnlockBaseAddress(pixbuf, kCVPixelBufferLock_ReadOnly);
if (ret < 0)
return ret;
av_frame_unref(frame);
av_frame_move_ref(frame, vt->tmp_frame);
return 0;
}
static void videotoolbox_uninit(AVCodecContext *s)
{
InputStream *ist = s->opaque;
VTContext *vt = ist->hwaccel_ctx;
ist->hwaccel_uninit = NULL;
ist->hwaccel_retrieve_data = NULL;
av_frame_free(&vt->tmp_frame);
av_videotoolbox_default_free(s);
av_freep(&ist->hwaccel_ctx);
}
int videotoolbox_init(AVCodecContext *s)
{
InputStream *ist = s->opaque;
int loglevel = (ist->hwaccel_id == HWACCEL_AUTO) ? AV_LOG_VERBOSE : AV_LOG_ERROR;
int ret = 0;
VTContext *vt;
vt = av_mallocz(sizeof(*vt));
if (!vt)
return AVERROR(ENOMEM);
ist->hwaccel_ctx = vt;
ist->hwaccel_uninit = videotoolbox_uninit;
ist->hwaccel_retrieve_data = videotoolbox_retrieve_data;
vt->tmp_frame = av_frame_alloc();
if (!vt->tmp_frame) {
ret = AVERROR(ENOMEM);
goto fail;
}
// TODO: reindent
if (!videotoolbox_pixfmt) {
ret = av_videotoolbox_default_init(s);
} else {
AVVideotoolboxContext *vtctx = av_videotoolbox_alloc_context();
CFStringRef pixfmt_str = CFStringCreateWithCString(kCFAllocatorDefault,
videotoolbox_pixfmt,
kCFStringEncodingUTF8);
#if HAVE_UTGETOSTYPEFROMSTRING
vtctx->cv_pix_fmt_type = UTGetOSTypeFromString(pixfmt_str);
#else
av_log(s, loglevel, "UTGetOSTypeFromString() is not available "
"on this platform, %s pixel format can not be honored from "
"the command line\n", videotoolbox_pixfmt);
#endif
ret = av_videotoolbox_default_init2(s, vtctx);
CFRelease(pixfmt_str);
}
if (ret < 0) {
av_log(NULL, loglevel, "Error creating Videotoolbox decoder.\n");
goto fail;
}
return 0;
fail:
videotoolbox_uninit(s);
return ret;
}

File diff suppressed because it is too large Load Diff

@ -0,0 +1,79 @@
/*
* 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 is the modified version of fopen_utf8.h file living in ffmpeg source code under the fftools folder. We
* manually update it each time we depend on a new ffmpeg version. Below you can see the list of changes applied
* by us to develop the ffmpeg-kit library.
*
* ffmpeg-kit changes by Taner Sener
*/
#ifndef FFTOOLS_FOPEN_UTF8_H
#define FFTOOLS_FOPEN_UTF8_H
#include <stdio.h>
/* The fopen_utf8 function here is essentially equivalent to avpriv_fopen_utf8,
* except that it doesn't set O_CLOEXEC, and that it isn't exported
* from a different library. (On Windows, each DLL might use a different
* CRT, and FILE* handles can't be shared across them.) */
#ifdef _WIN32
#include "libavutil/wchar_filename.h"
static inline FILE *fopen_utf8(const char *path_utf8, const char *mode)
{
wchar_t *path_w, *mode_w;
FILE *f;
/* convert UTF-8 to wide chars */
if (get_extended_win32_path(path_utf8, &path_w)) /* This sets errno on error. */
return NULL;
if (!path_w)
goto fallback;
if (utf8towchar(mode, &mode_w))
return NULL;
if (!mode_w) {
/* If failing to interpret the mode string as utf8, it is an invalid
* parameter. */
av_freep(&path_w);
errno = EINVAL;
return NULL;
}
f = _wfopen(path_w, mode_w);
av_freep(&path_w);
av_freep(&mode_w);
return f;
fallback:
/* path may be in CP_ACP */
return fopen(path_utf8, mode);
}
#else
static inline FILE *fopen_utf8(const char *path, const char *mode)
{
return fopen(path, mode);
}
#endif
#endif /* FFTOOLS_FOPEN_UTF8_H */

File diff suppressed because it is too large Load Diff

@ -0,0 +1,202 @@
/*
* Option handlers shared between the tools.
* copyright (c) 2022 Taner Sener ( tanersener 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
*/
/*
* This file is the modified version of opt_common.h file living in ffmpeg source code under the fftools folder. We
* manually update it each time we depend on a new ffmpeg version. Below you can see the list of changes applied
* by us to develop the ffmpeg-kit library.
*
* ffmpeg-kit changes by Taner Sener
*
* 09.2022
* --------------------------------------------------------
* - CMDUTILS_COMMON_OPTIONS and CMDUTILS_COMMON_OPTIONS_AVDEVICE defines dropped
* - fftools_ prefix added to fftools headers
*/
#ifndef FFTOOLS_OPT_COMMON_H
#define FFTOOLS_OPT_COMMON_H
#include "config.h"
#include "fftools_cmdutils.h"
#if CONFIG_AVDEVICE
/**
* Print a listing containing autodetected sinks of the output device.
* Device name with options may be passed as an argument to limit results.
*/
int show_sinks(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing autodetected sources of the input device.
* Device name with options may be passed as an argument to limit results.
*/
int show_sources(void *optctx, const char *opt, const char *arg);
#endif
/**
* Print the license of the program to stdout. The license depends on
* the license of the libraries compiled into the program.
* This option processing function does not utilize the arguments.
*/
int show_license(void *optctx, const char *opt, const char *arg);
/**
* Generic -h handler common to all fftools.
*/
int show_help(void *optctx, const char *opt, const char *arg);
/**
* Print the version of the program to stdout. The version message
* depends on the current versions of the repository and of the libav*
* libraries.
* This option processing function does not utilize the arguments.
*/
int show_version(void *optctx, const char *opt, const char *arg);
/**
* Print the build configuration of the program to stdout. The contents
* depend on the definition of FFMPEG_CONFIGURATION.
* This option processing function does not utilize the arguments.
*/
int show_buildconf(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the formats supported by the
* program (including devices).
* This option processing function does not utilize the arguments.
*/
int show_formats(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the muxers supported by the
* program (including devices).
* This option processing function does not utilize the arguments.
*/
int show_muxers(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the demuxer supported by the
* program (including devices).
* This option processing function does not utilize the arguments.
*/
int show_demuxers(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the devices supported by the
* program.
* This option processing function does not utilize the arguments.
*/
int show_devices(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the codecs supported by the
* program.
* This option processing function does not utilize the arguments.
*/
int show_codecs(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the decoders supported by the
* program.
*/
int show_decoders(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the encoders supported by the
* program.
*/
int show_encoders(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the bit stream filters supported by the
* program.
* This option processing function does not utilize the arguments.
*/
int show_bsfs(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the protocols supported by the
* program.
* This option processing function does not utilize the arguments.
*/
int show_protocols(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the filters supported by the
* program.
* This option processing function does not utilize the arguments.
*/
int show_filters(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the pixel formats supported by the
* program.
* This option processing function does not utilize the arguments.
*/
int show_pix_fmts(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the standard channel layouts supported by
* the program.
* This option processing function does not utilize the arguments.
*/
int show_layouts(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the sample formats supported by the
* program.
*/
int show_sample_fmts(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all supported stream dispositions.
*/
int show_dispositions(void *optctx, const char *opt, const char *arg);
/**
* Print a listing containing all the color names and values recognized
* by the program.
*/
int show_colors(void *optctx, const char *opt, const char *arg);
/**
* Set the libav* libraries log level.
*/
int opt_loglevel(void *optctx, const char *opt, const char *arg);
int opt_report(void *optctx, const char *opt, const char *arg);
int init_report(const char *env, FILE **file);
int opt_max_alloc(void *optctx, const char *opt, const char *arg);
/**
* Override the cpuflags.
*/
int opt_cpuflags(void *optctx, const char *opt, const char *arg);
/**
* Override the cpucount.
*/
int opt_cpucount(void *optctx, const char *opt, const char *arg);
#endif /* FFTOOLS_OPT_COMMON_H */

@ -10,5 +10,5 @@ show_downloads: true
github:
zip_url:
tar_url:
owner_name: Taner Sener
owner_url: https://github.com/tanersener
owner_name: ARTHENICA
owner_url: https://github.com/arthenica

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save