diff --git a/src/rust/Cargo.lock b/src/rust/Cargo.lock index a0791d014..5c48490bd 100644 --- a/src/rust/Cargo.lock +++ b/src/rust/Cargo.lock @@ -160,9 +160,12 @@ checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c" [[package]] name = "cc" -version = "1.0.79" +version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +checksum = "6c6b2562119bf28c3439f7f02db99faf0aa1a8cdfe5772a2ee155d32227239f0" +dependencies = [ + "libc", +] [[package]] name = "ccx_rust" @@ -176,6 +179,8 @@ dependencies = [ "log", "palette", "rsmpeg", + "strum", + "strum_macros", "tesseract-sys", ] @@ -261,7 +266,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.27", + "syn 2.0.28", ] [[package]] @@ -303,9 +308,9 @@ dependencies = [ [[package]] name = "errno" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +checksum = "6b30f669a7961ef1631673d2766cc92f52d64f7ef354d4fe0ddfd30ed52f0f4f" dependencies = [ "errno-dragonfly", "libc", @@ -399,9 +404,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "leptonica-sys" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09dd47056f65626f6e62bfa695d44275d115fdbe04adf2162b3e047439f6c264" +checksum = "eff3f1dc2f0112411228f8db99ca8a6a1157537a7887b28b1c91fdc4051fb326" dependencies = [ "bindgen 0.64.0", "pkg-config", @@ -426,9 +431,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.4.3" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09fc20d2ca12cb9f044c93e3bd6d32d523e6e2ec3db4f7b2939cd99026ecd3f0" +checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503" [[package]] name = "log" @@ -549,7 +554,7 @@ dependencies = [ "phf_shared", "proc-macro2", "quote", - "syn 2.0.27", + "syn 2.0.28", ] [[package]] @@ -614,9 +619,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39354c10dd07468c2e73926b23bb9c2caca74c5501e38a35da70406f1d923310" +checksum = "b7b6d6190b7594385f61bd3911cd1be99dfddcfc365a4160cc2ab5bff4aed294" dependencies = [ "aho-corasick", "memchr", @@ -649,9 +654,9 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustix" -version = "0.38.4" +version = "0.38.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a962918ea88d644592894bc6dc55acc6c0956488adcebbfb6e273506b7fd6e5" +checksum = "1ee020b1716f0a80e2ace9b03441a749e402e86712f15f16fe8a8f75afac732f" dependencies = [ "bitflags 2.3.3", "errno", @@ -660,6 +665,12 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "rustversion" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + [[package]] name = "rusty_ffmpeg" version = "0.13.1+ffmpeg.6.0" @@ -676,9 +687,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.175" +version = "1.0.180" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d25439cd7397d044e2748a6fe2432b5e85db703d6d097bd014b3c0ad1ebff0b" +checksum = "0ea67f183f058fe88a4e3ec6e2788e003840893b91bac4559cabedd00863b3ed" [[package]] name = "shlex" @@ -704,6 +715,25 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "strum" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" + +[[package]] +name = "strum_macros" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6069ca09d878a33f883cc06aaa9718ede171841d3832450354410b718b097232" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.28", +] + [[package]] name = "syn" version = "1.0.109" @@ -717,9 +747,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.27" +version = "2.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b60f673f44a8255b9c8c657daf66a596d435f2da81a555b06dc644d080ba45e0" +checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567" dependencies = [ "proc-macro2", "quote", @@ -773,7 +803,7 @@ checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96" dependencies = [ "proc-macro2", "quote", - "syn 2.0.27", + "syn 2.0.28", ] [[package]] diff --git a/src/rust/Cargo.toml b/src/rust/Cargo.toml index 7fac61949..f8bb4a69c 100644 --- a/src/rust/Cargo.toml +++ b/src/rust/Cargo.toml @@ -15,14 +15,17 @@ log = "0.4.0" env_logger = "0.8.4" iconv = "0.1.1" palette = "0.6.0" -rsmpeg = { version = "0.14.1", optional = true, features = ["link_system_ffmpeg"] } -tesseract-sys = { version = "0.5.14", optional = true, default-features = false} -leptonica-sys = { version = "0.4.3", optional = true, default-features = false} +rsmpeg = { version = "0.14.1", optional = true, features = [ + "link_system_ffmpeg", +] } +tesseract-sys = { version = "0.5.14", optional = true, default-features = false } +leptonica-sys = { version = "0.4.3", optional = true, default-features = false } clap = { version = "4.3.19", features = ["derive"] } +strum = "0.25" +strum_macros = "0.25" [build-dependencies] bindgen = "0.58.1" [features] hardsubx_ocr = ["rsmpeg", "tesseract-sys", "leptonica-sys"] - diff --git a/src/rust/src/args.rs b/src/rust/src/args.rs index dc3d972b5..1c04d4208 100644 --- a/src/rust/src/args.rs +++ b/src/rust/src/args.rs @@ -1,4 +1,5 @@ use clap::{Parser, ValueEnum}; +use strum_macros::Display; const FILE_NAME_RELATED_OPTIONS: &str = "File name related options"; const OUTPUT_FILE_SEGMENTATION: &str = "Output File Segmentation"; @@ -24,7 +25,7 @@ const COMMUNICATION_PROTOCOL: &str = "Communication with other programs and cons // const SPUPNG_NOTES: &str= "Notes on spupng output format"; const BURNEDIN_SUBTITLE_EXTRACTION: &str = "Burned-in subtitle extraction"; -#[derive(Parser)] +#[derive(Debug, Parser)] #[command(name = "CCExtractor")] #[command(author = "Carlos Fernandez Sanz, Volker Quetschke.")] #[command(version = "0.94")] @@ -41,7 +42,8 @@ http://www.ccextractor.org .mp4, HDHomeRun are known to work). Syntax: - ccextractor [options] inputfile1 [inputfile2...] [-o outputfilename]")] + ccextractor [options] inputfile1 [inputfile2...] [-o outputfilename] +")] #[command( help_template = "{name} {version}, {author}.\n{about}\n {all-args} {tab}\n An example command for burned-in subtitle extraction is as follows: @@ -50,102 +52,136 @@ http://www.ccextractor.org #[command(arg_required_else_help = true)] pub struct Args { /// file(s) to process - #[arg(value_name="inputfile", help_heading=FILE_NAME_RELATED_OPTIONS)] - inputfile: Vec, + #[arg(value_name = "inputfile")] + pub inputfile: Vec, /// Use -o parameters to define output filename if you don't /// like the default ones (same as infile plus _1 or _2 when /// needed and file extension, e.g. .srt). #[arg(short, value_name="outputfilename", verbatim_doc_comment, help_heading=FILE_NAME_RELATED_OPTIONS)] - output: Option, + pub output: Option, /// Write output to stdout (console) instead of file. If /// stdout is used, then -o can't be used. Also /// --stdout will redirect all messages to stderr (error). #[arg(long, verbatim_doc_comment, help_heading=FILE_NAME_RELATED_OPTIONS)] - stdout: bool, + pub stdout: bool, /// Dump the PES Header to stdout (console). This is /// used for debugging purposes to see the contents /// of each PES packet header. #[arg(long, verbatim_doc_comment, help_heading=FILE_NAME_RELATED_OPTIONS)] - pesheader: bool, + pub pesheader: bool, /// Write the DVB subtitle debug traces to console. #[arg(long, help_heading=FILE_NAME_RELATED_OPTIONS)] - debugdvdsub: bool, + pub debugdvdsub: bool, /// Ignore PTS jumps (default). #[arg(long, help_heading=FILE_NAME_RELATED_OPTIONS)] - ignoreptsjumps: bool, + pub ignoreptsjumps: bool, /// fix pts jumps. Use this parameter if you /// experience timeline resets/jumps in the output. #[arg(long, verbatim_doc_comment, help_heading=FILE_NAME_RELATED_OPTIONS)] - fixptsjumps: bool, + pub fixptsjumps: bool, /// Reads input from stdin (console) instead of file. /// Alternatively, - can be used instead of --stdin #[arg(long, verbatim_doc_comment, help_heading=FILE_NAME_RELATED_OPTIONS)] - stdin: bool, + pub stdin: bool, #[arg(long, value_name="x", help_heading=OUTPUT_FILE_SEGMENTATION)] - outinterval: Option, + pub outinterval: Option, /// When segmenting files, do it only after a I frame /// trying to behave like FFmpeg #[arg(long, verbatim_doc_comment, help_heading=OUTPUT_FILE_SEGMENTATION)] - segmentonkeyonly: bool, + pub segmentonkeyonly: bool, /// Read the input via UDP (listening in the specified port) /// instead of reading a file. #[arg(long, value_name="port", verbatim_doc_comment, help_heading=NETWORK_SUPPORT)] - udp: Option, + pub udp: Option, /// Read the input via UDP (listening in the specified port) /// instead of reading a file. #[arg(long, value_name="port", verbatim_doc_comment, help_heading=NETWORK_SUPPORT)] - host: Option, + pub host: Option, /// Can be a hostname or IPv4 address. #[arg(long, value_name="port", verbatim_doc_comment, help_heading=NETWORK_SUPPORT)] - src: Option, + pub src: Option, /// Sends data in BIN format to the server /// according to the CCExtractor's protocol over /// TCP. For IPv6 use [address] instead #[arg(long, value_name="port", verbatim_doc_comment, help_heading=NETWORK_SUPPORT)] + pub sendto: Option, /// Specfies optional port for sendto - sendto: Option, #[arg(long, value_name="port", verbatim_doc_comment, help_heading=NETWORK_SUPPORT)] - sendto_port: Option, - /// Reads the input data in BIN format according to + pub sendto_port: Option, + /// Reads the input da`ta in BIN format according to /// CCExtractor's protocol, listening specified port on the /// local host #[arg(long, value_name="port", verbatim_doc_comment, help_heading=NETWORK_SUPPORT)] - tcp: Option, + pub tcp: Option, /// Sets server password for new connections to /// tcp server #[arg(long, value_name="port", verbatim_doc_comment, help_heading=NETWORK_SUPPORT)] - tcp_password: Option, + pub tcp_password: Option, /// Sends to the server short description about /// captions e.g. channel name or file name #[arg(long, value_name="port", verbatim_doc_comment, help_heading=NETWORK_SUPPORT)] - tcp_description: Option, + pub tcp_description: Option, /// With the exception of McPoodle's raw format, which is just the closed /// caption data with no other info, CCExtractor can usually detect the /// input format correctly. Use this parameter to override the detected #[arg(long, value_name="format",verbatim_doc_comment, help_heading=INPUT_FORMATS)] - input: Option, + pub input: Option, + #[arg(long, hide = true)] + pub es: bool, + #[arg(long, hide = true)] + pub ts: bool, + #[arg(long, hide = true)] + pub ps: bool, + #[arg(long, hide = true)] + pub asf: bool, + #[arg(long, hide = true)] + pub wtv: bool, + #[arg(long, hide = true)] + pub mp4: bool, + #[arg(long, hide = true)] + pub mkv: bool, + #[arg(long, hide = true)] + pub dvr_ms: bool, #[arg(long, value_name="format", help_heading=OUTPUT_FORMATS)] - out: Option, + pub out: Option, + #[arg(long, hide = true)] + pub srt: bool, + #[arg(long, hide = true)] + pub webvtt: bool, + #[arg(long, hide = true)] + pub sami: bool, + #[arg(long, hide = true)] + pub smi: bool, + #[arg(long, hide = true)] + pub dvdraw: bool, + #[arg(long, hide = true)] + pub mcc: bool, + #[arg(long, hide = true)] + pub txt: bool, + #[arg(long, hide = true)] + pub ttxt: bool, + #[arg(long, hide = true)] + pub null: bool, /// Use GOP for timing instead of PTS. This only applies /// to Program or Transport Streams with MPEG2 data and /// overrides the default PTS timing. /// GOP timing is always used for Elementary Streams. #[arg(long, verbatim_doc_comment, help_heading=OPTIONS_AFFECTING_INPUT_FILES)] - goptime: bool, + pub goptime: bool, /// Never use GOP timing (use PTS), even if ccextractor /// detects GOP timing is the reasonable choice. #[arg(long, verbatim_doc_comment, conflicts_with="goptime", help_heading=OPTIONS_AFFECTING_INPUT_FILES)] - no_goptime: bool, + pub no_goptime: bool, /// Fix padding - some cards (or providers, or whatever) /// seem to send 0000 as CC padding instead of 8080. If you /// get bad timing, this might solve it. #[arg(long, verbatim_doc_comment, help_heading=OPTIONS_AFFECTING_INPUT_FILES)] - fixpadding: bool, + pub fixpadding: bool, /// Use 90090 (instead of 90000) as MPEG clock frequency. /// (reported to be needed at least by Panasonic DMR-ES15 /// DVD Recorder) #[arg(long="90090", verbatim_doc_comment, help_heading=OPTIONS_AFFECTING_INPUT_FILES)] - mpeg90090: bool, + pub mpeg90090: bool, /// By default, ccextractor will process input files in /// sequence as if they were all one large file (i.e. /// split by a generic, non video-aware tool. If you @@ -153,7 +189,7 @@ pub struct Args { /// tool, use --videoedited so ccextractor doesn't try to rebuild /// the original timing. #[arg(long, verbatim_doc_comment, help_heading=OPTIONS_AFFECTING_INPUT_FILES)] - videoedited: bool, + pub videoedited: bool, /// Consider the file as a continuous stream that is /// growing as ccextractor processes it, so don't try /// to figure out its size and don't terminate processing @@ -166,16 +202,16 @@ pub struct Args { /// Note: If --s is used then only one input file is /// allowed. #[arg(short, long, verbatim_doc_comment, help_heading=OPTIONS_AFFECTING_INPUT_FILES)] - stream: Option, + pub stream: Option, /// Use the pic_order_cnt_lsb in AVC/H.264 data streams /// to order the CC information. The default way is to /// use the PTS information. Use this switch only when /// needed. #[arg(long, verbatim_doc_comment, help_heading=OPTIONS_AFFECTING_INPUT_FILES)] - usepicorder: bool, + pub usepicorder: bool, /// Force MythTV code branch. #[arg(long, verbatim_doc_comment, help_heading=OPTIONS_AFFECTING_INPUT_FILES)] - myth: bool, + pub myth: bool, /// Disable MythTV code branch. /// The MythTV branch is needed for analog captures where /// the closed caption data is stored in the VBI, such as @@ -183,17 +219,17 @@ pub struct Args { /// is detected automatically so you don't need to worry /// about this unless autodetection doesn't work for you. #[arg(long, verbatim_doc_comment, conflicts_with="myth", help_heading=OPTIONS_AFFECTING_INPUT_FILES)] - no_myth: bool, + pub no_myth: bool, /// This switch works around a bug in Windows 7's built in /// software to convert *.wtv to *.dvr-ms. For analog NTSC /// recordings the CC information is marked as digital /// captions. Use this switch only when needed. #[arg(long, verbatim_doc_comment, help_heading=OPTIONS_AFFECTING_INPUT_FILES)] - wtvconvertfix: bool, + pub wtvconvertfix: bool, /// Read the captions from the MPEG2 video stream rather /// than the captions stream in WTV files #[arg(long, verbatim_doc_comment, help_heading=OPTIONS_AFFECTING_INPUT_FILES)] - wtvmpeg2: bool, + pub wtvmpeg2: bool, /// In TS mode, specifically select a program to process. /// Not needed if the TS only has one. If this parameter /// is not specified and CCExtractor detects more than one @@ -201,55 +237,55 @@ pub struct Args { /// and terminate without doing anything, unless /// --autoprogram (see below) is used. #[arg(long, verbatim_doc_comment, help_heading=OPTIONS_AFFECTING_INPUT_FILES)] - program_number: Option, + pub program_number: Option, /// If there's more than one program in the stream, just use /// the first one we find that contains a suitable stream. #[arg(long, verbatim_doc_comment, help_heading=OPTIONS_AFFECTING_INPUT_FILES)] - autoprogram: bool, + pub autoprogram: bool, /// Uses multiple programs from the same input stream. #[arg(long, verbatim_doc_comment, help_heading=OPTIONS_AFFECTING_INPUT_FILES)] - multiprogram: bool, + pub multiprogram: bool, /// Don't try to find out the stream for caption/teletext /// data, just use this one instead. #[arg(long, verbatim_doc_comment, help_heading=OPTIONS_AFFECTING_INPUT_FILES)] - datapid: Option, + pub datapid: Option, /// Instead of selecting the stream by its PID, select it /// by its type (pick the stream that has this type in /// the PMT) #[arg(long, verbatim_doc_comment, help_heading=OPTIONS_AFFECTING_INPUT_FILES)] - datastreamtype: Option, + pub datastreamtype: Option, /// Assume the data is of this type, don't autodetect. This /// parameter may be needed if --datapid or --datastreamtype /// is used and CCExtractor cannot determine how to process /// the stream. The value will usually be 2 (MPEG video) or /// 6 (MPEG private data). #[arg(long, verbatim_doc_comment, help_heading=OPTIONS_AFFECTING_INPUT_FILES)] - streamtype: Option, + pub streamtype: Option, /// If the video was recorder using a Hauppauge card, it /// might need special processing. This parameter will /// force the special treatment. #[arg(long, verbatim_doc_comment, help_heading=OPTIONS_AFFECTING_INPUT_FILES)] - hauppauge: bool, + pub hauppauge: bool, /// In MP4 files the closed caption data can be embedded in /// the video track or in a dedicated CC track. If a /// dedicated track is detected it will be processed instead /// of the video track. If you need to force the video track /// to be processed instead use this option. #[arg(long, verbatim_doc_comment, help_heading=OPTIONS_AFFECTING_INPUT_FILES)] - mp4vidtrack: Option, + pub mp4vidtrack: Option, /// Some streams come with broadcast date information. When /// such data is available, CCExtractor will set its time /// reference to the received data. Use this parameter if /// you prefer your own reference. Note: Current this only /// affects Teletext in timed transcript with --datets. #[arg(long, verbatim_doc_comment, help_heading=OPTIONS_AFFECTING_INPUT_FILES)] - no_autotimeref: bool, + pub no_autotimeref: bool, /// Ignore SCTE-20 data if present. #[arg(long, verbatim_doc_comment, help_heading=OPTIONS_AFFECTING_INPUT_FILES)] - no_scte20: bool, + pub no_scte20: bool, /// Create a separate file for CSS instead of inline. #[arg(long, verbatim_doc_comment, help_heading=OPTIONS_AFFECTING_INPUT_FILES)] - webvtt_create_css: bool, + pub webvtt_create_css: bool, /// Enable debug so the calculated distance for each two /// strings is displayed. The output includes both strings, /// the calculated distance, the maximum allowed distance, @@ -257,23 +293,23 @@ pub struct Args { /// equivalent or not, i.e. the calculated distance is /// less or equal than the max allowed. #[arg(long, verbatim_doc_comment, help_heading=OPTIONS_AFFECTING_INPUT_FILES)] - deblev: bool, + pub deblev: bool, /// Analyze the video stream even if it's not used for /// subtitles. This allows to provide video information. #[arg(long, verbatim_doc_comment, help_heading=OPTIONS_AFFECTING_INPUT_FILES)] - analyzevideo: bool, + pub analyzevideo: bool, /// Enable the X-TIMESTAMP-MAP header for WebVTT (HLS) #[arg(long, verbatim_doc_comment, help_heading=OPTIONS_AFFECTING_INPUT_FILES)] - timestamp_map: bool, + pub timestamp_map: bool, /// Don't attempt to correct typos with Levenshtein distance. #[arg(long, verbatim_doc_comment, help_heading=LEVENSHTEIN_DISTANCE)] - no_levdist: bool, + pub no_levdist: bool, /// 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. #[arg(long, value_name="value", verbatim_doc_comment, help_heading=LEVENSHTEIN_DISTANCE)] - levdistmincnt: Option, + pub levdistmincnt: Option, /// Maximum distance we allow, as a percentage of /// the shortest string length. Default 10%.0 /// For example, consider a comparison of one string of @@ -286,55 +322,55 @@ pub struct Args { /// percentage is 10%, we would allow a distance of up /// to 3 between the first 30 characters. #[arg(long, value_name="value", verbatim_doc_comment, help_heading=LEVENSHTEIN_DISTANCE)] - levdistmaxpct: Option, + pub levdistmaxpct: Option, /// (Experimental) Produces a chapter file from MP4 files. /// Note that this must only be used with MP4 files, /// for other files it will simply generate subtitles file. #[arg(long, verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_OUTPUT_FILES)] - chapters: bool, + pub chapters: bool, /// Append a BOM (Byte Order Mark) to output files. /// Note that most text processing tools in linux will not /// like BOM. #[arg(long, verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_OUTPUT_FILES)] - bom: bool, + pub bom: bool, /// Do not append a BOM (Byte Order Mark) to output /// files. Note that this may break files when using /// Windows. This is the default in non-Windows builds. #[arg(long, verbatim_doc_comment, conflicts_with="bom", help_heading=OUTPUT_AFFECTING_OUTPUT_FILES)] - no_bom: bool, + pub no_bom: bool, /// Encode subtitles in Unicode instead of Latin-1. #[arg(long, verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_OUTPUT_FILES)] - unicode: bool, + pub unicode: bool, /// Encode subtitles in UTF-8 (no longer needed. /// because UTF-8 is now the default). #[arg(long, verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_OUTPUT_FILES)] - utf8: bool, + pub utf8: bool, /// Encode subtitles in Latin-1 #[arg(long, verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_OUTPUT_FILES)] - latin1: bool, + pub latin1: bool, /// For .srt/.sami/.vtt, don't add font color tags. #[arg(long, verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_OUTPUT_FILES)] - no_fontcolor: bool, + pub no_fontcolor: bool, /// For .srt/.sami/.vtt, don't covert html unsafe character #[arg(long, verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_OUTPUT_FILES)] - no_htmlescape: bool, + pub no_htmlescape: bool, /// For .srt/.sami/.vtt, don't add typesetting tags. #[arg(long, verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_OUTPUT_FILES)] - no_typesetting: bool, + pub no_typesetting: bool, /// Trim lines. #[arg(long, verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_OUTPUT_FILES)] - trim: bool, + pub trim: bool, /// Select a different default color (instead of /// white). This causes all output in .srt/.smi/.vtt /// files to have a font tag, which makes the files /// larger. Add the color you want in RGB, such as /// --dc #FF0000 for red. #[arg(long, verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_OUTPUT_FILES)] - defaultcolor: Option, + pub defaultcolor: Option, /// Sentence capitalization. Use if you hate /// ALL CAPS in subtitles. #[arg(long, verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_OUTPUT_FILES)] - sentencecap: bool, + pub sentencecap: bool, /// Add the contents of 'file' to the list of words /// that must be capitalized. For example, if file /// is a plain text file that contains @@ -347,20 +383,20 @@ pub struct Args { /// Use one line per word. Lines starting with # are /// considered comments and discarded. #[arg(long, verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_OUTPUT_FILES)] - capfile: bool, + pub capfile: bool, /// Censors profane words from subtitles. #[arg(long, verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_OUTPUT_FILES)] - kf: bool, + pub kf: bool, /// Add the contents of to the list of words that. /// must be censored. The content of , follows the /// same syntax as for the capitalization file #[arg(long, verbatim_doc_comment, value_name="file", help_heading=OUTPUT_AFFECTING_OUTPUT_FILES)] - profanity_file: Option, + pub profanity_file: Option, /// Split output text so each frame contains a complete /// sentence. Timings are adjusted based on number of /// characters #[arg(long, verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_OUTPUT_FILES)] - splitbysentence: bool, + pub splitbysentence: bool, /// For timed transcripts that have an absolute date /// instead of a timestamp relative to the file start), use /// this time reference (UNIX timestamp). 0 => Use current @@ -368,64 +404,64 @@ pub struct Args { /// ccextractor will automatically switch to transport /// stream UTC timestamps when available. #[arg(long, verbatim_doc_comment, value_name="REF", help_heading=OUTPUT_AFFECTING_OUTPUT_FILES)] - unixts: Option, + pub unixts: Option, /// In transcripts, write time as YYYYMMDDHHMMss,ms. #[arg(long, verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_OUTPUT_FILES)] - datets: bool, + pub datets: bool, /// In transcripts, write time as ss,ms #[arg(long, verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_OUTPUT_FILES)] - sects: bool, + pub sects: bool, /// Transcripts are generated with a specific format /// that is convenient for a specific project, feel /// free to play with it but be aware that this format /// is really live - don't rely on its output format /// not changing between versions. #[arg(long="UCLA", verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_OUTPUT_FILES)] - ucla: bool, + pub ucla: bool, /// Map Latin symbols to Cyrillic ones in special cases /// of Russian Teletext files (issue #1086) #[arg(long, verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_OUTPUT_FILES)] - latrusmap: bool, + pub latrusmap: bool, /// In timed transcripts, all XDS information will be saved /// to the output file. #[arg(long, verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_OUTPUT_FILES)] - xds: bool, + pub xds: bool, /// Use LF (UNIX) instead of CRLF (DOS, Windows) as line /// terminator. #[arg(long, verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_OUTPUT_FILES)] - lf: bool, + pub lf: bool, /// For MCC Files, force dropframe frame count. #[arg(long, verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_OUTPUT_FILES)] - df: bool, + pub df: bool, /// Based on position on screen, attempt to determine /// the different speakers and a dash (-) when each /// of them talks (.srt/.vtt only, --trim required). #[arg(long, verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_OUTPUT_FILES)] - autodash: bool, + pub autodash: bool, /// produce an XMLTV file containing the EPG data from /// the source TS file. Mode: 1 = full output /// 2 = live output. 3 = both #[arg(long, verbatim_doc_comment, value_name="mode", help_heading=OUTPUT_AFFECTING_OUTPUT_FILES)] - xmltv: Option, + pub xmltv: Option, /// interval of x seconds between writing live mode xmltv output. #[arg(long, verbatim_doc_comment, value_name="x", help_heading=OUTPUT_AFFECTING_OUTPUT_FILES)] - xmltvliveinterval: Option, + pub xmltvliveinterval: Option, /// interval of x seconds between writing full file xmltv output. #[arg(long, verbatim_doc_comment, value_name="x", help_heading=OUTPUT_AFFECTING_OUTPUT_FILES)] - xmltvoutputinterval: Option, + pub xmltvoutputinterval: Option, /// Only print current events for xmltv output. #[arg(long, verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_OUTPUT_FILES)] - xmltvonlycurrent: bool, + pub xmltvonlycurrent: bool, /// Create a .sem file for each output file that is open /// and delete it on file close. #[arg(long, verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_OUTPUT_FILES)] - sem: bool, + pub sem: bool, /// For DVB subtitles, select which language's caption /// stream will be processed. e.g. 'eng' for English. /// If there are multiple languages, only this specified /// language stream will be processed (default). #[arg(long, verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_OUTPUT_FILES)] - dvblang: Option, + pub dvblang: Option, /// Manually select the name of the Tesseract .traineddata /// file. Helpful if you want to OCR a caption stream of /// one language with the data of another language. @@ -435,14 +471,14 @@ pub struct Args { /// This option is also helpful when the traineddata file /// has non standard names that don't follow ISO specs #[arg(long, verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_OUTPUT_FILES)] - ocrlang: Option, + pub ocrlang: Option, /// How to quantize the bitmap before passing it to tesseract /// for OCR'ing. /// 0: Don't quantize at all. /// 1: Use CCExtractor's internal function (default). /// 2: Reduce distinct color count in image for faster results. #[arg(long, verbatim_doc_comment, value_name="mode", help_heading=OUTPUT_AFFECTING_OUTPUT_FILES)] - quant: Option, + pub quant: Option, /// Select the OEM mode for Tesseract. /// Available modes : /// 0: OEM_TESSERACT_ONLY - the fastest mode. @@ -452,7 +488,7 @@ pub struct Args { /// Tesseract v3 : default mode is 0, /// Tesseract v4 : default mode is 1. #[arg(long, verbatim_doc_comment, value_name="mode", help_heading=OUTPUT_AFFECTING_OUTPUT_FILES)] - oem: Option, + pub oem: Option, /// For MKV subtitles, select which language's caption /// stream will be processed. e.g. 'eng' for English. /// Language codes can be either the 3 letters bibliographic @@ -460,53 +496,53 @@ pub struct Args { /// code followed by a dash and a country code for specialities /// in languages (like "fre-ca" for Canadian French). #[arg(long, verbatim_doc_comment, value_name="lang", help_heading=OUTPUT_AFFECTING_OUTPUT_FILES)] - mkvlang: Option, + pub mkvlang: Option, /// When processing DVB don't use the OCR to write the text as /// comments in the XML file. #[arg(long, verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_OUTPUT_FILES)] - no_spupngocr: bool, + pub no_spupngocr: bool, /// Specify the full path of the font that is to be used when /// generating SPUPNG files. If not specified, you need to /// have the default font installed (Helvetica for macOS, Calibri /// for Windows, and Noto for other operating systems at their /// default location) #[arg(long, verbatim_doc_comment, value_name="path", help_heading=OUTPUT_AFFECTING_OUTPUT_FILES)] - font: Option, + pub font: Option, /// Specify the full path of the italics font that is to be used when /// generating SPUPNG files. If not specified, you need to /// have the default font installed (Helvetica Oblique for macOS, Calibri Italic /// for Windows, and NotoSans Italic for other operating systems at their /// default location) #[arg(long, verbatim_doc_comment, value_name="path", help_heading=OUTPUT_AFFECTING_OUTPUT_FILES)] - italics: Option, + pub italics: Option, /// Forces input buffering. #[arg(long, verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_BUFFERING)] - bufferinput: bool, + pub bufferinput: bool, /// Disables input buffering. #[arg(long, verbatim_doc_comment, conflicts_with="bufferinput", help_heading=OUTPUT_AFFECTING_BUFFERING)] - no_bufferinput: bool, + pub no_bufferinput: bool, /// Specify a size for reading, in bytes (suffix with K or /// or M for kilobytes and megabytes). Default is 16M. #[arg(long, verbatim_doc_comment, value_name="val", help_heading=OUTPUT_AFFECTING_BUFFERING)] - buffersize: Option, + pub buffersize: Option, /// keep-output-close. If used then CCExtractor will close /// the output file after writing each subtitle frame and /// attempt to create it again when needed. #[arg(long, verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_BUFFERING)] - koc: bool, + pub koc: bool, /// Flush the file buffer whenever content is written. #[arg(long, verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_BUFFERING)] - forceflush: bool, + pub forceflush: bool, /// Direct Roll-Up. When in roll-up mode, write character by /// character instead of line by line. Note that this /// produces (much) larger files. #[arg(long, verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_BUFFERING)] - dru: bool, + pub dru: bool, /// If you hate the repeated lines caused by the roll-up /// emulation, you can have ccextractor write only one /// line at a time, getting rid of these repeated lines. #[arg(long, verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_BUFFERING)] - no_rollup: bool, + pub no_rollup: bool, /// roll-up captions can consist of 2, 3 or 4 visible /// lines at any time (the number of lines is part of /// the transmission). If having 3 or 4 lines annoys @@ -518,30 +554,30 @@ pub struct Args { /// of the first character received which is possibly more /// accurate. #[arg(long, verbatim_doc_comment, value_name="type", help_heading=OUTPUT_AFFECTING_BUFFERING)] - ru: Option, + pub ru: Option, /// For srt/sami/webvtt, add this number of milliseconds to /// all times. For example, --delay 400 makes subtitles /// appear 400ms late. You can also use negative numbers /// to make subs appear early. #[arg(long, verbatim_doc_comment, value_name="ms", help_heading=OUTPUT_AFFECTING_TIMING)] - delay: Option, + pub delay: Option, /// Only write caption information that starts after the /// given time. /// Time can be seconds, MM:SS or HH:MM:SS. /// For example, --startat 3:00 means 'start writing from /// minute 3. #[arg(long, verbatim_doc_comment, value_name="time", help_heading=OUTPUT_AFFECTING_SEGMENT)] - startat: Option, + pub startat: Option, /// Stop processing after the given time (same format as /// --startat). /// The --startat and --endat options are honored in all /// output formats. In all formats with timing information /// the times are unchanged. #[arg(long, verbatim_doc_comment, value_name="time", help_heading=OUTPUT_AFFECTING_SEGMENT)] - endat: Option, + pub endat: Option, /// Write 'num' screenfuls and terminate processing. #[arg(long, verbatim_doc_comment, value_name="num", help_heading=OUTPUT_AFFECTING_SEGMENT)] - screenfuls: Option, + pub screenfuls: Option, /// --codec dvbsub /// select the dvb subtitle from all elementary stream, /// if stream of dvb subtitle type is not found then @@ -549,118 +585,118 @@ pub struct Args { /// --codec teletext /// select the teletext subtitle from elementary stream #[arg(long, verbatim_doc_comment, value_name="value", help_heading=OUTPUT_AFFECTING_CODEC)] - codec: Option, + pub codec: Option, /// --no-codec dvbsub /// ignore dvb subtitle and follow default behaviour /// --no-codec teletext /// ignore teletext subtitle #[arg(long, verbatim_doc_comment, conflicts_with="codec", value_name="value", help_heading=OUTPUT_AFFECTING_CODEC)] - no_codec: Option, + pub no_codec: Option, /// Write this text as start credits. If there are /// several lines, separate them with the /// characters \n, for example Line1\nLine 2. #[arg(long, verbatim_doc_comment, value_name="text", help_heading=ADDING_CREDITS)] - startcreditstext: Option, + pub startcreditstext: Option, /// Don't display the start credits before this /// time (S, or MM:SS). Default: 0 #[arg(long, verbatim_doc_comment, value_name="time", help_heading=ADDING_CREDITS)] - startcreditsnotbefore: Option, + pub startcreditsnotbefore: Option, /// Don't display the start credits after this /// time (S, or MM:SS). Default: 5:00 #[arg(long, verbatim_doc_comment, value_name="time", help_heading=ADDING_CREDITS)] - startcreditsnotafter: Option, + pub startcreditsnotafter: Option, /// Start credits need to be displayed for at least /// this time (S, or MM:SS). Default: 2 #[arg(long, verbatim_doc_comment, value_name="time", help_heading=ADDING_CREDITS)] - startcreditsforatleast: Option, + pub startcreditsforatleast: Option, /// Start credits should be displayed for at most /// this time (S, or MM:SS). Default: 5 #[arg(long, verbatim_doc_comment, value_name="time", help_heading=ADDING_CREDITS)] - startcreditsforatmost: Option, + pub startcreditsforatmost: Option, /// Write this text as end credits. If there are /// several lines, separate them with the /// characters \n, for example Line1\nLine 2. #[arg(long, verbatim_doc_comment, value_name="txt", help_heading=ADDING_CREDITS)] - endcreditstext: Option, + pub endcreditstext: Option, /// End credits need to be displayed for at least /// this time (S, or MM:SS). Default: 2 #[arg(long, verbatim_doc_comment, value_name="time", help_heading=ADDING_CREDITS)] - endcreditsforatleast: Option, + pub endcreditsforatleast: Option, /// End credits should be displayed for at most /// this time (S, or MM:SS). Default: 5 #[arg(long, verbatim_doc_comment, value_name="time", help_heading=ADDING_CREDITS)] - endcreditsforatmost: Option, + pub endcreditsforatmost: Option, /// Show lots of debugging output. #[arg(long, verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_DEBUG_DATA)] - debug: bool, + pub debug: bool, /// Print debug traces from the EIA-608 decoder. /// If you need to submit a bug report, please send /// the output from this option. #[arg(long="608", verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_DEBUG_DATA)] - eia608: bool, + pub eia608: bool, /// Print debug information from the (currently /// in development) EIA-708 (DTV) decoder. #[arg(long="708", verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_DEBUG_DATA)] - eia708: bool, + pub eia708: bool, /// Enable lots of time stamp output. #[arg(long, verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_DEBUG_DATA)] - goppts: bool, + pub goppts: bool, /// Enable XDS debug data (lots of it). #[arg(long, verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_DEBUG_DATA)] - xdsdebug: bool, + pub xdsdebug: bool, /// Print debug info about the analysed elementary /// video stream. #[arg(long, verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_DEBUG_DATA)] - vides: bool, + pub vides: bool, /// Print debug trace with the raw 608/708 data with /// time stamps. #[arg(long, verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_DEBUG_DATA)] - cbraw: bool, + pub cbraw: bool, /// Disable the syncing code. Only useful for debugging /// purposes. #[arg(long, verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_DEBUG_DATA)] - no_sync: bool, + pub no_sync: bool, /// Disable the removal of trailing padding blocks /// when exporting to bin format. Only useful for /// for debugging purposes. #[arg(long, verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_DEBUG_DATA)] - fullbin: bool, + pub fullbin: bool, /// Print debug info about the parsed container /// file. (Only for TS/ASF files at the moment.) #[arg(long, verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_DEBUG_DATA)] - parsedebug: bool, + pub parsedebug: bool, /// Print Program Association Table dump. #[arg(long="parsePAT", verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_DEBUG_DATA)] - parse_pat: bool, + pub parse_pat: bool, /// Print Program Map Table dump. #[arg(long="parsePMT", verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_DEBUG_DATA)] - parse_pmt: bool, + pub parse_pmt: bool, /// Hex-dump defective TS packets. #[arg(long, verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_DEBUG_DATA)] - dumpdef: bool, + pub dumpdef: bool, /// If no CC packets are detected based on the PMT, try /// to find data in all packets by scanning. #[arg(long, verbatim_doc_comment, help_heading=OUTPUT_AFFECTING_DEBUG_DATA)] - investigate_packets: bool, + pub investigate_packets: bool, /// Use this page for subtitles (if this parameter /// is not used, try to autodetect). In Spain the /// page is always 888, may vary in other countries. #[arg(long, verbatim_doc_comment, value_name="page", help_heading=TELETEXT_OPTIONS)] - tpage: Option, + pub tpage: Option, /// Enable verbose mode in the teletext decoder. #[arg(long, verbatim_doc_comment, help_heading=TELETEXT_OPTIONS)] - tverbose: bool, + pub tverbose: bool, /// Force teletext mode even if teletext is not detected. /// If used, you should also pass --datapid to specify /// the stream ID you want to process. #[arg(long, verbatim_doc_comment, help_heading=TELETEXT_OPTIONS)] - teletext: bool, + pub teletext: bool, /// Disable teletext processing. This might be needed /// for video streams that have both teletext packets /// and CEA-608/708 packets (if teletext is processed /// then CEA-608/708 processing is disabled). #[arg(long, verbatim_doc_comment, conflicts_with="teletext", help_heading=TELETEXT_OPTIONS)] - no_teletext: bool, + pub no_teletext: bool, /// Use the passed format to customize the (Timed) Transcript /// output. The format must be like this: 1100100 (7 digits). /// These indicate whether the next things should be @@ -681,32 +717,32 @@ pub struct Args { /// affect these settings (--out, --ucla, --xds, --txt, /// --ttxt ...) #[arg(long, verbatim_doc_comment, value_name="format", help_heading=TRANSCRIPT_OPTIONS)] - customtxt: Option, + pub customtxt: Option, /// Report progress and interesting events to stderr /// in a easy to parse format. This is intended to be /// used by other programs. See docs directory for. /// details. #[arg(long, verbatim_doc_comment, help_heading=COMMUNICATION_PROTOCOL)] - gui_mode_reports: bool, + pub gui_mode_reports: bool, /// Suppress the output of the progress bar #[arg(long, verbatim_doc_comment, help_heading=COMMUNICATION_PROTOCOL)] - no_progress_bar: bool, + pub no_progress_bar: bool, /// Don't write any message. #[arg(long, verbatim_doc_comment, help_heading=COMMUNICATION_PROTOCOL)] - quiet: bool, + pub quiet: bool, /// Enable the burned-in subtitle extraction subsystem. #[arg(long, verbatim_doc_comment, help_heading=BURNEDIN_SUBTITLE_EXTRACTION)] - hardsubx: bool, + pub hardsubx: bool, /// Search for burned-in ticker text at the bottom of /// the screen. #[arg(long, verbatim_doc_comment, help_heading=BURNEDIN_SUBTITLE_EXTRACTION)] - tickertext: bool, + pub tickertext: bool, /// Set the OCR mode to either frame-wise, word-wise /// or letter wise. /// e.g. --ocr-mode frame (default), --ocr-mode word, /// --ocr-mode letter #[arg(long, verbatim_doc_comment, value_name="mode", help_heading=BURNEDIN_SUBTITLE_EXTRACTION)] - ocr_mode: Option, + pub ocr_mode: Option, /// Specify the color of the subtitles /// Possible values are in the set /// {white,yellow,green,cyan,blue,magenta,red}. @@ -715,7 +751,7 @@ pub struct Args { /// e.g. --subcolor white or --subcolor 270 (for violet). /// Refer to an HSV color chart for values. #[arg(long, verbatim_doc_comment, value_name="color", help_heading=BURNEDIN_SUBTITLE_EXTRACTION)] - subcolor: Option, + pub subcolor: Option, /// Specify the minimum duration that a subtitle line /// must exist on the screen. /// The value is specified in seconds. @@ -724,20 +760,20 @@ pub struct Args { /// The recommended value is 0.5 (default). /// e.g. --min_sub_duration 1.0 (for a duration of 1 second) #[arg(long, verbatim_doc_comment, value_name="duration", help_heading=BURNEDIN_SUBTITLE_EXTRACTION)] - min_sub_duration: Option, + pub min_sub_duration: Option, /// Specify whether italics are to be detected from the /// OCR text. /// Italic detection automatically enforces the OCR mode /// to be word-wise #[arg(long, verbatim_doc_comment, help_heading=BURNEDIN_SUBTITLE_EXTRACTION)] - detect_italics: bool, + pub detect_italics: bool, /// Specify the classifier confidence threshold between /// 1 and 100. /// Try and use a threshold which works for you if you get /// a lot of garbage text. /// e.g. --conf_thresh 50 #[arg(long, verbatim_doc_comment, help_heading=BURNEDIN_SUBTITLE_EXTRACTION)] - conf_thresh: bool, + pub conf_thresh: Option, /// For white subtitles only, specify the luminance /// threshold between 1 and 100 /// This threshold is content dependent, and adjusting @@ -745,28 +781,28 @@ pub struct Args { /// Recommended values are in the range 80 to 100. /// The default value is 95 #[arg(long, verbatim_doc_comment, value_name="threshold", help_heading=BURNEDIN_SUBTITLE_EXTRACTION)] - whiteness_thresh: Option, + pub whiteness_thresh: Option, /// This option will be used if the file should have both /// closed captions and burned in subtitles #[arg(long, verbatim_doc_comment, help_heading=BURNEDIN_SUBTITLE_EXTRACTION)] - hcc: bool, + pub hcc: bool, } -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum)] -enum Codec { +#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum)] +pub enum Codec { Dvbsub, Teletext, } -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum)] -enum Ru { +#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum)] +pub enum Ru { Ru1, Ru2, Ru3, } -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum)] -enum InputFormat { +#[derive(Display, Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum)] +pub enum InputFormat { /// For Transport Streams. Ts, /// For Program Streams. @@ -791,8 +827,8 @@ enum InputFormat { Mxf, } -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum)] -enum OutFormat { +#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum)] +pub enum OutFormat { /// SubRip (default, so not actually needed). Srt, /// SubStation Alpha. diff --git a/src/rust/src/main.rs b/src/rust/src/main.rs index 7086d5524..67798d7d0 100644 --- a/src/rust/src/main.rs +++ b/src/rust/src/main.rs @@ -1,9 +1,405 @@ mod args; use args::Args; +mod structs; use clap::Parser; +use structs::CcxSOptions; + +use crate::{args::Codec, structs::*}; + +static mut FILEBUFFERSIZE: i64 = 1024 * 1024 * 16; + +fn set_input_format(opt: &mut CcxSOptions, args: &Args) { + if opt.input_source == CcxDatasource::Tcp { + println!("Input format is changed to bin\n"); + opt.demux_cfg.auto_stream = CcxStreamMode::Rcwt; + return; + } + + let can_unwrap = args.input.is_some(); + #[cfg(feature = "wtv_debug")] + if can_unwrap && args.input.unwrap().to_string() == "hex" { + opt.demux_cfg.auto_stream = CcxStreamMode::HexDump; + return; + } + + if args.es || can_unwrap && args.input.unwrap().to_string() == "es" { + opt.demux_cfg.auto_stream = CcxStreamMode::ElementaryOrNotFound; + } else if args.ts || can_unwrap && args.input.unwrap().to_string() == "ts" { + opt.demux_cfg.auto_stream = CcxStreamMode::Transport; + } else if can_unwrap && args.input.unwrap().to_string() == "m2ts" { + opt.demux_cfg.auto_stream = CcxStreamMode::Transport; + } else if args.ps || can_unwrap && args.input.unwrap().to_string() == "ps" { + opt.demux_cfg.auto_stream = CcxStreamMode::Program; + } else if args.asf + || args.dvr_ms + || can_unwrap + && (args.input.unwrap().to_string() == "asf" + || args.input.unwrap().to_string() == "dvr-ms") + { + opt.demux_cfg.auto_stream = CcxStreamMode::Asf; + } else if args.wtv || can_unwrap && args.input.unwrap().to_string() == "wtv" { + opt.demux_cfg.auto_stream = CcxStreamMode::Wtv; + } else if can_unwrap && args.input.unwrap().to_string() == "raw" { + opt.demux_cfg.auto_stream = CcxStreamMode::McpoodlesRaw; + } else if can_unwrap && args.input.unwrap().to_string() == "bin" { + opt.demux_cfg.auto_stream = CcxStreamMode::Rcwt; + } else if can_unwrap && args.input.unwrap().to_string() == "mp4" { + opt.demux_cfg.auto_stream = CcxStreamMode::Mp4; + } else if can_unwrap && args.input.unwrap().to_string() == "mkv" { + opt.demux_cfg.auto_stream = CcxStreamMode::Mkv; + } else if can_unwrap && args.input.unwrap().to_string() == "bin" { + opt.demux_cfg.auto_stream = CcxStreamMode::Mxf; + } else { + println!( + "Unknown input file format: {}\n", + args.input.unwrap().to_string() + ); + std::process::exit(ExitCode::MalformedParameter as i32); + } +} + +fn mkvlang_params_check(lang: &str) { + let mut initial = 0; + let mut present = 0; + + for (char_index, c) in lang.to_lowercase().chars().enumerate() { + if c == ',' { + present = char_index; + + if present - initial < 3 || present - initial > 6 { + panic!("language codes should be xxx,xxx,xxx,....\n"); + } + + if present - initial == 6 { + let sub_slice = &lang[initial..present]; + if !sub_slice.contains("-") { + panic!("language code is not of the form xxx-xx\n"); + } + } + + initial = present + 1; + } + } + + // Steps to check for the last lang of multiple mkvlangs provided by the user. + present = lang.len() - 1; + + for char_index in (0..present).rev() { + if lang.chars().nth(char_index) == Some(',') { + initial = char_index + 1; + break; + } + } + + if present - initial < 2 || present - initial > 5 { + panic!("last language code should be xxx.\n"); + } + + if present - initial == 5 { + let sub_slice = &lang[initial..present]; + if !sub_slice.contains("-") { + panic!("last language code is not of the form xxx-xx\n"); + } + } +} + fn main() { - let _cli = Args::parse(); + let args: Args = Args::parse(); + let mut opt = CcxSOptions { + ..Default::default() + }; + + if args.stdin { + if cfg!(windows) { + // TODO(prateekmedia): check this + // setmode(fileno(stdin), O_BINARY); + } + opt.input_source = CcxDatasource::Stdin; + opt.live_stream = Some(-1); + } + + // #[cfg(feature = "hardsubx_ocr")] + { + if args.hardsubx { + opt.hardsubx = Some(1); + + if args.hcc { + opt.hardsubx_and_common = Some(1); + } + + match args.ocr_mode { + Some(ref ocr_mode) => { + let ocr_mode = match ocr_mode.as_str() { + "simple" | "frame" => Some(HardsubxOcrMode::Frame), + "word" => Some(HardsubxOcrMode::Word), + "letter" | "symbol" => Some(HardsubxOcrMode::Letter), + _ => None, + }; + + if ocr_mode.is_none() { + println!("Invalid OCR mode"); + std::process::exit(ExitCode::MalformedParameter as i32); + } + + let value = Some(ocr_mode.unwrap() as i32); + opt.hardsubx_ocr_mode = value; + } + None => {} + } + + match args.subcolor { + Some(ref subcolor) => match subcolor.as_str() { + "white" => { + opt.hardsubx_subcolor = Some(HardsubxColorType::White as i32); + opt.hardsubx_hue = Some(0.0); + } + "yellow" => { + opt.hardsubx_subcolor = Some(HardsubxColorType::Yellow as i32); + opt.hardsubx_hue = Some(60.0); + } + "green" => { + opt.hardsubx_subcolor = Some(HardsubxColorType::Green as i32); + opt.hardsubx_hue = Some(120.0); + } + "cyan" => { + opt.hardsubx_subcolor = Some(HardsubxColorType::Cyan as i32); + opt.hardsubx_hue = Some(180.0); + } + "blue" => { + opt.hardsubx_subcolor = Some(HardsubxColorType::Blue as i32); + opt.hardsubx_hue = Some(240.0); + } + "magenta" => { + opt.hardsubx_subcolor = Some(HardsubxColorType::Magenta as i32); + opt.hardsubx_hue = Some(300.0); + } + "red" => { + opt.hardsubx_subcolor = Some(HardsubxColorType::Red as i32); + opt.hardsubx_hue = Some(0.0); + } + _ => { + let result = subcolor.parse::(); + if result.is_err() { + println!("Invalid Hue value"); + std::process::exit(ExitCode::MalformedParameter as i32); + } + + let hue: f32 = result.unwrap(); + + if hue <= 0.0 || hue > 360.0 { + println!("Invalid Hue value"); + std::process::exit(ExitCode::MalformedParameter as i32); + } + opt.hardsubx_subcolor = Some(HardsubxColorType::Custom as i32); + opt.hardsubx_hue = Some(hue); + } + }, + None => {} + } + + match args.min_sub_duration { + Some(value) => { + if value == 0.0 { + println!("Invalid minimum subtitle duration"); + std::process::exit(ExitCode::MalformedParameter as i32); + } + opt.hardsubx_min_sub_duration = Some(value); + } + None => {} + } + + if args.detect_italics { + opt.hardsubx_detect_italics = Some(1); + } + + match args.conf_thresh { + Some(value) => { + if value <= 0.0 || value > 100.0 { + println!("Invalid confidence threshold, valid values are between 0 & 100"); + std::process::exit(ExitCode::MalformedParameter as i32); + } + opt.hardsubx_conf_thresh = Some(value); + } + None => {} + } + + match args.whiteness_thresh { + Some(value) => { + if value <= 0.0 || value > 100.0 { + println!("Invalid whiteness threshold, valid values are between 0 & 100"); + std::process::exit(ExitCode::MalformedParameter as i32); + } + opt.hardsubx_lum_thresh = Some(value); + } + None => {} + } + } + } // END OF HARDSUBX + + if args.chapters { + opt.extract_chapters = Some(1); + } + + if args.bufferinput { + opt.buffer_input = Some(1); + } + + if args.no_bufferinput { + opt.buffer_input = Some(0); + } + + if args.koc { + opt.keep_output_closed = Some(1); + } + + if args.forceflush { + opt.force_flush = Some(1); + } + + // TODO(prateekmedia): Check this too + // if args.append { + // opt.append_mode = Some(1); + // } + + match args.buffersize { + Some(buffersize) => unsafe { + let mut_ref = &mut FILEBUFFERSIZE; + + if buffersize < 8 { + *mut_ref = 8; // Otherwise crashes are guaranteed at least in MythTV + } else { + *mut_ref = buffersize; + } + }, + None => {} + } + + if args.dru { + opt.settings_608.direct_rollup = 1; + } + + if args.no_fontcolor { + opt.nofontcolor = true; + } + + if args.no_htmlescape { + opt.nohtmlescape = true; + } + + if args.bom { + opt.enc_cfg.no_bom = false; + } + if args.no_bom { + opt.enc_cfg.no_bom = true; + } + + if args.sem { + opt.enc_cfg.with_semaphore = true; + } + + if args.no_typesetting { + opt.notypesetting = true; + } + + if args.timestamp_map { + opt.timestamp_map = Some(1); + } + + if args.es + || args.ts + || args.ps + || args.asf + || args.wtv + || args.mp4 + || args.mkv + || args.dvr_ms + || args.input.is_some() + { + set_input_format(&mut opt, &args); + } + + match args.codec { + Some(codec) => match codec { + Codec::Teletext => { + opt.demux_cfg.codec = CcxCodeType::Teletext; + } + Codec::Dvbsub => { + opt.demux_cfg.codec = CcxCodeType::Dvb; + } + _ => { + println!("Invalid codec"); + std::process::exit(ExitCode::MalformedParameter as i32); + } + }, + None => {} + } + + match args.no_codec { + Some(codec) => match codec { + Codec::Dvbsub => { + opt.demux_cfg.codec = CcxCodeType::Teletext; + } + Codec::Teletext => { + opt.demux_cfg.codec = CcxCodeType::Dvb; + } + _ => { + println!("Invalid codec"); + std::process::exit(ExitCode::MalformedParameter as i32); + } + }, + None => {} + } + + match args.dvblang { + Some(lang) => { + opt.dvblang = Some(lang); + } + None => {} + } + + match args.ocrlang { + Some(lang) => { + opt.ocrlang = Some(lang); + } + None => {} + } + + match args.quant { + Some(quant) => { + if quant < 0 || quant > 2 { + println!("Invalid quant value"); + std::process::exit(ExitCode::MalformedParameter as i32); + } + opt.ocr_quantmode = Some(quant); + } + None => {} + } + + if args.no_spupngocr { + opt.enc_cfg.nospupngocr = true; + } + + match args.oem { + Some(oem) => { + if oem < 0 || oem > 2 { + println!("Invalid oem value"); + std::process::exit(ExitCode::MalformedParameter as i32); + } + opt.ocr_oem = Some(oem); + } + None => {} + } + + match args.mkvlang { + Some(ref lang) => { + opt.mkvlang = Some(lang.to_string()); + let str = lang.as_str(); + mkvlang_params_check(str); + } + None => {} + } + println!("Issues? Open a ticket here\n https://github.com/CCExtractor/ccextractor/issues"); } diff --git a/src/rust/src/structs.rs b/src/rust/src/structs.rs new file mode 100644 index 000000000..53790aed7 --- /dev/null +++ b/src/rust/src/structs.rs @@ -0,0 +1,594 @@ +#[derive(Debug, Default)] +pub struct CcxBoundaryTime { + pub hh: i32, + pub mm: i32, + pub ss: i32, + pub time_in_ms: i64, + pub set: bool, +} + +#[derive(Debug, Default)] +pub struct CcxDecoder608Report { + pub xds: bool, + pub cc_channels: [u8; 4], +} + +#[derive(Debug, Default)] +pub struct CcxDecoder608Settings { + pub direct_rollup: i32, + pub force_rollup: i32, + pub no_rollup: i32, + pub default_color: CcxDecoder608ColorCode, + pub screens_to_process: i32, + pub report: Option<&'static CcxDecoder608Report>, +} + +const CCX_DTVCC_MAX_SERVICES: usize = 63; + +impl Default for CcxFrameType { + fn default() -> Self { + Self::ResetOrUnknown + } +} + +#[derive(Debug)] +pub enum CcxFrameType { + ResetOrUnknown = 0, + IFrame = 1, + PFrame = 2, + BFrame = 3, + DFrame = 4, +} + +#[derive(Debug, Default)] +pub struct CcxCommonTimingCtx { + pub pts_set: u8, // 0 = No, 1 = received, 2 = min_pts set + pub min_pts_adjusted: u8, // 0 = No, 1=Yes (don't adjust again) + pub current_pts: i64, + pub current_picture_coding_type: CcxFrameType, + pub current_tref: i32, // Store temporal reference of current frame + pub min_pts: i64, + pub max_pts: i64, + pub sync_pts: i64, + pub minimum_fts: i64, // No screen should start before this FTS + pub fts_now: i64, // Time stamp of current file (w/ fts_offset, w/o fts_global) + pub fts_offset: i64, // Time before first sync_pts + pub fts_fc_offset: i64, // Time before first GOP + pub fts_max: i64, // Remember the maximum fts that we saw in current file + pub fts_global: i64, // Duration of previous files (-ve mode) + pub sync_pts2fts_set: u8, // 0 = No, 1 = Yes + pub sync_pts2fts_fts: i64, + pub sync_pts2fts_pts: i64, + pub pts_reset: u8, // 0 = No, 1 = Yes. PTS resets when current_pts is lower than prev +} + +impl Default for CcxDecoderDtvccSettings { + fn default() -> Self { + Self { + enabled: false, + print_file_reports: false, + no_rollup: false, + report: None, + active_services_count: 0, + services_enabled: [false; CCX_DTVCC_MAX_SERVICES], + timing: CcxCommonTimingCtx::default(), + } + } +} + +#[derive(Debug)] +pub struct CcxDecoderDtvccSettings { + pub enabled: bool, + pub print_file_reports: bool, + pub no_rollup: bool, + pub report: Option<&'static CcxDecoderDtvccReport>, + pub active_services_count: usize, + pub services_enabled: [bool; CCX_DTVCC_MAX_SERVICES], + pub timing: CcxCommonTimingCtx, +} + +impl Default for CcxDecoderDtvccReport { + fn default() -> Self { + Self { + reset_count: 0, + services: [0; CCX_DTVCC_MAX_SERVICES], + } + } +} + +#[derive(Debug)] + +pub struct CcxDecoderDtvccReport { + pub reset_count: usize, + pub services: [u32; CCX_DTVCC_MAX_SERVICES], +} + +#[derive(Debug, Default)] +pub struct CcxEncodersTranscriptFormat { + show_start_time: bool, + show_end_time: bool, + show_mode: bool, + show_cc: bool, + relative_timestamp: bool, + xds: bool, + use_colors: bool, + is_final: bool, +} + +impl Default for CcxOutputDateFormat { + fn default() -> Self { + Self::None + } +} + +#[derive(Debug)] +pub enum CcxOutputDateFormat { + None = 0, + HHMMSS = 1, + Seconds = 2, + Date = 3, + HHMMSSMS = 4, // HH:MM:SS,MILIS (.srt style) +} + +impl Default for CcxStreamMode { + fn default() -> Self { + Self::ElementaryOrNotFound + } +} + +#[derive(Debug)] +pub enum CcxStreamMode { + ElementaryOrNotFound = 0, + Transport = 1, + Program = 2, + Asf = 3, + McpoodlesRaw = 4, + Rcwt = 5, // Raw Captions With Time, not used yet. + Myth = 6, // Use the myth loop + Mp4 = 7, // MP4, ISO- + #[cfg(feature = "wtv_debug")] + HexDump = 8, // Hexadecimal dump generated by wtvccdump + Wtv = 9, + #[cfg(feature = "enable_ffmpeg")] + Ffmpeg = 10, + Gxf = 11, + Mkv = 12, + Mxf = 13, + Autodetect = 16, +} +impl Default for CcxCodeType { + fn default() -> Self { + Self::None + } +} + +#[derive(Debug)] +pub enum CcxCodeType { + Any = 0, + Teletext = 1, + Dvb = 2, + IsdbCc = 3, + AtscCc = 4, + None = 5, +} + +impl Default for CcxDemuxerCfg { + fn default() -> Self { + Self { + m2ts: false, + auto_stream: CcxStreamMode::default(), + codec: CcxCodeType::default(), + nocodec: CcxCodeType::default(), + ts_autoprogram: 0, + ts_allprogram: 0, + ts_cappids: [0; 128], + nb_ts_cappid: 0, + ts_forced_cappid: 0, + ts_forced_program: 0, + ts_forced_program_selected: false, + ts_datastreamtype: 0, + ts_forced_streamtype: 0, + } + } +} + +#[derive(Debug)] +pub struct CcxDemuxerCfg { + pub m2ts: bool, + pub auto_stream: CcxStreamMode, + pub codec: CcxCodeType, + pub nocodec: CcxCodeType, + pub ts_autoprogram: u32, + pub ts_allprogram: u32, + pub ts_cappids: [u32; 128], + pub nb_ts_cappid: usize, + pub ts_forced_cappid: u32, + pub ts_forced_program: u32, + pub ts_forced_program_selected: bool, + pub ts_datastreamtype: u32, + pub ts_forced_streamtype: u32, +} + +impl Default for CcxOutputFormat { + fn default() -> Self { + Self::Raw + } +} + +#[derive(Debug)] +pub enum CcxOutputFormat { + Raw = 0, + Srt = 1, + Sami = 2, + Transcript = 3, + Rcwt = 4, + Null = 5, + Smptett = 6, + Spupng = 7, + Dvdraw = 8, // See -d at http://www.theneitherworld.com/mcpoodle/SCC_TOOLS/DOCS/SCC_TOOLS.HTML#CCExtract + Webvtt = 9, + SimpleXml = 10, + G608 = 11, + Curl = 12, + Ssa = 13, + Mcc = 14, + Scc = 15, + Ccd = 16, +} + +impl Default for CcxEncodingType { + fn default() -> Self { + Self::Unicode + } +} + +#[derive(Debug)] +pub enum CcxEncodingType { + Unicode = 0, + Latin1 = 1, + Utf8 = 2, + Ascii = 3, +} + +impl Default for CcxEncoderCfg { + fn default() -> Self { + Self { + extract: false, + dtvcc_extract: false, + gui_mode_reports: false, + output_filename: String::default(), + write_format: CcxOutputFormat::default(), + keep_output_closed: false, + force_flush: false, + append_mode: false, + ucla: false, + encoding: CcxEncodingType::default(), + date_format: CcxOutputDateFormat::default(), + millis_separator: char::default(), + autodash: false, + trim_subs: false, + sentence_cap: false, + splitbysentence: false, + curlposturl: None, + filter_profanity: false, + with_semaphore: false, + start_credits_text: String::default(), + end_credits_text: String::default(), + startcreditsnotbefore: CcxBoundaryTime::default(), + startcreditsnotafter: CcxBoundaryTime::default(), + startcreditsforatleast: CcxBoundaryTime::default(), + startcreditsforatmost: CcxBoundaryTime::default(), + endcreditsforatleast: CcxBoundaryTime::default(), + endcreditsforatmost: CcxBoundaryTime::default(), + transcript_settings: CcxEncodersTranscriptFormat::default(), + send_to_srv: 0, + no_bom: false, + first_input_file: String::default(), + multiple_files: false, + no_font_color: false, + no_type_setting: false, + cc_to_stdout: false, + line_terminator_lf: false, + subs_delay: 0, + program_number: 0, + in_format: 0, + nospupngocr: false, + force_dropframe: false, + render_font: String::default(), + render_font_italics: String::default(), + services_enabled: [false; 63], + services_charsets: vec![], + all_services_charset: String::default(), + extract_only_708: false, + } + } +} + +#[derive(Debug)] +pub struct CcxEncoderCfg { + pub extract: bool, + pub dtvcc_extract: bool, + pub gui_mode_reports: bool, + pub output_filename: String, + pub write_format: CcxOutputFormat, + pub keep_output_closed: bool, + pub force_flush: bool, + pub append_mode: bool, + pub ucla: bool, + pub encoding: CcxEncodingType, + pub date_format: CcxOutputDateFormat, + pub millis_separator: char, + pub autodash: bool, + pub trim_subs: bool, + pub sentence_cap: bool, + pub splitbysentence: bool, + pub curlposturl: Option, + pub filter_profanity: bool, + pub with_semaphore: bool, + pub start_credits_text: String, + pub end_credits_text: String, + pub startcreditsnotbefore: CcxBoundaryTime, + pub startcreditsnotafter: CcxBoundaryTime, + pub startcreditsforatleast: CcxBoundaryTime, + pub startcreditsforatmost: CcxBoundaryTime, + pub endcreditsforatleast: CcxBoundaryTime, + pub endcreditsforatmost: CcxBoundaryTime, + pub transcript_settings: CcxEncodersTranscriptFormat, + pub send_to_srv: u32, + pub no_bom: bool, + pub first_input_file: String, + pub multiple_files: bool, + pub no_font_color: bool, + pub no_type_setting: bool, + pub cc_to_stdout: bool, + pub line_terminator_lf: bool, + pub subs_delay: i64, + pub program_number: u32, + pub in_format: u8, + pub nospupngocr: bool, + pub force_dropframe: bool, + pub render_font: String, + pub render_font_italics: String, + pub services_enabled: [bool; CCX_DTVCC_MAX_SERVICES], + pub services_charsets: Vec, + pub all_services_charset: String, + pub extract_only_708: bool, +} + +#[derive(Debug, Default)] +pub struct CcxSOptions { + pub extract: Option, + pub no_rollup: Option, + pub noscte20: Option, + pub webvtt_create_css: Option, + pub cc_channel: Option, + pub buffer_input: Option, + pub nofontcolor: bool, + pub nohtmlescape: bool, + pub notypesetting: bool, + pub extraction_start: CcxBoundaryTime, + pub extraction_end: CcxBoundaryTime, + pub print_file_reports: Option, + pub settings_608: CcxDecoder608Settings, + pub settings_dtvcc: CcxDecoderDtvccSettings, + pub is_608_enabled: Option, + pub is_708_enabled: Option, + pub millis_separator: char, + pub binary_concat: Option, + pub use_gop_as_pts: Option, + pub fix_padding: Option, + pub gui_mode_reports: Option, + pub no_progress_bar: Option, + pub sentence_cap_file: Option, + pub live_stream: Option, + pub filter_profanity_file: Option, + pub messages_target: Option, + pub timestamp_map: Option, + pub dolevdist: Option, + pub levdistmincnt: Option, + pub levdistmaxpct: Option, + pub investigate_packets: Option, + pub fullbin: Option, + pub nosync: Option, + pub hauppauge_mode: Option, + pub wtvconvertfix: Option, + pub wtvmpeg2: Option, + pub auto_myth: Option, + pub mp4vidtrack: Option, + pub extract_chapters: Option, + pub usepicorder: Option, + pub xmltv: Option, + pub xmltvliveinterval: Option, + pub xmltvoutputinterval: Option, + pub xmltvonlycurrent: Option, + pub keep_output_closed: Option, + pub force_flush: Option, + pub append_mode: Option, + pub ucla: Option, + pub tickertext: Option, + pub hardsubx: Option, + pub hardsubx_and_common: Option, + pub dvblang: Option, + pub ocrlang: Option, + pub ocr_oem: Option, + pub ocr_quantmode: Option, + pub mkvlang: Option, + pub analyze_video_stream: Option, + pub hardsubx_ocr_mode: Option, + pub hardsubx_subcolor: Option, + pub hardsubx_min_sub_duration: Option, + pub hardsubx_detect_italics: Option, + pub hardsubx_conf_thresh: Option, + pub hardsubx_hue: Option, + pub hardsubx_lum_thresh: Option, + pub transcript_settings: CcxEncodersTranscriptFormat, + pub date: CcxOutputDateFormat, + pub format: Option, + pub write_format_rewritten: Option, + pub use_ass_instead_of_ssa: Option, + pub use_webvtt_styling: Option, + pub debug_mask: u64, + pub debug_mask_on_debug: u64, + pub udpsrc: Option, + pub udpaddr: Option, + pub udpport: Option, + pub tcpport: Option, + pub tcp_password: Option, + pub tcp_desc: Option, + pub srv_addr: Option, + pub srv_port: Option, + pub noautotimeref: Option, + pub input_source: CcxDatasource, + pub output_filename: Option, + pub inputfile: Option>, + pub num_input_files: Option, + pub demux_cfg: CcxDemuxerCfg, + pub enc_cfg: CcxEncoderCfg, + pub subs_delay: u64, + pub cc_to_stdout: Option, + pub pes_header_to_stdout: Option, + pub ignore_pts_jumps: Option, + pub multiprogram: Option, + pub out_interval: Option, + pub segment_on_key_frames_only: Option, + pub curlposturl: Option, + pub sharing_enabled: Option, + pub sharing_url: Option, + pub translate_enabled: Option, + pub translate_langs: Option, + pub translate_key: Option, +} + +impl Default for HardsubxOcrMode { + fn default() -> Self { + Self::Frame + } +} +pub enum HardsubxOcrMode { + Frame = 0, + Word = 1, + Letter = 2, +} + +impl Default for CcxDatasource { + fn default() -> Self { + Self::File + } +} + +#[derive(Debug, PartialEq)] +pub enum CcxDatasource { + File = 0, + Stdin = 1, + Network = 2, + Tcp = 3, +} + +impl Default for CcxEia608Format { + fn default() -> Self { + Self::CcScreen + } +} +pub enum CcxEia608Format { + CcScreen, + CcLine, + Xds, +} + +impl Default for CcModes { + fn default() -> Self { + Self::Text + } +} + +#[derive(Debug)] +pub enum CcModes { + Popon = 0, + Rollup2 = 1, + Rollup3 = 2, + Rollup4 = 3, + Text = 4, + Painton = 5, + FakeRollup1 = 100, +} + +impl Default for FontBits { + fn default() -> Self { + Self::Regular + } +} + +#[derive(Debug)] +pub enum FontBits { + Regular = 0, + Italics = 1, + Underlined = 2, + UnderlinedItalics = 3, +} + +impl Default for CcxDecoder608ColorCode { + fn default() -> Self { + Self::Userdefined + } +} + +#[derive(Debug)] +pub enum CcxDecoder608ColorCode { + White = 0, + Green = 1, + Blue = 2, + Cyan = 3, + Red = 4, + Yellow = 5, + Magenta = 6, + Userdefined = 7, + Black = 8, + Transparent = 9, + + // Must keep at end + Max, +} + +#[derive(Copy, Clone, Debug)] +pub enum ExitCode { + OK = 0, + NoInputFiles = 2, + TooManyInputFiles = 3, + IncompatibleParameters = 4, + UnableToDetermineFileSize = 6, + MalformedParameter = 7, + ReadError = 8, + NoCaptions = 10, + WithHelp = 11, + NotClassified = 300, + ErrorInCapitalizationFile = 501, + BufferFull = 502, + MissingASFHeader = 1001, + MissingRCWTHeader = 1002, + FileCreationFailed = 5, + Unsupported = 9, + NotEnoughMemory = 500, + BugBug = 1000, +} + +#[derive(Copy, Clone, Debug)] +pub enum CCXResult { + Ok = 0, + EAGAIN = -100, + EOF = -101, + EINVAL = -102, + ENOSUPP = -103, + ENOMEM = -104, +} + +#[derive(Copy, Clone, Debug)] +pub enum HardsubxColorType { + White = 0, + Yellow = 1, + Green = 2, + Cyan = 3, + Blue = 4, + Magenta = 5, + Red = 6, + Custom = 7, +}