Beispiel #1
0
static void check_stream_type(APEG_LAYER *layer)
{
	// Assume a non-system stream
	layer->system_stream_flag = NO_SYSTEM;

	// Initialize the buffer
	_apeg_initialize_buffer(layer);

	// Transport streams (what'r those?) aren't supported
	if(show_bits(layer, 8) == 0x47)
		apeg_error_jump("Transport streams not supported");

	/* Get the first start code */
recheck:
	switch(show_bits32(layer))
	{
		case VIDEO_ELEMENTARY_STREAM:
			/* Found video, system stream */
			layer->system_stream_flag = MPEG_SYSTEM;
			/* fall-through; set flag and break */
		case SEQUENCE_HEADER_CODE:
			/* Found video */
			if(!_apeg_ignore_video)
				layer->stream.flags |= APEG_MPG_VIDEO;
			break;

		case AUDIO_ELEMENTARY_STREAM:
			/* apeg_start_audio will set APEG_MPG_AUDIO later */
			layer->system_stream_flag = MPEG_SYSTEM;
			apeg_start_code(layer);
			goto recheck;

		default:
			if(layer->system_stream_flag == NO_SYSTEM)
			{
				if(show_bits32(layer) == (('O'<<24)|('g'<<16)|('g'<<8)|('S')))
				{
					layer->system_stream_flag = OGG_SYSTEM;
					_apeg_initialize_buffer(layer);
					if(alogg_open(layer) != APEG_OK)
						apeg_error_jump("Error opening Ogg stream");
					return;
				}
#ifndef DISABLE_MPEG_AUDIO
				if(almpa_head_backcheck(show_bits32(layer)))
					break;
#endif
			}

			/* no positive stream identified; recheck */
			apeg_flush_bits8(layer, 8);
			goto recheck;
	}

	_apeg_initialize_buffer(layer);
}
static void p_picture(APEG_LAYER *layer)
{
	const int MBAmax = layer->mb_cols*layer->mb_rows;
	int macroblock_type;
	int coded_block_pattern;
	int MBA, MBAinc;
	int dc_dct_pred[3];
	int PMV[2];
	int bx, by;
	unsigned int code;

slice_start:
	dc_dct_pred[0] = dc_dct_pred[1] = dc_dct_pred[2] = 0;
	PMV[0] = PMV[1] = 0;

	code = apeg_start_code(layer);
	if(code < SLICE_START_CODE_MIN || code > SLICE_START_CODE_MAX)
		return;
	apeg_flush_bits32(layer);

	slice_header(layer);

	bx = get_mba_inc(layer);
	by = (code&255) - 1;

	MBA = by*layer->mb_cols + bx;

	bx <<= 4;
	by <<= 4;

block_start:
	code = show_bits(layer, 6);

	if(code >= 8)
	{
		code >>= 3;

		apeg_flush_bits8(layer, PMBtab0[code].len);
		macroblock_type = PMBtab0[code].val;

		dc_dct_pred[0] = dc_dct_pred[1] = dc_dct_pred[2] = 0;

		switch(macroblock_type & (MACROBLOCK_MOTION_FORWARD|MACROBLOCK_PATTERN))
		{
			case MACROBLOCK_MOTION_FORWARD|MACROBLOCK_PATTERN:
				apeg_motion_vector(layer,PMV,forward_code,full_forward_vector);
				apeg_form_f_pred(layer, bx, by, PMV);

				break;

			case MACROBLOCK_PATTERN:
				PMV[0] = PMV[1] = 0;
				apeg_empty_pred(layer->forward_frame, layer->current_frame, bx, by, layer->coded_width);

				break;

			default:
				apeg_motion_vector(layer,PMV,forward_code,full_forward_vector);
				apeg_form_f_pred(layer, bx, by, PMV);

				goto next;
		}
	}
/* decode all macroblocks of the current picture */
static void i_picture(APEG_LAYER *layer)
{
	const int MBAmax = layer->mb_cols*layer->mb_rows;
	int MBA, MBAinc;
	int dc_dct_pred[3];
	int bx, by;
	unsigned int code;

slice_start:
	dc_dct_pred[0] = dc_dct_pred[1] = dc_dct_pred[2] = 0;

	code = apeg_start_code(layer);
	if(code < SLICE_START_CODE_MIN || code > SLICE_START_CODE_MAX)
		return;
	apeg_flush_bits32(layer);

	slice_header(layer);

	bx = get_mba_inc(layer);
	by = (code&255) - 1;

	MBA = by*layer->mb_cols + bx;

	bx <<= 4;
	by <<= 4;

block_start:
	switch(show_bits(layer, 2))
	{
		case 0:
			goto slice_start;

		case 1:
			layer->quantizer_scale = apeg_get_bits(layer, 7) & MASK_BITS(5);
			break;

		default:
			apeg_flush_bits1(layer);
	}

	apeg_decode_intra_blocks(layer, dc_dct_pred);

	apeg_fast_idct(apeg_block[0]);
	apeg_fast_idct(apeg_block[1]);
	apeg_fast_idct(apeg_block[2]);
	apeg_fast_idct(apeg_block[3]);
	apeg_fast_idct(apeg_block[4]);
	apeg_fast_idct(apeg_block[5]);
	Move_Blocks(layer, bx, by);

	if(++MBA >= MBAmax)
		return;

	if(show_bits(layer, 24) == 1)
		goto slice_start;

	MBAinc = get_mba_inc(layer);
	if(MBAinc == 0)
	{
		if((bx += 16) == layer->coded_width)
		{
			bx = 0;
			by += 16;
		}
		goto block_start;
	}

	dc_dct_pred[0] = dc_dct_pred[1] = dc_dct_pred[2] = 0;

	MBA += MBAinc;
	if(MBA >= MBAmax)
		return;

	bx = (MBA%layer->mb_cols) << 4;
	by = (MBA/layer->mb_cols) << 4;

	goto block_start;
}