mirror of
https://github.com/CCExtractor/ccextractor.git
synced 2026-07-08 18:06:30 +00:00
[FIX] Route --hardsubx --tickertext through subtitle encoder (#2230)
* fix(hardsubx): route --tickertext through subtitle encoder (#2229) * chore(pr): drop changelog entry for bug fix
This commit is contained in:
committed by
GitHub
parent
1b4123b302
commit
47ad8388b1
@@ -96,9 +96,13 @@ void _display_frame(struct lib_hardsubx_ctx *ctx, AVFrame *frame, int width, int
|
||||
int hardsubx_process_frames_tickertext(struct lib_hardsubx_ctx *ctx, struct encoder_ctx *enc_ctx)
|
||||
{
|
||||
// Search for ticker text at the bottom of the screen, such as in Russia TV1 or stock prices
|
||||
int prev_sub_encoded = 1; // Previous seen subtitle encoded or not
|
||||
int dist = 0;
|
||||
int cur_sec = 0, total_sec, progress;
|
||||
int frame_number = 0;
|
||||
int64_t prev_begin_time = 0, prev_end_time = 0; // Begin and end time of previous seen subtitle
|
||||
char *ticker_text = NULL;
|
||||
char *prev_ticker_text = NULL;
|
||||
|
||||
while (av_read_frame(ctx->format_ctx, &ctx->packet) >= 0)
|
||||
{
|
||||
@@ -109,6 +113,9 @@ int hardsubx_process_frames_tickertext(struct lib_hardsubx_ctx *ctx, struct enco
|
||||
avcodec_send_packet(ctx->codec_ctx, &ctx->packet);
|
||||
if (avcodec_receive_frame(ctx->codec_ctx, ctx->frame) == 0 && frame_number % 1000 == 0)
|
||||
{
|
||||
int64_t current_pts_ms = 0;
|
||||
current_pts_ms = convert_pts_to_ms(ctx->packet.pts, ctx->format_ctx->streams[ctx->video_stream_id]->time_base);
|
||||
|
||||
// sws_scale is used to convert the pixel format to RGB24 from all other cases
|
||||
sws_scale(
|
||||
ctx->sws_ctx,
|
||||
@@ -120,19 +127,88 @@ int hardsubx_process_frames_tickertext(struct lib_hardsubx_ctx *ctx, struct enco
|
||||
ctx->rgb_frame->linesize);
|
||||
|
||||
ticker_text = _process_frame_tickertext(ctx, ctx->rgb_frame, ctx->codec_ctx->width, ctx->codec_ctx->height, frame_number);
|
||||
printf("frame_number: %d\n", frame_number);
|
||||
|
||||
if (strlen(ticker_text) > 0)
|
||||
printf("%s\n", ticker_text);
|
||||
if (ticker_text)
|
||||
{
|
||||
char *ticker_text_copy = strdup(ticker_text);
|
||||
free_rust_c_string(ticker_text);
|
||||
ticker_text = ticker_text_copy;
|
||||
}
|
||||
|
||||
cur_sec = (int)convert_pts_to_s(ctx->packet.pts, ctx->format_ctx->streams[ctx->video_stream_id]->time_base);
|
||||
total_sec = (int)convert_pts_to_s(ctx->format_ctx->duration, AV_TIME_BASE_Q);
|
||||
progress = (cur_sec * 100) / total_sec;
|
||||
activity_progress(progress, cur_sec / 60, cur_sec % 60);
|
||||
|
||||
if ((!ticker_text && !prev_ticker_text) || (ticker_text && !strlen(ticker_text) && !prev_ticker_text))
|
||||
{
|
||||
prev_end_time = current_pts_ms;
|
||||
}
|
||||
|
||||
if (ticker_text)
|
||||
{
|
||||
char *double_enter = strstr(ticker_text, "\n\n");
|
||||
if (double_enter != NULL)
|
||||
*(double_enter) = '\0';
|
||||
}
|
||||
|
||||
if (!prev_sub_encoded && prev_ticker_text)
|
||||
{
|
||||
if (ticker_text)
|
||||
{
|
||||
dist = edit_distance(ticker_text, prev_ticker_text, (int)strlen(ticker_text), (int)strlen(prev_ticker_text));
|
||||
if (dist < (0.2 * MIN(strlen(ticker_text), strlen(prev_ticker_text))))
|
||||
{
|
||||
dist = -1;
|
||||
free(ticker_text);
|
||||
ticker_text = NULL;
|
||||
prev_end_time = current_pts_ms;
|
||||
}
|
||||
}
|
||||
if (dist != -1)
|
||||
{
|
||||
add_cc_sub_text(ctx->dec_sub, prev_ticker_text, prev_begin_time, prev_end_time, "", "BURN", CCX_ENC_UTF_8);
|
||||
encode_sub(enc_ctx, ctx->dec_sub);
|
||||
prev_begin_time = prev_end_time + 1;
|
||||
free(prev_ticker_text);
|
||||
prev_ticker_text = NULL;
|
||||
prev_sub_encoded = 1;
|
||||
prev_end_time = current_pts_ms;
|
||||
if (ticker_text)
|
||||
{
|
||||
prev_ticker_text = ticker_text;
|
||||
ticker_text = NULL;
|
||||
prev_sub_encoded = 0;
|
||||
}
|
||||
}
|
||||
dist = 0;
|
||||
}
|
||||
|
||||
if (!prev_ticker_text && ticker_text)
|
||||
{
|
||||
prev_begin_time = prev_end_time + 1;
|
||||
prev_end_time = current_pts_ms;
|
||||
prev_ticker_text = ticker_text;
|
||||
ticker_text = NULL;
|
||||
prev_sub_encoded = 0;
|
||||
}
|
||||
|
||||
// Free any unconsumed C-owned ticker text from this iteration.
|
||||
free(ticker_text);
|
||||
ticker_text = NULL;
|
||||
}
|
||||
}
|
||||
av_packet_unref(&ctx->packet);
|
||||
}
|
||||
|
||||
if (!prev_sub_encoded)
|
||||
{
|
||||
add_cc_sub_text(ctx->dec_sub, prev_ticker_text, prev_begin_time, prev_end_time, "", "BURN", CCX_ENC_UTF_8);
|
||||
encode_sub(enc_ctx, ctx->dec_sub);
|
||||
prev_sub_encoded = 1;
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
free(prev_ticker_text);
|
||||
activity_progress(100, cur_sec / 60, cur_sec % 60);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -4,9 +4,7 @@ use leptonica_sys::*;
|
||||
// #[cfg(feature = "hardsubx_ocr")]
|
||||
// use rsmpeg::*;
|
||||
|
||||
use std::eprintln;
|
||||
use std::ffi;
|
||||
use std::format;
|
||||
use std::os::raw::c_char;
|
||||
use std::process::exit;
|
||||
use std::ptr::null;
|
||||
@@ -255,7 +253,7 @@ pub unsafe extern "C" fn _process_frame_tickertext(
|
||||
frame: *mut AVFrame,
|
||||
width: ::std::os::raw::c_int,
|
||||
height: ::std::os::raw::c_int,
|
||||
index: ::std::os::raw::c_int,
|
||||
_index: ::std::os::raw::c_int,
|
||||
) -> *mut ::std::os::raw::c_char {
|
||||
let mut im: *mut Pix = pixCreate(width, height, 32);
|
||||
let mut lum_im: *mut Pix = pixCreate(width, height, 32);
|
||||
@@ -290,7 +288,7 @@ pub unsafe extern "C" fn _process_frame_tickertext(
|
||||
|
||||
let mut feat_im: *mut Pix = pixCreate(width, height, 32);
|
||||
|
||||
for i in (92 * (height / 100))..height {
|
||||
for i in ((92 * height) / 100)..height {
|
||||
for j in 0..width {
|
||||
let mut p1: u32 = 0;
|
||||
let mut p2: u32 = 0;
|
||||
@@ -306,17 +304,7 @@ pub unsafe extern "C" fn _process_frame_tickertext(
|
||||
}
|
||||
}
|
||||
|
||||
let subtitle_text = get_ocr_text_simple_threshold(ctx, lum_im, 0.0);
|
||||
|
||||
let write_path: String = format!("./lum_im{}.jpg", index);
|
||||
let write_path_c: *mut c_char = string_to_c_char(&write_path);
|
||||
pixWrite(write_path_c, lum_im, IFF_JFIF_JPEG as i32);
|
||||
let _dealloc = std::ffi::CString::from_raw(write_path_c); // for memory reasons
|
||||
|
||||
let write_path: String = format!("./im{}.jpg", index);
|
||||
let write_path_c: *mut c_char = string_to_c_char(&write_path);
|
||||
pixWrite(write_path_c, lum_im, IFF_JFIF_JPEG as i32);
|
||||
let _dealloc = std::ffi::CString::from_raw(write_path_c); // for memory reasons
|
||||
let subtitle_text = dispatch_classifier_functions(ctx, feat_im);
|
||||
|
||||
pixDestroy(&mut im as *mut *mut Pix);
|
||||
pixDestroy(&mut gray_im as *mut *mut Pix);
|
||||
@@ -326,5 +314,5 @@ pub unsafe extern "C" fn _process_frame_tickertext(
|
||||
pixDestroy(&mut lum_im as *mut *mut Pix);
|
||||
pixDestroy(&mut feat_im as *mut *mut Pix);
|
||||
|
||||
subtitle_text
|
||||
string_to_c_char(&subtitle_text)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user