output of dvb in srt sami smptett format

This commit is contained in:
Anshul Maheshwari 2014-07-30 21:17:04 +05:30
parent 45d1dfe425
commit c054594383
11 changed files with 452 additions and 20 deletions

View File

@ -1,6 +1,9 @@
#include "ccextractor.h"
#include "cc_encoders_common.h"
#include "png.h"
#include "spupng_encoder.h"
#include "ocr.h"
#include "utility.h"
void write_stringz_as_sami(char *string, struct encoder_ctx *context, LLONG ms_start, LLONG ms_end)
{
int used;
@ -74,7 +77,152 @@ void write_stringz_as_sami(char *string, struct encoder_ctx *context, LLONG ms_s
}
int write_cc_bitmap_as_sami(struct cc_subtitle *sub, struct encoder_ctx *context)
{
struct spupng_t *sp = (struct spupng_t *)context->out->spupng_data;
int x_pos, y_pos, width, height, i;
int x, y, y_off, x_off, ret;
uint8_t *pbuf;
char *filename;
struct cc_bitmap* rect;
png_color *palette = NULL;
png_byte *alpha = NULL;
#ifdef ENABLE_OCR
char*str = NULL;
#endif
int used;
unsigned h1,m1,s1,ms1;
unsigned h2,m2,s2,ms2;
LLONG ms_start, ms_end;
char timeline[128];
int len = 0;
x_pos = -1;
y_pos = -1;
width = 0;
height = 0;
if (context->prev_start != -1 && (sub->flags & SUB_EOD_MARKER))
{
ms_start = context->prev_start + subs_delay;
ms_end = sub->start_time - 1;
}
else if ( !(sub->flags & SUB_EOD_MARKER))
{
ms_start = sub->start_time + subs_delay;
ms_end = sub->end_time - 1;
}
if(sub->nb_data == 0 )
return 0;
rect = sub->data;
for(i = 0;i < sub->nb_data;i++)
{
if(x_pos == -1)
{
x_pos = rect[i].x;
y_pos = rect[i].y;
width = rect[i].w;
height = rect[i].h;
}
else
{
if(x_pos > rect[i].x)
{
width += (x_pos - rect[i].x);
x_pos = rect[i].x;
}
if (rect[i].y < y_pos)
{
height += (y_pos - rect[i].y);
y_pos = rect[i].y;
}
if (rect[i].x + rect[i].w > x_pos + width)
{
width = rect[i].x + rect[i].w - x_pos;
}
if (rect[i].y + rect[i].h > y_pos + height)
{
height = rect[i].y + rect[i].h - y_pos;
}
}
}
if ( sub->flags & SUB_EOD_MARKER )
context->prev_start = sub->start_time;
pbuf = (uint8_t*) malloc(width * height);
memset(pbuf, 0x0, width * height);
for(i = 0;i < sub->nb_data;i++)
{
x_off = rect[i].x - x_pos;
y_off = rect[i].y - y_pos;
for (y = 0; y < rect[i].h; y++)
{
for (x = 0; x < rect[i].w; x++)
pbuf[((y + y_off) * width) + x_off + x] = rect[i].data[0][y * rect[i].w + x];
}
}
palette = (png_color*) malloc(rect[0].nb_colors * sizeof(png_color));
if(!palette)
{
ret = -1;
goto end;
}
alpha = (png_byte*) malloc(rect[0].nb_colors * sizeof(png_byte));
if(!alpha)
{
ret = -1;
goto end;
}
/* TODO do rectangle, wise one color table should not be used for all rectangle */
mapclut_paletee(palette, alpha, (uint32_t *)rect[0].data[1],rect[0].nb_colors);
quantize_map(alpha, palette, pbuf, width*height, 3, rect[0].nb_colors);
#ifdef ENABLE_OCR
str = ocr_bitmap(palette,alpha,pbuf,width,height);
if(str && str[0])
{
if (context->prev_start != -1 || !(sub->flags & SUB_EOD_MARKER))
{
char *token = NULL;
sprintf(context->buffer,
"<SYNC start=%llu><P class=\"UNKNOWNCC\">\r\n"
,(unsigned long long)ms_start);
write(context->out->fh,context->buffer,strlen(context->buffer));
token = strtok(str,"\r\n");
while (token)
{
sprintf(context->buffer,"%s",token);
token = strtok(NULL,"\r\n");
if(token)
strcat(context->buffer,"<br>\n");
else
strcat(context->buffer,"\n");
write(context->out->fh,context->buffer,strlen(context->buffer));
}
sprintf(context->buffer,
"<SYNC start=%llu><P class=\"UNKNOWNCC\">&nbsp;</P></SYNC>\r\n\r\n"
,(unsigned long long)ms_end);
write(context->out->fh,context->buffer,strlen(context->buffer));
}
}
#endif
end:
sub->nb_data = 0;
freep(&sub->data);
freep(&palette);
freep(&alpha);
return ret;
}
int write_cc_buffer_as_sami(struct eia608_screen *data, struct encoder_ctx *context)
{
int used;

View File

@ -1,5 +1,9 @@
#include "ccextractor.h"
#include "cc_encoders_common.h"
#include "png.h"
#include "spupng_encoder.h"
#include "ocr.h"
#include "utility.h"
// Produces minimally-compliant SMPTE Timed Text (W3C TTML)
// format-compatible output
@ -99,6 +103,138 @@ void write_stringz_as_smptett(char *string, struct encoder_ctx *context, LLONG m
}
int write_cc_bitmap_as_smptett(struct cc_subtitle *sub, struct encoder_ctx *context)
{
struct spupng_t *sp = (struct spupng_t *)context->out->spupng_data;
int x_pos, y_pos, width, height, i;
int x, y, y_off, x_off, ret;
uint8_t *pbuf;
char *filename;
struct cc_bitmap* rect;
png_color *palette = NULL;
png_byte *alpha = NULL;
#ifdef ENABLE_OCR
char*str = NULL;
#endif
int used;
unsigned h1,m1,s1,ms1;
unsigned h2,m2,s2,ms2;
LLONG ms_start, ms_end;
char timeline[128];
int len = 0;
x_pos = -1;
y_pos = -1;
width = 0;
height = 0;
if (context->prev_start != -1 && (sub->flags & SUB_EOD_MARKER))
{
ms_start = context->prev_start + subs_delay;
ms_end = sub->start_time - 1;
}
else if ( !(sub->flags & SUB_EOD_MARKER))
{
ms_start = sub->start_time + subs_delay;
ms_end = sub->end_time - 1;
}
if(sub->nb_data == 0 )
return 0;
rect = sub->data;
for(i = 0;i < sub->nb_data;i++)
{
if(x_pos == -1)
{
x_pos = rect[i].x;
y_pos = rect[i].y;
width = rect[i].w;
height = rect[i].h;
}
else
{
if(x_pos > rect[i].x)
{
width += (x_pos - rect[i].x);
x_pos = rect[i].x;
}
if (rect[i].y < y_pos)
{
height += (y_pos - rect[i].y);
y_pos = rect[i].y;
}
if (rect[i].x + rect[i].w > x_pos + width)
{
width = rect[i].x + rect[i].w - x_pos;
}
if (rect[i].y + rect[i].h > y_pos + height)
{
height = rect[i].y + rect[i].h - y_pos;
}
}
}
if ( sub->flags & SUB_EOD_MARKER )
context->prev_start = sub->start_time;
pbuf = (uint8_t*) malloc(width * height);
memset(pbuf, 0x0, width * height);
for(i = 0;i < sub->nb_data;i++)
{
x_off = rect[i].x - x_pos;
y_off = rect[i].y - y_pos;
for (y = 0; y < rect[i].h; y++)
{
for (x = 0; x < rect[i].w; x++)
pbuf[((y + y_off) * width) + x_off + x] = rect[i].data[0][y * rect[i].w + x];
}
}
palette = (png_color*) malloc(rect[0].nb_colors * sizeof(png_color));
if(!palette)
{
ret = -1;
goto end;
}
alpha = (png_byte*) malloc(rect[0].nb_colors * sizeof(png_byte));
if(!alpha)
{
ret = -1;
goto end;
}
/* TODO do rectangle, wise one color table should not be used for all rectangle */
mapclut_paletee(palette, alpha, (uint32_t *)rect[0].data[1],rect[0].nb_colors);
quantize_map(alpha, palette, pbuf, width*height, 3, rect[0].nb_colors);
#ifdef ENABLE_OCR
str = ocr_bitmap(palette,alpha,pbuf,width,height);
if(str && str[0])
{
if (context->prev_start != -1 || !(sub->flags & SUB_EOD_MARKER))
{
mstotime (ms_start,&h1,&m1,&s1,&ms1);
mstotime (ms_end-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, context->buffer,strlen(context->buffer) );
len = strlen(str);
write (context->out->fh, str, len);
write (context->out->fh, encoded_crlf, encoded_crlf_length);
sprintf ((char *) str,"</p>\n");
}
}
#endif
end:
sub->nb_data = 0;
freep(&sub->data);
freep(&palette);
freep(&alpha);
return ret;
}
int write_cc_buffer_as_smptett(struct eia608_screen *data, struct encoder_ctx *context)
{

View File

@ -1,5 +1,9 @@
#include "ccextractor.h"
#include "cc_encoders_common.h"
#include "png.h"
#include "spupng_encoder.h"
#include "ocr.h"
#include "utility.h"
/* The timing here is not PTS based, but output based, i.e. user delay must be accounted for
if there is any */
@ -68,6 +72,142 @@ void write_stringz_as_srt(char *string, struct encoder_ctx *context, LLONG ms_st
free(unescaped);
}
int write_cc_bitmap_as_srt(struct cc_subtitle *sub, struct encoder_ctx *context)
{
struct spupng_t *sp = (struct spupng_t *)context->out->spupng_data;
int x_pos, y_pos, width, height, i;
int x, y, y_off, x_off, ret;
uint8_t *pbuf;
char *filename;
struct cc_bitmap* rect;
png_color *palette = NULL;
png_byte *alpha = NULL;
#ifdef ENABLE_OCR
char*str = NULL;
#endif
int used;
unsigned h1,m1,s1,ms1;
unsigned h2,m2,s2,ms2;
LLONG ms_start, ms_end;
char timeline[128];
int len = 0;
x_pos = -1;
y_pos = -1;
width = 0;
height = 0;
if (context->prev_start != -1 && (sub->flags & SUB_EOD_MARKER))
{
ms_start = context->prev_start;
ms_end = sub->start_time;
}
else if ( !(sub->flags & SUB_EOD_MARKER))
{
ms_start = sub->start_time;
ms_end = sub->end_time;
}
if(sub->nb_data == 0 )
return 0;
rect = sub->data;
for(i = 0;i < sub->nb_data;i++)
{
if(x_pos == -1)
{
x_pos = rect[i].x;
y_pos = rect[i].y;
width = rect[i].w;
height = rect[i].h;
}
else
{
if(x_pos > rect[i].x)
{
width += (x_pos - rect[i].x);
x_pos = rect[i].x;
}
if (rect[i].y < y_pos)
{
height += (y_pos - rect[i].y);
y_pos = rect[i].y;
}
if (rect[i].x + rect[i].w > x_pos + width)
{
width = rect[i].x + rect[i].w - x_pos;
}
if (rect[i].y + rect[i].h > y_pos + height)
{
height = rect[i].y + rect[i].h - y_pos;
}
}
}
if ( sub->flags & SUB_EOD_MARKER )
context->prev_start = sub->start_time;
pbuf = (uint8_t*) malloc(width * height);
memset(pbuf, 0x0, width * height);
for(i = 0;i < sub->nb_data;i++)
{
x_off = rect[i].x - x_pos;
y_off = rect[i].y - y_pos;
for (y = 0; y < rect[i].h; y++)
{
for (x = 0; x < rect[i].w; x++)
pbuf[((y + y_off) * width) + x_off + x] = rect[i].data[0][y * rect[i].w + x];
}
}
palette = (png_color*) malloc(rect[0].nb_colors * sizeof(png_color));
if(!palette)
{
ret = -1;
goto end;
}
alpha = (png_byte*) malloc(rect[0].nb_colors * sizeof(png_byte));
if(!alpha)
{
ret = -1;
goto end;
}
/* TODO do rectangle, wise one color table should not be used for all rectangle */
mapclut_paletee(palette, alpha, (uint32_t *)rect[0].data[1],rect[0].nb_colors);
quantize_map(alpha, palette, pbuf, width*height, 3, rect[0].nb_colors);
#ifdef ENABLE_OCR
str = ocr_bitmap(palette,alpha,pbuf,width,height);
if(str && str[0])
{
if (context->prev_start != -1 || !(sub->flags & SUB_EOD_MARKER))
{
mstotime (ms_start,&h1,&m1,&s1,&ms1);
mstotime (ms_end-1,&h2,&m2,&s2,&ms2); // -1 To prevent overlapping with next line.
context->srt_counter++;
sprintf(timeline, "%u\r\n", context->srt_counter);
used = encode_line(context->buffer,(unsigned char *) timeline);
write(context->out->fh, context->buffer, used);
sprintf (timeline, "%02u:%02u:%02u,%03u --> %02u:%02u:%02u,%03u\r\n",
h1,m1,s1,ms1, h2,m2,s2,ms2);
used = encode_line(context->buffer,(unsigned char *) timeline);
write (context->out->fh, context->buffer, used);
len = strlen(str);
write (context->out->fh, str, len);
write (context->out->fh, encoded_crlf, encoded_crlf_length);
}
}
#endif
end:
sub->nb_data = 0;
freep(&sub->data);
freep(&palette);
freep(&alpha);
return ret;
}
int write_cc_buffer_as_srt(struct eia608_screen *data, struct encoder_ctx *context)
{
int used;

View File

@ -3,12 +3,6 @@
/* flag raised when end of display marker arrives in Dvb Subtitle */
#define SUB_EOD_MARKER (1 << 0 )
enum subtype
{
CC_BITMAP,
CC_608,
};
struct cc_bitmap
{
int x;

View File

@ -388,12 +388,22 @@ int encode_sub(struct encoder_ctx *context, struct cc_subtitle *sub)
switch (ccx_options.write_format)
{
case CCX_OF_SRT:
if (!startcredits_displayed && ccx_options.start_credits_text!=NULL)
try_to_add_start_credits(context, sub->start_time);
wrote_something = write_cc_bitmap_as_srt(sub, context);
case CCX_OF_SAMI:
if (!startcredits_displayed && ccx_options.start_credits_text!=NULL)
try_to_add_start_credits(context, sub->start_time);
wrote_something = write_cc_bitmap_as_sami(sub, context);
case CCX_OF_SMPTETT:
if (!startcredits_displayed && ccx_options.start_credits_text!=NULL)
try_to_add_start_credits(context, sub->start_time);
wrote_something = write_cc_bitmap_as_smptett(sub, context);
case CCX_OF_TRANSCRIPT:
// wrote_something = write_cc_bitmap_as_transcript(sub, context);
break;
case CCX_OF_SPUPNG:
write_cc_bitmap_as_spupng(sub, context);
wrote_something = write_cc_bitmap_as_spupng(sub, context);
break;
default:
break;

View File

@ -61,4 +61,7 @@ void write_stringz_as_smptett(char *string, struct encoder_ctx *context, LLONG m
void write_cc_buffer_to_gui(struct eia608_screen *data, struct encoder_ctx *context);
int write_cc_bitmap_as_spupng(struct cc_subtitle *sub, struct encoder_ctx *context);
int write_cc_bitmap_as_srt(struct cc_subtitle *sub, struct encoder_ctx *context);
int write_cc_bitmap_as_sami(struct cc_subtitle *sub, struct encoder_ctx *context);
int write_cc_bitmap_as_smptett(struct cc_subtitle *sub, struct encoder_ctx *context);
#endif

View File

@ -258,8 +258,11 @@ enum cxx_code_type
#define CCX_TXT_AUTO_NOT_YET_FOUND 1
#define CCX_TXT_IN_USE 2 // Positive autodetected, or forced, etc
#define CCX_OF_TYPE_TEXT 1
#define CCX_OF_TYPE_IMAGE 2
enum subtype
{
CC_BITMAP,
CC_608,
CC_TEXT,
};
#endif

View File

@ -317,10 +317,6 @@ void write_spucomment(struct spupng_t *sp,const char *str)
fprintf(sp->fpxml, "-->\n");
}
int get_spupng_subtype(void)
{
return (1 << CCX_OF_TYPE_TEXT)|(1<<CCX_OF_TYPE_IMAGE);
}
char* get_spupng_filename(void *ctx)
{
struct spupng_t *sp = (struct spupng_t *)ctx;

View File

@ -32,4 +32,8 @@ void write_spucomment(struct spupng_t *sp,const char *str);
char* get_spupng_filename(void *ctx);
void inc_spupng_fileindex(void *ctx);
void set_spupng_offset(void *ctx,int x,int y);
int mapclut_paletee(png_color *palette, png_byte *alpha, uint32_t *clut,
uint8_t depth);
int quantize_map(png_byte *alpha, png_color *palette,
uint8_t *bitmap, int size, int max_color, int nb_color);
#endif

View File

@ -267,11 +267,13 @@ int parse_PMT (unsigned char *buf,int len, int pos)
{
enum ccx_mpeg_descriptor descriptor_tag = (enum ccx_mpeg_descriptor)(*es_info++);
desc_len = (*es_info++);
#ifndef ENABLE_OCR
if(ccx_options.write_format != CCX_OF_SPUPNG )
{
mprint ("DVB subtitle only support spupng type as output\n");
mprint ("Please Compile with ENABLE_OCR flag \n");
continue;
}
#endif
if(CCX_MPEG_DSC_DVB_SUBTITLE == descriptor_tag)
{
struct dvb_config cnf;

View File

@ -5,10 +5,6 @@
#include <arpa/inet.h>
#endif
#ifdef _MSC_VER
#define snprintf(str,size,format,...) _snprintf(str,size-1,format,__VA_ARGS__)
#endif
#define RL32(x) (*(unsigned int *)(x))
#define RB32(x) (ntohl(*(unsigned int *)(x)))
#define RL16(x) (*(unsigned short int*)(x))