int write_cc_buffer_as_smptett (struct eia608_screen *data, struct s_write *wb)
{
    unsigned h1,m1,s1,ms1;
    unsigned h2,m2,s2,ms2;
    int wrote_something=0;
    LLONG startms = wb->data608->current_visible_start_ms;

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

    LLONG endms   = get_visible_end()+subs_delay;
    endms--; // To prevent overlapping with next line.
    mstotime (startms,&h1,&m1,&s1,&ms1);
    mstotime (endms-1,&h2,&m2,&s2,&ms2);

    sprintf ((char *) str,"<p begin=\"%02u:%02u:%02u,%03u\" end=\"%02u:%02u:%02u,%03u\">\n",h1,m1,s1,ms1, h2,m2,s2,ms2);

    if (encoding!=ENC_UNICODE)
    {
        dbg_print(DMT_608, "\r%s\n", str);
    }
    enc_buffer_used=encode_line (enc_buffer,(unsigned char *) str);
    write (wb->fh, enc_buffer,enc_buffer_used);
    for (int i=0;i<15;i++)
    {
        if (data->row_used[i])
        {				
            int length = get_decoder_line_encoded (subline, i, data);
            if (encoding!=ENC_UNICODE)
            {
                dbg_print(DMT_608, "\r");
                dbg_print(DMT_608, "%s\n",subline);
            }
            write (wb->fh, subline, length);            
            wrote_something=1;
            //if (i!=14)            
              //write (wb->fh, encoded_br, encoded_br_length);            
            write (wb->fh,encoded_crlf, encoded_crlf_length);
        }
    }
    sprintf ((char *) str,"</p>\n");
    if (encoding!=ENC_UNICODE)
    {
        dbg_print(DMT_608, "\r%s\n", str);
    }
    enc_buffer_used=encode_line (enc_buffer,(unsigned char *) str);
    write (wb->fh, enc_buffer,enc_buffer_used);

    if (encoding!=ENC_UNICODE)
    {
        dbg_print(DMT_608, "\r%s\n", str);
    }
    enc_buffer_used=encode_line (enc_buffer,(unsigned char *) str);
    //write (wb->fh, enc_buffer,enc_buffer_used);

    return wrote_something;
}
Beispiel #2
0
int write_cc_buffer_as_sami(struct eia608_screen *data, struct encoder_ctx *context)
{
	int used;
	LLONG startms, endms;
	int wrote_something=0;
	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 ((char *) str,
			"<SYNC start=%llu><P class=\"UNKNOWNCC\">\r\n",
			(unsigned long long)startms);
	if (context->encoding != CCX_ENC_UNICODE)
	{
		dbg_print(CCX_DMT_DECODER_608, "\r%s\n", str);
	}
	used = encode_line(context->buffer,(unsigned char *) str);
	write (context->out->fh, context->buffer, used);
	for (int i=0;i<15;i++)
	{
		if (data->row_used[i])
		{
			int length = get_decoder_line_encoded (context->subline, i, data);
			if (context->encoding != CCX_ENC_UNICODE)
			{
				dbg_print(CCX_DMT_DECODER_608, "\r");
				dbg_print(CCX_DMT_DECODER_608, "%s\n",context->subline);
			}
			write (context->out->fh, context->subline, length);
			wrote_something = 1;
			if (i!=14)
				write (context->out->fh, encoded_br, encoded_br_length);
			write (context->out->fh, encoded_crlf, encoded_crlf_length);
		}
	}
	sprintf ((char *) str,"</P></SYNC>\r\n");
	if (context->encoding != CCX_ENC_UNICODE)
	{
		dbg_print(CCX_DMT_DECODER_608, "\r%s\n", str);
	}
	used = encode_line(context->buffer,(unsigned char *) str);
	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);
	if (context->encoding!=CCX_ENC_UNICODE)
	{
		dbg_print(CCX_DMT_DECODER_608, "\r%s\n", str);
	}
	used = encode_line(context->buffer,(unsigned char *) str);
	write (context->out->fh, context->buffer, used);
	return wrote_something;
}
Beispiel #3
0
int write_cc_buffer_as_srt(struct eia608_screen *data, struct encoder_ctx *context)
{
	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
	int empty_buf=1;
	for (int i=0;i<15;i++)
	{
		if (data->row_used[i])
		{
			empty_buf=0;
			break;
		}
	}
	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;

	mstotime (ms_start,&h1,&m1,&s1,&ms1);
	mstotime (ms_end-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);
	used = encode_line(context, context->buffer,(unsigned char *) timeline);
	write(context->out->fh, context->buffer, used);
	sprintf (timeline, "%02u:%02u:%02u,%03u --> %02u:%02u:%02u,%03u%s",
		h1, m1, s1, ms1, h2, m2, s2, ms2, context->encoded_crlf);
	used = encode_line(context, context->buffer,(unsigned char *) timeline);

	dbg_print(CCX_DMT_DECODER_608, "\n- - - SRT caption ( %d) - - -\n", context->srt_counter);
	dbg_print(CCX_DMT_DECODER_608, "%s",timeline);

	write (context->out->fh, context->buffer, used);
	for (int i=0;i<15;i++)
	{
		if (data->row_used[i])
		{
			if (context->sentence_cap)
			{
				capitalize (i,data);
				correct_case(i,data);
			}
			if (context->autodash && context->trim_subs)
			{
				int first=0, last=31, center1=-1, center2=-1;
				unsigned char *line = data->characters[i];
				int do_dash=1, colon_pos=-1;
				find_limit_characters(line,&first,&last);
				if (first==-1 || last==-1)  // Probably a bug somewhere though
					break;
				// Is there a speaker named, for example: TOM: What are you doing?
				for (int j=first;j<=last;j++)
				{
					if (line[j]==':')
					{
						colon_pos=j;
						break;
					}
					if (!isupper (line[j]))
						break;
				}
				if (prev_line_start==-1)
					do_dash=0;
				if (first==prev_line_start) // Case of left alignment
					do_dash=0;
				if (last==prev_line_end)  // Right align
					do_dash=0;
				if (first>prev_line_start && last<prev_line_end) // Fully contained
					do_dash=0;
				if ((first>prev_line_start && first<prev_line_end) || // Overlap
						(last>prev_line_start && last<prev_line_end))
					do_dash=0;

				center1=(first+last)/2;
				if (colon_pos!=-1)
				{
					while (colon_pos<CCX_DECODER_608_SCREEN_WIDTH &&
							(line[colon_pos]==':' ||
							 line[colon_pos]==' ' ||
							 line[colon_pos]==0x89))
						colon_pos++; // Find actual text
					center2=(colon_pos+last)/2;
				}
				else
					center2=center1;

				if (center1>=prev_line_center1-1 && center1<=prev_line_center1+1 && center1!=-1) // Center align
					do_dash=0;
				if (center2>=prev_line_center2-2 && center1<=prev_line_center2+2 && center1!=-1) // Center align
					do_dash=0;

				if (do_dash)
					write(context->out->fh, "- ", 2);
				prev_line_start=first;
				prev_line_end=last;
				prev_line_center1=center1;
				prev_line_center2=center2;

			}
			int length = get_decoder_line_encoded (context, context->subline, i, data);
			if (context->encoding!=CCX_ENC_UNICODE)
			{
				dbg_print(CCX_DMT_DECODER_608, "\r");
				dbg_print(CCX_DMT_DECODER_608, "%s\n",context->subline);
			}
			write(context->out->fh, context->subline, length);
			write(context->out->fh, context->encoded_crlf, context->encoded_crlf_length);
			wrote_something=1;
			// fprintf (wb->fh,context->encoded_crlf);
		}
	}
	dbg_print(CCX_DMT_DECODER_608, "- - - - - - - - - - - -\r\n");

	// fprintf (wb->fh, context->encoded_crlf);
	write (context->out->fh, context->encoded_crlf, context->encoded_crlf_length);
	return wrote_something;
}
Beispiel #4
0
int write_cc_buffer_as_srt (struct eia608_screen *data, struct s_write *wb)
{
    unsigned h1,m1,s1,ms1;
    unsigned h2,m2,s2,ms2;
    int wrote_something = 0;
    LLONG ms_start= wb->data608->current_visible_start_ms;

	int empty_buf=1;
    for (int i=0;i<15;i++)
    {
        if (data->row_used[i])
		{
			empty_buf=0;
			break;
		}
	}
	if (empty_buf) // Prevent writing empty screens. Not needed in .srt
		return 0;

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

	LLONG ms_end = get_visible_end()+subs_delay;		
    mstotime (ms_start,&h1,&m1,&s1,&ms1);
    mstotime (ms_end-1,&h2,&m2,&s2,&ms2); // -1 To prevent overlapping with next line.
    char timeline[128];   
    wb->data608->srt_counter++;
    sprintf (timeline,"%u\r\n",wb->data608->srt_counter);
    enc_buffer_used=encode_line (enc_buffer,(unsigned char *) timeline);
    write (wb->fh, enc_buffer,enc_buffer_used);
    sprintf (timeline, "%02u:%02u:%02u,%03u --> %02u:%02u:%02u,%03u\r\n",
        h1,m1,s1,ms1, h2,m2,s2,ms2);
    enc_buffer_used=encode_line (enc_buffer,(unsigned char *) timeline);

    dbg_print(DMT_608, "\n- - - SRT caption - - -\n");
    dbg_print(DMT_608, "%s",timeline);

    write (wb->fh, enc_buffer,enc_buffer_used);		
    for (int i=0;i<15;i++)
    {
        if (data->row_used[i])
        {		
            if (sentence_cap)
            {
                capitalize (i,data);
                correct_case(i,data);
            }
            int length = get_decoder_line_encoded (subline, i, data);
            if (encoding!=ENC_UNICODE)
            {
                dbg_print(DMT_608, "\r");
                dbg_print(DMT_608, "%s\n",subline);
            }
            write (wb->fh, subline, length);
            write (wb->fh, encoded_crlf, encoded_crlf_length);
            wrote_something=1;
            // fprintf (wb->fh,encoded_crlf);
        }
    }
    dbg_print(DMT_608, "- - - - - - - - - - - -\r\n");
    
    // fprintf (wb->fh, encoded_crlf);
    write (wb->fh, encoded_crlf, encoded_crlf_length);
    return wrote_something;
}
int spupng_write_ccbuffer(struct spupng_t *sp, struct eia608_screen* data,
		struct encoder_ctx *context)
{

	int row;
	int empty_buf = 1;
	char str[256] = "";
	int str_len = 0;
	LLONG ms_start = data->start_time + context->subs_delay;
	if (ms_start < 0)
	{
		dbg_print(CCX_DMT_VERBOSE, "Negative start\n");
		return 0;
	}
	for (row = 0; row < 15; row++)
	{
		if (data->row_used[row])
		{
			empty_buf = 0;
			break;
		}
	}
	if (empty_buf)
	{
		dbg_print(CCX_DMT_VERBOSE, "Blank page\n");
		return 0;
	}

	LLONG ms_end = data->end_time;

	sprintf(sp->pngfile, "%s/sub%04d.png", sp->dirname, sp->fileIndex++);
	if ((sp->fppng = fopen(sp->pngfile, "wb")) == NULL)
	{
		fatal(CCX_COMMON_EXIT_FILE_CREATION_FAILED, "Cannot open %s: %s\n",
				sp->pngfile, strerror(errno));
	}
	if (!spupng_export_png(sp, data))
	{
		fatal(CCX_COMMON_EXIT_FILE_CREATION_FAILED, "Cannot write %s: %s\n",
				sp->pngfile, strerror(errno));
	}
	fclose(sp->fppng);
	write_sputag(sp,ms_start,ms_end);
	for (row = 0; row < ROWS; row++)
	{
		if (data->row_used[row])
		{
			int len = get_decoder_line_encoded(context, context->subline, row, data);
			// Check for characters that spumux won't parse
			// null chars will be changed to space
			// pairs of dashes will be changed to underscores
			for (unsigned char* ptr = context->subline; ptr < context->subline+len; ptr++)
			{
				switch (*ptr)
				{
					case 0:
						*ptr = ' ';
						break;
					case '-':
						if (*(ptr+1) == '-')
						{
							*ptr++ = '_';
							*ptr = '_';
						}
						break;
				}
			}
			if (str_len + len + 3 > 256 )
			{
				mprint("WARNING: Possible Loss of data\n");
				break;
			}
			strncat(str, (const char*)context->subline, len);
			strncat(str,"\n",3);
			str_len = str_len + len + 2;
		}
	}

	write_spucomment(sp,str);
	return 1;
}