Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/lib_ccx/ccx_common_constants.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ const unsigned char UTF8_BOM[] = {0xef, 0xbb, 0xbf};
const unsigned char DVD_HEADER[8] = {0x00, 0x00, 0x01, 0xb2, 0x43, 0x43, 0x01, 0xf8};
const unsigned char lc1[1] = {0x8a};
const unsigned char lc2[1] = {0x8f};
const unsigned char lc3[2] = {0x16, 0xfe};
const unsigned char lc4[2] = {0x1e, 0xfe};
const unsigned char lc3[1] = {0x16}; // McPoodle uses single-byte loop markers
const unsigned char lc4[1] = {0x1e};
const unsigned char lc5[1] = {0xff};
const unsigned char lc6[1] = {0xfe};

Expand Down
4 changes: 2 additions & 2 deletions src/lib_ccx/ccx_common_constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ extern const unsigned char UTF8_BOM[3];
extern const unsigned char DVD_HEADER[8];
extern const unsigned char lc1[1];
extern const unsigned char lc2[1];
extern const unsigned char lc3[2];
extern const unsigned char lc4[2];
extern const unsigned char lc3[1];
extern const unsigned char lc4[1];
extern const unsigned char lc5[1];
extern const unsigned char lc6[1];

Expand Down
31 changes: 26 additions & 5 deletions src/lib_ccx/general_loop.c
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,7 @@ int raw_loop(struct lib_ccx_ctx *ctx)
struct encoder_ctx *enc_ctx = update_encoder_list(ctx);
struct lib_cc_decode *dec_ctx = NULL;
int caps = 0;
int is_dvdraw = 0; // Flag to track if this is DVD raw format

dec_ctx = update_decoder_list(ctx);
dec_sub = &dec_ctx->dec_sub;
Expand All @@ -545,18 +546,33 @@ int raw_loop(struct lib_ccx_ctx *ctx)
if (ret == CCX_EOF)
break;

ret = process_raw(dec_ctx, dec_sub, data->buffer, data->len);
// Check if this is DVD raw format using Rust detection
if (!is_dvdraw && ccxr_is_dvdraw_header(data->buffer, (unsigned int)data->len))
{
is_dvdraw = 1;
mprint("Detected McPoodle's DVD raw format\n");
}

if (is_dvdraw)
{
// Use Rust implementation - handles timing internally
ret = ccxr_process_dvdraw(dec_ctx, dec_sub, data->buffer, (unsigned int)data->len);
}
else
{
ret = process_raw(dec_ctx, dec_sub, data->buffer, data->len);
// For regular raw format, advance timing based on field 1 blocks
add_current_pts(dec_ctx->timing, cb_field1 * 1001 / 30 * (MPEG_CLOCK_FREQ / 1000));
set_fts(dec_ctx->timing);
}

if (dec_sub->got_output)
{
caps = 1;
encode_sub(enc_ctx, dec_sub);
dec_sub->got_output = 0;
}

// int ccblocks = cb_field1;
add_current_pts(dec_ctx->timing, cb_field1 * 1001 / 30 * (MPEG_CLOCK_FREQ / 1000));
set_fts(dec_ctx->timing); // Now set the FTS related variables including fts_max

} while (data->len);
free(data);
return caps;
Expand Down Expand Up @@ -618,6 +634,11 @@ size_t process_raw(struct lib_cc_decode *ctx, struct cc_subtitle *sub, unsigned
return len;
}

/* NOTE: process_dvdraw() has been migrated to Rust.
* The implementation is now in src/rust/src/demuxer/dvdraw.rs
* and exported via ccxr_process_dvdraw() in src/rust/src/libccxr_exports/demuxer.rs
*/

void delete_datalist(struct demuxer_data *list)
{
struct demuxer_data *slist = list;
Expand Down
5 changes: 5 additions & 0 deletions src/lib_ccx/lib_ccx.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,11 @@ int ps_get_more_data(struct lib_ccx_ctx *ctx, struct demuxer_data **ppdata);
int general_get_more_data(struct lib_ccx_ctx *ctx, struct demuxer_data **data);
int raw_loop(struct lib_ccx_ctx *ctx);
size_t process_raw(struct lib_cc_decode *ctx, struct cc_subtitle *sub, unsigned char *buffer, size_t len);

// Rust FFI: McPoodle DVD raw format processing (see src/rust/src/demuxer/dvdraw.rs)
unsigned int ccxr_process_dvdraw(struct lib_cc_decode *ctx, struct cc_subtitle *sub, const unsigned char *buffer, unsigned int len);
int ccxr_is_dvdraw_header(const unsigned char *buffer, unsigned int len);

int general_loop(struct lib_ccx_ctx *ctx);
void process_hex(struct lib_ccx_ctx *ctx, char *filename);
int rcwt_loop(struct lib_ccx_ctx *ctx);
Expand Down
106 changes: 71 additions & 35 deletions src/lib_ccx/output.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,51 +119,87 @@ void writeDVDraw(const unsigned char *data1, int length1,
struct cc_subtitle *sub)
{
/* these are only used by DVD raw mode: */
static int loopcount = 1; /* loop 1: 5 elements, loop 2: 8 elements,
loop 3: 11 elements, rest: 15 elements */
static int datacount = 0; /* counts within loop */
static int loopcount = 1; /* loop 1: 5 elements, loop 2: 8 elements,
loop 3: 11 elements, rest: 15 elements */
static int datacount = 0; /* counts within loop */
static int waiting_for_field2 = 0; /* track if we're waiting for field 2 data */

if (datacount == 0)
/* printdata() is called separately for field 1 and field 2 data.
* Field 1: data1 set, data2 NULL
* Field 2: data1 NULL, data2 set
* We need to combine them into the DVD raw format: ff [d1] fe [d2]
*/

/* If we have data1 only (field 1), write ff + data1 and wait for field 2 */
if (data1 && length1 && (!data2 || !length2))
{
writeraw(DVD_HEADER, sizeof(DVD_HEADER), NULL, sub);
if (loopcount == 1)
writeraw(lc1, sizeof(lc1), NULL, sub);
if (loopcount == 2)
writeraw(lc2, sizeof(lc2), NULL, sub);
if (loopcount == 3)
{
writeraw(lc3, sizeof(lc3), NULL, sub);
if (data2 && length2)
writeraw(data2, length2, NULL, sub);
}
if (loopcount > 3)
if (datacount == 0)
{
writeraw(lc4, sizeof(lc4), NULL, sub);
if (data2 && length2)
writeraw(data2, length2, NULL, sub);
writeraw(DVD_HEADER, sizeof(DVD_HEADER), NULL, sub);
if (loopcount == 1)
writeraw(lc1, sizeof(lc1), NULL, sub);
else if (loopcount == 2)
writeraw(lc2, sizeof(lc2), NULL, sub);
else if (loopcount == 3)
writeraw(lc3, sizeof(lc3), NULL, sub);
else
writeraw(lc4, sizeof(lc4), NULL, sub);
}
}
datacount++;
writeraw(lc5, sizeof(lc5), NULL, sub);
if (data1 && length1)
writeraw(lc5, sizeof(lc5), NULL, sub); /* ff */
writeraw(data1, length1, NULL, sub);
if (((loopcount == 1) && (datacount < 5)) || ((loopcount == 2) && (datacount < 8)) || ((loopcount == 3) && (datacount < 11)) ||
((loopcount > 3) && (datacount < 15)))
waiting_for_field2 = 1;
return;
}

/* If we have data2 only (field 2), write fe + data2 */
if ((!data1 || !length1) && data2 && length2)
{
writeraw(lc6, sizeof(lc6), NULL, sub);
if (data2 && length2)
writeraw(data2, length2, NULL, sub);
writeraw(lc6, sizeof(lc6), NULL, sub); /* fe */
writeraw(data2, length2, NULL, sub);
waiting_for_field2 = 0;
datacount++;

/* Check if we've completed a loop */
int max_count = (loopcount == 1) ? 5 : (loopcount == 2) ? 8
: (loopcount == 3) ? 11
: 15;
if (datacount >= max_count)
{
loopcount++;
datacount = 0;
}
return;
}
else

/* If we have both data1 and data2 (legacy behavior, just in case) */
if (data1 && length1 && data2 && length2)
{
if (loopcount == 1)
if (datacount == 0)
{
writeraw(DVD_HEADER, sizeof(DVD_HEADER), NULL, sub);
if (loopcount == 1)
writeraw(lc1, sizeof(lc1), NULL, sub);
else if (loopcount == 2)
writeraw(lc2, sizeof(lc2), NULL, sub);
else if (loopcount == 3)
writeraw(lc3, sizeof(lc3), NULL, sub);
else
writeraw(lc4, sizeof(lc4), NULL, sub);
}
writeraw(lc5, sizeof(lc5), NULL, sub); /* ff */
writeraw(data1, length1, NULL, sub);
writeraw(lc6, sizeof(lc6), NULL, sub); /* fe */
writeraw(data2, length2, NULL, sub);
datacount++;

int max_count = (loopcount == 1) ? 5 : (loopcount == 2) ? 8
: (loopcount == 3) ? 11
: 15;
if (datacount >= max_count)
{
writeraw(lc6, sizeof(lc6), NULL, sub);
if (data2 && length2)
writeraw(data2, length2, NULL, sub);
loopcount++;
datacount = 0;
}
loopcount++;
datacount = 0;
}
}

Expand Down
13 changes: 13 additions & 0 deletions src/lib_ccx/stream_functions.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,19 @@ void detect_stream_type(struct ccx_demuxer *ctx)
ctx->startbytes[3] == 0x20)
ctx->stream_mode = CCX_SM_WTV;
}
// Check for McPoodle DVD raw format: 00 00 01 B2 43 43 ("CC") 01 F8
if (ctx->stream_mode == CCX_SM_ELEMENTARY_OR_NOT_FOUND && ctx->startbytes_avail >= 8)
{
if (ctx->startbytes[0] == 0x00 &&
ctx->startbytes[1] == 0x00 &&
ctx->startbytes[2] == 0x01 &&
ctx->startbytes[3] == 0xb2 &&
ctx->startbytes[4] == 0x43 && // 'C'
ctx->startbytes[5] == 0x43 && // 'C'
ctx->startbytes[6] == 0x01 &&
ctx->startbytes[7] == 0xf8)
ctx->stream_mode = CCX_SM_MCPOODLESRAW;
}
#ifdef WTV_DEBUG
if (ctx->stream_mode == CCX_SM_ELEMENTARY_OR_NOT_FOUND && ctx->startbytes_avail >= 6)
{
Expand Down
4 changes: 2 additions & 2 deletions src/rust/lib_ccxr/src/common/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ pub const UTF8_BOM: [u8; 3] = [0xef, 0xbb, 0xbf];
pub const DVD_HEADER: [u8; 8] = [0x00, 0x00, 0x01, 0xb2, 0x43, 0x43, 0x01, 0xf8];
pub const LC1: [u8; 1] = [0x8a];
pub const LC2: [u8; 1] = [0x8f];
pub const LC3: [u8; 2] = [0x16, 0xfe];
pub const LC4: [u8; 2] = [0x1e, 0xfe];
pub const LC3: [u8; 1] = [0x16]; // McPoodle uses single-byte loop markers
pub const LC4: [u8; 1] = [0x1e];
pub const LC5: [u8; 1] = [0xff];
pub const LC6: [u8; 1] = [0xfe];

Expand Down
Loading
Loading