Skip to content
Permalink
Browse files

[Fix] Make -delay all output formats (#1167)

* Fix indentation

* Calculate subs_delay in encode_sub rather than in the individual encoders

Fix #1103

* Use precalculated times when sub->type == CC_TEXT

* Use calculate delay in encode_sub when sub->type == CC_608
  • Loading branch information
NilsIrl authored and cfsmp3 committed Jan 10, 2020
1 parent 1db731a commit 34d0df1d962cb1bde5451aa0943b02e9d6fd5fd2
@@ -15,7 +15,7 @@ made to reuse, not duplicate, as many functions as possible */
#include "ccx_encoders_mcc.h"
#include "ccx_dtvcc.h"

uint64_t utc_refvalue = UINT64_MAX; /* _UI64_MAX means don't use UNIX, 0 = use current system time as reference, +1 use a specific reference */
uint64_t utc_refvalue = UINT64_MAX; /* _UI64_MAX/UINT64_MAX means don't use UNIX, 0 = use current system time as reference, +1 use a specific reference */
extern int in_xds_mode;


@@ -693,13 +693,12 @@ static void try_to_add_end_credits(struct encoder_ctx *context, struct ccx_s_wri
}
}

void try_to_add_start_credits(struct encoder_ctx *context,LLONG start_ms)
void try_to_add_start_credits(struct encoder_ctx *context, LLONG start_ms)
{
LLONG st, end, window, length;
LLONG l = start_ms + context->subs_delay;
// We have a windows from last_displayed_subs_ms to l - we need to see if it fits
// We have a windows from last_displayed_subs_ms to start_ms - we need to see if it fits

if (l < context->startcreditsnotbefore.time_in_ms) // Too early
if (start_ms < context->startcreditsnotbefore.time_in_ms) // Too early
return;

if (context->last_displayed_subs_ms+1 > context->startcreditsnotafter.time_in_ms) // Too late
@@ -708,8 +707,8 @@ void try_to_add_start_credits(struct encoder_ctx *context,LLONG start_ms)
st = context->startcreditsnotbefore.time_in_ms>(context->last_displayed_subs_ms+1) ?
context->startcreditsnotbefore.time_in_ms : (context->last_displayed_subs_ms+1); // When would credits actually start

end = context->startcreditsnotafter.time_in_ms<(l-1) ?
context->startcreditsnotafter.time_in_ms : (l-1);
end = context->startcreditsnotafter.time_in_ms < start_ms - 1 ?
context->startcreditsnotafter.time_in_ms : start_ms - 1;

window = end-st; // Allowable time in MS

@@ -720,7 +719,7 @@ void try_to_add_start_credits(struct encoder_ctx *context,LLONG start_ms)
window : context->startcreditsforatmost.time_in_ms;

dbg_print(CCX_DMT_VERBOSE, "Last subs: %lld Current position: %lld\n",
context->last_displayed_subs_ms, l);
context->last_displayed_subs_ms, start_ms);
dbg_print(CCX_DMT_VERBOSE, "Not before: %lld Not after: %lld\n",
context->startcreditsnotbefore.time_in_ms,
context->startcreditsnotafter.time_in_ms);
@@ -1099,6 +1098,11 @@ int encode_sub(struct encoder_ctx *context, struct cc_subtitle *sub)
return wrote_something;
}

sub->start_time += context->subs_delay;
sub->end_time += context->subs_delay;
if (sub->start_time < 0)
return 0;

// Write subtitles as they come
if (sub->type == CC_608)
{
@@ -1109,9 +1113,11 @@ int encode_sub(struct encoder_ctx *context, struct cc_subtitle *sub)
// Determine context based on channel. This replaces the code that was above, as this was incomplete (for cases where -12 was used for example)
out = get_output_ctx(context, data->my_field);

data->end_time += context->subs_delay;
data->start_time += context->subs_delay;

if (data->format == SFORMAT_XDS)
{
data->end_time = data->end_time + context->subs_delay;
xds_write_transcript_line_prefix(context, out, data->start_time, data->end_time, data->cur_xds_packet_class);
if (data->xds_len > 0)
{
@@ -1126,7 +1132,6 @@ int encode_sub(struct encoder_ctx *context, struct cc_subtitle *sub)
continue;
}

data->end_time = data->end_time + context->subs_delay;

if (utc_refvalue != UINT64_MAX)
{
@@ -1315,7 +1320,6 @@ void write_cc_buffer_to_gui(struct eia608_screen *data, struct encoder_ctx *cont
{
unsigned h1, m1, s1, ms1;
unsigned h2, m2, s2, ms2;
LLONG ms_start;
int with_data = 0;

for (int i = 0; i<15; i++)
@@ -1326,11 +1330,6 @@ void write_cc_buffer_to_gui(struct eia608_screen *data, struct encoder_ctx *cont
if (!with_data)
return;

ms_start = data->start_time;

ms_start += context->subs_delay;
if (ms_start<0) // Drop screens that because of subs_delay start too early
return;
int time_reported = 0;
for (int i = 0; i<15; i++)
{
@@ -1339,9 +1338,8 @@ void write_cc_buffer_to_gui(struct eia608_screen *data, struct encoder_ctx *cont
fprintf(stderr, "###SUBTITLE#");
if (!time_reported)
{
LLONG ms_end = data->end_time;
millis_to_time(ms_start, &h1, &m1, &s1, &ms1);
millis_to_time(ms_end - 1, &h2, &m2, &s2, &ms2); // -1 To prevent overlapping with next line.
millis_to_time(data->start_time, &h1, &m1, &s1, &ms1);
millis_to_time(data->end_time - 1, &h2, &m2, &s2, &ms2); // -1 To prevent overlapping with next line.
// Note, only MM:SS here as we need to save space in the preview window
fprintf(stderr, "%02u:%02u#%02u:%02u#",
h1 * 60 + m1, s1, h2 * 60 + m2, s2);
@@ -18,7 +18,6 @@ int write_cc_bitmap_as_libcurl(struct cc_subtitle *sub, struct encoder_ctx *cont
int ret = 0;
#ifdef ENABLE_OCR
struct cc_bitmap* rect;
LLONG ms_start, ms_end;
unsigned h1, m1, s1, ms1;
unsigned h2, m2, s2, ms2;
char timeline[128];
@@ -8,18 +8,10 @@ int write_cc_buffer_as_g608(struct eia608_screen *data, struct encoder_ctx *cont
int used;
unsigned h1,m1,s1,ms1;
unsigned h2,m2,s2,ms2;
LLONG ms_start, ms_end;
int wrote_something = 0;
ms_start = data->start_time;

ms_start+=context->subs_delay;
if (ms_start<0) // Drop screens that because of subs_delay start too early
return 0;

ms_end = data->end_time;

millis_to_time (ms_start,&h1,&m1,&s1,&ms1);
millis_to_time (ms_end-1,&h2,&m2,&s2,&ms2); // -1 To prevent overlapping with next line.
millis_to_time (data->start_time,&h1,&m1,&s1,&ms1);
millis_to_time (data->end_time - 1,&h2,&m2,&s2,&ms2); // -1 To prevent overlapping with next line.
char timeline[128];
context->srt_counter++;
sprintf(timeline, "%u%s", context->srt_counter, context->encoded_crlf);
@@ -63,19 +63,11 @@ int pass_cc_buffer_to_python(struct eia608_screen *data, struct encoder_ctx *con
{
unsigned h1,m1,s1,ms1;
unsigned h2,m2,s2,ms2;
LLONG ms_start, ms_end;
int wrote_something = 0;
ms_start = data->start_time;
char *timeline;

ms_start+=context->subs_delay;
if (ms_start<0) // Drop screens that because of subs_delay start too early
return 0;

ms_end = data->end_time;

millis_to_time (ms_start,&h1,&m1,&s1,&ms1);
millis_to_time (ms_end-1,&h2,&m2,&s2,&ms2); // -1 To prevent overlapping with next line.
millis_to_time (data->start_time,&h1,&m1,&s1,&ms1);
millis_to_time (data->end_time-1,&h2,&m2,&s2,&ms2); // -1 To prevent overlapping with next line.

context->srt_counter++;
Asprintf(&timeline, "%02u:%02u:%02u,%03u --> %02u:%02u:%02u,%03u%s",
@@ -119,11 +119,6 @@ int write_cc_bitmap_as_sami(struct cc_subtitle *sub, struct encoder_ctx *context
int ret = 0;
#ifdef ENABLE_OCR
struct cc_bitmap* rect;
LLONG ms_start, ms_end;

ms_start = sub->start_time;
ms_end = sub->end_time;


rect = sub->data;

@@ -137,7 +132,7 @@ int write_cc_bitmap_as_sami(struct cc_subtitle *sub, struct encoder_ctx *context
{
sprintf(buf,
"<SYNC start=%llu><P class=\"UNKNOWNCC\">\r\n"
, (unsigned long long)ms_start);
, (unsigned long long) sub->start_time);
write(context->out->fh, buf, strlen(buf));
for (int i = sub->nb_data - 1; i >= 0; i--)
{
@@ -162,7 +157,7 @@ int write_cc_bitmap_as_sami(struct cc_subtitle *sub, struct encoder_ctx *context
{
sprintf(buf,
"<SYNC start=%llu><P class=\"UNKNOWNCC\">&nbsp;</P></SYNC>\r\n\r\n"
, (unsigned long long)ms_start);
, (unsigned long long) sub->start_time);
write(context->out->fh, buf, strlen(buf));
}
#endif
@@ -201,20 +196,11 @@ int write_cc_subtitle_as_sami(struct cc_subtitle *sub, struct encoder_ctx *conte
int write_cc_buffer_as_sami(struct eia608_screen *data, struct encoder_ctx *context)
{
int used;
LLONG startms, endms;
int wrote_something=0;
char str[1024];

startms = data->start_time;

startms+=context->subs_delay;
if (startms<0) // Drop screens that because of subs_delay start too early
return 0;

endms = data->end_time;
endms--; // To prevent overlapping with next line.
sprintf (str,"<SYNC start=%llu><P class=\"UNKNOWNCC\">\r\n",
(unsigned long long)startms);
(unsigned long long)data->start_time);
if (context->encoding != CCX_ENC_UNICODE)
{
dbg_print(CCX_DMT_DECODER_608, "\r%s\n", str);
@@ -247,7 +233,7 @@ int write_cc_buffer_as_sami(struct eia608_screen *data, struct encoder_ctx *cont
write (context->out->fh, context->buffer, used);
sprintf ((char *) str,
"<SYNC start=%llu><P class=\"UNKNOWNCC\">&nbsp;</P></SYNC>\r\n\r\n",
(unsigned long long)endms);
(unsigned long long)data->end_time - 1); // - 1 to prevent overlap
if (context->encoding!=CCX_ENC_UNICODE)
{
dbg_print(CCX_DMT_DECODER_608, "\r%s\n", str);
@@ -112,13 +112,9 @@ int write_cc_bitmap_as_smptett(struct cc_subtitle *sub, struct encoder_ctx *cont
int ret = 0;
#ifdef ENABLE_OCR
struct cc_bitmap* rect;
LLONG ms_start, ms_end;
//char timeline[128];
int i,len = 0;

ms_start = sub->start_time;
ms_end = sub->end_time;

if(sub->nb_data == 0 )
return 0;

@@ -136,8 +132,8 @@ int write_cc_bitmap_as_smptett(struct cc_subtitle *sub, struct encoder_ctx *cont
char *buf = (char *)context->buffer;
unsigned h1, m1, s1, ms1;
unsigned h2, m2, s2, ms2;
millis_to_time(ms_start, &h1, &m1, &s1, &ms1);
millis_to_time(ms_end - 1, &h2, &m2, &s2, &ms2); // -1 To prevent overlapping with next line.
millis_to_time(sub->start_time, &h1, &m1, &s1, &ms1);
millis_to_time(sub->end_time - 1, &h2, &m2, &s2, &ms2); // -1 To prevent overlapping with next line.
sprintf((char *)context->buffer, "<p begin=\"%02u:%02u:%02u.%03u\" end=\"%02u:%02u:%02u.%03u\">\n", h1, m1, s1, ms1, h2, m2, s2, ms2);
write(context->out->fh, buf, strlen(buf));
len = strlen(rect[i].ocr_text);
@@ -195,19 +191,11 @@ int write_cc_buffer_as_smptett(struct eia608_screen *data, struct encoder_ctx *c
int used;
unsigned h1,m1,s1,ms1;
unsigned h2,m2,s2,ms2;
LLONG endms;
int wrote_something=0;
LLONG startms = data->start_time;
char str[1024];

startms+=context->subs_delay;
if (startms<0) // Drop screens that because of subs_delay start too early
return 0;

endms = data->end_time;
endms--; // To prevent overlapping with next line.
millis_to_time (startms,&h1,&m1,&s1,&ms1);
millis_to_time (endms-1,&h2,&m2,&s2,&ms2);
millis_to_time (data->start_time,&h1,&m1,&s1,&ms1);
millis_to_time (data->end_time-1,&h2,&m2,&s2,&ms2);

for (int row=0; row < 15; row++)
{
@@ -993,15 +993,6 @@ int eia608_to_str(struct encoder_ctx *context, struct eia608_screen *data, char
int spupng_write_string(struct spupng_t *sp, char *string, LLONG start_time, LLONG end_time,
struct encoder_ctx *context)
{
LLONG ms_start = start_time + context->subs_delay;
if (ms_start < 0)
{
dbg_print(CCX_DMT_VERBOSE, "Negative start\n");
return 0;
}

LLONG ms_end = end_time + context->subs_delay;

inc_spupng_fileindex(sp);
if ((sp->fppng = fopen(sp->pngfile, "wb")) == NULL)
{
@@ -1017,7 +1008,7 @@ int spupng_write_string(struct spupng_t *sp, char *string, LLONG start_time, LLO
}
//free(string_utf32);
fclose(sp->fppng);
write_sputag_open(sp, ms_start, ms_end);
write_sputag_open(sp, start_time, end_time);
write_spucomment(sp, string);
write_sputag_close(sp);
return 1;
@@ -1045,14 +1036,6 @@ int spupng_write_ccbuffer(struct spupng_t *sp, struct eia608_screen* data,
int empty_buf = 1;
char str[512] = "";

// Check if it has negative start.
LLONG ms_start = data->start_time + context->subs_delay;
if (ms_start < 0)
{
dbg_print(CCX_DMT_VERBOSE, "Negative start\n");
return 0;
}

// Check if it is blank page.
for (row = 0; row < 15; row++)
{
@@ -18,11 +18,8 @@ int write_stringz_as_srt(char *string, struct encoder_ctx *context, LLONG ms_sta
if(!string || !string[0])
return 0;

if (ms_start<0) // Drop screens that because of subs_delay start too early
return 0;

millis_to_time (ms_start,&h1,&m1,&s1,&ms1);
millis_to_time (ms_end-1,&h2,&m2,&s2,&ms2); // -1 To prevent overlapping with next line.
millis_to_time(ms_start,&h1,&m1,&s1,&ms1);
millis_to_time(ms_end-1,&h2,&m2,&s2,&ms2); // -1 To prevent overlapping with next line.
context->srt_counter++;
sprintf(timeline, "%u%s", context->srt_counter, context->encoded_crlf);
used = encode_line(context, context->buffer,(unsigned char *) timeline);
@@ -86,7 +83,6 @@ int write_cc_bitmap_as_srt(struct cc_subtitle *sub, struct encoder_ctx *context)
int ret = 0;
#ifdef ENABLE_OCR
struct cc_bitmap* rect;
LLONG ms_start, ms_end;
unsigned h1,m1,s1,ms1;
unsigned h2,m2,s2,ms2;
char timeline[128];
@@ -95,13 +91,7 @@ int write_cc_bitmap_as_srt(struct cc_subtitle *sub, struct encoder_ctx *context)
int i = 0;
char *str;

ms_start = sub->start_time + context->subs_delay;
ms_end = sub->end_time + context->subs_delay;

if (ms_start<0) // Drop screens that because of subs_delay start too early
return 0;

if(sub->nb_data == 0 )
if(sub->nb_data == 0)
return 0;

if(sub->flags & SUB_EOD_MARKER)
@@ -116,8 +106,8 @@ int write_cc_bitmap_as_srt(struct cc_subtitle *sub, struct encoder_ctx *context)
} else {
if (context->prev_start != -1 || !(sub->flags & SUB_EOD_MARKER))
{
millis_to_time (ms_start,&h1,&m1,&s1,&ms1);
millis_to_time (ms_end-1,&h2,&m2,&s2,&ms2); // -1 To prevent overlapping with next line.
millis_to_time(sub->start_time,&h1,&m1,&s1,&ms1);
millis_to_time(sub->end_time - 1,&h2,&m2,&s2,&ms2); // -1 To prevent overlapping with next line.
context->srt_counter++;
sprintf(timeline, "%u%s", context->srt_counter, context->encoded_crlf);
used = encode_line(context, context->buffer,(unsigned char *) timeline);
@@ -158,7 +148,7 @@ int write_cc_subtitle_as_srt(struct cc_subtitle *sub,struct encoder_ctx *context
{
if(sub->type == CC_TEXT)
{
ret = write_stringz_as_srt(sub->data, context, sub->start_time + context->subs_delay, sub->end_time + context->subs_delay);
ret = write_stringz_as_srt(sub->data, context, sub->start_time, sub->end_time);
freep(&sub->data);
sub->nb_data = 0;
ret = 1;
@@ -180,9 +170,7 @@ int write_cc_buffer_as_srt(struct eia608_screen *data, struct encoder_ctx *conte
int used;
unsigned h1,m1,s1,ms1;
unsigned h2,m2,s2,ms2;
LLONG ms_start, ms_end;
int wrote_something = 0;
ms_start = data->start_time;

int prev_line_start=-1, prev_line_end=-1; // Column in which the previous line started and ended, for autodash
int prev_line_center1=-1, prev_line_center2=-1; // Center column of previous line text
@@ -198,14 +186,8 @@ int write_cc_buffer_as_srt(struct eia608_screen *data, struct encoder_ctx *conte
if (empty_buf) // Prevent writing empty screens. Not needed in .srt
return 0;

ms_start+=context->subs_delay;
if (ms_start<0) // Drop screens that because of subs_delay start too early
return 0;

ms_end = data->end_time;

millis_to_time (ms_start,&h1,&m1,&s1,&ms1);
millis_to_time (ms_end-1,&h2,&m2,&s2,&ms2); // -1 To prevent overlapping with next line.
millis_to_time (data->start_time,&h1,&m1,&s1,&ms1);
millis_to_time (data->end_time - 1,&h2,&m2,&s2,&ms2); // -1 To prevent overlapping with next line.
char timeline[128];
context->srt_counter++;
sprintf(timeline, "%u%s", context->srt_counter, context->encoded_crlf);

0 comments on commit 34d0df1

Please sign in to comment.
You can’t perform that action at this time.