📄 encoder.c
字号:
dec_frame_num(pEnc); pEnc->iFrameNum--; pEnc->queue_head = (pEnc->queue_head + (pEnc->mbParam.max_bframes+1) - 1) % (pEnc->mbParam.max_bframes+1); pEnc->queue_size++; image_swap(&pEnc->current->image, &pEnc->queue[pEnc->queue_head].image); /* grab the last frame from the bframe-queue */ pEnc->bframenum_tail--; SWAP(FRAMEINFO*, pEnc->current, pEnc->bframes[pEnc->bframenum_tail]); if ((pEnc->current->vop_flags & XVID_VOP_DEBUG)) { image_printf(&pEnc->current->image, pEnc->mbParam.edged_width, pEnc->mbParam.height, 5, 100, "DX50 BVOP->PVOP"); } /* convert B-VOP quant to P-VOP */ pEnc->current->quant = 100*pEnc->current->quant - pEnc->mbParam.bquant_offset; pEnc->current->quant += pEnc->mbParam.bquant_ratio - 1; /* to avoid rouding issues */ pEnc->current->quant /= pEnc->mbParam.bquant_ratio; type = P_VOP; } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% * encode this frame as an i-vop * %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */ if (type == I_VOP) { DPRINTF(XVID_DEBUG_DEBUG,"*** IFRAME bf: head=%i tail=%i queue: head=%i tail=%i size=%i\n", pEnc->bframenum_head, pEnc->bframenum_tail, pEnc->queue_head, pEnc->queue_tail, pEnc->queue_size); if ((pEnc->current->vop_flags & XVID_VOP_DEBUG)) { image_printf(&pEnc->current->image, pEnc->mbParam.edged_width, pEnc->mbParam.height, 5, 200, "IVOP"); } pEnc->iFrameNum = 1; /* ---- update vol flags at IVOP ----------- */ pEnc->mbParam.vol_flags = pEnc->current->vol_flags; /* Aspect ratio */ switch(frame->par) { case XVID_PAR_11_VGA: case XVID_PAR_43_PAL: case XVID_PAR_43_NTSC: case XVID_PAR_169_PAL: case XVID_PAR_169_NTSC: case XVID_PAR_EXT: pEnc->mbParam.par = frame->par; break; default: pEnc->mbParam.par = XVID_PAR_11_VGA; break; } /* For extended PAR only, we try to sanityse/simplify par values */ if (pEnc->mbParam.par == XVID_PAR_EXT) { pEnc->mbParam.par_width = frame->par_width; pEnc->mbParam.par_height = frame->par_height; simplify_par(&pEnc->mbParam.par_width, &pEnc->mbParam.par_height); } if ((pEnc->mbParam.vol_flags & XVID_VOL_MPEGQUANT)) { if (frame->quant_intra_matrix != NULL) set_intra_matrix(pEnc->mbParam.mpeg_quant_matrices, frame->quant_intra_matrix); if (frame->quant_inter_matrix != NULL) set_inter_matrix(pEnc->mbParam.mpeg_quant_matrices, frame->quant_inter_matrix); } /* prevent vol/vop misuse */ if (!(pEnc->current->vol_flags & XVID_VOL_REDUCED_ENABLE)) pEnc->current->vop_flags &= ~XVID_VOP_REDUCED; if (!(pEnc->current->vol_flags & XVID_VOL_INTERLACING)) pEnc->current->vop_flags &= ~(XVID_VOP_TOPFIELDFIRST|XVID_VOP_ALTERNATESCAN); /* ^^^------------------------ */ if ((pEnc->mbParam.plugin_flags & XVID_REQORIGINAL)) { image_copy(&pEnc->sOriginal, &pEnc->current->image, pEnc->mbParam.edged_width, pEnc->mbParam.height); } FrameCodeI(pEnc, &bs); xFrame->out_flags |= XVID_KEYFRAME; /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% * encode this frame as an p-vop * %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */ } else { /* (type == P_VOP || type == S_VOP) */ DPRINTF(XVID_DEBUG_DEBUG,"*** PFRAME bf: head=%i tail=%i queue: head=%i tail=%i size=%i\n", pEnc->bframenum_head, pEnc->bframenum_tail, pEnc->queue_head, pEnc->queue_tail, pEnc->queue_size); if ((pEnc->current->vop_flags & XVID_VOP_DEBUG)) { image_printf(&pEnc->current->image, pEnc->mbParam.edged_width, pEnc->mbParam.height, 5, 200, "PVOP"); } if ((pEnc->mbParam.plugin_flags & XVID_REQORIGINAL)) { image_copy(&pEnc->sOriginal, &pEnc->current->image, pEnc->mbParam.edged_width, pEnc->mbParam.height); } if ( FrameCodeP(pEnc, &bs) == 0 ) { /* N-VOP, we mustn't code b-frames yet */ call_plugins(pEnc, pEnc->current, &pEnc->sOriginal, XVID_PLG_AFTER, 0, 0, stats); goto done; } } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% * on next enc_encode call we must flush bframes * %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% *//*done_flush:*/ pEnc->flush_bframes = 1; /* packed & queued_bframes: dont bother outputting stats here, we do so after the flush */ if ((pEnc->mbParam.global_flags & XVID_GLOBAL_PACKED) && pEnc->bframenum_tail > 0) { goto repeat; } /* packed or no-bframes or no-bframes-queued: output stats */ if ((pEnc->mbParam.global_flags & XVID_GLOBAL_PACKED) || pEnc->mbParam.max_bframes == 0 ) { call_plugins(pEnc, pEnc->current, &pEnc->sOriginal, XVID_PLG_AFTER, 0, 0, stats); } /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% * done; return number of bytes consumed * %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */done: stop_global_timer(); write_timer(); emms(); return BitstreamLength(&bs);}static void SetMacroblockQuants(MBParam * const pParam, FRAMEINFO * frame){ unsigned int i; MACROBLOCK * pMB = frame->mbs; int quant = frame->mbs[0].quant; /* set by XVID_PLG_FRAME */ if (quant > 31) frame->quant = quant = 31; else if (quant < 1) frame->quant = quant = 1; for (i = 0; i < pParam->mb_height * pParam->mb_width; i++) { quant += pMB->dquant; if (quant > 31) quant = 31; else if (quant < 1) quant = 1; pMB->quant = quant; pMB++; }}static __inline voidCodeIntraMB(Encoder * pEnc, MACROBLOCK * pMB){ pMB->mode = MODE_INTRA; /* zero mv statistics */ pMB->mvs[0].x = pMB->mvs[1].x = pMB->mvs[2].x = pMB->mvs[3].x = 0; pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = 0; pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = 0; pMB->sad16 = 0; if (pMB->dquant != 0) { pMB->mode = MODE_INTRA_Q; }}static intFrameCodeI(Encoder * pEnc, Bitstream * bs){ int bits = BitstreamPos(bs); int mb_width = pEnc->mbParam.mb_width; int mb_height = pEnc->mbParam.mb_height; DECLARE_ALIGNED_MATRIX(dct_codes, 6, 64, int16_t, CACHE_LINE); DECLARE_ALIGNED_MATRIX(qcoeff, 6, 64, int16_t, CACHE_LINE); uint16_t x, y; if ((pEnc->current->vol_flags & XVID_VOL_REDUCED_ENABLE)) { mb_width = (pEnc->mbParam.width + 31) / 32; mb_height = (pEnc->mbParam.height + 31) / 32; /* 16x16->8x8 downsample requires 1 additional edge pixel*/ /* XXX: setedges is overkill */ start_timer(); image_setedges(&pEnc->current->image, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height, pEnc->mbParam.width, pEnc->mbParam.height, 0); stop_edges_timer(); } pEnc->mbParam.m_rounding_type = 1; pEnc->current->rounding_type = pEnc->mbParam.m_rounding_type; pEnc->current->coding_type = I_VOP; call_plugins(pEnc, pEnc->current, NULL, XVID_PLG_FRAME, NULL, NULL, NULL); SetMacroblockQuants(&pEnc->mbParam, pEnc->current); BitstreamWriteVolHeader(bs, &pEnc->mbParam, pEnc->current); set_timecodes(pEnc->current,pEnc->reference,pEnc->mbParam.fbase); BitstreamPad(bs); BitstreamWriteVopHeader(bs, &pEnc->mbParam, pEnc->current, 1, pEnc->current->mbs[0].quant); pEnc->current->sStat.iTextBits = 0; pEnc->current->sStat.kblks = mb_width * mb_height; pEnc->current->sStat.mblks = pEnc->current->sStat.ublks = 0; for (y = 0; y < mb_height; y++) for (x = 0; x < mb_width; x++) { MACROBLOCK *pMB = &pEnc->current->mbs[x + y * pEnc->mbParam.mb_width]; CodeIntraMB(pEnc, pMB); MBTransQuantIntra(&pEnc->mbParam, pEnc->current, pMB, x, y, dct_codes, qcoeff); start_timer(); MBPrediction(pEnc->current, x, y, pEnc->mbParam.mb_width, qcoeff); stop_prediction_timer(); start_timer(); if (pEnc->current->vop_flags & XVID_VOP_GREYSCALE) { pMB->cbp &= 0x3C; /* keep only bits 5-2 */ qcoeff[4*64+0]=0; /* zero, because for INTRA MBs DC value is saved */ qcoeff[5*64+0]=0; } MBCoding(pEnc->current, pMB, qcoeff, bs, &pEnc->current->sStat); stop_coding_timer(); } if ((pEnc->current->vop_flags & XVID_VOP_REDUCED)) { image_deblock_rrv(&pEnc->current->image, pEnc->mbParam.edged_width, pEnc->current->mbs, mb_width, mb_height, pEnc->mbParam.mb_width, 16, 0); } emms(); BitstreamPadAlways(bs); /* next_start_code() at the end of VideoObjectPlane() */ pEnc->current->length = (BitstreamPos(bs) - bits) / 8; pEnc->fMvPrevSigma = -1; pEnc->mbParam.m_fcode = 2; pEnc->current->is_edged = 0; /* not edged */ pEnc->current->is_interpolated = -1; /* not interpolated (fake rounding -1) */ return 1; /* intra */}#define INTRA_THRESHOLD 0.5#define BFRAME_SKIP_THRESHHOLD 30/* FrameCodeP also handles S(GMC)-VOPs */static intFrameCodeP(Encoder * pEnc, Bitstream * bs){ float fSigma; int bits = BitstreamPos(bs); DECLARE_ALIGNED_MATRIX(dct_codes, 6, 64, int16_t, CACHE_LINE); DECLARE_ALIGNED_MATRIX(qcoeff, 6, 64, int16_t, CACHE_LINE); int x, y, k; int iSearchRange; int skip_possible; FRAMEINFO *const current = pEnc->current; FRAMEINFO *const reference = pEnc->reference; MBParam * const pParam = &pEnc->mbParam; int mb_width = pParam->mb_width; int mb_height = pParam->mb_height; int coded = 1; /* IMAGE *pCurrent = ¤t->image; */ IMAGE *pRef = &reference->image; if ((current->vop_flags & XVID_VOP_REDUCED)) { mb_width = (pParam->width + 31) / 32; mb_height = (pParam->height + 31) / 32; } if (!reference->is_edged) { start_timer(); image_setedges(pRef, pParam->edged_width, pParam->edged_height, pParam->width, pParam->height, 0); stop_edges_timer(); reference->is_edged = 1; } pParam->m_rounding_type = 1 - pParam->m_rounding_type; current->rounding_type = pParam->m_rounding_type; current->fcode = pParam->m_fcode; if ((current->vop_flags & XVID_VOP_HALFPEL)) { if (reference->is_interpolated != current->rounding_type) { start_timer(); image_interpolate(pRef, &pEnc->vInterH, &pEnc->vInterV, &pEnc->vInterHV, pParam->edged_width, pParam->edged_height, (pParam->vol_flags & XVID_VOL_QUARTERPEL), current->rounding_type); stop_inter_timer(); reference->is_interpolated = current->rounding_type; } } current->coding_type = P_VOP; call_plugins(pEnc, pEnc->current, NULL, XVID_PLG_FRAME, NULL, NULL, NULL); SetMacroblockQuants(&pEnc->mbParam, current); start_timer(); if (current->vol_flags & XVID_VOL_GMC ) /* GMC only for S(GMC)-VOPs */ { int gmcval; current->warp = GlobalMotionEst( current->mbs, pParam, current, reference, &pEnc->vInterH, &pEnc->vInterV, &pEnc->vInterHV); if (current->motion_flags & XVID_ME_GME_REFINE) { gmcval = GlobalMotionEstRefine(¤t->warp, current->mbs, pParam, current, reference, ¤t->image, &reference->image, &pEnc->vInterH, &pEnc->vInterV, &pEnc->vInterHV); } else { gmcval = globalSAD(¤t->warp, pParam, current->mbs, current, &reference->image, ¤t->image, pEnc->vGMC.y); } gmcval += /*current->quant*/ 2 * (int)(pParam->mb_width*pParam->mb_height); /* 1st '3': 3 warpoints, 2nd '3': 16th pel res (2<<3) */ generate_GMCparameters( 3, 3, ¤t->warp, pParam->width, pParam->height, ¤t->new_gmc_data); if ( (gmcval<0) && ( (current->warp.duv[1].x != 0) || (current->warp.duv[1].y != 0) || (current->warp.duv[2].x != 0) || (current->warp.duv[2].y != 0) ) ) { current->coding_type = S_VOP; generate_GMCimage(¤t->new_gmc_data, &reference->image, pParam->mb_width, pParam->mb_height, pParam->edged_width, pParam->edged_width/2, pParam->m_fcode, ((pParam->vol_flags & XVID_VOL_QUARTERPEL)?1:0), 0, current->rounding_type, current->mbs, &pEnc->vGMC); } else { generate_GMCimage(¤t->new_gmc_data, &reference->image, pParam->mb_width, pParam->mb_height, pParam->edged_width, pParam->edged_width/2, pParam->m_fcode, ((pParam->vol_flags & XVID_VOL_QUARTERPEL)?1:0), 0, current->rounding_type, current->mbs, NULL); /* no warping, just AMV */ } } MotionEstimation(&pEnc->mbParam, current, reference, &pEnc->vInterH, &pEnc->vInterV, &pEnc->vInterHV, &pEnc->vGMC, 256*4096); stop_motion_timer(); set_timecodes(current,reference,pParam->fbase); BitstreamWriteVopHeader(bs, &pEnc->mbParam, current, 1, current->mbs[0].quant); current->sStat.iTextBits = current->sStat.iMvSum = current->sStat.iMvCount = current->sStat.kblks = current->sStat.mblks = current->sStat.ublks = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -