Added support of SAMI and TTXT in CEA-708

This commit is contained in:
Evgeny 2017-01-13 16:04:37 +03:00
parent bff384e677
commit 0855c0a41d

View File

@ -106,7 +106,7 @@ void _dtvcc_change_pen_attribs(dtvcc_tv_screen *tv, ccx_dtvcc_pen_attribs pen_at
write(encoder->dtvcc_writers[tv->service_number - 1].fd, buf, buf_len);
}
void _dtvcc_write_row(ccx_dtvcc_writer_ctx *writer, ccx_dtvcc_service_decoder *decoder, int row_index, struct encoder_ctx *encoder)
void _dtvcc_write_row(ccx_dtvcc_writer_ctx *writer, ccx_dtvcc_service_decoder *decoder, int row_index, struct encoder_ctx *encoder, int use_colors)
{
char *buf = (char *)encoder->buffer;
size_t buf_len = 0;
@ -130,10 +130,12 @@ void _dtvcc_write_row(ccx_dtvcc_writer_ctx *writer, ccx_dtvcc_service_decoder *d
for (int i = 0; i < length; i++)
{
_dtvcc_change_pen_colors(decoder->tv, pen_color, row_index, i, encoder, 0);
if (use_colors)
_dtvcc_change_pen_colors(decoder->tv, pen_color, row_index, i, encoder, 0);
_dtvcc_change_pen_attribs(decoder->tv, pen_attribs, row_index, i, encoder, 0);
_dtvcc_change_pen_attribs(decoder->tv, pen_attribs, row_index, i, encoder, 1);
_dtvcc_change_pen_colors(decoder->tv, pen_color, row_index, i, encoder, 1);
if (use_colors)
_dtvcc_change_pen_colors(decoder->tv, pen_color, row_index, i, encoder, 1);
pen_color = decoder->tv->pen_colors[row_index][i];
pen_attribs = decoder->tv->pen_attribs[row_index][i];
@ -148,7 +150,8 @@ void _dtvcc_write_row(ccx_dtvcc_writer_ctx *writer, ccx_dtvcc_service_decoder *d
}
// there can be unclosed tags or colors after the last symbol in a row
_dtvcc_change_pen_colors(decoder->tv, pen_color, row_index, CCX_DTVCC_SCREENGRID_COLUMNS, encoder, 0);
if (use_colors)
_dtvcc_change_pen_colors(decoder->tv, pen_color, row_index, CCX_DTVCC_SCREENGRID_COLUMNS, encoder, 0);
_dtvcc_change_pen_attribs(decoder->tv, pen_attribs, row_index, CCX_DTVCC_SCREENGRID_COLUMNS, encoder, 0);
// Tags can still be crossed e.g <f><i>text</f></i>, but testing HTML code has shown that they still are handled correctly.
// In case of errors fix it once and for all.
@ -205,7 +208,7 @@ void ccx_dtvcc_write_srt(ccx_dtvcc_writer_ctx *writer, ccx_dtvcc_service_decoder
{
if (!_dtvcc_is_row_empty(decoder->tv, i))
{
_dtvcc_write_row(writer, decoder, i, encoder);
_dtvcc_write_row(writer, decoder, i, encoder, 1);
write(encoder->dtvcc_writers[decoder->tv->service_number - 1].fd,
encoder->encoded_crlf, encoder->encoded_crlf_length);
}
@ -236,28 +239,28 @@ void ccx_dtvcc_write_debug(dtvcc_tv_screen *tv)
}
}
void ccx_dtvcc_write_transcript(ccx_dtvcc_writer_ctx *writer, dtvcc_tv_screen *tv, struct encoder_ctx *encoder)
void ccx_dtvcc_write_transcript(ccx_dtvcc_writer_ctx *writer, ccx_dtvcc_service_decoder *decoder, struct encoder_ctx *encoder)
{
if (_dtvcc_is_screen_empty(tv))
if (_dtvcc_is_screen_empty(decoder->tv))
return;
if (tv->time_ms_show + encoder->subs_delay < 0) // Drop screens that because of subs_delay start too early
if (decoder->tv->time_ms_show + encoder->subs_delay < 0) // Drop screens that because of subs_delay start too early
return;
char *buf = (char *) encoder->buffer;
for (int i = 0; i < CCX_DTVCC_SCREENGRID_ROWS; i++)
{
if (!_dtvcc_is_row_empty(tv, i))
if (!_dtvcc_is_row_empty(decoder->tv, i))
{
buf[0] = 0;
if (encoder->transcript_settings->showStartTime)
print_mstime_buff(tv->time_ms_show + encoder->subs_delay,
print_mstime_buff(decoder->tv->time_ms_show + encoder->subs_delay,
"%02u:%02u:%02u,%03u|", buf + strlen(buf));
if (encoder->transcript_settings->showEndTime)
print_mstime_buff(tv->time_ms_hide + encoder->subs_delay,
print_mstime_buff(decoder->tv->time_ms_hide + encoder->subs_delay,
"%02u:%02u:%02u,%03u|", buf + strlen(buf));
if (encoder->transcript_settings->showCC)
@ -267,10 +270,10 @@ void ccx_dtvcc_write_transcript(ccx_dtvcc_writer_ctx *writer, dtvcc_tv_screen *t
sprintf(buf + strlen(buf), "POP|"); //TODO caption mode(pop, rollup, etc.)
if (strlen(buf))
write(encoder->dtvcc_writers[tv->service_number - 1].fd, buf, strlen(buf));
write(encoder->dtvcc_writers[decoder->tv->service_number - 1].fd, buf, strlen(buf));
_dtvcc_write_row(writer, tv, i, encoder);
write(encoder->dtvcc_writers[tv->service_number - 1].fd,
_dtvcc_write_row(writer, decoder->tv, i, encoder, 0);
write(encoder->dtvcc_writers[decoder->tv->service_number - 1].fd,
encoder->encoded_crlf, encoder->encoded_crlf_length);
}
}
@ -310,43 +313,41 @@ void _dtvcc_write_sami_footer(dtvcc_tv_screen *tv, struct encoder_ctx *encoder)
encoder->encoded_crlf, encoder->encoded_crlf_length);
}
void ccx_dtvcc_write_sami(ccx_dtvcc_writer_ctx *writer, dtvcc_tv_screen *tv, struct encoder_ctx *encoder)
void ccx_dtvcc_write_sami(ccx_dtvcc_writer_ctx *writer, ccx_dtvcc_service_decoder *decoder, struct encoder_ctx *encoder)
{
if (_dtvcc_is_screen_empty(tv))
if (_dtvcc_is_screen_empty(decoder->tv))
return;
if (tv->time_ms_show + encoder->subs_delay < 0)
if (decoder->tv->time_ms_show + encoder->subs_delay < 0)
return;
if (tv->cc_count == 1)
_dtvcc_write_sami_header(tv, encoder);
if (decoder->tv->cc_count == 1)
_dtvcc_write_sami_header(decoder->tv, encoder);
char *buf = (char *) encoder->buffer;
buf[0] = 0;
sprintf(buf, "<sync start=%llu><p class=\"unknowncc\">%s",
(unsigned long long) tv->time_ms_show + encoder->subs_delay,
(unsigned long long) decoder->tv->time_ms_show + encoder->subs_delay,
encoder->encoded_crlf);
write(encoder->dtvcc_writers[tv->service_number - 1].fd, buf, strlen(buf));
write(encoder->dtvcc_writers[decoder->tv->service_number - 1].fd, buf, strlen(buf));
for (int i = 0; i < CCX_DTVCC_SCREENGRID_ROWS; i++)
{
if (!_dtvcc_is_row_empty(tv, i))
if (!_dtvcc_is_row_empty(decoder->tv, i))
{
//_dtvcc_write_tag_open(tv, encoder, i);
//_dtvcc_write_row(writer, tv, i, encoder);
//_dtvcc_write_tag_close(tv, encoder, i);
write(encoder->dtvcc_writers[tv->service_number - 1].fd,
_dtvcc_write_row(writer, decoder, i, encoder, 1);
write(encoder->dtvcc_writers[decoder->tv->service_number - 1].fd,
encoder->encoded_br, encoder->encoded_br_length);
write(encoder->dtvcc_writers[tv->service_number - 1].fd,
write(encoder->dtvcc_writers[decoder->tv->service_number - 1].fd,
encoder->encoded_crlf, encoder->encoded_crlf_length);
}
}
sprintf(buf, "<sync start=%llu><p class=\"unknowncc\">&nbsp;</p></sync>%s%s",
(unsigned long long) tv->time_ms_hide + encoder->subs_delay,
(unsigned long long) decoder->tv->time_ms_hide + encoder->subs_delay,
encoder->encoded_crlf, encoder->encoded_crlf);
write(encoder->dtvcc_writers[tv->service_number - 1].fd, buf, strlen(buf));
write(encoder->dtvcc_writers[decoder->tv->service_number - 1].fd, buf, strlen(buf));
}
void _ccx_dtvcc_write(ccx_dtvcc_writer_ctx *writer, ccx_dtvcc_service_decoder *decoder, struct encoder_ctx *encoder)
@ -359,10 +360,10 @@ void _ccx_dtvcc_write(ccx_dtvcc_writer_ctx *writer, ccx_dtvcc_service_decoder *d
ccx_dtvcc_write_srt(writer, decoder, encoder);
break;
case CCX_OF_TRANSCRIPT:
ccx_dtvcc_write_transcript(writer, decoder->tv, encoder);
ccx_dtvcc_write_transcript(writer, decoder, encoder);
break;
case CCX_OF_SAMI:
ccx_dtvcc_write_sami(writer, decoder->tv, encoder);
ccx_dtvcc_write_sami(writer, decoder, encoder);
break;
default:
ccx_dtvcc_write_debug(decoder->tv);