mirror of
https://github.com/CCExtractor/ccextractor.git
synced 2026-02-07 21:22:17 +00:00
Compare commits
47 Commits
compatibil
...
v0.94
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
97b381a2b0 | ||
|
|
03b0749e91 | ||
|
|
7bcdd6729f | ||
|
|
3dd3d5f6aa | ||
|
|
ba37cc41c8 | ||
|
|
6efa41a7e6 | ||
|
|
9b90c91f07 | ||
|
|
35936618e3 | ||
|
|
e98a584e98 | ||
|
|
1a8c8a86f3 | ||
|
|
57663b8cf1 | ||
|
|
2b3d759e20 | ||
|
|
ed1b5dddce | ||
|
|
86fede6af8 | ||
|
|
68e6390c76 | ||
|
|
0ebeec4183 | ||
|
|
8c10ded107 | ||
|
|
3a1851f904 | ||
|
|
50aceb45fb | ||
|
|
cad6b0495c | ||
|
|
c7ebd45d9f | ||
|
|
77abe01885 | ||
|
|
98cec31516 | ||
|
|
46b145a396 | ||
|
|
ccf2a031e9 | ||
|
|
9784cd5bd1 | ||
|
|
5d8dc3b9eb | ||
|
|
a42e847bcb | ||
|
|
b7a1dd1030 | ||
|
|
b18e696c85 | ||
|
|
d58f078c38 | ||
|
|
0bbdfc13ee | ||
|
|
5127da50d1 | ||
|
|
352f035214 | ||
|
|
f04ba8d0c4 | ||
|
|
1ea94d0b14 | ||
|
|
7f99603859 | ||
|
|
3713283dfc | ||
|
|
09129f1e63 | ||
|
|
c56840ff2c | ||
|
|
2a34bd99e6 | ||
|
|
c7886ed615 | ||
|
|
948531a4be | ||
|
|
022987c804 | ||
|
|
db6c852fae | ||
|
|
b793f16343 | ||
|
|
ceaaa65a26 |
2
.github/ISSUE_TEMPLATE.md
vendored
2
.github/ISSUE_TEMPLATE.md
vendored
@@ -2,6 +2,8 @@ Please prefix your issue with one of the following: [BUG], [PROPOSAL], [QUESTION
|
||||
|
||||
To get the version of CCExtractor, you can use `--version`.
|
||||
|
||||
If this issue is related to the flutter GUI, please make the issue on the GUI repo [here](https://github.com/CCExtractor/ccextractorfluttergui/issues/new)
|
||||
|
||||
Please check all that apply and **remove the ones that do not**.
|
||||
|
||||
In the necessary information section, if this is a regression (something that used to work does not work anymore), make sure to specify the last known working version.
|
||||
|
||||
46
.github/workflows/build_linux.yml
vendored
46
.github/workflows/build_linux.yml
vendored
@@ -9,6 +9,9 @@ on:
|
||||
- '**Makefile**'
|
||||
- 'linux/**'
|
||||
- 'package_creators/**'
|
||||
- 'src/rust/**'
|
||||
tags-ignore: # ignore push via new tag
|
||||
- '*.*'
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
paths:
|
||||
@@ -18,18 +21,20 @@ on:
|
||||
- '**Makefile**'
|
||||
- 'linux/**'
|
||||
- 'package_creators/**'
|
||||
- 'src/rust/**'
|
||||
jobs:
|
||||
build_shell:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Install tesseract
|
||||
run: sudo apt-get install libtesseract-dev
|
||||
- uses: actions/checkout@v2.3.4
|
||||
- uses: actions/checkout@v2.4.0
|
||||
- name: build
|
||||
run: ./build
|
||||
working-directory: ./linux
|
||||
- name: Display version information
|
||||
run: ./linux/ccextractor --version
|
||||
run: ./ccextractor --version
|
||||
working-directory: ./linux
|
||||
- name: Prepare artifacts
|
||||
run: mkdir ./linux/artifacts
|
||||
- name: Copy release artifact
|
||||
@@ -41,22 +46,23 @@ jobs:
|
||||
build_autoconf:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2.3.4
|
||||
- uses: actions/checkout@v2.4.0
|
||||
- name: run autogen
|
||||
run: ./autogen.sh
|
||||
working-directory: ./linux
|
||||
- name: configure
|
||||
run: ./configure
|
||||
run: ./configure --enable-debug
|
||||
working-directory: ./linux
|
||||
- name: make
|
||||
run: make
|
||||
working-directory: ./linux
|
||||
- name: Display version information
|
||||
run: ./linux/ccextractor --version
|
||||
run: ./ccextractor --version
|
||||
working-directory: ./linux
|
||||
cmake:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2.3.4
|
||||
- uses: actions/checkout@v2.4.0
|
||||
- name: cmake
|
||||
run: mkdir build && cd build && cmake ../src
|
||||
- name: build
|
||||
@@ -67,7 +73,7 @@ jobs:
|
||||
cmake_ocr_hardsubx:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2.3.4
|
||||
- uses: actions/checkout@v2.4.0
|
||||
- name: dependencies
|
||||
run: sudo apt update && sudo apt install libtesseract-dev libavformat-dev libswscale-dev
|
||||
- name: cmake
|
||||
@@ -77,13 +83,23 @@ jobs:
|
||||
working-directory: build
|
||||
- name: Display version information
|
||||
run: ./build/ccextractor --version
|
||||
bazel:
|
||||
build_rust:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2.3.4
|
||||
- name: bazel build
|
||||
working-directory: ./
|
||||
run: bazel build //src:ccextractor --verbose_failures
|
||||
- name: Display version information
|
||||
working-directory: ./bazel-bin
|
||||
run: ./src/ccextractor --version
|
||||
- uses: actions/checkout@v2.4.0
|
||||
- name: cache
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: |
|
||||
src/rust/.cargo/registry
|
||||
src/rust/.cargo/git
|
||||
src/rust/target
|
||||
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
|
||||
restore-keys: ${{ runner.os }}-cargo-
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
override: true
|
||||
- name: build
|
||||
run: cargo build
|
||||
working-directory: ./src/rust
|
||||
|
||||
222
.github/workflows/build_windows.yml
vendored
222
.github/workflows/build_windows.yml
vendored
@@ -3,106 +3,156 @@ name: Build CCExtractor on Windows
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- '.github/workflows/build_windows.yml'
|
||||
- '**.c'
|
||||
- '**.h'
|
||||
- 'windows/**'
|
||||
- ".github/workflows/build_windows.yml"
|
||||
- "**.c"
|
||||
- "**.h"
|
||||
- "windows/**"
|
||||
tags-ignore: # ignore push via new tag
|
||||
- "*.*"
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
paths:
|
||||
- '.github/workflows/build_windows.yml'
|
||||
- '**.c'
|
||||
- '**.h'
|
||||
- 'windows/**'
|
||||
- ".github/workflows/build_windows.yml"
|
||||
- "**.c"
|
||||
- "**.h"
|
||||
- "windows/**"
|
||||
|
||||
jobs:
|
||||
build_non_ocr_release:
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@v2.3.4
|
||||
- name: Setup MSBuild.exe
|
||||
uses: microsoft/setup-msbuild@v1.0.2
|
||||
- name: build Release
|
||||
run: msbuild ccextractor.sln /p:Configuration=Release
|
||||
working-directory: ./windows
|
||||
- name: Display version information
|
||||
run: ./ccextractorwin.exe --version
|
||||
working-directory: ./windows/Release
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: CCExtractor Windows Non-OCR Release build
|
||||
path: |
|
||||
./windows/Release/ccextractorwin.exe
|
||||
./windows/Release/ccextractorgui.exe
|
||||
./windows/Release/*.dll
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@v2.4.0
|
||||
- name: Setup MSBuild.exe
|
||||
uses: microsoft/setup-msbuild@v1.0.2
|
||||
- name: Install llvm and clang
|
||||
run: choco install llvm
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: 1.56.0
|
||||
override: true
|
||||
- name: Install Win 10 SDK
|
||||
uses: ilammy/msvc-dev-cmd@v1
|
||||
- name: build Release
|
||||
env:
|
||||
LIBCLANG_PATH: "C:\\Program Files\\LLVM\\lib"
|
||||
LLVM_CONFIG_PATH: "C:\\Program Files\\LLVM\\bin\\llvm-config"
|
||||
CARGO_TARGET_DIR: "..\\..\\windows"
|
||||
BINDGEN_EXTRA_CLANG_ARGS: -fmsc-version=0
|
||||
run: msbuild ccextractor.sln /p:Configuration=Release /p:Platform=x64
|
||||
working-directory: ./windows
|
||||
- name: Display version information
|
||||
run: ./ccextractorwin.exe --version
|
||||
working-directory: ./windows/x64/Release
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: CCExtractor Windows Non-OCR Release build
|
||||
path: |
|
||||
./windows/x64/Release/ccextractorwin.exe
|
||||
./windows/x64/Release/*.dll
|
||||
build_non_ocr_debug:
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@v2.3.4
|
||||
- name: Setup MSBuild.exe
|
||||
uses: microsoft/setup-msbuild@v1.0.2
|
||||
- name: build Debug
|
||||
run: msbuild ccextractor.sln /p:Configuration=Debug
|
||||
working-directory: ./windows
|
||||
- name: Display version information
|
||||
run: ./ccextractorwin.exe --version
|
||||
working-directory: ./windows/Debug
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: CCExtractor Windows Non-OCR Debug build
|
||||
path: |
|
||||
./windows/Debug/ccextractorwin.exe
|
||||
./windows/Debug/ccextractorwin.pdb
|
||||
./windows/Debug/ccextractorgui.exe
|
||||
./windows/Debug/*.dll
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@v2.4.0
|
||||
- name: Setup MSBuild.exe
|
||||
uses: microsoft/setup-msbuild@v1.0.2
|
||||
- name: Install llvm and clang
|
||||
run: choco install llvm
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: 1.56.0
|
||||
override: true
|
||||
- name: Install Win 10 SDK
|
||||
uses: ilammy/msvc-dev-cmd@v1
|
||||
- name: build Debug
|
||||
env:
|
||||
LIBCLANG_PATH: "C:\\Program Files\\LLVM\\lib"
|
||||
LLVM_CONFIG_PATH: "C:\\Program Files\\LLVM\\bin\\llvm-config"
|
||||
CARGO_TARGET_DIR: "..\\..\\windows"
|
||||
BINDGEN_EXTRA_CLANG_ARGS: -fmsc-version=0
|
||||
run: msbuild ccextractor.sln /p:Configuration=Debug /p:Platform=x64
|
||||
working-directory: ./windows
|
||||
- name: Display version information
|
||||
run: ./ccextractorwin.exe --version
|
||||
working-directory: ./windows/x64/Debug
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: CCExtractor Windows Non-OCR Debug build
|
||||
path: |
|
||||
./windows/x64/Debug/ccextractorwin.exe
|
||||
./windows/x64/Debug/ccextractorwin.pdb
|
||||
./windows/x64/Debug/*.dll
|
||||
build_ocr_hardsubx_release:
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@v2.3.4
|
||||
- name: Setup MSBuild.exe
|
||||
uses: microsoft/setup-msbuild@v1.0.2
|
||||
- name: build Release
|
||||
run: msbuild ccextractor.sln /p:Configuration=Release-Full
|
||||
working-directory: ./windows
|
||||
- name: Display version information
|
||||
run: ./ccextractorwinfull.exe --version
|
||||
working-directory: ./windows/Release-Full
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: CCExtractor Windows OCR and HardSubX Release build
|
||||
path: |
|
||||
./windows/Release-Full/ccextractorwinfull.exe
|
||||
./windows/Release-Full/*.dll
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: CCExtractor Windows OCR and HardSubX Release build
|
||||
path: |
|
||||
./windows/Release/ccextractorgui.exe
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@v2.4.0
|
||||
- name: Setup MSBuild.exe
|
||||
uses: microsoft/setup-msbuild@v1.0.2
|
||||
- name: Install llvm and clang
|
||||
uses: egor-tensin/setup-clang@v1
|
||||
with:
|
||||
version: latest
|
||||
platform: x86
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: 1.56.0
|
||||
override: true
|
||||
target: i686-pc-windows-msvc
|
||||
- name: Install Win 10 SDK
|
||||
uses: ilammy/msvc-dev-cmd@v1
|
||||
- name: build Release-Full
|
||||
env:
|
||||
LIBCLANG_PATH: "C:\\Program Files\\LLVM\\lib"
|
||||
LLVM_CONFIG_PATH: "C:\\Program Files\\LLVM\\bin\\llvm-config"
|
||||
CARGO_TARGET_DIR: "..\\..\\windows"
|
||||
BINDGEN_EXTRA_CLANG_ARGS: -fmsc-version=0
|
||||
run: msbuild ccextractor.sln /p:Configuration=Release-Full /p:Platform=Win32
|
||||
working-directory: ./windows
|
||||
- name: Display version information
|
||||
run: ./ccextractorwinfull.exe --version
|
||||
working-directory: ./windows/Release-Full
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: CCExtractor Windows OCR and HardSubX Release build
|
||||
path: |
|
||||
./windows/Release-Full/ccextractorwinfull.exe
|
||||
./windows/Release-Full/*.dll
|
||||
build_ocr_hardsubx_debug:
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@v2.3.4
|
||||
- name: Setup MSBuild.exe
|
||||
uses: microsoft/setup-msbuild@v1.0.2
|
||||
- name: build Debug
|
||||
run: msbuild ccextractor.sln /p:Configuration=Debug-Full
|
||||
working-directory: ./windows
|
||||
- name: Display version information
|
||||
run: ./ccextractorwinfull.exe --version
|
||||
working-directory: ./windows/Debug-Full
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: CCExtractor Windows OCR and HardSubX Debug build
|
||||
path: |
|
||||
./windows/Debug-Full/ccextractorwinfull.exe
|
||||
./windows/Debug-Full/ccextractorwinfull.pdb
|
||||
./windows/Debug-Full/*.dll
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: CCExtractor Windows OCR and HardSubX Debug build
|
||||
path: |
|
||||
./windows/Debug/ccextractorgui.exe
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@v2.4.0
|
||||
- name: Setup MSBuild.exe
|
||||
uses: microsoft/setup-msbuild@v1.0.2
|
||||
- name: Install llvm and clang
|
||||
uses: egor-tensin/setup-clang@v1
|
||||
with:
|
||||
version: latest
|
||||
platform: x86
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: 1.56.0
|
||||
override: true
|
||||
target: i686-pc-windows-msvc
|
||||
- name: Install Win 10 SDK
|
||||
uses: ilammy/msvc-dev-cmd@v1
|
||||
- name: build Debug-Full
|
||||
env:
|
||||
LIBCLANG_PATH: "C:\\Program Files\\LLVM\\lib"
|
||||
LLVM_CONFIG_PATH: "C:\\Program Files\\LLVM\\bin\\llvm-config"
|
||||
CARGO_TARGET_DIR: "..\\..\\windows"
|
||||
BINDGEN_EXTRA_CLANG_ARGS: -fmsc-version=0
|
||||
run: msbuild ccextractor.sln /p:Configuration=Debug-Full /p:Platform=Win32
|
||||
working-directory: ./windows
|
||||
- name: Display version information
|
||||
run: ./ccextractorwinfull.exe --version
|
||||
working-directory: ./windows/Debug-Full
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: CCExtractor Windows OCR and HardSubX Debug build
|
||||
path: |
|
||||
./windows/Debug-Full/ccextractorwinfull.exe
|
||||
./windows/Debug-Full/ccextractorwinfull.pdb
|
||||
./windows/Debug-Full/*.dll
|
||||
|
||||
31
.github/workflows/format.yml
vendored
31
.github/workflows/format.yml
vendored
@@ -5,18 +5,47 @@ on:
|
||||
- '.github/workflows/format.yml'
|
||||
- 'src/**.c'
|
||||
- 'src/**.h'
|
||||
- 'src/rust/**'
|
||||
tags-ignore: # ignore push via new tag
|
||||
- '*.*'
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
paths:
|
||||
- '.github/workflows/format.yml'
|
||||
- 'src/**.c'
|
||||
- 'src/**.h'
|
||||
- 'src/rust/**'
|
||||
jobs:
|
||||
format:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2.3.4
|
||||
- uses: actions/checkout@v2.4.0
|
||||
- name: Format code
|
||||
run: |
|
||||
find src/ -type f -not -path "src/thirdparty/*" -not -path "src/lib_ccx/zvbi/*" -name '*.c' -not -path "src/GUI/icon_data.c" | xargs clang-format -i
|
||||
git diff-index --quiet HEAD -- || (git diff && exit 1)
|
||||
format_rust:
|
||||
runs-on: ubuntu-latest
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ./src/rust
|
||||
steps:
|
||||
- uses: actions/checkout@v2.4.0
|
||||
- name: cache
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: |
|
||||
src/rust/.cargo/registry
|
||||
src/rust/.cargo/git
|
||||
src/rust/target
|
||||
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
|
||||
restore-keys: ${{ runner.os }}-cargo-
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
override: true
|
||||
components: rustfmt, clippy
|
||||
- name: rustfmt
|
||||
run: cargo fmt --all -- --check
|
||||
- name: clippy
|
||||
run: cargo clippy -- -D warnings
|
||||
|
||||
82
.github/workflows/release.yml
vendored
Normal file
82
.github/workflows/release.yml
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
name: Upload releases
|
||||
|
||||
on:
|
||||
release:
|
||||
types:
|
||||
- created
|
||||
|
||||
jobs:
|
||||
build_windows:
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@v2.4.0
|
||||
- name: Get the version
|
||||
id: get_version
|
||||
run: echo ::set-output name=VERSION::${GITHUB_REF/refs\/tags\/v/}
|
||||
shell: bash
|
||||
- name: Setup MSBuild.exe
|
||||
uses: microsoft/setup-msbuild@v1.0.2
|
||||
- name: Install llvm and clang
|
||||
uses: egor-tensin/setup-clang@v1
|
||||
with:
|
||||
version: latest
|
||||
platform: x86
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: 1.56.0
|
||||
override: true
|
||||
target: i686-pc-windows-msvc
|
||||
- name: Install Win 10 SDK
|
||||
uses: ilammy/msvc-dev-cmd@v1
|
||||
- name: build Release-Full
|
||||
env:
|
||||
LIBCLANG_PATH: "C:\\Program Files\\LLVM\\lib"
|
||||
LLVM_CONFIG_PATH: "C:\\Program Files\\LLVM\\bin\\llvm-config"
|
||||
CARGO_TARGET_DIR: "..\\..\\windows"
|
||||
BINDGEN_EXTRA_CLANG_ARGS: -fmsc-version=0
|
||||
run: msbuild ccextractor.sln /p:Configuration=Release-Full /p:Platform=Win32
|
||||
working-directory: ./windows
|
||||
- name: Copy files to directory for installer
|
||||
run: mkdir installer; cp ./Release-Full/ccextractorwinfull.exe ./installer; cp ./Release-Full/*.dll ./installer
|
||||
working-directory: ./windows
|
||||
- name: install WiX
|
||||
run: dotnet tool install --global wix --version 4.0.0-preview.0 && wix extension -g add WixToolset.UI.wixext
|
||||
- name: Make sure WiX works
|
||||
run: wix --version && wix extension -g list
|
||||
- name: Download Flutter GUI
|
||||
run: ((Invoke-WebRequest -UseBasicParsing https://api.github.com/repos/CCExtractor/ccextractorfluttergui/releases/latest).Content | ConvertFrom-Json).assets | ForEach-Object {if ($_.name -eq "windows.zip") { Invoke-WebRequest -UseBasicParsing -Uri $_.browser_download_url -OutFile windows.zip}}
|
||||
working-directory: ./windows
|
||||
- name: Display contents of dir
|
||||
run: ls
|
||||
working-directory: ./windows
|
||||
- name: Unzip Flutter GUI
|
||||
run: Expand-Archive -Path ./windows.zip -DestinationPath ./installer
|
||||
working-directory: ./windows
|
||||
- name: Display installer folder contents
|
||||
run: Get-ChildItem -Recurse ./installer
|
||||
working-directory: ./windows
|
||||
- name: Create portable zip
|
||||
run: Compress-Archive -Path ./installer/* -DestinationPath ./CCExtractor_win_portable.zip
|
||||
working-directory: ./windows
|
||||
- name: Build installer
|
||||
run: wix build -ext "$HOME\.wix\extensions\WixToolset.UI.wixext\4.0.0-preview.0\tools\WixToolset.UI.wixext.dll" -d "AppVersion=${{ steps.get_version.outputs.VERSION }}.0.0" -o CCExtractor.msi installer.wxs
|
||||
working-directory: ./windows
|
||||
- name: Upload as asset
|
||||
uses: AButler/upload-release-assets@v2.0
|
||||
with:
|
||||
files: './windows/CCExtractor.msi;./windows/CCExtractor_win_portable.zip'
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
create_linux_package:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2.4.0
|
||||
with:
|
||||
path: ./ccextractor
|
||||
- name: Create .tar.gz without git and windows folders
|
||||
run: tar -pczf ./ccextractor_minimal.tar.gz --exclude "ccextractor/windows" --exclude "ccextractor/.git" ccextractor
|
||||
- name: Upload as asset
|
||||
uses: AButler/upload-release-assets@v2.0
|
||||
with:
|
||||
files: './ccextractor_minimal.tar.gz'
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -4,7 +4,7 @@ MAINTAINER = Marc Espie <espie@openbsd.org>
|
||||
CATEGORIES = multimedia
|
||||
COMMENT = closed caption subtitles extractor
|
||||
HOMEPAGE = https://ccextractor.org
|
||||
V = 0.89
|
||||
V = 0.94
|
||||
DISTFILES = ccextractor.${V:S/.//}-src.zip
|
||||
MASTER_SITES = ${MASTER_SITE_SOURCEFORGE:=ccextractor/}
|
||||
DISTNAME = ccextractor-$V
|
||||
|
||||
@@ -38,7 +38,7 @@ This will extract the subtitles.
|
||||
More usage information can be found on our website:
|
||||
|
||||
- [Using the command line tool](https://ccextractor.org/public/general/command_line_usage/)
|
||||
- [Using the Windows GUI](https://ccextractor.org/public/general/win_gui_usage/)
|
||||
- [Using the Flutter GUI](https://ccextractor.org/public/general/flutter_gui/)
|
||||
|
||||
You can also find the list of parameters and their brief description by running `ccextractor` without any arguments.
|
||||
|
||||
|
||||
284
docs/CHANGES.TXT
284
docs/CHANGES.TXT
@@ -1,3 +1,37 @@
|
||||
0.94 (2021-12-14)
|
||||
-----------------
|
||||
- BOM is no longer enabled by default on windows platforms
|
||||
- CEA-708: Rust decoder is now default instead of C decoder
|
||||
- CEA-708 subs are now extracted by default
|
||||
- New: Add check for Minimum supported rust version (MSRV) (#1387)
|
||||
- Fix: Fix CEA-708 Carriage Return command implementation
|
||||
- Fix: Fix bug with startat/endat parameter (#1396)
|
||||
- Fix: Mac Build processes (#1390)
|
||||
- Fix: Fix bug with negative delay parameter (#1365)
|
||||
|
||||
0.93 (2021-08-16)
|
||||
-----------------
|
||||
- Minor Rust updates (format, typos, docs)
|
||||
- Updated GUI
|
||||
|
||||
0.92 (2021-08-10)
|
||||
-----------------
|
||||
- Rust updates: Added srt writer
|
||||
- Rust updates:-Added writers for transcripts and SAMI
|
||||
- Added missing DLL to Windows installer
|
||||
- Updated Windows GUI
|
||||
|
||||
0.91 (2021-07-26)
|
||||
-----------------
|
||||
- More Rust in the 708 decoder (Add Pen Presets and timing functions)
|
||||
- Updated GUI
|
||||
|
||||
0.90 (2021-07-14)
|
||||
-----------------
|
||||
- New installer (WiX based)
|
||||
- New GUI (flutter based)
|
||||
- More Rust (the 708 decoder is being rewritten)
|
||||
|
||||
0.89 (2021-06-13)
|
||||
-----------------
|
||||
- Fix: Fix broken links in README
|
||||
@@ -56,7 +90,7 @@
|
||||
- New: Add support for DVB inside .mkv
|
||||
- Fix: Added -latrusmap Map Latin symbols to Cyrillic ones in special cases
|
||||
of Russian Teletext files (issue #1086)
|
||||
- Fix: Several OCR crashes
|
||||
- Fix: Several OCR crashes
|
||||
|
||||
0.87 (2018-10-23)
|
||||
-----------------
|
||||
@@ -136,10 +170,10 @@
|
||||
- New: Added tarball generation script.
|
||||
- New: Added --analyzevideo. If present the video stream will be processed even if the
|
||||
subtitles are in a different stream. This is useful when we want video information
|
||||
(resolution, frame type, etc). -vides now implies this option too.
|
||||
(resolution, frame type, etc). -vides now implies this option too.
|
||||
[Note: Tentative - some possibly breaking changed were made for this, so if you
|
||||
use it validate results]
|
||||
- New: Added a GUI in the main CCExtractor binary (separate from the external GUIs
|
||||
- New: Added a GUI in the main CCExtractor binary (separate from the external GUIs
|
||||
such as CCExtractorGUI).
|
||||
- New: A Python binding extension so it's possible to use CCExtractor's tools from
|
||||
Python.
|
||||
@@ -150,29 +184,29 @@
|
||||
- New: FreeType-based text renderer (-out=spupng with teletext/EIA608).
|
||||
- New: Upgrade library UTF8proc
|
||||
- New: Upgrade library win_iconv
|
||||
- New: Upgrade library zlib
|
||||
- New: Upgrade library LibPNG
|
||||
- New: Upgrade library zlib
|
||||
- New: Upgrade library LibPNG
|
||||
- New: Support for Source-Specific Multicast
|
||||
- New: Added Travis CI support
|
||||
- New: Added Travis CI support
|
||||
- New: Made error messages clearer, less ambiguous
|
||||
- Fix: Prevent the OCR being initialized more than once (happened on multiprogram and
|
||||
PAT changes)
|
||||
- Fix: Makefiles, build scripts, etc... everything updated and corrected for all
|
||||
platforms.
|
||||
-Fix: Proper line ending for .srt files from bitmaps.
|
||||
- Fix: OCR corrections using grayscale before extracting texts.
|
||||
-Fix: Proper line ending for .srt files from bitmaps.
|
||||
- Fix: OCR corrections using grayscale before extracting texts.
|
||||
- Fix: End timestamps in transcripts from DVB.
|
||||
- Fix: Forcing -noru to cause deduplication in ISDB
|
||||
- Fix: TS: Skip NULL packets
|
||||
- Fix: TS: Skip NULL packets
|
||||
- Fix: When NAL decoding fails, don't dump the whole decoded thing, limit to 160 bytes.
|
||||
- Fix: Modify Autoconf scripts to generate tarball for mac from `/package_creators/tarball.sh`
|
||||
- Fix: Modify Autoconf scripts to generate tarball for mac from `/package_creators/tarball.sh`
|
||||
and include GUI files in tarball
|
||||
- Fix: Started work on libGPAC upgrade.
|
||||
- Fix: DVB subtitle not extracted if there's no display segment
|
||||
- Fix: Heap corruption in add_ocrtext2str
|
||||
- Fix: bug that caused -out=spupng sometimes crashes
|
||||
- Fix: Checks for text before newlines on DVB subtitles
|
||||
- Fix: OCR issue caused by separated dvb subtitle regions
|
||||
- Fix: Checks for text before newlines on DVB subtitles
|
||||
- Fix: OCR issue caused by separated dvb subtitle regions
|
||||
- Fix: DVB crash on specific condition (!rect->ocr_text)
|
||||
- Fix: DVB bug (Multiple-line subtitle; Missing last line)
|
||||
- Fix: --sentencecap for teletext samples
|
||||
@@ -219,7 +253,7 @@
|
||||
|
||||
0.84 (2016-12-16)
|
||||
-----------------
|
||||
- New: In Windows, both with and without-OCR binaries are bundled, since the OCR one causes problems due to
|
||||
- New: In Windows, both with and without-OCR binaries are bundled, since the OCR one causes problems due to
|
||||
dependencies in some system. So unless you need the OCR just use the non-OCR version.
|
||||
- New: Added -sbs (sentence by sentence) for DVB output. Each frame in the output file contains a complete
|
||||
sentence (experimental).
|
||||
@@ -242,7 +276,7 @@
|
||||
- Fix: Added detail in many error messages.
|
||||
- Fix: Memory leaks in videos with XDS.
|
||||
- Fix: Makefile compatibility issues with Raspberry pi.
|
||||
- Fix: missing separation between WebVTT header and body.
|
||||
- Fix: missing separation between WebVTT header and body.
|
||||
- Fix: Stupid bug in M2TS that preventing it from working.
|
||||
- Fix: OCR libraries dependencies for the release version in Windows.
|
||||
- Fix: non-buffered reading from pipes.
|
||||
@@ -289,7 +323,7 @@
|
||||
- Fix: Timing in -ucla
|
||||
- Fix: Timing in ISDB (some instances)
|
||||
- Fix: "mfra" mp4 box weight changed to 1 (this helps with correct file format detection)
|
||||
- Fix: Fix for TARGET File is null.
|
||||
- Fix: Fix for TARGET File is null.
|
||||
- Fix: Fixed SegFaults while parsing parameters (if mandatory parameter is not present in -outinterval, -codec or -nocodec)
|
||||
- Fix: Crash when input small is too small
|
||||
- Fix: Update some URLs in code (references to docs)
|
||||
@@ -347,7 +381,7 @@
|
||||
- CCExtractor can be used as library if compiled using cmake
|
||||
- By default the Windows version adds BOM to generated UTF files (this is
|
||||
because it's needed to open the files correctly) while all other
|
||||
builds don't add it (because it messes with text processing tools).
|
||||
builds don't add it (because it messes with text processing tools).
|
||||
You can use -bom and -nobom to change the behaviour.
|
||||
|
||||
0.74 (2014-09-24)
|
||||
@@ -386,7 +420,7 @@
|
||||
------------------------
|
||||
This is the first release that is part of Google's Summer of Code.
|
||||
Anshul, Ruslan and Willem joined CCExtractor to work on a number of things
|
||||
over the summer, and their work is already reaching the mainstream
|
||||
over the summer, and their work is already reaching the mainstream
|
||||
version of CCExtractor.
|
||||
|
||||
- Added a huge dictionary submitted by Matt Stockard.
|
||||
@@ -419,7 +453,7 @@ version of CCExtractor.
|
||||
0000101 is the default setting for transcripts
|
||||
1110101 is the default for timed transcripts
|
||||
1111001 is the default setting for -ucla
|
||||
Make sure you use this parameter after others that might affect these
|
||||
Make sure you use this parameter after others that might affect these
|
||||
settings (-out, -ucla, -xds, -txt, -ttxt, ...)
|
||||
- Fixed Negative timing Bug
|
||||
|
||||
@@ -437,7 +471,7 @@ version of CCExtractor.
|
||||
- Started refactoring and clean-up.
|
||||
- Fix: MPEG clock rollover (happens each 26 hours) caused a time
|
||||
discontinuity.
|
||||
- Windows GUI: Started work on HDHomeRun support. For now it just looks
|
||||
- Windows GUI: Started work on HDHomeRun support. For now it just looks
|
||||
for HDHomeRun devices. Lots of other things will arrive in the next
|
||||
versions.
|
||||
- Windows GUI: Some code refactoring, since the HDHomeRun support makes
|
||||
@@ -454,7 +488,7 @@ version of CCExtractor.
|
||||
a good test sample file...
|
||||
- Color and fonts in PAC commands were ignored, fixed (Helen Buus).
|
||||
- Added a new output format, spupng. It consists on one .png file
|
||||
for each subtitle frame and one .xml with all the timing
|
||||
for each subtitle frame and one .xml with all the timing
|
||||
(Heleen Buus).
|
||||
- Some fixes (Chris Small).
|
||||
|
||||
@@ -476,12 +510,12 @@ version of CCExtractor.
|
||||
- Added -latin1 to select Latin 1 as encoding. Default is now
|
||||
UTF-8 (-utf8 still exists but it's not needed).
|
||||
- Added -ru1, which emulates a (non-existing in real life) 1 line
|
||||
roll-up mode.
|
||||
roll-up mode.
|
||||
|
||||
|
||||
0.66 (2013-07-01)
|
||||
-----------------
|
||||
- Fixed bug in auto detection code that triggered a message
|
||||
- Fixed bug in auto detection code that triggered a message
|
||||
about file being auto of sync.
|
||||
- Added -investigate_packets
|
||||
The PMT is used to select the most promising elementary stream
|
||||
@@ -490,39 +524,39 @@ version of CCExtractor.
|
||||
manually, in case the CC location is not obvious from the PMT
|
||||
contents. To assist looking for the right stream, the parameter
|
||||
"-investigate_packets" will have CCExtractor look inside each
|
||||
stream, looking for CC markers, and report the streams that
|
||||
stream, looking for CC markers, and report the streams that
|
||||
are likely to contain CC data even if it can't be determined from
|
||||
their PMT entry.
|
||||
- Added -datastreamtype to manually selecting a stream based on
|
||||
its type instead of its PID. Useful if your recording program
|
||||
always hides the caption under the stream type.
|
||||
always hides the caption under the stream type.
|
||||
- Added -streamtype so if an elementary stream is selected manually
|
||||
for processing, the streamtype can be selected too. This can be
|
||||
needed if you process, for example a stream that is declared as
|
||||
for processing, the streamtype can be selected too. This can be
|
||||
needed if you process, for example a stream that is declared as
|
||||
"private MPEG" in the PMT, so CCExtractor can't tell what it is.
|
||||
Usually you'll want -streamtype 2 (MPEG video) or -streamtype 6
|
||||
(MPEG private data).
|
||||
- PMT content listing improved, it now shows the stream type for
|
||||
more types.
|
||||
- Fixes in roll-up, cursor was being moved to column 1 if a
|
||||
- Fixes in roll-up, cursor was being moved to column 1 if a
|
||||
RU2, RU3 or RU4 was received even if already in roll-up mode.
|
||||
- Added -autoprogram. If a multiprogram TS is processed and
|
||||
- Added -autoprogram. If a multiprogram TS is processed and
|
||||
-autoprogram is used, CCExtractor will analyze all PMTs and use
|
||||
the first program that has a suitable data stream.
|
||||
- Timed transcript (ttxt) now also exports the caption mode
|
||||
(roll-up, paint-on, etc.) next to each line, as it's useful to
|
||||
- Timed transcript (ttxt) now also exports the caption mode
|
||||
(roll-up, paint-on, etc.) next to each line, as it's useful to
|
||||
detect things like commercials.
|
||||
- Content Advisory information from XDS is now decoded if it's
|
||||
transmitted in "US TV parental guidelines" or "MPA".
|
||||
Other encoding such as Canada's are not supported yet due
|
||||
transmitted in "US TV parental guidelines" or "MPA".
|
||||
Other encoding such as Canada's are not supported yet due
|
||||
to lack of samples.
|
||||
- Copy Management information from XDS is now decoded.
|
||||
- Added -xds. If present and export format is timed transcript
|
||||
(only), XDS information will be saved to file (same file as the
|
||||
transcript, with XDS being clearly marked). Note that for now
|
||||
all XDS data is exported even if it doesn't change, so the
|
||||
all XDS data is exported even if it doesn't change, so the
|
||||
transcript file will be significantly larger.
|
||||
- Added some PaintOn support, at least enough to prevent it
|
||||
- Added some PaintOn support, at least enough to prevent it
|
||||
from breaking things when the other modes are used.
|
||||
- Removed afd_data() warning. AFD doesn't carry any caption related
|
||||
data. AFD still detected in code in case we want to do something
|
||||
@@ -540,21 +574,21 @@ version of CCExtractor.
|
||||
calculated distance, the maximum allowed distance, and whether
|
||||
the strings are ultimately considered equivalent or not, i.e.
|
||||
the calculated distance is less or equal than the max allowed.
|
||||
-levdistmincnt value: Minimum distance we always allow
|
||||
regardless of the length of the strings. Default 2. This means
|
||||
that if the calculated distance is 0, 1 or 2, we consider the
|
||||
-levdistmincnt value: Minimum distance we always allow
|
||||
regardless of the length of the strings. Default 2. This means
|
||||
that if the calculated distance is 0, 1 or 2, we consider the
|
||||
strings to be equivalent.
|
||||
-levdistmaxpct value: Maximum distance we allow, as a
|
||||
percentage of the shortest string length. Default 10%. For
|
||||
example, consider a comparison of one string of 30 characters
|
||||
and one of 60 characters. We want to determine whether the
|
||||
first 30 characters of the longer string are more or less the
|
||||
same as the shortest string, i.e. whether the longest string
|
||||
is the shortest one plus new characters and maybe some
|
||||
corrections. Since the shortest string is 30 characters and
|
||||
the default percentage is 10%, we would allow a distance of
|
||||
-levdistmaxpct value: Maximum distance we allow, as a
|
||||
percentage of the shortest string length. Default 10%. For
|
||||
example, consider a comparison of one string of 30 characters
|
||||
and one of 60 characters. We want to determine whether the
|
||||
first 30 characters of the longer string are more or less the
|
||||
same as the shortest string, i.e. whether the longest string
|
||||
is the shortest one plus new characters and maybe some
|
||||
corrections. Since the shortest string is 30 characters and
|
||||
the default percentage is 10%, we would allow a distance of
|
||||
up to 3 between the first 30 characters.
|
||||
- Added -lf : Use UNIX line terminator (LF) instead of Windows (CRLF).
|
||||
- Added -lf : Use UNIX line terminator (LF) instead of Windows (CRLF).
|
||||
- Added -noautotimeref: Prevent UTC reference from being auto set from
|
||||
the stream data.
|
||||
|
||||
@@ -564,7 +598,7 @@ version of CCExtractor.
|
||||
- Added end timestamps in timed transcripts
|
||||
- Added support for SMPTE (patch by John Kemp)
|
||||
- Initial support for MPEG2 video tracks inside MP4 files (thanks a
|
||||
lot to GPAC's Jean who assisted in analyzing the sample and
|
||||
lot to GPAC's Jean who assisted in analyzing the sample and
|
||||
doing the required changes in GPAC).
|
||||
- Improved MP4 auto detection
|
||||
- Support for PCR if PTS is not available (needed for some teletext
|
||||
@@ -590,7 +624,7 @@ version of CCExtractor.
|
||||
data (bypassing detections).
|
||||
- Added -ru2 and -ru3 to limit the number of visible lines in roll-up
|
||||
captions (bypassing whatever the broadcast says).
|
||||
- Added support for a .hex (hexadecimal) dump of data.
|
||||
- Added support for a .hex (hexadecimal) dump of data.
|
||||
- Added support for wtv in Windows. This is done by using a new program
|
||||
(wtvccdump.exe) and a new DirectShow filter (CCExtractorDump.dll) that
|
||||
process the .wtv using DirecShow's filters and export the line 21 data
|
||||
@@ -601,9 +635,9 @@ version of CCExtractor.
|
||||
0.63 (2012-08-17)
|
||||
-----------------
|
||||
- Telext support added, by integrating Petr Kutalek's telxcc. Integration is
|
||||
still quite basic (there's equivalent code from both CCExtractor and
|
||||
telxcc) and some clean up is needed, but it works. Petr has announced that
|
||||
he's abandoning telxcc so further development will happen directly in
|
||||
still quite basic (there's equivalent code from both CCExtractor and
|
||||
telxcc) and some clean up is needed, but it works. Petr has announced that
|
||||
he's abandoning telxcc so further development will happen directly in
|
||||
CCExtractor.
|
||||
- Some bug fixes, as usual.
|
||||
|
||||
@@ -613,14 +647,14 @@ version of CCExtractor.
|
||||
Mac users that sent this.
|
||||
- Hauppauge mode now uses PES timing, needed for files that don't have
|
||||
caption data during all the video (such as in commercial breaks).
|
||||
- Added -mp4 and -in:mp4 to force the input to be processed as MP4.
|
||||
- Added -mp4 and -in:mp4 to force the input to be processed as MP4.
|
||||
- CC608 data embedded in a separate stream (as opposed as in the video
|
||||
stream itself) in MP4 files is now supported (not heavily tested).
|
||||
stream itself) in MP4 files is now supported (not heavily tested).
|
||||
This should be rather useful since closed captioned files from iTunes
|
||||
use this format.
|
||||
- More CEA-708 work. The debugger is now able to dump the "TV" contents for
|
||||
the first time. Also, a .srt can be generated, however timing is not quite
|
||||
good yet (still need to figure out why).
|
||||
the first time. Also, a .srt can be generated, however timing is not quite
|
||||
good yet (still need to figure out why).
|
||||
- Added -svc (or --service) to select the CEA-708 services to be processed.
|
||||
For example, -svc 1,2 will process the primary and secondary language
|
||||
services. Valid values are 1-63, where 1 is the primary language, 2 is
|
||||
@@ -635,9 +669,9 @@ version of CCExtractor.
|
||||
- Fix: GCC 3.4.4 can now build CCExtractor.
|
||||
- Fix: Damaged TS packets (those that come with 'error in transport' bit
|
||||
on) are now skipped.
|
||||
- Fix: Part of the changes for MP4 support (CC packets buffering in
|
||||
particular) broke some stuff for other files, causing at least very
|
||||
annoying character duplication. We hope we've fixed it without breaking
|
||||
- Fix: Part of the changes for MP4 support (CC packets buffering in
|
||||
particular) broke some stuff for other files, causing at least very
|
||||
annoying character duplication. We hope we've fixed it without breaking
|
||||
anything but please report).
|
||||
- Some non-interesting cleanup.
|
||||
|
||||
@@ -648,13 +682,13 @@ version of CCExtractor.
|
||||
code, the stream must be a file (no streaming), etc.
|
||||
- Fix: The Windows version was writing text files with double \r.
|
||||
- Fix: Closed captions blocks with no data could cause a crash.
|
||||
- Fix: -noru (to generate files without duplicate lines in
|
||||
- Fix: -noru (to generate files without duplicate lines in
|
||||
roll-up) was broken, with complete lines being missing.
|
||||
- Fix: bin format not working as input.
|
||||
- Fix: bin format not working as input.
|
||||
|
||||
0.59 (2011-10-07)
|
||||
-----------------
|
||||
- More AVC/H.264 work. pic_order_cnt_type != 0 will be processed now.
|
||||
- More AVC/H.264 work. pic_order_cnt_type != 0 will be processed now.
|
||||
- Fix: Roll-up captions with interruptions for Text (with ResumeTextDisplay
|
||||
in the middle of the caption data) were missing complete lines.
|
||||
- Added a timed text transcript output format, probably only useful for
|
||||
@@ -677,7 +711,7 @@ version of CCExtractor.
|
||||
- Added -stdout => If used, the captions will be sent to stdout (console)
|
||||
instead of file. Combined with -, CCExtractor can work as a filter in
|
||||
a larger process, receiving the stream from stdin and sending the
|
||||
captions to stdout.
|
||||
captions to stdout.
|
||||
- Some code clean up, minor refactoring.
|
||||
- Teletext detection (not yet processing).
|
||||
|
||||
@@ -686,20 +720,20 @@ version of CCExtractor.
|
||||
- Implemented new PTS based mode to order the caption information
|
||||
of AVC/H.264 data streams. The old pic_order_cnt_lsb based method
|
||||
is still available via the -poc or --usepicorder command switches.
|
||||
- Removed a couple of those annoying "Impossible!" error messages
|
||||
- Removed a couple of those annoying "Impossible!" error messages
|
||||
that appears when processing some (possibly broken, unsure) files.
|
||||
- Added -nots --notypesettings to prevent italics and underline
|
||||
- Added -nots --notypesettings to prevent italics and underline
|
||||
codes from being displayed.
|
||||
- Note to those not liking the paragraph symbol being used for the
|
||||
- Note to those not liking the paragraph symbol being used for the
|
||||
music note: Submit a VALID replacement in latin-1.
|
||||
- Added preliminary support for multiple program TS files. The
|
||||
- Added preliminary support for multiple program TS files. The
|
||||
parameter --program-number (or -pn) will let you choose which
|
||||
program number to process. If no number is passed and the TS
|
||||
program number to process. If no number is passed and the TS
|
||||
file contains more than one, CCExtractor will display a list of
|
||||
found programs and terminate.
|
||||
- Added support (basic, because I only received one sample) for some
|
||||
Hauppauge cards that save CC data in their own format. Use the
|
||||
parameter -haup to enable it (CCExtractor will display a notice
|
||||
parameter -haup to enable it (CCExtractor will display a notice
|
||||
if it thinks that it's processing a Hauppauge capture anyway).
|
||||
- Fixed bug in roll-up.
|
||||
- More AVC work, now TS files from echostar that provided garbled
|
||||
@@ -709,7 +743,7 @@ version of CCExtractor.
|
||||
0.57 (2010-12-16)
|
||||
-----------------
|
||||
- Bug fixes in the Windows version. Some debug code was unintentionally
|
||||
left in the released version.
|
||||
left in the released version.
|
||||
|
||||
0.56 (2010-12-09)
|
||||
-----------------
|
||||
@@ -726,10 +760,10 @@ version of CCExtractor.
|
||||
- Start implementation of EIA-708 decoding (not active yet).
|
||||
- Add -gt / --goptime switch to use GOP timing instead of PTS timing.
|
||||
- Start implementation of AVC/H.264 decoding (not active yet).
|
||||
- Fixed: The basic problem is that when 24fps movie film gets converted to 30fps NTSC
|
||||
they repeat every 4th frame. Some pics have 3 fields of CC data with field 3 CC data
|
||||
belongs to the same channel as field 1. The following pics have the fields reversed
|
||||
because of the odd number of fields. I used top_field_first to tell when the channels
|
||||
- Fixed: The basic problem is that when 24fps movie film gets converted to 30fps NTSC
|
||||
they repeat every 4th frame. Some pics have 3 fields of CC data with field 3 CC data
|
||||
belongs to the same channel as field 1. The following pics have the fields reversed
|
||||
because of the odd number of fields. I used top_field_first to tell when the channels
|
||||
are reversed. See Table 6-1 of the SCTE 20 [Paul Fernquist]
|
||||
|
||||
0.54 (2009-04-16)
|
||||
@@ -739,9 +773,9 @@ version of CCExtractor.
|
||||
- Improve synchronization of captions for source files with
|
||||
jumps in their time information or gaps in the caption
|
||||
information.
|
||||
- [R. Abarca] Changed Mac script, it now compiles/link
|
||||
everything from the /src directory.
|
||||
- It's now possible to have CCExtractor add credits
|
||||
- [R. Abarca] Changed Mac script, it now compiles/link
|
||||
everything from the /src directory.
|
||||
- It's now possible to have CCExtractor add credits
|
||||
automatically.
|
||||
- Added a feature to add start and end messages (for credits).
|
||||
See help screen for details.
|
||||
@@ -762,13 +796,13 @@ version of CCExtractor.
|
||||
for Raw Captions With Time). This new format
|
||||
allows one file to contain all the available
|
||||
closed caption data instead of just one stream.
|
||||
- Added --no_progress_bar to disable status
|
||||
- Added --no_progress_bar to disable status
|
||||
information (mostly used when debugging, as the
|
||||
progress information is annoying in the middle
|
||||
of debug logs).
|
||||
- The Windows GUI was reported to freeze in some
|
||||
- The Windows GUI was reported to freeze in some
|
||||
conditions. Fixed.
|
||||
- The Windows GUI is now targeted for .NET 2.0
|
||||
- The Windows GUI is now targeted for .NET 2.0
|
||||
instead of 3.5. This allows Windows 2000 to run
|
||||
it (there's not .NET 3.5 for Windows 2000), as
|
||||
requested by a couple of key users.
|
||||
@@ -776,17 +810,17 @@ version of CCExtractor.
|
||||
0.51 (unreleased)
|
||||
-----------------
|
||||
- Removed -autopad and -goppad, no longer needed.
|
||||
- In preparation to a new binary format we have
|
||||
renamed the current .bin to .raw. Raw files
|
||||
- In preparation to a new binary format we have
|
||||
renamed the current .bin to .raw. Raw files
|
||||
have only CC data (with no header, timing, etc.).
|
||||
- The input file format (when forced) is now
|
||||
specified with
|
||||
specified with
|
||||
-in=format
|
||||
such as -in=ts, -in=raw, -in=ps ...
|
||||
The old switches (-ts, -ps, etc.) still work.
|
||||
The only exception is -bin which has been removed
|
||||
(reserved for the new binary format). Use
|
||||
-in=raw to process a raw file.
|
||||
-in=raw to process a raw file.
|
||||
- Removed -d, which when produced a raw file used
|
||||
a DVD format. This has been merged into a new
|
||||
output type "dvdraw". So now instead of using
|
||||
@@ -795,7 +829,7 @@ version of CCExtractor.
|
||||
- Removed --noff
|
||||
- Added gui_mode_reports for frontend communications,
|
||||
see related file.
|
||||
- Windows GUI rewritten. Source code now included,
|
||||
- Windows GUI rewritten. Source code now included,
|
||||
too.
|
||||
- [Volker] Dish Network clean-up
|
||||
|
||||
@@ -808,12 +842,12 @@ version of CCExtractor.
|
||||
0.49 (2008-12-10)
|
||||
-----------------
|
||||
- [Volker] Major MPEG parser rework. Code much
|
||||
cleaner now.
|
||||
cleaner now.
|
||||
- Some stations transmit broken roll-up captions,
|
||||
and for some reason don't send CRs but RUs...
|
||||
Added work-around code to make captions readable.
|
||||
- Started work on EIA-708 (DTV). Right now you can
|
||||
add -debug-708 to get a dump of the 708 data.
|
||||
add -debug-708 to get a dump of the 708 data.
|
||||
An actually useful decoder will come soon.
|
||||
- Some of the changes MIGHT HAVE BROKEN MythTV's
|
||||
code. I don't use MythTV myself so I rely on
|
||||
@@ -829,9 +863,9 @@ version of CCExtractor.
|
||||
can now process files that are being recorded
|
||||
at the same time.
|
||||
|
||||
- [Volker] Added a new DVR-MS loop - this is
|
||||
- [Volker] Added a new DVR-MS loop - this is
|
||||
completely new, DVR-MS specific code, so we no
|
||||
longer use the generic MPEG code for DVR-MS.
|
||||
longer use the generic MPEG code for DVR-MS.
|
||||
DVR-MS should (or will be eventually at least)
|
||||
be as reliable as TS.
|
||||
Note: For now, it's only ATSC recordings, not
|
||||
@@ -850,11 +884,11 @@ version of CCExtractor.
|
||||
new options.
|
||||
- Added -lg --largegops
|
||||
From the help screen:
|
||||
Each Group-of-Picture comes with timing
|
||||
information. When this info is too separate
|
||||
(for example because there are a lot of
|
||||
frames in a GOP) ccextractor may prefer not
|
||||
to use GOP timing. Use this option is you
|
||||
Each Group-of-Picture comes with timing
|
||||
information. When this info is too separate
|
||||
(for example because there are a lot of
|
||||
frames in a GOP) ccextractor may prefer not
|
||||
to use GOP timing. Use this option is you
|
||||
need ccextractor to use GOP timing in large
|
||||
GOPs.
|
||||
|
||||
@@ -873,8 +907,8 @@ version of CCExtractor.
|
||||
0.43 (2008-06-20)
|
||||
-----------------
|
||||
- Fixed a bug in the read loop (no less)
|
||||
that caused some files to fail when
|
||||
reading without buffering (which is
|
||||
that caused some files to fail when
|
||||
reading without buffering (which is
|
||||
the default in the Linux build).
|
||||
- Several improvements in the GUI, such as
|
||||
saving current options as default.
|
||||
@@ -891,8 +925,8 @@ version of CCExtractor.
|
||||
-----------------
|
||||
- Default output is now .srt instead of .bin,
|
||||
use -raw if you need the data dump instead of
|
||||
.srt.
|
||||
- Added -trim, which removes blank spaces at
|
||||
.srt.
|
||||
- Added -trim, which removes blank spaces at
|
||||
the left and rights of each line in .srt.
|
||||
Note that those spaces are there to help
|
||||
deaf people know if the person talking is
|
||||
@@ -902,8 +936,8 @@ version of CCExtractor.
|
||||
|
||||
0.40 (2008-05-20)
|
||||
-----------------
|
||||
- Fixed a bug in the sanity check function
|
||||
that caused the Myth branch to abort.
|
||||
- Fixed a bug in the sanity check function
|
||||
that caused the Myth branch to abort.
|
||||
- Fixed the OSX build script, it needed a
|
||||
new #define to work.
|
||||
|
||||
@@ -913,30 +947,30 @@ version of CCExtractor.
|
||||
have no time information. Also, if in roll-up
|
||||
mode there will be no repeated lines.
|
||||
- Lots of changes in the MPEG parser, most of
|
||||
them submitted by Volker Quetschke.
|
||||
them submitted by Volker Quetschke.
|
||||
- Fixed a bug in the CC decoder that could cause
|
||||
the first line not to be cleared in roll-up
|
||||
mode.
|
||||
mode.
|
||||
- CCExtractor can now follow number sequences in
|
||||
file names, by suffixing the name with +.
|
||||
For example,
|
||||
|
||||
DVD0001.VOB+
|
||||
DVD0001.VOB+
|
||||
|
||||
means DVD0001.VOB, DVD0002.VOB, etc. This works
|
||||
for all files, so part001.ts+ does what you
|
||||
could expect.
|
||||
- Added -90090 which changes the clock frequency
|
||||
from the MPEG standard 90000 to 90090. It
|
||||
from the MPEG standard 90000 to 90090. It
|
||||
*could* (remains to be seen) help if there are
|
||||
timing issues.
|
||||
timing issues.
|
||||
- Better support for Tivo files.
|
||||
- By default ccextractor now considers the whole
|
||||
input file list a one large file, instead of
|
||||
several, independent, video files. This has
|
||||
been changed because most programs (for example
|
||||
DVDDecrypt) just cut the files by size.
|
||||
If you need the old behaviour (because you
|
||||
DVDDecrypt) just cut the files by size.
|
||||
If you need the old behaviour (because you
|
||||
actually edited the video files and want to
|
||||
join the subs), use -ve.
|
||||
|
||||
@@ -954,7 +988,7 @@ version of CCExtractor.
|
||||
that have been added because old behaviour was
|
||||
annoying to most people: _1 and _2 at the end
|
||||
of the output file names is now added ONLY if
|
||||
-12 is used (i.e. when there are two output
|
||||
-12 is used (i.e. when there are two output
|
||||
files to produce). So
|
||||
|
||||
ccextractor -srt sopranos.mpg
|
||||
@@ -1015,7 +1049,7 @@ version of CCExtractor.
|
||||
Alan
|
||||
Tony
|
||||
|
||||
So you get
|
||||
So you get
|
||||
|
||||
You better respect
|
||||
this robe, Alan.
|
||||
@@ -1024,7 +1058,7 @@ version of CCExtractor.
|
||||
have a different spelling file per TV
|
||||
show, or a large file with a lot of
|
||||
words, etc.
|
||||
- ccextractor has been reported to
|
||||
- ccextractor has been reported to
|
||||
compile and run on Mac with a minor
|
||||
change in the build script, so I've
|
||||
created a mac directory with the
|
||||
@@ -1038,17 +1072,17 @@ version of CCExtractor.
|
||||
-----------------
|
||||
- Added -scr or --screenfuls, to select the
|
||||
number of screenfuls ccextractor should
|
||||
write before exiting. A screenful is
|
||||
write before exiting. A screenful is
|
||||
a change of screen contents caused by
|
||||
a CC command (not new characters). In
|
||||
practice, this means that for .srt each
|
||||
group of lines is a screenful, except when
|
||||
using -dru (which produces a lot of
|
||||
using -dru (which produces a lot of
|
||||
groups of lines because each new character
|
||||
produces a new group).
|
||||
- Completed tables for all encodings.
|
||||
- Fixed bug in .srt related to milliseconds
|
||||
in time lines.
|
||||
in time lines.
|
||||
- Font colors are back for .srt (apparently
|
||||
some programs do support them after all).
|
||||
Use -nofc or --nofontcolor if you don't
|
||||
@@ -1057,7 +1091,7 @@ version of CCExtractor.
|
||||
0.32 (unreleased)
|
||||
-----------------
|
||||
- Added -delay ms, which adds (or subtracts)
|
||||
a number of milliseconds to all times in
|
||||
a number of milliseconds to all times in
|
||||
.srt/.sami files. For example,
|
||||
|
||||
-delay 400
|
||||
@@ -1088,8 +1122,8 @@ version of CCExtractor.
|
||||
- Fix in extended char decoding, I wasn't
|
||||
replacing the previous char.
|
||||
- When a sequence code was found before
|
||||
having a PTS, reported time was
|
||||
undefined.
|
||||
having a PTS, reported time was
|
||||
undefined.
|
||||
|
||||
0.29 (unreleased)
|
||||
-----------------
|
||||
@@ -1114,7 +1148,7 @@ version of CCExtractor.
|
||||
0.26 (unreleased)
|
||||
-----------------
|
||||
- Added -gp (or -goppad) to make ccextractor use
|
||||
GOP timing. Try it for non TS files where
|
||||
GOP timing. Try it for non TS files where
|
||||
subs start OK but desync as the video advances.
|
||||
|
||||
0.25 (unreleased)
|
||||
@@ -1123,7 +1157,7 @@ version of CCExtractor.
|
||||
-nomyth to prevent the MytvTV code path to be
|
||||
called. I've seen apparently correct files that
|
||||
make MythTV's MPEG decoder to choke. So, if it
|
||||
doesn't work correctly automatically: Try
|
||||
doesn't work correctly automatically: Try
|
||||
-nomyth and -myth. Hopefully one of the two
|
||||
options will work.
|
||||
|
||||
@@ -1136,7 +1170,7 @@ version of CCExtractor.
|
||||
- Reworked input buffer code, faster now.
|
||||
- Completed MythTV's MPEG decoder for Program Streams,
|
||||
which results in better processing of some specific
|
||||
files.
|
||||
files.
|
||||
- Automatic file format detection for all kind of
|
||||
files and closed caption storage method. No need to
|
||||
tell ccextractor anything about your file (but you
|
||||
@@ -1145,10 +1179,10 @@ version of CCExtractor.
|
||||
|
||||
0.22 (2007-05-15)
|
||||
-----------------
|
||||
- Added text mode handling into decoder, which gets rids
|
||||
- Added text mode handling into decoder, which gets rids
|
||||
of junk when text mode data is present.
|
||||
- Added support for certain (possibly non standard
|
||||
compliant) DVDs that add more captions block in a
|
||||
compliant) DVDs that add more captions block in a
|
||||
user data block than they should (such as Red October).
|
||||
- Fix in roll-up init code that caused the previous popup
|
||||
captions not to be written to disk.
|
||||
@@ -1159,13 +1193,13 @@ version of CCExtractor.
|
||||
-----------------
|
||||
- Unicode should be decent now.
|
||||
- Added support for Hauppauge PVR 250 cards, and (possibly)
|
||||
many others (bttv) with the same closed caption recording
|
||||
many others (bttv) with the same closed caption recording
|
||||
format.
|
||||
This is the result of hacking MythTV's MPEG parser into
|
||||
CCExtractor. Integration is not very good (to put it
|
||||
midly) but it seems to work. Depending on the feedback I
|
||||
may continue working on this or just leave it 'as it'
|
||||
(good enough).
|
||||
(good enough).
|
||||
If you want to process a file generated by one of these
|
||||
analog cards, use -myth. This is essential as it will
|
||||
make the program take a totally different code path.
|
||||
@@ -1175,10 +1209,10 @@ version of CCExtractor.
|
||||
|
||||
0.19 (2007-05-03)
|
||||
-----------------
|
||||
- Work on Dish Network streams, timing was completely broken.
|
||||
- Work on Dish Network streams, timing was completely broken.
|
||||
It's fixed now at least for the samples I have, if it's not
|
||||
completely fixed let me know. Credit for this goes to
|
||||
Jack Ha who sent me a couple of samples and a first
|
||||
Jack Ha who sent me a couple of samples and a first
|
||||
implementation of a semi working-fix.
|
||||
- Added support for several input files (see help screen for
|
||||
details).
|
||||
|
||||
@@ -17,16 +17,17 @@ git clone https://github.com/CCExtractor/ccextractor.git
|
||||
Debian:
|
||||
|
||||
```bash
|
||||
sudo apt-get install -y libglew-dev libglfw3-dev cmake gcc libcurl4-gnutls-dev tesseract-ocr tesseract-ocr-dev libleptonica-dev
|
||||
sudo apt-get install -y libglew-dev libglfw3-dev cmake gcc libcurl4-gnutls-dev tesseract-ocr libtesseract-dev libleptonica-dev clang libclang-dev
|
||||
```
|
||||
|
||||
RHEL:
|
||||
|
||||
```bash
|
||||
yum install -y glew-devel glfw-devel cmake gcc libcurl-devel tesseract-devel leptonica-devel
|
||||
yum install -y glew-devel glfw-devel cmake gcc libcurl-devel tesseract-devel leptonica-devel clang
|
||||
```
|
||||
Rust 1.54 or above is also required.[Install Rust](https://www.rust-lang.org/tools/install). Check specific compilation methods below, on how to compile without rust
|
||||
|
||||
**Note:** On Ubuntu Version 18.04 (Bionic) and (probably) later, install `libtesseract-dev` rather than `tesseract-ocr-dev`, which does not exist anymore.
|
||||
**Note:** On Ubuntu Version 18.04 (Bionic) and later, `libtesseract-dev` is installed rather than `tesseract-ocr-dev`, which does not exist anymore.
|
||||
|
||||
**Note:** On Ubuntu Version 14.04 (Trusty) and earlier, you should build leptonica and tesseract from source
|
||||
|
||||
@@ -43,6 +44,9 @@ cd ccextractor/linux
|
||||
# compile without debug flags
|
||||
./build
|
||||
|
||||
# compile without rust
|
||||
./build -without-rust
|
||||
|
||||
# compile with debug info
|
||||
./builddebug
|
||||
|
||||
@@ -56,7 +60,7 @@ cd ccextractor/linux
|
||||
sudo apt-get install autoconf #Dependency to generate configuration script
|
||||
cd ccextractor/linux
|
||||
./autogen.sh
|
||||
./configure
|
||||
./configure # OR ./configure --without-rust
|
||||
make
|
||||
|
||||
# test your build
|
||||
@@ -70,14 +74,12 @@ sudo make install
|
||||
|
||||
```bash
|
||||
#Create and navigate to directory where you want to store built files
|
||||
|
||||
cd ccextractor/
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
#Generate makefile using cmake and then compile
|
||||
|
||||
cmake ../src/
|
||||
cmake ../src/ # options here
|
||||
make
|
||||
|
||||
# test your build
|
||||
@@ -87,13 +89,16 @@ make
|
||||
sudo make install
|
||||
```
|
||||
|
||||
`cmake` also accepts the argument `-DWITH_OCR=ON` to enable OCR.
|
||||
`cmake` also accepts the options:
|
||||
`-DWITH_OCR=ON` to enable OCR
|
||||
`-DWITHOUT_RUST=ON` to disable rust.
|
||||
`-DWITH_HARDSUBX=ON` to enable burned-in subtitles
|
||||
|
||||
### Compiling with GUI:
|
||||
|
||||
To build CCExtractor with a gui you will additionally need to install [GLEW](http://glew.sourceforge.net/build.html) and [GLFW](http://www.glfw.org/docs/latest/compile.html)
|
||||
To build CCExtractor with a GUI, you will additionally need to install [GLEW](http://glew.sourceforge.net/build.html) and [GLFW](http://www.glfw.org/docs/latest/compile.html)
|
||||
|
||||
In order to compile it you'll need to configure it using autoconf by passing the `-with-gui` option.
|
||||
In order to compile it, you'll need to configure it using autoconf by passing the `-with-gui` option.
|
||||
|
||||
```bash
|
||||
./autogen.sh
|
||||
@@ -108,16 +113,18 @@ Once set up you can run the GUI interface from the terminal `./ccextractorGUI`
|
||||
|
||||
## macOS
|
||||
|
||||
1. Make sure all the dependencies are met. They can be installed via Homebrew as
|
||||
1. Make sure all the dependencies are met. Decide if you want OCR; if so, you'll need to install tesseract and leptonica.
|
||||
Dependencies can be installed via Homebrew as:
|
||||
|
||||
```bash
|
||||
brew install pkg-config
|
||||
brew install autoconf automake libtool
|
||||
# optional if you want OCR:
|
||||
brew install tesseract
|
||||
brew install leptonica
|
||||
```
|
||||
|
||||
Use pkg-config to verify tesseract and leptonica dependencies, e.g.
|
||||
If configuring OCR, use pkg-config to verify tesseract and leptonica dependencies, e.g.
|
||||
|
||||
```bash
|
||||
pkg-config --exists --print-errors tesseract
|
||||
@@ -130,17 +137,7 @@ pkg-config --exists --print-errors lept
|
||||
|
||||
```bash
|
||||
cd ccextractor/mac
|
||||
./build.command OCR
|
||||
|
||||
# test your build
|
||||
./ccextractor
|
||||
```
|
||||
|
||||
If you don't want the OCR capabilities, then you don't need to configure the tesseract and leptonica packages, and build it with just
|
||||
|
||||
```bash
|
||||
cd ccextractor/mac
|
||||
./build.command
|
||||
./build.command # OR ./build.command OCR
|
||||
|
||||
# test your build
|
||||
./ccextractor
|
||||
@@ -150,26 +147,29 @@ cd ccextractor/mac
|
||||
|
||||
```bash
|
||||
#Create and navigate to directory where you want to store built files
|
||||
|
||||
cd ccextractor/
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
#Generate makefile using cmake and then compile
|
||||
|
||||
cmake ../src/
|
||||
cmake ../src/ # options here
|
||||
make
|
||||
|
||||
# test your build
|
||||
./ccextractor
|
||||
```
|
||||
|
||||
`cmake` also accepts the options:
|
||||
`-DWITH_OCR=ON` to enable OCR
|
||||
`-DWITHOUT_RUST=ON` to disable rust.
|
||||
`-DWITH_HARDSUBX=ON` to enable burned-in subtitles
|
||||
|
||||
#### Standard compilation through Autoconf scripts:
|
||||
|
||||
```bash
|
||||
cd ccextractor/mac
|
||||
./autogen.sh
|
||||
./configure
|
||||
./configure # OR ./configure --without-rust
|
||||
make
|
||||
|
||||
# test your build
|
||||
@@ -185,17 +185,19 @@ brew install glfw
|
||||
brew install glew
|
||||
```
|
||||
|
||||
In order to compile it you'll need to configure it using autoconf by passing the `-with-gui` option.
|
||||
In order to compile it, you'll need to configure it using autoconf by passing the `-with-gui` option.
|
||||
|
||||
```bash
|
||||
./autogen.sh
|
||||
./configure --with-gui
|
||||
./configure --with-gui #OR .configure --with-gui --without-rust
|
||||
make
|
||||
```
|
||||
|
||||
Once set up you can run the GUI interface from the terminal `./ccextractorGUI`
|
||||
Once set up, you can run the GUI interface from the terminal `./ccextractorGUI`
|
||||
|
||||
## Windows
|
||||
Dependencies are clang and rust. To enable OCR, rust i686-pc-windows-msvc target should be installed
|
||||
|
||||
Note: Following screenshots and steps are based on Visual Studio 2017, but they should be more or less same for other versions.
|
||||
|
||||
1.Open `windows/` directory to locate `ccextractor.vcxproj`, `ccextractorGUI.vcxproj` (blue arrows) and `ccextractor.sln` (red arrow).
|
||||
@@ -234,6 +236,22 @@ cmake ../src/ -G "Visual Studio 14 2015"
|
||||
cmake --build . --config Release --ccextractor
|
||||
```
|
||||
|
||||
### Using MSBuild
|
||||
|
||||
Run the following command in `windows/` directory
|
||||
|
||||
```bash
|
||||
msbuild ccextractor.sln /p:Configuration=Release /p:Platform=x64
|
||||
```
|
||||
Different configuration options are,
|
||||
|
||||
| Configuration | Platform | Rust target required |
|
||||
| ------------- |:-------------:| -----:|
|
||||
| Release | x64 | default |
|
||||
| Debug | x64 | default |
|
||||
| Release-Full(OCR) | Win32 | i686-pc-windows-msvc |
|
||||
| Debug-Full(OCR) | Win32 | i686-pc-windows-msvc |
|
||||
|
||||
## Building Installation Packages
|
||||
|
||||
### Arch Linux
|
||||
|
||||
@@ -35,5 +35,8 @@ cmake -DWITH_SHARING=ON ../src/
|
||||
If you want to build CCExtractor with HARDSUBX support
|
||||
cmake -DWITH_HARDSUBX=ON ../src/
|
||||
|
||||
If you want to build CCExtractor with rust disabled you need to pass
|
||||
cmake -DWITHOUT_RUST=ON ../src/
|
||||
|
||||
Hint for looking all the things you want to set from outside
|
||||
cmake -LAH ../src/
|
||||
|
||||
2
linux/.gitignore
vendored
Normal file
2
linux/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
libccx_rust.a
|
||||
rust
|
||||
@@ -1,5 +1,5 @@
|
||||
AUTOMAKE_OPTIONS = foreign
|
||||
|
||||
ACLOCAL_AMFLAGS = -I m4/
|
||||
|
||||
bin_PROGRAMS = ccextractor
|
||||
ccextractor_SOURCES = \
|
||||
@@ -262,7 +262,7 @@ ccextractor_SOURCES = \
|
||||
../src/thirdparty/lib_hash/sha2.h \
|
||||
../src/thirdparty/protobuf-c/protobuf-c.c \
|
||||
../src/thirdparty/protobuf-c/protobuf-c.h \
|
||||
../src/thirdparty/zvbi/bcd.h \
|
||||
../src/lib_ccx/zvbi/bcd.h \
|
||||
../src/lib_ccx/zvbi/bit_slicer.c \
|
||||
../src/lib_ccx/zvbi/bit_slicer.h \
|
||||
../src/lib_ccx/zvbi/decoder.c \
|
||||
@@ -274,7 +274,7 @@ ccextractor_SOURCES = \
|
||||
../src/lib_ccx/zvbi/sampling_par.h \
|
||||
../src/lib_ccx/zvbi/sliced.h \
|
||||
../src/lib_ccx/zvbi/zvbi_decoder.h \
|
||||
../src/freetype/* \
|
||||
../src/freetype/* \
|
||||
../src/thirdparty/freetype/autofit/autofit.c \
|
||||
../src/thirdparty/freetype/base/ftbase.c \
|
||||
../src/thirdparty/freetype/base/ftbbox.c \
|
||||
@@ -303,7 +303,7 @@ ccextractor_SOURCES = \
|
||||
../src/thirdparty/freetype/cff/cff.c \
|
||||
../src/thirdparty/freetype/cid/type1cid.c \
|
||||
../src/thirdparty/freetype/gzip/ftgzip.c \
|
||||
../src/thirdparty/freetype/include/ft2build.h \
|
||||
../src/thirdparty/freetype/include/ft2build.h \
|
||||
../src/thirdparty/freetype/lzw/ftlzw.c \
|
||||
../src/thirdparty/freetype/pcf/pcf.c \
|
||||
../src/thirdparty/freetype/pfr/pfr.c \
|
||||
@@ -318,20 +318,43 @@ ccextractor_SOURCES = \
|
||||
../src/thirdparty/freetype/type42/type42.c \
|
||||
../src/thirdparty/freetype/winfonts/winfnt.c
|
||||
|
||||
if SYS_IS_APPLE_SILICON
|
||||
ccextractor_SOURCES += ../src/thirdparty/libpng/arm/arm_init.c \
|
||||
../src/thirdparty/libpng/arm/filter_neon_intrinsics.c \
|
||||
../src/thirdparty/libpng/arm/palette_neon_intrinsics.c
|
||||
endif
|
||||
|
||||
ccextractor_CFLAGS = -std=gnu99 -Wno-write-strings -Wno-pointer-sign -D_FILE_OFFSET_BITS=64 -DVERSION_FILE_PRESENT -DFT2_BUILD_LIBRARY -DGPAC_DISABLE_VTT -DGPAC_DISABLE_OD_DUMP -DGPAC_DISABLE_REMOTERY -DNO_GZIP -DGPAC_HAVE_CONFIG_H
|
||||
|
||||
ccextractor_CPPFLAGS =-I../src/lib_ccx/ -I../src/thirdparty/gpacmp4/ -I../src/thirdparty/libpng/ -I../src/thirdparty/zlib/ -I../src/thirdparty/zvbi/ -I../src/thirdparty/lib_hash/ -I../src/thirdparty/protobuf-c/ -I../src/thirdparty -I../src/ -I../src/thirdparty/freetype/include/
|
||||
ccextractor_CPPFLAGS =-I../src/lib_ccx/ -I../src/thirdparty/gpacmp4/ -I../src/thirdparty/libpng/ -I../src/thirdparty/zlib/ -I../src/lib_ccx/zvbi/ -I../src/thirdparty/lib_hash/ -I../src/thirdparty/protobuf-c/ -I../src/thirdparty -I../src/ -I../src/thirdparty/freetype/include/
|
||||
|
||||
|
||||
ccextractor_LDADD=-lm -lpthread -ldl
|
||||
|
||||
if WITH_RUST
|
||||
ccextractor_LDADD += ./rust/@RUST_TARGET_SUBDIR@/libccx_rust.a
|
||||
else
|
||||
ccextractor_CFLAGS += -DDISABLE_RUST
|
||||
ccextractor_CPPFLAGS += -DDISABLE_RUST
|
||||
endif
|
||||
|
||||
if DEBUG_RELEASE
|
||||
CARGO_RELEASE_ARGS=
|
||||
else
|
||||
CARGO_RELEASE_ARGS=--release
|
||||
endif
|
||||
|
||||
./rust/@RUST_TARGET_SUBDIR@/libccx_rust.a:
|
||||
cd ../src/rust && \
|
||||
CARGO_TARGET_DIR=../../linux/rust $(CARGO) build $(CARGO_RELEASE_ARGS);
|
||||
|
||||
if SYS_IS_LINUX
|
||||
ccextractor_CFLAGS += -O3 -s -DGPAC_CONFIG_LINUX
|
||||
endif
|
||||
|
||||
if SYS_IS_MAC
|
||||
ccextractor_CFLAGS += -DPAC_CONFIG_DARWIN -Dfopen64=fopen -Dopen64=open -Dlseek64=lseek
|
||||
ccextractor_LDADD += -liconv -lz
|
||||
ccextractor_LDADD += -liconv -lz
|
||||
endif
|
||||
|
||||
if SYS_IS_64_BIT
|
||||
@@ -428,7 +451,7 @@ endif
|
||||
|
||||
if HARDSUBX_IS_ENABLED
|
||||
if OCR_IS_ENABLED
|
||||
ccextractorGUI_CFLAGS += -DENABLE_OCR
|
||||
ccextractorGUI_CFLAGS += -DENABLE_OCR
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
28
linux/build
28
linux/build
@@ -61,6 +61,34 @@ echo "Running pre-build script..."
|
||||
./pre-build.sh
|
||||
echo "Trying to compile..."
|
||||
|
||||
if [ "$1" = "-without-rust" ]; then
|
||||
echo "Building without rust files..."
|
||||
BLD_FLAGS="$BLD_FLAGS -DDISABLE_RUST"
|
||||
else
|
||||
BLD_LINKER="$BLD_LINKER ./libccx_rust.a"
|
||||
echo "Checking for cargo..."
|
||||
if ! [ -x "$(command -v cargo)" ]; then
|
||||
echo 'Error: cargo is not installed.' >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
rustc_version="$(rustc --version)"
|
||||
semver=( ${rustc_version//./ } )
|
||||
version="${semver[1]}.${semver[2]}.${semver[3]}"
|
||||
MSRV="1.54.0"
|
||||
if [ "$(printf '%s\n' "$MSRV" "$version" | sort -V | head -n1)" = "$MSRV" ]; then
|
||||
echo "rustc >= MSRV(${MSRV})"
|
||||
else
|
||||
echo "Minimum supported rust version(MSRV) is ${MSRV}, please upgrade rust"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Building rust files..."
|
||||
(cd ../src/rust && CARGO_TARGET_DIR=../../linux/rust cargo build) || { echo "Failed. " ; exit 1; }
|
||||
cp rust/debug/libccx_rust.a ./libccx_rust.a
|
||||
fi
|
||||
|
||||
echo "Building ccextractor"
|
||||
out=$((LC_ALL=C gcc $BLD_FLAGS $BLD_INCLUDE -o ccextractor $BLD_SOURCES $BLD_LINKER)2>&1)
|
||||
res=$?
|
||||
if [[ $out == *"gcc: command not found"* ]]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env sh -ex
|
||||
#!/usr/bin/env -S sh -ex
|
||||
|
||||
####################################################################
|
||||
# setup by tracey apr 2012
|
||||
@@ -83,9 +83,6 @@ cd -;
|
||||
# ccextractor -- build static
|
||||
git clone https://github.com/CCExtractor/ccextractor;
|
||||
cd ccextractor/linux/;
|
||||
# wget https://sourceforge.net/projects/ccextractor/files/ccextractor/0.82/ccextractor.src.0.82.zip;
|
||||
# unzip ccextractor*.zip;
|
||||
# cd ccextractor.*/linux/;
|
||||
perl -i -pe 's/O3 /O3 -static /' Makefile;
|
||||
# quick patch:
|
||||
perl -i -pe 's/(strchr|strstr)\(/$1((char *)/' ../src/thirdparty/gpacmp4/url.c ../src/thirdparty/gpacmp4/error.c;
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_PREREQ([2.69])
|
||||
AC_INIT([CCExtractor], [0.89], [carlos@ccextractor.org])
|
||||
AC_INIT([CCExtractor], [0.94], [carlos@ccextractor.org])
|
||||
AC_CONFIG_AUX_DIR([build-conf])
|
||||
AC_CONFIG_SRCDIR([../src/ccextractor.c])
|
||||
AM_INIT_AUTOMAKE([foreign subdir-objects])
|
||||
|
||||
AC_CONFIG_MACRO_DIRS([m4])
|
||||
|
||||
# Checks for programs.
|
||||
AC_PROG_CC
|
||||
@@ -91,6 +91,50 @@ AC_HELP_STRING([--with-gui], [Builds CCExtractor with GUI (requires GLFW and GLE
|
||||
[PKG_CHECK_MODULES([glfw3], [glfw3]) && PKG_CHECK_MODULES([glew], [glew])],
|
||||
[with_gui=no])
|
||||
|
||||
#Add argument for rust
|
||||
AC_ARG_WITH([rust],
|
||||
AC_HELP_STRING([--with-rust], [Builds CCExtractor with rust library]),
|
||||
[with_rust=$withval],
|
||||
[with_rust=yes])
|
||||
|
||||
AC_MSG_CHECKING(whether to build with rust library)
|
||||
if test "x$with_rust" = "xyes" ; then
|
||||
AC_MSG_RESULT(yes)
|
||||
|
||||
#Check if cargo and rust is installed
|
||||
AC_PATH_PROG([CARGO], [cargo], [notfound])
|
||||
AS_IF([test "$CARGO" = "notfound"], [AC_MSG_ERROR([cargo is required])])
|
||||
|
||||
AC_PATH_PROG([RUSTC], [rustc], [notfound])
|
||||
AS_IF([test "$RUSTC" = "notfound"], [AC_MSG_ERROR([rustc is required])])
|
||||
|
||||
rustc_version=$(rustc --version)
|
||||
MSRV="1.54.0"
|
||||
AX_COMPARE_VERSION($rustc_version, [ge], [$MSRV],
|
||||
[AC_MSG_RESULT(rustc >= $MSRV)],
|
||||
[AC_MSG_ERROR([Minimum supported rust version(MSRV) is $MSRV, please upgrade rust])])
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
AM_CONDITIONAL([WITH_RUST], [test "x$with_rust" = "xyes"])
|
||||
|
||||
AC_ARG_ENABLE(debug,
|
||||
AC_HELP_STRING([--enable-debug],
|
||||
[Build Rust code with debugging information [default=no]]),
|
||||
[debug_release=$enableval],
|
||||
[debug_release=no])
|
||||
|
||||
AC_MSG_CHECKING(whether to build Rust code with debugging information)
|
||||
if test "x$debug_release" = "xyes" ; then
|
||||
AC_MSG_RESULT(yes)
|
||||
RUST_TARGET_SUBDIR=debug
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
RUST_TARGET_SUBDIR=release
|
||||
fi
|
||||
AM_CONDITIONAL([DEBUG_RELEASE], [test "x$debug_release" = "xyes"])
|
||||
|
||||
AC_SUBST([RUST_TARGET_SUBDIR])
|
||||
|
||||
#Checks and prompts if libraries found/not found to avoild failure while building
|
||||
AS_IF([ test x$hardsubx = xtrue && test $HAS_AVCODEC -gt 0 ], [AC_MSG_NOTICE(avcodec library found)])
|
||||
@@ -114,6 +158,7 @@ AM_CONDITIONAL(TESSERACT_PRESENT, [ test ! -z `pkg-config --libs-only-l --silen
|
||||
AM_CONDITIONAL(TESSERACT_PRESENT_RPI, [ test -d "/usr/include/tesseract" && test `ls -A /usr/include/tesseract | wc -l` -gt 0 ])
|
||||
AM_CONDITIONAL(SYS_IS_LINUX, [ test `uname -s` = "Linux"])
|
||||
AM_CONDITIONAL(SYS_IS_MAC, [ test `uname -s` = "Darwin"])
|
||||
AM_CONDITIONAL(SYS_IS_APPLE_SILICON, [ test `uname -a | awk '{print $NF}'` = "arm64" ])
|
||||
AM_CONDITIONAL(BUILD_WITH_GUI, [test "x$with_gui" = "xyes"])
|
||||
AM_CONDITIONAL(SYS_IS_64_BIT,[test `getconf LONG_BIT` = "64"])
|
||||
|
||||
|
||||
177
linux/m4/ax_compare_version.m4
Normal file
177
linux/m4/ax_compare_version.m4
Normal file
@@ -0,0 +1,177 @@
|
||||
# ===========================================================================
|
||||
# https://www.gnu.org/software/autoconf-archive/ax_compare_version.html
|
||||
# ===========================================================================
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# AX_COMPARE_VERSION(VERSION_A, OP, VERSION_B, [ACTION-IF-TRUE], [ACTION-IF-FALSE])
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# This macro compares two version strings. Due to the various number of
|
||||
# minor-version numbers that can exist, and the fact that string
|
||||
# comparisons are not compatible with numeric comparisons, this is not
|
||||
# necessarily trivial to do in a autoconf script. This macro makes doing
|
||||
# these comparisons easy.
|
||||
#
|
||||
# The six basic comparisons are available, as well as checking equality
|
||||
# limited to a certain number of minor-version levels.
|
||||
#
|
||||
# The operator OP determines what type of comparison to do, and can be one
|
||||
# of:
|
||||
#
|
||||
# eq - equal (test A == B)
|
||||
# ne - not equal (test A != B)
|
||||
# le - less than or equal (test A <= B)
|
||||
# ge - greater than or equal (test A >= B)
|
||||
# lt - less than (test A < B)
|
||||
# gt - greater than (test A > B)
|
||||
#
|
||||
# Additionally, the eq and ne operator can have a number after it to limit
|
||||
# the test to that number of minor versions.
|
||||
#
|
||||
# eq0 - equal up to the length of the shorter version
|
||||
# ne0 - not equal up to the length of the shorter version
|
||||
# eqN - equal up to N sub-version levels
|
||||
# neN - not equal up to N sub-version levels
|
||||
#
|
||||
# When the condition is true, shell commands ACTION-IF-TRUE are run,
|
||||
# otherwise shell commands ACTION-IF-FALSE are run. The environment
|
||||
# variable 'ax_compare_version' is always set to either 'true' or 'false'
|
||||
# as well.
|
||||
#
|
||||
# Examples:
|
||||
#
|
||||
# AX_COMPARE_VERSION([3.15.7],[lt],[3.15.8])
|
||||
# AX_COMPARE_VERSION([3.15],[lt],[3.15.8])
|
||||
#
|
||||
# would both be true.
|
||||
#
|
||||
# AX_COMPARE_VERSION([3.15.7],[eq],[3.15.8])
|
||||
# AX_COMPARE_VERSION([3.15],[gt],[3.15.8])
|
||||
#
|
||||
# would both be false.
|
||||
#
|
||||
# AX_COMPARE_VERSION([3.15.7],[eq2],[3.15.8])
|
||||
#
|
||||
# would be true because it is only comparing two minor versions.
|
||||
#
|
||||
# AX_COMPARE_VERSION([3.15.7],[eq0],[3.15])
|
||||
#
|
||||
# would be true because it is only comparing the lesser number of minor
|
||||
# versions of the two values.
|
||||
#
|
||||
# Note: The characters that separate the version numbers do not matter. An
|
||||
# empty string is the same as version 0. OP is evaluated by autoconf, not
|
||||
# configure, so must be a string, not a variable.
|
||||
#
|
||||
# The author would like to acknowledge Guido Draheim whose advice about
|
||||
# the m4_case and m4_ifvaln functions make this macro only include the
|
||||
# portions necessary to perform the specific comparison specified by the
|
||||
# OP argument in the final configure script.
|
||||
#
|
||||
# LICENSE
|
||||
#
|
||||
# Copyright (c) 2008 Tim Toolan <toolan@ele.uri.edu>
|
||||
#
|
||||
# Copying and distribution of this file, with or without modification, are
|
||||
# permitted in any medium without royalty provided the copyright notice
|
||||
# and this notice are preserved. This file is offered as-is, without any
|
||||
# warranty.
|
||||
|
||||
#serial 13
|
||||
|
||||
dnl #########################################################################
|
||||
AC_DEFUN([AX_COMPARE_VERSION], [
|
||||
AC_REQUIRE([AC_PROG_AWK])
|
||||
|
||||
# Used to indicate true or false condition
|
||||
ax_compare_version=false
|
||||
|
||||
# Convert the two version strings to be compared into a format that
|
||||
# allows a simple string comparison. The end result is that a version
|
||||
# string of the form 1.12.5-r617 will be converted to the form
|
||||
# 0001001200050617. In other words, each number is zero padded to four
|
||||
# digits, and non digits are removed.
|
||||
AS_VAR_PUSHDEF([A],[ax_compare_version_A])
|
||||
A=`echo "$1" | sed -e 's/\([[0-9]]*\)/Z\1Z/g' \
|
||||
-e 's/Z\([[0-9]]\)Z/Z0\1Z/g' \
|
||||
-e 's/Z\([[0-9]][[0-9]]\)Z/Z0\1Z/g' \
|
||||
-e 's/Z\([[0-9]][[0-9]][[0-9]]\)Z/Z0\1Z/g' \
|
||||
-e 's/[[^0-9]]//g'`
|
||||
|
||||
AS_VAR_PUSHDEF([B],[ax_compare_version_B])
|
||||
B=`echo "$3" | sed -e 's/\([[0-9]]*\)/Z\1Z/g' \
|
||||
-e 's/Z\([[0-9]]\)Z/Z0\1Z/g' \
|
||||
-e 's/Z\([[0-9]][[0-9]]\)Z/Z0\1Z/g' \
|
||||
-e 's/Z\([[0-9]][[0-9]][[0-9]]\)Z/Z0\1Z/g' \
|
||||
-e 's/[[^0-9]]//g'`
|
||||
|
||||
dnl # In the case of le, ge, lt, and gt, the strings are sorted as necessary
|
||||
dnl # then the first line is used to determine if the condition is true.
|
||||
dnl # The sed right after the echo is to remove any indented white space.
|
||||
m4_case(m4_tolower($2),
|
||||
[lt],[
|
||||
ax_compare_version=`echo "x$A
|
||||
x$B" | sed 's/^ *//' | sort -r | sed "s/x${A}/false/;s/x${B}/true/;1q"`
|
||||
],
|
||||
[gt],[
|
||||
ax_compare_version=`echo "x$A
|
||||
x$B" | sed 's/^ *//' | sort | sed "s/x${A}/false/;s/x${B}/true/;1q"`
|
||||
],
|
||||
[le],[
|
||||
ax_compare_version=`echo "x$A
|
||||
x$B" | sed 's/^ *//' | sort | sed "s/x${A}/true/;s/x${B}/false/;1q"`
|
||||
],
|
||||
[ge],[
|
||||
ax_compare_version=`echo "x$A
|
||||
x$B" | sed 's/^ *//' | sort -r | sed "s/x${A}/true/;s/x${B}/false/;1q"`
|
||||
],[
|
||||
dnl Split the operator from the subversion count if present.
|
||||
m4_bmatch(m4_substr($2,2),
|
||||
[0],[
|
||||
# A count of zero means use the length of the shorter version.
|
||||
# Determine the number of characters in A and B.
|
||||
ax_compare_version_len_A=`echo "$A" | $AWK '{print(length)}'`
|
||||
ax_compare_version_len_B=`echo "$B" | $AWK '{print(length)}'`
|
||||
|
||||
# Set A to no more than B's length and B to no more than A's length.
|
||||
A=`echo "$A" | sed "s/\(.\{$ax_compare_version_len_B\}\).*/\1/"`
|
||||
B=`echo "$B" | sed "s/\(.\{$ax_compare_version_len_A\}\).*/\1/"`
|
||||
],
|
||||
[[0-9]+],[
|
||||
# A count greater than zero means use only that many subversions
|
||||
A=`echo "$A" | sed "s/\(\([[0-9]]\{4\}\)\{m4_substr($2,2)\}\).*/\1/"`
|
||||
B=`echo "$B" | sed "s/\(\([[0-9]]\{4\}\)\{m4_substr($2,2)\}\).*/\1/"`
|
||||
],
|
||||
[.+],[
|
||||
AC_WARNING(
|
||||
[invalid OP numeric parameter: $2])
|
||||
],[])
|
||||
|
||||
# Pad zeros at end of numbers to make same length.
|
||||
ax_compare_version_tmp_A="$A`echo $B | sed 's/./0/g'`"
|
||||
B="$B`echo $A | sed 's/./0/g'`"
|
||||
A="$ax_compare_version_tmp_A"
|
||||
|
||||
# Check for equality or inequality as necessary.
|
||||
m4_case(m4_tolower(m4_substr($2,0,2)),
|
||||
[eq],[
|
||||
test "x$A" = "x$B" && ax_compare_version=true
|
||||
],
|
||||
[ne],[
|
||||
test "x$A" != "x$B" && ax_compare_version=true
|
||||
],[
|
||||
AC_WARNING([invalid OP parameter: $2])
|
||||
])
|
||||
])
|
||||
|
||||
AS_VAR_POPDEF([A])dnl
|
||||
AS_VAR_POPDEF([B])dnl
|
||||
|
||||
dnl # Execute ACTION-IF-TRUE / ACTION-IF-FALSE.
|
||||
if test "$ax_compare_version" = "true" ; then
|
||||
m4_ifvaln([$4],[$4],[:])dnl
|
||||
m4_ifvaln([$5],[else $5])dnl
|
||||
fi
|
||||
]) dnl AX_COMPARE_VERSION
|
||||
@@ -1,5 +1,5 @@
|
||||
AUTOMAKE_OPTIONS = foreign
|
||||
|
||||
ACLOCAL_AMFLAGS = -I m4/
|
||||
|
||||
bin_PROGRAMS = ccextractor
|
||||
ccextractor_SOURCES = \
|
||||
@@ -80,6 +80,7 @@ ccextractor_SOURCES = \
|
||||
../src/thirdparty/gpacmp4/gpac/tools.h \
|
||||
../src/thirdparty/gpacmp4/gpac/utf.h \
|
||||
../src/thirdparty/gpacmp4/gpac/version.h \
|
||||
../src/thirdparty/gpacmp4/gpac/iso639.h \
|
||||
../src/thirdparty/gpacmp4/gpac/internal/avilib.h \
|
||||
../src/thirdparty/gpacmp4/gpac/internal/isomedia_dev.h \
|
||||
../src/thirdparty/gpacmp4/gpac/internal/media_dev.h \
|
||||
@@ -261,18 +262,19 @@ ccextractor_SOURCES = \
|
||||
../src/thirdparty/lib_hash/sha2.h \
|
||||
../src/thirdparty/protobuf-c/protobuf-c.c \
|
||||
../src/thirdparty/protobuf-c/protobuf-c.h \
|
||||
../src/thirdparty/zvbi/bcd.h \
|
||||
../src/thirdparty/zvbi/bit_slicer.c \
|
||||
../src/thirdparty/zvbi/bit_slicer.h \
|
||||
../src/thirdparty/zvbi/decoder.c \
|
||||
../src/thirdparty/zvbi/macros.h \
|
||||
../src/thirdparty/zvbi/misc.h \
|
||||
../src/thirdparty/zvbi/raw_decoder.c \
|
||||
../src/thirdparty/zvbi/raw_decoder.h \
|
||||
../src/thirdparty/zvbi/sampling_par.c \
|
||||
../src/thirdparty/zvbi/sampling_par.h \
|
||||
../src/thirdparty/zvbi/sliced.h \
|
||||
../src/thirdparty/zvbi/zvbi_decoder.h \
|
||||
../src/lib_ccx/zvbi/bcd.h \
|
||||
../src/lib_ccx/zvbi/bit_slicer.c \
|
||||
../src/lib_ccx/zvbi/bit_slicer.h \
|
||||
../src/lib_ccx/zvbi/decoder.c \
|
||||
../src/lib_ccx/zvbi/macros.h \
|
||||
../src/lib_ccx/zvbi/misc.h \
|
||||
../src/lib_ccx/zvbi/raw_decoder.c \
|
||||
../src/lib_ccx/zvbi/raw_decoder.h \
|
||||
../src/lib_ccx/zvbi/sampling_par.c \
|
||||
../src/lib_ccx/zvbi/sampling_par.h \
|
||||
../src/lib_ccx/zvbi/sliced.h \
|
||||
../src/lib_ccx/zvbi/zvbi_decoder.h \
|
||||
../src/freetype/* \
|
||||
../src/thirdparty/freetype/autofit/autofit.c \
|
||||
../src/thirdparty/freetype/base/ftbase.c \
|
||||
../src/thirdparty/freetype/base/ftbbox.c \
|
||||
@@ -301,6 +303,7 @@ ccextractor_SOURCES = \
|
||||
../src/thirdparty/freetype/cff/cff.c \
|
||||
../src/thirdparty/freetype/cid/type1cid.c \
|
||||
../src/thirdparty/freetype/gzip/ftgzip.c \
|
||||
../src/thirdparty/freetype/include/ft2build.h \
|
||||
../src/thirdparty/freetype/lzw/ftlzw.c \
|
||||
../src/thirdparty/freetype/pcf/pcf.c \
|
||||
../src/thirdparty/freetype/pfr/pfr.c \
|
||||
@@ -314,22 +317,48 @@ ccextractor_SOURCES = \
|
||||
../src/thirdparty/freetype/type1/type1.c \
|
||||
../src/thirdparty/freetype/type42/type42.c \
|
||||
../src/thirdparty/freetype/winfonts/winfnt.c
|
||||
|
||||
|
||||
if SYS_IS_APPLE_SILICON
|
||||
ccextractor_SOURCES += ../src/thirdparty/libpng/arm/arm_init.c \
|
||||
../src/thirdparty/libpng/arm/filter_neon_intrinsics.c \
|
||||
../src/thirdparty/libpng/arm/palette_neon_intrinsics.c
|
||||
endif
|
||||
|
||||
ccextractor_CFLAGS = -std=gnu99 -Wno-write-strings -Wno-pointer-sign -D_FILE_OFFSET_BITS=64 -DVERSION_FILE_PRESENT -DFT2_BUILD_LIBRARY -DGPAC_DISABLE_VTT -DGPAC_DISABLE_OD_DUMP -DGPAC_DISABLE_REMOTERY -DNO_GZIP -DGPAC_HAVE_CONFIG_H
|
||||
|
||||
ccextractor_CPPFLAGS =-I../src/lib_ccx/ -I../src/thirdparty/gpacmp4/ -I../src/thirdparty/libpng/ -I../src/thirdparty/zlib/ -I../src/thirdparty/zvbi/ -I../src/thirdparty/lib_hash/ -I../src/thirdparty/protobuf-c -I../src/thirdparty -I../src -I../src/thirdparty/freetype/include
|
||||
ccextractor_CPPFLAGS =-I../src/lib_ccx/ -I../src/thirdparty/gpacmp4/ -I../src/thirdparty/libpng/ -I../src/thirdparty/zlib/ -I../src/lib_ccx/zvbi/ -I../src/thirdparty/lib_hash/ -I../src/thirdparty/protobuf-c/ -I../src/thirdparty -I../src/ -I../src/thirdparty/freetype/include/
|
||||
|
||||
|
||||
ccextractor_LDADD=-lm -lpthread -ldl
|
||||
|
||||
if WITH_RUST
|
||||
ccextractor_LDADD += ./rust/@RUST_TARGET_SUBDIR@/libccx_rust.a
|
||||
else
|
||||
ccextractor_CFLAGS += -DDISABLE_RUST
|
||||
ccextractor_CPPFLAGS += -DDISABLE_RUST
|
||||
endif
|
||||
|
||||
if DEBUG_RELEASE
|
||||
CARGO_RELEASE_ARGS=
|
||||
else
|
||||
CARGO_RELEASE_ARGS=--release
|
||||
endif
|
||||
|
||||
./rust/@RUST_TARGET_SUBDIR@/libccx_rust.a:
|
||||
cd ../src/rust && \
|
||||
CARGO_TARGET_DIR=../../linux/rust $(CARGO) build $(CARGO_RELEASE_ARGS);
|
||||
|
||||
if SYS_IS_LINUX
|
||||
ccextractor_CFLAGS += -O3 -s -DGPAC_CONFIG_LINUX
|
||||
endif
|
||||
|
||||
if SYS_IS_MAC
|
||||
ccextractor_CFLAGS += -DPAC_CONFIG_DARWIN -Dfopen64=fopen -Dopen64=open -Dlseek64=lseek
|
||||
ccextractor_LDADD += -liconv -lz
|
||||
ccextractor_LDADD += -liconv -lz
|
||||
endif
|
||||
|
||||
if SYS_IS_64_BIT
|
||||
ccextractor_CFLAGS += -DGPAC_64_BITS
|
||||
endif
|
||||
|
||||
if HARDSUBX_IS_ENABLED
|
||||
@@ -417,12 +446,12 @@ ccextractorGUI_CFLAGS += -O3 -DUNIX
|
||||
ccextractorGUI_CFLAGS += ${glew_CFLAGS}
|
||||
ccextractorGUI_LDADD += ${glew_LIBS}
|
||||
ccextractorGUI_LDFLAGS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo
|
||||
ccextractorGUI_LDADD += -lm -L/usr/local/lib -lpthread
|
||||
ccextractorGUI_LDADD += -lglfw -lm -L/usr/local/lib -lpthread
|
||||
endif
|
||||
|
||||
if HARDSUBX_IS_ENABLED
|
||||
if OCR_IS_ENABLED
|
||||
ccextractorGUI_CFLAGS += -DENABLE_OCR
|
||||
ccextractorGUI_CFLAGS += -DENABLE_OCR
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#!/bin/bash
|
||||
cd `dirname $0`
|
||||
BLD_FLAGS="-std=gnu99 -Wno-write-strings -Wno-pointer-sign -DGPAC_CONFIG_DARWIN -D_FILE_OFFSET_BITS=64 -DVERSION_FILE_PRESENT -Dfopen64=fopen -Dopen64=open -Dlseek64=lseek -DFT2_BUILD_LIBRARY -DGPAC_DISABLE_VTT -DGPAC_DISABLE_OD_DUMP -DGPAC_DISABLE_REMOTERY -DNO_GZIP -DGPAC_HAVE_CONFIG_H"
|
||||
BLD_FLAGS="-std=gnu99 -Wno-write-strings -Wno-pointer-sign -DGPAC_CONFIG_DARWIN -D_FILE_OFFSET_BITS=64 -DVERSION_FILE_PRESENT -Dfopen64=fopen -Dopen64=open -Dlseek64=lseek -DFT2_BUILD_LIBRARY -DGPAC_DISABLE_VTT -DGPAC_DISABLE_OD_DUMP -DGPAC_DISABLE_REMOTERY -DNO_GZIP -DGPAC_HAVE_CONFIG_H -DDISABLE_RUST"
|
||||
[[ $1 = "OCR" ]] && BLD_FLAGS="$BLD_FLAGS -DENABLE_OCR"
|
||||
BLD_INCLUDE="-I../src/ -I../src/lib_ccx -I../src/thirdparty/gpacmp4 -I../src/lib_hash -I../src/thirdparty/libpng -I../src/thirdparty -I../src/thirdparty/protobuf-c -I../src/thirdparty/zlib -I../src/thirdparty/zvbi -I../src/thirdparty/freetype/include"
|
||||
BLD_INCLUDE="-I../src/ -I../src/lib_ccx -I../src/thirdparty/gpacmp4 -I../src/lib_hash -I../src/thirdparty/libpng -I../src/thirdparty -I../src/thirdparty/protobuf-c -I../src/thirdparty/zlib -I../src/thirdparty/freetype/include"
|
||||
[[ $1 = "OCR" ]] && BLD_INCLUDE="$BLD_INCLUDE `pkg-config --cflags --silence-errors tesseract`"
|
||||
SRC_CCX="$(find ../src/lib_ccx -name '*.c')"
|
||||
SRC_GPAC="$(find ../src/thirdparty/gpacmp4 -name '*.c')"
|
||||
@@ -11,7 +11,6 @@ SRC_LIBPNG="$(find ../src/thirdparty/libpng -name '*.c')"
|
||||
SRC_PROTOBUF="$(find ../src/thirdparty/protobuf-c -name '*.c')"
|
||||
SRC_UTF8="../src/thirdparty/utf8proc/utf8proc.c"
|
||||
SRC_ZLIB="$(find ../src/thirdparty/zlib -name '*.c')"
|
||||
SRC_ZVBI="$(find ../src/thirdparty/zvbi -name '*.c')"
|
||||
SRC_FREETYPE="../src/thirdparty/freetype/autofit/autofit.c \
|
||||
../src/thirdparty/freetype/base/ftbase.c \
|
||||
../src/thirdparty/freetype/base/ftbbox.c \
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
# -*- Autoconf -*-
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_PREREQ([2.69])
|
||||
AC_INIT([CCExtractor], [0.89], [carlos@ccextractor.org])
|
||||
AC_PREREQ([2.71])
|
||||
AC_INIT([CCExtractor],[0.94],[carlos@ccextractor.org])
|
||||
AC_CONFIG_AUX_DIR([build-conf])
|
||||
AC_CONFIG_SRCDIR([../src/ccextractor.c])
|
||||
AM_INIT_AUTOMAKE([foreign subdir-objects])
|
||||
|
||||
AC_CONFIG_MACRO_DIRS([m4])
|
||||
|
||||
# Checks for programs.
|
||||
AC_PROG_CC
|
||||
@@ -63,7 +63,7 @@ AC_CHECK_FUNCS([floor ftruncate gethostbyname gettimeofday inet_ntoa mblen memch
|
||||
|
||||
# Checks for arguments with configure
|
||||
AC_ARG_ENABLE([hardsubx],
|
||||
AC_HELP_STRING([--enable-hardsubx], [Enables extraction of burnt subtitles (hard subtitles)]),
|
||||
AS_HELP_STRING([--enable-hardsubx],[Enables extraction of burnt subtitles (hard subtitles)]),
|
||||
[case "${enableval}" in
|
||||
yes) hardsubx=true ;;
|
||||
no) hardsubx=false ;;
|
||||
@@ -71,7 +71,7 @@ AC_HELP_STRING([--enable-hardsubx], [Enables extraction of burnt subtitles (hard
|
||||
esac],[hardsubx=false])
|
||||
|
||||
AC_ARG_ENABLE([ocr],
|
||||
AC_HELP_STRING([--enable-ocr], [Enables Optical Character Recognition]),
|
||||
AS_HELP_STRING([--enable-ocr],[Enables Optical Character Recognition]),
|
||||
[case "${enableval}" in
|
||||
yes) ocr=true ;;
|
||||
no) ocr=false ;;
|
||||
@@ -79,7 +79,7 @@ AC_HELP_STRING([--enable-ocr], [Enables Optical Character Recognition]),
|
||||
esac],[ocr=false])
|
||||
|
||||
AC_ARG_ENABLE([ffmpeg],
|
||||
AC_HELP_STRING([--enable-ffmpeg], [Enable FFmpeg integration]),
|
||||
AS_HELP_STRING([--enable-ffmpeg],[Enable FFmpeg integration]),
|
||||
[case "${enableval}" in
|
||||
yes) ffmpeg=true ;;
|
||||
no) ffmpeg=false ;;
|
||||
@@ -87,12 +87,55 @@ AC_HELP_STRING([--enable-ffmpeg], [Enable FFmpeg integration]),
|
||||
esac],[ffmpeg=false])
|
||||
|
||||
AC_ARG_WITH([gui],
|
||||
AC_HELP_STRING([--with-gui], [Builds CCExtractor with GUI (requires GLFW and GLEW)]),
|
||||
AS_HELP_STRING([--with-gui],[Builds CCExtractor with GUI (requires GLFW and GLEW)]),
|
||||
[PKG_CHECK_MODULES([glfw3], [glfw3]) && PKG_CHECK_MODULES([glew], [glew])],
|
||||
[with_gui=no])
|
||||
|
||||
#Add argument for rust
|
||||
AC_ARG_WITH([rust],
|
||||
AS_HELP_STRING([--with-rust],[Builds CCExtractor with rust library]),
|
||||
[with_rust=$withval],
|
||||
[with_rust=yes])
|
||||
|
||||
#Checks and prompts if libraries found/not found to avoild failure while building
|
||||
AC_MSG_CHECKING(whether to build with rust library)
|
||||
if test "x$with_rust" = "xyes" ; then
|
||||
AC_MSG_RESULT(yes)
|
||||
|
||||
#Check if cargo and rust is installed
|
||||
AC_PATH_PROG([CARGO], [cargo], [notfound])
|
||||
AS_IF([test "$CARGO" = "notfound"], [AC_MSG_ERROR([cargo is required])])
|
||||
|
||||
AC_PATH_PROG([RUSTC], [rustc], [notfound])
|
||||
AS_IF([test "$RUSTC" = "notfound"], [AC_MSG_ERROR([rustc is required])])
|
||||
|
||||
rustc_version=$(rustc --version)
|
||||
MSRV="1.54.0"
|
||||
AX_COMPARE_VERSION($rustc_version, [ge], [$MSRV],
|
||||
[AC_MSG_RESULT(rustc >= $MSRV)],
|
||||
[AC_MSG_ERROR([Minimum supported rust version(MSRV) is $MSRV, please upgrade rust])])
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
fi
|
||||
AM_CONDITIONAL([WITH_RUST], [test "x$with_rust" = "xyes"])
|
||||
|
||||
AC_ARG_ENABLE(debug,
|
||||
AS_HELP_STRING([--enable-debug],[Build Rust code with debugging information [default=no]]),
|
||||
[debug_release=$enableval],
|
||||
[debug_release=no])
|
||||
|
||||
AC_MSG_CHECKING(whether to build Rust code with debugging information)
|
||||
if test "x$debug_release" = "xyes" ; then
|
||||
AC_MSG_RESULT(yes)
|
||||
RUST_TARGET_SUBDIR=debug
|
||||
else
|
||||
AC_MSG_RESULT(no)
|
||||
RUST_TARGET_SUBDIR=release
|
||||
fi
|
||||
AM_CONDITIONAL([DEBUG_RELEASE], [test "x$debug_release" = "xyes"])
|
||||
|
||||
AC_SUBST([RUST_TARGET_SUBDIR])
|
||||
|
||||
#Checks and prompts if libraries found/not found to avoid failure while building
|
||||
AS_IF([ test x$hardsubx = xtrue && test $HAS_AVCODEC -gt 0 ], [AC_MSG_NOTICE(avcodec library found)])
|
||||
AS_IF([ test x$hardsubx = xtrue && test ! $HAS_AVCODEC -gt 0 ], [AC_MSG_ERROR(avcodec library not found. Please install the avcodec library before proceeding)])
|
||||
AS_IF([ test x$hardsubx = xtrue && test $HAS_AVFORMAT -gt 0 ], [AC_MSG_NOTICE(avformat library found)])
|
||||
@@ -110,11 +153,13 @@ AS_IF([ (test x$ocr = xtrue || test x$hardsubx = xtrue) && test ! $HAS_LEPT -gt
|
||||
AM_CONDITIONAL(HARDSUBX_IS_ENABLED, [ test x$hardsubx = xtrue ])
|
||||
AM_CONDITIONAL(OCR_IS_ENABLED, [ test x$ocr = xtrue || test x$hardsubx = xtrue ])
|
||||
AM_CONDITIONAL(FFMPEG_IS_ENABLED, [ test x$ffmpeg = xtrue ])
|
||||
AM_CONDITIONAL(TESSERACT_PRESENT, [ test ! -z `pkg-config --libs-only-l --silence-errors tesseract`])
|
||||
AM_CONDITIONAL(TESSERACT_PRESENT, [ test ! -z `pkg-config --libs-only-l --silence-errors tesseract` ])
|
||||
AM_CONDITIONAL(TESSERACT_PRESENT_RPI, [ test -d "/usr/include/tesseract" && test `ls -A /usr/include/tesseract | wc -l` -gt 0 ])
|
||||
AM_CONDITIONAL(SYS_IS_LINUX, [ test `uname -s` = "Linux"])
|
||||
AM_CONDITIONAL(SYS_IS_MAC, [ test `uname -s` = "Darwin"])
|
||||
AM_CONDITIONAL(SYS_IS_APPLE_SILICON, [ test `uname -a | awk '{print $NF}'` = "arm64" ])
|
||||
AM_CONDITIONAL(BUILD_WITH_GUI, [test "x$with_gui" = "xyes"])
|
||||
AM_CONDITIONAL(SYS_IS_64_BIT,[test `getconf LONG_BIT` = "64"])
|
||||
|
||||
AC_CONFIG_FILES([Makefile])
|
||||
AC_OUTPUT
|
||||
|
||||
177
mac/m4/ax_compare_version.m4
Normal file
177
mac/m4/ax_compare_version.m4
Normal file
@@ -0,0 +1,177 @@
|
||||
# ===========================================================================
|
||||
# https://www.gnu.org/software/autoconf-archive/ax_compare_version.html
|
||||
# ===========================================================================
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# AX_COMPARE_VERSION(VERSION_A, OP, VERSION_B, [ACTION-IF-TRUE], [ACTION-IF-FALSE])
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# This macro compares two version strings. Due to the various number of
|
||||
# minor-version numbers that can exist, and the fact that string
|
||||
# comparisons are not compatible with numeric comparisons, this is not
|
||||
# necessarily trivial to do in a autoconf script. This macro makes doing
|
||||
# these comparisons easy.
|
||||
#
|
||||
# The six basic comparisons are available, as well as checking equality
|
||||
# limited to a certain number of minor-version levels.
|
||||
#
|
||||
# The operator OP determines what type of comparison to do, and can be one
|
||||
# of:
|
||||
#
|
||||
# eq - equal (test A == B)
|
||||
# ne - not equal (test A != B)
|
||||
# le - less than or equal (test A <= B)
|
||||
# ge - greater than or equal (test A >= B)
|
||||
# lt - less than (test A < B)
|
||||
# gt - greater than (test A > B)
|
||||
#
|
||||
# Additionally, the eq and ne operator can have a number after it to limit
|
||||
# the test to that number of minor versions.
|
||||
#
|
||||
# eq0 - equal up to the length of the shorter version
|
||||
# ne0 - not equal up to the length of the shorter version
|
||||
# eqN - equal up to N sub-version levels
|
||||
# neN - not equal up to N sub-version levels
|
||||
#
|
||||
# When the condition is true, shell commands ACTION-IF-TRUE are run,
|
||||
# otherwise shell commands ACTION-IF-FALSE are run. The environment
|
||||
# variable 'ax_compare_version' is always set to either 'true' or 'false'
|
||||
# as well.
|
||||
#
|
||||
# Examples:
|
||||
#
|
||||
# AX_COMPARE_VERSION([3.15.7],[lt],[3.15.8])
|
||||
# AX_COMPARE_VERSION([3.15],[lt],[3.15.8])
|
||||
#
|
||||
# would both be true.
|
||||
#
|
||||
# AX_COMPARE_VERSION([3.15.7],[eq],[3.15.8])
|
||||
# AX_COMPARE_VERSION([3.15],[gt],[3.15.8])
|
||||
#
|
||||
# would both be false.
|
||||
#
|
||||
# AX_COMPARE_VERSION([3.15.7],[eq2],[3.15.8])
|
||||
#
|
||||
# would be true because it is only comparing two minor versions.
|
||||
#
|
||||
# AX_COMPARE_VERSION([3.15.7],[eq0],[3.15])
|
||||
#
|
||||
# would be true because it is only comparing the lesser number of minor
|
||||
# versions of the two values.
|
||||
#
|
||||
# Note: The characters that separate the version numbers do not matter. An
|
||||
# empty string is the same as version 0. OP is evaluated by autoconf, not
|
||||
# configure, so must be a string, not a variable.
|
||||
#
|
||||
# The author would like to acknowledge Guido Draheim whose advice about
|
||||
# the m4_case and m4_ifvaln functions make this macro only include the
|
||||
# portions necessary to perform the specific comparison specified by the
|
||||
# OP argument in the final configure script.
|
||||
#
|
||||
# LICENSE
|
||||
#
|
||||
# Copyright (c) 2008 Tim Toolan <toolan@ele.uri.edu>
|
||||
#
|
||||
# Copying and distribution of this file, with or without modification, are
|
||||
# permitted in any medium without royalty provided the copyright notice
|
||||
# and this notice are preserved. This file is offered as-is, without any
|
||||
# warranty.
|
||||
|
||||
#serial 13
|
||||
|
||||
dnl #########################################################################
|
||||
AC_DEFUN([AX_COMPARE_VERSION], [
|
||||
AC_REQUIRE([AC_PROG_AWK])
|
||||
|
||||
# Used to indicate true or false condition
|
||||
ax_compare_version=false
|
||||
|
||||
# Convert the two version strings to be compared into a format that
|
||||
# allows a simple string comparison. The end result is that a version
|
||||
# string of the form 1.12.5-r617 will be converted to the form
|
||||
# 0001001200050617. In other words, each number is zero padded to four
|
||||
# digits, and non digits are removed.
|
||||
AS_VAR_PUSHDEF([A],[ax_compare_version_A])
|
||||
A=`echo "$1" | sed -e 's/\([[0-9]]*\)/Z\1Z/g' \
|
||||
-e 's/Z\([[0-9]]\)Z/Z0\1Z/g' \
|
||||
-e 's/Z\([[0-9]][[0-9]]\)Z/Z0\1Z/g' \
|
||||
-e 's/Z\([[0-9]][[0-9]][[0-9]]\)Z/Z0\1Z/g' \
|
||||
-e 's/[[^0-9]]//g'`
|
||||
|
||||
AS_VAR_PUSHDEF([B],[ax_compare_version_B])
|
||||
B=`echo "$3" | sed -e 's/\([[0-9]]*\)/Z\1Z/g' \
|
||||
-e 's/Z\([[0-9]]\)Z/Z0\1Z/g' \
|
||||
-e 's/Z\([[0-9]][[0-9]]\)Z/Z0\1Z/g' \
|
||||
-e 's/Z\([[0-9]][[0-9]][[0-9]]\)Z/Z0\1Z/g' \
|
||||
-e 's/[[^0-9]]//g'`
|
||||
|
||||
dnl # In the case of le, ge, lt, and gt, the strings are sorted as necessary
|
||||
dnl # then the first line is used to determine if the condition is true.
|
||||
dnl # The sed right after the echo is to remove any indented white space.
|
||||
m4_case(m4_tolower($2),
|
||||
[lt],[
|
||||
ax_compare_version=`echo "x$A
|
||||
x$B" | sed 's/^ *//' | sort -r | sed "s/x${A}/false/;s/x${B}/true/;1q"`
|
||||
],
|
||||
[gt],[
|
||||
ax_compare_version=`echo "x$A
|
||||
x$B" | sed 's/^ *//' | sort | sed "s/x${A}/false/;s/x${B}/true/;1q"`
|
||||
],
|
||||
[le],[
|
||||
ax_compare_version=`echo "x$A
|
||||
x$B" | sed 's/^ *//' | sort | sed "s/x${A}/true/;s/x${B}/false/;1q"`
|
||||
],
|
||||
[ge],[
|
||||
ax_compare_version=`echo "x$A
|
||||
x$B" | sed 's/^ *//' | sort -r | sed "s/x${A}/true/;s/x${B}/false/;1q"`
|
||||
],[
|
||||
dnl Split the operator from the subversion count if present.
|
||||
m4_bmatch(m4_substr($2,2),
|
||||
[0],[
|
||||
# A count of zero means use the length of the shorter version.
|
||||
# Determine the number of characters in A and B.
|
||||
ax_compare_version_len_A=`echo "$A" | $AWK '{print(length)}'`
|
||||
ax_compare_version_len_B=`echo "$B" | $AWK '{print(length)}'`
|
||||
|
||||
# Set A to no more than B's length and B to no more than A's length.
|
||||
A=`echo "$A" | sed "s/\(.\{$ax_compare_version_len_B\}\).*/\1/"`
|
||||
B=`echo "$B" | sed "s/\(.\{$ax_compare_version_len_A\}\).*/\1/"`
|
||||
],
|
||||
[[0-9]+],[
|
||||
# A count greater than zero means use only that many subversions
|
||||
A=`echo "$A" | sed "s/\(\([[0-9]]\{4\}\)\{m4_substr($2,2)\}\).*/\1/"`
|
||||
B=`echo "$B" | sed "s/\(\([[0-9]]\{4\}\)\{m4_substr($2,2)\}\).*/\1/"`
|
||||
],
|
||||
[.+],[
|
||||
AC_WARNING(
|
||||
[invalid OP numeric parameter: $2])
|
||||
],[])
|
||||
|
||||
# Pad zeros at end of numbers to make same length.
|
||||
ax_compare_version_tmp_A="$A`echo $B | sed 's/./0/g'`"
|
||||
B="$B`echo $A | sed 's/./0/g'`"
|
||||
A="$ax_compare_version_tmp_A"
|
||||
|
||||
# Check for equality or inequality as necessary.
|
||||
m4_case(m4_tolower(m4_substr($2,0,2)),
|
||||
[eq],[
|
||||
test "x$A" = "x$B" && ax_compare_version=true
|
||||
],
|
||||
[ne],[
|
||||
test "x$A" != "x$B" && ax_compare_version=true
|
||||
],[
|
||||
AC_WARNING([invalid OP parameter: $2])
|
||||
])
|
||||
])
|
||||
|
||||
AS_VAR_POPDEF([A])dnl
|
||||
AS_VAR_POPDEF([B])dnl
|
||||
|
||||
dnl # Execute ACTION-IF-TRUE / ACTION-IF-FALSE.
|
||||
if test "$ax_compare_version" = "true" ; then
|
||||
m4_ifvaln([$4],[$4],[:])dnl
|
||||
m4_ifvaln([$5],[else $5])dnl
|
||||
fi
|
||||
]) dnl AX_COMPARE_VERSION
|
||||
@@ -1,5 +1,5 @@
|
||||
pkgname=ccextractor
|
||||
pkgver=0.89
|
||||
pkgver=0.94
|
||||
pkgrel=1
|
||||
pkgdesc="A closed captions and teletext subtitles extractor for video streams."
|
||||
arch=('i686' 'x86_64')
|
||||
|
||||
@@ -6,6 +6,7 @@ option (WITH_FFMPEG "Build using FFmpeg demuxer and decoder" OFF)
|
||||
option (WITH_OCR "Build with OCR (Optical Character Recognition) feature" OFF)
|
||||
option (WITH_SHARING "Build with sharing and translation support" OFF)
|
||||
option (WITH_HARDSUBX "Build with support for burned-in subtitles" OFF)
|
||||
option (WITHOUT_RUST "Build without Rust library" OFF)
|
||||
|
||||
# Version number
|
||||
set (CCEXTRACTOR_VERSION_MAJOR 0)
|
||||
@@ -42,6 +43,14 @@ configure_file (
|
||||
|
||||
add_definitions(-DVERSION_FILE_PRESENT -DFT2_BUILD_LIBRARY -DGPAC_DISABLE_VTT -DGPAC_DISABLE_OD_DUMP -DGPAC_DISABLE_REMOTERY -DNO_GZIP -DGPAC_HAVE_CONFIG_H)
|
||||
|
||||
if(UNIX)
|
||||
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
add_definitions(-DGPAC_CONFIG_DARWIN)
|
||||
else ()
|
||||
add_definitions(-DGPAC_CONFIG_LINUX)
|
||||
endif()
|
||||
endif(UNIX)
|
||||
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
add_definitions(-DGPAC_64_BITS)
|
||||
endif()
|
||||
@@ -54,6 +63,12 @@ include_directories(${PROJECT_SOURCE_DIR}/thirdparty/gpacmp4)
|
||||
include_directories(${PROJECT_SOURCE_DIR}/thirdparty/protobuf-c)
|
||||
include_directories(${PROJECT_SOURCE_DIR}/thirdparty/lib_hash)
|
||||
include_directories(${PROJECT_SOURCE_DIR}/thirdparty/libpng)
|
||||
|
||||
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin" AND ${CMAKE_HOST_SYSTEM_PROCESSOR} MATCHES "arm64")
|
||||
include_directories(${PROJECT_SOURCE_DIR}/thirdparty/libpng/arm)
|
||||
aux_source_directory(${PROJECT_SOURCE_DIR}/thirdparty/libpng/arm SOURCEFILE)
|
||||
endif ()
|
||||
|
||||
include_directories(${PROJECT_SOURCE_DIR}/thirdparty/zlib)
|
||||
include_directories(${PROJECT_SOURCE_DIR}/thirdparty/freetype/include)
|
||||
aux_source_directory(${PROJECT_SOURCE_DIR}/thirdparty/gpacmp4/ SOURCEFILE)
|
||||
@@ -226,6 +241,21 @@ if (PKG_CONFIG_FOUND AND WITH_HARDSUBX)
|
||||
endif (PKG_CONFIG_FOUND AND WITH_HARDSUBX)
|
||||
|
||||
add_executable (ccextractor ${SOURCEFILE} ${FREETYPE_SOURCE} ${UTF8PROC_SOURCE})
|
||||
|
||||
########################################################
|
||||
# Build with Rust library
|
||||
########################################################
|
||||
|
||||
if (PKG_CONFIG_FOUND AND NOT WITHOUT_RUST)
|
||||
add_subdirectory (rust)
|
||||
get_target_property(RUST_LIB ccx_rust LOCATION)
|
||||
set (EXTRA_LIBS ${EXTRA_LIBS} ${RUST_LIB})
|
||||
add_dependencies(ccextractor ccx_rust)
|
||||
else ()
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DDISABLE_RUST")
|
||||
endif (PKG_CONFIG_FOUND AND NOT WITHOUT_RUST)
|
||||
|
||||
|
||||
target_link_libraries (ccextractor ${EXTRA_LIBS})
|
||||
target_include_directories (ccextractor PUBLIC ${EXTRA_INCLUDES})
|
||||
|
||||
|
||||
@@ -86,6 +86,10 @@ if (MINGW OR CYGWIN)
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DGPAC_CONFIG_WIN32")
|
||||
endif (MINGW OR CYGWIN)
|
||||
|
||||
if (WITHOUT_RUST)
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DDISABLE_RUST")
|
||||
endif (WITHOUT_RUST)
|
||||
|
||||
if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DGPAC_CONFIG_LINUX")
|
||||
endif (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
|
||||
@@ -22,6 +22,8 @@ void init_options(struct ccx_s_options *options)
|
||||
options->settings_608.force_rollup = 0;
|
||||
options->settings_608.screens_to_process = -1;
|
||||
options->settings_608.default_color = COL_TRANSPARENT; // Defaults to transparent/no-color.
|
||||
options->is_608_enabled = 0;
|
||||
options->is_708_enabled = 0;
|
||||
|
||||
options->extract = 1; // Extract 1st field only (primary language)
|
||||
options->cc_channel = 1; // Channel we want to dump in srt mode
|
||||
@@ -131,15 +133,12 @@ void init_options(struct ccx_s_options *options)
|
||||
options->enc_cfg.start_credits_text = NULL;
|
||||
options->enc_cfg.end_credits_text = NULL;
|
||||
options->enc_cfg.encoding = CCX_ENC_UTF_8;
|
||||
#ifdef _WIN32
|
||||
options->enc_cfg.no_bom = 0; // Use BOM by default for windows only
|
||||
#else
|
||||
options->enc_cfg.no_bom = 1;
|
||||
#endif
|
||||
options->enc_cfg.services_charsets = NULL;
|
||||
options->enc_cfg.all_services_charset = NULL;
|
||||
options->enc_cfg.with_semaphore = 0;
|
||||
options->enc_cfg.force_dropframe = 0; // Assume No Drop Frame for MCC Encode.
|
||||
options->enc_cfg.extract_only_708 = 0;
|
||||
|
||||
options->settings_dtvcc.enabled = 0;
|
||||
options->settings_dtvcc.active_services_count = 0;
|
||||
|
||||
@@ -84,6 +84,7 @@ struct encoder_cfg
|
||||
int services_enabled[CCX_DTVCC_MAX_SERVICES];
|
||||
char** services_charsets;
|
||||
char* all_services_charset;
|
||||
int extract_only_708; // 1 if only 708 subs extraction is enabled
|
||||
};
|
||||
|
||||
struct ccx_s_options // Options from user parameters
|
||||
@@ -102,6 +103,8 @@ struct ccx_s_options // Options from user parameters
|
||||
|
||||
ccx_decoder_608_settings settings_608; // Contains the settings for the 608 decoder.
|
||||
ccx_decoder_dtvcc_settings settings_dtvcc; // Same for 708 decoder
|
||||
int is_608_enabled; // Is 608 enabled by explicitly using flags(-1,-2,-12)
|
||||
int is_708_enabled; // Is 708 enabled by explicitly using flags(-svc)
|
||||
|
||||
char millis_separator;
|
||||
int binary_concat; // Disabled by -ve or --videoedited
|
||||
|
||||
@@ -1,119 +1,119 @@
|
||||
#ifndef CCX_PLATFORM_H
|
||||
#define CCX_PLATFORM_H
|
||||
|
||||
// Default includes (cross-platform)
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <time.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdarg.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define __STDC_FORMAT_MACROS
|
||||
|
||||
#ifdef _WIN32
|
||||
#define inline _inline
|
||||
#define typeof decltype
|
||||
#include <io.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <windows.h>
|
||||
#define STDIN_FILENO 0
|
||||
#define STDOUT_FILENO 1
|
||||
#define STDERR_FILENO 2
|
||||
#include "inttypes.h"
|
||||
#define UINT64_MAX _UI64_MAX
|
||||
typedef int socklen_t;
|
||||
typedef int ssize_t;
|
||||
typedef uint32_t in_addr_t;
|
||||
#ifndef IN_CLASSD
|
||||
#define IN_CLASSD(i) (((INT32)(i) & 0xf0000000) == 0xe0000000)
|
||||
#define IN_MULTICAST(i) IN_CLASSD(i)
|
||||
#endif
|
||||
#include <direct.h>
|
||||
#define mkdir(path, mode) _mkdir(path)
|
||||
#ifndef snprintf
|
||||
// Added ifndef because VS2013 warns for macro redefinition.
|
||||
#define snprintf(buf, len, fmt, ...) _snprintf(buf, len, fmt, __VA_ARGS__)
|
||||
#endif
|
||||
#define sleep(sec) Sleep((sec) * 1000)
|
||||
|
||||
#include <fcntl.h>
|
||||
#else // _WIN32
|
||||
#include <unistd.h>
|
||||
#define __STDC_LIMIT_MACROS
|
||||
#include <inttypes.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#endif // _WIN32
|
||||
|
||||
#include "disable_warnings.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include "stdintmsc.h"
|
||||
// Don't bug me with strcpy() deprecation warnings
|
||||
#pragma warning(disable : 4996)
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#ifdef __OpenBSD__
|
||||
#define FOPEN64 fopen
|
||||
#define OPEN open
|
||||
#define FSEEK fseek
|
||||
#define FTELL ftell
|
||||
#define LSEEK lseek
|
||||
#define FSTAT fstat
|
||||
#else
|
||||
#ifdef _WIN32
|
||||
#define OPEN _open
|
||||
// 64 bit file functions
|
||||
#if defined(_MSC_VER)
|
||||
#define FSEEK _fseeki64
|
||||
#define FTELL _ftelli64
|
||||
#else
|
||||
// For MinGW
|
||||
#define FSEEK fseeko64
|
||||
#define FTELL ftello64
|
||||
#endif
|
||||
#define TELL _telli64
|
||||
#define LSEEK _lseeki64
|
||||
typedef struct _stati64 FSTATSTRUCT;
|
||||
#else
|
||||
// Linux internally maps these functions to 64bit usage,
|
||||
// if _FILE_OFFSET_BITS macro is set to 64
|
||||
#define FOPEN64 fopen
|
||||
#define OPEN open
|
||||
#define LSEEK lseek
|
||||
#define FSEEK fseek
|
||||
#define FTELL ftell
|
||||
#define FSTAT fstat
|
||||
#define TELL tell
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef int64_t_C
|
||||
#define int64_t_C(c) (c ## LL)
|
||||
#define uint64_t_C(c) (c ## ULL)
|
||||
#endif
|
||||
|
||||
#ifndef O_BINARY
|
||||
#define O_BINARY 0 // Not present in Linux because it's always binary
|
||||
#endif
|
||||
|
||||
#ifndef max
|
||||
#define max(a,b) (((a) > (b)) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
typedef int64_t LLONG;
|
||||
typedef uint64_t ULLONG;
|
||||
typedef uint8_t UBYTE;
|
||||
|
||||
#endif // CCX_PLATFORM_H
|
||||
#ifndef CCX_PLATFORM_H
|
||||
#define CCX_PLATFORM_H
|
||||
|
||||
// Default includes (cross-platform)
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <time.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdarg.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define __STDC_FORMAT_MACROS
|
||||
|
||||
#ifdef _WIN32
|
||||
#define inline _inline
|
||||
#define typeof decltype
|
||||
#include <io.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <windows.h>
|
||||
#define STDIN_FILENO 0
|
||||
#define STDOUT_FILENO 1
|
||||
#define STDERR_FILENO 2
|
||||
#include "inttypes.h"
|
||||
#define UINT64_MAX _UI64_MAX
|
||||
typedef int socklen_t;
|
||||
typedef int ssize_t;
|
||||
typedef uint32_t in_addr_t;
|
||||
#ifndef IN_CLASSD
|
||||
#define IN_CLASSD(i) (((INT32)(i) & 0xf0000000) == 0xe0000000)
|
||||
#define IN_MULTICAST(i) IN_CLASSD(i)
|
||||
#endif
|
||||
#include <direct.h>
|
||||
#define mkdir(path, mode) _mkdir(path)
|
||||
#ifndef snprintf
|
||||
// Added ifndef because VS2013 warns for macro redefinition.
|
||||
#define snprintf(buf, len, fmt, ...) _snprintf(buf, len, fmt, __VA_ARGS__)
|
||||
#endif
|
||||
#define sleep(sec) Sleep((sec) * 1000)
|
||||
|
||||
#include <fcntl.h>
|
||||
#else // _WIN32
|
||||
#include <unistd.h>
|
||||
#define __STDC_LIMIT_MACROS
|
||||
#include <inttypes.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#endif // _WIN32
|
||||
|
||||
//#include "disable_warnings.h"
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
#include "stdintmsc.h"
|
||||
// Don't bug me with strcpy() deprecation warnings
|
||||
#pragma warning(disable : 4996)
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#ifdef __OpenBSD__
|
||||
#define FOPEN64 fopen
|
||||
#define OPEN open
|
||||
#define FSEEK fseek
|
||||
#define FTELL ftell
|
||||
#define LSEEK lseek
|
||||
#define FSTAT fstat
|
||||
#else
|
||||
#ifdef _WIN32
|
||||
#define OPEN _open
|
||||
// 64 bit file functions
|
||||
#if defined(_MSC_VER)
|
||||
#define FSEEK _fseeki64
|
||||
#define FTELL _ftelli64
|
||||
#else
|
||||
// For MinGW
|
||||
#define FSEEK fseeko64
|
||||
#define FTELL ftello64
|
||||
#endif
|
||||
#define TELL _telli64
|
||||
#define LSEEK _lseeki64
|
||||
typedef struct _stati64 FSTATSTRUCT;
|
||||
#else
|
||||
// Linux internally maps these functions to 64bit usage,
|
||||
// if _FILE_OFFSET_BITS macro is set to 64
|
||||
#define FOPEN64 fopen
|
||||
#define OPEN open
|
||||
#define LSEEK lseek
|
||||
#define FSEEK fseek
|
||||
#define FTELL ftell
|
||||
#define FSTAT fstat
|
||||
#define TELL tell
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef int64_t_C
|
||||
#define int64_t_C(c) (c ## LL)
|
||||
#define uint64_t_C(c) (c ## ULL)
|
||||
#endif
|
||||
|
||||
#ifndef O_BINARY
|
||||
#define O_BINARY 0 // Not present in Linux because it's always binary
|
||||
#endif
|
||||
|
||||
#ifndef max
|
||||
#define max(a,b) (((a) > (b)) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
typedef int64_t LLONG;
|
||||
typedef uint64_t ULLONG;
|
||||
typedef uint8_t UBYTE;
|
||||
|
||||
#endif // CCX_PLATFORM_H
|
||||
|
||||
@@ -1105,17 +1105,21 @@ int process608(const unsigned char *data, int length, void *private_data, struct
|
||||
struct ccx_decoder_608_context *context;
|
||||
int i;
|
||||
|
||||
if (dec_ctx->current_field == 1)
|
||||
if (dec_ctx->current_field == 1 && (dec_ctx->extract == 1 || dec_ctx->extract == 12))
|
||||
{
|
||||
context = dec_ctx->context_cc608_field_1;
|
||||
}
|
||||
else if (dec_ctx->current_field == 2 && (dec_ctx->extract == 2 || dec_ctx->extract == 12))
|
||||
{
|
||||
context = dec_ctx->context_cc608_field_2;
|
||||
}
|
||||
else if (dec_ctx->current_field == 2 && dec_ctx->extract == 1)
|
||||
{
|
||||
context = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
context = dec_ctx->context_cc608_field_2;
|
||||
return -1;
|
||||
}
|
||||
if (context)
|
||||
{
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -28,55 +28,55 @@
|
||||
|
||||
#define CCX_DTVCC_NO_LAST_SEQUENCE -1
|
||||
|
||||
enum CCX_DTVCC_COMMANDS_C0_CODES
|
||||
enum DTVCC_COMMANDS_C0_CODES
|
||||
{
|
||||
CCX_DTVCC_C0_NUL = 0x00,
|
||||
CCX_DTVCC_C0_ETX = 0x03,
|
||||
CCX_DTVCC_C0_BS = 0x08,
|
||||
CCX_DTVCC_C0_FF = 0x0c,
|
||||
CCX_DTVCC_C0_CR = 0x0d,
|
||||
CCX_DTVCC_C0_HCR = 0x0e,
|
||||
CCX_DTVCC_C0_EXT1 = 0x10,
|
||||
CCX_DTVCC_C0_P16 = 0x18
|
||||
DTVCC_C0_NUL = 0x00,
|
||||
DTVCC_C0_ETX = 0x03,
|
||||
DTVCC_C0_BS = 0x08,
|
||||
DTVCC_C0_FF = 0x0c,
|
||||
DTVCC_C0_CR = 0x0d,
|
||||
DTVCC_C0_HCR = 0x0e,
|
||||
DTVCC_C0_EXT1 = 0x10,
|
||||
DTVCC_C0_P16 = 0x18
|
||||
};
|
||||
|
||||
enum CCX_DTVCC_COMMANDS_C1_CODES
|
||||
enum DTVCC_COMMANDS_C1_CODES
|
||||
{
|
||||
CCX_DTVCC_C1_CW0 = 0x80,
|
||||
CCX_DTVCC_C1_CW1 = 0x81,
|
||||
CCX_DTVCC_C1_CW2 = 0x82,
|
||||
CCX_DTVCC_C1_CW3 = 0x83,
|
||||
CCX_DTVCC_C1_CW4 = 0x84,
|
||||
CCX_DTVCC_C1_CW5 = 0x85,
|
||||
CCX_DTVCC_C1_CW6 = 0x86,
|
||||
CCX_DTVCC_C1_CW7 = 0x87,
|
||||
CCX_DTVCC_C1_CLW = 0x88,
|
||||
CCX_DTVCC_C1_DSW = 0x89,
|
||||
CCX_DTVCC_C1_HDW = 0x8A,
|
||||
CCX_DTVCC_C1_TGW = 0x8B,
|
||||
CCX_DTVCC_C1_DLW = 0x8C,
|
||||
CCX_DTVCC_C1_DLY = 0x8D,
|
||||
CCX_DTVCC_C1_DLC = 0x8E,
|
||||
CCX_DTVCC_C1_RST = 0x8F,
|
||||
CCX_DTVCC_C1_SPA = 0x90,
|
||||
CCX_DTVCC_C1_SPC = 0x91,
|
||||
CCX_DTVCC_C1_SPL = 0x92,
|
||||
CCX_DTVCC_C1_RSV93 = 0x93,
|
||||
CCX_DTVCC_C1_RSV94 = 0x94,
|
||||
CCX_DTVCC_C1_RSV95 = 0x95,
|
||||
CCX_DTVCC_C1_RSV96 = 0x96,
|
||||
CCX_DTVCC_C1_SWA = 0x97,
|
||||
CCX_DTVCC_C1_DF0 = 0x98,
|
||||
CCX_DTVCC_C1_DF1 = 0x99,
|
||||
CCX_DTVCC_C1_DF2 = 0x9A,
|
||||
CCX_DTVCC_C1_DF3 = 0x9B,
|
||||
CCX_DTVCC_C1_DF4 = 0x9C,
|
||||
CCX_DTVCC_C1_DF5 = 0x9D,
|
||||
CCX_DTVCC_C1_DF6 = 0x9E,
|
||||
CCX_DTVCC_C1_DF7 = 0x9F
|
||||
DTVCC_C1_CW0 = 0x80,
|
||||
DTVCC_C1_CW1 = 0x81,
|
||||
DTVCC_C1_CW2 = 0x82,
|
||||
DTVCC_C1_CW3 = 0x83,
|
||||
DTVCC_C1_CW4 = 0x84,
|
||||
DTVCC_C1_CW5 = 0x85,
|
||||
DTVCC_C1_CW6 = 0x86,
|
||||
DTVCC_C1_CW7 = 0x87,
|
||||
DTVCC_C1_CLW = 0x88,
|
||||
DTVCC_C1_DSW = 0x89,
|
||||
DTVCC_C1_HDW = 0x8A,
|
||||
DTVCC_C1_TGW = 0x8B,
|
||||
DTVCC_C1_DLW = 0x8C,
|
||||
DTVCC_C1_DLY = 0x8D,
|
||||
DTVCC_C1_DLC = 0x8E,
|
||||
DTVCC_C1_RST = 0x8F,
|
||||
DTVCC_C1_SPA = 0x90,
|
||||
DTVCC_C1_SPC = 0x91,
|
||||
DTVCC_C1_SPL = 0x92,
|
||||
DTVCC_C1_RSV93 = 0x93,
|
||||
DTVCC_C1_RSV94 = 0x94,
|
||||
DTVCC_C1_RSV95 = 0x95,
|
||||
DTVCC_C1_RSV96 = 0x96,
|
||||
DTVCC_C1_SWA = 0x97,
|
||||
DTVCC_C1_DF0 = 0x98,
|
||||
DTVCC_C1_DF1 = 0x99,
|
||||
DTVCC_C1_DF2 = 0x9A,
|
||||
DTVCC_C1_DF3 = 0x9B,
|
||||
DTVCC_C1_DF4 = 0x9C,
|
||||
DTVCC_C1_DF5 = 0x9D,
|
||||
DTVCC_C1_DF6 = 0x9E,
|
||||
DTVCC_C1_DF7 = 0x9F
|
||||
};
|
||||
|
||||
struct CCX_DTVCC_S_COMMANDS_C1
|
||||
struct DTVCC_S_COMMANDS_C1
|
||||
{
|
||||
int code;
|
||||
const char *name;
|
||||
@@ -84,142 +84,142 @@ struct CCX_DTVCC_S_COMMANDS_C1
|
||||
int length;
|
||||
};
|
||||
|
||||
enum ccx_dtvcc_window_justify
|
||||
enum dtvcc_window_justify
|
||||
{
|
||||
CCX_DTVCC_WINDOW_JUSTIFY_LEFT = 0,
|
||||
CCX_DTVCC_WINDOW_JUSTIFY_RIGHT = 1,
|
||||
CCX_DTVCC_WINDOW_JUSTIFY_CENTER = 2,
|
||||
CCX_DTVCC_WINDOW_JUSTIFY_FULL = 3
|
||||
DTVCC_WINDOW_JUSTIFY_LEFT = 0,
|
||||
DTVCC_WINDOW_JUSTIFY_RIGHT = 1,
|
||||
DTVCC_WINDOW_JUSTIFY_CENTER = 2,
|
||||
DTVCC_WINDOW_JUSTIFY_FULL = 3
|
||||
};
|
||||
|
||||
enum ccx_dtvcc_window_pd //Print Direction
|
||||
enum dtvcc_window_pd //Print Direction
|
||||
{
|
||||
CCX_DTVCC_WINDOW_PD_LEFT_RIGHT = 0, //left -> right
|
||||
CCX_DTVCC_WINDOW_PD_RIGHT_LEFT = 1,
|
||||
CCX_DTVCC_WINDOW_PD_TOP_BOTTOM = 2,
|
||||
CCX_DTVCC_WINDOW_PD_BOTTOM_TOP = 3
|
||||
DTVCC_WINDOW_PD_LEFT_RIGHT = 0, //left -> right
|
||||
DTVCC_WINDOW_PD_RIGHT_LEFT = 1,
|
||||
DTVCC_WINDOW_PD_TOP_BOTTOM = 2,
|
||||
DTVCC_WINDOW_PD_BOTTOM_TOP = 3
|
||||
};
|
||||
|
||||
enum ccx_dtvcc_window_sd //Scroll Direction
|
||||
enum dtvcc_window_sd //Scroll Direction
|
||||
{
|
||||
CCX_DTVCC_WINDOW_SD_LEFT_RIGHT = 0,
|
||||
CCX_DTVCC_WINDOW_SD_RIGHT_LEFT = 1,
|
||||
CCX_DTVCC_WINDOW_SD_TOP_BOTTOM = 2,
|
||||
CCX_DTVCC_WINDOW_SD_BOTTOM_TOP = 3
|
||||
DTVCC_WINDOW_SD_LEFT_RIGHT = 0,
|
||||
DTVCC_WINDOW_SD_RIGHT_LEFT = 1,
|
||||
DTVCC_WINDOW_SD_TOP_BOTTOM = 2,
|
||||
DTVCC_WINDOW_SD_BOTTOM_TOP = 3
|
||||
};
|
||||
|
||||
enum ccx_dtvcc_window_sde //Scroll Display Effect
|
||||
enum dtvcc_window_sde //Scroll Display Effect
|
||||
{
|
||||
CCX_DTVCC_WINDOW_SDE_SNAP = 0,
|
||||
CCX_DTVCC_WINDOW_SDE_FADE = 1,
|
||||
CCX_DTVCC_WINDOW_SDE_WIPE = 2
|
||||
DTVCC_WINDOW_SDE_SNAP = 0,
|
||||
DTVCC_WINDOW_SDE_FADE = 1,
|
||||
DTVCC_WINDOW_SDE_WIPE = 2
|
||||
};
|
||||
|
||||
enum ccx_dtvcc_window_ed //Effect Direction
|
||||
enum dtvcc_window_ed //Effect Direction
|
||||
{
|
||||
CCX_DTVCC_WINDOW_ED_LEFT_RIGHT = 0,
|
||||
CCX_DTVCC_WINDOW_ED_RIGHT_LEFT = 1,
|
||||
CCX_DTVCC_WINDOW_ED_TOP_BOTTOM = 2,
|
||||
CCX_DTVCC_WINDOW_ED_BOTTOM_TOP = 3
|
||||
DTVCC_WINDOW_ED_LEFT_RIGHT = 0,
|
||||
DTVCC_WINDOW_ED_RIGHT_LEFT = 1,
|
||||
DTVCC_WINDOW_ED_TOP_BOTTOM = 2,
|
||||
DTVCC_WINDOW_ED_BOTTOM_TOP = 3
|
||||
};
|
||||
|
||||
enum ccx_dtvcc_window_fo //Fill Opacity
|
||||
enum dtvcc_window_fo //Fill Opacity
|
||||
{
|
||||
CCX_DTVCC_WINDOW_FO_SOLID = 0,
|
||||
CCX_DTVCC_WINDOW_FO_FLASH = 1,
|
||||
CCX_DTVCC_WINDOW_FO_TRANSLUCENT = 2,
|
||||
CCX_DTVCC_WINDOW_FO_TRANSPARENT = 3
|
||||
DTVCC_WINDOW_FO_SOLID = 0,
|
||||
DTVCC_WINDOW_FO_FLASH = 1,
|
||||
DTVCC_WINDOW_FO_TRANSLUCENT = 2,
|
||||
DTVCC_WINDOW_FO_TRANSPARENT = 3
|
||||
};
|
||||
|
||||
enum ccx_dtvcc_window_border
|
||||
enum dtvcc_window_border
|
||||
{
|
||||
CCX_DTVCC_WINDOW_BORDER_NONE = 0,
|
||||
CCX_DTVCC_WINDOW_BORDER_RAISED = 1,
|
||||
CCX_DTVCC_WINDOW_BORDER_DEPRESSED = 2,
|
||||
CCX_DTVCC_WINDOW_BORDER_UNIFORM = 3,
|
||||
CCX_DTVCC_WINDOW_BORDER_SHADOW_LEFT = 4,
|
||||
CCX_DTVCC_WINDOW_BORDER_SHADOW_RIGHT = 5
|
||||
DTVCC_WINDOW_BORDER_NONE = 0,
|
||||
DTVCC_WINDOW_BORDER_RAISED = 1,
|
||||
DTVCC_WINDOW_BORDER_DEPRESSED = 2,
|
||||
DTVCC_WINDOW_BORDER_UNIFORM = 3,
|
||||
DTVCC_WINDOW_BORDER_SHADOW_LEFT = 4,
|
||||
DTVCC_WINDOW_BORDER_SHADOW_RIGHT = 5
|
||||
};
|
||||
|
||||
enum ccx_dtvcc_pen_size
|
||||
enum dtvcc_pen_size
|
||||
{
|
||||
CCX_DTVCC_PEN_SIZE_SMALL = 0,
|
||||
CCX_DTVCC_PEN_SIZE_STANDART = 1,
|
||||
CCX_DTVCC_PEN_SIZE_LARGE = 2
|
||||
DTVCC_PEN_SIZE_SMALL = 0,
|
||||
DTVCC_PEN_SIZE_STANDART = 1,
|
||||
DTVCC_PEN_SIZE_LARGE = 2
|
||||
};
|
||||
|
||||
enum ccx_dtvcc_pen_font_style
|
||||
enum dtvcc_pen_font_style
|
||||
{
|
||||
CCX_DTVCC_PEN_FONT_STYLE_DEFAULT_OR_UNDEFINED = 0,
|
||||
CCX_DTVCC_PEN_FONT_STYLE_MONOSPACED_WITH_SERIFS = 1,
|
||||
CCX_DTVCC_PEN_FONT_STYLE_PROPORTIONALLY_SPACED_WITH_SERIFS = 2,
|
||||
CCX_DTVCC_PEN_FONT_STYLE_MONOSPACED_WITHOUT_SERIFS = 3,
|
||||
CCX_DTVCC_PEN_FONT_STYLE_PROPORTIONALLY_SPACED_WITHOUT_SERIFS = 4,
|
||||
CCX_DTVCC_PEN_FONT_STYLE_CASUAL_FONT_TYPE = 5,
|
||||
CCX_DTVCC_PEN_FONT_STYLE_CURSIVE_FONT_TYPE = 6,
|
||||
CCX_DTVCC_PEN_FONT_STYLE_SMALL_CAPITALS = 7
|
||||
DTVCC_PEN_FONT_STYLE_DEFAULT_OR_UNDEFINED = 0,
|
||||
DTVCC_PEN_FONT_STYLE_MONOSPACED_WITH_SERIFS = 1,
|
||||
DTVCC_PEN_FONT_STYLE_PROPORTIONALLY_SPACED_WITH_SERIFS = 2,
|
||||
DTVCC_PEN_FONT_STYLE_MONOSPACED_WITHOUT_SERIFS = 3,
|
||||
DTVCC_PEN_FONT_STYLE_PROPORTIONALLY_SPACED_WITHOUT_SERIFS = 4,
|
||||
DTVCC_PEN_FONT_STYLE_CASUAL_FONT_TYPE = 5,
|
||||
DTVCC_PEN_FONT_STYLE_CURSIVE_FONT_TYPE = 6,
|
||||
DTVCC_PEN_FONT_STYLE_SMALL_CAPITALS = 7
|
||||
};
|
||||
|
||||
enum ccx_dtvcc_pen_text_tag
|
||||
enum dtvcc_pen_text_tag
|
||||
{
|
||||
CCX_DTVCC_PEN_TEXT_TAG_DIALOG = 0,
|
||||
CCX_DTVCC_PEN_TEXT_TAG_SOURCE_OR_SPEAKER_ID = 1,
|
||||
CCX_DTVCC_PEN_TEXT_TAG_ELECTRONIC_VOICE = 2,
|
||||
CCX_DTVCC_PEN_TEXT_TAG_FOREIGN_LANGUAGE = 3,
|
||||
CCX_DTVCC_PEN_TEXT_TAG_VOICEOVER = 4,
|
||||
CCX_DTVCC_PEN_TEXT_TAG_AUDIBLE_TRANSLATION = 5,
|
||||
CCX_DTVCC_PEN_TEXT_TAG_SUBTITLE_TRANSLATION = 6,
|
||||
CCX_DTVCC_PEN_TEXT_TAG_VOICE_QUALITY_DESCRIPTION = 7,
|
||||
CCX_DTVCC_PEN_TEXT_TAG_SONG_LYRICS = 8,
|
||||
CCX_DTVCC_PEN_TEXT_TAG_SOUND_EFFECT_DESCRIPTION = 9,
|
||||
CCX_DTVCC_PEN_TEXT_TAG_MUSICAL_SCORE_DESCRIPTION = 10,
|
||||
CCX_DTVCC_PEN_TEXT_TAG_EXPLETIVE = 11,
|
||||
CCX_DTVCC_PEN_TEXT_TAG_UNDEFINED_12 = 12,
|
||||
CCX_DTVCC_PEN_TEXT_TAG_UNDEFINED_13 = 13,
|
||||
CCX_DTVCC_PEN_TEXT_TAG_UNDEFINED_14 = 14,
|
||||
CCX_DTVCC_PEN_TEXT_TAG_NOT_TO_BE_DISPLAYED = 15
|
||||
DTVCC_PEN_TEXT_TAG_DIALOG = 0,
|
||||
DTVCC_PEN_TEXT_TAG_SOURCE_OR_SPEAKER_ID = 1,
|
||||
DTVCC_PEN_TEXT_TAG_ELECTRONIC_VOICE = 2,
|
||||
DTVCC_PEN_TEXT_TAG_FOREIGN_LANGUAGE = 3,
|
||||
DTVCC_PEN_TEXT_TAG_VOICEOVER = 4,
|
||||
DTVCC_PEN_TEXT_TAG_AUDIBLE_TRANSLATION = 5,
|
||||
DTVCC_PEN_TEXT_TAG_SUBTITLE_TRANSLATION = 6,
|
||||
DTVCC_PEN_TEXT_TAG_VOICE_QUALITY_DESCRIPTION = 7,
|
||||
DTVCC_PEN_TEXT_TAG_SONG_LYRICS = 8,
|
||||
DTVCC_PEN_TEXT_TAG_SOUND_EFFECT_DESCRIPTION = 9,
|
||||
DTVCC_PEN_TEXT_TAG_MUSICAL_SCORE_DESCRIPTION = 10,
|
||||
DTVCC_PEN_TEXT_TAG_EXPLETIVE = 11,
|
||||
DTVCC_PEN_TEXT_TAG_UNDEFINED_12 = 12,
|
||||
DTVCC_PEN_TEXT_TAG_UNDEFINED_13 = 13,
|
||||
DTVCC_PEN_TEXT_TAG_UNDEFINED_14 = 14,
|
||||
DTVCC_PEN_TEXT_TAG_NOT_TO_BE_DISPLAYED = 15
|
||||
};
|
||||
|
||||
enum ccx_dtvcc_pen_offset
|
||||
enum dtvcc_pen_offset
|
||||
{
|
||||
CCX_DTVCC_PEN_OFFSET_SUBSCRIPT = 0,
|
||||
CCX_DTVCC_PEN_OFFSET_NORMAL = 1,
|
||||
CCX_DTVCC_PEN_OFFSET_SUPERSCRIPT = 2
|
||||
DTVCC_PEN_OFFSET_SUBSCRIPT = 0,
|
||||
DTVCC_PEN_OFFSET_NORMAL = 1,
|
||||
DTVCC_PEN_OFFSET_SUPERSCRIPT = 2
|
||||
};
|
||||
|
||||
enum ccx_dtvcc_pen_edge
|
||||
enum dtvcc_pen_edge
|
||||
{
|
||||
CCX_DTVCC_PEN_EDGE_NONE = 0,
|
||||
CCX_DTVCC_PEN_EDGE_RAISED = 1,
|
||||
CCX_DTVCC_PEN_EDGE_DEPRESSED = 2,
|
||||
CCX_DTVCC_PEN_EDGE_UNIFORM = 3,
|
||||
CCX_DTVCC_PEN_EDGE_LEFT_DROP_SHADOW = 4,
|
||||
CCX_DTVCC_PEN_EDGE_RIGHT_DROP_SHADOW = 5
|
||||
DTVCC_PEN_EDGE_NONE = 0,
|
||||
DTVCC_PEN_EDGE_RAISED = 1,
|
||||
DTVCC_PEN_EDGE_DEPRESSED = 2,
|
||||
DTVCC_PEN_EDGE_UNIFORM = 3,
|
||||
DTVCC_PEN_EDGE_LEFT_DROP_SHADOW = 4,
|
||||
DTVCC_PEN_EDGE_RIGHT_DROP_SHADOW = 5
|
||||
};
|
||||
|
||||
enum ccx_dtvcc_pen_anchor_point
|
||||
enum dtvcc_pen_anchor_point
|
||||
{
|
||||
CCX_DTVCC_ANCHOR_POINT_TOP_LEFT = 0,
|
||||
CCX_DTVCC_ANCHOR_POINT_TOP_CENTER = 1,
|
||||
CCX_DTVCC_ANCHOR_POINT_TOP_RIGHT = 2,
|
||||
CCX_DTVCC_ANCHOR_POINT_MIDDLE_LEFT = 3,
|
||||
CCX_DTVCC_ANCHOR_POINT_MIDDLE_CENTER = 4,
|
||||
CCX_DTVCC_ANCHOR_POINT_MIDDLE_RIGHT = 5,
|
||||
CCX_DTVCC_ANCHOR_POINT_BOTTOM_LEFT = 6,
|
||||
CCX_DTVCC_ANCHOR_POINT_BOTTOM_CENTER = 7,
|
||||
CCX_DTVCC_ANCHOR_POINT_BOTTOM_RIGHT = 8
|
||||
DTVCC_ANCHOR_POINT_TOP_LEFT = 0,
|
||||
DTVCC_ANCHOR_POINT_TOP_CENTER = 1,
|
||||
DTVCC_ANCHOR_POINT_TOP_RIGHT = 2,
|
||||
DTVCC_ANCHOR_POINT_MIDDLE_LEFT = 3,
|
||||
DTVCC_ANCHOR_POINT_MIDDLE_CENTER = 4,
|
||||
DTVCC_ANCHOR_POINT_MIDDLE_RIGHT = 5,
|
||||
DTVCC_ANCHOR_POINT_BOTTOM_LEFT = 6,
|
||||
DTVCC_ANCHOR_POINT_BOTTOM_CENTER = 7,
|
||||
DTVCC_ANCHOR_POINT_BOTTOM_RIGHT = 8
|
||||
};
|
||||
|
||||
typedef struct ccx_dtvcc_pen_color
|
||||
typedef struct dtvcc_pen_color
|
||||
{
|
||||
int fg_color;
|
||||
int fg_opacity;
|
||||
int bg_color;
|
||||
int bg_opacity;
|
||||
int edge_color;
|
||||
} ccx_dtvcc_pen_color;
|
||||
} dtvcc_pen_color;
|
||||
|
||||
typedef struct ccx_dtvcc_pen_attribs
|
||||
typedef struct dtvcc_pen_attribs
|
||||
{
|
||||
int pen_size;
|
||||
int offset;
|
||||
@@ -228,9 +228,9 @@ typedef struct ccx_dtvcc_pen_attribs
|
||||
int edge_type;
|
||||
int underline;
|
||||
int italic;
|
||||
} ccx_dtvcc_pen_attribs;
|
||||
} dtvcc_pen_attribs;
|
||||
|
||||
typedef struct ccx_dtvcc_window_attribs
|
||||
typedef struct dtvcc_window_attribs
|
||||
{
|
||||
int justify;
|
||||
int print_direction;
|
||||
@@ -243,18 +243,18 @@ typedef struct ccx_dtvcc_window_attribs
|
||||
int fill_opacity;
|
||||
int border_type;
|
||||
int border_color;
|
||||
} ccx_dtvcc_window_attribs;
|
||||
} dtvcc_window_attribs;
|
||||
|
||||
/**
|
||||
* Since 1-byte and 2-byte symbols could appear in captions and
|
||||
* since we have to keep symbols alignment and several windows could appear on a screen at one time,
|
||||
* we use special structure for holding symbols
|
||||
*/
|
||||
typedef struct ccx_dtvcc_symbol
|
||||
typedef struct dtvcc_symbol
|
||||
{
|
||||
unsigned short sym; //symbol itself, at least 16 bit
|
||||
unsigned char init; //initialized or not. could be 0 or 1
|
||||
} ccx_dtvcc_symbol;
|
||||
} dtvcc_symbol;
|
||||
|
||||
#define CCX_DTVCC_SYM_SET(x, c) {x.init = 1; x.sym = c;}
|
||||
#define CCX_DTVCC_SYM_SET_16(x, c1, c2) {x.init = 1; x.sym = (c1 << 8) | c2;}
|
||||
@@ -262,7 +262,7 @@ typedef struct ccx_dtvcc_symbol
|
||||
#define CCX_DTVCC_SYM_IS_EMPTY(x) (x.init == 0)
|
||||
#define CCX_DTVCC_SYM_IS_SET(x) (x.init == 1)
|
||||
|
||||
typedef struct ccx_dtvcc_window
|
||||
typedef struct dtvcc_window
|
||||
{
|
||||
int is_defined;
|
||||
int number;
|
||||
@@ -279,25 +279,25 @@ typedef struct ccx_dtvcc_window
|
||||
int pen_style;
|
||||
int win_style;
|
||||
unsigned char commands[6]; // Commands used to create this window
|
||||
ccx_dtvcc_window_attribs attribs;
|
||||
dtvcc_window_attribs attribs;
|
||||
int pen_row;
|
||||
int pen_column;
|
||||
ccx_dtvcc_symbol *rows[CCX_DTVCC_MAX_ROWS];
|
||||
ccx_dtvcc_pen_color pen_colors[CCX_DTVCC_MAX_ROWS][CCX_DTVCC_SCREENGRID_COLUMNS];
|
||||
ccx_dtvcc_pen_attribs pen_attribs[CCX_DTVCC_MAX_ROWS][CCX_DTVCC_SCREENGRID_COLUMNS];
|
||||
ccx_dtvcc_pen_color pen_color_pattern;
|
||||
ccx_dtvcc_pen_attribs pen_attribs_pattern;
|
||||
dtvcc_symbol *rows[CCX_DTVCC_MAX_ROWS];
|
||||
dtvcc_pen_color pen_colors[CCX_DTVCC_MAX_ROWS][CCX_DTVCC_SCREENGRID_COLUMNS];
|
||||
dtvcc_pen_attribs pen_attribs[CCX_DTVCC_MAX_ROWS][CCX_DTVCC_SCREENGRID_COLUMNS];
|
||||
dtvcc_pen_color pen_color_pattern;
|
||||
dtvcc_pen_attribs pen_attribs_pattern;
|
||||
int memory_reserved;
|
||||
int is_empty;
|
||||
LLONG time_ms_show;
|
||||
LLONG time_ms_hide;
|
||||
} ccx_dtvcc_window;
|
||||
} dtvcc_window;
|
||||
|
||||
typedef struct dtvcc_tv_screen
|
||||
{
|
||||
ccx_dtvcc_symbol chars[CCX_DTVCC_SCREENGRID_ROWS][CCX_DTVCC_SCREENGRID_COLUMNS];
|
||||
ccx_dtvcc_pen_color pen_colors[CCX_DTVCC_SCREENGRID_ROWS][CCX_DTVCC_SCREENGRID_COLUMNS];
|
||||
ccx_dtvcc_pen_attribs pen_attribs[CCX_DTVCC_SCREENGRID_ROWS][CCX_DTVCC_SCREENGRID_COLUMNS];
|
||||
dtvcc_symbol chars[CCX_DTVCC_SCREENGRID_ROWS][CCX_DTVCC_SCREENGRID_COLUMNS];
|
||||
dtvcc_pen_color pen_colors[CCX_DTVCC_SCREENGRID_ROWS][CCX_DTVCC_SCREENGRID_COLUMNS];
|
||||
dtvcc_pen_attribs pen_attribs[CCX_DTVCC_SCREENGRID_ROWS][CCX_DTVCC_SCREENGRID_COLUMNS];
|
||||
LLONG time_ms_show;
|
||||
LLONG time_ms_hide;
|
||||
unsigned int cc_count;
|
||||
@@ -314,13 +314,13 @@ typedef struct ccx_decoder_dtvcc_report
|
||||
unsigned services[CCX_DTVCC_MAX_SERVICES];
|
||||
} ccx_decoder_dtvcc_report;
|
||||
|
||||
typedef struct ccx_dtvcc_service_decoder
|
||||
typedef struct dtvcc_service_decoder
|
||||
{
|
||||
ccx_dtvcc_window windows[CCX_DTVCC_MAX_WINDOWS];
|
||||
dtvcc_window windows[CCX_DTVCC_MAX_WINDOWS];
|
||||
int current_window;
|
||||
dtvcc_tv_screen *tv;
|
||||
int cc_count;
|
||||
} ccx_dtvcc_service_decoder;
|
||||
} dtvcc_service_decoder;
|
||||
|
||||
typedef struct ccx_decoder_dtvcc_settings
|
||||
{
|
||||
@@ -339,7 +339,7 @@ typedef struct ccx_decoder_dtvcc_settings
|
||||
* decoders have to know nothing about output files
|
||||
*/
|
||||
|
||||
typedef struct ccx_dtvcc_ctx
|
||||
typedef struct dtvcc_ctx
|
||||
{
|
||||
int is_active;
|
||||
int active_services_count;
|
||||
@@ -348,7 +348,7 @@ typedef struct ccx_dtvcc_ctx
|
||||
|
||||
ccx_decoder_dtvcc_report *report;
|
||||
|
||||
ccx_dtvcc_service_decoder decoders[CCX_DTVCC_MAX_SERVICES];
|
||||
dtvcc_service_decoder decoders[CCX_DTVCC_MAX_SERVICES];
|
||||
|
||||
unsigned char current_packet[CCX_DTVCC_MAX_PACKET_LENGTH];
|
||||
int current_packet_length;
|
||||
@@ -359,20 +359,84 @@ typedef struct ccx_dtvcc_ctx
|
||||
void *encoder; //we can't include header, so keeping it this way
|
||||
int no_rollup;
|
||||
struct ccx_common_timing_ctx *timing;
|
||||
} ccx_dtvcc_ctx;
|
||||
} dtvcc_ctx;
|
||||
|
||||
|
||||
void ccx_dtvcc_clear_packet(ccx_dtvcc_ctx *ctx);
|
||||
void ccx_dtvcc_windows_reset(ccx_dtvcc_service_decoder *decoder);
|
||||
void ccx_dtvcc_decoder_flush(ccx_dtvcc_ctx *dtvcc, ccx_dtvcc_service_decoder *decoder);
|
||||
void dtvcc_clear_packet(dtvcc_ctx *ctx);
|
||||
void dtvcc_windows_reset(dtvcc_service_decoder *decoder);
|
||||
void dtvcc_decoder_flush(dtvcc_ctx *dtvcc, dtvcc_service_decoder *decoder);
|
||||
|
||||
void ccx_dtvcc_process_current_packet(ccx_dtvcc_ctx *dtvcc, int len);
|
||||
void ccx_dtvcc_process_service_block(ccx_dtvcc_ctx *dtvcc,
|
||||
ccx_dtvcc_service_decoder *decoder,
|
||||
void dtvcc_process_current_packet(dtvcc_ctx *dtvcc, int len);
|
||||
void dtvcc_process_service_block(dtvcc_ctx *dtvcc,
|
||||
dtvcc_service_decoder *decoder,
|
||||
unsigned char *data,
|
||||
int data_length);
|
||||
|
||||
extern ccx_dtvcc_pen_color ccx_dtvcc_default_pen_color;
|
||||
extern ccx_dtvcc_pen_attribs ccx_dtvcc_default_pen_attribs;
|
||||
void dtvcc_tv_clear(dtvcc_service_decoder *decoder);
|
||||
int dtvcc_decoder_has_visible_windows(dtvcc_service_decoder *decoder);
|
||||
void dtvcc_window_clear_row(dtvcc_window *window, int row_index);
|
||||
void dtvcc_window_clear_text(dtvcc_window *window);
|
||||
void dtvcc_window_clear(dtvcc_service_decoder *decoder, int window_id);
|
||||
void dtvcc_window_apply_style(dtvcc_window *window, dtvcc_window_attribs *style);
|
||||
|
||||
#ifdef DTVCC_PRINT_DEBUG
|
||||
int dtvcc_is_win_row_empty(dtvcc_window *window, int row_index);
|
||||
void dtvcc_get_win_write_interval(dtvcc_window *window, int row_index, int *first, int *last);
|
||||
void dtvcc_window_dump(dtvcc_service_decoder *decoder, dtvcc_window *window);
|
||||
#endif
|
||||
|
||||
void dtvcc_decoders_reset(dtvcc_ctx *dtvcc);
|
||||
int dtvcc_compare_win_priorities(const void *a, const void *b);
|
||||
void dtvcc_window_update_time_show(dtvcc_window *window, struct ccx_common_timing_ctx *timing);
|
||||
void dtvcc_window_update_time_hide(dtvcc_window *window, struct ccx_common_timing_ctx *timing);
|
||||
void dtvcc_screen_update_time_show(dtvcc_tv_screen *tv, LLONG time);
|
||||
void dtvcc_screen_update_time_hide(dtvcc_tv_screen *tv, LLONG time);
|
||||
void dtvcc_get_window_dimensions(dtvcc_window *window, int *x1, int *x2, int *y1, int *y2);
|
||||
int dtvcc_is_window_overlapping(dtvcc_service_decoder *decoder, dtvcc_window *window);
|
||||
void dtvcc_window_copy_to_screen(dtvcc_service_decoder *decoder, dtvcc_window *window);
|
||||
void dtvcc_screen_print(dtvcc_ctx *dtvcc, dtvcc_service_decoder *decoder);
|
||||
void dtvcc_process_hcr(dtvcc_service_decoder *decoder);
|
||||
void dtvcc_process_ff(dtvcc_service_decoder *decoder);
|
||||
void dtvcc_process_etx(dtvcc_service_decoder *decoder);
|
||||
void dtvcc_process_bs(dtvcc_service_decoder *decoder);
|
||||
void dtvcc_window_rollup(dtvcc_service_decoder *decoder, dtvcc_window *window);
|
||||
void dtvcc_process_cr(dtvcc_ctx *dtvcc, dtvcc_service_decoder *decoder);
|
||||
void dtvcc_process_character(dtvcc_service_decoder *decoder, dtvcc_symbol symbol);
|
||||
void dtvcc_handle_CWx_SetCurrentWindow(dtvcc_service_decoder *decoder, int window_id);
|
||||
void dtvcc_handle_CLW_ClearWindows(dtvcc_ctx *dtvcc, dtvcc_service_decoder *decoder, int windows_bitmap);
|
||||
void dtvcc_handle_DSW_DisplayWindows(dtvcc_service_decoder *decoder, int windows_bitmap, struct ccx_common_timing_ctx *timing);
|
||||
void dtvcc_handle_HDW_HideWindows(dtvcc_ctx *dtvcc,dtvcc_service_decoder *decoder,
|
||||
int windows_bitmap);
|
||||
void dtvcc_handle_TGW_ToggleWindows(dtvcc_ctx *dtvcc,
|
||||
dtvcc_service_decoder *decoder,
|
||||
int windows_bitmap);
|
||||
void dtvcc_handle_DFx_DefineWindow(dtvcc_service_decoder *decoder, int window_id, unsigned char *data, struct ccx_common_timing_ctx *timing);
|
||||
void dtvcc_handle_SWA_SetWindowAttributes(dtvcc_service_decoder *decoder, unsigned char *data);
|
||||
void dtvcc_handle_DLW_DeleteWindows(dtvcc_ctx *dtvcc,
|
||||
dtvcc_service_decoder *decoder,
|
||||
int windows_bitmap);
|
||||
void dtvcc_handle_SPA_SetPenAttributes(dtvcc_service_decoder *decoder, unsigned char *data);
|
||||
void dtvcc_handle_SPC_SetPenColor(dtvcc_service_decoder *decoder, unsigned char *data);
|
||||
void dtvcc_handle_SPL_SetPenLocation(dtvcc_service_decoder *decoder, unsigned char *data);
|
||||
void dtvcc_handle_RST_Reset(dtvcc_service_decoder *decoder);
|
||||
void dtvcc_handle_DLY_Delay(dtvcc_service_decoder *decoder, int tenths_of_sec);
|
||||
void dtvcc_handle_DLC_DelayCancel(dtvcc_service_decoder *decoder);
|
||||
void dtvcc_handle_C0_P16(dtvcc_service_decoder *decoder, unsigned char *data);
|
||||
int dtvcc_handle_G0(dtvcc_service_decoder *decoder, unsigned char *data, int data_length);
|
||||
int dtvcc_handle_G1(dtvcc_service_decoder *decoder, unsigned char *data, int data_length);
|
||||
int dtvcc_handle_C0(dtvcc_ctx *dtvcc,
|
||||
dtvcc_service_decoder *decoder,
|
||||
unsigned char *data,
|
||||
int data_length);
|
||||
int dtvcc_handle_C1(dtvcc_ctx *dtvcc,
|
||||
dtvcc_service_decoder *decoder,
|
||||
unsigned char *data,
|
||||
int data_length);
|
||||
int dtvcc_handle_C2(dtvcc_service_decoder *decoder, unsigned char *data, int data_length);
|
||||
int dtvcc_handle_C3(dtvcc_service_decoder *decoder, unsigned char *data, int data_length);
|
||||
int dtvcc_handle_extended_char(dtvcc_service_decoder *decoder, unsigned char *data, int data_length);
|
||||
|
||||
extern dtvcc_pen_color dtvcc_default_pen_color;
|
||||
extern dtvcc_pen_attribs dtvcc_default_pen_attribs;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -4,7 +4,11 @@
|
||||
#include "utility.h"
|
||||
#include "ccx_common_common.h"
|
||||
|
||||
int _dtvcc_is_row_empty(dtvcc_tv_screen *tv, int row_index)
|
||||
#if !defined(DISABLE_RUST) && defined(WIN32)
|
||||
extern void ccxr_close_handle(void *handle);
|
||||
#endif
|
||||
|
||||
int dtvcc_is_row_empty(dtvcc_tv_screen *tv, int row_index)
|
||||
{
|
||||
for (int j = 0; j < CCX_DTVCC_SCREENGRID_COLUMNS; j++)
|
||||
{
|
||||
@@ -14,11 +18,11 @@ int _dtvcc_is_row_empty(dtvcc_tv_screen *tv, int row_index)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int _dtvcc_is_screen_empty(dtvcc_tv_screen *tv, struct encoder_ctx *encoder)
|
||||
int dtvcc_is_screen_empty(dtvcc_tv_screen *tv, struct encoder_ctx *encoder)
|
||||
{
|
||||
for (int i = 0; i < CCX_DTVCC_SCREENGRID_ROWS; i++)
|
||||
{
|
||||
if (!_dtvcc_is_row_empty(tv, i))
|
||||
if (!dtvcc_is_row_empty(tv, i))
|
||||
{
|
||||
// we will write subtitle
|
||||
encoder->cea_708_counter++;
|
||||
@@ -28,7 +32,7 @@ int _dtvcc_is_screen_empty(dtvcc_tv_screen *tv, struct encoder_ctx *encoder)
|
||||
return 1;
|
||||
}
|
||||
|
||||
void _dtvcc_get_write_interval(dtvcc_tv_screen *tv, int row_index, int *first, int *last)
|
||||
void dtvcc_get_write_interval(dtvcc_tv_screen *tv, int row_index, int *first, int *last)
|
||||
{
|
||||
for (*first = 0; *first < CCX_DTVCC_SCREENGRID_COLUMNS; (*first)++)
|
||||
if (CCX_DTVCC_SYM_IS_SET(tv->chars[row_index][*first]))
|
||||
@@ -38,7 +42,7 @@ void _dtvcc_get_write_interval(dtvcc_tv_screen *tv, int row_index, int *first, i
|
||||
break;
|
||||
}
|
||||
|
||||
void _dtvcc_color_to_hex(int color, unsigned *hR, unsigned *hG, unsigned *hB)
|
||||
void dtvcc_color_to_hex(int color, unsigned *hR, unsigned *hG, unsigned *hB)
|
||||
{
|
||||
*hR = (unsigned)(color >> 4);
|
||||
*hG = (unsigned)((color >> 2) & 0x3);
|
||||
@@ -47,16 +51,16 @@ void _dtvcc_color_to_hex(int color, unsigned *hR, unsigned *hG, unsigned *hB)
|
||||
color, color, *hR, *hG, *hB);
|
||||
}
|
||||
|
||||
void _dtvcc_change_pen_colors(dtvcc_tv_screen *tv, ccx_dtvcc_pen_color pen_color, int row_index, int column_index, struct encoder_ctx *encoder, size_t *buf_len, int open)
|
||||
void dtvcc_change_pen_colors(dtvcc_tv_screen *tv, dtvcc_pen_color pen_color, int row_index, int column_index, struct encoder_ctx *encoder, size_t *buf_len, int open)
|
||||
{
|
||||
if (encoder->no_font_color)
|
||||
return;
|
||||
|
||||
char *buf = (char *)encoder->buffer;
|
||||
|
||||
ccx_dtvcc_pen_color new_pen_color;
|
||||
dtvcc_pen_color new_pen_color;
|
||||
if (column_index >= CCX_DTVCC_SCREENGRID_COLUMNS)
|
||||
new_pen_color = ccx_dtvcc_default_pen_color;
|
||||
new_pen_color = dtvcc_default_pen_color;
|
||||
else
|
||||
new_pen_color = tv->pen_colors[row_index][column_index];
|
||||
if (pen_color.fg_color != new_pen_color.fg_color)
|
||||
@@ -67,7 +71,7 @@ void _dtvcc_change_pen_colors(dtvcc_tv_screen *tv, ccx_dtvcc_pen_color pen_color
|
||||
if (new_pen_color.fg_color != 0x3f && open)
|
||||
{
|
||||
unsigned red, green, blue;
|
||||
_dtvcc_color_to_hex(new_pen_color.fg_color, &red, &green, &blue);
|
||||
dtvcc_color_to_hex(new_pen_color.fg_color, &red, &green, &blue);
|
||||
red = (255 / 3) * red;
|
||||
green = (255 / 3) * green;
|
||||
blue = (255 / 3) * blue;
|
||||
@@ -76,16 +80,16 @@ void _dtvcc_change_pen_colors(dtvcc_tv_screen *tv, ccx_dtvcc_pen_color pen_color
|
||||
}
|
||||
}
|
||||
|
||||
void _dtvcc_change_pen_attribs(dtvcc_tv_screen *tv, ccx_dtvcc_pen_attribs pen_attribs, int row_index, int column_index, struct encoder_ctx *encoder, size_t *buf_len, int open)
|
||||
void dtvcc_change_pen_attribs(dtvcc_tv_screen *tv, dtvcc_pen_attribs pen_attribs, int row_index, int column_index, struct encoder_ctx *encoder, size_t *buf_len, int open)
|
||||
{
|
||||
if (encoder->no_font_color)
|
||||
return;
|
||||
|
||||
char *buf = (char *)encoder->buffer;
|
||||
|
||||
ccx_dtvcc_pen_attribs new_pen_attribs;
|
||||
dtvcc_pen_attribs new_pen_attribs;
|
||||
if (column_index >= CCX_DTVCC_SCREENGRID_COLUMNS)
|
||||
new_pen_attribs = ccx_dtvcc_default_pen_attribs;
|
||||
new_pen_attribs = dtvcc_default_pen_attribs;
|
||||
else
|
||||
new_pen_attribs = tv->pen_attribs[row_index][column_index];
|
||||
if (pen_attribs.italic != new_pen_attribs.italic)
|
||||
@@ -119,7 +123,7 @@ size_t write_utf16_char(unsigned short utf16_char, char *out)
|
||||
}
|
||||
}
|
||||
|
||||
void _dtvcc_write_row(ccx_dtvcc_writer_ctx *writer, ccx_dtvcc_service_decoder *decoder, int row_index, struct encoder_ctx *encoder, int use_colors)
|
||||
void dtvcc_write_row(dtvcc_writer_ctx *writer, dtvcc_service_decoder *decoder, int row_index, struct encoder_ctx *encoder, int use_colors)
|
||||
{
|
||||
dtvcc_tv_screen *tv = decoder->tv;
|
||||
char *buf = (char *)encoder->buffer;
|
||||
@@ -129,19 +133,19 @@ void _dtvcc_write_row(ccx_dtvcc_writer_ctx *writer, ccx_dtvcc_service_decoder *d
|
||||
|
||||
int fd = encoder->dtvcc_writers[tv->service_number - 1].fd;
|
||||
|
||||
ccx_dtvcc_pen_color pen_color = ccx_dtvcc_default_pen_color;
|
||||
ccx_dtvcc_pen_attribs pen_attribs = ccx_dtvcc_default_pen_attribs;
|
||||
_dtvcc_get_write_interval(tv, row_index, &first, &last);
|
||||
dtvcc_pen_color pen_color = dtvcc_default_pen_color;
|
||||
dtvcc_pen_attribs pen_attribs = dtvcc_default_pen_attribs;
|
||||
dtvcc_get_write_interval(tv, row_index, &first, &last);
|
||||
|
||||
for (int i = 0; i < last + 1; i++)
|
||||
{
|
||||
|
||||
if (use_colors)
|
||||
_dtvcc_change_pen_colors(tv, pen_color, row_index, i, encoder, &buf_len, 0);
|
||||
_dtvcc_change_pen_attribs(tv, pen_attribs, row_index, i, encoder, &buf_len, 0);
|
||||
_dtvcc_change_pen_attribs(tv, pen_attribs, row_index, i, encoder, &buf_len, 1);
|
||||
dtvcc_change_pen_colors(tv, pen_color, row_index, i, encoder, &buf_len, 0);
|
||||
dtvcc_change_pen_attribs(tv, pen_attribs, row_index, i, encoder, &buf_len, 0);
|
||||
dtvcc_change_pen_attribs(tv, pen_attribs, row_index, i, encoder, &buf_len, 1);
|
||||
if (use_colors)
|
||||
_dtvcc_change_pen_colors(tv, pen_color, row_index, i, encoder, &buf_len, 1);
|
||||
dtvcc_change_pen_colors(tv, pen_color, row_index, i, encoder, &buf_len, 1);
|
||||
|
||||
pen_color = tv->pen_colors[row_index][i];
|
||||
pen_attribs = tv->pen_attribs[row_index][i];
|
||||
@@ -159,8 +163,8 @@ void _dtvcc_write_row(ccx_dtvcc_writer_ctx *writer, ccx_dtvcc_service_decoder *d
|
||||
|
||||
// there can be unclosed tags or colors after the last symbol in a row
|
||||
if (use_colors)
|
||||
_dtvcc_change_pen_colors(tv, pen_color, row_index, CCX_DTVCC_SCREENGRID_COLUMNS, encoder, &buf_len, 0);
|
||||
_dtvcc_change_pen_attribs(tv, pen_attribs, row_index, CCX_DTVCC_SCREENGRID_COLUMNS, encoder, &buf_len, 0);
|
||||
dtvcc_change_pen_colors(tv, pen_color, row_index, CCX_DTVCC_SCREENGRID_COLUMNS, encoder, &buf_len, 0);
|
||||
dtvcc_change_pen_attribs(tv, pen_attribs, row_index, CCX_DTVCC_SCREENGRID_COLUMNS, encoder, &buf_len, 0);
|
||||
// Tags can still be crossed e.g <f><i>text</f></i>, but testing HTML code has shown that they still are handled correctly.
|
||||
// In case of errors fix it once and for all.
|
||||
|
||||
@@ -168,7 +172,7 @@ void _dtvcc_write_row(ccx_dtvcc_writer_ctx *writer, ccx_dtvcc_service_decoder *d
|
||||
{
|
||||
char *encoded_buf = calloc(INITIAL_ENC_BUFFER_CAPACITY, sizeof(char));
|
||||
if (!encoded_buf)
|
||||
ccx_common_logging.fatal_ftn(EXIT_NOT_ENOUGH_MEMORY, "_dtvcc_write_row");
|
||||
ccx_common_logging.fatal_ftn(EXIT_NOT_ENOUGH_MEMORY, "dtvcc_write_row");
|
||||
|
||||
char *encoded_buf_start = encoded_buf;
|
||||
|
||||
@@ -178,7 +182,7 @@ void _dtvcc_write_row(ccx_dtvcc_writer_ctx *writer, ccx_dtvcc_service_decoder *d
|
||||
size_t result = iconv(writer->cd, &buf, &in_bytes_left, &encoded_buf, &out_bytes_left);
|
||||
|
||||
if (result == -1)
|
||||
ccx_common_logging.log_ftn("[CEA-708] _dtvcc_write_row: "
|
||||
ccx_common_logging.log_ftn("[CEA-708] dtvcc_write_row: "
|
||||
"conversion failed: %s\n",
|
||||
strerror(errno));
|
||||
|
||||
@@ -192,10 +196,10 @@ void _dtvcc_write_row(ccx_dtvcc_writer_ctx *writer, ccx_dtvcc_service_decoder *d
|
||||
}
|
||||
}
|
||||
|
||||
void ccx_dtvcc_write_srt(ccx_dtvcc_writer_ctx *writer, ccx_dtvcc_service_decoder *decoder, struct encoder_ctx *encoder)
|
||||
void dtvcc_write_srt(dtvcc_writer_ctx *writer, dtvcc_service_decoder *decoder, struct encoder_ctx *encoder)
|
||||
{
|
||||
dtvcc_tv_screen *tv = decoder->tv;
|
||||
if (_dtvcc_is_screen_empty(tv, encoder))
|
||||
if (dtvcc_is_screen_empty(tv, encoder))
|
||||
return;
|
||||
|
||||
if (tv->time_ms_show + encoder->subs_delay < 0)
|
||||
@@ -216,9 +220,9 @@ void ccx_dtvcc_write_srt(ccx_dtvcc_writer_ctx *writer, ccx_dtvcc_service_decoder
|
||||
|
||||
for (int i = 0; i < CCX_DTVCC_SCREENGRID_ROWS; i++)
|
||||
{
|
||||
if (!_dtvcc_is_row_empty(tv, i))
|
||||
if (!dtvcc_is_row_empty(tv, i))
|
||||
{
|
||||
_dtvcc_write_row(writer, decoder, i, encoder, 1);
|
||||
dtvcc_write_row(writer, decoder, i, encoder, 1);
|
||||
write_wrapped(encoder->dtvcc_writers[tv->service_number - 1].fd,
|
||||
encoder->encoded_crlf, encoder->encoded_crlf_length);
|
||||
}
|
||||
@@ -227,7 +231,7 @@ void ccx_dtvcc_write_srt(ccx_dtvcc_writer_ctx *writer, ccx_dtvcc_service_decoder
|
||||
encoder->encoded_crlf, encoder->encoded_crlf_length);
|
||||
}
|
||||
|
||||
void ccx_dtvcc_write_debug(dtvcc_tv_screen *tv)
|
||||
void dtvcc_write_debug(dtvcc_tv_screen *tv)
|
||||
{
|
||||
char tbuf1[SUBLINESIZE],
|
||||
tbuf2[SUBLINESIZE];
|
||||
@@ -238,10 +242,10 @@ void ccx_dtvcc_write_debug(dtvcc_tv_screen *tv)
|
||||
ccx_common_logging.debug_ftn(CCX_DMT_GENERIC_NOTICES, "\r%s --> %s\n", tbuf1, tbuf2);
|
||||
for (int i = 0; i < CCX_DTVCC_SCREENGRID_ROWS; i++)
|
||||
{
|
||||
if (!_dtvcc_is_row_empty(tv, i))
|
||||
if (!dtvcc_is_row_empty(tv, i))
|
||||
{
|
||||
int first, last;
|
||||
_dtvcc_get_write_interval(tv, i, &first, &last);
|
||||
dtvcc_get_write_interval(tv, i, &first, &last);
|
||||
for (int j = first; j <= last; j++)
|
||||
ccx_common_logging.debug_ftn(CCX_DMT_GENERIC_NOTICES, "%c", tv->chars[i][j]);
|
||||
ccx_common_logging.debug_ftn(CCX_DMT_GENERIC_NOTICES, "\n");
|
||||
@@ -249,10 +253,10 @@ void ccx_dtvcc_write_debug(dtvcc_tv_screen *tv)
|
||||
}
|
||||
}
|
||||
|
||||
void ccx_dtvcc_write_transcript(ccx_dtvcc_writer_ctx *writer, ccx_dtvcc_service_decoder *decoder, struct encoder_ctx *encoder)
|
||||
void dtvcc_write_transcript(dtvcc_writer_ctx *writer, dtvcc_service_decoder *decoder, struct encoder_ctx *encoder)
|
||||
{
|
||||
dtvcc_tv_screen *tv = decoder->tv;
|
||||
if (_dtvcc_is_screen_empty(tv, encoder))
|
||||
if (dtvcc_is_screen_empty(tv, encoder))
|
||||
return;
|
||||
|
||||
if (tv->time_ms_show + encoder->subs_delay < 0) // Drop screens that because of subs_delay start too early
|
||||
@@ -262,7 +266,7 @@ void ccx_dtvcc_write_transcript(ccx_dtvcc_writer_ctx *writer, ccx_dtvcc_service_
|
||||
|
||||
for (int i = 0; i < CCX_DTVCC_SCREENGRID_ROWS; i++)
|
||||
{
|
||||
if (!_dtvcc_is_row_empty(tv, i))
|
||||
if (!dtvcc_is_row_empty(tv, i))
|
||||
{
|
||||
buf[0] = 0;
|
||||
|
||||
@@ -284,14 +288,14 @@ void ccx_dtvcc_write_transcript(ccx_dtvcc_writer_ctx *writer, ccx_dtvcc_service_
|
||||
if (buf_len != 0)
|
||||
write_wrapped(encoder->dtvcc_writers[tv->service_number - 1].fd, buf, buf_len);
|
||||
|
||||
_dtvcc_write_row(writer, decoder, i, encoder, 0);
|
||||
dtvcc_write_row(writer, decoder, i, encoder, 0);
|
||||
write_wrapped(encoder->dtvcc_writers[tv->service_number - 1].fd,
|
||||
encoder->encoded_crlf, encoder->encoded_crlf_length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void _dtvcc_write_sami_header(dtvcc_tv_screen *tv, struct encoder_ctx *encoder)
|
||||
void dtvcc_write_sami_header(dtvcc_tv_screen *tv, struct encoder_ctx *encoder)
|
||||
{
|
||||
char *buf = (char *)encoder->buffer;
|
||||
memset(buf, 0, INITIAL_ENC_BUFFER_CAPACITY);
|
||||
@@ -316,7 +320,7 @@ void _dtvcc_write_sami_header(dtvcc_tv_screen *tv, struct encoder_ctx *encoder)
|
||||
write_wrapped(encoder->dtvcc_writers[tv->service_number - 1].fd, buf, buf_len);
|
||||
}
|
||||
|
||||
void _dtvcc_write_sami_footer(dtvcc_tv_screen *tv, struct encoder_ctx *encoder)
|
||||
void dtvcc_write_sami_footer(dtvcc_tv_screen *tv, struct encoder_ctx *encoder)
|
||||
{
|
||||
char *buf = (char *)encoder->buffer;
|
||||
sprintf(buf, "</body></sami>");
|
||||
@@ -325,17 +329,17 @@ void _dtvcc_write_sami_footer(dtvcc_tv_screen *tv, struct encoder_ctx *encoder)
|
||||
encoder->encoded_crlf, encoder->encoded_crlf_length);
|
||||
}
|
||||
|
||||
void ccx_dtvcc_write_sami(ccx_dtvcc_writer_ctx *writer, ccx_dtvcc_service_decoder *decoder, struct encoder_ctx *encoder)
|
||||
void dtvcc_write_sami(dtvcc_writer_ctx *writer, dtvcc_service_decoder *decoder, struct encoder_ctx *encoder)
|
||||
{
|
||||
dtvcc_tv_screen *tv = decoder->tv;
|
||||
if (_dtvcc_is_screen_empty(tv, encoder))
|
||||
if (dtvcc_is_screen_empty(tv, encoder))
|
||||
return;
|
||||
|
||||
if (tv->time_ms_show + encoder->subs_delay < 0)
|
||||
return;
|
||||
|
||||
if (tv->cc_count == 1)
|
||||
_dtvcc_write_sami_header(tv, encoder);
|
||||
dtvcc_write_sami_header(tv, encoder);
|
||||
|
||||
char *buf = (char *)encoder->buffer;
|
||||
|
||||
@@ -347,9 +351,9 @@ void ccx_dtvcc_write_sami(ccx_dtvcc_writer_ctx *writer, ccx_dtvcc_service_decode
|
||||
|
||||
for (int i = 0; i < CCX_DTVCC_SCREENGRID_ROWS; i++)
|
||||
{
|
||||
if (!_dtvcc_is_row_empty(tv, i))
|
||||
if (!dtvcc_is_row_empty(tv, i))
|
||||
{
|
||||
_dtvcc_write_row(writer, decoder, i, encoder, 1);
|
||||
dtvcc_write_row(writer, decoder, i, encoder, 1);
|
||||
write_wrapped(encoder->dtvcc_writers[tv->service_number - 1].fd,
|
||||
encoder->encoded_br, encoder->encoded_br_length);
|
||||
write_wrapped(encoder->dtvcc_writers[tv->service_number - 1].fd,
|
||||
@@ -363,52 +367,52 @@ void ccx_dtvcc_write_sami(ccx_dtvcc_writer_ctx *writer, ccx_dtvcc_service_decode
|
||||
write_wrapped(encoder->dtvcc_writers[tv->service_number - 1].fd, buf, strlen(buf));
|
||||
}
|
||||
|
||||
void _ccx_dtvcc_write(ccx_dtvcc_writer_ctx *writer, ccx_dtvcc_service_decoder *decoder, struct encoder_ctx *encoder)
|
||||
void dtvcc_write(dtvcc_writer_ctx *writer, dtvcc_service_decoder *decoder, struct encoder_ctx *encoder)
|
||||
{
|
||||
switch (encoder->write_format)
|
||||
{
|
||||
case CCX_OF_NULL:
|
||||
break;
|
||||
case CCX_OF_SRT:
|
||||
ccx_dtvcc_write_srt(writer, decoder, encoder);
|
||||
dtvcc_write_srt(writer, decoder, encoder);
|
||||
break;
|
||||
case CCX_OF_TRANSCRIPT:
|
||||
ccx_dtvcc_write_transcript(writer, decoder, encoder);
|
||||
dtvcc_write_transcript(writer, decoder, encoder);
|
||||
break;
|
||||
case CCX_OF_SAMI:
|
||||
ccx_dtvcc_write_sami(writer, decoder, encoder);
|
||||
dtvcc_write_sami(writer, decoder, encoder);
|
||||
break;
|
||||
case CCX_OF_MCC:
|
||||
printf("REALLY BAD... [%s:%d]\n", __FILE__, __LINE__);
|
||||
break;
|
||||
default:
|
||||
ccx_dtvcc_write_debug(decoder->tv);
|
||||
dtvcc_write_debug(decoder->tv);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ccx_dtvcc_write_done(dtvcc_tv_screen *tv, struct encoder_ctx *encoder)
|
||||
void dtvcc_write_done(dtvcc_tv_screen *tv, struct encoder_ctx *encoder)
|
||||
{
|
||||
switch (encoder->write_format)
|
||||
{
|
||||
case CCX_OF_SAMI:
|
||||
_dtvcc_write_sami_footer(tv, encoder);
|
||||
dtvcc_write_sami_footer(tv, encoder);
|
||||
break;
|
||||
default:
|
||||
ccx_common_logging.debug_ftn(
|
||||
CCX_DMT_708, "[CEA-708] ccx_dtvcc_write_done: no handling required\n");
|
||||
CCX_DMT_708, "[CEA-708] dtvcc_write_done: no handling required\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ccx_dtvcc_writer_init(ccx_dtvcc_writer_ctx *writer,
|
||||
char *base_filename,
|
||||
int program_number,
|
||||
int service_number,
|
||||
enum ccx_output_format write_format,
|
||||
struct encoder_cfg *cfg)
|
||||
void dtvcc_writer_init(dtvcc_writer_ctx *writer,
|
||||
char *base_filename,
|
||||
int program_number,
|
||||
int service_number,
|
||||
enum ccx_output_format write_format,
|
||||
struct encoder_cfg *cfg)
|
||||
{
|
||||
ccx_common_logging.debug_ftn(CCX_DMT_708, "[CEA-708] ccx_dtvcc_writer_init\n");
|
||||
ccx_common_logging.debug_ftn(CCX_DMT_708, "[CEA-708] dtvcc_writer_init\n");
|
||||
writer->fd = -1;
|
||||
writer->cd = (iconv_t)-1;
|
||||
if ((write_format == CCX_OF_NULL) || (write_format == CCX_OF_MCC))
|
||||
@@ -417,7 +421,7 @@ void ccx_dtvcc_writer_init(ccx_dtvcc_writer_ctx *writer,
|
||||
return;
|
||||
}
|
||||
|
||||
ccx_common_logging.debug_ftn(CCX_DMT_708, "[CEA-708] ccx_dtvcc_writer_init: "
|
||||
ccx_common_logging.debug_ftn(CCX_DMT_708, "[CEA-708] dtvcc_writer_init: "
|
||||
"[%s][%d][%d]\n",
|
||||
base_filename, program_number, service_number);
|
||||
|
||||
@@ -428,12 +432,17 @@ void ccx_dtvcc_writer_init(ccx_dtvcc_writer_ctx *writer,
|
||||
writer->filename = create_outfilename(base_filename, suffix, ext);
|
||||
if (!writer->filename)
|
||||
ccx_common_logging.fatal_ftn(
|
||||
EXIT_NOT_ENOUGH_MEMORY, "[CEA-708] _dtvcc_decoder_init_write: not enough memory");
|
||||
EXIT_NOT_ENOUGH_MEMORY, "[CEA-708] dtvcc_decoder_init_write: not enough memory");
|
||||
|
||||
ccx_common_logging.debug_ftn(CCX_DMT_708, "[CEA-708] ccx_dtvcc_writer_init: inited [%s]\n", writer->filename);
|
||||
ccx_common_logging.debug_ftn(CCX_DMT_708, "[CEA-708] dtvcc_writer_init: inited [%s]\n", writer->filename);
|
||||
|
||||
char *charset = cfg->all_services_charset ? cfg->all_services_charset : cfg->services_charsets[service_number - 1];
|
||||
|
||||
#ifndef DISABLE_RUST
|
||||
writer->fhandle = NULL;
|
||||
writer->charset = charset;
|
||||
#endif
|
||||
|
||||
if (charset)
|
||||
{
|
||||
writer->cd = iconv_open("UTF-8", charset);
|
||||
@@ -446,10 +455,14 @@ void ccx_dtvcc_writer_init(ccx_dtvcc_writer_ctx *writer,
|
||||
}
|
||||
}
|
||||
|
||||
void ccx_dtvcc_writer_cleanup(ccx_dtvcc_writer_ctx *writer)
|
||||
void dtvcc_writer_cleanup(dtvcc_writer_ctx *writer)
|
||||
{
|
||||
if (writer->fd >= 0 && writer->fd != STDOUT_FILENO)
|
||||
close(writer->fd);
|
||||
#if !defined(DISABLE_RUST) && defined(WIN32)
|
||||
ccxr_close_handle(writer->fhandle);
|
||||
writer->charset = NULL;
|
||||
#endif
|
||||
free(writer->filename);
|
||||
if (writer->cd == (iconv_t)-1)
|
||||
{
|
||||
@@ -459,9 +472,9 @@ void ccx_dtvcc_writer_cleanup(ccx_dtvcc_writer_ctx *writer)
|
||||
iconv_close(writer->cd);
|
||||
}
|
||||
|
||||
void ccx_dtvcc_writer_output(ccx_dtvcc_writer_ctx *writer, ccx_dtvcc_service_decoder *decoder, struct encoder_ctx *encoder)
|
||||
void dtvcc_writer_output(dtvcc_writer_ctx *writer, dtvcc_service_decoder *decoder, struct encoder_ctx *encoder)
|
||||
{
|
||||
ccx_common_logging.debug_ftn(CCX_DMT_708, "[CEA-708] ccx_dtvcc_writer_output: "
|
||||
ccx_common_logging.debug_ftn(CCX_DMT_708, "[CEA-708] dtvcc_writer_output: "
|
||||
"writing... [%s][%d]\n",
|
||||
writer->filename, writer->fd);
|
||||
|
||||
@@ -471,7 +484,7 @@ void ccx_dtvcc_writer_output(ccx_dtvcc_writer_ctx *writer, ccx_dtvcc_service_dec
|
||||
if (writer->filename && writer->fd < 0) //first request to write
|
||||
{
|
||||
ccx_common_logging.debug_ftn(CCX_DMT_708, "[CEA-708] "
|
||||
"ccx_dtvcc_writer_output: creating %s\n",
|
||||
"dtvcc_writer_output: creating %s\n",
|
||||
writer->filename);
|
||||
writer->fd = open(writer->filename, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, S_IREAD | S_IWRITE);
|
||||
if (writer->fd == -1)
|
||||
@@ -483,5 +496,5 @@ void ccx_dtvcc_writer_output(ccx_dtvcc_writer_ctx *writer, ccx_dtvcc_service_dec
|
||||
write_wrapped(writer->fd, UTF8_BOM, sizeof(UTF8_BOM));
|
||||
}
|
||||
|
||||
_ccx_dtvcc_write(writer, decoder, encoder);
|
||||
dtvcc_write(writer, decoder, encoder);
|
||||
}
|
||||
|
||||
@@ -5,15 +5,31 @@
|
||||
#include "ccx_encoders_common.h"
|
||||
#include "ccx_common_option.h"
|
||||
|
||||
void ccx_dtvcc_write_done(dtvcc_tv_screen *tv, struct encoder_ctx *encoder);
|
||||
void dtvcc_write_done(dtvcc_tv_screen *tv, struct encoder_ctx *encoder);
|
||||
|
||||
void ccx_dtvcc_writer_init(ccx_dtvcc_writer_ctx *writer,
|
||||
void dtvcc_writer_init(dtvcc_writer_ctx *writer,
|
||||
char *base_filename,
|
||||
int program_number,
|
||||
int service_number,
|
||||
enum ccx_output_format write_format,
|
||||
struct encoder_cfg *cfg);
|
||||
void ccx_dtvcc_writer_cleanup(ccx_dtvcc_writer_ctx *writer);
|
||||
void ccx_dtvcc_writer_output(ccx_dtvcc_writer_ctx *writer, ccx_dtvcc_service_decoder *decoder, struct encoder_ctx *encoder);
|
||||
void dtvcc_writer_cleanup(dtvcc_writer_ctx *writer);
|
||||
void dtvcc_writer_output(dtvcc_writer_ctx *writer, dtvcc_service_decoder *decoder, struct encoder_ctx *encoder);
|
||||
|
||||
int dtvcc_is_row_empty(dtvcc_tv_screen *tv, int row_index);
|
||||
int dtvcc_is_screen_empty(dtvcc_tv_screen *tv, struct encoder_ctx *encoder);
|
||||
void dtvcc_get_write_interval(dtvcc_tv_screen *tv, int row_index, int *first, int *last);
|
||||
void dtvcc_color_to_hex(int color, unsigned *hR, unsigned *hG, unsigned *hB);
|
||||
void dtvcc_change_pen_colors(dtvcc_tv_screen *tv, dtvcc_pen_color pen_color, int row_index, int column_index, struct encoder_ctx *encoder, size_t *buf_len, int open);
|
||||
void dtvcc_change_pen_attribs(dtvcc_tv_screen *tv, dtvcc_pen_attribs pen_attribs, int row_index, int column_index, struct encoder_ctx *encoder, size_t *buf_len, int open);
|
||||
size_t write_utf16_char(unsigned short utf16_char, char *out);
|
||||
void dtvcc_write_row(dtvcc_writer_ctx *writer, dtvcc_service_decoder *decoder, int row_index, struct encoder_ctx *encoder, int use_colors);
|
||||
void dtvcc_write_srt(dtvcc_writer_ctx *writer, dtvcc_service_decoder *decoder, struct encoder_ctx *encoder);
|
||||
void dtvcc_write_debug(dtvcc_tv_screen *tv);
|
||||
void dtvcc_write_transcript(dtvcc_writer_ctx *writer, dtvcc_service_decoder *decoder, struct encoder_ctx *encoder);
|
||||
void dtvcc_write_sami_header(dtvcc_tv_screen *tv, struct encoder_ctx *encoder);
|
||||
void dtvcc_write_sami_footer(dtvcc_tv_screen *tv, struct encoder_ctx *encoder);
|
||||
void dtvcc_write_sami(dtvcc_writer_ctx *writer, dtvcc_service_decoder *decoder, struct encoder_ctx *encoder);
|
||||
void dtvcc_write(dtvcc_writer_ctx *writer, dtvcc_service_decoder *decoder, struct encoder_ctx *encoder);
|
||||
|
||||
#endif /*_CCX_DECODERS_708_OUTPUT_H_*/
|
||||
@@ -15,6 +15,11 @@ made to reuse, not duplicate, as many functions as possible */
|
||||
#include "ccx_encoders_mcc.h"
|
||||
#include "ccx_dtvcc.h"
|
||||
|
||||
#ifndef DISABLE_RUST
|
||||
extern int ccxr_process_cc_data(struct lib_cc_decode *dec_ctx, unsigned char *cc_data, int cc_count);
|
||||
extern void ccxr_flush_decoder(struct dtvcc_ctx *dtvcc, struct dtvcc_service_decoder *decoder);
|
||||
#endif
|
||||
|
||||
uint64_t utc_refvalue = UINT64_MAX; /* _UI64_MAX/UINT64_MAX means don't use UNIX, 0 = use current system time as reference, +1 use a specific reference */
|
||||
extern int in_xds_mode;
|
||||
|
||||
@@ -49,6 +54,10 @@ int process_cc_data(struct encoder_ctx *enc_ctx, struct lib_cc_decode *dec_ctx,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef DISABLE_RUST
|
||||
ret = ccxr_process_cc_data(dec_ctx, cc_data, cc_count);
|
||||
#endif
|
||||
|
||||
for (int j = 0; j < cc_count * 3; j = j + 3)
|
||||
{
|
||||
if (validate_cc_data_pair(cc_data + j))
|
||||
@@ -187,15 +196,19 @@ int do_cb(struct lib_cc_decode *ctx, unsigned char *cc_block, struct cc_subtitle
|
||||
timeok = 0;
|
||||
ctx->processed_enough = 1;
|
||||
}
|
||||
char temp[4];
|
||||
temp[0] = cc_valid;
|
||||
temp[1] = cc_type;
|
||||
temp[2] = cc_block[1];
|
||||
temp[3] = cc_block[2];
|
||||
if (timeok)
|
||||
{
|
||||
if (ctx->write_format != CCX_OF_RCWT)
|
||||
ccx_dtvcc_process_data(ctx, (const unsigned char *)temp, 4);
|
||||
{
|
||||
#ifdef DISABLE_RUST
|
||||
char temp[4];
|
||||
temp[0] = cc_valid;
|
||||
temp[1] = cc_type;
|
||||
temp[2] = cc_block[1];
|
||||
temp[3] = cc_block[2];
|
||||
dtvcc_process_data(ctx->dtvcc, (const unsigned char *)temp);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
writercwtdata(ctx, cc_block, sub);
|
||||
}
|
||||
@@ -219,7 +232,7 @@ int do_cb(struct lib_cc_decode *ctx, unsigned char *cc_block, struct cc_subtitle
|
||||
void dinit_cc_decode(struct lib_cc_decode **ctx)
|
||||
{
|
||||
struct lib_cc_decode *lctx = *ctx;
|
||||
ccx_dtvcc_free(&lctx->dtvcc);
|
||||
dtvcc_free(&lctx->dtvcc);
|
||||
dinit_avc(&lctx->avc_ctx);
|
||||
ccx_decoder_608_dinit_library(&lctx->context_cc608_field_1);
|
||||
ccx_decoder_608_dinit_library(&lctx->context_cc608_field_2);
|
||||
@@ -248,7 +261,7 @@ struct lib_cc_decode *init_cc_decode(struct ccx_decoders_common_settings_t *sett
|
||||
ctx->no_rollup = setting->no_rollup;
|
||||
ctx->noscte20 = setting->noscte20;
|
||||
|
||||
ctx->dtvcc = ccx_dtvcc_init(setting->settings_dtvcc);
|
||||
ctx->dtvcc = dtvcc_init(setting->settings_dtvcc);
|
||||
ctx->dtvcc->is_active = setting->settings_dtvcc->enabled;
|
||||
|
||||
if (setting->codec == CCX_CODEC_ATSC_CC)
|
||||
@@ -432,13 +445,17 @@ void flush_cc_decode(struct lib_cc_decode *ctx, struct cc_subtitle *sub)
|
||||
{
|
||||
for (int i = 0; i < CCX_DTVCC_MAX_SERVICES; i++)
|
||||
{
|
||||
ccx_dtvcc_service_decoder *decoder = &ctx->dtvcc->decoders[i];
|
||||
dtvcc_service_decoder *decoder = &ctx->dtvcc->decoders[i];
|
||||
if (!ctx->dtvcc->services_active[i])
|
||||
continue;
|
||||
if (decoder->cc_count > 0)
|
||||
{
|
||||
ctx->current_field = 3;
|
||||
ccx_dtvcc_decoder_flush(ctx->dtvcc, decoder);
|
||||
#ifndef DISABLE_RUST
|
||||
ccxr_flush_decoder(ctx->dtvcc, decoder);
|
||||
#else
|
||||
dtvcc_decoder_flush(ctx->dtvcc, decoder);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -520,8 +537,8 @@ struct lib_cc_decode *copy_decoder_context(struct lib_cc_decode *ctx)
|
||||
ctx_copy->private_data = NULL;
|
||||
if (ctx->dtvcc)
|
||||
{
|
||||
ctx_copy->dtvcc = malloc(sizeof(struct ccx_dtvcc_ctx));
|
||||
memcpy(ctx_copy->dtvcc, ctx->dtvcc, sizeof(struct ccx_dtvcc_ctx));
|
||||
ctx_copy->dtvcc = malloc(sizeof(struct dtvcc_ctx));
|
||||
memcpy(ctx_copy->dtvcc, ctx->dtvcc, sizeof(struct dtvcc_ctx));
|
||||
}
|
||||
if (ctx->xds_ctx)
|
||||
{
|
||||
|
||||
@@ -208,7 +208,7 @@ struct lib_cc_decode
|
||||
int stat_divicom;
|
||||
int false_pict_header;
|
||||
|
||||
ccx_dtvcc_ctx *dtvcc;
|
||||
dtvcc_ctx *dtvcc;
|
||||
int current_field;
|
||||
// Analyse/use the picture information
|
||||
int maxtref; // Use to remember the temporal reference number
|
||||
|
||||
@@ -3,9 +3,8 @@
|
||||
#include "ccx_encoders_common.h"
|
||||
#include "ccx_decoders_708_output.h"
|
||||
|
||||
void ccx_dtvcc_process_data(struct lib_cc_decode *ctx,
|
||||
const unsigned char *data,
|
||||
int data_length)
|
||||
void dtvcc_process_data(struct dtvcc_ctx *dtvcc,
|
||||
const unsigned char *data)
|
||||
{
|
||||
/*
|
||||
* Note: the data has following format:
|
||||
@@ -14,78 +13,73 @@ void ccx_dtvcc_process_data(struct lib_cc_decode *ctx,
|
||||
* 2 bytes for the actual data
|
||||
*/
|
||||
|
||||
ccx_dtvcc_ctx *dtvcc = ctx->dtvcc;
|
||||
|
||||
if (!dtvcc->is_active && !dtvcc->report_enabled)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < data_length; i += 4)
|
||||
unsigned char cc_valid = data[0];
|
||||
unsigned char cc_type = data[1];
|
||||
|
||||
switch (cc_type)
|
||||
{
|
||||
unsigned char cc_valid = data[i];
|
||||
unsigned char cc_type = data[i + 1];
|
||||
|
||||
switch (cc_type)
|
||||
{
|
||||
case 2:
|
||||
ccx_common_logging.debug_ftn(CCX_DMT_708, "[CEA-708] dtvcc_process_data: DTVCC Channel Packet Data\n");
|
||||
if (cc_valid && dtvcc->is_current_packet_header_parsed)
|
||||
case 2:
|
||||
ccx_common_logging.debug_ftn(CCX_DMT_708, "[CEA-708] dtvcc_process_data: DTVCC Channel Packet Data\n");
|
||||
if (cc_valid && dtvcc->is_current_packet_header_parsed)
|
||||
{
|
||||
if (dtvcc->current_packet_length > 253)
|
||||
{
|
||||
if (dtvcc->current_packet_length > 253)
|
||||
{
|
||||
ccx_common_logging.debug_ftn(CCX_DMT_708, "[CEA-708] dtvcc_process_data: "
|
||||
"Warning: Legal packet size exceeded (1), data not added.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
dtvcc->current_packet[dtvcc->current_packet_length++] = data[i + 2];
|
||||
dtvcc->current_packet[dtvcc->current_packet_length++] = data[i + 3];
|
||||
int len = dtvcc->current_packet[0] & 0x3F; // 6 least significants bits
|
||||
|
||||
if (len == 0) // This is well defined in EIA-708; no magic.
|
||||
len = 128;
|
||||
else
|
||||
len = len * 2;
|
||||
// Note that len here is the length including the header
|
||||
|
||||
if (dtvcc->current_packet_length >= len)
|
||||
ccx_dtvcc_process_current_packet(dtvcc, len);
|
||||
}
|
||||
ccx_common_logging.debug_ftn(CCX_DMT_708, "[CEA-708] dtvcc_process_data: "
|
||||
"Warning: Legal packet size exceeded (1), data not added.\n");
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
ccx_common_logging.debug_ftn(CCX_DMT_708, "[CEA-708] dtvcc_process_data: DTVCC Channel Packet Start\n");
|
||||
if (cc_valid)
|
||||
else
|
||||
{
|
||||
if (dtvcc->current_packet_length > CCX_DTVCC_MAX_PACKET_LENGTH - 1)
|
||||
{
|
||||
ccx_common_logging.debug_ftn(CCX_DMT_708, "[CEA-708] dtvcc_process_data: "
|
||||
"Warning: Legal packet size exceeded (2), data not added.\n");
|
||||
}
|
||||
dtvcc->current_packet[dtvcc->current_packet_length++] = data[2];
|
||||
dtvcc->current_packet[dtvcc->current_packet_length++] = data[3];
|
||||
int len = dtvcc->current_packet[0] & 0x3F; // 6 least significants bits
|
||||
|
||||
if (len == 0) // This is well defined in EIA-708; no magic.
|
||||
len = 128;
|
||||
else
|
||||
{
|
||||
dtvcc->current_packet[dtvcc->current_packet_length++] = data[i + 2];
|
||||
dtvcc->current_packet[dtvcc->current_packet_length++] = data[i + 3];
|
||||
dtvcc->is_current_packet_header_parsed = 1;
|
||||
}
|
||||
len = len * 2;
|
||||
// Note that len here is the length including the header
|
||||
|
||||
if (dtvcc->current_packet_length >= len)
|
||||
dtvcc_process_current_packet(dtvcc, len);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ccx_common_logging.fatal_ftn(CCX_COMMON_EXIT_BUG_BUG, "[CEA-708] dtvcc_process_data: "
|
||||
"shouldn't be here - cc_type: %d\n",
|
||||
cc_type);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
ccx_common_logging.debug_ftn(CCX_DMT_708, "[CEA-708] dtvcc_process_data: DTVCC Channel Packet Start\n");
|
||||
if (cc_valid)
|
||||
{
|
||||
if (dtvcc->current_packet_length > CCX_DTVCC_MAX_PACKET_LENGTH - 1)
|
||||
{
|
||||
ccx_common_logging.debug_ftn(CCX_DMT_708, "[CEA-708] dtvcc_process_data: "
|
||||
"Warning: Legal packet size exceeded (2), data not added.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
dtvcc->current_packet[dtvcc->current_packet_length++] = data[2];
|
||||
dtvcc->current_packet[dtvcc->current_packet_length++] = data[3];
|
||||
dtvcc->is_current_packet_header_parsed = 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ccx_common_logging.fatal_ftn(CCX_COMMON_EXIT_BUG_BUG, "[CEA-708] dtvcc_process_data: "
|
||||
"shouldn't be here - cc_type: %d\n",
|
||||
cc_type);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
ccx_dtvcc_ctx *ccx_dtvcc_init(struct ccx_decoder_dtvcc_settings *opts)
|
||||
dtvcc_ctx *dtvcc_init(struct ccx_decoder_dtvcc_settings *opts)
|
||||
{
|
||||
ccx_common_logging.debug_ftn(CCX_DMT_708, "[CEA-708] initializing dtvcc decoder\n");
|
||||
ccx_dtvcc_ctx *ctx = (ccx_dtvcc_ctx *)malloc(sizeof(ccx_dtvcc_ctx));
|
||||
dtvcc_ctx *ctx = (dtvcc_ctx *)malloc(sizeof(dtvcc_ctx));
|
||||
if (!ctx)
|
||||
{
|
||||
ccx_common_logging.fatal_ftn(EXIT_NOT_ENOUGH_MEMORY, "[CEA-708] ccx_dtvcc_init");
|
||||
ccx_common_logging.fatal_ftn(EXIT_NOT_ENOUGH_MEMORY, "[CEA-708] dtvcc_init");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -98,7 +92,7 @@ ccx_dtvcc_ctx *ccx_dtvcc_init(struct ccx_decoder_dtvcc_settings *opts)
|
||||
|
||||
memcpy(ctx->services_active, opts->services_enabled, CCX_DTVCC_MAX_SERVICES * sizeof(int));
|
||||
|
||||
ccx_dtvcc_clear_packet(ctx);
|
||||
dtvcc_clear_packet(ctx);
|
||||
|
||||
ctx->last_sequence = CCX_DTVCC_NO_LAST_SEQUENCE;
|
||||
|
||||
@@ -112,35 +106,35 @@ ccx_dtvcc_ctx *ccx_dtvcc_init(struct ccx_decoder_dtvcc_settings *opts)
|
||||
if (!ctx->services_active[i])
|
||||
continue;
|
||||
|
||||
ccx_dtvcc_service_decoder *decoder = &ctx->decoders[i];
|
||||
dtvcc_service_decoder *decoder = &ctx->decoders[i];
|
||||
decoder->cc_count = 0;
|
||||
decoder->tv = (dtvcc_tv_screen *)malloc(sizeof(dtvcc_tv_screen));
|
||||
decoder->tv->service_number = i + 1;
|
||||
decoder->tv->cc_count = 0;
|
||||
if (!decoder->tv)
|
||||
ccx_common_logging.fatal_ftn(EXIT_NOT_ENOUGH_MEMORY, "ccx_dtvcc_init");
|
||||
ccx_common_logging.fatal_ftn(EXIT_NOT_ENOUGH_MEMORY, "dtvcc_init");
|
||||
|
||||
for (int j = 0; j < CCX_DTVCC_MAX_WINDOWS; j++)
|
||||
decoder->windows[j].memory_reserved = 0;
|
||||
|
||||
ccx_dtvcc_windows_reset(decoder);
|
||||
dtvcc_windows_reset(decoder);
|
||||
}
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
void ccx_dtvcc_free(ccx_dtvcc_ctx **ctx_ptr)
|
||||
void dtvcc_free(dtvcc_ctx **ctx_ptr)
|
||||
{
|
||||
ccx_common_logging.debug_ftn(CCX_DMT_708, "[CEA-708] dtvcc_free: cleaning up\n");
|
||||
|
||||
ccx_dtvcc_ctx *ctx = *ctx_ptr;
|
||||
dtvcc_ctx *ctx = *ctx_ptr;
|
||||
|
||||
for (int i = 0; i < CCX_DTVCC_MAX_SERVICES; i++)
|
||||
{
|
||||
if (!ctx->services_active[i])
|
||||
continue;
|
||||
|
||||
ccx_dtvcc_service_decoder *decoder = &ctx->decoders[i];
|
||||
dtvcc_service_decoder *decoder = &ctx->decoders[i];
|
||||
|
||||
for (int j = 0; j < CCX_DTVCC_MAX_WINDOWS; j++)
|
||||
if (decoder->windows[j].memory_reserved)
|
||||
|
||||
@@ -4,11 +4,10 @@
|
||||
#include "ccx_decoders_708.h"
|
||||
#include "ccx_common_option.h"
|
||||
|
||||
void ccx_dtvcc_process_data(struct lib_cc_decode *ctx,
|
||||
const unsigned char *data,
|
||||
int data_length);
|
||||
void dtvcc_process_data(struct dtvcc_ctx *dtvcc,
|
||||
const unsigned char *data);
|
||||
|
||||
ccx_dtvcc_ctx *ccx_dtvcc_init(ccx_decoder_dtvcc_settings *opts);
|
||||
void ccx_dtvcc_free(ccx_dtvcc_ctx **);
|
||||
dtvcc_ctx *dtvcc_init(ccx_decoder_dtvcc_settings *opts);
|
||||
void dtvcc_free(dtvcc_ctx **);
|
||||
|
||||
#endif //CCEXTRACTOR_CCX_DTVCC_H
|
||||
|
||||
@@ -764,7 +764,7 @@ static void dinit_output_ctx(struct encoder_ctx *ctx)
|
||||
if (ctx->dtvcc_extract)
|
||||
{
|
||||
for (i = 0; i < CCX_DTVCC_MAX_SERVICES; i++)
|
||||
ccx_dtvcc_writer_cleanup(&ctx->dtvcc_writers[i]);
|
||||
dtvcc_writer_cleanup(&ctx->dtvcc_writers[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -796,7 +796,7 @@ static int init_output_ctx(struct encoder_ctx *ctx, struct encoder_cfg *cfg)
|
||||
ctx->ucla = cfg->ucla;
|
||||
ctx->force_dropframe = cfg->force_dropframe;
|
||||
|
||||
if (ctx->generates_file && cfg->cc_to_stdout == CCX_FALSE && cfg->send_to_srv == CCX_FALSE)
|
||||
if (ctx->generates_file && cfg->cc_to_stdout == CCX_FALSE && cfg->send_to_srv == CCX_FALSE && cfg->extract_only_708 == CCX_FALSE)
|
||||
{
|
||||
if (cfg->output_filename != NULL)
|
||||
{
|
||||
@@ -869,6 +869,10 @@ static int init_output_ctx(struct encoder_ctx *ctx, struct encoder_cfg *cfg)
|
||||
if (!cfg->services_enabled[i])
|
||||
{
|
||||
ctx->dtvcc_writers[i].fd = -1;
|
||||
#ifndef DISABLE_RUST
|
||||
ctx->dtvcc_writers[i].fhandle = NULL;
|
||||
ctx->dtvcc_writers[i].charset = NULL;
|
||||
#endif
|
||||
ctx->dtvcc_writers[i].filename = NULL;
|
||||
ctx->dtvcc_writers[i].cd = (iconv_t)-1;
|
||||
continue;
|
||||
@@ -877,6 +881,10 @@ static int init_output_ctx(struct encoder_ctx *ctx, struct encoder_cfg *cfg)
|
||||
if (cfg->cc_to_stdout)
|
||||
{
|
||||
ctx->dtvcc_writers[i].fd = STDOUT_FILENO;
|
||||
#ifndef DISABLE_RUST
|
||||
ctx->dtvcc_writers[i].fhandle = NULL;
|
||||
ctx->dtvcc_writers[i].charset = NULL;
|
||||
#endif
|
||||
ctx->dtvcc_writers[i].filename = NULL;
|
||||
ctx->dtvcc_writers[i].cd = (iconv_t)-1;
|
||||
}
|
||||
@@ -888,8 +896,8 @@ static int init_output_ctx(struct encoder_ctx *ctx, struct encoder_cfg *cfg)
|
||||
else
|
||||
basefilename = get_basename(ctx->first_input_file);
|
||||
|
||||
ccx_dtvcc_writer_init(&ctx->dtvcc_writers[i], basefilename,
|
||||
ctx->program_number, i + 1, cfg->write_format, cfg);
|
||||
dtvcc_writer_init(&ctx->dtvcc_writers[i], basefilename,
|
||||
ctx->program_number, i + 1, cfg->write_format, cfg);
|
||||
free(basefilename);
|
||||
}
|
||||
}
|
||||
@@ -1096,11 +1104,6 @@ int encode_sub(struct encoder_ctx *context, struct cc_subtitle *sub)
|
||||
return wrote_something;
|
||||
}
|
||||
|
||||
sub->start_time += context->subs_delay;
|
||||
sub->end_time += context->subs_delay;
|
||||
if (sub->start_time < 0)
|
||||
return 0;
|
||||
|
||||
// Write subtitles as they come
|
||||
switch (sub->type)
|
||||
{
|
||||
@@ -1117,6 +1120,12 @@ int encode_sub(struct encoder_ctx *context, struct cc_subtitle *sub)
|
||||
data->end_time += context->subs_delay;
|
||||
data->start_time += context->subs_delay;
|
||||
|
||||
// After adding delay, if start/end time is lower than 0, then continue with the next subtitle
|
||||
if (data->start_time < 0 || data->end_time <= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (data->format == SFORMAT_XDS)
|
||||
{
|
||||
xds_write_transcript_line_prefix(context, out, data->start_time, data->end_time, data->cur_xds_packet_class);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#define _CC_ENCODER_COMMON_H
|
||||
|
||||
#ifdef WIN32
|
||||
#include "..\\win_iconv\\iconv.h"
|
||||
#include "..\\thirdparty\\win_iconv\\iconv.h"
|
||||
#else
|
||||
#include "iconv.h"
|
||||
#endif
|
||||
@@ -21,12 +21,18 @@ if (ctx->buffer == NULL) { fatal(EXIT_NOT_ENOUGH_MEMORY, "Not enough memory for
|
||||
#define ROWS 15
|
||||
#define COLUMNS 32
|
||||
|
||||
typedef struct ccx_dtvcc_writer_ctx
|
||||
typedef struct dtvcc_writer_ctx
|
||||
{
|
||||
int fd;
|
||||
#ifndef DISABLE_RUST
|
||||
// File handle used to work with files on windows
|
||||
void *fhandle;
|
||||
// Charset of the subtitle
|
||||
char *charset;
|
||||
#endif
|
||||
char *filename;
|
||||
iconv_t cd;
|
||||
} ccx_dtvcc_writer_ctx;
|
||||
} dtvcc_writer_ctx;
|
||||
|
||||
typedef struct ccx_sbs_utf8_character
|
||||
{
|
||||
@@ -106,7 +112,7 @@ struct encoder_ctx
|
||||
int extract;
|
||||
|
||||
int dtvcc_extract; // 1 or 0 depending if we have to handle dtvcc
|
||||
ccx_dtvcc_writer_ctx dtvcc_writers[CCX_DTVCC_MAX_SERVICES];
|
||||
dtvcc_writer_ctx dtvcc_writers[CCX_DTVCC_MAX_SERVICES];
|
||||
|
||||
/* Timing related variables*/
|
||||
/* start time of previous sub */
|
||||
|
||||
@@ -1690,17 +1690,30 @@ void dvbsub_handle_display_segment(struct encoder_ctx *enc_ctx,
|
||||
{
|
||||
sub->prev->end_time = sub->prev->start_time + sub->prev->time_out;
|
||||
}
|
||||
encode_sub(enc_ctx->prev, sub->prev); //we encode it
|
||||
int timeok = 1;
|
||||
if (dec_ctx->extraction_start.set &&
|
||||
sub->prev->start_time < dec_ctx->extraction_start.time_in_ms)
|
||||
timeok = 0;
|
||||
if (dec_ctx->extraction_end.set &&
|
||||
sub->prev->end_time > dec_ctx->extraction_end.time_in_ms)
|
||||
{
|
||||
timeok = 0;
|
||||
dec_ctx->processed_enough = 1;
|
||||
}
|
||||
if (timeok)
|
||||
{
|
||||
encode_sub(enc_ctx->prev, sub->prev); //we encode it
|
||||
|
||||
enc_ctx->last_string = enc_ctx->prev->last_string; // Update last recognized string (used in Matroska)
|
||||
enc_ctx->prev->last_string = NULL;
|
||||
enc_ctx->last_string = enc_ctx->prev->last_string; // Update last recognized string (used in Matroska)
|
||||
enc_ctx->prev->last_string = NULL;
|
||||
|
||||
enc_ctx->srt_counter = enc_ctx->prev->srt_counter; //for dvb subs we need to update the current srt counter because we always encode the previous subtitle (and the counter is increased for the previous context)
|
||||
enc_ctx->prev_start = enc_ctx->prev->prev_start;
|
||||
sub->prev->got_output = 0;
|
||||
if (enc_ctx->write_format == CCX_OF_WEBVTT)
|
||||
{ // we already wrote header, but since we encoded last sub, we must prevent multiple headers in future
|
||||
enc_ctx->wrote_webvtt_header = 1;
|
||||
enc_ctx->srt_counter = enc_ctx->prev->srt_counter; //for dvb subs we need to update the current srt counter because we always encode the previous subtitle (and the counter is increased for the previous context)
|
||||
enc_ctx->prev_start = enc_ctx->prev->prev_start;
|
||||
sub->prev->got_output = 0;
|
||||
if (enc_ctx->write_format == CCX_OF_WEBVTT)
|
||||
{ // we already wrote header, but since we encoded last sub, we must prevent multiple headers in future
|
||||
enc_ctx->wrote_webvtt_header = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* copy previous encoder context*/
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef CCX_CCEXTRACTOR_H
|
||||
#define CCX_CCEXTRACTOR_H
|
||||
|
||||
#define VERSION "0.89"
|
||||
#define VERSION "0.94"
|
||||
|
||||
// Load common includes and constants for library usage
|
||||
#include "ccx_common_platform.h"
|
||||
|
||||
@@ -68,40 +68,40 @@ struct list_head {
|
||||
* This is only for internal list manipulation where we know
|
||||
* the prev/next entries already!
|
||||
*/
|
||||
static inline void __list_add(struct list_head *new,
|
||||
static inline void __list_add(struct list_head *elem,
|
||||
struct list_head *prev,
|
||||
struct list_head *next)
|
||||
{
|
||||
next->prev = new;
|
||||
new->next = next;
|
||||
new->prev = prev;
|
||||
prev->next = new;
|
||||
next->prev = elem;
|
||||
elem->next = next;
|
||||
elem->prev = prev;
|
||||
prev->next = elem;
|
||||
}
|
||||
|
||||
/**
|
||||
* list_add - add a new entry
|
||||
* @new: new entry to be added
|
||||
* @elem: new entry to be added
|
||||
* @head: list head to add it after
|
||||
*
|
||||
* Insert a new entry after the specified head.
|
||||
* This is good for implementing stacks.
|
||||
*/
|
||||
static inline void list_add(struct list_head *new, struct list_head *head)
|
||||
static inline void list_add(struct list_head *elem, struct list_head *head)
|
||||
{
|
||||
__list_add(new, head, head->next);
|
||||
__list_add(elem, head, head->next);
|
||||
}
|
||||
|
||||
/**
|
||||
* list_add_tail - add a new entry
|
||||
* @new: new entry to be added
|
||||
* @elem: new entry to be added
|
||||
* @head: list head to add it before
|
||||
*
|
||||
* Insert a new entry before the specified head.
|
||||
* This is useful for implementing queues.
|
||||
*/
|
||||
static inline void list_add_tail(struct list_head *new, struct list_head *head)
|
||||
static inline void list_add_tail(struct list_head *elem, struct list_head *head)
|
||||
{
|
||||
__list_add(new, head->prev, head);
|
||||
__list_add(elem, head->prev, head);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -395,8 +395,7 @@ static int process_clcp(struct lib_ccx_ctx *ctx, struct encoder_ctx *enc_ctx,
|
||||
}
|
||||
// WARN: otherwise cea-708 will not work
|
||||
dec_ctx->dtvcc->encoder = (void *)enc_ctx;
|
||||
// TODO: is it really always 4-bytes long?
|
||||
ccx_dtvcc_process_data(dec_ctx, (unsigned char *)temp, 4);
|
||||
dtvcc_process_data(dec_ctx->dtvcc, (unsigned char *)temp);
|
||||
cb_708++;
|
||||
}
|
||||
if (ctx->write_format == CCX_OF_MCC)
|
||||
@@ -697,9 +696,22 @@ int processmp4(struct lib_ccx_ctx *ctx, struct ccx_s_mp4Cfg *cfg, char *file)
|
||||
&dec_sub, &mp4_ret, subtype,
|
||||
data, sample->dataLength);
|
||||
break;
|
||||
case MEDIA_TYPE(GF_ISOM_MEDIA_TEXT, GF_ISOM_SUBTYPE_TEXT): // text:text
|
||||
{
|
||||
static int unsupported_reported = 0;
|
||||
if (!unsupported_reported)
|
||||
{
|
||||
mprint("\ntext:text not yet supported, see\n");
|
||||
mprint("https://developer.apple.com/library/mac/documentation/quicktime/qtff/QTFFChap3/qtff3.html\n");
|
||||
mprint("If you want to work on a PR.\n");
|
||||
unsupported_reported = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
// See https://gpac.wp.imt.fr/2014/09/04/subtitling-with-gpac/ for more possible types
|
||||
mprint("\nUnsupported track type %c%c%c%c:%c%c%c%c! Please report.\n",
|
||||
mprint("\nUnsupported track type \"%c%c%c%c:%c%c%c%c\". Please report.\n",
|
||||
(unsigned char)(type >> 24 % 0x100), (unsigned char)((type >> 16) % 0x100),
|
||||
(unsigned char)((type >> 8) % 0x100), (unsigned char)(type % 0x100),
|
||||
(unsigned char)(subtype >> 24 % 0x100), (unsigned char)((subtype >> 16) % 0x100),
|
||||
|
||||
@@ -35,6 +35,10 @@
|
||||
#define DEFAULT_FONT_PATH_ITALICS "/usr/share/fonts/truetype/noto/NotoSans-Italic.ttf"
|
||||
#endif
|
||||
|
||||
#ifndef DISABLE_RUST
|
||||
extern void ccxr_init_logger();
|
||||
#endif
|
||||
|
||||
static int inputfile_capacity = 0;
|
||||
|
||||
size_t remove_trailing_whitespace(char *line)
|
||||
@@ -597,7 +601,6 @@ void print_usage(void)
|
||||
mprint(" -bom: Append a BOM (Byte Order Mark) to output files.\n");
|
||||
mprint(" Note that most text processing tools in linux will not\n");
|
||||
mprint(" like BOM.\n");
|
||||
mprint(" This is the default in Windows builds.\n");
|
||||
mprint(" -nobom: Do not append a BOM (Byte Order Mark) to output\n");
|
||||
mprint(" files. Note that this may break files when using\n");
|
||||
mprint(" Windows. This is the default in non-Windows builds.\n");
|
||||
@@ -1024,6 +1027,11 @@ void version(char *location)
|
||||
mprint(" Version: %s\n", VERSION);
|
||||
mprint(" Git commit: %s\n", GIT_COMMIT);
|
||||
mprint(" Compilation date: %s\n", COMPILE_DATE);
|
||||
#ifndef DISABLE_RUST
|
||||
mprint(" CEA-708 decoder: Rust\n");
|
||||
#else
|
||||
mprint(" CEA-708 decoder: C\n");
|
||||
#endif
|
||||
mprint(" File SHA256: %s\n", hash);
|
||||
|
||||
mprint("Libraries used by CCExtractor\n");
|
||||
@@ -1832,6 +1840,7 @@ int parse_parameters(struct ccx_s_options *opt, int argc, char *argv[])
|
||||
}
|
||||
if (strcmp(argv[i], "-12") == 0)
|
||||
{
|
||||
opt->is_608_enabled = 1;
|
||||
opt->extract = 12;
|
||||
continue;
|
||||
}
|
||||
@@ -2082,11 +2091,13 @@ int parse_parameters(struct ccx_s_options *opt, int argc, char *argv[])
|
||||
}
|
||||
if (strcmp(argv[i], "-1") == 0)
|
||||
{
|
||||
opt->is_608_enabled = 1;
|
||||
opt->extract = 1;
|
||||
continue;
|
||||
}
|
||||
if (strcmp(argv[i], "-2") == 0)
|
||||
{
|
||||
opt->is_608_enabled = 1;
|
||||
opt->extract = 2;
|
||||
continue;
|
||||
}
|
||||
@@ -2179,6 +2190,9 @@ int parse_parameters(struct ccx_s_options *opt, int argc, char *argv[])
|
||||
if (strcmp(argv[i], "-708") == 0)
|
||||
{
|
||||
opt->debug_mask |= CCX_DMT_708;
|
||||
#ifndef DISABLE_RUST
|
||||
ccxr_init_logger();
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
if (strcmp(argv[i], "-goppts") == 0)
|
||||
@@ -2329,6 +2343,7 @@ int parse_parameters(struct ccx_s_options *opt, int argc, char *argv[])
|
||||
{
|
||||
if (i < argc - 1)
|
||||
{
|
||||
opt->is_708_enabled = 1;
|
||||
i++;
|
||||
parse_708_services(opt, argv[i]);
|
||||
continue;
|
||||
@@ -2961,6 +2976,24 @@ int parse_parameters(struct ccx_s_options *opt, int argc, char *argv[])
|
||||
{
|
||||
opt->enc_cfg.output_filename = NULL;
|
||||
}
|
||||
|
||||
if (!opt->is_608_enabled && !opt->is_708_enabled)
|
||||
{
|
||||
// If nothing is selected then extract both 608 and 708 subs
|
||||
|
||||
// 608 field 1 is enabled by default
|
||||
// Enable 708 subs extraction
|
||||
parse_708_services(opt, "all");
|
||||
}
|
||||
else if (!opt->is_608_enabled && opt->is_708_enabled)
|
||||
{
|
||||
// Extract only 708 subs
|
||||
|
||||
// 608 field 1 is enabled by default, disable it
|
||||
opt->extract = 0;
|
||||
opt->enc_cfg.extract_only_708 = 1;
|
||||
}
|
||||
|
||||
#ifdef WITH_LIBCURL
|
||||
opt->enc_cfg.curlposturl = opt->curlposturl;
|
||||
#endif
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "utility.h"
|
||||
#include <stdbool.h>
|
||||
#ifdef WIN32
|
||||
#include "..\\win_iconv\\iconv.h"
|
||||
#include "..\\thirdparty\\win_iconv\\iconv.h"
|
||||
#else
|
||||
#include "iconv.h"
|
||||
#endif
|
||||
|
||||
41
src/rust/CMakeLists.txt
Normal file
41
src/rust/CMakeLists.txt
Normal file
@@ -0,0 +1,41 @@
|
||||
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
set(CARGO_CMD cargo build)
|
||||
set(TARGET_DIR "debug")
|
||||
else ()
|
||||
set(CARGO_CMD cargo build --release)
|
||||
set(TARGET_DIR "release")
|
||||
endif ()
|
||||
|
||||
# Check rust version
|
||||
set(MSRV "1.54.0")
|
||||
execute_process(COMMAND rustc --version
|
||||
OUTPUT_VARIABLE Rust_Version)
|
||||
string(REGEX MATCH "[0-9]+.[0-9]+.[0-9]+" Rust_Version_string ${Rust_Version})
|
||||
message(STATUS "Detected rustc version ${Rust_Version_string}")
|
||||
if (Rust_Version_string VERSION_GREATER_EQUAL ${MSRV})
|
||||
message(STATUS "rustc >= MSRV(${MSRV})")
|
||||
else()
|
||||
message(FATAL_ERROR "Minimum supported rust version(MSRV) is ${MSRV}, please upgrade rust")
|
||||
endif(Rust_Version_string VERSION_GREATER_EQUAL ${MSRV})
|
||||
|
||||
if(WIN32)
|
||||
set(CCX_RUST_SO "${CMAKE_CURRENT_BINARY_DIR}/${TARGET_DIR}/libccx_rust.lib")
|
||||
message("${CCX_RUST_SO}")
|
||||
add_custom_target(ccx_rust ALL
|
||||
COMMENT "Compiling ccx_rust module"
|
||||
COMMAND set CARGO_TARGET_DIR=${CMAKE_CURRENT_BINARY_DIR} ${CARGO_CMD}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
set_target_properties(ccx_rust PROPERTIES LOCATION ${CCX_RUST_SO})
|
||||
else()
|
||||
set(CCX_RUST_SO "${CMAKE_CURRENT_BINARY_DIR}/${TARGET_DIR}/libccx_rust.a")
|
||||
add_custom_target(ccx_rust ALL
|
||||
COMMENT "Compiling ccx_rust module"
|
||||
COMMAND CARGO_TARGET_DIR=${CMAKE_CURRENT_BINARY_DIR} ${CARGO_CMD}
|
||||
COMMAND cp ${CCX_RUST_SO} ${CMAKE_CURRENT_BINARY_DIR}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
set_target_properties(ccx_rust PROPERTIES LOCATION ${CCX_RUST_SO})
|
||||
endif()
|
||||
|
||||
add_test(NAME ccx_rust_test
|
||||
COMMAND cargo test
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
354
src/rust/Cargo.lock
generated
Normal file
354
src/rust/Cargo.lock
generated
Normal file
@@ -0,0 +1,354 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.7.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ansi_term"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bindgen"
|
||||
version = "0.58.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0f8523b410d7187a43085e7e064416ea32ded16bd0a4e6fc025e21616d01258f"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cexpr",
|
||||
"clang-sys",
|
||||
"clap",
|
||||
"env_logger",
|
||||
"lazy_static",
|
||||
"lazycell",
|
||||
"log",
|
||||
"peeking_take_while",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"regex",
|
||||
"rustc-hash",
|
||||
"shlex",
|
||||
"which",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||
|
||||
[[package]]
|
||||
name = "ccx_rust"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bindgen",
|
||||
"env_logger",
|
||||
"iconv",
|
||||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cexpr"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4aedb84272dbe89af497cf81375129abda4fc0a9e7c5d317498c15cc30c0d27"
|
||||
dependencies = [
|
||||
"nom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "clang-sys"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "853eda514c284c2287f4bf20ae614f8781f40a81d32ecda6e91449304dfe077c"
|
||||
dependencies = [
|
||||
"glob",
|
||||
"libc",
|
||||
"libloading",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "2.33.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002"
|
||||
dependencies = [
|
||||
"ansi_term",
|
||||
"atty",
|
||||
"bitflags",
|
||||
"strsim",
|
||||
"textwrap",
|
||||
"unicode-width",
|
||||
"vec_map",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dyn_buf"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "74c57ab96715773d9cb9789b38eb7cbf04b3c6f5624a9d98f51761603376767c"
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.8.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a19187fea3ac7e84da7dacf48de0c45d63c6a76f9490dae389aead16c243fce3"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"humantime",
|
||||
"log",
|
||||
"regex",
|
||||
"termcolor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glob"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "humantime"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
|
||||
|
||||
[[package]]
|
||||
name = "iconv"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07e6a7db0df823ef299ef75b6951975c7a1f9019910b3665614bac4161bab1a9"
|
||||
dependencies = [
|
||||
"dyn_buf",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "lazycell"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.98"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790"
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f84d96438c15fcd6c3f244c8fce01d1e2b9c6b5623e9c711dc9286d8fc92d6a"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc"
|
||||
|
||||
[[package]]
|
||||
name = "nom"
|
||||
version = "5.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "peeking_take_while"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0d8caf72986c1a598726adc988bb5984792ef84f5ee5aa50209145ee8077038"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||
|
||||
[[package]]
|
||||
name = "shlex"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42a568c8f2cd051a4d283bd6eb0343ac214c1b0f1ac19f93e1175b2dee38c73d"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "textwrap"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
|
||||
dependencies = [
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||
|
||||
[[package]]
|
||||
name = "vec_map"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
|
||||
|
||||
[[package]]
|
||||
name = "which"
|
||||
version = "3.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d011071ae14a2f6671d0b74080ae0cd8ebf3a6f8c9589a2cd45f23126fe29724"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
19
src/rust/Cargo.toml
Normal file
19
src/rust/Cargo.toml
Normal file
@@ -0,0 +1,19 @@
|
||||
[package]
|
||||
name = "ccx_rust"
|
||||
version = "0.1.0"
|
||||
authors = ["PunitLodha <punitlodha@pm.me>"]
|
||||
description = "Rust library for CCExtractor"
|
||||
edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[lib]
|
||||
crate-type = ["staticlib"]
|
||||
|
||||
[dependencies]
|
||||
log = "0.4.0"
|
||||
env_logger = "0.8.4"
|
||||
iconv = "0.1.1"
|
||||
|
||||
[build-dependencies]
|
||||
bindgen = "0.58.1"
|
||||
46
src/rust/build.rs
Normal file
46
src/rust/build.rs
Normal file
@@ -0,0 +1,46 @@
|
||||
use std::env;
|
||||
use std::path::PathBuf;
|
||||
|
||||
fn main() {
|
||||
let mut builder = bindgen::Builder::default()
|
||||
// The input header we would like to generate
|
||||
// bindings for.
|
||||
.header("wrapper.h")
|
||||
// Tell cargo to invalidate the built crate whenever any of the
|
||||
// included header files changed.
|
||||
.parse_callbacks(Box::new(bindgen::CargoCallbacks));
|
||||
|
||||
for type_name in ALLOWLIST_TYPES {
|
||||
builder = builder.allowlist_type(type_name);
|
||||
}
|
||||
|
||||
for fn_name in ALLOWLIST_FUNCTIONS {
|
||||
builder = builder.allowlist_function(fn_name);
|
||||
}
|
||||
|
||||
for rust_enum in RUSTIFIED_ENUMS {
|
||||
builder = builder.rustified_enum(rust_enum);
|
||||
}
|
||||
|
||||
let bindings = builder
|
||||
// Finish the builder and generate the bindings.
|
||||
.generate()
|
||||
// Unwrap the Result and panic on failure.
|
||||
.expect("Unable to generate bindings");
|
||||
|
||||
// Write the bindings to the $OUT_DIR/bindings.rs file.
|
||||
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
|
||||
bindings
|
||||
.write_to_file(out_path.join("bindings.rs"))
|
||||
.expect("Couldn't write bindings!");
|
||||
}
|
||||
|
||||
const ALLOWLIST_FUNCTIONS: &[&str] = &[
|
||||
".*(?i)_?dtvcc_.*",
|
||||
"get_visible_.*",
|
||||
"get_fts",
|
||||
"printdata",
|
||||
"writercwtdata",
|
||||
];
|
||||
const ALLOWLIST_TYPES: &[&str] = &[".*(?i)_?dtvcc_.*", "encoder_ctx", "lib_cc_decode"];
|
||||
const RUSTIFIED_ENUMS: &[&str] = &["dtvcc_(window|pen)_.*", "ccx_output_format"];
|
||||
186
src/rust/src/decoder/commands.rs
Normal file
186
src/rust/src/decoder/commands.rs
Normal file
@@ -0,0 +1,186 @@
|
||||
//! Different code sets as defined in CEA-708-E
|
||||
//!
|
||||
//! Refer section 7.1 CEA-708-E.
|
||||
//! Different code sets are:
|
||||
//!
|
||||
//! | Name | Description | Space |
|
||||
//! | --- | --- | --- |
|
||||
//! | C0 | Miscellaneous Control Codes | 0x00 to 0x1F |
|
||||
//! | C2 | Extended Control Code Set 1 | 0x00 to 0x1F |
|
||||
//! | G0 | ASCII Printable Characters | 0x20 to 0x7F |
|
||||
//! | G2 | Extended Miscellaneous Characters | 0x20 to 0x7F |
|
||||
//! | C1 | Captioning Command Control Codes | 0x80 to 0x9F |
|
||||
//! | C3 | Extended Control Code Set 2 | 0x80 to 0x9F |
|
||||
//! | G1 | ISO 8859-1 Latin-1 Character Set | 0xA0 to 0xFF |
|
||||
//! | G3 | Future Expansion | 0xA0 to 0xFF |
|
||||
|
||||
/// Different C0 commands
|
||||
#[allow(clippy::upper_case_acronyms)]
|
||||
#[derive(Debug)]
|
||||
pub enum C0CodeSet {
|
||||
NUL,
|
||||
ETX,
|
||||
BS,
|
||||
FF,
|
||||
CR,
|
||||
HCR,
|
||||
EXT1,
|
||||
P16,
|
||||
RESERVED,
|
||||
}
|
||||
|
||||
impl C0CodeSet {
|
||||
/// Create a new command from the byte value
|
||||
pub fn new(data: u8) -> Self {
|
||||
match data {
|
||||
0 => C0CodeSet::NUL,
|
||||
0x3 => C0CodeSet::ETX,
|
||||
0x8 => C0CodeSet::BS,
|
||||
0xC => C0CodeSet::FF,
|
||||
0xD => C0CodeSet::CR,
|
||||
0xE => C0CodeSet::HCR,
|
||||
0x10 => C0CodeSet::EXT1,
|
||||
0x18 => C0CodeSet::P16,
|
||||
_ => C0CodeSet::RESERVED,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// C0 command with its length
|
||||
pub struct C0Command {
|
||||
pub command: C0CodeSet,
|
||||
pub length: u8,
|
||||
}
|
||||
|
||||
impl C0Command {
|
||||
/// Create a new command from the byte value
|
||||
pub fn new(data: u8) -> Self {
|
||||
let command = C0CodeSet::new(data);
|
||||
// lengths are defined in CEA-708-E section 7.1.4
|
||||
let length = match data {
|
||||
0..=0xF => 1,
|
||||
0x10..=0x17 => 2,
|
||||
0x18..=0x1F => 3,
|
||||
// Unreachable arm as C0 code set is only from 0 - 0x1F
|
||||
_ => 1,
|
||||
};
|
||||
C0Command { command, length }
|
||||
}
|
||||
}
|
||||
|
||||
/// Different C1 commands
|
||||
#[allow(clippy::upper_case_acronyms)]
|
||||
#[derive(Debug)]
|
||||
pub enum C1CodeSet {
|
||||
CW0,
|
||||
CW1,
|
||||
CW2,
|
||||
CW3,
|
||||
CW4,
|
||||
CW5,
|
||||
CW6,
|
||||
CW7,
|
||||
CLW,
|
||||
DSW,
|
||||
HDW,
|
||||
TGW,
|
||||
DLW,
|
||||
DLY,
|
||||
DLC,
|
||||
RST,
|
||||
SPA,
|
||||
SPC,
|
||||
SPL,
|
||||
SWA,
|
||||
DF0,
|
||||
DF1,
|
||||
DF2,
|
||||
DF3,
|
||||
DF4,
|
||||
DF5,
|
||||
DF6,
|
||||
DF7,
|
||||
RESERVED,
|
||||
}
|
||||
|
||||
/// C1 command with its length
|
||||
pub struct C1Command {
|
||||
pub command: C1CodeSet,
|
||||
pub length: u8,
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
impl C1Command {
|
||||
/// Create a new command from the byte value
|
||||
pub fn new(data: u8) -> Self {
|
||||
let (command, name, length) = match data {
|
||||
0x80 => (C1CodeSet::CW0, "SetCurrentWindow0", 1),
|
||||
0x81 => (C1CodeSet::CW1, "SetCurrentWindow1", 1),
|
||||
0x82 => (C1CodeSet::CW2, "SetCurrentWindow2", 1),
|
||||
0x83 => (C1CodeSet::CW3, "SetCurrentWindow3", 1),
|
||||
0x84 => (C1CodeSet::CW4, "SetCurrentWindow4", 1),
|
||||
0x85 => (C1CodeSet::CW5, "SetCurrentWindow5", 1),
|
||||
0x86 => (C1CodeSet::CW6, "SetCurrentWindow6", 1),
|
||||
0x87 => (C1CodeSet::CW7, "SetCurrentWindow7", 1),
|
||||
0x88 => (C1CodeSet::CLW, "ClearWindows", 2),
|
||||
0x89 => (C1CodeSet::DSW, "DisplayWindows", 2),
|
||||
0x8A => (C1CodeSet::HDW, "HideWindows", 2),
|
||||
0x8B => (C1CodeSet::TGW, "ToggleWindows", 2),
|
||||
0x8C => (C1CodeSet::DLW, "DeleteWindows", 2),
|
||||
0x8D => (C1CodeSet::DLY, "Delay", 2),
|
||||
0x8E => (C1CodeSet::DLC, "DelayCancel", 1),
|
||||
0x8F => (C1CodeSet::RST, "Reset", 1),
|
||||
0x90 => (C1CodeSet::SPA, "SetPenAttributes", 3),
|
||||
0x91 => (C1CodeSet::SPC, "SetPenColor", 4),
|
||||
0x92 => (C1CodeSet::SPL, "SetPenLocation", 3),
|
||||
0x97 => (C1CodeSet::SWA, "SetWindowAttributes", 5),
|
||||
0x98 => (C1CodeSet::DF0, "DefineWindow0", 7),
|
||||
0x99 => (C1CodeSet::DF1, "DefineWindow1", 7),
|
||||
0x9A => (C1CodeSet::DF2, "DefineWindow2", 7),
|
||||
0x9B => (C1CodeSet::DF3, "DefineWindow3", 7),
|
||||
0x9C => (C1CodeSet::DF4, "DefineWindow4", 7),
|
||||
0x9D => (C1CodeSet::DF5, "DefineWindow5", 7),
|
||||
0x9E => (C1CodeSet::DF6, "DefineWindow6", 7),
|
||||
0x9F => (C1CodeSet::DF7, "DefineWindow7", 7),
|
||||
_ => (C1CodeSet::RESERVED, "Reserved", 1),
|
||||
};
|
||||
let name = name.to_owned();
|
||||
Self {
|
||||
command,
|
||||
length,
|
||||
name,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Handle C2 - Code Set - Extended Control Code Set 1
|
||||
pub fn handle_C2(code: u8) -> u8 {
|
||||
match code {
|
||||
// ... Single-byte control bytes (0 additional bytes)
|
||||
0..=0x07 => 1,
|
||||
// ..two-byte control codes (1 additional byte)
|
||||
0x08..=0x0F => 2,
|
||||
// ..three-byte control codes (2 additional bytes)
|
||||
0x10..=0x17 => 3,
|
||||
// 18-1F => four-byte control codes (3 additional bytes)
|
||||
_ => 4,
|
||||
}
|
||||
}
|
||||
|
||||
/// Handle C3 - Code Set - Extended Control Code Set 2
|
||||
pub fn handle_C3(code: u8, next_code: u8) -> u8 {
|
||||
match code {
|
||||
// Five-byte control bytes (4 additional bytes)
|
||||
0x80..=0x87 => 5,
|
||||
// Six-byte control codes (5 additional byte)
|
||||
0x88..=0x8F => 6,
|
||||
// 90-9F variable length commands
|
||||
// Refer Section 7.1.11.2
|
||||
_ => {
|
||||
// next code is the header which specifies additional bytes
|
||||
let length = (next_code & 0x3F) + 1;
|
||||
// + 1 for current code
|
||||
length + 1
|
||||
}
|
||||
}
|
||||
}
|
||||
221
src/rust/src/decoder/mod.rs
Normal file
221
src/rust/src/decoder/mod.rs
Normal file
@@ -0,0 +1,221 @@
|
||||
//! CEA 708 decoder
|
||||
//!
|
||||
//! Provides a CEA 708 decoder as defined by ANSI/CTA-708-E R-2018
|
||||
|
||||
mod commands;
|
||||
mod output;
|
||||
mod service_decoder;
|
||||
mod timing;
|
||||
mod tv_screen;
|
||||
mod window;
|
||||
|
||||
use crate::{bindings::*, utils::is_true};
|
||||
|
||||
use log::{debug, warn};
|
||||
|
||||
const CCX_DTVCC_MAX_PACKET_LENGTH: u8 = 128;
|
||||
const CCX_DTVCC_NO_LAST_SEQUENCE: i32 = -1;
|
||||
const CCX_DTVCC_SCREENGRID_ROWS: u8 = 75;
|
||||
const CCX_DTVCC_SCREENGRID_COLUMNS: u8 = 210;
|
||||
const CCX_DTVCC_MAX_ROWS: u8 = 15;
|
||||
const CCX_DTVCC_MAX_COLUMNS: u8 = 32 * 2;
|
||||
|
||||
/// Context required for processing 708 data
|
||||
pub struct Dtvcc<'a> {
|
||||
pub is_active: bool,
|
||||
pub active_services_count: u8,
|
||||
pub services_active: Vec<i32>,
|
||||
pub report_enabled: bool,
|
||||
pub report: &'a mut ccx_decoder_dtvcc_report,
|
||||
pub decoders: Vec<&'a mut dtvcc_service_decoder>,
|
||||
pub packet: Vec<u8>,
|
||||
pub packet_length: u8,
|
||||
pub is_header_parsed: bool,
|
||||
pub last_sequence: i32,
|
||||
pub encoder: &'a mut encoder_ctx,
|
||||
pub no_rollup: bool,
|
||||
pub timing: &'a mut ccx_common_timing_ctx,
|
||||
}
|
||||
|
||||
impl<'a> Dtvcc<'a> {
|
||||
/// Create a new dtvcc context
|
||||
pub fn new(ctx: &'a mut dtvcc_ctx) -> Self {
|
||||
let report = unsafe { &mut *ctx.report };
|
||||
let encoder = unsafe { &mut *(ctx.encoder as *mut encoder_ctx) };
|
||||
let timing = unsafe { &mut *ctx.timing };
|
||||
|
||||
Self {
|
||||
is_active: is_true(ctx.is_active),
|
||||
active_services_count: ctx.active_services_count as u8,
|
||||
services_active: ctx.services_active.iter().copied().collect(),
|
||||
report_enabled: is_true(ctx.report_enabled),
|
||||
report,
|
||||
decoders: ctx.decoders.iter_mut().collect(),
|
||||
packet: ctx.current_packet.to_vec(),
|
||||
packet_length: ctx.current_packet_length as u8,
|
||||
is_header_parsed: is_true(ctx.is_current_packet_header_parsed),
|
||||
last_sequence: ctx.last_sequence,
|
||||
encoder,
|
||||
no_rollup: is_true(ctx.no_rollup),
|
||||
timing,
|
||||
}
|
||||
}
|
||||
/// Process cc data and add it to the dtvcc packet
|
||||
pub fn process_cc_data(&mut self, cc_valid: u8, cc_type: u8, data1: u8, data2: u8) {
|
||||
if !self.is_active && !self.report_enabled {
|
||||
return;
|
||||
}
|
||||
|
||||
match cc_type {
|
||||
// type 0 and 1 are for CEA 608 data and are handled before calling this function
|
||||
// valid types for CEA 708 data are only 2 and 3
|
||||
2 => {
|
||||
debug!("dtvcc_process_data: DTVCC Channel Packet Data");
|
||||
if cc_valid == 1 && self.is_header_parsed {
|
||||
if self.packet_length > 253 {
|
||||
warn!("dtvcc_process_data: Warning: Legal packet size exceeded (1), data not added.");
|
||||
} else {
|
||||
self.add_data_to_packet(data1, data2);
|
||||
|
||||
let mut max_len = self.packet[0] & 0x3F;
|
||||
|
||||
if max_len == 0 {
|
||||
// This is well defined in EIA-708; no magic.
|
||||
max_len = 128;
|
||||
} else {
|
||||
max_len *= 2;
|
||||
}
|
||||
|
||||
// If packet is complete then process the packet
|
||||
if self.packet_length >= max_len {
|
||||
self.process_current_packet(max_len);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
3 => {
|
||||
debug!("dtvcc_process_data: DTVCC Channel Packet Start");
|
||||
if cc_valid == 1 {
|
||||
if self.packet_length > (CCX_DTVCC_MAX_PACKET_LENGTH - 1) {
|
||||
warn!("dtvcc_process_data: Warning: Legal packet size exceeded (2), data not added.");
|
||||
} else {
|
||||
self.add_data_to_packet(data1, data2);
|
||||
self.is_header_parsed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => warn!(
|
||||
"dtvcc_process_data: shouldn't be here - cc_type: {}",
|
||||
cc_type
|
||||
),
|
||||
}
|
||||
}
|
||||
/// Add data to the packet
|
||||
pub fn add_data_to_packet(&mut self, data1: u8, data2: u8) {
|
||||
self.packet[self.packet_length as usize] = data1;
|
||||
self.packet_length += 1;
|
||||
self.packet[self.packet_length as usize] = data2;
|
||||
self.packet_length += 1;
|
||||
}
|
||||
/// Process current packet into service blocks
|
||||
pub fn process_current_packet(&mut self, len: u8) {
|
||||
let seq = (self.packet[0] & 0xC0) >> 6;
|
||||
debug!(
|
||||
"dtvcc_process_current_packet: Sequence: {}, packet length: {}",
|
||||
seq, len
|
||||
);
|
||||
if self.packet_length == 0 {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if current sequence is correct
|
||||
// Sequence number is a 2 bit rolling sequence from (0-3)
|
||||
if self.last_sequence != CCX_DTVCC_NO_LAST_SEQUENCE
|
||||
&& (self.last_sequence + 1) % 4 != seq as i32
|
||||
{
|
||||
warn!("dtvcc_process_current_packet: Unexpected sequence number, it is {} but should be {}", seq, (self.last_sequence +1) % 4);
|
||||
}
|
||||
self.last_sequence = seq as i32;
|
||||
|
||||
let mut pos: u8 = 1;
|
||||
while pos < len {
|
||||
let mut service_number = (self.packet[pos as usize] & 0xE0) >> 5; // 3 more significant bits
|
||||
let block_length = self.packet[pos as usize] & 0x1F; // 5 less significant bits
|
||||
debug!("dtvcc_process_current_packet: Standard header Service number: {}, Block length: {}", service_number, block_length);
|
||||
|
||||
if service_number == 7 {
|
||||
// There is an extended header
|
||||
// CEA-708-E 6.2.2 Extended Service Block Header
|
||||
pos += 1;
|
||||
service_number = self.packet[pos as usize] & 0x3F; // 6 more significant bits
|
||||
if service_number > 7 {
|
||||
warn!("dtvcc_process_current_packet: Illegal service number in extended header: {}", service_number);
|
||||
}
|
||||
}
|
||||
|
||||
pos += 1;
|
||||
|
||||
if service_number == 0 && block_length != 0 {
|
||||
// Illegal, but specs say what to do...
|
||||
pos = len; // Move to end
|
||||
break;
|
||||
}
|
||||
|
||||
if block_length != 0 {
|
||||
self.report.services[service_number as usize] = 1;
|
||||
}
|
||||
|
||||
if service_number > 0 && is_true(self.services_active[(service_number - 1) as usize]) {
|
||||
let decoder = &mut self.decoders[(service_number - 1) as usize];
|
||||
decoder.process_service_block(
|
||||
&self.packet[pos as usize..(pos + block_length) as usize],
|
||||
self.encoder,
|
||||
self.timing,
|
||||
self.no_rollup,
|
||||
);
|
||||
}
|
||||
|
||||
pos += block_length // Skip data
|
||||
}
|
||||
|
||||
self.clear_packet();
|
||||
|
||||
if len < 128 && self.packet[pos as usize] != 0 {
|
||||
// Null header is mandatory if there is room
|
||||
warn!("dtvcc_process_current_packet: Warning: Null header expected but not found.");
|
||||
}
|
||||
}
|
||||
/// Clear current packet
|
||||
pub fn clear_packet(&mut self) {
|
||||
self.packet_length = 0;
|
||||
self.is_header_parsed = false;
|
||||
self.packet.iter_mut().for_each(|x| *x = 0);
|
||||
}
|
||||
}
|
||||
|
||||
/// A single character symbol
|
||||
///
|
||||
/// sym stores the symbol
|
||||
/// init is used to know if the symbol is initialized
|
||||
impl dtvcc_symbol {
|
||||
/// Create a new symbol
|
||||
pub fn new(sym: u16) -> Self {
|
||||
Self { init: 1, sym }
|
||||
}
|
||||
/// Create a new 16 bit symbol
|
||||
pub fn new_16(data1: u8, data2: u8) -> Self {
|
||||
let sym = (data1 as u16) << 8 | data2 as u16;
|
||||
Self { init: 1, sym }
|
||||
}
|
||||
/// Check if symbol is initialized
|
||||
pub fn is_set(&self) -> bool {
|
||||
is_true(self.init)
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for dtvcc_symbol {
|
||||
/// Create a blank uninitialized symbol
|
||||
fn default() -> Self {
|
||||
Self { sym: 0, init: 0 }
|
||||
}
|
||||
}
|
||||
112
src/rust/src/decoder/output.rs
Normal file
112
src/rust/src/decoder/output.rs
Normal file
@@ -0,0 +1,112 @@
|
||||
//! Utilty functions to write captions
|
||||
|
||||
#[cfg(unix)]
|
||||
use std::os::unix::prelude::{FromRawFd, IntoRawFd};
|
||||
#[cfg(windows)]
|
||||
use std::os::windows::io::{FromRawHandle, IntoRawHandle};
|
||||
use std::{fs::File, io::Write};
|
||||
|
||||
use crate::{bindings::*, utils::is_true};
|
||||
|
||||
use log::{debug, warn};
|
||||
|
||||
// Context for writing subtitles to file
|
||||
pub struct Writer<'a> {
|
||||
pub cea_708_counter: &'a mut u32,
|
||||
pub subs_delay: LLONG,
|
||||
pub crlf: String,
|
||||
pub write_format: ccx_output_format,
|
||||
pub writer_ctx: &'a mut dtvcc_writer_ctx,
|
||||
pub no_font_color: bool,
|
||||
pub transcript_settings: &'a ccx_encoders_transcript_format,
|
||||
pub no_bom: i32,
|
||||
}
|
||||
|
||||
impl<'a> Writer<'a> {
|
||||
/// Create a new writer context
|
||||
pub fn new(
|
||||
cea_708_counter: &'a mut u32,
|
||||
subs_delay: LLONG,
|
||||
write_format: ccx_output_format,
|
||||
writer_ctx: &'a mut dtvcc_writer_ctx,
|
||||
no_font_color: i32,
|
||||
transcript_settings: &'a ccx_encoders_transcript_format,
|
||||
no_bom: i32,
|
||||
) -> Self {
|
||||
Self {
|
||||
cea_708_counter,
|
||||
subs_delay,
|
||||
crlf: "\r\n".to_owned(),
|
||||
write_format,
|
||||
writer_ctx,
|
||||
no_font_color: is_true(no_font_color),
|
||||
transcript_settings,
|
||||
no_bom,
|
||||
}
|
||||
}
|
||||
/// Write subtitles to the file
|
||||
///
|
||||
/// File must already exist
|
||||
/// On Unix Platforms, uses the raw fd from context to access the file
|
||||
/// On Windows Platforms, uses the raw handle from context to access the file
|
||||
pub fn write_to_file(&mut self, buf: &[u8]) -> Result<(), String> {
|
||||
#[cfg(unix)]
|
||||
{
|
||||
let mut file = unsafe { File::from_raw_fd(self.writer_ctx.fd) };
|
||||
file.write_all(buf).map_err(|err| err.to_string())?;
|
||||
self.writer_ctx.fd = file.into_raw_fd();
|
||||
}
|
||||
#[cfg(windows)]
|
||||
{
|
||||
let mut file = unsafe { File::from_raw_handle(self.writer_ctx.fhandle) };
|
||||
file.write_all(buf).map_err(|err| err.to_string())?;
|
||||
self.writer_ctx.fhandle = file.into_raw_handle();
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
/// Finish writing up any remaining parts
|
||||
pub fn write_done(&mut self) {
|
||||
if self.write_format == ccx_output_format::CCX_OF_SAMI {
|
||||
if let Err(err) = self.write_sami_footer() {
|
||||
warn!("{}", err);
|
||||
}
|
||||
} else {
|
||||
debug!("dtvcc_write_done: no handling required");
|
||||
}
|
||||
}
|
||||
/// Writes the footer according to the SAMI format
|
||||
pub fn write_sami_footer(&mut self) -> Result<(), String> {
|
||||
self.write_to_file(b"</body></sami>")?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Write the symbol to the provided buffer
|
||||
///
|
||||
/// If symbol is 8-bit, then it's written to the buffer
|
||||
/// If symbol is 16-bit, then two 8-bit symbols are written to the buffer
|
||||
pub fn write_char(sym: &dtvcc_symbol, buf: &mut Vec<u8>) {
|
||||
if sym.sym >> 8 != 0 {
|
||||
buf.push((sym.sym >> 8) as u8);
|
||||
buf.push((sym.sym & 0xff) as u8);
|
||||
} else {
|
||||
buf.push(sym.sym as u8);
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert from CEA-708 color representation to hex code
|
||||
///
|
||||
/// Two bits are specified for each red, green, and blue color value which defines the
|
||||
/// intensity of each individual color component.
|
||||
///
|
||||
/// Refer section 8.8 CEA-708-E
|
||||
pub fn color_to_hex(color: u8) -> (u8, u8, u8) {
|
||||
let red = color >> 4;
|
||||
let green = (color >> 2) & 0x3;
|
||||
let blue = color & 0x3;
|
||||
debug!(
|
||||
"Color: {} [{:06x}] {} {} {}",
|
||||
color, color, red, green, blue
|
||||
);
|
||||
(red, green, blue)
|
||||
}
|
||||
1224
src/rust/src/decoder/service_decoder.rs
Normal file
1224
src/rust/src/decoder/service_decoder.rs
Normal file
File diff suppressed because it is too large
Load Diff
49
src/rust/src/decoder/timing.rs
Normal file
49
src/rust/src/decoder/timing.rs
Normal file
@@ -0,0 +1,49 @@
|
||||
//! Utilty functions to get timing for captions
|
||||
|
||||
use crate::{bindings::*, cb_708, cb_field1, cb_field2};
|
||||
|
||||
use log::{debug, error};
|
||||
|
||||
impl ccx_common_timing_ctx {
|
||||
/// Return the current FTS
|
||||
pub fn get_fts(&self, current_field: u8) -> LLONG {
|
||||
unsafe {
|
||||
match current_field {
|
||||
1 => self.fts_now + self.fts_global + cb_field1 as i64 * 1001 / 30,
|
||||
2 => self.fts_now + self.fts_global + cb_field2 as i64 * 1001 / 30,
|
||||
3 => self.fts_now + self.fts_global + cb_708 as i64 * 1001 / 30,
|
||||
_ => {
|
||||
error!("get_fts: Unknown field");
|
||||
0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/// Returns the current FTS and saves it so it can be used by [get_visible_start][Self::get_visible_start()]
|
||||
pub fn get_visible_end(&mut self, current_field: u8) -> LLONG {
|
||||
let fts = self.get_fts(current_field);
|
||||
if fts > self.minimum_fts {
|
||||
self.minimum_fts = fts;
|
||||
}
|
||||
debug!("Visible End time={}", get_time_str(fts));
|
||||
fts
|
||||
}
|
||||
/// Returns a FTS that is guaranteed to be at least 1 ms later than the end of the previous screen, so that there's no timing overlap
|
||||
pub fn get_visible_start(self, current_field: u8) -> LLONG {
|
||||
let mut fts = self.get_fts(current_field);
|
||||
if fts <= self.minimum_fts {
|
||||
fts = self.minimum_fts + 1;
|
||||
}
|
||||
debug!("Visible Start time={}", get_time_str(fts));
|
||||
fts
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a hh:mm:ss,ms string of time
|
||||
pub fn get_time_str(time: LLONG) -> String {
|
||||
let hh = time / 1000 / 60 / 60;
|
||||
let mm = time / 1000 / 60 - 60 * hh;
|
||||
let ss = time / 1000 - 60 * (mm + 60 * hh);
|
||||
let ms = time - 1000 * (ss + 60 * (mm + 60 * hh));
|
||||
format!("{:02}:{:02}:{:02},{:03}", hh, mm, ss, ms)
|
||||
}
|
||||
477
src/rust/src/decoder/tv_screen.rs
Normal file
477
src/rust/src/decoder/tv_screen.rs
Normal file
@@ -0,0 +1,477 @@
|
||||
//! TV screen to be displayed
|
||||
//!
|
||||
//! TV screen contains the captions to be displayed.
|
||||
//! Captions are added to TV screen from a window when any of DSW, HDW, TGW, DLW or CR commands are received
|
||||
|
||||
#[cfg(unix)]
|
||||
use std::os::unix::prelude::IntoRawFd;
|
||||
#[cfg(windows)]
|
||||
use std::os::windows::io::IntoRawHandle;
|
||||
use std::{ffi::CStr, fs::File};
|
||||
|
||||
use super::output::{color_to_hex, write_char, Writer};
|
||||
use super::timing::get_time_str;
|
||||
use super::{CCX_DTVCC_SCREENGRID_COLUMNS, CCX_DTVCC_SCREENGRID_ROWS};
|
||||
use crate::{
|
||||
bindings::*,
|
||||
utils::{is_false, is_true},
|
||||
};
|
||||
|
||||
use log::{debug, warn};
|
||||
|
||||
impl dtvcc_tv_screen {
|
||||
/// Clear all text from TV screen
|
||||
pub fn clear(&mut self) {
|
||||
for row in 0..CCX_DTVCC_SCREENGRID_ROWS as usize {
|
||||
self.chars[row].fill(dtvcc_symbol::default());
|
||||
}
|
||||
self.time_ms_hide = -1;
|
||||
self.time_ms_show = -1;
|
||||
}
|
||||
|
||||
/// Update TV screen show time
|
||||
pub fn update_time_show(&mut self, time: LLONG) {
|
||||
let prev_time_str = get_time_str(self.time_ms_show);
|
||||
let curr_time_str = get_time_str(time);
|
||||
debug!("Screen show time: {} -> {}", prev_time_str, curr_time_str);
|
||||
if self.time_ms_show == -1 || self.time_ms_show > time {
|
||||
self.time_ms_show = time;
|
||||
}
|
||||
}
|
||||
|
||||
/// Update TV screen hide time
|
||||
pub fn update_time_hide(&mut self, time: LLONG) {
|
||||
let prev_time_str = get_time_str(self.time_ms_hide);
|
||||
let curr_time_str = get_time_str(time);
|
||||
debug!("Screen hide time: {} -> {}", prev_time_str, curr_time_str);
|
||||
if self.time_ms_hide == -1 || self.time_ms_hide < time {
|
||||
self.time_ms_hide = time;
|
||||
}
|
||||
}
|
||||
|
||||
/// Write captions to the output file
|
||||
///
|
||||
/// Opens a new file when called for the first time.
|
||||
/// Uses the already open file on subsequent calls.
|
||||
pub fn writer_output(&self, writer: &mut Writer) -> Result<(), String> {
|
||||
debug!(
|
||||
"dtvcc_writer_output: writing... [{:?}][{}]",
|
||||
unsafe { CStr::from_ptr(writer.writer_ctx.filename) },
|
||||
writer.writer_ctx.fd
|
||||
);
|
||||
|
||||
#[cfg(unix)]
|
||||
if writer.writer_ctx.filename.is_null() && writer.writer_ctx.fd < 0 {
|
||||
return Err("Filename missing".to_owned());
|
||||
} else if writer.writer_ctx.fd < 0 {
|
||||
let filename = unsafe {
|
||||
CStr::from_ptr(writer.writer_ctx.filename)
|
||||
.to_str()
|
||||
.map_err(|err| err.to_string())
|
||||
}?;
|
||||
debug!("dtvcc_writer_output: creating {}", filename);
|
||||
let file = File::create(filename).map_err(|err| err.to_string())?;
|
||||
writer.writer_ctx.fd = file.into_raw_fd();
|
||||
|
||||
if is_false(writer.no_bom) {
|
||||
let BOM = [0xef, 0xbb, 0xbf];
|
||||
writer.write_to_file(&BOM)?;
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
if writer.writer_ctx.filename.is_null() && writer.writer_ctx.fhandle.is_null() {
|
||||
return Err("Filename missing".to_owned())?;
|
||||
} else if writer.writer_ctx.fhandle.is_null() {
|
||||
let filename = unsafe {
|
||||
CStr::from_ptr(writer.writer_ctx.filename)
|
||||
.to_str()
|
||||
.map_err(|err| err.to_string())
|
||||
}?;
|
||||
debug!("dtvcc_writer_output: creating {}", filename);
|
||||
let file = File::create(filename).map_err(|err| err.to_string())?;
|
||||
writer.writer_ctx.fhandle = file.into_raw_handle();
|
||||
|
||||
if is_false(writer.no_bom) {
|
||||
let BOM = [0xef, 0xbb, 0xbf];
|
||||
writer.write_to_file(&BOM)?;
|
||||
}
|
||||
}
|
||||
self.write(writer);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Returns the bounds in which captions are present
|
||||
pub fn get_write_interval(&self, row_index: usize) -> (usize, usize) {
|
||||
let mut first = 0;
|
||||
let mut last = CCX_DTVCC_SCREENGRID_COLUMNS as usize - 1;
|
||||
for col in 0..CCX_DTVCC_SCREENGRID_COLUMNS as usize {
|
||||
if self.chars[row_index][col].is_set() {
|
||||
first = col;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for col in (0..(CCX_DTVCC_SCREENGRID_COLUMNS as usize - 1)).rev() {
|
||||
if self.chars[row_index][col].is_set() {
|
||||
last = col;
|
||||
break;
|
||||
}
|
||||
}
|
||||
(first, last)
|
||||
}
|
||||
|
||||
/// Write captions according to the output file type
|
||||
///
|
||||
/// Calls the respective function for the output file type
|
||||
pub fn write(&self, writer: &mut Writer) {
|
||||
let result = match writer.write_format {
|
||||
ccx_output_format::CCX_OF_SRT => self.write_srt(writer),
|
||||
ccx_output_format::CCX_OF_SAMI => self.write_sami(writer),
|
||||
ccx_output_format::CCX_OF_TRANSCRIPT => self.write_transcript(writer),
|
||||
_ => {
|
||||
self.write_debug();
|
||||
Err("Unsupported write format".to_owned())
|
||||
}
|
||||
};
|
||||
if let Err(err) = result {
|
||||
warn!("{}", err);
|
||||
}
|
||||
}
|
||||
|
||||
/// Write all captions from the row to the output file
|
||||
///
|
||||
/// If use_colors is 'true' then <font color="xxx"></font> tags are added to the output
|
||||
pub fn write_row(
|
||||
&self,
|
||||
writer: &mut Writer,
|
||||
row_index: usize,
|
||||
use_colors: bool,
|
||||
) -> Result<(), String> {
|
||||
let mut buf = Vec::new();
|
||||
let mut pen_color = dtvcc_pen_color::default();
|
||||
let mut pen_attribs = dtvcc_pen_attribs::default();
|
||||
let (first, last) = self.get_write_interval(row_index);
|
||||
debug!("First: {}, Last: {}", first, last);
|
||||
|
||||
for i in 0..last + 1 {
|
||||
if use_colors {
|
||||
self.change_pen_color(
|
||||
&pen_color,
|
||||
writer.no_font_color,
|
||||
row_index,
|
||||
i,
|
||||
false,
|
||||
&mut buf,
|
||||
);
|
||||
}
|
||||
self.change_pen_attribs(
|
||||
&pen_attribs,
|
||||
writer.no_font_color,
|
||||
row_index,
|
||||
i,
|
||||
false,
|
||||
&mut buf,
|
||||
);
|
||||
self.change_pen_attribs(
|
||||
&pen_attribs,
|
||||
writer.no_font_color,
|
||||
row_index,
|
||||
i,
|
||||
true,
|
||||
&mut buf,
|
||||
);
|
||||
if use_colors {
|
||||
self.change_pen_color(
|
||||
&pen_color,
|
||||
writer.no_font_color,
|
||||
row_index,
|
||||
i,
|
||||
true,
|
||||
&mut buf,
|
||||
)
|
||||
}
|
||||
pen_color = self.pen_colors[row_index][i];
|
||||
pen_attribs = self.pen_attribs[row_index][i];
|
||||
if i < first {
|
||||
buf.push(b' ');
|
||||
} else {
|
||||
write_char(&self.chars[row_index][i], &mut buf)
|
||||
}
|
||||
}
|
||||
// there can be unclosed tags or colors after the last symbol in a row
|
||||
if use_colors {
|
||||
self.change_pen_color(
|
||||
&pen_color,
|
||||
writer.no_font_color,
|
||||
row_index,
|
||||
CCX_DTVCC_SCREENGRID_COLUMNS as usize,
|
||||
false,
|
||||
&mut buf,
|
||||
)
|
||||
}
|
||||
self.change_pen_attribs(
|
||||
&pen_attribs,
|
||||
writer.no_font_color,
|
||||
row_index,
|
||||
CCX_DTVCC_SCREENGRID_COLUMNS as usize,
|
||||
false,
|
||||
&mut buf,
|
||||
);
|
||||
// Tags can still be crossed e.g <f><i>text</f></i>, but testing HTML code has shown that they still are handled correctly.
|
||||
if writer.writer_ctx.cd != (-1_isize) as iconv_t {
|
||||
if writer.writer_ctx.charset.is_null() {
|
||||
debug!("Charset: null");
|
||||
} else {
|
||||
let charset = unsafe {
|
||||
CStr::from_ptr(writer.writer_ctx.charset)
|
||||
.to_str()
|
||||
.map_err(|err| err.to_string())?
|
||||
};
|
||||
debug!("Charset: {}", charset);
|
||||
|
||||
let op = iconv::decode(&buf, charset).map_err(|err| err.to_string())?;
|
||||
writer.write_to_file(op.as_bytes())?;
|
||||
}
|
||||
} else {
|
||||
writer.write_to_file(&buf)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Write captions in SRT format
|
||||
pub fn write_srt(&self, writer: &mut Writer) -> Result<(), String> {
|
||||
if self.is_screen_empty(writer) {
|
||||
return Ok(());
|
||||
}
|
||||
if self.time_ms_show + writer.subs_delay < 0 {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let time_show = get_time_str(self.time_ms_show);
|
||||
let time_hide = get_time_str(self.time_ms_hide);
|
||||
|
||||
let counter = *writer.cea_708_counter;
|
||||
let line = format!(
|
||||
"{}{}{} --> {}{}",
|
||||
counter, "\r\n", time_show, time_hide, "\r\n"
|
||||
);
|
||||
writer.write_to_file(line.as_bytes())?;
|
||||
|
||||
for row_index in 0..CCX_DTVCC_SCREENGRID_ROWS as usize {
|
||||
if !self.is_row_empty(row_index) {
|
||||
self.write_row(writer, row_index, true)?;
|
||||
writer.write_to_file(b"\r\n")?;
|
||||
}
|
||||
}
|
||||
writer.write_to_file(b"\r\n")?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Write captions in Transcripts format
|
||||
pub fn write_transcript(&self, writer: &mut Writer) -> Result<(), String> {
|
||||
if self.is_screen_empty(writer) {
|
||||
return Ok(());
|
||||
}
|
||||
if self.time_ms_show + writer.subs_delay < 0 {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let time_show = get_time_str(self.time_ms_show);
|
||||
let time_hide = get_time_str(self.time_ms_hide);
|
||||
|
||||
for row_index in 0..CCX_DTVCC_SCREENGRID_ROWS as usize {
|
||||
if !self.is_row_empty(row_index) {
|
||||
let mut buf = String::new();
|
||||
|
||||
if is_true(writer.transcript_settings.showStartTime) {
|
||||
buf.push_str(&time_show);
|
||||
buf.push('|');
|
||||
}
|
||||
if is_true(writer.transcript_settings.showEndTime) {
|
||||
buf.push_str(&time_hide);
|
||||
buf.push('|');
|
||||
}
|
||||
if is_true(writer.transcript_settings.showCC) {
|
||||
buf.push_str("CC1|"); //always CC1 because CEA-708 is field-independent
|
||||
}
|
||||
if is_true(writer.transcript_settings.showMode) {
|
||||
buf.push_str("POP|"); //TODO caption mode(pop, rollup, etc.)
|
||||
}
|
||||
writer.write_to_file(buf.as_bytes())?;
|
||||
self.write_row(writer, row_index, false)?;
|
||||
writer.write_to_file(b"\r\n")?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Write captions in SAMI format
|
||||
pub fn write_sami(&self, writer: &mut Writer) -> Result<(), String> {
|
||||
if self.is_screen_empty(writer) {
|
||||
return Err("Sami:- Screen is empty".to_owned());
|
||||
}
|
||||
if self.time_ms_show + writer.subs_delay < 0 {
|
||||
return Err(format!(
|
||||
"Sami:- timing is -ve, {}:{}",
|
||||
self.time_ms_show, writer.subs_delay
|
||||
));
|
||||
}
|
||||
if self.cc_count == 1 {
|
||||
self.write_sami_header(writer)?;
|
||||
}
|
||||
let buf = format!(
|
||||
"<sync start={}><p class=\"unknowncc\">\r\n",
|
||||
self.time_ms_show + writer.subs_delay
|
||||
);
|
||||
writer.write_to_file(buf.as_bytes())?;
|
||||
|
||||
for row_index in 0..CCX_DTVCC_SCREENGRID_ROWS as usize {
|
||||
if !self.is_row_empty(row_index) {
|
||||
self.write_row(writer, row_index, true)?;
|
||||
writer.write_to_file("<br>\r\n".as_bytes())?;
|
||||
}
|
||||
}
|
||||
let buf = format!(
|
||||
"<sync start={}><p class=\"unknowncc\"> </p></sync>\r\n\r\n",
|
||||
self.time_ms_hide + writer.subs_delay
|
||||
);
|
||||
writer.write_to_file(buf.as_bytes())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Writes the header according to the SAMI format
|
||||
pub fn write_sami_header(&self, writer: &mut Writer) -> Result<(), String> {
|
||||
let buf = b"<sami>\r\n\
|
||||
<head>\r\n\
|
||||
<style type=\"text/css\">\r\n\
|
||||
<!--\r\n\
|
||||
p {margin-left: 16pt; margin-right: 16pt; margin-bottom: 16pt; margin-top: 16pt;\r\n\
|
||||
text-align: center; font-size: 18pt; font-family: arial; font-weight: bold; color: #f0f0f0;}\r\n\
|
||||
.unknowncc {Name:Unknown; lang:en-US; SAMIType:CC;}\r\n\
|
||||
-->\r\n\
|
||||
</style>\r\n\
|
||||
</head>\r\n\r\n\
|
||||
<body>\r\n";
|
||||
|
||||
writer.write_to_file(buf)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Write debug messages
|
||||
///
|
||||
/// Write all characters,show and hide time as a debug log
|
||||
pub fn write_debug(&self) {
|
||||
let time_show = get_time_str(self.time_ms_show);
|
||||
let time_hide = get_time_str(self.time_ms_hide);
|
||||
debug!("{} --> {}", time_show, time_hide);
|
||||
|
||||
for row_index in 0..CCX_DTVCC_SCREENGRID_ROWS as usize {
|
||||
if !self.is_row_empty(row_index) {
|
||||
let mut buf = String::new();
|
||||
let (first, last) = self.get_write_interval(row_index);
|
||||
for sym in self.chars[row_index][first..=last].iter() {
|
||||
buf.push_str(&format!("{:04X},", sym.sym));
|
||||
}
|
||||
debug!("{}", buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if TV screen has no text
|
||||
///
|
||||
/// If any text is found then 708 counter is incremented
|
||||
pub fn is_screen_empty(&self, writer: &mut Writer) -> bool {
|
||||
for index in 0..CCX_DTVCC_SCREENGRID_ROWS as usize {
|
||||
if !self.is_row_empty(index) {
|
||||
// we will write subtitle
|
||||
*writer.cea_708_counter += 1;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
/// Returns `true` if row has no text
|
||||
pub fn is_row_empty(&self, row_index: usize) -> bool {
|
||||
for col_index in 0..CCX_DTVCC_SCREENGRID_COLUMNS as usize {
|
||||
if self.chars[row_index][col_index].is_set() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
/// Add underline(<u>) and italic(<i>) tags according to the pen attributes
|
||||
///
|
||||
/// Open specifies if tag is an opening or closing tag
|
||||
pub fn change_pen_attribs(
|
||||
&self,
|
||||
pen_attribs: &dtvcc_pen_attribs,
|
||||
no_font_color: bool,
|
||||
row_index: usize,
|
||||
col_index: usize,
|
||||
open: bool,
|
||||
buf: &mut Vec<u8>,
|
||||
) {
|
||||
if no_font_color {
|
||||
return;
|
||||
}
|
||||
let new_pen_attribs = if col_index >= CCX_DTVCC_SCREENGRID_COLUMNS as usize {
|
||||
dtvcc_pen_attribs::default()
|
||||
} else {
|
||||
self.pen_attribs[row_index][col_index]
|
||||
};
|
||||
|
||||
if pen_attribs.italic != new_pen_attribs.italic {
|
||||
if is_true(pen_attribs.italic) && !open {
|
||||
buf.extend_from_slice(b"</i>");
|
||||
} else if is_false(pen_attribs.italic) && open {
|
||||
buf.extend_from_slice(b"<i>");
|
||||
}
|
||||
}
|
||||
if pen_attribs.underline != new_pen_attribs.underline {
|
||||
if is_true(pen_attribs.underline) && !open {
|
||||
buf.extend_from_slice(b"</u>");
|
||||
} else if is_false(pen_attribs.underline) && open {
|
||||
buf.extend_from_slice(b"<u>");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Add font(<font color="xxx">) tag according to the pen color
|
||||
///
|
||||
/// Open specifies if tag is an opening or closing tag
|
||||
pub fn change_pen_color(
|
||||
&self,
|
||||
pen_color: &dtvcc_pen_color,
|
||||
no_font_color: bool,
|
||||
row_index: usize,
|
||||
col_index: usize,
|
||||
open: bool,
|
||||
buf: &mut Vec<u8>,
|
||||
) {
|
||||
if no_font_color {
|
||||
return;
|
||||
}
|
||||
let new_pen_color = if col_index >= CCX_DTVCC_SCREENGRID_COLUMNS as usize {
|
||||
dtvcc_pen_color::default()
|
||||
} else {
|
||||
self.pen_colors[row_index][col_index]
|
||||
};
|
||||
if pen_color.fg_color != new_pen_color.fg_color {
|
||||
if pen_color.fg_color != 0x3F && !open {
|
||||
// should close older non-white color
|
||||
buf.extend_from_slice(b"</font>");
|
||||
} else if new_pen_color.fg_color != 0x3F && open {
|
||||
debug!("Colors: {}", col_index);
|
||||
let (mut red, mut green, mut blue) = color_to_hex(new_pen_color.fg_color as u8);
|
||||
red *= 255 / 3;
|
||||
green *= 255 / 3;
|
||||
blue *= 255 / 3;
|
||||
let font_tag = format!("<font color=\"{:02x}{:02x}{:02x}\">", red, green, blue);
|
||||
buf.extend_from_slice(font_tag.as_bytes());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
550
src/rust/src/decoder/window.rs
Normal file
550
src/rust/src/decoder/window.rs
Normal file
@@ -0,0 +1,550 @@
|
||||
//! Caption windows
|
||||
//!
|
||||
//! Refer Section 8.4 CEA-708-E
|
||||
//!
|
||||
//! All caption text is displayed and manipulated in the context of caption windows. There are 8
|
||||
//! possible windows per service in which caption providers may write caption text.
|
||||
//! Each of the eight windows is uniquely addressed by its window ID. Window ID
|
||||
//! numbers range from 0 to 7.
|
||||
//!
|
||||
//! At any time there is a current window to which all subsequent
|
||||
//! window/pen commands are directed. All caption text is written to the current window
|
||||
|
||||
use std::{
|
||||
alloc::{alloc_zeroed, dealloc, Layout},
|
||||
intrinsics::copy_nonoverlapping,
|
||||
};
|
||||
|
||||
use super::timing::get_time_str;
|
||||
use super::{
|
||||
CCX_DTVCC_MAX_COLUMNS, CCX_DTVCC_MAX_ROWS, CCX_DTVCC_SCREENGRID_COLUMNS,
|
||||
CCX_DTVCC_SCREENGRID_ROWS,
|
||||
};
|
||||
use crate::{bindings::*, utils::is_true};
|
||||
|
||||
use log::{debug, error};
|
||||
|
||||
impl dtvcc_window {
|
||||
/// Sets the window style according to the window preset
|
||||
pub fn set_style(&mut self, preset: WindowPreset) {
|
||||
let style_id = preset as i32;
|
||||
let window_style = WindowStyle::new(preset);
|
||||
self.win_style = style_id;
|
||||
self.attribs.border_color = window_style.border_color as i32;
|
||||
self.attribs.border_type = window_style.border_type as i32;
|
||||
self.attribs.display_effect = window_style.display_effect as i32;
|
||||
self.attribs.effect_direction = window_style.effect_direction as i32;
|
||||
self.attribs.effect_speed = window_style.effect_speed as i32;
|
||||
self.attribs.fill_color = window_style.fill_color as i32;
|
||||
self.attribs.fill_opacity = window_style.fill_opacity as i32;
|
||||
self.attribs.justify = window_style.justify as i32;
|
||||
self.attribs.print_direction = window_style.print_direction as i32;
|
||||
self.attribs.scroll_direction = window_style.scroll_direction as i32;
|
||||
self.attribs.word_wrap = window_style.word_wrap as i32;
|
||||
}
|
||||
/// Sets the pen style according to the pen preset
|
||||
pub fn set_pen_style(&mut self, preset: PenPreset) {
|
||||
let pen_style = PenStyle::new(preset);
|
||||
let pen = &mut self.pen_attribs_pattern;
|
||||
pen.pen_size = pen_style.pen_size as i32;
|
||||
pen.offset = pen_style.offset as i32;
|
||||
pen.edge_type = pen_style.edge_type as i32;
|
||||
pen.underline = pen_style.underline as i32;
|
||||
pen.italic = pen_style.italics as i32;
|
||||
|
||||
let pen_color = &mut self.pen_color_pattern;
|
||||
pen_color.fg_color = pen_style.color.fg_color as i32;
|
||||
pen_color.fg_opacity = pen_style.color.fg_opacity as i32;
|
||||
pen_color.bg_color = pen_style.color.bg_color as i32;
|
||||
pen_color.bg_opacity = pen_style.color.bg_opacity as i32;
|
||||
pen_color.edge_color = pen_style.color.edge_color as i32;
|
||||
}
|
||||
/// Update the show time for the window
|
||||
pub fn update_time_show(&mut self, timing: &mut ccx_common_timing_ctx) {
|
||||
self.time_ms_show = timing.get_visible_start(3);
|
||||
let time = get_time_str(self.time_ms_show);
|
||||
debug!("[W-{}] show time updated to {}", self.number, time);
|
||||
}
|
||||
/// Update the hide time for the window
|
||||
pub fn update_time_hide(&mut self, timing: &mut ccx_common_timing_ctx) {
|
||||
self.time_ms_hide = timing.get_visible_end(3);
|
||||
let time = get_time_str(self.time_ms_hide);
|
||||
debug!("[W-{}] hide time updated to {}", self.number, time);
|
||||
}
|
||||
/// Get dimensions of the window
|
||||
///
|
||||
/// The dimensions of a unique window specify an area on the screen which may contain caption text.
|
||||
pub fn get_dimensions(&self) -> Result<(i32, i32, i32, i32), String> {
|
||||
let anchor = dtvcc_pen_anchor_point::new(self.anchor_point)?;
|
||||
let (mut x1, mut x2, mut y1, mut y2) = match anchor {
|
||||
dtvcc_pen_anchor_point::DTVCC_ANCHOR_POINT_TOP_LEFT => (
|
||||
self.anchor_vertical,
|
||||
self.anchor_vertical + self.row_count,
|
||||
self.anchor_horizontal,
|
||||
self.anchor_horizontal + self.col_count,
|
||||
),
|
||||
dtvcc_pen_anchor_point::DTVCC_ANCHOR_POINT_TOP_CENTER => (
|
||||
self.anchor_vertical,
|
||||
self.anchor_vertical + self.row_count,
|
||||
self.anchor_horizontal - self.col_count,
|
||||
self.anchor_horizontal + self.col_count / 2,
|
||||
),
|
||||
dtvcc_pen_anchor_point::DTVCC_ANCHOR_POINT_TOP_RIGHT => (
|
||||
self.anchor_vertical,
|
||||
self.anchor_vertical + self.row_count,
|
||||
self.anchor_horizontal - self.col_count,
|
||||
self.anchor_horizontal,
|
||||
),
|
||||
dtvcc_pen_anchor_point::DTVCC_ANCHOR_POINT_MIDDLE_LEFT => (
|
||||
self.anchor_vertical - self.row_count / 2,
|
||||
self.anchor_vertical + self.row_count / 2,
|
||||
self.anchor_horizontal,
|
||||
self.anchor_horizontal + self.col_count,
|
||||
),
|
||||
dtvcc_pen_anchor_point::DTVCC_ANCHOR_POINT_MIDDLE_CENTER => (
|
||||
self.anchor_vertical - self.row_count / 2,
|
||||
self.anchor_vertical + self.row_count / 2,
|
||||
self.anchor_horizontal - self.col_count / 2,
|
||||
self.anchor_horizontal + self.col_count / 2,
|
||||
),
|
||||
dtvcc_pen_anchor_point::DTVCC_ANCHOR_POINT_MIDDLE_RIGHT => (
|
||||
self.anchor_vertical - self.row_count / 2,
|
||||
self.anchor_vertical + self.row_count / 2,
|
||||
self.anchor_horizontal - self.col_count,
|
||||
self.anchor_horizontal,
|
||||
),
|
||||
dtvcc_pen_anchor_point::DTVCC_ANCHOR_POINT_BOTTOM_LEFT => (
|
||||
self.anchor_vertical - self.row_count,
|
||||
self.anchor_vertical,
|
||||
self.anchor_horizontal,
|
||||
self.anchor_horizontal + self.col_count,
|
||||
),
|
||||
dtvcc_pen_anchor_point::DTVCC_ANCHOR_POINT_BOTTOM_CENTER => (
|
||||
self.anchor_vertical - self.row_count,
|
||||
self.anchor_vertical,
|
||||
self.anchor_horizontal - self.col_count / 2,
|
||||
self.anchor_horizontal + self.col_count / 2,
|
||||
),
|
||||
dtvcc_pen_anchor_point::DTVCC_ANCHOR_POINT_BOTTOM_RIGHT => (
|
||||
self.anchor_vertical - self.row_count,
|
||||
self.anchor_vertical,
|
||||
self.anchor_horizontal - self.col_count,
|
||||
self.anchor_horizontal,
|
||||
),
|
||||
};
|
||||
if x1 < 0 {
|
||||
x1 = 0
|
||||
}
|
||||
if y1 < 0 {
|
||||
y1 = 0
|
||||
}
|
||||
if x2 > CCX_DTVCC_SCREENGRID_ROWS as i32 {
|
||||
x2 = CCX_DTVCC_SCREENGRID_ROWS as i32
|
||||
}
|
||||
if y2 > CCX_DTVCC_SCREENGRID_COLUMNS as i32 {
|
||||
y2 = CCX_DTVCC_SCREENGRID_COLUMNS as i32
|
||||
}
|
||||
Ok((x1, x2, y1, y2))
|
||||
}
|
||||
/// Clear all text from the window
|
||||
pub fn clear_text(&mut self) {
|
||||
// Set pen color to default value
|
||||
self.pen_color_pattern = dtvcc_pen_color::default();
|
||||
// Set pen attributes to default value
|
||||
self.pen_attribs_pattern = dtvcc_pen_attribs::default();
|
||||
for row in 0..CCX_DTVCC_MAX_ROWS as usize {
|
||||
self.clear_row(row);
|
||||
}
|
||||
self.is_empty = 1;
|
||||
}
|
||||
/// Clear text from the selected row
|
||||
pub fn clear_row(&mut self, row_index: usize) {
|
||||
if is_true(self.memory_reserved) {
|
||||
unsafe {
|
||||
let layout = Layout::array::<dtvcc_symbol>(CCX_DTVCC_MAX_COLUMNS as usize);
|
||||
if let Err(e) = layout {
|
||||
error!("clear_row: Incorrect Layout, {}", e);
|
||||
} else {
|
||||
let layout = layout.unwrap();
|
||||
// deallocate previous memory
|
||||
dealloc(self.rows[row_index] as *mut u8, layout);
|
||||
|
||||
// allocate new zero initialized memory
|
||||
let ptr = alloc_zeroed(layout);
|
||||
if ptr.is_null() {
|
||||
error!("clear_row: Not enough memory",);
|
||||
}
|
||||
self.rows[row_index] = ptr as *mut dtvcc_symbol;
|
||||
}
|
||||
}
|
||||
for col in 0..CCX_DTVCC_MAX_COLUMNS as usize {
|
||||
// Set pen attributes to default value
|
||||
self.pen_attribs[row_index][col] = dtvcc_pen_attribs {
|
||||
pen_size: dtvcc_pen_size::DTVCC_PEN_SIZE_STANDART as i32,
|
||||
offset: 0,
|
||||
text_tag: dtvcc_pen_text_tag::DTVCC_PEN_TEXT_TAG_UNDEFINED_12 as i32,
|
||||
font_tag: 0,
|
||||
edge_type: dtvcc_pen_edge::DTVCC_PEN_EDGE_NONE as i32,
|
||||
underline: 0,
|
||||
italic: 0,
|
||||
};
|
||||
// Set pen color to default value
|
||||
self.pen_colors[row_index][col] = dtvcc_pen_color {
|
||||
fg_color: 0x3F,
|
||||
fg_opacity: 0,
|
||||
bg_color: 0,
|
||||
bg_opacity: 0,
|
||||
edge_color: 0,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
/// Roll-up the captions
|
||||
///
|
||||
/// Scroll all the rows above by 1 to achieve the rollup effect
|
||||
pub fn rollup(&mut self) {
|
||||
debug!("roller");
|
||||
for row_index in 0..(self.row_count - 1) as usize {
|
||||
let curr_row = self.rows[row_index];
|
||||
let next_row = self.rows[row_index + 1] as *const dtvcc_symbol;
|
||||
unsafe { copy_nonoverlapping(next_row, curr_row, CCX_DTVCC_MAX_COLUMNS as usize) };
|
||||
for col_index in 0..CCX_DTVCC_MAX_COLUMNS as usize {
|
||||
self.pen_colors[row_index][col_index] = self.pen_colors[row_index + 1][col_index];
|
||||
self.pen_attribs[row_index][col_index] = self.pen_attribs[row_index + 1][col_index];
|
||||
}
|
||||
}
|
||||
self.clear_row((self.row_count - 1) as usize);
|
||||
}
|
||||
}
|
||||
|
||||
impl dtvcc_window_pd {
|
||||
/// Create new window direction
|
||||
pub fn new(direction: i32) -> Result<Self, String> {
|
||||
match direction {
|
||||
0 => Ok(dtvcc_window_pd::DTVCC_WINDOW_PD_LEFT_RIGHT),
|
||||
1 => Ok(dtvcc_window_pd::DTVCC_WINDOW_PD_RIGHT_LEFT),
|
||||
2 => Ok(dtvcc_window_pd::DTVCC_WINDOW_PD_TOP_BOTTOM),
|
||||
3 => Ok(dtvcc_window_pd::DTVCC_WINDOW_PD_BOTTOM_TOP),
|
||||
_ => Err(String::from("Invalid print direction")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl dtvcc_pen_anchor_point {
|
||||
/// Create new pen anchor point
|
||||
pub fn new(anchor: i32) -> Result<Self, String> {
|
||||
match anchor {
|
||||
0 => Ok(dtvcc_pen_anchor_point::DTVCC_ANCHOR_POINT_TOP_LEFT),
|
||||
1 => Ok(dtvcc_pen_anchor_point::DTVCC_ANCHOR_POINT_TOP_CENTER),
|
||||
2 => Ok(dtvcc_pen_anchor_point::DTVCC_ANCHOR_POINT_TOP_RIGHT),
|
||||
3 => Ok(dtvcc_pen_anchor_point::DTVCC_ANCHOR_POINT_MIDDLE_LEFT),
|
||||
4 => Ok(dtvcc_pen_anchor_point::DTVCC_ANCHOR_POINT_MIDDLE_CENTER),
|
||||
5 => Ok(dtvcc_pen_anchor_point::DTVCC_ANCHOR_POINT_MIDDLE_RIGHT),
|
||||
6 => Ok(dtvcc_pen_anchor_point::DTVCC_ANCHOR_POINT_BOTTOM_LEFT),
|
||||
7 => Ok(dtvcc_pen_anchor_point::DTVCC_ANCHOR_POINT_BOTTOM_CENTER),
|
||||
8 => Ok(dtvcc_pen_anchor_point::DTVCC_ANCHOR_POINT_BOTTOM_RIGHT),
|
||||
_ => Err(String::from("Invalid pen anchor")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Window style for a specific window preset
|
||||
struct WindowStyle {
|
||||
justify: dtvcc_window_justify,
|
||||
print_direction: dtvcc_window_pd,
|
||||
scroll_direction: dtvcc_window_sd,
|
||||
word_wrap: u8,
|
||||
display_effect: dtvcc_window_sde,
|
||||
effect_direction: u8,
|
||||
effect_speed: u8,
|
||||
fill_color: u8,
|
||||
fill_opacity: dtvcc_window_fo,
|
||||
border_type: dtvcc_window_border,
|
||||
border_color: u8,
|
||||
}
|
||||
|
||||
impl WindowStyle {
|
||||
/// Create new window style using a window preset
|
||||
pub fn new(preset: WindowPreset) -> Self {
|
||||
// All styles have these common attributes
|
||||
let effect_direction = 0;
|
||||
let effect_speed = 0;
|
||||
let fill_color = 0;
|
||||
let border_color = 0;
|
||||
let display_effect = dtvcc_window_sde::DTVCC_WINDOW_SDE_SNAP;
|
||||
let border_type = dtvcc_window_border::DTVCC_WINDOW_BORDER_NONE;
|
||||
|
||||
let (justify, pd, sd, word_wrap, fill_opacity) = match preset {
|
||||
WindowPreset::NtscPopup => (
|
||||
dtvcc_window_justify::DTVCC_WINDOW_JUSTIFY_LEFT,
|
||||
dtvcc_window_pd::DTVCC_WINDOW_PD_LEFT_RIGHT,
|
||||
dtvcc_window_sd::DTVCC_WINDOW_SD_BOTTOM_TOP,
|
||||
0,
|
||||
dtvcc_window_fo::DTVCC_WINDOW_FO_SOLID,
|
||||
),
|
||||
WindowPreset::Popup => (
|
||||
dtvcc_window_justify::DTVCC_WINDOW_JUSTIFY_LEFT,
|
||||
dtvcc_window_pd::DTVCC_WINDOW_PD_LEFT_RIGHT,
|
||||
dtvcc_window_sd::DTVCC_WINDOW_SD_BOTTOM_TOP,
|
||||
0,
|
||||
dtvcc_window_fo::DTVCC_WINDOW_FO_TRANSPARENT,
|
||||
),
|
||||
WindowPreset::NtscCenteredPopup => (
|
||||
dtvcc_window_justify::DTVCC_WINDOW_JUSTIFY_CENTER,
|
||||
dtvcc_window_pd::DTVCC_WINDOW_PD_LEFT_RIGHT,
|
||||
dtvcc_window_sd::DTVCC_WINDOW_SD_BOTTOM_TOP,
|
||||
0,
|
||||
dtvcc_window_fo::DTVCC_WINDOW_FO_SOLID,
|
||||
),
|
||||
WindowPreset::NtscRollup => (
|
||||
dtvcc_window_justify::DTVCC_WINDOW_JUSTIFY_LEFT,
|
||||
dtvcc_window_pd::DTVCC_WINDOW_PD_LEFT_RIGHT,
|
||||
dtvcc_window_sd::DTVCC_WINDOW_SD_BOTTOM_TOP,
|
||||
1,
|
||||
dtvcc_window_fo::DTVCC_WINDOW_FO_SOLID,
|
||||
),
|
||||
WindowPreset::Rollup => (
|
||||
dtvcc_window_justify::DTVCC_WINDOW_JUSTIFY_LEFT,
|
||||
dtvcc_window_pd::DTVCC_WINDOW_PD_LEFT_RIGHT,
|
||||
dtvcc_window_sd::DTVCC_WINDOW_SD_BOTTOM_TOP,
|
||||
1,
|
||||
dtvcc_window_fo::DTVCC_WINDOW_FO_TRANSPARENT,
|
||||
),
|
||||
WindowPreset::NtscCenteredRollup => (
|
||||
dtvcc_window_justify::DTVCC_WINDOW_JUSTIFY_CENTER,
|
||||
dtvcc_window_pd::DTVCC_WINDOW_PD_LEFT_RIGHT,
|
||||
dtvcc_window_sd::DTVCC_WINDOW_SD_BOTTOM_TOP,
|
||||
1,
|
||||
dtvcc_window_fo::DTVCC_WINDOW_FO_SOLID,
|
||||
),
|
||||
WindowPreset::TickerTape => (
|
||||
dtvcc_window_justify::DTVCC_WINDOW_JUSTIFY_LEFT,
|
||||
dtvcc_window_pd::DTVCC_WINDOW_PD_TOP_BOTTOM,
|
||||
dtvcc_window_sd::DTVCC_WINDOW_SD_RIGHT_LEFT,
|
||||
0,
|
||||
dtvcc_window_fo::DTVCC_WINDOW_FO_SOLID,
|
||||
),
|
||||
};
|
||||
Self {
|
||||
justify,
|
||||
print_direction: pd,
|
||||
scroll_direction: sd,
|
||||
word_wrap,
|
||||
display_effect,
|
||||
effect_direction,
|
||||
effect_speed,
|
||||
fill_color,
|
||||
fill_opacity,
|
||||
border_type,
|
||||
border_color,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Predefined window style ids
|
||||
#[derive(Clone, Copy)]
|
||||
pub enum WindowPreset {
|
||||
/// #1 NTSC Style Popup Captions
|
||||
NtscPopup = 1,
|
||||
/// #2 Popup Captions w/o Black Background
|
||||
Popup = 2,
|
||||
/// #3 NTSC Style Centered Popup Captions
|
||||
NtscCenteredPopup = 3,
|
||||
/// #4 NTSC Style Rollup Captions
|
||||
NtscRollup = 4,
|
||||
/// #4 Rollup Captions w/o Black Background
|
||||
Rollup = 5,
|
||||
/// #6 NTSC Style Centered Rollup Captions
|
||||
NtscCenteredRollup = 6,
|
||||
/// #7 Ticker Tape
|
||||
TickerTape = 7,
|
||||
}
|
||||
|
||||
impl WindowPreset {
|
||||
/// Returns a 'WindowPreset' according to the style id
|
||||
pub fn get_style(style_id: u8) -> Result<Self, String> {
|
||||
match style_id {
|
||||
1 => Ok(WindowPreset::NtscPopup),
|
||||
2 => Ok(WindowPreset::Popup),
|
||||
3 => Ok(WindowPreset::NtscCenteredPopup),
|
||||
4 => Ok(WindowPreset::NtscRollup),
|
||||
5 => Ok(WindowPreset::Rollup),
|
||||
6 => Ok(WindowPreset::NtscCenteredRollup),
|
||||
7 => Ok(WindowPreset::TickerTape),
|
||||
_ => Err("Invalid style".to_owned()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Predefined pen style ids
|
||||
#[derive(PartialEq)]
|
||||
pub enum PenPreset {
|
||||
/// #1 Default NTSC Style
|
||||
NtscStyle,
|
||||
/// #2 NTSC Style Mono w/ Serif
|
||||
NtscStyleMonoSerif,
|
||||
/// #3 NTSC Style Prop w/ Serif
|
||||
NtscStylePropSerif,
|
||||
/// #4 NTSC Style Mono w/o Serif
|
||||
NtscStyleMono,
|
||||
/// #5 NTSC Style Prop w/o Serif
|
||||
NtscStyleProp,
|
||||
/// #6 Mono w/o Serif, Bordered Text, No bg
|
||||
MonoBordered,
|
||||
/// #7 Prop w/o Serif, Bordered Text, No bg
|
||||
PropBordered,
|
||||
}
|
||||
|
||||
impl PenPreset {
|
||||
/// Returns a 'PenPreset' according to the style id
|
||||
pub fn get_style(style_id: u8) -> Result<Self, String> {
|
||||
match style_id {
|
||||
1 => Ok(PenPreset::NtscStyle),
|
||||
2 => Ok(PenPreset::NtscStyleMonoSerif),
|
||||
3 => Ok(PenPreset::NtscStylePropSerif),
|
||||
4 => Ok(PenPreset::NtscStyleMono),
|
||||
5 => Ok(PenPreset::NtscStyleProp),
|
||||
6 => Ok(PenPreset::MonoBordered),
|
||||
7 => Ok(PenPreset::PropBordered),
|
||||
_ => Err("Invalid style".to_owned()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Pen style for a specific pen preset
|
||||
pub struct PenStyle {
|
||||
/// always standard pen size
|
||||
pen_size: dtvcc_pen_size,
|
||||
/// Font style, ranged from 1-7
|
||||
/// Not being used current in the C code(bindings)
|
||||
_font_style: dtvcc_pen_font_style,
|
||||
offset: dtvcc_pen_offset,
|
||||
/// always no, i.e. 0
|
||||
italics: u8,
|
||||
/// always no, i.e. 0
|
||||
underline: u8,
|
||||
edge_type: dtvcc_pen_edge,
|
||||
color: PenColor,
|
||||
}
|
||||
|
||||
impl PenStyle {
|
||||
/// Create new pen style using a pen preset
|
||||
pub fn new(preset: PenPreset) -> Self {
|
||||
// All styles have these common attributes
|
||||
let pen_size = dtvcc_pen_size::DTVCC_PEN_SIZE_STANDART;
|
||||
let offset = dtvcc_pen_offset::DTVCC_PEN_OFFSET_NORMAL;
|
||||
let italics = 0;
|
||||
let underline = 0;
|
||||
let bg_opacity = match preset {
|
||||
PenPreset::MonoBordered | PenPreset::PropBordered => Opacity::Transparent,
|
||||
_ => Opacity::Solid,
|
||||
};
|
||||
|
||||
let color = PenColor {
|
||||
/// White(2,2,2) i.e 10,10,10 i.e 42
|
||||
fg_color: 42,
|
||||
fg_opacity: Opacity::Solid,
|
||||
/// Either N/A or black, still always 0
|
||||
bg_color: 0,
|
||||
bg_opacity,
|
||||
/// Either N/A or black, still always 0
|
||||
edge_color: 0,
|
||||
};
|
||||
|
||||
let (font_style, edge_type) = match preset {
|
||||
PenPreset::NtscStyle => (
|
||||
dtvcc_pen_font_style::DTVCC_PEN_FONT_STYLE_DEFAULT_OR_UNDEFINED,
|
||||
dtvcc_pen_edge::DTVCC_PEN_EDGE_UNIFORM,
|
||||
),
|
||||
PenPreset::NtscStyleMonoSerif => (
|
||||
dtvcc_pen_font_style::DTVCC_PEN_FONT_STYLE_MONOSPACED_WITH_SERIFS,
|
||||
dtvcc_pen_edge::DTVCC_PEN_EDGE_UNIFORM,
|
||||
),
|
||||
PenPreset::NtscStylePropSerif => (
|
||||
dtvcc_pen_font_style::DTVCC_PEN_FONT_STYLE_PROPORTIONALLY_SPACED_WITH_SERIFS,
|
||||
dtvcc_pen_edge::DTVCC_PEN_EDGE_UNIFORM,
|
||||
),
|
||||
PenPreset::NtscStyleMono => (
|
||||
dtvcc_pen_font_style::DTVCC_PEN_FONT_STYLE_MONOSPACED_WITHOUT_SERIFS,
|
||||
dtvcc_pen_edge::DTVCC_PEN_EDGE_UNIFORM,
|
||||
),
|
||||
PenPreset::NtscStyleProp => (
|
||||
dtvcc_pen_font_style::DTVCC_PEN_FONT_STYLE_PROPORTIONALLY_SPACED_WITHOUT_SERIFS,
|
||||
dtvcc_pen_edge::DTVCC_PEN_EDGE_UNIFORM,
|
||||
),
|
||||
PenPreset::MonoBordered => (
|
||||
dtvcc_pen_font_style::DTVCC_PEN_FONT_STYLE_MONOSPACED_WITHOUT_SERIFS,
|
||||
dtvcc_pen_edge::DTVCC_PEN_EDGE_UNIFORM,
|
||||
),
|
||||
PenPreset::PropBordered => (
|
||||
dtvcc_pen_font_style::DTVCC_PEN_FONT_STYLE_PROPORTIONALLY_SPACED_WITHOUT_SERIFS,
|
||||
dtvcc_pen_edge::DTVCC_PEN_EDGE_UNIFORM,
|
||||
),
|
||||
};
|
||||
|
||||
Self {
|
||||
pen_size,
|
||||
_font_style: font_style,
|
||||
offset,
|
||||
italics,
|
||||
underline,
|
||||
edge_type,
|
||||
color,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Pen Color attributes
|
||||
///
|
||||
/// Set by the SPC(SetPenColor) command. Refer Section 8.10.5.10 CEA-708-E
|
||||
///
|
||||
/// Text written to the current window will have the color attributes specified by
|
||||
/// the most recent SetPenColor command written to the window.
|
||||
struct PenColor {
|
||||
/// Color of text forground body
|
||||
fg_color: u8,
|
||||
/// Opacity of text foreground body
|
||||
fg_opacity: Opacity,
|
||||
/// Color of background box surrounding the text
|
||||
bg_color: u8,
|
||||
/// Opacity of background box surrounding the text
|
||||
bg_opacity: Opacity,
|
||||
/// Color of the outlined edges of text
|
||||
edge_color: u8,
|
||||
}
|
||||
|
||||
/// Opacity of the window/pen colors
|
||||
enum Opacity {
|
||||
Solid = 0,
|
||||
_Flash = 1,
|
||||
_Translucent = 2,
|
||||
Transparent = 3,
|
||||
}
|
||||
|
||||
impl Default for dtvcc_pen_color {
|
||||
/// Returns the default pen color
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
fg_color: 0x3F,
|
||||
fg_opacity: 0,
|
||||
bg_color: 0,
|
||||
bg_opacity: 0,
|
||||
edge_color: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for dtvcc_pen_attribs {
|
||||
/// Returns the default pen attributes
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
pen_size: dtvcc_pen_size::DTVCC_PEN_SIZE_STANDART as i32,
|
||||
offset: 0,
|
||||
text_tag: dtvcc_pen_text_tag::DTVCC_PEN_TEXT_TAG_UNDEFINED_12 as i32,
|
||||
font_tag: 0,
|
||||
edge_type: dtvcc_pen_edge::DTVCC_PEN_EDGE_NONE as i32,
|
||||
underline: 0,
|
||||
italic: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
169
src/rust/src/lib.rs
Normal file
169
src/rust/src/lib.rs
Normal file
@@ -0,0 +1,169 @@
|
||||
//! Rust library for CCExtractor
|
||||
//!
|
||||
//! Currently we are in the process of porting the 708 decoder to rust. See [decoder]
|
||||
|
||||
// Allow C naming style
|
||||
#![allow(non_upper_case_globals)]
|
||||
#![allow(non_camel_case_types)]
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
/// CCExtractor C bindings generated by bindgen
|
||||
#[allow(clippy::all)]
|
||||
pub mod bindings {
|
||||
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
|
||||
}
|
||||
pub mod decoder;
|
||||
pub mod utils;
|
||||
|
||||
#[cfg(windows)]
|
||||
use std::os::windows::io::{FromRawHandle, RawHandle};
|
||||
use std::{io::Write, os::raw::c_int};
|
||||
|
||||
use bindings::*;
|
||||
use decoder::Dtvcc;
|
||||
use utils::is_true;
|
||||
|
||||
use env_logger::{builder, Target};
|
||||
use log::{warn, LevelFilter};
|
||||
|
||||
extern "C" {
|
||||
static mut cb_708: c_int;
|
||||
static mut cb_field1: c_int;
|
||||
static mut cb_field2: c_int;
|
||||
}
|
||||
|
||||
/// Initialize env logger with custom format, using stdout as target
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ccxr_init_logger() {
|
||||
builder()
|
||||
.format(|buf, record| writeln!(buf, "[CEA-708] {}", record.args()))
|
||||
.filter_level(LevelFilter::Debug)
|
||||
.target(Target::Stdout)
|
||||
.init();
|
||||
}
|
||||
|
||||
/// Process cc_data
|
||||
///
|
||||
/// # Safety
|
||||
/// dec_ctx should not be a null pointer
|
||||
/// data should point to cc_data of length cc_count
|
||||
#[no_mangle]
|
||||
extern "C" fn ccxr_process_cc_data(
|
||||
dec_ctx: *mut lib_cc_decode,
|
||||
data: *const ::std::os::raw::c_uchar,
|
||||
cc_count: c_int,
|
||||
) -> c_int {
|
||||
let mut ret = -1;
|
||||
let mut cc_data: Vec<u8> = (0..cc_count * 3)
|
||||
.map(|x| unsafe { *data.add(x as usize) })
|
||||
.collect();
|
||||
let dec_ctx = unsafe { &mut *dec_ctx };
|
||||
let dtvcc_ctx = unsafe { &mut *dec_ctx.dtvcc };
|
||||
let mut dtvcc = Dtvcc::new(dtvcc_ctx);
|
||||
for cc_block in cc_data.chunks_exact_mut(3) {
|
||||
if !validate_cc_pair(cc_block) {
|
||||
continue;
|
||||
}
|
||||
let success = do_cb(dec_ctx, &mut dtvcc, cc_block);
|
||||
if success {
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
/// Returns `true` if cc_block pair is valid
|
||||
///
|
||||
/// For CEA-708 data, only cc_valid is checked
|
||||
/// For CEA-608 data, parity is also checked
|
||||
pub fn validate_cc_pair(cc_block: &mut [u8]) -> bool {
|
||||
let cc_valid = (cc_block[0] & 4) >> 2;
|
||||
let cc_type = cc_block[0] & 3;
|
||||
if cc_valid == 0 {
|
||||
return false;
|
||||
}
|
||||
if cc_type == 0 || cc_type == 1 {
|
||||
// For CEA-608 data we verify parity.
|
||||
if verify_parity(cc_block[2]) {
|
||||
// If the second byte doesn't pass parity, ignore pair
|
||||
return false;
|
||||
}
|
||||
if verify_parity(cc_block[1]) {
|
||||
// If the first byte doesn't pass parity,
|
||||
// we replace it with a solid blank and process the pair.
|
||||
cc_block[1] = 0x7F;
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
/// Returns `true` if data has odd parity
|
||||
///
|
||||
/// CC uses odd parity (i.e., # of 1's in byte is odd.)
|
||||
pub fn verify_parity(data: u8) -> bool {
|
||||
if data.count_ones() & 1 == 1 {
|
||||
return true;
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
/// Process CC data according to its type
|
||||
pub fn do_cb(ctx: &mut lib_cc_decode, dtvcc: &mut Dtvcc, cc_block: &[u8]) -> bool {
|
||||
let cc_valid = (cc_block[0] & 4) >> 2;
|
||||
let cc_type = cc_block[0] & 3;
|
||||
let mut timeok = true;
|
||||
|
||||
if ctx.write_format != ccx_output_format::CCX_OF_DVDRAW
|
||||
&& ctx.write_format != ccx_output_format::CCX_OF_RAW
|
||||
&& (cc_block[0] == 0xFA || cc_block[0] == 0xFC || cc_block[0] == 0xFD)
|
||||
&& (cc_block[1] & 0x7F) == 0
|
||||
&& (cc_block[2] & 0x7F) == 0
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if cc_valid == 1 || cc_type == 3 {
|
||||
ctx.cc_stats[cc_type as usize] += 1;
|
||||
match cc_type {
|
||||
// Type 0 and 1 are for CEA-608 data. Handled by C code, do nothing
|
||||
0 | 1 => {}
|
||||
// Type 2 and 3 are for CEA-708 data.
|
||||
2 | 3 => {
|
||||
let current_time = unsafe { (*ctx.timing).get_fts(ctx.current_field as u8) };
|
||||
ctx.current_field = 3;
|
||||
|
||||
// Check whether current time is within start and end bounds
|
||||
if is_true(ctx.extraction_start.set)
|
||||
&& current_time < ctx.extraction_start.time_in_ms
|
||||
{
|
||||
timeok = false;
|
||||
}
|
||||
if is_true(ctx.extraction_end.set) && current_time > ctx.extraction_end.time_in_ms {
|
||||
timeok = false;
|
||||
ctx.processed_enough = 1;
|
||||
}
|
||||
|
||||
if timeok && ctx.write_format != ccx_output_format::CCX_OF_RAW {
|
||||
dtvcc.process_cc_data(cc_valid, cc_type, cc_block[1], cc_block[2]);
|
||||
}
|
||||
unsafe { cb_708 += 1 }
|
||||
}
|
||||
_ => warn!("Invalid cc_type"),
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
#[no_mangle]
|
||||
extern "C" fn ccxr_close_handle(handle: RawHandle) {
|
||||
use std::fs::File;
|
||||
|
||||
if handle.is_null() {
|
||||
return;
|
||||
}
|
||||
unsafe {
|
||||
// File will close automatically (due to Drop) once it goes out of scope
|
||||
let _file = File::from_raw_handle(handle);
|
||||
}
|
||||
}
|
||||
11
src/rust/src/utils.rs
Normal file
11
src/rust/src/utils.rs
Normal file
@@ -0,0 +1,11 @@
|
||||
//! Some utility functions to deal with values from C bindings
|
||||
|
||||
/// Check if the value is true (Set to 1). Use only for values from C bindings
|
||||
pub fn is_true<T: Into<i32>>(val: T) -> bool {
|
||||
val.into() == 1
|
||||
}
|
||||
|
||||
/// Check if the value is false (Set to 0). Use only for values from C bindings
|
||||
pub fn is_false<T: Into<i32>>(val: T) -> bool {
|
||||
val.into() == 0
|
||||
}
|
||||
7
src/rust/wrapper.h
Normal file
7
src/rust/wrapper.h
Normal file
@@ -0,0 +1,7 @@
|
||||
#include "../lib_ccx/ccx_decoders_708.h"
|
||||
#include "../lib_ccx/ccx_decoders_common.h"
|
||||
#include "../lib_ccx/ccx_dtvcc.h"
|
||||
#include "../lib_ccx/ccx_decoders_708_output.h"
|
||||
#include "../lib_ccx/ccx_decoders_708_encoding.h"
|
||||
#include "../lib_ccx/ccx_common_timing.h"
|
||||
#include "../lib_ccx/lib_ccx.h"
|
||||
136
src/thirdparty/libpng/arm/arm_init.c
vendored
Normal file
136
src/thirdparty/libpng/arm/arm_init.c
vendored
Normal file
@@ -0,0 +1,136 @@
|
||||
|
||||
/* arm_init.c - NEON optimised filter functions
|
||||
*
|
||||
* Copyright (c) 2018 Cosmin Truta
|
||||
* Copyright (c) 2014,2016 Glenn Randers-Pehrson
|
||||
* Written by Mans Rullgard, 2011.
|
||||
*
|
||||
* This code is released under the libpng license.
|
||||
* For conditions of distribution and use, see the disclaimer
|
||||
* and license in png.h
|
||||
*/
|
||||
|
||||
/* Below, after checking __linux__, various non-C90 POSIX 1003.1 functions are
|
||||
* called.
|
||||
*/
|
||||
#define _POSIX_SOURCE 1
|
||||
|
||||
#include "../pngpriv.h"
|
||||
|
||||
#ifdef PNG_READ_SUPPORTED
|
||||
|
||||
#if PNG_ARM_NEON_OPT > 0
|
||||
#ifdef PNG_ARM_NEON_CHECK_SUPPORTED /* Do run-time checks */
|
||||
/* WARNING: it is strongly recommended that you do not build libpng with
|
||||
* run-time checks for CPU features if at all possible. In the case of the ARM
|
||||
* NEON instructions there is no processor-specific way of detecting the
|
||||
* presence of the required support, therefore run-time detection is extremely
|
||||
* OS specific.
|
||||
*
|
||||
* You may set the macro PNG_ARM_NEON_FILE to the file name of file containing
|
||||
* a fragment of C source code which defines the png_have_neon function. There
|
||||
* are a number of implementations in contrib/arm-neon, but the only one that
|
||||
* has partial support is contrib/arm-neon/linux.c - a generic Linux
|
||||
* implementation which reads /proc/cpufino.
|
||||
*/
|
||||
#ifndef PNG_ARM_NEON_FILE
|
||||
# ifdef __linux__
|
||||
# define PNG_ARM_NEON_FILE "contrib/arm-neon/linux.c"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef PNG_ARM_NEON_FILE
|
||||
|
||||
#include <signal.h> /* for sig_atomic_t */
|
||||
static int png_have_neon(png_structp png_ptr);
|
||||
#include PNG_ARM_NEON_FILE
|
||||
|
||||
#else /* PNG_ARM_NEON_FILE */
|
||||
# error "PNG_ARM_NEON_FILE undefined: no support for run-time ARM NEON checks"
|
||||
#endif /* PNG_ARM_NEON_FILE */
|
||||
#endif /* PNG_ARM_NEON_CHECK_SUPPORTED */
|
||||
|
||||
#ifndef PNG_ALIGNED_MEMORY_SUPPORTED
|
||||
# error "ALIGNED_MEMORY is required; set: -DPNG_ALIGNED_MEMORY_SUPPORTED"
|
||||
#endif
|
||||
|
||||
void
|
||||
png_init_filter_functions_neon(png_structp pp, unsigned int bpp)
|
||||
{
|
||||
/* The switch statement is compiled in for ARM_NEON_API, the call to
|
||||
* png_have_neon is compiled in for ARM_NEON_CHECK. If both are defined
|
||||
* the check is only performed if the API has not set the NEON option on
|
||||
* or off explicitly. In this case the check controls what happens.
|
||||
*
|
||||
* If the CHECK is not compiled in and the option is UNSET the behavior prior
|
||||
* to 1.6.7 was to use the NEON code - this was a bug caused by having the
|
||||
* wrong order of the 'ON' and 'default' cases. UNSET now defaults to OFF,
|
||||
* as documented in png.h
|
||||
*/
|
||||
png_debug(1, "in png_init_filter_functions_neon");
|
||||
#ifdef PNG_ARM_NEON_API_SUPPORTED
|
||||
switch ((pp->options >> PNG_ARM_NEON) & 3)
|
||||
{
|
||||
case PNG_OPTION_UNSET:
|
||||
/* Allow the run-time check to execute if it has been enabled -
|
||||
* thus both API and CHECK can be turned on. If it isn't supported
|
||||
* this case will fall through to the 'default' below, which just
|
||||
* returns.
|
||||
*/
|
||||
#endif /* PNG_ARM_NEON_API_SUPPORTED */
|
||||
#ifdef PNG_ARM_NEON_CHECK_SUPPORTED
|
||||
{
|
||||
static volatile sig_atomic_t no_neon = -1; /* not checked */
|
||||
|
||||
if (no_neon < 0)
|
||||
no_neon = !png_have_neon(pp);
|
||||
|
||||
if (no_neon)
|
||||
return;
|
||||
}
|
||||
#ifdef PNG_ARM_NEON_API_SUPPORTED
|
||||
break;
|
||||
#endif
|
||||
#endif /* PNG_ARM_NEON_CHECK_SUPPORTED */
|
||||
|
||||
#ifdef PNG_ARM_NEON_API_SUPPORTED
|
||||
default: /* OFF or INVALID */
|
||||
return;
|
||||
|
||||
case PNG_OPTION_ON:
|
||||
/* Option turned on */
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* IMPORTANT: any new external functions used here must be declared using
|
||||
* PNG_INTERNAL_FUNCTION in ../pngpriv.h. This is required so that the
|
||||
* 'prefix' option to configure works:
|
||||
*
|
||||
* ./configure --with-libpng-prefix=foobar_
|
||||
*
|
||||
* Verify you have got this right by running the above command, doing a build
|
||||
* and examining pngprefix.h; it must contain a #define for every external
|
||||
* function you add. (Notice that this happens automatically for the
|
||||
* initialization function.)
|
||||
*/
|
||||
pp->read_filter[PNG_FILTER_VALUE_UP-1] = png_read_filter_row_up_neon;
|
||||
|
||||
if (bpp == 3)
|
||||
{
|
||||
pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub3_neon;
|
||||
pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg3_neon;
|
||||
pp->read_filter[PNG_FILTER_VALUE_PAETH-1] =
|
||||
png_read_filter_row_paeth3_neon;
|
||||
}
|
||||
|
||||
else if (bpp == 4)
|
||||
{
|
||||
pp->read_filter[PNG_FILTER_VALUE_SUB-1] = png_read_filter_row_sub4_neon;
|
||||
pp->read_filter[PNG_FILTER_VALUE_AVG-1] = png_read_filter_row_avg4_neon;
|
||||
pp->read_filter[PNG_FILTER_VALUE_PAETH-1] =
|
||||
png_read_filter_row_paeth4_neon;
|
||||
}
|
||||
}
|
||||
#endif /* PNG_ARM_NEON_OPT > 0 */
|
||||
#endif /* READ */
|
||||
253
src/thirdparty/libpng/arm/filter_neon.S
vendored
Normal file
253
src/thirdparty/libpng/arm/filter_neon.S
vendored
Normal file
@@ -0,0 +1,253 @@
|
||||
|
||||
/* filter_neon.S - NEON optimised filter functions
|
||||
*
|
||||
* Copyright (c) 2018 Cosmin Truta
|
||||
* Copyright (c) 2014,2017 Glenn Randers-Pehrson
|
||||
* Written by Mans Rullgard, 2011.
|
||||
*
|
||||
* This code is released under the libpng license.
|
||||
* For conditions of distribution and use, see the disclaimer
|
||||
* and license in png.h
|
||||
*/
|
||||
|
||||
/* This is required to get the symbol renames, which are #defines, and the
|
||||
* definitions (or not) of PNG_ARM_NEON_OPT and PNG_ARM_NEON_IMPLEMENTATION.
|
||||
*/
|
||||
#define PNG_VERSION_INFO_ONLY
|
||||
#include "../pngpriv.h"
|
||||
|
||||
#if (defined(__linux__) || defined(__FreeBSD__)) && defined(__ELF__)
|
||||
.section .note.GNU-stack,"",%progbits /* mark stack as non-executable */
|
||||
#endif
|
||||
|
||||
#ifdef PNG_READ_SUPPORTED
|
||||
|
||||
/* Assembler NEON support - only works for 32-bit ARM (i.e. it does not work for
|
||||
* ARM64). The code in arm/filter_neon_intrinsics.c supports ARM64, however it
|
||||
* only works if -mfpu=neon is specified on the GCC command line. See pngpriv.h
|
||||
* for the logic which sets PNG_USE_ARM_NEON_ASM:
|
||||
*/
|
||||
#if PNG_ARM_NEON_IMPLEMENTATION == 2 /* hand-coded assembler */
|
||||
|
||||
#if PNG_ARM_NEON_OPT > 0
|
||||
|
||||
#ifdef __ELF__
|
||||
# define ELF
|
||||
#else
|
||||
# define ELF @
|
||||
#endif
|
||||
|
||||
.arch armv7-a
|
||||
.fpu neon
|
||||
|
||||
.macro func name, export=0
|
||||
.macro endfunc
|
||||
ELF .size \name, . - \name
|
||||
.endfunc
|
||||
.purgem endfunc
|
||||
.endm
|
||||
.text
|
||||
|
||||
/* Explicitly specifying alignment here because some versions of
|
||||
* GAS don't align code correctly. This is harmless in correctly
|
||||
* written versions of GAS.
|
||||
*/
|
||||
.align 2
|
||||
|
||||
.if \export
|
||||
.global \name
|
||||
.endif
|
||||
ELF .type \name, STT_FUNC
|
||||
.func \name
|
||||
\name:
|
||||
.endm
|
||||
|
||||
func png_read_filter_row_sub4_neon, export=1
|
||||
ldr r3, [r0, #4] @ rowbytes
|
||||
vmov.i8 d3, #0
|
||||
1:
|
||||
vld4.32 {d4[],d5[],d6[],d7[]}, [r1,:128]
|
||||
vadd.u8 d0, d3, d4
|
||||
vadd.u8 d1, d0, d5
|
||||
vadd.u8 d2, d1, d6
|
||||
vadd.u8 d3, d2, d7
|
||||
vst4.32 {d0[0],d1[0],d2[0],d3[0]},[r1,:128]!
|
||||
subs r3, r3, #16
|
||||
bgt 1b
|
||||
|
||||
bx lr
|
||||
endfunc
|
||||
|
||||
func png_read_filter_row_sub3_neon, export=1
|
||||
ldr r3, [r0, #4] @ rowbytes
|
||||
vmov.i8 d3, #0
|
||||
mov r0, r1
|
||||
mov r2, #3
|
||||
mov r12, #12
|
||||
vld1.8 {q11}, [r0], r12
|
||||
1:
|
||||
vext.8 d5, d22, d23, #3
|
||||
vadd.u8 d0, d3, d22
|
||||
vext.8 d6, d22, d23, #6
|
||||
vadd.u8 d1, d0, d5
|
||||
vext.8 d7, d23, d23, #1
|
||||
vld1.8 {q11}, [r0], r12
|
||||
vst1.32 {d0[0]}, [r1,:32], r2
|
||||
vadd.u8 d2, d1, d6
|
||||
vst1.32 {d1[0]}, [r1], r2
|
||||
vadd.u8 d3, d2, d7
|
||||
vst1.32 {d2[0]}, [r1], r2
|
||||
vst1.32 {d3[0]}, [r1], r2
|
||||
subs r3, r3, #12
|
||||
bgt 1b
|
||||
|
||||
bx lr
|
||||
endfunc
|
||||
|
||||
func png_read_filter_row_up_neon, export=1
|
||||
ldr r3, [r0, #4] @ rowbytes
|
||||
1:
|
||||
vld1.8 {q0}, [r1,:128]
|
||||
vld1.8 {q1}, [r2,:128]!
|
||||
vadd.u8 q0, q0, q1
|
||||
vst1.8 {q0}, [r1,:128]!
|
||||
subs r3, r3, #16
|
||||
bgt 1b
|
||||
|
||||
bx lr
|
||||
endfunc
|
||||
|
||||
func png_read_filter_row_avg4_neon, export=1
|
||||
ldr r12, [r0, #4] @ rowbytes
|
||||
vmov.i8 d3, #0
|
||||
1:
|
||||
vld4.32 {d4[],d5[],d6[],d7[]}, [r1,:128]
|
||||
vld4.32 {d16[],d17[],d18[],d19[]},[r2,:128]!
|
||||
vhadd.u8 d0, d3, d16
|
||||
vadd.u8 d0, d0, d4
|
||||
vhadd.u8 d1, d0, d17
|
||||
vadd.u8 d1, d1, d5
|
||||
vhadd.u8 d2, d1, d18
|
||||
vadd.u8 d2, d2, d6
|
||||
vhadd.u8 d3, d2, d19
|
||||
vadd.u8 d3, d3, d7
|
||||
vst4.32 {d0[0],d1[0],d2[0],d3[0]},[r1,:128]!
|
||||
subs r12, r12, #16
|
||||
bgt 1b
|
||||
|
||||
bx lr
|
||||
endfunc
|
||||
|
||||
func png_read_filter_row_avg3_neon, export=1
|
||||
push {r4,lr}
|
||||
ldr r12, [r0, #4] @ rowbytes
|
||||
vmov.i8 d3, #0
|
||||
mov r0, r1
|
||||
mov r4, #3
|
||||
mov lr, #12
|
||||
vld1.8 {q11}, [r0], lr
|
||||
1:
|
||||
vld1.8 {q10}, [r2], lr
|
||||
vext.8 d5, d22, d23, #3
|
||||
vhadd.u8 d0, d3, d20
|
||||
vext.8 d17, d20, d21, #3
|
||||
vadd.u8 d0, d0, d22
|
||||
vext.8 d6, d22, d23, #6
|
||||
vhadd.u8 d1, d0, d17
|
||||
vext.8 d18, d20, d21, #6
|
||||
vadd.u8 d1, d1, d5
|
||||
vext.8 d7, d23, d23, #1
|
||||
vld1.8 {q11}, [r0], lr
|
||||
vst1.32 {d0[0]}, [r1,:32], r4
|
||||
vhadd.u8 d2, d1, d18
|
||||
vst1.32 {d1[0]}, [r1], r4
|
||||
vext.8 d19, d21, d21, #1
|
||||
vadd.u8 d2, d2, d6
|
||||
vhadd.u8 d3, d2, d19
|
||||
vst1.32 {d2[0]}, [r1], r4
|
||||
vadd.u8 d3, d3, d7
|
||||
vst1.32 {d3[0]}, [r1], r4
|
||||
subs r12, r12, #12
|
||||
bgt 1b
|
||||
|
||||
pop {r4,pc}
|
||||
endfunc
|
||||
|
||||
.macro paeth rx, ra, rb, rc
|
||||
vaddl.u8 q12, \ra, \rb @ a + b
|
||||
vaddl.u8 q15, \rc, \rc @ 2*c
|
||||
vabdl.u8 q13, \rb, \rc @ pa
|
||||
vabdl.u8 q14, \ra, \rc @ pb
|
||||
vabd.u16 q15, q12, q15 @ pc
|
||||
vcle.u16 q12, q13, q14 @ pa <= pb
|
||||
vcle.u16 q13, q13, q15 @ pa <= pc
|
||||
vcle.u16 q14, q14, q15 @ pb <= pc
|
||||
vand q12, q12, q13 @ pa <= pb && pa <= pc
|
||||
vmovn.u16 d28, q14
|
||||
vmovn.u16 \rx, q12
|
||||
vbsl d28, \rb, \rc
|
||||
vbsl \rx, \ra, d28
|
||||
.endm
|
||||
|
||||
func png_read_filter_row_paeth4_neon, export=1
|
||||
ldr r12, [r0, #4] @ rowbytes
|
||||
vmov.i8 d3, #0
|
||||
vmov.i8 d20, #0
|
||||
1:
|
||||
vld4.32 {d4[],d5[],d6[],d7[]}, [r1,:128]
|
||||
vld4.32 {d16[],d17[],d18[],d19[]},[r2,:128]!
|
||||
paeth d0, d3, d16, d20
|
||||
vadd.u8 d0, d0, d4
|
||||
paeth d1, d0, d17, d16
|
||||
vadd.u8 d1, d1, d5
|
||||
paeth d2, d1, d18, d17
|
||||
vadd.u8 d2, d2, d6
|
||||
paeth d3, d2, d19, d18
|
||||
vmov d20, d19
|
||||
vadd.u8 d3, d3, d7
|
||||
vst4.32 {d0[0],d1[0],d2[0],d3[0]},[r1,:128]!
|
||||
subs r12, r12, #16
|
||||
bgt 1b
|
||||
|
||||
bx lr
|
||||
endfunc
|
||||
|
||||
func png_read_filter_row_paeth3_neon, export=1
|
||||
push {r4,lr}
|
||||
ldr r12, [r0, #4] @ rowbytes
|
||||
vmov.i8 d3, #0
|
||||
vmov.i8 d4, #0
|
||||
mov r0, r1
|
||||
mov r4, #3
|
||||
mov lr, #12
|
||||
vld1.8 {q11}, [r0], lr
|
||||
1:
|
||||
vld1.8 {q10}, [r2], lr
|
||||
paeth d0, d3, d20, d4
|
||||
vext.8 d5, d22, d23, #3
|
||||
vadd.u8 d0, d0, d22
|
||||
vext.8 d17, d20, d21, #3
|
||||
paeth d1, d0, d17, d20
|
||||
vst1.32 {d0[0]}, [r1,:32], r4
|
||||
vext.8 d6, d22, d23, #6
|
||||
vadd.u8 d1, d1, d5
|
||||
vext.8 d18, d20, d21, #6
|
||||
paeth d2, d1, d18, d17
|
||||
vext.8 d7, d23, d23, #1
|
||||
vld1.8 {q11}, [r0], lr
|
||||
vst1.32 {d1[0]}, [r1], r4
|
||||
vadd.u8 d2, d2, d6
|
||||
vext.8 d19, d21, d21, #1
|
||||
paeth d3, d2, d19, d18
|
||||
vst1.32 {d2[0]}, [r1], r4
|
||||
vmov d4, d19
|
||||
vadd.u8 d3, d3, d7
|
||||
vst1.32 {d3[0]}, [r1], r4
|
||||
subs r12, r12, #12
|
||||
bgt 1b
|
||||
|
||||
pop {r4,pc}
|
||||
endfunc
|
||||
#endif /* PNG_ARM_NEON_OPT > 0 */
|
||||
#endif /* PNG_ARM_NEON_IMPLEMENTATION == 2 (assembler) */
|
||||
#endif /* READ */
|
||||
402
src/thirdparty/libpng/arm/filter_neon_intrinsics.c
vendored
Normal file
402
src/thirdparty/libpng/arm/filter_neon_intrinsics.c
vendored
Normal file
@@ -0,0 +1,402 @@
|
||||
|
||||
/* filter_neon_intrinsics.c - NEON optimised filter functions
|
||||
*
|
||||
* Copyright (c) 2018 Cosmin Truta
|
||||
* Copyright (c) 2014,2016 Glenn Randers-Pehrson
|
||||
* Written by James Yu <james.yu at linaro.org>, October 2013.
|
||||
* Based on filter_neon.S, written by Mans Rullgard, 2011.
|
||||
*
|
||||
* This code is released under the libpng license.
|
||||
* For conditions of distribution and use, see the disclaimer
|
||||
* and license in png.h
|
||||
*/
|
||||
|
||||
#include "../pngpriv.h"
|
||||
|
||||
#ifdef PNG_READ_SUPPORTED
|
||||
|
||||
/* This code requires -mfpu=neon on the command line: */
|
||||
#if PNG_ARM_NEON_IMPLEMENTATION == 1 /* intrinsics code from pngpriv.h */
|
||||
|
||||
#if defined(_MSC_VER) && defined(_M_ARM64)
|
||||
# include <arm64_neon.h>
|
||||
#else
|
||||
# include <arm_neon.h>
|
||||
#endif
|
||||
|
||||
/* libpng row pointers are not necessarily aligned to any particular boundary,
|
||||
* however this code will only work with appropriate alignment. arm/arm_init.c
|
||||
* checks for this (and will not compile unless it is done). This code uses
|
||||
* variants of png_aligncast to avoid compiler warnings.
|
||||
*/
|
||||
#define png_ptr(type,pointer) png_aligncast(type *,pointer)
|
||||
#define png_ptrc(type,pointer) png_aligncastconst(const type *,pointer)
|
||||
|
||||
/* The following relies on a variable 'temp_pointer' being declared with type
|
||||
* 'type'. This is written this way just to hide the GCC strict aliasing
|
||||
* warning; note that the code is safe because there never is an alias between
|
||||
* the input and output pointers.
|
||||
*
|
||||
* When compiling with MSVC ARM64, the png_ldr macro can't be passed directly
|
||||
* to vst4_lane_u32, because of an internal compiler error inside MSVC.
|
||||
* To avoid this compiler bug, we use a temporary variable (vdest_val) to store
|
||||
* the result of png_ldr.
|
||||
*/
|
||||
#define png_ldr(type,pointer)\
|
||||
(temp_pointer = png_ptr(type,pointer), *temp_pointer)
|
||||
|
||||
#if PNG_ARM_NEON_OPT > 0
|
||||
|
||||
void
|
||||
png_read_filter_row_up_neon(png_row_infop row_info, png_bytep row,
|
||||
png_const_bytep prev_row)
|
||||
{
|
||||
png_bytep rp = row;
|
||||
png_bytep rp_stop = row + row_info->rowbytes;
|
||||
png_const_bytep pp = prev_row;
|
||||
|
||||
png_debug(1, "in png_read_filter_row_up_neon");
|
||||
|
||||
for (; rp < rp_stop; rp += 16, pp += 16)
|
||||
{
|
||||
uint8x16_t qrp, qpp;
|
||||
|
||||
qrp = vld1q_u8(rp);
|
||||
qpp = vld1q_u8(pp);
|
||||
qrp = vaddq_u8(qrp, qpp);
|
||||
vst1q_u8(rp, qrp);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
png_read_filter_row_sub3_neon(png_row_infop row_info, png_bytep row,
|
||||
png_const_bytep prev_row)
|
||||
{
|
||||
png_bytep rp = row;
|
||||
png_bytep rp_stop = row + row_info->rowbytes;
|
||||
|
||||
uint8x16_t vtmp = vld1q_u8(rp);
|
||||
uint8x8x2_t *vrpt = png_ptr(uint8x8x2_t, &vtmp);
|
||||
uint8x8x2_t vrp = *vrpt;
|
||||
|
||||
uint8x8x4_t vdest;
|
||||
vdest.val[3] = vdup_n_u8(0);
|
||||
|
||||
png_debug(1, "in png_read_filter_row_sub3_neon");
|
||||
|
||||
for (; rp < rp_stop;)
|
||||
{
|
||||
uint8x8_t vtmp1, vtmp2;
|
||||
uint32x2_t *temp_pointer;
|
||||
|
||||
vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 3);
|
||||
vdest.val[0] = vadd_u8(vdest.val[3], vrp.val[0]);
|
||||
vtmp2 = vext_u8(vrp.val[0], vrp.val[1], 6);
|
||||
vdest.val[1] = vadd_u8(vdest.val[0], vtmp1);
|
||||
|
||||
vtmp1 = vext_u8(vrp.val[1], vrp.val[1], 1);
|
||||
vdest.val[2] = vadd_u8(vdest.val[1], vtmp2);
|
||||
vdest.val[3] = vadd_u8(vdest.val[2], vtmp1);
|
||||
|
||||
vtmp = vld1q_u8(rp + 12);
|
||||
vrpt = png_ptr(uint8x8x2_t, &vtmp);
|
||||
vrp = *vrpt;
|
||||
|
||||
vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[0]), 0);
|
||||
rp += 3;
|
||||
vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[1]), 0);
|
||||
rp += 3;
|
||||
vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[2]), 0);
|
||||
rp += 3;
|
||||
vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[3]), 0);
|
||||
rp += 3;
|
||||
}
|
||||
|
||||
PNG_UNUSED(prev_row)
|
||||
}
|
||||
|
||||
void
|
||||
png_read_filter_row_sub4_neon(png_row_infop row_info, png_bytep row,
|
||||
png_const_bytep prev_row)
|
||||
{
|
||||
png_bytep rp = row;
|
||||
png_bytep rp_stop = row + row_info->rowbytes;
|
||||
|
||||
uint8x8x4_t vdest;
|
||||
vdest.val[3] = vdup_n_u8(0);
|
||||
|
||||
png_debug(1, "in png_read_filter_row_sub4_neon");
|
||||
|
||||
for (; rp < rp_stop; rp += 16)
|
||||
{
|
||||
uint32x2x4_t vtmp = vld4_u32(png_ptr(uint32_t,rp));
|
||||
uint8x8x4_t *vrpt = png_ptr(uint8x8x4_t,&vtmp);
|
||||
uint8x8x4_t vrp = *vrpt;
|
||||
uint32x2x4_t *temp_pointer;
|
||||
uint32x2x4_t vdest_val;
|
||||
|
||||
vdest.val[0] = vadd_u8(vdest.val[3], vrp.val[0]);
|
||||
vdest.val[1] = vadd_u8(vdest.val[0], vrp.val[1]);
|
||||
vdest.val[2] = vadd_u8(vdest.val[1], vrp.val[2]);
|
||||
vdest.val[3] = vadd_u8(vdest.val[2], vrp.val[3]);
|
||||
|
||||
vdest_val = png_ldr(uint32x2x4_t, &vdest);
|
||||
vst4_lane_u32(png_ptr(uint32_t,rp), vdest_val, 0);
|
||||
}
|
||||
|
||||
PNG_UNUSED(prev_row)
|
||||
}
|
||||
|
||||
void
|
||||
png_read_filter_row_avg3_neon(png_row_infop row_info, png_bytep row,
|
||||
png_const_bytep prev_row)
|
||||
{
|
||||
png_bytep rp = row;
|
||||
png_const_bytep pp = prev_row;
|
||||
png_bytep rp_stop = row + row_info->rowbytes;
|
||||
|
||||
uint8x16_t vtmp;
|
||||
uint8x8x2_t *vrpt;
|
||||
uint8x8x2_t vrp;
|
||||
uint8x8x4_t vdest;
|
||||
vdest.val[3] = vdup_n_u8(0);
|
||||
|
||||
vtmp = vld1q_u8(rp);
|
||||
vrpt = png_ptr(uint8x8x2_t,&vtmp);
|
||||
vrp = *vrpt;
|
||||
|
||||
png_debug(1, "in png_read_filter_row_avg3_neon");
|
||||
|
||||
for (; rp < rp_stop; pp += 12)
|
||||
{
|
||||
uint8x8_t vtmp1, vtmp2, vtmp3;
|
||||
|
||||
uint8x8x2_t *vppt;
|
||||
uint8x8x2_t vpp;
|
||||
|
||||
uint32x2_t *temp_pointer;
|
||||
|
||||
vtmp = vld1q_u8(pp);
|
||||
vppt = png_ptr(uint8x8x2_t,&vtmp);
|
||||
vpp = *vppt;
|
||||
|
||||
vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 3);
|
||||
vdest.val[0] = vhadd_u8(vdest.val[3], vpp.val[0]);
|
||||
vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]);
|
||||
|
||||
vtmp2 = vext_u8(vpp.val[0], vpp.val[1], 3);
|
||||
vtmp3 = vext_u8(vrp.val[0], vrp.val[1], 6);
|
||||
vdest.val[1] = vhadd_u8(vdest.val[0], vtmp2);
|
||||
vdest.val[1] = vadd_u8(vdest.val[1], vtmp1);
|
||||
|
||||
vtmp2 = vext_u8(vpp.val[0], vpp.val[1], 6);
|
||||
vtmp1 = vext_u8(vrp.val[1], vrp.val[1], 1);
|
||||
|
||||
vtmp = vld1q_u8(rp + 12);
|
||||
vrpt = png_ptr(uint8x8x2_t,&vtmp);
|
||||
vrp = *vrpt;
|
||||
|
||||
vdest.val[2] = vhadd_u8(vdest.val[1], vtmp2);
|
||||
vdest.val[2] = vadd_u8(vdest.val[2], vtmp3);
|
||||
|
||||
vtmp2 = vext_u8(vpp.val[1], vpp.val[1], 1);
|
||||
|
||||
vdest.val[3] = vhadd_u8(vdest.val[2], vtmp2);
|
||||
vdest.val[3] = vadd_u8(vdest.val[3], vtmp1);
|
||||
|
||||
vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[0]), 0);
|
||||
rp += 3;
|
||||
vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[1]), 0);
|
||||
rp += 3;
|
||||
vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[2]), 0);
|
||||
rp += 3;
|
||||
vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[3]), 0);
|
||||
rp += 3;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
png_read_filter_row_avg4_neon(png_row_infop row_info, png_bytep row,
|
||||
png_const_bytep prev_row)
|
||||
{
|
||||
png_bytep rp = row;
|
||||
png_bytep rp_stop = row + row_info->rowbytes;
|
||||
png_const_bytep pp = prev_row;
|
||||
|
||||
uint8x8x4_t vdest;
|
||||
vdest.val[3] = vdup_n_u8(0);
|
||||
|
||||
png_debug(1, "in png_read_filter_row_avg4_neon");
|
||||
|
||||
for (; rp < rp_stop; rp += 16, pp += 16)
|
||||
{
|
||||
uint32x2x4_t vtmp;
|
||||
uint8x8x4_t *vrpt, *vppt;
|
||||
uint8x8x4_t vrp, vpp;
|
||||
uint32x2x4_t *temp_pointer;
|
||||
uint32x2x4_t vdest_val;
|
||||
|
||||
vtmp = vld4_u32(png_ptr(uint32_t,rp));
|
||||
vrpt = png_ptr(uint8x8x4_t,&vtmp);
|
||||
vrp = *vrpt;
|
||||
vtmp = vld4_u32(png_ptrc(uint32_t,pp));
|
||||
vppt = png_ptr(uint8x8x4_t,&vtmp);
|
||||
vpp = *vppt;
|
||||
|
||||
vdest.val[0] = vhadd_u8(vdest.val[3], vpp.val[0]);
|
||||
vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]);
|
||||
vdest.val[1] = vhadd_u8(vdest.val[0], vpp.val[1]);
|
||||
vdest.val[1] = vadd_u8(vdest.val[1], vrp.val[1]);
|
||||
vdest.val[2] = vhadd_u8(vdest.val[1], vpp.val[2]);
|
||||
vdest.val[2] = vadd_u8(vdest.val[2], vrp.val[2]);
|
||||
vdest.val[3] = vhadd_u8(vdest.val[2], vpp.val[3]);
|
||||
vdest.val[3] = vadd_u8(vdest.val[3], vrp.val[3]);
|
||||
|
||||
vdest_val = png_ldr(uint32x2x4_t, &vdest);
|
||||
vst4_lane_u32(png_ptr(uint32_t,rp), vdest_val, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static uint8x8_t
|
||||
paeth(uint8x8_t a, uint8x8_t b, uint8x8_t c)
|
||||
{
|
||||
uint8x8_t d, e;
|
||||
uint16x8_t p1, pa, pb, pc;
|
||||
|
||||
p1 = vaddl_u8(a, b); /* a + b */
|
||||
pc = vaddl_u8(c, c); /* c * 2 */
|
||||
pa = vabdl_u8(b, c); /* pa */
|
||||
pb = vabdl_u8(a, c); /* pb */
|
||||
pc = vabdq_u16(p1, pc); /* pc */
|
||||
|
||||
p1 = vcleq_u16(pa, pb); /* pa <= pb */
|
||||
pa = vcleq_u16(pa, pc); /* pa <= pc */
|
||||
pb = vcleq_u16(pb, pc); /* pb <= pc */
|
||||
|
||||
p1 = vandq_u16(p1, pa); /* pa <= pb && pa <= pc */
|
||||
|
||||
d = vmovn_u16(pb);
|
||||
e = vmovn_u16(p1);
|
||||
|
||||
d = vbsl_u8(d, b, c);
|
||||
e = vbsl_u8(e, a, d);
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
void
|
||||
png_read_filter_row_paeth3_neon(png_row_infop row_info, png_bytep row,
|
||||
png_const_bytep prev_row)
|
||||
{
|
||||
png_bytep rp = row;
|
||||
png_const_bytep pp = prev_row;
|
||||
png_bytep rp_stop = row + row_info->rowbytes;
|
||||
|
||||
uint8x16_t vtmp;
|
||||
uint8x8x2_t *vrpt;
|
||||
uint8x8x2_t vrp;
|
||||
uint8x8_t vlast = vdup_n_u8(0);
|
||||
uint8x8x4_t vdest;
|
||||
vdest.val[3] = vdup_n_u8(0);
|
||||
|
||||
vtmp = vld1q_u8(rp);
|
||||
vrpt = png_ptr(uint8x8x2_t,&vtmp);
|
||||
vrp = *vrpt;
|
||||
|
||||
png_debug(1, "in png_read_filter_row_paeth3_neon");
|
||||
|
||||
for (; rp < rp_stop; pp += 12)
|
||||
{
|
||||
uint8x8x2_t *vppt;
|
||||
uint8x8x2_t vpp;
|
||||
uint8x8_t vtmp1, vtmp2, vtmp3;
|
||||
uint32x2_t *temp_pointer;
|
||||
|
||||
vtmp = vld1q_u8(pp);
|
||||
vppt = png_ptr(uint8x8x2_t,&vtmp);
|
||||
vpp = *vppt;
|
||||
|
||||
vdest.val[0] = paeth(vdest.val[3], vpp.val[0], vlast);
|
||||
vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]);
|
||||
|
||||
vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 3);
|
||||
vtmp2 = vext_u8(vpp.val[0], vpp.val[1], 3);
|
||||
vdest.val[1] = paeth(vdest.val[0], vtmp2, vpp.val[0]);
|
||||
vdest.val[1] = vadd_u8(vdest.val[1], vtmp1);
|
||||
|
||||
vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 6);
|
||||
vtmp3 = vext_u8(vpp.val[0], vpp.val[1], 6);
|
||||
vdest.val[2] = paeth(vdest.val[1], vtmp3, vtmp2);
|
||||
vdest.val[2] = vadd_u8(vdest.val[2], vtmp1);
|
||||
|
||||
vtmp1 = vext_u8(vrp.val[1], vrp.val[1], 1);
|
||||
vtmp2 = vext_u8(vpp.val[1], vpp.val[1], 1);
|
||||
|
||||
vtmp = vld1q_u8(rp + 12);
|
||||
vrpt = png_ptr(uint8x8x2_t,&vtmp);
|
||||
vrp = *vrpt;
|
||||
|
||||
vdest.val[3] = paeth(vdest.val[2], vtmp2, vtmp3);
|
||||
vdest.val[3] = vadd_u8(vdest.val[3], vtmp1);
|
||||
|
||||
vlast = vtmp2;
|
||||
|
||||
vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[0]), 0);
|
||||
rp += 3;
|
||||
vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[1]), 0);
|
||||
rp += 3;
|
||||
vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[2]), 0);
|
||||
rp += 3;
|
||||
vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[3]), 0);
|
||||
rp += 3;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
png_read_filter_row_paeth4_neon(png_row_infop row_info, png_bytep row,
|
||||
png_const_bytep prev_row)
|
||||
{
|
||||
png_bytep rp = row;
|
||||
png_bytep rp_stop = row + row_info->rowbytes;
|
||||
png_const_bytep pp = prev_row;
|
||||
|
||||
uint8x8_t vlast = vdup_n_u8(0);
|
||||
uint8x8x4_t vdest;
|
||||
vdest.val[3] = vdup_n_u8(0);
|
||||
|
||||
png_debug(1, "in png_read_filter_row_paeth4_neon");
|
||||
|
||||
for (; rp < rp_stop; rp += 16, pp += 16)
|
||||
{
|
||||
uint32x2x4_t vtmp;
|
||||
uint8x8x4_t *vrpt, *vppt;
|
||||
uint8x8x4_t vrp, vpp;
|
||||
uint32x2x4_t *temp_pointer;
|
||||
uint32x2x4_t vdest_val;
|
||||
|
||||
vtmp = vld4_u32(png_ptr(uint32_t,rp));
|
||||
vrpt = png_ptr(uint8x8x4_t,&vtmp);
|
||||
vrp = *vrpt;
|
||||
vtmp = vld4_u32(png_ptrc(uint32_t,pp));
|
||||
vppt = png_ptr(uint8x8x4_t,&vtmp);
|
||||
vpp = *vppt;
|
||||
|
||||
vdest.val[0] = paeth(vdest.val[3], vpp.val[0], vlast);
|
||||
vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]);
|
||||
vdest.val[1] = paeth(vdest.val[0], vpp.val[1], vpp.val[0]);
|
||||
vdest.val[1] = vadd_u8(vdest.val[1], vrp.val[1]);
|
||||
vdest.val[2] = paeth(vdest.val[1], vpp.val[2], vpp.val[1]);
|
||||
vdest.val[2] = vadd_u8(vdest.val[2], vrp.val[2]);
|
||||
vdest.val[3] = paeth(vdest.val[2], vpp.val[3], vpp.val[2]);
|
||||
vdest.val[3] = vadd_u8(vdest.val[3], vrp.val[3]);
|
||||
|
||||
vlast = vpp.val[3];
|
||||
|
||||
vdest_val = png_ldr(uint32x2x4_t, &vdest);
|
||||
vst4_lane_u32(png_ptr(uint32_t,rp), vdest_val, 0);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* PNG_ARM_NEON_OPT > 0 */
|
||||
#endif /* PNG_ARM_NEON_IMPLEMENTATION == 1 (intrinsics) */
|
||||
#endif /* READ */
|
||||
149
src/thirdparty/libpng/arm/palette_neon_intrinsics.c
vendored
Normal file
149
src/thirdparty/libpng/arm/palette_neon_intrinsics.c
vendored
Normal file
@@ -0,0 +1,149 @@
|
||||
|
||||
/* palette_neon_intrinsics.c - NEON optimised palette expansion functions
|
||||
*
|
||||
* Copyright (c) 2018-2019 Cosmin Truta
|
||||
* Copyright (c) 2017-2018 Arm Holdings. All rights reserved.
|
||||
* Written by Richard Townsend <Richard.Townsend@arm.com>, February 2017.
|
||||
*
|
||||
* This code is released under the libpng license.
|
||||
* For conditions of distribution and use, see the disclaimer
|
||||
* and license in png.h
|
||||
*/
|
||||
|
||||
#include "../pngpriv.h"
|
||||
|
||||
#if PNG_ARM_NEON_IMPLEMENTATION == 1
|
||||
|
||||
#if defined(_MSC_VER) && defined(_M_ARM64)
|
||||
# include <arm64_neon.h>
|
||||
#else
|
||||
# include <arm_neon.h>
|
||||
#endif
|
||||
|
||||
/* Build an RGBA8 palette from the separate RGB and alpha palettes. */
|
||||
void
|
||||
png_riffle_palette_neon(png_structrp png_ptr)
|
||||
{
|
||||
png_const_colorp palette = png_ptr->palette;
|
||||
png_bytep riffled_palette = png_ptr->riffled_palette;
|
||||
png_const_bytep trans_alpha = png_ptr->trans_alpha;
|
||||
int num_trans = png_ptr->num_trans;
|
||||
int i;
|
||||
|
||||
png_debug(1, "in png_riffle_palette_neon");
|
||||
|
||||
/* Initially black, opaque. */
|
||||
uint8x16x4_t w = {{
|
||||
vdupq_n_u8(0x00),
|
||||
vdupq_n_u8(0x00),
|
||||
vdupq_n_u8(0x00),
|
||||
vdupq_n_u8(0xff),
|
||||
}};
|
||||
|
||||
/* First, riffle the RGB colours into an RGBA8 palette.
|
||||
* The alpha component is set to opaque for now.
|
||||
*/
|
||||
for (i = 0; i < 256; i += 16)
|
||||
{
|
||||
uint8x16x3_t v = vld3q_u8((png_const_bytep)(palette + i));
|
||||
w.val[0] = v.val[0];
|
||||
w.val[1] = v.val[1];
|
||||
w.val[2] = v.val[2];
|
||||
vst4q_u8(riffled_palette + (i << 2), w);
|
||||
}
|
||||
|
||||
/* Fix up the missing transparency values. */
|
||||
for (i = 0; i < num_trans; i++)
|
||||
riffled_palette[(i << 2) + 3] = trans_alpha[i];
|
||||
}
|
||||
|
||||
/* Expands a palettized row into RGBA8. */
|
||||
int
|
||||
png_do_expand_palette_rgba8_neon(png_structrp png_ptr, png_row_infop row_info,
|
||||
png_const_bytep row, png_bytepp ssp, png_bytepp ddp)
|
||||
{
|
||||
png_uint_32 row_width = row_info->width;
|
||||
const png_uint_32 *riffled_palette =
|
||||
(const png_uint_32 *)png_ptr->riffled_palette;
|
||||
const png_int_32 pixels_per_chunk = 4;
|
||||
int i;
|
||||
|
||||
png_debug(1, "in png_do_expand_palette_rgba8_neon");
|
||||
|
||||
if (row_width < pixels_per_chunk)
|
||||
return 0;
|
||||
|
||||
/* This function originally gets the last byte of the output row.
|
||||
* The NEON part writes forward from a given position, so we have
|
||||
* to seek this back by 4 pixels x 4 bytes.
|
||||
*/
|
||||
*ddp = *ddp - ((pixels_per_chunk * sizeof(png_uint_32)) - 1);
|
||||
|
||||
for (i = 0; i < row_width; i += pixels_per_chunk)
|
||||
{
|
||||
uint32x4_t cur;
|
||||
png_bytep sp = *ssp - i, dp = *ddp - (i << 2);
|
||||
cur = vld1q_dup_u32 (riffled_palette + *(sp - 3));
|
||||
cur = vld1q_lane_u32(riffled_palette + *(sp - 2), cur, 1);
|
||||
cur = vld1q_lane_u32(riffled_palette + *(sp - 1), cur, 2);
|
||||
cur = vld1q_lane_u32(riffled_palette + *(sp - 0), cur, 3);
|
||||
vst1q_u32((void *)dp, cur);
|
||||
}
|
||||
if (i != row_width)
|
||||
{
|
||||
/* Remove the amount that wasn't processed. */
|
||||
i -= pixels_per_chunk;
|
||||
}
|
||||
|
||||
/* Decrement output pointers. */
|
||||
*ssp = *ssp - i;
|
||||
*ddp = *ddp - (i << 2);
|
||||
return i;
|
||||
}
|
||||
|
||||
/* Expands a palettized row into RGB8. */
|
||||
int
|
||||
png_do_expand_palette_rgb8_neon(png_structrp png_ptr, png_row_infop row_info,
|
||||
png_const_bytep row, png_bytepp ssp, png_bytepp ddp)
|
||||
{
|
||||
png_uint_32 row_width = row_info->width;
|
||||
png_const_bytep palette = (png_const_bytep)png_ptr->palette;
|
||||
const png_uint_32 pixels_per_chunk = 8;
|
||||
int i;
|
||||
|
||||
png_debug(1, "in png_do_expand_palette_rgb8_neon");
|
||||
|
||||
if (row_width <= pixels_per_chunk)
|
||||
return 0;
|
||||
|
||||
/* Seeking this back by 8 pixels x 3 bytes. */
|
||||
*ddp = *ddp - ((pixels_per_chunk * sizeof(png_color)) - 1);
|
||||
|
||||
for (i = 0; i < row_width; i += pixels_per_chunk)
|
||||
{
|
||||
uint8x8x3_t cur;
|
||||
png_bytep sp = *ssp - i, dp = *ddp - ((i << 1) + i);
|
||||
cur = vld3_dup_u8(palette + sizeof(png_color) * (*(sp - 7)));
|
||||
cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 6)), cur, 1);
|
||||
cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 5)), cur, 2);
|
||||
cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 4)), cur, 3);
|
||||
cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 3)), cur, 4);
|
||||
cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 2)), cur, 5);
|
||||
cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 1)), cur, 6);
|
||||
cur = vld3_lane_u8(palette + sizeof(png_color) * (*(sp - 0)), cur, 7);
|
||||
vst3_u8((void *)dp, cur);
|
||||
}
|
||||
|
||||
if (i != row_width)
|
||||
{
|
||||
/* Remove the amount that wasn't processed. */
|
||||
i -= pixels_per_chunk;
|
||||
}
|
||||
|
||||
/* Decrement output pointers. */
|
||||
*ssp = *ssp - i;
|
||||
*ddp = *ddp - ((i << 1) + i);
|
||||
return i;
|
||||
}
|
||||
|
||||
#endif /* PNG_ARM_NEON_IMPLEMENTATION */
|
||||
@@ -5,8 +5,6 @@ VisualStudioVersion = 14.0.25420.1
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ccextractor", "ccextractor.vcxproj", "{0F0063C4-BCBC-4379-A6D5-84A5669C940A}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ccextractorGUI", "ccextractorGUI.vcxproj", "{74290DA6-174D-4F4B-A48E-F30B824B7925}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
|
||||
@@ -334,6 +334,7 @@
|
||||
<ProjectGuid>{0F0063C4-BCBC-4379-A6D5-84A5669C940A}</ProjectGuid>
|
||||
<RootNamespace>ccextractor</RootNamespace>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
@@ -342,7 +343,7 @@
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
@@ -350,15 +351,15 @@
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Full|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v140_xp</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Full|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Full|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
@@ -366,7 +367,7 @@
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Full|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
@@ -421,7 +422,7 @@
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<TargetName>ccextractorwin</TargetName>
|
||||
<IncludePath>$(ProjectDir)\libs\include;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(ProjectDir)\libs\lib;$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86)</LibraryPath>
|
||||
<LibraryPath>$(ProjectDir)\libs\lib;$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64)</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release-Full|Win32'">
|
||||
<OutDir>Release-Full\</OutDir>
|
||||
@@ -435,7 +436,7 @@
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<TargetName>ccextractorwin</TargetName>
|
||||
<IncludePath>$(ProjectDir)\libs\include;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(ProjectDir)\libs\lib;$(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86)</LibraryPath>
|
||||
<LibraryPath>$(ProjectDir)\libs\lib;$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64)</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<OutDir>Release\</OutDir>
|
||||
@@ -450,7 +451,7 @@
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\src\thirdparty\freetype\include;..\src\thirdparty\win_spec_incld;..\src\lib_ccx;..\src\thirdparty\lib_hash;..\src\lib_ccx\zvbi;..\src\thirdparty\protobuf-c;..\src\thirdparty\gpacmp4;..\src\thirdparty\win_iconv;..\src\thirdparty\zlib;..\src\thirdparty\libpng;..\src\thirdparty;..\src;libs\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>..\src\thirdparty\freetype\include;..\src;..\src\thirdparty\win_spec_incld;..\src\lib_ccx;..\src\thirdparty\lib_hash;..\src\lib_ccx\zvbi;..\src\thirdparty\protobuf-c;..\src\thirdparty\gpacmp4;..\src\thirdparty\win_iconv;..\src\thirdparty\zlib;..\src\thirdparty\libpng;..\src\thirdparty;..\src;libs\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;FT2_BUILD_LIBRARY;GPAC_DISABLE_VTT;GPAC_DISABLE_OD_DUMP;_DEBUG;_CONSOLE;_FILE_OFFSET_BITS=64;_CRT_SECURE_NO_WARNINGS;GPAC_DISABLE_REMOTERY;GPAC_DISABLE_ZLIB;GPAC_HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>true</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
@@ -461,7 +462,7 @@
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>avcodec.lib;
|
||||
<AdditionalDependencies>ccx_rust.lib;UserEnv.lib;avcodec.lib;
|
||||
avformat.lib;
|
||||
avutil.lib;
|
||||
swscale.lib;WS2_32.Lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
@@ -483,7 +484,7 @@ xcopy /y "$(ProjectDir)libs\lib\ffmpeg-lib\swscale-4.dll" "$(ProjectDir)$(OutDir
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>../src/thirdparty/protobuf-c;../src/thirdparty/win_spec_incld;../src/thirdparty/gpacmp4;../src/thirdparty/libpng;../src/thirdparty/zlib;../src;../src/lib_ccx;../src/lib_ccx/zvbi;../src/thirdparty;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>..\src\thirdparty\freetype\include;..\src;../src/thirdparty/protobuf-c;../src/thirdparty/win_spec_incld;../src/thirdparty/gpacmp4;../src/thirdparty/libpng;../src/thirdparty/zlib;../src;../src/lib_ccx;../src/lib_ccx/zvbi;../src/thirdparty;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;FT2_BUILD_LIBRARY;GPAC_DISABLE_VTT;GPAC_DISABLE_OD_DUMP;_DEBUG;_CONSOLE;_FILE_OFFSET_BITS=64;GPAC_DISABLE_REMOTERY;GPAC_DISABLE_ZLIB;GPAC_HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
@@ -493,16 +494,19 @@ xcopy /y "$(ProjectDir)libs\lib\ffmpeg-lib\swscale-4.dll" "$(ProjectDir)$(OutDir
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>WS2_32.Lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>ccx_rust.lib;UserEnv.lib;WS2_32.Lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<ShowProgress>NotSet</ShowProgress>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
</Link>
|
||||
<PreBuildEvent>
|
||||
<Command>call rust.bat</Command>
|
||||
</PreBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Full|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\src\thirdparty\freetype\include;..\src\thirdparty\win_spec_incld;..\src\lib_ccx;..\src\thirdparty\lib_hash;..\src\lib_ccx\zvbi;..\src\thirdparty\protobuf-c;..\src\thirdparty\gpacmp4;..\src\thirdparty\win_iconv;..\src\thirdparty\zlib;..\src\thirdparty\;..\src\thirdparty\libpng;..\src;libs\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>..\src\thirdparty\freetype\include;..\src;.\libs\lib\ffmpeg-lib;..\src\thirdparty\win_spec_incld;..\src\lib_ccx;..\src\thirdparty\lib_hash;..\src\lib_ccx\zvbi;..\src\thirdparty\protobuf-c;..\src\thirdparty\gpacmp4;..\src\thirdparty\win_iconv;..\src\thirdparty\zlib;..\src\thirdparty\;..\src\thirdparty\libpng;..\src;libs\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>SEGMENT_BY_FILE_TIME;ENABLE_HARDSUBX;FT2_BUILD_LIBRARY;GPAC_DISABLE_VTT;GPAC_DISABLE_OD_DUMP;ENABLE_OCR;WIN32;_DEBUG;_CONSOLE;_FILE_OFFSET_BITS=64;GPAC_DISABLE_REMOTERY;GPAC_DISABLE_ZLIB;GPAC_HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
@@ -517,7 +521,7 @@ xcopy /y "$(ProjectDir)libs\lib\ffmpeg-lib\swscale-4.dll" "$(ProjectDir)$(OutDir
|
||||
<DisableSpecificWarnings>4005;4996</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>Ws2_32.lib;$(ProjectDir)libs\lib\debug-lib\pvt.cppan.demo.danbloomberg.leptonica-1.74.0.lib;$(ProjectDir)libs\lib\debug-lib\pvt.cppan.demo.google.tesseract.tesseract-master.lib;$(ProjectDir)libs\lib\debug-lib\pvt.cppan.demo.gif-5.1.4.lib;$(ProjectDir)libs\lib\debug-lib\pvt.cppan.demo.tiff-4.0.7.lib;$(ProjectDir)libs\lib\debug-lib\pvt.cppan.demo.jpeg-9.2.0.lib;$(ProjectDir)libs\lib\debug-lib\pvt.cppan.demo.openjpeg.openjp2-2.1.2.lib;$(ProjectDir)libs\lib\debug-lib\pvt.cppan.demo.mgk25.jbig.jbig-2.1.0.lib;$(ProjectDir)libs\lib\debug-lib\pvt.cppan.demo.mgk25.jbig.ar-2.1.0.lib;$(ProjectDir)libs\lib\debug-lib\pvt.cppan.demo.xz_utils.lzma-5.2.2.lib;$(ProjectDir)libs\lib\debug-lib\pvt.cppan.demo.webp-0.5.1.lib;$(ProjectDir)libs\lib\ffmpeg-lib\avcodec.lib;$(ProjectDir)libs\lib\ffmpeg-lib\avformat.lib;$(ProjectDir)libs\lib\ffmpeg-lib\avutil.lib;$(ProjectDir)libs\lib\ffmpeg-lib\swscale.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>ccx_rust.lib;UserEnv.lib;Ws2_32.lib;avcodec_x32.lib;avformat_x32.lib;avutil_x32.lib;swscale_x32.lib;$(ProjectDir)libs\lib\debug-lib\pvt.cppan.demo.danbloomberg.leptonica-1.74.0.lib;$(ProjectDir)libs\lib\debug-lib\pvt.cppan.demo.google.tesseract.tesseract-master.lib;$(ProjectDir)libs\lib\debug-lib\pvt.cppan.demo.gif-5.1.4.lib;$(ProjectDir)libs\lib\debug-lib\pvt.cppan.demo.tiff-4.0.7.lib;$(ProjectDir)libs\lib\debug-lib\pvt.cppan.demo.jpeg-9.2.0.lib;$(ProjectDir)libs\lib\debug-lib\pvt.cppan.demo.openjpeg.openjp2-2.1.2.lib;$(ProjectDir)libs\lib\debug-lib\pvt.cppan.demo.mgk25.jbig.jbig-2.1.0.lib;$(ProjectDir)libs\lib\debug-lib\pvt.cppan.demo.mgk25.jbig.ar-2.1.0.lib;$(ProjectDir)libs\lib\debug-lib\pvt.cppan.demo.xz_utils.lzma-5.2.2.lib;$(ProjectDir)libs\lib\debug-lib\pvt.cppan.demo.webp-0.5.1.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<ShowProgress>NotSet</ShowProgress>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@@ -526,6 +530,9 @@ xcopy /y "$(ProjectDir)libs\lib\ffmpeg-lib\swscale-4.dll" "$(ProjectDir)$(OutDir
|
||||
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
|
||||
<AdditionalLibraryDirectories>$(ProjectDir)libs\lib\ffmpeg-lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
<PreBuildEvent>
|
||||
<Command>call rustx86.bat</Command>
|
||||
</PreBuildEvent>
|
||||
<PostBuildEvent>
|
||||
<Command>xcopy /y "$(ProjectDir)libs\lib\ffmpeg-lib\avcodec-57.dll" "$(ProjectDir)$(OutDir)"
|
||||
xcopy /y "$(ProjectDir)libs\lib\ffmpeg-lib\avformat-57.dll" "$(ProjectDir)$(OutDir)"
|
||||
@@ -540,7 +547,7 @@ xcopy /y "$(ProjectDir)libs\lib\ffmpeg-lib\swscale-4.dll" "$(ProjectDir)$(OutDir
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug-Full|x64'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>../src/thirdparty/protobuf-c;../src/thirdparty/win_spec_incld;../src/thirdparty/gpacmp4;../src/thirdparty/libpng;../src/thirdparty/zlib;../src;../src/lib_ccx;../src/lib_ccx/zvbi;../src/thirdparty;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>..\src\thirdparty\freetype\include;..\src;.\libs\lib\ffmpeg-lib;../src/thirdparty/protobuf-c;../src/thirdparty/win_spec_incld;../src/thirdparty/gpacmp4;../src/thirdparty/libpng;../src/thirdparty/zlib;../src;../src/lib_ccx;../src/lib_ccx/zvbi;../src/thirdparty;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>ENABLE_OCR;FT2_BUILD_LIBRARY;GPAC_DISABLE_VTT;GPAC_DISABLE_OD_DUMP;WIN32;_DEBUG;_CONSOLE;_FILE_OFFSET_BITS=64;GPAC_DISABLE_REMOTERY;GPAC_DISABLE_ZLIB;GPAC_HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
@@ -550,10 +557,11 @@ xcopy /y "$(ProjectDir)libs\lib\ffmpeg-lib\swscale-4.dll" "$(ProjectDir)$(OutDir
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>WS2_32.Lib;avcodec.lib;avformat.lib;avutil.lib;swscale.lib;liblept172.lib;libtesseract304d.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>ccx_rust.lib;UserEnv.lib;WS2_32.Lib;avcodec.lib;avformat.lib;avutil.lib;swscale.lib;$(ProjectDir)libs\lib\debug-lib\pvt.cppan.demo.danbloomberg.leptonica-1.74.0.lib;$(ProjectDir)libs\lib\debug-lib\pvt.cppan.demo.google.tesseract.tesseract-master.lib;$(ProjectDir)libs\lib\debug-lib\pvt.cppan.demo.gif-5.1.4.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<ShowProgress>NotSet</ShowProgress>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<AdditionalLibraryDirectories>.\libs\lib\ffmpeg-lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
<PostBuildEvent>
|
||||
<Command>xcopy /y "$(ProjectDir)libs\lib\liblept172.dll" "$(ProjectDir)$(OutDir)"
|
||||
@@ -563,7 +571,7 @@ xcopy /y "$(ProjectDir)libs\lib\libtesseract304d.dll" "$(ProjectDir)$(OutDir)"</
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Full|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<AdditionalIncludeDirectories>..\src\thirdparty\freetype\include;..\src\thirdparty\win_spec_incld;..\src\lib_ccx;..\src\thirdparty\lib_hash;..\src\lib_ccx\zvbi;..\src\thirdparty\protobuf-c;..\src\thirdparty\gpacmp4;..\src\thirdparty\win_iconv;..\src\thirdparty\zlib;..\src\thirdparty\;..\src\thirdparty\libpng;..\src;libs\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>..\src\thirdparty\freetype\include;..\src;.\libs\lib\ffmpeg-lib;..\src\thirdparty\win_spec_incld;..\src\lib_ccx;..\src\thirdparty\lib_hash;..\src\lib_ccx\zvbi;..\src\thirdparty\protobuf-c;..\src\thirdparty\gpacmp4;..\src\thirdparty\win_iconv;..\src\thirdparty\zlib;..\src\thirdparty\;..\src\thirdparty\libpng;..\src;libs\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>ENABLE_HARDSUBX;FT2_BUILD_LIBRARY;GPAC_DISABLE_VTT;GPAC_DISABLE_OD_DUMP;VERSION_FILE_PRESENT;ENABLE_OCR;WIN32;NDEBUG;_CONSOLE;_FILE_OFFSET_BITS=64;GPAC_DISABLE_REMOTERY;GPAC_DISABLE_ZLIB;GPAC_HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
@@ -575,7 +583,7 @@ xcopy /y "$(ProjectDir)libs\lib\libtesseract304d.dll" "$(ProjectDir)$(OutDir)"</
|
||||
<DisableSpecificWarnings>4005;4996</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>Ws2_32.lib;$(ProjectDir)libs\lib\release-lib\pvt.cppan.demo.danbloomberg.leptonica-1.74.0.lib;$(ProjectDir)libs\lib\release-lib\pvt.cppan.demo.google.tesseract.tesseract-master.lib;$(ProjectDir)libs\lib\release-lib\pvt.cppan.demo.gif-5.1.4.lib;$(ProjectDir)libs\lib\release-lib\pvt.cppan.demo.tiff-4.0.7.lib;$(ProjectDir)libs\lib\release-lib\pvt.cppan.demo.jpeg-9.2.0.lib;$(ProjectDir)libs\lib\release-lib\pvt.cppan.demo.openjpeg.openjp2-2.1.2.lib;$(ProjectDir)libs\lib\release-lib\pvt.cppan.demo.mgk25.jbig.jbig-2.1.0.lib;$(ProjectDir)libs\lib\release-lib\pvt.cppan.demo.mgk25.jbig.ar-2.1.0.lib;$(ProjectDir)libs\lib\release-lib\pvt.cppan.demo.xz_utils.lzma-5.2.2.lib;$(ProjectDir)libs\lib\release-lib\pvt.cppan.demo.webp-0.5.1.lib;$(ProjectDir)libs\lib\ffmpeg-lib\avcodec.lib;$(ProjectDir)libs\lib\ffmpeg-lib\avformat.lib;$(ProjectDir)libs\lib\ffmpeg-lib\avutil.lib;$(ProjectDir)libs\lib\ffmpeg-lib\swscale.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>ccx_rust.lib;UserEnv.lib;Ws2_32.lib;$(ProjectDir)libs\lib\ffmpeg-lib\avcodec_x32.lib;$(ProjectDir)libs\lib\ffmpeg-lib\avformat_x32.lib;$(ProjectDir)libs\lib\ffmpeg-lib\avutil_x32.lib;$(ProjectDir)libs\lib\ffmpeg-lib\swscale_x32.lib;$(ProjectDir)libs\lib\release-lib\pvt.cppan.demo.danbloomberg.leptonica-1.74.0.lib;$(ProjectDir)libs\lib\release-lib\pvt.cppan.demo.google.tesseract.tesseract-master.lib;$(ProjectDir)libs\lib\release-lib\pvt.cppan.demo.gif-5.1.4.lib;$(ProjectDir)libs\lib\release-lib\pvt.cppan.demo.tiff-4.0.7.lib;$(ProjectDir)libs\lib\release-lib\pvt.cppan.demo.jpeg-9.2.0.lib;$(ProjectDir)libs\lib\release-lib\pvt.cppan.demo.openjpeg.openjp2-2.1.2.lib;$(ProjectDir)libs\lib\release-lib\pvt.cppan.demo.mgk25.jbig.jbig-2.1.0.lib;$(ProjectDir)libs\lib\release-lib\pvt.cppan.demo.mgk25.jbig.ar-2.1.0.lib;$(ProjectDir)libs\lib\release-lib\pvt.cppan.demo.xz_utils.lzma-5.2.2.lib;$(ProjectDir)libs\lib\release-lib\pvt.cppan.demo.webp-0.5.1.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
@@ -591,7 +599,8 @@ xcopy /y "$(ProjectDir)libs\lib\ffmpeg-lib\swresample-2.dll" "$(ProjectDir)$(Out
|
||||
xcopy /y "$(ProjectDir)libs\lib\ffmpeg-lib\swscale-4.dll" "$(ProjectDir)$(OutDir)"</Command>
|
||||
</PostBuildEvent>
|
||||
<PreBuildEvent>
|
||||
<Command>pre-build.bat</Command>
|
||||
<Command>call pre-build.bat
|
||||
call rustx86.bat</Command>
|
||||
</PreBuildEvent>
|
||||
<ProjectReference>
|
||||
<LinkLibraryDependencies>false</LinkLibraryDependencies>
|
||||
@@ -600,8 +609,8 @@ xcopy /y "$(ProjectDir)libs\lib\ffmpeg-lib\swscale-4.dll" "$(ProjectDir)$(OutDir
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release-Full|x64'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>../src/thirdparty/protobuf-c;../src/thirdparty/win_spec_incld;../src/thirdparty/gpacmp4;../src/thirdparty/libpng;../src/thirdparty/zlib;../src;../src/lib_ccx;../src/lib_ccx/zvbi;../src/thirdparty;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>VERSION_FILE_PRESENT;ENABLE_OCR;WIN32;NDEBUG;_CONSOLE;_FILE_OFFSET_BITS=64;GPAC_DISABLE_REMOTERY;GPAC_DISABLE_ZLIB;GPAC_HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>..\src\thirdparty\freetype\include;..\src;.\libs\lib\ffmpeg-lib;../src/thirdparty/protobuf-c;../src/thirdparty/win_spec_incld;../src/thirdparty/gpacmp4;../src/thirdparty/libpng;../src/thirdparty/zlib;../src;../src/lib_ccx;../src/lib_ccx/zvbi;../src/thirdparty;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>VERSION_FILE_PRESENT;FT2_BUILD_LIBRARY;ENABLE_OCR;WIN32;NDEBUG;_CONSOLE;_FILE_OFFSET_BITS=64;GPAC_DISABLE_REMOTERY;GPAC_DISABLE_ZLIB;GPAC_HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
@@ -609,12 +618,16 @@ xcopy /y "$(ProjectDir)libs\lib\ffmpeg-lib\swscale-4.dll" "$(ProjectDir)$(OutDir
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>WS2_32.Lib;avcodec.lib;avformat.lib;avutil.lib;swscale.lib;liblept172.lib;libtesseract304d.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>ccx_rust.lib;UserEnv.lib;WS2_32.Lib;avcodec.lib;avformat.lib;avutil.lib;swscale.lib;$(ProjectDir)libs\lib\debug-lib\pvt.cppan.demo.danbloomberg.leptonica-1.74.0.lib;$(ProjectDir)libs\lib\debug-lib\pvt.cppan.demo.google.tesseract.tesseract-master.lib;$(ProjectDir)libs\lib\debug-lib\pvt.cppan.demo.gif-5.1.4.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<AdditionalLibraryDirectories>$(ProjectDir)libs\lib\ffmpeg-lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
<PreBuildEvent>
|
||||
<Command>call pre-build.bat</Command>
|
||||
</PreBuildEvent>
|
||||
<PostBuildEvent>
|
||||
<Command>xcopy /y "$(ProjectDir)libs\lib\liblept172.dll" "$(ProjectDir)$(OutDir)"
|
||||
xcopy /y "$(ProjectDir)libs\lib\libtesseract304d.dll" "$(ProjectDir)$(OutDir)"</Command>
|
||||
@@ -622,7 +635,7 @@ xcopy /y "$(ProjectDir)libs\lib\libtesseract304d.dll" "$(ProjectDir)$(OutDir)"</
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>..\src\thirdparty\freetype\include;..\src\thirdparty\win_spec_incld;..\src\lib_ccx;..\src\thirdparty\lib_hash;..\src\lib_ccx\zvbi;..\src\thirdparty\protobuf-c;..\src\thirdparty\gpacmp4;..\src\thirdparty\win_iconv;..\src\thirdparty\zlib;..\src\thirdparty\libpng;..\src\thirdparty;..\src;libs\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>..\src\thirdparty\freetype\include;..\src;..\src\thirdparty\win_spec_incld;..\src\lib_ccx;..\src\thirdparty\lib_hash;..\src\lib_ccx\zvbi;..\src\thirdparty\protobuf-c;..\src\thirdparty\gpacmp4;..\src\thirdparty\win_iconv;..\src\thirdparty\zlib;..\src\thirdparty\libpng;..\src\thirdparty;..\src;libs\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>VERSION_FILE_PRESENT;FT2_BUILD_LIBRARY;GPAC_DISABLE_VTT;GPAC_DISABLE_OD_DUMP;WIN32;NDEBUG;_CONSOLE;_FILE_OFFSET_BITS=64;GPAC_DISABLE_REMOTERY;GPAC_DISABLE_ZLIB;GPAC_HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<PrecompiledHeader />
|
||||
@@ -632,7 +645,7 @@ xcopy /y "$(ProjectDir)libs\lib\libtesseract304d.dll" "$(ProjectDir)$(OutDir)"</
|
||||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>avcodec.lib;avformat.lib;avutil.lib;swscale.lib;WS2_32.Lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>ccx_rust.lib;UserEnv.lib;avcodec.lib;avformat.lib;avutil.lib;swscale.lib;WS2_32.Lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
@@ -642,7 +655,7 @@ xcopy /y "$(ProjectDir)libs\lib\libtesseract304d.dll" "$(ProjectDir)$(OutDir)"</
|
||||
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
|
||||
</Link>
|
||||
<PreBuildEvent>
|
||||
<Command>pre-build.bat</Command>
|
||||
<Command>call pre-build.bat</Command>
|
||||
</PreBuildEvent>
|
||||
<PostBuildEvent>
|
||||
<Command>xcopy /y "$(ProjectDir)libs\lib\ffmpeg-lib\avcodec-57.dll" "$(ProjectDir)$(OutDir)"
|
||||
@@ -654,7 +667,7 @@ xcopy /y "$(ProjectDir)libs\lib\ffmpeg-lib\swscale-4.dll" "$(ProjectDir)$(OutDir
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>..\src\thirdparty\freetype\include;../src/thirdparty/protobuf-c;../src/thirdparty/win_spec_incld;../src/lib_ccx;../src/thirdparty/lib_hash;../src/thirdparty/gpacmp4;../src/thirdparty/libpng;../src/thirdparty/zlib;../src/lib_ccx/zvbi;../src/thirdparty;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>..\src\thirdparty\freetype\include;..\src;../src/thirdparty/protobuf-c;../src/thirdparty/win_spec_incld;../src/lib_ccx;../src/thirdparty/lib_hash;../src/thirdparty/gpacmp4;../src/thirdparty/libpng;../src/thirdparty/zlib;../src/lib_ccx/zvbi;../src/thirdparty;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>VERSION_FILE_PRESENT;FT2_BUILD_LIBRARY;GPAC_DISABLE_VTT;GPAC_DISABLE_OD_DUMP;WIN32;NDEBUG;_CONSOLE;_FILE_OFFSET_BITS=64;GPAC_DISABLE_REMOTERY;GPAC_DISABLE_ZLIB;GPAC_HAVE_CONFIG_H;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<PrecompiledHeader>
|
||||
@@ -663,17 +676,18 @@ xcopy /y "$(ProjectDir)libs\lib\ffmpeg-lib\swscale-4.dll" "$(ProjectDir)$(OutDir
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>WS2_32.Lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>ccx_rust.lib;UserEnv.lib;WS2_32.Lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
</Link>
|
||||
<PreBuildEvent>
|
||||
<Command>pre-build.bat</Command>
|
||||
<Command>call pre-build.bat
|
||||
call rust.bat </Command>
|
||||
</PreBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
@@ -333,30 +333,6 @@
|
||||
<ClInclude Include="..\src\thirdparty\zlib\zutil.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\thirdparty\zvbi\bcd.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\thirdparty\zvbi\bit_slicer.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\thirdparty\zvbi\macros.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\thirdparty\zvbi\misc.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\thirdparty\zvbi\raw_decoder.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\thirdparty\zvbi\sampling_par.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\thirdparty\zvbi\sliced.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\thirdparty\zvbi\zvbi_decoder.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\thirdparty\win_spec_incld\inttypes.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
@@ -381,6 +357,30 @@
|
||||
<ClInclude Include="..\src\thirdparty\freetype\include\freetype\config\ftstdlib.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\lib_ccx\zvbi\bcd.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\lib_ccx\zvbi\bit_slicer.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\lib_ccx\zvbi\macros.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\lib_ccx\zvbi\misc.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\lib_ccx\zvbi\raw_decoder.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\lib_ccx\zvbi\sampling_par.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\lib_ccx\zvbi\sliced.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\lib_ccx\zvbi\zvbi_decoder.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\src\ccextractor.c">
|
||||
@@ -704,9 +704,6 @@
|
||||
<ClCompile Include="..\src\thirdparty\gpacmp4\movie_fragments.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\thirdparty\gpacmp4\mp4.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\thirdparty\gpacmp4\odf_code.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
@@ -833,18 +830,6 @@
|
||||
<ClCompile Include="..\src\thirdparty\zlib\zutil.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\thirdparty\zvbi\bit_slicer.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\thirdparty\zvbi\decoder.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\thirdparty\zvbi\raw_decoder.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\thirdparty\zvbi\sampling_par.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\thirdparty\freetype\autofit\autofit.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
@@ -959,10 +944,40 @@
|
||||
<ClCompile Include="..\src\thirdparty\zlib\adler32.c">
|
||||
<Filter>Source Files\zlib</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\lib_ccx\mp4.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\thirdparty\gpacmp4\os_thread.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\thirdparty\gpacmp4\module.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\thirdparty\gpacmp4\os_module.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\thirdparty\gpacmp4\xml_parser.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\thirdparty\gpacmp4\constants.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\lib_ccx\zvbi\bit_slicer.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\lib_ccx\zvbi\decoder.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\lib_ccx\zvbi\raw_decoder.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\lib_ccx\zvbi\sampling_par.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\src\lib_ccx\ccx_sub_entry_message.proto">
|
||||
<Filter>Header Files\lib_ccx</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
183
windows/installer.wxs
Normal file
183
windows/installer.wxs
Normal file
@@ -0,0 +1,183 @@
|
||||
<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
|
||||
<Package Name="CCExtractor" Language="1033" Version="$(AppVersion)" Manufacturer="CCExtractor development" UpgradeCode="e70dbe37-bb04-4c39-bedc-966a6b073bcf" InstallerVersion="200">
|
||||
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed."/>
|
||||
<MediaTemplate EmbedCab="yes"/>
|
||||
<Feature Id="CCX" Title="CCExtractor Setup" Level="1">
|
||||
<ComponentGroupRef Id="CCX_Components_MainFolder"/>
|
||||
<ComponentGroupRef Id="CCX_Components_MainFolder_data"/>
|
||||
<ComponentGroupRef Id="CCX_Components_MainFolder_data_flutter_assets"/>
|
||||
<ComponentGroupRef Id="CCX_Components_MainFolder_data_flutter_assets_assets"/>
|
||||
<ComponentGroupRef Id="CCX_Components_MainFolder_data_flutter_assets_fonts"/>
|
||||
<ComponentGroupRef Id="CCX_Components_MainFolder_data_flutter_assets_cupertino"/>
|
||||
<ComponentRef Id="ApplicationShortcutDesktop"/>
|
||||
</Feature>
|
||||
<Icon Id="ccxgui.exe" SourceFile="./installer/ccxgui.exe"/>
|
||||
<!-- Derives from the regular install dir, but skips the license dialog. -->
|
||||
<UI Id="WixUI_InstallDir">
|
||||
<TextStyle Id="WixUI_Font_Normal" FaceName="Tahoma" Size="8" />
|
||||
<TextStyle Id="WixUI_Font_Bigger" FaceName="Tahoma" Size="12" />
|
||||
<TextStyle Id="WixUI_Font_Title" FaceName="Tahoma" Size="9" Bold="yes" />
|
||||
|
||||
<Property Id="DefaultUIFont" Value="WixUI_Font_Normal" />
|
||||
<Property Id="WixUI_Mode" Value="InstallDir" />
|
||||
|
||||
<DialogRef Id="BrowseDlg" />
|
||||
<DialogRef Id="DiskCostDlg" />
|
||||
<DialogRef Id="ErrorDlg" />
|
||||
<DialogRef Id="FatalError" />
|
||||
<DialogRef Id="FilesInUse" />
|
||||
<DialogRef Id="MsiRMFilesInUse" />
|
||||
<DialogRef Id="PrepareDlg" />
|
||||
<DialogRef Id="ProgressDlg" />
|
||||
<DialogRef Id="ResumeDlg" />
|
||||
<DialogRef Id="UserExit" />
|
||||
<Publish Dialog="BrowseDlg" Control="OK" Event="DoAction" Value="WixUIValidatePath" Order="3" />
|
||||
<Publish Dialog="BrowseDlg" Control="OK" Event="SpawnDialog" Value="InvalidDirDlg" Order="4" Condition="NOT WIXUI_DONTVALIDATEPATH AND WIXUI_INSTALLDIR_VALID<>"1"" />
|
||||
|
||||
<Publish Dialog="ExitDialog" Control="Finish" Event="EndDialog" Value="Return" Order="999" />
|
||||
|
||||
<Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="InstallDirDlg" Condition="NOT Installed" />
|
||||
<Publish Dialog="WelcomeDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg" Condition="Installed AND PATCH" />
|
||||
|
||||
<Publish Dialog="InstallDirDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg" />
|
||||
<Publish Dialog="InstallDirDlg" Control="Next" Event="SetTargetPath" Value="[WIXUI_INSTALLDIR]" Order="1" />
|
||||
<Publish Dialog="InstallDirDlg" Control="Next" Event="DoAction" Value="WixUIValidatePath" Order="2" Condition="NOT WIXUI_DONTVALIDATEPATH" />
|
||||
<Publish Dialog="InstallDirDlg" Control="Next" Event="SpawnDialog" Value="InvalidDirDlg" Order="3" Condition="NOT WIXUI_DONTVALIDATEPATH AND WIXUI_INSTALLDIR_VALID<>"1"" />
|
||||
<Publish Dialog="InstallDirDlg" Control="Next" Event="NewDialog" Value="VerifyReadyDlg" Order="4" Condition="WIXUI_DONTVALIDATEPATH OR WIXUI_INSTALLDIR_VALID="1"" />
|
||||
<Publish Dialog="InstallDirDlg" Control="ChangeFolder" Property="_BrowseProperty" Value="[WIXUI_INSTALLDIR]" Order="1" />
|
||||
<Publish Dialog="InstallDirDlg" Control="ChangeFolder" Event="SpawnDialog" Value="BrowseDlg" Order="2" />
|
||||
<Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="InstallDirDlg" Order="1" Condition="NOT Installed" />
|
||||
<Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="MaintenanceTypeDlg" Order="2" Condition="Installed AND NOT PATCH" />
|
||||
<Publish Dialog="VerifyReadyDlg" Control="Back" Event="NewDialog" Value="WelcomeDlg" Order="2" Condition="Installed AND PATCH" />
|
||||
|
||||
<Publish Dialog="MaintenanceWelcomeDlg" Control="Next" Event="NewDialog" Value="MaintenanceTypeDlg" />
|
||||
|
||||
<Publish Dialog="MaintenanceTypeDlg" Control="RepairButton" Event="NewDialog" Value="VerifyReadyDlg" />
|
||||
<Publish Dialog="MaintenanceTypeDlg" Control="RemoveButton" Event="NewDialog" Value="VerifyReadyDlg" />
|
||||
<Publish Dialog="MaintenanceTypeDlg" Control="Back" Event="NewDialog" Value="MaintenanceWelcomeDlg" />
|
||||
|
||||
<Property Id="ARPNOMODIFY" Value="1" />
|
||||
</UI>
|
||||
|
||||
<UIRef Id="WixUI_Common" />
|
||||
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLFOLDER"/>
|
||||
</Package>
|
||||
<Fragment>
|
||||
<Directory Id="DesktopFolder" Name="Desktop">
|
||||
<Component Id="ApplicationShortcutDesktop" Guid="*">
|
||||
<Shortcut Id="ApplicationDesktopShortcut"
|
||||
Name="CCExtractor"
|
||||
Description="Run CCExtractor"
|
||||
Target="[INSTALLFOLDER]ccxgui.exe"
|
||||
WorkingDirectory="INSTALLFOLDER"/>
|
||||
<RemoveFolder Id="DesktopFolder" On="uninstall"/>
|
||||
<RegistryValue
|
||||
Root="HKCU"
|
||||
Key="Software\CCExtractor\ccextractor"
|
||||
Name="installed"
|
||||
Type="integer"
|
||||
Value="1"
|
||||
KeyPath="yes"/>
|
||||
</Component>
|
||||
</Directory>
|
||||
<StandardDirectory Id="ProgramFiles6432Folder">
|
||||
<Directory Id="INSTALLFOLDER" Name="CCExtractor">
|
||||
<Directory Id="CCX_data" Name="data">
|
||||
<Directory Id="CCX_data_flutter_assets" Name="flutter_assets">
|
||||
<Directory Id="CCX_data_flutter_assets_assets" Name="assets"/>
|
||||
<Directory Id="CCX_data_flutter_assets_fonts" Name="fonts"/>
|
||||
<Directory Id="dirEE44DD2D485FE70BEAFB55755745AB6E" Name="packages">
|
||||
<Directory Id="dir382F01892F72FB688A688BE6E01B93A3" Name="cupertino_icons">
|
||||
<Directory Id="CCX_data_flutter_assets_cupertino" Name="assets"/>
|
||||
</Directory>
|
||||
</Directory>
|
||||
</Directory>
|
||||
</Directory>
|
||||
</Directory>
|
||||
</StandardDirectory>
|
||||
</Fragment>
|
||||
<Fragment>
|
||||
<ComponentGroup Id="CCX_Components_MainFolder" Directory="INSTALLFOLDER">
|
||||
<Component Guid="{2D6CDFAD-A645-4929-9518-B43788B9E5F3}">
|
||||
<File Id="CCX_Full_executable" Source="./installer/ccextractorwinfull.exe" KeyPath="yes"/>
|
||||
</Component>
|
||||
<Component Guid="{5DA8F5F9-922B-45E1-B0A9-CB241996D9EE}">
|
||||
<File Id="CCX_avcodec" Source="./installer/avcodec-57.dll" KeyPath="yes"/>
|
||||
</Component>
|
||||
<Component Guid="{00E5F91A-D4D9-4A3D-B498-1CF45D18770F}">
|
||||
<File Id="CCX_avformat" Source="./installer/avformat-57.dll" KeyPath="yes"/>
|
||||
</Component>
|
||||
<Component Guid="{AA5FE610-7566-483C-84D0-70B0435E08B0}">
|
||||
<File Id="CCX_avutil" Source="./installer/avutil-55.dll" KeyPath="yes"/>
|
||||
</Component>
|
||||
<Component Guid="{334ABDD6-FDBB-41EB-87FE-DAD3295DAE2D}">
|
||||
<File Id="CCX_swresample" Source="./installer/swresample-2.dll" KeyPath="yes"/>
|
||||
</Component>
|
||||
<Component Guid="{888B47CF-0377-490A-8B7E-341D2C71EAD0}">
|
||||
<File Id="CCX_swscale" Source="./installer/swscale-4.dll" KeyPath="yes"/>
|
||||
</Component>
|
||||
<Component Guid="{8B69210B-5091-4C63-8902-E0ADDBE2C080}">
|
||||
<File Source="./installer/ccxgui.exe" KeyPath="yes"/>
|
||||
</Component>
|
||||
<Component Guid="{1B37F14A-3BA6-4837-8A6F-6EA01A25DA26}">
|
||||
<File Source="./installer/file_selector_windows_plugin.dll" KeyPath="yes"/>
|
||||
</Component>
|
||||
<Component Guid="{B276C96D-9737-4B8C-B55B-60F392DED331}">
|
||||
<File Source="./installer/url_launcher_windows_plugin.dll" KeyPath="yes"/>
|
||||
</Component>
|
||||
<Component Guid="{4B627AA9-55DD-40ED-99F9-54F67EC73887}">
|
||||
<File Source="./installer/flutter_windows.dll" KeyPath="yes"/>
|
||||
</Component>
|
||||
<Component Guid="{32F0A64B-0C07-4807-A48C-714B2533A03C}">
|
||||
<File Source="./installer/msvcp140.dll" KeyPath="yes"/>
|
||||
</Component>
|
||||
<Component Guid="{8425DEB5-8CF4-4672-AE45-561CF76B2072}">
|
||||
<File Source="./installer/vcruntime140.dll" KeyPath="yes"/>
|
||||
</Component>
|
||||
<Component Guid="{1F3DBC7E-25D5-441D-9B41-96C33FEA5157}">
|
||||
<File Source="./installer/vcruntime140_1.dll" KeyPath="yes"/>
|
||||
</Component>
|
||||
<Component Guid="{BE7FE765-EBA8-4FAB-8864-8561C50D39CF}">
|
||||
<File Source="./installer/window_size_plugin.dll" KeyPath="yes"/>
|
||||
</Component>
|
||||
</ComponentGroup>
|
||||
<ComponentGroup Id="CCX_Components_MainFolder_data" Directory="CCX_data">
|
||||
<Component Id="cmp205CD51FCB7438CA9DDF9D318D5BDD93" Guid="{50D63F41-6529-4009-9092-F4D5B60DDF1B}">
|
||||
<File Id="filBBF0A8ED8BF5DEEA3D5FE3E0B96C18FF" KeyPath="yes" Source="./installer/data/app.so"/>
|
||||
</Component>
|
||||
<Component Id="cmp3BB4C81F1F7BAB8E1AEB858EBC85CC1E" Guid="{88E94229-FBE7-4DC8-B9E2-B5E27FFB844C}">
|
||||
<File Id="fil3F969272E8EAC0F75CC6D464590D2FBE" KeyPath="yes" Source="./installer/data/icudtl.dat"/>
|
||||
</Component>
|
||||
</ComponentGroup>
|
||||
<ComponentGroup Id="CCX_Components_MainFolder_data_flutter_assets" Directory="CCX_data_flutter_assets">
|
||||
<Component Id="cmp1C63471C238EEA92D0AE37BC7DF9E605" Guid="{DEAF277D-3D05-4B37-A732-9514B503B74A}">
|
||||
<File Id="fil3F43BEEF0A85EE6619E4674CA43CB616" KeyPath="yes" Source="./installer/data/flutter_assets/AssetManifest.json"/>
|
||||
</Component>
|
||||
<Component Id="cmp414DC13EF11DED7194619DD3FC5F4CA7" Guid="{E66832FA-6880-4249-92A0-A26A4FF0A1F9}">
|
||||
<File Id="filD6CD37343140A4FABEA77420A8B86B57" KeyPath="yes" Source="./installer/data/flutter_assets/FontManifest.json"/>
|
||||
</Component>
|
||||
<Component Id="cmp4AD05995360EA9B961C2D73FE38274D2" Guid="{B09977A1-1C36-4F5D-B3BC-394D10AC950D}">
|
||||
<File Id="filC4871B1F6646D8021500E7E62CF93FAC" KeyPath="yes" Source="./installer/data/flutter_assets/NOTICES.Z"/>
|
||||
</Component>
|
||||
</ComponentGroup>
|
||||
<ComponentGroup Id="CCX_Components_MainFolder_data_flutter_assets_assets" Directory="CCX_data_flutter_assets_assets">
|
||||
<Component Id="cmp5F6AEEA1DB53EC5D0D51921A0B62098C" Guid="{CECCAC58-B818-42E2-849A-BFA4A8CA4FBE}">
|
||||
<File Id="fil0E47318EAF44F6EEF60A89C92FCD2FAA" KeyPath="yes" Source="./installer/data/flutter_assets/assets/ccextractor"/>
|
||||
</Component>
|
||||
<Component Id="cmpDA8A6D10314F9C5A931AB86118A106CC" Guid="{75DE9E26-1024-4E83-8995-078624187483}">
|
||||
<File Id="fil72BB9315DC954394F9980ECD2DA6D21F" KeyPath="yes" Source="./installer/data/flutter_assets/assets/ccx.svg"/>
|
||||
</Component>
|
||||
</ComponentGroup>
|
||||
<ComponentGroup Id="CCX_Components_MainFolder_data_flutter_assets_fonts" Directory="CCX_data_flutter_assets_fonts">
|
||||
<Component Id="cmp97B1795B6861175BEF48B71FC703EDA6" Guid="{292269F8-9FC7-464A-A9AB-AF5BA97D7F06}">
|
||||
<File Id="fil26D47F100D1B90F2759D0EAE797393FC" KeyPath="yes" Source="./installer/data/flutter_assets/fonts/MaterialIcons-Regular.otf"/>
|
||||
</Component>
|
||||
</ComponentGroup>
|
||||
<ComponentGroup Id="CCX_Components_MainFolder_data_flutter_assets_cupertino" Directory="CCX_data_flutter_assets_cupertino">
|
||||
<Component Id="cmp18EDD5C842814546AE2A43759CD36C77" Guid="{30AFB9BB-1C7D-4CDB-ADCA-D0773F152B45}">
|
||||
<File Id="fil341334402AF57DB92DF3F7C92E983317" KeyPath="yes" Source="./installer/data/flutter_assets/packages/cupertino_icons/assets/CupertinoIcons.ttf"/>
|
||||
</Component>
|
||||
</ComponentGroup>
|
||||
</Fragment>
|
||||
</Wix>
|
||||
|
||||
Binary file not shown.
BIN
windows/libs/lib/ffmpeg-lib/avcodec_x32.lib
Normal file
BIN
windows/libs/lib/ffmpeg-lib/avcodec_x32.lib
Normal file
Binary file not shown.
Binary file not shown.
BIN
windows/libs/lib/ffmpeg-lib/avformat_x32.lib
Normal file
BIN
windows/libs/lib/ffmpeg-lib/avformat_x32.lib
Normal file
Binary file not shown.
Binary file not shown.
BIN
windows/libs/lib/ffmpeg-lib/avutil_x32.lib
Normal file
BIN
windows/libs/lib/ffmpeg-lib/avutil_x32.lib
Normal file
Binary file not shown.
Binary file not shown.
BIN
windows/libs/lib/ffmpeg-lib/swscale_x32.lib
Normal file
BIN
windows/libs/lib/ffmpeg-lib/swscale_x32.lib
Normal file
Binary file not shown.
6
windows/rust.bat
Normal file
6
windows/rust.bat
Normal file
@@ -0,0 +1,6 @@
|
||||
for /f "delims=" %%i in ('cd') do set output=%%i
|
||||
set CARGO_TARGET_DIR=%output%
|
||||
cd ..\src\rust
|
||||
cargo build
|
||||
cd ..\..\windows
|
||||
copy debug\ccx_rust.lib .\ccx_rust.lib
|
||||
6
windows/rustx86.bat
Normal file
6
windows/rustx86.bat
Normal file
@@ -0,0 +1,6 @@
|
||||
for /f "delims=" %%i in ('cd') do set output=%%i
|
||||
set CARGO_TARGET_DIR=%output%
|
||||
cd ..\src\rust
|
||||
cargo build --target=i686-pc-windows-msvc
|
||||
cd ..\..\windows
|
||||
copy i686-pc-windows-msvc\debug\ccx_rust.lib .\ccx_rust.lib
|
||||
Reference in New Issue
Block a user