Skip to content

Conversation

steel-bucket
Copy link
Contributor

@steel-bucket steel-bucket commented Feb 11, 2025

In raising this pull request, I confirm the following (please check boxes):

  • I have read and understood the contributors guide.
  • I have checked that another pull request for this purpose does not exist.
  • I have considered, and confirmed that this submission will be valuable to others.
  • I accept that this submission may not be used, and the pull request closed at the will of the maintainer.
  • I give this submission freely, and claim no ownership to its content.
  • I have mentioned this change in the changelog.

My familiarity with the project is as follows (check one):

  • I have never used CCExtractor.
  • I have used CCExtractor just a couple of times.
  • I absolutely love CCExtractor, but have not contributed previously.
  • I am an active contributor to CCExtractor(2 previous contributions).

In this PR, I have attempted to port the large demuxer module to Rust, the primary logic of the heavily interconnected C libraries file_functions.c and, ccx_demuxer.c and their corresponding header files has aleady been implemented here.
This PR was inspired by the ones done for the 708 Decoder in CCextractor.
The part of the codebase that the demuxer part of this PR migrates to Rust is the part that Opens a File(ccx_demuxer_open), points the codebase towards that file, detects the stream type and some other parameters like myth, and then closes the file or gets the file size.
The file_functions part of this PR is tested locally, and in unit tests, but integrating it into C made the codebase really slow, due to the constant copying back and forth C and Rust, so it was left to be used in future Rust Libraries like MythTV, MXF, GXF, etc.
Any criticism or suggestion is wholeheartedly welcome.

  • It is built and ready to be reviewed now.

@cfsmp3 cfsmp3 requested a review from prateekmedia February 12, 2025 20:45
@prateekmedia
Copy link
Member

@steel-bucket Is it still WIP?

@steel-bucket
Copy link
Contributor Author

@steel-bucket Is it still WIP?

Yes, I'm done with the hard part though, file_functions module is fully tested and ready. And the demuxer module just needs a couple more tests. Then I just have the gxf one to do. It won't be long though. Sorry to be late with it, I had some exams which are cleared out now.

@steel-bucket steel-bucket changed the title [WIP] feat: added demuxer module [FEAT]feat: added demuxer module Mar 27, 2025
@prateekmedia prateekmedia changed the title [FEAT]feat: added demuxer module [FEAT] added demuxer module Mar 29, 2025
@steel-bucket
Copy link
Contributor Author

steel-bucket commented Mar 31, 2025

Hi, @prateekmedia the builds and tests are all working(other than regression). Please review it if time permits. Also should I squash the commits together?
Thank you so much.

@steel-bucket steel-bucket changed the title [FEAT] added demuxer module [FEAT] added demuxer and file_functions module Jun 7, 2025
@steel-bucket steel-bucket force-pushed the migration-demuxer-module branch from 5268a7d to bfbe1d6 Compare June 7, 2025 08:21
@prateekmedia prateekmedia requested a review from Copilot June 12, 2025 10:06
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR ports the C demuxer and file_functions modules to Rust, adds corresponding FFI bindings for MXF/GXF, and updates build configuration.

  • Introduced new Rust modules (demuxer, file_functions) and added them to the crate root.
  • Extended the C wrapper (wrapper.h) and extern "C" block in lib.rs for MXF/GXF and demuxer functions.
  • Updated C source (ccx_gxf.*, ccx_demuxer_mxf.*, ccx_demuxer.c) to remove duplicate definitions and conditionally call Rust implementations.

Reviewed Changes

Copilot reviewed 27 out of 27 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/rust/wrapper.h Added headers for GXF and MXF demuxer
src/rust/src/parser.rs Tightened cast to usize for input file capacity check
src/rust/src/libccxr_exports/mod.rs Exported the new demuxer module
src/rust/src/lib.rs Declared new Rust modules and FFI externs
src/rust/src/file_functions/mod.rs Added file_functions module with documentation stub
src/rust/src/demuxer/common_structs.rs New demuxer data structures and defaults
src/lib_ccx/ccx_gxf.h Defined ccx_gxf struct for GXF support
src/lib_ccx/ccx_gxf.c Removed duplicate struct; left stray comments
src/lib_ccx/ccx_demuxer_mxf.h Added MXF context and type definitions
src/lib_ccx/ccx_demuxer_mxf.c Cleaned up duplicate MXF definitions
src/lib_ccx/ccx_demuxer.c Wrapped demuxer calls under DISABLE_RUST
docs/CHANGES.TXT Updated changelog with new entries
Comments suppressed due to low confidence (5)

src/lib_ccx/ccx_demuxer_mxf.c:1

  • This file uses uint8_t and other fixed-width types but does not include <stdint.h>. Add the proper include to avoid compilation errors.
#define IS_KLV_KEY(x, y) (!memcmp(x, y, sizeof(y)))

docs/CHANGES.TXT:44

  • The leading -- appears duplicated in this changelog entry. Use a single - to match the existing formatting.
-- Fix: Unit Test Rust failing due to changes in Rust Version 1.86.0

src/rust/src/lib.rs:43

  • [nitpick] The imported types c_uchar, c_ulong, and c_void are not used elsewhere in this file; consider removing this import.
use std::os::raw::{c_uchar, c_ulong, c_void};

src/lib_ccx/ccx_gxf.h:9

  • Ensure this header has proper include guards or #pragma once to prevent duplicate definitions when included multiple times.
struct ccx_gxf

src/lib_ccx/ccx_demuxer_mxf.h:6

  • Add include guards or #pragma once to this header to prevent multiple inclusion, and verify that <stdint.h> is included for uint8_t.
typedef uint8_t UID[16];

Comment on lines 4 to 7
* @param ctx ccx_demuxer context properly initilaized ccx_demuxer with some input
* Not to be NULL, since ctx is derefrenced inside this function
*
* @param buffer if buffer then it must be allocated to at;east bytes len as
Copy link
Preview

Copilot AI Jun 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix typos in the documentation: change "initilaized" to "initialized", "derefrenced" to "dereferenced", and "at;east" to "at least".

Suggested change
* @param ctx ccx_demuxer context properly initilaized ccx_demuxer with some input
* Not to be NULL, since ctx is derefrenced inside this function
*
* @param buffer if buffer then it must be allocated to at;east bytes len as
* @param ctx ccx_demuxer context properly initialized ccx_demuxer with some input
* Not to be NULL, since ctx is dereferenced inside this function
*
* @param buffer if buffer then it must be allocated to at least bytes len as

Copilot uses AI. Check for mistakes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolved

Comment on lines 119 to 127
#[allow(unused)] // used in tests
pub(crate) fn default() -> PSIBuffer {
PSIBuffer {
prev_ccounter: 0,
buffer: Box::into_raw(Box::new(0u8)),
buffer_length: 0,
ccounter: 0,
}
}
Copy link
Preview

Copilot AI Jun 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You have both an impl Default for PSIBuffer and an inherent default() method; consider removing the duplicate inherent method or merging them to avoid confusion.

Suggested change
#[allow(unused)] // used in tests
pub(crate) fn default() -> PSIBuffer {
PSIBuffer {
prev_ccounter: 0,
buffer: Box::into_raw(Box::new(0u8)),
buffer_length: 0,
ccounter: 0,
}
}

Copilot uses AI. Check for mistakes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolved

@@ -1000,6 +951,7 @@ static int parse_ad_vbi(struct ccx_demuxer *demux, int len, struct demuxer_data
if (result != len)
ret = CCX_EOF;
return ret;
// #endif
Copy link
Preview

Copilot AI Jun 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Remove stray commented // #endif lines inside function bodies to clean up leftover conditional compilation markers.

Suggested change
// #endif

Copilot uses AI. Check for mistakes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolved

@@ -27,7 +28,11 @@ cfg-if = "1.0.0"
num-integer = "0.1.46"
lib_ccxr = { path = "lib_ccxr" }
url = "2.5.4"
encoding_rs = "0.8.5"
tempfile = "3.20.0"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add this to dev-dependencies if it is only used for tests.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

moved to dev-dependencies

Comment on lines 32 to 33
memoffset = "0.9.1"
byteorder = "1.5.0"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't find them being used in the code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolved

@@ -13,6 +13,7 @@ crate-type = ["staticlib"]
[dependencies]
log = "0.4.26"
env_logger = "0.8.4"
iconv = "0.1.1"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't seem to find it in the rust code.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolved

Comment on lines 708 to 775
/// This function is unsafe because it takes a raw pointer to a C struct.
pub unsafe fn from_ctype_PSI_buffer(buffer_ptr: *mut PSI_buffer) -> Option<*mut PSIBuffer> {
if buffer_ptr.is_null() {
return None;
}

// Safety: We've checked that the pointer is not null
let buffer = unsafe { &*buffer_ptr };

// Create a new PSIBuffer
let psi_buffer = PSIBuffer {
prev_ccounter: buffer.prev_ccounter,
buffer: buffer.buffer,
buffer_length: buffer.buffer_length,
ccounter: buffer.ccounter,
};

// Box it and convert to raw pointer
Some(Box::into_raw(Box::new(psi_buffer)))
}
/// # Safety
/// This function is unsafe because it takes a raw pointer to a C struct.
pub unsafe fn from_ctype_PMT_entry(buffer_ptr: *mut PMT_entry) -> Option<*mut PMTEntry> {
if buffer_ptr.is_null() {
return None;
}

let buffer = unsafe { &*buffer_ptr };

let program_number = if buffer.program_number != 0 {
buffer.program_number
} else {
0
};

let elementary_pid = if buffer.elementary_PID != 0 {
buffer.elementary_PID
} else {
0
};

let stream_type = if buffer.stream_type != 0 {
StreamType::from_ctype(buffer.stream_type as u32).unwrap_or(StreamType::Unknownstream)
} else {
StreamType::Unknownstream
};

let printable_stream_type = if buffer.printable_stream_type != 0 {
buffer.printable_stream_type
} else {
0
};

let mut pmt_entry = PMTEntry {
program_number,
elementary_pid,
stream_type,
printable_stream_type,
};

Some(&mut pmt_entry as *mut PMTEntry)
}
pub fn from_ctype_DebugMessageMask(mask_on_normal: u32, mask_on_debug: u32) -> DebugMessageMask {
DebugMessageMask::new(
DebugMessageFlag::from_bits_truncate(mask_on_normal as u16),
DebugMessageFlag::from_bits_truncate(mask_on_debug as u16),
)
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These doesn't seem to be following the pattern of FromC, but they are declared as methods only. Any reason for this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolved

Comment on lines 248 to 251
// Helper function for array conversion
fn c_array_to_vec(c_array: &[c_uint; 128usize]) -> Vec<u32> {
c_array.to_vec()
}
Copy link
Member

@prateekmedia prateekmedia Aug 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move to separate file as this seems different? If you feel this belong here only then move to top.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolved(It was just being used once and was pretty redundant so I removed it)

Comment on lines +27 to +31
// Helper struct for DtvccServiceCharset conversion
pub struct DtvccServiceCharsetArgs {
pub services_charsets: *mut *mut ::std::os::raw::c_char,
pub all_services_charset: *mut ::std::os::raw::c_char,
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't belong here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please tell me where could I place it? It's only used in this file so that we could pass 2 pointers into FromCType instead of just one.

pub const CCX_NOPTS: i64 = 0x8000_0000_0000_0000u64 as i64;

#[repr(u32)]
pub enum Stream_Type {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seem very weird casing, it should be CamelCase, like:
StreamType

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually there are 2 stream types
I've named it this way.
ccx_stream_type => StreamType
STREAM_TYPE => Stream_Type

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But it's wrong way to write it, you'll need to rename one whilst maintaining meaning and consistency.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Renamed to DemuxerStreamType

pub initialized_ocr: bool, // Avoid initializing the OCR more than once
pub analysed_pmt_once: u8, // 1-bit field
pub version: u8,
pub saved_section: [u8; 1021],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No magic numbers, we can take out 1021 as a constant, since it is not something that's general.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolved

Comment on lines 209 to 219
let mut pi = ProgramInfo {
has_all_min_pts: false,
..Default::default()
};
for j in 0..(Stream_Type::Count as usize) {
pi.got_important_streams_min_pts[j] = u64::MAX;
}
pi.initialized_ocr = false;
pi.version = 0xFF; // “not initialized” marker
// pid and program_number remain zero for now
pinfo_vec.push(pi);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we do something to not run it for MAX_PROGRAM times cause you are just creating a similar looking pi, maybe just create and assign it once and deep copy it to pinfo_vec for each value.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolved


(*c_data).rollover_bits = rust_data.rollover_bits as c_uint;
(*c_data).pts = rust_data.pts as i64;
(*c_data).tb = rust_data.tb.to_ctype(); // Assuming Into trait is implemented
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assuming?

Copy link
Contributor Author

@steel-bucket steel-bucket Aug 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolved, I removed these comments, they're from the old version of DemuxerData which was removed.

if rust_data.codec.is_some() {
(*c_data).codec = rust_data.codec.unwrap().to_ctype();
} // Assuming Into trait is implemented
(*c_data).bufferdatatype = rust_data.bufferdatatype.to_ctype(); // Assuming Into trait is implemented
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assuming?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolved, I removed these comments, they're from the old version of DemuxerData which was removed.

len: (*c_data).len, // Reset position to start of buffer
rollover_bits: (*c_data).rollover_bits as u32,
pts: (*c_data).pts as i64,
tb: CcxRational::from_ctype((*c_data).tb).unwrap_or(CcxRational::default()), // Assuming From trait is implemented
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assuming?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolved, I removed these comments, they're from the old version of DemuxerData which was removed.

bufferdatatype: BufferdataType::from_ctype((*c_data).bufferdatatype)
.unwrap_or(BufferdataType::Unknown),
buffer: (*c_data).buffer,
len: (*c_data).len, // Reset position to start of buffer
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where are your resetting the position?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment is wrong, we're not resetting, actually it's an old comment from when I used to use a slice, which cause terrible memory corruption issues when modifying the buffer in any ways. I removed the old logic, the comment stayed. I'll remove it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolved, I removed these comments, they're from the old version of DemuxerData which was removed.

let c_data = Box::into_raw(Box::new(demuxer_data {
program_number: 42,
stream_pid: 256,
codec: Codec::Any.to_ctype(), // Assuming H264 codec exists
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assuming again?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolved, I removed these comments, they're from the old version of DemuxerData which was removed.


#[allow(clippy::ptr_eq)]
pub fn list_empty(head: &list_head) -> bool {
head.next == head as *const list_head as *mut list_head
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can also check is_null() so instead of this why are you checking head.next == head?

Copy link
Contributor Author

@steel-bucket steel-bucket Aug 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, the same function is in list.h the same way. I think an empty list would always be not null because of the way its initiated, I could be wrong, but I think the name of that function may be misleading.

///
/// This function is unsafe because we are dereferencing the pointer passed to it.
#[allow(clippy::unnecessary_cast)]
pub unsafe fn copy_to_rust(ccx_s_options: *const ccx_s_options) -> Options {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We also had this, right? IT was used in params if I am not wrong.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We had copy_from_rust, that was because we only needed to get the data from the params and copy it to c, the parser module had no need to copy ccx_options from C to Rust. And it does get mutated in C after being copied from the parser module, so I had to make this function.

Comment on lines 68 to 72
#[cfg(unix)]
let _ = file.into_raw_fd();
#[cfg(windows)]
let _ = file.into_raw_handle();
return -1;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you take out this function or write once and use as much as you want.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolved

Comment on lines 76 to 77
// If current or length is negative, return -1.
// (This check is somewhat redundant because seek returns Result<u64, _>,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You may remove this comment if it is handled differenty in rust!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolved

0
}
pub fn get_stream_mode(&mut self) -> i32 {
self.stream_mode as i32
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we are not modifying stream_mode then this method doesn't makes sense, why not just use self.stream_mode ? Or is it private field.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are modifying the stream mode, basically detecting it through detect_stream_type. But yes, that function is redundant and just for C's sake, if you see the C library, it's there.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can remove it then.

Comment on lines 146 to 148
drop(file); // This closes the file descriptor
self.infd = -1;
ccx_options.activity_input_file_closed();
Copy link
Member

@prateekmedia prateekmedia Aug 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only first line is different, right? You can keep either last three lines outside this or either last two lines outside this, depending on if you can extract drop(file).

Unless there is another case other than these unix and windows.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolved

Comment on lines 228 to 235
if self.infd != -1 {
if ccx_options.print_file_reports {
{
print_file_report(*self.parent.as_mut().unwrap());
}
}
return -1;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can extract this since it is used for three cases beginning.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolved

@ccextractor-bot
Copy link
Collaborator

CCExtractor CI platform finished running the test files on linux. Below is a summary of the test results, when compared to test for commit afde4d6...:
Report Name Tests Passed
Broken 12/13
CEA-708 13/14
DVB 7/7
DVD 0/3
DVR-MS 2/2
General 22/27
Hauppage 3/3
MP4 3/3
NoCC 10/10
Options 83/86
Teletext 21/21
WTV 13/13
XDS 33/34

Your PR breaks these cases:

NOTE: The following tests have been failing on the master branch as well as the PR:

  • ccextractor --service 1 --out=txt f17524b53f..., Last passed:

    Never

  • ccextractor --autoprogram --out=ttxt --latin1 5ae2007a79..., Last passed:

    Never

  • ccextractor --autoprogram --out=ttxt --latin1 1e44efd810..., Last passed:

    Never

  • ccextractor --autoprogram --out=ttxt --latin1 add511677c..., Last passed:

    Never

  • ccextractor --autoprogram --out=srt --latin1 e9b9008fdf..., Last passed:

    Never

  • ccextractor --autoprogram --out=ttxt --latin1 27e46255f0..., Last passed:

    Never

  • ccextractor --autoprogram --out=ttxt --latin1 1974a299f0..., Last passed:

    Never

  • ccextractor --autoprogram --out=ttxt --latin1 132d7df7e9..., Last passed:

    Never

  • ccextractor --autoprogram --out=ttxt --latin1 99e5eaafdc..., Last passed:

    Never

  • ccextractor --in=ps e9b9008fdf..., Last passed:

    Never

  • ccextractor --autoprogram --out=ttxt --latin1 --ucla --xds 0069dffd21..., Last passed:

    Never


It seems that not all tests were passed completely. This is an indication that the output of some files is not as expected (but might be according to you).

Check the result page for more info.

@ccextractor-bot
Copy link
Collaborator

CCExtractor CI platform finished running the test files on windows. Below is a summary of the test results, when compared to test for commit afde4d6...:
Report Name Tests Passed
Broken 12/13
CEA-708 13/14
DVB 2/7
DVD 0/3
DVR-MS 2/2
General 22/27
Hauppage 3/3
MP4 3/3
NoCC 10/10
Options 82/86
Teletext 7/21
WTV 10/13
XDS 33/34

Your PR breaks these cases:

NOTE: The following tests have been failing on the master branch as well as the PR:

  • ccextractor --service 1 --out=txt f17524b53f..., Last passed:

    Never

  • ccextractor --stdout --quiet --no-fontcolor 79a51f3500..., Last passed:

    Never

  • ccextractor --stdout --quiet --no-fontcolor 767b546f96..., Last passed:

    Never

  • ccextractor --autoprogram --out=srt --latin1 --quant 0 85271be4d2..., Last passed:

    Never

  • ccextractor --autoprogram --out=ttxt --latin1 5ae2007a79..., Last passed:

    Never

  • ccextractor --autoprogram --out=ttxt --latin1 1e44efd810..., Last passed:

    Never

  • ccextractor --autoprogram --out=ttxt --latin1 add511677c..., Last passed:

    Never

  • ccextractor --autoprogram --out=srt --latin1 e9b9008fdf..., Last passed:

    Never

  • ccextractor --autoprogram --out=ttxt --latin1 27e46255f0..., Last passed:

    Never

  • ccextractor --autoprogram --out=ttxt --latin1 1974a299f0..., Last passed:

    Never

  • ccextractor --autoprogram --out=ttxt --latin1 132d7df7e9..., Last passed:

    Never

  • ccextractor --autoprogram --out=ttxt --latin1 99e5eaafdc..., Last passed:

    Never

  • ccextractor --in=ps e9b9008fdf..., Last passed:

    Never

  • ccextractor --out=srt --latin1 f23a544ba8..., Last passed:

    Never

  • ccextractor --out=srt --latin1 10f0f77cf4..., Last passed:

    Test 5913

  • ccextractor --out=srt --latin1 df3b4d62d3..., Last passed:

    Never

  • ccextractor --autoprogram --out=ttxt --latin1 --ucla --xds 0069dffd21..., Last passed:

    Never


It seems that not all tests were passed completely. This is an indication that the output of some files is not as expected (but might be according to you).

Check the result page for more info.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants