mirror of
https://github.com/CCExtractor/ccextractor.git
synced 2026-07-08 18:06:30 +00:00
Port hardsubx utility (#1443)
* set up bindings conversion of hardsubx utility functions (and structs) and set up the module
* add low level ffmpeg rust binding
* Methods ported:
- convert_pts_to_ns
- convert_pts_to_ms
- convert_pts_to_s
A pure rust method was added called _edit_distance_rec that implements levenstein distance calculation using recursion and dynamic programming
The port of edit_distance_rec is simply a wrapper that calls above function.
This redundancy won't be nevessary as more downstream modules are ported to Rust
* put C code of hardsubx_utility under define rust flag
* run formatter
* make compilation of hardsubx rust modules conditional on the HARDSUBX and the OCR flags. Make ffmpeg a conditional dependency based on those flags
* remove namespaced dependency in cargo because that is a nightly feature
* add conditioal compilatio of ffmpeg related bindigs in build.rs
* make clang argument of -DENABLE_HARDSUBX conditional on cargo feature of hardsubx_ocr
* enable specific relevant features for ffmpeg-sys-next
* enable hardsubx_ocr feature in windows build
* add build feature in ffmpeg-sys-next
* ffmpeg build feature is conditional on platform
* Revert "ffmpeg build feature is conditional on platform"
This reverts commit e456fee942.
This is because conditional features do not work in cargo toml
* install yasm in the linux build github action for ocr and hardsubx enabled cmake
* turn globals to locals to reduce code
* remove redundant attributes
* style changes
* make import of ffmpeg-sys-next conditional on hardsubx_ocr flag
* add --all-features flag in clippy for github workflow
* run formatter
* fix clippy command
* install yasm as part of rust format build check
* install libtesseract-dev etc. for clippy build test
* readability change
* declare the function edit_distance as unsafe
* remove commented code
* formatting changes
* combine declaration and assignment
* add build command for building hardsubx rust
context to issue: #1445
* make hardsubx rust work with autoconf build. For issue: #1445
* update autoconf for mac for issue #1445
This commit is contained in:
2
.github/workflows/build_linux.yml
vendored
2
.github/workflows/build_linux.yml
vendored
@@ -75,7 +75,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: dependencies
|
||||
run: sudo apt update && sudo apt install libtesseract-dev libavformat-dev libswscale-dev
|
||||
run: sudo apt update && sudo apt install libtesseract-dev libavformat-dev libswscale-dev yasm
|
||||
- name: cmake
|
||||
run: mkdir build && cd build && cmake -DWITH_OCR=ON -DWITH_HARDSUBX=ON ../src
|
||||
- name: build
|
||||
|
||||
4
.github/workflows/format.yml
vendored
4
.github/workflows/format.yml
vendored
@@ -45,7 +45,9 @@ jobs:
|
||||
toolchain: 1.56.0
|
||||
override: true
|
||||
components: rustfmt, clippy
|
||||
- name: dependencies
|
||||
run: sudo apt update && sudo apt install libtesseract-dev libavformat-dev libswscale-dev yasm
|
||||
- name: rustfmt
|
||||
run: cargo fmt --all -- --check
|
||||
- name: clippy
|
||||
run: cargo clippy -- -D warnings
|
||||
run: cargo clippy --all-features -- -D warnings
|
||||
|
||||
@@ -331,22 +331,6 @@ ccextractor_CPPFLAGS =-I../src/lib_ccx/ -I../src/thirdparty/gpacmp4/ -I../src/th
|
||||
|
||||
ccextractor_LDADD=-lm -lpthread -ldl
|
||||
|
||||
if WITH_RUST
|
||||
ccextractor_LDADD += ./rust/@RUST_TARGET_SUBDIR@/libccx_rust.a
|
||||
else
|
||||
ccextractor_CFLAGS += -DDISABLE_RUST
|
||||
ccextractor_CPPFLAGS += -DDISABLE_RUST
|
||||
endif
|
||||
|
||||
if DEBUG_RELEASE
|
||||
CARGO_RELEASE_ARGS=
|
||||
else
|
||||
CARGO_RELEASE_ARGS=--release
|
||||
endif
|
||||
|
||||
./rust/@RUST_TARGET_SUBDIR@/libccx_rust.a:
|
||||
cd ../src/rust && \
|
||||
CARGO_TARGET_DIR=../../linux/rust $(CARGO) build $(CARGO_RELEASE_ARGS);
|
||||
|
||||
if SYS_IS_LINUX
|
||||
ccextractor_CFLAGS += -O3 -s -DGPAC_CONFIG_LINUX
|
||||
@@ -361,6 +345,8 @@ 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}
|
||||
@@ -372,6 +358,7 @@ 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
|
||||
@@ -398,5 +385,22 @@ ccextractor_LDADD += $(TESS_LIB)
|
||||
ccextractor_LDADD += $(LEPT_LIB)
|
||||
endif
|
||||
|
||||
if WITH_RUST
|
||||
ccextractor_LDADD += ./rust/@RUST_TARGET_SUBDIR@/libccx_rust.a
|
||||
else
|
||||
ccextractor_CFLAGS += -DDISABLE_RUST
|
||||
ccextractor_CPPFLAGS += -DDISABLE_RUST
|
||||
endif
|
||||
|
||||
if DEBUG_RELEASE
|
||||
CARGO_RELEASE_ARGS=
|
||||
else
|
||||
CARGO_RELEASE_ARGS=--release
|
||||
endif
|
||||
|
||||
./rust/@RUST_TARGET_SUBDIR@/libccx_rust.a:
|
||||
cd ../src/rust && \
|
||||
CARGO_TARGET_DIR=../../linux/rust $(CARGO) build $(HARDSUBX_FEATURE_RUST) $(CARGO_RELEASE_ARGS);
|
||||
|
||||
EXTRA_DIST = ../src/thirdparty/gpacmp4/gpac/sync_layer.h ../src/lib_ccx/ccfont2.xbm ../src/thirdparty/utf8proc/utf8proc_data.c fonts/ icon/
|
||||
|
||||
|
||||
@@ -84,7 +84,13 @@ else
|
||||
fi
|
||||
|
||||
echo "Building rust files..."
|
||||
(cd ../src/rust && CARGO_TARGET_DIR=../../linux/rust cargo build) || { echo "Failed. " ; exit 1; }
|
||||
echo "${BLD_FLAGS}"
|
||||
tokens=( ${BLD_FLAGS} )
|
||||
if [ ${tokens[0]} = "-DENABLE_HARDSUBX" ]; then
|
||||
(cd ../src/rust && CARGO_TARGET_DIR=../../linux/rust cargo build --features "hardsubx_ocr") || { echo "Failed. " ; exit 1; }
|
||||
else
|
||||
(cd ../src/rust && CARGO_TARGET_DIR=../../linux/rust cargo build) || { echo "Failed. " ; exit 1; }
|
||||
fi
|
||||
cp rust/debug/libccx_rust.a ./libccx_rust.a
|
||||
fi
|
||||
|
||||
|
||||
@@ -331,22 +331,6 @@ ccextractor_CPPFLAGS =-I../src/lib_ccx/ -I../src/thirdparty/gpacmp4/ -I../src/th
|
||||
|
||||
ccextractor_LDADD=-lm -lpthread -ldl
|
||||
|
||||
if WITH_RUST
|
||||
ccextractor_LDADD += ./rust/@RUST_TARGET_SUBDIR@/libccx_rust.a
|
||||
else
|
||||
ccextractor_CFLAGS += -DDISABLE_RUST
|
||||
ccextractor_CPPFLAGS += -DDISABLE_RUST
|
||||
endif
|
||||
|
||||
if DEBUG_RELEASE
|
||||
CARGO_RELEASE_ARGS=
|
||||
else
|
||||
CARGO_RELEASE_ARGS=--release
|
||||
endif
|
||||
|
||||
./rust/@RUST_TARGET_SUBDIR@/libccx_rust.a:
|
||||
cd ../src/rust && \
|
||||
CARGO_TARGET_DIR=../../linux/rust $(CARGO) build $(CARGO_RELEASE_ARGS);
|
||||
|
||||
if SYS_IS_LINUX
|
||||
ccextractor_CFLAGS += -O3 -s -DGPAC_CONFIG_LINUX
|
||||
@@ -361,6 +345,8 @@ 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}
|
||||
@@ -372,6 +358,7 @@ 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
|
||||
@@ -398,4 +385,22 @@ ccextractor_LDADD += $(TESS_LIB)
|
||||
ccextractor_LDADD += $(LEPT_LIB)
|
||||
endif
|
||||
|
||||
if WITH_RUST
|
||||
ccextractor_LDADD += ./rust/@RUST_TARGET_SUBDIR@/libccx_rust.a
|
||||
else
|
||||
ccextractor_CFLAGS += -DDISABLE_RUST
|
||||
ccextractor_CPPFLAGS += -DDISABLE_RUST
|
||||
endif
|
||||
|
||||
if DEBUG_RELEASE
|
||||
CARGO_RELEASE_ARGS=
|
||||
else
|
||||
CARGO_RELEASE_ARGS=--release
|
||||
endif
|
||||
|
||||
./rust/@RUST_TARGET_SUBDIR@/libccx_rust.a:
|
||||
cd ../src/rust && \
|
||||
CARGO_TARGET_DIR=../../linux/rust $(CARGO) build $(HARDSUBX_FEATURE_RUST) $(CARGO_RELEASE_ARGS);
|
||||
|
||||
EXTRA_DIST = ../src/thirdparty/gpacmp4/gpac/sync_layer.h ../src/lib_ccx/ccfont2.xbm ../src/thirdparty/utf8proc/utf8proc_data.c fonts/ icon/
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "lib_ccx.h"
|
||||
#include "utility.h"
|
||||
|
||||
#ifdef ENABLE_HARDSUBX
|
||||
#if defined(ENABLE_HARDSUBX) && defined(DISABLE_RUST)
|
||||
//TODO: Correct FFMpeg integration
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavformat/avformat.h>
|
||||
|
||||
@@ -1,8 +1,16 @@
|
||||
if (WITH_OCR AND WITH_HARDSUBX)
|
||||
set(FEATURE_ARG "\"hardsubx_ocr\"")
|
||||
set(FEATURE_FLAG "--features")
|
||||
else ()
|
||||
set(FEATURE_ARG "")
|
||||
set(FEATURE_FLAG "")
|
||||
endif ()
|
||||
|
||||
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
set(CARGO_CMD cargo build)
|
||||
set(CARGO_CMD cargo build ${FEATURE_FLAG} ${FEATURE_ARG})
|
||||
set(TARGET_DIR "debug")
|
||||
else ()
|
||||
set(CARGO_CMD cargo build --release)
|
||||
set(CARGO_CMD cargo build ${FEATURE_FLAG} ${FEATURE_ARG} --release)
|
||||
set(TARGET_DIR "release")
|
||||
endif ()
|
||||
|
||||
|
||||
93
src/rust/Cargo.lock
generated
93
src/rust/Cargo.lock
generated
@@ -53,7 +53,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0f8523b410d7187a43085e7e064416ea32ded16bd0a4e6fc025e21616d01258f"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cexpr",
|
||||
"cexpr 0.4.0",
|
||||
"clang-sys",
|
||||
"clap",
|
||||
"env_logger",
|
||||
@@ -69,18 +69,44 @@ dependencies = [
|
||||
"which",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bindgen"
|
||||
version = "0.59.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2bd2a9a458e8f4304c52c43ebb0cfbd520289f8379a52e329a38afda99bf8eb8"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cexpr 0.6.0",
|
||||
"clang-sys",
|
||||
"lazy_static",
|
||||
"lazycell",
|
||||
"peeking_take_while",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"regex",
|
||||
"rustc-hash",
|
||||
"shlex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.73"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
|
||||
|
||||
[[package]]
|
||||
name = "ccx_rust"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bindgen",
|
||||
"bindgen 0.58.1",
|
||||
"env_logger",
|
||||
"ffmpeg-sys-next",
|
||||
"iconv",
|
||||
"log",
|
||||
"palette",
|
||||
@@ -92,7 +118,16 @@ version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4aedb84272dbe89af497cf81375129abda4fc0a9e7c5d317498c15cc30c0d27"
|
||||
dependencies = [
|
||||
"nom",
|
||||
"nom 5.1.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cexpr"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
|
||||
dependencies = [
|
||||
"nom 7.1.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -146,6 +181,20 @@ dependencies = [
|
||||
"termcolor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ffmpeg-sys-next"
|
||||
version = "5.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ba12dea33516e30c160ce557c7e43dd857276368eb1cd0eef4fce6529f2dee5"
|
||||
dependencies = [
|
||||
"bindgen 0.59.2",
|
||||
"cc",
|
||||
"libc",
|
||||
"num_cpus",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "find-crate"
|
||||
version = "0.6.3"
|
||||
@@ -240,6 +289,12 @@ version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc"
|
||||
|
||||
[[package]]
|
||||
name = "minimal-lexical"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
||||
|
||||
[[package]]
|
||||
name = "nom"
|
||||
version = "5.1.2"
|
||||
@@ -250,6 +305,16 @@ dependencies = [
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nom"
|
||||
version = "7.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"minimal-lexical",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.15"
|
||||
@@ -259,6 +324,16 @@ dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
version = "1.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "palette"
|
||||
version = "0.6.0"
|
||||
@@ -333,6 +408,12 @@ dependencies = [
|
||||
"siphasher",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae"
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.16"
|
||||
@@ -490,6 +571,12 @@ version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
|
||||
|
||||
[[package]]
|
||||
name = "vcpkg"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
||||
|
||||
[[package]]
|
||||
name = "vec_map"
|
||||
version = "0.8.2"
|
||||
|
||||
@@ -15,6 +15,10 @@ log = "0.4.0"
|
||||
env_logger = "0.8.4"
|
||||
iconv = "0.1.1"
|
||||
palette = "0.6.0"
|
||||
ffmpeg-sys-next = { version = "5.0.1", optional = true, default-features = false, features = ["avcodec", "build"]}
|
||||
|
||||
[build-dependencies]
|
||||
bindgen = "0.58.1"
|
||||
bindgen = "0.58.1"
|
||||
|
||||
[features]
|
||||
hardsubx_ocr = ["ffmpeg-sys-next"]
|
||||
|
||||
@@ -2,19 +2,42 @@ use std::env;
|
||||
use std::path::PathBuf;
|
||||
|
||||
fn main() {
|
||||
let mut allowlist_functions = vec![
|
||||
".*(?i)_?dtvcc_.*",
|
||||
"get_visible_.*",
|
||||
"get_fts",
|
||||
"printdata",
|
||||
"writercwtdata",
|
||||
];
|
||||
|
||||
#[cfg(feature = "hardsubx_ocr")]
|
||||
allowlist_functions.extend_from_slice(&["edit_distance", "convert_pts_to_.*", "av_rescale_q"]);
|
||||
|
||||
let mut allowlist_types = vec![".*(?i)_?dtvcc_.*", "encoder_ctx", "lib_cc_decode"];
|
||||
|
||||
#[cfg(feature = "hardsubx_ocr")]
|
||||
allowlist_types.extend_from_slice(&["AVRational"]);
|
||||
|
||||
let mut builder = bindgen::Builder::default()
|
||||
// The input header we would like to generate
|
||||
// bindings for.
|
||||
.header("wrapper.h")
|
||||
// Tell cargo to invalidate the built crate whenever any of the
|
||||
// included header files changed.
|
||||
.parse_callbacks(Box::new(bindgen::CargoCallbacks));
|
||||
.header("wrapper.h");
|
||||
|
||||
for type_name in ALLOWLIST_TYPES {
|
||||
// enable hardsubx if and only if the feature is on
|
||||
#[cfg(feature = "hardsubx_ocr")]
|
||||
{
|
||||
builder = builder.clang_arg("-DENABLE_HARDSUBX");
|
||||
}
|
||||
|
||||
// Tell cargo to invalidate the built crate whenever any of the
|
||||
// included header files changed.
|
||||
builder = builder.parse_callbacks(Box::new(bindgen::CargoCallbacks));
|
||||
|
||||
for type_name in allowlist_types {
|
||||
builder = builder.allowlist_type(type_name);
|
||||
}
|
||||
|
||||
for fn_name in ALLOWLIST_FUNCTIONS {
|
||||
for fn_name in allowlist_functions {
|
||||
builder = builder.allowlist_function(fn_name);
|
||||
}
|
||||
|
||||
@@ -35,12 +58,4 @@ fn main() {
|
||||
.expect("Couldn't write bindings!");
|
||||
}
|
||||
|
||||
const ALLOWLIST_FUNCTIONS: &[&str] = &[
|
||||
".*(?i)_?dtvcc_.*",
|
||||
"get_visible_.*",
|
||||
"get_fts",
|
||||
"printdata",
|
||||
"writercwtdata",
|
||||
];
|
||||
const ALLOWLIST_TYPES: &[&str] = &[".*(?i)_?dtvcc_.*", "encoder_ctx", "lib_cc_decode"];
|
||||
const RUSTIFIED_ENUMS: &[&str] = &["dtvcc_(window|pen)_.*", "ccx_output_format"];
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
pub mod imgops;
|
||||
pub mod utility;
|
||||
|
||||
88
src/rust/src/hardsubx/utility.rs
Normal file
88
src/rust/src/hardsubx/utility.rs
Normal file
@@ -0,0 +1,88 @@
|
||||
#[cfg(feature = "hardsubx_ocr")]
|
||||
use ffmpeg_sys_next::*;
|
||||
use std::os::raw::{c_char, c_int};
|
||||
use std::{cmp, ffi};
|
||||
|
||||
const AV_TIME_BASE: i32 = 1000000;
|
||||
const AV_TIME_BASE_Q: AVRational = AVRational {
|
||||
num: 1,
|
||||
den: AV_TIME_BASE,
|
||||
};
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn convert_pts_to_ns(pts: i64, time_base: AVRational) -> i64 {
|
||||
unsafe { av_rescale_q(pts, time_base, AV_TIME_BASE_Q) }
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn convert_pts_to_ms(pts: i64, time_base: AVRational) -> i64 {
|
||||
unsafe { av_rescale_q(pts, time_base, AV_TIME_BASE_Q) / 1000 }
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn convert_pts_to_s(pts: i64, time_base: AVRational) -> i64 {
|
||||
unsafe { av_rescale_q(pts, time_base, AV_TIME_BASE_Q) / 1000000 }
|
||||
}
|
||||
|
||||
fn _edit_distance_rec(
|
||||
word1: &[u8],
|
||||
word2: &[u8],
|
||||
i: usize,
|
||||
j: usize,
|
||||
dp_array: &mut Vec<Vec<i32>>,
|
||||
) -> i32 {
|
||||
// Recursive implementation with DP of Levenshtein distance
|
||||
|
||||
if dp_array.is_empty() || dp_array[0].is_empty() {
|
||||
// in case word1 or word2 has length 0
|
||||
|
||||
cmp::max(i as i32, j as i32)
|
||||
} else if dp_array[i][j] != -1 {
|
||||
dp_array[i][j]
|
||||
} else if cmp::min(i, j) == 0 {
|
||||
dp_array[i][j] = cmp::max(i as i32, j as i32);
|
||||
cmp::max(i as i32, j as i32)
|
||||
} else {
|
||||
let length_branch_one = _edit_distance_rec(word1, word2, i - 1, j, dp_array) + 1;
|
||||
let length_branch_two = _edit_distance_rec(word1, word2, i, j - 1, dp_array) + 1;
|
||||
|
||||
let length_branch_three = _edit_distance_rec(word1, word2, i - 1, j - 1, dp_array)
|
||||
+ if word1[i - 1] == word2[j - 1] { 0 } else { 1 };
|
||||
dp_array[i][j] = cmp::min(
|
||||
length_branch_one,
|
||||
cmp::min(length_branch_two, length_branch_three),
|
||||
);
|
||||
dp_array[i][j]
|
||||
}
|
||||
}
|
||||
|
||||
/// # Safety
|
||||
///
|
||||
/// Function deals with C string pointers
|
||||
/// which might be null
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn edit_distance(
|
||||
word1: *mut c_char,
|
||||
word2: *mut c_char,
|
||||
len1: c_int,
|
||||
len2: c_int,
|
||||
) -> c_int {
|
||||
// The actual edit_distance function
|
||||
|
||||
let word1_string: &ffi::CStr = ffi::CStr::from_ptr(word1);
|
||||
let word2_string: &ffi::CStr = ffi::CStr::from_ptr(word2);
|
||||
|
||||
let len1 = len1 as usize;
|
||||
let len2 = len2 as usize;
|
||||
|
||||
let mut dp_array = vec![vec![-1; len2 + 1]; len1 + 1];
|
||||
|
||||
_edit_distance_rec(
|
||||
word1_string.to_bytes(),
|
||||
word2_string.to_bytes(),
|
||||
len1,
|
||||
len2,
|
||||
&mut dp_array,
|
||||
) as c_int
|
||||
}
|
||||
@@ -13,6 +13,7 @@ pub mod bindings {
|
||||
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
|
||||
}
|
||||
pub mod decoder;
|
||||
#[cfg(feature = "hardsubx_ocr")]
|
||||
pub mod hardsubx;
|
||||
pub mod utils;
|
||||
|
||||
|
||||
@@ -4,4 +4,5 @@
|
||||
#include "../lib_ccx/ccx_decoders_708_output.h"
|
||||
#include "../lib_ccx/ccx_decoders_708_encoding.h"
|
||||
#include "../lib_ccx/ccx_common_timing.h"
|
||||
#include "../lib_ccx/lib_ccx.h"
|
||||
#include "../lib_ccx/lib_ccx.h"
|
||||
#include "../lib_ccx/hardsubx.h"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
for /f "delims=" %%i in ('cd') do set output=%%i
|
||||
set CARGO_TARGET_DIR=%output%
|
||||
cd ..\src\rust
|
||||
cargo build --target=i686-pc-windows-msvc
|
||||
cargo build --target=i686-pc-windows-msvc --features "hardsubx_ocr"
|
||||
cd ..\..\windows
|
||||
copy i686-pc-windows-msvc\debug\ccx_rust.lib .\ccx_rust.lib
|
||||
Reference in New Issue
Block a user