📄 decoder.c
字号:
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 bound; uint32_t x, y; bound = 0; for (y = 0; y < dec->mb_height; y++) { for (x = 0; x < dec->mb_width; x++) { MACROBLOCK *mb; uint32_t mcbpc; uint32_t cbpc; uint32_t acpred_flag; uint32_t cbpy; uint32_t cbp; while (BitstreamShowBits(bs, 9) == 1) BitstreamSkip(bs, 9); if (check_resync_marker(bs, 0)) { bound = read_video_packet_header(dec,I_VOP,bs, 0, &quant); if (bound) { x = bound % dec->mb_width; y = bound / dec->mb_width; } } mb = &dec->mbs[y * dec->mb_width + x]; // DEBUG //printf("xvid mb %u %u 0x%08x, start %u\n", //y, x, BitstreamShowBits(bs, 32), BitstreamPos(bs)); mcbpc = get_mcbpc_intra(bs); mb->mode = mcbpc & 7; cbpc = (mcbpc >> 4);#ifdef MPEG4IP if (dec->have_short_header) { acpred_flag = 0; } else { acpred_flag = BitstreamGetBit(bs); }#else acpred_flag = BitstreamGetBit(bs);#endif 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, bound); } }}static void get_motion_vector(DECODER *dec, Bitstream *bs, int x, int y, int k, VECTOR * mv, int fcode, const int bound){ int scale_fac = 1 << (fcode - 1); int high = (32 * scale_fac) - 1; int low = ((-32) * scale_fac); int range = (64 * scale_fac); VECTOR pmv; int mv_x, mv_y; pmv = get_pmv2(dec->mbs, dec->mb_width, bound, x, y, k); 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;}staticvoid decoder_pframe(DECODER * dec, Bitstream * bs, int rounding, int quant, int fcode, int intra_dc_threshold){ uint32_t bound; uint32_t x, y; int cp_mb, st_mb; 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(); bound = 0; for (y = 0; y < dec->mb_height; y++) { for (x = 0; x < dec->mb_width; x++) { MACROBLOCK *mb; // skip stuffing while (BitstreamShowBits(bs, 10) == 1) BitstreamSkip(bs, 10); if (check_resync_marker(bs, fcode - 1)) { bound = read_video_packet_header(dec,P_VOP,bs, fcode - 1, &quant); if (bound) { x = bound % dec->mb_width; y = bound / dec->mb_width; } } 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) {#ifdef MPEG4IP if (!dec->have_short_header) { acpred_flag = BitstreamGetBit(bs); }#else acpred_flag = BitstreamGetBit(bs);#endif } 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 (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, bound); get_motion_vector(dec, bs, x, y, 0, &mb->mvs[1], fcode, bound); } else { get_motion_vector(dec, bs, x, y, 0, &mb->mvs[0], fcode, bound); 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, bound); get_motion_vector(dec, bs, x, y, 1, &mb->mvs[1], fcode, bound); get_motion_vector(dec, bs, x, y, 2, &mb->mvs[2], fcode, bound); get_motion_vector(dec, bs, x, y, 3, &mb->mvs[3], fcode, bound); } 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, bound); 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;}// entire function added for mpeg4ipint 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; int len = frame->length; BitstreamInit(&bs, frame->bitstream, frame->length); ret = BitstreamReadHeaders(&bs, dec, &rounding, &quant, &fcode, &intra_dc_threshold, 1);#ifdef MPEG4IP if (dec->have_short_header) { frame->length = len; } else #endif { frame->length = len - (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 + -