mirror of
https://github.com/CCExtractor/ccextractor.git
synced 2026-02-08 13:34:59 +00:00
Compare commits
463 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a8f25ce25e | ||
|
|
2781a7f7d6 | ||
|
|
903ccc1442 | ||
|
|
941604b33c | ||
|
|
1950f096b6 | ||
|
|
1fc5ec00d4 | ||
|
|
c0deae4b0c | ||
|
|
84692b5658 | ||
|
|
4a51ad114e | ||
|
|
6789376b92 | ||
|
|
ea5125f030 | ||
|
|
000b39775c | ||
|
|
23fe02f0d2 | ||
|
|
394fb39a9c | ||
|
|
294bf5bc18 | ||
|
|
4e52e61c91 | ||
|
|
faaaabf63c | ||
|
|
f5a9018ef0 | ||
|
|
e01720c05e | ||
|
|
f80b1f26ca | ||
|
|
f9ebfd2a32 | ||
|
|
9f670de8ed | ||
|
|
fc4a14e7d6 | ||
|
|
4f13b861cd | ||
|
|
df692f296d | ||
|
|
419fc4694d | ||
|
|
fc230fc217 | ||
|
|
825e160e72 | ||
|
|
8e24c17c1e | ||
|
|
4e21fae053 | ||
|
|
be239a5c46 | ||
|
|
1d9f32239e | ||
|
|
cbb5f0b0a8 | ||
|
|
fd063931ea | ||
|
|
7a9acb7bd2 | ||
|
|
cbf180eb39 | ||
|
|
614e6c42b5 | ||
|
|
38bcb7ed85 | ||
|
|
d57354830e | ||
|
|
7b43201ce1 | ||
|
|
ea1c82ac17 | ||
|
|
b3f1e27f5c | ||
|
|
82c92d3910 | ||
|
|
5bf8e7de0d | ||
|
|
5b8a9709df | ||
|
|
063786c4b7 | ||
|
|
44363c0acd | ||
|
|
701271ec82 | ||
|
|
7c74ea4112 | ||
|
|
ed42525f44 | ||
|
|
b88d1ebab2 | ||
|
|
ec11b00f9f | ||
|
|
8c0fe08781 | ||
|
|
3304c1b094 | ||
|
|
5bad3732c3 | ||
|
|
e3b0defb49 | ||
|
|
2065c5509d | ||
|
|
5458370346 | ||
|
|
9e19c58edf | ||
|
|
0bb56d508a | ||
|
|
2c67381d2b | ||
|
|
94a43928ad | ||
|
|
25d68b75bd | ||
|
|
73cd19f5d0 | ||
|
|
d0caf23a82 | ||
|
|
da3dc52b45 | ||
|
|
0fdfb751ba | ||
|
|
0b5f13e2c4 | ||
|
|
60cec9e6de | ||
|
|
d758f3156a | ||
|
|
da802a0a39 | ||
|
|
8f78a8bbb2 | ||
|
|
e87807ec27 | ||
|
|
d097ec881c | ||
|
|
87c898497a | ||
|
|
49b698259d | ||
|
|
5715d6d315 | ||
|
|
9fddaab3b0 | ||
|
|
6fdfde0838 | ||
|
|
8db7fc7a6d | ||
|
|
d8504f80bd | ||
|
|
70404c29ca | ||
|
|
feb2a61c1d | ||
|
|
6503502624 | ||
|
|
bf271de52c | ||
|
|
67e560d288 | ||
|
|
54bc97a3f8 | ||
|
|
3d7c534824 | ||
|
|
eda489265d | ||
|
|
0ac093e4b2 | ||
|
|
6838666b79 | ||
|
|
08d59ecb5f | ||
|
|
2ce3e0c0de | ||
|
|
3f45a4e136 | ||
|
|
d0d46fc176 | ||
|
|
3e9ed3043b | ||
|
|
1bdd9abd35 | ||
|
|
9e970fd788 | ||
|
|
87bc1d9613 | ||
|
|
440cd5527f | ||
|
|
0fbbc06bcf | ||
|
|
5f0c6728bf | ||
|
|
b9aabcd60d | ||
|
|
d0243237db | ||
|
|
a86a4ca7ce | ||
|
|
77624ec678 | ||
|
|
73db3a2c39 | ||
|
|
dd3dab7d52 | ||
|
|
ebfa31c333 | ||
|
|
d52d26baf8 | ||
|
|
3a852b7915 | ||
|
|
c3f637a10e | ||
|
|
f3768625c6 | ||
|
|
c733902473 | ||
|
|
6c44100f97 | ||
|
|
a0593c60e3 | ||
|
|
300f8ca65a | ||
|
|
8988152fa5 | ||
|
|
78642bcf02 | ||
|
|
0c0e44472d | ||
|
|
2060db99c8 | ||
|
|
a299d06d97 | ||
|
|
50b51e4234 | ||
|
|
0b74c9226a | ||
|
|
80957d645b | ||
|
|
80a117e643 | ||
|
|
63999369b7 | ||
|
|
0e815c6e2d | ||
|
|
0ef7227d7e | ||
|
|
2fa023b9fe | ||
|
|
2f0770d45f | ||
|
|
ee36ac1d4d | ||
|
|
e160a533b0 | ||
|
|
083c12698f | ||
|
|
88fbe9190a | ||
|
|
ac49bb5978 | ||
|
|
138ccd01c2 | ||
|
|
9fe2dab6d4 | ||
|
|
a28561ad0d | ||
|
|
c8f6b565fd | ||
|
|
442ce1015d | ||
|
|
e2dfdaa6a8 | ||
|
|
a0809caa94 | ||
|
|
859741a22c | ||
|
|
4429067965 | ||
|
|
d72646ac85 | ||
|
|
4a304346c9 | ||
|
|
627e0855ce | ||
|
|
7b1a169b8f | ||
|
|
3d5d8e2a0a | ||
|
|
683468e233 | ||
|
|
89849d321f | ||
|
|
588ad5260a | ||
|
|
ebd8148cad | ||
|
|
ba33f7572d | ||
|
|
9cf96b1899 | ||
|
|
0b3ad40377 | ||
|
|
ac72625030 | ||
|
|
f6cb862dcb | ||
|
|
53c0f56b6f | ||
|
|
62272e7be6 | ||
|
|
a7e05c265c | ||
|
|
9ce13cf45f | ||
|
|
e0ac99a241 | ||
|
|
6ebf98ea4a | ||
|
|
9372e15024 | ||
|
|
7e1a01447a | ||
|
|
b728ddadfa | ||
|
|
300541b873 | ||
|
|
2f1c1bf227 | ||
|
|
0bcb532428 | ||
|
|
d8698dc9cb | ||
|
|
4cc9231fc8 | ||
|
|
d202a66fd0 | ||
|
|
d8048bc95a | ||
|
|
af3ab5acd4 | ||
|
|
90519e2296 | ||
|
|
494b14b651 | ||
|
|
5b286c5b8d | ||
|
|
ea4f884b9d | ||
|
|
3b0a63d9c6 | ||
|
|
390c96f00d | ||
|
|
95f6f09659 | ||
|
|
42885caedd | ||
|
|
8d95ad0e7b | ||
|
|
1f0980185f | ||
|
|
6c764aa56c | ||
|
|
a0129df16c | ||
|
|
d2ab31fe38 | ||
|
|
3f6656176e | ||
|
|
f2f63ed65f | ||
|
|
3738540804 | ||
|
|
31c6e94e25 | ||
|
|
33f41f6045 | ||
|
|
137719ebea | ||
|
|
ecb0780af5 | ||
|
|
abce0864a5 | ||
|
|
9ff46656be | ||
|
|
446923c79d | ||
|
|
cde9e1f842 | ||
|
|
6c75b26484 | ||
|
|
9c4d5a8a58 | ||
|
|
a49ebf4230 | ||
|
|
7b8533a2dc | ||
|
|
134cd75d3b | ||
|
|
80e21171b1 | ||
|
|
0b262d0e17 | ||
|
|
f579cbe45d | ||
|
|
1a83913540 | ||
|
|
075ae04f1d | ||
|
|
d4949ccfa3 | ||
|
|
588c981184 | ||
|
|
941b88f3f9 | ||
|
|
071d017b27 | ||
|
|
65d9a7ed1a | ||
|
|
54df50f4fe | ||
|
|
bc5d605543 | ||
|
|
a1a0094167 | ||
|
|
5b8d8a72d8 | ||
|
|
621871eb7c | ||
|
|
ffcb5fe149 | ||
|
|
1b0808b4f3 | ||
|
|
68da0a044d | ||
|
|
87b0d22057 | ||
|
|
af5e36cdab | ||
|
|
8329257b99 | ||
|
|
1869c4c713 | ||
|
|
b3c3bdcdac | ||
|
|
6e295ac374 | ||
|
|
468bd2c156 | ||
|
|
bcf7eb2a50 | ||
|
|
54c7dfa45f | ||
|
|
984123521d | ||
|
|
a2cb65f181 | ||
|
|
fe7a4b3f45 | ||
|
|
d4ec0fe49b | ||
|
|
4a98bf5290 | ||
|
|
249cac359f | ||
|
|
69e521b320 | ||
|
|
8af19df556 | ||
|
|
bff08bec9e | ||
|
|
a66fb8c661 | ||
|
|
042716adde | ||
|
|
1342e4edee | ||
|
|
4d1d874243 | ||
|
|
155f56ede7 | ||
|
|
fb49d9460d | ||
|
|
37fed5e5b5 | ||
|
|
7113036719 | ||
|
|
d93d6731ba | ||
|
|
77e1dff779 | ||
|
|
58dedba93f | ||
|
|
9eb266914a | ||
|
|
1510396aa0 | ||
|
|
a7dfaea559 | ||
|
|
e8383c84ee | ||
|
|
810c869bc5 | ||
|
|
b32c120e89 | ||
|
|
3d7553349f | ||
|
|
d524a0247f | ||
|
|
f30f276456 | ||
|
|
17a8e1ec7b | ||
|
|
ebe25af476 | ||
|
|
1f7120f32f | ||
|
|
9e9023c258 | ||
|
|
b2930178be | ||
|
|
759c3f5d41 | ||
|
|
3c51fb6536 | ||
|
|
494df3edae | ||
|
|
810e02f7fa | ||
|
|
2720448e87 | ||
|
|
5fceac5e90 | ||
|
|
60ae6fb760 | ||
|
|
c9d80e12b8 | ||
|
|
a0aa9e4616 | ||
|
|
1515f5c1be | ||
|
|
42d750950a | ||
|
|
5338c15f8d | ||
|
|
ee232b5ded | ||
|
|
654d00a54e | ||
|
|
d86ee721df | ||
|
|
da03c1ec9d | ||
|
|
ebd8252b88 | ||
|
|
1c7e2a0995 | ||
|
|
fb6a8301f6 | ||
|
|
f2168b4c79 | ||
|
|
24f718427f | ||
|
|
c2a1f0d91f | ||
|
|
12a27f34a0 | ||
|
|
ba59eb0887 | ||
|
|
3f441150b4 | ||
|
|
f09b6ff446 | ||
|
|
8c23447d35 | ||
|
|
4b5f68a6a4 | ||
|
|
25a447d42e | ||
|
|
7eba462b67 | ||
|
|
a34ba0f6b7 | ||
|
|
1ac3f05765 | ||
|
|
39e051b731 | ||
|
|
7d95b0574d | ||
|
|
6300bb7bca | ||
|
|
afde4d601f | ||
|
|
5a016d09b1 | ||
|
|
b63a29cd2e | ||
|
|
81fdecd5af | ||
|
|
099fa059c7 | ||
|
|
e663eca763 | ||
|
|
77b93e5ced | ||
|
|
2260165682 | ||
|
|
715597e325 | ||
|
|
407d0f4e93 | ||
|
|
9d1718f85f | ||
|
|
5b327c78fa | ||
|
|
17247daf8b | ||
|
|
888ffa4ee0 | ||
|
|
3851d24315 | ||
|
|
e597f01994 | ||
|
|
b62027a0ae | ||
|
|
9685ad6149 | ||
|
|
d7231d4567 | ||
|
|
a84256da01 | ||
|
|
9e2a594bca | ||
|
|
fc01fa05bd | ||
|
|
9ea3c9fd41 | ||
|
|
d276fb17f7 | ||
|
|
8c90bda9a2 | ||
|
|
27e1a3c849 | ||
|
|
0912ac8de0 | ||
|
|
65a0348b4f | ||
|
|
564795cdd3 | ||
|
|
ffe075b1f3 | ||
|
|
b08c5faa74 | ||
|
|
cbd8e27fe3 | ||
|
|
349020ece9 | ||
|
|
1a13bbb071 | ||
|
|
90f9f0a183 | ||
|
|
98a85e1be3 | ||
|
|
92f2ce0fa0 | ||
|
|
b92ca87835 | ||
|
|
8d4fdd7f3e | ||
|
|
b679215752 | ||
|
|
25e8b3642d | ||
|
|
f8001ae295 | ||
|
|
5f9b395bc6 | ||
|
|
9340cc7df6 | ||
|
|
90204d4cc6 | ||
|
|
34bb9dd20d | ||
|
|
8d9bf42be2 | ||
|
|
8e4c07ed97 | ||
|
|
cf9c9dde53 | ||
|
|
f5da158935 | ||
|
|
f12f12b916 | ||
|
|
d6ccf1bfcb | ||
|
|
8e3b145477 | ||
|
|
5748042f6d | ||
|
|
3f504412f5 | ||
|
|
312d10c001 | ||
|
|
f08febfd61 | ||
|
|
89a12a7dd0 | ||
|
|
2ada36d50e | ||
|
|
2d2a210c54 | ||
|
|
deaa4a68e0 | ||
|
|
f449d06cd1 | ||
|
|
c550726778 | ||
|
|
bce63b88dc | ||
|
|
63a259a313 | ||
|
|
eef2591c25 | ||
|
|
870e8bb6ac | ||
|
|
d2f17deb2c | ||
|
|
376ff83161 | ||
|
|
79aaf86593 | ||
|
|
280939df75 | ||
|
|
af6308b167 | ||
|
|
aa4a76a941 | ||
|
|
35e73c1c90 | ||
|
|
5b7666965f | ||
|
|
3efb2b1a68 | ||
|
|
6bcc53ecf9 | ||
|
|
7b873e1902 | ||
|
|
005ef5a731 | ||
|
|
72e769b145 | ||
|
|
cf2d207ba1 | ||
|
|
d768474e50 | ||
|
|
4a7dd139ec | ||
|
|
fa85a5270d | ||
|
|
7994096669 | ||
|
|
d379d72685 | ||
|
|
9b2215d9c2 | ||
|
|
29562759d2 | ||
|
|
0b6a8987ca | ||
|
|
a679aadd3a | ||
|
|
77b9696a37 | ||
|
|
f21d9e8737 | ||
|
|
fb3da4cd3a | ||
|
|
b983de6a54 | ||
|
|
260052b68c | ||
|
|
8105bc0b73 | ||
|
|
ea4998f635 | ||
|
|
cb496a7119 | ||
|
|
79958f7393 | ||
|
|
0264e7da2b | ||
|
|
257388bad3 | ||
|
|
1604572995 | ||
|
|
9125165231 | ||
|
|
b1cbfcea9b | ||
|
|
8bb52fa6d5 | ||
|
|
7bd3f7e788 | ||
|
|
f4bf40b05d | ||
|
|
b488126d09 | ||
|
|
1c6160f548 | ||
|
|
40145abccf | ||
|
|
492f0d5197 | ||
|
|
4b0928ad9b | ||
|
|
0e3dfdc73b | ||
|
|
4cb474c5a3 | ||
|
|
19f6ef43ef | ||
|
|
4dbcbe083e | ||
|
|
2a9a922d1a | ||
|
|
0d3e1d003d | ||
|
|
170066f046 | ||
|
|
0bd213e789 | ||
|
|
4712d85190 | ||
|
|
d95a3b3354 | ||
|
|
39724fe6a7 | ||
|
|
0f90afaa1b | ||
|
|
689d92ab59 | ||
|
|
ca303d6942 | ||
|
|
6a9a16e611 | ||
|
|
30bc27aa0c | ||
|
|
c3fc323150 | ||
|
|
b5fe0609fc | ||
|
|
0a4049c97c | ||
|
|
6e4ac56e9c | ||
|
|
e6503d5c81 | ||
|
|
1717cbb44d | ||
|
|
caa960e657 | ||
|
|
290e2f10f9 | ||
|
|
325464f793 | ||
|
|
f533a53902 | ||
|
|
97b381a2b0 | ||
|
|
03b0749e91 | ||
|
|
7bcdd6729f | ||
|
|
3dd3d5f6aa | ||
|
|
ba37cc41c8 | ||
|
|
6efa41a7e6 | ||
|
|
9b90c91f07 | ||
|
|
35936618e3 | ||
|
|
e98a584e98 | ||
|
|
1a8c8a86f3 | ||
|
|
57663b8cf1 | ||
|
|
2b3d759e20 | ||
|
|
ed1b5dddce | ||
|
|
86fede6af8 | ||
|
|
68e6390c76 | ||
|
|
0ebeec4183 | ||
|
|
8c10ded107 | ||
|
|
3a1851f904 | ||
|
|
50aceb45fb | ||
|
|
cad6b0495c | ||
|
|
c7ebd45d9f | ||
|
|
77abe01885 | ||
|
|
98cec31516 | ||
|
|
46b145a396 |
37
.dockerignore
Normal file
37
.dockerignore
Normal file
@@ -0,0 +1,37 @@
|
||||
# Build artifacts
|
||||
linux/ccextractor
|
||||
linux/rust/
|
||||
linux/*.o
|
||||
linux/*.a
|
||||
mac/ccextractor
|
||||
mac/rust/
|
||||
build/
|
||||
build_*/
|
||||
|
||||
# Git
|
||||
.git/
|
||||
.github/
|
||||
|
||||
# IDE
|
||||
.vscode/
|
||||
.idea/
|
||||
*.swp
|
||||
*.swo
|
||||
|
||||
# Docker
|
||||
docker/
|
||||
|
||||
# Documentation (not needed for build)
|
||||
docs/
|
||||
*.md
|
||||
!README.md
|
||||
|
||||
# Test files
|
||||
*.ts
|
||||
*.mp4
|
||||
*.mkv
|
||||
*.srt
|
||||
*.vtt
|
||||
|
||||
# Plans
|
||||
plans/
|
||||
157
.github/workflows/build_appimage.yml
vendored
Normal file
157
.github/workflows/build_appimage.yml
vendored
Normal file
@@ -0,0 +1,157 @@
|
||||
name: Build Linux AppImage
|
||||
|
||||
on:
|
||||
# Build on releases
|
||||
release:
|
||||
types: [published]
|
||||
# Allow manual trigger
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
build_type:
|
||||
description: 'Build type (all, minimal, ocr, hardsubx)'
|
||||
required: false
|
||||
default: 'all'
|
||||
# Build on pushes to workflow file for testing
|
||||
push:
|
||||
paths:
|
||||
- '.github/workflows/build_appimage.yml'
|
||||
- 'linux/build_appimage.sh'
|
||||
|
||||
jobs:
|
||||
build-appimage:
|
||||
runs-on: ubuntu-22.04
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
build_type: [minimal, ocr, hardsubx]
|
||||
|
||||
steps:
|
||||
- name: Check if should build this variant
|
||||
id: should_build
|
||||
run: |
|
||||
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
|
||||
INPUT_TYPE="${{ github.event.inputs.build_type }}"
|
||||
if [ "$INPUT_TYPE" = "all" ] || [ "$INPUT_TYPE" = "${{ matrix.build_type }}" ]; then
|
||||
echo "should_build=true" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "should_build=false" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
else
|
||||
echo "should_build=true" >> $GITHUB_OUTPUT
|
||||
fi
|
||||
|
||||
- name: Checkout repository
|
||||
if: steps.should_build.outputs.should_build == 'true'
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Install base dependencies
|
||||
if: steps.should_build.outputs.should_build == 'true'
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y --no-install-recommends \
|
||||
build-essential \
|
||||
cmake \
|
||||
pkg-config \
|
||||
wget \
|
||||
file \
|
||||
libfuse2 \
|
||||
zlib1g-dev \
|
||||
libpng-dev \
|
||||
libjpeg-dev \
|
||||
libfreetype-dev \
|
||||
libxml2-dev \
|
||||
libcurl4-gnutls-dev \
|
||||
libssl-dev \
|
||||
clang \
|
||||
libclang-dev
|
||||
|
||||
- name: Install OCR dependencies
|
||||
if: steps.should_build.outputs.should_build == 'true' && (matrix.build_type == 'ocr' || matrix.build_type == 'hardsubx')
|
||||
run: |
|
||||
sudo apt-get install -y --no-install-recommends \
|
||||
tesseract-ocr \
|
||||
libtesseract-dev \
|
||||
libleptonica-dev \
|
||||
tesseract-ocr-eng
|
||||
|
||||
- name: Install FFmpeg dependencies (HardSubX)
|
||||
if: steps.should_build.outputs.should_build == 'true' && matrix.build_type == 'hardsubx'
|
||||
run: |
|
||||
sudo apt-get install -y --no-install-recommends \
|
||||
libavcodec-dev \
|
||||
libavformat-dev \
|
||||
libavutil-dev \
|
||||
libswscale-dev \
|
||||
libswresample-dev \
|
||||
libavfilter-dev \
|
||||
libavdevice-dev
|
||||
|
||||
- name: Install Rust toolchain
|
||||
if: steps.should_build.outputs.should_build == 'true'
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
|
||||
- name: Cache GPAC build
|
||||
if: steps.should_build.outputs.should_build == 'true'
|
||||
id: cache-gpac
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: /usr/local/lib/libgpac*
|
||||
key: gpac-v2.4.0-ubuntu22
|
||||
|
||||
- name: Build and install GPAC
|
||||
if: steps.should_build.outputs.should_build == 'true' && steps.cache-gpac.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
git clone -b v2.4.0 --depth 1 https://github.com/gpac/gpac
|
||||
cd gpac
|
||||
./configure
|
||||
make -j$(nproc) lib
|
||||
sudo make install-lib
|
||||
sudo ldconfig
|
||||
|
||||
- name: Update library cache
|
||||
if: steps.should_build.outputs.should_build == 'true'
|
||||
run: sudo ldconfig
|
||||
|
||||
- name: Build AppImage
|
||||
if: steps.should_build.outputs.should_build == 'true'
|
||||
run: |
|
||||
cd linux
|
||||
chmod +x build_appimage.sh
|
||||
BUILD_TYPE=${{ matrix.build_type }} ./build_appimage.sh
|
||||
|
||||
- name: Get AppImage name
|
||||
if: steps.should_build.outputs.should_build == 'true'
|
||||
id: appimage_name
|
||||
run: |
|
||||
case "${{ matrix.build_type }}" in
|
||||
minimal)
|
||||
echo "name=ccextractor-minimal-x86_64.AppImage" >> $GITHUB_OUTPUT
|
||||
;;
|
||||
ocr)
|
||||
echo "name=ccextractor-x86_64.AppImage" >> $GITHUB_OUTPUT
|
||||
;;
|
||||
hardsubx)
|
||||
echo "name=ccextractor-hardsubx-x86_64.AppImage" >> $GITHUB_OUTPUT
|
||||
;;
|
||||
esac
|
||||
|
||||
- name: Test AppImage
|
||||
if: steps.should_build.outputs.should_build == 'true'
|
||||
run: |
|
||||
chmod +x linux/${{ steps.appimage_name.outputs.name }}
|
||||
linux/${{ steps.appimage_name.outputs.name }} --version
|
||||
|
||||
- name: Upload AppImage artifact
|
||||
if: steps.should_build.outputs.should_build == 'true'
|
||||
uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: ${{ steps.appimage_name.outputs.name }}
|
||||
path: linux/${{ steps.appimage_name.outputs.name }}
|
||||
|
||||
- name: Upload to Release
|
||||
if: steps.should_build.outputs.should_build == 'true' && github.event_name == 'release'
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
files: linux/${{ steps.appimage_name.outputs.name }}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
92
.github/workflows/build_docker.yml
vendored
Normal file
92
.github/workflows/build_docker.yml
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
name: Build CCExtractor Docker Images
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
paths:
|
||||
- '.github/workflows/build_docker.yml'
|
||||
- 'docker/**'
|
||||
- '**.c'
|
||||
- '**.h'
|
||||
- 'src/rust/**'
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
paths:
|
||||
- '.github/workflows/build_docker.yml'
|
||||
- 'docker/**'
|
||||
- '**.c'
|
||||
- '**.h'
|
||||
- 'src/rust/**'
|
||||
|
||||
jobs:
|
||||
build_minimal:
|
||||
name: Docker build (minimal)
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
- name: Build minimal image
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
file: docker/Dockerfile
|
||||
build-args: |
|
||||
BUILD_TYPE=minimal
|
||||
USE_LOCAL_SOURCE=1
|
||||
tags: ccextractor:minimal
|
||||
load: true
|
||||
cache-from: type=gha,scope=docker-minimal
|
||||
cache-to: type=gha,mode=max,scope=docker-minimal
|
||||
- name: Test minimal image
|
||||
run: |
|
||||
docker run --rm ccextractor:minimal --version
|
||||
echo "Minimal build successful"
|
||||
|
||||
build_ocr:
|
||||
name: Docker build (ocr)
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
- name: Build OCR image
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
file: docker/Dockerfile
|
||||
build-args: |
|
||||
BUILD_TYPE=ocr
|
||||
USE_LOCAL_SOURCE=1
|
||||
tags: ccextractor:ocr
|
||||
load: true
|
||||
cache-from: type=gha,scope=docker-ocr
|
||||
cache-to: type=gha,mode=max,scope=docker-ocr
|
||||
- name: Test OCR image
|
||||
run: |
|
||||
docker run --rm ccextractor:ocr --version
|
||||
echo "OCR build successful"
|
||||
|
||||
build_hardsubx:
|
||||
name: Docker build (hardsubx)
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
- name: Build HardSubX image
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
file: docker/Dockerfile
|
||||
build-args: |
|
||||
BUILD_TYPE=hardsubx
|
||||
USE_LOCAL_SOURCE=1
|
||||
tags: ccextractor:hardsubx
|
||||
load: true
|
||||
cache-from: type=gha,scope=docker-hardsubx
|
||||
cache-to: type=gha,mode=max,scope=docker-hardsubx
|
||||
- name: Test HardSubX image
|
||||
run: |
|
||||
docker run --rm ccextractor:hardsubx --version
|
||||
echo "HardSubX build successful"
|
||||
58
.github/workflows/build_linux.yml
vendored
58
.github/workflows/build_linux.yml
vendored
@@ -1,6 +1,7 @@
|
||||
name: Build CCExtractor on Linux
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
paths:
|
||||
- '.github/workflows/build_linux.yml'
|
||||
@@ -10,8 +11,6 @@ on:
|
||||
- 'linux/**'
|
||||
- 'package_creators/**'
|
||||
- 'src/rust/**'
|
||||
tags-ignore: # ignore push via new tag
|
||||
- '*.*'
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
paths:
|
||||
@@ -26,41 +25,47 @@ jobs:
|
||||
build_shell:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Install tesseract
|
||||
run: sudo apt-get install libtesseract-dev
|
||||
- uses: actions/checkout@v2.3.4
|
||||
- name: Install dependencies
|
||||
run: sudo apt update && sudo apt-get install libgpac-dev libtesseract-dev libavcodec-dev libavdevice-dev libx11-dev libxcb1-dev libxcb-shm0-dev
|
||||
- uses: actions/checkout@v6
|
||||
- name: build
|
||||
run: ./build
|
||||
run: ./build -hardsubx
|
||||
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
|
||||
run: cp ./linux/ccextractor ./linux/artifacts/
|
||||
- uses: actions/upload-artifact@v2
|
||||
- uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: CCExtractor Linux build
|
||||
path: ./linux/artifacts
|
||||
build_autoconf:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2.3.4
|
||||
- name: Install dependencies
|
||||
run: sudo apt update && sudo apt-get install libgpac-dev
|
||||
- uses: actions/checkout@v6
|
||||
- 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
|
||||
- name: Install dependencies
|
||||
run: sudo apt update && sudo apt-get install libgpac-dev
|
||||
- uses: actions/checkout@v6
|
||||
- name: cmake
|
||||
run: mkdir build && cd build && cmake ../src
|
||||
- name: build
|
||||
@@ -71,32 +76,27 @@ jobs:
|
||||
cmake_ocr_hardsubx:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2.3.4
|
||||
- name: dependencies
|
||||
run: sudo apt update && sudo apt install libtesseract-dev libavformat-dev libswscale-dev
|
||||
- uses: actions/checkout@v6
|
||||
- name: Install dependencies
|
||||
run: sudo apt update && sudo apt install libgpac-dev libtesseract-dev libavformat-dev libavdevice-dev libswscale-dev yasm
|
||||
- name: cmake
|
||||
run: mkdir build && cd build && cmake -DWITH_OCR=ON -DWITH_HARDSUBX=ON ../src
|
||||
run: |
|
||||
mkdir build && cd build
|
||||
cmake -DWITH_OCR=ON -DWITH_HARDSUBX=ON ../src
|
||||
- name: build
|
||||
run: make -j$(nproc)
|
||||
run: |
|
||||
make -j$(nproc)
|
||||
working-directory: build
|
||||
- name: Display version information
|
||||
run: ./build/ccextractor --version
|
||||
bazel:
|
||||
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
|
||||
build_rust:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2.3.4
|
||||
- name: Install dependencies
|
||||
run: sudo apt update && sudo apt-get install libgpac-dev
|
||||
- uses: actions/checkout@v6
|
||||
- name: cache
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: |
|
||||
src/rust/.cargo/registry
|
||||
|
||||
173
.github/workflows/build_mac.yml
vendored
Normal file
173
.github/workflows/build_mac.yml
vendored
Normal file
@@ -0,0 +1,173 @@
|
||||
name: Build CCExtractor on Mac
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
paths:
|
||||
- '.github/workflows/build_mac.yml'
|
||||
- '**.c'
|
||||
- '**.h'
|
||||
- '**Makefile**'
|
||||
- 'mac/**'
|
||||
- 'package_creators/**'
|
||||
- 'src/rust/**'
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
paths:
|
||||
- '.github/workflows/build_mac.yml'
|
||||
- '**.c'
|
||||
- '**.h'
|
||||
- '**Makefile**'
|
||||
- 'mac/**'
|
||||
- 'package_creators/**'
|
||||
- 'src/rust/**'
|
||||
jobs:
|
||||
build_shell:
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- name: Install dependencies
|
||||
run: brew install pkg-config autoconf automake libtool tesseract leptonica gpac
|
||||
- uses: actions/checkout@v6
|
||||
- name: build
|
||||
run: ./build.command
|
||||
working-directory: ./mac
|
||||
- name: Display version information
|
||||
run: ./ccextractor --version
|
||||
working-directory: ./mac
|
||||
- name: Prepare artifacts
|
||||
run: mkdir ./mac/artifacts
|
||||
- name: Copy release artifact
|
||||
run: cp ./mac/ccextractor ./mac/artifacts/
|
||||
- uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: CCExtractor mac build
|
||||
path: ./mac/artifacts
|
||||
build_shell_system_libs:
|
||||
# Test building with system libraries via pkg-config (for Homebrew formula compatibility)
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- name: Install dependencies
|
||||
run: brew install pkg-config autoconf automake libtool tesseract leptonica gpac freetype libpng protobuf-c utf8proc zlib
|
||||
- uses: actions/checkout@v6
|
||||
- name: build with system libs
|
||||
run: ./build.command -system-libs
|
||||
working-directory: ./mac
|
||||
- name: Display version information
|
||||
run: ./ccextractor --version
|
||||
working-directory: ./mac
|
||||
build_autoconf:
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- name: Install dependencies
|
||||
run: brew install pkg-config autoconf automake libtool gpac
|
||||
- name: run autogen
|
||||
run: ./autogen.sh
|
||||
working-directory: ./mac
|
||||
- name: configure
|
||||
run: ./configure --enable-debug
|
||||
working-directory: ./mac
|
||||
- name: make
|
||||
run: make
|
||||
working-directory: ./mac
|
||||
- name: Display version information
|
||||
run: ./ccextractor --version
|
||||
working-directory: ./mac
|
||||
cmake:
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- name: dependencies
|
||||
run: brew install gpac
|
||||
- uses: actions/checkout@v6
|
||||
- name: cmake
|
||||
run: mkdir build && cd build && cmake ../src
|
||||
- name: build
|
||||
run: make -j$(nproc)
|
||||
working-directory: build
|
||||
- name: Display version information
|
||||
run: ./build/ccextractor --version
|
||||
cmake_ocr_hardsubx:
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- name: Install dependencies
|
||||
run: brew install pkg-config autoconf automake libtool tesseract leptonica gpac ffmpeg
|
||||
- name: cmake
|
||||
run: |
|
||||
mkdir build && cd build
|
||||
cmake -DWITH_OCR=ON -DWITH_HARDSUBX=ON ../src
|
||||
- name: build
|
||||
run: |
|
||||
make -j$(nproc)
|
||||
working-directory: build
|
||||
- name: Display version information
|
||||
run: ./build/ccextractor --version
|
||||
build_shell_hardsubx:
|
||||
# Test build.command with -hardsubx flag (burned-in subtitle extraction)
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- name: Install dependencies
|
||||
run: brew install pkg-config autoconf automake libtool tesseract leptonica gpac ffmpeg
|
||||
- uses: actions/checkout@v6
|
||||
- name: build with hardsubx
|
||||
run: ./build.command -hardsubx
|
||||
working-directory: ./mac
|
||||
- name: Display version information
|
||||
run: ./ccextractor --version
|
||||
working-directory: ./mac
|
||||
- name: Verify hardsubx support
|
||||
run: |
|
||||
# Check that -hardsubx is recognized (will fail if not compiled in)
|
||||
./ccextractor -hardsubx --help 2>&1 | head -20 || true
|
||||
working-directory: ./mac
|
||||
build_autoconf_hardsubx:
|
||||
# Test autoconf build with HARDSUBX enabled (fixes issue #1173)
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- name: Install dependencies
|
||||
run: brew install pkg-config autoconf automake libtool tesseract leptonica gpac ffmpeg
|
||||
- name: run autogen
|
||||
run: ./autogen.sh
|
||||
working-directory: ./mac
|
||||
- name: configure with hardsubx
|
||||
run: |
|
||||
# Set Homebrew paths for configure to find libraries
|
||||
export HOMEBREW_PREFIX="$(brew --prefix)"
|
||||
export LDFLAGS="-L${HOMEBREW_PREFIX}/lib"
|
||||
export CPPFLAGS="-I${HOMEBREW_PREFIX}/include"
|
||||
export PKG_CONFIG_PATH="${HOMEBREW_PREFIX}/lib/pkgconfig"
|
||||
./configure --enable-hardsubx --enable-ocr
|
||||
working-directory: ./mac
|
||||
- name: make
|
||||
run: make
|
||||
working-directory: ./mac
|
||||
- name: Display version information
|
||||
run: ./ccextractor --version
|
||||
working-directory: ./mac
|
||||
- name: Verify hardsubx support
|
||||
run: |
|
||||
# Check that -hardsubx is recognized
|
||||
./ccextractor -hardsubx --help 2>&1 | head -20 || true
|
||||
working-directory: ./mac
|
||||
build_rust:
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- name: cache
|
||||
uses: actions/cache@v5
|
||||
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
|
||||
205
.github/workflows/build_windows.yml
vendored
205
.github/workflows/build_windows.yml
vendored
@@ -1,98 +1,131 @@
|
||||
name: Build CCExtractor on Windows
|
||||
|
||||
env:
|
||||
RUSTFLAGS: -Ctarget-feature=+crt-static
|
||||
VCPKG_DEFAULT_TRIPLET: x64-windows-static
|
||||
VCPKG_DEFAULT_BINARY_CACHE: C:\vcpkg\.cache
|
||||
VCPKG_COMMIT: ab2977be50c702126336e5088f4836060733c899
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
push:
|
||||
paths:
|
||||
- '.github/workflows/build_windows.yml'
|
||||
- '**.c'
|
||||
- '**.h'
|
||||
- 'windows/**'
|
||||
tags-ignore: # ignore push via new tag
|
||||
- '*.*'
|
||||
- ".github/workflows/build_windows.yml"
|
||||
- "**.c"
|
||||
- "**.h"
|
||||
- "windows/**"
|
||||
- "src/rust/**"
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
paths:
|
||||
- '.github/workflows/build_windows.yml'
|
||||
- '**.c'
|
||||
- '**.h'
|
||||
- 'windows/**'
|
||||
- ".github/workflows/build_windows.yml"
|
||||
- "**.c"
|
||||
- "**.h"
|
||||
- "windows/**"
|
||||
- "src/rust/**"
|
||||
|
||||
jobs:
|
||||
build_non_ocr_release:
|
||||
runs-on: windows-latest
|
||||
build_release:
|
||||
runs-on: windows-2022
|
||||
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/*.dll
|
||||
build_non_ocr_debug:
|
||||
runs-on: windows-latest
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@v6
|
||||
- name: Setup MSBuild.exe
|
||||
uses: microsoft/setup-msbuild@v2.0.0
|
||||
with:
|
||||
msbuild-architecture: x64
|
||||
- name: Install gpac
|
||||
run: choco install gpac --version 2.4.0
|
||||
- name: Setup vcpkg
|
||||
run: mkdir C:\vcpkg\.cache
|
||||
- name: Cache vcpkg
|
||||
id: cache
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: |
|
||||
C:\vcpkg\.cache
|
||||
key: vcpkg-${{ runner.os }}-${{ env.VCPKG_COMMIT }}
|
||||
- name: Build vcpkg
|
||||
run: |
|
||||
git clone https://github.com/microsoft/vcpkg
|
||||
./vcpkg/bootstrap-vcpkg.bat
|
||||
- name: Install dependencies
|
||||
run: ${{ github.workspace }}/vcpkg/vcpkg.exe install --x-install-root ${{ github.workspace }}/vcpkg/installed/
|
||||
working-directory: windows
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
override: true
|
||||
- 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
|
||||
VCPKG_ROOT: ${{ github.workspace }}/vcpkg
|
||||
run: msbuild ccextractor.sln /p:Configuration=Release-Full /p:Platform=x64
|
||||
working-directory: ./windows
|
||||
- name: Display version information
|
||||
run: ./ccextractorwinfull.exe --version
|
||||
working-directory: ./windows/x64/Release-Full
|
||||
- uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: CCExtractor Windows Release build
|
||||
path: |
|
||||
./windows/x64/Release-Full/ccextractorwinfull.exe
|
||||
./windows/x64/Release-Full/*.dll
|
||||
build_debug:
|
||||
runs-on: windows-2022
|
||||
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/*.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
|
||||
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
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@v6
|
||||
- name: Setup MSBuild.exe
|
||||
uses: microsoft/setup-msbuild@v2.0.0
|
||||
with:
|
||||
msbuild-architecture: x64
|
||||
- name: Install gpac
|
||||
run: choco install gpac --version 2.4.0
|
||||
- name: Setup vcpkg
|
||||
run: mkdir C:\vcpkg\.cache
|
||||
- name: Cache vcpkg
|
||||
id: cache
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: |
|
||||
C:\vcpkg\.cache
|
||||
key: vcpkg-${{ runner.os }}-${{ env.VCPKG_COMMIT }}
|
||||
- name: Build vcpkg
|
||||
run: |
|
||||
git clone https://github.com/microsoft/vcpkg
|
||||
./vcpkg/bootstrap-vcpkg.bat
|
||||
- name: Install dependencies
|
||||
run: ${{ github.workspace }}/vcpkg/vcpkg.exe install --x-install-root ${{ github.workspace }}/vcpkg/installed/
|
||||
working-directory: windows
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
override: true
|
||||
- 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
|
||||
VCPKG_ROOT: ${{ github.workspace }}/vcpkg
|
||||
run: msbuild ccextractor.sln /p:Configuration=Debug-Full /p:Platform=x64
|
||||
working-directory: ./windows
|
||||
- name: Display version information
|
||||
continue-on-error: true
|
||||
run: ./ccextractorwinfull.exe --version
|
||||
working-directory: ./windows/x64/Debug-Full
|
||||
- uses: actions/upload-artifact@v6
|
||||
with:
|
||||
name: CCExtractor Windows Debug build
|
||||
path: |
|
||||
./windows/x64/Debug-Full/ccextractorwinfull.exe
|
||||
./windows/x64/Debug-Full/ccextractorwinfull.pdb
|
||||
./windows/x64/Debug-Full/*.dll
|
||||
|
||||
24
.github/workflows/format.yml
vendored
24
.github/workflows/format.yml
vendored
@@ -19,33 +19,39 @@ jobs:
|
||||
format:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2.3.4
|
||||
- uses: actions/checkout@v6
|
||||
- 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
|
||||
strategy:
|
||||
matrix:
|
||||
workdir: ['./src/rust', './src/rust/lib_ccxr']
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ./src/rust
|
||||
working-directory: ${{ matrix.workdir }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2.3.4
|
||||
- uses: actions/checkout@v6
|
||||
- name: cache
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: |
|
||||
src/rust/.cargo/registry
|
||||
src/rust/.cargo/git
|
||||
src/rust/target
|
||||
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
|
||||
${{ matrix.workdir }}/.cargo/registry
|
||||
${{ matrix.workdir }}/.cargo/git
|
||||
${{ matrix.workdir }}/target
|
||||
key: ${{ runner.os }}-cargo-${{ hashFiles('${{ matrix.workdir }}/Cargo.lock') }}
|
||||
restore-keys: ${{ runner.os }}-cargo-
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
override: true
|
||||
components: rustfmt, clippy
|
||||
- name: dependencies
|
||||
run: sudo apt update && sudo apt install libtesseract-dev libavformat-dev libavdevice-dev libswscale-dev yasm
|
||||
- name: rustfmt
|
||||
run: cargo fmt --all -- --check
|
||||
- name: clippy
|
||||
run: cargo clippy -- -D warnings
|
||||
run: |
|
||||
cargo clippy -- -D warnings
|
||||
|
||||
91
.github/workflows/release.yml
vendored
91
.github/workflows/release.yml
vendored
@@ -5,28 +5,73 @@ on:
|
||||
types:
|
||||
- created
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
env:
|
||||
RUSTFLAGS: -Ctarget-feature=+crt-static
|
||||
VCPKG_DEFAULT_TRIPLET: x64-windows-static
|
||||
VCPKG_DEFAULT_BINARY_CACHE: C:\vcpkg\.cache
|
||||
VCPKG_COMMIT: ab2977be50c702126336e5088f4836060733c899
|
||||
|
||||
jobs:
|
||||
build_windows:
|
||||
runs-on: windows-latest
|
||||
runs-on: windows-2022
|
||||
steps:
|
||||
- name: Check out repository
|
||||
uses: actions/checkout@v2.3.4
|
||||
uses: actions/checkout@v6
|
||||
- name: Get the version
|
||||
id: get_version
|
||||
run: echo ::set-output name=VERSION::${GITHUB_REF/refs\/tags\/v/}
|
||||
run: |
|
||||
# Extract version from tag, strip 'v' prefix and everything after first dash
|
||||
VERSION=${GITHUB_REF/refs\/tags\/v/}
|
||||
VERSION=${VERSION%%-*}
|
||||
echo ::set-output name=VERSION::$VERSION
|
||||
shell: bash
|
||||
- name: Setup MSBuild.exe
|
||||
uses: microsoft/setup-msbuild@v1.0.2
|
||||
- name: build Release
|
||||
run: msbuild ccextractor.sln /p:Configuration=Release-Full
|
||||
uses: microsoft/setup-msbuild@v2.0.0
|
||||
with:
|
||||
msbuild-architecture: x64
|
||||
- name: Install gpac
|
||||
run: choco install gpac --version 2.4.0
|
||||
- name: Setup vcpkg
|
||||
run: mkdir C:\vcpkg\.cache
|
||||
- name: Cache vcpkg
|
||||
id: cache
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: |
|
||||
C:\vcpkg\.cache
|
||||
key: vcpkg-${{ runner.os }}-${{ env.VCPKG_COMMIT }}
|
||||
- name: Build vcpkg
|
||||
run: |
|
||||
git clone https://github.com/microsoft/vcpkg
|
||||
./vcpkg/bootstrap-vcpkg.bat
|
||||
- name: Install dependencies
|
||||
run: ${{ github.workspace }}/vcpkg/vcpkg.exe install --x-install-root ${{ github.workspace }}/vcpkg/installed/
|
||||
working-directory: windows
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
override: true
|
||||
- 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
|
||||
VCPKG_ROOT: ${{ github.workspace }}/vcpkg
|
||||
run: msbuild ccextractor.sln /p:Configuration=Release-Full /p:Platform=x64
|
||||
working-directory: ./windows
|
||||
- name: Copy files to directory for installer
|
||||
run: mkdir installer; cp ./Release-Full/ccextractorwinfull.exe ./installer; cp ./Release-Full/*.dll ./installer
|
||||
run: mkdir installer; cp ./x64/Release-Full/ccextractorwinfull.exe ./installer; cp ./x64/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
|
||||
run: dotnet tool uninstall --global wix; dotnet tool install --global wix --version 6.0.2 && wix extension add -g WixToolset.UI.wixext/6.0.2
|
||||
- name: Make sure WiX works
|
||||
run: wix --version && wix extension -g list
|
||||
run: wix --version && wix extension list -g
|
||||
- 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
|
||||
@@ -34,16 +79,32 @@ jobs:
|
||||
run: ls
|
||||
working-directory: ./windows
|
||||
- name: Unzip Flutter GUI
|
||||
run: Expand-Archive -Path ./windows.zip -DestinationPath ./installer
|
||||
run: Expand-Archive -Path ./windows.zip -DestinationPath ./installer -Force
|
||||
working-directory: ./windows
|
||||
- name: Display installer folder contents
|
||||
run: Get-ChildItem -Recurse ./installer
|
||||
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
|
||||
- name: Create portable zip
|
||||
run: Compress-Archive -Path ./installer/* -DestinationPath ./CCExtractor_win_portable.zip
|
||||
working-directory: ./windows
|
||||
- name: Build installer
|
||||
run: wix build -ext WixToolset.UI.wixext -d "AppVersion=${{ steps.get_version.outputs.VERSION }}.0.0" -o CCExtractor.msi installer.wxs CustomUI.wxs
|
||||
working-directory: ./windows
|
||||
- name: Upload as asset
|
||||
uses: AButler/upload-release-assets@v2.0
|
||||
uses: AButler/upload-release-assets@v3.0
|
||||
with:
|
||||
files: './windows/CCExtractor.msi'
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
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@v6
|
||||
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@v3.0
|
||||
with:
|
||||
files: './ccextractor_minimal.tar.gz'
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
41
.github/workflows/test_rust.yml
vendored
Normal file
41
.github/workflows/test_rust.yml
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
name: Unit Test Rust
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- ".github/workflows/test.yml"
|
||||
- "src/rust/**"
|
||||
tags-ignore:
|
||||
- "*.*"
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
paths:
|
||||
- ".github/workflows/test.yml"
|
||||
- "src/rust/**"
|
||||
jobs:
|
||||
test_rust:
|
||||
runs-on: ubuntu-latest
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ./src/rust
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- name: cache
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: |
|
||||
src/rust/.cargo/registry
|
||||
src/rust/.cargo/git
|
||||
src/rust/target
|
||||
src/rust/lib_ccxr/target
|
||||
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
|
||||
restore-keys: ${{ runner.os }}-cargo-
|
||||
- uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
override: true
|
||||
- name: Test main module
|
||||
run: cargo test
|
||||
working-directory: ./src/rust
|
||||
- name: Test lib_ccxr module
|
||||
run: cargo test
|
||||
working-directory: ./src/rust/lib_ccxr
|
||||
29
.gitignore
vendored
29
.gitignore
vendored
@@ -17,8 +17,10 @@ CVS
|
||||
mac/ccextractor
|
||||
linux/ccextractor
|
||||
linux/depend
|
||||
windows/x86_64-pc-windows-msvc/**
|
||||
windows/Debug/**
|
||||
windows/Debug-OCR/**
|
||||
windows/release-with-debug/**
|
||||
windows/Release/**
|
||||
windows/Release-Full/**
|
||||
windows/Release-OCR/**
|
||||
@@ -84,6 +86,7 @@ linux/aclocal.m4
|
||||
linux/*.in
|
||||
linux/configure
|
||||
linux/build-conf/
|
||||
mac/rust/
|
||||
mac/config.h
|
||||
mac/config.log
|
||||
mac/config.status
|
||||
@@ -97,16 +100,12 @@ package_creators/*tar.gz
|
||||
package_creators/build/*.deb
|
||||
src/.deps/
|
||||
src/.dirstamp
|
||||
src/gpacmp4/.deps/
|
||||
src/gpacmp4/.dirstamp
|
||||
src/lib_ccx/.deps/
|
||||
src/lib_ccx/.dirstamp
|
||||
src/lib_hash/.deps/
|
||||
src/lib_hash/.dirstamp
|
||||
src/libpng/.deps/
|
||||
src/libpng/.dirstamp
|
||||
src/protobuf-c/.deps/
|
||||
src/protobuf-c/.dirstamp
|
||||
src/utf8proc/.deps/
|
||||
src/utf8proc/.dirstamp
|
||||
src/zlib/.deps/
|
||||
@@ -140,3 +139,25 @@ mac/CMakeCache.txt
|
||||
|
||||
# Bazel
|
||||
bazel*
|
||||
|
||||
#Intellij IDEs
|
||||
.idea/
|
||||
|
||||
# Rust build and MakeFiles (and CMake files)
|
||||
src/rust/CMakeFiles/
|
||||
src/rust/CMakeCache.txt
|
||||
src/rust/Makefile
|
||||
src/rust/cmake_install.cmake
|
||||
src/rust/target/
|
||||
src/rust/lib_ccxr/target/
|
||||
windows/ccx_rust.lib
|
||||
windows/*/debug/*
|
||||
windows/*/CACHEDIR.TAG
|
||||
windows/.rustc_info.json
|
||||
linux/configure~
|
||||
|
||||
# Plans and temporary files
|
||||
plans/
|
||||
tess.log
|
||||
**/tess.log
|
||||
ut=srt*
|
||||
|
||||
@@ -4,7 +4,7 @@ MAINTAINER = Marc Espie <espie@openbsd.org>
|
||||
CATEGORIES = multimedia
|
||||
COMMENT = closed caption subtitles extractor
|
||||
HOMEPAGE = https://ccextractor.org
|
||||
V = 0.92
|
||||
V = 0.96
|
||||
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.
|
||||
|
||||
|
||||
239
docker/Dockerfile
Normal file
239
docker/Dockerfile
Normal file
@@ -0,0 +1,239 @@
|
||||
# CCExtractor Docker Build
|
||||
#
|
||||
# Build variants via BUILD_TYPE argument:
|
||||
# - minimal: Basic CCExtractor without OCR
|
||||
# - ocr: CCExtractor with OCR support (default)
|
||||
# - hardsubx: CCExtractor with burned-in subtitle extraction (requires FFmpeg)
|
||||
#
|
||||
# Source options via USE_LOCAL_SOURCE argument:
|
||||
# - 0 (default): Clone from GitHub (standalone Dockerfile usage)
|
||||
# - 1: Use local source (when building from cloned repo)
|
||||
#
|
||||
# Build examples:
|
||||
#
|
||||
# # Standalone (just the Dockerfile, clones from GitHub):
|
||||
# docker build -t ccextractor docker/
|
||||
# docker build --build-arg BUILD_TYPE=hardsubx -t ccextractor docker/
|
||||
#
|
||||
# # From cloned repository (faster, uses local source):
|
||||
# docker build --build-arg USE_LOCAL_SOURCE=1 -f docker/Dockerfile -t ccextractor .
|
||||
# docker build --build-arg USE_LOCAL_SOURCE=1 --build-arg BUILD_TYPE=minimal -f docker/Dockerfile -t ccextractor .
|
||||
|
||||
ARG DEBIAN_VERSION=bookworm-slim
|
||||
|
||||
FROM debian:${DEBIAN_VERSION} AS base
|
||||
|
||||
FROM base AS builder
|
||||
|
||||
# Build arguments
|
||||
ARG BUILD_TYPE=ocr
|
||||
ARG USE_LOCAL_SOURCE=0
|
||||
# BUILD_TYPE: minimal, ocr, hardsubx
|
||||
# USE_LOCAL_SOURCE: 0 = git clone, 1 = copy local source
|
||||
|
||||
# Avoid interactive prompts during package installation
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
# Install base build dependencies
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
git \
|
||||
curl \
|
||||
ca-certificates \
|
||||
gcc \
|
||||
g++ \
|
||||
cmake \
|
||||
make \
|
||||
pkg-config \
|
||||
bash \
|
||||
zlib1g-dev \
|
||||
libpng-dev \
|
||||
libjpeg-dev \
|
||||
libssl-dev \
|
||||
libfreetype-dev \
|
||||
libxml2-dev \
|
||||
libcurl4-gnutls-dev \
|
||||
clang \
|
||||
libclang-dev \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install Rust toolchain
|
||||
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable
|
||||
ENV PATH="/root/.cargo/bin:${PATH}"
|
||||
|
||||
# Install OCR dependencies (for ocr and hardsubx builds)
|
||||
RUN if [ "$BUILD_TYPE" = "ocr" ] || [ "$BUILD_TYPE" = "hardsubx" ]; then \
|
||||
apt-get update && apt-get install -y --no-install-recommends \
|
||||
tesseract-ocr \
|
||||
libtesseract-dev \
|
||||
libleptonica-dev \
|
||||
&& rm -rf /var/lib/apt/lists/*; \
|
||||
fi
|
||||
|
||||
# Install FFmpeg dependencies (for hardsubx build)
|
||||
RUN if [ "$BUILD_TYPE" = "hardsubx" ]; then \
|
||||
apt-get update && apt-get install -y --no-install-recommends \
|
||||
libavcodec-dev \
|
||||
libavformat-dev \
|
||||
libavutil-dev \
|
||||
libswscale-dev \
|
||||
libswresample-dev \
|
||||
libavfilter-dev \
|
||||
libavdevice-dev \
|
||||
&& rm -rf /var/lib/apt/lists/*; \
|
||||
fi
|
||||
|
||||
# Build and install GPAC library
|
||||
WORKDIR /root
|
||||
RUN git clone -b v2.4.0 --depth 1 https://github.com/gpac/gpac
|
||||
WORKDIR /root/gpac
|
||||
RUN ./configure && make -j$(nproc) lib && make install-lib && ldconfig
|
||||
WORKDIR /root
|
||||
RUN rm -rf /root/gpac
|
||||
|
||||
# Get CCExtractor source (either clone or copy based on USE_LOCAL_SOURCE)
|
||||
WORKDIR /root
|
||||
# First, copy local source if provided (will be empty dir if building standalone)
|
||||
COPY . /root/ccextractor-local/
|
||||
|
||||
# Then get source: use local copy if USE_LOCAL_SOURCE=1 and source exists,
|
||||
# otherwise clone from GitHub
|
||||
RUN if [ "$USE_LOCAL_SOURCE" = "1" ] && [ -f /root/ccextractor-local/src/ccextractor.c ]; then \
|
||||
echo "Using local source"; \
|
||||
mv /root/ccextractor-local /root/ccextractor; \
|
||||
else \
|
||||
echo "Cloning from GitHub"; \
|
||||
rm -rf /root/ccextractor-local; \
|
||||
git clone --depth 1 https://github.com/CCExtractor/ccextractor.git /root/ccextractor; \
|
||||
fi
|
||||
|
||||
WORKDIR /root/ccextractor/linux
|
||||
|
||||
# Generate build info
|
||||
RUN ./pre-build.sh
|
||||
|
||||
# Build Rust library with appropriate features
|
||||
RUN if [ "$BUILD_TYPE" = "hardsubx" ]; then \
|
||||
cd ../src/rust && \
|
||||
CARGO_TARGET_DIR=../../linux/rust cargo build --release --features hardsubx_ocr; \
|
||||
else \
|
||||
cd ../src/rust && \
|
||||
CARGO_TARGET_DIR=../../linux/rust cargo build --release; \
|
||||
fi
|
||||
|
||||
RUN cp rust/release/libccx_rust.a ./libccx_rust.a
|
||||
|
||||
# Compile CCExtractor
|
||||
RUN if [ "$BUILD_TYPE" = "minimal" ]; then \
|
||||
BLD_FLAGS="-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_64_BITS"; \
|
||||
BLD_INCLUDE="-I../src -I../src/lib_ccx/ -I /usr/include/gpac/ -I../src/thirdparty/libpng -I../src/thirdparty/zlib -I../src/lib_ccx/zvbi -I../src/thirdparty/lib_hash -I../src/thirdparty -I../src/thirdparty/freetype/include"; \
|
||||
BLD_LINKER="-lm -Wl,--allow-multiple-definition -lpthread -ldl -lgpac ./libccx_rust.a"; \
|
||||
elif [ "$BUILD_TYPE" = "hardsubx" ]; then \
|
||||
BLD_FLAGS="-std=gnu99 -Wno-write-strings -Wno-pointer-sign -D_FILE_OFFSET_BITS=64 -DVERSION_FILE_PRESENT -DENABLE_OCR -DENABLE_HARDSUBX -DFT2_BUILD_LIBRARY -DGPAC_DISABLE_VTT -DGPAC_DISABLE_OD_DUMP -DGPAC_DISABLE_REMOTERY -DNO_GZIP -DGPAC_64_BITS"; \
|
||||
BLD_INCLUDE="-I../src -I /usr/include/leptonica/ -I /usr/include/tesseract/ -I../src/lib_ccx/ -I /usr/include/gpac/ -I../src/thirdparty/libpng -I../src/thirdparty/zlib -I../src/lib_ccx/zvbi -I../src/thirdparty/lib_hash -I../src/thirdparty -I../src/thirdparty/freetype/include"; \
|
||||
BLD_LINKER="-lm -Wl,--allow-multiple-definition -ltesseract -lleptonica -lpthread -ldl -lgpac -lswscale -lavutil -lavformat -lavcodec -lavfilter -lswresample ./libccx_rust.a"; \
|
||||
else \
|
||||
BLD_FLAGS="-std=gnu99 -Wno-write-strings -Wno-pointer-sign -D_FILE_OFFSET_BITS=64 -DVERSION_FILE_PRESENT -DENABLE_OCR -DFT2_BUILD_LIBRARY -DGPAC_DISABLE_VTT -DGPAC_DISABLE_OD_DUMP -DGPAC_DISABLE_REMOTERY -DNO_GZIP -DGPAC_64_BITS"; \
|
||||
BLD_INCLUDE="-I../src -I /usr/include/leptonica/ -I /usr/include/tesseract/ -I../src/lib_ccx/ -I /usr/include/gpac/ -I../src/thirdparty/libpng -I../src/thirdparty/zlib -I../src/lib_ccx/zvbi -I../src/thirdparty/lib_hash -I../src/thirdparty -I../src/thirdparty/freetype/include"; \
|
||||
BLD_LINKER="-lm -Wl,--allow-multiple-definition -ltesseract -lleptonica -lpthread -ldl -lgpac ./libccx_rust.a"; \
|
||||
fi && \
|
||||
SRC_LIBPNG="$(find ../src/thirdparty/libpng/ -name '*.c')" && \
|
||||
SRC_ZLIB="$(find ../src/thirdparty/zlib/ -name '*.c')" && \
|
||||
SRC_CCX="$(find ../src/lib_ccx/ -name '*.c')" && \
|
||||
SRC_GPAC="$(find /usr/include/gpac/ -name '*.c' 2>/dev/null || true)" && \
|
||||
SRC_HASH="$(find ../src/thirdparty/lib_hash/ -name '*.c')" && \
|
||||
SRC_UTF8PROC="../src/thirdparty/utf8proc/utf8proc.c" && \
|
||||
SRC_FREETYPE="../src/thirdparty/freetype/autofit/autofit.c \
|
||||
../src/thirdparty/freetype/base/ftbase.c \
|
||||
../src/thirdparty/freetype/base/ftbbox.c \
|
||||
../src/thirdparty/freetype/base/ftbdf.c \
|
||||
../src/thirdparty/freetype/base/ftbitmap.c \
|
||||
../src/thirdparty/freetype/base/ftcid.c \
|
||||
../src/thirdparty/freetype/base/ftfntfmt.c \
|
||||
../src/thirdparty/freetype/base/ftfstype.c \
|
||||
../src/thirdparty/freetype/base/ftgasp.c \
|
||||
../src/thirdparty/freetype/base/ftglyph.c \
|
||||
../src/thirdparty/freetype/base/ftgxval.c \
|
||||
../src/thirdparty/freetype/base/ftinit.c \
|
||||
../src/thirdparty/freetype/base/ftlcdfil.c \
|
||||
../src/thirdparty/freetype/base/ftmm.c \
|
||||
../src/thirdparty/freetype/base/ftotval.c \
|
||||
../src/thirdparty/freetype/base/ftpatent.c \
|
||||
../src/thirdparty/freetype/base/ftpfr.c \
|
||||
../src/thirdparty/freetype/base/ftstroke.c \
|
||||
../src/thirdparty/freetype/base/ftsynth.c \
|
||||
../src/thirdparty/freetype/base/ftsystem.c \
|
||||
../src/thirdparty/freetype/base/fttype1.c \
|
||||
../src/thirdparty/freetype/base/ftwinfnt.c \
|
||||
../src/thirdparty/freetype/bdf/bdf.c \
|
||||
../src/thirdparty/freetype/bzip2/ftbzip2.c \
|
||||
../src/thirdparty/freetype/cache/ftcache.c \
|
||||
../src/thirdparty/freetype/cff/cff.c \
|
||||
../src/thirdparty/freetype/cid/type1cid.c \
|
||||
../src/thirdparty/freetype/gzip/ftgzip.c \
|
||||
../src/thirdparty/freetype/lzw/ftlzw.c \
|
||||
../src/thirdparty/freetype/pcf/pcf.c \
|
||||
../src/thirdparty/freetype/pfr/pfr.c \
|
||||
../src/thirdparty/freetype/psaux/psaux.c \
|
||||
../src/thirdparty/freetype/pshinter/pshinter.c \
|
||||
../src/thirdparty/freetype/psnames/psnames.c \
|
||||
../src/thirdparty/freetype/raster/raster.c \
|
||||
../src/thirdparty/freetype/sfnt/sfnt.c \
|
||||
../src/thirdparty/freetype/smooth/smooth.c \
|
||||
../src/thirdparty/freetype/truetype/truetype.c \
|
||||
../src/thirdparty/freetype/type1/type1.c \
|
||||
../src/thirdparty/freetype/type42/type42.c \
|
||||
../src/thirdparty/freetype/winfonts/winfnt.c" && \
|
||||
BLD_SOURCES="../src/ccextractor.c $SRC_CCX $SRC_GPAC $SRC_ZLIB $SRC_LIBPNG $SRC_HASH $SRC_UTF8PROC $SRC_FREETYPE" && \
|
||||
gcc $BLD_FLAGS $BLD_INCLUDE -o ccextractor $BLD_SOURCES $BLD_LINKER
|
||||
|
||||
# Copy binary to known location
|
||||
RUN cp /root/ccextractor/linux/ccextractor /ccextractor
|
||||
|
||||
# Final minimal image
|
||||
FROM base AS final
|
||||
|
||||
ARG BUILD_TYPE=ocr
|
||||
|
||||
# Avoid interactive prompts
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
|
||||
# Install runtime dependencies based on build type
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
libpng16-16 \
|
||||
libjpeg62-turbo \
|
||||
zlib1g \
|
||||
libssl3 \
|
||||
libcurl4 \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# OCR runtime dependencies
|
||||
RUN if [ "$BUILD_TYPE" = "ocr" ] || [ "$BUILD_TYPE" = "hardsubx" ]; then \
|
||||
apt-get update && apt-get install -y --no-install-recommends \
|
||||
tesseract-ocr \
|
||||
liblept5 \
|
||||
&& rm -rf /var/lib/apt/lists/*; \
|
||||
fi
|
||||
|
||||
# HardSubX runtime dependencies
|
||||
RUN if [ "$BUILD_TYPE" = "hardsubx" ]; then \
|
||||
apt-get update && apt-get install -y --no-install-recommends \
|
||||
libavcodec59 \
|
||||
libavformat59 \
|
||||
libavutil57 \
|
||||
libswscale6 \
|
||||
libswresample4 \
|
||||
libavfilter8 \
|
||||
libavdevice59 \
|
||||
&& rm -rf /var/lib/apt/lists/*; \
|
||||
fi
|
||||
|
||||
# Copy GPAC library from builder
|
||||
COPY --from=builder /usr/local/lib/libgpac.so* /usr/local/lib/
|
||||
|
||||
# Update library cache
|
||||
RUN ldconfig
|
||||
|
||||
# Copy CCExtractor binary
|
||||
COPY --from=builder /ccextractor /ccextractor
|
||||
|
||||
ENTRYPOINT ["/ccextractor"]
|
||||
91
docker/README.md
Normal file
91
docker/README.md
Normal file
@@ -0,0 +1,91 @@
|
||||
# CCExtractor Docker Image
|
||||
|
||||
This Dockerfile builds CCExtractor with support for multiple build variants.
|
||||
|
||||
## Build Variants
|
||||
|
||||
| Variant | Description | Features |
|
||||
|---------|-------------|----------|
|
||||
| `minimal` | Basic CCExtractor | No OCR support |
|
||||
| `ocr` | With OCR support (default) | Tesseract OCR for bitmap subtitles |
|
||||
| `hardsubx` | With burned-in subtitle extraction | OCR + FFmpeg for hardcoded subtitles |
|
||||
|
||||
## Building
|
||||
|
||||
### Standalone Build (from Dockerfile only)
|
||||
|
||||
You can build CCExtractor using just the Dockerfile - it will clone the source from GitHub:
|
||||
|
||||
```bash
|
||||
# Default build (OCR enabled)
|
||||
docker build -t ccextractor docker/
|
||||
|
||||
# Minimal build (no OCR)
|
||||
docker build --build-arg BUILD_TYPE=minimal -t ccextractor docker/
|
||||
|
||||
# HardSubX build (OCR + FFmpeg for burned-in subtitles)
|
||||
docker build --build-arg BUILD_TYPE=hardsubx -t ccextractor docker/
|
||||
```
|
||||
|
||||
### Build from Cloned Repository (faster)
|
||||
|
||||
If you have already cloned the repository, you can use local source for faster builds:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/CCExtractor/ccextractor.git
|
||||
cd ccextractor
|
||||
|
||||
# Default build (OCR enabled)
|
||||
docker build --build-arg USE_LOCAL_SOURCE=1 -f docker/Dockerfile -t ccextractor .
|
||||
|
||||
# Minimal build
|
||||
docker build --build-arg USE_LOCAL_SOURCE=1 --build-arg BUILD_TYPE=minimal -f docker/Dockerfile -t ccextractor .
|
||||
|
||||
# HardSubX build
|
||||
docker build --build-arg USE_LOCAL_SOURCE=1 --build-arg BUILD_TYPE=hardsubx -f docker/Dockerfile -t ccextractor .
|
||||
```
|
||||
|
||||
## Build Arguments
|
||||
|
||||
| Argument | Default | Description |
|
||||
|----------|---------|-------------|
|
||||
| `BUILD_TYPE` | `ocr` | Build variant: `minimal`, `ocr`, or `hardsubx` |
|
||||
| `USE_LOCAL_SOURCE` | `0` | Set to `1` to use local source instead of cloning |
|
||||
| `DEBIAN_VERSION` | `bookworm-slim` | Debian version to use as base |
|
||||
|
||||
## Usage
|
||||
|
||||
### Basic Usage
|
||||
|
||||
```bash
|
||||
# Show version
|
||||
docker run --rm ccextractor --version
|
||||
|
||||
# Show help
|
||||
docker run --rm ccextractor --help
|
||||
```
|
||||
|
||||
### Processing Local Files
|
||||
|
||||
Mount your local directory to process files:
|
||||
|
||||
```bash
|
||||
# Process a video file with output file
|
||||
docker run --rm -v $(pwd):$(pwd) -w $(pwd) ccextractor input.mp4 -o output.srt
|
||||
|
||||
# Process using stdout
|
||||
docker run --rm -v $(pwd):$(pwd) -w $(pwd) ccextractor input.mp4 --stdout > output.srt
|
||||
```
|
||||
|
||||
### Interactive Mode
|
||||
|
||||
```bash
|
||||
docker run --rm -it --entrypoint=/bin/bash ccextractor
|
||||
```
|
||||
|
||||
## Image Size
|
||||
|
||||
The multi-stage build produces runtime images:
|
||||
- `minimal`: ~130MB
|
||||
- `ocr`: ~215MB (includes Tesseract)
|
||||
- `hardsubx`: ~610MB (includes Tesseract + FFmpeg)
|
||||
@@ -29,7 +29,7 @@ To do:
|
||||
though. No samples, no support.
|
||||
- A few commands are not yet supported, specifically those related
|
||||
to delay.
|
||||
- Detect and extract captions from MP4 (MOV) files, handled by gpacmp4
|
||||
- Detect and extract captions from MP4 (MOV) files, handled by gpac
|
||||
|
||||
Done (18.08.2015):
|
||||
|
||||
|
||||
157
docs/Building_macos_system_libs.md
Normal file
157
docs/Building_macos_system_libs.md
Normal file
@@ -0,0 +1,157 @@
|
||||
# Building CCExtractor on macOS using System Libraries (-system-libs)
|
||||
|
||||
## Overview
|
||||
|
||||
This document explains how to build CCExtractor on macOS using system-installed libraries instead of bundled third-party libraries.
|
||||
|
||||
This build mode is required for Homebrew compatibility and is enabled via the `-system-libs` flag introduced in PR #1862.
|
||||
|
||||
## Why is -system-libs needed?
|
||||
|
||||
### Background
|
||||
|
||||
CCExtractor was removed from Homebrew (homebrew-core) because:
|
||||
|
||||
- Homebrew does not allow bundling third-party libraries
|
||||
- The default CCExtractor build compiles libraries from `src/thirdparty/`
|
||||
- This violates Homebrew packaging policies
|
||||
|
||||
### What -system-libs fixes
|
||||
|
||||
The `-system-libs` flag allows CCExtractor to:
|
||||
|
||||
- Use system-installed libraries via Homebrew
|
||||
- Resolve headers and linker flags using `pkg-config`
|
||||
- Skip compiling bundled copies of common libraries
|
||||
|
||||
This makes CCExtractor acceptable for Homebrew packaging.
|
||||
|
||||
## Build Modes Explained
|
||||
|
||||
### 1️⃣ Default Build (Bundled Libraries)
|
||||
|
||||
**Command:**
|
||||
|
||||
```bash
|
||||
./mac/build.command
|
||||
```
|
||||
|
||||
**Behavior:**
|
||||
|
||||
- Compiles bundled libraries:
|
||||
- `freetype`
|
||||
- `libpng`
|
||||
- `zlib`
|
||||
- `utf8proc`
|
||||
- Self-contained binary
|
||||
- Larger size
|
||||
- Suitable for standalone builds
|
||||
|
||||
### 2️⃣ System Libraries Build (Homebrew-compatible)
|
||||
|
||||
**Command:**
|
||||
|
||||
```bash
|
||||
./mac/build.command -system-libs
|
||||
```
|
||||
|
||||
**Behavior:**
|
||||
|
||||
- Uses system libraries via `pkg-config`
|
||||
- Does not compile bundled libraries
|
||||
- Smaller binary
|
||||
- Faster build
|
||||
- Required for Homebrew
|
||||
|
||||
## Required Homebrew Dependencies
|
||||
|
||||
Install required dependencies:
|
||||
|
||||
```bash
|
||||
brew install pkg-config autoconf automake libtool \
|
||||
gpac freetype libpng protobuf-c utf8proc zlib
|
||||
```
|
||||
|
||||
**Optional** (OCR / HARDSUBX support):
|
||||
|
||||
```bash
|
||||
brew install tesseract leptonica ffmpeg
|
||||
```
|
||||
|
||||
## How to Build
|
||||
|
||||
```bash
|
||||
cd mac
|
||||
./build.command -system-libs
|
||||
```
|
||||
|
||||
**Verify:**
|
||||
|
||||
```bash
|
||||
./ccextractor --version
|
||||
```
|
||||
|
||||
## What Changes Internally with -system-libs
|
||||
|
||||
### Libraries NOT compiled (system-provided)
|
||||
|
||||
- **FreeType**
|
||||
- **libpng**
|
||||
- **zlib**
|
||||
- **utf8proc**
|
||||
|
||||
### Libraries STILL bundled
|
||||
|
||||
- **lib_hash** (Custom SHA-256 implementation, no system equivalent)
|
||||
|
||||
## CI Coverage
|
||||
|
||||
A new CI job was added:
|
||||
|
||||
- `build_shell_system_libs`
|
||||
|
||||
**What it does:**
|
||||
|
||||
- Installs Homebrew dependencies
|
||||
- Runs `./build.command -system-libs`
|
||||
- Verifies the binary runs correctly
|
||||
|
||||
This ensures Homebrew-compatible builds stay working.
|
||||
|
||||
## Verification (Local)
|
||||
|
||||
You can confirm system libraries are used:
|
||||
|
||||
```bash
|
||||
otool -L mac/ccextractor
|
||||
```
|
||||
|
||||
**Expected output includes paths like:**
|
||||
|
||||
```
|
||||
/opt/homebrew/opt/gpac/lib/libgpac.dylib
|
||||
```
|
||||
|
||||
## Homebrew Formula Usage (Future)
|
||||
|
||||
Example formula snippet:
|
||||
|
||||
```ruby
|
||||
def install
|
||||
system "./mac/build.command", "-system-libs"
|
||||
bin.install "mac/ccextractor"
|
||||
end
|
||||
```
|
||||
|
||||
## Summary
|
||||
|
||||
- `-system-libs` is opt-in
|
||||
- Default build remains unchanged
|
||||
- Enables CCExtractor to return to Homebrew
|
||||
- Fully tested in CI and locally
|
||||
|
||||
## Related
|
||||
|
||||
- **PR #1862** — Add `-system-libs` flag
|
||||
- **Issue #1580** — Homebrew compatibility
|
||||
- **Issue #1534** — System library support
|
||||
301
docs/CHANGES.TXT
301
docs/CHANGES.TXT
@@ -1,3 +1,54 @@
|
||||
0.96 (2025-12-23)
|
||||
-----------------
|
||||
- New: Multi-page teletext extraction support (#665)
|
||||
- Extract multiple teletext pages simultaneously with separate output files
|
||||
- Use --tpage multiple times (e.g., --tpage 100 --tpage 200)
|
||||
- Output files are named with page suffix (e.g., output_p100.srt, output_p200.srt)
|
||||
|
||||
- New: Added --list-tracks (-L) option to list all tracks in media files without processing
|
||||
New: Chinese, Korean, Japanese support - proper encoding and OCR.
|
||||
New: Correct McPoodle DVD raw format support
|
||||
Fix: Timing is now frame perfect (using FFMpeg timing dump as reference) in all formats.
|
||||
Fix: Solved garbling in all the pending issues we had on GitHub.
|
||||
Fix: All causes of "premature end of file" messages due to bugs and not actual file cuts.
|
||||
Fix: All memory leaks, double frees and usual C nastyness that valgrind could find.
|
||||
- Fix Include ATSC VCT virtual channel numbers and call signs in XMLTV output
|
||||
- Fix: Restore ATSC XMLTV generation with ETT parsing for extended descriptions, multi-segment handling, extended table ID's (EIT/VCT), corrected <programme> XMLTV formatting, buffer bounds fixes
|
||||
- Fix: Add HEVC/H.265 stream type recognition to prevent crashes on ATSC 3.0 streams.
|
||||
Fix: Tolerance to damaged streams - recover where possible instead of terminating.
|
||||
Issues closed: Over 40! Too many to list here, but each of them was either a bug squashed or a feature implemented.
|
||||
|
||||
0.95 (2025-09-15 - never formally packaged)
|
||||
-----------------
|
||||
- New: Create a Docker image to simplify the CCExtractor usage without any environmental hustle (#1611)
|
||||
- New: Add SCC support for CEA-708 decoder (#1595)
|
||||
Refactor: Lots of code ported to Rust.
|
||||
- Fix: Improved handling of IETF language tags in Matroska files (#1665)
|
||||
- Breaking: Major argument flags revamp for CCExtractor (#1564 & #1619)
|
||||
- Fix: segmentation fault in using hardsubx
|
||||
- Fix: WebVTT X-TIMESTAMP-MAP placement (#1463)
|
||||
- Fix: ffmpeg 5.0, tesseract 5.0 compatibility and remove deprecated methods
|
||||
- Fix: tesseract 5.x traineddata location in ocr
|
||||
- Improvement: Ignore MXF Caption Essence Container version byte to enhance SRT subtitle extraction compatibility
|
||||
- New: Add tesseract page segmentation modes control with `--psm` flag
|
||||
- Fix: Support for MINGW-w64 cross compiling
|
||||
|
||||
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
|
||||
@@ -74,7 +125,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)
|
||||
-----------------
|
||||
@@ -154,10 +205,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.
|
||||
@@ -168,29 +219,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
|
||||
@@ -237,7 +288,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).
|
||||
@@ -260,7 +311,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.
|
||||
@@ -307,7 +358,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)
|
||||
@@ -365,7 +416,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)
|
||||
@@ -404,7 +455,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.
|
||||
@@ -437,7 +488,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
|
||||
|
||||
@@ -455,7 +506,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
|
||||
@@ -472,7 +523,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).
|
||||
|
||||
@@ -494,12 +545,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
|
||||
@@ -508,39 +559,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
|
||||
@@ -558,21 +609,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.
|
||||
|
||||
@@ -582,7 +633,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
|
||||
@@ -608,7 +659,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
|
||||
@@ -619,9 +670,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.
|
||||
|
||||
@@ -631,14 +682,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
|
||||
@@ -653,9 +704,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.
|
||||
|
||||
@@ -666,13 +717,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
|
||||
@@ -695,7 +746,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).
|
||||
|
||||
@@ -704,20 +755,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
|
||||
@@ -727,7 +778,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)
|
||||
-----------------
|
||||
@@ -744,10 +795,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)
|
||||
@@ -757,9 +808,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.
|
||||
@@ -780,13 +831,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.
|
||||
@@ -794,17 +845,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
|
||||
@@ -813,7 +864,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
|
||||
|
||||
@@ -826,12 +877,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
|
||||
@@ -847,9 +898,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
|
||||
@@ -868,11 +919,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.
|
||||
|
||||
@@ -891,8 +942,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.
|
||||
@@ -909,8 +960,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
|
||||
@@ -920,8 +971,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.
|
||||
|
||||
@@ -931,30 +982,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.
|
||||
|
||||
@@ -972,7 +1023,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
|
||||
@@ -1033,7 +1084,7 @@ version of CCExtractor.
|
||||
Alan
|
||||
Tony
|
||||
|
||||
So you get
|
||||
So you get
|
||||
|
||||
You better respect
|
||||
this robe, Alan.
|
||||
@@ -1042,7 +1093,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
|
||||
@@ -1056,17 +1107,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
|
||||
@@ -1075,7 +1126,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
|
||||
@@ -1106,8 +1157,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)
|
||||
-----------------
|
||||
@@ -1132,7 +1183,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)
|
||||
@@ -1141,7 +1192,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.
|
||||
|
||||
@@ -1154,7 +1205,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
|
||||
@@ -1163,10 +1214,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.
|
||||
@@ -1177,13 +1228,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.
|
||||
@@ -1193,10 +1244,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).
|
||||
|
||||
@@ -6,10 +6,23 @@ Downloads for precompiled binaries and source code can be found [on our website]
|
||||
|
||||
Clone the latest repository from Github
|
||||
|
||||
```
|
||||
```bash
|
||||
git clone https://github.com/CCExtractor/ccextractor.git
|
||||
```
|
||||
|
||||
### Hardsubx (Burned-in Subtitles) and FFmpeg Versions
|
||||
|
||||
CCExtractor's hardsubx feature extracts burned-in subtitles from videos using OCR. It requires FFmpeg libraries. The build system automatically selects appropriate FFmpeg versions for each platform:
|
||||
|
||||
- **Linux**: FFmpeg 6.x (default)
|
||||
- **Windows**: FFmpeg 6.x (default)
|
||||
- **macOS**: FFmpeg 8.x (default)
|
||||
|
||||
You can override the default by setting the `FFMPEG_VERSION` environment variable to `ffmpeg6`, `ffmpeg7`, or `ffmpeg8` before building. This flexibility ensures compatibility with different FFmpeg installations across platforms.
|
||||
|
||||
## Docker
|
||||
You can now use docker image to build latest source of CCExtractor without any environmental hustle. Follow these [instructions](https://github.com/CCExtractor/ccextractor/tree/master/docker/README.md) for building docker image & usage of it.
|
||||
|
||||
## Linux
|
||||
|
||||
1. Make sure all the dependencies are met.
|
||||
@@ -17,26 +30,40 @@ 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 libgpac-dev libglew-dev libglfw3-dev cmake gcc libcurl4-gnutls-dev tesseract-ocr libtesseract-dev libleptonica-dev clang libclang-dev
|
||||
```
|
||||
|
||||
RHEL:
|
||||
RHEL/Fedora:
|
||||
|
||||
```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 gpac-devel
|
||||
```
|
||||
|
||||
**Note:** On Ubuntu Version 18.04 (Bionic) and (probably) later, install `libtesseract-dev` rather than `tesseract-ocr-dev`, which does not exist anymore.
|
||||
Arch:
|
||||
```bash
|
||||
sudo paru -S glew glfw curl tesseract leptonica cmake gcc clang gpac
|
||||
```
|
||||
or
|
||||
```bash
|
||||
sudo pacman -S glew glfw curl tesseract leptonica cmake gcc clang gpac
|
||||
```
|
||||
|
||||
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 23.10 (Mantic) and later, `libgpac-dev` isn't available, you should build gpac from source by following the easy build instructions [here](https://github.com/gpac/gpac/wiki/GPAC-Build-Guide-for-Linux)
|
||||
|
||||
**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
|
||||
|
||||
2. Compiling
|
||||
|
||||
### Using the build script
|
||||
|
||||
By default build script does not include debugging information hence, you cannot debug the executable produced (i.e. `./ccextractor`) on a debugger. To include debugging information, use the `builddebug` script.
|
||||
|
||||
```bash
|
||||
#Navigate to linux directory and call the build script
|
||||
# navigate to linux directory and call the build script
|
||||
|
||||
cd ccextractor/linux
|
||||
|
||||
@@ -44,7 +71,25 @@ cd ccextractor/linux
|
||||
./build
|
||||
|
||||
# compile with debug info
|
||||
./builddebug
|
||||
./build -debug # same as ./builddebug
|
||||
|
||||
# compile with hardsubx (burned-in subtitle extraction)
|
||||
# Hardsubx requires FFmpeg libraries. Different FFmpeg versions are used by default:
|
||||
# - Linux: FFmpeg 6.x (automatic)
|
||||
# - Windows: FFmpeg 6.x (automatic)
|
||||
# - macOS: FFmpeg 8.x (automatic)
|
||||
|
||||
./build -hardsubx # uses platform-specific FFmpeg version
|
||||
|
||||
# To override the default FFmpeg version, set FFMPEG_VERSION:
|
||||
FFMPEG_VERSION=ffmpeg8 ./build -hardsubx # force FFmpeg 8 on any platform
|
||||
FFMPEG_VERSION=ffmpeg6 ./build -hardsubx # force FFmpeg 6 on any platform
|
||||
FFMPEG_VERSION=ffmpeg7 ./build -hardsubx # force FFmpeg 7 on any platform
|
||||
|
||||
# [Optional] For custom FFmpeg installations, set these environment variables:
|
||||
FFMPEG_INCLUDE_DIR=/usr/include
|
||||
FFMPEG_PKG_CONFIG_PATH=/usr/lib/pkgconfig
|
||||
|
||||
|
||||
# test your build
|
||||
./ccextractor
|
||||
@@ -53,7 +98,7 @@ cd ccextractor/linux
|
||||
### Standard linux compilation through Autoconf scripts
|
||||
|
||||
```bash
|
||||
sudo apt-get install autoconf #Dependency to generate configuration script
|
||||
sudo apt-get install autoconf # dependency to generate configuration script
|
||||
cd ccextractor/linux
|
||||
./autogen.sh
|
||||
./configure
|
||||
@@ -69,15 +114,13 @@ sudo make install
|
||||
### Using CMake
|
||||
|
||||
```bash
|
||||
#Create and navigate to directory where you want to store built files
|
||||
|
||||
# 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/
|
||||
# generate makefile using cmake and then compile
|
||||
cmake ../src/ # options here
|
||||
make
|
||||
|
||||
# test your build
|
||||
@@ -87,37 +130,42 @@ make
|
||||
sudo make install
|
||||
```
|
||||
|
||||
`cmake` also accepts the argument `-DWITH_OCR=ON` to enable OCR and `-DWITH_RUST=ON` to enable rust.
|
||||
`cmake` also accepts the options:
|
||||
`-DWITH_OCR=ON` to enable OCR
|
||||
`-DWITH_HARDSUBX=ON` to enable burned-in subtitles (requires FFmpeg)
|
||||
|
||||
For hardsubx with specific FFmpeg versions:
|
||||
Set `FFMPEG_VERSION=ffmpeg6` for FFmpeg 6.x (default on Linux and Windows)
|
||||
Set `FFMPEG_VERSION=ffmpeg7` for FFmpeg 7.x
|
||||
Set `FFMPEG_VERSION=ffmpeg8` for FFmpeg 8.x
|
||||
(Defaults: Linux=FFmpeg 6, Windows=FFmpeg 6, macOS=FFmpeg 8)
|
||||
|
||||
### Compiling with GUI:
|
||||
([OPTIONAL] For custom FFmpeg installations, set these environment variables)
|
||||
|
||||
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)
|
||||
FFMPEG_INCLUDE_DIR=/usr/include
|
||||
FFMPEG_PKG_CONFIG_PATH=/usr/lib/pkgconfig
|
||||
|
||||
In order to compile it you'll need to configure it using autoconf by passing the `-with-gui` option.
|
||||
### Compiling with GUI
|
||||
|
||||
```bash
|
||||
./autogen.sh
|
||||
./configure --with-gui
|
||||
make
|
||||
|
||||
# make build systemwide
|
||||
sudo make install
|
||||
```
|
||||
|
||||
Once set up you can run the GUI interface from the terminal `./ccextractorGUI`
|
||||
The GUI for CCExtractor has been moved to a separate repository ([https://github.com/CCExtractor/ccextractorfluttergui](https://github.com/CCExtractor/ccextractorfluttergui)).
|
||||
|
||||
## 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
|
||||
brew install cmake gpac
|
||||
# optional if you want OCR:
|
||||
brew install tesseract
|
||||
brew install leptonica
|
||||
# optional if you want hardsubx (burned-in subtitle extraction):
|
||||
brew install ffmpeg
|
||||
```
|
||||
|
||||
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 +178,12 @@ pkg-config --exists --print-errors lept
|
||||
|
||||
```bash
|
||||
cd ccextractor/mac
|
||||
./build.command OCR
|
||||
./build.command # basic build
|
||||
./build.command -ocr # build with OCR support
|
||||
./build.command -hardsubx # build with hardsubx (uses FFmpeg 8 by default on macOS)
|
||||
|
||||
# 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
|
||||
# Override FFmpeg version if needed:
|
||||
FFMPEG_VERSION=ffmpeg7 ./build.command -hardsubx
|
||||
|
||||
# test your build
|
||||
./ccextractor
|
||||
@@ -149,27 +192,29 @@ cd ccextractor/mac
|
||||
#### Using CMake
|
||||
|
||||
```bash
|
||||
#Create and navigate to directory where you want to store built files
|
||||
|
||||
# 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/
|
||||
# generate makefile using cmake and then compile
|
||||
cmake ../src/ # options here
|
||||
make
|
||||
|
||||
# test your build
|
||||
./ccextractor
|
||||
```
|
||||
|
||||
`cmake` also accepts the options:
|
||||
`-DWITH_OCR=ON` to enable OCR
|
||||
`-DWITH_HARDSUBX=ON` to enable burned-in subtitles
|
||||
|
||||
#### Standard compilation through Autoconf scripts:
|
||||
|
||||
```bash
|
||||
cd ccextractor/mac
|
||||
./autogen.sh
|
||||
./configure
|
||||
./configure
|
||||
make
|
||||
|
||||
# test your build
|
||||
@@ -178,27 +223,49 @@ make
|
||||
|
||||
#### Compiling with GUI:
|
||||
|
||||
To use CCExtractor with a gui you will additionally need to install GLEW and GLFW. You can do that by installing it via homebrew using:
|
||||
|
||||
```bash
|
||||
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.
|
||||
|
||||
```bash
|
||||
./autogen.sh
|
||||
./configure --with-gui
|
||||
make
|
||||
```
|
||||
|
||||
Once set up you can run the GUI interface from the terminal `./ccextractorGUI`
|
||||
The GUI for CCExtractor has been moved to a separate repository ([https://github.com/CCExtractor/ccextractorfluttergui](https://github.com/CCExtractor/ccextractorfluttergui)).
|
||||
|
||||
## Windows
|
||||
Dependencies are clang and rust. To enable OCR, rust x86_64-pc-windows-msvc or i686-pc-windows-msvc target should be installed
|
||||
|
||||
GPAC is also required, you can install it through chocolatey:
|
||||
```
|
||||
choco install gpac
|
||||
```
|
||||
|
||||
Other dependencies are required through vcpkg, so you can follow below steps:
|
||||
1. Download vcpkg (prefer version `2023.02.24` as it is supported)
|
||||
2. Integrate vcpkg into your system, run the below command in the downloaded vcpkg folder:
|
||||
```
|
||||
vcpkg integrate install
|
||||
```
|
||||
3. Set Environment Variable for Vcpkg triplet, you can choose between x86 or x64 based on your system.
|
||||
```
|
||||
setx VCPKG_DEFAULT_TRIPLET "x64-windows-static"
|
||||
setx RUSTFLAGS "-Ctarget-feature=+crt-static"
|
||||
```
|
||||
4. Install dependencies from vcpkg
|
||||
|
||||
In this step we are using `x64-windows-static` triplet, but you will have to use the triplet you set in Step 3
|
||||
|
||||
if building Debug-Full, Release-Full (HardSubx)
|
||||
```
|
||||
vcpkg install ffmpeg leptonica tesseract --triplet x64-windows-static
|
||||
```
|
||||
Note: Windows builds use FFmpeg 6 by default. To override:
|
||||
```
|
||||
set FFMPEG_VERSION=ffmpeg8
|
||||
msbuild ccextractor.sln /p:Configuration=Debug-Full /p:Platform=x64
|
||||
```
|
||||
|
||||
otherwise if you have Debug, Release
|
||||
```
|
||||
vcpkg install libpng --triplet x64-windows-static
|
||||
```
|
||||
|
||||
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).
|
||||
1.Open `windows/` directory to locate `ccextractor.vcxproj` and `ccextractor.sln` (red arrow).
|
||||
|
||||

|
||||
|
||||
@@ -234,6 +301,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
|
||||
|
||||
@@ -16,10 +16,24 @@ Note:If you installed ffmpeg on non-standard location, please change/update your
|
||||
environment variable `$PATH` and `$LD_LIBRARY_PATH`
|
||||
|
||||
### Download and Install FFmpeg on your Windows pc:
|
||||
Download prebuilt library from following link:
|
||||
http://ffmpeg.zeranoe.com/builds/
|
||||
1. Download vcpkg (prefer version `2023.02.24` as it is supported)
|
||||
2. Integrate vcpkg into your system, run the below command in the downloaded vcpkg folder:
|
||||
```
|
||||
vcpkg integrate install
|
||||
```
|
||||
3. Set Environment Variable for Vcpkg triplet, you can choose between x86 or x64 based on your system.
|
||||
```
|
||||
setx VCPKG_DEFAULT_TRIPLET "x64-windows-static"
|
||||
setx RUSTFLAGS "-Ctarget-feature=+crt-static"
|
||||
```
|
||||
4. Install ffmpeg from vcpkg
|
||||
|
||||
You need to download Shared Versions to run the program and Dev Versions to compile.
|
||||
|
||||
In this step we are using `x64-windows-static` triplet, but you will have to use the triplet you set in Step 3
|
||||
|
||||
```
|
||||
vcpkg install ffmpeg --triplet x64-windows-static
|
||||
```
|
||||
|
||||
## How to compile ccextractor
|
||||
|
||||
@@ -27,24 +41,8 @@ You need to download Shared Versions to run the program and Dev Versions to comp
|
||||
`make ENABLE_FFMPEG=yes`
|
||||
|
||||
### On Windows:
|
||||
#### Put the path of libs/include of ffmpeg library in library paths.
|
||||
1. In visual studio 2013 right click <Project> and select property.
|
||||
2. Select Configuration properties in left panel(column) of property.
|
||||
3. Select VC++ Directory.
|
||||
4. In the right pane, in the right-hand column of the VC++ Directory property, open the drop-down menu and choose Edit.
|
||||
5. Add path of Directory where you have kept uncompressed library of FFmpeg.
|
||||
|
||||
|
||||
#### Set preprocessor flag `ENABLE_FFMPEG=1`
|
||||
1. In visual studio 2013 right click <Project> and select property.
|
||||
1. In visual studio 2022 right click <Project> and select property.
|
||||
2. In the left panel, select Configuration Properties, C/C++, Preprocessor.
|
||||
3. In the right panel, in the right-hand column of the Preprocessor Definitions property, open the drop-down menu and choose Edit.
|
||||
4. In the Preprocessor Definitions dialog box, add `ENABLE_FFMPEG=1`. Choose OK to save your changes.
|
||||
|
||||
#### Add library in linker
|
||||
1. Open property of project
|
||||
2. Select Configuration properties
|
||||
3. Select Linker in left panel(column)
|
||||
4. Select Input
|
||||
5. Select Additional dependencies in right panel
|
||||
6. Add all FFmpeg's lib in new line
|
||||
|
||||
@@ -54,6 +54,32 @@ To build the program with hardsubx support,
|
||||
|
||||
NOTE: The build has been tested with FFMpeg version 3.1.0, and Tesseract 3.04.
|
||||
|
||||
macOS
|
||||
-----
|
||||
|
||||
Install the required dependencies using Homebrew:
|
||||
brew install tesseract leptonica ffmpeg
|
||||
|
||||
To build the program with hardsubx support, use one of these methods:
|
||||
|
||||
== Using build.command (Recommended):
|
||||
cd ccextractor/mac
|
||||
./build.command -hardsubx
|
||||
|
||||
== Using autoconf:
|
||||
cd ccextractor/mac
|
||||
./autogen.sh
|
||||
./configure --enable-hardsubx --enable-ocr
|
||||
make
|
||||
|
||||
== Using cmake:
|
||||
cd ccextractor
|
||||
mkdir build && cd build
|
||||
cmake -DWITH_OCR=ON -DWITH_HARDSUBX=ON ../src/
|
||||
make
|
||||
|
||||
NOTE: The -hardsubx parameter uses a single dash (not --hardsubx).
|
||||
|
||||
Windows
|
||||
-------
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ Download prebuild library of leptonica and tesseract from following link
|
||||
https://drive.google.com/file/d/0B2ou7ZfB-2nZOTRtc3hJMHBtUFk/view?usp=sharing
|
||||
|
||||
put the path of libs/include of leptonica and tesseract in library paths.
|
||||
1. In visual studio 2013 right click <Project> and select property.
|
||||
1. In visual studio 2022 right click <Project> and select property.
|
||||
2. Select Configuration properties in left panel(column) of property.
|
||||
3. Select VC++ Directory.
|
||||
4. In the right pane, in the right-hand column of the VC++ Directory property, open the drop-down menu and choose Edit.
|
||||
@@ -101,7 +101,7 @@ put the path of libs/include of leptonica and tesseract in library paths.
|
||||
|
||||
|
||||
Set preprocessor flag ENABLE_OCR=1
|
||||
1. In visual studio 2013 right click <Project> and select property.
|
||||
1. In visual studio 2022 right click <Project> and select property.
|
||||
2. In the left panel, select Configuration Properties, C/C++, Preprocessor.
|
||||
3. In the right panel, in the right-hand column of the Preprocessor Definitions property, open the drop-down menu and choose Edit.
|
||||
4. In the Preprocessor Definitions dialog box, add ENABLE_OCR=1. Choose OK to save your changes.
|
||||
|
||||
71
docs/Rust_migration_guide.md
Normal file
71
docs/Rust_migration_guide.md
Normal file
@@ -0,0 +1,71 @@
|
||||
# C to Rust Migration Guide
|
||||
|
||||
## Porting C Functions to Rust
|
||||
|
||||
This guide outlines the process of migrating C functions to Rust while maintaining compatibility with existing C code.
|
||||
|
||||
### Step 1: Identify the C Function
|
||||
|
||||
First, identify the C function you want to port. For example, let's consider a function named `net_send_cc()` in a file called `networking.c`:
|
||||
|
||||
```c
|
||||
void net_send_cc() {
|
||||
// Some C code
|
||||
}
|
||||
```
|
||||
|
||||
### Step 2: Create a Pure Rust Equivalent
|
||||
|
||||
Write an equivalent function in pure Rust within the `lib_ccxr` module:
|
||||
|
||||
```rust
|
||||
fn net_send_cc() {
|
||||
// Rust equivalent code to `net_send_cc` function in `networking.c`
|
||||
}
|
||||
```
|
||||
|
||||
### Step 3: Create a C-Compatible Rust Function
|
||||
|
||||
In the `libccxr_exports` module, create a new function that will be callable from C:
|
||||
|
||||
```rust
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ccxr_net_send_cc() {
|
||||
net_send_cc() // Call the pure Rust function
|
||||
}
|
||||
```
|
||||
|
||||
### Step 4: Declare the Rust Function in C
|
||||
|
||||
In the original C file (`networking.c`), declare the Rust function as an external function:
|
||||
|
||||
```rust
|
||||
extern void ccxr_net_send_cc();
|
||||
```
|
||||
|
||||
### Step 5: Modify the Original C Function
|
||||
|
||||
Update the original C function to use the Rust implementation when available:
|
||||
|
||||
```c
|
||||
void net_send_cc() {
|
||||
#ifndef DISABLE_RUST
|
||||
return ccxr_net_send_cc(); // Use the Rust implementation
|
||||
#else
|
||||
// Original C code
|
||||
#endif
|
||||
}
|
||||
```
|
||||
|
||||
## Rust module system
|
||||
|
||||
- `lib_ccxr` crate -> **The Idiomatic Rust layer**
|
||||
|
||||
- Path: `src/rust/lib_ccxr`
|
||||
- This layer will contain the migrated idiomatic Rust. It will have complete documentation and tests.
|
||||
|
||||
- `libccxr_exports` module -> **The C-like Rust layer**
|
||||
|
||||
- Path: `src/rust/src/libccxr_exports`
|
||||
- This layer will have function names the same as defined in C but with the prefix `ccxr_`. These are the functions defined in the `lib_ccx` crate under appropriate modules. And these functions will be provided to the C library.
|
||||
- Ex: `extern "C" fn ccxr_<function_name>(<args>) {}`
|
||||
821
docs/guidoc.md
821
docs/guidoc.md
@@ -1,821 +0,0 @@
|
||||
# Documentation
|
||||
## CCExtractor Graphical User Interface
|
||||
### Code Structure:
|
||||
```
|
||||
src/GUI
|
||||
├── activity.c -Activity window definitions
|
||||
├── activity.h -Activity window declarations
|
||||
├── ccextractorGUI.c -Contains main() and GUI code for 'Main' Tab + 'Menu'
|
||||
├── ccextractorGUI.h -Function and structure declarations
|
||||
├── ccx_cli_thread.c -All the functions (definitions) passed in threads
|
||||
├── ccx_cli_thread.h -Function, variables & structs declaration used in thread
|
||||
├── command_builder.c -Builds command to pass to CLI CCExtractor
|
||||
├── command_builder.h -Function, variables & structs declaration used
|
||||
├── file_browser.c -Function definition for File Browser
|
||||
├── file_browser.h -Function, struct & variable declaration
|
||||
├── nuklear_lib -Diretory contains Library Files
|
||||
│ ├── nuklear_glfw_gl2.h -GLFW backend source header to interact with Nuklear
|
||||
│ └── nuklear.h -Nuklear library source code
|
||||
├── popups.c -Function definitions for all Popups used
|
||||
├── popups.h -Function & network struct declaration for all Popups
|
||||
├── preview.c -Preview window definitions
|
||||
├── preview.h -Preview window definitions
|
||||
├── save_load_data.c -Function definition to save last run state
|
||||
├── save_load_data.h -Function declaration to save last run state
|
||||
├── stb_image.h -Code to load images
|
||||
├── tabs.c -Function definitions for all tabs except 'Main' tab
|
||||
├── tabs.h -Function, variable and structure declarations
|
||||
├── terminal.c -Code for terminal Window
|
||||
└── win_dirent.h -Dirent API for Windows
|
||||
```
|
||||
### File by File functions:
|
||||
activity.c
|
||||
[nk_begin](#nk-begin)(ctx, "Activity", nk_rect(x, y, width, height), NK_WINDOW_TITLE|NK_WINDOW_BACKGROUND);
|
||||
[nk_end](#nk-end)(ctx);
|
||||
[nk_layout_row_dynamic](#nk-layout-row-dynamic)(ctx, 40, 1);
|
||||
[nk_label_wrap](#nk-label-wrap)(ctx, [main_settings](#struct-main-tab)->activity_string[i]);
|
||||
[nk_window_is_closed](#nk-window-is-closed)(ctx, "Activity");
|
||||
|
||||
activity.h
|
||||
int [activity](#func-activity)(struct [nk_context](#nk-context) *ctx, int x, int y, int width, int height, struct [main_tab](#struct-main-tab) *main_settings);
|
||||
|
||||
ccextractorGUI.c
|
||||
[nk_menubar_begin](#nk-menubar-begin)(ctx);
|
||||
[nk_layout_row_begin](#nk-layout-row-begin)(ctx, NK_STATIC, 30, 3);
|
||||
[nk_layout_row_push](#nk-layout-row-push)(ctx, 80);
|
||||
[nk_menu_begin_label](#nk-menu-begin-label)(ctx, "Preferences", NK_TEXT_LEFT, [nk_vec2](#nk-vec2)(120, 200));
|
||||
[nk_menu_end](#nk-menu-end)(ctx);
|
||||
[nk_menubar_end](#nk-menubar-end)(ctx);
|
||||
[nk_layout_space_begin](#nk-layout-space-begin)(ctx, NK_STATIC, 15, 1);
|
||||
[nk_layout_space_end](#nk-layout-space-end)(ctx);
|
||||
[nk_style_push_vec2](#nk-style-push-vec2)(ctx, &ctx->style.window.spacing, [nk_vec2(](#nk-vec2)0, 0));
|
||||
[nk_style_push_float](#nk-style-push-float)(ctx, &ctx->style.button.rounding, 0);
|
||||
[nk_button_label](#nk-label-button)(ctx, names[i]);
|
||||
[nk_style_pop_float](#nk-style-pop-float)(ctx);
|
||||
[nk_group_begin](#nk-group-begin)(ctx, "Advanced Tabs", NK_WINDOW_NO_SCROLLBAR);
|
||||
[nk_group_end](#nk-group-end)(ctx);
|
||||
[nk_layout_row](#nk-layout-row)(ctx, NK_DYNAMIC, 20, 3, ratio_adv_mode);
|
||||
[nk_spacing](#nk-spacing)(ctx, 1);
|
||||
[nk_checkbox_label](#nk-checkbox-label)(ctx, "Advanced Mode", &advanced_mode_check);
|
||||
[nk_option_label](#nk-option-label)(ctx, "Extract from files below:", [main_settings](#struct-main-tab).port_or_files == FILES));
|
||||
[nk_selectable_label](#nk-selectable-label)(ctx, [truncate_path_string](#func-truncate-path-string)([main_settings](#struct-main-tab).filenames[i]), NK_TEXT_LEFT, &[main_settings](#struct-main-tab).is_file_selected[i]);
|
||||
[nk_combo](#nk-combo)(ctx, [main_settings](#struct-main-tab).port_type, 2, [main_settings](#struct-main-tab).port_select, 20, [nk_vec2](#nk-vec2)_(85,100));
|
||||
[nk_label](#nk-label)(ctx, "Drag and Drop files for extraction.", NK_TEXT_CENTERED
|
||||
[nk_progress](#nk-progress)(ctx, &[main_settings](#struct-main-tab).progress_cursor, 101, nk_true);
|
||||
|
||||
ccextractorGUI.h
|
||||
void [setup_main_settings](#func-setup-main-settings)(struct main_tab *main_settings);
|
||||
char* [truncate_path_string](#func-truncate-path-string)(char *filePath);
|
||||
void [remove_path_entry](#func-remove-path-entry)(struct [main_tab](#struct-main-tab) *main_settings, int indexToRemove);
|
||||
|
||||
ccx_cli_thread.c || ccx_cli_thread.h
|
||||
void* [read_activity_data](#func-read-activity-data)(void *read_args);
|
||||
void* [read_data_from_thread](#func-read-data-from-thread)(void* read_args);
|
||||
void* [extract_thread](#func-extract-thread)(void* extract_args);
|
||||
void* [feed_files_for_extraction](#func-feed-files-for-extraction)(void* file_args);
|
||||
void [setup_and_create_thread](#fun-setup-and-create-thread)(struct [main_tab](#struct-main-tab) *main_settings, struct [built_string](#struct-built-string) *command);
|
||||
void&asst; [find_hd_homerun_devices](#func-hd-homerun-devices)(void *args);
|
||||
void* [setup_hd_homerun_device](#func-setup-hd-homerun-device)(void *args);
|
||||
|
||||
command_builder.c || command_builder.h
|
||||
void [command_builder](#func-command-builder)(struct [built_string](#struct-built-string) *command,
|
||||
struct [main_tab](#struct-main-tab) *main_settings,
|
||||
struct [network_popup](#struct-network-popup) *network_settings,
|
||||
struct [input_tab](#struct-input-tab) *input,
|
||||
struct [advanced_input_tab](#struct-advanced-input-tab) *advanced_input,
|
||||
struct [output_tab](#struct-output-tab) *output,
|
||||
struct [decoders_tab](#struct-output-tab) *decoders,
|
||||
struct [credits_tab](#struct-output-tab) *credits,
|
||||
struct [debug_tab](#struct-debug-tab) *debug,
|
||||
struct [burned_subs_tab](#struct-debug-tab) *burned_subs);
|
||||
|
||||
file_browser.c || file_browser.h
|
||||
void [die](#func-die)(const char *fmt, ...);
|
||||
char* [file_load](#func-file-load)(const char* path, size_t* siz);
|
||||
char* [str_duplicate](#func-str-duplicate)(const char *src);
|
||||
void [dir_free_list](#func-dir-free-list)(char **list, size_t size);
|
||||
char** [dir_list](#func-dir-list)(const char *dir, int return_subdirs, size_t *count);
|
||||
struct file_group [FILE_GROUP](#func-file-group)(enum file_groups group, const char *name, struct nk_image *icon);
|
||||
struct file [FILE_DEF](#func-file-def)(enum file_types type, const char *suffix, enum file_groups group);
|
||||
struct nk_image* [media_icon_for_file](#func-media-icon-for-file)(struct media *media, const char *file);
|
||||
void [media_init](#func-media-init)(struct media *media);
|
||||
void [file_browser_reload_directory_content](#func-file-browser-reload-directory-content)(struct file_browser *browser, const char *path);
|
||||
void [get_drives](#func-get-drives)(struct file_browser *browser);
|
||||
void [file_browser_init](#func-file-browser-init)(struct file_browser *browser, struct media *media);
|
||||
void [file_browser_free](#func-file-browser-free)(struct file_browser *browser);
|
||||
int [file_browser_run](#func-file-browser-run)(struct file_browser *browser, struct [nk_context](#nk-context) *ctx, struct [main_tab](#struct-main-tab) *main_settings, struct [output_tab](#struct-output-tab) *output, struct [debug_tab](#struct-debug-tab) *debug, struct [hd_homerun_tab](#struct-hd-homerun-tab) *hd_homerun);
|
||||
|
||||
popups.c || popups.h
|
||||
void [draw_network_popup](#func-draw-network-popup)(struct [nk_context](#nk-context) *ctx, int *show_preferences_network, struct [network_popup](#struct-network-popup) *network_settings);
|
||||
void [draw_getting_started_popup](#func-draw-getting-started-popup)(struct [nk_context](#nk-context) *ctx, int *show_getting_started);
|
||||
void [draw_about_ccx_popup](#func-draw-about-ccx-popup)(struct [nk_context](#nk-context) *ctx, int *show_about_ccx, struct nk_user_font *droid_big, struct nk_user_font *droid_head);
|
||||
void [draw_progress_details_popup](#func-draw-progress-details-popup)(struct [nk_context](#nk-context) *ctx, int *show_progress_details, struct [main_tab](#struct-main-tab) *main_settings);
|
||||
void [draw_color_popup](#func-draw-color-popup)(struct [nk_context](#nk-context) *ctx, struct [output_tab](#struct-output-tab) *output);
|
||||
void [draw_thread_popup](#fun-draw-thread-popup)(struct [nk_context](#nk-context) *ctx, int *show_thread_popup);
|
||||
void [setup_network_settings](#func-setup-network-settings)(struct [network_popup](#struct-network-popup) *network_settings);
|
||||
|
||||
preview.c || preview.h
|
||||
int [preview](#func-preview)(struct [nk_context](#nk-context) *ctx, int x, int y, int width, int height, struct [main_tab](#struct-main-tab) *main_settings);
|
||||
|
||||
save_load_data.c || save_load_data.h
|
||||
void [load_data](#func-load-data)(FILE *file,
|
||||
struct [main_tab](#struct-main-tab) *main_settings,
|
||||
struct [input_tab](#struct-input-tab) *input,
|
||||
struct [advanced_input_tab](#struct-advanced-input-tab) *advanced_input,
|
||||
struct [output_tab](#struct-output-tab) *output,
|
||||
struct [decoders_tab](#struct-decoders-tab) *decoders,
|
||||
struct [credits_tab](#struct-credits-tab) *credits,
|
||||
struct [debug_tab](#struct-debug-tab) *debug,
|
||||
struct [hd_homerun_tab](#struct-hd-homerun-tab) *hd_homerun,
|
||||
struct [burned_subs_tab](#struct-burned-subs-tab) *burned_subs);
|
||||
|
||||
void [save_data](#func-save-data)(FILE *file,
|
||||
struct [main_tab](#struct-main-tab) *main_settings,
|
||||
struct [input_tab](#struct-input-tab) *input,
|
||||
struct [advanced_input_tab](#struct-advanced-input-tab) *advanced_input,
|
||||
struct [output_tab](#struct-output-tab) *output,
|
||||
struct [decoders_tab](#struct-decoders-tab) *decoders,
|
||||
struct [credits_tab](#struct-credits-tab) *credits,
|
||||
struct [debug_tab](#struct-debug-tab) *debug,
|
||||
struct [hd_homerun_tab](#struct-hd-homerun-tab) *hd_homerun,
|
||||
struct [burned_subs_tab](#struct-burned-subs-tab) *burned_subs);
|
||||
|
||||
void [write_credits](#func-write-credits)(FILE* file, struct [credits_tab](#struct-credits-tab) *credits);
|
||||
void [read_credits](#func-read-credits)(FILE* file, struct [credits_tab](#struct-credits-tab) *credits);
|
||||
|
||||
terminal.c
|
||||
int [terminal](#func-terminal)(struct [nk_context](#nk-context) *ctx, int x, int y, int width, int height, char *command);
|
||||
|
||||
### About CCExtractor specific functions
|
||||
#### int <a id="func-activity">activity</a>(struct nk_context *ctx, int x, int y, int width, int height, struct [main_tab](#struct-main-tab) *main_settings);
|
||||
##### Info:
|
||||
--Contains the procedure to be carried out when Activity Window is toggled.
|
||||
##### Parameters:
|
||||
* *ctx - pointer to `nk_context` structure.
|
||||
* x - X co-ordinate to draw Activity Window
|
||||
* y - Y co-ordinate to draw Activty Window.
|
||||
* width - width of window to draw.
|
||||
* height - height of window to draw.
|
||||
* *main_settings - pointer to [`main_tab`](#struct-main-tab) structure.
|
||||
##### Return Type: int
|
||||
* Returns non-zero value if window is not closed.
|
||||
* Returns zero if window is closed.
|
||||
#### void <a id="func-setup-main-settings">setup_main_settings</a>(struct [main_tab](#struct-main-tab) *main_settings);
|
||||
##### Info:
|
||||
Setups the required defaults of variables in [`main_tab`](#struct-main-tab) structure.
|
||||
##### Parameters:
|
||||
* *main_settings - pointer to [`main_tab`](#struct-main-tab) structure.
|
||||
##### Return Type: void
|
||||
#### char* <a id="func-truncate-path-string">truncate_path_string</a>(char *filePath);
|
||||
##### Info:
|
||||
Truncated the Path String of file to visible area using `...`
|
||||
##### Parameters:
|
||||
* *filePath - Pointer to string to be truncated.
|
||||
##### Return Type: *char
|
||||
* Returns pointer to truncated string.
|
||||
#### void <a id="func-remove-path-entry">remove_path_entry</a>(struct [main_tab](#struct-main-tab) *main_settings, int indexToRemove);
|
||||
##### Info:
|
||||
Removes the selected path in the extraction queue (Selected entry's index is passed).
|
||||
##### Parameters:
|
||||
* *main_settings - pointer to [`main_tab`](#struct-main-tab) structure.
|
||||
* indexToRemove - index of the string to be removed from dynamic array of many strings.
|
||||
##### Return Type: void
|
||||
|
||||
#### void* <a id="func-read-activity-data">read_activity_data</a>(void *read_args);
|
||||
##### Info:
|
||||
Reads activity data related to CCExtractor on `stdout`. And outputs to activity window (Updates variables that code of activity window uses).
|
||||
##### Parameters:
|
||||
* *read_args - Pointer to void, because thread functions don't allow any datatype as argument or return type. Therefore they are passed as void then typecasted later in the function.
|
||||
##### Return type: void*
|
||||
|
||||
#### void* <a id="func-read-data-from-thread>read_data_from_thread</a>(void* read_args);
|
||||
##### Info:
|
||||
Reads data from`--gui_mode_reports` redirected from `stderr` to a file. Reads the subtitles extracted in realtime and updates the variables for the same, updates the state of progress bar. Also, lanches [read_activity_data](#func-read-activity-data) in a new thread.
|
||||
##### Parameters:
|
||||
* *read_args - Pointer to void, because thread functions don't allow any datatype as argument or return type. Therefore they are passed as void then typecasted later in the function.
|
||||
##### Return type: void*
|
||||
|
||||
#### void* <a id="func-extract-thread">extract_thread</a>(void* extract_args);
|
||||
##### Info:
|
||||
Passes command with all options from GUI to CLI CCExtractor.
|
||||
##### Parameters:
|
||||
* *extract_args - Pointer to void, because thread functions don't allow any datatype as argument or return type. Therefore they are passed as void then typecasted later in the function.
|
||||
##### Return type: void*
|
||||
|
||||
#### void* <a id="func-feed-files-for-extraction">feed_files_for_extraction</a>(void* file_args);
|
||||
##### Info:
|
||||
Feeds file by file to a new thread and waits until its extraction is done. This is done until all the files in extraction queue are extracted.
|
||||
##### Parameters:
|
||||
* *file_args - Pointer to void, because thread functions don't allow any datatype as argument or return type. Therefore they are passed as void then typecasted later in the function.
|
||||
##### Return type: void*
|
||||
|
||||
#### void <a id="func-setup-and-create-thread">setup_and_create_thread</a>(struct [main_tab](#struct-main-tab) *main_settings, struct [built_string](#struct-built-string) *command);
|
||||
##### Info:
|
||||
Initialises some values for the structure used in thread arguments and creates [feed_files_for_extraction](#feed-files-for-extraction).
|
||||
##### Parameters:
|
||||
* *main_settings - Pointer to `main_tab` struct.
|
||||
* *command - Pointer to `built_string` struct.
|
||||
##### Return type: void*
|
||||
|
||||
#### void* <a id="func-hind-hd-homerun-devices">find_hd_homerun_devices</a>(void *args);
|
||||
Finds devices connected to HD HomeRun Network.
|
||||
#### Parameters:
|
||||
* *args - Pointer to void, because thread functions don't allow any datatype as argument or return type. Therefore they are passed as void then typecasted later in the function.
|
||||
#### Return type: void*
|
||||
|
||||
#### void* <a id="func-setup-hd-homerun-device">setup_hd_homerun_device</a>(void *args);
|
||||
##### Info:
|
||||
Sets up various parameters required to extract subtitle from incoming stream from a HD HomeRun Device.
|
||||
##### Parameters:
|
||||
* *args - Pointer to void, because thread functions don't allow any datatype as argument or return type. Therefore they are passed as void then typecasted later in the function.
|
||||
##### Return type: void*
|
||||
|
||||
#### void [command_builder](#func-command-builder)(struct [built_string](#struct-built-string) *command, struct [main_tab](#struct-main-tab) *main_settings, struct [network_popup](#struct-network-popup) *network_settings, struct [input_tab](#struct-input-tab) *input, struct [advanced_input_tab](#struct-advanced-input-tab) *advanced_input, struct [output_tab](#struct-output-tab) *output, struct [decoders_tab](#struct-output-tab) *decoders, struct [credits_tab](#struct-output-tab) *credits, struct [debug_tab](#struct-debug-tab) *debug, struct [burned_subs_tab](#struct-debug-tab) *burned_subs);
|
||||
##### Info:
|
||||
Fetches the options from the whole GUI and adds the respective CLI commands to the `term_string` in `built_string` struct.
|
||||
##### Parameters:
|
||||
* *command - Pointer to `built_string` command.
|
||||
* *main_settings - Pointer to `main_tab` struct.
|
||||
* *network_settings - Pointer to `network_popup` struct.
|
||||
* *input - Pointer to `input_tab` struct.
|
||||
* *advance_input - Pointer to `advanced_input` struct.
|
||||
* *output - Pointer to `output_tab` struct.
|
||||
* *decoders - Pointer to `decoders_tab` struct.
|
||||
* *credits - Pointer to `credits_tab` struct.
|
||||
* *debug - Pointer to `debug_tab` struct.
|
||||
* *burned_subs - Pointer to `burned_subs_tab` struct.
|
||||
##### Return type: void
|
||||
|
||||
#### void <a id="func-die">die</a>(const char *fmt, ...);
|
||||
##### Info:
|
||||
Custom function to generate error if something in File Browser goes wrong.
|
||||
##### Parameters:
|
||||
* *fmt - Format of char string along with place holder for variables.
|
||||
* ... - Variables in order of their specified place holder.
|
||||
##### Return type: void
|
||||
|
||||
#### char* <a id="func-file-load">file_load</a>(const char* path, size_t* siz);
|
||||
##### Info:
|
||||
Custom function to load file and read data from loaded file.
|
||||
##### Parameters:
|
||||
* *path - Pointer to string literal (Path of the file).
|
||||
* *siz - Size of string literal provided (To allocate memory accordingly).
|
||||
##### Return type: void
|
||||
|
||||
#### char* <a id="func-str-duplicate">str_duplicate</a>(const char *src);
|
||||
##### Info:
|
||||
Dynamically copies specified string to memory.
|
||||
##### Parameters:
|
||||
* *src - The String to be copied.
|
||||
##### Return type: char*
|
||||
* Pointer to the string in the memory.
|
||||
|
||||
#### void <a id="func-dir-free-list">dir_free_list</a>(char **list, size_t size);
|
||||
##### Info:
|
||||
Frees the memory allocated to Files' and Directories' name and path.
|
||||
##### Parameters:
|
||||
* **char - Pointer to list (array of strings) to be freed
|
||||
##### Return type: void
|
||||
|
||||
#### char** <a id="func-dir-list">dir_list</a>(const char *dir, int return_subdirs, size_t *count);
|
||||
##### Info:
|
||||
Opens the selected directory and adds its path to list and returns the same list.
|
||||
#####Parameters:
|
||||
* *dir - Pointer to string (name of directory to be opened).
|
||||
* return_subdirs - `nk_true` if subdirectories are to be returned then.
|
||||
* *count - Number of directories in opened directories.
|
||||
#### Retrun type: char**
|
||||
* Pointer to List (Array of strings, name of directories and files) is returned.
|
||||
|
||||
#### struct file_group <a id="func-file-group">FILE_GROUP</a>(enum file_groups group, const char *name, struct nk_image *icon);
|
||||
##### Info:
|
||||
Initialises variables for `file_group` struct.
|
||||
##### Parameters:
|
||||
* group - specifies to which group does the file belong to. Selected from `file_groups` enum, like `FILE_GROUP_MUSIC`.
|
||||
* *name - Pointer to a string literal (to set `name` member in `file_group`.
|
||||
* *icon - Pointer to `nk_image` struct (Holds attributes for loaded image file) to set to `icon`member of `file_group`.
|
||||
##### Returnt type: struct `file_group`
|
||||
* Returns a `file_group` instance with set variables.
|
||||
|
||||
#### struct file <a id="func-file-def">FILE_DEF</a>(enum file_types type, const char *suffix, enum file_groups group);
|
||||
##### Info:
|
||||
Initialises variables for `file` struct.
|
||||
##### Parameters:
|
||||
* type - specifies which type does the file belong to. Selected from `file_types` enum, like `FILE_TEXT`.
|
||||
* *suffix - Pointer to string( to set `suffix` member in `file`).
|
||||
* group - specifies to which group does the file belong to. Selected from `file_groups` enum, like `FILE_GROUP_MUSIC`.
|
||||
##### Return type: struct `file`
|
||||
* Returns a `file` instance with set variables.
|
||||
|
||||
#### struct nk_image* <a id="func-media-icon-for-file">media_icon_for_file</a>(struct media *media, const char *file);
|
||||
##### Info:
|
||||
Analyses the files and checks to which `file` or `file_group` they belong and assign appropriate icon to the file and returns the same.
|
||||
##### Parameters:
|
||||
* *media - pointer to `media` struct.
|
||||
* *file - pointer to string literal (name of file with extension)
|
||||
##### Return type: struct `nk_image`*
|
||||
* Returns appropriate `nk_image` corresponding to the file.
|
||||
|
||||
#### void <a id="func-media-init">media_init</a>(struct media *media);
|
||||
##### Info:
|
||||
Assigns icons to `file` and `file_group` members from.
|
||||
##### Parameters:
|
||||
* *media - pointer to `media` struct.
|
||||
#### Return type: void
|
||||
|
||||
#### void <a is="func-file-browser-reload-directory-content">file_browser_reload_directory_content</a>(struct file_browser *browser, const char *path);
|
||||
##### Info:
|
||||
Updates various variables related to Files/Directories path and names when screen of File Browser reloads. (Due to clicking on a directory or any other button leading to different directory).
|
||||
##### Parameters:
|
||||
* *browser - Pointer to `file_browser` struct.
|
||||
* *path - Path of the new directory whose contents are to be reloaded and showed on file browser.
|
||||
##### Return type: void
|
||||
|
||||
#### void <a id="func-get-drives">get_drives</a>(struct file_browser *browser);
|
||||
##### Info:
|
||||
NOTE: Windows Specific Function.
|
||||
Detects the number of drives and their respective Drive Letters to show the same in File Browser.
|
||||
#####Parameters:
|
||||
* *browser - pointer to `file_browser` struct.
|
||||
##### Return type: void
|
||||
|
||||
#### void <a id="func-file-browser-init">file_browser_init</a>(struct file_browser *browser, struct media *media);
|
||||
##### Info:
|
||||
Initialised various variables/attributes required whenever the File Browser is run.
|
||||
##### Parameters:
|
||||
* *browser - Pointer to `file_browser` struct.
|
||||
* *media - pointer to `media` struct.
|
||||
##### Return type: void
|
||||
|
||||
#### void <a id="func-file-browser-free">file_browser_free</a>(struct file_browser *browser);
|
||||
##### Info:
|
||||
Frees the memory allocated to various variables in [file_browser_init](#func-file-browser-init).
|
||||
##### Parameters:
|
||||
* *browser - pointer to `file_browser` struct.
|
||||
##### Return type: void
|
||||
|
||||
#### int <a id="func-file-browser-run">file_browser_run</a>(struct file_browser *browser, struct [nk_context](#nk-context) *ctx, struct [main_tab](#struct-main-tab) *main_settings, struct [output_tab](#struct-output-tab) *output, struct [debug_tab](#struct-debug-tab) *debug, struct [hd_homerun_tab](#struct-hd-homerun-tab) *hd_homerun);
|
||||
##### Info:
|
||||
Provides runtime of File Browser on GUI.
|
||||
##### Parameters:
|
||||
* *browser - pointer to `file_browser` struct.
|
||||
* *ctx - pointer to `nk_context` struct.
|
||||
* *main_settings - pointer to `main_tab` struct.
|
||||
* *output - poiter to `output_tab` struct.
|
||||
* *debug - pointer to `debug_tab` struct.
|
||||
* *hd_homerun - pointer to `hd_homerun_tab` struct.
|
||||
##### Return type: int
|
||||
* Returns `1` if any File name/path is copied to current variable.
|
||||
* Returns `0` otherwise.
|
||||
|
||||
#### void <a -d="func-draw-network-popup">draw_network_popup</a>(struct [nk_context](#nk-context) *ctx, int *show_preferences_network, struct [network_popup](#struct-network-popup) *network_settings);
|
||||
##### Info:
|
||||
Draws popup with Network Settings on GUI.
|
||||
##### Parameters:
|
||||
* *ctx - pointer to `nk_context` struct.
|
||||
* *show_preferences_network - pointer to variable status if which triggers the popup.
|
||||
* *network_settings - pointer to `network_popup` struct.
|
||||
##### Return type: void
|
||||
|
||||
#### void <a id="func-draw-getting-started-popup">draw_getting_started_popup</a>(struct [nk_context](#nk-context) *ctx, int *show_getting_started);
|
||||
##### Info:
|
||||
Draws popup on screen which shows Getting Started Info.
|
||||
##### Parameters:
|
||||
* *ctx - pointer to `nk_context` struct.
|
||||
* *show_getting_started - pointer to variable status if which triggers the popup.
|
||||
##### Return type: void
|
||||
|
||||
#### void <a id="func-draw-about-ccx-popup">draw_about_ccx_popup</a>(struct [nk_context](#nk-context) *ctx, int *show_about_ccx, struct nk_user_font *droid_big, struct nk_user_font *droid_head);
|
||||
##### Info:
|
||||
Draws popup on screen containing information about CCExtractor.
|
||||
##### Parameters:
|
||||
* *ctx - pointer to `nk_context` struct.
|
||||
* *show_about_ccx - pointer to variable status if which triggers the popup.
|
||||
* *droid_big - pointer to `nk_user_font` struct.
|
||||
* *droid_head - pointer to `nk_user_font` struct.
|
||||
##### Return type: void
|
||||
|
||||
#### void <a id="func-draw-progress-details-popup">draw_progress_details_popup</a>(struct [nk_context](#nk-context) *ctx, int *show_progress_details, struct [main_tab](#struct-main-tab) *main_settings);
|
||||
##### Info:
|
||||
Draws popup on screen which shows progress details.
|
||||
##### Parameters:
|
||||
* *ctx - pointer to `nk_context` struct.
|
||||
* *show_pogress_details - pointer to variable status if which triggers the popup.
|
||||
* *main_settings - pointer to `main_tab` struct.
|
||||
##### Return type: void
|
||||
#### void <a id="func-draw-color-popup">draw_color_popup</a>(struct [nk_context](#nk-context) *ctx, struct [output_tab](#struct-output-tab) *output);
|
||||
##### Info:
|
||||
Draws popup on screen which shows color-picker.
|
||||
##### Parameters:
|
||||
* *ctx - pointer to `nk_context` struct.
|
||||
* *output - pointer to `output_tab` struct.
|
||||
##### Return type: void
|
||||
|
||||
#### void <a id="func-draw-thread-popup">draw_thread_popup</a>(struct [nk_context](#nk-context) *ctx, int *show_thread_popup);
|
||||
##### Info:
|
||||
This popup is shown if anyhow the GUI is unable to read file.
|
||||
##### Parameters:
|
||||
* *ctx - pointer to `nk_context` struct.
|
||||
* *show_thread_popup - pointer to variable status if which triggers the popup.
|
||||
##### Return type: void
|
||||
|
||||
#### void <a id="func-setup-network-settings">setup_network_settings</a>(struct [network_popup](#struct-network-popup) *network_settings);
|
||||
##### Info:
|
||||
Sets up defaults for Network Settings.
|
||||
##### Parameters:
|
||||
* *network_settings - pointer to `network_popup` struct.
|
||||
##### Return type: void
|
||||
|
||||
#### int <a id="func-preview">preview</a>(struct [nk_context](#nk-context) *ctx, int x, int y, int width, int height, struct [main_tab](#struct-main-tab) *main_settings);
|
||||
##### Info:
|
||||
Draws `Preview` Nuklear window and shows preview strings (lines of subtitles extracted in realtime).
|
||||
##### Parameters:
|
||||
* *ctx - pointer to `nk_context` struct.
|
||||
* x - X co-ordinate from where to draw window.
|
||||
* y - Y co-ordinate from where to draw window.
|
||||
* width - width of window.
|
||||
* height - height of window.
|
||||
* *main_settings - pointer to `main_tab ` struct.
|
||||
##### Return type:
|
||||
* Returns non-zero value if window is not closed.
|
||||
* Returns zero if window is closed.
|
||||
|
||||
#### void <a id="func-load-data">load_data</a>(FILE *file, struct [main_tab](#struct-main-tab) *main_settings, struct [input_tab](#struct-input-tab) *input, struct [advanced_input_tab](#struct-advanced-input-tab) *advanced_input, struct [output_tab](#struct-output-tab) *output, struct [decoders_tab](#struct-decoders-tab) *decoders, struct [credits_tab](#struct-credits-tab) *credits, struct [debug_tab](#struct-debug-tab) *debug, struct [hd_homerun_tab](#struct-hd-homerun-tab) *hd_homerun, struct [burned_subs_tab](#struct-burned-subs-tab) *burned_subs);
|
||||
##### Info:
|
||||
Loads values of all the variables stored in a file at last exit of GUI.
|
||||
##### Parameters:
|
||||
* *file - pointer to `FILE`.
|
||||
* *main_settings - pointer to `main_tab` struct.
|
||||
* *intput - pointer to `input_tab` struct.
|
||||
* *advanced_input - pointer to `advanced_input_tab` struct.
|
||||
* *output - pointer to `output_tab` struct.
|
||||
* *decoders - pointer to `decoders_tab` struct.
|
||||
* *credits - poitner to `credits_tab` struct.
|
||||
* *debug - pointer to `debug_tab` struct.
|
||||
* *hd_homerun - pointer to `hd_homerun_tab` struct.
|
||||
* *burned_subs - pointer to `burned_subs_tab` struct.
|
||||
##### Return type: void
|
||||
|
||||
#### void <a id="func-save-data">save_data</a>(FILE *file, struct [main_tab](#struct-main-tab) *main_settings, struct [input_tab](#struct-input-tab) *input, struct [advanced_input_tab](#struct-advanced-input-tab) *advanced_input, struct [output_tab](#struct-output-tab) *output, struct [decoders_tab](#struct-decoders-tab) *decoders, struct [credits_tab](#struct-credits-tab) *credits, struct [debug_tab](#struct-debug-tab) *debug, struct [hd_homerun_tab](#struct-hd-homerun-tab) *hd_homerun, struct [burned_subs_tab](#struct-burned-subs-tab) *burned_subs);
|
||||
##### info:
|
||||
Saves values of all the variables as a "Current State" in a file on exit.
|
||||
##### Parameters:
|
||||
* *file - pointer to `FILE`.
|
||||
* *main_settings - pointer to `main_tab` struct.
|
||||
* *intput - pointer to `input_tab` struct.
|
||||
* *advanced_input - pointer to `advanced_input_tab` struct.
|
||||
* *output - pointer to `output_tab` struct.
|
||||
* *decoders - pointer to `decoders_tab` struct.
|
||||
* *credits - poitner to `credits_tab` struct.
|
||||
* *debug - pointer to `debug_tab` struct.
|
||||
* *hd_homerun - pointer to `hd_homerun_tab` struct.
|
||||
* *burned_subs - pointer to `burned_subs_tab` struct.
|
||||
##### Return type: void
|
||||
|
||||
#### void <a id="func-write-credits">write_credits</a>(FILE *file, struct [credits_tab](#struct-credits-tab) *credits);
|
||||
##### Info:
|
||||
Writes Credits to files after some operations, since extra`\n` character gives problems while reading file.
|
||||
##### Parameters:
|
||||
* *file - pointer to `FILE`.
|
||||
* *credits - pointer to `credits_tab` struct.
|
||||
##### Return type: void
|
||||
|
||||
#### void <a id="func-read-credits">read_credits</a>(FILE* file, struct [credits_tab](#struct-credits-tab) *credits);
|
||||
##### Info:
|
||||
Reads credits from file in a specific format (as written by [write_credits](#func-write-credits)) from file.
|
||||
##### Parameters:
|
||||
* *file - pointer to `FILE`.
|
||||
* *credits - pointer to `credits_tab` struct.
|
||||
##### Return type: void
|
||||
|
||||
#### int <a id="func-terminal">terminal</a>(struct [nk_context](#nk-context) *ctx, int x, int y, int width, int height, char *command);
|
||||
##### Info:
|
||||
Writes the command string (that would be passed to CLI CCExtractor) in "Terminal" Nuklear Window.
|
||||
##### Parameters:
|
||||
* *ctx - pointer to `nk_context` struct.
|
||||
* x - X co-ordinate from where to draw the window.
|
||||
* y - Y co-ordinate from where to draw the window.
|
||||
* width - Width of the window.
|
||||
* height - height of the window.
|
||||
* *command - String to write on window (the command to be passed).
|
||||
##### Return type: int
|
||||
* Returns non-zero value if window is not closed.
|
||||
* Returns zero if window is closed.
|
||||
|
||||
|
||||
### About CCExtractor specific Structures/Variables
|
||||
#### <a id="struct-main-tab">main_tab</a>
|
||||
##### Info:
|
||||
Contains all the variables for `Main` tab.
|
||||
##### Variables worth noting:
|
||||
* `int is_file_browser_active`
|
||||
* `nk_true` if File Browser is triggered by any event.
|
||||
* `nk_false` otherwise.
|
||||
* `int scaleWindowForFileBrowser`
|
||||
* Sets to `nk_true` if `is_file_browser_active` is `nk_true` to scale the `glfwWindow` to required size to accommodate File Browser.
|
||||
* Sets to `nk_false` otherwise.
|
||||
|
||||
#### <a id="struct-input-tab">input_tab</a>
|
||||
##### Info:
|
||||
Contains all variables to hold data of options selected/changed and view dynamically generated data to GUI in `Input` tab.
|
||||
|
||||
#### <a id="struct-advanced-input">advanced_input_tab</a>
|
||||
Info:
|
||||
Contains all variables to hold data of options selected/changed and view dynamically generated data to GUI in `Advanced Input` tab.
|
||||
|
||||
#### <a id="struct-output-tab">output_tab</a>
|
||||
#####Info:
|
||||
Contains all variables to hold data of options selected/changed and view dynamically generated data to GUI in `Advanced Input` tab.
|
||||
|
||||
#### <a id="struct-decoders-tab">decoders_tab</a>
|
||||
##### Info:
|
||||
Contains all variables to hold data of options selected/changed and view dynamically generated data to GUI in `Decoders` tab.
|
||||
|
||||
#### <a id="struct-credits-tab">credits_tab</a>
|
||||
##### Info:
|
||||
Contains all variables to hold data of options selected/changed and view dynamically generated data to GUI in `Credits` tab.
|
||||
|
||||
#### <a id="struct-debug-tab">debug_tab</a>
|
||||
##### Info:
|
||||
Contains all variables to hold data of options selected/changed and view dynamically generated data to GUI in `Debug` tab.
|
||||
|
||||
#### <a id="struct-hd-homerun-tab">hd_homerun_tab</a>
|
||||
##### Info:
|
||||
Contains all variables to hold data of options selected/changed and view dynamically generated data to GUI in `HDHomeRun` tab.
|
||||
|
||||
#### <a id="struct-burned-subs-tab">burned_subs</a>
|
||||
##### Info:
|
||||
Contains all variables to hold data of options selected/changed and view dynamically generated data to GUI in `HDHomeRun` tab.
|
||||
|
||||
#### <a id="struct-network-popup">networ_popup</a>
|
||||
##### Info:
|
||||
Contains all the variables to store all the Network related options or showing them in GUI dynamically.
|
||||
|
||||
### About Nuklear Specific functions
|
||||
#### int <a id="nk-begin">nk_begin</a>(struct nk_context*, const char *title, struct nk_rect bounds, nk_flags flags);
|
||||
##### Info:
|
||||
Draws a basic(and blank) window(Nuklear Window inside main GLFW window) to hold other Nuklear widgets.
|
||||
##### Parameters:
|
||||
* nk_context* - Pointer to `nk_context` structure.
|
||||
* *title - Title for the so drawn Nuklear Window.
|
||||
* bounds - instance of `nk_rect` structure to hold co-ordinates, width and height of the Nuklear Window.
|
||||
* flags - Which flags to pass( from those contained in `enum flags`) to change behaviour of the Nuklear Window.
|
||||
##### Return Type: int
|
||||
* Returns true if window creation is successful.
|
||||
* Returns false if window creation fails.
|
||||
|
||||
#### void <a id="nk-end">nk_end</a>(struct nk_context *ctx)
|
||||
##### Info:
|
||||
Marks the end of the Nuklear Window.
|
||||
##### Parameter:
|
||||
* *ctx - Pointer to `nk_context` structure.
|
||||
##### Return type: void
|
||||
|
||||
#### void <a id="nk-layout-row-dynamic">nk_layout_row_dynamic</a>(struct nk_context*, float height, int cols);
|
||||
##### Info:
|
||||
Used to define a dynamic row layout(to hold widgets), dynamic in the sense that the width is dynamically allocated to widgets.
|
||||
##### Parameters:
|
||||
* *nk_context - Pointer to `nk_context` structure.
|
||||
* height - height to set for widgets of that row.
|
||||
* cols - Columns to set for layout (generally the number of widgets to place).
|
||||
##### Return Type: void
|
||||
|
||||
#### void <a id="nk-label-wrap">nk_label_wrap</a>(struct nk_context*, const char*);
|
||||
##### Info:
|
||||
Writes a label ( A plain String) and wraps it to the next line if the border of Nuklear Window, Group or Popup is reached.
|
||||
*Note*: If the text wraps to next line, height for a new line must be considered while defining a layout, else the wrapped text won't be visible (but it will be there).
|
||||
##### Parameters:
|
||||
* nk_context* - Pointer to `nk_context` structure.
|
||||
* char* - Pointer to string literal (to view).
|
||||
|
||||
#### int <a id="nk-window-is-closed">nk_window_is_closed</a>(struct nk_context *ctx, const char *name);
|
||||
##### Info:
|
||||
Checks if the active Nuklear Window is closed (by any trigger).
|
||||
##### Parameters:
|
||||
* *ctx - Pointer to `nk_context` structure.
|
||||
* *name - Pointer to String literal(Name of window to check).
|
||||
##### Return type: int
|
||||
* Returns true if window is closed (by any trigger).
|
||||
* Returns false of window is not closed.
|
||||
|
||||
#### void <a id="nk-menubar-begin">nk_menubar_begin</a>(struct nk_context *ctx);
|
||||
##### Info:
|
||||
Marks the end of Menu Bar definition(Menubar code).
|
||||
##### Parameters:
|
||||
* *ctx - Pointer to `nk_context` structure.
|
||||
##### Return type: void
|
||||
|
||||
#### void <a id="nk-layout-row-begin">nk_layout_row_begin</a>(struct nk_context *ctx, enum nk_layout_format fmt, float row_height, int cols);
|
||||
##### Info:
|
||||
Marks the beginning of custom layout. Which means, marking that layout has begun, now the widgets will be pushed row by row as per requirement using [nk_layout_row_push](#nk-layout-row-push).
|
||||
##### Parameters:
|
||||
* *ctx - Pointer to `nk_context` structure.
|
||||
* fmt - Layout format from provided formats (`enum nk_layout_format`), example - `NK_STATIC`, `NK_DYNAMIC`.
|
||||
* row_height - height of row pushed.
|
||||
* cols - Number of columns pushed in row.
|
||||
##### Return type: void
|
||||
|
||||
#### void <a id="nk-layout-row-push">nk_layout_row_push</a>(struct nk_context*, float value);
|
||||
##### Info:
|
||||
Pushes a row to hold widgets after defining the beginning of custom layout by [nk_layout_row_begin](#nk-layout-row-begin).
|
||||
##### Parameters:
|
||||
* nk_context* - Pointer to `nk_context` structure.
|
||||
* value - ratio or width of the widget to be pushed next.
|
||||
##### Return Type: void
|
||||
|
||||
#### int <a id="nk-menu-begin-label">nk_menu_begin_label</a>(struct nk_context *ctx, const char *text, nk_flags align, struct [nk_vec2](#nk-vec2) size);
|
||||
##### Info:
|
||||
The label of the Menu Item to be pushed, for example - "Preferences" is marked by this function.
|
||||
##### Parameters:
|
||||
* *ctx - pointer to `nk_context` structure.
|
||||
* *text - pointer to string literal (Title of the Menu, example - "Settings").
|
||||
* align - alignment enumeration in `nk_flags`, example `NK_TEXT_LEFT`.
|
||||
* size - Size of label (as `nk_vec2` struct)
|
||||
##### Return type: int
|
||||
* Returns true if label creation successful.
|
||||
* Returns false if label creation fails.
|
||||
|
||||
#### void <a id="nk-menubar-end">nk_menubar_end</a>(struct nk_context*);
|
||||
##### Info:
|
||||
Marks the end of the MenuBar definition.
|
||||
##### Parameters:
|
||||
* nk_context* - Pointer to `nk_context` structure.
|
||||
##### Return type: void
|
||||
|
||||
#### void <a id="nk-layout-space-begin">nk_layout_space_begin</a>(struct nk_context *ctx, enum nk_layout_format fmt, float height, int widget_count);
|
||||
##### Info:
|
||||
Marks the beginning of an empty space (Custom space for proper placement of widgets).
|
||||
##### Parameters:
|
||||
* *ctx - pointer to `nk_context` structure.
|
||||
* fmt - Layout format as in `enu nk_layout_format`, example - `NK_STATIC`, `NK_DYNAMIC`.
|
||||
* height = height of space to be added.
|
||||
* widget_count - Number of spaces to add.
|
||||
##### Return type: void
|
||||
|
||||
#### void <a id="nk-layout-space-end">nk_layout_space_end</a>(struct nk_context *ctx);
|
||||
##### Info:
|
||||
Marks the end of custom space (empty) definition.
|
||||
##### Parameters:
|
||||
* *ctx - pointer to `nk_context` structure.
|
||||
##### Return type: void
|
||||
|
||||
#### int <a id="nk-style-push-vec2">nk_style_push_vec2</a>(struct nk_context* struct nk_vec2*, struct nk_vec2);
|
||||
##### Info:
|
||||
Comes under `Style Stack`. Used to temporarily modify length, width, spacing related attributes of Styles of Nuklear Context.
|
||||
##### Parameters:
|
||||
* nk_context* - Pointer to `nk_context` structure.
|
||||
* nk_vec2* - Pointer to attribute to be modified.
|
||||
* nk_vec2* - New value in the form `nk_vec2(x, y)` as an instance of nk_vec2 structure.
|
||||
##### Return type: int
|
||||
* Returns true if successful.
|
||||
* Returns false if unsuccessful.
|
||||
|
||||
#### int <a id="nk-style-push-float">nk_style_push_float</a>(struct nk_context*, float*, float);
|
||||
##### Info:
|
||||
Comes under `Style Stack`. Used to temporarily modify attributes requiring precision with floating point such as rounding value for buttons.
|
||||
##### Parameters:
|
||||
* nk_context* - Pointer to `nk_context` structure.
|
||||
* float* - Pointer to variable whose value is to be changed.
|
||||
* float - new value to set.
|
||||
|
||||
#### int <a id="nk-button-label">nk_button_label</a>(struct nk_context*, const char *title);
|
||||
##### Info:
|
||||
Draws a Button with provided label.
|
||||
##### Parameters:
|
||||
* nk_context* - Pointer to `nk_context` struct.
|
||||
* *title - Pointer to string literal (Label to put on button).
|
||||
##### Return type: int
|
||||
* Returns true of Button is clicked.
|
||||
* Returns false of Button is in 'unclicked' state.
|
||||
|
||||
#### int <a id="nk-style-pop-float">nk_style_pop_float</a>(struct nk_context*);
|
||||
##### Info:
|
||||
Pops the float values modified off the `Style Stack`. Which means, returns them to original state as they were before being modified by [nk_style_push_float](#nk-style-push-float).
|
||||
##### Paramaters:
|
||||
* nk_context* - Pointer to `nk_context` struct.
|
||||
##### Return type: int
|
||||
* Returns true if successful.
|
||||
* Returns false if unsuccessful.
|
||||
|
||||
#### int <a id="nk-group-begin">nk_group_begin</a>(struct nk_context *ctx, const char *title, nk_flags flags);
|
||||
##### Info:
|
||||
Makes a group with given flags. Looks just like a window created by [nk_begin](#nk-begin) but can be created inside a window.
|
||||
##### Parameters:
|
||||
* *ctx - pointer to `nk_context` struct.
|
||||
* *title - string literal (Title of the group).
|
||||
* flags - All the required flags among available flags in `nk_flags`.
|
||||
##### Return Type: int
|
||||
* Returns false if creation unsuccessful.
|
||||
* Returns true if creation successful.
|
||||
|
||||
#### void <a id="nk-group-end">nk_group_end</a>(struct nk_context *ctx);
|
||||
##### Info:
|
||||
Marks the end of the group created by [nk_group_begin](#nk-group-begin).
|
||||
##### Parameters:
|
||||
* *ctx - pointer to `nk_context` struct.
|
||||
##### Return type: void
|
||||
|
||||
#### void <a id="nk-layout-row">nk_layout_row</a>(struct nk_context*, enum nk_layout_format, float height, int cols, const float *ratio);
|
||||
##### Info:
|
||||
Used to create custom row layout in which widget placement (including spacing) is done using ratios in floating point. Maximum ratio allowed is one. So, if there are two widgets (say buttons) need to placed in 50% available area each. Then `ratio` will be {0.5f, 0.5f}.
|
||||
##### Parameters:
|
||||
* nk_context* - pointer to `nk_context` struct.
|
||||
* nk_layout_format - format from available formats in `enum nk_layout_format` like `NK_STATIC` , `NK_DYNAMIC`.
|
||||
* height - height of the layout.
|
||||
* cols - Number of widgets(including spaces) to be used.
|
||||
* *ratio - Ratio for widget placement.
|
||||
##### Return type: void
|
||||
|
||||
#### void <a id="nk-spacing">nk_spacing</a>(struct nk_context*, int cols);
|
||||
##### Info:
|
||||
Used to create spacing (blank) of specified columns.
|
||||
##### Parameters:
|
||||
* nk_context* - pointer to `nk_context` struct.
|
||||
* cols - Number of columns for which spacing has to be true.
|
||||
##### Return type: void
|
||||
|
||||
#### int <a id="nk-checkbox-label">nk_checkbox_label</a>(struct nk_context *ctx, const char *label, int *active);
|
||||
##### Info:
|
||||
Creates a checkbox with specified label.
|
||||
##### Parameters:
|
||||
* *ctx - Pointer to `nk_context` struct.
|
||||
* * - Pointer to string literal(Label of checkbox).
|
||||
* * - Pointer to variable to store the active value. `nk_false` if unchecked, `nk_true` if checked.
|
||||
##### Return type: int
|
||||
* Returns false if unable to draw widget or old value of `*active` = new value of `*active`.
|
||||
* Returns true of old value of `*active` != new value of `*active`.
|
||||
|
||||
#### int <a id="nk-option-label">nk_option_label</a>(struct nk_context *ctx, const char *label, int active);
|
||||
##### Info:
|
||||
Draws radio button (among radio group) with specified label.
|
||||
##### Parameters:
|
||||
* *ctx - pointer to `nk_context` struct.
|
||||
* *label - Pointer to string literal (label of radio button).
|
||||
* active - Any check to specify if the radio button is active.
|
||||
##### Return type: int
|
||||
* Returns true if radio button is active.
|
||||
* Returns false if radio button is inactive.
|
||||
|
||||
#### int <a id="nk-selectable-label">nk_selectable_label</a>(struct nk_context*, const char*, nk_flags align, int *value);
|
||||
##### Info:
|
||||
Draws a selectable label. (Just like a regular [nk_label](#nk-label) but with a difference that it can be selected)
|
||||
##### Parameters:
|
||||
* nk_context* - pointer to `nk_context` struct.
|
||||
* char* - Pointer to string literal (Label to display on GUI).
|
||||
* align - required alignment flags from `nk_flags` like `NK_TEXT_LEFT`.
|
||||
* *value - Pointer to integer variable to store the value if the label is triggered or not.
|
||||
* Sets to `nk_true` if label selected.
|
||||
* Sets to `nk_false` if label is in unselected state.
|
||||
##### Return type: int
|
||||
* Returns false if unable to draw widget or old value of `*value` = new value of `*value`.
|
||||
* Returns true of old value of `*value` != new value of `*value`.
|
||||
|
||||
#### int <a id="nk-combo">nk_combo</a>(struct nk_context*, const char **items, int count, int selected, int item_height, struct nk_vec2 size);
|
||||
##### Info:
|
||||
Draws combobox with given items as array of strings.
|
||||
##### Parameters:
|
||||
* nk_context* - Pointer to `nk_context` structure.
|
||||
* **items - Array of strings of items to populate the list of combobox.
|
||||
* count - Number of items in the combobox.
|
||||
* selected - variable to store the index of selected item.
|
||||
* item_height - Height to allocate to each item in combobox.
|
||||
* size - size of combobox after expansion(when dropdown arrow is clicked). Given as [nk_vec2](#nk-vec2)(x, y).
|
||||
##### Return type: int
|
||||
* Returns the index of selected item.
|
||||
|
||||
#### void <a id="nk-label">nk_label</a>(struct nk_context *ctx, const char *str, nk_flags alignment);
|
||||
##### Info:
|
||||
Draws a plain text on Nuklear Window, Popup or group.
|
||||
##### Parameters:
|
||||
* *ctx - pointer to `nk_context` structure.
|
||||
* *str - Pointer to string literal (Text to draw).
|
||||
* alignment - required flags for text alignment from `nk_flags`, like `NK_TEXT_LEFT`.
|
||||
##### Return type: void
|
||||
|
||||
#### int <a id="nk-progress">nk_progress</a>(struct nk_context *ctx, nk_size *cur, nk_size max, int is_modifyable);
|
||||
##### Info:
|
||||
Draws a progress bar.
|
||||
##### Parameters:
|
||||
* *ctx - Poitner to `nk_context` struct.
|
||||
* *cur - Realtime value to update in progress bar.
|
||||
* max - Maximum value `*cur` can achieve (usually 100, for 100% progress).
|
||||
* is_modifyable -
|
||||
* `nk_true` if progress bar can be modified with other events like mouse click and drag.
|
||||
* `nk_false` if progress bar needs to be modified only by value of `*cur`
|
||||
##### Return type: int
|
||||
* Returns false if unable to draw widget or old value of `*cur` = new value of `*cur`.
|
||||
* Returns true of old value of `*cur` != new value of `*cur`.
|
||||
|
||||
|
||||
|
||||
|
||||
### About Nuklear Specific Structures/Variables
|
||||
#### <a id="nk-context">nk_context</a>
|
||||
##### Info:
|
||||
Contains various Variables/attributes related to current Window.
|
||||
|
||||
#### <a id="nk-vec2">nk_vec2</a>
|
||||
##### Info:
|
||||
A simple structure containing 2 variables `x` and `y`. Used for various purposes where 2 variables are required for example.. using offset for position or size of any widget/window.
|
||||
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 129 KiB After Width: | Height: | Size: 131 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 106 KiB After Width: | Height: | Size: 101 KiB |
@@ -13,7 +13,7 @@ Step 2) create a separate directory where you want to build the target.
|
||||
|
||||
Step 3) make the build system using cmake. Params in [] are optional and have
|
||||
been explained later in the document.
|
||||
~> cmake [-DWITH_FFMPEG=ON] [-DWITH_OCR=ON] [-DWITH_SHARING=ON]
|
||||
~> cmake [-DWITH_FFMPEG=ON] [-DWITH_OCR=ON]
|
||||
[-DWITH_HARDSUBX=ON] ../src/
|
||||
|
||||
Step 4) Compile the code.
|
||||
@@ -29,14 +29,8 @@ cmake -DWITH_FFMPEG=ON ../src/
|
||||
If you want to build CCExtractor with OCR you need to pass
|
||||
cmake -DWITH_OCR=ON ../src/
|
||||
|
||||
If you want to build CCExtractor with Sharing and Translating service:
|
||||
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 enabled you need to pass
|
||||
cmake -DWITH_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,92 +1,37 @@
|
||||
AUTOMAKE_OPTIONS = foreign
|
||||
|
||||
ACLOCAL_AMFLAGS = -I m4/
|
||||
|
||||
bin_PROGRAMS = ccextractor
|
||||
ccextractor_SOURCES = \
|
||||
../src/ccextractor.c \
|
||||
../src/ccextractor.h \
|
||||
../src/thirdparty/gpacmp4/avc_ext.c \
|
||||
../src/thirdparty/gpacmp4/avilib.c \
|
||||
../src/thirdparty/gpacmp4/av_parsers.c \
|
||||
../src/thirdparty/gpacmp4/base_encoding.c \
|
||||
../src/thirdparty/gpacmp4/bitstream.c \
|
||||
../src/thirdparty/gpacmp4/box_code_3gpp.c \
|
||||
../src/thirdparty/gpacmp4/box_code_adobe.c \
|
||||
../src/thirdparty/gpacmp4/box_code_apple.c \
|
||||
../src/thirdparty/gpacmp4/box_code_base.c \
|
||||
../src/thirdparty/gpacmp4/box_code_drm.c \
|
||||
../src/thirdparty/gpacmp4/box_dump.c \
|
||||
../src/thirdparty/gpacmp4/box_code_meta.c \
|
||||
../src/thirdparty/gpacmp4/box_funcs.c \
|
||||
../src/thirdparty/gpacmp4/color.c \
|
||||
../src/thirdparty/gpacmp4/configfile.c \
|
||||
../src/thirdparty/gpacmp4/data_map.c \
|
||||
../src/thirdparty/gpacmp4/desc_private.c \
|
||||
../src/thirdparty/gpacmp4/descriptors.c \
|
||||
../src/thirdparty/gpacmp4/drm_sample.c \
|
||||
../src/thirdparty/gpacmp4/error.c \
|
||||
../src/thirdparty/gpacmp4/gpac_ogg.c \
|
||||
../src/thirdparty/gpacmp4/hint_track.c \
|
||||
../src/thirdparty/gpacmp4/hinting.c \
|
||||
../src/thirdparty/gpacmp4/ipmpx_code.c \
|
||||
../src/thirdparty/gpacmp4/ipmpx_parse.c \
|
||||
../src/thirdparty/gpacmp4/isom_intern.c \
|
||||
../src/thirdparty/gpacmp4/isom_read.c \
|
||||
../src/thirdparty/gpacmp4/isom_store.c \
|
||||
../src/thirdparty/gpacmp4/isom_write.c \
|
||||
../src/thirdparty/gpacmp4/list.c \
|
||||
../src/thirdparty/gpacmp4/math.c \
|
||||
../src/thirdparty/gpacmp4/media.c \
|
||||
../src/thirdparty/gpacmp4/media_odf.c \
|
||||
../src/thirdparty/gpacmp4/meta.c \
|
||||
../src/thirdparty/gpacmp4/movie_fragments.c \
|
||||
../src/thirdparty/gpacmp4/odf_code.c \
|
||||
../src/thirdparty/gpacmp4/odf_codec.c \
|
||||
../src/thirdparty/gpacmp4/odf_command.c \
|
||||
../src/thirdparty/gpacmp4/os_config_init.c \
|
||||
../src/thirdparty/gpacmp4/os_divers.c \
|
||||
../src/thirdparty/gpacmp4/os_file.c \
|
||||
../src/thirdparty/gpacmp4/qos.c \
|
||||
../src/thirdparty/gpacmp4/sample_descs.c \
|
||||
../src/thirdparty/gpacmp4/slc.c \
|
||||
../src/thirdparty/gpacmp4/stbl_read.c \
|
||||
../src/thirdparty/gpacmp4/stbl_write.c \
|
||||
../src/thirdparty/gpacmp4/track.c \
|
||||
../src/thirdparty/gpacmp4/tx3g.c \
|
||||
../src/thirdparty/gpacmp4/url.c \
|
||||
../src/thirdparty/gpacmp4/utf.c \
|
||||
../src/thirdparty/gpacmp4/os_thread.c \
|
||||
../src/thirdparty/gpacmp4/module.c \
|
||||
../src/thirdparty/gpacmp4/os_module.c \
|
||||
../src/thirdparty/gpacmp4/xml_parser.c \
|
||||
../src/thirdparty/gpacmp4/constants.c \
|
||||
../src/thirdparty/gpacmp4/gpac/avparse.h \
|
||||
../src/thirdparty/gpacmp4/gpac/base_coding.h \
|
||||
../src/thirdparty/gpacmp4/gpac/bitstream.h \
|
||||
../src/thirdparty/gpacmp4/gpac/color.h \
|
||||
../src/thirdparty/gpacmp4/gpac/config_file.h \
|
||||
../src/thirdparty/gpacmp4/gpac/configuration.h \
|
||||
../src/thirdparty/gpacmp4/gpac/constants.h \
|
||||
../src/thirdparty/gpacmp4/gpac/events_constants.h \
|
||||
../src/thirdparty/gpacmp4/gpac/ietf.h \
|
||||
../src/thirdparty/gpacmp4/gpac/isomedia.h \
|
||||
../src/thirdparty/gpacmp4/gpac/list.h \
|
||||
../src/thirdparty/gpacmp4/gpac/maths.h \
|
||||
../src/thirdparty/gpacmp4/gpac/media_tools.h \
|
||||
../src/thirdparty/gpacmp4/gpac/mpeg4_odf.h \
|
||||
../src/thirdparty/gpacmp4/gpac/network.h \
|
||||
../src/thirdparty/gpacmp4/gpac/revision.h \
|
||||
../src/thirdparty/gpacmp4/gpac/setup.h \
|
||||
../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 \
|
||||
../src/thirdparty/gpacmp4/gpac/internal/odf_dev.h \
|
||||
../src/thirdparty/gpacmp4/gpac/internal/odf_parse_common.h \
|
||||
../src/thirdparty/gpacmp4/gpac/internal/ogg.h \
|
||||
/usr/include/gpac/avparse.h \
|
||||
/usr/include/gpac/base_coding.h \
|
||||
/usr/include/gpac/bitstream.h \
|
||||
/usr/include/gpac/color.h \
|
||||
/usr/include/gpac/config_file.h \
|
||||
/usr/include/gpac/configuration.h \
|
||||
/usr/include/gpac/constants.h \
|
||||
/usr/include/gpac/events_constants.h \
|
||||
/usr/include/gpac/ietf.h \
|
||||
/usr/include/gpac/isomedia.h \
|
||||
/usr/include/gpac/list.h \
|
||||
/usr/include/gpac/maths.h \
|
||||
/usr/include/gpac/media_tools.h \
|
||||
/usr/include/gpac/mpeg4_odf.h \
|
||||
/usr/include/gpac/network.h \
|
||||
/usr/include/gpac/revision.h \
|
||||
/usr/include/gpac/setup.h \
|
||||
/usr/include/gpac/tools.h \
|
||||
/usr/include/gpac/utf.h \
|
||||
/usr/include/gpac/version.h \
|
||||
/usr/include/gpac/iso639.h \
|
||||
/usr/include/gpac/internal/avilib.h \
|
||||
/usr/include/gpac/internal/isomedia_dev.h \
|
||||
/usr/include/gpac/internal/media_dev.h \
|
||||
/usr/include/gpac/internal/odf_dev.h \
|
||||
/usr/include/gpac/internal/odf_parse_common.h \
|
||||
/usr/include/gpac/internal/ogg.h \
|
||||
../src/thirdparty/libpng/pngstruct.h \
|
||||
../src/thirdparty/libpng/pngpriv.h \
|
||||
../src/thirdparty/libpng/pnginfo.h \
|
||||
@@ -115,9 +60,10 @@ ccextractor_SOURCES = \
|
||||
../src/lib_ccx/activity.h \
|
||||
../src/lib_ccx/asf_constants.h \
|
||||
../src/lib_ccx/avc_functions.h \
|
||||
../src/lib_ccx/bitstream.h \
|
||||
../src/lib_ccx/cc_bitstream.h \
|
||||
../src/lib_ccx/ccx_common_option.c \
|
||||
../src/lib_ccx/ccx_common_common.c \
|
||||
../src/lib_ccx/compile_info_real.h \
|
||||
../src/lib_ccx/utility.c \
|
||||
../src/lib_ccx/activity.c \
|
||||
../src/lib_ccx/asf_functions.c \
|
||||
@@ -177,10 +123,6 @@ ccextractor_SOURCES = \
|
||||
../src/lib_ccx/ccx_gxf.c \
|
||||
../src/lib_ccx/ccx_gxf.h \
|
||||
../src/lib_ccx/ccx_mp4.h \
|
||||
../src/lib_ccx/ccx_share.c \
|
||||
../src/lib_ccx/ccx_share.h \
|
||||
../src/lib_ccx/ccx_sub_entry_message.pb-c.c \
|
||||
../src/lib_ccx/ccx_sub_entry_message.pb-c.h \
|
||||
../src/lib_ccx/compile_info.h \
|
||||
../src/lib_ccx/compile_info_real.h \
|
||||
../src/lib_ccx/configuration.c \
|
||||
@@ -260,9 +202,7 @@ ccextractor_SOURCES = \
|
||||
../src/thirdparty/utf8proc/utf8proc.h \
|
||||
../src/thirdparty/lib_hash/sha2.c \
|
||||
../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 +214,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 +243,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,37 +258,55 @@ ccextractor_SOURCES = \
|
||||
../src/thirdparty/freetype/type42/type42.c \
|
||||
../src/thirdparty/freetype/winfonts/winfnt.c
|
||||
|
||||
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
|
||||
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_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_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
|
||||
|
||||
ccextractor_CPPFLAGS =-I../src/lib_ccx/ -I/usr/include/ -I../src/thirdparty/libpng/ -I../src/thirdparty/zlib/ -I../src/lib_ccx/zvbi/ -I../src/thirdparty/lib_hash/ -I../src/thirdparty -I../src/ -I../src/thirdparty/freetype/include/
|
||||
|
||||
|
||||
ccextractor_LDADD=-lm -lpthread -ldl
|
||||
ccextractor_LDADD=-lm -lpthread -ldl -lgpac
|
||||
|
||||
|
||||
if SYS_IS_LINUX
|
||||
ccextractor_CFLAGS += -O3 -s -DGPAC_CONFIG_LINUX
|
||||
ccextractor_CFLAGS += -O3 -s
|
||||
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
|
||||
|
||||
HARDSUBX_FEATURE_RUST=
|
||||
|
||||
if HARDSUBX_IS_ENABLED
|
||||
ccextractor_CFLAGS += -DENABLE_HARDSUBX
|
||||
ccextractor_CPPFLAGS+= ${libavcodec_CFLAGS}
|
||||
ccextractor_CPPFLAGS+= ${libavformat_CFLAGS}
|
||||
ccextractor_CPPFLAGS+= ${libavfilter_CFLAGS}
|
||||
ccextractor_CPPFLAGS+= ${libavutil_CFALGS}
|
||||
ccextractor_CPPFLAGS+= ${libswscale_CFLAGS}
|
||||
# HARDSUBX requires tesseract/leptonica for OCR (same as OCR feature)
|
||||
ccextractor_CPPFLAGS+= ${tesseract_CFLAGS}
|
||||
ccextractor_CPPFLAGS+= ${lept_CFLAGS}
|
||||
AV_LIB = ${libavcodec_LIBS}
|
||||
AV_LIB += ${libavformat_LIBS}
|
||||
AV_LIB += ${libavfilter_LIBS}
|
||||
AV_LIB += ${libavutil_LIBS}
|
||||
AV_LIB += ${libswscale_LIBS}
|
||||
ccextractor_LDADD += $(AV_LIB)
|
||||
# HARDSUBX requires tesseract/leptonica libs for OCR
|
||||
ccextractor_LDADD += ${tesseract_LIBS}
|
||||
ccextractor_LDADD += ${lept_LIBS}
|
||||
HARDSUBX_FEATURE_RUST += --features "hardsubx_ocr"
|
||||
endif
|
||||
|
||||
if OCR_IS_ENABLED
|
||||
@@ -375,64 +333,17 @@ ccextractor_LDADD += $(TESS_LIB)
|
||||
ccextractor_LDADD += $(LEPT_LIB)
|
||||
endif
|
||||
|
||||
EXTRA_DIST = ../src/thirdparty/gpacmp4/gpac/sync_layer.h ../src/lib_ccx/ccfont2.xbm ../src/thirdparty/utf8proc/utf8proc_data.c fonts/ icon/
|
||||
ccextractor_LDADD += ./rust/@RUST_TARGET_SUBDIR@/libccx_rust.a
|
||||
|
||||
#For GUI
|
||||
if BUILD_WITH_GUI
|
||||
bin_PROGRAMS += ccextractorGUI
|
||||
|
||||
ccextractorGUI_SOURCES = \
|
||||
../src/GUI/ccextractorGUI.c \
|
||||
../src/GUI/ccextractorGUI.h \
|
||||
../src/GUI/activity.c \
|
||||
../src/GUI/activity.h \
|
||||
../src/GUI/terminal.c \
|
||||
../src/GUI/preview.c \
|
||||
../src/GUI/preview.h \
|
||||
../src/GUI/ccx_cli_thread.c \
|
||||
../src/GUI/ccx_cli_thread.h \
|
||||
../src/GUI/command_builder.c \
|
||||
../src/GUI/command_builder.h \
|
||||
../src/GUI/save_load_data.c \
|
||||
../src/GUI/save_load_data.h \
|
||||
../src/GUI/file_browser.c \
|
||||
../src/GUI/file_browser.h \
|
||||
../src/GUI/popups.c \
|
||||
../src/GUI/popups.h \
|
||||
../src/GUI/tabs.c \
|
||||
../src/GUI/tabs.h \
|
||||
../src/GUI/stb_image.h \
|
||||
../src/GUI/nuklear_lib/nuklear.h \
|
||||
../src/GUI/nuklear_lib/nuklear_glfw_gl2.h
|
||||
|
||||
ccextractorGUI_CFLAGS = -std=gnu99
|
||||
|
||||
|
||||
ccextractorGUI_LDADD = ${glfw3_LIBS}
|
||||
|
||||
|
||||
if SYS_IS_LINUX
|
||||
ccextractorGUI_CFLAGS += -s -O3 -DUNIX
|
||||
ccextractorGUI_CFLAGS += ${glew_CFLAGS}
|
||||
ccextractorGUI_LDADD += ${glew_LIBS}
|
||||
ccextractorGUI_LDADD += -lX11 -lXinerama -lXcursor -lXi -lXrandr -lXxf86vm -lm -ldl -lpthread
|
||||
if DEBUG_RELEASE
|
||||
CARGO_RELEASE_ARGS=
|
||||
else
|
||||
CARGO_RELEASE_ARGS=--release
|
||||
endif
|
||||
|
||||
if SYS_IS_MAC
|
||||
ccextractorGUI_CFLAGS += -O3 -DUNIX
|
||||
ccextractorGUI_CFLAGS += ${glew_CFLAGS}
|
||||
ccextractorGUI_LDADD += ${glew_LIBS}
|
||||
ccextractorGUI_LDFLAGS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo
|
||||
ccextractorGUI_LDADD += -lglfw -lm -L/usr/local/lib -lpthread
|
||||
endif
|
||||
./rust/@RUST_TARGET_SUBDIR@/libccx_rust.a:
|
||||
cd ../src/rust && \
|
||||
CARGO_TARGET_DIR=../../linux/rust $(CARGO) build $(HARDSUBX_FEATURE_RUST) $(CARGO_RELEASE_ARGS);
|
||||
|
||||
if HARDSUBX_IS_ENABLED
|
||||
if OCR_IS_ENABLED
|
||||
ccextractorGUI_CFLAGS += -DENABLE_OCR
|
||||
endif
|
||||
endif
|
||||
|
||||
EXTRA_DIST += ../icon/ ../fonts/
|
||||
|
||||
endif
|
||||
EXTRA_DIST = /usr/include/gpac/sync_layer.h ../src/lib_ccx/ccfont2.xbm ../src/thirdparty/utf8proc/utf8proc_data.c fonts/ icon/
|
||||
|
||||
|
||||
68
linux/build
68
linux/build
@@ -1,17 +1,47 @@
|
||||
#!/usr/bin/env bash
|
||||
BLD_FLAGS="$BLD_FLAGS -std=gnu99 -Wno-write-strings -Wno-pointer-sign -DGPAC_CONFIG_LINUX -D_FILE_OFFSET_BITS=64 -DVERSION_FILE_PRESENT -DENABLE_OCR -DFT2_BUILD_LIBRARY -DGPAC_DISABLE_VTT -DGPAC_DISABLE_OD_DUMP -DGPAC_DISABLE_REMOTERY -DNO_GZIP -DGPAC_HAVE_CONFIG_H"
|
||||
|
||||
RUST_LIB="rust/release/libccx_rust.a"
|
||||
RUST_PROFILE="--release"
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
-debug)
|
||||
DEBUG=true
|
||||
BLD_FLAGS="$BLD_FLAGS -g -fsanitize=address"
|
||||
RUST_PROFILE=""
|
||||
RUST_LIB="rust/debug/libccx_rust.a"
|
||||
shift
|
||||
;;
|
||||
-hardsubx)
|
||||
HARDSUBX=true
|
||||
# Allow overriding FFmpeg version via environment variable
|
||||
if [ -n "$FFMPEG_VERSION" ]; then
|
||||
RUST_FEATURES="--features hardsubx_ocr,$FFMPEG_VERSION"
|
||||
else
|
||||
RUST_FEATURES="--features hardsubx_ocr"
|
||||
fi
|
||||
BLD_FLAGS="$BLD_FLAGS -DENABLE_HARDSUBX"
|
||||
BLD_LINKER="$BLD_LINKER -lswscale -lavutil -pthread -lavformat -lavcodec -lavfilter -lxcb-shm -lxcb -lX11 -llzma -lswresample"
|
||||
shift
|
||||
;;
|
||||
-*)
|
||||
echo "Unknown option $1"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
BLD_FLAGS="$BLD_FLAGS -std=gnu99 -Wno-write-strings -Wno-pointer-sign -D_FILE_OFFSET_BITS=64 -DVERSION_FILE_PRESENT -DENABLE_OCR -DFT2_BUILD_LIBRARY -DGPAC_DISABLE_VTT -DGPAC_DISABLE_OD_DUMP -DGPAC_DISABLE_REMOTERY -DNO_GZIP"
|
||||
bit_os=$(getconf LONG_BIT)
|
||||
if [ "$bit_os"=="64" ]
|
||||
if [ "$bit_os" == "64" ]
|
||||
then
|
||||
BLD_FLAGS="$BLD_FLAGS -DGPAC_64_BITS"
|
||||
fi
|
||||
BLD_INCLUDE="-I../src -I /usr/include/leptonica/ -I /usr/include/tesseract/ -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/thirdparty/freetype/include"
|
||||
BLD_INCLUDE="-I../src -I /usr/include/leptonica/ -I /usr/include/tesseract/ -I../src/lib_ccx/ -I /usr/include/gpac/ -I../src/thirdparty/libpng -I../src/thirdparty/zlib -I../src/lib_ccx/zvbi -I../src/thirdparty/lib_hash -I../src/thirdparty -I../src/thirdparty/freetype/include"
|
||||
SRC_LIBPNG="$(find ../src/thirdparty/libpng/ -name '*.c')"
|
||||
SRC_ZLIB="$(find ../src/thirdparty/zlib/ -name '*.c')"
|
||||
SRC_CCX="$(find ../src/lib_ccx/ -name '*.c')"
|
||||
SRC_GPAC="$(find ../src/thirdparty/gpacmp4/ -name '*.c')"
|
||||
SRC_GPAC="$(find /usr/include/gpac/ -name '*.c' 2>/dev/null)"
|
||||
SRC_HASH="$(find ../src/thirdparty/lib_hash/ -name '*.c')"
|
||||
SRC_PROTOBUF="$(find ../src/thirdparty/protobuf-c/ -name '*.c')"
|
||||
SRC_UTF8PROC="../src/thirdparty/utf8proc/utf8proc.c"
|
||||
SRC_FREETYPE="../src/thirdparty/freetype/autofit/autofit.c
|
||||
../src/thirdparty/freetype/base/ftbase.c
|
||||
@@ -54,13 +84,37 @@ SRC_FREETYPE="../src/thirdparty/freetype/autofit/autofit.c
|
||||
../src/thirdparty/freetype/type1/type1.c
|
||||
../src/thirdparty/freetype/type42/type42.c
|
||||
../src/thirdparty/freetype/winfonts/winfnt.c"
|
||||
BLD_SOURCES="../src/ccextractor.c $SRC_CCX $SRC_GPAC $SRC_ZLIB $SRC_LIBPNG $SRC_HASH $SRC_PROTOBUF $SRC_UTF8PROC $SRC_FREETYPE"
|
||||
BLD_LINKER="$BLD_LINKER -lm -zmuldefs -l tesseract -l lept -lpthread -ldl"
|
||||
BLD_SOURCES="../src/ccextractor.c $SRC_CCX $SRC_GPAC $SRC_ZLIB $SRC_LIBPNG $SRC_HASH $SRC_UTF8PROC $SRC_FREETYPE"
|
||||
BLD_LINKER="$BLD_LINKER -lm -zmuldefs -l tesseract -l leptonica -lpthread -ldl -lgpac"
|
||||
|
||||
echo "Running pre-build script..."
|
||||
./pre-build.sh
|
||||
echo "Trying to compile..."
|
||||
|
||||
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.87.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 $RUST_PROFILE $RUST_FEATURES) || { echo "Failed. " ; exit 1; }
|
||||
|
||||
cp $RUST_LIB ./libccx_rust.a
|
||||
|
||||
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,109 +0,0 @@
|
||||
#!/usr/bin/env sh -ex
|
||||
|
||||
####################################################################
|
||||
# setup by tracey apr 2012
|
||||
# updated version dec 2016
|
||||
# see: http://www.ccextractor.org/doku.php
|
||||
####################################################################
|
||||
|
||||
|
||||
# build it static!
|
||||
# simplest way is with linux alpine
|
||||
# hop onto box with docker on it and cd to dir of the file you are staring at
|
||||
# You will get a static-compiled binary and english language library file in the end.
|
||||
if [ ! -e /tmp/cc/ccextractor-README.txt ]; then
|
||||
rm -rf /tmp/cc;
|
||||
mkdir -p -m777 /tmp/cc;
|
||||
mkdir -p -m777 ../lib/tessdata/;
|
||||
cp ccextractor-README.txt /tmp/cc/;
|
||||
sudo docker run -v /tmp/cc:/tmp/cc --rm -it alpine:latest /tmp/cc/ccextractor-README.txt;
|
||||
# NOTE: _AFTER_ testing/validating, you can promote it from "ccextractor.next" to "ccextractor"... ;-)
|
||||
cp /tmp/cc/*traineddata ../lib/tessdata/;
|
||||
chmod go-w ../lib/tessdata/;
|
||||
exit 0;
|
||||
fi
|
||||
|
||||
# NOW we are inside docker container...
|
||||
cd /tmp/cc;
|
||||
|
||||
|
||||
# we want tesseract (for OCR)
|
||||
echo '
|
||||
http://dl-cdn.alpinelinux.org/alpine/v3.5/main
|
||||
http://dl-cdn.alpinelinux.org/alpine/v3.5/community
|
||||
' >| /etc/apk/repositories;
|
||||
apk update; apk upgrade;
|
||||
|
||||
apk add --update bash zsh alpine-sdk perl;
|
||||
|
||||
# (needed by various static builds below)
|
||||
# Even though we're going to (re)builid tesseract from source statically, get its dependencies setup by
|
||||
# installing it now, too.
|
||||
apk add autoconf automake libtool tesseract-ocr-dev;
|
||||
|
||||
|
||||
# Now comes the not-so-fun parts... Many packages _only_ provide .so files in their distros -- not the .a
|
||||
# needed files for building something with it statically. Step through them now...
|
||||
|
||||
|
||||
# libgif
|
||||
wget https://sourceforge.net/projects/giflib/files/giflib-5.1.4.tar.gz;
|
||||
zcat giflib*tar.gz | tar xf -;
|
||||
cd giflib*/;
|
||||
./configure --disable-shared --enable-static; make; make install;
|
||||
hash -r;
|
||||
cd -;
|
||||
|
||||
|
||||
# libwebp
|
||||
git clone https://github.com/webmproject/libwebp;
|
||||
cd libwebp;
|
||||
./autogen.sh;
|
||||
./configure --disable-shared --enable-static; make; make install;
|
||||
cd -;
|
||||
|
||||
|
||||
# leptonica
|
||||
wget http://www.leptonica.org/source/leptonica-1.73.tar.gz;
|
||||
zcat leptonica*tar.gz | tar xf -;
|
||||
cd leptonica*/;
|
||||
./configure --disable-shared --enable-static; make; make install;
|
||||
hash -r;
|
||||
cd -;
|
||||
|
||||
|
||||
# tesseract
|
||||
git clone https://github.com/tesseract-ocr/tesseract;
|
||||
cd tesseract;
|
||||
./autogen.sh;
|
||||
./configure --disable-shared --enable-static; make; make install;
|
||||
cd -;
|
||||
|
||||
|
||||
# ccextractor -- build static
|
||||
git clone https://github.com/CCExtractor/ccextractor;
|
||||
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;
|
||||
set +e; # this _will_ FAIL at the end..
|
||||
make ENABLE_OCR=yes;
|
||||
set -e;
|
||||
# I confess hand-compiling (cherrypicking which .a to use when there are 2, etc.) is fragile...
|
||||
# But it was the _only_ way I could get a fully static build after hours of thrashing...
|
||||
gcc -Wno-write-strings -Wno-pointer-sign -D_FILE_OFFSET_BITS=64 -DVERSION_FILE_PRESENT -O3 -std=gnu99 -s -DGPAC_CONFIG_LINUX -DENABLE_OCR -DPNG_NO_CONFIG_H -I/usr/local/include/tesseract -I/usr/local/include/leptonica objs/*.o -o ccextractor \
|
||||
--static -lm \
|
||||
/usr/local/lib/libtesseract.a \
|
||||
/usr/local/lib/liblept.a \
|
||||
/usr/local/lib/libgif.a \
|
||||
/usr/local/lib/libwebp.a \
|
||||
/usr/lib/libjpeg.a \
|
||||
/usr/lib/libtiff.a \
|
||||
/usr/lib/libgomp.a \
|
||||
-lstdc++;
|
||||
|
||||
cp ccextractor /tmp/cc/ccextractor.next;
|
||||
cd -;
|
||||
|
||||
# get english lang trained data
|
||||
wget https://github.com/tesseract-ocr/tessdata/raw/master/eng.traineddata;
|
||||
230
linux/build_appimage.sh
Executable file
230
linux/build_appimage.sh
Executable file
@@ -0,0 +1,230 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# CCExtractor AppImage Build Script
|
||||
#
|
||||
# Build variants via BUILD_TYPE environment variable:
|
||||
# - minimal: Basic CCExtractor without OCR (smallest size)
|
||||
# - ocr: CCExtractor with OCR support (default)
|
||||
# - hardsubx: CCExtractor with burned-in subtitle extraction (requires FFmpeg)
|
||||
#
|
||||
# Usage:
|
||||
# ./build_appimage.sh # Builds 'ocr' variant (default)
|
||||
# BUILD_TYPE=minimal ./build_appimage.sh
|
||||
# BUILD_TYPE=hardsubx ./build_appimage.sh
|
||||
#
|
||||
# Requirements:
|
||||
# - CMake, GCC, pkg-config, Rust toolchain
|
||||
# - For OCR: tesseract-ocr, libtesseract-dev, libleptonica-dev
|
||||
# - For HardSubX: libavcodec-dev, libavformat-dev, libswscale-dev, etc.
|
||||
# - wget for downloading linuxdeploy
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
# Build type: minimal, ocr, hardsubx (default: ocr)
|
||||
BUILD_TYPE="${BUILD_TYPE:-ocr}"
|
||||
|
||||
echo "=========================================="
|
||||
echo "CCExtractor AppImage Builder"
|
||||
echo "Build type: $BUILD_TYPE"
|
||||
echo "=========================================="
|
||||
|
||||
# Validate build type
|
||||
case "$BUILD_TYPE" in
|
||||
minimal|ocr|hardsubx)
|
||||
;;
|
||||
*)
|
||||
echo "Error: Invalid BUILD_TYPE '$BUILD_TYPE'"
|
||||
echo "Valid options: minimal, ocr, hardsubx"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# Store paths
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
REPO_ROOT="$(dirname "$SCRIPT_DIR")"
|
||||
BUILD_DIR="$SCRIPT_DIR/appimage_build"
|
||||
|
||||
# Clean up function
|
||||
cleanup() {
|
||||
if [ -d "$BUILD_DIR" ]; then
|
||||
echo "Cleaning up build directory..."
|
||||
rm -rf "$BUILD_DIR"
|
||||
fi
|
||||
}
|
||||
|
||||
# Cleanup on exit (comment out for debugging)
|
||||
trap cleanup EXIT
|
||||
|
||||
# Create fresh build directory
|
||||
rm -rf "$BUILD_DIR" 2>/dev/null || true
|
||||
mkdir -p "$BUILD_DIR"
|
||||
|
||||
cd "$BUILD_DIR"
|
||||
|
||||
# Determine CMake options based on build type
|
||||
CMAKE_OPTIONS=""
|
||||
case "$BUILD_TYPE" in
|
||||
minimal)
|
||||
CMAKE_OPTIONS=""
|
||||
;;
|
||||
ocr)
|
||||
CMAKE_OPTIONS="-DWITH_OCR=ON"
|
||||
;;
|
||||
hardsubx)
|
||||
CMAKE_OPTIONS="-DWITH_OCR=ON -DWITH_HARDSUBX=ON -DWITH_FFMPEG=ON"
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "CMake options: $CMAKE_OPTIONS"
|
||||
|
||||
# Configure with CMake
|
||||
echo "Configuring with CMake..."
|
||||
cmake $CMAKE_OPTIONS "$REPO_ROOT/src"
|
||||
|
||||
# Build
|
||||
echo "Building CCExtractor..."
|
||||
make -j$(nproc)
|
||||
|
||||
# Verify binary was built
|
||||
if [ ! -f "$BUILD_DIR/ccextractor" ]; then
|
||||
echo "Error: ccextractor binary not found after build"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Build successful!"
|
||||
"$BUILD_DIR/ccextractor" --version
|
||||
|
||||
# Download linuxdeploy
|
||||
echo "Downloading linuxdeploy..."
|
||||
LINUXDEPLOY_URL="https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage"
|
||||
wget -q --show-progress "$LINUXDEPLOY_URL" -O linuxdeploy-x86_64.AppImage
|
||||
chmod +x linuxdeploy-x86_64.AppImage
|
||||
|
||||
# Create AppDir structure
|
||||
echo "Creating AppDir structure..."
|
||||
mkdir -p AppDir/usr/bin
|
||||
mkdir -p AppDir/usr/share/icons/hicolor/256x256/apps
|
||||
mkdir -p AppDir/usr/share/applications
|
||||
mkdir -p AppDir/usr/share/tessdata
|
||||
|
||||
# Copy binary
|
||||
cp "$BUILD_DIR/ccextractor" AppDir/usr/bin/
|
||||
|
||||
# Download icon
|
||||
echo "Downloading icon..."
|
||||
PNG_URL="https://ccextractor.org/images/ccextractor.png"
|
||||
if wget -q "$PNG_URL" -O AppDir/usr/share/icons/hicolor/256x256/apps/ccextractor.png 2>/dev/null; then
|
||||
echo "Icon downloaded successfully"
|
||||
else
|
||||
# Create a simple placeholder icon if download fails
|
||||
echo "Warning: Could not download icon, creating placeholder"
|
||||
convert -size 256x256 xc:navy -fill white -gravity center -pointsize 40 -annotate 0 "CCX" \
|
||||
AppDir/usr/share/icons/hicolor/256x256/apps/ccextractor.png 2>/dev/null || \
|
||||
echo "P3 256 256 255" > AppDir/usr/share/icons/hicolor/256x256/apps/ccextractor.ppm
|
||||
fi
|
||||
|
||||
# Create desktop file
|
||||
cat > AppDir/usr/share/applications/ccextractor.desktop << 'EOF'
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Name=CCExtractor
|
||||
Comment=Extract closed captions and subtitles from video files
|
||||
Exec=ccextractor
|
||||
Icon=ccextractor
|
||||
Categories=AudioVideo;Video;
|
||||
Terminal=true
|
||||
NoDisplay=true
|
||||
EOF
|
||||
|
||||
# Copy desktop file to AppDir root (required by linuxdeploy)
|
||||
cp AppDir/usr/share/applications/ccextractor.desktop AppDir/
|
||||
|
||||
# Copy icon to AppDir root
|
||||
cp AppDir/usr/share/icons/hicolor/256x256/apps/ccextractor.png AppDir/ 2>/dev/null || true
|
||||
|
||||
# For OCR builds, bundle tessdata
|
||||
if [ "$BUILD_TYPE" = "ocr" ] || [ "$BUILD_TYPE" = "hardsubx" ]; then
|
||||
echo "Bundling tessdata for OCR support..."
|
||||
|
||||
# Try to find system tessdata
|
||||
TESSDATA_PATHS=(
|
||||
"/usr/share/tesseract-ocr/5/tessdata"
|
||||
"/usr/share/tesseract-ocr/4.00/tessdata"
|
||||
"/usr/share/tessdata"
|
||||
"/usr/local/share/tessdata"
|
||||
)
|
||||
|
||||
TESSDATA_SRC=""
|
||||
for path in "${TESSDATA_PATHS[@]}"; do
|
||||
if [ -d "$path" ] && [ -f "$path/eng.traineddata" ]; then
|
||||
TESSDATA_SRC="$path"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -n "$TESSDATA_SRC" ]; then
|
||||
echo "Found tessdata at: $TESSDATA_SRC"
|
||||
# Copy English language data (most common)
|
||||
cp "$TESSDATA_SRC/eng.traineddata" AppDir/usr/share/tessdata/ 2>/dev/null || true
|
||||
# Copy OSD (orientation and script detection) if available
|
||||
cp "$TESSDATA_SRC/osd.traineddata" AppDir/usr/share/tessdata/ 2>/dev/null || true
|
||||
else
|
||||
echo "Warning: tessdata not found, downloading English language data..."
|
||||
wget -q "https://github.com/tesseract-ocr/tessdata/raw/main/eng.traineddata" \
|
||||
-O AppDir/usr/share/tessdata/eng.traineddata || true
|
||||
fi
|
||||
|
||||
# Create wrapper script that sets TESSDATA_PREFIX
|
||||
mv AppDir/usr/bin/ccextractor AppDir/usr/bin/ccextractor.bin
|
||||
cat > AppDir/usr/bin/ccextractor << 'WRAPPER'
|
||||
#!/bin/bash
|
||||
SELF_DIR="$(dirname "$(readlink -f "$0")")"
|
||||
export TESSDATA_PREFIX="${SELF_DIR}/../share/tessdata"
|
||||
exec "${SELF_DIR}/ccextractor.bin" "$@"
|
||||
WRAPPER
|
||||
chmod +x AppDir/usr/bin/ccextractor
|
||||
fi
|
||||
|
||||
# Determine output name based on build type
|
||||
ARCH="x86_64"
|
||||
case "$BUILD_TYPE" in
|
||||
minimal)
|
||||
OUTPUT_NAME="ccextractor-minimal-${ARCH}.AppImage"
|
||||
;;
|
||||
ocr)
|
||||
OUTPUT_NAME="ccextractor-${ARCH}.AppImage"
|
||||
;;
|
||||
hardsubx)
|
||||
OUTPUT_NAME="ccextractor-hardsubx-${ARCH}.AppImage"
|
||||
;;
|
||||
esac
|
||||
|
||||
# Build AppImage
|
||||
echo "Building AppImage..."
|
||||
export OUTPUT="$OUTPUT_NAME"
|
||||
|
||||
# Determine which executable to pass to linuxdeploy
|
||||
# For OCR builds, we have a wrapper script, so pass the actual binary (.bin)
|
||||
if [ -f "AppDir/usr/bin/ccextractor.bin" ]; then
|
||||
LINUXDEPLOY_EXEC="AppDir/usr/bin/ccextractor.bin"
|
||||
else
|
||||
LINUXDEPLOY_EXEC="AppDir/usr/bin/ccextractor"
|
||||
fi
|
||||
|
||||
./linuxdeploy-x86_64.AppImage \
|
||||
--appdir=AppDir \
|
||||
--executable="$LINUXDEPLOY_EXEC" \
|
||||
--desktop-file=AppDir/ccextractor.desktop \
|
||||
--icon-file=AppDir/ccextractor.png \
|
||||
--output=appimage
|
||||
|
||||
# Move to output directory
|
||||
mv "$OUTPUT_NAME" "$SCRIPT_DIR/"
|
||||
|
||||
echo "=========================================="
|
||||
echo "AppImage built successfully!"
|
||||
echo "Output: $SCRIPT_DIR/$OUTPUT_NAME"
|
||||
echo ""
|
||||
echo "Test with: $SCRIPT_DIR/$OUTPUT_NAME --version"
|
||||
echo "=========================================="
|
||||
@@ -1,4 +1,3 @@
|
||||
#!/usr/bin/env bash
|
||||
export BLD_FLAGS="-DENABLE_HARDSUBX"
|
||||
export BLD_LINKER="-lswscale -lavutil -pthread -lavformat -lavcodec -lxcb-shm -lxcb -lX11 -llzma -lswresample"
|
||||
./build
|
||||
|
||||
./build -hardsubx
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
#!/usr/bin/env bash
|
||||
export BLD_FLAGS="-g"
|
||||
./build
|
||||
|
||||
./build -debug
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
# -*- Autoconf -*-
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_PREREQ([2.69])
|
||||
AC_INIT([CCExtractor], [0.92], [carlos@ccextractor.org])
|
||||
AC_PREREQ([2.71])
|
||||
AC_INIT([CCExtractor], [0.96], [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
|
||||
@@ -15,7 +15,7 @@ AC_PROG_MAKE_SET
|
||||
|
||||
#Checks for "pkg-config" utility
|
||||
AC_MSG_CHECKING([pkg-config m4 macros])
|
||||
if test m4_ifdef([PKG_CHECK_MODULES], [yes], [no]) == yes; then
|
||||
if test m4_ifdef([PKG_CHECK_MODULES], [yes], [no]) = yes; then
|
||||
AC_MSG_RESULT([yes]);
|
||||
else
|
||||
AC_MSG_RESULT([no]);
|
||||
@@ -25,13 +25,18 @@ fi
|
||||
|
||||
# Checks for libraries.
|
||||
AC_CHECK_LIB([m], [sin], [], [AC_MSG_ERROR(Math library not installed. Install it before proceeding.)])
|
||||
AC_CHECK_LIB([lept], [getLeptonicaVersion], [HAS_LEPT=1 && PKG_CHECK_MODULES([lept], [lept])], [HAS_LEPT=0])
|
||||
AC_CHECK_LIB([leptonica], [getLeptonicaVersion], [HAS_LEPT=1 && PKG_CHECK_MODULES([lept], [lept])], [HAS_LEPT=0])
|
||||
AC_CHECK_LIB([tesseract], [TessVersion], [HAS_TESSERACT=1 && PKG_CHECK_MODULES([tesseract], [tesseract])], [HAS_TESSERACT=0])
|
||||
AC_CHECK_LIB([avcodec], [avcodec_version], [HAS_AVCODEC=1 && PKG_CHECK_MODULES([libavcodec], [libavcodec])], [HAS_AVCODEC=0])
|
||||
AC_CHECK_LIB([avformat], [avformat_version], [HAS_AVFORMAT=1 && PKG_CHECK_MODULES([libavformat], [libavformat])], [HAS_AVFORMAT=0])
|
||||
AC_CHECK_LIB([avutil], [avutil_version], [HAS_AVUTIL=1 && PKG_CHECK_MODULES([libavutil], [libavutil])], [HAS_AVUTIL=0])
|
||||
AC_CHECK_LIB([swscale], [swscale_version], [HAS_SWSCALE=1 && PKG_CHECK_MODULES([libswscale], [libswscale])], [HAS_SWSCALE=0])
|
||||
|
||||
# Check for GPAC library (required for MP4 support)
|
||||
PKG_CHECK_MODULES([gpac], [gpac], [HAS_GPAC=1], [HAS_GPAC=0])
|
||||
AS_IF([test $HAS_GPAC -eq 0],
|
||||
[AC_MSG_ERROR([GPAC library not found. Install gpac-devel (Fedora/RHEL), libgpac-dev (Debian/Ubuntu), or gpac (Arch) before proceeding.])])
|
||||
|
||||
# Checks for header files.
|
||||
AC_CHECK_HEADERS([arpa/inet.h fcntl.h float.h inttypes.h limits.h locale.h malloc.h netdb.h netinet/in.h stddef.h stdint.h stdlib.h string.h sys/socket.h sys/time.h sys/timeb.h termios.h unistd.h wchar.h])
|
||||
|
||||
@@ -63,7 +68,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 +76,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,18 +84,57 @@ 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 ;;
|
||||
*) AC_MSG_ERROR([bad value ${enableval} for --enable-ffmpeg]) ;;
|
||||
esac],[ffmpeg=false])
|
||||
|
||||
AC_ARG_WITH([gui],
|
||||
AC_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])
|
||||
|
||||
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.87.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 avoild failure while building
|
||||
AS_IF([ test x$hardsubx = xtrue && test $HAS_AVCODEC -gt 0 ], [AC_MSG_NOTICE(avcodec library found)])
|
||||
@@ -101,21 +145,21 @@ AS_IF([ test x$hardsubx = xtrue && test $HAS_AVUTIL -gt 0 ], [AC_MSG_NOTICE(avut
|
||||
AS_IF([ test x$hardsubx = xtrue && test ! $HAS_AVUTIL -gt 0 ], [AC_MSG_ERROR(avutil library not found. Please install the avutil library before proceeding)])
|
||||
AS_IF([ test x$hardsubx = xtrue && test $HAS_SWSCALE -gt 0 ], [AC_MSG_NOTICE(swscale library found)])
|
||||
AS_IF([ test x$hardsubx = xtrue && test ! $HAS_SWSCALE -gt 0 ], [AC_MSG_ERROR(swscale library not found. Please install the swscale library before proceeding)])
|
||||
AS_IF([ (test x$ocr = xtrue || test x$hardsubx = xtrue) && test $HAS_TESSERACT -gt 0 ], [TESS_VERSION=`tesseract --version 2>&1 | grep tesseract` && AC_MSG_NOTICE(tesseract library found... $TESS_VERSION)])
|
||||
AS_IF([ (test x$ocr = xtrue || test x$hardsubx = xtrue) && test $HAS_TESSERACT -gt 0 ], [TESS_VERSION=$(tesseract --version 2>&1 | grep tesseract) && AC_MSG_NOTICE(tesseract library found... $TESS_VERSION)])
|
||||
AS_IF([ (test x$ocr = xtrue || test x$hardsubx = xtrue) && test ! $HAS_TESSERACT -gt 0 ], [AC_MSG_ERROR(tesserect library not found. Please install the tesseract library before proceeding)])
|
||||
AS_IF([ (test x$ocr = xtrue || test x$hardsubx = xtrue) && test $HAS_LEPT -gt 0 ], [LEPT_VERSION=`tesseract --version 2>&1 | grep leptonica` && AC_MSG_NOTICE(leptonica library found... $LEPT_VERSION)])
|
||||
AS_IF([ (test x$ocr = xtrue || test x$hardsubx = xtrue) && test $HAS_LEPT -gt 0 ], [LEPT_VERSION=$(tesseract --version 2>&1 | grep leptonica) && AC_MSG_NOTICE(leptonica library found... $LEPT_VERSION)])
|
||||
AS_IF([ (test x$ocr = xtrue || test x$hardsubx = xtrue) && test ! $HAS_LEPT -gt 0 ], [AC_MSG_ERROR(leptonica library not found. Please install the leptonica library before proceeding)])
|
||||
|
||||
#AM_CONDITIONAL(s) for setting values to enable/disable flags in Makefile.am
|
||||
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_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(BUILD_WITH_GUI, [test "x$with_gui" = "xyes"])
|
||||
AM_CONDITIONAL(SYS_IS_64_BIT,[test `getconf LONG_BIT` = "64"])
|
||||
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(SYS_IS_64_BIT,[test $(getconf LONG_BIT) = "64"])
|
||||
|
||||
AC_CONFIG_FILES([Makefile])
|
||||
AC_OUTPUT
|
||||
|
||||
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,12 +1,10 @@
|
||||
#!/usr/bin/env bash
|
||||
SRC_LIBPNG="$(find ../src/thirdparty/libpng/ -name '*.c')"
|
||||
SRC_ZLIB="$(find ../sr/thirdpartyc/zlib/ -name '*.c')"
|
||||
SRC_ZVBI="$(find ../sr/thirdpartyc/zvbi/ -name '*.c')"
|
||||
SRC_ZLIB="$(find ../src/thirdparty/zlib/ -name '*.c')"
|
||||
SRC_ZVBI="$(find ../src/thirdparty/zvbi/ -name '*.c')"
|
||||
SRC_CCX="$(find ../src/lib_ccx/ -name '*.c')"
|
||||
SRC_GPAC="$(find ../sr/thirdpartyc/gpacmp4/ -name '*.c')"
|
||||
SRC_HASH="$(find ../sr/thirdpartyc/lib_hash/ -name '*.c')"
|
||||
SRC_PROTOBUF="$(find ../src/thirdparty/protobuf-c/ -name '*.c')"
|
||||
SRC_HASH="$(find ../src/thirdparty/lib_hash/ -name '*.c')"
|
||||
SRC_UTF8PROC="../src/utf8proc/utf8proc.c"
|
||||
BLD_SOURCES="../src/ccextractor.c ../src/ccextractorapi_wrap.c $SRC_CCX $SRC_GPAC $SRC_ZLIB $SRC_ZVBI $SRC_LIBPNG $SRC_HASH $SRC_PROTOBUF $SRC_UTF8PROC"
|
||||
BLD_SOURCES="../src/ccextractor.c ../src/ccextractorapi_wrap.c $SRC_CCX $SRC_ZLIB $SRC_ZVBI $SRC_LIBPNG $SRC_HASH $SRC_UTF8PROC"
|
||||
|
||||
python setup.py $BLD_SOURCES
|
||||
|
||||
211
mac/Makefile.am
211
mac/Makefile.am
@@ -1,91 +1,10 @@
|
||||
AUTOMAKE_OPTIONS = foreign
|
||||
|
||||
ACLOCAL_AMFLAGS = -I m4/
|
||||
|
||||
bin_PROGRAMS = ccextractor
|
||||
ccextractor_SOURCES = \
|
||||
../src/ccextractor.c \
|
||||
../src/ccextractor.h \
|
||||
../src/thirdparty/gpacmp4/avc_ext.c \
|
||||
../src/thirdparty/gpacmp4/avilib.c \
|
||||
../src/thirdparty/gpacmp4/av_parsers.c \
|
||||
../src/thirdparty/gpacmp4/base_encoding.c \
|
||||
../src/thirdparty/gpacmp4/bitstream.c \
|
||||
../src/thirdparty/gpacmp4/box_code_3gpp.c \
|
||||
../src/thirdparty/gpacmp4/box_code_adobe.c \
|
||||
../src/thirdparty/gpacmp4/box_code_apple.c \
|
||||
../src/thirdparty/gpacmp4/box_code_base.c \
|
||||
../src/thirdparty/gpacmp4/box_code_drm.c \
|
||||
../src/thirdparty/gpacmp4/box_dump.c \
|
||||
../src/thirdparty/gpacmp4/box_code_meta.c \
|
||||
../src/thirdparty/gpacmp4/box_funcs.c \
|
||||
../src/thirdparty/gpacmp4/color.c \
|
||||
../src/thirdparty/gpacmp4/configfile.c \
|
||||
../src/thirdparty/gpacmp4/data_map.c \
|
||||
../src/thirdparty/gpacmp4/desc_private.c \
|
||||
../src/thirdparty/gpacmp4/descriptors.c \
|
||||
../src/thirdparty/gpacmp4/drm_sample.c \
|
||||
../src/thirdparty/gpacmp4/error.c \
|
||||
../src/thirdparty/gpacmp4/gpac_ogg.c \
|
||||
../src/thirdparty/gpacmp4/hint_track.c \
|
||||
../src/thirdparty/gpacmp4/hinting.c \
|
||||
../src/thirdparty/gpacmp4/ipmpx_code.c \
|
||||
../src/thirdparty/gpacmp4/ipmpx_parse.c \
|
||||
../src/thirdparty/gpacmp4/isom_intern.c \
|
||||
../src/thirdparty/gpacmp4/isom_read.c \
|
||||
../src/thirdparty/gpacmp4/isom_store.c \
|
||||
../src/thirdparty/gpacmp4/isom_write.c \
|
||||
../src/thirdparty/gpacmp4/list.c \
|
||||
../src/thirdparty/gpacmp4/math.c \
|
||||
../src/thirdparty/gpacmp4/media.c \
|
||||
../src/thirdparty/gpacmp4/media_odf.c \
|
||||
../src/thirdparty/gpacmp4/meta.c \
|
||||
../src/thirdparty/gpacmp4/movie_fragments.c \
|
||||
../src/thirdparty/gpacmp4/odf_code.c \
|
||||
../src/thirdparty/gpacmp4/odf_codec.c \
|
||||
../src/thirdparty/gpacmp4/odf_command.c \
|
||||
../src/thirdparty/gpacmp4/os_config_init.c \
|
||||
../src/thirdparty/gpacmp4/os_divers.c \
|
||||
../src/thirdparty/gpacmp4/os_file.c \
|
||||
../src/thirdparty/gpacmp4/qos.c \
|
||||
../src/thirdparty/gpacmp4/sample_descs.c \
|
||||
../src/thirdparty/gpacmp4/slc.c \
|
||||
../src/thirdparty/gpacmp4/stbl_read.c \
|
||||
../src/thirdparty/gpacmp4/stbl_write.c \
|
||||
../src/thirdparty/gpacmp4/track.c \
|
||||
../src/thirdparty/gpacmp4/tx3g.c \
|
||||
../src/thirdparty/gpacmp4/url.c \
|
||||
../src/thirdparty/gpacmp4/utf.c \
|
||||
../src/thirdparty/gpacmp4/os_thread.c \
|
||||
../src/thirdparty/gpacmp4/module.c \
|
||||
../src/thirdparty/gpacmp4/os_module.c \
|
||||
../src/thirdparty/gpacmp4/xml_parser.c \
|
||||
../src/thirdparty/gpacmp4/constants.c \
|
||||
../src/thirdparty/gpacmp4/gpac/avparse.h \
|
||||
../src/thirdparty/gpacmp4/gpac/base_coding.h \
|
||||
../src/thirdparty/gpacmp4/gpac/bitstream.h \
|
||||
../src/thirdparty/gpacmp4/gpac/color.h \
|
||||
../src/thirdparty/gpacmp4/gpac/config_file.h \
|
||||
../src/thirdparty/gpacmp4/gpac/configuration.h \
|
||||
../src/thirdparty/gpacmp4/gpac/constants.h \
|
||||
../src/thirdparty/gpacmp4/gpac/events_constants.h \
|
||||
../src/thirdparty/gpacmp4/gpac/ietf.h \
|
||||
../src/thirdparty/gpacmp4/gpac/isomedia.h \
|
||||
../src/thirdparty/gpacmp4/gpac/list.h \
|
||||
../src/thirdparty/gpacmp4/gpac/maths.h \
|
||||
../src/thirdparty/gpacmp4/gpac/media_tools.h \
|
||||
../src/thirdparty/gpacmp4/gpac/mpeg4_odf.h \
|
||||
../src/thirdparty/gpacmp4/gpac/network.h \
|
||||
../src/thirdparty/gpacmp4/gpac/revision.h \
|
||||
../src/thirdparty/gpacmp4/gpac/setup.h \
|
||||
../src/thirdparty/gpacmp4/gpac/tools.h \
|
||||
../src/thirdparty/gpacmp4/gpac/utf.h \
|
||||
../src/thirdparty/gpacmp4/gpac/version.h \
|
||||
../src/thirdparty/gpacmp4/gpac/internal/avilib.h \
|
||||
../src/thirdparty/gpacmp4/gpac/internal/isomedia_dev.h \
|
||||
../src/thirdparty/gpacmp4/gpac/internal/media_dev.h \
|
||||
../src/thirdparty/gpacmp4/gpac/internal/odf_dev.h \
|
||||
../src/thirdparty/gpacmp4/gpac/internal/odf_parse_common.h \
|
||||
../src/thirdparty/gpacmp4/gpac/internal/ogg.h \
|
||||
../src/thirdparty/libpng/pngstruct.h \
|
||||
../src/thirdparty/libpng/pngpriv.h \
|
||||
../src/thirdparty/libpng/pnginfo.h \
|
||||
@@ -114,7 +33,7 @@ ccextractor_SOURCES = \
|
||||
../src/lib_ccx/activity.h \
|
||||
../src/lib_ccx/asf_constants.h \
|
||||
../src/lib_ccx/avc_functions.h \
|
||||
../src/lib_ccx/bitstream.h \
|
||||
../src/lib_ccx/cc_bitstream.h \
|
||||
../src/lib_ccx/ccx_common_option.c \
|
||||
../src/lib_ccx/ccx_common_common.c \
|
||||
../src/lib_ccx/utility.c \
|
||||
@@ -176,10 +95,6 @@ ccextractor_SOURCES = \
|
||||
../src/lib_ccx/ccx_gxf.c \
|
||||
../src/lib_ccx/ccx_gxf.h \
|
||||
../src/lib_ccx/ccx_mp4.h \
|
||||
../src/lib_ccx/ccx_share.c \
|
||||
../src/lib_ccx/ccx_share.h \
|
||||
../src/lib_ccx/ccx_sub_entry_message.pb-c.c \
|
||||
../src/lib_ccx/ccx_sub_entry_message.pb-c.h \
|
||||
../src/lib_ccx/compile_info.h \
|
||||
../src/lib_ccx/compile_info_real.h \
|
||||
../src/lib_ccx/configuration.c \
|
||||
@@ -259,20 +174,19 @@ ccextractor_SOURCES = \
|
||||
../src/thirdparty/utf8proc/utf8proc.h \
|
||||
../src/thirdparty/lib_hash/sha2.c \
|
||||
../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 +215,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,35 +229,51 @@ ccextractor_SOURCES = \
|
||||
../src/thirdparty/freetype/type1/type1.c \
|
||||
../src/thirdparty/freetype/type42/type42.c \
|
||||
../src/thirdparty/freetype/winfonts/winfnt.c
|
||||
|
||||
|
||||
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
|
||||
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_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_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
|
||||
|
||||
ccextractor_LDFLAGS = $(shell pkg-config --libs gpac)
|
||||
GPAC_CPPFLAGS = $(shell pkg-config --cflags gpac)
|
||||
|
||||
ccextractor_CPPFLAGS =-I../src/lib_ccx/ -I../src/thirdparty/libpng/ -I../src/thirdparty/zlib/ -I../src/lib_ccx/zvbi/ -I../src/thirdparty/lib_hash/ -I../src/thirdparty -I../src/ -I../src/thirdparty/freetype/include/
|
||||
ccextractor_CPPFLAGS += $(GPAC_CPPFLAGS)
|
||||
ccextractor_CPPFLAGS += $(FFMPEG_CPPFLAGS)
|
||||
|
||||
ccextractor_LDADD=-lm -lpthread -ldl
|
||||
|
||||
if SYS_IS_LINUX
|
||||
ccextractor_CFLAGS += -O3 -s -DGPAC_CONFIG_LINUX
|
||||
ccextractor_CFLAGS += -O3 -s
|
||||
endif
|
||||
|
||||
if SYS_IS_MAC
|
||||
ccextractor_CFLAGS += -DPAC_CONFIG_DARWIN -Dfopen64=fopen -Dopen64=open -Dlseek64=lseek
|
||||
ccextractor_LDADD += -liconv -lz
|
||||
ccextractor_CFLAGS += -Dfopen64=fopen -Dopen64=open -Dlseek64=lseek
|
||||
ccextractor_LDADD += -liconv -lz
|
||||
endif
|
||||
|
||||
if SYS_IS_64_BIT
|
||||
ccextractor_CFLAGS += -DGPAC_64_BITS
|
||||
endif
|
||||
|
||||
HARDSUBX_FEATURE_RUST=
|
||||
|
||||
if HARDSUBX_IS_ENABLED
|
||||
ccextractor_CFLAGS += -DENABLE_HARDSUBX
|
||||
ccextractor_CPPFLAGS+= ${libavcodec_CFLAGS}
|
||||
ccextractor_CPPFLAGS+= ${libavformat_CFLAGS}
|
||||
ccextractor_CPPFLAGS+= ${libavutil_CFALGS}
|
||||
ccextractor_CPPFLAGS+= ${libavutil_CFLAGS}
|
||||
ccextractor_CPPFLAGS+= ${libswscale_CFLAGS}
|
||||
AV_LIB = ${libavcodec_LIBS}
|
||||
AV_LIB += ${libavformat_LIBS}
|
||||
AV_LIB += ${libavutil_LIBS}
|
||||
AV_LIB += ${libswscale_LIBS}
|
||||
ccextractor_LDADD += $(AV_LIB)
|
||||
HARDSUBX_FEATURE_RUST += --features "hardsubx_ocr"
|
||||
endif
|
||||
|
||||
if OCR_IS_ENABLED
|
||||
@@ -369,64 +300,18 @@ ccextractor_LDADD += $(TESS_LIB)
|
||||
ccextractor_LDADD += $(LEPT_LIB)
|
||||
endif
|
||||
|
||||
EXTRA_DIST = ../src/thirdparty/gpacmp4/gpac/sync_layer.h ../src/lib_ccx/ccfont2.xbm ../src/thirdparty/utf8proc/utf8proc_data.c fonts/ icon/
|
||||
|
||||
#For GUI
|
||||
if BUILD_WITH_GUI
|
||||
bin_PROGRAMS += ccextractorGUI
|
||||
|
||||
ccextractorGUI_SOURCES = \
|
||||
../src/GUI/ccextractorGUI.c \
|
||||
../src/GUI/ccextractorGUI.h \
|
||||
../src/GUI/activity.c \
|
||||
../src/GUI/activity.h \
|
||||
../src/GUI/terminal.c \
|
||||
../src/GUI/preview.c \
|
||||
../src/GUI/preview.h \
|
||||
../src/GUI/ccx_cli_thread.c \
|
||||
../src/GUI/ccx_cli_thread.h \
|
||||
../src/GUI/command_builder.c \
|
||||
../src/GUI/command_builder.h \
|
||||
../src/GUI/save_load_data.c \
|
||||
../src/GUI/save_load_data.h \
|
||||
../src/GUI/file_browser.c \
|
||||
../src/GUI/file_browser.h \
|
||||
../src/GUI/popups.c \
|
||||
../src/GUI/popups.h \
|
||||
../src/GUI/tabs.c \
|
||||
../src/GUI/tabs.h \
|
||||
../src/GUI/stb_image.h \
|
||||
../src/GUI/nuklear_lib/nuklear.h \
|
||||
../src/GUI/nuklear_lib/nuklear_glfw_gl2.h
|
||||
|
||||
ccextractorGUI_CFLAGS = -std=gnu99
|
||||
ccextractor_LDADD += ./rust/@RUST_TARGET_SUBDIR@/libccx_rust.a
|
||||
|
||||
|
||||
ccextractorGUI_LDADD = ${glfw3_LIBS}
|
||||
|
||||
|
||||
if SYS_IS_LINUX
|
||||
ccextractorGUI_CFLAGS += -s -O3 -DUNIX
|
||||
ccextractorGUI_CFLAGS += ${glew_CFLAGS}
|
||||
ccextractorGUI_LDADD += ${glew_LIBS}
|
||||
ccextractorGUI_LDADD += -lX11 -lXinerama -lXcursor -lXi -lXrandr -lXxf86vm -lm -ldl -lpthread
|
||||
if DEBUG_RELEASE
|
||||
CARGO_RELEASE_ARGS=
|
||||
else
|
||||
CARGO_RELEASE_ARGS=--release
|
||||
endif
|
||||
|
||||
if SYS_IS_MAC
|
||||
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
|
||||
endif
|
||||
./rust/@RUST_TARGET_SUBDIR@/libccx_rust.a:
|
||||
cd ../src/rust && \
|
||||
CARGO_TARGET_DIR=../../mac/rust $(CARGO) build $(HARDSUBX_FEATURE_RUST) $(CARGO_RELEASE_ARGS);
|
||||
|
||||
if HARDSUBX_IS_ENABLED
|
||||
if OCR_IS_ENABLED
|
||||
ccextractorGUI_CFLAGS += -DENABLE_OCR
|
||||
endif
|
||||
endif
|
||||
|
||||
EXTRA_DIST += ../icon/ ../fonts/
|
||||
|
||||
endif
|
||||
EXTRA_DIST = ../src/lib_ccx/ccfont2.xbm ../src/thirdparty/utf8proc/utf8proc_data.c fonts/ icon/
|
||||
|
||||
|
||||
@@ -1,61 +1,311 @@
|
||||
#!/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"
|
||||
[[ $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"
|
||||
[[ $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')"
|
||||
SRC_LIB_HASH="$(find ../src/thirdparty/lib_hash -name '*.c')"
|
||||
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 \
|
||||
../src/thirdparty/freetype/base/ftbdf.c \
|
||||
../src/thirdparty/freetype/base/ftbitmap.c \
|
||||
../src/thirdparty/freetype/base/ftcid.c \
|
||||
../src/thirdparty/freetype/base/ftfntfmt.c \
|
||||
../src/thirdparty/freetype/base/ftfstype.c \
|
||||
../src/thirdparty/freetype/base/ftgasp.c \
|
||||
../src/thirdparty/freetype/base/ftglyph.c \
|
||||
../src/thirdparty/freetype/base/ftgxval.c \
|
||||
../src/thirdparty/freetype/base/ftinit.c \
|
||||
../src/thirdparty/freetype/base/ftlcdfil.c \
|
||||
../src/thirdparty/freetype/base/ftmm.c \
|
||||
../src/thirdparty/freetype/base/ftotval.c \
|
||||
../src/thirdparty/freetype/base/ftpatent.c \
|
||||
../src/thirdparty/freetype/base/ftpfr.c \
|
||||
../src/thirdparty/freetype/base/ftstroke.c \
|
||||
../src/thirdparty/freetype/base/ftsynth.c \
|
||||
../src/thirdparty/freetype/base/ftsystem.c \
|
||||
../src/thirdparty/freetype/base/fttype1.c \
|
||||
../src/thirdparty/freetype/base/ftwinfnt.c \
|
||||
../src/thirdparty/freetype/bdf/bdf.c \
|
||||
../src/thirdparty/freetype/bzip2/ftbzip2.c \
|
||||
../src/thirdparty/freetype/cache/ftcache.c \
|
||||
../src/thirdparty/freetype/cff/cff.c \
|
||||
../src/thirdparty/freetype/cid/type1cid.c \
|
||||
../src/thirdparty/freetype/gzip/ftgzip.c \
|
||||
../src/thirdparty/freetype/lzw/ftlzw.c \
|
||||
../src/thirdparty/freetype/pcf/pcf.c \
|
||||
../src/thirdparty/freetype/pfr/pfr.c \
|
||||
../src/thirdparty/freetype/psaux/psaux.c \
|
||||
../src/thirdparty/freetype/pshinter/pshinter.c \
|
||||
../src/thirdparty/freetype/psnames/psnames.c \
|
||||
../src/thirdparty/freetype/raster/raster.c \
|
||||
../src/thirdparty/freetype/sfnt/sfnt.c \
|
||||
../src/thirdparty/freetype/smooth/smooth.c \
|
||||
../src/thirdparty/freetype/truetype/truetype.c \
|
||||
../src/thirdparty/freetype/type1/type1.c \
|
||||
../src/thirdparty/freetype/type42/type42.c \
|
||||
../src/thirdparty/freetype/winfonts/winfnt.c"
|
||||
BLD_SOURCES="../src/ccextractor.c $SRC_API $SRC_CCX $SRC_GPAC $SRC_LIB_HASH $SRC_LIBPNG $SRC_PROTOBUF $SRC_UTF8 $SRC_ZLIB $SRC_ZVBI $SRC_FREETYPE"
|
||||
BLD_LINKER="-lm -liconv -lpthread -ldl"
|
||||
[[ $1 = "OCR" ]] && BLD_LINKER="$BLD_LINKER `pkg-config --libs --silence-errors tesseract` `pkg-config --libs --silence-errors lept`"
|
||||
|
||||
RUST_LIB="rust/release/libccx_rust.a"
|
||||
RUST_PROFILE="--release"
|
||||
RUST_FEATURES=""
|
||||
|
||||
# Parse command line arguments
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
OCR)
|
||||
ENABLE_OCR=true
|
||||
shift
|
||||
;;
|
||||
-debug)
|
||||
DEBUG=true
|
||||
RUST_PROFILE=""
|
||||
RUST_LIB="rust/debug/libccx_rust.a"
|
||||
shift
|
||||
;;
|
||||
-hardsubx)
|
||||
HARDSUBX=true
|
||||
ENABLE_OCR=true
|
||||
# Allow overriding FFmpeg version via environment variable
|
||||
if [ -n "$FFMPEG_VERSION" ]; then
|
||||
RUST_FEATURES="--features hardsubx_ocr,$FFMPEG_VERSION"
|
||||
else
|
||||
RUST_FEATURES="--features hardsubx_ocr"
|
||||
fi
|
||||
shift
|
||||
;;
|
||||
-system-libs)
|
||||
# Use system-installed libraries via pkg-config instead of bundled ones
|
||||
# This is required for Homebrew formula compatibility
|
||||
USE_SYSTEM_LIBS=true
|
||||
shift
|
||||
;;
|
||||
-*)
|
||||
echo "Unknown option $1"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
BLD_FLAGS="-std=gnu99 -Wno-write-strings -Wno-pointer-sign -D_FILE_OFFSET_BITS=64 -DVERSION_FILE_PRESENT -Dfopen64=fopen -Dopen64=open -Dlseek64=lseek"
|
||||
|
||||
# Add flags for bundled libraries (not needed when using system libs)
|
||||
if [[ "$USE_SYSTEM_LIBS" != "true" ]]; then
|
||||
BLD_FLAGS="$BLD_FLAGS -DFT2_BUILD_LIBRARY -DGPAC_DISABLE_VTT -DGPAC_DISABLE_OD_DUMP -DGPAC_DISABLE_REMOTERY -DNO_GZIP"
|
||||
fi
|
||||
|
||||
# Add debug flags if needed
|
||||
if [[ "$DEBUG" == "true" ]]; then
|
||||
BLD_FLAGS="$BLD_FLAGS -g -fsanitize=address"
|
||||
fi
|
||||
|
||||
# Add OCR support if requested
|
||||
if [[ "$ENABLE_OCR" == "true" ]]; then
|
||||
BLD_FLAGS="$BLD_FLAGS -DENABLE_OCR"
|
||||
fi
|
||||
|
||||
# Add hardsubx support if requested
|
||||
if [[ "$HARDSUBX" == "true" ]]; then
|
||||
BLD_FLAGS="$BLD_FLAGS -DENABLE_HARDSUBX"
|
||||
fi
|
||||
|
||||
# Set up include paths based on whether we're using system libs or bundled
|
||||
if [[ "$USE_SYSTEM_LIBS" == "true" ]]; then
|
||||
# Use system libraries via pkg-config (for Homebrew compatibility)
|
||||
# Note: -I../src/thirdparty/lib_hash is needed so that "../lib_hash/sha2.h" resolves correctly
|
||||
# (the .. goes up from lib_hash to thirdparty, then lib_hash/sha2.h finds the file)
|
||||
BLD_INCLUDE="-I../src/ -I../src/lib_ccx -I../src/thirdparty/lib_hash -I../src/thirdparty"
|
||||
BLD_INCLUDE="$BLD_INCLUDE $(pkg-config --cflags --silence-errors freetype2)"
|
||||
BLD_INCLUDE="$BLD_INCLUDE $(pkg-config --cflags --silence-errors gpac)"
|
||||
BLD_INCLUDE="$BLD_INCLUDE $(pkg-config --cflags --silence-errors libpng)"
|
||||
BLD_INCLUDE="$BLD_INCLUDE $(pkg-config --cflags --silence-errors libprotobuf-c)"
|
||||
BLD_INCLUDE="$BLD_INCLUDE $(pkg-config --cflags --silence-errors libutf8proc)"
|
||||
else
|
||||
# Use bundled libraries (default for standalone builds)
|
||||
BLD_INCLUDE="-I../src/ -I../src/lib_ccx -I../src/thirdparty/lib_hash -I../src/thirdparty/libpng -I../src/thirdparty -I../src/thirdparty/zlib -I../src/thirdparty/freetype/include $(pkg-config --cflags --silence-errors gpac)"
|
||||
fi
|
||||
|
||||
# Add FFmpeg include path for Mac
|
||||
if [[ -d "/opt/homebrew/Cellar/ffmpeg" ]]; then
|
||||
FFMPEG_VERSION=$(ls -1 /opt/homebrew/Cellar/ffmpeg | head -1)
|
||||
if [[ -n "$FFMPEG_VERSION" ]]; then
|
||||
BLD_INCLUDE="$BLD_INCLUDE -I/opt/homebrew/Cellar/ffmpeg/$FFMPEG_VERSION/include"
|
||||
fi
|
||||
elif [[ -d "/usr/local/Cellar/ffmpeg" ]]; then
|
||||
FFMPEG_VERSION=$(ls -1 /usr/local/Cellar/ffmpeg | head -1)
|
||||
if [[ -n "$FFMPEG_VERSION" ]]; then
|
||||
BLD_INCLUDE="$BLD_INCLUDE -I/usr/local/Cellar/ffmpeg/$FFMPEG_VERSION/include"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Add Leptonica include path for Mac
|
||||
if [[ -d "/opt/homebrew/Cellar/leptonica" ]]; then
|
||||
LEPT_VERSION=$(ls -1 /opt/homebrew/Cellar/leptonica | head -1)
|
||||
if [[ -n "$LEPT_VERSION" ]]; then
|
||||
BLD_INCLUDE="$BLD_INCLUDE -I/opt/homebrew/Cellar/leptonica/$LEPT_VERSION/include"
|
||||
fi
|
||||
elif [[ -d "/usr/local/Cellar/leptonica" ]]; then
|
||||
LEPT_VERSION=$(ls -1 /usr/local/Cellar/leptonica | head -1)
|
||||
if [[ -n "$LEPT_VERSION" ]]; then
|
||||
BLD_INCLUDE="$BLD_INCLUDE -I/usr/local/Cellar/leptonica/$LEPT_VERSION/include"
|
||||
fi
|
||||
elif [[ -d "/opt/homebrew/include/leptonica" ]]; then
|
||||
BLD_INCLUDE="$BLD_INCLUDE -I/opt/homebrew/include"
|
||||
elif [[ -d "/usr/local/include/leptonica" ]]; then
|
||||
BLD_INCLUDE="$BLD_INCLUDE -I/usr/local/include"
|
||||
fi
|
||||
|
||||
# Add Tesseract include path for Mac
|
||||
if [[ -d "/opt/homebrew/Cellar/tesseract" ]]; then
|
||||
TESS_VERSION=$(ls -1 /opt/homebrew/Cellar/tesseract | head -1)
|
||||
if [[ -n "$TESS_VERSION" ]]; then
|
||||
BLD_INCLUDE="$BLD_INCLUDE -I/opt/homebrew/Cellar/tesseract/$TESS_VERSION/include"
|
||||
fi
|
||||
elif [[ -d "/usr/local/Cellar/tesseract" ]]; then
|
||||
TESS_VERSION=$(ls -1 /usr/local/Cellar/tesseract | head -1)
|
||||
if [[ -n "$TESS_VERSION" ]]; then
|
||||
BLD_INCLUDE="$BLD_INCLUDE -I/usr/local/Cellar/tesseract/$TESS_VERSION/include"
|
||||
fi
|
||||
elif [[ -d "/opt/homebrew/include/tesseract" ]]; then
|
||||
BLD_INCLUDE="$BLD_INCLUDE -I/opt/homebrew/include"
|
||||
elif [[ -d "/usr/local/include/tesseract" ]]; then
|
||||
BLD_INCLUDE="$BLD_INCLUDE -I/usr/local/include"
|
||||
fi
|
||||
|
||||
if [[ "$ENABLE_OCR" == "true" ]]; then
|
||||
BLD_INCLUDE="$BLD_INCLUDE `pkg-config --cflags --silence-errors tesseract`"
|
||||
fi
|
||||
|
||||
SRC_CCX="$(find ../src/lib_ccx -name '*.c')"
|
||||
SRC_LIB_HASH="$(find ../src/thirdparty/lib_hash -name '*.c')"
|
||||
|
||||
# Set up sources and linker based on whether we're using system libs or bundled
|
||||
if [[ "$USE_SYSTEM_LIBS" == "true" ]]; then
|
||||
# Use system libraries - don't compile bundled sources
|
||||
BLD_SOURCES="../src/ccextractor.c $SRC_CCX $SRC_LIB_HASH"
|
||||
|
||||
BLD_LINKER="-lm -liconv -lpthread -ldl"
|
||||
BLD_LINKER="$BLD_LINKER $(pkg-config --libs --silence-errors freetype2)"
|
||||
BLD_LINKER="$BLD_LINKER $(pkg-config --libs --silence-errors gpac)"
|
||||
BLD_LINKER="$BLD_LINKER $(pkg-config --libs --silence-errors libpng)"
|
||||
BLD_LINKER="$BLD_LINKER $(pkg-config --libs --silence-errors libprotobuf-c)"
|
||||
BLD_LINKER="$BLD_LINKER $(pkg-config --libs --silence-errors libutf8proc)"
|
||||
BLD_LINKER="$BLD_LINKER $(pkg-config --libs --silence-errors zlib)"
|
||||
else
|
||||
# Use bundled libraries (default)
|
||||
SRC_LIBPNG="$(find ../src/thirdparty/libpng -name '*.c')"
|
||||
SRC_UTF8="../src/thirdparty/utf8proc/utf8proc.c"
|
||||
SRC_ZLIB="$(find ../src/thirdparty/zlib -name '*.c')"
|
||||
SRC_FREETYPE="../src/thirdparty/freetype/autofit/autofit.c \
|
||||
../src/thirdparty/freetype/base/ftbase.c \
|
||||
../src/thirdparty/freetype/base/ftbbox.c \
|
||||
../src/thirdparty/freetype/base/ftbdf.c \
|
||||
../src/thirdparty/freetype/base/ftbitmap.c \
|
||||
../src/thirdparty/freetype/base/ftcid.c \
|
||||
../src/thirdparty/freetype/base/ftfntfmt.c \
|
||||
../src/thirdparty/freetype/base/ftfstype.c \
|
||||
../src/thirdparty/freetype/base/ftgasp.c \
|
||||
../src/thirdparty/freetype/base/ftglyph.c \
|
||||
../src/thirdparty/freetype/base/ftgxval.c \
|
||||
../src/thirdparty/freetype/base/ftinit.c \
|
||||
../src/thirdparty/freetype/base/ftlcdfil.c \
|
||||
../src/thirdparty/freetype/base/ftmm.c \
|
||||
../src/thirdparty/freetype/base/ftotval.c \
|
||||
../src/thirdparty/freetype/base/ftpatent.c \
|
||||
../src/thirdparty/freetype/base/ftpfr.c \
|
||||
../src/thirdparty/freetype/base/ftstroke.c \
|
||||
../src/thirdparty/freetype/base/ftsynth.c \
|
||||
../src/thirdparty/freetype/base/ftsystem.c \
|
||||
../src/thirdparty/freetype/base/fttype1.c \
|
||||
../src/thirdparty/freetype/base/ftwinfnt.c \
|
||||
../src/thirdparty/freetype/bdf/bdf.c \
|
||||
../src/thirdparty/freetype/bzip2/ftbzip2.c \
|
||||
../src/thirdparty/freetype/cache/ftcache.c \
|
||||
../src/thirdparty/freetype/cff/cff.c \
|
||||
../src/thirdparty/freetype/cid/type1cid.c \
|
||||
../src/thirdparty/freetype/gzip/ftgzip.c \
|
||||
../src/thirdparty/freetype/lzw/ftlzw.c \
|
||||
../src/thirdparty/freetype/pcf/pcf.c \
|
||||
../src/thirdparty/freetype/pfr/pfr.c \
|
||||
../src/thirdparty/freetype/psaux/psaux.c \
|
||||
../src/thirdparty/freetype/pshinter/pshinter.c \
|
||||
../src/thirdparty/freetype/psnames/psnames.c \
|
||||
../src/thirdparty/freetype/raster/raster.c \
|
||||
../src/thirdparty/freetype/sfnt/sfnt.c \
|
||||
../src/thirdparty/freetype/smooth/smooth.c \
|
||||
../src/thirdparty/freetype/truetype/truetype.c \
|
||||
../src/thirdparty/freetype/type1/type1.c \
|
||||
../src/thirdparty/freetype/type42/type42.c \
|
||||
../src/thirdparty/freetype/winfonts/winfnt.c"
|
||||
|
||||
BLD_SOURCES="../src/ccextractor.c $SRC_CCX $SRC_LIB_HASH $SRC_LIBPNG $SRC_UTF8 $SRC_ZLIB $SRC_FREETYPE"
|
||||
BLD_LINKER="-lm -liconv -lpthread -ldl $(pkg-config --libs --silence-errors gpac)"
|
||||
fi
|
||||
|
||||
if [[ "$ENABLE_OCR" == "true" ]]; then
|
||||
BLD_LINKER="$BLD_LINKER `pkg-config --libs --silence-errors tesseract` `pkg-config --libs --silence-errors lept`"
|
||||
fi
|
||||
|
||||
if [[ "$HARDSUBX" == "true" ]]; then
|
||||
# Add FFmpeg library path for Mac
|
||||
if [[ -d "/opt/homebrew/Cellar/ffmpeg" ]]; then
|
||||
FFMPEG_VERSION=$(ls -1 /opt/homebrew/Cellar/ffmpeg | head -1)
|
||||
if [[ -n "$FFMPEG_VERSION" ]]; then
|
||||
BLD_LINKER="$BLD_LINKER -L/opt/homebrew/Cellar/ffmpeg/$FFMPEG_VERSION/lib"
|
||||
fi
|
||||
elif [[ -d "/usr/local/Cellar/ffmpeg" ]]; then
|
||||
FFMPEG_VERSION=$(ls -1 /usr/local/Cellar/ffmpeg | head -1)
|
||||
if [[ -n "$FFMPEG_VERSION" ]]; then
|
||||
BLD_LINKER="$BLD_LINKER -L/usr/local/Cellar/ffmpeg/$FFMPEG_VERSION/lib"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Add library paths for Leptonica and Tesseract from Cellar
|
||||
if [[ -d "/opt/homebrew/Cellar/leptonica" ]]; then
|
||||
LEPT_VERSION=$(ls -1 /opt/homebrew/Cellar/leptonica | head -1)
|
||||
if [[ -n "$LEPT_VERSION" ]]; then
|
||||
BLD_LINKER="$BLD_LINKER -L/opt/homebrew/Cellar/leptonica/$LEPT_VERSION/lib"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -d "/opt/homebrew/Cellar/tesseract" ]]; then
|
||||
TESS_VERSION=$(ls -1 /opt/homebrew/Cellar/tesseract | head -1)
|
||||
if [[ -n "$TESS_VERSION" ]]; then
|
||||
BLD_LINKER="$BLD_LINKER -L/opt/homebrew/Cellar/tesseract/$TESS_VERSION/lib"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Also add homebrew lib path as fallback
|
||||
if [[ -d "/opt/homebrew/lib" ]]; then
|
||||
BLD_LINKER="$BLD_LINKER -L/opt/homebrew/lib"
|
||||
elif [[ -d "/usr/local/lib" ]]; then
|
||||
BLD_LINKER="$BLD_LINKER -L/usr/local/lib"
|
||||
fi
|
||||
|
||||
BLD_LINKER="$BLD_LINKER -lswscale -lavutil -pthread -lavformat -lavcodec -lavfilter -lleptonica -ltesseract"
|
||||
fi
|
||||
|
||||
echo "Running pre-build script..."
|
||||
./pre-build.sh
|
||||
gcc $BLD_FLAGS $BLD_INCLUDE -o ccextractor $BLD_SOURCES $BLD_LINKER
|
||||
echo "Trying to compile..."
|
||||
|
||||
# Check for cargo
|
||||
echo "Checking for cargo..."
|
||||
if ! [ -x "$(command -v cargo)" ]; then
|
||||
echo 'Error: cargo is not installed.' >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check rust version
|
||||
rustc_version="$(rustc --version)"
|
||||
semver=( ${rustc_version//./ } )
|
||||
version="${semver[1]}.${semver[2]}.${semver[3]}"
|
||||
MSRV="1.87.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=../../mac/rust cargo build $RUST_PROFILE $RUST_FEATURES) || { echo "Failed building Rust components." ; exit 1; }
|
||||
|
||||
# Copy the Rust library
|
||||
cp $RUST_LIB ./libccx_rust.a
|
||||
|
||||
# Add Rust library to linker flags
|
||||
BLD_LINKER="$BLD_LINKER ./libccx_rust.a"
|
||||
|
||||
echo "Building ccextractor"
|
||||
out=$((LC_ALL=C gcc $BLD_FLAGS $BLD_INCLUDE -o ccextractor $BLD_SOURCES $BLD_LINKER) 2>&1)
|
||||
res=$?
|
||||
|
||||
# Handle common error cases
|
||||
if [[ $out == *"gcc: command not found"* ]]; then
|
||||
echo "Error: please install gcc or Xcode command line tools"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ $out == *"curl.h: No such file or directory"* ]]; then
|
||||
echo "Error: please install curl development library"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
if [[ $out == *"capi.h: No such file or directory"* ]]; then
|
||||
echo "Error: please install tesseract development library"
|
||||
exit 3
|
||||
fi
|
||||
|
||||
if [[ $out == *"allheaders.h: No such file or directory"* ]]; then
|
||||
echo "Error: please install leptonica development library"
|
||||
exit 4
|
||||
fi
|
||||
|
||||
if [[ $res -ne 0 ]]; then # Unknown error
|
||||
echo "Compiled with errors"
|
||||
>&2 echo "$out"
|
||||
exit 5
|
||||
fi
|
||||
|
||||
if [[ "$out" != "" ]]; then
|
||||
echo "$out"
|
||||
echo "Compilation successful, compiler message shown in previous lines"
|
||||
else
|
||||
echo "Compilation successful, no compiler messages."
|
||||
fi
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
# -*- Autoconf -*-
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_PREREQ([2.69])
|
||||
AC_INIT([CCExtractor], [0.92], [carlos@ccextractor.org])
|
||||
AC_PREREQ([2.71])
|
||||
AC_INIT([CCExtractor],[0.96],[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
|
||||
@@ -15,7 +15,7 @@ AC_PROG_MAKE_SET
|
||||
|
||||
#Checks for "pkg-config" utility
|
||||
AC_MSG_CHECKING([pkg-config m4 macros])
|
||||
if test m4_ifdef([PKG_CHECK_MODULES], [yes], [no]) == yes; then
|
||||
if test m4_ifdef([PKG_CHECK_MODULES], [yes], [no]) = yes; then
|
||||
AC_MSG_RESULT([yes]);
|
||||
else
|
||||
AC_MSG_RESULT([no]);
|
||||
@@ -25,7 +25,7 @@ fi
|
||||
|
||||
# Checks for libraries.
|
||||
AC_CHECK_LIB([m], [sin], [], [AC_MSG_ERROR(Math library not installed. Install it before proceeding.)])
|
||||
AC_CHECK_LIB([lept], [getLeptonicaVersion], [HAS_LEPT=1 && PKG_CHECK_MODULES([lept], [lept])], [HAS_LEPT=0])
|
||||
AC_CHECK_LIB([leptonica], [getLeptonicaVersion], [HAS_LEPT=1 && PKG_CHECK_MODULES([lept], [lept])], [HAS_LEPT=0])
|
||||
AC_CHECK_LIB([tesseract], [TessVersion], [HAS_TESSERACT=1 && PKG_CHECK_MODULES([tesseract], [tesseract])], [HAS_TESSERACT=0])
|
||||
AC_CHECK_LIB([avcodec], [avcodec_version], [HAS_AVCODEC=1 && PKG_CHECK_MODULES([libavcodec], [libavcodec])], [HAS_AVCODEC=0])
|
||||
AC_CHECK_LIB([avformat], [avformat_version], [HAS_AVFORMAT=1 && PKG_CHECK_MODULES([libavformat], [libavformat])], [HAS_AVFORMAT=0])
|
||||
@@ -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,20 +79,58 @@ 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 ;;
|
||||
*) AC_MSG_ERROR([bad value ${enableval} for --enable-ffmpeg]) ;;
|
||||
esac],[ffmpeg=false])
|
||||
|
||||
AC_ARG_WITH([gui],
|
||||
AC_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])
|
||||
|
||||
AC_MSG_CHECKING(whether to build with rust library)
|
||||
if test "x$with_rust" = "xyes" ; then
|
||||
AC_MSG_RESULT(yes)
|
||||
|
||||
#Checks and prompts if libraries found/not found to avoild failure while building
|
||||
#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.87.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)])
|
||||
@@ -101,20 +139,21 @@ AS_IF([ test x$hardsubx = xtrue && test $HAS_AVUTIL -gt 0 ], [AC_MSG_NOTICE(avut
|
||||
AS_IF([ test x$hardsubx = xtrue && test ! $HAS_AVUTIL -gt 0 ], [AC_MSG_ERROR(avutil library not found. Please install the avutil library before proceeding)])
|
||||
AS_IF([ test x$hardsubx = xtrue && test $HAS_SWSCALE -gt 0 ], [AC_MSG_NOTICE(swscale library found)])
|
||||
AS_IF([ test x$hardsubx = xtrue && test ! $HAS_SWSCALE -gt 0 ], [AC_MSG_ERROR(swscale library not found. Please install the swscale library before proceeding)])
|
||||
AS_IF([ (test x$ocr = xtrue || test x$hardsubx = xtrue) && test $HAS_TESSERACT -gt 0 ], [TESS_VERSION=`tesseract --version 2>&1 | grep tesseract` && AC_MSG_NOTICE(tesseract library found... $TESS_VERSION)])
|
||||
AS_IF([ (test x$ocr = xtrue || test x$hardsubx = xtrue) && test $HAS_TESSERACT -gt 0 ], [TESS_VERSION=$(tesseract --version 2>&1 | grep tesseract) && AC_MSG_NOTICE(tesseract library found... $TESS_VERSION)])
|
||||
AS_IF([ (test x$ocr = xtrue || test x$hardsubx = xtrue) && test ! $HAS_TESSERACT -gt 0 ], [AC_MSG_ERROR(tesserect library not found. Please install the tesseract library before proceeding)])
|
||||
AS_IF([ (test x$ocr = xtrue || test x$hardsubx = xtrue) && test $HAS_LEPT -gt 0 ], [LEPT_VERSION=`tesseract --version 2>&1 | grep leptonica` && AC_MSG_NOTICE(leptonica library found... $LEPT_VERSION)])
|
||||
AS_IF([ (test x$ocr = xtrue || test x$hardsubx = xtrue) && test $HAS_LEPT -gt 0 ], [LEPT_VERSION=$(tesseract --version 2>&1 | grep leptonica) && AC_MSG_NOTICE(leptonica library found... $LEPT_VERSION)])
|
||||
AS_IF([ (test x$ocr = xtrue || test x$hardsubx = xtrue) && test ! $HAS_LEPT -gt 0 ], [AC_MSG_ERROR(leptonica library not found. Please install the leptonica library before proceeding)])
|
||||
|
||||
#AM_CONDITIONAL(s) for setting values to enable/disable flags in Makefile.am
|
||||
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_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(BUILD_WITH_GUI, [test "x$with_gui" = "xyes"])
|
||||
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(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,22 +1,21 @@
|
||||
pkgname=ccextractor
|
||||
pkgver=0.92
|
||||
pkgver=0.96
|
||||
pkgrel=1
|
||||
pkgdesc="A closed captions and teletext subtitles extractor for video streams."
|
||||
arch=('i686' 'x86_64')
|
||||
url="http://www.ccextractor.org"
|
||||
url="https://www.ccextractor.org"
|
||||
license=('GPL')
|
||||
depends=('gcc-libs' 'tesseract')
|
||||
depends=('gcc-libs' 'tesseract' 'leptonica' 'ffmpeg' 'rust' 'clang')
|
||||
source=(
|
||||
$pkgname-$pkgver.tar.gz
|
||||
https://github.com/CCExtractor/ccextractor/releases/download/v$pkgver/ccextractor_minimal.tar.gz
|
||||
)
|
||||
|
||||
build() {
|
||||
cd "$srcdir/$pkgname-$pkgver"
|
||||
CC=gcc ./configure --enable-ocr --prefix="$pkgdir/usr/local"
|
||||
make -j4
|
||||
cd "$srcdir/$pkgname/linux"
|
||||
./build_hardsubx
|
||||
}
|
||||
|
||||
package() {
|
||||
cd "$srcdir/$pkgname-$pkgver"
|
||||
make install
|
||||
cd "$srcdir/$pkgname/linux"
|
||||
install -Dm755 "$pkgname" "$pkgdir/usr/bin/$pkgname"
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
Name: ccextractor
|
||||
Version: 0.88
|
||||
Version: 0.96
|
||||
Release: 1
|
||||
Summary: A closed captions and teletext subtitles extractor for video streams.
|
||||
Group: Applications/Internet
|
||||
License: GPL
|
||||
URL: http://ccextractor.org/
|
||||
URL: https://ccextractor.org/
|
||||
Source0: %{name}-%{version}.tar.gz
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/bin/bash
|
||||
TYPE="debian" # can be one of 'slackware', 'debian', 'rpm'
|
||||
PROGRAM_NAME="ccextractor"
|
||||
VERSION="0.88"
|
||||
VERSION="0.96"
|
||||
RELEASE="1"
|
||||
LICENSE="GPL-2.0"
|
||||
MAINTAINER="carlos@ccextractor.org"
|
||||
|
||||
@@ -4,12 +4,10 @@ cc_binary(
|
||||
"ccextractor.h"],
|
||||
deps = [
|
||||
"//src/lib_ccx:lib_ccx",
|
||||
"//src/thirdparty/protobuf-c:protobuf-c",
|
||||
"//src/thirdparty/gpacmp4:gpacmp4",
|
||||
"//src/thirdparty/zlib:zlib",
|
||||
"//src/thirdparty/freetype:freetype"
|
||||
],
|
||||
copts = [ "-Isrc/thirdparty/protobuf-c", "-Isrc/thirdparty/libpng", "-Isrc" ]
|
||||
copts = [ "-Isrc/thirdparty/libpng", "-Isrc" ]
|
||||
)
|
||||
|
||||
exports_files (["ccextractor.h"], ["//src/lib_ccx:__pkg__"])
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
cmake_minimum_required (VERSION 3.0.2)
|
||||
|
||||
cmake_minimum_required (VERSION 3.24.0)
|
||||
project (CCExtractor)
|
||||
|
||||
include (CTest)
|
||||
|
||||
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 (WITH_RUST "Build with Rust library" OFF)
|
||||
|
||||
# Version number
|
||||
set (CCEXTRACTOR_VERSION_MAJOR 0)
|
||||
@@ -41,11 +40,7 @@ configure_file (
|
||||
"${PROJECT_SOURCE_DIR}/lib_ccx/compile_info_real.h"
|
||||
)
|
||||
|
||||
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)
|
||||
add_definitions(-DGPAC_CONFIG_LINUX)
|
||||
endif(UNIX)
|
||||
add_definitions(-DVERSION_FILE_PRESENT -DFT2_BUILD_LIBRARY -DGPAC_DISABLE_VTT -DGPAC_DISABLE_OD_DUMP -DGPAC_DISABLE_REMOTERY -DNO_GZIP)
|
||||
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
add_definitions(-DGPAC_64_BITS)
|
||||
@@ -55,16 +50,25 @@ include_directories(${PROJECT_SOURCE_DIR})
|
||||
include_directories(${PROJECT_SOURCE_DIR}/lib_ccx)
|
||||
include_directories(${PROJECT_SOURCE_DIR}/lib_ccx/zvbi)
|
||||
include_directories(${PROJECT_SOURCE_DIR}/thirdparty)
|
||||
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)
|
||||
|
||||
# Check if the operating system is macOS (Darwin)
|
||||
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
if(${CMAKE_HOST_SYSTEM_PROCESSOR} MATCHES "arm64")
|
||||
# ARM Macs
|
||||
include_directories("/opt/homebrew/include")
|
||||
include_directories(${PROJECT_SOURCE_DIR}/thirdparty/libpng/arm)
|
||||
aux_source_directory(${PROJECT_SOURCE_DIR}/thirdparty/libpng/arm SOURCEFILE)
|
||||
else()
|
||||
include_directories("/usr/local/include")
|
||||
endif()
|
||||
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)
|
||||
aux_source_directory(${PROJECT_SOURCE_DIR}/thirdparty/lib_hash/ SOURCEFILE)
|
||||
aux_source_directory(${PROJECT_SOURCE_DIR}/thirdparty/libpng/ SOURCEFILE)
|
||||
aux_source_directory(${PROJECT_SOURCE_DIR}/thirdparty/protobuf-c/ SOURCEFILE)
|
||||
aux_source_directory(${PROJECT_SOURCE_DIR}/thirdparty/zlib/ SOURCEFILE)
|
||||
aux_source_directory(${PROJECT_SOURCE_DIR}/lib_ccx/zvbi/ SOURCEFILE)
|
||||
|
||||
@@ -115,14 +119,23 @@ set(FREETYPE_SOURCE
|
||||
)
|
||||
#Windows specific libraries and linker flags
|
||||
if(WIN32)
|
||||
include_directories ("${PROJECT_SOURCE_DIR}/thirdparty/win_spec_incld/")
|
||||
if(NOT MINGW)
|
||||
include_directories ("${PROJECT_SOURCE_DIR}/thirdparty/win_spec_incld/")
|
||||
endif()
|
||||
include_directories ("${PROJECT_SOURCE_DIR}/thirdparty/win_iconv/")
|
||||
aux_source_directory ("${PROJECT_SOURCE_DIR}/thirdparty/win_iconv/" SOURCEFILE)
|
||||
set (EXTRA_LIBS ${EXTRA_LIBS} ws2_32 winmm)
|
||||
set (EXTRA_LIBS ${EXTRA_LIBS} ws2_32 winmm Bcrypt)
|
||||
else (WIN32)
|
||||
# Adding some platform specific library path
|
||||
link_directories (/opt/local/lib)
|
||||
link_directories (/usr/local/lib)
|
||||
if(UNIX AND NOT APPLE)
|
||||
link_directories (/usr/local/lib)
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
# Homebrew library paths
|
||||
link_directories(/usr/local/lib)
|
||||
link_directories(/opt/homebrew/lib)
|
||||
endif()
|
||||
endif(WIN32)
|
||||
|
||||
if(MSVC)
|
||||
@@ -136,6 +149,7 @@ add_subdirectory (lib_ccx)
|
||||
|
||||
aux_source_directory(${PROJECT_SOURCE_DIR} SOURCEFILE)
|
||||
set (EXTRA_LIBS ${EXTRA_LIBS} ccx)
|
||||
set (EXTRA_LIBS ${EXTRA_LIBS} ${GPAC_LIBRARIES})
|
||||
# set (EXTRA_LIBS ${EXTRA_LIBS} m)
|
||||
|
||||
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
@@ -190,21 +204,6 @@ if (PKG_CONFIG_FOUND AND WITH_OCR)
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DENABLE_OCR")
|
||||
endif (PKG_CONFIG_FOUND AND WITH_OCR)
|
||||
|
||||
########################################################
|
||||
# Build with CC sharing and translation support
|
||||
########################################################
|
||||
|
||||
if (PKG_CONFIG_FOUND AND WITH_SHARING)
|
||||
|
||||
pkg_check_modules (NANOMSG REQUIRED libnanomsg)
|
||||
set (EXTRA_LIBS ${EXTRA_LIBS} ${NANOMSG_STATIC_LIBRARIES})
|
||||
|
||||
include_directories ("${PROJECT_SOURCE_DIR}/thirdparty/protobuf-c/")
|
||||
aux_source_directory ("${PROJECT_SOURCE_DIR}/thirdparty/protobuf-c/" SOURCEFILE)
|
||||
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DENABLE_SHARING")
|
||||
endif (PKG_CONFIG_FOUND AND WITH_SHARING)
|
||||
|
||||
########################################################
|
||||
# Build for hardsubx using avformat, avutil, avcodec and
|
||||
# swscale
|
||||
@@ -215,19 +214,30 @@ if (PKG_CONFIG_FOUND AND WITH_HARDSUBX)
|
||||
pkg_check_modules (AVFORMAT REQUIRED libavformat)
|
||||
pkg_check_modules (AVUTIL REQUIRED libavutil)
|
||||
pkg_check_modules (AVCODEC REQUIRED libavcodec)
|
||||
pkg_check_modules (AVFILTER REQUIRED libavfilter)
|
||||
pkg_check_modules (SWSCALE REQUIRED libswscale)
|
||||
|
||||
set (EXTRA_LIBS ${EXTRA_LIBS} ${AVFORMAT_LIBRARIES})
|
||||
set (EXTRA_LIBS ${EXTRA_LIBS} ${AVUTIL_LIBRARIES})
|
||||
set (EXTRA_LIBS ${EXTRA_LIBS} ${AVCODEC_LIBRARIES})
|
||||
set (EXTRA_LIBS ${EXTRA_LIBS} ${AVFILTER_LIBRARIES})
|
||||
set (EXTRA_LIBS ${EXTRA_LIBS} ${SWSCALE_LIBRARIES})
|
||||
|
||||
set (EXTRA_INCLUDES ${EXTRA_INCLUDES} ${AVFORMAT_INCLUDE_DIRS})
|
||||
set (EXTRA_INCLUDES ${EXTRA_INCLUDES} ${AVUTIL_INCLUDE_DIRS})
|
||||
set (EXTRA_INCLUDES ${EXTRA_INCLUDES} ${AVCODEC_INCLUDE_DIRS})
|
||||
set (EXTRA_INCLUDES ${EXTRA_INCLUDES} ${AVFILTER_INCLUDE_DIRS})
|
||||
set (EXTRA_INCLUDES ${EXTRA_INCLUDES} ${SWSCALE_INCLUDE_DIRS})
|
||||
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DENABLE_HARDSUBX")
|
||||
pkg_check_modules (TESSERACT REQUIRED tesseract)
|
||||
pkg_check_modules (LEPTONICA REQUIRED lept)
|
||||
|
||||
set (EXTRA_LIBS ${EXTRA_LIBS} ${TESSERACT_LIBRARIES})
|
||||
set (EXTRA_LIBS ${EXTRA_LIBS} ${LEPTONICA_LIBRARIES})
|
||||
|
||||
set (EXTRA_INCLUDES ${EXTRA_INCLUDES} ${TESSERACT_INCLUDE_DIRS})
|
||||
set (EXTRA_INCLUDES ${EXTRA_INCLUDES} ${LEPTONICA_INCLUDE_DIRS})
|
||||
endif (PKG_CONFIG_FOUND AND WITH_HARDSUBX)
|
||||
|
||||
add_executable (ccextractor ${SOURCEFILE} ${FREETYPE_SOURCE} ${UTF8PROC_SOURCE})
|
||||
@@ -236,13 +246,11 @@ add_executable (ccextractor ${SOURCEFILE} ${FREETYPE_SOURCE} ${UTF8PROC_SOURCE})
|
||||
# Build with Rust library
|
||||
########################################################
|
||||
|
||||
if (PKG_CONFIG_FOUND AND WITH_RUST)
|
||||
if (PKG_CONFIG_FOUND)
|
||||
add_subdirectory (rust)
|
||||
get_target_property(RUST_LIB ccx_rust LOCATION)
|
||||
set (EXTRA_LIBS ${EXTRA_LIBS} ${RUST_LIB})
|
||||
add_dependencies(ccextractor ccx_rust)
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DENABLE_RUST")
|
||||
endif (PKG_CONFIG_FOUND AND WITH_RUST)
|
||||
set (EXTRA_LIBS ${EXTRA_LIBS} ccx_rust)
|
||||
endif (PKG_CONFIG_FOUND)
|
||||
|
||||
|
||||
target_link_libraries (ccextractor ${EXTRA_LIBS})
|
||||
target_include_directories (ccextractor PUBLIC ${EXTRA_INCLUDES})
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
#ifndef NK_IMPLEMENTATION
|
||||
#include "nuklear_lib/nuklear.h"
|
||||
#endif // !NK_IMPLEMENTATION
|
||||
|
||||
#include "activity.h"
|
||||
|
||||
int activity(struct nk_context *ctx, int x, int y, int width, int height, struct main_tab *main_settings)
|
||||
{
|
||||
static int i;
|
||||
if (nk_begin(ctx, "Activity", nk_rect(x, y, width, height), NK_WINDOW_TITLE | NK_WINDOW_BACKGROUND))
|
||||
{
|
||||
nk_layout_row_dynamic(ctx, 40, 1);
|
||||
for (i = 0; i < main_settings->activity_string_count; i++)
|
||||
nk_label_wrap(ctx, main_settings->activity_string[i]);
|
||||
}
|
||||
nk_end(ctx);
|
||||
return !nk_window_is_closed(ctx, "Activity");
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
#ifndef ACTIVITY_H
|
||||
#define ACTIVITY_H
|
||||
|
||||
#include "ccextractorGUI.h"
|
||||
|
||||
int activity(struct nk_context *ctx, int x, int y, int width, int height, struct main_tab *main_settings);
|
||||
|
||||
#endif
|
||||
@@ -1,902 +0,0 @@
|
||||
/* nuklear - v1.32.0 - public domain */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <limits.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <GL/glew.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#define PATH_LENGTH 66
|
||||
#define NAME_LENGTH 56
|
||||
#define PREFIX_LENGTH_TRUNCATED 10
|
||||
|
||||
#define NK_INCLUDE_FIXED_TYPES
|
||||
#define NK_INCLUDE_STANDARD_IO
|
||||
#define NK_INCLUDE_STANDARD_VARARGS
|
||||
#define NK_INCLUDE_DEFAULT_ALLOCATOR
|
||||
#define NK_INCLUDE_VERTEX_BUFFER_OUTPUT
|
||||
#define NK_INCLUDE_FONT_BAKING
|
||||
#define NK_INCLUDE_DEFAULT_FONT
|
||||
#define NK_IMPLEMENTATION
|
||||
#define NK_GLFW_GL2_IMPLEMENTATION
|
||||
#include "nuklear_lib/nuklear.h"
|
||||
#include "nuklear_lib/nuklear_glfw_gl2.h"
|
||||
|
||||
#include "icon_data.c"
|
||||
|
||||
//#define WINDOW_WIDTH 1200
|
||||
//#define WINDOW_HEIGHT 800
|
||||
//#define true 1
|
||||
//#define false 0
|
||||
//#define UNUSED(a) (void)a
|
||||
//#define MIN(a,b) ((a) < (b) ? (a) : (b))
|
||||
//#define MAX(a,b) ((a) < (b) ? (b) : (a))
|
||||
//#define LEN(a) (sizeof(a)/sizeof(a)[0])
|
||||
#include "ccextractorGUI.h"
|
||||
#include "tabs.h"
|
||||
#include "activity.h"
|
||||
#include "terminal.c"
|
||||
#include "preview.h"
|
||||
#include "popups.h"
|
||||
#include "command_builder.h"
|
||||
#include "ccx_cli_thread.h"
|
||||
#include "file_browser.h"
|
||||
#include "save_load_data.h"
|
||||
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include "stb_image.h"
|
||||
|
||||
static struct main_tab main_settings;
|
||||
|
||||
/*Trigger command for CLI*/
|
||||
char command[20];
|
||||
|
||||
/*Global Variables for Drag and Drop files*/
|
||||
|
||||
/* Width and Height of all frames*/
|
||||
const GLint WIDTH_mainPanelAndWindow = 530, HEIGHT_mainPanelandWindow = 550;
|
||||
const GLint WIDTH_termORPreviewPanel = 530, HEIGHT_termORPreviewPanel = 100;
|
||||
const GLint WIDTH_termANDPreviewPanel = 400, HEIGHT_termANDPreviewPanel = 650;
|
||||
const GLint WIDTH_activityPanel = 400, HEIGHT_activityPanelSolo = 550, HEIGHT_activityPanelDuo = 650;
|
||||
const GLint WIDTH_mainTermORPreviewWindow = 530, HEIGHT_mainORPreviewTermWindow = 650;
|
||||
const GLint WIDTH_mainTermANDPreviewWindow = 930, HEIGHT_mainTermAndPreviewWindow = 650;
|
||||
const GLint WIDTH_mainActivityWindow = 930, HEIGHT_mainActivityWindowSolo = 550, HEIGHT_mainActivityWindowDuo = 650;
|
||||
|
||||
/*Tab constants*/
|
||||
static int tab_screen_height;
|
||||
|
||||
/*Parameter Constants*/
|
||||
static int modifiedParams = 0;
|
||||
|
||||
static void error_callback(int e, const char *d)
|
||||
{
|
||||
printf("Error %d: %s\n", e, d);
|
||||
}
|
||||
|
||||
void drop_callback(GLFWwindow *window, int count, const char **paths)
|
||||
{
|
||||
int i, j, k, z, copycount, prefix_length, slash_length, fileNameTruncated_index;
|
||||
|
||||
printf("Number of selected paths:%d\n", count);
|
||||
|
||||
if (main_settings.filename_count == 0 && main_settings.filenames == NULL)
|
||||
main_settings.filenames = (char **)calloc(count + 1, sizeof(char *));
|
||||
else
|
||||
main_settings.filenames = (char **)realloc(main_settings.filenames, (main_settings.filename_count + count + 1) * sizeof(char *));
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
printf("\n%d", main_settings.filename_count);
|
||||
|
||||
main_settings.filenames[main_settings.filename_count] = (char *)calloc((strlen(paths[i]) + 5), sizeof(char));
|
||||
main_settings.filenames[main_settings.filename_count][0] = '\"';
|
||||
strcat(main_settings.filenames[main_settings.filename_count], paths[i]);
|
||||
strcat(main_settings.filenames[main_settings.filename_count], "\"");
|
||||
puts(main_settings.filenames[main_settings.filename_count]);
|
||||
main_settings.filename_count++;
|
||||
}
|
||||
main_settings.filenames[main_settings.filename_count] = NULL;
|
||||
}
|
||||
|
||||
/*Rectangle to hold file names*/
|
||||
//void draw_file_rectangle_widget(struct nk_context *ctx, struct nk_font *font)
|
||||
//{
|
||||
// struct nk_command_buffer *canvas;
|
||||
// struct nk_input *input = &ctx->input;
|
||||
// canvas = nk_window_get_canvas(ctx);
|
||||
//
|
||||
// struct nk_rect space;
|
||||
// enum nk_widget_layout_states state;
|
||||
// state = nk_widget(&space, ctx);
|
||||
// if (!state) return;
|
||||
//
|
||||
// /*if (state != NK_WIDGET_ROM)
|
||||
// update_your_widget_by_user_input(...);*/
|
||||
// nk_fill_rect(canvas, space, 5, nk_rgb(88, 81, 96));
|
||||
// if (!strcmp(filePath[0], "\0")) {
|
||||
// space.y = space.y + (space.h / 2) -10;
|
||||
// space.x = space.x + 90;
|
||||
// nk_draw_text(canvas, space, "Drag and Drop files here for Extraction.", 40, &font->handle, nk_rgb(88, 81, 96), nk_rgb(0, 0, 0));
|
||||
// }
|
||||
// else {
|
||||
// for (int i = 0; i < fileCount; i++)
|
||||
// {
|
||||
// nk_draw_text(canvas, space, filePath[i], strlen(filePath[i]), &font->handle, nk_rgb(88, 81, 96), nk_rgb(0, 0, 0));
|
||||
// space.y = space.y + 20;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//}
|
||||
|
||||
/*Rectangle to hold extraction info*/
|
||||
//void draw_info_rectangle_widget(struct nk_context *ctx, struct nk_font *font)
|
||||
//{
|
||||
// struct nk_command_buffer *canvas;
|
||||
// struct nk_input *input = &ctx->input;
|
||||
// canvas = nk_window_get_canvas(ctx);
|
||||
//
|
||||
// struct nk_rect space;
|
||||
// enum nk_widget_layout_states state;
|
||||
// state = nk_widget(&space, ctx);
|
||||
// if (!state) return;
|
||||
//
|
||||
// /*if (state != NK_WIDGET_ROM)
|
||||
// update_your_widget_by_user_input(...);*/
|
||||
// nk_fill_rect(canvas, space, 5, nk_rgb(88, 81, 96));
|
||||
// space.x = space.x + 3;
|
||||
// nk_draw_text(canvas, space, "Input Type: Auto", 16, &font->handle, nk_rgb(88, 81, 96), nk_rgb(0, 0, 0));
|
||||
// space.y = space.y + 20;
|
||||
// nk_draw_text(canvas, space, "Output Type: Default(.srt)", 26, &font->handle, nk_rgb(88, 81, 96), nk_rgb(0, 0, 0));
|
||||
// space.y = space.y + 20;
|
||||
// nk_draw_text(canvas, space, "Output Path: Default", 20, &font->handle, nk_rgb(88, 81, 96), nk_rgb(0, 0, 0));
|
||||
// space.y = space.y + 20;
|
||||
// nk_draw_text(canvas, space, "Hardsubs Extraction: Yes", 24, &font->handle, nk_rgb(88, 81, 96), nk_rgb(0, 0, 0));
|
||||
//}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
|
||||
//Platform
|
||||
static GLFWwindow *win;
|
||||
struct nk_context *ctx;
|
||||
int screenWidth, screenHeight;
|
||||
//int winWidth, winHeight;
|
||||
|
||||
//GLFW
|
||||
glfwSetErrorCallback(error_callback);
|
||||
if (!glfwInit())
|
||||
{
|
||||
fprintf(stdout, "GLFW failed to initialise.\n");
|
||||
}
|
||||
win = glfwCreateWindow(WIDTH_mainPanelAndWindow, HEIGHT_mainPanelandWindow, "CCExtractor", NULL, NULL);
|
||||
if (win == NULL)
|
||||
printf("Window Could not be created!\n");
|
||||
glfwMakeContextCurrent(win);
|
||||
glfwSetWindowSizeLimits(win, WIDTH_mainPanelAndWindow, HEIGHT_mainPanelandWindow, WIDTH_mainPanelAndWindow, HEIGHT_mainPanelandWindow);
|
||||
glfwSetWindowUserPointer(win, &ctx);
|
||||
glfwSetDropCallback(win, drop_callback);
|
||||
|
||||
if (glewInit() != GLEW_OK)
|
||||
{
|
||||
fprintf(stderr, "Failed to setup GLEW\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
//GUI
|
||||
|
||||
struct file_browser browser;
|
||||
static const struct file_browser reset_browser;
|
||||
struct media media;
|
||||
|
||||
ctx = nk_glfw3_init(win, NK_GLFW3_INSTALL_CALLBACKS);
|
||||
struct nk_font_atlas *font_atlas;
|
||||
nk_glfw3_font_stash_begin(&font_atlas);
|
||||
struct nk_font *droid = nk_font_atlas_add_from_memory(font_atlas, roboto_regular_font, sizeof(roboto_regular_font), 16, 0);
|
||||
struct nk_font *droid_big = nk_font_atlas_add_from_memory(font_atlas, roboto_regular_font, sizeof(roboto_regular_font), 25, 0);
|
||||
struct nk_font *droid_head = nk_font_atlas_add_from_memory(font_atlas, roboto_regular_font, sizeof(roboto_regular_font), 20, 0);
|
||||
nk_glfw3_font_stash_end();
|
||||
nk_style_set_font(ctx, &droid->handle);
|
||||
|
||||
//CHECKBOX VALUES
|
||||
static int show_terminal_check = nk_false;
|
||||
static int show_preview_check = nk_false;
|
||||
static int show_activity_check = nk_false;
|
||||
static int advanced_mode_check = nk_false;
|
||||
static int file_extension_check = nk_true;
|
||||
|
||||
/*Settings and tab options*/
|
||||
setup_main_settings(&main_settings);
|
||||
static struct network_popup network_settings;
|
||||
setup_network_settings(&network_settings);
|
||||
static struct output_tab output;
|
||||
setup_output_tab(&output);
|
||||
static struct decoders_tab decoders;
|
||||
setup_decoders_tab(&decoders);
|
||||
static struct credits_tab credits;
|
||||
setup_credits_tab(&credits);
|
||||
static struct input_tab input;
|
||||
setup_input_tab(&input);
|
||||
static struct advanced_input_tab advanced_input;
|
||||
setup_advanced_input_tab(&advanced_input);
|
||||
static struct debug_tab debug;
|
||||
setup_debug_tab(&debug);
|
||||
static struct hd_homerun_tab hd_homerun;
|
||||
setup_hd_homerun_tab(&hd_homerun);
|
||||
static struct burned_subs_tab burned_subs;
|
||||
setup_burned_subs_tab(&burned_subs);
|
||||
static struct built_string command;
|
||||
|
||||
/* icons */
|
||||
|
||||
media.icons.home = icon_load(home_icon_data, sizeof(home_icon_data));
|
||||
media.icons.directory = icon_load(directory_icon_data, sizeof(directory_icon_data));
|
||||
media.icons.computer = icon_load(computer_icon_data, sizeof(computer_icon_data));
|
||||
#ifdef _WIN32
|
||||
media.icons.drives = icon_load(drive_icon_data, sizeof(drive_icon_data));
|
||||
#endif
|
||||
media.icons.desktop = icon_load(desktop_icon_data, sizeof(desktop_icon_data));
|
||||
media.icons.default_file = icon_load(default_icon_data, sizeof(default_icon_data));
|
||||
media.icons.text_file = icon_load(text_icon_data, sizeof(text_icon_data));
|
||||
media.icons.music_file = icon_load(music_icon_data, sizeof(music_icon_data));
|
||||
media.icons.font_file = icon_load(font_icon_data, sizeof(font_icon_data));
|
||||
media.icons.img_file = icon_load(img_icon_data, sizeof(img_icon_data));
|
||||
media.icons.movie_file = icon_load(movie_icon_data, sizeof(movie_icon_data));
|
||||
|
||||
media_init(&media);
|
||||
|
||||
file_browser_init(&browser, &media);
|
||||
|
||||
/*Read Last run state*/
|
||||
FILE *loadFile;
|
||||
loadFile = fopen("ccxGUI.ini", "r");
|
||||
if (loadFile != NULL)
|
||||
{
|
||||
printf("File found and reading it!\n");
|
||||
load_data(loadFile, &main_settings, &input, &advanced_input, &output, &decoders, &credits, &debug, &hd_homerun, &burned_subs, &network_settings);
|
||||
fclose(loadFile);
|
||||
}
|
||||
|
||||
/*Main GUI loop*/
|
||||
while (nk_true)
|
||||
{
|
||||
if (glfwWindowShouldClose(win))
|
||||
{
|
||||
FILE *saveFile;
|
||||
saveFile = fopen("ccxGUI.ini", "w");
|
||||
save_data(saveFile, &main_settings, &input, &advanced_input, &output, &decoders, &credits, &debug, &hd_homerun, &burned_subs, &network_settings);
|
||||
fclose(saveFile);
|
||||
break;
|
||||
}
|
||||
//Input
|
||||
glfwPollEvents();
|
||||
nk_glfw3_new_frame();
|
||||
|
||||
//Popups
|
||||
static int show_progress_details = nk_false;
|
||||
static int show_about_ccx = nk_false;
|
||||
static int show_getting_started = nk_false;
|
||||
|
||||
//GUI
|
||||
if (nk_begin(ctx, "CCExtractor", nk_rect(0, 0, WIDTH_mainPanelAndWindow, HEIGHT_mainPanelandWindow),
|
||||
NK_WINDOW_NO_SCROLLBAR | NK_WINDOW_BACKGROUND))
|
||||
{
|
||||
|
||||
//MENUBAR
|
||||
nk_menubar_begin(ctx);
|
||||
nk_layout_row_begin(ctx, NK_STATIC, 30, 3);
|
||||
nk_layout_row_push(ctx, 80);
|
||||
if (nk_menu_begin_label(ctx, "Preferences", NK_TEXT_LEFT, nk_vec2(120, 200)))
|
||||
{
|
||||
nk_layout_row_dynamic(ctx, 30, 1);
|
||||
if (nk_menu_item_label(ctx, "Reset Defaults", NK_TEXT_LEFT))
|
||||
{
|
||||
remove("ccxGUI.ini");
|
||||
setup_main_settings(&main_settings);
|
||||
setup_network_settings(&network_settings);
|
||||
setup_output_tab(&output);
|
||||
setup_decoders_tab(&decoders);
|
||||
setup_credits_tab(&credits);
|
||||
setup_input_tab(&input);
|
||||
setup_advanced_input_tab(&advanced_input);
|
||||
setup_debug_tab(&debug);
|
||||
setup_hd_homerun_tab(&hd_homerun);
|
||||
setup_burned_subs_tab(&burned_subs);
|
||||
}
|
||||
if (nk_menu_item_label(ctx, "Network Settings", NK_TEXT_LEFT))
|
||||
network_settings.show_network_settings = nk_true;
|
||||
nk_menu_end(ctx);
|
||||
}
|
||||
nk_layout_row_push(ctx, 70);
|
||||
if (nk_menu_begin_label(ctx, "Windows", NK_TEXT_LEFT, nk_vec2(120, 200)))
|
||||
{
|
||||
nk_layout_row_dynamic(ctx, 30, 1);
|
||||
nk_checkbox_label(ctx, "Activity", &show_activity_check);
|
||||
nk_checkbox_label(ctx, "Terminal", &show_terminal_check);
|
||||
nk_checkbox_label(ctx, "Preview", &show_preview_check);
|
||||
nk_menu_end(ctx);
|
||||
}
|
||||
nk_layout_row_push(ctx, 45);
|
||||
if (nk_menu_begin_label(ctx, "Help", NK_TEXT_LEFT, nk_vec2(120, 200)))
|
||||
{
|
||||
nk_layout_row_dynamic(ctx, 30, 1);
|
||||
if (nk_menu_item_label(ctx, "Getting Started", NK_TEXT_LEFT))
|
||||
show_getting_started = nk_true;
|
||||
if (nk_menu_item_label(ctx, "About CCExtractor", NK_TEXT_LEFT))
|
||||
show_about_ccx = nk_true;
|
||||
nk_menu_end(ctx);
|
||||
}
|
||||
|
||||
//Network Settings
|
||||
if (network_settings.show_network_settings)
|
||||
draw_network_popup(ctx, &network_settings);
|
||||
|
||||
//About CCExtractor Popup
|
||||
if (show_about_ccx)
|
||||
draw_about_ccx_popup(ctx, &show_about_ccx, &droid_big->handle, &droid_head->handle);
|
||||
|
||||
//Getting Started
|
||||
if (show_getting_started)
|
||||
draw_getting_started_popup(ctx, &show_getting_started);
|
||||
|
||||
//Color Popup
|
||||
if (output.color_popup)
|
||||
draw_color_popup(ctx, &output);
|
||||
|
||||
//File Browser as Popup
|
||||
if (main_settings.scaleWindowForFileBrowser)
|
||||
{
|
||||
int width = 0, height = 0;
|
||||
glfwGetWindowSize(win, &width, &height);
|
||||
glfwSetWindowSize(win, 930, 650);
|
||||
glfwSetWindowSizeLimits(win, 930, 650, 930, 650);
|
||||
file_browser_run(&browser, ctx, &main_settings, &output, &debug, &hd_homerun);
|
||||
}
|
||||
|
||||
//Thread popop when file can't be read
|
||||
if (main_settings.threadPopup)
|
||||
draw_thread_popup(ctx, &main_settings.threadPopup);
|
||||
|
||||
//Thread popup for hd_homerun thread
|
||||
if (hd_homerun.threadPopup)
|
||||
draw_thread_popup(ctx, &hd_homerun.threadPopup);
|
||||
|
||||
nk_layout_row_end(ctx);
|
||||
nk_menubar_end(ctx);
|
||||
nk_layout_space_begin(ctx, NK_STATIC, 15, 1);
|
||||
nk_layout_space_end(ctx);
|
||||
|
||||
/*TABS TRIGGERED IN ADVANCED MODE FLAG*/
|
||||
if (advanced_mode_check)
|
||||
{
|
||||
static int current_tab = 0;
|
||||
enum tab_name
|
||||
{
|
||||
MAIN,
|
||||
INPUT,
|
||||
ADV_INPUT,
|
||||
OUTPUT,
|
||||
DECODERS,
|
||||
CREDITS,
|
||||
DEBUG,
|
||||
HDHOMERUN,
|
||||
BURNEDSUBS
|
||||
};
|
||||
const char *names[] = {"Main", "Input", "Advanced Input", "Output", "Decoders", "Credits", "Debug", "HDHomeRun", "BurnedSubs"};
|
||||
float id = 0;
|
||||
int i;
|
||||
|
||||
nk_style_push_vec2(ctx, &ctx->style.window.spacing, nk_vec2(0, 0));
|
||||
nk_style_push_float(ctx, &ctx->style.button.rounding, 0);
|
||||
nk_layout_row_begin(ctx, NK_STATIC, 20, 9);
|
||||
for (i = 0; i < 9; ++i)
|
||||
{
|
||||
/*Make sure button perfectly fits text*/
|
||||
const struct nk_user_font *f = ctx->style.font;
|
||||
float text_width = f->width(f->userdata, f->height, names[i], nk_strlen(names[i]));
|
||||
float widget_width = text_width + 3 * ctx->style.button.padding.x;
|
||||
nk_layout_row_push(ctx, widget_width);
|
||||
if (current_tab == i)
|
||||
{
|
||||
/*Active tab gets highlighted*/
|
||||
struct nk_style_item button_color = ctx->style.button.normal;
|
||||
ctx->style.button.normal = ctx->style.button.active;
|
||||
current_tab = nk_button_label(ctx, names[i]) ? i : current_tab;
|
||||
ctx->style.button.normal = button_color;
|
||||
}
|
||||
else
|
||||
current_tab = nk_button_label(ctx, names[i]) ? i : current_tab;
|
||||
}
|
||||
nk_style_pop_float(ctx);
|
||||
/*Body*/
|
||||
|
||||
nk_layout_row_dynamic(ctx, tab_screen_height, 1);
|
||||
if (nk_group_begin(ctx, "Advanced Tabs", NK_WINDOW_NO_SCROLLBAR))
|
||||
{
|
||||
nk_style_pop_vec2(ctx);
|
||||
switch (current_tab)
|
||||
{
|
||||
case MAIN:
|
||||
tab_screen_height = 0;
|
||||
break;
|
||||
|
||||
case INPUT:
|
||||
draw_input_tab(ctx, &tab_screen_height, &input, &decoders);
|
||||
break;
|
||||
|
||||
case ADV_INPUT:
|
||||
draw_advanced_input_tab(ctx, &tab_screen_height, &advanced_input);
|
||||
break;
|
||||
|
||||
case OUTPUT:
|
||||
draw_output_tab(ctx, &tab_screen_height, &output, &main_settings);
|
||||
break;
|
||||
|
||||
case DECODERS:
|
||||
draw_decoders_tab(ctx, &tab_screen_height, &decoders);
|
||||
break;
|
||||
|
||||
case CREDITS:
|
||||
draw_credits_tab(ctx, &tab_screen_height, &credits);
|
||||
break;
|
||||
|
||||
case DEBUG:
|
||||
draw_debug_tab(ctx, &tab_screen_height, &main_settings, &output, &debug);
|
||||
break;
|
||||
|
||||
case HDHOMERUN:
|
||||
draw_hd_homerun_tab(ctx, &tab_screen_height, &hd_homerun, &main_settings);
|
||||
break;
|
||||
|
||||
case BURNEDSUBS:
|
||||
draw_burned_subs_tab(ctx, &tab_screen_height, &burned_subs);
|
||||
break;
|
||||
}
|
||||
nk_group_end(ctx);
|
||||
}
|
||||
else
|
||||
nk_style_pop_vec2(ctx);
|
||||
}
|
||||
|
||||
//ADVANCED MODE FLAG
|
||||
static const float ratio_adv_mode[] = {0.75f, 0.22f, .03f};
|
||||
nk_layout_row(ctx, NK_DYNAMIC, 20, 3, ratio_adv_mode);
|
||||
nk_spacing(ctx, 1);
|
||||
nk_checkbox_label(ctx, "Advanced Mode", &advanced_mode_check);
|
||||
|
||||
//RADIO BUTTON 1
|
||||
static const float ratio_button[] = {.10f, .90f};
|
||||
static const float check_extension_ratio[] = {.10f, .53f, .12f, .15f, .10f};
|
||||
//static int op = FILES;
|
||||
nk_layout_row(ctx, NK_DYNAMIC, 20, 2, ratio_button);
|
||||
nk_spacing(ctx, 1);
|
||||
if (nk_option_label(ctx, "Extract from files below:", main_settings.port_or_files == FILES))
|
||||
{
|
||||
//op = FILES;
|
||||
main_settings.port_or_files = FILES;
|
||||
}
|
||||
|
||||
//CHECKBOX FOR FILE TYPES
|
||||
static int add_remove_button = nk_false;
|
||||
nk_layout_row(ctx, NK_DYNAMIC, 20, 5, check_extension_ratio);
|
||||
nk_spacing(ctx, 1);
|
||||
nk_checkbox_label(ctx, "Check for common video file extensions", &file_extension_check);
|
||||
if (main_settings.filename_count > 0)
|
||||
{
|
||||
if (nk_button_label(ctx, "Add"))
|
||||
{
|
||||
main_settings.is_file_browser_active = nk_true;
|
||||
main_settings.scaleWindowForFileBrowser = nk_true;
|
||||
}
|
||||
|
||||
for (int i = 0; i < main_settings.filename_count; i++)
|
||||
{
|
||||
if (main_settings.is_file_selected[i])
|
||||
{
|
||||
add_remove_button = nk_true;
|
||||
break;
|
||||
}
|
||||
else
|
||||
add_remove_button = nk_false;
|
||||
}
|
||||
if (add_remove_button)
|
||||
{
|
||||
|
||||
if (nk_button_label(ctx, "Remove"))
|
||||
{
|
||||
for (int i = main_settings.filename_count - 1; i != -1; i--)
|
||||
if (main_settings.is_file_selected[i])
|
||||
{
|
||||
remove_path_entry(&main_settings, i);
|
||||
main_settings.is_file_selected[i] = nk_false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else if (nk_button_label(ctx, "Clear"))
|
||||
{
|
||||
free(main_settings.filenames);
|
||||
main_settings.filename_count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//RECTANGLE-FILES
|
||||
static const float ratio_rect_files[] = {0.10f, 0.80f};
|
||||
nk_layout_row(ctx, NK_DYNAMIC, 180, 2, ratio_rect_files);
|
||||
nk_spacing(ctx, 1);
|
||||
if (nk_group_begin(ctx, "Files in extraction queue:", NK_WINDOW_BORDER | NK_WINDOW_TITLE))
|
||||
{
|
||||
if (main_settings.filename_count != 0)
|
||||
{
|
||||
int i = 0;
|
||||
nk_layout_row_static(ctx, 18, 380, 1);
|
||||
for (i = 0; i < main_settings.filename_count; ++i)
|
||||
nk_selectable_label(ctx, truncate_path_string(main_settings.filenames[i]), NK_TEXT_LEFT, &main_settings.is_file_selected[i]);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
nk_layout_row_dynamic(ctx, 1, 1);
|
||||
nk_spacing(ctx, 1);
|
||||
nk_layout_row_dynamic(ctx, 25, 1);
|
||||
nk_label(ctx, "Drag and Drop files for extraction.", NK_TEXT_CENTERED);
|
||||
nk_layout_row_dynamic(ctx, 25, 1);
|
||||
nk_label(ctx, "OR", NK_TEXT_CENTERED);
|
||||
nk_layout_row_dynamic(ctx, 25, 3);
|
||||
nk_spacing(ctx, 1);
|
||||
if (nk_button_label(ctx, "Browse Files"))
|
||||
{
|
||||
main_settings.is_file_browser_active = nk_true;
|
||||
main_settings.scaleWindowForFileBrowser = nk_true;
|
||||
}
|
||||
nk_spacing(ctx, 1);
|
||||
}
|
||||
nk_group_end(ctx);
|
||||
}
|
||||
|
||||
//RadioButton 2 along with combobox
|
||||
static const float ratio_port[] = {0.10f, 0.20f, 0.20f, 0.20f, 0.20f, 0.10f};
|
||||
nk_layout_row(ctx, NK_DYNAMIC, 20, 6, ratio_port);
|
||||
nk_spacing(ctx, 1);
|
||||
if (nk_option_label(ctx, "Extract from", main_settings.port_or_files == PORT))
|
||||
{
|
||||
//op = PORT;
|
||||
main_settings.port_or_files = PORT;
|
||||
}
|
||||
main_settings.port_select = nk_combo(ctx, main_settings.port_type, 2, main_settings.port_select, 20, nk_vec2(85, 100));
|
||||
nk_label(ctx, " stream, on port:", NK_TEXT_LEFT);
|
||||
|
||||
//RADDIO BUTTON 2, TEXTEDIT FOR ENTERING PORT NUMBER
|
||||
|
||||
static int len;
|
||||
static char buffer[10];
|
||||
nk_edit_string(ctx, NK_EDIT_SIMPLE, main_settings.port_num, &main_settings.port_num_len, 8, nk_filter_decimal);
|
||||
nk_layout_space_begin(ctx, NK_STATIC, 10, 1);
|
||||
nk_layout_space_end(ctx);
|
||||
|
||||
//Extraction Information
|
||||
nk_layout_row_dynamic(ctx, 10, 1);
|
||||
nk_text(ctx, "Extraction Info:", 16, NK_TEXT_CENTERED);
|
||||
|
||||
//RECTANGLE-INFO
|
||||
static const float ratio_rect_info[] = {0.10f, 0.80f, 0.10f};
|
||||
nk_layout_row(ctx, NK_DYNAMIC, 75, 2, ratio_rect_info);
|
||||
nk_spacing(ctx, 1);
|
||||
if (nk_group_begin(ctx, "Extraction Info:", NK_WINDOW_BORDER))
|
||||
{
|
||||
if (main_settings.filename_count != 0)
|
||||
{
|
||||
nk_layout_row_static(ctx, 18, 380, 1);
|
||||
nk_label(ctx, concat("Input type: ", input.type[input.type_select]), NK_TEXT_LEFT);
|
||||
nk_label(ctx, concat("Output type: ", output.type[output.type_select]), NK_TEXT_LEFT);
|
||||
if (output.is_filename)
|
||||
nk_label(ctx, concat("Output path: ", output.filename), NK_TEXT_LEFT);
|
||||
else
|
||||
nk_label(ctx, "Output path: Default", NK_TEXT_LEFT);
|
||||
if (burned_subs.is_burned_subs)
|
||||
nk_label(ctx, "Hardsubtitles extraction: Yes", NK_TEXT_LEFT);
|
||||
else
|
||||
nk_label(ctx, "Hardsubtitles extraction: No", NK_TEXT_LEFT);
|
||||
}
|
||||
nk_group_end(ctx);
|
||||
}
|
||||
|
||||
nk_layout_space_begin(ctx, NK_STATIC, 10, 1);
|
||||
nk_layout_space_end(ctx);
|
||||
//PROGRESSBAR
|
||||
static const float ratio_progress[] = {0.10f, 0.03f, 0.57f, 0.03f, 0.17f, 0.10f};
|
||||
nk_layout_row(ctx, NK_DYNAMIC, 20, 6, ratio_progress);
|
||||
nk_spacing(ctx, 1);
|
||||
nk_spacing(ctx, 1);
|
||||
nk_progress(ctx, &main_settings.progress_cursor, 101, nk_false);
|
||||
|
||||
//Extract Button
|
||||
nk_spacing(ctx, 1);
|
||||
if (nk_button_label(ctx, "Extract"))
|
||||
{
|
||||
|
||||
setup_and_create_thread(&main_settings, &command);
|
||||
}
|
||||
|
||||
nk_layout_space_begin(ctx, NK_STATIC, 10, 1);
|
||||
nk_layout_space_end(ctx);
|
||||
|
||||
//PROGRESS_DETAILS_BUTTON
|
||||
if (!show_activity_check)
|
||||
{
|
||||
nk_layout_row_dynamic(ctx, 20, 3);
|
||||
nk_spacing(ctx, 1);
|
||||
if (nk_button_label(ctx, "Progress Details"))
|
||||
{
|
||||
show_progress_details = nk_true;
|
||||
}
|
||||
nk_spacing(ctx, 1);
|
||||
}
|
||||
|
||||
//PROGRESS_DETAILS_POPUP
|
||||
if (show_progress_details)
|
||||
draw_progress_details_popup(ctx, &show_progress_details, &main_settings);
|
||||
|
||||
//build command string
|
||||
command_builder(&command, &main_settings, &network_settings, &input, &advanced_input, &output, &decoders, &credits, &debug, &burned_subs);
|
||||
}
|
||||
nk_end(ctx);
|
||||
|
||||
glfwGetWindowSize(win, &screenWidth, &screenHeight);
|
||||
|
||||
if (!main_settings.scaleWindowForFileBrowser)
|
||||
{
|
||||
if (show_activity_check && show_preview_check && show_terminal_check)
|
||||
{
|
||||
if (screenWidth != 930 || screenHeight != 650)
|
||||
{
|
||||
glfwSetWindowSize(win, 930, 550);
|
||||
glfwSetWindowSizeLimits(win, 930, 650, 930, 650);
|
||||
}
|
||||
preview(ctx, 530, 0, 400, 550, &main_settings);
|
||||
terminal(ctx, 0, 550, 530, 100, &command.term_string);
|
||||
activity(ctx, 530, 550, 400, 100, &main_settings);
|
||||
}
|
||||
if (show_activity_check && show_preview_check && !show_terminal_check)
|
||||
{
|
||||
if (screenWidth != 930 || screenHeight != 650)
|
||||
{
|
||||
glfwSetWindowSize(win, 930, 650);
|
||||
glfwSetWindowSizeLimits(win, 930, 650, 930, 650);
|
||||
}
|
||||
preview(ctx, 530, 0, 400, 650, &main_settings);
|
||||
activity(ctx, 0, 550, 530, 100, &main_settings);
|
||||
}
|
||||
if (show_activity_check && !show_preview_check && show_terminal_check)
|
||||
{
|
||||
if (screenWidth != 930 || screenHeight != 650)
|
||||
{
|
||||
glfwSetWindowSize(win, 930, 650);
|
||||
glfwSetWindowSizeLimits(win, 930, 650, 930, 650);
|
||||
}
|
||||
activity(ctx, 530, 0, 400, 650, &main_settings);
|
||||
terminal(ctx, 0, 550, 530, 100, &command.term_string);
|
||||
}
|
||||
if (show_terminal_check && show_preview_check && !show_activity_check)
|
||||
{
|
||||
if (screenWidth != 930 || screenHeight != 650)
|
||||
{
|
||||
glfwSetWindowSize(win, 930, 650);
|
||||
glfwSetWindowSizeLimits(win, 930, 650, 930, 650);
|
||||
}
|
||||
terminal(ctx, 0, 550, 530, 100, &command.term_string);
|
||||
preview(ctx, 530, 0, 400, 650, &main_settings);
|
||||
}
|
||||
if (show_activity_check && !show_preview_check && !show_terminal_check)
|
||||
{
|
||||
if (screenWidth != 930 || screenHeight == 650)
|
||||
{
|
||||
glfwSetWindowSize(win, 930, 550);
|
||||
glfwSetWindowSizeLimits(win, 930, 550, 930, 550);
|
||||
}
|
||||
activity(ctx, 530, 0, 400, 550, &main_settings);
|
||||
}
|
||||
if (show_terminal_check && !show_activity_check && !show_preview_check)
|
||||
{
|
||||
if (screenHeight != 650 || screenWidth == 930)
|
||||
{
|
||||
glfwSetWindowSize(win, 530, 650);
|
||||
glfwSetWindowSizeLimits(win, 530, 650, 530, 650);
|
||||
}
|
||||
terminal(ctx, 0, 550, 530, 100, &command.term_string);
|
||||
}
|
||||
if (show_preview_check && !show_terminal_check && !show_activity_check)
|
||||
{
|
||||
if (screenHeight != 650 || screenWidth == 930)
|
||||
{
|
||||
glfwSetWindowSize(win, 930, 550);
|
||||
glfwSetWindowSizeLimits(win, 930, 550, 930, 550);
|
||||
}
|
||||
preview(ctx, 530, 0, 400, 550, &main_settings);
|
||||
}
|
||||
if (!show_preview_check && !show_terminal_check && !show_activity_check)
|
||||
{
|
||||
glfwSetWindowSize(win, WIDTH_mainPanelAndWindow, HEIGHT_mainPanelandWindow);
|
||||
glfwSetWindowSizeLimits(win, WIDTH_mainPanelAndWindow, HEIGHT_mainPanelandWindow,
|
||||
WIDTH_mainPanelAndWindow, HEIGHT_mainPanelandWindow);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
glfwSetWindowSize(win, 930, 650);
|
||||
glfwSetWindowSizeLimits(win, 930, 650, 930, 650);
|
||||
}
|
||||
|
||||
glViewport(0, 0, screenWidth, screenHeight);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
/* IMPORTANT: `nk_glfw_render` modifies some global OpenGL state
|
||||
* with blending, scissor, face culling and depth test and defaults everything
|
||||
* back into a default state. Make sure to either save and restore or
|
||||
* reset your own state after drawing rendering the UI. */
|
||||
nk_glfw3_render(NK_ANTI_ALIASING_ON);
|
||||
glfwSwapBuffers(win);
|
||||
}
|
||||
|
||||
glDeleteTextures(1, (const GLuint *)&media.icons.home.handle.id);
|
||||
glDeleteTextures(1, (const GLuint *)&media.icons.directory.handle.id);
|
||||
glDeleteTextures(1, (const GLuint *)&media.icons.computer.handle.id);
|
||||
#ifdef _WIN32
|
||||
glDeleteTextures(1, (const GLuint *)&media.icons.drives.handle.id);
|
||||
#endif
|
||||
glDeleteTextures(1, (const GLuint *)&media.icons.desktop.handle.id);
|
||||
glDeleteTextures(1, (const GLuint *)&media.icons.default_file.handle.id);
|
||||
glDeleteTextures(1, (const GLuint *)&media.icons.text_file.handle.id);
|
||||
glDeleteTextures(1, (const GLuint *)&media.icons.music_file.handle.id);
|
||||
glDeleteTextures(1, (const GLuint *)&media.icons.font_file.handle.id);
|
||||
glDeleteTextures(1, (const GLuint *)&media.icons.img_file.handle.id);
|
||||
glDeleteTextures(1, (const GLuint *)&media.icons.movie_file.handle.id);
|
||||
|
||||
file_browser_free(&browser);
|
||||
//free(main_settings.filenames);
|
||||
|
||||
nk_glfw3_shutdown();
|
||||
glfwTerminate();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void setup_main_settings(struct main_tab *main_settings)
|
||||
{
|
||||
|
||||
main_settings->is_check_common_extension = nk_false;
|
||||
main_settings->port_num_len = 0;
|
||||
main_settings->port_or_files = FILES;
|
||||
main_settings->port_type = (char **)malloc(2 * sizeof(char *));
|
||||
main_settings->port_type[0] = "UDP";
|
||||
main_settings->port_type[1] = "TCP";
|
||||
main_settings->port_select = 0;
|
||||
main_settings->is_file_browser_active = nk_false;
|
||||
main_settings->scaleWindowForFileBrowser = nk_false;
|
||||
main_settings->preview_string_count = 0;
|
||||
main_settings->activity_string_count = 0;
|
||||
main_settings->threadPopup = nk_false;
|
||||
}
|
||||
|
||||
char *truncate_path_string(char *filePath)
|
||||
{
|
||||
char *file_path = strdup(filePath);
|
||||
int i, j, z, slash_length, fileNameTruncated_index, copycount, prefix_length;
|
||||
char file_name[PATH_LENGTH], *ptr_slash, fileNameTruncated[NAME_LENGTH];
|
||||
//strcpy(filePath[i], paths[i]);
|
||||
if (strlen(filePath) >= PATH_LENGTH - 1)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
ptr_slash = strrchr(file_path, '\\');
|
||||
#else
|
||||
ptr_slash = strrchr(file_path, '/');
|
||||
#endif
|
||||
slash_length = strlen(ptr_slash);
|
||||
if (slash_length >= NAME_LENGTH)
|
||||
{
|
||||
fileNameTruncated_index = NAME_LENGTH - 1;
|
||||
for (z = 0; z < 6; z++)
|
||||
{
|
||||
fileNameTruncated[fileNameTruncated_index] = ptr_slash[slash_length];
|
||||
fileNameTruncated_index--;
|
||||
slash_length--;
|
||||
}
|
||||
for (z = 0; z < 4; z++)
|
||||
{
|
||||
fileNameTruncated[fileNameTruncated_index] = '.';
|
||||
fileNameTruncated_index--;
|
||||
}
|
||||
strncpy(fileNameTruncated, ptr_slash, 47);
|
||||
|
||||
strncpy(file_name, file_path, 7);
|
||||
file_name[7] = '.';
|
||||
file_name[8] = '.';
|
||||
file_name[9] = '.';
|
||||
file_name[10] = '\0';
|
||||
file_name[11] = '\0';
|
||||
file_name[12] = '\0';
|
||||
strcat(file_name, fileNameTruncated);
|
||||
strcpy(file_path, file_name);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
copycount = PATH_LENGTH - 1;
|
||||
prefix_length = copycount - slash_length - 3;
|
||||
strncpy(file_name, file_path, prefix_length);
|
||||
while (slash_length >= 0)
|
||||
{
|
||||
file_name[copycount] = ptr_slash[slash_length];
|
||||
copycount--;
|
||||
slash_length--;
|
||||
}
|
||||
for (j = 0; j < 3; j++, copycount--)
|
||||
file_name[copycount] = '.';
|
||||
|
||||
file_name[65] = '\0';
|
||||
strcpy(file_path, file_name);
|
||||
}
|
||||
return file_path;
|
||||
}
|
||||
else
|
||||
return filePath;
|
||||
}
|
||||
|
||||
void remove_path_entry(struct main_tab *main_settings, int indexToRemove)
|
||||
{
|
||||
//printf("Beginning processing. Array is currently: ");
|
||||
//for (int i = 0; i < arraySize; ++i)
|
||||
// printf("%d ", (*array)[i]);
|
||||
//printf("\n");
|
||||
|
||||
char **temp = (char **)calloc(main_settings->filename_count, sizeof(char *)); // allocate an array with a size 1 less than the current one
|
||||
|
||||
memmove(
|
||||
temp,
|
||||
main_settings->filenames,
|
||||
(indexToRemove + 1) * sizeof(char *)); // copy everything BEFORE the index
|
||||
|
||||
memmove(
|
||||
temp + indexToRemove,
|
||||
(main_settings->filenames) + (indexToRemove + 1),
|
||||
(main_settings->filename_count - indexToRemove) * sizeof(char *)); // copy everything AFTER the index
|
||||
|
||||
free(main_settings->filenames);
|
||||
main_settings->filenames = temp;
|
||||
main_settings->filename_count--;
|
||||
main_settings->filenames[main_settings->filename_count] = NULL;
|
||||
}
|
||||
|
||||
struct nk_image
|
||||
icon_load(char icon_data[], int len)
|
||||
{
|
||||
int x, y, n;
|
||||
GLuint tex;
|
||||
|
||||
unsigned char *data = stbi_load_from_memory(icon_data, len, &x, &y, &n, 0);
|
||||
if (!data)
|
||||
die("[SDL]: failed to load icons");
|
||||
|
||||
glGenTextures(1, &tex);
|
||||
glBindTexture(GL_TEXTURE_2D, tex);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_NEAREST);
|
||||
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, x, y, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
stbi_image_free(data);
|
||||
return nk_image_id((int)tex);
|
||||
}
|
||||
|
||||
char *concat(char *string1, char *string2)
|
||||
{
|
||||
static char prefix[300], suffix[300];
|
||||
strcpy(prefix, string1);
|
||||
strcpy(suffix, string2);
|
||||
return strcat(prefix, suffix);
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
#ifndef CCEXTRACTORGUI_H
|
||||
#define CCEXTRACTORGUI_H
|
||||
|
||||
#ifndef NK_IMPLEMENTATION
|
||||
#include "nuklear_lib/nuklear.h"
|
||||
#endif // !NK_IMPLEMENTATION
|
||||
|
||||
|
||||
struct main_tab
|
||||
{
|
||||
enum {PORT, FILES} port_or_files;
|
||||
char port_num[8];
|
||||
int port_num_len;
|
||||
int is_check_common_extension;
|
||||
char **port_type;
|
||||
int port_select;
|
||||
char **filenames;
|
||||
int filename_count;
|
||||
int is_file_selected[1000];
|
||||
int is_file_browser_active;
|
||||
int scaleWindowForFileBrowser;
|
||||
nk_size progress_cursor;
|
||||
char** activity_string;
|
||||
int activity_string_count;
|
||||
char** preview_string;
|
||||
int preview_string_count;
|
||||
int threadPopup;
|
||||
};
|
||||
|
||||
void setup_main_settings(struct main_tab *main_settings);
|
||||
char* truncate_path_string(char *filePath);
|
||||
void remove_path_entry(struct main_tab *main_settings, int indexToRemove);
|
||||
char* concat(char* string1, char *string2);
|
||||
|
||||
#endif //!CCEXTRACTORGUI_H
|
||||
@@ -1,374 +0,0 @@
|
||||
#include "ccx_cli_thread.h"
|
||||
#include "ccextractorGUI.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#define MAX_WAIT 10
|
||||
#define PROGRESS_COMPLETE 100
|
||||
|
||||
void *extract_thread(void *extract_args)
|
||||
{
|
||||
struct args_extract *params = (struct args_extract *)extract_args;
|
||||
static char term_string[500];
|
||||
strcpy(term_string, params->command_string);
|
||||
strcat(term_string, " ");
|
||||
strcat(term_string, params->file_string);
|
||||
strcat(term_string, " 1>>ccx.log 2>>gui_report.log");
|
||||
printf("%s", term_string);
|
||||
system(term_string);
|
||||
pthread_exit(0);
|
||||
}
|
||||
|
||||
void *read_activity_data(void *read_args)
|
||||
{
|
||||
puts("Inside activity thread!");
|
||||
char line[500];
|
||||
char buffer[500];
|
||||
#if UNIX
|
||||
struct timespec time;
|
||||
time.tv_sec = 0;
|
||||
time.tv_nsec = 10000000L;
|
||||
#endif
|
||||
int wait = 0;
|
||||
struct args_extract *read_params = (struct args_extract *)read_args;
|
||||
FILE *file;
|
||||
char current_input[500];
|
||||
int concat_index = 0;
|
||||
file = fopen("ccx.log", "r");
|
||||
|
||||
while (file == NULL)
|
||||
{
|
||||
printf("Cannot open ccx.log, trying again.\n");
|
||||
file = fopen("ccx.log", "r");
|
||||
#if UNIX
|
||||
nanosleep(&time, NULL);
|
||||
#else
|
||||
_sleep(10);
|
||||
#endif
|
||||
wait++;
|
||||
if (wait == MAX_WAIT)
|
||||
{
|
||||
read_params->main_threadsettings->threadPopup = nk_true;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
while (!feof(file))
|
||||
{
|
||||
if (fgets(current_input, sizeof(current_input), file) == NULL)
|
||||
continue;
|
||||
if (concat_index == 0)
|
||||
{
|
||||
strcpy(line, current_input);
|
||||
}
|
||||
else
|
||||
{
|
||||
strcat(line, current_input);
|
||||
}
|
||||
concat_index++;
|
||||
if (current_input[strlen(current_input) - 1] != '\n')
|
||||
continue;
|
||||
|
||||
sscanf(line, "%[^\n]", buffer);
|
||||
if (read_params->main_threadsettings->activity_string_count == 0)
|
||||
read_params->main_threadsettings->activity_string =
|
||||
malloc(sizeof(*read_params->main_threadsettings->activity_string));
|
||||
else
|
||||
read_params->main_threadsettings->activity_string =
|
||||
realloc(read_params->main_threadsettings->activity_string,
|
||||
(read_params->main_threadsettings->activity_string_count + 1) * sizeof(char *));
|
||||
|
||||
read_params->main_threadsettings->activity_string[read_params->main_threadsettings->activity_string_count] = strdup(buffer);
|
||||
read_params->main_threadsettings->activity_string_count++;
|
||||
|
||||
memset(line, 0, sizeof(line));
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
concat_index = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void *read_data_from_thread(void *read_args)
|
||||
{
|
||||
pthread_t tid_activity;
|
||||
pthread_attr_t attr_activity;
|
||||
static char buffer[500];
|
||||
char t_start[6], t_end[6], subtitle1[100], subtitle2[100];
|
||||
#if UNIX
|
||||
struct timespec time;
|
||||
time.tv_sec = 0;
|
||||
time.tv_nsec = 10000000L;
|
||||
#endif
|
||||
|
||||
int wait = 0;
|
||||
struct args_extract *read_params = (struct args_extract *)read_args;
|
||||
int unknown1 = 0, unknown2 = 0, progress_count = 0;
|
||||
FILE *file;
|
||||
char prev_line[500];
|
||||
char line[500];
|
||||
char current_input[500];
|
||||
int concat_index = 0;
|
||||
char sub_line[500];
|
||||
char prog_line[500];
|
||||
int subs_success1, subs_success2, progress_success;
|
||||
|
||||
/*Setup activity thread*/
|
||||
pthread_attr_init(&attr_activity);
|
||||
int err = pthread_create(&tid_activity, &attr_activity, read_activity_data, read_params);
|
||||
if (!err)
|
||||
puts("Activity Thread created");
|
||||
|
||||
file = fopen("gui_report.log", "r");
|
||||
|
||||
while (file == NULL)
|
||||
{
|
||||
printf("Cannot open gui_report.log, trying again.\n");
|
||||
file = fopen("gui_report.log", "r");
|
||||
#if UNIX
|
||||
nanosleep(&time, NULL);
|
||||
#else
|
||||
_sleep(10);
|
||||
#endif
|
||||
wait++;
|
||||
if (wait >= MAX_WAIT)
|
||||
{
|
||||
read_params->main_threadsettings->threadPopup = nk_true;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (fgets(current_input, sizeof(current_input), file) == NULL)
|
||||
continue;
|
||||
if (concat_index == 0)
|
||||
{
|
||||
strcpy(line, current_input);
|
||||
}
|
||||
else
|
||||
{
|
||||
strcat(line, current_input);
|
||||
}
|
||||
concat_index++;
|
||||
if (current_input[strlen(current_input) - 1] != '\n')
|
||||
continue;
|
||||
|
||||
progress_success = sscanf(line, "###PROGRESS#%d#%d#%d", &progress_count, &unknown1, &unknown2);
|
||||
if (progress_success == 3)
|
||||
read_params->main_threadsettings->progress_cursor = progress_count;
|
||||
subs_success1 = sscanf(line, "###SUBTITLE#%[^#]#%[^#]#%[^\n]", t_start, t_end, subtitle1);
|
||||
subs_success2 = sscanf(line, "###SUBTITLE###%[^\n]", subtitle2);
|
||||
if (subs_success1 == 3)
|
||||
{
|
||||
sprintf(buffer, "%s-%s: %s", t_start, t_end, subtitle1);
|
||||
if (read_params->main_threadsettings->preview_string_count == 0)
|
||||
read_params->main_threadsettings->preview_string =
|
||||
malloc(sizeof(*read_params->main_threadsettings->preview_string));
|
||||
else
|
||||
read_params->main_threadsettings->preview_string =
|
||||
realloc(read_params->main_threadsettings->preview_string,
|
||||
(read_params->main_threadsettings->preview_string_count + 1) * sizeof(char *));
|
||||
|
||||
read_params->main_threadsettings->preview_string[read_params->main_threadsettings->preview_string_count] = strdup(buffer);
|
||||
read_params->main_threadsettings->preview_string_count++;
|
||||
}
|
||||
|
||||
if (subs_success2 == 1)
|
||||
{
|
||||
sprintf(buffer, " %s", subtitle2);
|
||||
if (read_params->main_threadsettings->preview_string_count == 0)
|
||||
read_params->main_threadsettings->preview_string =
|
||||
malloc(sizeof(*read_params->main_threadsettings->preview_string));
|
||||
else
|
||||
read_params->main_threadsettings->preview_string =
|
||||
realloc(read_params->main_threadsettings->preview_string,
|
||||
(read_params->main_threadsettings->preview_string_count + 1) * sizeof(char *));
|
||||
|
||||
read_params->main_threadsettings->preview_string[read_params->main_threadsettings->preview_string_count] = strdup(buffer);
|
||||
read_params->main_threadsettings->preview_string_count++;
|
||||
}
|
||||
|
||||
if (progress_count == PROGRESS_COMPLETE)
|
||||
break;
|
||||
memset(line, 0, sizeof(line));
|
||||
concat_index = 0;
|
||||
}
|
||||
|
||||
printf("progress count:%d\n", progress_count);
|
||||
fclose(file);
|
||||
printf("File closed\n");
|
||||
for (int i = 0; i < read_params->main_threadsettings->preview_string_count; i++)
|
||||
printf("%s\n", read_params->main_threadsettings->preview_string[i]);
|
||||
pthread_exit(0);
|
||||
}
|
||||
|
||||
void *feed_files_for_extraction(void *file_args)
|
||||
{
|
||||
printf("Inside feeder\n");
|
||||
|
||||
struct args_extract *extract_params = (struct args_extract *)file_args;
|
||||
printf("count:%d\n", extract_params->main_threadsettings->filename_count);
|
||||
extract_params->command_string = extract_params->threadcommand->term_string;
|
||||
int count = extract_params->main_threadsettings->filename_count;
|
||||
pthread_t tid_extract, tid_read;
|
||||
pthread_attr_t attr_extract, attr_read;
|
||||
|
||||
for (int i = 0; count != 0; i++, count--)
|
||||
{
|
||||
pthread_t tid_extract, tid_read;
|
||||
pthread_attr_t attr_extract, attr_read;
|
||||
|
||||
pthread_attr_init(&attr_extract);
|
||||
pthread_attr_init(&attr_read);
|
||||
|
||||
extract_params->main_threadsettings->is_file_selected[i] = nk_true;
|
||||
extract_args.file_string = extract_params->main_threadsettings->filenames[i];
|
||||
int err1 = pthread_create(&tid_extract, &attr_extract, extract_thread, extract_params);
|
||||
int err2 = pthread_create(&tid_read, &attr_read, read_data_from_thread, extract_params);
|
||||
if (!err1)
|
||||
printf("Extraction Thread Complete:%d\n", i);
|
||||
if (!err2)
|
||||
printf("Read Thread Complete:%d\n", i);
|
||||
|
||||
pthread_join(tid_extract, NULL);
|
||||
printf("Extract thread joined\n");
|
||||
pthread_join(tid_read, NULL);
|
||||
printf("Read thread joined\n");
|
||||
|
||||
extract_params->main_threadsettings->is_file_selected[i] = nk_false;
|
||||
|
||||
remove("gui_report.log");
|
||||
remove("ccx.log");
|
||||
}
|
||||
printf("File feeding over\n");
|
||||
}
|
||||
|
||||
void setup_and_create_thread(struct main_tab *main_settings, struct built_string *command)
|
||||
{
|
||||
extract_args.main_threadsettings = (struct main_tab *)main_settings;
|
||||
extract_args.threadcommand = (struct built_string *)command;
|
||||
|
||||
pthread_attr_init(&attr_launch);
|
||||
int err = pthread_create(&tid_launch, &attr_launch, feed_files_for_extraction, &extract_args);
|
||||
if (!err)
|
||||
printf("Feeder created!\n");
|
||||
}
|
||||
|
||||
/*THREAD FUNCTIONS FOR HD_HOMERUN*/
|
||||
void *find_hd_homerun_devices(void *args)
|
||||
{
|
||||
char command[300];
|
||||
extract_args.homerun_thread = (struct hd_homerun_tab *)args;
|
||||
int wait = 0;
|
||||
FILE *file;
|
||||
char line[200];
|
||||
int device_success;
|
||||
char device[200];
|
||||
|
||||
#if UNIX
|
||||
struct timespec time;
|
||||
time.tv_sec = 0;
|
||||
time.tv_nsec = 10000000L;
|
||||
#endif
|
||||
|
||||
#if HD_HOMERUN
|
||||
strcpy(command, "hdhomerun_config");
|
||||
#else
|
||||
strncpy(command, extract_args.homerun_thread->location, extract_args.homerun_thread->location_len);
|
||||
#endif
|
||||
strcpy(command, " discover >> homerun.log");
|
||||
system(command);
|
||||
|
||||
file = fopen("homerun.log", "r");
|
||||
|
||||
while (file == NULL)
|
||||
{
|
||||
printf("Cannot open file! Trying again.\n");
|
||||
file = fopen("homerun.log", "r");
|
||||
#if UNIX
|
||||
nanosleep(&time, NULL);
|
||||
#else
|
||||
_sleep(10);
|
||||
#endif
|
||||
wait++;
|
||||
if (wait >= MAX_WAIT)
|
||||
{
|
||||
extract_args.homerun_thread->threadPopup = nk_true;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
fgets(line, sizeof(line), file);
|
||||
device_success = sscanf(line, "hdhomerun device %[^\n]", device);
|
||||
if (feof(file))
|
||||
break;
|
||||
if (device_success == 1)
|
||||
{
|
||||
if (extract_args.homerun_thread->device_num == 0)
|
||||
{
|
||||
extract_args.homerun_thread->devices = malloc(sizeof(char *));
|
||||
extract_args.homerun_thread->devices[extract_args.homerun_thread->device_num] = strdup(device);
|
||||
extract_args.homerun_thread->device_num++;
|
||||
}
|
||||
else
|
||||
{
|
||||
extract_args.homerun_thread->devices = realloc(extract_args.homerun_thread->devices,
|
||||
(extract_args.homerun_thread->device_num + 1) * sizeof(char *));
|
||||
extract_args.homerun_thread->devices[extract_args.homerun_thread->device_num] = strdup(device);
|
||||
extract_args.homerun_thread->device_num++;
|
||||
}
|
||||
}
|
||||
}
|
||||
printf("Find device thread finished\n");
|
||||
}
|
||||
|
||||
void *setup_hd_homerun_device(void *args)
|
||||
{
|
||||
char device[20];
|
||||
extract_args.homerun_thread = (struct hd_homerun_tab *)args;
|
||||
char channel_command[300];
|
||||
char program_command[300];
|
||||
char target_command[300];
|
||||
|
||||
sscanf(extract_args.homerun_thread->devices[extract_args.homerun_thread->selected], "%s", device);
|
||||
#if HD_HOMERUN
|
||||
strcpy(channel_command, "hdhomerun_config");
|
||||
strcpy(program_command, "hdhomerun_config");
|
||||
strcpy(target_command, "hdhomerun_config");
|
||||
#else
|
||||
strncpy(channel_command, extract_args.homerun_thread->location, extract_args.homerun_thread->location_len);
|
||||
strncpy(program_command, extract_args.homerun_thread->location, extract_args.homerun_thread->location_len);
|
||||
strncpy(target_command, extract_args.homerun_thread->location, extract_args.homerun_thread->location_len);
|
||||
#endif
|
||||
strcat(channel_command, " ");
|
||||
strcat(program_command, " ");
|
||||
strcat(target_command, " ");
|
||||
|
||||
strcat(channel_command, device);
|
||||
strcat(program_command, device);
|
||||
strcat(target_command, device);
|
||||
|
||||
strcat(channel_command, " set /tuner");
|
||||
strcat(program_command, " set /tuner");
|
||||
strcat(target_command, " set /tuner");
|
||||
|
||||
strncat(channel_command, extract_args.homerun_thread->tuner, extract_args.homerun_thread->tuner_len);
|
||||
strncat(program_command, extract_args.homerun_thread->tuner, extract_args.homerun_thread->tuner_len);
|
||||
strncat(target_command, extract_args.homerun_thread->tuner, extract_args.homerun_thread->tuner_len);
|
||||
|
||||
strcat(channel_command, "/channel ");
|
||||
strcat(program_command, "/program ");
|
||||
strcat(target_command, "/target ");
|
||||
|
||||
strncat(channel_command, extract_args.homerun_thread->channel, extract_args.homerun_thread->channel_len);
|
||||
strncat(program_command, extract_args.homerun_thread->program, extract_args.homerun_thread->program_len);
|
||||
strncat(target_command, extract_args.homerun_thread->ipv4_address, extract_args.homerun_thread->ipv4_address_len);
|
||||
|
||||
system(channel_command);
|
||||
system(program_command);
|
||||
system(target_command);
|
||||
|
||||
pthread_exit(0);
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
#ifndef CCX_CLI_THREAD_H
|
||||
#define CCX_CLI_THREAD_H
|
||||
#define HAVE_STRUCT_TIMESPEC
|
||||
#include "ccextractorGUI.h"
|
||||
#include "popups.h"
|
||||
#include "tabs.h"
|
||||
#include "command_builder.h"
|
||||
#include "pthread.h"
|
||||
struct args_extract {
|
||||
struct main_tab *main_threadsettings;
|
||||
struct built_string *threadcommand;
|
||||
struct hd_homerun_tab *homerun_thread;
|
||||
char *file_string;
|
||||
char *command_string;
|
||||
};
|
||||
|
||||
|
||||
static struct args_extract extract_args;
|
||||
|
||||
//FOR EXTRACT BUTTON TRIGGER ---- MAIN_TAB
|
||||
pthread_t tid_launch;
|
||||
pthread_attr_t attr_launch;
|
||||
|
||||
//FOR FIND DEVICES BUTTON TRIGGER ----- HD_HOMERUN_TAB
|
||||
pthread_t tid_find;
|
||||
pthread_attr_t attr_find;
|
||||
|
||||
//FOR SETUP DEVICE BUTTON TRIGGER ------ HD_HOMERUN_TAB
|
||||
pthread_t tid_setup;
|
||||
pthread_attr_t attr_setup;
|
||||
|
||||
void* read_activity_data(void *read_args);
|
||||
void* read_data_from_thread(void* read_args);
|
||||
void* extract_thread(void* extract_args);
|
||||
void* feed_files_for_extraction(void* file_args);
|
||||
void setup_and_create_thread(struct main_tab *main_settings, struct built_string *command);
|
||||
void* find_hd_homerun_devices(void *args);
|
||||
void* setup_hd_homerun_device(void *args);
|
||||
|
||||
#endif //!CCX_CLI_THREAD_H
|
||||
@@ -1,504 +0,0 @@
|
||||
#ifndef NK_IMPLEMENTATION
|
||||
#include "nuklear_lib/nuklear.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#endif //!NK_IMPLEMENTATION
|
||||
|
||||
#include "ccextractorGUI.h"
|
||||
#include "tabs.h"
|
||||
#include "command_builder.h"
|
||||
|
||||
void command_builder(struct built_string *command,
|
||||
struct main_tab *main_settings,
|
||||
struct network_popup *network_settings, struct input_tab *input,
|
||||
struct advanced_input_tab *advanced_input,
|
||||
struct output_tab *output,
|
||||
struct decoders_tab *decoders,
|
||||
struct credits_tab *credits,
|
||||
struct debug_tab *debug,
|
||||
struct burned_subs_tab *burned_subs)
|
||||
{
|
||||
static char buffer[1000];
|
||||
#ifdef _WIN32
|
||||
strcpy(buffer, "ccextractorwin --gui_mode_reports");
|
||||
#else
|
||||
strcpy(buffer, "./ccextractor --gui_mode_reports");
|
||||
#endif
|
||||
|
||||
/*INPUT COMMANDS*/
|
||||
if (main_settings->port_or_files == FILES)
|
||||
{
|
||||
if (input->type_select != 0)
|
||||
{
|
||||
strcat(buffer, " -in=");
|
||||
strcat(buffer, input->type[input->type_select]);
|
||||
}
|
||||
|
||||
if (input->is_split)
|
||||
strcat(buffer, " --videoedited");
|
||||
|
||||
if (input->is_process_from)
|
||||
{
|
||||
strcat(buffer, " -startat ");
|
||||
strcat(buffer, input->from_time_buffer);
|
||||
}
|
||||
|
||||
if (input->is_process_until)
|
||||
{
|
||||
strcat(buffer, " -endat ");
|
||||
strcat(buffer, input->until_time_buffer);
|
||||
}
|
||||
|
||||
switch (input->elementary_stream)
|
||||
{
|
||||
case AUTO_DETECT:
|
||||
break;
|
||||
case STREAM_TYPE:
|
||||
strcat(buffer, " -datastreamtype ");
|
||||
strncat(buffer, input->stream_type, input->stream_type_len);
|
||||
break;
|
||||
case STREAM_PID:
|
||||
strcat(buffer, " -datapid ");
|
||||
strncat(buffer, input->stream_pid, input->stream_pid_len);
|
||||
}
|
||||
|
||||
if (input->is_assume_mpeg)
|
||||
{
|
||||
strcat(buffer, " -streamtype ");
|
||||
strncat(buffer, input->mpeg_type, input->mpeg_type_len);
|
||||
}
|
||||
|
||||
if (decoders->teletext_dvb == TELETEXT)
|
||||
{
|
||||
switch (input->teletext_decoder)
|
||||
{
|
||||
case AUTO_DECODE:
|
||||
break;
|
||||
case FORCE:
|
||||
strcat(buffer, " -teletext");
|
||||
break;
|
||||
case DISABLE:
|
||||
strcat(buffer, " -noteletext");
|
||||
}
|
||||
|
||||
if (input->is_process_teletext_page)
|
||||
{
|
||||
strcat(buffer, " -tpage ");
|
||||
strncat(buffer, input->teletext_page_number, input->teletext_page_numer_len);
|
||||
}
|
||||
}
|
||||
|
||||
switch (input->is_limit)
|
||||
{
|
||||
case NO_LIMIT:
|
||||
break;
|
||||
case LIMITED:
|
||||
strcat(buffer, " --screenfuls ");
|
||||
strcat(buffer, input->screenful_limit_buffer);
|
||||
}
|
||||
|
||||
switch (input->clock_input)
|
||||
{
|
||||
case AUTO:
|
||||
break;
|
||||
case GOP:
|
||||
strcat(buffer, " --goptime");
|
||||
break;
|
||||
case PTS:
|
||||
strcat(buffer, " --nogoptime");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*Main tab and network settings*/
|
||||
if (main_settings->port_or_files == PORT)
|
||||
{
|
||||
switch (main_settings->port_select)
|
||||
{
|
||||
case 0:
|
||||
strcat(buffer, " -udp ");
|
||||
if (!strstr(network_settings->udp_ipv4, "None"))
|
||||
{
|
||||
strncat(buffer, network_settings->udp_ipv4, network_settings->udp_ipv4_len);
|
||||
strcat(buffer, ":");
|
||||
}
|
||||
strncat(buffer, main_settings->port_num, main_settings->port_num_len);
|
||||
break;
|
||||
case 1:
|
||||
strcat(buffer, " -tcp ");
|
||||
strncat(buffer, main_settings->port_num, main_settings->port_num_len);
|
||||
if (!strstr(network_settings->tcp_pass, "None"))
|
||||
{
|
||||
strcat(buffer, " -tcppassword ");
|
||||
strncat(buffer, network_settings->tcp_pass, network_settings->tcp_pass_len);
|
||||
}
|
||||
if (!strstr(network_settings->tcp_desc, "None"))
|
||||
{
|
||||
strcat(buffer, " -tcpdesc ");
|
||||
strncat(buffer, network_settings->tcp_desc, network_settings->tcp_desc_len);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (input->is_live_stream)
|
||||
{
|
||||
strcat(buffer, " -s ");
|
||||
strncat(buffer, input->wait_data_sec, input->wait_data_sec_len);
|
||||
}
|
||||
|
||||
if (input->is_process_from)
|
||||
{
|
||||
strcat(buffer, " -startat ");
|
||||
strcat(buffer, input->from_time_buffer);
|
||||
}
|
||||
|
||||
if (input->is_process_until)
|
||||
{
|
||||
strcat(buffer, " -endat ");
|
||||
strcat(buffer, input->until_time_buffer);
|
||||
}
|
||||
|
||||
switch (input->elementary_stream)
|
||||
{
|
||||
case AUTO_DETECT:
|
||||
break;
|
||||
case STREAM_TYPE:
|
||||
strcat(buffer, " -datastreamtype ");
|
||||
strncat(buffer, input->stream_type, input->stream_type_len);
|
||||
break;
|
||||
case STREAM_PID:
|
||||
strcat(buffer, " -datapid ");
|
||||
strncat(buffer, input->stream_pid, input->stream_pid_len);
|
||||
}
|
||||
|
||||
if (input->is_assume_mpeg)
|
||||
{
|
||||
strcat(buffer, " -streamtype ");
|
||||
strncat(buffer, input->mpeg_type, input->mpeg_type_len);
|
||||
}
|
||||
|
||||
switch (input->teletext_decoder)
|
||||
{
|
||||
case AUTO_DECODE:
|
||||
break;
|
||||
case FORCE:
|
||||
strcat(buffer, " -teletext");
|
||||
break;
|
||||
case DISABLE:
|
||||
strcat(buffer, " -noteletext");
|
||||
}
|
||||
|
||||
if (input->is_process_teletext_page)
|
||||
{
|
||||
strcat(buffer, " -tpage ");
|
||||
strncat(buffer, input->teletext_page_number, input->teletext_page_numer_len);
|
||||
}
|
||||
|
||||
switch (input->is_limit)
|
||||
{
|
||||
case NO_LIMIT:
|
||||
break;
|
||||
case LIMITED:
|
||||
strcat(buffer, " --screenfuls ");
|
||||
strcat(buffer, input->screenful_limit_buffer);
|
||||
}
|
||||
|
||||
switch (input->clock_input)
|
||||
{
|
||||
case AUTO:
|
||||
break;
|
||||
case GOP:
|
||||
strcat(buffer, " --goptime");
|
||||
break;
|
||||
case PTS:
|
||||
strcat(buffer, " --nogoptime");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*ADVANCED INPUT SETTINGS*/
|
||||
if (advanced_input->is_multiple_program)
|
||||
{
|
||||
switch (advanced_input->multiple_program)
|
||||
{
|
||||
case FIRST_PROG:
|
||||
strcat(buffer, " -autoprogram");
|
||||
break;
|
||||
case PROG_NUM:
|
||||
strcat(buffer, " -pn ");
|
||||
strcat(buffer, advanced_input->prog_number);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
switch (advanced_input->set_myth)
|
||||
{
|
||||
case AUTO_MYTH:
|
||||
break;
|
||||
case FORCE_MYTH:
|
||||
strcat(buffer, " -myth");
|
||||
break;
|
||||
case DISABLE_MYTH:
|
||||
strcat(buffer, " -nomyth");
|
||||
break;
|
||||
}
|
||||
|
||||
if (advanced_input->is_mpeg_90090)
|
||||
strcat(buffer, " -90090");
|
||||
if (advanced_input->is_padding_0000)
|
||||
strcat(buffer, " -fp");
|
||||
if (advanced_input->is_order_ccinfo)
|
||||
strcat(buffer, " -poc");
|
||||
if (advanced_input->is_win_bug)
|
||||
strcat(buffer, " -wtvconvertfix");
|
||||
if (advanced_input->is_hauppage_file)
|
||||
strcat(buffer, " -haup");
|
||||
if (advanced_input->is_process_mp4)
|
||||
strcat(buffer, " -mp4vidtrack");
|
||||
if (advanced_input->is_ignore_broadcast)
|
||||
strcat(buffer, " -noautotimeref");
|
||||
|
||||
/*DECODERS TAB*/
|
||||
if (decoders->is_field2)
|
||||
strcat(buffer, " -12");
|
||||
|
||||
switch (decoders->channel)
|
||||
{
|
||||
case CHANNEL_1:
|
||||
break;
|
||||
case CHANNEL_2:
|
||||
strcat(buffer, " -cc2");
|
||||
break;
|
||||
}
|
||||
|
||||
if (decoders->is_708)
|
||||
{
|
||||
strcat(buffer, " -svc ");
|
||||
strncat(buffer, decoders->services, decoders->services_len);
|
||||
}
|
||||
|
||||
switch (decoders->teletext_dvb)
|
||||
{
|
||||
case TELETEXT:
|
||||
if (strcmp(decoders->min_distance, "2"))
|
||||
{
|
||||
strcat(buffer, " -levdistmincnt ");
|
||||
strncat(buffer, decoders->min_distance, decoders->min_distance_len);
|
||||
}
|
||||
if (strcmp(decoders->max_distance, "10"))
|
||||
{
|
||||
strcat(buffer, " -levdistmaxpct ");
|
||||
strncat(buffer, decoders->max_distance, decoders->max_distance_len);
|
||||
}
|
||||
break;
|
||||
|
||||
case DVB:
|
||||
strcat(buffer, " -codec dvdsub");
|
||||
break;
|
||||
}
|
||||
|
||||
/*CREDITS TAB*/
|
||||
if (credits->is_start_text)
|
||||
{
|
||||
strcat(buffer, " --startcreditstext \"");
|
||||
strncat(buffer, credits->start_text, credits->start_text_len);
|
||||
strcat(buffer, "\" --startcreditsforatleast ");
|
||||
strncat(buffer, credits->start_atleast_sec, credits->start_atleast_sec_len);
|
||||
strcat(buffer, " --startcreditsforatmost ");
|
||||
strncat(buffer, credits->start_atmost_sec, credits->start_atmost_sec_len);
|
||||
if (credits->is_before)
|
||||
{
|
||||
strcat(buffer, " --startcreditsnotbefore ");
|
||||
strcat(buffer, credits->before_time_buffer);
|
||||
}
|
||||
if (credits->is_after)
|
||||
{
|
||||
strcat(buffer, " --startcreditsnotafter ");
|
||||
strcat(buffer, credits->after_time_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
if (credits->is_end_text)
|
||||
{
|
||||
strcat(buffer, " --endcreditstext \"");
|
||||
strncat(buffer, credits->end_text, credits->end_text_len);
|
||||
strcat(buffer, "\" --endcreditsforatleast ");
|
||||
strncat(buffer, credits->end_atleast_sec, credits->end_atleast_sec_len);
|
||||
strcat(buffer, " --endcreditsforatmost ");
|
||||
strncat(buffer, credits->end_atmost_sec, credits->end_atmost_sec_len);
|
||||
}
|
||||
|
||||
/*DEBUG TAB*/
|
||||
if (debug->is_elementary_stream)
|
||||
{
|
||||
strcat(buffer, " -cf ");
|
||||
strncat(buffer, debug->elementary_stream, debug->elementary_stream_len);
|
||||
}
|
||||
if (debug->is_dump_packets)
|
||||
strcat(buffer, " -debug");
|
||||
if (debug->is_debug_608)
|
||||
strcat(buffer, " -608");
|
||||
if (debug->is_debug_708)
|
||||
strcat(buffer, " -708");
|
||||
if (debug->is_stamp_output)
|
||||
strcat(buffer, " -goppts");
|
||||
if (debug->is_debug_analysed_vid)
|
||||
strcat(buffer, " -vides");
|
||||
if (debug->is_raw_608_708)
|
||||
strcat(buffer, " -cbraw");
|
||||
if (debug->is_debug_parsed)
|
||||
strcat(buffer, " -parsedebug");
|
||||
if (!strcmp(output->type[output->type_select], "bin"))
|
||||
{
|
||||
if (debug->is_disable_sync)
|
||||
strcat(buffer, " -nosync");
|
||||
if (debug->is_no_padding)
|
||||
strcat(buffer, " -fullbin");
|
||||
}
|
||||
if (debug->is_debug_xds)
|
||||
strcat(buffer, " -xdsdebug");
|
||||
if (debug->is_output_pat)
|
||||
strcat(buffer, " -parsePAT");
|
||||
if (debug->is_output_pmt)
|
||||
strcat(buffer, " -parsePMT");
|
||||
if (debug->is_scan_ccdata)
|
||||
strcat(buffer, " -investigate_packets");
|
||||
if (debug->is_output_levenshtein)
|
||||
strcat(buffer, " -deblev");
|
||||
|
||||
/*HARD_BURNED SUBS SETTINGS*/
|
||||
if (burned_subs->is_burned_subs)
|
||||
{
|
||||
strcat(buffer, " -hardsubx -ocr_mode");
|
||||
switch (burned_subs->ocr_mode)
|
||||
{
|
||||
case FRAME_WISE:
|
||||
strcat(buffer, " frame");
|
||||
break;
|
||||
case WORD_WISE:
|
||||
strcat(buffer, " word");
|
||||
break;
|
||||
case LETTER_WISE:
|
||||
strcat(buffer, " letter");
|
||||
break;
|
||||
}
|
||||
|
||||
strcat(buffer, " -min_sub_duration ");
|
||||
strcat(buffer, burned_subs->min_duration);
|
||||
|
||||
if (!burned_subs->subs_color_select && burned_subs->color_type == PRESET)
|
||||
sprintf(buffer, "%s -whiteness_thresh %d", buffer, burned_subs->luminance_threshold);
|
||||
|
||||
sprintf(buffer, "%s -conf_thresh %d", buffer, burned_subs->confidence_threshold);
|
||||
|
||||
if (burned_subs->is_italic)
|
||||
strcat(buffer, " -detect_italics");
|
||||
}
|
||||
|
||||
//Output
|
||||
{
|
||||
strcat(buffer, " -out=");
|
||||
strcat(buffer, output->type[output->type_select]);
|
||||
if (output->is_filename)
|
||||
{
|
||||
strcat(buffer, " -o \"");
|
||||
strncat(buffer, output->filename, output->filename_len);
|
||||
strcat(buffer, "\"");
|
||||
}
|
||||
|
||||
if (output->is_delay)
|
||||
{
|
||||
strcat(buffer, " -delay ");
|
||||
strcat(buffer, output->delay_sec_buffer);
|
||||
}
|
||||
|
||||
if (output->is_export_xds)
|
||||
strcat(buffer, " -xds");
|
||||
|
||||
switch (output->encoding)
|
||||
{
|
||||
case LATIN:
|
||||
strcat(buffer, " -latin1");
|
||||
break;
|
||||
case UNIC:
|
||||
strcat(buffer, " -unicode");
|
||||
break;
|
||||
case UTF:
|
||||
strcat(buffer, " -utf8");
|
||||
break;
|
||||
}
|
||||
|
||||
if (output->is_bom)
|
||||
strcat(buffer, " -bom");
|
||||
else
|
||||
strcat(buffer, " -nobom");
|
||||
|
||||
if (output->is_cap_standard)
|
||||
strcat(buffer, " --sentencecap");
|
||||
|
||||
if (output->is_cap_file)
|
||||
{
|
||||
strcat(buffer, " --capfile \"");
|
||||
strncat(buffer, output->cap_dictionary, output->cap_dictionary_len);
|
||||
strcat(buffer, "\"");
|
||||
}
|
||||
|
||||
switch (output->line_ending)
|
||||
{
|
||||
case CRLF:
|
||||
break;
|
||||
case LF:
|
||||
strcat(buffer, " -lf");
|
||||
break;
|
||||
}
|
||||
|
||||
if (output->is_center)
|
||||
strcat(buffer, " -trim");
|
||||
|
||||
if (output->is_dash)
|
||||
strcat(buffer, " -autodash");
|
||||
|
||||
if (output->no_typesetting)
|
||||
strcat(buffer, " --notypesetting");
|
||||
|
||||
switch (output->font_color)
|
||||
{
|
||||
case NO_COLOR:
|
||||
strcat(buffer, " --nofontcolor");
|
||||
break;
|
||||
case DEFAULT_COLOR:
|
||||
strcat(buffer, " --defaultcolor #");
|
||||
strcat(buffer, output->color_hex);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (output->onetime_or_realtime)
|
||||
{
|
||||
case ONETIME:
|
||||
strcat(buffer, " --norollup");
|
||||
break;
|
||||
case REALTIME:
|
||||
strcat(buffer, " -dru");
|
||||
switch (output->roll_limit_select)
|
||||
{
|
||||
case 1:
|
||||
strcat(buffer, " -ru1");
|
||||
break;
|
||||
case 2:
|
||||
strcat(buffer, " -ru2");
|
||||
break;
|
||||
case 3:
|
||||
strcat(buffer, " -ru3");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
memset(command->term_string, 0, sizeof(command->term_string));
|
||||
strncpy(command->term_string, buffer, strlen(buffer));
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
#ifndef COMMAND_BUILDER_H
|
||||
#define COMMAND_BUILDER_H
|
||||
|
||||
#include "ccextractorGUI.h"
|
||||
#include "tabs.h"
|
||||
#include "popups.h"
|
||||
|
||||
struct built_string
|
||||
{
|
||||
char term_string[1000];
|
||||
};
|
||||
|
||||
void command_builder(struct built_string *command,
|
||||
struct main_tab *main_settings,
|
||||
struct network_popup *network_settings,
|
||||
struct input_tab *input,
|
||||
struct advanced_input_tab *advanced_input,
|
||||
struct output_tab *output,
|
||||
struct decoders_tab *decoders,
|
||||
struct credits_tab *credits,
|
||||
struct debug_tab *debug,
|
||||
struct burned_subs_tab *burned_subs);
|
||||
|
||||
#endif //!COMMAND_BUILDER_H
|
||||
@@ -1,598 +0,0 @@
|
||||
#include "file_browser.h"
|
||||
#ifdef _WIN32
|
||||
#include "win_dirent.h"
|
||||
#else
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#ifndef STB_IMAGE_IMPLEMENTATION
|
||||
#include "stb_image.h"
|
||||
#endif
|
||||
#if UNIX
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <GL/glew.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef NK_IMPLEMENTATION
|
||||
#include "nuklear_lib/nuklear.h"
|
||||
#endif
|
||||
|
||||
#include "ccextractorGUI.h"
|
||||
#include "tabs.h"
|
||||
|
||||
void die(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
vfprintf(stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
fputs("\n", stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
char *
|
||||
file_load(const char *path, size_t *siz)
|
||||
{
|
||||
char *buf;
|
||||
FILE *fd = fopen(path, "rb");
|
||||
if (!fd)
|
||||
die("Failed to open file: %s\n", path);
|
||||
fseek(fd, 0, SEEK_END);
|
||||
*siz = (size_t)ftell(fd);
|
||||
fseek(fd, 0, SEEK_SET);
|
||||
buf = (char *)calloc(*siz, 1);
|
||||
fread(buf, *siz, 1, fd);
|
||||
fclose(fd);
|
||||
return buf;
|
||||
}
|
||||
|
||||
char *
|
||||
str_duplicate(const char *src)
|
||||
{
|
||||
char *ret;
|
||||
size_t len = strlen(src);
|
||||
if (!len)
|
||||
return 0;
|
||||
ret = (char *)malloc(len + 1);
|
||||
if (!ret)
|
||||
return 0;
|
||||
memcpy(ret, src, len);
|
||||
ret[len] = '\0';
|
||||
return ret;
|
||||
}
|
||||
|
||||
void dir_free_list(char **list, size_t size)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < size; ++i)
|
||||
free(list[i]);
|
||||
free(list);
|
||||
}
|
||||
|
||||
char **
|
||||
dir_list(const char *dir, int return_subdirs, size_t *count)
|
||||
{
|
||||
size_t n = 0;
|
||||
char buffer[MAX_PATH_LEN];
|
||||
char **results = NULL;
|
||||
const DIR *none = NULL;
|
||||
size_t capacity = 32;
|
||||
size_t size;
|
||||
DIR *z;
|
||||
|
||||
assert(dir);
|
||||
assert(count);
|
||||
strncpy(buffer, dir, MAX_PATH_LEN);
|
||||
n = strlen(buffer);
|
||||
|
||||
#ifdef _WIN32
|
||||
if (n > 0 && (buffer[n - 1] != '\\'))
|
||||
buffer[n++] = '\\';
|
||||
#else
|
||||
if (n > 0 && (buffer[n - 1] != '/'))
|
||||
buffer[n++] = '/';
|
||||
#endif
|
||||
|
||||
size = 0;
|
||||
|
||||
z = opendir(dir);
|
||||
if (z != none)
|
||||
{
|
||||
int nonempty = 1;
|
||||
struct dirent *data = readdir(z);
|
||||
nonempty = (data != NULL);
|
||||
if (!nonempty)
|
||||
return NULL;
|
||||
|
||||
do
|
||||
{
|
||||
DIR *y;
|
||||
char *p;
|
||||
int is_subdir;
|
||||
if (data->d_name[0] == '.')
|
||||
continue;
|
||||
|
||||
strncpy(buffer + n, data->d_name, MAX_PATH_LEN - n);
|
||||
y = opendir(buffer);
|
||||
is_subdir = (y != NULL);
|
||||
if (y != NULL)
|
||||
closedir(y);
|
||||
|
||||
if ((return_subdirs && is_subdir) || (!is_subdir && !return_subdirs))
|
||||
{
|
||||
if (!size)
|
||||
{
|
||||
results = (char **)calloc(sizeof(char *), capacity);
|
||||
}
|
||||
else if (size >= capacity)
|
||||
{
|
||||
void *old = results;
|
||||
capacity = capacity * 2;
|
||||
results = (char **)realloc(results, capacity * sizeof(char *));
|
||||
assert(results);
|
||||
if (!results)
|
||||
free(old);
|
||||
}
|
||||
p = str_duplicate(data->d_name);
|
||||
results[size++] = p;
|
||||
}
|
||||
} while ((data = readdir(z)) != NULL);
|
||||
}
|
||||
|
||||
if (z)
|
||||
closedir(z);
|
||||
*count = size;
|
||||
return results;
|
||||
}
|
||||
|
||||
struct file_group
|
||||
FILE_GROUP(enum file_groups group, const char *name, struct nk_image *icon)
|
||||
{
|
||||
struct file_group fg;
|
||||
fg.group = group;
|
||||
fg.name = name;
|
||||
fg.icon = icon;
|
||||
return fg;
|
||||
}
|
||||
|
||||
struct file
|
||||
FILE_DEF(enum file_types type, const char *suffix, enum file_groups group)
|
||||
{
|
||||
struct file fd;
|
||||
fd.type = type;
|
||||
fd.suffix = suffix;
|
||||
fd.group = group;
|
||||
return fd;
|
||||
}
|
||||
|
||||
struct nk_image *
|
||||
media_icon_for_file(struct media *media, const char *file)
|
||||
{
|
||||
int i = 0;
|
||||
const char *s = file;
|
||||
char suffix[4];
|
||||
int found = 0;
|
||||
memset(suffix, 0, sizeof(suffix));
|
||||
|
||||
/* extract suffix .xxx from file */
|
||||
while (*s++ != '\0')
|
||||
{
|
||||
if (found && i < 3)
|
||||
suffix[i++] = *s;
|
||||
|
||||
if (*s == '.')
|
||||
{
|
||||
if (found)
|
||||
{
|
||||
found = 0;
|
||||
break;
|
||||
}
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* check for all file definition of all groups for fitting suffix*/
|
||||
for (i = 0; i < FILE_MAX && found; ++i)
|
||||
{
|
||||
struct file *d = &media->files[i];
|
||||
{
|
||||
const char *f = d->suffix;
|
||||
s = suffix;
|
||||
while (f && *f && *s && *s == *f)
|
||||
{
|
||||
s++;
|
||||
f++;
|
||||
}
|
||||
|
||||
/* found correct file definition so */
|
||||
|
||||
if (f && *s == '\0' && *f == '\0')
|
||||
return media->group[d->group].icon;
|
||||
}
|
||||
}
|
||||
return &media->icons.default_file;
|
||||
}
|
||||
|
||||
void media_init(struct media *media)
|
||||
{
|
||||
/* file groups */
|
||||
struct icons *icons = &media->icons;
|
||||
media->group[FILE_GROUP_DEFAULT] = FILE_GROUP(FILE_GROUP_DEFAULT, "default", &icons->default_file);
|
||||
media->group[FILE_GROUP_TEXT] = FILE_GROUP(FILE_GROUP_TEXT, "textual", &icons->text_file);
|
||||
media->group[FILE_GROUP_MUSIC] = FILE_GROUP(FILE_GROUP_MUSIC, "music", &icons->music_file);
|
||||
media->group[FILE_GROUP_FONT] = FILE_GROUP(FILE_GROUP_FONT, "font", &icons->font_file);
|
||||
media->group[FILE_GROUP_IMAGE] = FILE_GROUP(FILE_GROUP_IMAGE, "image", &icons->img_file);
|
||||
media->group[FILE_GROUP_MOVIE] = FILE_GROUP(FILE_GROUP_MOVIE, "movie", &icons->movie_file);
|
||||
|
||||
/* files */
|
||||
media->files[FILE_DEFAULT] = FILE_DEF(FILE_DEFAULT, NULL, FILE_GROUP_DEFAULT);
|
||||
media->files[FILE_TEXT] = FILE_DEF(FILE_TEXT, "txt", FILE_GROUP_TEXT);
|
||||
media->files[FILE_C_SOURCE] = FILE_DEF(FILE_C_SOURCE, "c", FILE_GROUP_TEXT);
|
||||
media->files[FILE_CPP_SOURCE] = FILE_DEF(FILE_CPP_SOURCE, "cpp", FILE_GROUP_TEXT);
|
||||
media->files[FILE_HEADER] = FILE_DEF(FILE_HEADER, "h", FILE_GROUP_TEXT);
|
||||
media->files[FILE_CPP_HEADER] = FILE_DEF(FILE_HEADER, "hpp", FILE_GROUP_TEXT);
|
||||
media->files[FILE_MP3] = FILE_DEF(FILE_MP3, "mp3", FILE_GROUP_MUSIC);
|
||||
media->files[FILE_WAV] = FILE_DEF(FILE_WAV, "wav", FILE_GROUP_MUSIC);
|
||||
media->files[FILE_OGG] = FILE_DEF(FILE_OGG, "ogg", FILE_GROUP_MUSIC);
|
||||
media->files[FILE_TTF] = FILE_DEF(FILE_TTF, "ttf", FILE_GROUP_FONT);
|
||||
media->files[FILE_BMP] = FILE_DEF(FILE_BMP, "bmp", FILE_GROUP_IMAGE);
|
||||
media->files[FILE_PNG] = FILE_DEF(FILE_PNG, "png", FILE_GROUP_IMAGE);
|
||||
media->files[FILE_JPEG] = FILE_DEF(FILE_JPEG, "jpg", FILE_GROUP_IMAGE);
|
||||
media->files[FILE_PCX] = FILE_DEF(FILE_PCX, "pcx", FILE_GROUP_IMAGE);
|
||||
media->files[FILE_TGA] = FILE_DEF(FILE_TGA, "tga", FILE_GROUP_IMAGE);
|
||||
media->files[FILE_GIF] = FILE_DEF(FILE_GIF, "gif", FILE_GROUP_IMAGE);
|
||||
}
|
||||
|
||||
void file_browser_reload_directory_content(struct file_browser *browser, const char *path)
|
||||
{
|
||||
strncpy(browser->directory, path, MAX_PATH_LEN);
|
||||
dir_free_list(browser->files, browser->file_count);
|
||||
dir_free_list(browser->directories, browser->dir_count);
|
||||
browser->files = dir_list(path, 0, &browser->file_count);
|
||||
browser->directories = dir_list(path, 1, &browser->dir_count);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
void get_drives(struct file_browser *browser)
|
||||
{
|
||||
static int drive_num;
|
||||
static char drive_list[50][4];
|
||||
int c, prev_char;
|
||||
|
||||
system("wmic logicaldisk get name 1> drive.txt");
|
||||
|
||||
FILE *file;
|
||||
file = fopen("drive.txt", "r");
|
||||
if (file == NULL)
|
||||
{
|
||||
printf("cannot find any drives! try again with different settings/permissions");
|
||||
}
|
||||
else
|
||||
{
|
||||
puts("File opened");
|
||||
while ((c = getc(file)) != EOF)
|
||||
{
|
||||
if (c == ':')
|
||||
{
|
||||
sprintf(drive_list[drive_num], "%c", prev_char);
|
||||
drive_num++;
|
||||
continue;
|
||||
}
|
||||
if (c < 65 || c > 90)
|
||||
continue;
|
||||
|
||||
prev_char = c;
|
||||
}
|
||||
}
|
||||
printf("drive nums:%d\n", drive_num);
|
||||
|
||||
for (int i = 0; i < drive_num; i++)
|
||||
strcat(drive_list[i], ":\\");
|
||||
|
||||
browser->drives_num = drive_num;
|
||||
browser->drives = (char **)calloc(drive_num + 1, sizeof(char *));
|
||||
for (int i = 0; i < drive_num; i++)
|
||||
{
|
||||
browser->drives[i] = (char *)calloc(strlen(drive_list[i]), sizeof(char));
|
||||
browser->drives[i] = strdup(drive_list[i]);
|
||||
}
|
||||
browser->drives[browser->drives_num] = NULL;
|
||||
|
||||
for (int i = 0; i < drive_num; i++)
|
||||
puts(browser->drives[i]);
|
||||
|
||||
fclose(file);
|
||||
remove("drive.txt");
|
||||
}
|
||||
#endif
|
||||
|
||||
void file_browser_init(struct file_browser *browser, struct media *media)
|
||||
{
|
||||
memset(browser, 0, sizeof(*browser));
|
||||
browser->media = media;
|
||||
|
||||
#ifdef _WIN32
|
||||
get_drives(browser);
|
||||
#endif
|
||||
{
|
||||
/* load files and sub-directory list */
|
||||
const char *home = getenv("HOME");
|
||||
#ifdef _WIN32
|
||||
if (!home)
|
||||
home = getenv("USERPROFILE");
|
||||
#else
|
||||
if (!home)
|
||||
home = getpwuid(getuid());
|
||||
#endif
|
||||
{
|
||||
size_t l;
|
||||
strncpy(browser->home, home, MAX_PATH_LEN);
|
||||
l = strlen(browser->home);
|
||||
#ifdef _WIN32
|
||||
strcpy(browser->home + l, "\\");
|
||||
#else
|
||||
strcpy(browser->home + l, "/");
|
||||
#endif
|
||||
strcpy(browser->directory, browser->home);
|
||||
}
|
||||
{
|
||||
size_t l;
|
||||
strcpy(browser->desktop, browser->home);
|
||||
l = strlen(browser->desktop);
|
||||
#ifdef _WIN32
|
||||
strcpy(browser->desktop + l, "Desktop\\");
|
||||
#else
|
||||
strcpy(browser->desktop + l, "Desktop/");
|
||||
#endif
|
||||
}
|
||||
browser->files = dir_list(browser->directory, 0, &browser->file_count);
|
||||
browser->directories = dir_list(browser->directory, 1, &browser->dir_count);
|
||||
}
|
||||
}
|
||||
|
||||
void file_browser_free(struct file_browser *browser)
|
||||
{
|
||||
if (browser->files)
|
||||
dir_free_list(browser->files, browser->file_count);
|
||||
if (browser->directories)
|
||||
dir_free_list(browser->directories, browser->dir_count);
|
||||
browser->files = NULL;
|
||||
browser->directories = NULL;
|
||||
memset(browser, 0, sizeof(*browser));
|
||||
}
|
||||
|
||||
int file_browser_run(struct file_browser *browser,
|
||||
struct nk_context *ctx,
|
||||
struct main_tab *main_settings,
|
||||
struct output_tab *output,
|
||||
struct debug_tab *debug,
|
||||
struct hd_homerun_tab *hd_homerun)
|
||||
{
|
||||
static int isFileAdded = nk_false;
|
||||
int ret = 0;
|
||||
struct media *media = browser->media;
|
||||
struct nk_rect total_space;
|
||||
|
||||
if (nk_popup_begin(ctx, NK_POPUP_STATIC, "File Browser", NK_WINDOW_CLOSABLE | NK_WINDOW_BORDER | NK_WINDOW_NO_SCROLLBAR | NK_WINDOW_MOVABLE,
|
||||
nk_rect(0, 0, 930, 650)))
|
||||
{
|
||||
static float ratio[] = {0.25f, NK_UNDEFINED};
|
||||
float spacing_x = ctx->style.window.spacing.x;
|
||||
|
||||
/* output path directory selector in the menubar */
|
||||
ctx->style.window.spacing.x = 0;
|
||||
nk_menubar_begin(ctx);
|
||||
{
|
||||
char *d = browser->directory;
|
||||
char *begin = d + 1;
|
||||
nk_layout_row_dynamic(ctx, 25, 6);
|
||||
while (*d++)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (*d == '\\')
|
||||
#else
|
||||
if (*d == '/')
|
||||
#endif
|
||||
{
|
||||
*d = '\0';
|
||||
if (nk_button_label(ctx, begin))
|
||||
{
|
||||
#ifdef _WIN32
|
||||
*d++ = '\\';
|
||||
#else
|
||||
*d++ = '/';
|
||||
#endif
|
||||
*d = '\0';
|
||||
file_browser_reload_directory_content(browser, browser->directory);
|
||||
|
||||
break;
|
||||
}
|
||||
#ifdef _WIN32
|
||||
*d = '\\';
|
||||
#else
|
||||
*d = '/';
|
||||
#endif
|
||||
begin = d + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
nk_menubar_end(ctx);
|
||||
ctx->style.window.spacing.x = spacing_x;
|
||||
|
||||
/* window layout */
|
||||
total_space = nk_window_get_content_region(ctx);
|
||||
nk_layout_row(ctx, NK_DYNAMIC, total_space.h, 2, ratio);
|
||||
nk_group_begin(ctx, "Special", NK_WINDOW_NO_SCROLLBAR);
|
||||
{
|
||||
struct nk_image home = media->icons.home;
|
||||
struct nk_image desktop = media->icons.desktop;
|
||||
struct nk_image computer = media->icons.computer;
|
||||
#ifdef _WIN32
|
||||
struct nk_image drive = media->icons.drives;
|
||||
#endif
|
||||
|
||||
nk_layout_row_dynamic(ctx, 40, 1);
|
||||
if (nk_button_image_label(ctx, home, "Home", NK_TEXT_CENTERED))
|
||||
file_browser_reload_directory_content(browser, browser->home);
|
||||
if (nk_button_image_label(ctx, desktop, "Desktop", NK_TEXT_CENTERED))
|
||||
file_browser_reload_directory_content(browser, browser->desktop);
|
||||
#ifdef _WIN32
|
||||
for (int drive_counter = 0; drive_counter < browser->drives_num; drive_counter++)
|
||||
{
|
||||
if (nk_button_image_label(ctx, drive, browser->drives[drive_counter], NK_TEXT_CENTERED))
|
||||
file_browser_reload_directory_content(browser, browser->drives[drive_counter]);
|
||||
}
|
||||
#else
|
||||
if (nk_button_image_label(ctx, computer, "Computer", NK_TEXT_CENTERED))
|
||||
file_browser_reload_directory_content(browser, "/");
|
||||
#endif
|
||||
nk_group_end(ctx);
|
||||
}
|
||||
|
||||
/* output directory content window */
|
||||
nk_group_begin(ctx, "Content", 0);
|
||||
{
|
||||
int index = -1;
|
||||
size_t i = 0, j = 0, k = 0;
|
||||
size_t rows = 0, cols = 0;
|
||||
size_t count = browser->dir_count + browser->file_count;
|
||||
|
||||
cols = 4;
|
||||
rows = count / cols;
|
||||
for (i = 0; i <= rows; i += 1)
|
||||
{
|
||||
{
|
||||
size_t n = j + cols;
|
||||
nk_layout_row_dynamic(ctx, 135, (int)cols);
|
||||
for (; j < count && j < n; ++j)
|
||||
{
|
||||
/* draw one row of icons */
|
||||
if (j < browser->dir_count)
|
||||
{
|
||||
/* draw and execute directory buttons */
|
||||
if (nk_button_image(ctx, media->icons.directory))
|
||||
index = (int)j;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* draw and execute files buttons */
|
||||
struct nk_image *icon;
|
||||
size_t fileIndex = ((size_t)j - browser->dir_count);
|
||||
icon = media_icon_for_file(media, browser->files[fileIndex]);
|
||||
if (nk_button_image(ctx, *icon))
|
||||
{
|
||||
strncpy(browser->file, browser->directory, MAX_PATH_LEN);
|
||||
n = strlen(browser->file);
|
||||
strncpy(browser->file + n, browser->files[fileIndex], MAX_PATH_LEN - n);
|
||||
ret = 1;
|
||||
|
||||
if (hd_homerun->is_homerun_browser_active)
|
||||
{
|
||||
hd_homerun->location_len = strlen(browser->file);
|
||||
strncpy(hd_homerun->location, browser->file, hd_homerun->location_len);
|
||||
isFileAdded = nk_true;
|
||||
hd_homerun->is_homerun_browser_active = nk_false;
|
||||
break;
|
||||
}
|
||||
if (debug->is_debug_browser_active)
|
||||
{
|
||||
debug->elementary_stream_len = strlen(browser->file);
|
||||
strcpy(debug->elementary_stream, browser->file);
|
||||
isFileAdded = nk_true;
|
||||
debug->is_debug_browser_active = nk_false;
|
||||
break;
|
||||
}
|
||||
if (output->is_output_browser_active)
|
||||
{
|
||||
output->filename_len = strlen(browser->file);
|
||||
strcpy(output->filename, browser->file);
|
||||
isFileAdded = nk_true;
|
||||
output->is_output_browser_active = nk_false;
|
||||
break;
|
||||
}
|
||||
if (output->is_cap_browser_active)
|
||||
{
|
||||
output->cap_dictionary_len = strlen(browser->file);
|
||||
strcpy(output->cap_dictionary, browser->file);
|
||||
isFileAdded = nk_true;
|
||||
output->is_cap_browser_active = nk_false;
|
||||
break;
|
||||
}
|
||||
if (main_settings->is_file_browser_active)
|
||||
{
|
||||
if (main_settings->filename_count == 0)
|
||||
main_settings->filenames = (char **)calloc(2, sizeof(char *));
|
||||
else
|
||||
main_settings->filenames = (char **)realloc(main_settings->filenames, (main_settings->filename_count + 2) * sizeof(char *));
|
||||
|
||||
main_settings->filenames[main_settings->filename_count] = (char *)calloc((strlen(browser->file) + 5), sizeof(char));
|
||||
main_settings->filenames[main_settings->filename_count][0] = '\"';
|
||||
strcat(main_settings->filenames[main_settings->filename_count], browser->file);
|
||||
strcat(main_settings->filenames[main_settings->filename_count], "\"");
|
||||
main_settings->filename_count++;
|
||||
main_settings->filenames[main_settings->filename_count] = NULL;
|
||||
isFileAdded = nk_true;
|
||||
main_settings->is_file_browser_active = nk_false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
size_t n = k + cols;
|
||||
nk_layout_row_dynamic(ctx, 20, (int)cols);
|
||||
for (; k < count && k < n; k++)
|
||||
{
|
||||
/* draw one row of labels */
|
||||
if (k < browser->dir_count)
|
||||
{
|
||||
nk_label(ctx, browser->directories[k], NK_TEXT_CENTERED);
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t t = k - browser->dir_count;
|
||||
nk_label(ctx, browser->files[t], NK_TEXT_CENTERED);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (index != -1)
|
||||
{
|
||||
size_t n = strlen(browser->directory);
|
||||
strncpy(browser->directory + n, browser->directories[index], MAX_PATH_LEN - n);
|
||||
n = strlen(browser->directory);
|
||||
if (n < MAX_PATH_LEN - 1)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
browser->directory[n] = '\\';
|
||||
#else
|
||||
browser->directory[n] = '/';
|
||||
#endif
|
||||
browser->directory[n + 1] = '\0';
|
||||
}
|
||||
file_browser_reload_directory_content(browser, browser->directory);
|
||||
}
|
||||
nk_group_end(ctx);
|
||||
}
|
||||
if (isFileAdded)
|
||||
{
|
||||
isFileAdded = nk_false;
|
||||
main_settings->scaleWindowForFileBrowser = nk_false;
|
||||
nk_popup_close(ctx);
|
||||
}
|
||||
|
||||
nk_popup_end(ctx);
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
main_settings->scaleWindowForFileBrowser = nk_false;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -1,159 +0,0 @@
|
||||
#ifndef FILE_BROWSER_H
|
||||
#define FILE_BROWSER_H
|
||||
|
||||
#include "ccextractorGUI.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#ifndef STB_IMAGE_IMPLEMENTATION
|
||||
#include "stb_image.h"
|
||||
#endif
|
||||
#include "tabs.h"
|
||||
|
||||
|
||||
/* ===============================================================
|
||||
*
|
||||
* GUI
|
||||
*
|
||||
* ===============================================================*/
|
||||
struct icons {
|
||||
struct nk_image desktop;
|
||||
#ifdef _WIN32
|
||||
struct nk_image drives;
|
||||
#endif
|
||||
struct nk_image home;
|
||||
struct nk_image computer;
|
||||
struct nk_image directory;
|
||||
|
||||
struct nk_image default_file;
|
||||
struct nk_image text_file;
|
||||
struct nk_image music_file;
|
||||
struct nk_image font_file;
|
||||
struct nk_image img_file;
|
||||
struct nk_image movie_file;
|
||||
};
|
||||
|
||||
enum file_groups {
|
||||
FILE_GROUP_DEFAULT,
|
||||
FILE_GROUP_TEXT,
|
||||
FILE_GROUP_MUSIC,
|
||||
FILE_GROUP_FONT,
|
||||
FILE_GROUP_IMAGE,
|
||||
FILE_GROUP_MOVIE,
|
||||
FILE_GROUP_MAX
|
||||
};
|
||||
|
||||
enum file_types {
|
||||
FILE_DEFAULT,
|
||||
FILE_TEXT,
|
||||
FILE_C_SOURCE,
|
||||
FILE_CPP_SOURCE,
|
||||
FILE_HEADER,
|
||||
FILE_CPP_HEADER,
|
||||
FILE_MP3,
|
||||
FILE_WAV,
|
||||
FILE_OGG,
|
||||
FILE_TTF,
|
||||
FILE_BMP,
|
||||
FILE_PNG,
|
||||
FILE_JPEG,
|
||||
FILE_PCX,
|
||||
FILE_TGA,
|
||||
FILE_GIF,
|
||||
FILE_MAX
|
||||
};
|
||||
|
||||
struct file_group {
|
||||
enum file_groups group;
|
||||
const char *name;
|
||||
struct nk_image *icon;
|
||||
};
|
||||
|
||||
struct file {
|
||||
enum file_types type;
|
||||
const char *suffix;
|
||||
enum file_groups group;
|
||||
};
|
||||
|
||||
struct media {
|
||||
int font;
|
||||
int icon_sheet;
|
||||
struct icons icons;
|
||||
struct file_group group[FILE_GROUP_MAX];
|
||||
struct file files[FILE_MAX];
|
||||
};
|
||||
|
||||
#define MAX_PATH_LEN 512
|
||||
struct file_browser {
|
||||
/* path */
|
||||
char file[MAX_PATH_LEN];
|
||||
char home[MAX_PATH_LEN];
|
||||
char desktop[MAX_PATH_LEN];
|
||||
char directory[MAX_PATH_LEN];
|
||||
#ifdef _WIN32
|
||||
char **drives;
|
||||
int drives_num;
|
||||
#endif
|
||||
|
||||
/* directory content */
|
||||
char **files;
|
||||
char **directories;
|
||||
size_t file_count;
|
||||
size_t dir_count;
|
||||
struct media *media;
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
die(const char *fmt, ...);
|
||||
|
||||
char*
|
||||
file_load(const char* path, size_t* siz);
|
||||
|
||||
char*
|
||||
str_duplicate(const char *src);
|
||||
|
||||
void
|
||||
dir_free_list(char **list, size_t size);
|
||||
|
||||
char**
|
||||
dir_list(const char *dir, int return_subdirs, size_t *count);
|
||||
|
||||
struct file_group
|
||||
FILE_GROUP(enum file_groups group, const char *name, struct nk_image *icon);
|
||||
|
||||
struct file
|
||||
FILE_DEF(enum file_types type, const char *suffix, enum file_groups group);
|
||||
|
||||
struct nk_image*
|
||||
media_icon_for_file(struct media *media, const char *file);
|
||||
|
||||
void
|
||||
media_init(struct media *media);
|
||||
|
||||
void
|
||||
file_browser_reload_directory_content(struct file_browser *browser, const char *path);
|
||||
|
||||
#if _WIN32
|
||||
void
|
||||
get_drives(struct file_browser *browser);
|
||||
#endif
|
||||
|
||||
void
|
||||
file_browser_init(struct file_browser *browser, struct media *media);
|
||||
|
||||
void
|
||||
file_browser_free(struct file_browser *browser);
|
||||
|
||||
int
|
||||
file_browser_run(struct file_browser *browser,
|
||||
struct nk_context *ctx,
|
||||
struct main_tab *main_settings,
|
||||
struct output_tab *output,
|
||||
struct debug_tab *debug,
|
||||
struct hd_homerun_tab *hd_homerun);
|
||||
|
||||
struct nk_image
|
||||
icon_load(char icon_data[], int len);
|
||||
|
||||
#endif
|
||||
27786
src/GUI/icon_data.c
27786
src/GUI/icon_data.c
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,352 +0,0 @@
|
||||
/*
|
||||
* Nuklear - v1.32.0 - public domain
|
||||
* no warrenty implied; use at your own risk.
|
||||
* authored from 2015-2017 by Micha Mettke
|
||||
*/
|
||||
/*
|
||||
* ==============================================================
|
||||
*
|
||||
* API
|
||||
*
|
||||
* ===============================================================
|
||||
*/
|
||||
#ifndef NK_GLFW_GL2_H_
|
||||
#define NK_GLFW_GL2_H_
|
||||
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
enum nk_glfw_init_state{
|
||||
NK_GLFW3_DEFAULT = 0,
|
||||
NK_GLFW3_INSTALL_CALLBACKS
|
||||
};
|
||||
NK_API struct nk_context* nk_glfw3_init(GLFWwindow *win, enum nk_glfw_init_state);
|
||||
NK_API void nk_glfw3_font_stash_begin(struct nk_font_atlas **atlas);
|
||||
NK_API void nk_glfw3_font_stash_end(void);
|
||||
|
||||
NK_API void nk_glfw3_new_frame(void);
|
||||
NK_API void nk_glfw3_render(enum nk_anti_aliasing);
|
||||
NK_API void nk_glfw3_shutdown(void);
|
||||
|
||||
NK_API void nk_glfw3_char_callback(GLFWwindow *win, unsigned int codepoint);
|
||||
NK_API void nk_gflw3_scroll_callback(GLFWwindow *win, double xoff, double yoff);
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ==============================================================
|
||||
*
|
||||
* IMPLEMENTATION
|
||||
*
|
||||
* ===============================================================
|
||||
*/
|
||||
#ifdef NK_GLFW_GL2_IMPLEMENTATION
|
||||
|
||||
#ifndef NK_GLFW_TEXT_MAX
|
||||
#define NK_GLFW_TEXT_MAX 256
|
||||
#endif
|
||||
|
||||
struct nk_glfw_device {
|
||||
struct nk_buffer cmds;
|
||||
struct nk_draw_null_texture null;
|
||||
GLuint font_tex;
|
||||
GLint uniform_tex;
|
||||
GLint uniform_proj;
|
||||
};
|
||||
|
||||
struct nk_glfw_vertex {
|
||||
float position[2];
|
||||
float uv[2];
|
||||
nk_byte col[4];
|
||||
};
|
||||
|
||||
static struct nk_glfw {
|
||||
GLFWwindow *win;
|
||||
int width, height;
|
||||
int display_width, display_height;
|
||||
struct nk_glfw_device ogl;
|
||||
struct nk_context ctx;
|
||||
struct nk_font_atlas atlas;
|
||||
struct nk_vec2 fb_scale;
|
||||
unsigned int text[NK_GLFW_TEXT_MAX];
|
||||
int text_len;
|
||||
float scroll;
|
||||
} glfw;
|
||||
|
||||
NK_INTERN void
|
||||
nk_glfw3_device_upload_atlas(const void *image, int width, int height)
|
||||
{
|
||||
struct nk_glfw_device *dev = &glfw.ogl;
|
||||
glGenTextures(1, &dev->font_tex);
|
||||
glBindTexture(GL_TEXTURE_2D, dev->font_tex);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)width, (GLsizei)height, 0,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE, image);
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_glfw3_render(enum nk_anti_aliasing AA)
|
||||
{
|
||||
/* setup global state */
|
||||
struct nk_glfw_device *dev = &glfw.ogl;
|
||||
glPushAttrib(GL_ENABLE_BIT|GL_COLOR_BUFFER_BIT|GL_TRANSFORM_BIT);
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
glEnable(GL_BLEND);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
/* setup viewport/project */
|
||||
glViewport(0,0,(GLsizei)glfw.display_width,(GLsizei)glfw.display_height);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
glOrtho(0.0f, glfw.width, glfw.height, 0.0f, -1.0f, 1.0f);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glEnableClientState(GL_COLOR_ARRAY);
|
||||
{
|
||||
GLsizei vs = sizeof(struct nk_glfw_vertex);
|
||||
size_t vp = offsetof(struct nk_glfw_vertex, position);
|
||||
size_t vt = offsetof(struct nk_glfw_vertex, uv);
|
||||
size_t vc = offsetof(struct nk_glfw_vertex, col);
|
||||
|
||||
/* convert from command queue into draw list and draw to screen */
|
||||
const struct nk_draw_command *cmd;
|
||||
const nk_draw_index *offset = NULL;
|
||||
struct nk_buffer vbuf, ebuf;
|
||||
|
||||
/* fill convert configuration */
|
||||
struct nk_convert_config config;
|
||||
static const struct nk_draw_vertex_layout_element vertex_layout[] = {
|
||||
{NK_VERTEX_POSITION, NK_FORMAT_FLOAT, NK_OFFSETOF(struct nk_glfw_vertex, position)},
|
||||
{NK_VERTEX_TEXCOORD, NK_FORMAT_FLOAT, NK_OFFSETOF(struct nk_glfw_vertex, uv)},
|
||||
{NK_VERTEX_COLOR, NK_FORMAT_R8G8B8A8, NK_OFFSETOF(struct nk_glfw_vertex, col)},
|
||||
{NK_VERTEX_LAYOUT_END}
|
||||
};
|
||||
NK_MEMSET(&config, 0, sizeof(config));
|
||||
config.vertex_layout = vertex_layout;
|
||||
config.vertex_size = sizeof(struct nk_glfw_vertex);
|
||||
config.vertex_alignment = NK_ALIGNOF(struct nk_glfw_vertex);
|
||||
config.null = dev->null;
|
||||
config.circle_segment_count = 22;
|
||||
config.curve_segment_count = 22;
|
||||
config.arc_segment_count = 22;
|
||||
config.global_alpha = 1.0f;
|
||||
config.shape_AA = AA;
|
||||
config.line_AA = AA;
|
||||
|
||||
/* convert shapes into vertexes */
|
||||
nk_buffer_init_default(&vbuf);
|
||||
nk_buffer_init_default(&ebuf);
|
||||
nk_convert(&glfw.ctx, &dev->cmds, &vbuf, &ebuf, &config);
|
||||
|
||||
/* setup vertex buffer pointer */
|
||||
{const void *vertices = nk_buffer_memory_const(&vbuf);
|
||||
glVertexPointer(2, GL_FLOAT, vs, (const void*)((const nk_byte*)vertices + vp));
|
||||
glTexCoordPointer(2, GL_FLOAT, vs, (const void*)((const nk_byte*)vertices + vt));
|
||||
glColorPointer(4, GL_UNSIGNED_BYTE, vs, (const void*)((const nk_byte*)vertices + vc));}
|
||||
|
||||
/* iterate over and execute each draw command */
|
||||
offset = (const nk_draw_index*)nk_buffer_memory_const(&ebuf);
|
||||
nk_draw_foreach(cmd, &glfw.ctx, &dev->cmds)
|
||||
{
|
||||
if (!cmd->elem_count) continue;
|
||||
glBindTexture(GL_TEXTURE_2D, (GLuint)cmd->texture.id);
|
||||
glScissor(
|
||||
(GLint)(cmd->clip_rect.x * glfw.fb_scale.x),
|
||||
(GLint)((glfw.height - (GLint)(cmd->clip_rect.y + cmd->clip_rect.h)) * glfw.fb_scale.y),
|
||||
(GLint)(cmd->clip_rect.w * glfw.fb_scale.x),
|
||||
(GLint)(cmd->clip_rect.h * glfw.fb_scale.y));
|
||||
glDrawElements(GL_TRIANGLES, (GLsizei)cmd->elem_count, GL_UNSIGNED_SHORT, offset);
|
||||
offset += cmd->elem_count;
|
||||
}
|
||||
nk_clear(&glfw.ctx);
|
||||
nk_buffer_free(&vbuf);
|
||||
nk_buffer_free(&ebuf);
|
||||
}
|
||||
|
||||
/* default OpenGL state */
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
glDisable(GL_BLEND);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
glPopAttrib();
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_glfw3_char_callback(GLFWwindow *win, unsigned int codepoint)
|
||||
{
|
||||
(void)win;
|
||||
if (glfw.text_len < NK_GLFW_TEXT_MAX)
|
||||
glfw.text[glfw.text_len++] = codepoint;
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_gflw3_scroll_callback(GLFWwindow *win, double xoff, double yoff)
|
||||
{
|
||||
(void)win; (void)xoff;
|
||||
glfw.scroll += (float)yoff;
|
||||
}
|
||||
|
||||
NK_INTERN void
|
||||
nk_glfw3_clipbard_paste(nk_handle usr, struct nk_text_edit *edit)
|
||||
{
|
||||
const char *text = glfwGetClipboardString(glfw.win);
|
||||
if (text) nk_textedit_paste(edit, text, nk_strlen(text));
|
||||
(void)usr;
|
||||
}
|
||||
|
||||
NK_INTERN void
|
||||
nk_glfw3_clipbard_copy(nk_handle usr, const char *text, int len)
|
||||
{
|
||||
char *str = 0;
|
||||
(void)usr;
|
||||
if (!len) return;
|
||||
str = (char*)malloc((size_t)len+1);
|
||||
if (!str) return;
|
||||
memcpy(str, text, (size_t)len);
|
||||
str[len] = '\0';
|
||||
glfwSetClipboardString(glfw.win, str);
|
||||
free(str);
|
||||
}
|
||||
|
||||
NK_API struct nk_context*
|
||||
nk_glfw3_init(GLFWwindow *win, enum nk_glfw_init_state init_state)
|
||||
{
|
||||
glfw.win = win;
|
||||
if (init_state == NK_GLFW3_INSTALL_CALLBACKS) {
|
||||
glfwSetScrollCallback(win, nk_gflw3_scroll_callback);
|
||||
glfwSetCharCallback(win, nk_glfw3_char_callback);
|
||||
}
|
||||
|
||||
nk_init_default(&glfw.ctx, 0);
|
||||
glfw.ctx.clip.copy = nk_glfw3_clipbard_copy;
|
||||
glfw.ctx.clip.paste = nk_glfw3_clipbard_paste;
|
||||
glfw.ctx.clip.userdata = nk_handle_ptr(0);
|
||||
nk_buffer_init_default(&glfw.ogl.cmds);
|
||||
return &glfw.ctx;
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_glfw3_font_stash_begin(struct nk_font_atlas **atlas)
|
||||
{
|
||||
nk_font_atlas_init_default(&glfw.atlas);
|
||||
nk_font_atlas_begin(&glfw.atlas);
|
||||
*atlas = &glfw.atlas;
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_glfw3_font_stash_end(void)
|
||||
{
|
||||
const void *image; int w, h;
|
||||
image = nk_font_atlas_bake(&glfw.atlas, &w, &h, NK_FONT_ATLAS_RGBA32);
|
||||
nk_glfw3_device_upload_atlas(image, w, h);
|
||||
nk_font_atlas_end(&glfw.atlas, nk_handle_id((int)glfw.ogl.font_tex), &glfw.ogl.null);
|
||||
if (glfw.atlas.default_font)
|
||||
nk_style_set_font(&glfw.ctx, &glfw.atlas.default_font->handle);
|
||||
}
|
||||
|
||||
NK_API void
|
||||
nk_glfw3_new_frame(void)
|
||||
{
|
||||
int i;
|
||||
double x, y;
|
||||
struct nk_context *ctx = &glfw.ctx;
|
||||
struct GLFWwindow *win = glfw.win;
|
||||
|
||||
glfwGetWindowSize(win, &glfw.width, &glfw.height);
|
||||
glfwGetFramebufferSize(win, &glfw.display_width, &glfw.display_height);
|
||||
glfw.fb_scale.x = (float)glfw.display_width/(float)glfw.width;
|
||||
glfw.fb_scale.y = (float)glfw.display_height/(float)glfw.height;
|
||||
|
||||
nk_input_begin(ctx);
|
||||
for (i = 0; i < glfw.text_len; ++i)
|
||||
nk_input_unicode(ctx, glfw.text[i]);
|
||||
|
||||
/* optional grabbing behavior */
|
||||
if (ctx->input.mouse.grab)
|
||||
glfwSetInputMode(glfw.win, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
|
||||
else if (ctx->input.mouse.ungrab)
|
||||
glfwSetInputMode(glfw.win, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
|
||||
|
||||
nk_input_key(ctx, NK_KEY_DEL, glfwGetKey(win, GLFW_KEY_DELETE) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_ENTER, glfwGetKey(win, GLFW_KEY_ENTER) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_TAB, glfwGetKey(win, GLFW_KEY_TAB) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_BACKSPACE, glfwGetKey(win, GLFW_KEY_BACKSPACE) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_UP, glfwGetKey(win, GLFW_KEY_UP) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_DOWN, glfwGetKey(win, GLFW_KEY_DOWN) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_TEXT_START, glfwGetKey(win, GLFW_KEY_HOME) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_TEXT_END, glfwGetKey(win, GLFW_KEY_END) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_SCROLL_START, glfwGetKey(win, GLFW_KEY_HOME) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_SCROLL_END, glfwGetKey(win, GLFW_KEY_END) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_SCROLL_DOWN, glfwGetKey(win, GLFW_KEY_PAGE_DOWN) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_SCROLL_UP, glfwGetKey(win, GLFW_KEY_PAGE_UP) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_SHIFT, glfwGetKey(win, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS||
|
||||
glfwGetKey(win, GLFW_KEY_RIGHT_SHIFT) == GLFW_PRESS);
|
||||
|
||||
if (glfwGetKey(win, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS ||
|
||||
glfwGetKey(win, GLFW_KEY_RIGHT_CONTROL) == GLFW_PRESS) {
|
||||
nk_input_key(ctx, NK_KEY_COPY, glfwGetKey(win, GLFW_KEY_C) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_PASTE, glfwGetKey(win, GLFW_KEY_V) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_CUT, glfwGetKey(win, GLFW_KEY_X) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_TEXT_UNDO, glfwGetKey(win, GLFW_KEY_Z) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_TEXT_REDO, glfwGetKey(win, GLFW_KEY_R) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_TEXT_WORD_LEFT, glfwGetKey(win, GLFW_KEY_LEFT) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_TEXT_WORD_RIGHT, glfwGetKey(win, GLFW_KEY_RIGHT) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_TEXT_LINE_START, glfwGetKey(win, GLFW_KEY_B) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_TEXT_LINE_END, glfwGetKey(win, GLFW_KEY_E) == GLFW_PRESS);
|
||||
} else {
|
||||
nk_input_key(ctx, NK_KEY_LEFT, glfwGetKey(win, GLFW_KEY_LEFT) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_RIGHT, glfwGetKey(win, GLFW_KEY_RIGHT) == GLFW_PRESS);
|
||||
nk_input_key(ctx, NK_KEY_COPY, 0);
|
||||
nk_input_key(ctx, NK_KEY_PASTE, 0);
|
||||
nk_input_key(ctx, NK_KEY_CUT, 0);
|
||||
nk_input_key(ctx, NK_KEY_SHIFT, 0);
|
||||
}
|
||||
|
||||
glfwGetCursorPos(win, &x, &y);
|
||||
nk_input_motion(ctx, (int)x, (int)y);
|
||||
if (ctx->input.mouse.grabbed) {
|
||||
glfwSetCursorPos(glfw.win, ctx->input.mouse.prev.x, ctx->input.mouse.prev.y);
|
||||
ctx->input.mouse.pos.x = ctx->input.mouse.prev.x;
|
||||
ctx->input.mouse.pos.y = ctx->input.mouse.prev.y;
|
||||
}
|
||||
|
||||
nk_input_button(ctx, NK_BUTTON_LEFT, (int)x, (int)y, glfwGetMouseButton(win, GLFW_MOUSE_BUTTON_LEFT) == GLFW_PRESS);
|
||||
nk_input_button(ctx, NK_BUTTON_MIDDLE, (int)x, (int)y, glfwGetMouseButton(win, GLFW_MOUSE_BUTTON_MIDDLE) == GLFW_PRESS);
|
||||
nk_input_button(ctx, NK_BUTTON_RIGHT, (int)x, (int)y, glfwGetMouseButton(win, GLFW_MOUSE_BUTTON_RIGHT) == GLFW_PRESS);
|
||||
nk_input_scroll(ctx, glfw.scroll);
|
||||
nk_input_end(&glfw.ctx);
|
||||
glfw.text_len = 0;
|
||||
glfw.scroll = 0;
|
||||
}
|
||||
|
||||
NK_API
|
||||
void nk_glfw3_shutdown(void)
|
||||
{
|
||||
struct nk_glfw_device *dev = &glfw.ogl;
|
||||
nk_font_atlas_clear(&glfw.atlas);
|
||||
nk_free(&glfw.ctx);
|
||||
glDeleteTextures(1, &dev->font_tex);
|
||||
nk_buffer_free(&dev->cmds);
|
||||
memset(&glfw, 0, sizeof(glfw));
|
||||
}
|
||||
|
||||
#endif
|
||||
313
src/GUI/popups.c
313
src/GUI/popups.c
@@ -1,313 +0,0 @@
|
||||
#ifndef NK_IMPLEMENTATION
|
||||
#include "nuklear_lib/nuklear.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#endif // !NK_IMPLEMENTATION
|
||||
#include "tabs.h"
|
||||
#include "popups.h"
|
||||
|
||||
void setup_network_settings(struct network_popup *network_settings)
|
||||
{
|
||||
network_settings->show_network_settings = nk_false;
|
||||
network_settings->save_network_settings = nk_false;
|
||||
strcpy(network_settings->udp_ipv4, "None");
|
||||
network_settings->udp_ipv4_len = strlen(network_settings->udp_ipv4);
|
||||
strcpy(network_settings->tcp_pass, "None");
|
||||
network_settings->tcp_pass_len = strlen(network_settings->tcp_pass);
|
||||
strcpy(network_settings->tcp_desc, "None");
|
||||
network_settings->tcp_desc_len = strlen(network_settings->tcp_desc);
|
||||
strcpy(network_settings->send_port, "None");
|
||||
network_settings->send_port_len = strlen(network_settings->send_port);
|
||||
strcpy(network_settings->send_host, "None");
|
||||
network_settings->send_host_len = strlen(network_settings->send_host);
|
||||
}
|
||||
|
||||
void draw_network_popup(struct nk_context *ctx, struct network_popup *network_settings)
|
||||
{
|
||||
const float save_ok_ratio[] = {0.8f, 0.1f, 0.1f};
|
||||
const float udp_tcp_ratio[] = {0.45f, 0.1f, 0.45f};
|
||||
static char udp_ipv4_buffer[30];
|
||||
static int udp_ipv4_len[30];
|
||||
static char tcp_pass_buf[30];
|
||||
static int tcp_pass_len[30];
|
||||
static char tcp_desc_buf[30];
|
||||
static int tcp_desc_len[30];
|
||||
static char send_port_buf[30];
|
||||
static int send_port_len[30];
|
||||
static char send_host_buf[30];
|
||||
static int send_host_len[30];
|
||||
const char network_attr[][30] = {"-udp port:", "-udp [host:]port:", "-sendto host[:port]:", "-tcp port:", "-tcppassword password:", "-tcpdesc description:"};
|
||||
static struct nk_rect s = {20, 30, 480, 500};
|
||||
if (nk_popup_begin(ctx, NK_POPUP_STATIC, "Network Settings", NK_WINDOW_CLOSABLE | NK_WINDOW_NO_SCROLLBAR, s))
|
||||
{
|
||||
nk_layout_row_dynamic(ctx, 220, 1);
|
||||
if (nk_group_begin(ctx, "Receive", NK_WINDOW_TITLE))
|
||||
{
|
||||
nk_layout_row(ctx, NK_DYNAMIC, 21, 3, udp_tcp_ratio);
|
||||
nk_spacing(ctx, 1);
|
||||
nk_label(ctx, "UDP:", NK_TEXT_CENTERED);
|
||||
nk_layout_row_static(ctx, 20, 200, 2);
|
||||
nk_label(ctx, "Hostname/IPv4 Address:", NK_TEXT_LEFT);
|
||||
nk_edit_string(ctx, NK_EDIT_SIMPLE, network_settings->udp_ipv4, &network_settings->udp_ipv4_len, 50, nk_filter_default);
|
||||
|
||||
nk_layout_row(ctx, NK_DYNAMIC, 21, 3, udp_tcp_ratio);
|
||||
nk_spacing(ctx, 1);
|
||||
nk_label(ctx, "TCP:", NK_TEXT_CENTERED);
|
||||
nk_layout_row_static(ctx, 20, 200, 2);
|
||||
nk_label(ctx, "Password:", NK_TEXT_LEFT);
|
||||
nk_edit_string(ctx, NK_EDIT_SIMPLE, network_settings->tcp_pass, &network_settings->tcp_pass_len, 25, nk_filter_default);
|
||||
nk_layout_row_static(ctx, 20, 200, 2);
|
||||
nk_label(ctx, "Description:", NK_TEXT_LEFT);
|
||||
nk_edit_string(ctx, NK_EDIT_SIMPLE, network_settings->tcp_desc, &network_settings->tcp_desc_len, 25, nk_filter_default);
|
||||
|
||||
nk_group_end(ctx);
|
||||
}
|
||||
|
||||
nk_layout_row_dynamic(ctx, 200, 1);
|
||||
if (nk_group_begin(ctx, "Send", NK_WINDOW_TITLE))
|
||||
{
|
||||
nk_layout_row(ctx, NK_DYNAMIC, 21, 3, udp_tcp_ratio);
|
||||
nk_spacing(ctx, 1);
|
||||
nk_label(ctx, "Send to:", NK_TEXT_CENTERED);
|
||||
nk_layout_row_static(ctx, 20, 200, 2);
|
||||
nk_label(ctx, "Port:", NK_TEXT_LEFT);
|
||||
nk_edit_string(ctx, NK_EDIT_SIMPLE, network_settings->send_port, &network_settings->send_port_len, 25, nk_filter_default);
|
||||
nk_layout_row_static(ctx, 20, 200, 2);
|
||||
nk_label(ctx, "Host:", NK_TEXT_LEFT);
|
||||
nk_edit_string(ctx, NK_EDIT_SIMPLE, network_settings->send_host, &network_settings->send_host_len, 25, nk_filter_default);
|
||||
|
||||
nk_group_end(ctx);
|
||||
}
|
||||
|
||||
/*nk_layout_row_static(ctx, 20, 200, 2);
|
||||
nk_label(ctx, network_attr[5], NK_TEXT_LEFT);
|
||||
nk_edit_string(ctx, NK_EDIT_SIMPLE, text_buffer[5], &text_len[5], 50, nk_filter_default);*/
|
||||
|
||||
//OK Button
|
||||
nk_layout_row(ctx, NK_DYNAMIC, 27, 3, save_ok_ratio);
|
||||
nk_spacing(ctx, 1);
|
||||
if (nk_button_label(ctx, "Save"))
|
||||
{
|
||||
network_settings->save_network_settings = nk_true;
|
||||
network_settings->show_network_settings = nk_false;
|
||||
nk_popup_close(ctx);
|
||||
}
|
||||
if (nk_button_label(ctx, "OK"))
|
||||
{
|
||||
network_settings->save_network_settings = nk_false;
|
||||
network_settings->show_network_settings = nk_false;
|
||||
nk_popup_close(ctx);
|
||||
}
|
||||
|
||||
nk_popup_end(ctx);
|
||||
}
|
||||
else
|
||||
network_settings->show_network_settings = nk_false;
|
||||
}
|
||||
|
||||
void draw_getting_started_popup(struct nk_context *ctx, int *show_getting_started)
|
||||
{
|
||||
static struct nk_rect s = {20, 30, 480, 500};
|
||||
if (nk_popup_begin(ctx, NK_POPUP_STATIC, "Getting Started", NK_WINDOW_CLOSABLE, s))
|
||||
{
|
||||
nk_layout_row_dynamic(ctx, 80, 1);
|
||||
nk_label_wrap(ctx, "Getting Started information about CCX will come here! This popup will be populated at the end.");
|
||||
nk_popup_end(ctx);
|
||||
}
|
||||
else
|
||||
*show_getting_started = nk_false;
|
||||
}
|
||||
|
||||
void draw_about_ccx_popup(struct nk_context *ctx, int *show_about_ccx, struct nk_user_font *droid_big, struct nk_user_font *droid_head)
|
||||
{
|
||||
const float ccx_ratio[] = {0.3f, 0.4f, 0.3f};
|
||||
const float ok_ratio[] = {0.9f, 0.1f};
|
||||
static struct nk_rect s = {20, 30, 480, 500};
|
||||
if (nk_popup_begin(ctx, NK_POPUP_STATIC, "About CCExtractor", NK_WINDOW_CLOSABLE | NK_WINDOW_NO_SCROLLBAR, s))
|
||||
{
|
||||
nk_style_push_font(ctx, droid_big);
|
||||
nk_layout_row(ctx, NK_DYNAMIC, 30, 3, ccx_ratio);
|
||||
nk_spacing(ctx, 1);
|
||||
nk_label_wrap(ctx, "About CCExtractor" /*, NK_TEXT_LEFT*/);
|
||||
nk_style_pop_font(ctx);
|
||||
|
||||
nk_layout_row_dynamic(ctx, 390, 1);
|
||||
if (nk_group_begin(ctx, "About CCExtractor", NK_WINDOW_BACKGROUND))
|
||||
{
|
||||
nk_style_push_font(ctx, droid_head);
|
||||
nk_layout_row_dynamic(ctx, 23, 1);
|
||||
nk_label_wrap(ctx, "What's CCExtractor?");
|
||||
nk_style_pop_font(ctx);
|
||||
|
||||
nk_layout_row_dynamic(ctx, 65, 1);
|
||||
nk_label_wrap(ctx, "A tool that analyzes video files and produces independent subtitle files from the closed captions data. CCExtractor is portable, small, and very fast. It works in Linux, Windows, and OSX.");
|
||||
|
||||
nk_style_push_font(ctx, droid_head);
|
||||
nk_layout_row_dynamic(ctx, 23, 1);
|
||||
nk_label_wrap(ctx, "What kind of closed captions does CCExtractor support?");
|
||||
nk_style_pop_font(ctx);
|
||||
|
||||
nk_layout_row_dynamic(ctx, 47, 1);
|
||||
nk_label_wrap(ctx, "American TV captions (CEA-608 is well supported, and CEA-708 is starting to look good) and Teletext based European subtitles.");
|
||||
|
||||
nk_style_push_font(ctx, droid_head);
|
||||
nk_layout_row_dynamic(ctx, 23, 1);
|
||||
nk_label_wrap(ctx, "How easy is it to use CCExtractor?");
|
||||
nk_style_pop_font(ctx);
|
||||
|
||||
nk_layout_row_dynamic(ctx, 30, 1);
|
||||
nk_label_wrap(ctx, "Very. Just tell it what file to process and it does everything for you.");
|
||||
|
||||
nk_style_push_font(ctx, droid_head);
|
||||
nk_layout_row_dynamic(ctx, 23, 1);
|
||||
nk_label_wrap(ctx, "CCExtractor integration with other tools");
|
||||
nk_style_pop_font(ctx);
|
||||
|
||||
nk_layout_row_dynamic(ctx, 147, 1);
|
||||
nk_label_wrap(ctx, "It is possible to integrate CCExtractor in a larger process. A couple of tools already call CCExtractor as part their video process - this way they get subtitle support for free. Starting in 0.52, CCExtractor is very front - end friendly.Front - ends can easily get real - time status information.The GUI source code is provided and can be used for reference. Any tool, commercial or not, is specifically allowed to use CCExtractor for any use the authors seem fit. So if your favourite video tools still lacks captioning tool, feel free to send the authors here.");
|
||||
|
||||
nk_style_push_font(ctx, droid_head);
|
||||
nk_layout_row_dynamic(ctx, 50, 1);
|
||||
nk_label_wrap(ctx, "What's the point of generating separate files for subtitles, if they are already in the source file?");
|
||||
nk_style_pop_font(ctx);
|
||||
|
||||
nk_layout_row_dynamic(ctx, 367, 1);
|
||||
nk_label_wrap(ctx, "There are several reasons to have subtitles separated from the video file, including: - Closed captions never survive MPEG processing. If you take a MPEG file and encode it to any format (such as divx), your result file will not have closed captions. This means that if you want to keep the subtitles, you need to keep the original file. This is hardly practical if you are archiving HDTV shows for example. - Subtitles files are small - so small (around 250 Kb for a movie) that you can quickly download them, or email them, etc, in case you have a recording without subtitles. - Subtitles files are indexable: You can have a database with all your subtitles if you want (there are many available), so you can search the dialogs. - Subtitles files are a de-facto standard: Almost every player can use them. In fact, many setbox players accept subtitles files in .srt format - so you can have subtitles in your divx movies and not just in your original DVDs. - Closed captions are stored in many different formats by capture cards. Upgrading to a new card, if it comes with a new player, may mean that you can't use your previously recorded closed captions, even if the audio/video are fine. - Closed captions require a closed caption decoder. All US TV have one (it's a legal requirement), but no European TV does, since there are not closed captions in Europe (teletext is used instead). Basically this means that if you buy a DVD in the US which has closed captions but no DVD subtitles, you are out of luck. This is a problem with many (most) old TV shows DVDs, which only come with closed captions. DVD producers don't bother doing DVD subs, since it's another way to segment the market, same as with DVD regions. ");
|
||||
|
||||
nk_style_push_font(ctx, droid_head);
|
||||
nk_layout_row_dynamic(ctx, 23, 1);
|
||||
nk_label_wrap(ctx, "How I do use subtitles once they are in a separate file?");
|
||||
nk_style_pop_font(ctx);
|
||||
|
||||
nk_layout_row_dynamic(ctx, 80, 1);
|
||||
nk_label_wrap(ctx, "CCExtractor generates files in the two most common formats: .srt (SubRip) and .smi (which is a Microsoft standard). Most players support at least .srt natively. You just need to name the .srt file as the file you want to play it with, for example sample.avi and sample.srt.");
|
||||
|
||||
nk_style_push_font(ctx, droid_head);
|
||||
nk_layout_row_dynamic(ctx, 23, 1);
|
||||
nk_label_wrap(ctx, "What kind of files can I extract closed captions from?");
|
||||
nk_style_pop_font(ctx);
|
||||
|
||||
nk_layout_row_dynamic(ctx, 20, 1);
|
||||
nk_label_wrap(ctx, "CCExtractor currently handles:");
|
||||
nk_layout_row_dynamic(ctx, 20, 1);
|
||||
nk_label_wrap(ctx, "- DVDs.");
|
||||
nk_layout_row_dynamic(ctx, 20, 1);
|
||||
nk_label_wrap(ctx, "- Most HDTV captures(where you save the Transport Stream).");
|
||||
nk_layout_row_dynamic(ctx, 52, 1);
|
||||
nk_label_wrap(ctx, "- Captures where captions are recorded in bttv format.The number of cards that use this card is huge.My test samples came from a Hauppage PVR - 250. You can check the complete list here:");
|
||||
nk_layout_row_dynamic(ctx, 40, 1);
|
||||
nk_label_colored_wrap(ctx, "http://linuxtv.org/hg/v4l-dvb/file/tip/linux/Documentation/video4linux/CARDLIST.bttv", nk_rgb(61, 117, 206));
|
||||
nk_layout_row_dynamic(ctx, 20, 1);
|
||||
nk_label_wrap(ctx, "- DVR - MS(microsoft digital video recording).");
|
||||
nk_layout_row_dynamic(ctx, 20, 1);
|
||||
nk_label_wrap(ctx, "- Tivo files");
|
||||
nk_layout_row_dynamic(ctx, 20, 1);
|
||||
nk_label_wrap(ctx, "- ReplayTV files");
|
||||
nk_layout_row_dynamic(ctx, 20, 1);
|
||||
nk_label_wrap(ctx, "- Dish Network files");
|
||||
nk_layout_row_dynamic(ctx, 80, 1);
|
||||
nk_label_wrap(ctx, "Usually, if you record a TV show with your capture card and CCExtractor produces the expected result, it will work for your all recordings.If it doesn't, which means that your card uses a format CCExtractor can't handle, please contact me and we'll try to make it work.");
|
||||
|
||||
nk_style_push_font(ctx, droid_head);
|
||||
nk_layout_row_dynamic(ctx, 23, 1);
|
||||
nk_label_wrap(ctx, "Can I edit the subtitles? ");
|
||||
nk_style_pop_font(ctx);
|
||||
|
||||
nk_layout_row_dynamic(ctx, 43, 1);
|
||||
nk_label_wrap(ctx, ".srt files are just text files, with time information (when subtitles are supposed to be shown and for how long) and some basic formatting (use italics, bold, etc). So you can edit them with any text editor. If you need to do serious editing (such as adjusting timing), you can use subtitle editing tools - there are many available.");
|
||||
|
||||
nk_style_push_font(ctx, droid_head);
|
||||
nk_layout_row_dynamic(ctx, 23, 1);
|
||||
nk_label_wrap(ctx, "Can CCExtractor generate other subtitles formats?");
|
||||
nk_style_pop_font(ctx);
|
||||
|
||||
nk_layout_row_dynamic(ctx, 23, 1);
|
||||
nk_label_wrap(ctx, "At this time, CCExtractor can generate .srt, .smi and raw and bin files.");
|
||||
|
||||
nk_style_push_font(ctx, droid_head);
|
||||
nk_layout_row_dynamic(ctx, 23, 1);
|
||||
nk_label_wrap(ctx, "How I can contact the author?");
|
||||
nk_style_pop_font(ctx);
|
||||
|
||||
nk_layout_row_dynamic(ctx, 23, 1);
|
||||
nk_label_wrap(ctx, "Send me an email: carlos@ccextractor.org");
|
||||
|
||||
nk_group_end(ctx);
|
||||
}
|
||||
|
||||
nk_layout_row(ctx, NK_DYNAMIC, 27, 2, ok_ratio);
|
||||
nk_spacing(ctx, 1);
|
||||
if (nk_button_label(ctx, "OK"))
|
||||
{
|
||||
*show_about_ccx = nk_false;
|
||||
nk_popup_close(ctx);
|
||||
}
|
||||
nk_popup_end(ctx);
|
||||
}
|
||||
else
|
||||
*show_about_ccx = nk_false;
|
||||
}
|
||||
|
||||
void draw_progress_details_popup(struct nk_context *ctx, int *show_progress_details, struct main_tab *main_settings)
|
||||
{
|
||||
static struct nk_rect s = {20, 30, 480, 500};
|
||||
if (nk_popup_begin(ctx, NK_POPUP_STATIC, "Progress Details of Extraction", NK_WINDOW_CLOSABLE, s))
|
||||
{
|
||||
nk_layout_row_dynamic(ctx, 20, 1);
|
||||
for (int i = 0; i < main_settings->activity_string_count; i++)
|
||||
nk_label_wrap(ctx, main_settings->activity_string[i]);
|
||||
nk_popup_end(ctx);
|
||||
}
|
||||
else
|
||||
*show_progress_details = nk_false;
|
||||
}
|
||||
|
||||
void draw_color_popup(struct nk_context *ctx, struct output_tab *output)
|
||||
{
|
||||
static struct nk_rect s = {250, 250, 200, 230};
|
||||
if (nk_popup_begin(ctx, NK_POPUP_STATIC, "Color Picker", NK_WINDOW_TITLE | NK_WINDOW_NO_SCROLLBAR | NK_WINDOW_BORDER, s))
|
||||
{
|
||||
nk_layout_row_dynamic(ctx, 160, 1);
|
||||
output->color_rgb = nk_color_picker(ctx, output->color_rgb, NK_RGBA);
|
||||
|
||||
nk_layout_row_dynamic(ctx, 25, 3);
|
||||
nk_spacing(ctx, 1);
|
||||
if (nk_button_label(ctx, "OK"))
|
||||
{
|
||||
show_color_from_picker = nk_true;
|
||||
output->color_popup = nk_false;
|
||||
nk_popup_close(ctx);
|
||||
}
|
||||
nk_spacing(ctx, 1);
|
||||
|
||||
nk_popup_end(ctx);
|
||||
}
|
||||
else
|
||||
output->color_popup = nk_false;
|
||||
}
|
||||
|
||||
void draw_thread_popup(struct nk_context *ctx, int *show_thread_popup)
|
||||
{
|
||||
static struct nk_rect s = {100, 100, 300, 175};
|
||||
static const float ratio[] = {0.85f, 0.15f};
|
||||
if (nk_popup_begin(ctx, NK_POPUP_STATIC, "File Read Error",
|
||||
NK_WINDOW_TITLE | NK_WINDOW_NO_SCROLLBAR | NK_WINDOW_BORDER, s))
|
||||
{
|
||||
nk_layout_row_dynamic(ctx, 25, 1);
|
||||
nk_label(ctx, "Cannot read file.", NK_TEXT_CENTERED);
|
||||
nk_layout_row_dynamic(ctx, 60, 1);
|
||||
nk_label_wrap(ctx, "Make sure the directory isn't write protected OR you are running the program with write permissions.");
|
||||
|
||||
nk_layout_row(ctx, NK_DYNAMIC, 25, 2, ratio);
|
||||
nk_spacing(ctx, 1);
|
||||
if (nk_button_label(ctx, "OK"))
|
||||
{
|
||||
*show_thread_popup = nk_false;
|
||||
nk_popup_close(ctx);
|
||||
}
|
||||
nk_popup_end(ctx);
|
||||
}
|
||||
|
||||
else
|
||||
*show_thread_popup = nk_false;
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
#ifndef POPUPS_H
|
||||
#define POPUPS_H
|
||||
|
||||
#include "tabs.h"
|
||||
|
||||
struct network_popup
|
||||
{
|
||||
int show_network_settings;
|
||||
int save_network_settings;
|
||||
char udp_ipv4[30];
|
||||
int udp_ipv4_len;
|
||||
char tcp_pass[30];
|
||||
int tcp_pass_len;
|
||||
char tcp_desc[30];
|
||||
int tcp_desc_len;
|
||||
char send_port[30];
|
||||
int send_port_len;
|
||||
char send_host[30];
|
||||
int send_host_len;
|
||||
};
|
||||
|
||||
void draw_network_popup(struct nk_context *ctx, struct network_popup *network_settings);
|
||||
void draw_getting_started_popup(struct nk_context *ctx, int *show_getting_started);
|
||||
void draw_about_ccx_popup(struct nk_context *ctx, int *show_about_ccx, struct nk_user_font *droid_big, struct nk_user_font *droid_head);
|
||||
void draw_progress_details_popup(struct nk_context *ctx, int *show_progress_details, struct main_tab *main_settings);
|
||||
void draw_color_popup(struct nk_context *ctx, struct output_tab *output);
|
||||
void draw_thread_popup(struct nk_context *ctx, int *show_thread_popup);
|
||||
|
||||
void setup_network_settings(struct network_popup *network_settings);
|
||||
|
||||
#endif //!POPUPS_H
|
||||
@@ -1,19 +0,0 @@
|
||||
#ifndef NK_IMPLEMENTATION
|
||||
#include "nuklear_lib/nuklear.h"
|
||||
#endif // !NK_IMPLEMENTATION
|
||||
|
||||
#include <stdio.h>
|
||||
#include "preview.h"
|
||||
|
||||
int preview(struct nk_context *ctx, int x, int y, int width, int height, struct main_tab *main_settings)
|
||||
{
|
||||
static int i;
|
||||
if (nk_begin(ctx, "Preview", nk_rect(x, y, width, height), NK_WINDOW_TITLE | NK_WINDOW_BACKGROUND))
|
||||
{
|
||||
nk_layout_row_dynamic(ctx, 20, 1);
|
||||
for (i = 0; i < main_settings->preview_string_count; i++)
|
||||
nk_label_wrap(ctx, main_settings->preview_string[i]);
|
||||
}
|
||||
nk_end(ctx);
|
||||
return !nk_window_is_closed(ctx, "Preview");
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
#ifndef PREVIEW_H
|
||||
#define PREVIEW_H
|
||||
|
||||
#include "ccextractorGUI.h"
|
||||
|
||||
int preview(struct nk_context *ctx, int x, int y, int width, int height, struct main_tab *main_settings);
|
||||
|
||||
#endif //!PREVIEW_H
|
||||
@@ -1,561 +0,0 @@
|
||||
#include "save_load_data.h"
|
||||
#include "ccextractorGUI.h"
|
||||
#include "tabs.h"
|
||||
#include "popups.h"
|
||||
|
||||
void load_data(FILE *file,
|
||||
struct main_tab *main_settings,
|
||||
struct input_tab *input,
|
||||
struct advanced_input_tab *advanced_input,
|
||||
struct output_tab *output,
|
||||
struct decoders_tab *decoders,
|
||||
struct credits_tab *credits,
|
||||
struct debug_tab *debug,
|
||||
struct hd_homerun_tab *hd_homerun,
|
||||
struct burned_subs_tab *burned_subs,
|
||||
struct network_popup *network_settings)
|
||||
{
|
||||
int null_int, r, g, b;
|
||||
char null_char[260];
|
||||
|
||||
//Read main_tab data
|
||||
fscanf(file, "port_or_files:%d\n", &main_settings->port_or_files);
|
||||
fscanf(file, "port_num_len:%d\n", &main_settings->port_num_len);
|
||||
if (main_settings->port_num_len > 0)
|
||||
fscanf(file, "port_num:%[^\n]\n", main_settings->port_num);
|
||||
else
|
||||
fscanf(file, "%[^\n]\n", null_char);
|
||||
|
||||
fscanf(file, "is_check_common_extension:%d\n", &main_settings->is_check_common_extension);
|
||||
fscanf(file, "port_select:%d\n", &main_settings->port_select);
|
||||
|
||||
//Read input_tab data
|
||||
fscanf(file, "type_select:%d\n", &input->type_select);
|
||||
fscanf(file, "is_split:%d\n", &input->is_split);
|
||||
fscanf(file, "is_live_stream:%d\n", &input->is_live_stream);
|
||||
fscanf(file, "wait_data_sec_len:%d\n", &input->wait_data_sec_len);
|
||||
if (input->wait_data_sec_len > 0)
|
||||
fscanf(file, "wait_data_sec:%[^\n]\n", input->wait_data_sec);
|
||||
else
|
||||
fscanf(file, "%[^\n]\n", null_char);
|
||||
fscanf(file, "is_process_from:%d\n", &input->is_process_from);
|
||||
fscanf(file, "is_process_until:%d\n", &input->is_process_until);
|
||||
|
||||
fscanf(file, "from_time_buffer:%[^\n]\n", input->from_time_buffer);
|
||||
|
||||
fscanf(file, "until_time_buffer:%[^\n]\n", input->until_time_buffer);
|
||||
|
||||
fscanf(file, "elementary_stream:%d\n", &input->elementary_stream);
|
||||
fscanf(file, "is_assume_mpeg:%d\n", &input->is_assume_mpeg);
|
||||
fscanf(file, "stream_type_len:%d\n", &input->stream_type_len);
|
||||
if (input->stream_type_len > 0)
|
||||
fscanf(file, "stream_type:%[^\n]\n", input->stream_type);
|
||||
else
|
||||
fscanf(file, "%[^\n]\n", null_char);
|
||||
fscanf(file, "stream_pid_len:%d\n", &input->stream_pid_len);
|
||||
if (input->stream_pid_len > 0)
|
||||
fscanf(file, "stream_pid:%[^\n]\n", input->stream_pid);
|
||||
else
|
||||
fscanf(file, "%[^\n]\n", null_char);
|
||||
fscanf(file, "mpeg_type_len:%d\n", &input->mpeg_type_len);
|
||||
if (input->mpeg_type_len > 0)
|
||||
fscanf(file, "mpeg_type:%[^\n]\n", input->mpeg_type);
|
||||
else
|
||||
fscanf(file, "%[^\n]\n", null_char);
|
||||
|
||||
fscanf(file, "teletext_decoder:%d\n", &input->teletext_decoder);
|
||||
fscanf(file, "is_process_teletext_page:%d\n", &input->is_process_teletext_page);
|
||||
fscanf(file, "teletext_page_number_len:%d\n", &input->teletext_page_numer_len);
|
||||
if (input->teletext_page_numer_len)
|
||||
fscanf(file, "teletext_page_number:%[^\n]\n", input->teletext_page_number);
|
||||
else
|
||||
fscanf(file, "%[^\n]\n", null_char);
|
||||
|
||||
fscanf(file, "is_limit:%d\n", &input->is_limit);
|
||||
fscanf(file, "screenful_limit_buffer:%[^\n]\n", input->screenful_limit_buffer);
|
||||
fscanf(file, "clock_input:%d\n", &input->clock_input);
|
||||
|
||||
//Read advanced_input_tab data
|
||||
fscanf(file, "is_multiple_program:%d\n", &advanced_input->is_multiple_program);
|
||||
fscanf(file, "multiple_program:%d\n", &advanced_input->multiple_program);
|
||||
fscanf(file, "prog_number_len:%d\n", &advanced_input->prog_number_len);
|
||||
if (advanced_input->prog_number_len)
|
||||
fscanf(file, "prog_number:%[^\n]\n", advanced_input->prog_number);
|
||||
else
|
||||
fscanf(file, "%[^\n]\n", null_char);
|
||||
|
||||
fscanf(file, "set_myth:%d\n", &advanced_input->set_myth);
|
||||
fscanf(file, "is_mpeg_90090:%d\n", &advanced_input->is_mpeg_90090);
|
||||
fscanf(file, "is_padding_0000:%d\n", &advanced_input->is_padding_0000);
|
||||
fscanf(file, "is_order_ccinfo:%d\n", &advanced_input->is_order_ccinfo);
|
||||
fscanf(file, "is_win_bug:%d\n", &advanced_input->is_win_bug);
|
||||
fscanf(file, "is_hauppage_file:%d\n", &advanced_input->is_hauppage_file);
|
||||
fscanf(file, "is_process_mp4:%d\n", &advanced_input->is_process_mp4);
|
||||
fscanf(file, "is_ignore_broadcast:%d\n", &advanced_input->is_ignore_broadcast);
|
||||
|
||||
//Read output_tab data
|
||||
fscanf(file, "type_select:%d\n", &output->type_select);
|
||||
fscanf(file, "is_filename:%d\n", &output->is_filename);
|
||||
fscanf(file, "filename_len:%d\n", &output->filename_len);
|
||||
if (output->filename_len > 0)
|
||||
fscanf(file, "filename:%[^\n]\n", output->filename);
|
||||
else
|
||||
fscanf(file, "%[^\n]\n", null_char);
|
||||
|
||||
fscanf(file, "is_delay:%d\n", &output->is_delay);
|
||||
fscanf(file, "delay_sec_buffer:%[^\n]\n", output->delay_sec_buffer);
|
||||
fscanf(file, "is_export_xds:%d\n", &output->is_export_xds);
|
||||
fscanf(file, "encoding:%d\n", &output->encoding);
|
||||
fscanf(file, "is_bom:%d\n", &output->is_bom);
|
||||
fscanf(file, "is_cap_standard:%d\n", &output->is_cap_standard);
|
||||
fscanf(file, "is_cap_file:%d\n", &output->is_cap_file);
|
||||
fscanf(file, "cap_dictionary_len:%d\n", &output->cap_dictionary_len);
|
||||
if (output->cap_dictionary_len > 0)
|
||||
fscanf(file, "cap_dictionary:%[^\n]\n", output->cap_dictionary);
|
||||
else
|
||||
fscanf(file, "%[^\n]\n", null_char);
|
||||
|
||||
fscanf(file, "line_ending:%d\n", &output->line_ending);
|
||||
fscanf(file, "is_center:%d\n", &output->is_center);
|
||||
fscanf(file, "is_dash:%d\n", &output->is_dash);
|
||||
fscanf(file, "no_typesetting:%d\n", &output->no_typesetting);
|
||||
fscanf(file, "font_color:%d\n", &output->font_color);
|
||||
fscanf(file, "color_hex:%[^\n]\n", output->color_hex);
|
||||
fscanf(file, "color_rgb_r:%d\n", &r);
|
||||
fscanf(file, "color_rgb_g:%d\n", &g);
|
||||
fscanf(file, "color_rgb_b:%d\n", &b);
|
||||
output->color_rgb.r = (nk_byte)r;
|
||||
output->color_rgb.g = (nk_byte)g;
|
||||
output->color_rgb.b = (nk_byte)b;
|
||||
|
||||
fscanf(file, "onetime_or_realtime:%d\n", &output->onetime_or_realtime);
|
||||
fscanf(file, "roll_limit_select:%d\n", &output->roll_limit_select);
|
||||
|
||||
//Read decoders_tab data
|
||||
fscanf(file, "is_field1:%d\n", &decoders->is_field1);
|
||||
fscanf(file, "is_field2:%d\n", &decoders->is_field2);
|
||||
fscanf(file, "channel:%d\n", &decoders->channel);
|
||||
fscanf(file, "is_708:%d\n", &decoders->is_708);
|
||||
fscanf(file, "services_len:%d\n", &decoders->services_len);
|
||||
if (decoders->services_len > 0)
|
||||
fscanf(file, "services:%[^\n]\n", decoders->services);
|
||||
else
|
||||
fscanf(file, "%[^\n]\n", null_char);
|
||||
|
||||
fscanf(file, "teletext_dvb:%d\n", &decoders->teletext_dvb);
|
||||
fscanf(file, "min_distance_len:%d\n", &decoders->min_distance_len);
|
||||
if (decoders->min_distance_len > 0)
|
||||
fscanf(file, "min_distance:%[^\n]\n", decoders->min_distance);
|
||||
else
|
||||
fscanf(file, "%[^\n]\n", null_char);
|
||||
fscanf(file, "max_distance_len:%d\n", &decoders->max_distance_len);
|
||||
if (decoders->max_distance_len > 0)
|
||||
fscanf(file, "max_distance:%[^\n]\n", decoders->max_distance);
|
||||
else
|
||||
fscanf(file, "%[^\n]\n", null_char);
|
||||
|
||||
//Read credits tab data
|
||||
fscanf(file, "is_start_text:%d\n", &credits->is_start_text);
|
||||
|
||||
fscanf(file, "is_before:%d\n", &credits->is_before);
|
||||
fscanf(file, "is_after:%d\n", &credits->is_after);
|
||||
fscanf(file, "before_time_buffer:%[^\n]\n", credits->before_time_buffer);
|
||||
fscanf(file, "after_time_buffer:%[^\n]\n", credits->after_time_buffer);
|
||||
fscanf(file, "start_atmost_sec_len:%d\n", &credits->start_atmost_sec_len);
|
||||
if (credits->start_atmost_sec_len > 0)
|
||||
fscanf(file, "start_atmost_sec:%[^\n]\n", credits->start_atmost_sec);
|
||||
else
|
||||
fscanf(file, "%[^\n]\n", null_char);
|
||||
fscanf(file, "start_atleast_sec_len:%d\n", &credits->start_atleast_sec_len);
|
||||
if (credits->start_atleast_sec_len > 0)
|
||||
fscanf(file, "start_atleast_sec:%[^\n]\n", credits->start_atleast_sec);
|
||||
else
|
||||
fscanf(file, "%[^\n]\n", null_char);
|
||||
|
||||
fscanf(file, "is_end_text:%d\n", &credits->is_end_text);
|
||||
fscanf(file, "end_atmost_sec_len:%d\n", &credits->end_atmost_sec_len);
|
||||
if (credits->end_atmost_sec_len > 0)
|
||||
fscanf(file, "end_atmost_sec:%[^\n]\n", credits->end_atmost_sec);
|
||||
else
|
||||
fscanf(file, "%[^\n]\n", null_char);
|
||||
|
||||
fscanf(file, "end_atleast_sec_len:%d\n", &credits->end_atleast_sec_len);
|
||||
if (credits->end_atleast_sec_len > 0)
|
||||
fscanf(file, "end_atleast_sec:%[^\n]\n", credits->end_atleast_sec);
|
||||
else
|
||||
fscanf(file, "%[^\n]\n", null_char);
|
||||
|
||||
fscanf(file, "start_text_len:%d\n", &credits->start_text_len);
|
||||
fscanf(file, "end_text_len:%d\n", &credits->end_text_len);
|
||||
read_credits(file, credits);
|
||||
|
||||
//Read debug tab data
|
||||
fscanf(file, "is_elementary_stream:%d\n", &debug->is_elementary_stream);
|
||||
fscanf(file, "elementary_stream_len:%d\n", &debug->elementary_stream_len);
|
||||
if (debug->elementary_stream_len > 0)
|
||||
fscanf(file, "elementary_stream:%[^\n]\n", debug->elementary_stream);
|
||||
else
|
||||
fscanf(file, "%[^\n]\n", null_char);
|
||||
|
||||
fscanf(file, "is_dump_packets:%d\n", &debug->is_dump_packets);
|
||||
fscanf(file, "is_debug_608:%d\n", &debug->is_debug_608);
|
||||
fscanf(file, "is_debug_708:%d\n", &debug->is_debug_708);
|
||||
fscanf(file, "is_stamp_output:%d\n", &debug->is_stamp_output);
|
||||
fscanf(file, "is_debug_analysed_vid:%d\n", &debug->is_debug_analysed_vid);
|
||||
fscanf(file, "is_raw_608_708:%d\n", &debug->is_raw_608_708);
|
||||
fscanf(file, "is_debug_parsed:%d\n", &debug->is_debug_parsed);
|
||||
fscanf(file, "is_disable_sync:%d\n", &debug->is_disable_sync);
|
||||
fscanf(file, "is_no_padding:%d\n", &debug->is_no_padding);
|
||||
fscanf(file, "is_debug_xds:%d\n", &debug->is_debug_xds);
|
||||
fscanf(file, "is_output_pat:%d\n", &debug->is_output_pat);
|
||||
fscanf(file, "is_output_pmt:%d\n", &debug->is_output_pmt);
|
||||
fscanf(file, "is_scan_ccdata:%d\n", &debug->is_scan_ccdata);
|
||||
fscanf(file, "is_output_levenshtein:%d\n", &debug->is_output_levenshtein);
|
||||
|
||||
//Read HD Homerun Tab data
|
||||
fscanf(file, "location_len:%d\n", &hd_homerun->location_len);
|
||||
if (hd_homerun->location_len > 0)
|
||||
fscanf(file, "location:%[^\n]\n", hd_homerun->location);
|
||||
else
|
||||
fscanf(file, "%[^\n]\n", null_char);
|
||||
fscanf(file, "tuner_len:%d\n", &hd_homerun->tuner_len);
|
||||
if (hd_homerun->tuner_len > 0)
|
||||
fscanf(file, "tuner:%[^\n]\n", hd_homerun->tuner);
|
||||
else
|
||||
fscanf(file, "%[^\n]\n", null_char);
|
||||
fscanf(file, "channel_len:%d\n", &hd_homerun->channel_len);
|
||||
if (hd_homerun->channel_len > 0)
|
||||
fscanf(file, "channel:%[^\n]\n", hd_homerun->channel);
|
||||
else
|
||||
fscanf(file, "%[^\n]\n", null_char);
|
||||
fscanf(file, "program_len:%d\n", &hd_homerun->program_len);
|
||||
if (hd_homerun->program_len > 0)
|
||||
fscanf(file, "program:%[^\n]\n", hd_homerun->program);
|
||||
else
|
||||
fscanf(file, "%[^\n]\n", null_char);
|
||||
fscanf(file, "ipv4_address_len:%d\n", &hd_homerun->ipv4_address_len);
|
||||
if (hd_homerun->ipv4_address_len > 0)
|
||||
fscanf(file, "ipv4_address:%[^\n]\n", hd_homerun->ipv4_address);
|
||||
else
|
||||
fscanf(file, "%[^\n]\n", null_char);
|
||||
fscanf(file, "port_number_len:%d\n", &hd_homerun->port_number_len);
|
||||
if (hd_homerun->port_number_len > 0)
|
||||
fscanf(file, "port_number:%[^\n]\n", hd_homerun->port_number);
|
||||
else
|
||||
fscanf(file, "%[^\n]\n", null_char);
|
||||
|
||||
//Read Burned Subs tab data
|
||||
fscanf(file, "is_burnded_subs:%d\n", &burned_subs->is_burned_subs);
|
||||
fscanf(file, "color_type:%d\n", &burned_subs->color_type);
|
||||
fscanf(file, "sub_color_select:%d\n", &burned_subs->subs_color_select);
|
||||
fscanf(file, "custom_hue_len:%d\n", &burned_subs->custom_hue_len);
|
||||
if (burned_subs->custom_hue_len > 0)
|
||||
fscanf(file, "custom_hue:%[^\n]\n", burned_subs->custom_hue);
|
||||
else
|
||||
fscanf(file, "%[^\n]\n", null_char);
|
||||
|
||||
fscanf(file, "ocr_mode:%d\n", &burned_subs->ocr_mode);
|
||||
fscanf(file, "min_duration_len:%d\n", &burned_subs->min_duration_len);
|
||||
if (burned_subs->min_duration_len > 0)
|
||||
fscanf(file, "min_duration:%[^\n]\n", burned_subs->min_duration);
|
||||
else
|
||||
fscanf(file, "%[^\n]\n", null_char);
|
||||
|
||||
fscanf(file, "luminance_threshold:%d\n", &burned_subs->luminance_threshold);
|
||||
fscanf(file, "confidence_threshold:%d\n", &burned_subs->confidence_threshold);
|
||||
fscanf(file, "is_italic:%d\n", &burned_subs->is_italic);
|
||||
|
||||
//Read Network Settings data
|
||||
fscanf(file, "udp_ipv4_len:%d\n", &network_settings->udp_ipv4_len);
|
||||
if (network_settings->udp_ipv4_len > 0)
|
||||
fscanf(file, "udp_ipv4:%[^\n]\n", network_settings->udp_ipv4);
|
||||
else
|
||||
fscanf(file, "udp_ipv4:%[^\n]\n", null_char);
|
||||
fscanf(file, "tcp_pass_len:%d\n", &network_settings->tcp_pass_len);
|
||||
if (network_settings->tcp_pass_len > 0)
|
||||
fscanf(file, "tcp_pass:%[^\n]\n", network_settings->tcp_pass);
|
||||
else
|
||||
fscanf(file, "tcp_pass:%[^\n]\n", null_char);
|
||||
fscanf(file, "tcp_desc_len:%d\n", &network_settings->tcp_desc_len);
|
||||
if (network_settings->tcp_desc_len > 0)
|
||||
fscanf(file, "tcp_desc:%[^\n]\n", network_settings->tcp_desc);
|
||||
else
|
||||
fscanf(file, "tcp_desc:%[^\n]\n", null_char);
|
||||
fscanf(file, "send_port_len:%d\n", &network_settings->send_port_len);
|
||||
if (network_settings->send_port_len > 0)
|
||||
fscanf(file, "send_port:%[^\n]\n", network_settings->send_port);
|
||||
else
|
||||
fscanf(file, "send_port:%[^\n]\n", null_char);
|
||||
fscanf(file, "send_host_len:%d\n", &network_settings->send_host_len);
|
||||
if (network_settings->send_host_len > 0)
|
||||
fscanf(file, "send_host:%[^\n]\n", network_settings->send_host);
|
||||
fscanf(file, "send_host:%[^\n]\n", null_char);
|
||||
}
|
||||
|
||||
void save_data(FILE *file,
|
||||
struct main_tab *main_settings,
|
||||
struct input_tab *input,
|
||||
struct advanced_input_tab *advanced_input,
|
||||
struct output_tab *output,
|
||||
struct decoders_tab *decoders,
|
||||
struct credits_tab *credits,
|
||||
struct debug_tab *debug,
|
||||
struct hd_homerun_tab *hd_homerun,
|
||||
struct burned_subs_tab *burned_subs,
|
||||
struct network_popup *network_settings)
|
||||
{
|
||||
//Write main_tab data
|
||||
fprintf(file, "port_or_files:%d\n", main_settings->port_or_files);
|
||||
fprintf(file, "port_num_len:%d\n", main_settings->port_num_len);
|
||||
fprintf(file, "port_num:%s\n", main_settings->port_num);
|
||||
|
||||
fprintf(file, "is_check_common_extension:%d\n", main_settings->is_check_common_extension);
|
||||
fprintf(file, "port_select:%d\n", main_settings->port_select);
|
||||
|
||||
//Write input_tab data
|
||||
fprintf(file, "type_select:%d\n", input->type_select);
|
||||
fprintf(file, "is_split:%d\n", input->is_split);
|
||||
fprintf(file, "is_live_stream:%d\n", input->is_live_stream);
|
||||
fprintf(file, "wait_data_sec_len:%d\n", input->wait_data_sec_len);
|
||||
fprintf(file, "wait_data_sec:%s\n", input->wait_data_sec);
|
||||
|
||||
fprintf(file, "is_process_from:%d\n", input->is_process_from);
|
||||
fprintf(file, "is_process_until:%d\n", input->is_process_until);
|
||||
fprintf(file, "from_time_buffer:%s\n", input->from_time_buffer);
|
||||
fprintf(file, "until_time_buffer:%s\n", input->until_time_buffer);
|
||||
fprintf(file, "elementary_stream:%d\n", input->elementary_stream);
|
||||
fprintf(file, "is_assume_mpeg:%d\n", input->is_assume_mpeg);
|
||||
fprintf(file, "stream_type_len:%d\n", input->stream_type_len);
|
||||
fprintf(file, "stream_type:%s\n", input->stream_type);
|
||||
fprintf(file, "stream_pid_len:%d\n", input->stream_pid_len);
|
||||
fprintf(file, "stream_pid:%s\n", input->stream_pid);
|
||||
fprintf(file, "mpeg_type_len:%d\n", input->mpeg_type_len);
|
||||
fprintf(file, "mpeg_type:%s\n", input->mpeg_type);
|
||||
|
||||
fprintf(file, "teletext_decoder:%d\n", input->teletext_decoder);
|
||||
fprintf(file, "is_process_teletext_page:%d\n", input->is_process_teletext_page);
|
||||
fprintf(file, "teletext_page_number_len:%d\n", input->teletext_page_numer_len);
|
||||
fprintf(file, "teletext_page_number:%s\n", input->teletext_page_number);
|
||||
|
||||
fprintf(file, "is_limit:%d\n", input->is_limit);
|
||||
fprintf(file, "screenful_limit_buffer:%s\n", input->screenful_limit_buffer);
|
||||
fprintf(file, "clock_input:%d\n", input->clock_input);
|
||||
|
||||
//Write advanced_input_tab data
|
||||
fprintf(file, "is_multiple_program:%d\n", advanced_input->is_multiple_program);
|
||||
fprintf(file, "multiple_program:%d\n", advanced_input->multiple_program);
|
||||
fprintf(file, "prog_number_len:%d\n", advanced_input->prog_number_len);
|
||||
fprintf(file, "prog_number:%s\n", advanced_input->prog_number);
|
||||
|
||||
fprintf(file, "set_myth:%d\n", advanced_input->set_myth);
|
||||
fprintf(file, "is_mpeg_90090:%d\n", advanced_input->is_mpeg_90090);
|
||||
fprintf(file, "is_padding_0000:%d\n", advanced_input->is_padding_0000);
|
||||
fprintf(file, "is_order_ccinfo:%d\n", advanced_input->is_order_ccinfo);
|
||||
fprintf(file, "is_win_bug:%d\n", advanced_input->is_win_bug);
|
||||
fprintf(file, "is_hauppage_file:%d\n", advanced_input->is_hauppage_file);
|
||||
fprintf(file, "is_process_mp4:%d\n", advanced_input->is_process_mp4);
|
||||
fprintf(file, "is_ignore_broadcast:%d\n", advanced_input->is_ignore_broadcast);
|
||||
|
||||
//Write output_tab data
|
||||
fprintf(file, "type_select:%d\n", output->type_select);
|
||||
fprintf(file, "is_filename:%d\n", output->is_filename);
|
||||
fprintf(file, "filename_len:%d\n", output->filename_len);
|
||||
fprintf(file, "filename:%s\n", output->filename);
|
||||
fprintf(file, "is_delay:%d\n", output->is_delay);
|
||||
fprintf(file, "delay_sec_buffer:%s\n", output->delay_sec_buffer);
|
||||
fprintf(file, "is_export_xds:%d\n", output->is_export_xds);
|
||||
fprintf(file, "encoding:%d\n", output->encoding);
|
||||
fprintf(file, "is_bom:%d\n", output->is_bom);
|
||||
fprintf(file, "is_cap_standard:%d\n", output->is_cap_standard);
|
||||
fprintf(file, "is_cap_file:%d\n", output->is_cap_file);
|
||||
fprintf(file, "cap_dictionary_len:%d\n", output->cap_dictionary_len);
|
||||
fprintf(file, "cap_dictionary:%s\n", output->cap_dictionary);
|
||||
|
||||
fprintf(file, "line_ending:%d\n", output->line_ending);
|
||||
fprintf(file, "is_center:%d\n", output->is_center);
|
||||
fprintf(file, "is_dash:%d\n", output->is_dash);
|
||||
fprintf(file, "no_typesetting:%d\n", output->no_typesetting);
|
||||
fprintf(file, "font_color:%d\n", output->font_color);
|
||||
fprintf(file, "color_hex:%s\n", output->color_hex);
|
||||
fprintf(file, "color_rgb_r:%d\n", output->color_rgb.r);
|
||||
fprintf(file, "color_rgb_g:%d\n", output->color_rgb.g);
|
||||
fprintf(file, "color_rgb_b:%d\n", output->color_rgb.b);
|
||||
fprintf(file, "onetime_or_realtime:%d\n", output->onetime_or_realtime);
|
||||
fprintf(file, "roll_limit_select:%d\n", output->roll_limit_select);
|
||||
|
||||
//Write decoders_tab data
|
||||
fprintf(file, "is_field1:%d\n", decoders->is_field1);
|
||||
fprintf(file, "is_field2:%d\n", decoders->is_field2);
|
||||
fprintf(file, "channel:%d\n", decoders->channel);
|
||||
fprintf(file, "is_708:%d\n", decoders->is_708);
|
||||
fprintf(file, "services_len:%d\n", decoders->services_len);
|
||||
fprintf(file, "services:%s\n", decoders->services);
|
||||
|
||||
fprintf(file, "teletext_dvb:%d\n", decoders->teletext_dvb);
|
||||
fprintf(file, "min_distance_len:%d\n", decoders->min_distance_len);
|
||||
fprintf(file, "min_distance:%s\n", decoders->min_distance);
|
||||
fprintf(file, "max_distance_len:%d\n", decoders->max_distance_len);
|
||||
fprintf(file, "max_distance:%s\n", decoders->max_distance);
|
||||
|
||||
//Write credits tab data
|
||||
fprintf(file, "is_start_text:%d\n", credits->is_start_text);
|
||||
|
||||
fprintf(file, "is_before:%d\n", credits->is_before);
|
||||
fprintf(file, "is_after:%d\n", credits->is_after);
|
||||
fprintf(file, "before_time_buffer:%s\n", credits->before_time_buffer);
|
||||
fprintf(file, "after_time_buffer:%s\n", credits->after_time_buffer);
|
||||
fprintf(file, "start_atmost_sec_len:%d\n", credits->start_atmost_sec_len);
|
||||
fprintf(file, "start_atmost_sec:%s\n", credits->start_atmost_sec);
|
||||
fprintf(file, "start_atleast_sec_len:%d\n", credits->start_atleast_sec_len);
|
||||
fprintf(file, "start_atleast_sec:%s\n", credits->start_atleast_sec);
|
||||
|
||||
fprintf(file, "is_end_text:%d\n", credits->is_end_text);
|
||||
fprintf(file, "end_atmost_sec_len:%d\n", credits->end_atmost_sec_len);
|
||||
fprintf(file, "end_atmost_sec:%s\n", credits->end_atmost_sec);
|
||||
fprintf(file, "end_atleast_sec_len:%d\n", credits->end_atleast_sec_len);
|
||||
fprintf(file, "end_atleast_sec:%s\n", credits->end_atleast_sec);
|
||||
fprintf(file, "start_text_len:%d\n", credits->start_text_len);
|
||||
fprintf(file, "end_text_len:%d\n", credits->end_text_len);
|
||||
write_credits(file, credits);
|
||||
|
||||
//Write debug tab data
|
||||
fprintf(file, "is_elementary_stream:%d\n", debug->is_elementary_stream);
|
||||
fprintf(file, "elementary_stream_len:%d\n", debug->elementary_stream_len);
|
||||
fprintf(file, "elementary_stream:%s\n", debug->elementary_stream);
|
||||
|
||||
fprintf(file, "is_dump_packets:%d\n", debug->is_dump_packets);
|
||||
fprintf(file, "is_debug_608:%d\n", debug->is_debug_608);
|
||||
fprintf(file, "is_debug_708:%d\n", debug->is_debug_708);
|
||||
fprintf(file, "is_stamp_output:%d\n", debug->is_stamp_output);
|
||||
fprintf(file, "is_debug_analysed_vid:%d\n", debug->is_debug_analysed_vid);
|
||||
fprintf(file, "is_raw_608_708:%d\n", debug->is_raw_608_708);
|
||||
fprintf(file, "is_debug_parsed:%d\n", debug->is_debug_parsed);
|
||||
fprintf(file, "is_disable_sync:%d\n", debug->is_disable_sync);
|
||||
fprintf(file, "is_no_padding:%d\n", debug->is_no_padding);
|
||||
fprintf(file, "is_debug_xds:%d\n", debug->is_debug_xds);
|
||||
fprintf(file, "is_output_pat:%d\n", debug->is_output_pat);
|
||||
fprintf(file, "is_output_pmt:%d\n", debug->is_output_pmt);
|
||||
fprintf(file, "is_scan_ccdata:%d\n", debug->is_scan_ccdata);
|
||||
fprintf(file, "is_output_levenshtein:%d\n", debug->is_output_levenshtein);
|
||||
|
||||
//Write HD Homerun Tab data
|
||||
fprintf(file, "location_len:%d\n", hd_homerun->location_len);
|
||||
fprintf(file, "location:%s\n", hd_homerun->location);
|
||||
fprintf(file, "tuner_len:%d\n", hd_homerun->tuner_len);
|
||||
fprintf(file, "tuner:%s\n", hd_homerun->tuner);
|
||||
fprintf(file, "channel_len:%d\n", hd_homerun->channel_len);
|
||||
fprintf(file, "channel:%s\n", hd_homerun->channel);
|
||||
fprintf(file, "program_len:%d\n", hd_homerun->program_len);
|
||||
fprintf(file, "program:%s\n", hd_homerun->program);
|
||||
fprintf(file, "ipv4_address_len:%d\n", hd_homerun->ipv4_address_len);
|
||||
fprintf(file, "ipv4_address:%s\n", hd_homerun->ipv4_address);
|
||||
fprintf(file, "port_number_len:%d\n", hd_homerun->port_number_len);
|
||||
fprintf(file, "port_number:%s\n", hd_homerun->port_number);
|
||||
|
||||
//Write Burned Subs tab data
|
||||
fprintf(file, "is_burnded_subs:%d\n", burned_subs->is_burned_subs);
|
||||
fprintf(file, "color_type:%d\n", burned_subs->color_type);
|
||||
fprintf(file, "sub_color_select:%d\n", burned_subs->subs_color_select);
|
||||
fprintf(file, "custom_hue_len:%d\n", burned_subs->custom_hue_len);
|
||||
fprintf(file, "custom_hue:%s\n", burned_subs->custom_hue);
|
||||
|
||||
fprintf(file, "ocr_mode:%d\n", burned_subs->ocr_mode);
|
||||
fprintf(file, "min_duration_len:%d\n", burned_subs->min_duration_len);
|
||||
fprintf(file, "min_duration:%s\n", burned_subs->min_duration);
|
||||
|
||||
fprintf(file, "luminance_threshold:%d\n", burned_subs->luminance_threshold);
|
||||
fprintf(file, "confidence_threshold:%d\n", burned_subs->confidence_threshold);
|
||||
fprintf(file, "is_italic:%d\n", burned_subs->is_italic);
|
||||
|
||||
//Write Network Settings popup data
|
||||
if (network_settings->save_network_settings)
|
||||
{
|
||||
fprintf(file, "udp_ipv4_len:%d\n", network_settings->udp_ipv4_len);
|
||||
fprintf(file, "udp_ipv4:%s\n", network_settings->udp_ipv4);
|
||||
fprintf(file, "tcp_pass_len:%d\n", network_settings->tcp_pass_len);
|
||||
fprintf(file, "tcp_pass:%s\n", network_settings->tcp_pass);
|
||||
fprintf(file, "tcp_desc_len:%d\n", network_settings->tcp_desc_len);
|
||||
fprintf(file, "tcp_desc:%s\n", network_settings->tcp_desc);
|
||||
fprintf(file, "send_port_len:%d\n", network_settings->send_port_len);
|
||||
fprintf(file, "send_port:%s\n", network_settings->send_port);
|
||||
fprintf(file, "send_host_len:%d\n", network_settings->send_host_len);
|
||||
fprintf(file, "send_host:%s\n", network_settings->send_host);
|
||||
}
|
||||
}
|
||||
|
||||
void write_credits(FILE *file, struct credits_tab *credits)
|
||||
{
|
||||
//Number of newlines in end_text
|
||||
static int newlines_end;
|
||||
//Number of newlines in start_text
|
||||
static int newlines_start;
|
||||
int newline_char = 10; // '\n' is 10 in ascii encoding
|
||||
for (int i = 0; i < credits->start_text_len; i++)
|
||||
{
|
||||
if (credits->start_text[i] == newline_char)
|
||||
newlines_start++;
|
||||
}
|
||||
|
||||
for (int i = 0; i < credits->end_text_len; i++)
|
||||
{
|
||||
if (credits->end_text[i] == newline_char)
|
||||
newlines_end++;
|
||||
}
|
||||
|
||||
fprintf(file, "start_text:%d\n", newlines_start);
|
||||
if (credits->start_text_len > 0)
|
||||
fprintf(file, "%s\n", credits->start_text);
|
||||
fprintf(file, "end_text:%d\n", newlines_end);
|
||||
if (credits->end_text_len > 0)
|
||||
fprintf(file, "%s\n", credits->end_text);
|
||||
}
|
||||
|
||||
void read_credits(FILE *file, struct credits_tab *credits)
|
||||
{
|
||||
//Number of newlines in end_text
|
||||
static int newlines_end;
|
||||
//Number of newlines in start_text
|
||||
static int newlines_start;
|
||||
static char buffer[1000], null_char[260];
|
||||
if (credits->start_text_len == 0)
|
||||
fscanf(file, "%[^\n]\n", null_char);
|
||||
else
|
||||
{
|
||||
fscanf(file, "start_text:%d\n", &newlines_start);
|
||||
for (int i = 0; i != newlines_start + 1; i++)
|
||||
{
|
||||
static char line[200];
|
||||
fscanf(file, "%[^\n]\n", line);
|
||||
if (!(i == newlines_start))
|
||||
strcat(line, "\n");
|
||||
if (strlen(buffer) > 0)
|
||||
strcat(buffer, line);
|
||||
else
|
||||
strcpy(buffer, line);
|
||||
}
|
||||
|
||||
memset(credits->start_text, 0, sizeof(credits->start_text));
|
||||
strcpy(credits->start_text, buffer);
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
}
|
||||
|
||||
if (credits->end_text_len == 0)
|
||||
fscanf(file, "%[^\n]\n", null_char);
|
||||
else
|
||||
{
|
||||
fscanf(file, "end_text:%d\n", &newlines_end);
|
||||
for (int i = 0; i != newlines_end + 1; i++)
|
||||
{
|
||||
static char line[200];
|
||||
fscanf(file, "%[^\n]\n", line);
|
||||
if (!(i == newlines_end))
|
||||
strcat(line, "\n");
|
||||
if (strlen(buffer) > 0)
|
||||
strcat(buffer, line);
|
||||
else
|
||||
strcpy(buffer, line);
|
||||
}
|
||||
memset(credits->end_text, 0, sizeof(credits->end_text));
|
||||
strcpy(credits->end_text, buffer);
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
#ifndef SAVE_LOAD_DATA_H
|
||||
#define SAVE_LOAD_DATA_H
|
||||
|
||||
#include "ccextractorGUI.h"
|
||||
#include "tabs.h"
|
||||
#include "popups.h"
|
||||
#include <stdio.h>
|
||||
|
||||
void load_data(FILE *file,
|
||||
struct main_tab* main_settings,
|
||||
struct input_tab* input,
|
||||
struct advanced_input_tab* advanced_input,
|
||||
struct output_tab* output,
|
||||
struct decoders_tab* decoders,
|
||||
struct credits_tab* credits,
|
||||
struct debug_tab* debug,
|
||||
struct hd_homerun_tab* hd_homerun,
|
||||
struct burned_subs_tab* burned_subs,
|
||||
struct network_popup* network_settings);
|
||||
|
||||
void save_data(FILE *file,
|
||||
struct main_tab* main_settings,
|
||||
struct input_tab* input,
|
||||
struct advanced_input_tab* advanced_input,
|
||||
struct output_tab* output,
|
||||
struct decoders_tab* decoders,
|
||||
struct credits_tab* credits,
|
||||
struct debug_tab* debug,
|
||||
struct hd_homerun_tab* hd_homerun,
|
||||
struct burned_subs_tab* burned_subs,
|
||||
struct network_popup* network_settings);
|
||||
|
||||
void write_credits(FILE* file, struct credits_tab* credits);
|
||||
void read_credits(FILE* file, struct credits_tab* credits);
|
||||
//Number of newlines in end_text
|
||||
static int newlines_end;
|
||||
//Number of newlines in start_text
|
||||
static int newlines_start;
|
||||
|
||||
#endif //!SAVE_LOAD_DATA_H
|
||||
6509
src/GUI/stb_image.h
6509
src/GUI/stb_image.h
File diff suppressed because it is too large
Load Diff
1130
src/GUI/tabs.c
1130
src/GUI/tabs.c
File diff suppressed because it is too large
Load Diff
241
src/GUI/tabs.h
241
src/GUI/tabs.h
@@ -1,241 +0,0 @@
|
||||
#ifndef TABS_H
|
||||
#define TABS_H
|
||||
|
||||
#include "ccextractorGUI.h"
|
||||
/*Global variable for output tab*/
|
||||
int show_color_from_picker;
|
||||
|
||||
/*Data containers for other functions*/
|
||||
|
||||
struct output_tab
|
||||
{
|
||||
//General
|
||||
char **type;
|
||||
int type_select;
|
||||
int is_filename;
|
||||
char filename[260];
|
||||
int filename_len;
|
||||
int is_output_browser_active;
|
||||
int is_delay;
|
||||
char delay_sec_buffer[4];
|
||||
int is_export_xds;
|
||||
//Encoding
|
||||
enum { LATIN, UNIC, UTF } encoding;
|
||||
int is_bom;
|
||||
//Capitalization
|
||||
int is_cap_browser_active;
|
||||
int is_cap_standard;
|
||||
int is_cap_file;
|
||||
char cap_dictionary[260];
|
||||
int cap_dictionary_len;
|
||||
//Line Endings
|
||||
enum { CRLF, LF } line_ending;
|
||||
//Colors and Styles
|
||||
int is_center;
|
||||
int is_dash;
|
||||
int no_typesetting;
|
||||
enum { NO_COLOR, DEFAULT_COLOR } font_color;
|
||||
int color_popup;
|
||||
char color_hex[7];
|
||||
struct nk_color color_rgb;
|
||||
//Roll-up Captions
|
||||
enum {ONETIME, REALTIME} onetime_or_realtime;
|
||||
char **roll_limit;
|
||||
int roll_limit_select;
|
||||
};
|
||||
|
||||
struct time {
|
||||
int hours, minutes, seconds;
|
||||
};
|
||||
|
||||
|
||||
struct input_tab {
|
||||
//General
|
||||
char **type;
|
||||
int type_select;
|
||||
int is_split;
|
||||
int is_live_stream;
|
||||
char wait_data_sec[4];
|
||||
int wait_data_sec_len;
|
||||
//Timing
|
||||
int is_process_from;
|
||||
int is_process_until;
|
||||
char from_time_buffer[10];
|
||||
char until_time_buffer[10];
|
||||
//Elementary Stream
|
||||
enum {AUTO_DETECT,STREAM_TYPE,STREAM_PID} elementary_stream;
|
||||
int is_assume_mpeg;
|
||||
char stream_type[10];
|
||||
int stream_type_len;
|
||||
char stream_pid[10];
|
||||
int stream_pid_len;
|
||||
char mpeg_type[10];
|
||||
int mpeg_type_len;
|
||||
//Teletext
|
||||
enum { AUTO_DECODE, FORCE, DISABLE } teletext_decoder;
|
||||
int is_process_teletext_page;
|
||||
char teletext_page_number[6];
|
||||
int teletext_page_numer_len;
|
||||
//Screenfuls limit
|
||||
enum { NO_LIMIT, LIMITED } is_limit;
|
||||
char screenful_limit_buffer[4];
|
||||
//Clock
|
||||
enum { AUTO, GOP, PTS } clock_input;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct advanced_input_tab{
|
||||
|
||||
//Multiple Programs
|
||||
int is_multiple_program;
|
||||
enum { FIRST_PROG, PROG_NUM } multiple_program;
|
||||
char prog_number[6];
|
||||
int prog_number_len;
|
||||
|
||||
//Myth TV
|
||||
enum { AUTO_MYTH, FORCE_MYTH, DISABLE_MYTH } set_myth;
|
||||
|
||||
//Miscellaneous
|
||||
int is_mpeg_90090;
|
||||
int is_padding_0000;
|
||||
int is_order_ccinfo;
|
||||
int is_win_bug;
|
||||
int is_hauppage_file;
|
||||
int is_process_mp4;
|
||||
int is_ignore_broadcast;
|
||||
|
||||
};
|
||||
|
||||
struct debug_tab{
|
||||
int is_elementary_stream;
|
||||
char elementary_stream[260];
|
||||
int elementary_stream_len;
|
||||
int is_dump_packets;
|
||||
int is_debug_608;
|
||||
int is_debug_708;
|
||||
int is_stamp_output;
|
||||
int is_debug_analysed_vid;
|
||||
int is_raw_608_708;
|
||||
int is_debug_parsed;
|
||||
int is_disable_sync;
|
||||
int is_no_padding;
|
||||
int is_debug_xds;
|
||||
int is_output_pat;
|
||||
int is_output_pmt;
|
||||
int is_scan_ccdata;
|
||||
int is_output_levenshtein;
|
||||
//File browser trigger
|
||||
int is_debug_browser_active;
|
||||
};
|
||||
|
||||
|
||||
struct burned_subs_tab{
|
||||
int is_burned_subs;
|
||||
enum {PRESET, CUSTOM} color_type;
|
||||
char** subs_color;
|
||||
int subs_color_select;
|
||||
char custom_hue[4];
|
||||
int custom_hue_len;
|
||||
enum {FRAME_WISE, WORD_WISE, LETTER_WISE} ocr_mode;
|
||||
char min_duration[4];
|
||||
int min_duration_len;
|
||||
int luminance_threshold;
|
||||
int confidence_threshold;
|
||||
int is_italic;
|
||||
};
|
||||
|
||||
struct decoders_tab{
|
||||
//608 DECODER
|
||||
int is_field1;
|
||||
int is_field2;
|
||||
enum { CHANNEL_1, CHANNEL_2 } channel;
|
||||
|
||||
//708 DECODER
|
||||
int is_708;
|
||||
char services[15];
|
||||
int services_len;
|
||||
|
||||
//Teletext or DVB
|
||||
enum { TELETEXT, DVB } teletext_dvb;
|
||||
|
||||
//Teletext line Duplication
|
||||
char min_distance[4];
|
||||
int min_distance_len;
|
||||
char max_distance[4];
|
||||
int max_distance_len;
|
||||
};
|
||||
|
||||
struct credits_tab{
|
||||
//START CREDITS
|
||||
int is_start_text;
|
||||
char start_text[1000];
|
||||
int start_text_len;
|
||||
int is_before;
|
||||
int is_after;
|
||||
char before_time_buffer[10];
|
||||
char after_time_buffer[10];
|
||||
char start_atmost_sec[4];
|
||||
int start_atmost_sec_len;
|
||||
char start_atleast_sec[4];
|
||||
int start_atleast_sec_len;
|
||||
|
||||
//END CREDITS
|
||||
int is_end_text;
|
||||
char end_text[1000];
|
||||
int end_text_len;
|
||||
char end_atmost_sec[4];
|
||||
int end_atmost_sec_len;
|
||||
char end_atleast_sec[4];
|
||||
int end_atleast_sec_len;
|
||||
};
|
||||
|
||||
struct hd_homerun_tab{
|
||||
char location[260];
|
||||
int location_len;
|
||||
int device_select[50];
|
||||
int device_num;
|
||||
char **devices;
|
||||
int is_homerun_browser_active;
|
||||
char tuner[2];
|
||||
int tuner_len;
|
||||
char channel[5];
|
||||
int channel_len;
|
||||
char program[10];
|
||||
int program_len;
|
||||
char ipv4_address[16];
|
||||
int ipv4_address_len;
|
||||
char port_number[8];
|
||||
int port_number_len;
|
||||
int selected;
|
||||
int threadPopup;
|
||||
};
|
||||
|
||||
/*Tab Functions*/
|
||||
void setup_output_tab(struct output_tab *output);
|
||||
void setup_decoders_tab(struct decoders_tab *decoders);
|
||||
void setup_credits_tab(struct credits_tab *credits);
|
||||
void setup_input_tab(struct input_tab *input);
|
||||
void setup_advanced_input_tab(struct advanced_input_tab *advaned_input);
|
||||
void setup_debug_tab(struct debug_tab *debug);
|
||||
void setup_hd_homerun_tab(struct hd_homerun_tab *hd_homerun);
|
||||
void setup_burned_subs_tab(struct burned_subs_tab *burned_subs);
|
||||
|
||||
void draw_input_tab(struct nk_context *ctx, int *tab_screen_height, struct input_tab *input,
|
||||
struct decoders_tab *decoders);
|
||||
void draw_advanced_input_tab(struct nk_context *ctx, int *tab_screen_height,
|
||||
struct advanced_input_tab *advaned_input);
|
||||
void draw_output_tab(struct nk_context *ctx, int *tab_screen_height, struct output_tab *output,
|
||||
struct main_tab *main_settings);
|
||||
void draw_decoders_tab(struct nk_context *ctx, int *tab_screen_height, struct decoders_tab *decoders);
|
||||
void draw_credits_tab(struct nk_context *ctx, int *tab_screen_height, struct credits_tab *credits);
|
||||
void draw_debug_tab(struct nk_context *ctx, int *tab_screen_height,
|
||||
struct main_tab *main_settings,
|
||||
struct output_tab *output,
|
||||
struct debug_tab *debug);
|
||||
void draw_hd_homerun_tab(struct nk_context *ctx, int *tab_screen_height,
|
||||
struct hd_homerun_tab *hd_homerun,
|
||||
struct main_tab *main_settings);
|
||||
void draw_burned_subs_tab(struct nk_context *ctx, int *tab_screen_height, struct burned_subs_tab *burned_subs);
|
||||
|
||||
#endif //!TABS_H
|
||||
@@ -1,16 +0,0 @@
|
||||
#ifndef NK_IMPLEMENTATION
|
||||
#include "nuklear_lib/nuklear.h"
|
||||
#endif // !NK_IMPLEMENTATION
|
||||
|
||||
static int
|
||||
terminal(struct nk_context *ctx, int x, int y, int width, int height, char *command)
|
||||
{
|
||||
if (nk_begin(ctx, "Terminal", nk_rect(x, y, width, height),
|
||||
NK_WINDOW_TITLE | NK_WINDOW_BACKGROUND))
|
||||
{
|
||||
nk_layout_row_dynamic(ctx, 60, 1);
|
||||
nk_label_wrap(ctx, command);
|
||||
}
|
||||
nk_end(ctx);
|
||||
return !nk_window_is_closed(ctx, "Terminal");
|
||||
}
|
||||
@@ -1,951 +0,0 @@
|
||||
/*
|
||||
* Dirent interface for Microsoft Visual Studio
|
||||
* Version 1.21
|
||||
*
|
||||
* Copyright (C) 2006-2012 Toni Ronkko
|
||||
* This file is part of dirent. Dirent may be freely distributed
|
||||
* under the MIT license. For all details and documentation, see
|
||||
* https://github.com/tronkko/dirent
|
||||
*/
|
||||
#ifndef DIRENT_H
|
||||
#define DIRENT_H
|
||||
|
||||
/*
|
||||
* Include windows.h without Windows Sockets 1.1 to prevent conflicts with
|
||||
* Windows Sockets 2.0.
|
||||
*/
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <windows.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <wchar.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <malloc.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
|
||||
/* Indicates that d_type field is available in dirent structure */
|
||||
#define _DIRENT_HAVE_D_TYPE
|
||||
|
||||
/* Indicates that d_namlen field is available in dirent structure */
|
||||
#define _DIRENT_HAVE_D_NAMLEN
|
||||
|
||||
/* Entries missing from MSVC 6.0 */
|
||||
#if !defined(FILE_ATTRIBUTE_DEVICE)
|
||||
# define FILE_ATTRIBUTE_DEVICE 0x40
|
||||
#endif
|
||||
|
||||
/* File type and permission flags for stat(), general mask */
|
||||
#if !defined(S_IFMT)
|
||||
# define S_IFMT _S_IFMT
|
||||
#endif
|
||||
|
||||
/* Directory bit */
|
||||
#if !defined(S_IFDIR)
|
||||
# define S_IFDIR _S_IFDIR
|
||||
#endif
|
||||
|
||||
/* Character device bit */
|
||||
#if !defined(S_IFCHR)
|
||||
# define S_IFCHR _S_IFCHR
|
||||
#endif
|
||||
|
||||
/* Pipe bit */
|
||||
#if !defined(S_IFFIFO)
|
||||
# define S_IFFIFO _S_IFFIFO
|
||||
#endif
|
||||
|
||||
/* Regular file bit */
|
||||
#if !defined(S_IFREG)
|
||||
# define S_IFREG _S_IFREG
|
||||
#endif
|
||||
|
||||
/* Read permission */
|
||||
#if !defined(S_IREAD)
|
||||
# define S_IREAD _S_IREAD
|
||||
#endif
|
||||
|
||||
/* Write permission */
|
||||
#if !defined(S_IWRITE)
|
||||
# define S_IWRITE _S_IWRITE
|
||||
#endif
|
||||
|
||||
/* Execute permission */
|
||||
#if !defined(S_IEXEC)
|
||||
# define S_IEXEC _S_IEXEC
|
||||
#endif
|
||||
|
||||
/* Pipe */
|
||||
#if !defined(S_IFIFO)
|
||||
# define S_IFIFO _S_IFIFO
|
||||
#endif
|
||||
|
||||
/* Block device */
|
||||
#if !defined(S_IFBLK)
|
||||
# define S_IFBLK 0
|
||||
#endif
|
||||
|
||||
/* Link */
|
||||
#if !defined(S_IFLNK)
|
||||
# define S_IFLNK 0
|
||||
#endif
|
||||
|
||||
/* Socket */
|
||||
#if !defined(S_IFSOCK)
|
||||
# define S_IFSOCK 0
|
||||
#endif
|
||||
|
||||
/* Read user permission */
|
||||
#if !defined(S_IRUSR)
|
||||
# define S_IRUSR S_IREAD
|
||||
#endif
|
||||
|
||||
/* Write user permission */
|
||||
#if !defined(S_IWUSR)
|
||||
# define S_IWUSR S_IWRITE
|
||||
#endif
|
||||
|
||||
/* Execute user permission */
|
||||
#if !defined(S_IXUSR)
|
||||
# define S_IXUSR 0
|
||||
#endif
|
||||
|
||||
/* Read group permission */
|
||||
#if !defined(S_IRGRP)
|
||||
# define S_IRGRP 0
|
||||
#endif
|
||||
|
||||
/* Write group permission */
|
||||
#if !defined(S_IWGRP)
|
||||
# define S_IWGRP 0
|
||||
#endif
|
||||
|
||||
/* Execute group permission */
|
||||
#if !defined(S_IXGRP)
|
||||
# define S_IXGRP 0
|
||||
#endif
|
||||
|
||||
/* Read others permission */
|
||||
#if !defined(S_IROTH)
|
||||
# define S_IROTH 0
|
||||
#endif
|
||||
|
||||
/* Write others permission */
|
||||
#if !defined(S_IWOTH)
|
||||
# define S_IWOTH 0
|
||||
#endif
|
||||
|
||||
/* Execute others permission */
|
||||
#if !defined(S_IXOTH)
|
||||
# define S_IXOTH 0
|
||||
#endif
|
||||
|
||||
/* Maximum length of file name */
|
||||
#if !defined(PATH_MAX)
|
||||
# define PATH_MAX MAX_PATH
|
||||
#endif
|
||||
#if !defined(FILENAME_MAX)
|
||||
# define FILENAME_MAX MAX_PATH
|
||||
#endif
|
||||
#if !defined(NAME_MAX)
|
||||
# define NAME_MAX FILENAME_MAX
|
||||
#endif
|
||||
|
||||
/* File type flags for d_type */
|
||||
#define DT_UNKNOWN 0
|
||||
#define DT_REG S_IFREG
|
||||
#define DT_DIR S_IFDIR
|
||||
#define DT_FIFO S_IFIFO
|
||||
#define DT_SOCK S_IFSOCK
|
||||
#define DT_CHR S_IFCHR
|
||||
#define DT_BLK S_IFBLK
|
||||
#define DT_LNK S_IFLNK
|
||||
|
||||
/* Macros for converting between st_mode and d_type */
|
||||
#define IFTODT(mode) ((mode) & S_IFMT)
|
||||
#define DTTOIF(type) (type)
|
||||
|
||||
/*
|
||||
* File type macros. Note that block devices, sockets and links cannot be
|
||||
* distinguished on Windows and the macros S_ISBLK, S_ISSOCK and S_ISLNK are
|
||||
* only defined for compatibility. These macros should always return false
|
||||
* on Windows.
|
||||
*/
|
||||
#if !defined(S_ISFIFO)
|
||||
# define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
|
||||
#endif
|
||||
#if !defined(S_ISDIR)
|
||||
# define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
|
||||
#endif
|
||||
#if !defined(S_ISREG)
|
||||
# define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
|
||||
#endif
|
||||
#if !defined(S_ISLNK)
|
||||
# define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)
|
||||
#endif
|
||||
#if !defined(S_ISSOCK)
|
||||
# define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
|
||||
#endif
|
||||
#if !defined(S_ISCHR)
|
||||
# define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR)
|
||||
#endif
|
||||
#if !defined(S_ISBLK)
|
||||
# define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK)
|
||||
#endif
|
||||
|
||||
/* Return the exact length of d_namlen without zero terminator */
|
||||
#define _D_EXACT_NAMLEN(p) ((p)->d_namlen)
|
||||
|
||||
/* Return number of bytes needed to store d_namlen */
|
||||
#define _D_ALLOC_NAMLEN(p) (PATH_MAX)
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* Wide-character version */
|
||||
struct _wdirent {
|
||||
/* Always zero */
|
||||
long d_ino;
|
||||
|
||||
/* Structure size */
|
||||
unsigned short d_reclen;
|
||||
|
||||
/* Length of name without \0 */
|
||||
size_t d_namlen;
|
||||
|
||||
/* File type */
|
||||
int d_type;
|
||||
|
||||
/* File name */
|
||||
wchar_t d_name[PATH_MAX];
|
||||
};
|
||||
typedef struct _wdirent _wdirent;
|
||||
|
||||
struct _WDIR {
|
||||
/* Current directory entry */
|
||||
struct _wdirent ent;
|
||||
|
||||
/* Private file data */
|
||||
WIN32_FIND_DATAW data;
|
||||
|
||||
/* True if data is valid */
|
||||
int cached;
|
||||
|
||||
/* Win32 search handle */
|
||||
HANDLE handle;
|
||||
|
||||
/* Initial directory name */
|
||||
wchar_t *patt;
|
||||
};
|
||||
typedef struct _WDIR _WDIR;
|
||||
|
||||
static _WDIR *_wopendir(const wchar_t *dirname);
|
||||
static struct _wdirent *_wreaddir(_WDIR *dirp);
|
||||
static int _wclosedir(_WDIR *dirp);
|
||||
static void _wrewinddir(_WDIR* dirp);
|
||||
|
||||
|
||||
/* For compatibility with Symbian */
|
||||
#define wdirent _wdirent
|
||||
#define WDIR _WDIR
|
||||
#define wopendir _wopendir
|
||||
#define wreaddir _wreaddir
|
||||
#define wclosedir _wclosedir
|
||||
#define wrewinddir _wrewinddir
|
||||
|
||||
|
||||
/* Multi-byte character versions */
|
||||
struct dirent {
|
||||
/* Always zero */
|
||||
long d_ino;
|
||||
|
||||
/* Structure size */
|
||||
unsigned short d_reclen;
|
||||
|
||||
/* Length of name without \0 */
|
||||
size_t d_namlen;
|
||||
|
||||
/* File type */
|
||||
int d_type;
|
||||
|
||||
/* File name */
|
||||
char d_name[PATH_MAX];
|
||||
};
|
||||
typedef struct dirent dirent;
|
||||
|
||||
struct DIR {
|
||||
struct dirent ent;
|
||||
struct _WDIR *wdirp;
|
||||
};
|
||||
typedef struct DIR DIR;
|
||||
|
||||
static DIR *opendir(const char *dirname);
|
||||
static struct dirent *readdir(DIR *dirp);
|
||||
static int closedir(DIR *dirp);
|
||||
static void rewinddir(DIR* dirp);
|
||||
|
||||
|
||||
/* Internal utility functions */
|
||||
static WIN32_FIND_DATAW *dirent_first(_WDIR *dirp);
|
||||
static WIN32_FIND_DATAW *dirent_next(_WDIR *dirp);
|
||||
|
||||
static int dirent_mbstowcs_s(
|
||||
size_t *pReturnValue,
|
||||
wchar_t *wcstr,
|
||||
size_t sizeInWords,
|
||||
const char *mbstr,
|
||||
size_t count);
|
||||
|
||||
static int dirent_wcstombs_s(
|
||||
size_t *pReturnValue,
|
||||
char *mbstr,
|
||||
size_t sizeInBytes,
|
||||
const wchar_t *wcstr,
|
||||
size_t count);
|
||||
|
||||
static void dirent_set_errno(int error);
|
||||
|
||||
/*
|
||||
* Open directory stream DIRNAME for read and return a pointer to the
|
||||
* internal working area that is used to retrieve individual directory
|
||||
* entries.
|
||||
*/
|
||||
static _WDIR*
|
||||
_wopendir(
|
||||
const wchar_t *dirname)
|
||||
{
|
||||
_WDIR *dirp = NULL;
|
||||
int error;
|
||||
|
||||
/* Must have directory name */
|
||||
if (dirname == NULL || dirname[0] == '\0') {
|
||||
dirent_set_errno(ENOENT);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Allocate new _WDIR structure */
|
||||
dirp = (_WDIR*)malloc(sizeof(struct _WDIR));
|
||||
if (dirp != NULL) {
|
||||
DWORD n;
|
||||
|
||||
/* Reset _WDIR structure */
|
||||
dirp->handle = INVALID_HANDLE_VALUE;
|
||||
dirp->patt = NULL;
|
||||
dirp->cached = 0;
|
||||
|
||||
/* Compute the length of full path plus zero terminator
|
||||
*
|
||||
* Note that on WinRT there's no way to convert relative paths
|
||||
* into absolute paths, so just assume its an absolute path.
|
||||
*/
|
||||
# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
|
||||
n = wcslen(dirname);
|
||||
# else
|
||||
n = GetFullPathNameW(dirname, 0, NULL, NULL);
|
||||
# endif
|
||||
|
||||
/* Allocate room for absolute directory name and search pattern */
|
||||
dirp->patt = (wchar_t*)malloc(sizeof(wchar_t) * n + 16);
|
||||
if (dirp->patt) {
|
||||
|
||||
/*
|
||||
* Convert relative directory name to an absolute one. This
|
||||
* allows rewinddir() to function correctly even when current
|
||||
* working directory is changed between opendir() and rewinddir().
|
||||
*
|
||||
* Note that on WinRT there's no way to convert relative paths
|
||||
* into absolute paths, so just assume its an absolute path.
|
||||
*/
|
||||
# if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP)
|
||||
wcsncpy_s(dirp->patt, n + 1, dirname, n);
|
||||
# else
|
||||
n = GetFullPathNameW(dirname, n, dirp->patt, NULL);
|
||||
# endif
|
||||
if (n > 0) {
|
||||
wchar_t *p;
|
||||
|
||||
/* Append search pattern \* to the directory name */
|
||||
p = dirp->patt + n;
|
||||
if (dirp->patt < p) {
|
||||
switch (p[-1]) {
|
||||
case '\\':
|
||||
case '/':
|
||||
case ':':
|
||||
/* Directory ends in path separator, e.g. c:\temp\ */
|
||||
/*NOP*/;
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Directory name doesn't end in path separator */
|
||||
*p++ = '\\';
|
||||
}
|
||||
}
|
||||
*p++ = '*';
|
||||
*p = '\0';
|
||||
|
||||
/* Open directory stream and retrieve the first entry */
|
||||
if (dirent_first(dirp)) {
|
||||
/* Directory stream opened successfully */
|
||||
error = 0;
|
||||
}
|
||||
else {
|
||||
/* Cannot retrieve first entry */
|
||||
error = 1;
|
||||
dirent_set_errno(ENOENT);
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
/* Cannot retrieve full path name */
|
||||
dirent_set_errno(ENOENT);
|
||||
error = 1;
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
/* Cannot allocate memory for search pattern */
|
||||
error = 1;
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
/* Cannot allocate _WDIR structure */
|
||||
error = 1;
|
||||
}
|
||||
|
||||
/* Clean up in case of error */
|
||||
if (error && dirp) {
|
||||
_wclosedir(dirp);
|
||||
dirp = NULL;
|
||||
}
|
||||
|
||||
return dirp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read next directory entry. The directory entry is returned in dirent
|
||||
* structure in the d_name field. Individual directory entries returned by
|
||||
* this function include regular files, sub-directories, pseudo-directories
|
||||
* "." and ".." as well as volume labels, hidden files and system files.
|
||||
*/
|
||||
static struct _wdirent*
|
||||
_wreaddir(
|
||||
_WDIR *dirp)
|
||||
{
|
||||
WIN32_FIND_DATAW *datap;
|
||||
struct _wdirent *entp;
|
||||
|
||||
/* Read next directory entry */
|
||||
datap = dirent_next(dirp);
|
||||
if (datap) {
|
||||
size_t n;
|
||||
DWORD attr;
|
||||
|
||||
/* Pointer to directory entry to return */
|
||||
entp = &dirp->ent;
|
||||
|
||||
/*
|
||||
* Copy file name as wide-character string. If the file name is too
|
||||
* long to fit in to the destination buffer, then truncate file name
|
||||
* to PATH_MAX characters and zero-terminate the buffer.
|
||||
*/
|
||||
n = 0;
|
||||
while (n + 1 < PATH_MAX && datap->cFileName[n] != 0) {
|
||||
entp->d_name[n] = datap->cFileName[n];
|
||||
n++;
|
||||
}
|
||||
dirp->ent.d_name[n] = 0;
|
||||
|
||||
/* Length of file name excluding zero terminator */
|
||||
entp->d_namlen = n;
|
||||
|
||||
/* File type */
|
||||
attr = datap->dwFileAttributes;
|
||||
if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) {
|
||||
entp->d_type = DT_CHR;
|
||||
}
|
||||
else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
|
||||
entp->d_type = DT_DIR;
|
||||
}
|
||||
else {
|
||||
entp->d_type = DT_REG;
|
||||
}
|
||||
|
||||
/* Reset dummy fields */
|
||||
entp->d_ino = 0;
|
||||
entp->d_reclen = sizeof(struct _wdirent);
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
/* Last directory entry read */
|
||||
entp = NULL;
|
||||
|
||||
}
|
||||
|
||||
return entp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Close directory stream opened by opendir() function. This invalidates the
|
||||
* DIR structure as well as any directory entry read previously by
|
||||
* _wreaddir().
|
||||
*/
|
||||
static int
|
||||
_wclosedir(
|
||||
_WDIR *dirp)
|
||||
{
|
||||
int ok;
|
||||
if (dirp) {
|
||||
|
||||
/* Release search handle */
|
||||
if (dirp->handle != INVALID_HANDLE_VALUE) {
|
||||
FindClose(dirp->handle);
|
||||
dirp->handle = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
/* Release search pattern */
|
||||
if (dirp->patt) {
|
||||
free(dirp->patt);
|
||||
dirp->patt = NULL;
|
||||
}
|
||||
|
||||
/* Release directory structure */
|
||||
free(dirp);
|
||||
ok = /*success*/0;
|
||||
|
||||
}
|
||||
else {
|
||||
/* Invalid directory stream */
|
||||
dirent_set_errno(EBADF);
|
||||
ok = /*failure*/-1;
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
/*
|
||||
* Rewind directory stream such that _wreaddir() returns the very first
|
||||
* file name again.
|
||||
*/
|
||||
static void
|
||||
_wrewinddir(
|
||||
_WDIR* dirp)
|
||||
{
|
||||
if (dirp) {
|
||||
/* Release existing search handle */
|
||||
if (dirp->handle != INVALID_HANDLE_VALUE) {
|
||||
FindClose(dirp->handle);
|
||||
}
|
||||
|
||||
/* Open new search handle */
|
||||
dirent_first(dirp);
|
||||
}
|
||||
}
|
||||
|
||||
/* Get first directory entry (internal) */
|
||||
static WIN32_FIND_DATAW*
|
||||
dirent_first(
|
||||
_WDIR *dirp)
|
||||
{
|
||||
WIN32_FIND_DATAW *datap;
|
||||
|
||||
/* Open directory and retrieve the first entry */
|
||||
dirp->handle = FindFirstFileExW(
|
||||
dirp->patt, FindExInfoStandard, &dirp->data,
|
||||
FindExSearchNameMatch, NULL, 0);
|
||||
if (dirp->handle != INVALID_HANDLE_VALUE) {
|
||||
|
||||
/* a directory entry is now waiting in memory */
|
||||
datap = &dirp->data;
|
||||
dirp->cached = 1;
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
/* Failed to re-open directory: no directory entry in memory */
|
||||
dirp->cached = 0;
|
||||
datap = NULL;
|
||||
|
||||
}
|
||||
return datap;
|
||||
}
|
||||
|
||||
/* Get next directory entry (internal) */
|
||||
static WIN32_FIND_DATAW*
|
||||
dirent_next(
|
||||
_WDIR *dirp)
|
||||
{
|
||||
WIN32_FIND_DATAW *p;
|
||||
|
||||
/* Get next directory entry */
|
||||
if (dirp->cached != 0) {
|
||||
|
||||
/* A valid directory entry already in memory */
|
||||
p = &dirp->data;
|
||||
dirp->cached = 0;
|
||||
|
||||
}
|
||||
else if (dirp->handle != INVALID_HANDLE_VALUE) {
|
||||
|
||||
/* Get the next directory entry from stream */
|
||||
if (FindNextFileW(dirp->handle, &dirp->data) != FALSE) {
|
||||
/* Got a file */
|
||||
p = &dirp->data;
|
||||
}
|
||||
else {
|
||||
/* The very last entry has been processed or an error occurred */
|
||||
FindClose(dirp->handle);
|
||||
dirp->handle = INVALID_HANDLE_VALUE;
|
||||
p = NULL;
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
/* End of directory stream reached */
|
||||
p = NULL;
|
||||
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
/*
|
||||
* Open directory stream using plain old C-string.
|
||||
*/
|
||||
static DIR*
|
||||
opendir(
|
||||
const char *dirname)
|
||||
{
|
||||
struct DIR *dirp;
|
||||
int error;
|
||||
|
||||
/* Must have directory name */
|
||||
if (dirname == NULL || dirname[0] == '\0') {
|
||||
dirent_set_errno(ENOENT);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Allocate memory for DIR structure */
|
||||
dirp = (DIR*)malloc(sizeof(struct DIR));
|
||||
if (dirp) {
|
||||
wchar_t wname[PATH_MAX];
|
||||
size_t n;
|
||||
|
||||
/* Convert directory name to wide-character string */
|
||||
error = dirent_mbstowcs_s(&n, wname, PATH_MAX, dirname, PATH_MAX);
|
||||
if (!error) {
|
||||
|
||||
/* Open directory stream using wide-character name */
|
||||
dirp->wdirp = _wopendir(wname);
|
||||
if (dirp->wdirp) {
|
||||
/* Directory stream opened */
|
||||
error = 0;
|
||||
}
|
||||
else {
|
||||
/* Failed to open directory stream */
|
||||
error = 1;
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* Cannot convert file name to wide-character string. This
|
||||
* occurs if the string contains invalid multi-byte sequences or
|
||||
* the output buffer is too small to contain the resulting
|
||||
* string.
|
||||
*/
|
||||
error = 1;
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
/* Cannot allocate DIR structure */
|
||||
error = 1;
|
||||
}
|
||||
|
||||
/* Clean up in case of error */
|
||||
if (error && dirp) {
|
||||
free(dirp);
|
||||
dirp = NULL;
|
||||
}
|
||||
|
||||
return dirp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read next directory entry.
|
||||
*
|
||||
* When working with text consoles, please note that file names returned by
|
||||
* readdir() are represented in the default ANSI code page while any output to
|
||||
* console is typically formatted on another code page. Thus, non-ASCII
|
||||
* characters in file names will not usually display correctly on console. The
|
||||
* problem can be fixed in two ways: (1) change the character set of console
|
||||
* to 1252 using chcp utility and use Lucida Console font, or (2) use
|
||||
* _cprintf function when writing to console. The _cprinf() will re-encode
|
||||
* ANSI strings to the console code page so many non-ASCII characters will
|
||||
* display correctly.
|
||||
*/
|
||||
static struct dirent*
|
||||
readdir(
|
||||
DIR *dirp)
|
||||
{
|
||||
WIN32_FIND_DATAW *datap;
|
||||
struct dirent *entp;
|
||||
|
||||
/* Read next directory entry */
|
||||
datap = dirent_next(dirp->wdirp);
|
||||
if (datap) {
|
||||
size_t n;
|
||||
int error;
|
||||
|
||||
/* Attempt to convert file name to multi-byte string */
|
||||
error = dirent_wcstombs_s(
|
||||
&n, dirp->ent.d_name, PATH_MAX, datap->cFileName, PATH_MAX);
|
||||
|
||||
/*
|
||||
* If the file name cannot be represented by a multi-byte string,
|
||||
* then attempt to use old 8+3 file name. This allows traditional
|
||||
* Unix-code to access some file names despite of unicode
|
||||
* characters, although file names may seem unfamiliar to the user.
|
||||
*
|
||||
* Be ware that the code below cannot come up with a short file
|
||||
* name unless the file system provides one. At least
|
||||
* VirtualBox shared folders fail to do this.
|
||||
*/
|
||||
if (error && datap->cAlternateFileName[0] != '\0') {
|
||||
error = dirent_wcstombs_s(
|
||||
&n, dirp->ent.d_name, PATH_MAX,
|
||||
datap->cAlternateFileName, PATH_MAX);
|
||||
}
|
||||
|
||||
if (!error) {
|
||||
DWORD attr;
|
||||
|
||||
/* Initialize directory entry for return */
|
||||
entp = &dirp->ent;
|
||||
|
||||
/* Length of file name excluding zero terminator */
|
||||
entp->d_namlen = n - 1;
|
||||
|
||||
/* File attributes */
|
||||
attr = datap->dwFileAttributes;
|
||||
if ((attr & FILE_ATTRIBUTE_DEVICE) != 0) {
|
||||
entp->d_type = DT_CHR;
|
||||
}
|
||||
else if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
|
||||
entp->d_type = DT_DIR;
|
||||
}
|
||||
else {
|
||||
entp->d_type = DT_REG;
|
||||
}
|
||||
|
||||
/* Reset dummy fields */
|
||||
entp->d_ino = 0;
|
||||
entp->d_reclen = sizeof(struct dirent);
|
||||
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* Cannot convert file name to multi-byte string so construct
|
||||
* an errornous directory entry and return that. Note that
|
||||
* we cannot return NULL as that would stop the processing
|
||||
* of directory entries completely.
|
||||
*/
|
||||
entp = &dirp->ent;
|
||||
entp->d_name[0] = '?';
|
||||
entp->d_name[1] = '\0';
|
||||
entp->d_namlen = 1;
|
||||
entp->d_type = DT_UNKNOWN;
|
||||
entp->d_ino = 0;
|
||||
entp->d_reclen = 0;
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
/* No more directory entries */
|
||||
entp = NULL;
|
||||
}
|
||||
|
||||
return entp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Close directory stream.
|
||||
*/
|
||||
static int
|
||||
closedir(
|
||||
DIR *dirp)
|
||||
{
|
||||
int ok;
|
||||
if (dirp) {
|
||||
|
||||
/* Close wide-character directory stream */
|
||||
ok = _wclosedir(dirp->wdirp);
|
||||
dirp->wdirp = NULL;
|
||||
|
||||
/* Release multi-byte character version */
|
||||
free(dirp);
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
/* Invalid directory stream */
|
||||
dirent_set_errno(EBADF);
|
||||
ok = /*failure*/-1;
|
||||
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
/*
|
||||
* Rewind directory stream to beginning.
|
||||
*/
|
||||
static void
|
||||
rewinddir(
|
||||
DIR* dirp)
|
||||
{
|
||||
/* Rewind wide-character string directory stream */
|
||||
_wrewinddir(dirp->wdirp);
|
||||
}
|
||||
|
||||
/* Convert multi-byte string to wide character string */
|
||||
static int
|
||||
dirent_mbstowcs_s(
|
||||
size_t *pReturnValue,
|
||||
wchar_t *wcstr,
|
||||
size_t sizeInWords,
|
||||
const char *mbstr,
|
||||
size_t count)
|
||||
{
|
||||
int error;
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1400
|
||||
|
||||
/* Microsoft Visual Studio 2005 or later */
|
||||
error = mbstowcs_s(pReturnValue, wcstr, sizeInWords, mbstr, count);
|
||||
|
||||
#else
|
||||
|
||||
/* Older Visual Studio or non-Microsoft compiler */
|
||||
size_t n;
|
||||
|
||||
/* Convert to wide-character string (or count characters) */
|
||||
n = mbstowcs(wcstr, mbstr, sizeInWords);
|
||||
if (!wcstr || n < count) {
|
||||
|
||||
/* Zero-terminate output buffer */
|
||||
if (wcstr && sizeInWords) {
|
||||
if (n >= sizeInWords) {
|
||||
n = sizeInWords - 1;
|
||||
}
|
||||
wcstr[n] = 0;
|
||||
}
|
||||
|
||||
/* Length of resulting multi-byte string WITH zero terminator */
|
||||
if (pReturnValue) {
|
||||
*pReturnValue = n + 1;
|
||||
}
|
||||
|
||||
/* Success */
|
||||
error = 0;
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
/* Could not convert string */
|
||||
error = 1;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/* Convert wide-character string to multi-byte string */
|
||||
static int
|
||||
dirent_wcstombs_s(
|
||||
size_t *pReturnValue,
|
||||
char *mbstr,
|
||||
size_t sizeInBytes, /* max size of mbstr */
|
||||
const wchar_t *wcstr,
|
||||
size_t count)
|
||||
{
|
||||
int error;
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1400
|
||||
|
||||
/* Microsoft Visual Studio 2005 or later */
|
||||
error = wcstombs_s(pReturnValue, mbstr, sizeInBytes, wcstr, count);
|
||||
|
||||
#else
|
||||
|
||||
/* Older Visual Studio or non-Microsoft compiler */
|
||||
size_t n;
|
||||
|
||||
/* Convert to multi-byte string (or count the number of bytes needed) */
|
||||
n = wcstombs(mbstr, wcstr, sizeInBytes);
|
||||
if (!mbstr || n < count) {
|
||||
|
||||
/* Zero-terminate output buffer */
|
||||
if (mbstr && sizeInBytes) {
|
||||
if (n >= sizeInBytes) {
|
||||
n = sizeInBytes - 1;
|
||||
}
|
||||
mbstr[n] = '\0';
|
||||
}
|
||||
|
||||
/* Length of resulting multi-bytes string WITH zero-terminator */
|
||||
if (pReturnValue) {
|
||||
*pReturnValue = n + 1;
|
||||
}
|
||||
|
||||
/* Success */
|
||||
error = 0;
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
/* Cannot convert string */
|
||||
error = 1;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/* Set errno variable */
|
||||
static void
|
||||
dirent_set_errno(
|
||||
int error)
|
||||
{
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1400
|
||||
|
||||
/* Microsoft Visual Studio 2005 and later */
|
||||
_set_errno(error);
|
||||
|
||||
#else
|
||||
|
||||
/* Non-Microsoft compiler or older Microsoft compiler */
|
||||
errno = error;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /*DIRENT_H*/
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
/* CCExtractor, originally by carlos at ccextractor.org, now a lot of people.
|
||||
Credits: See AUTHORS.TXT
|
||||
License: GPL 2.0
|
||||
|
||||
CI verification run: 2025-12-19T08:30 - Testing merged fixes from PRs #1847 and #1848
|
||||
*/
|
||||
#include "ccextractor.h"
|
||||
#include <stdio.h>
|
||||
@@ -38,7 +40,7 @@ void print_end_msg(void)
|
||||
mprint("https://github.com/CCExtractor/ccextractor/issues\n");
|
||||
}
|
||||
|
||||
int api_start(struct ccx_s_options api_options)
|
||||
int start_ccx()
|
||||
{
|
||||
struct lib_ccx_ctx *ctx = NULL; // Context for libs
|
||||
struct lib_cc_decode *dec_ctx = NULL; // Context for decoder
|
||||
@@ -48,17 +50,8 @@ int api_start(struct ccx_s_options api_options)
|
||||
#if defined(ENABLE_OCR) && defined(_WIN32)
|
||||
setMsgSeverity(LEPT_MSG_SEVERITY);
|
||||
#endif
|
||||
#ifdef ENABLE_HARDSUBX
|
||||
if (api_options.hardsubx)
|
||||
{
|
||||
// Perform burned in subtitle extraction
|
||||
hardsubx(&api_options);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Initialize CCExtractor libraries
|
||||
ctx = init_libraries(&api_options);
|
||||
ctx = init_libraries(&ccx_options);
|
||||
|
||||
if (!ctx)
|
||||
{
|
||||
@@ -74,6 +67,15 @@ int api_start(struct ccx_s_options api_options)
|
||||
fatal(EXIT_NOT_CLASSIFIED, "Unable to create Library Context %d\n", errno);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_HARDSUBX
|
||||
if (ccx_options.hardsubx)
|
||||
{
|
||||
// Perform burned in subtitle extraction
|
||||
hardsubx(&ccx_options, ctx);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WITH_LIBCURL
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
|
||||
@@ -97,11 +99,11 @@ int api_start(struct ccx_s_options api_options)
|
||||
tlt_config.page = ((tlt_config.page / 100) << 8) | (((tlt_config.page / 10) % 10) << 4) | (tlt_config.page % 10);
|
||||
}
|
||||
|
||||
if (api_options.transcript_settings.xds)
|
||||
if (ccx_options.transcript_settings.xds)
|
||||
{
|
||||
if (api_options.write_format != CCX_OF_TRANSCRIPT)
|
||||
if (ccx_options.write_format != CCX_OF_TRANSCRIPT)
|
||||
{
|
||||
api_options.transcript_settings.xds = 0;
|
||||
ccx_options.transcript_settings.xds = 0;
|
||||
mprint("Warning: -xds ignored, XDS can only be exported to transcripts at this time.\n");
|
||||
}
|
||||
}
|
||||
@@ -109,7 +111,7 @@ int api_start(struct ccx_s_options api_options)
|
||||
time_t start, final;
|
||||
time(&start);
|
||||
|
||||
if (api_options.binary_concat)
|
||||
if (ccx_options.binary_concat)
|
||||
{
|
||||
ctx->total_inputsize = get_total_file_size(ctx);
|
||||
if (ctx->total_inputsize < 0)
|
||||
@@ -138,27 +140,10 @@ int api_start(struct ccx_s_options api_options)
|
||||
#endif
|
||||
terminate_asap = 0;
|
||||
|
||||
#ifdef ENABLE_SHARING
|
||||
if (api_options.translate_enabled && ctx->num_input_files > 1)
|
||||
{
|
||||
mprint("[share] WARNING: simultaneous translation of several input files is not supported yet\n");
|
||||
api_options.translate_enabled = 0;
|
||||
api_options.sharing_enabled = 0;
|
||||
}
|
||||
if (api_options.translate_enabled)
|
||||
{
|
||||
mprint("[share] launching translate service\n");
|
||||
ccx_share_launch_translator(api_options.translate_langs, api_options.translate_key);
|
||||
}
|
||||
#endif //ENABLE_SHARING
|
||||
ret = 0;
|
||||
while (switch_to_next_file(ctx, 0))
|
||||
{
|
||||
prepare_for_new_file(ctx);
|
||||
#ifdef ENABLE_SHARING
|
||||
if (api_options.sharing_enabled)
|
||||
ccx_share_start(ctx->basefilename);
|
||||
#endif //ENABLE_SHARING
|
||||
|
||||
stream_mode = ctx->demux_ctx->get_stream_mode(ctx->demux_ctx);
|
||||
// Disable sync check for raw formats - they have the right timeline.
|
||||
@@ -183,9 +168,10 @@ int api_start(struct ccx_s_options api_options)
|
||||
----------------------------------------------------------------- */
|
||||
switch (stream_mode)
|
||||
{
|
||||
// Note: This case is meant to fall through
|
||||
case CCX_SM_ELEMENTARY_OR_NOT_FOUND:
|
||||
if (!api_options.use_gop_as_pts) // If !0 then the user selected something
|
||||
api_options.use_gop_as_pts = 1; // Force GOP timing for ES
|
||||
if (!ccx_options.use_gop_as_pts) // If !0 then the user selected something
|
||||
ccx_options.use_gop_as_pts = 1; // Force GOP timing for ES
|
||||
ccx_common_timing_settings.is_elementary_stream = 1;
|
||||
case CCX_SM_TRANSPORT:
|
||||
case CCX_SM_PROGRAM:
|
||||
@@ -196,9 +182,14 @@ int api_start(struct ccx_s_options api_options)
|
||||
#ifdef ENABLE_FFMPEG
|
||||
case CCX_SM_FFMPEG:
|
||||
#endif
|
||||
if (!api_options.use_gop_as_pts) // If !0 then the user selected something
|
||||
api_options.use_gop_as_pts = 0;
|
||||
if (api_options.ignore_pts_jumps)
|
||||
if (!ccx_options.use_gop_as_pts) // If !0 then the user selected something
|
||||
ccx_options.use_gop_as_pts = 0;
|
||||
if (ccx_options.ignore_pts_jumps)
|
||||
ccx_common_timing_settings.disable_sync_check = 1;
|
||||
// When using GOP timing (--goptime), disable sync check because
|
||||
// GOP time (wall-clock) and PES PTS (stream-relative) are in
|
||||
// different time bases and will always appear as huge jumps.
|
||||
if (ccx_options.use_gop_as_pts == 1)
|
||||
ccx_common_timing_settings.disable_sync_check = 1;
|
||||
mprint("\rAnalyzing data in general mode\n");
|
||||
tmp = general_loop(ctx);
|
||||
@@ -231,7 +222,7 @@ int api_start(struct ccx_s_options api_options)
|
||||
{
|
||||
fatal(EXIT_INCOMPATIBLE_PARAMETERS, "MP4 requires an actual file, it's not possible to read from a stream, including stdin.\n");
|
||||
}
|
||||
if (api_options.extract_chapters)
|
||||
if (ccx_options.extract_chapters)
|
||||
{
|
||||
tmp = dumpchapters(ctx, &ctx->mp4_cfg, ctx->inputfile[ctx->current_file]);
|
||||
}
|
||||
@@ -239,7 +230,7 @@ int api_start(struct ccx_s_options api_options)
|
||||
{
|
||||
tmp = processmp4(ctx, &ctx->mp4_cfg, ctx->inputfile[ctx->current_file]);
|
||||
}
|
||||
if (api_options.print_file_reports)
|
||||
if (ccx_options.print_file_reports)
|
||||
print_file_report(ctx);
|
||||
if (!ret)
|
||||
ret = tmp;
|
||||
@@ -309,14 +300,6 @@ int api_start(struct ccx_s_options api_options)
|
||||
dec_ctx->timing->fts_now = 0;
|
||||
dec_ctx->timing->fts_max = 0;
|
||||
|
||||
#ifdef ENABLE_SHARING
|
||||
if (api_options.sharing_enabled)
|
||||
{
|
||||
ccx_share_stream_done(ctx->basefilename);
|
||||
ccx_share_stop();
|
||||
}
|
||||
#endif //ENABLE_SHARING
|
||||
|
||||
if (dec_ctx->total_pulldownframes)
|
||||
mprint("incl. pulldown frames: %s (%u frames at %.2ffps)\n",
|
||||
print_mstime_static((LLONG)(dec_ctx->total_pulldownframes * 1000 / current_fps)),
|
||||
@@ -425,25 +408,26 @@ int api_start(struct ccx_s_options api_options)
|
||||
mprint("code in the MythTV's branch. Please report results to the address above. If\n");
|
||||
mprint("something is broken it will be fixed. Thanks\n");
|
||||
}
|
||||
return ret ? EXIT_OK : EXIT_NO_CAPTIONS;
|
||||
}
|
||||
|
||||
struct ccx_s_options *api_init_options()
|
||||
{
|
||||
init_options(&ccx_options);
|
||||
return &ccx_options;
|
||||
return ret ? EXIT_OK : EXIT_NO_CAPTIONS;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
setlocale(LC_ALL, ""); // Supports non-English CCs
|
||||
// Use POSIX locale for numbers so we get "." as decimal separator and no
|
||||
// thousands' groupoing instead of what the locale might say
|
||||
setlocale(LC_NUMERIC, "POSIX");
|
||||
|
||||
init_options(&ccx_options);
|
||||
|
||||
struct ccx_s_options *api_options = api_init_options();
|
||||
parse_configuration(api_options);
|
||||
// If "ccextractor.cnf" is present, takes options from it.
|
||||
// See docs/ccextractor.cnf.sample for more info.
|
||||
parse_configuration(&ccx_options);
|
||||
|
||||
int compile_ret = parse_parameters(api_options, argc, argv);
|
||||
ccxr_init_basic_logger();
|
||||
|
||||
int compile_ret = ccxr_parse_parameters(argc, argv);
|
||||
|
||||
if (compile_ret == EXIT_NO_INPUT_FILES)
|
||||
{
|
||||
@@ -459,6 +443,6 @@ int main(int argc, char *argv[])
|
||||
exit(compile_ret);
|
||||
}
|
||||
|
||||
int start_ret = api_start(*api_options);
|
||||
int start_ret = start_ccx();
|
||||
return start_ret;
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
#include "lib_ccx/ccx_common_option.h"
|
||||
#include "lib_ccx/ccx_mp4.h"
|
||||
#include "lib_ccx/hardsubx.h"
|
||||
#include "lib_ccx/ccx_share.h"
|
||||
#ifdef WITH_LIBCURL
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
@@ -30,17 +29,16 @@ CURLcode res;
|
||||
|
||||
extern struct ccx_s_options ccx_options;
|
||||
extern struct lib_ccx_ctx *signal_ctx;
|
||||
//volatile int terminate_asap = 0;
|
||||
// volatile int terminate_asap = 0;
|
||||
|
||||
struct ccx_s_options* api_init_options();
|
||||
struct ccx_s_options *api_init_options();
|
||||
|
||||
int api_start(struct ccx_s_options api_options);
|
||||
|
||||
|
||||
void sigterm_handler(int sig);
|
||||
void sigint_handler(int sig);
|
||||
void print_end_msg(void);
|
||||
|
||||
int main(int argc, char *argv[]);
|
||||
|
||||
#endif //CCEXTRACTOR_H
|
||||
#endif // CCEXTRACTOR_H
|
||||
|
||||
@@ -6,25 +6,19 @@ cc_library(
|
||||
hdrs = glob (["*.h", "zvbi/*.h", "*.xbm"]) + [ "//src:ccextractor.h" ],
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//src/thirdparty/protobuf-c:protobuf-c",
|
||||
"//src/thirdparty/libpng:libpng",
|
||||
"//src/thirdparty/freetype:freetype",
|
||||
"//src/thirdparty/gpacmp4:gpacmp4",
|
||||
"//src/thirdparty/lib_hash:lib_hash",
|
||||
"//src/thirdparty/utf8proc:utf8proc",
|
||||
],
|
||||
includes = [ "thirdparty/protobuf-c", "thirdparty/libpng", "thirdparty/gpacmp4" , "." ,
|
||||
includes = [ "thirdparty/libpng", "." ,
|
||||
"thirdparty/freetype/include" ],
|
||||
copts = [ "-Isrc/thirdparty/protobuf-c",
|
||||
"-Isrc/thirdparty/libpng",
|
||||
copts = [ "-Isrc/thirdparty/libpng",
|
||||
"-Isrc/",
|
||||
"-Isrc/thirdparty/gpacmp4",
|
||||
"-Isrc/thirdparty/freetype",
|
||||
"-Isrc/thirdparty/lib_hash",
|
||||
"-Isrc/thirdparty/freetype/include",
|
||||
"-Isrc/thirdparty/",
|
||||
"-DGPAC_HAVE_CONFIG_H"
|
||||
|
||||
"-Isrc/thirdparty/"
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
@@ -10,6 +10,12 @@ if(WIN32)
|
||||
add_definitions(-DWIN32)
|
||||
endif(WIN32)
|
||||
|
||||
find_package(PkgConfig)
|
||||
pkg_check_modules (GPAC REQUIRED gpac)
|
||||
|
||||
set (EXTRA_INCLUDES ${EXTRA_INCLUDES} ${GPAC_INCLUDE_DIRS})
|
||||
set (EXTRA_LIBS ${EXTRA_LIBS} ${GPAC_LIBRARIES})
|
||||
|
||||
if (WITH_FFMPEG)
|
||||
find_package(PkgConfig)
|
||||
|
||||
@@ -50,12 +56,8 @@ if (WITH_OCR)
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DENABLE_OCR")
|
||||
endif (WITH_OCR)
|
||||
|
||||
if (WITH_SHARING)
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DENABLE_SHARING")
|
||||
endif (WITH_SHARING)
|
||||
|
||||
aux_source_directory ("${PROJECT_SOURCE_DIR}/lib_ccx/" SOURCEFILE)
|
||||
aux_source_directory ("${PROJECT_SOURCE_DIR}/gpacmp4/" SOURCEFILE)
|
||||
|
||||
add_library (ccx ${SOURCEFILE} ccx_dtvcc.h ccx_dtvcc.c ccx_encoders_mcc.c ccx_encoders_mcc.h)
|
||||
target_link_libraries (ccx ${EXTRA_LIBS})
|
||||
@@ -67,38 +69,24 @@ if (WITH_HARDSUBX)
|
||||
pkg_check_modules (AVFORMAT REQUIRED libavformat)
|
||||
pkg_check_modules (AVUTIL REQUIRED libavutil)
|
||||
pkg_check_modules (AVCODEC REQUIRED libavcodec)
|
||||
pkg_check_modules (AVFILTER REQUIRED libavfilter)
|
||||
pkg_check_modules (SWSCALE REQUIRED libswscale)
|
||||
|
||||
set (EXTRA_LIBS ${EXTRA_LIBS} ${AVFORMAT_LIBRARIES})
|
||||
set (EXTRA_LIBS ${EXTRA_LIBS} ${AVUTIL_LIBRARIES})
|
||||
set (EXTRA_LIBS ${EXTRA_LIBS} ${AVCODEC_LIBRARIES})
|
||||
set (EXTRA_LIBS ${EXTRA_LIBS} ${AVFILTER_LIBRARIES})
|
||||
set (EXTRA_LIBS ${EXTRA_LIBS} ${SWSCALE_LIBRARIES})
|
||||
|
||||
set (EXTRA_INCLUDES ${EXTRA_INCLUDES} ${AVFORMAT_INCLUDE_DIRS})
|
||||
set (EXTRA_INCLUDES ${EXTRA_INCLUDES} ${AVUTIL_INCLUDE_DIRS})
|
||||
set (EXTRA_INCLUDES ${EXTRA_INCLUDES} ${AVCODEC_INCLUDE_DIRS})
|
||||
set (EXTRA_INCLUDES ${EXTRA_INCLUDES} ${AVFILTER_INCLUDE_DIRS})
|
||||
set (EXTRA_INCLUDES ${EXTRA_INCLUDES} ${SWSCALE_INCLUDE_DIRS})
|
||||
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DENABLE_HARDSUBX")
|
||||
endif (WITH_HARDSUBX)
|
||||
|
||||
if (MINGW OR CYGWIN)
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DGPAC_CONFIG_WIN32")
|
||||
endif (MINGW OR CYGWIN)
|
||||
|
||||
if (WITH_RUST)
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DENABLE_RUST")
|
||||
endif (WITH_RUST)
|
||||
|
||||
if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DGPAC_CONFIG_LINUX")
|
||||
endif (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
|
||||
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DGPAC_CONFIG_DARWIN")
|
||||
endif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
|
||||
|
||||
file (GLOB HeaderFiles *.h)
|
||||
file (WRITE ccx.pc "prefix=${CMAKE_INSTALL_PREFIX}\n"
|
||||
"includedir=\${prefix}/include\n"
|
||||
|
||||
@@ -4,7 +4,6 @@ relevant events. */
|
||||
#include "lib_ccx.h"
|
||||
#include "ccx_common_option.h"
|
||||
|
||||
static int credits_shown = 0;
|
||||
unsigned long net_activity_gui = 0;
|
||||
|
||||
/* Print current progress. For percentage, -1 -> streaming mode */
|
||||
@@ -16,7 +15,7 @@ void activity_progress(int percentage, int cur_min, int cur_sec)
|
||||
mprint("Streaming | %02d:%02d\r", cur_min, cur_sec);
|
||||
else
|
||||
mprint("%3d%% | %02d:%02d\r", percentage, cur_min, cur_sec);
|
||||
if (ccx_options.pes_header_to_stdout || ccx_options.debug_mask & CCX_DMT_DVB) //For PES Header dumping and DVB debug traces
|
||||
if (ccx_options.pes_header_to_stdout || ccx_options.debug_mask & CCX_DMT_DVB) // For PES Header dumping and DVB debug traces
|
||||
{
|
||||
mprint("\n");
|
||||
}
|
||||
@@ -129,11 +128,7 @@ void activity_report_data_read(void)
|
||||
|
||||
void activity_header(void)
|
||||
{
|
||||
if (!credits_shown)
|
||||
{
|
||||
credits_shown = 1;
|
||||
mprint("CCExtractor %s, Carlos Fernandez Sanz, Volker Quetschke.\n", VERSION);
|
||||
mprint("Teletext portions taken from Petr Kutalek's telxcc\n");
|
||||
mprint("--------------------------------------------------------------------------\n");
|
||||
}
|
||||
mprint("CCExtractor %s, Carlos Fernandez Sanz, Volker Quetschke.\n", VERSION);
|
||||
mprint("Teletext portions taken from Petr Kutalek's telxcc\n");
|
||||
mprint("--------------------------------------------------------------------------\n");
|
||||
}
|
||||
|
||||
@@ -2,16 +2,16 @@
|
||||
#define ACTIVITY_H
|
||||
|
||||
extern unsigned long net_activity_gui;
|
||||
void activity_header (void);
|
||||
void activity_progress (int percentaje, int cur_min, int cur_sec);
|
||||
void activity_report_version (void);
|
||||
void activity_input_file_closed (void);
|
||||
void activity_input_file_open (const char *filename);
|
||||
void activity_message (const char *fmt, ...);
|
||||
void activity_video_info (int hor_size,int vert_size,
|
||||
const char *aspect_ratio, const char *framerate);
|
||||
void activity_program_number (unsigned program_number);
|
||||
void activity_header(void);
|
||||
void activity_progress(int percentaje, int cur_min, int cur_sec);
|
||||
void activity_report_version(void);
|
||||
void activity_input_file_closed(void);
|
||||
void activity_input_file_open(const char *filename);
|
||||
void activity_message(const char *fmt, ...);
|
||||
void activity_video_info(int hor_size, int vert_size,
|
||||
const char *aspect_ratio, const char *framerate);
|
||||
void activity_program_number(unsigned program_number);
|
||||
void activity_library_process(enum ccx_common_logging_gui message_type, ...);
|
||||
void activity_report_data_read (void);
|
||||
void activity_report_data_read(void);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -30,28 +30,30 @@
|
||||
// 10.13 - Undocumented DVR-MS properties
|
||||
#define DVRMS_PTS "\x2A\xC0\x3C\xFD\xDB\x06\xFA\x4C\x80\x1C\x72\x12\xD3\x87\x45\xE4"
|
||||
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
int VideoStreamNumber;
|
||||
int AudioStreamNumber;
|
||||
int CaptionStreamNumber;
|
||||
int CaptionStreamStyle; // 1 = NTSC, 2 = ATSC
|
||||
int DecodeStreamNumber; // The stream that is chosen to be decoded
|
||||
int DecodeStreamPTS; // This will be used for the next returned block
|
||||
int CaptionStreamStyle; // 1 = NTSC, 2 = ATSC
|
||||
int DecodeStreamNumber; // The stream that is chosen to be decoded
|
||||
int DecodeStreamPTS; // This will be used for the next returned block
|
||||
int currDecodeStreamPTS; // Time of the data returned by the function
|
||||
int prevDecodeStreamPTS; // Previous time
|
||||
int VideoStreamMS; // See ableve, just for video
|
||||
int VideoStreamMS; // See ableve, just for video
|
||||
int currVideoStreamMS;
|
||||
int prevVideoStreamMS;
|
||||
int VideoJump; // Remember a jump in the video timeline
|
||||
int VideoJump; // Remember a jump in the video timeline
|
||||
} asf_data_stream_properties;
|
||||
|
||||
#define STREAMNUM 10
|
||||
#define STREAMNUM 10
|
||||
#define PAYEXTNUM 10
|
||||
|
||||
typedef struct {
|
||||
typedef struct
|
||||
{
|
||||
// Generic buffer to hold data
|
||||
unsigned char *parsebuf;
|
||||
long parsebufsize;
|
||||
int64_t parsebufsize;
|
||||
// Header Object variables
|
||||
int64_t HeaderObjectSize;
|
||||
int64_t FileSize;
|
||||
@@ -72,23 +74,23 @@ typedef struct {
|
||||
uint32_t TotalDataPackets;
|
||||
int VideoClosedCaptioningFlag;
|
||||
// Payload data
|
||||
int PayloadLType; // ASF - Payload Length Type. <>0 for multiple payloads
|
||||
uint32_t PayloadLength; // ASF - Payload Length
|
||||
int NumberOfPayloads; // ASF - Number of payloads.
|
||||
int payloadcur; // local
|
||||
int PayloadLType; // ASF - Payload Length Type. <>0 for multiple payloads
|
||||
uint32_t PayloadLength; // ASF - Payload Length
|
||||
int NumberOfPayloads; // ASF - Number of payloads.
|
||||
int payloadcur; // local
|
||||
int PayloadStreamNumber; // ASF
|
||||
int KeyFrame; // ASF
|
||||
int KeyFrame; // ASF
|
||||
uint32_t PayloadMediaNumber; // ASF
|
||||
// Data Object Loop
|
||||
uint32_t datapacketcur; // Current packet number
|
||||
int64_t dobjectread; // Bytes read in Data Object
|
||||
uint32_t datapacketcur; // Current packet number
|
||||
int64_t dobjectread; // Bytes read in Data Object
|
||||
// Payload parsing information
|
||||
int MultiplePayloads; // ASF
|
||||
int PacketLType; // ASF
|
||||
int ReplicatedLType; // ASF
|
||||
int OffsetMediaLType; // ASF
|
||||
int MediaNumberLType; // ASF
|
||||
int StreamNumberLType; // ASF
|
||||
int MultiplePayloads; // ASF
|
||||
int PacketLType; // ASF
|
||||
int ReplicatedLType; // ASF
|
||||
int OffsetMediaLType; // ASF
|
||||
int MediaNumberLType; // ASF
|
||||
int StreamNumberLType; // ASF
|
||||
uint32_t PacketLength;
|
||||
uint32_t PaddingLength;
|
||||
} asf_data;
|
||||
|
||||
@@ -42,14 +42,14 @@ char *gui_data_string(void *val)
|
||||
{
|
||||
static char sbuf[40];
|
||||
|
||||
sprintf(sbuf, "%08lX-%04X-%04X-",
|
||||
(long)*((uint32_t *)((char *)val + 0)),
|
||||
(int)*((uint16_t *)((char *)val + 4)),
|
||||
(int)*((uint16_t *)((char *)val + 6)));
|
||||
snprintf(sbuf, sizeof(sbuf), "%08lX-%04X-%04X-",
|
||||
(long)*((uint32_t *)((char *)val + 0)),
|
||||
(int)*((uint16_t *)((char *)val + 4)),
|
||||
(int)*((uint16_t *)((char *)val + 6)));
|
||||
for (int ii = 0; ii < 2; ii++)
|
||||
sprintf(sbuf + 19 + ii * 2, "%02X-", *((unsigned char *)val + 8 + ii));
|
||||
snprintf(sbuf + 19 + ii * 2, sizeof(sbuf) - 19 - ii * 2, "%02X-", *((unsigned char *)val + 8 + ii));
|
||||
for (int ii = 0; ii < 6; ii++)
|
||||
sprintf(sbuf + 24 + ii * 2, "%02X", *((unsigned char *)val + 10 + ii));
|
||||
snprintf(sbuf + 24 + ii * 2, sizeof(sbuf) - 24 - ii * 2, "%02X", *((unsigned char *)val + 10 + ii));
|
||||
|
||||
return sbuf;
|
||||
}
|
||||
@@ -150,6 +150,10 @@ int asf_get_more_data(struct lib_ccx_ctx *ctx, struct demuxer_data **ppdata)
|
||||
.StreamNumberLType = 0,
|
||||
.PacketLength = 0,
|
||||
.PaddingLength = 0};
|
||||
// Check for allocation failure
|
||||
if (!asf_data_container.parsebuf)
|
||||
fatal(EXIT_NOT_ENOUGH_MEMORY, "In asf_getmoredata: Out of memory allocating initial parse buffer.");
|
||||
|
||||
// Initialize the Payload Extension System
|
||||
for (int stream = 0; stream < STREAMNUM; stream++)
|
||||
{
|
||||
@@ -185,9 +189,13 @@ int asf_get_more_data(struct lib_ccx_ctx *ctx, struct demuxer_data **ppdata)
|
||||
|
||||
if (asf_data_container.HeaderObjectSize > asf_data_container.parsebufsize)
|
||||
{
|
||||
asf_data_container.parsebuf = (unsigned char *)realloc(asf_data_container.parsebuf, (size_t)asf_data_container.HeaderObjectSize);
|
||||
if (!asf_data_container.parsebuf)
|
||||
unsigned char *tmp = (unsigned char *)realloc(asf_data_container.parsebuf, (size_t)asf_data_container.HeaderObjectSize);
|
||||
if (!tmp)
|
||||
{
|
||||
free(asf_data_container.parsebuf);
|
||||
fatal(EXIT_NOT_ENOUGH_MEMORY, "In asf_getmoredata: Out of memory requesting buffer for data container.");
|
||||
}
|
||||
asf_data_container.parsebuf = tmp;
|
||||
asf_data_container.parsebufsize = (long)asf_data_container.HeaderObjectSize;
|
||||
}
|
||||
|
||||
@@ -509,14 +517,14 @@ int asf_get_more_data(struct lib_ccx_ctx *ctx, struct demuxer_data **ppdata)
|
||||
if (asf_data_container.StreamProperties.CaptionStreamNumber > 0 && (asf_data_container.StreamProperties.CaptionStreamStyle == 1 ||
|
||||
(asf_data_container.StreamProperties.CaptionStreamStyle == 2 && ccx_options.wtvconvertfix)))
|
||||
{
|
||||
//if (debug_parse)
|
||||
// if (debug_parse)
|
||||
mprint("\nNTSC captions in stream #%d\n\n", asf_data_container.StreamProperties.CaptionStreamNumber);
|
||||
data->bufferdatatype = CCX_RAW;
|
||||
asf_data_container.StreamProperties.DecodeStreamNumber = asf_data_container.StreamProperties.CaptionStreamNumber;
|
||||
}
|
||||
else if (asf_data_container.StreamProperties.CaptionStreamNumber > 0 && asf_data_container.StreamProperties.CaptionStreamStyle == 2)
|
||||
{
|
||||
//if (debug_parse)
|
||||
// if (debug_parse)
|
||||
mprint("\nATSC captions (probably) in stream #%d - Decode the video stream #%d instead\n\n",
|
||||
asf_data_container.StreamProperties.CaptionStreamNumber, asf_data_container.StreamProperties.VideoStreamNumber);
|
||||
asf_data_container.StreamProperties.DecodeStreamNumber = asf_data_container.StreamProperties.VideoStreamNumber;
|
||||
@@ -524,7 +532,7 @@ int asf_get_more_data(struct lib_ccx_ctx *ctx, struct demuxer_data **ppdata)
|
||||
else
|
||||
{
|
||||
asf_data_container.StreamProperties.DecodeStreamNumber = asf_data_container.StreamProperties.VideoStreamNumber;
|
||||
//if (debug_parse)
|
||||
// if (debug_parse)
|
||||
mprint("\nAssume CC info in video stream #%d (No caption stream found)\n\n",
|
||||
asf_data_container.StreamProperties.DecodeStreamNumber);
|
||||
}
|
||||
@@ -561,7 +569,7 @@ int asf_get_more_data(struct lib_ccx_ctx *ctx, struct demuxer_data **ppdata)
|
||||
dbg_print(CCX_DMT_PARSE, "Number of data packets: %ld\n", (long)asf_data_container.TotalDataPackets);
|
||||
|
||||
reentry = 0; // Make sure we read the Data Packet Headers
|
||||
} // End of if (firstcall)
|
||||
} // End of if (firstcall)
|
||||
firstcall = 0;
|
||||
|
||||
// Start loop over Data Packets
|
||||
@@ -751,9 +759,13 @@ int asf_get_more_data(struct lib_ccx_ctx *ctx, struct demuxer_data **ppdata)
|
||||
|
||||
if ((long)replicated_length > asf_data_container.parsebufsize)
|
||||
{
|
||||
asf_data_container.parsebuf = (unsigned char *)realloc(asf_data_container.parsebuf, replicated_length);
|
||||
if (!asf_data_container.parsebuf)
|
||||
unsigned char *tmp = (unsigned char *)realloc(asf_data_container.parsebuf, replicated_length);
|
||||
if (!tmp)
|
||||
{
|
||||
free(asf_data_container.parsebuf);
|
||||
fatal(EXIT_NOT_ENOUGH_MEMORY, "In asf_getmoredata: Not enough memory for buffer, unable to continue.\n");
|
||||
}
|
||||
asf_data_container.parsebuf = tmp;
|
||||
asf_data_container.parsebufsize = replicated_length;
|
||||
}
|
||||
result = buffered_read(ctx->demux_ctx, asf_data_container.parsebuf, (long)replicated_length);
|
||||
@@ -768,7 +780,7 @@ int asf_get_more_data(struct lib_ccx_ctx *ctx, struct demuxer_data **ppdata)
|
||||
// Parse Replicated data
|
||||
unsigned char *replicate_position = asf_data_container.parsebuf;
|
||||
int media_object_size = 0;
|
||||
int presentation_time_millis = 0; //Payload ms time stamp
|
||||
int presentation_time_millis = 0; // Payload ms time stamp
|
||||
int extsize = 0;
|
||||
// int32_t dwVersion = 0;
|
||||
// int32_t unknown = 0;
|
||||
@@ -797,7 +809,7 @@ int asf_get_more_data(struct lib_ccx_ctx *ctx, struct demuxer_data **ppdata)
|
||||
extsize = asf_data_container.PayloadExtSize[asf_data_container.PayloadStreamNumber][i];
|
||||
}
|
||||
replicate_position += extsize;
|
||||
//printf("%2d. Ext. System - size: %d\n", i, extsize);
|
||||
// printf("%2d. Ext. System - size: %d\n", i, extsize);
|
||||
}
|
||||
if (asf_data_container.PayloadExtPTSEntry[asf_data_container.PayloadStreamNumber] > 0)
|
||||
{
|
||||
@@ -806,7 +818,7 @@ int asf_get_more_data(struct lib_ccx_ctx *ctx, struct demuxer_data **ppdata)
|
||||
rtStart = *((int64_t *)(replicate_position + 8));
|
||||
rtEnd = *((int64_t *)(replicate_position + 16));
|
||||
|
||||
//printf("dwVersion: %d unknown: 0x%04X\n", dwVersion, unknown);
|
||||
// printf("dwVersion: %d unknown: 0x%04X\n", dwVersion, unknown);
|
||||
}
|
||||
|
||||
// Avoid problems with unset PTS times
|
||||
@@ -1029,7 +1041,7 @@ int asf_get_more_data(struct lib_ccx_ctx *ctx, struct demuxer_data **ppdata)
|
||||
ctx->demux_ctx->past += result;
|
||||
// Don not set end_of_file (although it is true) as this would
|
||||
// produce an premature end error.
|
||||
//end_of_file=1;
|
||||
// end_of_file=1;
|
||||
|
||||
// parsebuf is freed automatically when the program closes.
|
||||
}
|
||||
|
||||
@@ -48,6 +48,7 @@ struct avc_ctx *init_avc(void)
|
||||
ctx->cc_databufsize = 1024;
|
||||
ctx->cc_buffer_saved = CCX_TRUE; // Was the CC buffer saved after it was last updated?
|
||||
|
||||
ctx->is_hevc = 0;
|
||||
ctx->got_seq_para = 0;
|
||||
ctx->nal_ref_idc = 0;
|
||||
ctx->seq_parameter_set_id = 0;
|
||||
@@ -87,16 +88,43 @@ struct avc_ctx *init_avc(void)
|
||||
return ctx;
|
||||
}
|
||||
|
||||
// HEVC NAL unit types for SEI messages
|
||||
#define HEVC_NAL_PREFIX_SEI 39
|
||||
#define HEVC_NAL_SUFFIX_SEI 40
|
||||
#define HEVC_NAL_VPS 32
|
||||
#define HEVC_NAL_SPS 33
|
||||
#define HEVC_NAL_PPS 34
|
||||
|
||||
void do_NAL(struct encoder_ctx *enc_ctx, struct lib_cc_decode *dec_ctx, unsigned char *NAL_start, LLONG NAL_length, struct cc_subtitle *sub)
|
||||
{
|
||||
unsigned char *NAL_stop;
|
||||
enum ccx_avc_nal_types nal_unit_type = *NAL_start & 0x1F;
|
||||
int nal_unit_type;
|
||||
int nal_header_size;
|
||||
unsigned char *payload_start;
|
||||
|
||||
// Determine if this is HEVC or H.264 based on NAL header
|
||||
// H.264 NAL header: 1 byte, type in bits [4:0]
|
||||
// HEVC NAL header: 2 bytes, type in bits [6:1] of first byte
|
||||
if (dec_ctx->avc_ctx->is_hevc)
|
||||
{
|
||||
// HEVC: NAL type is in bits [6:1] of byte 0
|
||||
nal_unit_type = (NAL_start[0] >> 1) & 0x3F;
|
||||
nal_header_size = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
// H.264: NAL type is in bits [4:0] of byte 0
|
||||
nal_unit_type = NAL_start[0] & 0x1F;
|
||||
nal_header_size = 1;
|
||||
}
|
||||
|
||||
NAL_stop = NAL_length + NAL_start;
|
||||
NAL_stop = remove_03emu(NAL_start + 1, NAL_stop); // Add +1 to NAL_stop for TS, without it for MP4. Still don't know why
|
||||
NAL_stop = remove_03emu(NAL_start + nal_header_size, NAL_stop);
|
||||
payload_start = NAL_start + nal_header_size;
|
||||
|
||||
dvprint("BEGIN NAL unit type: %d length %d ref_idc: %d - Buffered captions before: %d\n",
|
||||
nal_unit_type, NAL_stop - NAL_start - 1, dec_ctx->avc_ctx->nal_ref_idc, !dec_ctx->avc_ctx->cc_buffer_saved);
|
||||
dvprint("BEGIN NAL unit type: %d length %d ref_idc: %d - Buffered captions before: %d (HEVC: %d)\n",
|
||||
nal_unit_type, NAL_stop - NAL_start - nal_header_size, dec_ctx->avc_ctx->nal_ref_idc,
|
||||
!dec_ctx->avc_ctx->cc_buffer_saved, dec_ctx->avc_ctx->is_hevc);
|
||||
|
||||
if (NAL_stop == NULL) // remove_03emu failed.
|
||||
{
|
||||
@@ -104,51 +132,76 @@ void do_NAL(struct encoder_ctx *enc_ctx, struct lib_cc_decode *dec_ctx, unsigned
|
||||
return;
|
||||
}
|
||||
|
||||
if (nal_unit_type == CCX_NAL_TYPE_ACCESS_UNIT_DELIMITER_9)
|
||||
if (dec_ctx->avc_ctx->is_hevc)
|
||||
{
|
||||
// Found Access Unit Delimiter
|
||||
// HEVC NAL unit processing
|
||||
if (nal_unit_type == HEVC_NAL_VPS || nal_unit_type == HEVC_NAL_SPS || nal_unit_type == HEVC_NAL_PPS)
|
||||
{
|
||||
// Found HEVC parameter set - mark as having sequence params
|
||||
// We don't parse HEVC SPS fully, but we need to enable SEI processing
|
||||
dec_ctx->avc_ctx->got_seq_para = 1;
|
||||
}
|
||||
else if (nal_unit_type == HEVC_NAL_PREFIX_SEI || nal_unit_type == HEVC_NAL_SUFFIX_SEI)
|
||||
{
|
||||
// Found HEVC SEI (used for subtitles)
|
||||
// SEI payload format is similar to H.264
|
||||
sei_rbsp(dec_ctx->avc_ctx, payload_start, NAL_stop);
|
||||
}
|
||||
}
|
||||
else if (nal_unit_type == CCX_NAL_TYPE_SEQUENCE_PARAMETER_SET_7)
|
||||
else
|
||||
{
|
||||
// Found sequence parameter set
|
||||
// We need this to parse NAL type 1 (CCX_NAL_TYPE_CODED_SLICE_NON_IDR_PICTURE_1)
|
||||
dec_ctx->avc_ctx->num_nal_unit_type_7++;
|
||||
seq_parameter_set_rbsp(dec_ctx->avc_ctx, NAL_start + 1, NAL_stop);
|
||||
dec_ctx->avc_ctx->got_seq_para = 1;
|
||||
}
|
||||
else if (dec_ctx->avc_ctx->got_seq_para && (nal_unit_type == CCX_NAL_TYPE_CODED_SLICE_NON_IDR_PICTURE_1 ||
|
||||
nal_unit_type == CCX_NAL_TYPE_CODED_SLICE_IDR_PICTURE)) // Only if nal_unit_type=1
|
||||
{
|
||||
// Found coded slice of a non-IDR picture
|
||||
// We only need the slice header data, no need to implement
|
||||
// slice_layer_without_partitioning_rbsp( );
|
||||
slice_header(enc_ctx, dec_ctx, NAL_start + 1, NAL_stop, nal_unit_type, sub);
|
||||
}
|
||||
else if (dec_ctx->avc_ctx->got_seq_para && nal_unit_type == CCX_NAL_TYPE_SEI)
|
||||
{
|
||||
// Found SEI (used for subtitles)
|
||||
//set_fts(ctx->timing); // FIXME - check this!!!
|
||||
sei_rbsp(dec_ctx->avc_ctx, NAL_start + 1, NAL_stop);
|
||||
}
|
||||
else if (dec_ctx->avc_ctx->got_seq_para && nal_unit_type == CCX_NAL_TYPE_PICTURE_PARAMETER_SET)
|
||||
{
|
||||
// Found Picture parameter set
|
||||
// H.264 NAL unit processing (original code)
|
||||
if (nal_unit_type == CCX_NAL_TYPE_ACCESS_UNIT_DELIMITER_9)
|
||||
{
|
||||
// Found Access Unit Delimiter
|
||||
}
|
||||
else if (nal_unit_type == CCX_NAL_TYPE_SEQUENCE_PARAMETER_SET_7)
|
||||
{
|
||||
// Found sequence parameter set
|
||||
// We need this to parse NAL type 1 (CCX_NAL_TYPE_CODED_SLICE_NON_IDR_PICTURE_1)
|
||||
dec_ctx->avc_ctx->num_nal_unit_type_7++;
|
||||
seq_parameter_set_rbsp(dec_ctx->avc_ctx, payload_start, NAL_stop);
|
||||
dec_ctx->avc_ctx->got_seq_para = 1;
|
||||
}
|
||||
else if (dec_ctx->avc_ctx->got_seq_para && (nal_unit_type == CCX_NAL_TYPE_CODED_SLICE_NON_IDR_PICTURE_1 ||
|
||||
nal_unit_type == CCX_NAL_TYPE_CODED_SLICE_IDR_PICTURE))
|
||||
{
|
||||
// Found coded slice of a non-IDR picture
|
||||
// We only need the slice header data
|
||||
slice_header(enc_ctx, dec_ctx, payload_start, NAL_stop, nal_unit_type, sub);
|
||||
}
|
||||
else if (dec_ctx->avc_ctx->got_seq_para && nal_unit_type == CCX_NAL_TYPE_SEI)
|
||||
{
|
||||
// Found SEI (used for subtitles)
|
||||
sei_rbsp(dec_ctx->avc_ctx, payload_start, NAL_stop);
|
||||
}
|
||||
else if (dec_ctx->avc_ctx->got_seq_para && nal_unit_type == CCX_NAL_TYPE_PICTURE_PARAMETER_SET)
|
||||
{
|
||||
// Found Picture parameter set
|
||||
}
|
||||
}
|
||||
|
||||
if (temp_debug)
|
||||
{
|
||||
int len = NAL_stop - (NAL_start + 1);
|
||||
int len = NAL_stop - payload_start;
|
||||
dbg_print(CCX_DMT_VIDES, "\n After decoding, the actual thing was (length =%d)\n", len);
|
||||
dump(CCX_DMT_VIDES, NAL_start + 1, len > 160 ? 160 : len, 0, 0);
|
||||
dump(CCX_DMT_VIDES, payload_start, len > 160 ? 160 : len, 0, 0);
|
||||
}
|
||||
|
||||
dvprint("END NAL unit type: %d length %d ref_idc: %d - Buffered captions after: %d\n",
|
||||
nal_unit_type, NAL_stop - NAL_start - 1, dec_ctx->avc_ctx->nal_ref_idc, !dec_ctx->avc_ctx->cc_buffer_saved);
|
||||
nal_unit_type, NAL_stop - NAL_start - nal_header_size, dec_ctx->avc_ctx->nal_ref_idc, !dec_ctx->avc_ctx->cc_buffer_saved);
|
||||
}
|
||||
|
||||
// Process inbuf bytes in buffer holding and AVC (H.264) video stream.
|
||||
// The number of processed bytes is returned.
|
||||
#ifndef DISABLE_RUST
|
||||
size_t ccxr_process_avc(struct encoder_ctx *enc_ctx, struct lib_cc_decode *dec_ctx, unsigned char *avcbuf, size_t avcbuflen, struct cc_subtitle *sub);
|
||||
#endif
|
||||
size_t process_avc(struct encoder_ctx *enc_ctx, struct lib_cc_decode *dec_ctx, unsigned char *avcbuf, size_t avcbuflen, struct cc_subtitle *sub)
|
||||
{
|
||||
#ifndef DISABLE_RUST
|
||||
return ccxr_process_avc(enc_ctx, dec_ctx, avcbuf, avcbuflen, sub);
|
||||
#else
|
||||
unsigned char *buffer_position = avcbuf;
|
||||
unsigned char *NAL_start;
|
||||
unsigned char *NAL_stop;
|
||||
@@ -250,6 +303,7 @@ size_t process_avc(struct encoder_ctx *enc_ctx, struct lib_cc_decode *dec_ctx, u
|
||||
}
|
||||
|
||||
return avcbuflen;
|
||||
#endif
|
||||
}
|
||||
|
||||
#define ZEROBYTES_SHORTSTARTCODE 2
|
||||
@@ -266,16 +320,16 @@ int EBSPtoRBSP(unsigned char *streamBuffer, int end_bytepos, int begin_bytepos)
|
||||
j = begin_bytepos;
|
||||
|
||||
for (i = begin_bytepos; i < end_bytepos; ++i)
|
||||
{ //starting from begin_bytepos to avoid header information
|
||||
//in NAL unit, 0x000000, 0x000001 or 0x000002 shall not occur at any byte-aligned position
|
||||
{ // starting from begin_bytepos to avoid header information
|
||||
// in NAL unit, 0x000000, 0x000001 or 0x000002 shall not occur at any byte-aligned position
|
||||
if (count == ZEROBYTES_SHORTSTARTCODE && streamBuffer[i] < 0x03)
|
||||
return -1;
|
||||
if (count == ZEROBYTES_SHORTSTARTCODE && streamBuffer[i] == 0x03)
|
||||
{
|
||||
//check the 4th byte after 0x000003, except when cabac_zero_word is used, in which case the last three bytes of this NAL unit must be 0x000003
|
||||
// check the 4th byte after 0x000003, except when cabac_zero_word is used, in which case the last three bytes of this NAL unit must be 0x000003
|
||||
if ((i < end_bytepos - 1) && (streamBuffer[i + 1] > 0x03))
|
||||
return -1;
|
||||
//if cabac_zero_word is used, the final byte of this NAL unit(0x03) is discarded, and the last two bytes of RBSP must be 0x0000
|
||||
// if cabac_zero_word is used, the final byte of this NAL unit(0x03) is discarded, and the last two bytes of RBSP must be 0x0000
|
||||
if (i == end_bytepos - 1)
|
||||
return j;
|
||||
|
||||
@@ -301,7 +355,7 @@ u32 avc_remove_emulation_bytes(const unsigned char *buffer_src, unsigned char *b
|
||||
unsigned char *remove_03emu(unsigned char *from, unsigned char *to)
|
||||
{
|
||||
int num = to - from;
|
||||
int newsize = EBSPtoRBSP(from, num, 0); //TODO: Do something if newsize == -1 (broken NAL)
|
||||
int newsize = EBSPtoRBSP(from, num, 0); // TODO: Do something if newsize == -1 (broken NAL)
|
||||
if (newsize == -1)
|
||||
return NULL;
|
||||
return from + newsize;
|
||||
@@ -503,9 +557,13 @@ void user_data_registered_itu_t_t35(struct avc_ctx *ctx, unsigned char *userbuf,
|
||||
// Save the data and process once we know the sequence number
|
||||
if (((ctx->cc_count + local_cc_count) * 3) + 1 > ctx->cc_databufsize)
|
||||
{
|
||||
ctx->cc_data = (unsigned char *)realloc(ctx->cc_data, (size_t)((ctx->cc_count + local_cc_count) * 6) + 1);
|
||||
if (!ctx->cc_data)
|
||||
unsigned char *tmp = (unsigned char *)realloc(ctx->cc_data, (size_t)((ctx->cc_count + local_cc_count) * 6) + 1);
|
||||
if (!tmp)
|
||||
{
|
||||
free(ctx->cc_data);
|
||||
fatal(EXIT_NOT_ENOUGH_MEMORY, "In user_data_registered_itu_t_t35: Out of memory to allocate buffer for CC data.");
|
||||
}
|
||||
ctx->cc_data = tmp;
|
||||
ctx->cc_databufsize = (long)((ctx->cc_count + local_cc_count) * 6) + 1;
|
||||
}
|
||||
// Copy new cc data into cc_data
|
||||
@@ -574,15 +632,19 @@ void user_data_registered_itu_t_t35(struct avc_ctx *ctx, unsigned char *userbuf,
|
||||
// Save the data and process once we know the sequence number
|
||||
if ((((local_cc_count + ctx->cc_count) * 3) + 1) > ctx->cc_databufsize)
|
||||
{
|
||||
ctx->cc_data = (unsigned char *)realloc(ctx->cc_data, (size_t)(((local_cc_count + ctx->cc_count) * 6) + 1));
|
||||
if (!ctx->cc_data)
|
||||
unsigned char *tmp = (unsigned char *)realloc(ctx->cc_data, (size_t)(((local_cc_count + ctx->cc_count) * 6) + 1));
|
||||
if (!tmp)
|
||||
{
|
||||
free(ctx->cc_data);
|
||||
fatal(EXIT_NOT_ENOUGH_MEMORY, "In user_data_registered_itu_t_t35: Not enough memory trying to allocate buffer for CC data.");
|
||||
}
|
||||
ctx->cc_data = tmp;
|
||||
ctx->cc_databufsize = (long)(((local_cc_count + ctx->cc_count) * 6) + 1);
|
||||
}
|
||||
// Copy new cc data into cc_data - replace command below.
|
||||
copy_ccdata_to_buffer(ctx, (char *)cc_tmp_data, local_cc_count);
|
||||
|
||||
//dump(tbuf,user_data_len-1,0);
|
||||
// dump(tbuf,user_data_len-1,0);
|
||||
break;
|
||||
default:
|
||||
mprint("Not a supported user data SEI\n");
|
||||
@@ -833,8 +895,8 @@ void seq_parameter_set_rbsp(struct avc_ctx *ctx, unsigned char *seqbuf, unsigned
|
||||
if (tmp)
|
||||
{
|
||||
dvprint("nal_hrd. Not implemented for now. Hopefully not needed. Skipping rest of NAL\n");
|
||||
//printf("Boom nal_hrd\n");
|
||||
// exit(1);
|
||||
// printf("Boom nal_hrd\n");
|
||||
// exit(1);
|
||||
ctx->num_nal_hrd++;
|
||||
return;
|
||||
}
|
||||
@@ -862,7 +924,7 @@ void seq_parameter_set_rbsp(struct avc_ctx *ctx, unsigned char *seqbuf, unsigned
|
||||
// it was not set in the testfile. Ignore the rest here, it's
|
||||
// currently not needed.
|
||||
}
|
||||
//exit(1);
|
||||
// exit(1);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -892,6 +954,15 @@ void slice_header(struct encoder_ctx *enc_ctx, struct lib_cc_decode *dec_ctx, un
|
||||
dvprint("first_mb_in_slice= % 4lld (%#llX)\n", tmp, tmp);
|
||||
slice_type = read_exp_golomb_unsigned(&q1);
|
||||
dvprint("slice_type= % 4llX\n", slice_type);
|
||||
|
||||
// Validate slice_type to prevent buffer overflow in slice_types[] array
|
||||
// Valid H.264 slice_type values are 0-9 (H.264 spec Table 7-6)
|
||||
if (slice_type >= 10)
|
||||
{
|
||||
mprint("Invalid slice_type %lld in slice header, skipping.\n", slice_type);
|
||||
return;
|
||||
}
|
||||
|
||||
tmp = read_exp_golomb_unsigned(&q1);
|
||||
dvprint("pic_parameter_set_id= % 4lld (%#llX)\n", tmp, tmp);
|
||||
|
||||
@@ -924,7 +995,7 @@ void slice_header(struct encoder_ctx *enc_ctx, struct lib_cc_decode *dec_ctx, un
|
||||
{
|
||||
tmp = read_exp_golomb_unsigned(&q1);
|
||||
dvprint("idr_pic_id= % 4lld (%#llX)\n", tmp, tmp);
|
||||
//TODO
|
||||
// TODO
|
||||
}
|
||||
if (dec_ctx->avc_ctx->pic_order_cnt_type == 0)
|
||||
{
|
||||
@@ -936,7 +1007,7 @@ void slice_header(struct encoder_ctx *enc_ctx, struct lib_cc_decode *dec_ctx, un
|
||||
fatal(CCX_COMMON_EXIT_BUG_BUG, "In slice_header: AVC: ctx->avc_ctx->pic_order_cnt_type == 1 not yet supported.");
|
||||
}
|
||||
|
||||
//Ignore slice with same pic order or pts
|
||||
// Ignore slice with same pic order or pts
|
||||
if (ccx_options.usepicorder)
|
||||
{
|
||||
if (dec_ctx->avc_ctx->last_pic_order_cnt_lsb == pic_order_cnt_lsb)
|
||||
@@ -1031,7 +1102,12 @@ void slice_header(struct encoder_ctx *enc_ctx, struct lib_cc_decode *dec_ctx, un
|
||||
}
|
||||
|
||||
// if slices are buffered - flush
|
||||
if (isref)
|
||||
// For I/P-only streams (like HDHomeRun recordings), flushing on every
|
||||
// reference frame defeats reordering since all frames are reference frames.
|
||||
// Only flush and reset on IDR frames (nal_unit_type==5), not P-frames.
|
||||
// This allows P-frames to accumulate in the buffer and be sorted by PTS.
|
||||
int is_idr = (nal_unit_type == CCX_NAL_TYPE_CODED_SLICE_IDR_PICTURE);
|
||||
if (isref && is_idr)
|
||||
{
|
||||
dvprint("\nReference pic! [%s]\n", slice_types[slice_type]);
|
||||
dbg_print(CCX_DMT_TIME, "\nReference pic! [%s] maxrefcnt: %3d\n",
|
||||
@@ -1126,8 +1202,32 @@ void slice_header(struct encoder_ctx *enc_ctx, struct lib_cc_decode *dec_ctx, un
|
||||
|
||||
if (abs(current_index) >= MAXBFRAMES)
|
||||
{
|
||||
// Probably a jump in the timeline. Warn and handle gracefully.
|
||||
mprint("\nFound large gap(%d) in PTS! Trying to recover ...\n", current_index);
|
||||
// Large PTS gap detected. This can happen with certain encoders
|
||||
// (like HDHomeRun) that produce streams where PTS jumps are common.
|
||||
// Instead of just resetting current_index to 0 (which causes captions
|
||||
// to pile up at the same buffer slot and become garbled), we need to:
|
||||
// 1. Flush any buffered captions
|
||||
// 2. Reset the reference PTS to the current PTS
|
||||
// 3. Set current_index to 0 for a fresh start
|
||||
// This ensures subsequent frames use the new reference point.
|
||||
dbg_print(CCX_DMT_VERBOSE, "\nLarge PTS gap(%d) detected, flushing buffer and resetting reference.\n", current_index);
|
||||
|
||||
// Flush any buffered captions before resetting
|
||||
if (dec_ctx->has_ccdata_buffered)
|
||||
{
|
||||
process_hdcc(enc_ctx, dec_ctx, sub);
|
||||
}
|
||||
|
||||
// Reset the reference point to current PTS
|
||||
dec_ctx->avc_ctx->currefpts = dec_ctx->timing->current_pts;
|
||||
|
||||
// Reset tracking variables for the new reference
|
||||
dec_ctx->avc_ctx->lastmaxidx = -1;
|
||||
dec_ctx->avc_ctx->maxidx = 0;
|
||||
dec_ctx->avc_ctx->lastminidx = 10000;
|
||||
dec_ctx->avc_ctx->minidx = 10000;
|
||||
|
||||
// Start with index 0 relative to the new reference
|
||||
current_index = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
#ifndef AVC_FUNCTION_H
|
||||
#define AVC_FUNCTION_H
|
||||
|
||||
|
||||
struct avc_ctx
|
||||
{
|
||||
unsigned char cc_count;
|
||||
// buffer to hold cc data
|
||||
unsigned char *cc_data;
|
||||
long cc_databufsize;
|
||||
int64_t cc_databufsize;
|
||||
int cc_buffer_saved; // Was the CC buffer saved after it was last updated?
|
||||
|
||||
int is_hevc; // Flag to indicate HEVC (H.265) mode vs H.264
|
||||
int got_seq_para;
|
||||
unsigned nal_ref_idc;
|
||||
LLONG seq_parameter_set_id;
|
||||
@@ -19,11 +19,11 @@ struct avc_ctx
|
||||
int frame_mbs_only_flag;
|
||||
|
||||
// Use and throw stats for debug, remove this ugliness soon
|
||||
long num_nal_unit_type_7;
|
||||
long num_vcl_hrd;
|
||||
long num_nal_hrd;
|
||||
long num_jump_in_frames;
|
||||
long num_unexpected_sei_length;
|
||||
int64_t num_nal_unit_type_7;
|
||||
int64_t num_vcl_hrd;
|
||||
int64_t num_nal_hrd;
|
||||
int64_t num_jump_in_frames;
|
||||
int64_t num_unexpected_sei_length;
|
||||
|
||||
int ccblocks_in_avc_total;
|
||||
int ccblocks_in_avc_lost;
|
||||
@@ -50,6 +50,6 @@ struct avc_ctx
|
||||
|
||||
struct avc_ctx *init_avc(void);
|
||||
void dinit_avc(struct avc_ctx **ctx);
|
||||
void do_NAL (struct encoder_ctx *enc_ctx, struct lib_cc_decode *ctx, unsigned char *NAL_start, LLONG NAL_length, struct cc_subtitle *sub);
|
||||
void do_NAL(struct encoder_ctx *enc_ctx, struct lib_cc_decode *ctx, unsigned char *NAL_start, LLONG NAL_length, struct cc_subtitle *sub);
|
||||
size_t process_avc(struct encoder_ctx *enc_ctx, struct lib_cc_decode *ctx, unsigned char *avcbuf, size_t avcbuflen, struct cc_subtitle *sub);
|
||||
#endif
|
||||
|
||||
@@ -3,6 +3,19 @@
|
||||
// Hold functions to read streams on a bit or byte oriented basis
|
||||
// plus some data related helper functions.
|
||||
|
||||
extern uint64_t ccxr_next_bits(struct bitstream *bs, uint32_t bnum);
|
||||
extern uint64_t ccxr_read_bits(struct bitstream *bs, uint32_t bnum);
|
||||
extern int ccxr_skip_bits(struct bitstream *bs, uint32_t bnum);
|
||||
extern int ccxr_is_byte_aligned(struct bitstream *bs);
|
||||
extern void ccxr_make_byte_aligned(struct bitstream *bs);
|
||||
extern const uint8_t *ccxr_next_bytes(struct bitstream *bs, size_t bynum);
|
||||
extern const uint8_t *ccxr_read_bytes(struct bitstream *bs, size_t bynum);
|
||||
extern uint64_t ccxr_read_exp_golomb_unsigned(struct bitstream *bs);
|
||||
extern int64_t ccxr_read_exp_golomb(struct bitstream *bs);
|
||||
extern uint8_t ccxr_reverse8(uint8_t data);
|
||||
extern uint64_t ccxr_bitstream_get_num(struct bitstream *bs, unsigned bytes, int advance);
|
||||
extern int64_t ccxr_read_int(struct bitstream *bs, unsigned bnum);
|
||||
|
||||
// Guidelines for all bitsream functions:
|
||||
// * No function shall advance the pointer past the end marker
|
||||
// * If bitstream.bitsleft < 0 do not attempt any read access,
|
||||
@@ -35,88 +48,14 @@ int init_bitstream(struct bitstream *bstr, unsigned char *start, unsigned char *
|
||||
// there are not enough bits left in the bitstream.
|
||||
uint64_t next_bits(struct bitstream *bstr, unsigned bnum)
|
||||
{
|
||||
uint64_t res = 0;
|
||||
|
||||
if (bnum > 64)
|
||||
fatal(CCX_COMMON_EXIT_BUG_BUG, "In next_bits: Argument is greater than the maximum bit number i.e. 64: %u!", bnum);
|
||||
|
||||
// Sanity check
|
||||
if (bstr->end - bstr->pos < 0)
|
||||
fatal(CCX_COMMON_EXIT_BUG_BUG, "In next_bits: Bitstream can not have negative length!");
|
||||
|
||||
// Keep a negative bitstream.bitsleft, but correct it.
|
||||
if (bstr->bitsleft <= 0)
|
||||
{
|
||||
bstr->bitsleft -= bnum;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Calculate the remaining number of bits in bitstream after reading.
|
||||
bstr->bitsleft = 0LL + (bstr->end - bstr->pos - 1) * 8 + bstr->bpos - bnum;
|
||||
if (bstr->bitsleft < 0)
|
||||
return 0;
|
||||
|
||||
// Special case for reading zero bits. Return zero
|
||||
if (bnum == 0)
|
||||
return 0;
|
||||
|
||||
int vbit = bstr->bpos;
|
||||
unsigned char *vpos = bstr->pos;
|
||||
|
||||
if (vbit < 1 || vbit > 8)
|
||||
{
|
||||
fatal(CCX_COMMON_EXIT_BUG_BUG, "In next_bits: Illegal bit position value %d!", vbit);
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (vpos >= bstr->end)
|
||||
{
|
||||
// We should not get here ...
|
||||
fatal(CCX_COMMON_EXIT_BUG_BUG, "In next_bits: Trying to read after end of data ...");
|
||||
}
|
||||
|
||||
res |= (*vpos & (0x01 << (vbit - 1)) ? 1 : 0);
|
||||
vbit--;
|
||||
bnum--;
|
||||
|
||||
if (vbit == 0)
|
||||
{
|
||||
vpos++;
|
||||
vbit = 8;
|
||||
}
|
||||
|
||||
if (bnum)
|
||||
{
|
||||
res <<= 1;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
// Remember the bitstream position
|
||||
bstr->_i_bpos = vbit;
|
||||
bstr->_i_pos = vpos;
|
||||
|
||||
return res;
|
||||
return ccxr_next_bits(bstr, bnum);
|
||||
}
|
||||
|
||||
// Read bnum bits from bitstream bstr with the most significant
|
||||
// bit read first. A 64 bit unsigned integer is returned.
|
||||
uint64_t read_bits(struct bitstream *bstr, unsigned bnum)
|
||||
{
|
||||
uint64_t res = next_bits(bstr, bnum);
|
||||
|
||||
// Special case for reading zero bits. Also abort when not enough
|
||||
// bits are left. Return zero
|
||||
if (bnum == 0 || bstr->bitsleft < 0)
|
||||
return 0;
|
||||
|
||||
// Advance the bitstream
|
||||
bstr->bpos = bstr->_i_bpos;
|
||||
bstr->pos = bstr->_i_pos;
|
||||
|
||||
return res;
|
||||
return ccxr_read_bits(bstr, bnum);
|
||||
}
|
||||
|
||||
// This function will advance the bitstream by bnum bits, if possible.
|
||||
@@ -124,35 +63,7 @@ uint64_t read_bits(struct bitstream *bstr, unsigned bnum)
|
||||
// Return TRUE when successful, otherwise FALSE
|
||||
int skip_bits(struct bitstream *bstr, unsigned bnum)
|
||||
{
|
||||
// Sanity check
|
||||
if (bstr->end - bstr->pos < 0)
|
||||
fatal(CCX_COMMON_EXIT_BUG_BUG, "In skip_bits: bitstream length cannot be negative!");
|
||||
|
||||
// Keep a negative bstr->bitsleft, but correct it.
|
||||
if (bstr->bitsleft < 0)
|
||||
{
|
||||
bstr->bitsleft -= bnum;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Calculate the remaining number of bits in bitstream after reading.
|
||||
bstr->bitsleft = 0LL + (bstr->end - bstr->pos - 1) * 8 + bstr->bpos - bnum;
|
||||
if (bstr->bitsleft < 0)
|
||||
return 0;
|
||||
|
||||
// Special case for reading zero bits. Return zero
|
||||
if (bnum == 0)
|
||||
return 1;
|
||||
|
||||
bstr->bpos -= bnum % 8;
|
||||
bstr->pos += bnum / 8;
|
||||
|
||||
if (bstr->bpos < 1)
|
||||
{
|
||||
bstr->bpos += 8;
|
||||
bstr->pos += 1;
|
||||
}
|
||||
return 1;
|
||||
return ccxr_skip_bits(bstr, bnum);
|
||||
}
|
||||
|
||||
// Return TRUE if the current position in the bitstream is on a byte
|
||||
@@ -160,54 +71,13 @@ int skip_bits(struct bitstream *bstr, unsigned bnum)
|
||||
// a byte, otherwise return FALSE
|
||||
int is_byte_aligned(struct bitstream *bstr)
|
||||
{
|
||||
// Sanity check
|
||||
if (bstr->end - bstr->pos < 0)
|
||||
fatal(CCX_COMMON_EXIT_BUG_BUG, "In is_byte_aligned: bitstream length can not be negative!");
|
||||
|
||||
int vbit = bstr->bpos;
|
||||
|
||||
if (vbit == 0 || vbit > 8)
|
||||
{
|
||||
fatal(CCX_COMMON_EXIT_BUG_BUG, "In is_byte_aligned: Illegal bit position value %d!\n", vbit);
|
||||
}
|
||||
|
||||
if (vbit == 8)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
return ccxr_is_byte_aligned(bstr);
|
||||
}
|
||||
|
||||
// Move bitstream to next byte border. Adjust bitsleft.
|
||||
void make_byte_aligned(struct bitstream *bstr)
|
||||
{
|
||||
// Sanity check
|
||||
if (bstr->end - bstr->pos < 0)
|
||||
fatal(CCX_COMMON_EXIT_BUG_BUG, "In make_byte_aligned: bitstream length can not be negative!");
|
||||
|
||||
int vbit = bstr->bpos;
|
||||
|
||||
if (vbit == 0 || vbit > 8)
|
||||
{
|
||||
fatal(CCX_COMMON_EXIT_BUG_BUG, "In make_byte_aligned: Illegal bit position value %d!\n", vbit);
|
||||
}
|
||||
|
||||
// Keep a negative bstr->bitsleft, but correct it.
|
||||
if (bstr->bitsleft < 0)
|
||||
{
|
||||
// Pay attention to the bit alignment
|
||||
bstr->bitsleft = (bstr->bitsleft - 7) / 8 * 8;
|
||||
return;
|
||||
}
|
||||
|
||||
if (bstr->bpos != 8)
|
||||
{
|
||||
bstr->bpos = 8;
|
||||
bstr->pos += 1;
|
||||
}
|
||||
// Reset, in case a next_???() function was used before
|
||||
bstr->bitsleft = 0LL + 8 * (bstr->end - bstr->pos - 1) + bstr->bpos;
|
||||
|
||||
return;
|
||||
ccxr_make_byte_aligned(bstr);
|
||||
}
|
||||
|
||||
// Return pointer to first of bynum bytes from the bitstream if the
|
||||
@@ -217,27 +87,7 @@ void make_byte_aligned(struct bitstream *bstr)
|
||||
// This function does not advance the bitstream pointer.
|
||||
unsigned char *next_bytes(struct bitstream *bstr, unsigned bynum)
|
||||
{
|
||||
// Sanity check
|
||||
if (bstr->end - bstr->pos < 0)
|
||||
fatal(CCX_COMMON_EXIT_BUG_BUG, "In next_bytes: bitstream length can not be negative!");
|
||||
|
||||
// Keep a negative bstr->bitsleft, but correct it.
|
||||
if (bstr->bitsleft < 0)
|
||||
{
|
||||
bstr->bitsleft -= bynum * 8;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bstr->bitsleft = 0LL + (bstr->end - bstr->pos - 1) * 8 + bstr->bpos - bynum * 8;
|
||||
|
||||
if (!is_byte_aligned(bstr) || bstr->bitsleft < 0 || bynum < 1)
|
||||
return NULL;
|
||||
|
||||
// Remember the bitstream position
|
||||
bstr->_i_bpos = 8;
|
||||
bstr->_i_pos = bstr->pos + bynum;
|
||||
|
||||
return bstr->pos;
|
||||
return (unsigned char *)ccxr_next_bytes(bstr, bynum);
|
||||
}
|
||||
|
||||
// Return pointer to first of bynum bytes from the bitstream if the
|
||||
@@ -247,15 +97,7 @@ unsigned char *next_bytes(struct bitstream *bstr, unsigned bynum)
|
||||
// This function does advance the bitstream pointer.
|
||||
unsigned char *read_bytes(struct bitstream *bstr, unsigned bynum)
|
||||
{
|
||||
unsigned char *res = next_bytes(bstr, bynum);
|
||||
|
||||
// Advance the bitstream when a read was possible
|
||||
if (res)
|
||||
{
|
||||
bstr->bpos = bstr->_i_bpos;
|
||||
bstr->pos = bstr->_i_pos;
|
||||
}
|
||||
return res;
|
||||
return (unsigned char *)ccxr_read_bytes(bstr, bynum);
|
||||
}
|
||||
|
||||
// Return an integer number with "bytes" precision from the current
|
||||
@@ -266,65 +108,19 @@ unsigned char *read_bytes(struct bitstream *bstr, unsigned bynum)
|
||||
// little-endian and big-endian CPUs.
|
||||
uint64_t bitstream_get_num(struct bitstream *bstr, unsigned bytes, int advance)
|
||||
{
|
||||
void *bpos;
|
||||
uint64_t rval = 0;
|
||||
|
||||
if (advance)
|
||||
bpos = read_bytes(bstr, bytes);
|
||||
else
|
||||
bpos = next_bytes(bstr, bytes);
|
||||
|
||||
if (!bpos)
|
||||
return 0;
|
||||
|
||||
switch (bytes)
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
case 4:
|
||||
case 8:
|
||||
break;
|
||||
default:
|
||||
fatal(CCX_COMMON_EXIT_BUG_BUG, "In bitstream_get_num: Illegal precision value [%u]!",
|
||||
bytes);
|
||||
break;
|
||||
}
|
||||
for (unsigned i = 0; i < bytes; i++)
|
||||
{
|
||||
unsigned char *ucpos = ((unsigned char *)bpos) + bytes - i - 1; // Read backwards
|
||||
unsigned char uc = *ucpos;
|
||||
rval = (rval << 8) + uc;
|
||||
}
|
||||
return rval;
|
||||
return ccxr_bitstream_get_num(bstr, bytes, advance);
|
||||
}
|
||||
|
||||
// Read unsigned Exp-Golomb code from bitstream
|
||||
uint64_t read_exp_golomb_unsigned(struct bitstream *bstr)
|
||||
{
|
||||
uint64_t res = 0;
|
||||
int zeros = 0;
|
||||
|
||||
while (!read_bits(bstr, 1) && bstr->bitsleft >= 0)
|
||||
zeros++;
|
||||
|
||||
res = (0x01 << zeros) - 1 + read_bits(bstr, zeros);
|
||||
|
||||
return res;
|
||||
return ccxr_read_exp_golomb_unsigned(bstr);
|
||||
}
|
||||
|
||||
// Read signed Exp-Golomb code from bitstream
|
||||
int64_t read_exp_golomb(struct bitstream *bstr)
|
||||
{
|
||||
int64_t res = 0;
|
||||
|
||||
res = read_exp_golomb_unsigned(bstr);
|
||||
|
||||
// The following function might truncate when res+1 overflows
|
||||
//res = (res+1)/2 * (res % 2 ? 1 : -1);
|
||||
// Use this:
|
||||
res = (res / 2 + (res % 2 ? 1 : 0)) * (res % 2 ? 1 : -1);
|
||||
|
||||
return res;
|
||||
return ccxr_read_exp_golomb(bstr);
|
||||
}
|
||||
|
||||
// Read unsigned integer with bnum bits length. Basically an
|
||||
@@ -337,25 +133,11 @@ uint64_t read_int_unsigned(struct bitstream *bstr, unsigned bnum)
|
||||
// Read signed integer with bnum bits length.
|
||||
int64_t read_int(struct bitstream *bstr, unsigned bnum)
|
||||
{
|
||||
uint64_t res = read_bits(bstr, bnum);
|
||||
|
||||
// Special case for reading zero bits. Return zero
|
||||
if (bnum == 0)
|
||||
return 0;
|
||||
|
||||
return (0xFFFFFFFFFFFFFFFFULL << bnum) | res;
|
||||
return ccxr_read_int(bstr, bnum);
|
||||
}
|
||||
|
||||
// Return the value with the bit order reversed.
|
||||
uint8_t reverse8(uint8_t data)
|
||||
{
|
||||
uint8_t res = 0;
|
||||
|
||||
for (int k = 0; k < 8; k++)
|
||||
{
|
||||
res <<= 1;
|
||||
res |= (data & (0x01 << k) ? 1 : 0);
|
||||
}
|
||||
|
||||
return res;
|
||||
return ccxr_reverse8(data);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#ifndef _BITSTREAM_
|
||||
#define _BITSTREAM_
|
||||
|
||||
|
||||
// The structure holds the current position in the bitstream.
|
||||
// pos points to the current byte position and bpos counts the
|
||||
// bits left unread at the current byte pos. No bit read means
|
||||
@@ -27,26 +26,25 @@ struct bitstream
|
||||
int _i_bpos;
|
||||
};
|
||||
|
||||
#define read_u8(bstream) (uint8_t)bitstream_get_num(bstream,1,1)
|
||||
#define read_u16(bstream) (uint16_t)bitstream_get_num(bstream,2,1)
|
||||
#define read_u32(bstream) (uint32_t)bitstream_get_num(bstream,4,1)
|
||||
#define read_u64(bstream) (uint64_t)bitstream_get_num(bstream,8,1)
|
||||
#define read_i8(bstream) (int8_t)bitstream_get_num(bstream,1,1)
|
||||
#define read_i16(bstream) (int16_t)bitstream_get_num(bstream,2,1)
|
||||
#define read_i32(bstream) (int32_t)bitstream_get_num(bstream,4,1)
|
||||
#define read_i64(bstream) (int64_t)bitstream_get_num(bstream,8,1)
|
||||
#define read_u8(bstream) (uint8_t)bitstream_get_num(bstream, 1, 1)
|
||||
#define read_u16(bstream) (uint16_t)bitstream_get_num(bstream, 2, 1)
|
||||
#define read_u32(bstream) (uint32_t)bitstream_get_num(bstream, 4, 1)
|
||||
#define read_u64(bstream) (uint64_t)bitstream_get_num(bstream, 8, 1)
|
||||
#define read_i8(bstream) (int8_t)bitstream_get_num(bstream, 1, 1)
|
||||
#define read_i16(bstream) (int16_t)bitstream_get_num(bstream, 2, 1)
|
||||
#define read_i32(bstream) (int32_t)bitstream_get_num(bstream, 4, 1)
|
||||
#define read_i64(bstream) (int64_t)bitstream_get_num(bstream, 8, 1)
|
||||
|
||||
#define skip_u32(bstream) (void)bitstream_get_num(bstream,4,1)
|
||||
|
||||
#define next_u8(bstream) (uint8_t)bitstream_get_num(bstream,1,0)
|
||||
#define next_u16(bstream) (uint16_t)bitstream_get_num(bstream,2,0)
|
||||
#define next_u32(bstream) (uint32_t)bitstream_get_num(bstream,4,0)
|
||||
#define next_u64(bstream) (uint64_t)bitstream_get_num(bstream,8,0)
|
||||
#define next_i8(bstream) (int8_t)bitstream_get_num(bstream,1,0)
|
||||
#define next_i16(bstream) (int16_t)bitstream_get_num(bstream,2,0)
|
||||
#define next_i32(bstream) (int32_t)bitstream_get_num(bstream,4,0)
|
||||
#define next_i64(bstream) (int64_t)bitstream_get_num(bstream,8,0)
|
||||
#define skip_u32(bstream) (void)bitstream_get_num(bstream, 4, 1)
|
||||
|
||||
#define next_u8(bstream) (uint8_t)bitstream_get_num(bstream, 1, 0)
|
||||
#define next_u16(bstream) (uint16_t)bitstream_get_num(bstream, 2, 0)
|
||||
#define next_u32(bstream) (uint32_t)bitstream_get_num(bstream, 4, 0)
|
||||
#define next_u64(bstream) (uint64_t)bitstream_get_num(bstream, 8, 0)
|
||||
#define next_i8(bstream) (int8_t)bitstream_get_num(bstream, 1, 0)
|
||||
#define next_i16(bstream) (int16_t)bitstream_get_num(bstream, 2, 0)
|
||||
#define next_i32(bstream) (int32_t)bitstream_get_num(bstream, 4, 0)
|
||||
#define next_i64(bstream) (int64_t)bitstream_get_num(bstream, 8, 0)
|
||||
|
||||
int init_bitstream(struct bitstream *bstr, unsigned char *start, unsigned char *end);
|
||||
uint64_t next_bits(struct bitstream *bstr, unsigned bnum);
|
||||
@@ -35,6 +35,8 @@ void get_char_in_latin_1(unsigned char *buffer, unsigned char c)
|
||||
case 0x7e: // lowercase n tilde
|
||||
c1 = 0xf1;
|
||||
break;
|
||||
case 0x7f: // Solid Block - Does not exist in Latin 1
|
||||
break;
|
||||
default:
|
||||
c1 = c;
|
||||
break;
|
||||
@@ -292,6 +294,10 @@ void get_char_in_unicode(unsigned char *buffer, unsigned char c)
|
||||
unsigned char c1, c2;
|
||||
switch (c)
|
||||
{
|
||||
case 0x7f: // Solid block
|
||||
c2 = 0x25;
|
||||
c1 = 0xa0;
|
||||
break;
|
||||
case 0x84: // Trademark symbol (TM)
|
||||
c2 = 0x21;
|
||||
c1 = 0x22;
|
||||
|
||||
@@ -26,14 +26,7 @@ int fdprintf(int fd, const char *fmt, ...)
|
||||
void millis_to_time(LLONG milli, unsigned *hours, unsigned *minutes,
|
||||
unsigned *seconds, unsigned *ms)
|
||||
{
|
||||
// LLONG milli = (LLONG) ((ccblock*1000)/29.97);
|
||||
*ms = (unsigned)(milli % 1000); // milliseconds
|
||||
milli = (milli - *ms) / 1000; // Remainder, in seconds
|
||||
*seconds = (int)milli % 60;
|
||||
milli = (milli - *seconds) / 60; // Remainder, in minutes
|
||||
*minutes = (int)(milli % 60);
|
||||
milli = (milli - *minutes) / 60; // Remainder, in hours
|
||||
*hours = (int)milli;
|
||||
return ccxr_millis_to_time(milli, hours, minutes, seconds, ms);
|
||||
}
|
||||
|
||||
/* Frees the given pointer */
|
||||
|
||||
@@ -10,44 +10,47 @@
|
||||
<100 means display whatever was output to stderr as a warning
|
||||
>=100 means display whatever was output to stdout as an error
|
||||
*/
|
||||
#define EXIT_OK 0
|
||||
#define EXIT_NO_INPUT_FILES 2
|
||||
#define EXIT_TOO_MANY_INPUT_FILES 3
|
||||
#define EXIT_INCOMPATIBLE_PARAMETERS 4
|
||||
#define EXIT_UNABLE_TO_DETERMINE_FILE_SIZE 6
|
||||
#define EXIT_MALFORMED_PARAMETER 7
|
||||
#define EXIT_READ_ERROR 8
|
||||
#define EXIT_WITH_HELP 9
|
||||
#define EXIT_NO_CAPTIONS 10
|
||||
#define EXIT_NOT_CLASSIFIED 300
|
||||
#define EXIT_ERROR_IN_CAPITALIZATION_FILE 501
|
||||
#define EXIT_BUFFER_FULL 502
|
||||
#define EXIT_MISSING_ASF_HEADER 1001
|
||||
#define EXIT_MISSING_RCWT_HEADER 1002
|
||||
#define EXIT_OK 0
|
||||
#define EXIT_NO_INPUT_FILES 2
|
||||
#define EXIT_TOO_MANY_INPUT_FILES 3
|
||||
#define EXIT_INCOMPATIBLE_PARAMETERS 4
|
||||
#define EXIT_UNABLE_TO_DETERMINE_FILE_SIZE 6
|
||||
#define EXIT_MALFORMED_PARAMETER 7
|
||||
#define EXIT_READ_ERROR 8
|
||||
#define EXIT_NO_CAPTIONS 10
|
||||
#define EXIT_WITH_HELP 11
|
||||
#define EXIT_NOT_CLASSIFIED 300
|
||||
#define EXIT_ERROR_IN_CAPITALIZATION_FILE 501
|
||||
#define EXIT_BUFFER_FULL 502
|
||||
#define EXIT_MISSING_ASF_HEADER 1001
|
||||
#define EXIT_MISSING_RCWT_HEADER 1002
|
||||
|
||||
#define CCX_COMMON_EXIT_FILE_CREATION_FAILED 5
|
||||
#define CCX_COMMON_EXIT_UNSUPPORTED 9
|
||||
#define EXIT_NOT_ENOUGH_MEMORY 500
|
||||
#define CCX_COMMON_EXIT_BUG_BUG 1000
|
||||
#define CCX_COMMON_EXIT_FILE_CREATION_FAILED 5
|
||||
#define CCX_COMMON_EXIT_UNSUPPORTED 9
|
||||
#define EXIT_NOT_ENOUGH_MEMORY 500
|
||||
#define CCX_COMMON_EXIT_BUG_BUG 1000
|
||||
|
||||
#define CCX_OK 0
|
||||
#define CCX_FALSE 0
|
||||
#define CCX_TRUE 1
|
||||
#define CCX_EAGAIN -100
|
||||
#define CCX_EOF -101
|
||||
#define CCX_EINVAL -102
|
||||
#define CCX_OK 0
|
||||
#define CCX_FALSE 0
|
||||
#define CCX_TRUE 1
|
||||
#define CCX_EAGAIN -100
|
||||
#define CCX_EOF -101
|
||||
#define CCX_EINVAL -102
|
||||
#define CCX_ENOSUPP -103
|
||||
#define CCX_ENOMEM -104
|
||||
#define CCX_ENOMEM -104
|
||||
|
||||
// Declarations
|
||||
int cc608_parity(unsigned int byte);
|
||||
int fdprintf(int fd, const char *fmt, ...);
|
||||
void millis_to_time(LLONG milli, unsigned *hours, unsigned *minutes,unsigned *seconds, unsigned *ms);
|
||||
void millis_to_time(LLONG milli, unsigned *hours, unsigned *minutes, unsigned *seconds, unsigned *ms);
|
||||
|
||||
extern void ccxr_millis_to_time(LLONG milli, unsigned *hours, unsigned *minutes, unsigned *seconds, unsigned *ms);
|
||||
|
||||
void freep(void *arg);
|
||||
void dbg_print(LLONG mask, const char *fmt, ...);
|
||||
unsigned char *debug_608_to_ASC(unsigned char *ccdata, int channel);
|
||||
int add_cc_sub_text(struct cc_subtitle *sub, char *str, LLONG start_time,
|
||||
LLONG end_time, char *info, char *mode, enum ccx_encoding_type);
|
||||
LLONG end_time, char *info, char *mode, enum ccx_encoding_type);
|
||||
|
||||
extern int cc608_parity_table[256]; // From myth
|
||||
#endif
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
#include "ccx_common_constants.h"
|
||||
|
||||
// RCWT header (11 bytes):
|
||||
//byte(s) value description (All values below are hex numbers, not
|
||||
// byte(s) value description (All values below are hex numbers, not
|
||||
// actual numbers or values
|
||||
//0-2 CCCCED magic number, for Closed Caption CC Extractor Data
|
||||
//3 CC Creating program. Legal values: CC = CC Extractor
|
||||
//4-5 0050 Program version number
|
||||
//6-7 0001 File format version
|
||||
//8-10 000000 Padding, required :-)
|
||||
// 0-2 CCCCED magic number, for Closed Caption CC Extractor Data
|
||||
// 3 CC Creating program. Legal values: CC = CC Extractor
|
||||
// 4-5 0050 Program version number
|
||||
// 6-7 0001 File format version
|
||||
// 8-10 000000 Padding, required :-)
|
||||
unsigned char rcwt_header[11] = {0xCC, 0xCC, 0xED, 0xCC, 0x00, 0x50, 0, 1, 0, 0, 0};
|
||||
|
||||
const unsigned char BROADCAST_HEADER[] = {0xff, 0xff, 0xff, 0xff};
|
||||
@@ -17,8 +17,8 @@ const unsigned char UTF8_BOM[] = {0xef, 0xbb, 0xbf};
|
||||
const unsigned char DVD_HEADER[8] = {0x00, 0x00, 0x01, 0xb2, 0x43, 0x43, 0x01, 0xf8};
|
||||
const unsigned char lc1[1] = {0x8a};
|
||||
const unsigned char lc2[1] = {0x8f};
|
||||
const unsigned char lc3[2] = {0x16, 0xfe};
|
||||
const unsigned char lc4[2] = {0x1e, 0xfe};
|
||||
const unsigned char lc3[1] = {0x16}; // McPoodle uses single-byte loop markers
|
||||
const unsigned char lc4[1] = {0x1e};
|
||||
const unsigned char lc5[1] = {0xff};
|
||||
const unsigned char lc6[1] = {0xfe};
|
||||
|
||||
@@ -122,7 +122,7 @@ enum
|
||||
*/
|
||||
const char *language[NB_LANGUAGE] =
|
||||
{
|
||||
/*0*/ "und", //Undefined
|
||||
/*0*/ "und", // Undefined
|
||||
/*1*/ "eng",
|
||||
/*2*/ "afr",
|
||||
/*3*/ "amh",
|
||||
|
||||
@@ -22,45 +22,42 @@ extern const unsigned char UTF8_BOM[3];
|
||||
extern const unsigned char DVD_HEADER[8];
|
||||
extern const unsigned char lc1[1];
|
||||
extern const unsigned char lc2[1];
|
||||
extern const unsigned char lc3[2];
|
||||
extern const unsigned char lc4[2];
|
||||
extern const unsigned char lc3[1];
|
||||
extern const unsigned char lc4[1];
|
||||
extern const unsigned char lc5[1];
|
||||
extern const unsigned char lc6[1];
|
||||
|
||||
extern unsigned char rcwt_header[11];
|
||||
|
||||
#define ONEPASS 120 /* Bytes we can always look ahead without going out of limits */
|
||||
#define BUFSIZE (2048*1024+ONEPASS) /* 2 Mb plus the safety pass */
|
||||
#define ONEPASS 120 /* Bytes we can always look ahead without going out of limits */
|
||||
#define BUFSIZE (2048 * 1024 + ONEPASS) /* 2 Mb plus the safety pass */
|
||||
#define MAX_CLOSED_CAPTION_DATA_PER_PICTURE 32
|
||||
#define EIA_708_BUFFER_LENGTH 2048 // TODO: Find out what the real limit is
|
||||
#define TS_PACKET_PAYLOAD_LENGTH 184 // From specs
|
||||
#define SUBLINESIZE 2048 // Max. length of a .srt line - TODO: Get rid of this
|
||||
#define STARTBYTESLENGTH (1024*1024)
|
||||
#define EIA_708_BUFFER_LENGTH 2048 // TODO: Find out what the real limit is
|
||||
#define TS_PACKET_PAYLOAD_LENGTH 184 // From specs
|
||||
#define SUBLINESIZE 2048 // Max. length of a .srt line - TODO: Get rid of this
|
||||
#define STARTBYTESLENGTH (1024 * 1024)
|
||||
#define UTF8_MAX_BYTES 6
|
||||
#define XMLRPC_CHUNK_SIZE (64*1024) // 64 Kb per chunk, to avoid too many realloc()
|
||||
#define XMLRPC_CHUNK_SIZE (64 * 1024) // 64 Kb per chunk, to avoid too many realloc()
|
||||
|
||||
enum ccx_debug_message_types
|
||||
{
|
||||
/* Each debug message now belongs to one of these types. Use bitmaps in case
|
||||
we want one message to belong to more than one type. */
|
||||
CCX_DMT_PARSE = 1, // Show information related to parsing the container
|
||||
CCX_DMT_VIDES = 2, // Show video stream related information
|
||||
CCX_DMT_TIME = 4, // Show GOP and PTS timing information
|
||||
CCX_DMT_VERBOSE = 8, // Show lots of debugging output
|
||||
CCX_DMT_DECODER_608 = 0x10, // Show CC-608 decoder debug?
|
||||
CCX_DMT_708 = 0x20, // Show CC-708 decoder debug?
|
||||
CCX_DMT_DECODER_XDS = 0x40, // Show XDS decoder debug?
|
||||
CCX_DMT_CBRAW = 0x80, // Caption blocks with FTS timing
|
||||
CCX_DMT_PARSE = 1, // Show information related to parsing the container
|
||||
CCX_DMT_VIDES = 2, // Show video stream related information
|
||||
CCX_DMT_TIME = 4, // Show GOP and PTS timing information
|
||||
CCX_DMT_VERBOSE = 8, // Show lots of debugging output
|
||||
CCX_DMT_DECODER_608 = 0x10, // Show CC-608 decoder debug?
|
||||
CCX_DMT_708 = 0x20, // Show CC-708 decoder debug?
|
||||
CCX_DMT_DECODER_XDS = 0x40, // Show XDS decoder debug?
|
||||
CCX_DMT_CBRAW = 0x80, // Caption blocks with FTS timing
|
||||
CCX_DMT_GENERIC_NOTICES = 0x100, // Generic, always displayed even if no debug is selected
|
||||
CCX_DMT_TELETEXT = 0x200, // Show teletext debug?
|
||||
CCX_DMT_PAT = 0x400, // Program Allocation Table dump
|
||||
CCX_DMT_PMT = 0x800, // Program Map Table dump
|
||||
CCX_DMT_LEVENSHTEIN = 0x1000, // Levenshtein distance calculations
|
||||
CCX_DMT_DVB = 0x2000, // DVB
|
||||
#ifdef ENABLE_SHARING
|
||||
CCX_DMT_SHARE = 0x2000, // Extracted captions sharing service
|
||||
#endif //ENABLE_SHARING
|
||||
CCX_DMT_DUMPDEF = 0x4000 // Dump defective TS packets
|
||||
CCX_DMT_TELETEXT = 0x200, // Show teletext debug?
|
||||
CCX_DMT_PAT = 0x400, // Program Allocation Table dump
|
||||
CCX_DMT_PMT = 0x800, // Program Map Table dump
|
||||
CCX_DMT_LEVENSHTEIN = 0x1000, // Levenshtein distance calculations
|
||||
CCX_DMT_DVB = 0x2000, // DVB
|
||||
CCX_DMT_DUMPDEF = 0x4000 // Dump defective TS packets
|
||||
};
|
||||
|
||||
// AVC NAL types
|
||||
@@ -104,95 +101,95 @@ enum ccx_avc_nal_types
|
||||
enum ccx_stream_type
|
||||
{
|
||||
CCX_STREAM_TYPE_UNKNOWNSTREAM = 0,
|
||||
|
||||
/*
|
||||
|
||||
/*
|
||||
The later constants are defined by MPEG-TS standard
|
||||
Explore at: https://exiftool.org/TagNames/M2TS.html
|
||||
Explore at: https://exiftool.org/TagNames/M2TS.html
|
||||
*/
|
||||
CCX_STREAM_TYPE_VIDEO_MPEG1 = 0x01,
|
||||
CCX_STREAM_TYPE_VIDEO_MPEG2 = 0x02,
|
||||
CCX_STREAM_TYPE_AUDIO_MPEG1 = 0x03,
|
||||
CCX_STREAM_TYPE_AUDIO_MPEG2 = 0x04,
|
||||
CCX_STREAM_TYPE_PRIVATE_TABLE_MPEG2 = 0x05,
|
||||
CCX_STREAM_TYPE_PRIVATE_MPEG2 = 0x06,
|
||||
CCX_STREAM_TYPE_MHEG_PACKETS = 0x07,
|
||||
CCX_STREAM_TYPE_MPEG2_ANNEX_A_DSM_CC = 0x08,
|
||||
CCX_STREAM_TYPE_ITU_T_H222_1 = 0x09,
|
||||
CCX_STREAM_TYPE_VIDEO_MPEG1 = 0x01,
|
||||
CCX_STREAM_TYPE_VIDEO_MPEG2 = 0x02,
|
||||
CCX_STREAM_TYPE_AUDIO_MPEG1 = 0x03,
|
||||
CCX_STREAM_TYPE_AUDIO_MPEG2 = 0x04,
|
||||
CCX_STREAM_TYPE_PRIVATE_TABLE_MPEG2 = 0x05,
|
||||
CCX_STREAM_TYPE_PRIVATE_MPEG2 = 0x06,
|
||||
CCX_STREAM_TYPE_MHEG_PACKETS = 0x07,
|
||||
CCX_STREAM_TYPE_MPEG2_ANNEX_A_DSM_CC = 0x08,
|
||||
CCX_STREAM_TYPE_ITU_T_H222_1 = 0x09,
|
||||
CCX_STREAM_TYPE_ISO_IEC_13818_6_TYPE_A = 0x0A,
|
||||
CCX_STREAM_TYPE_ISO_IEC_13818_6_TYPE_B = 0x0B,
|
||||
CCX_STREAM_TYPE_ISO_IEC_13818_6_TYPE_C = 0x0C,
|
||||
CCX_STREAM_TYPE_ISO_IEC_13818_6_TYPE_D = 0x0D,
|
||||
CCX_STREAM_TYPE_AUDIO_AAC = 0x0f,
|
||||
CCX_STREAM_TYPE_VIDEO_MPEG4 = 0x10,
|
||||
CCX_STREAM_TYPE_VIDEO_H264 = 0x1b,
|
||||
CCX_STREAM_TYPE_PRIVATE_USER_MPEG2 = 0x80,
|
||||
CCX_STREAM_TYPE_AUDIO_AC3 = 0x81,
|
||||
CCX_STREAM_TYPE_AUDIO_HDMV_DTS = 0x82,
|
||||
CCX_STREAM_TYPE_AUDIO_DTS = 0x8a
|
||||
CCX_STREAM_TYPE_AUDIO_AAC = 0x0f,
|
||||
CCX_STREAM_TYPE_VIDEO_MPEG4 = 0x10,
|
||||
CCX_STREAM_TYPE_VIDEO_H264 = 0x1b,
|
||||
CCX_STREAM_TYPE_VIDEO_HEVC = 0x24,
|
||||
CCX_STREAM_TYPE_PRIVATE_USER_MPEG2 = 0x80,
|
||||
CCX_STREAM_TYPE_AUDIO_AC3 = 0x81,
|
||||
CCX_STREAM_TYPE_AUDIO_HDMV_DTS = 0x82,
|
||||
CCX_STREAM_TYPE_AUDIO_DTS = 0x8a
|
||||
};
|
||||
|
||||
enum ccx_mpeg_descriptor
|
||||
{
|
||||
/*
|
||||
/*
|
||||
The later constants are defined by ETSI EN 300 468 standard
|
||||
Explore at: https://www.etsi.org/deliver/etsi_en/300400_300499/300468/01.11.01_60/en_300468v011101p.pdf
|
||||
Explore at: https://www.etsi.org/deliver/etsi_en/300400_300499/300468/01.11.01_60/en_300468v011101p.pdf
|
||||
*/
|
||||
CCX_MPEG_DSC_REGISTRATION = 0x05,
|
||||
CCX_MPEG_DSC_DATA_STREAM_ALIGNMENT = 0x06,
|
||||
CCX_MPEG_DSC_ISO639_LANGUAGE = 0x0A,
|
||||
CCX_MPEG_DSC_VBI_DATA_DESCRIPTOR = 0x45,
|
||||
CCX_MPEG_DSC_REGISTRATION = 0x05,
|
||||
CCX_MPEG_DSC_DATA_STREAM_ALIGNMENT = 0x06,
|
||||
CCX_MPEG_DSC_ISO639_LANGUAGE = 0x0A,
|
||||
CCX_MPEG_DSC_VBI_DATA_DESCRIPTOR = 0x45,
|
||||
CCX_MPEG_DSC_VBI_TELETEXT_DESCRIPTOR = 0x46,
|
||||
CCX_MPEG_DSC_TELETEXT_DESCRIPTOR = 0x56,
|
||||
CCX_MPEG_DSC_DVB_SUBTITLE = 0x59,
|
||||
CCX_MPEG_DSC_TELETEXT_DESCRIPTOR = 0x56,
|
||||
CCX_MPEG_DSC_DVB_SUBTITLE = 0x59,
|
||||
/* User defined */
|
||||
CCX_MPEG_DSC_CAPTION_SERVICE = 0x86,
|
||||
CCX_MPEG_DESC_DATA_COMP = 0xfd // Consider to change DESC to DSC
|
||||
CCX_MPEG_DSC_CAPTION_SERVICE = 0x86,
|
||||
CCX_MPEG_DESC_DATA_COMP = 0xfd // Consider to change DESC to DSC
|
||||
};
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
CCX_MESSAGES_QUIET = 0,
|
||||
CCX_MESSAGES_QUIET = 0,
|
||||
CCX_MESSAGES_STDOUT = 1,
|
||||
CCX_MESSAGES_STDERR = 2
|
||||
};
|
||||
|
||||
enum ccx_datasource
|
||||
{
|
||||
CCX_DS_FILE = 0,
|
||||
CCX_DS_STDIN = 1,
|
||||
CCX_DS_FILE = 0,
|
||||
CCX_DS_STDIN = 1,
|
||||
CCX_DS_NETWORK = 2,
|
||||
CCX_DS_TCP = 3
|
||||
CCX_DS_TCP = 3
|
||||
};
|
||||
|
||||
enum ccx_output_format
|
||||
{
|
||||
CCX_OF_RAW = 0,
|
||||
CCX_OF_SRT = 1,
|
||||
CCX_OF_SAMI = 2,
|
||||
CCX_OF_RAW = 0,
|
||||
CCX_OF_SRT = 1,
|
||||
CCX_OF_SAMI = 2,
|
||||
CCX_OF_TRANSCRIPT = 3,
|
||||
CCX_OF_RCWT = 4,
|
||||
CCX_OF_NULL = 5,
|
||||
CCX_OF_SMPTETT = 6,
|
||||
CCX_OF_SPUPNG = 7,
|
||||
CCX_OF_DVDRAW = 8, // See -d at http://www.theneitherworld.com/mcpoodle/SCC_TOOLS/DOCS/SCC_TOOLS.HTML#CCExtract
|
||||
CCX_OF_WEBVTT = 9,
|
||||
CCX_OF_RCWT = 4,
|
||||
CCX_OF_NULL = 5,
|
||||
CCX_OF_SMPTETT = 6,
|
||||
CCX_OF_SPUPNG = 7,
|
||||
CCX_OF_DVDRAW = 8, // See -d at http://www.theneitherworld.com/mcpoodle/SCC_TOOLS/DOCS/SCC_TOOLS.HTML#CCExtract
|
||||
CCX_OF_WEBVTT = 9,
|
||||
CCX_OF_SIMPLE_XML = 10,
|
||||
CCX_OF_G608 = 11,
|
||||
CCX_OF_CURL = 12,
|
||||
CCX_OF_SSA = 13,
|
||||
CCX_OF_MCC = 14,
|
||||
CCX_OF_SCC = 15,
|
||||
CCX_OF_CCD = 16,
|
||||
CCX_OF_G608 = 11,
|
||||
CCX_OF_CURL = 12,
|
||||
CCX_OF_SSA = 13,
|
||||
CCX_OF_MCC = 14,
|
||||
CCX_OF_SCC = 15,
|
||||
CCX_OF_CCD = 16,
|
||||
};
|
||||
|
||||
enum ccx_output_date_format
|
||||
{
|
||||
ODF_NONE = 0,
|
||||
ODF_HHMMSS = 1,
|
||||
ODF_SECONDS = 2,
|
||||
ODF_DATE = 3,
|
||||
ODF_HHMMSSMS = 4 // HH:MM:SS,MILIS (.srt style)
|
||||
ODF_NONE = 0,
|
||||
ODF_HHMMSS = 1,
|
||||
ODF_SECONDS = 2,
|
||||
ODF_DATE = 3,
|
||||
ODF_HHMMSSMS = 4 // HH:MM:SS,MILIS (.srt style)
|
||||
};
|
||||
|
||||
enum ccx_stream_mode_enum
|
||||
@@ -202,9 +199,9 @@ enum ccx_stream_mode_enum
|
||||
CCX_SM_PROGRAM = 2,
|
||||
CCX_SM_ASF = 3,
|
||||
CCX_SM_MCPOODLESRAW = 4,
|
||||
CCX_SM_RCWT = 5, // Raw Captions With Time, not used yet.
|
||||
CCX_SM_MYTH = 6, // Use the myth loop
|
||||
CCX_SM_MP4 = 7, // MP4, ISO-
|
||||
CCX_SM_RCWT = 5, // Raw Captions With Time, not used yet.
|
||||
CCX_SM_MYTH = 6, // Use the myth loop
|
||||
CCX_SM_MP4 = 7, // MP4, ISO-
|
||||
#ifdef WTV_DEBUG
|
||||
CCX_SM_HEX_DUMP = 8, // Hexadecimal dump generated by wtvccdump
|
||||
#endif
|
||||
@@ -223,8 +220,8 @@ enum ccx_encoding_type
|
||||
{
|
||||
CCX_ENC_UNICODE = 0,
|
||||
CCX_ENC_LATIN_1 = 1,
|
||||
CCX_ENC_UTF_8 = 2,
|
||||
CCX_ENC_ASCII = 3
|
||||
CCX_ENC_UTF_8 = 2,
|
||||
CCX_ENC_ASCII = 3
|
||||
};
|
||||
|
||||
enum ccx_bufferdata_type
|
||||
@@ -240,7 +237,8 @@ enum ccx_bufferdata_type
|
||||
CCX_ISDB_SUBTITLE = 8,
|
||||
/* BUffer where cc data contain 3 byte cc_valid ccdata 1 ccdata 2 */
|
||||
CCX_RAW_TYPE = 9,
|
||||
CCX_DVD_SUBTITLE = 10
|
||||
CCX_DVD_SUBTITLE = 10,
|
||||
CCX_HEVC = 11
|
||||
};
|
||||
|
||||
enum ccx_frame_type
|
||||
@@ -252,32 +250,33 @@ enum ccx_frame_type
|
||||
CCX_FRAME_TYPE_D_FRAME = 4
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
NO = 0,
|
||||
typedef enum
|
||||
{
|
||||
NO = 0,
|
||||
YES = 1,
|
||||
UNDEFINED = 0xff
|
||||
} bool_t;
|
||||
|
||||
enum ccx_code_type
|
||||
{
|
||||
CCX_CODEC_ANY = 0,
|
||||
CCX_CODEC_ANY = 0,
|
||||
CCX_CODEC_TELETEXT = 1,
|
||||
CCX_CODEC_DVB = 2,
|
||||
CCX_CODEC_ISDB_CC = 3,
|
||||
CCX_CODEC_ATSC_CC = 4,
|
||||
CCX_CODEC_NONE = 5
|
||||
CCX_CODEC_DVB = 2,
|
||||
CCX_CODEC_ISDB_CC = 3,
|
||||
CCX_CODEC_ATSC_CC = 4,
|
||||
CCX_CODEC_NONE = 5
|
||||
};
|
||||
|
||||
/* Caption Distribution Packet */
|
||||
enum cdp_section_type
|
||||
{
|
||||
/*
|
||||
/*
|
||||
The later constants are defined by SMPTE ST 334
|
||||
Purchase for 80$ at: https://ieeexplore.ieee.org/document/8255806
|
||||
*/
|
||||
CDP_SECTION_DATA = 0x72,
|
||||
CDP_SECTION_DATA = 0x72,
|
||||
CDP_SECTION_SVC_INFO = 0x73,
|
||||
CDP_SECTION_FOOTER = 0x74
|
||||
CDP_SECTION_FOOTER = 0x74
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -290,9 +289,9 @@ enum cdp_section_type
|
||||
*
|
||||
*/
|
||||
|
||||
#define IS_VALID_TELETEXT_DESC(desc) ( ((desc) == CCX_MPEG_DSC_VBI_DATA_DESCRIPTOR )|| \
|
||||
( (desc) == CCX_MPEG_DSC_VBI_TELETEXT_DESCRIPTOR ) || \
|
||||
( (desc) == CCX_MPEG_DSC_TELETEXT_DESCRIPTOR ) )
|
||||
#define IS_VALID_TELETEXT_DESC(desc) (((desc) == CCX_MPEG_DSC_VBI_DATA_DESCRIPTOR) || \
|
||||
((desc) == CCX_MPEG_DSC_VBI_TELETEXT_DESCRIPTOR) || \
|
||||
((desc) == CCX_MPEG_DSC_TELETEXT_DESCRIPTOR))
|
||||
|
||||
/*
|
||||
* This macro to be used when you want to find out whether you
|
||||
@@ -311,19 +310,19 @@ enum cdp_section_type
|
||||
* @param f_sel pass the codec name whom you are testing to be feasible
|
||||
* to parse.
|
||||
*/
|
||||
#define IS_FEASIBLE(u_sel,u_nsel,f_sel) ( ( (u_sel) == CCX_CODEC_ANY && (u_nsel) != (f_sel) ) || (u_sel) == (f_sel) )
|
||||
#define CCX_TXT_FORBIDDEN 0 // Ignore teletext packets
|
||||
#define CCX_TXT_AUTO_NOT_YET_FOUND 1
|
||||
#define CCX_TXT_IN_USE 2 // Positive auto-detected, or forced, etc
|
||||
#define IS_FEASIBLE(u_sel, u_nsel, f_sel) (((u_sel) == CCX_CODEC_ANY && (u_nsel) != (f_sel)) || (u_sel) == (f_sel))
|
||||
#define CCX_TXT_FORBIDDEN 0 // Ignore teletext packets
|
||||
#define CCX_TXT_AUTO_NOT_YET_FOUND 1
|
||||
#define CCX_TXT_IN_USE 2 // Positive auto-detected, or forced, etc
|
||||
|
||||
#define NB_LANGUAGE 100
|
||||
extern const char *language[NB_LANGUAGE];
|
||||
|
||||
#define DEF_VAL_STARTCREDITSNOTBEFORE "0"
|
||||
#define DEF_VAL_STARTCREDITSNOTBEFORE "0"
|
||||
// To catch the theme after the teaser in TV shows
|
||||
#define DEF_VAL_STARTCREDITSNOTAFTER "5:00"
|
||||
#define DEF_VAL_STARTCREDITSFORATLEAST "2"
|
||||
#define DEF_VAL_STARTCREDITSFORATMOST "5"
|
||||
#define DEF_VAL_ENDCREDITSFORATLEAST "2"
|
||||
#define DEF_VAL_ENDCREDITSFORATMOST "5"
|
||||
#define DEF_VAL_STARTCREDITSNOTAFTER "5:00"
|
||||
#define DEF_VAL_STARTCREDITSFORATLEAST "2"
|
||||
#define DEF_VAL_STARTCREDITSFORATMOST "5"
|
||||
#define DEF_VAL_ENDCREDITSFORATLEAST "2"
|
||||
#define DEF_VAL_ENDCREDITSFORATMOST "5"
|
||||
#endif
|
||||
|
||||
@@ -22,10 +22,12 @@ 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
|
||||
options->binary_concat = 1; // Disabled by -ve or --videoedited
|
||||
options->binary_concat = 1; // Disabled by --videoedited
|
||||
options->use_gop_as_pts = 0; // Use GOP instead of PTS timing (0=do as needed, 1=always, -1=never)
|
||||
options->fix_padding = 0; // Replace 0000 with 8080 in HDTV (needed for some cards)
|
||||
options->gui_mode_reports = 0; // If 1, output in stderr progress updates so the GUI can grab them
|
||||
@@ -39,7 +41,7 @@ void init_options(struct ccx_s_options *options)
|
||||
options->live_stream = 0; // 0 -> A regular file
|
||||
options->messages_target = 1; // 1=stdout
|
||||
options->print_file_reports = 0;
|
||||
options->no_timestamp_map = 0; // Enable timestamps by default
|
||||
options->timestamp_map = 0; // Disable X-TIMESTAMP-MAP header by default
|
||||
|
||||
/* Levenshtein's parameters, for string comparison */
|
||||
options->dolevdist = 1; // By default attempt to correct typos
|
||||
@@ -63,14 +65,15 @@ void init_options(struct ccx_s_options *options)
|
||||
options->xmltvonlycurrent = 0; // 0 off 1 on
|
||||
options->keep_output_closed = 0; // By default just keep the file open.
|
||||
options->force_flush = 0; // Don't flush whenever content is written.
|
||||
options->append_mode = 0; //By default, files are overwritten.
|
||||
options->append_mode = 0; // By default, files are overwritten.
|
||||
options->ucla = 0; // By default, -UCLA not used
|
||||
options->tickertext = 0; // By default, do not assume ticker style text
|
||||
options->hardsubx = 0; // By default, don't try to extract hard subtitles
|
||||
options->dvblang = NULL; // By default, autodetect DVB language
|
||||
options->ocrlang = NULL; // By default, autodetect .traineddata file
|
||||
options->ocr_oem = -1; // By default, OEM mode depends on the tesseract version
|
||||
options->ocr_quantmode = 1; // CCExtractor's internal
|
||||
options->psm = 3; // Default PSM mode (3 is the default tesseract as well)
|
||||
options->ocr_quantmode = 0; // No quantization (better OCR accuracy for DVB subtitles)
|
||||
options->mkvlang = NULL; // By default, all the languages are extracted
|
||||
options->ignore_pts_jumps = 1;
|
||||
options->analyze_video_stream = 0;
|
||||
@@ -83,6 +86,7 @@ void init_options(struct ccx_s_options *options)
|
||||
options->hardsubx_conf_thresh = 0.0;
|
||||
options->hardsubx_hue = 0.0;
|
||||
options->hardsubx_lum_thresh = 95.0;
|
||||
options->hardsubx_and_common = 0;
|
||||
|
||||
options->transcript_settings = ccx_encoders_default_transcript_settings;
|
||||
options->millis_separator = ',';
|
||||
@@ -131,32 +135,23 @@ 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;
|
||||
options->settings_dtvcc.print_file_reports = 1;
|
||||
options->settings_dtvcc.no_rollup = 0;
|
||||
options->settings_dtvcc.report = NULL;
|
||||
options->settings_dtvcc.timing = NULL;
|
||||
memset(
|
||||
options->settings_dtvcc.services_enabled, 0,
|
||||
CCX_DTVCC_MAX_SERVICES * sizeof(options->settings_dtvcc.services_enabled[0]));
|
||||
|
||||
#ifdef ENABLE_SHARING
|
||||
options->sharing_enabled = 0;
|
||||
options->sharing_url = NULL;
|
||||
options->translate_enabled = 0;
|
||||
options->translate_key = NULL;
|
||||
options->translate_langs = NULL;
|
||||
#endif //ENABLE_SHARING
|
||||
#ifdef WITH_LIBCURL
|
||||
options->curlposturl = NULL;
|
||||
#endif
|
||||
|
||||
@@ -15,39 +15,38 @@ struct demuxer_cfg
|
||||
enum ccx_code_type codec;
|
||||
enum ccx_code_type nocodec;
|
||||
|
||||
unsigned ts_autoprogram; // Try to find a stream with captions automatically (no -pn needed)
|
||||
unsigned ts_autoprogram; // Try to find a stream with captions automatically (no -pn needed)
|
||||
unsigned ts_allprogram;
|
||||
unsigned ts_cappids[128]; // PID for stream that holds caption information
|
||||
unsigned ts_cappids[128]; // PID for stream that holds caption information
|
||||
int nb_ts_cappid;
|
||||
unsigned ts_forced_cappid ; // If 1, never mess with the selected PID
|
||||
int ts_forced_program; // Specific program to process in TS files, if ts_forced_program_selected==1
|
||||
unsigned ts_forced_cappid; // If 1, never mess with the selected PID
|
||||
int ts_forced_program; // Specific program to process in TS files, if ts_forced_program_selected==1
|
||||
unsigned ts_forced_program_selected;
|
||||
int ts_datastreamtype ; // User WANTED stream type (i.e. use the stream that has this type)
|
||||
int ts_datastreamtype; // User WANTED stream type (i.e. use the stream that has this type)
|
||||
unsigned ts_forced_streamtype; // User selected (forced) stream type
|
||||
};
|
||||
|
||||
struct encoder_cfg
|
||||
{
|
||||
int extract; // Extract 1st, 2nd or both fields
|
||||
int dtvcc_extract; // 1 or 0
|
||||
int gui_mode_reports; // If 1, output in stderr progress updates so the GUI can grab them
|
||||
int extract; // Extract 1st, 2nd or both fields
|
||||
int dtvcc_extract; // 1 or 0
|
||||
int gui_mode_reports; // If 1, output in stderr progress updates so the GUI can grab them
|
||||
char *output_filename;
|
||||
enum ccx_output_format write_format; // 0=Raw, 1=srt, 2=SMI
|
||||
int keep_output_closed;
|
||||
int force_flush; // Force flush on content write
|
||||
int append_mode; // Append mode for output files
|
||||
int ucla; // 1 if -UCLA used, 0 if not
|
||||
int no_timestamp_map; // 1 if timestamps disabled for WebVTT
|
||||
int force_flush; // Force flush on content write
|
||||
int append_mode; // Append mode for output files
|
||||
int ucla; // 1 if -UCLA used, 0 if not
|
||||
|
||||
enum ccx_encoding_type encoding;
|
||||
enum ccx_output_date_format date_format;
|
||||
char millis_separator;
|
||||
int autodash; // Add dashes (-) before each speaker automatically?
|
||||
int trim_subs; // " Remove spaces at sides? "
|
||||
int autodash; // Add dashes (-) before each speaker automatically?
|
||||
int trim_subs; // " Remove spaces at sides? "
|
||||
int sentence_cap; // FIX CASE? = Fix case?
|
||||
int splitbysentence; // Split text into complete sentences and prorate time?
|
||||
#ifdef WITH_LIBCURL
|
||||
char *curlposturl; // If out=curl, where do we send the data to?
|
||||
char *curlposturl; // If out=curl, where do we send the data to?
|
||||
#endif
|
||||
int filter_profanity; // Censors profane words from subtitles
|
||||
|
||||
@@ -55,44 +54,45 @@ struct encoder_cfg
|
||||
/* Credit stuff */
|
||||
char *start_credits_text;
|
||||
char *end_credits_text;
|
||||
struct ccx_boundary_time startcreditsnotbefore, startcreditsnotafter; // Where to insert start credits, if possible
|
||||
struct ccx_boundary_time startcreditsnotbefore, startcreditsnotafter; // Where to insert start credits, if possible
|
||||
struct ccx_boundary_time startcreditsforatleast, startcreditsforatmost; // How long to display them?
|
||||
struct ccx_boundary_time endcreditsforatleast, endcreditsforatmost;
|
||||
|
||||
ccx_encoders_transcript_format transcript_settings; // Keeps the settings for generating transcript output files.
|
||||
unsigned int send_to_srv;
|
||||
int no_bom; // Set to 1 when no BOM (Byte Order Mark) should be used for files. Note, this might make files unreadable in windows!
|
||||
int no_bom; // Set to 1 when no BOM (Byte Order Mark) should be used for files. Note, this might make files unreadable in windows!
|
||||
char *first_input_file;
|
||||
int multiple_files;
|
||||
int no_font_color;
|
||||
int no_type_setting;
|
||||
int cc_to_stdout; // If this is set to 1, the stdout will be flushed when data was written to the screen during a process_608 call.
|
||||
int line_terminator_lf; // 0 = CRLF, 1=LF
|
||||
LLONG subs_delay; // ms to delay (or advance) subs
|
||||
int cc_to_stdout; // If this is set to 1, the stdout will be flushed when data was written to the screen during a process_608 call.
|
||||
int line_terminator_lf; // 0 = CRLF, 1=LF
|
||||
LLONG subs_delay; // ms to delay (or advance) subs
|
||||
int program_number;
|
||||
unsigned char in_format;
|
||||
int nospupngocr; // 1 if we don't want to OCR bitmaps to add the text as comments in the XML file in spupng
|
||||
int nospupngocr; // 1 if we don't want to OCR bitmaps to add the text as comments in the XML file in spupng
|
||||
|
||||
// MCC File
|
||||
int force_dropframe; // 1 if dropframe frame count should be used. defaults to no drop frame.
|
||||
|
||||
int force_dropframe; // 1 if dropframe frame count should be used. defaults to no drop frame.
|
||||
|
||||
// text -> png (text render)
|
||||
char *render_font; // The font used to render text if needed (e.g. teletext->spupng)
|
||||
char *render_font; // The font used to render text if needed (e.g. teletext->spupng)
|
||||
char *render_font_italics;
|
||||
|
||||
//CEA-708
|
||||
// CEA-708
|
||||
int services_enabled[CCX_DTVCC_MAX_SERVICES];
|
||||
char** services_charsets;
|
||||
char* all_services_charset;
|
||||
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
|
||||
{
|
||||
int extract; // Extract 1st, 2nd or both fields
|
||||
int no_rollup; // Disable roll-up emulation (no duplicate output in generated file)
|
||||
int extract; // Extract 1st, 2nd or both fields
|
||||
int no_rollup; // Disable roll-up emulation (no duplicate output in generated file)
|
||||
int noscte20;
|
||||
int webvtt_create_css;
|
||||
int cc_channel; // Channel we want to dump in srt mode
|
||||
int cc_channel; // Channel we want to dump in srt mode
|
||||
int buffer_input;
|
||||
int nofontcolor;
|
||||
int nohtmlescape;
|
||||
@@ -100,53 +100,57 @@ struct ccx_s_options // Options from user parameters
|
||||
struct ccx_boundary_time extraction_start, extraction_end; // Segment we actually process
|
||||
int print_file_reports;
|
||||
|
||||
ccx_decoder_608_settings settings_608; // Contains the settings for the 608 decoder.
|
||||
ccx_decoder_dtvcc_settings settings_dtvcc; // Same for 708 decoder
|
||||
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
|
||||
int use_gop_as_pts; // Use GOP instead of PTS timing (0=do as needed, 1=always, -1=never)
|
||||
int fix_padding; // Replace 0000 with 8080 in HDTV (needed for some cards)
|
||||
int gui_mode_reports; // If 1, output in stderr progress updates so the GUI can grab them
|
||||
int no_progress_bar; // If 1, suppress the output of the progress to stdout
|
||||
char *sentence_cap_file; // Extra capitalization word file
|
||||
int live_stream; /* -1 -> Not a complete file but a live stream, without timeout
|
||||
0 -> A regular file
|
||||
>0 -> Live stream with a timeout of this value in seconds */
|
||||
char *filter_profanity_file; // Extra profanity word file
|
||||
int messages_target; // 0 = nowhere (quiet), 1=stdout, 2=stderr
|
||||
int no_timestamp_map; // 1 for no timestamps for WebVTT, 0 for the timestamp header
|
||||
int binary_concat; // Disabled by -ve or --videoedited
|
||||
int use_gop_as_pts; // Use GOP instead of PTS timing (0=do as needed, 1=always, -1=never)
|
||||
int fix_padding; // Replace 0000 with 8080 in HDTV (needed for some cards)
|
||||
int gui_mode_reports; // If 1, output in stderr progress updates so the GUI can grab them
|
||||
int no_progress_bar; // If 1, suppress the output of the progress to stdout
|
||||
char *sentence_cap_file; // Extra capitalization word file
|
||||
int live_stream; /* -1 -> Not a complete file but a live stream, without timeout
|
||||
0 -> A regular file
|
||||
>0 -> Live stream with a timeout of this value in seconds */
|
||||
char *filter_profanity_file; // Extra profanity word file
|
||||
int messages_target; // 0 = nowhere (quiet), 1=stdout, 2=stderr
|
||||
int timestamp_map; // If 1, add WebVTT X-TIMESTAMP-MAP header
|
||||
/* Levenshtein's parameters, for string comparison */
|
||||
int dolevdist; // 0 => don't attempt to correct typos with this algorithm
|
||||
int dolevdist; // 0 => don't attempt to correct typos with this algorithm
|
||||
int levdistmincnt, levdistmaxpct; // Means 2 fails or less is "the same", 10% or less is also "the same"
|
||||
int investigate_packets; // Look for captions in all packets when everything else fails
|
||||
int fullbin; // Disable pruning of padding cc blocks
|
||||
int nosync; // Disable syncing
|
||||
unsigned int hauppauge_mode; // If 1, use PID=1003, process specially and so on
|
||||
int wtvconvertfix; // Fix broken Windows 7 conversion
|
||||
int investigate_packets; // Look for captions in all packets when everything else fails
|
||||
int fullbin; // Disable pruning of padding cc blocks
|
||||
int nosync; // Disable syncing
|
||||
unsigned int hauppauge_mode; // If 1, use PID=1003, process specially and so on
|
||||
int wtvconvertfix; // Fix broken Windows 7 conversion
|
||||
int wtvmpeg2;
|
||||
int auto_myth; // Use myth-tv mpeg code? 0=no, 1=yes, 2=auto
|
||||
int auto_myth; // Use myth-tv mpeg code? 0=no, 1=yes, 2=auto
|
||||
/* MP4 related stuff */
|
||||
unsigned mp4vidtrack; // Process the video track even if a CC dedicated track exists.
|
||||
int extract_chapters; // If 1, extracts chapters (if present), from MP4 files.
|
||||
unsigned mp4vidtrack; // Process the video track even if a CC dedicated track exists.
|
||||
int extract_chapters; // If 1, extracts chapters (if present), from MP4 files.
|
||||
/* General settings */
|
||||
int usepicorder; // Force the use of pic_order_cnt_lsb in AVC/H.264 data streams
|
||||
int xmltv; // 1 = full output. 2 = live output. 3 = both
|
||||
int xmltvliveinterval; // interval in seconds between writing xmltv output files in live mode
|
||||
int xmltvoutputinterval; // interval in seconds between writing xmltv full file output
|
||||
int xmltvonlycurrent; // 0 off 1 on
|
||||
int usepicorder; // Force the use of pic_order_cnt_lsb in AVC/H.264 data streams
|
||||
int xmltv; // 1 = full output. 2 = live output. 3 = both
|
||||
int xmltvliveinterval; // interval in seconds between writing xmltv output files in live mode
|
||||
int xmltvoutputinterval; // interval in seconds between writing xmltv full file output
|
||||
int xmltvonlycurrent; // 0 off 1 on
|
||||
int keep_output_closed;
|
||||
int force_flush; // Force flush on content write
|
||||
int append_mode; // Append mode for output files
|
||||
int ucla; // 1 if UCLA used, 0 if not
|
||||
int tickertext; // 1 if ticker text style burned in subs, 0 if not
|
||||
int hardsubx; // 1 if burned-in subtitles to be extracted
|
||||
char *dvblang; // The name of the language stream for DVB
|
||||
const char *ocrlang; // The name of the .traineddata file to be loaded with tesseract
|
||||
int ocr_oem; // The Tesseract OEM mode, could be 0 (default), 1 or 2
|
||||
int ocr_quantmode; // How to quantize the bitmap before passing to to tesseract (0=no quantization at all, 1=CCExtractor's internal)
|
||||
char *mkvlang; // The name of the language stream for MKV
|
||||
int analyze_video_stream; // If 1, the video stream will be processed even if we're using a different one for subtitles.
|
||||
int force_flush; // Force flush on content write
|
||||
int append_mode; // Append mode for output files
|
||||
int ucla; // 1 if UCLA used, 0 if not
|
||||
int tickertext; // 1 if ticker text style burned in subs, 0 if not
|
||||
int hardsubx; // 1 if burned-in subtitles to be extracted
|
||||
int hardsubx_and_common; // 1 if both burned-in and not burned in need to be extracted
|
||||
char *dvblang; // The name of the language stream for DVB
|
||||
const char *ocrlang; // The name of the .traineddata file to be loaded with tesseract
|
||||
int ocr_oem; // The Tesseract OEM mode, could be 0 (default), 1 or 2
|
||||
int psm; // The Tesseract PSM mode, could be between 0 and 13. 3 is tesseract default
|
||||
int ocr_quantmode; // How to quantize the bitmap before passing to to tesseract (0=no quantization at all, 1=CCExtractor's internal)
|
||||
char *mkvlang; // The name of the language stream for MKV
|
||||
int analyze_video_stream; // If 1, the video stream will be processed even if we're using a different one for subtitles.
|
||||
|
||||
/*HardsubX related stuff*/
|
||||
int hardsubx_ocr_mode;
|
||||
@@ -160,53 +164,42 @@ struct ccx_s_options // Options from user parameters
|
||||
ccx_encoders_transcript_format transcript_settings; // Keeps the settings for generating transcript output files.
|
||||
enum ccx_output_date_format date_format;
|
||||
unsigned send_to_srv;
|
||||
enum ccx_output_format write_format; // 0=Raw, 1=srt, 2=SMI
|
||||
enum ccx_output_format write_format; // 0=Raw, 1=srt, 2=SMI
|
||||
int write_format_rewritten;
|
||||
int use_ass_instead_of_ssa;
|
||||
int use_webvtt_styling;
|
||||
LLONG debug_mask; // dbg_print will use this mask to print or ignore different types
|
||||
LLONG debug_mask_on_debug; // If we're using temp_debug to enable/disable debug "live", this is the mask when temp_debug=1
|
||||
LLONG debug_mask; // dbg_print will use this mask to print or ignore different types
|
||||
LLONG debug_mask_on_debug; // If we're using temp_debug to enable/disable debug "live", this is the mask when temp_debug=1
|
||||
/* Networking */
|
||||
char *udpsrc;
|
||||
char *udpaddr;
|
||||
unsigned udpport; // Non-zero => Listen for UDP packets on this port, no files.
|
||||
unsigned udpport; // Non-zero => Listen for UDP packets on this port, no files.
|
||||
char *tcpport;
|
||||
char *tcp_password;
|
||||
char *tcp_desc;
|
||||
char *srv_addr;
|
||||
char *srv_port;
|
||||
int noautotimeref; // Do NOT set time automatically?
|
||||
enum ccx_datasource input_source; // Files, stdin or network
|
||||
int noautotimeref; // Do NOT set time automatically?
|
||||
enum ccx_datasource input_source; // Files, stdin or network
|
||||
|
||||
char *output_filename;
|
||||
|
||||
char **inputfile; // List of files to process
|
||||
int num_input_files; // How many?
|
||||
char **inputfile; // List of files to process
|
||||
int num_input_files; // How many?
|
||||
struct demuxer_cfg demux_cfg;
|
||||
struct encoder_cfg enc_cfg;
|
||||
LLONG subs_delay; // ms to delay (or advance) subs
|
||||
int cc_to_stdout; // If this is set to 1, the stdout will be flushed when data was written to the screen during a process_608 call.
|
||||
int pes_header_to_stdout; // If this is set to 1, the PES Header will be printed to console (debugging purposes)
|
||||
int ignore_pts_jumps; // If 1, the program will ignore PTS jumps. Sometimes this parameter is required for DVB subs with > 30s pause time
|
||||
LLONG subs_delay; // ms to delay (or advance) subs
|
||||
int cc_to_stdout; // If this is set to 1, the stdout will be flushed when data was written to the screen during a process_608 call.
|
||||
int pes_header_to_stdout; // If this is set to 1, the PES Header will be printed to console (debugging purposes)
|
||||
int ignore_pts_jumps; // If 1, the program will ignore PTS jumps. Sometimes this parameter is required for DVB subs with > 30s pause time
|
||||
int multiprogram;
|
||||
int out_interval;
|
||||
int segment_on_key_frames_only;
|
||||
#ifdef WITH_LIBCURL
|
||||
char *curlposturl;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef ENABLE_SHARING
|
||||
//CC sharing
|
||||
int sharing_enabled;
|
||||
char *sharing_url;
|
||||
//Translating
|
||||
int translate_enabled;
|
||||
char *translate_langs;
|
||||
char *translate_key;
|
||||
#endif
|
||||
};
|
||||
|
||||
extern struct ccx_s_options ccx_options;
|
||||
void init_options (struct ccx_s_options *options);
|
||||
void init_options(struct ccx_s_options *options);
|
||||
#endif
|
||||
|
||||
@@ -1,119 +1,122 @@
|
||||
#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"
|
||||
#undef UINT64_MAX
|
||||
#define UINT64_MAX _UI64_MAX
|
||||
typedef int socklen_t;
|
||||
#if !defined(__MINGW64__) && !defined(__MINGW32__)
|
||||
typedef int ssize_t;
|
||||
#endif
|
||||
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
|
||||
|
||||
@@ -3,26 +3,28 @@
|
||||
|
||||
#include "ccx_common_constants.h"
|
||||
|
||||
enum ccx_common_logging_gui {
|
||||
CCX_COMMON_LOGGING_GUI_XDS_PROGRAM_NAME, // Called with xds_program_name
|
||||
CCX_COMMON_LOGGING_GUI_XDS_PROGRAM_ID_NR, // Called with current_xds_min, current_xds_hour, current_xds_date, current_xds_month
|
||||
enum ccx_common_logging_gui
|
||||
{
|
||||
CCX_COMMON_LOGGING_GUI_XDS_PROGRAM_NAME, // Called with xds_program_name
|
||||
CCX_COMMON_LOGGING_GUI_XDS_PROGRAM_ID_NR, // Called with current_xds_min, current_xds_hour, current_xds_date, current_xds_month
|
||||
CCX_COMMON_LOGGING_GUI_XDS_PROGRAM_DESCRIPTION, // Called with line_num, xds_desc
|
||||
CCX_COMMON_LOGGING_GUI_XDS_CALL_LETTERS // Called with current_xds_call_letters
|
||||
CCX_COMMON_LOGGING_GUI_XDS_CALL_LETTERS // Called with current_xds_call_letters
|
||||
};
|
||||
|
||||
struct ccx_common_logging_t {
|
||||
LLONG debug_mask; // The debug mask that is used to determine if things should be printed or not.
|
||||
void(*fatal_ftn) (int exit_code, const char *fmt, ...); // Used when an unrecoverable error happens. This should log output/save the error and then exit the program.
|
||||
void(*debug_ftn) (LLONG mask, const char *fmt, ...); // Used to process debug output. Mask can be ignored (custom set by debug_mask).
|
||||
void(*log_ftn)(const char *fmt, ...); // Used to print things. Replacement of standard printf, to allow more control.
|
||||
void(*gui_ftn)(enum ccx_common_logging_gui message_type, ...); // Used to display things in a gui (if appropriate). Is called with the message_type and appropriate variables (described in enum)
|
||||
struct ccx_common_logging_t
|
||||
{
|
||||
LLONG debug_mask; // The debug mask that is used to determine if things should be printed or not.
|
||||
void (*fatal_ftn)(int exit_code, const char *fmt, ...); // Used when an unrecoverable error happens. This should log output/save the error and then exit the program.
|
||||
void (*debug_ftn)(LLONG mask, const char *fmt, ...); // Used to process debug output. Mask can be ignored (custom set by debug_mask).
|
||||
void (*log_ftn)(const char *fmt, ...); // Used to print things. Replacement of standard printf, to allow more control.
|
||||
void (*gui_ftn)(enum ccx_common_logging_gui message_type, ...); // Used to display things in a gui (if appropriate). Is called with the message_type and appropriate variables (described in enum)
|
||||
};
|
||||
extern struct ccx_common_logging_t ccx_common_logging;
|
||||
|
||||
enum subdatatype
|
||||
{
|
||||
CC_DATATYPE_GENERIC=0,
|
||||
CC_DATATYPE_DVB=1
|
||||
CC_DATATYPE_GENERIC = 0,
|
||||
CC_DATATYPE_DVB = 1
|
||||
};
|
||||
|
||||
enum subtype
|
||||
@@ -34,18 +36,18 @@ enum subtype
|
||||
};
|
||||
|
||||
/**
|
||||
* Raw Subtitle struct used as output of decoder (cc608)
|
||||
* and input for encoder (sami, srt, transcript or smptett etc)
|
||||
*
|
||||
* if subtype CC_BITMAP then data contain nb_data numbers of rectangle
|
||||
* which have to be displayed at same time.
|
||||
*/
|
||||
* Raw Subtitle struct used as output of decoder (cc608)
|
||||
* and input for encoder (sami, srt, transcript or smptett etc)
|
||||
*
|
||||
* if subtype CC_BITMAP then data contain nb_data numbers of rectangle
|
||||
* which have to be displayed at same time.
|
||||
*/
|
||||
struct cc_subtitle
|
||||
{
|
||||
/**
|
||||
* A generic data which contain data according to decoder
|
||||
* @warn decoder cant output multiple types of data
|
||||
*/
|
||||
* A generic data which contain data according to decoder
|
||||
* @warn decoder cant output multiple types of data
|
||||
*/
|
||||
void *data;
|
||||
enum subdatatype datatype;
|
||||
|
||||
@@ -56,11 +58,11 @@ struct cc_subtitle
|
||||
enum subtype type;
|
||||
|
||||
/** Encoding type of Text, must be ignored in case of subtype as bitmap or cc_screen*/
|
||||
enum ccx_encoding_type enc_type;
|
||||
enum ccx_encoding_type enc_type;
|
||||
|
||||
/* set only when all the data is to be displayed at same time
|
||||
* Unit is of time is ms
|
||||
*/
|
||||
* Unit is of time is ms
|
||||
*/
|
||||
LLONG start_time;
|
||||
LLONG end_time;
|
||||
|
||||
@@ -72,13 +74,19 @@ struct cc_subtitle
|
||||
|
||||
/** flag to tell that decoder has given output */
|
||||
int got_output;
|
||||
|
||||
|
||||
char mode[5];
|
||||
char info[4];
|
||||
|
||||
/** Used for DVB end time in ms */
|
||||
int time_out;
|
||||
|
||||
/** Raw PTS value when this subtitle started (for DVB timing) */
|
||||
LLONG start_pts;
|
||||
|
||||
/** Teletext page number (for multi-page extraction, issue #665) */
|
||||
uint16_t teletext_page;
|
||||
|
||||
struct cc_subtitle *next;
|
||||
struct cc_subtitle *prev;
|
||||
};
|
||||
|
||||
@@ -30,6 +30,18 @@ int gop_rollover = 0;
|
||||
|
||||
struct ccx_common_timing_settings_t ccx_common_timing_settings;
|
||||
|
||||
void ccxr_add_current_pts(struct ccx_common_timing_ctx *ctx, LLONG pts);
|
||||
void ccxr_set_current_pts(struct ccx_common_timing_ctx *ctx, LLONG pts);
|
||||
int ccxr_set_fts(struct ccx_common_timing_ctx *ctx);
|
||||
LLONG ccxr_get_fts(struct ccx_common_timing_ctx *ctx, int current_field);
|
||||
LLONG ccxr_get_fts_max(struct ccx_common_timing_ctx *ctx);
|
||||
LLONG ccxr_get_visible_start(struct ccx_common_timing_ctx *ctx, int current_field);
|
||||
LLONG ccxr_get_visible_end(struct ccx_common_timing_ctx *ctx, int current_field);
|
||||
char *ccxr_print_mstime_static(LLONG mstime, char *buf);
|
||||
void ccxr_print_debug_timing(struct ccx_common_timing_ctx *ctx);
|
||||
void ccxr_calculate_ms_gop_time(struct gop_time_code *g);
|
||||
int ccxr_gop_accepted(struct gop_time_code *g);
|
||||
|
||||
void ccx_common_timing_init(LLONG *file_position, int no_sync)
|
||||
{
|
||||
ccx_common_timing_settings.disable_sync_check = 0;
|
||||
@@ -53,6 +65,9 @@ struct ccx_common_timing_ctx *init_timing_ctx(struct ccx_common_timing_settings_
|
||||
ctx->current_pts = 0;
|
||||
ctx->current_picture_coding_type = CCX_FRAME_TYPE_RESET_OR_UNKNOWN;
|
||||
ctx->min_pts_adjusted = 0;
|
||||
ctx->seen_known_frame_type = 0;
|
||||
ctx->pending_min_pts = 0x01FFFFFFFFLL;
|
||||
ctx->unknown_frame_count = 0;
|
||||
ctx->min_pts = 0x01FFFFFFFFLL; // 33 bit
|
||||
ctx->max_pts = 0;
|
||||
ctx->sync_pts = 0;
|
||||
@@ -73,236 +88,71 @@ struct ccx_common_timing_ctx *init_timing_ctx(struct ccx_common_timing_settings_
|
||||
|
||||
void add_current_pts(struct ccx_common_timing_ctx *ctx, LLONG pts)
|
||||
{
|
||||
set_current_pts(ctx, ctx->current_pts + pts);
|
||||
return ccxr_add_current_pts(ctx, pts);
|
||||
}
|
||||
|
||||
void set_current_pts(struct ccx_common_timing_ctx *ctx, LLONG pts)
|
||||
{
|
||||
LLONG prev_pts = ctx->current_pts;
|
||||
ctx->current_pts = pts;
|
||||
if (ctx->pts_set == 0)
|
||||
ctx->pts_set = 1;
|
||||
dbg_print(CCX_DMT_VIDES, "PTS: %s (%8u)", print_mstime_static(ctx->current_pts / (MPEG_CLOCK_FREQ / 1000)),
|
||||
(unsigned)(ctx->current_pts));
|
||||
dbg_print(CCX_DMT_VIDES, " FTS: %s \n", print_mstime_static(ctx->fts_now));
|
||||
|
||||
// Check if PTS reset
|
||||
if (ctx->current_pts < prev_pts)
|
||||
{
|
||||
ctx->pts_reset = 1;
|
||||
}
|
||||
return ccxr_set_current_pts(ctx, pts);
|
||||
}
|
||||
|
||||
int set_fts(struct ccx_common_timing_ctx *ctx)
|
||||
{
|
||||
int pts_jump = 0;
|
||||
|
||||
// ES don't have PTS unless GOP timing is used
|
||||
if (!ctx->pts_set && ccx_common_timing_settings.is_elementary_stream)
|
||||
return CCX_OK;
|
||||
|
||||
// First check for timeline jump (only when min_pts was set (implies sync_pts)).
|
||||
int dif = 0;
|
||||
if (ctx->pts_set == 2)
|
||||
{
|
||||
dif = (int)(ctx->current_pts - ctx->sync_pts) / MPEG_CLOCK_FREQ;
|
||||
|
||||
if (ccx_common_timing_settings.disable_sync_check)
|
||||
{
|
||||
// Disables sync check. Used for several input formats.
|
||||
dif = 0;
|
||||
}
|
||||
|
||||
if (dif < -0.2 || dif >= max_dif)
|
||||
{
|
||||
// ATSC specs: More than 3501 ms means missing component
|
||||
ccx_common_logging.log_ftn("\nWarning: Reference clock has changed abruptly (%d seconds filepos=%lld), attempting to synchronize\n", (int)dif, *ccx_common_timing_settings.file_position);
|
||||
ccx_common_logging.log_ftn("Last sync PTS value: %lld\n", ctx->sync_pts);
|
||||
ccx_common_logging.log_ftn("Current PTS value: %lld\n", ctx->current_pts);
|
||||
ccx_common_logging.log_ftn("Note: You can disable this behavior by adding -ignoreptsjumps to the parameters.\n");
|
||||
pts_jump = 1;
|
||||
pts_big_change = 1;
|
||||
|
||||
// Discard the gap if it is not on an I-frame or temporal reference zero.
|
||||
if (ctx->current_tref != 0 && ctx->current_picture_coding_type != CCX_FRAME_TYPE_I_FRAME)
|
||||
{
|
||||
ctx->fts_now = ctx->fts_max;
|
||||
ccx_common_logging.log_ftn("Change did not occur on first frame - probably a broken GOP\n");
|
||||
return CCX_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If min_pts was set just before a rollover we compensate by "roll-oving" it too
|
||||
if (ctx->pts_set == 2 && !ctx->min_pts_adjusted) // min_pts set
|
||||
{
|
||||
// We want to be aware of the upcoming rollover, not after it happened, so we don't take
|
||||
// the 3 most significant bits but the 3 next ones
|
||||
uint64_t min_pts_big_bits = (ctx->min_pts >> 30) & 7;
|
||||
uint64_t cur_pts_big_bits = (ctx->current_pts >> 30) & 7;
|
||||
if (cur_pts_big_bits == 7 && !min_pts_big_bits)
|
||||
{
|
||||
// Huge difference possibly means the first min_pts was actually just over the boundary
|
||||
// Take the current_pts (smaller, accounting for the rollover) instead
|
||||
ctx->min_pts = ctx->current_pts;
|
||||
ctx->min_pts_adjusted = 1;
|
||||
}
|
||||
else if (cur_pts_big_bits >= 1 && cur_pts_big_bits <= 6) // Far enough from the boundary
|
||||
{
|
||||
// Prevent the eventual difference with min_pts to make a bad adjustment
|
||||
ctx->min_pts_adjusted = 1;
|
||||
}
|
||||
}
|
||||
// Set min_pts, fts_offset
|
||||
if (ctx->pts_set != 0)
|
||||
{
|
||||
ctx->pts_set = 2;
|
||||
|
||||
// Use this part only the first time min_pts is set. Later treat
|
||||
// it as a reference clock change
|
||||
if (ctx->current_pts < ctx->min_pts && !pts_jump)
|
||||
{
|
||||
// If this is the first GOP, and seq 0 was not encountered yet
|
||||
// we might reset min_pts/fts_offset again
|
||||
|
||||
ctx->min_pts = ctx->current_pts;
|
||||
|
||||
// Avoid next async test
|
||||
ctx->sync_pts = (LLONG)(ctx->current_pts - ctx->current_tref * 1000.0 / current_fps * (MPEG_CLOCK_FREQ / 1000));
|
||||
|
||||
if (ctx->current_tref == 0)
|
||||
{ // Earliest time in GOP.
|
||||
ctx->fts_offset = 0;
|
||||
}
|
||||
else if (total_frames_count - frames_since_ref_time == 0)
|
||||
{ // If this is the first frame (PES) there cannot be an offset.
|
||||
// This part is also reached for dvr-ms/NTSC (RAW) as
|
||||
// total_frames_count = frames_since_ref_time = 0 when
|
||||
// this is called for the first time.
|
||||
ctx->fts_offset = 0;
|
||||
}
|
||||
else
|
||||
{ // It needs to be "+1" because the current frame is
|
||||
// not yet counted.
|
||||
ctx->fts_offset = (LLONG)((total_frames_count - frames_since_ref_time + 1) * 1000.0 / current_fps);
|
||||
}
|
||||
ccx_common_logging.debug_ftn(CCX_DMT_TIME, "\nFirst sync time PTS: %s %+lldms (time before this PTS)\n",
|
||||
print_mstime_static(ctx->min_pts / (MPEG_CLOCK_FREQ / 1000)),
|
||||
ctx->fts_offset);
|
||||
ccx_common_logging.debug_ftn(CCX_DMT_TIME, "Total_frames_count %u frames_since_ref_time %u\n",
|
||||
total_frames_count, frames_since_ref_time);
|
||||
}
|
||||
|
||||
// -nosync disables syncing
|
||||
if (pts_jump && !ccx_common_timing_settings.no_sync)
|
||||
{
|
||||
// The current time in the old time base is calculated using
|
||||
// sync_pts (set at the beginning of the last GOP) plus the
|
||||
// time of the frames since then.
|
||||
ctx->fts_offset = ctx->fts_offset + (ctx->sync_pts - ctx->min_pts) / (MPEG_CLOCK_FREQ / 1000) + (LLONG)(frames_since_ref_time * 1000 / current_fps);
|
||||
ctx->fts_max = ctx->fts_offset;
|
||||
|
||||
// Start counting again from here
|
||||
ctx->pts_set = 1; // Force min to be set again
|
||||
ctx->sync_pts2fts_set = 0; // Make note of the new conversion values
|
||||
|
||||
// Avoid next async test - the gap might have occured on
|
||||
// current_tref != 0.
|
||||
ctx->sync_pts = (LLONG)(ctx->current_pts - ctx->current_tref * 1000.0 / current_fps * (MPEG_CLOCK_FREQ / 1000));
|
||||
// Set min_pts = sync_pts as this is used for fts_now
|
||||
ctx->min_pts = ctx->sync_pts;
|
||||
|
||||
ccx_common_logging.debug_ftn(CCX_DMT_TIME, "\nNew min PTS time: %s %+lldms (time before this PTS)\n",
|
||||
print_mstime_static(ctx->min_pts / (MPEG_CLOCK_FREQ / 1000)),
|
||||
ctx->fts_offset);
|
||||
}
|
||||
}
|
||||
|
||||
// Set sync_pts, fts_offset
|
||||
if (ctx->current_tref == 0)
|
||||
ctx->sync_pts = ctx->current_pts;
|
||||
|
||||
// Reset counters
|
||||
cb_field1 = 0;
|
||||
cb_field2 = 0;
|
||||
cb_708 = 0;
|
||||
|
||||
// Avoid wrong "Calc. difference" and "Asynchronous by" numbers
|
||||
// for uninitialized min_pts
|
||||
if (1) // CFS: Remove or think decent condition
|
||||
{
|
||||
if (ctx->pts_set)
|
||||
{
|
||||
// If pts_set is TRUE we have min_pts
|
||||
ctx->fts_now = (LLONG)((ctx->current_pts - ctx->min_pts) / (MPEG_CLOCK_FREQ / 1000) + ctx->fts_offset);
|
||||
if (!ctx->sync_pts2fts_set)
|
||||
{
|
||||
ctx->sync_pts2fts_pts = ctx->current_pts;
|
||||
ctx->sync_pts2fts_fts = ctx->fts_now;
|
||||
ctx->sync_pts2fts_set = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// No PTS info at all!!
|
||||
ccx_common_logging.log_ftn("Set PTS called without any global timestamp set\n");
|
||||
return CCX_EINVAL;
|
||||
}
|
||||
}
|
||||
if (ctx->fts_now > ctx->fts_max)
|
||||
{
|
||||
ctx->fts_max = ctx->fts_now;
|
||||
}
|
||||
|
||||
// If PTS resets, then fix minimum_fts and fts_max
|
||||
if (ctx->pts_reset)
|
||||
{
|
||||
ctx->minimum_fts = 0;
|
||||
ctx->fts_max = ctx->fts_now;
|
||||
ctx->pts_reset = 0;
|
||||
}
|
||||
return CCX_OK;
|
||||
return ccxr_set_fts(ctx);
|
||||
}
|
||||
|
||||
LLONG get_fts(struct ccx_common_timing_ctx *ctx, int current_field)
|
||||
{
|
||||
LLONG fts;
|
||||
|
||||
switch (current_field)
|
||||
{
|
||||
case 1:
|
||||
fts = ctx->fts_now + ctx->fts_global + cb_field1 * 1001 / 30;
|
||||
break;
|
||||
case 2:
|
||||
fts = ctx->fts_now + ctx->fts_global + cb_field2 * 1001 / 30;
|
||||
break;
|
||||
case 3:
|
||||
fts = ctx->fts_now + ctx->fts_global + cb_708 * 1001 / 30;
|
||||
break;
|
||||
default:
|
||||
fatal(CCX_COMMON_EXIT_BUG_BUG, "get_fts: unhandled branch");
|
||||
}
|
||||
// ccx_common_logging.debug_ftn(CCX_DMT_TIME, "[FTS] "
|
||||
// "fts: %llu, fts_now: %llu, fts_global: %llu, current_field: %llu, cb_708: %llu\n",
|
||||
// fts, fts_now, fts_global, current_field, cb_708);
|
||||
return fts;
|
||||
return ccxr_get_fts(ctx, current_field);
|
||||
}
|
||||
|
||||
LLONG get_fts_max(struct ccx_common_timing_ctx *ctx)
|
||||
{
|
||||
// This returns the maximum FTS that belonged to a frame. Caption block
|
||||
// counters are not applicable.
|
||||
return ctx->fts_max + ctx->fts_global;
|
||||
return ccxr_get_fts_max(ctx);
|
||||
}
|
||||
|
||||
/**
|
||||
* SCC Time formatting
|
||||
* Note: buf must have at least 32 bytes available from the write position
|
||||
*/
|
||||
size_t print_scc_time(struct ccx_boundary_time time, char *buf)
|
||||
{
|
||||
char *fmt = "%02u:%02u:%02u;%02u";
|
||||
double frame;
|
||||
// Format produces "HH:MM:SS;FF" = 11 chars + null, use 32 for safety
|
||||
const size_t max_time_len = 32;
|
||||
|
||||
frame = ((double)(time.time_in_ms - 1000 * (time.ss + 60 * (time.mm + 60 * time.hh))) * 29.97 / 1000);
|
||||
|
||||
return (size_t)snprintf(buf + time.set, max_time_len, fmt, time.hh, time.mm, time.ss, (unsigned)frame);
|
||||
}
|
||||
|
||||
struct ccx_boundary_time get_time(LLONG time)
|
||||
{
|
||||
if (time < 0) // Avoid loss of data warning with abs()
|
||||
time = -time;
|
||||
|
||||
struct ccx_boundary_time result;
|
||||
result.hh = (unsigned)(time / 1000 / 60 / 60);
|
||||
result.mm = (unsigned)(time / 1000 / 60 - 60 * result.hh);
|
||||
result.ss = (unsigned)(time / 1000 - 60 * (result.mm + 60 * result.hh));
|
||||
result.time_in_ms = time;
|
||||
result.set = (time < 0 ? 1 : 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill buffer with a time string using specified format
|
||||
* @param fmt has to contain 4 format specifiers for h, m, s and ms respectively
|
||||
* Note: buf must have at least 32 bytes available from the write position
|
||||
*/
|
||||
size_t print_mstime_buff(LLONG mstime, char *fmt, char *buf)
|
||||
{
|
||||
unsigned hh, mm, ss, ms;
|
||||
int signoffset = (mstime < 0 ? 1 : 0);
|
||||
// Typical format produces "HH:MM:SS:MSS" = 12 chars + null, use 32 for safety
|
||||
const size_t max_time_len = 32;
|
||||
|
||||
if (mstime < 0) // Avoid loss of data warning with abs()
|
||||
mstime = -mstime;
|
||||
@@ -314,7 +164,7 @@ size_t print_mstime_buff(LLONG mstime, char *fmt, char *buf)
|
||||
|
||||
buf[0] = '-';
|
||||
|
||||
return (size_t)sprintf(buf + signoffset, fmt, hh, mm, ss, ms);
|
||||
return (size_t)snprintf(buf + signoffset, max_time_len, fmt, hh, mm, ss, ms);
|
||||
}
|
||||
|
||||
/* Fill a static buffer with a time string (hh:mm:ss:ms) corresponding
|
||||
@@ -322,63 +172,21 @@ size_t print_mstime_buff(LLONG mstime, char *fmt, char *buf)
|
||||
char *print_mstime_static(LLONG mstime)
|
||||
{
|
||||
static char buf[15]; // 14 should be long enough
|
||||
print_mstime_buff(mstime, "%02u:%02u:%02u:%03u", buf);
|
||||
return buf;
|
||||
return ccxr_print_mstime_static(mstime, buf);
|
||||
}
|
||||
|
||||
/* Helper function for to display debug timing info. */
|
||||
void print_debug_timing(struct ccx_common_timing_ctx *ctx)
|
||||
{
|
||||
// Avoid wrong "Calc. difference" and "Asynchronous by" numbers
|
||||
// for uninitialized min_pts
|
||||
LLONG tempmin_pts = (ctx->min_pts == 0x01FFFFFFFFLL ? ctx->sync_pts : ctx->min_pts);
|
||||
|
||||
ccx_common_logging.log_ftn("Sync time stamps: PTS: %s ",
|
||||
print_mstime_static((ctx->sync_pts) / (MPEG_CLOCK_FREQ / 1000)));
|
||||
ccx_common_logging.log_ftn("GOP: %s \n", print_mstime_static(gop_time.ms));
|
||||
|
||||
// Length first GOP to last GOP
|
||||
LLONG goplenms = (LLONG)(gop_time.ms - first_gop_time.ms);
|
||||
// Length at last sync point
|
||||
LLONG ptslenms = (unsigned)((ctx->sync_pts - tempmin_pts) / (MPEG_CLOCK_FREQ / 1000) + ctx->fts_offset);
|
||||
|
||||
ccx_common_logging.log_ftn("Last FTS: %s",
|
||||
print_mstime_static(get_fts_max(ctx)));
|
||||
ccx_common_logging.log_ftn(" GOP start FTS: %s\n",
|
||||
print_mstime_static(fts_at_gop_start));
|
||||
|
||||
// Times are based on last GOP and/or sync time
|
||||
ccx_common_logging.log_ftn("Max FTS diff. to PTS: %6lldms GOP: %6lldms\n\n",
|
||||
get_fts_max(ctx) + (LLONG)(1000.0 / current_fps) - ptslenms,
|
||||
get_fts_max(ctx) + (LLONG)(1000.0 / current_fps) - goplenms);
|
||||
return ccxr_print_debug_timing(ctx);
|
||||
}
|
||||
|
||||
void calculate_ms_gop_time(struct gop_time_code *g)
|
||||
{
|
||||
int seconds = (g->time_code_hours * 3600) + (g->time_code_minutes * 60) + g->time_code_seconds;
|
||||
g->ms = (LLONG)(1000 * (seconds + g->time_code_pictures / current_fps));
|
||||
if (gop_rollover)
|
||||
g->ms += 24 * 60 * 60 * 1000;
|
||||
return ccxr_calculate_ms_gop_time(g);
|
||||
}
|
||||
|
||||
int gop_accepted(struct gop_time_code *g)
|
||||
{
|
||||
if (!((g->time_code_hours <= 23) && (g->time_code_minutes <= 59) && (g->time_code_seconds <= 59) && (g->time_code_pictures <= 59)))
|
||||
return 0;
|
||||
|
||||
if (gop_time.time_code_hours == 23 && gop_time.time_code_minutes == 59 &&
|
||||
g->time_code_hours == 0 && g->time_code_minutes == 0)
|
||||
{
|
||||
gop_rollover = 1;
|
||||
return 1;
|
||||
}
|
||||
if (gop_time.inited)
|
||||
{
|
||||
if (gop_time.ms > g->ms)
|
||||
{
|
||||
// We are going back in time but it's not a complete day rollover
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
return ccxr_gop_accepted(g);
|
||||
}
|
||||
|
||||
@@ -17,40 +17,43 @@ struct gop_time_code
|
||||
|
||||
struct ccx_common_timing_settings_t
|
||||
{
|
||||
int disable_sync_check; // If 1, timeline jumps will be ignored. This is important in several input formats that are assumed to have correct timing, no matter what.
|
||||
int no_sync; // If 1, there will be no sync at all. Mostly useful for debugging.
|
||||
int disable_sync_check; // If 1, timeline jumps will be ignored. This is important in several input formats that are assumed to have correct timing, no matter what.
|
||||
int no_sync; // If 1, there will be no sync at all. Mostly useful for debugging.
|
||||
int is_elementary_stream; // Needs to be set, as it's used in set_fts.
|
||||
LLONG *file_position; // The position of the file
|
||||
LLONG *file_position; // The position of the file
|
||||
};
|
||||
extern struct ccx_common_timing_settings_t ccx_common_timing_settings;
|
||||
|
||||
struct ccx_boundary_time
|
||||
{
|
||||
int hh,mm,ss;
|
||||
int hh, mm, ss;
|
||||
LLONG time_in_ms;
|
||||
int set;
|
||||
};
|
||||
|
||||
struct ccx_common_timing_ctx
|
||||
{
|
||||
int pts_set; // 0 = No, 1 = received, 2 = min_pts set
|
||||
int min_pts_adjusted; // 0 = No, 1=Yes (don't adjust again)
|
||||
int pts_set; // 0 = No, 1 = received, 2 = min_pts set
|
||||
int min_pts_adjusted; // 0 = No, 1=Yes (don't adjust again)
|
||||
int seen_known_frame_type; // 0 = No, 1 = Yes. Tracks if we've seen a frame with known type
|
||||
LLONG pending_min_pts; // Minimum PTS seen while waiting for frame type determination
|
||||
unsigned int unknown_frame_count; // Count of set_fts calls with unknown frame type
|
||||
LLONG current_pts;
|
||||
enum ccx_frame_type current_picture_coding_type;
|
||||
int current_tref; // Store temporal reference of current frame
|
||||
int current_tref; // Store temporal reference of current frame
|
||||
LLONG min_pts;
|
||||
LLONG max_pts;
|
||||
LLONG sync_pts;
|
||||
LLONG minimum_fts; // No screen should start before this FTS
|
||||
LLONG fts_now; // Time stamp of current file (w/ fts_offset, w/o fts_global)
|
||||
LLONG fts_now; // Time stamp of current file (w/ fts_offset, w/o fts_global)
|
||||
LLONG fts_offset; // Time before first sync_pts
|
||||
LLONG fts_fc_offset; // Time before first GOP
|
||||
LLONG fts_max; // Remember the maximum fts that we saw in current file
|
||||
LLONG fts_max; // Remember the maximum fts that we saw in current file
|
||||
LLONG fts_global; // Duration of previous files (-ve mode)
|
||||
int sync_pts2fts_set; // 0 = No, 1 = Yes
|
||||
LLONG sync_pts2fts_fts;
|
||||
LLONG sync_pts2fts_pts;
|
||||
int pts_reset; // 0 = No, 1 = Yes. PTS resets when current_pts is lower than prev
|
||||
int pts_reset; // 0 = No, 1 = Yes. PTS resets when current_pts is lower than prev
|
||||
};
|
||||
// Count 608 (per field) and 708 blocks since last set_fts() call
|
||||
extern int cb_field1, cb_field2, cb_708;
|
||||
@@ -60,7 +63,6 @@ extern int MPEG_CLOCK_FREQ; // This is part of the standard
|
||||
extern int max_dif;
|
||||
extern unsigned pts_big_change;
|
||||
|
||||
|
||||
extern enum ccx_frame_type current_picture_coding_type;
|
||||
extern double current_fps;
|
||||
extern int frames_since_ref_time;
|
||||
@@ -77,13 +79,15 @@ struct ccx_common_timing_ctx *init_timing_ctx(struct ccx_common_timing_settings_
|
||||
|
||||
void set_current_pts(struct ccx_common_timing_ctx *ctx, LLONG pts);
|
||||
void add_current_pts(struct ccx_common_timing_ctx *ctx, LLONG pts);
|
||||
struct ccx_boundary_time get_time(LLONG mstime);
|
||||
size_t print_scc_time(struct ccx_boundary_time time, char *buf);
|
||||
int set_fts(struct ccx_common_timing_ctx *ctx);
|
||||
LLONG get_fts(struct ccx_common_timing_ctx *ctx, int current_field);
|
||||
LLONG get_fts_max(struct ccx_common_timing_ctx *ctx);
|
||||
char *print_mstime_static(LLONG mstime);
|
||||
size_t print_mstime_buff(LLONG mstime, char *fmt, char *buf);
|
||||
void print_debug_timing(struct ccx_common_timing_ctx *ctx);
|
||||
int gop_accepted(struct gop_time_code* g);
|
||||
int gop_accepted(struct gop_time_code *g);
|
||||
void calculate_ms_gop_time(struct gop_time_code *g);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -10,7 +10,7 @@ static const int rowdata[] = {11, -1, 1, 2, 3, 4, 12, 13, 14, 15, 5, 6, 7, 8, 9,
|
||||
// Relationship between the first PAC byte and the row number
|
||||
int in_xds_mode = 0;
|
||||
|
||||
//unsigned char str[2048]; // Another generic general purpose buffer
|
||||
// unsigned char str[2048]; // Another generic general purpose buffer
|
||||
|
||||
const unsigned char pac2_attribs[][3] = // Color, font, ident
|
||||
{
|
||||
@@ -127,6 +127,8 @@ ccx_decoder_608_context *ccx_decoder_608_init_library(struct ccx_decoder_608_set
|
||||
ccx_decoder_608_context *data = NULL;
|
||||
|
||||
data = malloc(sizeof(ccx_decoder_608_context));
|
||||
if (!data)
|
||||
return NULL;
|
||||
|
||||
data->cursor_column = 0;
|
||||
data->cursor_row = 0;
|
||||
@@ -147,10 +149,11 @@ ccx_decoder_608_context *ccx_decoder_608_init_library(struct ccx_decoder_608_set
|
||||
data->my_field = field;
|
||||
data->my_channel = channel;
|
||||
data->have_cursor_position = 0;
|
||||
data->rollup_from_popon = 0;
|
||||
data->output_format = output_format;
|
||||
data->cc_to_stdout = cc_to_stdout;
|
||||
data->textprinted = 0;
|
||||
data->ts_start_of_current_line = 0;
|
||||
// Note: ts_start_of_current_line already set to -1 above
|
||||
|
||||
data->halt = halt;
|
||||
|
||||
@@ -225,7 +228,9 @@ void write_char(const unsigned char c, ccx_decoder_608_context *context)
|
||||
|
||||
if (use_buffer->empty)
|
||||
{
|
||||
if (MODE_POPON != context->mode)
|
||||
// Don't set start time if we're in a transition from pop-on to roll-up
|
||||
// In this case, start time will be set when CR causes scrolling
|
||||
if (MODE_POPON != context->mode && !context->rollup_from_popon)
|
||||
context->current_visible_start_ms = get_visible_start(context->timing, context->my_field);
|
||||
}
|
||||
use_buffer->empty = 0;
|
||||
@@ -263,7 +268,7 @@ void handle_text_attr(const unsigned char c1, const unsigned char c2, ccx_decode
|
||||
font_text[context->font]);
|
||||
// Mid-row codes should put a non-transparent space at the current position
|
||||
// and advance the cursor
|
||||
//so use write_char
|
||||
// so use write_char
|
||||
write_char(0x20, context);
|
||||
}
|
||||
}
|
||||
@@ -311,12 +316,13 @@ int write_cc_buffer(ccx_decoder_608_context *context, struct cc_subtitle *sub)
|
||||
|
||||
if (!data->empty && context->output_format != CCX_OF_NULL)
|
||||
{
|
||||
sub->data = (struct eia608_screen *)realloc(sub->data, (sub->nb_data + 1) * sizeof(*data));
|
||||
if (!sub->data)
|
||||
struct eia608_screen *new_data = (struct eia608_screen *)realloc(sub->data, (sub->nb_data + 1) * sizeof(*data));
|
||||
if (!new_data)
|
||||
{
|
||||
ccx_common_logging.log_ftn("No Memory left");
|
||||
return 0;
|
||||
}
|
||||
sub->data = new_data;
|
||||
sub->datatype = CC_DATATYPE_GENERIC;
|
||||
memcpy(((struct eia608_screen *)sub->data) + sub->nb_data, data, sizeof(*data));
|
||||
sub->nb_data++;
|
||||
@@ -380,12 +386,13 @@ int write_cc_line(ccx_decoder_608_context *context, struct cc_subtitle *sub)
|
||||
|
||||
if (!data->empty)
|
||||
{
|
||||
sub->data = (struct eia608_screen *)realloc(sub->data, (sub->nb_data + 1) * sizeof(*data));
|
||||
if (!sub->data)
|
||||
struct eia608_screen *new_data = (struct eia608_screen *)realloc(sub->data, (sub->nb_data + 1) * sizeof(*data));
|
||||
if (!new_data)
|
||||
{
|
||||
ccx_common_logging.log_ftn("No Memory left");
|
||||
return 0;
|
||||
}
|
||||
sub->data = new_data;
|
||||
memcpy(((struct eia608_screen *)sub->data) + sub->nb_data, data, sizeof(*data));
|
||||
data = (struct eia608_screen *)sub->data + sub->nb_data;
|
||||
sub->datatype = CC_DATATYPE_GENERIC;
|
||||
@@ -720,6 +727,10 @@ void handle_command(unsigned char c1, const unsigned char c2, ccx_decoder_608_co
|
||||
if (write_cc_buffer(context, sub))
|
||||
context->screenfuls_counter++;
|
||||
erase_memory(context, true);
|
||||
// Track transition from pop-on/paint-on to roll-up for timing adjustment
|
||||
// Start time will be set when CR causes scrolling (matching FFmpeg behavior)
|
||||
context->rollup_from_popon = 1;
|
||||
context->ts_start_of_current_line = -1;
|
||||
}
|
||||
erase_memory(context, false);
|
||||
|
||||
@@ -772,6 +783,15 @@ void handle_command(unsigned char c1, const unsigned char c2, ccx_decoder_608_co
|
||||
changes = check_roll_up(context);
|
||||
if (changes)
|
||||
{
|
||||
// Handle pop-on to roll-up transition timing
|
||||
// Use ts_start_of_current_line (when current line started) as the start time
|
||||
// This matches FFmpeg's behavior of timestamping when the display changed
|
||||
if (context->rollup_from_popon && context->ts_start_of_current_line > 0)
|
||||
{
|
||||
context->current_visible_start_ms = context->ts_start_of_current_line;
|
||||
context->rollup_from_popon = 0;
|
||||
}
|
||||
|
||||
// Only if the roll up would actually cause a line to disappear we write the buffer
|
||||
if (context->output_format != CCX_OF_TRANSCRIPT)
|
||||
{
|
||||
@@ -781,8 +801,18 @@ void handle_command(unsigned char c1, const unsigned char c2, ccx_decoder_608_co
|
||||
erase_memory(context, true); // Make sure the lines we just wrote aren't written again
|
||||
}
|
||||
}
|
||||
roll_up(context); // The roll must be done anyway of course.
|
||||
context->ts_start_of_current_line = -1; // Unknown.
|
||||
roll_up(context); // The roll must be done anyway of course.
|
||||
// When in pop-on to roll-up transition with changes=0 (first CR, only 1 line),
|
||||
// preserve the CR time so the next caption uses the display state change time,
|
||||
// not the character typing time. This matches FFmpeg's timing behavior.
|
||||
if (context->rollup_from_popon && !changes)
|
||||
{
|
||||
context->ts_start_of_current_line = get_fts(context->timing, context->my_field);
|
||||
}
|
||||
else
|
||||
{
|
||||
context->ts_start_of_current_line = -1; // Unknown.
|
||||
}
|
||||
if (changes)
|
||||
context->current_visible_start_ms = get_visible_start(context->timing, context->my_field);
|
||||
context->cursor_column = 0;
|
||||
@@ -836,8 +866,8 @@ void handle_command(unsigned char c1, const unsigned char c2, ccx_decoder_608_co
|
||||
break;
|
||||
case COM_RESUMEDIRECTCAPTIONING:
|
||||
context->mode = MODE_PAINTON;
|
||||
//ccx_common_logging.log_ftn ("\nWarning: Received ResumeDirectCaptioning, this mode is almost impossible.\n");
|
||||
//ccx_common_logging.log_ftn ("to transcribe to a text file.\n");
|
||||
// ccx_common_logging.log_ftn ("\nWarning: Received ResumeDirectCaptioning, this mode is almost impossible.\n");
|
||||
// ccx_common_logging.log_ftn ("to transcribe to a text file.\n");
|
||||
break;
|
||||
default:
|
||||
ccx_common_logging.debug_ftn(CCX_DMT_DECODER_608, "\rNot yet implemented.\n");
|
||||
@@ -1029,20 +1059,20 @@ int check_channel(unsigned char c1, ccx_decoder_608_context *context)
|
||||
}
|
||||
|
||||
/* Handle Command, special char or attribute and also check for
|
||||
* channel changes.
|
||||
* Returns 1 if something was written to screen, 0 otherwise */
|
||||
* channel changes.
|
||||
* Returns 1 if something was written to screen, 0 otherwise */
|
||||
int disCommand(unsigned char hi, unsigned char lo, ccx_decoder_608_context *context, struct cc_subtitle *sub)
|
||||
{
|
||||
int wrote_to_screen = 0;
|
||||
|
||||
/* Full channel changes are only allowed for "GLOBAL CODES",
|
||||
* "OTHER POSITIONING CODES", "BACKGROUND COLOR CODES",
|
||||
* "MID-ROW CODES".
|
||||
* "PREAMBLE ACCESS CODES", "BACKGROUND COLOR CODES" and
|
||||
* SPECIAL/SPECIAL CHARACTERS allow only switching
|
||||
* between 1&3 or 2&4. */
|
||||
* "OTHER POSITIONING CODES", "BACKGROUND COLOR CODES",
|
||||
* "MID-ROW CODES".
|
||||
* "PREAMBLE ACCESS CODES", "BACKGROUND COLOR CODES" and
|
||||
* SPECIAL/SPECIAL CHARACTERS allow only switching
|
||||
* between 1&3 or 2&4. */
|
||||
context->new_channel = check_channel(hi, context);
|
||||
//if (wb->data608->channel!=cc_channel)
|
||||
// if (wb->data608->channel!=cc_channel)
|
||||
// continue;
|
||||
|
||||
if (hi >= 0x18 && hi <= 0x1f)
|
||||
@@ -1105,17 +1135,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)
|
||||
{
|
||||
@@ -1240,9 +1274,9 @@ int process608(const unsigned char *data, int length, void *private_data, struct
|
||||
if (!context->textprinted && context->channel == context->my_channel)
|
||||
{ // Current FTS information after the characters are shown
|
||||
ccx_common_logging.debug_ftn(CCX_DMT_DECODER_608, "Current FTS: %s\n", print_mstime_static(get_fts(dec_ctx->timing, context->my_field)));
|
||||
//printf(" N:%u", unsigned(fts_now) );
|
||||
//printf(" G:%u", unsigned(fts_global) );
|
||||
//printf(" F:%d %d %d %d\n",
|
||||
// printf(" N:%u", unsigned(fts_now) );
|
||||
// printf(" G:%u", unsigned(fts_global) );
|
||||
// printf(" F:%d %d %d %d\n",
|
||||
// current_field, cb_field1, cb_field2, cb_708 );
|
||||
}
|
||||
|
||||
@@ -1284,7 +1318,7 @@ unsigned char *debug_608_to_ASC(unsigned char *cc_data, int channel)
|
||||
if (hi >= 0x20)
|
||||
{
|
||||
output[0] = hi;
|
||||
output[1] = (lo >= 20 ? lo : '.');
|
||||
output[1] = (lo >= 0x20 ? lo : '.');
|
||||
output[2] = '\x00';
|
||||
}
|
||||
else
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef CCX_DECODER_608_H
|
||||
#define CCX_DECODER_608_H
|
||||
#define CCX_DECODER_608_H
|
||||
#include "ccx_common_platform.h"
|
||||
#include "ccx_common_structs.h"
|
||||
#include "ccx_decoders_structs.h"
|
||||
@@ -19,11 +19,11 @@ struct ccx_decoder_608_report
|
||||
|
||||
typedef struct ccx_decoder_608_settings
|
||||
{
|
||||
int direct_rollup; // Write roll-up captions directly instead of line by line?
|
||||
int force_rollup; // 0=Disabled, 1, 2 or 3=max lines in roll-up mode
|
||||
int no_rollup; // If 1, write one line at a time
|
||||
int direct_rollup; // Write roll-up captions directly instead of line by line?
|
||||
int force_rollup; // 0=Disabled, 1, 2 or 3=max lines in roll-up mode
|
||||
int no_rollup; // If 1, write one line at a time
|
||||
enum ccx_decoder_608_color_code default_color; // Default color to use.
|
||||
int screens_to_process; // How many screenfuls we want? Use -1 for unlimited
|
||||
int screens_to_process; // How many screenfuls we want? Use -1 for unlimited
|
||||
struct ccx_decoder_608_report *report;
|
||||
} ccx_decoder_608_settings;
|
||||
|
||||
@@ -34,33 +34,33 @@ typedef struct ccx_decoder_608_context
|
||||
struct eia608_screen buffer2;
|
||||
int cursor_row, cursor_column;
|
||||
int visible_buffer;
|
||||
int screenfuls_counter; // Number of meaningful screenfuls written
|
||||
int screenfuls_counter; // Number of meaningful screenfuls written
|
||||
LLONG current_visible_start_ms; // At what time did the current visible buffer became so?
|
||||
enum cc_modes mode;
|
||||
unsigned char last_c1, last_c2;
|
||||
int channel; // Currently selected channel
|
||||
enum ccx_decoder_608_color_code current_color; // Color we are currently using to write
|
||||
enum font_bits font; // Font we are currently using to write
|
||||
int channel; // Currently selected channel
|
||||
enum ccx_decoder_608_color_code current_color; // Color we are currently using to write
|
||||
enum font_bits font; // Font we are currently using to write
|
||||
int rollup_base_row;
|
||||
LLONG ts_start_of_current_line; /* Time at which the first character for current line was received, =-1 no character received yet */
|
||||
LLONG ts_last_char_received; /* Time at which the last written character was received, =-1 no character received yet */
|
||||
int new_channel; // The new channel after a channel change
|
||||
int my_field; // Used for sanity checks
|
||||
int my_channel; // Used for sanity checks
|
||||
long bytes_processed_608; // To be written ONLY by process_608
|
||||
LLONG ts_last_char_received; /* Time at which the last written character was received, =-1 no character received yet */
|
||||
int new_channel; // The new channel after a channel change
|
||||
int my_field; // Used for sanity checks
|
||||
int my_channel; // Used for sanity checks
|
||||
int rollup_from_popon; // Track transition from pop-on/paint-on to roll-up mode
|
||||
int64_t bytes_processed_608; // To be written ONLY by process_608
|
||||
int have_cursor_position;
|
||||
|
||||
int *halt; // Can be used to halt the feeding of caption data. Set to 1 if screens_to_progress != -1 && screenfuls_counter >= screens_to_process
|
||||
int cc_to_stdout; // If this is set to 1, the stdout will be flushed when data was written to the screen during a process_608 call.
|
||||
int *halt; // Can be used to halt the feeding of caption data. Set to 1 if screens_to_progress != -1 && screenfuls_counter >= screens_to_process
|
||||
int cc_to_stdout; // If this is set to 1, the stdout will be flushed when data was written to the screen during a process_608 call.
|
||||
struct ccx_decoder_608_report *report;
|
||||
LLONG subs_delay; // ms to delay (or advance) subs
|
||||
LLONG subs_delay; // ms to delay (or advance) subs
|
||||
enum ccx_output_format output_format; // What kind of output format should be used?
|
||||
int textprinted;
|
||||
struct ccx_common_timing_ctx *timing;
|
||||
|
||||
} ccx_decoder_608_context;
|
||||
|
||||
|
||||
#define MAX_COLOR 10
|
||||
extern const char *color_text[MAX_COLOR][2];
|
||||
|
||||
@@ -80,7 +80,7 @@ enum command_code
|
||||
COM_ERASENONDISPLAYEDMEMORY = 11,
|
||||
COM_BACKSPACE = 12,
|
||||
COM_RESUMETEXTDISPLAY = 13,
|
||||
COM_ALARMOFF =14,
|
||||
COM_ALARMOFF = 14,
|
||||
COM_ALARMON = 15,
|
||||
COM_DELETETOENDOFROW = 16,
|
||||
COM_RESUMEDIRECTCAPTIONING = 17,
|
||||
@@ -89,15 +89,14 @@ enum command_code
|
||||
COM_FAKE_RULLUP1 = 18
|
||||
};
|
||||
|
||||
|
||||
void ccx_decoder_608_dinit_library(void **ctx);
|
||||
/*
|
||||
*
|
||||
*/
|
||||
ccx_decoder_608_context* ccx_decoder_608_init_library(struct ccx_decoder_608_settings *settings, int channel,
|
||||
int field, int *halt,
|
||||
int cc_to_stdout,
|
||||
enum ccx_output_format output_format, struct ccx_common_timing_ctx *timing);
|
||||
ccx_decoder_608_context *ccx_decoder_608_init_library(struct ccx_decoder_608_settings *settings, int channel,
|
||||
int field, int *halt,
|
||||
int cc_to_stdout,
|
||||
enum ccx_output_format output_format, struct ccx_common_timing_ctx *timing);
|
||||
|
||||
/**
|
||||
* @param data raw cc608 data to be processed
|
||||
|
||||
@@ -104,7 +104,7 @@ dtvcc_pen_attribs dtvcc_default_pen_attribs =
|
||||
dtvcc_window_attribs dtvcc_predefined_window_styles[] =
|
||||
{
|
||||
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // Dummy, unused (position 0 doesn't use the table)
|
||||
{ //1 - NTSC Style PopUp Captions
|
||||
{ // 1 - NTSC Style PopUp Captions
|
||||
DTVCC_WINDOW_JUSTIFY_LEFT,
|
||||
DTVCC_WINDOW_PD_LEFT_RIGHT,
|
||||
DTVCC_WINDOW_SD_BOTTOM_TOP,
|
||||
@@ -116,7 +116,7 @@ dtvcc_window_attribs dtvcc_predefined_window_styles[] =
|
||||
DTVCC_WINDOW_FO_SOLID,
|
||||
DTVCC_WINDOW_BORDER_NONE,
|
||||
0},
|
||||
{//2 - PopUp Captions w/o Black Background
|
||||
{// 2 - PopUp Captions w/o Black Background
|
||||
DTVCC_WINDOW_JUSTIFY_LEFT,
|
||||
DTVCC_WINDOW_PD_LEFT_RIGHT,
|
||||
DTVCC_WINDOW_SD_BOTTOM_TOP,
|
||||
@@ -128,7 +128,7 @@ dtvcc_window_attribs dtvcc_predefined_window_styles[] =
|
||||
DTVCC_WINDOW_FO_TRANSPARENT,
|
||||
DTVCC_WINDOW_BORDER_NONE,
|
||||
0},
|
||||
{//3 - NTSC Style Centered PopUp Captions
|
||||
{// 3 - NTSC Style Centered PopUp Captions
|
||||
DTVCC_WINDOW_JUSTIFY_CENTER,
|
||||
DTVCC_WINDOW_PD_LEFT_RIGHT,
|
||||
DTVCC_WINDOW_SD_BOTTOM_TOP,
|
||||
@@ -140,7 +140,7 @@ dtvcc_window_attribs dtvcc_predefined_window_styles[] =
|
||||
DTVCC_WINDOW_FO_SOLID,
|
||||
DTVCC_WINDOW_BORDER_NONE,
|
||||
0},
|
||||
{//4 - NTSC Style RollUp Captions
|
||||
{// 4 - NTSC Style RollUp Captions
|
||||
DTVCC_WINDOW_JUSTIFY_LEFT,
|
||||
DTVCC_WINDOW_PD_LEFT_RIGHT,
|
||||
DTVCC_WINDOW_SD_BOTTOM_TOP,
|
||||
@@ -152,7 +152,7 @@ dtvcc_window_attribs dtvcc_predefined_window_styles[] =
|
||||
DTVCC_WINDOW_FO_SOLID,
|
||||
DTVCC_WINDOW_BORDER_NONE,
|
||||
0},
|
||||
{//5 - RollUp Captions w/o Black Background
|
||||
{// 5 - RollUp Captions w/o Black Background
|
||||
DTVCC_WINDOW_JUSTIFY_LEFT,
|
||||
DTVCC_WINDOW_PD_LEFT_RIGHT,
|
||||
DTVCC_WINDOW_SD_BOTTOM_TOP,
|
||||
@@ -164,7 +164,7 @@ dtvcc_window_attribs dtvcc_predefined_window_styles[] =
|
||||
DTVCC_WINDOW_FO_TRANSPARENT,
|
||||
DTVCC_WINDOW_BORDER_NONE,
|
||||
0},
|
||||
{//6 - NTSC Style Centered RollUp Captions
|
||||
{// 6 - NTSC Style Centered RollUp Captions
|
||||
DTVCC_WINDOW_JUSTIFY_CENTER,
|
||||
DTVCC_WINDOW_PD_LEFT_RIGHT,
|
||||
DTVCC_WINDOW_SD_BOTTOM_TOP,
|
||||
@@ -176,7 +176,7 @@ dtvcc_window_attribs dtvcc_predefined_window_styles[] =
|
||||
DTVCC_WINDOW_FO_SOLID,
|
||||
DTVCC_WINDOW_BORDER_NONE,
|
||||
0},
|
||||
{//7 - Ticker tape
|
||||
{// 7 - Ticker tape
|
||||
DTVCC_WINDOW_JUSTIFY_LEFT,
|
||||
DTVCC_WINDOW_PD_TOP_BOTTOM,
|
||||
DTVCC_WINDOW_SD_RIGHT_LEFT,
|
||||
@@ -240,7 +240,7 @@ void dtvcc_window_clear_text(dtvcc_window *window)
|
||||
void dtvcc_window_clear(dtvcc_service_decoder *decoder, int window_id)
|
||||
{
|
||||
dtvcc_window_clear_text(&decoder->windows[window_id]);
|
||||
//OPT fill window with a window fill color
|
||||
// OPT fill window with a window fill color
|
||||
}
|
||||
|
||||
void dtvcc_window_apply_style(dtvcc_window *window, dtvcc_window_attribs *style)
|
||||
@@ -258,7 +258,7 @@ void dtvcc_window_apply_style(dtvcc_window *window, dtvcc_window_attribs *style)
|
||||
window->attribs.word_wrap = style->word_wrap;
|
||||
}
|
||||
|
||||
//#define DTVCC_PRINT_DEBUG
|
||||
// #define DTVCC_PRINT_DEBUG
|
||||
#ifdef DTVCC_PRINT_DEBUG
|
||||
|
||||
int dtvcc_is_win_row_empty(dtvcc_window *window, int row_index)
|
||||
@@ -503,7 +503,7 @@ int dtvcc_is_window_overlapping(dtvcc_service_decoder *decoder, dtvcc_window *wi
|
||||
{
|
||||
flag = OVERLAPPING_WITH_HIGH_PRIORITY;
|
||||
}
|
||||
//priority is either higher or equals for *window , hence overlaps decoder->windows[i]
|
||||
// priority is either higher or equals for *window , hence overlaps decoder->windows[i]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -608,16 +608,16 @@ void dtvcc_window_copy_to_screen(dtvcc_service_decoder *decoder, dtvcc_window *w
|
||||
|
||||
void dtvcc_screen_print(dtvcc_ctx *dtvcc, dtvcc_service_decoder *decoder)
|
||||
{
|
||||
//TODO use priorities to solve windows overlap (with a video sample, please)
|
||||
//qsort(wnd, visible, sizeof(dtvcc_window *), dtvcc_compare_win_priorities);
|
||||
// TODO use priorities to solve windows overlap (with a video sample, please)
|
||||
// qsort(wnd, visible, sizeof(dtvcc_window *), dtvcc_compare_win_priorities);
|
||||
|
||||
ccx_common_logging.debug_ftn(CCX_DMT_708, "[CEA-708] dtvcc_screen_print\n");
|
||||
|
||||
dtvcc_screen_update_time_hide(decoder->tv, get_visible_end(dtvcc->timing, 3));
|
||||
|
||||
#ifdef DTVCC_PRINT_DEBUG
|
||||
//ccx_common_logging.debug_ftn(CCX_DMT_GENERIC_NOTICES, "[CEA-708] TV dump:\n");
|
||||
//dtvcc_write_debug(decoder->tv);
|
||||
// ccx_common_logging.debug_ftn(CCX_DMT_GENERIC_NOTICES, "[CEA-708] TV dump:\n");
|
||||
// dtvcc_write_debug(decoder->tv);
|
||||
#endif
|
||||
decoder->cc_count++;
|
||||
decoder->tv->cc_count++;
|
||||
@@ -653,14 +653,14 @@ void dtvcc_process_ff(dtvcc_service_decoder *decoder)
|
||||
dtvcc_window *window = &decoder->windows[decoder->current_window];
|
||||
window->pen_column = 0;
|
||||
window->pen_row = 0;
|
||||
//CEA-708-D doesn't say we have to clear neither window text nor text line,
|
||||
//but it seems we have to clean the line
|
||||
//dtvcc_window_clear_text(window);
|
||||
// CEA-708-D doesn't say we have to clear neither window text nor text line,
|
||||
// but it seems we have to clean the line
|
||||
// dtvcc_window_clear_text(window);
|
||||
}
|
||||
|
||||
void dtvcc_process_etx(dtvcc_service_decoder *decoder)
|
||||
{
|
||||
//it can help decoders with screen output, but could it help us?
|
||||
// it can help decoders with screen output, but could it help us?
|
||||
}
|
||||
|
||||
void dtvcc_process_bs(dtvcc_service_decoder *decoder)
|
||||
@@ -671,8 +671,8 @@ void dtvcc_process_bs(dtvcc_service_decoder *decoder)
|
||||
return;
|
||||
}
|
||||
|
||||
//it looks strange, but in some videos (rarely) we have a backspace command
|
||||
//we just print one character over another
|
||||
// it looks strange, but in some videos (rarely) we have a backspace command
|
||||
// we just print one character over another
|
||||
int cw = decoder->current_window;
|
||||
dtvcc_window *window = &decoder->windows[cw];
|
||||
|
||||
@@ -764,14 +764,12 @@ void dtvcc_process_cr(dtvcc_ctx *dtvcc, dtvcc_service_decoder *decoder)
|
||||
|
||||
if (window->is_defined)
|
||||
{
|
||||
ccx_common_logging.debug_ftn(CCX_DMT_708, "[CEA-708] dtvcc_process_cr: rolling up\n");
|
||||
|
||||
dtvcc_window_update_time_hide(window, dtvcc->timing);
|
||||
dtvcc_window_copy_to_screen(decoder, window);
|
||||
dtvcc_screen_print(dtvcc, decoder);
|
||||
|
||||
if (rollup_required)
|
||||
{
|
||||
ccx_common_logging.debug_ftn(CCX_DMT_708, "[CEA-708] dtvcc_process_cr: rolling up\n");
|
||||
dtvcc_window_copy_to_screen(decoder, window);
|
||||
dtvcc_screen_print(dtvcc, decoder);
|
||||
if (dtvcc->no_rollup)
|
||||
dtvcc_window_clear_row(window, window->pen_row);
|
||||
else
|
||||
@@ -826,27 +824,6 @@ void dtvcc_process_character(dtvcc_service_decoder *decoder, dtvcc_symbol symbol
|
||||
}
|
||||
}
|
||||
|
||||
void dtvcc_decoder_flush(dtvcc_ctx *dtvcc, dtvcc_service_decoder *decoder)
|
||||
{
|
||||
ccx_common_logging.debug_ftn(
|
||||
CCX_DMT_708, "[CEA-708] dtvcc_decoder_flush: Flushing decoder\n");
|
||||
int screen_content_changed = 0;
|
||||
for (int i = 0; i < CCX_DTVCC_MAX_WINDOWS; i++)
|
||||
{
|
||||
dtvcc_window *window = &decoder->windows[i];
|
||||
if (window->visible)
|
||||
{
|
||||
screen_content_changed = 1;
|
||||
dtvcc_window_update_time_hide(window, dtvcc->timing);
|
||||
dtvcc_window_copy_to_screen(decoder, window);
|
||||
window->visible = 0;
|
||||
}
|
||||
}
|
||||
if (screen_content_changed)
|
||||
dtvcc_screen_print(dtvcc, decoder);
|
||||
dtvcc_write_done(decoder->tv, dtvcc->encoder);
|
||||
}
|
||||
|
||||
//---------------------------------- COMMANDS ------------------------------------
|
||||
|
||||
void dtvcc_handle_CWx_SetCurrentWindow(dtvcc_service_decoder *decoder, int window_id)
|
||||
@@ -1018,9 +995,9 @@ void dtvcc_handle_DFx_DefineWindow(dtvcc_service_decoder *decoder, int window_id
|
||||
int anchor_vertical = data[2] & 0x7f;
|
||||
int relative_pos = data[2] >> 7;
|
||||
int anchor_horizontal = data[3];
|
||||
int row_count = (data[4] & 0xf) + 1; //according to CEA-708-D
|
||||
int row_count = (data[4] & 0xf) + 1; // according to CEA-708-D
|
||||
int anchor_point = data[4] >> 4;
|
||||
int col_count = (data[5] & 0x3f) + 1; //according to CEA-708-D
|
||||
int col_count = (data[5] & 0x3f) + 1; // according to CEA-708-D
|
||||
int pen_style = data[6] & 0x7;
|
||||
int win_style = (data[6] >> 3) & 0x7;
|
||||
|
||||
@@ -1048,6 +1025,18 @@ void dtvcc_handle_DFx_DefineWindow(dtvcc_service_decoder *decoder, int window_id
|
||||
if (anchor_horizontal > CCX_DTVCC_SCREENGRID_COLUMNS - col_count)
|
||||
anchor_horizontal = CCX_DTVCC_SCREENGRID_COLUMNS - col_count;
|
||||
|
||||
if (window->is_defined)
|
||||
{
|
||||
if (row_count < window->row_count)
|
||||
{
|
||||
// Remove the oldest row if the row count is reduced
|
||||
for (int i = row_count; i < window->row_count; i++)
|
||||
{
|
||||
dtvcc_window_rollup(decoder, window);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
window->priority = priority;
|
||||
window->col_lock = col_lock;
|
||||
window->row_lock = row_lock;
|
||||
@@ -1074,7 +1063,7 @@ void dtvcc_handle_DFx_DefineWindow(dtvcc_service_decoder *decoder, int window_id
|
||||
pen_style = 1;
|
||||
}
|
||||
|
||||
//Apply windows attribute presets
|
||||
// Apply windows attribute presets
|
||||
if (win_style > 0 && win_style < 8)
|
||||
{
|
||||
window->win_style = win_style;
|
||||
@@ -1093,7 +1082,7 @@ void dtvcc_handle_DFx_DefineWindow(dtvcc_service_decoder *decoder, int window_id
|
||||
|
||||
if (pen_style > 0)
|
||||
{
|
||||
//TODO apply static pen_style preset
|
||||
// TODO apply static pen_style preset
|
||||
window->pen_style = pen_style;
|
||||
}
|
||||
|
||||
@@ -1380,7 +1369,7 @@ void dtvcc_handle_DLC_DelayCancel(dtvcc_service_decoder *decoder)
|
||||
|
||||
//-------------------------- CHARACTERS AND COMMANDS -------------------------
|
||||
|
||||
void dtvcc_handle_C0_P16(dtvcc_service_decoder *decoder, unsigned char *data) //16-byte chars always have 2 bytes
|
||||
void dtvcc_handle_C0_P16(dtvcc_service_decoder *decoder, unsigned char *data) // 16-byte chars always have 2 bytes
|
||||
{
|
||||
if (decoder->current_window == -1)
|
||||
{
|
||||
@@ -1408,7 +1397,7 @@ int dtvcc_handle_G0(dtvcc_service_decoder *decoder, unsigned char *data, int dat
|
||||
if (decoder->current_window == -1)
|
||||
{
|
||||
ccx_common_logging.log_ftn("[CEA-708] dtvcc_handle_G0: Window has to be defined first\n");
|
||||
return data_length;
|
||||
return 1;
|
||||
}
|
||||
|
||||
unsigned char c = data[0];
|
||||
@@ -1684,7 +1673,7 @@ void dtvcc_process_service_block(dtvcc_ctx *dtvcc,
|
||||
unsigned char *data,
|
||||
int data_length)
|
||||
{
|
||||
//dump(CCX_DMT_708, data, data_length, 0, 0);
|
||||
// dump(CCX_DMT_708, data, data_length, 0, 0);
|
||||
|
||||
int i = 0;
|
||||
while (i < data_length)
|
||||
@@ -1706,7 +1695,7 @@ void dtvcc_process_service_block(dtvcc_ctx *dtvcc,
|
||||
ccx_common_logging.debug_ftn(CCX_DMT_708, "[CEA-708] dtvcc_process_service_block: "
|
||||
"There was a problem handling the data. Reseting service decoder\n");
|
||||
// TODO: Not sure if a local reset is going to be helpful here.
|
||||
//dtvcc_windows_reset(decoder);
|
||||
// dtvcc_windows_reset(decoder);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1744,10 +1733,10 @@ void dtvcc_process_current_packet(dtvcc_ctx *dtvcc, int len)
|
||||
ccx_common_logging.debug_ftn(CCX_DMT_708, "[CEA-708] dtvcc_process_current_packet: "
|
||||
"Unexpected sequence number, it is [%d] but should be [%d]\n",
|
||||
seq, (dtvcc->last_sequence + 1) % 4);
|
||||
//WARN: if we reset decoders here, buffer will not be written
|
||||
//WARN: resetting decoders breaks some samples
|
||||
//dtvcc_decoders_reset(dtvcc);
|
||||
//return;
|
||||
// WARN: if we reset decoders here, buffer will not be written
|
||||
// WARN: resetting decoders breaks some samples
|
||||
// dtvcc_decoders_reset(dtvcc);
|
||||
// return;
|
||||
}
|
||||
dtvcc->last_sequence = seq;
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include "ccx_common_constants.h"
|
||||
#include "ccx_common_structs.h"
|
||||
|
||||
#define CCX_DTVCC_MAX_PACKET_LENGTH 128 //According to EIA-708B, part 5
|
||||
#define CCX_DTVCC_MAX_PACKET_LENGTH 128 // According to EIA-708B, part 5
|
||||
#define CCX_DTVCC_MAX_SERVICES 63
|
||||
|
||||
#define CCX_DTVCC_MAX_ROWS 15
|
||||
@@ -14,7 +14,7 @@
|
||||
* This value should be 32, but there were 16-bit encoded samples (from Korea),
|
||||
* where RowCount calculated another way and equals 46 (23[8bit]*2)
|
||||
*/
|
||||
#define CCX_DTVCC_MAX_COLUMNS (32*2)
|
||||
#define CCX_DTVCC_MAX_COLUMNS (32 * 2)
|
||||
|
||||
#define CCX_DTVCC_SCREENGRID_ROWS 75
|
||||
#define CCX_DTVCC_SCREENGRID_COLUMNS 210
|
||||
@@ -30,14 +30,14 @@
|
||||
|
||||
enum DTVCC_COMMANDS_C0_CODES
|
||||
{
|
||||
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_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
|
||||
DTVCC_C0_P16 = 0x18
|
||||
};
|
||||
|
||||
enum DTVCC_COMMANDS_C1_CODES
|
||||
@@ -86,21 +86,21 @@ struct DTVCC_S_COMMANDS_C1
|
||||
|
||||
enum dtvcc_window_justify
|
||||
{
|
||||
DTVCC_WINDOW_JUSTIFY_LEFT = 0,
|
||||
DTVCC_WINDOW_JUSTIFY_RIGHT = 1,
|
||||
DTVCC_WINDOW_JUSTIFY_CENTER = 2,
|
||||
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 dtvcc_window_pd //Print Direction
|
||||
enum dtvcc_window_pd // Print Direction
|
||||
{
|
||||
DTVCC_WINDOW_PD_LEFT_RIGHT = 0, //left -> right
|
||||
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 dtvcc_window_sd //Scroll Direction
|
||||
enum dtvcc_window_sd // Scroll Direction
|
||||
{
|
||||
DTVCC_WINDOW_SD_LEFT_RIGHT = 0,
|
||||
DTVCC_WINDOW_SD_RIGHT_LEFT = 1,
|
||||
@@ -108,14 +108,14 @@ enum dtvcc_window_sd //Scroll Direction
|
||||
DTVCC_WINDOW_SD_BOTTOM_TOP = 3
|
||||
};
|
||||
|
||||
enum dtvcc_window_sde //Scroll Display Effect
|
||||
enum dtvcc_window_sde // Scroll Display Effect
|
||||
{
|
||||
DTVCC_WINDOW_SDE_SNAP = 0,
|
||||
DTVCC_WINDOW_SDE_FADE = 1,
|
||||
DTVCC_WINDOW_SDE_WIPE = 2
|
||||
};
|
||||
|
||||
enum dtvcc_window_ed //Effect Direction
|
||||
enum dtvcc_window_ed // Effect Direction
|
||||
{
|
||||
DTVCC_WINDOW_ED_LEFT_RIGHT = 0,
|
||||
DTVCC_WINDOW_ED_RIGHT_LEFT = 1,
|
||||
@@ -123,91 +123,91 @@ enum dtvcc_window_ed //Effect Direction
|
||||
DTVCC_WINDOW_ED_BOTTOM_TOP = 3
|
||||
};
|
||||
|
||||
enum dtvcc_window_fo //Fill Opacity
|
||||
enum dtvcc_window_fo // Fill Opacity
|
||||
{
|
||||
DTVCC_WINDOW_FO_SOLID = 0,
|
||||
DTVCC_WINDOW_FO_FLASH = 1,
|
||||
DTVCC_WINDOW_FO_TRANSLUCENT = 2,
|
||||
DTVCC_WINDOW_FO_SOLID = 0,
|
||||
DTVCC_WINDOW_FO_FLASH = 1,
|
||||
DTVCC_WINDOW_FO_TRANSLUCENT = 2,
|
||||
DTVCC_WINDOW_FO_TRANSPARENT = 3
|
||||
};
|
||||
|
||||
enum dtvcc_window_border
|
||||
{
|
||||
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
|
||||
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 dtvcc_pen_size
|
||||
{
|
||||
DTVCC_PEN_SIZE_SMALL = 0,
|
||||
DTVCC_PEN_SIZE_SMALL = 0,
|
||||
DTVCC_PEN_SIZE_STANDART = 1,
|
||||
DTVCC_PEN_SIZE_LARGE = 2
|
||||
DTVCC_PEN_SIZE_LARGE = 2
|
||||
};
|
||||
|
||||
enum dtvcc_pen_font_style
|
||||
{
|
||||
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
|
||||
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 dtvcc_pen_text_tag
|
||||
{
|
||||
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
|
||||
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 dtvcc_pen_offset
|
||||
{
|
||||
DTVCC_PEN_OFFSET_SUBSCRIPT = 0,
|
||||
DTVCC_PEN_OFFSET_NORMAL = 1,
|
||||
DTVCC_PEN_OFFSET_SUPERSCRIPT = 2
|
||||
DTVCC_PEN_OFFSET_SUBSCRIPT = 0,
|
||||
DTVCC_PEN_OFFSET_NORMAL = 1,
|
||||
DTVCC_PEN_OFFSET_SUPERSCRIPT = 2
|
||||
};
|
||||
|
||||
enum dtvcc_pen_edge
|
||||
{
|
||||
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
|
||||
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 dtvcc_pen_anchor_point
|
||||
{
|
||||
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
|
||||
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 dtvcc_pen_color
|
||||
@@ -252,12 +252,20 @@ typedef struct dtvcc_window_attribs
|
||||
*/
|
||||
typedef struct dtvcc_symbol
|
||||
{
|
||||
unsigned short sym; //symbol itself, at least 16 bit
|
||||
unsigned char init; //initialized or not. could be 0 or 1
|
||||
unsigned short sym; // symbol itself, at least 16 bit
|
||||
unsigned char init; // initialized or not. could be 0 or 1
|
||||
} 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;}
|
||||
#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; \
|
||||
}
|
||||
#define CCX_DTVCC_SYM(x) ((unsigned char)(x.sym))
|
||||
#define CCX_DTVCC_SYM_IS_EMPTY(x) (x.init == 0)
|
||||
#define CCX_DTVCC_SYM_IS_SET(x) (x.init == 1)
|
||||
@@ -302,6 +310,7 @@ typedef struct dtvcc_tv_screen
|
||||
LLONG time_ms_hide;
|
||||
unsigned int cc_count;
|
||||
int service_number;
|
||||
int old_cc_time_end;
|
||||
} dtvcc_tv_screen;
|
||||
|
||||
/**
|
||||
@@ -343,7 +352,7 @@ typedef struct dtvcc_ctx
|
||||
{
|
||||
int is_active;
|
||||
int active_services_count;
|
||||
int services_active[CCX_DTVCC_MAX_SERVICES]; //0 - inactive, 1 - active
|
||||
int services_active[CCX_DTVCC_MAX_SERVICES]; // 0 - inactive, 1 - active
|
||||
int report_enabled;
|
||||
|
||||
ccx_decoder_dtvcc_report *report;
|
||||
@@ -356,21 +365,20 @@ typedef struct dtvcc_ctx
|
||||
|
||||
int last_sequence;
|
||||
|
||||
void *encoder; //we can't include header, so keeping it this way
|
||||
void *encoder; // we can't include header, so keeping it this way
|
||||
int no_rollup;
|
||||
struct ccx_common_timing_ctx *timing;
|
||||
} dtvcc_ctx;
|
||||
|
||||
|
||||
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 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);
|
||||
dtvcc_service_decoder *decoder,
|
||||
unsigned char *data,
|
||||
int data_length);
|
||||
|
||||
void dtvcc_tv_clear(dtvcc_service_decoder *decoder);
|
||||
int dtvcc_decoder_has_visible_windows(dtvcc_service_decoder *decoder);
|
||||
@@ -380,9 +388,9 @@ 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);
|
||||
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);
|
||||
@@ -405,7 +413,7 @@ 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,
|
||||
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,
|
||||
@@ -425,13 +433,13 @@ 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);
|
||||
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);
|
||||
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);
|
||||
|
||||
@@ -11,35 +11,3 @@ EIA-708, SO INTERNALLY WE USE THIS TABLE (FOR CONVENIENCE)
|
||||
(there are several blank characters here, that's OK)
|
||||
A0-FF -> Group G1 as is - non-English characters and symbols
|
||||
*/
|
||||
|
||||
unsigned char dtvcc_get_internal_from_G0(unsigned char g0_char)
|
||||
{
|
||||
return g0_char;
|
||||
}
|
||||
|
||||
unsigned char dtvcc_get_internal_from_G1(unsigned char g1_char)
|
||||
{
|
||||
return g1_char;
|
||||
}
|
||||
|
||||
// TODO: Probably not right
|
||||
// G2: Extended Control Code Set 1
|
||||
unsigned char dtvcc_get_internal_from_G2(unsigned char g2_char)
|
||||
{
|
||||
if (g2_char >= 0x20 && g2_char <= 0x3F)
|
||||
return g2_char - (unsigned char)0x20;
|
||||
if (g2_char >= 0x60 && g2_char <= 0x7F)
|
||||
return g2_char + (unsigned char)0x20;
|
||||
// Rest unmapped, so we return a blank space
|
||||
return 0x20;
|
||||
}
|
||||
|
||||
// TODO: Probably not right
|
||||
// G3: Future Characters and Icon Expansion
|
||||
unsigned char dtvcc_get_internal_from_G3(unsigned char g3_char)
|
||||
{
|
||||
if (g3_char == 0xa0) // The "CC" (closed captions) sign
|
||||
return 0x06;
|
||||
// Rest unmapped, so we return a blank space
|
||||
return 0x20;
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
#ifndef _CCX_DECODERS_708_ENCODING_H_
|
||||
#define _CCX_DECODERS_708_ENCODING_H_
|
||||
|
||||
#define CCX_DTVCC_MUSICAL_NOTE_CHAR 9836 // Unicode Character 'BEAMED SIXTEENTH NOTES'
|
||||
#define CCX_DTVCC_MUSICAL_NOTE_CHAR 9836 // Unicode Character 'BEAMED SIXTEENTH NOTES'
|
||||
|
||||
unsigned char dtvcc_get_internal_from_G0(unsigned char g0_char);
|
||||
unsigned char dtvcc_get_internal_from_G1(unsigned char g1_char);
|
||||
unsigned char dtvcc_get_internal_from_G2(unsigned char g2_char);
|
||||
unsigned char dtvcc_get_internal_from_G3(unsigned char g3_char);
|
||||
extern unsigned char dtvcc_get_internal_from_G0(unsigned char g0_char);
|
||||
extern unsigned char dtvcc_get_internal_from_G1(unsigned char g1_char);
|
||||
extern unsigned char dtvcc_get_internal_from_G2(unsigned char g2_char);
|
||||
extern unsigned char dtvcc_get_internal_from_G3(unsigned char g3_char);
|
||||
|
||||
#endif /*_CCX_DECODERS_708_ENCODING_H_*/
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include "utility.h"
|
||||
#include "ccx_common_common.h"
|
||||
|
||||
#if defined(ENABLE_RUST) && defined(WIN32)
|
||||
#if defined(WIN32)
|
||||
extern void ccxr_close_handle(void *handle);
|
||||
#endif
|
||||
|
||||
@@ -57,6 +57,7 @@ void dtvcc_change_pen_colors(dtvcc_tv_screen *tv, dtvcc_pen_color pen_color, int
|
||||
return;
|
||||
|
||||
char *buf = (char *)encoder->buffer;
|
||||
size_t remaining = INITIAL_ENC_BUFFER_CAPACITY - *buf_len;
|
||||
|
||||
dtvcc_pen_color new_pen_color;
|
||||
if (column_index >= CCX_DTVCC_SCREENGRID_COLUMNS)
|
||||
@@ -66,7 +67,11 @@ void dtvcc_change_pen_colors(dtvcc_tv_screen *tv, dtvcc_pen_color pen_color, int
|
||||
if (pen_color.fg_color != new_pen_color.fg_color)
|
||||
{
|
||||
if (pen_color.fg_color != 0x3f && !open)
|
||||
(*buf_len) += sprintf(buf + (*buf_len), "</font>"); // should close older non-white color
|
||||
{
|
||||
int written = snprintf(buf + (*buf_len), remaining, "</font>"); // should close older non-white color
|
||||
if (written > 0 && (size_t)written < remaining)
|
||||
(*buf_len) += written;
|
||||
}
|
||||
|
||||
if (new_pen_color.fg_color != 0x3f && open)
|
||||
{
|
||||
@@ -75,7 +80,10 @@ void dtvcc_change_pen_colors(dtvcc_tv_screen *tv, dtvcc_pen_color pen_color, int
|
||||
red = (255 / 3) * red;
|
||||
green = (255 / 3) * green;
|
||||
blue = (255 / 3) * blue;
|
||||
(*buf_len) += sprintf(buf + (*buf_len), "<font color=\"%02x%02x%02x\">", red, green, blue);
|
||||
remaining = INITIAL_ENC_BUFFER_CAPACITY - *buf_len;
|
||||
int written = snprintf(buf + (*buf_len), remaining, "<font color=\"#%02x%02x%02x\">", red, green, blue);
|
||||
if (written > 0 && (size_t)written < remaining)
|
||||
(*buf_len) += written;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -86,6 +94,8 @@ void dtvcc_change_pen_attribs(dtvcc_tv_screen *tv, dtvcc_pen_attribs pen_attribs
|
||||
return;
|
||||
|
||||
char *buf = (char *)encoder->buffer;
|
||||
size_t remaining;
|
||||
int written;
|
||||
|
||||
dtvcc_pen_attribs new_pen_attribs;
|
||||
if (column_index >= CCX_DTVCC_SCREENGRID_COLUMNS)
|
||||
@@ -94,33 +104,47 @@ void dtvcc_change_pen_attribs(dtvcc_tv_screen *tv, dtvcc_pen_attribs pen_attribs
|
||||
new_pen_attribs = tv->pen_attribs[row_index][column_index];
|
||||
if (pen_attribs.italic != new_pen_attribs.italic)
|
||||
{
|
||||
remaining = INITIAL_ENC_BUFFER_CAPACITY - *buf_len;
|
||||
if (pen_attribs.italic && !open)
|
||||
(*buf_len) += sprintf(buf + (*buf_len), "</i>");
|
||||
{
|
||||
written = snprintf(buf + (*buf_len), remaining, "</i>");
|
||||
if (written > 0 && (size_t)written < remaining)
|
||||
(*buf_len) += written;
|
||||
}
|
||||
if (!pen_attribs.italic && open)
|
||||
(*buf_len) += sprintf(buf + (*buf_len), "<i>");
|
||||
{
|
||||
written = snprintf(buf + (*buf_len), remaining, "<i>");
|
||||
if (written > 0 && (size_t)written < remaining)
|
||||
(*buf_len) += written;
|
||||
}
|
||||
}
|
||||
if (pen_attribs.underline != new_pen_attribs.underline)
|
||||
{
|
||||
remaining = INITIAL_ENC_BUFFER_CAPACITY - *buf_len;
|
||||
if (pen_attribs.underline && !open)
|
||||
(*buf_len) += sprintf(buf + (*buf_len), "</u>");
|
||||
{
|
||||
written = snprintf(buf + (*buf_len), remaining, "</u>");
|
||||
if (written > 0 && (size_t)written < remaining)
|
||||
(*buf_len) += written;
|
||||
}
|
||||
if (!pen_attribs.underline && open)
|
||||
(*buf_len) += sprintf(buf + (*buf_len), "<u>");
|
||||
{
|
||||
written = snprintf(buf + (*buf_len), remaining, "<u>");
|
||||
if (written > 0 && (size_t)written < remaining)
|
||||
(*buf_len) += written;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t write_utf16_char(unsigned short utf16_char, char *out)
|
||||
{
|
||||
if ((utf16_char >> 8) != 0)
|
||||
{
|
||||
out[0] = (unsigned char)(utf16_char >> 8);
|
||||
out[1] = (unsigned char)(utf16_char & 0xff);
|
||||
return 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
out[0] = (unsigned char)(utf16_char);
|
||||
return 1;
|
||||
}
|
||||
// Always write 2 bytes for consistent UTF-16BE encoding.
|
||||
// Previously, this function wrote 1 byte for ASCII characters and 2 bytes
|
||||
// for non-ASCII, creating an invalid mix that iconv couldn't handle properly.
|
||||
// This caused garbled output with Japanese/Chinese characters (issue #1451).
|
||||
out[0] = (unsigned char)(utf16_char >> 8);
|
||||
out[1] = (unsigned char)(utf16_char & 0xff);
|
||||
return 2;
|
||||
}
|
||||
|
||||
void dtvcc_write_row(dtvcc_writer_ctx *writer, dtvcc_service_decoder *decoder, int row_index, struct encoder_ctx *encoder, int use_colors)
|
||||
@@ -207,16 +231,31 @@ void dtvcc_write_srt(dtvcc_writer_ctx *writer, dtvcc_service_decoder *decoder, s
|
||||
|
||||
char *buf = (char *)encoder->buffer;
|
||||
memset(buf, 0, INITIAL_ENC_BUFFER_CAPACITY);
|
||||
size_t buf_len = 0;
|
||||
size_t remaining = INITIAL_ENC_BUFFER_CAPACITY;
|
||||
int written;
|
||||
|
||||
sprintf(buf, "%u%s", encoder->cea_708_counter, encoder->encoded_crlf);
|
||||
written = snprintf(buf, remaining, "%u%s", encoder->cea_708_counter, encoder->encoded_crlf);
|
||||
if (written > 0 && (size_t)written < remaining)
|
||||
buf_len += written;
|
||||
remaining = INITIAL_ENC_BUFFER_CAPACITY - buf_len;
|
||||
print_mstime_buff(tv->time_ms_show + encoder->subs_delay,
|
||||
"%02u:%02u:%02u,%03u", buf + strlen(buf));
|
||||
sprintf(buf + strlen(buf), " --> ");
|
||||
"%02u:%02u:%02u,%03u", buf + buf_len);
|
||||
buf_len = strlen(buf);
|
||||
remaining = INITIAL_ENC_BUFFER_CAPACITY - buf_len;
|
||||
written = snprintf(buf + buf_len, remaining, " --> ");
|
||||
if (written > 0 && (size_t)written < remaining)
|
||||
buf_len += written;
|
||||
remaining = INITIAL_ENC_BUFFER_CAPACITY - buf_len;
|
||||
print_mstime_buff(tv->time_ms_hide + encoder->subs_delay,
|
||||
"%02u:%02u:%02u,%03u", buf + strlen(buf));
|
||||
sprintf(buf + strlen(buf), "%s", (char *)encoder->encoded_crlf);
|
||||
"%02u:%02u:%02u,%03u", buf + buf_len);
|
||||
buf_len = strlen(buf);
|
||||
remaining = INITIAL_ENC_BUFFER_CAPACITY - buf_len;
|
||||
written = snprintf(buf + buf_len, remaining, "%s", (char *)encoder->encoded_crlf);
|
||||
if (written > 0 && (size_t)written < remaining)
|
||||
buf_len += written;
|
||||
|
||||
write_wrapped(encoder->dtvcc_writers[tv->service_number - 1].fd, buf, strlen(buf));
|
||||
write_wrapped(encoder->dtvcc_writers[tv->service_number - 1].fd, buf, buf_len);
|
||||
|
||||
for (int i = 0; i < CCX_DTVCC_SCREENGRID_ROWS; i++)
|
||||
{
|
||||
@@ -263,28 +302,47 @@ void dtvcc_write_transcript(dtvcc_writer_ctx *writer, dtvcc_service_decoder *dec
|
||||
return;
|
||||
|
||||
char *buf = (char *)encoder->buffer;
|
||||
size_t buf_len;
|
||||
size_t remaining;
|
||||
int written;
|
||||
|
||||
for (int i = 0; i < CCX_DTVCC_SCREENGRID_ROWS; i++)
|
||||
{
|
||||
if (!dtvcc_is_row_empty(tv, i))
|
||||
{
|
||||
buf[0] = 0;
|
||||
buf_len = 0;
|
||||
|
||||
if (encoder->transcript_settings->showStartTime)
|
||||
{
|
||||
print_mstime_buff(tv->time_ms_show + encoder->subs_delay,
|
||||
"%02u:%02u:%02u,%03u|", buf + strlen(buf));
|
||||
"%02u:%02u:%02u,%03u|", buf + buf_len);
|
||||
buf_len = strlen(buf);
|
||||
}
|
||||
|
||||
if (encoder->transcript_settings->showEndTime)
|
||||
{
|
||||
print_mstime_buff(tv->time_ms_hide + encoder->subs_delay,
|
||||
"%02u:%02u:%02u,%03u|", buf + strlen(buf));
|
||||
"%02u:%02u:%02u,%03u|", buf + buf_len);
|
||||
buf_len = strlen(buf);
|
||||
}
|
||||
|
||||
if (encoder->transcript_settings->showCC)
|
||||
sprintf(buf + strlen(buf), "CC1|"); //always CC1 because CEA-708 is field-independent
|
||||
{
|
||||
remaining = INITIAL_ENC_BUFFER_CAPACITY - buf_len;
|
||||
written = snprintf(buf + buf_len, remaining, "CC1|"); // always CC1 because CEA-708 is field-independent
|
||||
if (written > 0 && (size_t)written < remaining)
|
||||
buf_len += written;
|
||||
}
|
||||
|
||||
if (encoder->transcript_settings->showMode)
|
||||
sprintf(buf + strlen(buf), "POP|"); //TODO caption mode(pop, rollup, etc.)
|
||||
{
|
||||
remaining = INITIAL_ENC_BUFFER_CAPACITY - buf_len;
|
||||
written = snprintf(buf + buf_len, remaining, "POP|"); // TODO caption mode(pop, rollup, etc.)
|
||||
if (written > 0 && (size_t)written < remaining)
|
||||
buf_len += written;
|
||||
}
|
||||
|
||||
const size_t buf_len = strlen(buf);
|
||||
if (buf_len != 0)
|
||||
write_wrapped(encoder->dtvcc_writers[tv->service_number - 1].fd, buf, buf_len);
|
||||
|
||||
@@ -300,22 +358,33 @@ 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);
|
||||
size_t buf_len = 0;
|
||||
size_t remaining = INITIAL_ENC_BUFFER_CAPACITY;
|
||||
int written;
|
||||
|
||||
buf_len += sprintf(buf + buf_len, "<sami>%s", encoder->encoded_crlf);
|
||||
buf_len += sprintf(buf + buf_len, "<head>%s", encoder->encoded_crlf);
|
||||
buf_len += sprintf(buf + buf_len, "<style type=\"text/css\">%s", encoder->encoded_crlf);
|
||||
buf_len += sprintf(buf + buf_len, "<!--%s", encoder->encoded_crlf);
|
||||
buf_len += sprintf(buf + buf_len,
|
||||
"p {margin-left: 16pt; margin-right: 16pt; margin-bottom: 16pt; margin-top: 16pt;%s",
|
||||
encoder->encoded_crlf);
|
||||
buf_len += sprintf(buf + buf_len,
|
||||
"text-align: center; font-size: 18pt; font-family: arial; font-weight: bold; color: #f0f0f0;}%s",
|
||||
encoder->encoded_crlf);
|
||||
buf_len += sprintf(buf + buf_len, ".unknowncc {Name:Unknown; lang:en-US; SAMIType:CC;}%s", encoder->encoded_crlf);
|
||||
buf_len += sprintf(buf + buf_len, "-->%s", encoder->encoded_crlf);
|
||||
buf_len += sprintf(buf + buf_len, "</style>%s", encoder->encoded_crlf);
|
||||
buf_len += sprintf(buf + buf_len, "</head>%s%s", encoder->encoded_crlf, encoder->encoded_crlf);
|
||||
buf_len += sprintf(buf + buf_len, "<body>%s", encoder->encoded_crlf);
|
||||
#define SAMI_SNPRINTF(fmt, ...) \
|
||||
do \
|
||||
{ \
|
||||
remaining = INITIAL_ENC_BUFFER_CAPACITY - buf_len; \
|
||||
written = snprintf(buf + buf_len, remaining, fmt, ##__VA_ARGS__); \
|
||||
if (written > 0 && (size_t)written < remaining) \
|
||||
buf_len += written; \
|
||||
} while (0)
|
||||
|
||||
SAMI_SNPRINTF("<sami>%s", encoder->encoded_crlf);
|
||||
SAMI_SNPRINTF("<head>%s", encoder->encoded_crlf);
|
||||
SAMI_SNPRINTF("<style type=\"text/css\">%s", encoder->encoded_crlf);
|
||||
SAMI_SNPRINTF("<!--%s", encoder->encoded_crlf);
|
||||
SAMI_SNPRINTF("p {margin-left: 16pt; margin-right: 16pt; margin-bottom: 16pt; margin-top: 16pt;%s",
|
||||
encoder->encoded_crlf);
|
||||
SAMI_SNPRINTF("text-align: center; font-size: 18pt; font-family: arial; font-weight: bold; color: #f0f0f0;}%s",
|
||||
encoder->encoded_crlf);
|
||||
SAMI_SNPRINTF(".unknowncc {Name:Unknown; lang:en-US; SAMIType:CC;}%s", encoder->encoded_crlf);
|
||||
SAMI_SNPRINTF("-->%s", encoder->encoded_crlf);
|
||||
SAMI_SNPRINTF("</style>%s", encoder->encoded_crlf);
|
||||
SAMI_SNPRINTF("</head>%s%s", encoder->encoded_crlf, encoder->encoded_crlf);
|
||||
SAMI_SNPRINTF("<body>%s", encoder->encoded_crlf);
|
||||
|
||||
#undef SAMI_SNPRINTF
|
||||
|
||||
write_wrapped(encoder->dtvcc_writers[tv->service_number - 1].fd, buf, buf_len);
|
||||
}
|
||||
@@ -323,8 +392,9 @@ 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)
|
||||
{
|
||||
char *buf = (char *)encoder->buffer;
|
||||
sprintf(buf, "</body></sami>");
|
||||
write_wrapped(encoder->dtvcc_writers[tv->service_number - 1].fd, buf, strlen(buf));
|
||||
int written = snprintf(buf, INITIAL_ENC_BUFFER_CAPACITY, "</body></sami>");
|
||||
if (written > 0 && (size_t)written < INITIAL_ENC_BUFFER_CAPACITY)
|
||||
write_wrapped(encoder->dtvcc_writers[tv->service_number - 1].fd, buf, written);
|
||||
write_wrapped(encoder->dtvcc_writers[tv->service_number - 1].fd,
|
||||
encoder->encoded_crlf, encoder->encoded_crlf_length);
|
||||
}
|
||||
@@ -342,12 +412,14 @@ void dtvcc_write_sami(dtvcc_writer_ctx *writer, dtvcc_service_decoder *decoder,
|
||||
dtvcc_write_sami_header(tv, encoder);
|
||||
|
||||
char *buf = (char *)encoder->buffer;
|
||||
int written;
|
||||
|
||||
buf[0] = 0;
|
||||
sprintf(buf, "<sync start=%llu><p class=\"unknowncc\">%s",
|
||||
(unsigned long long)tv->time_ms_show + encoder->subs_delay,
|
||||
encoder->encoded_crlf);
|
||||
write_wrapped(encoder->dtvcc_writers[tv->service_number - 1].fd, buf, strlen(buf));
|
||||
written = snprintf(buf, INITIAL_ENC_BUFFER_CAPACITY, "<sync start=%llu><p class=\"unknowncc\">%s",
|
||||
(unsigned long long)tv->time_ms_show + encoder->subs_delay,
|
||||
encoder->encoded_crlf);
|
||||
if (written > 0 && (size_t)written < INITIAL_ENC_BUFFER_CAPACITY)
|
||||
write_wrapped(encoder->dtvcc_writers[tv->service_number - 1].fd, buf, written);
|
||||
|
||||
for (int i = 0; i < CCX_DTVCC_SCREENGRID_ROWS; i++)
|
||||
{
|
||||
@@ -361,10 +433,189 @@ void dtvcc_write_sami(dtvcc_writer_ctx *writer, dtvcc_service_decoder *decoder,
|
||||
}
|
||||
}
|
||||
|
||||
sprintf(buf, "<sync start=%llu><p class=\"unknowncc\"> </p></sync>%s%s",
|
||||
(unsigned long long)tv->time_ms_hide + encoder->subs_delay,
|
||||
encoder->encoded_crlf, encoder->encoded_crlf);
|
||||
written = snprintf(buf, INITIAL_ENC_BUFFER_CAPACITY, "<sync start=%llu><p class=\"unknowncc\"> </p></sync>%s%s",
|
||||
(unsigned long long)tv->time_ms_hide + encoder->subs_delay,
|
||||
encoder->encoded_crlf, encoder->encoded_crlf);
|
||||
if (written > 0 && (size_t)written < INITIAL_ENC_BUFFER_CAPACITY)
|
||||
write_wrapped(encoder->dtvcc_writers[tv->service_number - 1].fd, buf, written);
|
||||
}
|
||||
|
||||
unsigned char adjust_odd_parity(const unsigned char value)
|
||||
{
|
||||
unsigned int i, ones = 0;
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
if ((value & (1 << i)) != 0)
|
||||
{
|
||||
ones += 1;
|
||||
}
|
||||
}
|
||||
if (ones % 2 == 0)
|
||||
{
|
||||
// make the number of ones always odd
|
||||
return value | 0b10000000;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
void dtvcc_write_scc_header(dtvcc_tv_screen *tv, struct encoder_ctx *encoder)
|
||||
{
|
||||
char *buf = (char *)encoder->buffer;
|
||||
// 18 characters long + 2 new lines = 20 characters total
|
||||
memset(buf, 0, INITIAL_ENC_BUFFER_CAPACITY);
|
||||
int written = snprintf(buf, INITIAL_ENC_BUFFER_CAPACITY, "Scenarist_SCC V1.0\n\n");
|
||||
|
||||
if (written > 0 && (size_t)written < INITIAL_ENC_BUFFER_CAPACITY)
|
||||
write_wrapped(encoder->dtvcc_writers[tv->service_number - 1].fd, buf, written);
|
||||
}
|
||||
|
||||
int count_captions_lines_scc(dtvcc_tv_screen *tv)
|
||||
{
|
||||
int count = 0;
|
||||
for (int i = 0; i < CCX_DTVCC_SCREENGRID_ROWS; i++)
|
||||
{
|
||||
if (!dtvcc_is_row_empty(tv, i))
|
||||
{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/** This function is designed to assign appropriate SSC labels for positioning subtitles based on their length.
|
||||
* In some scenarios where the video stream provides lengthy subtitles that cannot fit within a single line.
|
||||
* Single-line subtitle can be placed in 15th row(most bottom row)
|
||||
* 2 line length subtitles can be placed in 14th and 15th row
|
||||
* 3 line length subtitles can be placed in 13th, 14th and 15th row
|
||||
*/
|
||||
void add_needed_scc_labels(char *buf, size_t buf_size, size_t *buf_len, int total_subtitle_count, int current_subtitle_count)
|
||||
{
|
||||
size_t remaining = buf_size - *buf_len;
|
||||
int written;
|
||||
const char *label;
|
||||
|
||||
switch (total_subtitle_count)
|
||||
{
|
||||
case 1:
|
||||
// row 15, column 00
|
||||
label = " 94e0 94e0";
|
||||
break;
|
||||
case 2:
|
||||
// 9440: row 14, column 00 | 94e0: row 15, column 00
|
||||
label = (current_subtitle_count == 1) ? " 9440 9440" : " 94e0 94e0";
|
||||
break;
|
||||
default:
|
||||
// 13e0: row 13, column 04 | 9440: row 14, column 00 | 94e0: row 15, column 00
|
||||
label = (current_subtitle_count == 1) ? " 13e0 13e0" : ((current_subtitle_count == 2) ? " 9440 9440" : " 94e0 94e0");
|
||||
break;
|
||||
}
|
||||
|
||||
written = snprintf(buf + *buf_len, remaining, "%s", label);
|
||||
if (written > 0 && (size_t)written < remaining)
|
||||
*buf_len += written;
|
||||
}
|
||||
|
||||
void dtvcc_write_scc(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))
|
||||
return;
|
||||
|
||||
if (tv->time_ms_show + encoder->subs_delay < 0)
|
||||
return;
|
||||
|
||||
if (tv->cc_count == 2)
|
||||
dtvcc_write_scc_header(tv, encoder);
|
||||
|
||||
char *buf = (char *)encoder->buffer;
|
||||
size_t buf_len;
|
||||
size_t remaining;
|
||||
int written;
|
||||
|
||||
struct ccx_boundary_time time_show = get_time(tv->time_ms_show + encoder->subs_delay);
|
||||
// when hiding subtract a frame (1 frame = 34 ms)
|
||||
struct ccx_boundary_time time_end = get_time(tv->time_ms_hide + encoder->subs_delay - 34);
|
||||
|
||||
#define SCC_SNPRINTF(fmt, ...) \
|
||||
do \
|
||||
{ \
|
||||
remaining = INITIAL_ENC_BUFFER_CAPACITY - buf_len; \
|
||||
written = snprintf(buf + buf_len, remaining, fmt, ##__VA_ARGS__); \
|
||||
if (written > 0 && (size_t)written < remaining) \
|
||||
buf_len += written; \
|
||||
} while (0)
|
||||
|
||||
if (tv->old_cc_time_end > time_show.time_in_ms)
|
||||
{
|
||||
// Correct the frame delay
|
||||
time_show.time_in_ms -= 1000 / 29.97;
|
||||
print_scc_time(time_show, buf);
|
||||
buf_len = strlen(buf);
|
||||
SCC_SNPRINTF("\t942c 942c");
|
||||
time_show.time_in_ms += 1000 / 29.97;
|
||||
// Clear the buffer and start pop on caption
|
||||
SCC_SNPRINTF("94ae 94ae 9420 9420");
|
||||
}
|
||||
else if (tv->old_cc_time_end < time_show.time_in_ms)
|
||||
{
|
||||
// Clear the screen for new caption
|
||||
struct ccx_boundary_time time_to_display = get_time(tv->old_cc_time_end);
|
||||
print_scc_time(time_to_display, buf);
|
||||
buf_len = strlen(buf);
|
||||
SCC_SNPRINTF("\t942c 942c \n\n");
|
||||
// Correct the frame delay
|
||||
time_show.time_in_ms -= 1000 / 29.97;
|
||||
// Clear the buffer and start pop on caption in new time
|
||||
print_scc_time(time_show, buf + buf_len);
|
||||
buf_len = strlen(buf);
|
||||
SCC_SNPRINTF("\t94ae 94ae 9420 9420");
|
||||
time_show.time_in_ms += 1000 / 29.97;
|
||||
}
|
||||
else
|
||||
{
|
||||
time_show.time_in_ms -= 1000 / 29.97;
|
||||
print_scc_time(time_show, buf);
|
||||
buf_len = strlen(buf);
|
||||
SCC_SNPRINTF("\t942c 942c 94ae 94ae 9420 9420");
|
||||
time_show.time_in_ms += 1000 / 29.97;
|
||||
}
|
||||
|
||||
int total_subtitle_count = count_captions_lines_scc(tv);
|
||||
int current_subtitle_count = 0;
|
||||
|
||||
for (int i = 0; i < CCX_DTVCC_SCREENGRID_ROWS; i++)
|
||||
{
|
||||
if (!dtvcc_is_row_empty(tv, i))
|
||||
{
|
||||
current_subtitle_count++;
|
||||
add_needed_scc_labels(buf, INITIAL_ENC_BUFFER_CAPACITY, &buf_len, total_subtitle_count, current_subtitle_count);
|
||||
|
||||
int first, last, bytes_written = 0;
|
||||
dtvcc_get_write_interval(tv, i, &first, &last);
|
||||
for (int j = first; j <= last; j++)
|
||||
{
|
||||
if (bytes_written % 2 == 0)
|
||||
SCC_SNPRINTF(" ");
|
||||
SCC_SNPRINTF("%x", adjust_odd_parity(tv->chars[i][j].sym));
|
||||
bytes_written += 1;
|
||||
}
|
||||
// if byte pair are not even then make it even by adding 0x80 as padding
|
||||
if (bytes_written % 2 == 1)
|
||||
SCC_SNPRINTF("80 ");
|
||||
else
|
||||
SCC_SNPRINTF(" ");
|
||||
}
|
||||
}
|
||||
|
||||
// Display caption (942f 942f)
|
||||
SCC_SNPRINTF("942f 942f \n\n");
|
||||
|
||||
#undef SCC_SNPRINTF
|
||||
write_wrapped(encoder->dtvcc_writers[tv->service_number - 1].fd, buf, strlen(buf));
|
||||
|
||||
tv->old_cc_time_end = time_end.time_in_ms;
|
||||
}
|
||||
|
||||
void dtvcc_write(dtvcc_writer_ctx *writer, dtvcc_service_decoder *decoder, struct encoder_ctx *encoder)
|
||||
@@ -382,6 +633,9 @@ void dtvcc_write(dtvcc_writer_ctx *writer, dtvcc_service_decoder *decoder, struc
|
||||
case CCX_OF_SAMI:
|
||||
dtvcc_write_sami(writer, decoder, encoder);
|
||||
break;
|
||||
case CCX_OF_SCC:
|
||||
dtvcc_write_scc(writer, decoder, encoder);
|
||||
break;
|
||||
case CCX_OF_MCC:
|
||||
printf("REALLY BAD... [%s:%d]\n", __FILE__, __LINE__);
|
||||
break;
|
||||
@@ -427,7 +681,7 @@ void dtvcc_writer_init(dtvcc_writer_ctx *writer,
|
||||
|
||||
const char *ext = get_file_extension(write_format);
|
||||
char suffix[32];
|
||||
sprintf(suffix, CCX_DTVCC_FILENAME_TEMPLATE, program_number, service_number);
|
||||
snprintf(suffix, sizeof(suffix), CCX_DTVCC_FILENAME_TEMPLATE, program_number, service_number);
|
||||
|
||||
writer->filename = create_outfilename(base_filename, suffix, ext);
|
||||
if (!writer->filename)
|
||||
@@ -438,10 +692,8 @@ void dtvcc_writer_init(dtvcc_writer_ctx *writer,
|
||||
|
||||
char *charset = cfg->all_services_charset ? cfg->all_services_charset : cfg->services_charsets[service_number - 1];
|
||||
|
||||
#ifdef ENABLE_RUST
|
||||
writer->fhandle = NULL;
|
||||
writer->charset = charset;
|
||||
#endif
|
||||
|
||||
if (charset)
|
||||
{
|
||||
@@ -459,14 +711,14 @@ void dtvcc_writer_cleanup(dtvcc_writer_ctx *writer)
|
||||
{
|
||||
if (writer->fd >= 0 && writer->fd != STDOUT_FILENO)
|
||||
close(writer->fd);
|
||||
#if defined(ENABLE_RUST) && defined(WIN32)
|
||||
#if defined(WIN32)
|
||||
ccxr_close_handle(writer->fhandle);
|
||||
writer->charset = NULL;
|
||||
#endif
|
||||
free(writer->filename);
|
||||
if (writer->cd == (iconv_t)-1)
|
||||
{
|
||||
//TODO nothing to do here
|
||||
// TODO nothing to do here
|
||||
}
|
||||
else
|
||||
iconv_close(writer->cd);
|
||||
@@ -481,7 +733,7 @@ void dtvcc_writer_output(dtvcc_writer_ctx *writer, dtvcc_service_decoder *decode
|
||||
if (!writer->filename && writer->fd < 0)
|
||||
return;
|
||||
|
||||
if (writer->filename && writer->fd < 0) //first request to write
|
||||
if (writer->filename && writer->fd < 0) // first request to write
|
||||
{
|
||||
ccx_common_logging.debug_ftn(CCX_DMT_708, "[CEA-708] "
|
||||
"dtvcc_writer_output: creating %s\n",
|
||||
|
||||
@@ -8,11 +8,11 @@
|
||||
void dtvcc_write_done(dtvcc_tv_screen *tv, struct encoder_ctx *encoder);
|
||||
|
||||
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);
|
||||
char *base_filename,
|
||||
int program_number,
|
||||
int service_number,
|
||||
enum ccx_output_format write_format,
|
||||
struct encoder_cfg *cfg);
|
||||
void dtvcc_writer_cleanup(dtvcc_writer_ctx *writer);
|
||||
void dtvcc_writer_output(dtvcc_writer_ctx *writer, dtvcc_service_decoder *decoder, struct encoder_ctx *encoder);
|
||||
|
||||
@@ -30,6 +30,9 @@ void dtvcc_write_transcript(dtvcc_writer_ctx *writer, dtvcc_service_decoder *dec
|
||||
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_scc_header(dtvcc_tv_screen *tv, struct encoder_ctx *encoder);
|
||||
void add_needed_scc_labels(char *buf, size_t buf_size, size_t *buf_len, int total_subtitle_count, int current_subtitle_count);
|
||||
void dtvcc_write_scc(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_*/
|
||||
#endif /*_CCX_DECODERS_708_OUTPUT_H_*/
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user