Example #1
0
void process_xds_bytes (const unsigned char hi, int lo)
{	
	int is_new;
	if (hi>=0x01 && hi<=0x0f)
	{
		int xds_class=(hi-1)/2; // Start codes 1 and 2 are "class type" 0, 3-4 are 2, and so on.
		is_new=hi%2; // Start codes are even
		dbg_print(DMT_XDS, "XDS Start: %u.%u  Is new: %d  | Class: %d (%s), Used buffers: %d\n",hi,lo, is_new,xds_class, XDSclasses[xds_class], how_many_used());
		int first_free_buf=-1;
		int matching_buf=-1;
		for (int i=0;i<NUM_XDS_BUFFERS;i++)
		{
			if (xds_buffers[i].in_use && 
				xds_buffers[i].xds_class==xds_class &&
				xds_buffers[i].xds_type==lo)
			{
				matching_buf=i;
				break;
			}
			if (first_free_buf==-1 && !xds_buffers[i].in_use)
				first_free_buf=i;
		}
		/* Here, 3 possibilities: 
			1) We already had a buffer for this class/type and matching_buf points to it
			2) We didn't have a buffer for this class/type and first_free_buf points to an unused one
			3) All buffers are full and we will have to skip this packet.
			*/
		if (matching_buf==-1 && first_free_buf==-1)
		{
			mprint ("Note: All XDS buffers full (bug or suicidal stream). Ignoring this one (%d,%d).\n",xds_class,lo);
			cur_xds_buffer_idx=-1;
			return;

		}
		cur_xds_buffer_idx=(matching_buf!=-1)? matching_buf:first_free_buf;

		if (is_new || !xds_buffers[cur_xds_buffer_idx].in_use)
		{
			// Whatever we had before we discard; must belong to an interrupted packet
			xds_buffers[cur_xds_buffer_idx].xds_class=xds_class;
			xds_buffers[cur_xds_buffer_idx].xds_type=lo;
			xds_buffers[cur_xds_buffer_idx].used_bytes=0;
			xds_buffers[cur_xds_buffer_idx].in_use=1;
			memset (xds_buffers[cur_xds_buffer_idx].bytes,0,NUM_BYTES_PER_PACKET);						
		}
		if (!is_new)
		{
			// Continue codes aren't added to packet.
			return;
		}
	}
	else
	{
		// Informational: 00, or 0x20-0x7F, so 01-0x1f forbidden
		dbg_print(DMT_XDS, "XDS: %02X.%02X (%c, %c)\n",hi,lo,hi,lo);
		if ((hi>0 && hi<=0x1f) || (lo>0 && lo<=0x1f))
		{
			mprint ("\rNote: Illegal XDS data");
			return;
		}
	}
	if (xds_buffers[cur_xds_buffer_idx].used_bytes<=32)
	{
		// Should always happen
		xds_buffers[cur_xds_buffer_idx].bytes[xds_buffers[cur_xds_buffer_idx].used_bytes++]=hi;
		xds_buffers[cur_xds_buffer_idx].bytes[xds_buffers[cur_xds_buffer_idx].used_bytes++]=lo;
		xds_buffers[cur_xds_buffer_idx].bytes[xds_buffers[cur_xds_buffer_idx].used_bytes]=0; 
	}
}
Example #2
0
void do_end_of_xds (unsigned char expected_checksum)
{
	if (cur_xds_buffer_idx== -1 || /* Unknown buffer, or not in use (bug) */
		!xds_buffers[cur_xds_buffer_idx].in_use)
		return;
	cur_xds_packet_class=xds_buffers[cur_xds_buffer_idx].xds_class;	
	cur_xds_payload=xds_buffers[cur_xds_buffer_idx].bytes;
	cur_xds_payload_length=xds_buffers[cur_xds_buffer_idx].used_bytes;
	cur_xds_packet_type=cur_xds_payload[1];
	cur_xds_payload[cur_xds_payload_length++]=0x0F; // The end byte itself, added to the packet
	
	int cs=0;
	for (int i=0; i<cur_xds_payload_length;i++)
	{
		cs=cs+cur_xds_payload[i];
		cs=cs & 0x7f; // Keep 7 bits only
		int c=cur_xds_payload[i]&0x7F;
		dbg_print(DMT_XDS, "%02X - %c cs: %02X\n",
			c,(c>=0x20)?c:'?', cs);
	}
	cs=(128-cs) & 0x7F; // Convert to 2's complement & discard high-order bit

	dbg_print(DMT_XDS, "End of XDS. Class=%d (%s), size=%d  Checksum OK: %d   Used buffers: %d\n",
			cur_xds_packet_class,XDSclasses[cur_xds_packet_class],
			cur_xds_payload_length,
			cs==expected_checksum, how_many_used());	

	if (cs!=expected_checksum || cur_xds_payload_length<3)
	{
		dbg_print(DMT_XDS, "Expected checksum: %02X  Calculated: %02X\n", expected_checksum, cs);
		clear_xds_buffer (cur_xds_buffer_idx); 
		return; // Bad packets ignored as per specs
	}
	
	int was_proc=0; /* Indicated if the packet was processed. Not processed means "code to do it doesn't exist yet", not an error. */
	
	switch (cur_xds_packet_class)
	{
		case XDS_CLASS_FUTURE: // Info on future program
			if (!(debug_mask & DMT_XDS)) // Don't bother processing something we don't need
			{
				was_proc=1;
				break; 
			}
		case XDS_CLASS_CURRENT: // Info on current program	
			was_proc = xds_do_current_and_future();
			break;
		case XDS_CLASS_CHANNEL:
			was_proc = xds_do_channel();
			break;
			
		case XDS_CLASS_MISC:
			was_proc = xds_do_misc();
			break;
	}
	
	if (!was_proc)
	{
		mprint ("Note: We found an currently unsupported XDS packet.\n");
	}
	clear_xds_buffer (cur_xds_buffer_idx);

}
Example #3
0
void do_end_of_xds (struct cc_subtitle *sub, struct ccx_decoders_xds_context *ctx, unsigned char expected_checksum)
{
	int cs = 0;
	int i;

	if(!ctx)
		return;

	if (ctx->cur_xds_buffer_idx== -1 || /* Unknown buffer, or not in use (bug) */
			!ctx->xds_buffers[ctx->cur_xds_buffer_idx].in_use)
		return;
	ctx->cur_xds_packet_class = ctx->xds_buffers[ctx->cur_xds_buffer_idx].xds_class;
	ctx->cur_xds_payload = ctx->xds_buffers[ctx->cur_xds_buffer_idx].bytes;
	ctx->cur_xds_payload_length=ctx->xds_buffers[ctx->cur_xds_buffer_idx].used_bytes;
	ctx->cur_xds_packet_type=ctx->cur_xds_payload[1];
	ctx->cur_xds_payload[ctx->cur_xds_payload_length++]=0x0F; // The end byte itself, added to the packet

	for (i = 0; i < ctx->cur_xds_payload_length; i++)
	{
		cs=cs+ctx->cur_xds_payload[i];
		cs=cs & 0x7f; // Keep 7 bits only
		int c=ctx->cur_xds_payload[i]&0x7F;
		ccx_common_logging.debug_ftn(CCX_DMT_DECODER_XDS, "%02X - %c cs: %02X\n",
				c,(c>=0x20)?c:'?', cs);
	}
	cs=(128-cs) & 0x7F; // Convert to 2's complement & discard high-order bit

	ccx_common_logging.debug_ftn(CCX_DMT_DECODER_XDS, "End of XDS. Class=%d (%s), size=%d  Checksum OK: %d   Used buffers: %d\n",
			ctx->cur_xds_packet_class,XDSclasses[ctx->cur_xds_packet_class],
			ctx->cur_xds_payload_length,
			cs==expected_checksum, how_many_used(ctx));

	if (cs!=expected_checksum || ctx->cur_xds_payload_length<3)
	{
		ccx_common_logging.debug_ftn(CCX_DMT_DECODER_XDS, "Expected checksum: %02X  Calculated: %02X\n", expected_checksum, cs);
		clear_xds_buffer (ctx, ctx->cur_xds_buffer_idx);
		return; // Bad packets ignored as per specs
	}

	int was_proc=0; /* Indicated if the packet was processed. Not processed means "code to do it doesn't exist yet", not an error. */
	if (ctx->cur_xds_packet_type & 0x40) // Bit 6 set
	{
		ctx->cur_xds_packet_class = XDS_CLASS_OUT_OF_BAND;
	}

	switch (ctx->cur_xds_packet_class)
	{
		case XDS_CLASS_FUTURE: // Info on future program
			if (!(ccx_common_logging.debug_mask & CCX_DMT_DECODER_XDS)) // Don't bother processing something we don't need
			{
				was_proc=1;
				break;
			}
		case XDS_CLASS_CURRENT: // Info on current program
			was_proc = xds_do_current_and_future(sub, ctx);
			break;
		case XDS_CLASS_CHANNEL:
			was_proc = xds_do_channel(sub, ctx);
			break;

		case XDS_CLASS_MISC:
			was_proc = xds_do_misc(ctx);
			break;
		case XDS_CLASS_PRIVATE: // CEA-608:
			// The Private Data Class is for use in any closed system for whatever that
			// system wishes. It shall not be defined by this standard now or in the future.
			was_proc = xds_do_private_data(sub, ctx);
			break;
		case XDS_CLASS_OUT_OF_BAND:
			ccx_common_logging.debug_ftn(CCX_DMT_DECODER_XDS, "Out-of-band data, ignored.");
			was_proc = 1;
			break;
	}

	if (!was_proc)
	{
		ccx_common_logging.log_ftn ("Note: We found a currently unsupported XDS packet.\n");
		dump (CCX_DMT_DECODER_XDS,ctx->cur_xds_payload,ctx->cur_xds_payload_length,0,0);
	}
	clear_xds_buffer (ctx, ctx->cur_xds_buffer_idx);

}