Esempio n. 1
0
static void
cc_handler			(vbi_event *		ev,
				 void *			user_data)
{
	vbi_page page;
	vbi_bool success;
	int row;

	user_data = user_data;

	if (pgno != -1 && ev->ev.caption.pgno != pgno)
		return;

	/* Fetching & rendering in the handler
           is a bad idea, but this is only a test */

	success = vbi_fetch_cc_page (vbi, &page, ev->ev.caption.pgno, TRUE);
	assert (success);

#if 1 /* optional */
	if (abs (page.dirty.roll) > page.rows) {
		clear (&page);
	} else if (page.dirty.roll == -1) {
		roll_up (&page, page.dirty.y0, page.dirty.y1);
	} else {
#endif
		for (row = page.dirty.y0; row <= page.dirty.y1; ++row)
			render (&page, row);
	}

	vbi_unref_page (&page);
}
Esempio n. 2
0
/* Process GLOBAL CODES */
void handle_command(/*const */ unsigned char c1, const unsigned char c2, ccx_decoder_608_context *context, struct cc_subtitle *sub)
{
	int changes=0;

	// Handle channel change
	context->channel = context->new_channel;
	if (context->channel != context->my_channel)
		return;

	enum command_code command = COM_UNKNOWN;
	if (c1==0x15)
		c1=0x14;
	if ((c1==0x14 || c1==0x1C) && c2==0x2C)
		command = COM_ERASEDISPLAYEDMEMORY;
	if ((c1==0x14 || c1==0x1C) && c2==0x20)
		command = COM_RESUMECAPTIONLOADING;
	if ((c1==0x14 || c1==0x1C) && c2==0x2F)
		command = COM_ENDOFCAPTION;
	if ((c1==0x14 || c1==0x1C) && c2==0x22)
		command = COM_ALARMOFF;
	if ((c1==0x14 || c1==0x1C) && c2==0x23)
		command = COM_ALARMON;
	if ((c1==0x14 || c1==0x1C) && c2==0x24)
		command = COM_DELETETOENDOFROW;
	if ((c1==0x17 || c1==0x1F) && c2==0x21)
		command = COM_TABOFFSET1;
	if ((c1==0x17 || c1==0x1F) && c2==0x22)
		command = COM_TABOFFSET2;
	if ((c1==0x17 || c1==0x1F) && c2==0x23)
		command = COM_TABOFFSET3;
	if ((c1==0x14 || c1==0x1C) && c2==0x25)
		command = COM_ROLLUP2;
	if ((c1==0x14 || c1==0x1C) && c2==0x26)
		command = COM_ROLLUP3;
	if ((c1==0x14 || c1==0x1C) && c2==0x27)
		command = COM_ROLLUP4;
	if ((c1==0x14 || c1==0x1C) && c2==0x29)
		command = COM_RESUMEDIRECTCAPTIONING;
	if ((c1==0x14 || c1==0x1C) && c2==0x2D)
		command = COM_CARRIAGERETURN;
	if ((c1==0x14 || c1==0x1C) && c2==0x2E)
		command = COM_ERASENONDISPLAYEDMEMORY;
	if ((c1==0x14 || c1==0x1C) && c2==0x21)
		command = COM_BACKSPACE;
	if ((c1==0x14 || c1==0x1C) && c2==0x2b)
		command = COM_RESUMETEXTDISPLAY;

	if ((command == COM_ROLLUP2 || command == COM_ROLLUP3 || command == COM_ROLLUP4) && context->settings->force_rollup == 1)
		command=COM_FAKE_RULLUP1;

	if ((command == COM_ROLLUP3 || command == COM_ROLLUP4) && context->settings->force_rollup == 2)
		command=COM_ROLLUP2;
	else if (command == COM_ROLLUP4 && context->settings->force_rollup == 3)
		command=COM_ROLLUP3;

	ccx_common_logging.debug_ftn(CCX_DMT_DECODER_608, "\rCommand begin: %02X %02X (%s)\n", c1, c2, command_type[command]);
	ccx_common_logging.debug_ftn(CCX_DMT_DECODER_608, "\rCurrent mode: %d  Position: %d,%d  VisBuf: %d\n", context->mode,
		context->cursor_row, context->cursor_column, context->visible_buffer);

	switch (command)
	{
		case COM_BACKSPACE:
			if (context->cursor_column>0)
			{
				context->cursor_column--;
				get_writing_buffer(context)->characters[context->cursor_row][context->cursor_column] = ' ';
			}
			break;
		case COM_TABOFFSET1:
			if (context->cursor_column<CCX_DECODER_608_SCREEN_WIDTH - 1)
				context->cursor_column++;
			break;
		case COM_TABOFFSET2:
			context->cursor_column += 2;
			if (context->cursor_column>CCX_DECODER_608_SCREEN_WIDTH - 1)
				context->cursor_column = CCX_DECODER_608_SCREEN_WIDTH - 1;
			break;
		case COM_TABOFFSET3:
			context->cursor_column += 3;
			if (context->cursor_column>CCX_DECODER_608_SCREEN_WIDTH - 1)
				context->cursor_column = CCX_DECODER_608_SCREEN_WIDTH - 1;
			break;
		case COM_RESUMECAPTIONLOADING:
			context->mode = MODE_POPON;
			break;
		case COM_RESUMETEXTDISPLAY:
			context->mode = MODE_TEXT;
			break;
		case COM_FAKE_RULLUP1:
		case COM_ROLLUP2:
		case COM_ROLLUP3:
		case COM_ROLLUP4:
			if (context->mode == MODE_POPON || context->mode == MODE_PAINTON)
			{
				/* CEA-608 C.10 Style Switching (regulatory)
				[...]if pop-up or paint-on captioning is already present in
				either memory it shall be erased[...] */
				if (write_cc_buffer(context, sub))
					context->screenfuls_counter++;
				erase_memory(context, true);
			}
			erase_memory(context, false);

			// If the reception of data for a row is interrupted by data for the alternate
			// data channel or for text mode, the display of caption text will resume from the same
			// cursor position if a roll-up caption command is received and no PAC is given [...]
			if (context->mode != MODE_TEXT && context->have_cursor_position == 0)
			{
				// If no Preamble Address Code  is received, the base row shall default to row 15
				context->cursor_row = 14; // Default if the previous mode wasn't roll up already.
				context->cursor_column = 0;
				context->have_cursor_position = 1;
			}

			switch (command)
			{
				case COM_FAKE_RULLUP1:
					context->mode = MODE_FAKE_ROLLUP_1;
					break;
				case COM_ROLLUP2:
					context->mode = MODE_ROLLUP_2;
					break;
				case COM_ROLLUP3:
					context->mode = MODE_ROLLUP_3;
					break;
				case COM_ROLLUP4:
					context->mode = MODE_ROLLUP_4;
					break;
				default: // Impossible, but remove compiler warnings
					break;
			}
			break;
		case COM_CARRIAGERETURN:
			if (context->mode == MODE_PAINTON) // CR has no effect on painton mode according to zvbis' code
				break;
			if (context->mode == MODE_POPON) // CFS: Not sure about this. Is there a valid reason for CR in popup?
			{
				context->cursor_column = 0;
				if (context->cursor_row<15)
					context->cursor_row++;
				break;
			}
			if (context->output_format == CCX_OF_TRANSCRIPT)
			{
				write_cc_line(context,sub);
			}

			// In transcript mode, CR doesn't write the whole screen, to avoid
			// repeated lines.
			changes = check_roll_up(context);
			if (changes)
			{
				// Only if the roll up would actually cause a line to disappear we write the buffer
				if (context->output_format != CCX_OF_TRANSCRIPT)
				{
					if (write_cc_buffer(context, sub))
						context->screenfuls_counter++;
					if (context->settings->no_rollup)
						erase_memory(context, true); // Make sure the lines we just wrote aren't written again
				}
			}
			roll_up(context); // The roll must be done anyway of course.
			context->ts_start_of_current_line = -1; // Unknown.
			if (changes)
				context->current_visible_start_ms = get_visible_start();
			context->cursor_column = 0;
			break;
		case COM_ERASENONDISPLAYEDMEMORY:
			erase_memory(context, false);
			break;
		case COM_ERASEDISPLAYEDMEMORY:
			// Write it to disk before doing this, and make a note of the new
			// time it became clear.
			if (context->output_format == CCX_OF_TRANSCRIPT &&
				(context->mode == MODE_FAKE_ROLLUP_1 ||
				context->mode == MODE_ROLLUP_2 ||
				context->mode == MODE_ROLLUP_3 ||
				context->mode == MODE_ROLLUP_4))
			{
				// In transcript mode we just write the cursor line. The previous lines
				// should have been written already, so writing everything produces
				// duplicate lines.
				write_cc_line(context, sub);
			}
			else
			{
				if (context->output_format == CCX_OF_TRANSCRIPT)
					context->ts_start_of_current_line = context->current_visible_start_ms;
				if (write_cc_buffer(context, sub))
					context->screenfuls_counter++;
			}
			erase_memory(context, true);
			context->current_visible_start_ms = get_visible_start();
			break;
		case COM_ENDOFCAPTION: // Switch buffers
			// The currently *visible* buffer is leaving, so now we know its ending
			// time. Time to actually write it to file.
			if (write_cc_buffer(context, sub))
				context->screenfuls_counter++;
			context->visible_buffer = (context->visible_buffer == 1) ? 2 : 1;
			context->current_visible_start_ms = get_visible_start();
			context->cursor_column = 0;
			context->cursor_row = 0;
			context->current_color = context->settings->default_color;
			context->font = FONT_REGULAR;
			context->mode = MODE_POPON;
			break;
		case COM_DELETETOENDOFROW:
			delete_to_end_of_row(context);
			break;
		case COM_ALARMOFF:
		case COM_ALARMON:
			// These two are unused according to Robson's, and we wouldn't be able to do anything useful anyway
			break;
		case COM_RESUMEDIRECTCAPTIONING:
			context->mode = MODE_PAINTON;
			//ccx_common_logging.log_ftn ("\nWarning: Received ResumeDirectCaptioning, this mode is almost impossible.\n");
			//ccx_common_logging.log_ftn ("to transcribe to a text file.\n");
			break;
		default:
			ccx_common_logging.debug_ftn(CCX_DMT_DECODER_608, "\rNot yet implemented.\n");
			break;
	}
	ccx_common_logging.debug_ftn(CCX_DMT_DECODER_608, "\rCurrent mode: %d  Position: %d,%d	VisBuf: %d\n", context->mode,
		context->cursor_row, context->cursor_column, context->visible_buffer);
	ccx_common_logging.debug_ftn(CCX_DMT_DECODER_608, "\rCommand end: %02X %02X (%s)\n", c1, c2, command_type[command]);

}