Skip to content

Commit c2a1f0d

Browse files
authored
[Rust]Ported ES Module to Rust (#1736)
* Ported ES Module to Rust * Windows Failing CI * ES module: Clippy changes * ES module: Cmake failing CI * ES module: Cmake failing CI * ES Module: Fixed mistake in read_gop_info * ES Module: Minor mistakes in pic.rs and seq.rs * ES Module: Goptime regression failing * ES Module: Windows failing CI * ES Module: ASCII value change in userdata.rs * ES Module: Formatting issues
1 parent 12a27f3 commit c2a1f0d

File tree

21 files changed

+1985
-41
lines changed

21 files changed

+1985
-41
lines changed

src/lib_ccx/ccx_decoders_608.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1288,7 +1288,7 @@ unsigned char *debug_608_to_ASC(unsigned char *cc_data, int channel)
12881288
if (hi >= 0x20)
12891289
{
12901290
output[0] = hi;
1291-
output[1] = (lo >= 20 ? lo : '.');
1291+
output[1] = (lo >= 0x20 ? lo : '.');
12921292
output[2] = '\x00';
12931293
}
12941294
else

src/lib_ccx/ccx_decoders_vbi.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,4 @@ struct ccx_decoder_vbi_ctx
2525
};
2626

2727

28-
int decode_vbi(struct lib_cc_decode *dec_ctx, uint8_t field, unsigned char *buffer, size_t len, struct cc_subtitle *sub);
2928
#endif

src/lib_ccx/es_functions.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,14 @@ static int read_pic_data(struct bitstream *esstream);
2222
/* Process a mpeg-2 data stream with "length" bytes in buffer "data".
2323
* The number of processed bytes is returned.
2424
* Defined in ISO/IEC 13818-2 6.2 */
25+
#ifndef DISABLE_RUST
26+
size_t ccxr_process_m2v(struct encoder_ctx *enc_ctx, struct lib_cc_decode *dec_ctx, unsigned char *data, size_t length, struct cc_subtitle *sub);
27+
#endif
2528
size_t process_m2v(struct encoder_ctx *enc_ctx, struct lib_cc_decode *dec_ctx, unsigned char *data, size_t length, struct cc_subtitle *sub)
2629
{
30+
#ifndef DISABLE_RUST
31+
return ccxr_process_m2v(enc_ctx, dec_ctx, data, length, sub);
32+
#endif
2733
if (length < 8) // Need to look ahead 8 bytes
2834
return length;
2935

src/lib_ccx/lib_ccx.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,4 +325,6 @@ int process_non_multiprogram_general_loop(struct lib_ccx_ctx* ctx,
325325
int ret,
326326
int *caps);
327327
void segment_output_file(struct lib_ccx_ctx *ctx, struct lib_cc_decode *dec_ctx);
328+
int decode_vbi(struct lib_cc_decode *dec_ctx, uint8_t field, unsigned char *buffer, size_t len, struct cc_subtitle *sub);
329+
328330
#endif

src/rust/build.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,12 @@ fn main() {
1313
"version",
1414
"set_binary_mode",
1515
"net_send_header", // shall be removed after NET
16-
"realloc",
17-
"anchor_hdcc",
1816
"process_hdcc",
17+
"anchor_hdcc",
1918
"store_hdcc",
19+
"do_cb",
20+
"decode_vbi",
21+
"realloc",
2022
"write_spumux_footer",
2123
"write_spumux_header",
2224
]);

src/rust/lib_ccxr/src/activity.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@ use crate::common::Options;
55

66
pub trait ActivityExt {
77
fn activity_report_version(&mut self);
8+
fn activity_video_info(
9+
&mut self,
10+
hor_size: u32,
11+
vert_size: u32,
12+
aspect_ratio: &str,
13+
framerate: &str,
14+
);
815
}
916
impl ActivityExt for Options {
1017
fn activity_report_version(&mut self) {
@@ -15,4 +22,22 @@ impl ActivityExt for Options {
1522
stderr.flush().unwrap();
1623
}
1724
}
25+
fn activity_video_info(
26+
&mut self,
27+
hor_size: u32,
28+
vert_size: u32,
29+
aspect_ratio: &str,
30+
framerate: &str,
31+
) {
32+
if self.gui_mode_reports {
33+
let mut stderr = io::stderr();
34+
writeln!(
35+
stderr,
36+
"###VIDEOINFO#{}#{}#{}#{}",
37+
hor_size, vert_size, aspect_ratio, framerate
38+
)
39+
.unwrap();
40+
stderr.flush().unwrap();
41+
}
42+
}
1843
}

src/rust/lib_ccxr/src/common/bitstream.rs

Lines changed: 130 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::fatal;
22
use crate::util::log::ExitCause;
3+
use crate::util::log::{debug, DebugMessageFlag};
34
use thiserror::Error;
45

56
#[derive(Debug, Error)]
@@ -23,7 +24,12 @@ pub struct BitStreamRust<'a> {
2324
pub _i_pos: usize,
2425
pub _i_bpos: u8,
2526
}
26-
27+
#[macro_export]
28+
macro_rules! dbg_es {
29+
($($args:expr),*) => {
30+
debug!(msg_type = DebugMessageFlag::VERBOSE; "{}", format!($($args),*))
31+
};
32+
}
2733
impl<'a> BitStreamRust<'a> {
2834
/// Create a new bitstream. Empty data is allowed (bits_left = 0).
2935
pub fn new(data: &'a [u8]) -> Result<Self, BitstreamError> {
@@ -333,6 +339,129 @@ impl<'a> BitStreamRust<'a> {
333339

334340
res
335341
}
342+
// Return the next startcode or sequence_error_code if not enough
343+
// data was left in the bitstream. Also set esstream->bitsleft.
344+
// The bitstream pointer shall be moved to the begin of the start
345+
// code if found, or to the position where a search would continue
346+
// would more data be made available.
347+
// This function discards all data until the start code is
348+
// found
349+
pub fn search_start_code(&mut self) -> Result<u8, BitstreamError> {
350+
self.make_byte_aligned()?;
351+
352+
// Keep a negative esstream->bitsleft, but correct it.
353+
if self.bits_left <= 0 {
354+
dbg_es!("search_start_code: bitsleft <= 0");
355+
self.bits_left -= 8 * 4;
356+
return Ok(0xB4);
357+
}
358+
359+
let mut tpos = self.pos;
360+
361+
// Scan for 0x000001xx in header
362+
loop {
363+
// Find next 0x00 byte
364+
let remaining_data = &self.data[tpos..];
365+
if let Some(zero_offset) = remaining_data.iter().position(|&b| b == 0x00) {
366+
tpos += zero_offset;
367+
} else {
368+
// We don't even have the starting 0x00
369+
tpos = self.data.len();
370+
self.bits_left = -8 * 4;
371+
break;
372+
}
373+
374+
if tpos + 3 >= self.data.len() {
375+
// Not enough bytes left to check for 0x000001??
376+
self.bits_left = 8 * (self.data.len() as i64 - (tpos + 4) as i64);
377+
break;
378+
} else if self.data[tpos + 1] == 0x00 && self.data[tpos + 2] == 0x01 {
379+
// Found 0x000001??
380+
self.bits_left = 8 * (self.data.len() as i64 - (tpos + 4) as i64);
381+
break;
382+
}
383+
// Keep searching
384+
tpos += 1;
385+
}
386+
387+
self.pos = tpos;
388+
if self.bits_left < 0 {
389+
dbg_es!("search_start_code: bitsleft <= 0");
390+
Ok(0xB4)
391+
} else {
392+
dbg_es!("search_start_code: Found {:02X}", self.data[tpos + 3]);
393+
Ok(self.data[tpos + 3])
394+
}
395+
}
396+
397+
// Return the next startcode or sequence_error_code if not enough
398+
// data was left in the bitstream. Also set esstream->bitsleft.
399+
// The bitstream pointer shall be moved to the begin of the start
400+
// code if found, or to the position where a search would continue
401+
// would more data be made available.
402+
// Only NULL bytes before the start code are discarded, if a non
403+
// NULL byte is encountered esstream->error is set to TRUE and the
404+
// function returns sequence_error_code with the pointer set after
405+
// that byte.
406+
pub fn next_start_code(&mut self) -> Result<u8, BitstreamError> {
407+
if self.error || self.bits_left < 0 {
408+
return Ok(0xB4);
409+
}
410+
411+
self.make_byte_aligned()?;
412+
413+
// Only start looking if there is enough data. Adjust bitsleft.
414+
if self.bits_left < 4 * 8 {
415+
dbg_es!("next_start_code: bitsleft {} < 32", self.bits_left);
416+
self.bits_left -= 8 * 4;
417+
return Ok(0xB4);
418+
}
419+
420+
let mut tmp: u8;
421+
while (self.bitstream_get_num(4, false)? & 0x00FFFFFF) != 0x00010000 // LSB 0x000001??
422+
&& self.bits_left > 0
423+
{
424+
tmp = self.bitstream_get_num(1, true)? as u8;
425+
if tmp != 0 {
426+
dbg_es!("next_start_code: Non zero stuffing");
427+
self.error = true;
428+
return Ok(0xB4);
429+
}
430+
}
431+
432+
if self.bits_left < 8 {
433+
self.bits_left -= 8;
434+
dbg_es!("next_start_code: bitsleft <= 0");
435+
Ok(0xB4)
436+
} else {
437+
dbg_es!("next_start_code: Found {:02X}", self.data[self.pos + 3]);
438+
439+
if self.data[self.pos + 3] == 0xB4 {
440+
dbg_es!("B4: assume bitstream syntax error!");
441+
self.error = true;
442+
}
443+
444+
Ok(self.data[self.pos + 3])
445+
}
446+
}
447+
pub fn init_bitstream(&mut self, start: usize, end: usize) -> Result<(), BitstreamError> {
448+
if start > end || end > self.data.len() {
449+
return Err(BitstreamError::InsufficientData);
450+
}
451+
452+
self.pos = start;
453+
self.bpos = 8;
454+
self.bits_left = (end - start) as i64 * 8;
455+
self.error = false;
456+
self._i_pos = 0;
457+
self._i_bpos = 0;
458+
459+
if self.bits_left < 0 {
460+
return Err(BitstreamError::NegativeLength);
461+
}
462+
463+
Ok(())
464+
}
336465
}
337466
#[cfg(test)]
338467
mod tests {

src/rust/lib_ccxr/src/common/constants.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ pub const UTF8_MAX_BYTES: usize = 6;
155155
pub const XMLRPC_CHUNK_SIZE: usize = 64 * 1024; // 64 Kb per chunk, to avoid too many realloc()
156156

157157
// AVC NAL types
158-
#[derive(Debug, Eq, PartialEq)]
158+
#[derive(Debug, PartialEq, Eq)]
159159
pub enum AvcNalType {
160160
Unspecified0 = 0,
161161
CodedSliceNonIdrPicture1 = 1,

src/rust/lib_ccxr/src/time/units.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -537,12 +537,12 @@ impl FrameCount {
537537
/// [`Timestamp`] instead of the other format.
538538
#[derive(Copy, Clone, Debug)]
539539
pub struct GopTimeCode {
540-
drop_frame: bool,
541-
time_code_hours: u8,
542-
time_code_minutes: u8,
543-
time_code_seconds: u8,
544-
time_code_pictures: u8,
545-
timestamp: Timestamp,
540+
pub drop_frame: bool,
541+
pub time_code_hours: u8,
542+
pub time_code_minutes: u8,
543+
pub time_code_seconds: u8,
544+
pub time_code_pictures: u8,
545+
pub timestamp: Timestamp,
546546
}
547547

548548
impl GopTimeCode {

0 commit comments

Comments
 (0)