⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 decoder.c

📁 MPEG-4编解码的实现(包括MPEG4视音频编解码)
💻 C
📖 第 1 页 / 共 2 页
字号:
		transfer_16to8add(pY_Cur,                  &data[0*64], stride);
	if (cbp & 16)
		transfer_16to8add(pY_Cur + 8,              &data[1*64], stride);
	if (cbp & 8)
		transfer_16to8add(pY_Cur + next_block,     &data[2*64], stride);
	if (cbp & 4)
		transfer_16to8add(pY_Cur + 8 + next_block, &data[3*64], stride);
	if (cbp & 2)
		transfer_16to8add(pU_Cur,                  &data[4*64], stride2);
	if (cbp & 1)
		transfer_16to8add(pV_Cur,                  &data[5*64], stride2);
	stop_transfer_timer();
}


static void decoder_iframe(DECODER * dec, Bitstream * bs, int quant, int intra_dc_threshold)
{

	uint32_t x, y;

	for (y = 0; y < dec->mb_height; y++)
	{
		for (x = 0; x < dec->mb_width; x++)
		{
			MACROBLOCK * mb = &dec->mbs[y*dec->mb_width + x];

			uint32_t mcbpc;
			uint32_t cbpc;
			uint32_t acpred_flag;
			uint32_t cbpy;
			uint32_t cbp;

			mcbpc = get_mcbpc_intra(bs);
			mb->mode = mcbpc & 7;
			cbpc = (mcbpc >> 4);

			acpred_flag = BitstreamGetBit(bs);

			if (mb->mode == MODE_STUFFING)
			{
				DEBUG("-- STUFFING ?");
				continue;
			}

			cbpy = get_cbpy(bs, 1);
			cbp = (cbpy << 2) | cbpc;

			if (mb->mode == MODE_INTRA_Q)
			{
				quant += dquant_table[BitstreamGetBits(bs,2)];
				if (quant > 31)
				{
					quant = 31;
				}
				else if (quant < 1)
				{
					quant = 1;
				}
			}
			mb->quant = quant;

			if (dec->interlacing)
			{
				mb->field_dct = BitstreamGetBit(bs);
				DEBUG1("deci: field_dct: ", mb->field_dct);
			}

			decoder_mbintra(dec, mb, x, y, acpred_flag, cbp, bs, quant, intra_dc_threshold);
		}
	}

}


static void get_motion_vector(DECODER *dec, Bitstream *bs, int x, int y, int k, VECTOR * mv, int fcode)
{

	int scale_fac = 1 << (fcode - 1);
	int high = (32 * scale_fac) - 1;
	int low = ((-32) * scale_fac);
	int range = (64 * scale_fac);

	VECTOR pmv[4];
	uint32_t psad[4];

	int mv_x, mv_y;
	int pmv_x, pmv_y;


	get_pmvdata(dec->mbs, x, y, dec->mb_width, k, pmv, psad);

	pmv_x = pmv[0].x;
	pmv_y = pmv[0].y;

	mv_x = get_mv(bs, fcode);
	mv_y = get_mv(bs, fcode);
	
	mv_x += pmv_x;
	mv_y += pmv_y;

	if (mv_x < low)
	{
		mv_x += range;
	} 
	else if (mv_x > high)
	{
		mv_x -= range;
	}

	if (mv_y < low)
	{
		mv_y += range;
	} 
	else if (mv_y > high)
	{
		mv_y -= range;
	}

	mv->x = mv_x;
	mv->y = mv_y;

}

static
void decoder_pframe(DECODER * dec, Bitstream * bs, int rounding, int quant, int fcode, int intra_dc_threshold)
{

	uint32_t x, y;

	image_swap(&dec->cur, &dec->refn);
	
	start_timer();
	image_setedges(&dec->refn, dec->edged_width, dec->edged_height, dec->width, dec->height, dec->interlacing);
	stop_edges_timer();

	for (y = 0; y < dec->mb_height; y++)
	{
		for (x = 0; x < dec->mb_width; x++)
		{
			MACROBLOCK * mb = &dec->mbs[y*dec->mb_width + x];

			if (!BitstreamGetBit(bs))			// not_coded
			{
				uint32_t mcbpc;
				uint32_t cbpc;
				uint32_t acpred_flag;
				uint32_t cbpy;
				uint32_t cbp;
				uint32_t intra;

				mcbpc = get_mcbpc_inter(bs);
				mb->mode = mcbpc & 7;
				cbpc = (mcbpc >> 4);
				acpred_flag = 0;

				intra = (mb->mode == MODE_INTRA || mb->mode == MODE_INTRA_Q);
				
				if (intra)
				{
					acpred_flag = BitstreamGetBit(bs);
				}

				if (mb->mode == MODE_STUFFING)
				{
					DEBUG("-- STUFFING ?");
					continue;
				}

				cbpy = get_cbpy(bs, intra);
				cbp = (cbpy << 2) | cbpc;

				if (mb->mode == MODE_INTER_Q || mb->mode == MODE_INTRA_Q)
				{
					quant += dquant_table[BitstreamGetBits(bs,2)];
					if (quant > 31)
					{
						quant = 31;
					}
					else if (mb->quant < 1)
					{
						quant = 1;
					}
				}
				mb->quant = quant;

				if (dec->interlacing)
				{
					mb->field_dct = BitstreamGetBit(bs);
					DEBUG1("decp: field_dct: ", mb->field_dct);

					if (mb->mode == MODE_INTER || mb->mode == MODE_INTER_Q)
					{
						mb->field_pred = BitstreamGetBit(bs);
						DEBUG1("decp: field_pred: ", mb->field_pred);

						if (mb->field_pred)
						{
							mb->field_for_top = BitstreamGetBit(bs);
							DEBUG1("decp: field_for_top: ", mb->field_for_top);
							mb->field_for_bot = BitstreamGetBit(bs);
							DEBUG1("decp: field_for_bot: ", mb->field_for_bot);
						}
					}
				}

				if (mb->mode == MODE_INTER || mb->mode == MODE_INTER_Q)
				{
					if (dec->interlacing && mb->field_pred)
					{
						get_motion_vector(dec, bs, x, y, 0, &mb->mvs[0], fcode);
						get_motion_vector(dec, bs, x, y, 0, &mb->mvs[1], fcode);
					}
					else
					{
						get_motion_vector(dec, bs, x, y, 0, &mb->mvs[0], fcode);
						mb->mvs[1].x = mb->mvs[2].x = mb->mvs[3].x = mb->mvs[0].x;
						mb->mvs[1].y = mb->mvs[2].y = mb->mvs[3].y = mb->mvs[0].y;
					}
				}
				else if (mb->mode == MODE_INTER4V /* || mb->mode == MODE_INTER4V_Q */)
				{
					get_motion_vector(dec, bs, x, y, 0, &mb->mvs[0], fcode);
					get_motion_vector(dec, bs, x, y, 1, &mb->mvs[1], fcode);
					get_motion_vector(dec, bs, x, y, 2, &mb->mvs[2], fcode);
					get_motion_vector(dec, bs, x, y, 3, &mb->mvs[3], fcode);
				}
				else  // MODE_INTRA, MODE_INTRA_Q
				{
					mb->mvs[0].x = mb->mvs[1].x = mb->mvs[2].x = mb->mvs[3].x = 0;
					mb->mvs[0].y = mb->mvs[1].y = mb->mvs[2].y = mb->mvs[3].y = 0;
					decoder_mbintra(dec, mb, x, y, acpred_flag, cbp, bs, quant, intra_dc_threshold);
					continue;
				}

				decoder_mbinter(dec, mb, x, y, acpred_flag, cbp, bs, quant, rounding);
			}
			else	// not coded
			{

				mb->mode = MODE_NOT_CODED; 
				mb->mvs[0].x = mb->mvs[1].x = mb->mvs[2].x = mb->mvs[3].x = 0;
				mb->mvs[0].y = mb->mvs[1].y = mb->mvs[2].y = mb->mvs[3].y = 0;
					
				// copy macroblock directly from ref to cur

				start_timer();

				transfer8x8_copy(dec->cur.y + (16*y)*dec->edged_width + (16*x), 
						 dec->refn.y + (16*y)*dec->edged_width + (16*x), 
						 dec->edged_width);

				transfer8x8_copy(dec->cur.y + (16*y)*dec->edged_width + (16*x+8), 
						 dec->refn.y + (16*y)*dec->edged_width + (16*x+8), 
						 dec->edged_width);

				transfer8x8_copy(dec->cur.y + (16*y+8)*dec->edged_width + (16*x), 
						 dec->refn.y + (16*y+8)*dec->edged_width + (16*x), 
						 dec->edged_width);
					
				transfer8x8_copy(dec->cur.y + (16*y+8)*dec->edged_width + (16*x+8), 
						 dec->refn.y + (16*y+8)*dec->edged_width + (16*x+8), 
						 dec->edged_width);

				transfer8x8_copy(dec->cur.u + (8*y)*dec->edged_width/2 + (8*x), 
						 dec->refn.u + (8*y)*dec->edged_width/2 + (8*x), 
						 dec->edged_width/2);

				transfer8x8_copy(dec->cur.v + (8*y)*dec->edged_width/2 + (8*x), 
						 dec->refn.v + (8*y)*dec->edged_width/2 + (8*x), 
						 dec->edged_width/2);

				stop_transfer_timer();
			}
		}
	}
}

int decoder_decode(DECODER * dec, XVID_DEC_FRAME * frame)
{

	Bitstream bs;
	uint32_t rounding;
	uint32_t quant;
	uint32_t fcode;
	uint32_t intra_dc_threshold;

	start_global_timer();
	
	BitstreamInit(&bs, frame->bitstream, frame->length);

	switch (BitstreamReadHeaders(&bs, dec, &rounding, &quant, &fcode, &intra_dc_threshold, 0))
	{
	case P_VOP :
		decoder_pframe(dec, &bs, rounding, quant, fcode, intra_dc_threshold);
		break;

	case I_VOP :
		//DEBUG1("",intra_dc_threshold);
		decoder_iframe(dec, &bs, quant, intra_dc_threshold);
		break;

	case B_VOP :	// ignore
		break;
	
	case N_VOP :	// vop not coded
		break;

	default :
		return XVID_ERR_FAIL;
	}

	frame->length = BitstreamPos(&bs) / 8;

	start_timer();
	image_output(&dec->cur, dec->width, dec->height, dec->edged_width,
		     frame->image, frame->stride, frame->colorspace);
	stop_conv_timer();
	
	emms();

	stop_global_timer();

	return XVID_ERR_OK;

}

int decoder_find_vol (DECODER * dec, 
		      XVID_DEC_FRAME * frame, 
		      XVID_DEC_PARAM * param)
{
	Bitstream bs;
	uint32_t rounding;
	uint32_t quant;
	uint32_t fcode;
	uint32_t intra_dc_threshold;
	int ret;

	BitstreamInit(&bs, frame->bitstream, frame->length);

	ret = BitstreamReadHeaders(&bs, dec, &rounding, &quant, &fcode, &intra_dc_threshold, 1);
	frame->length = BitstreamPos(&bs) / 8;

	if (ret > 0) {
	  param->width = dec->width;
	  param->height = dec->height;

	  return decoder_initialize(dec);
	}
	if (ret < 0) return XVID_ERR_FORMAT;
	return XVID_ERR_FAIL;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -