📄 pframe.c
字号:
pattern = 63; ComputeDiffDCTs(current, prev, y, x, motionY, motionX, &pattern); assert(motionX+searchRangeP+1 >= 0); assert(motionY+searchRangeP+1 >= 0); if ( computeMVHist ) { assert(motionX+searchRangeP+1 <= 2*searchRangeP+2); assert(motionY+searchRangeP+1 <= 2*searchRangeP+2); pmvHistogram[motionX+searchRangeP+1] [motionY+searchRangeP+1]++; } /* Save specs for next loops */ dct_data[y][x].pattern = pattern; dct_data[y][x].fmotionX = motionX; dct_data[y][x].fmotionY = motionY; } else { /* output I-block inside a P-frame */ (*numIBlocksP)++; calculateForwardDcts(current, y, x, dct); } mbAddress++; } }}/*=====================* * EXPORTED PROCEDURES * *=====================*//*===========================================================================* * * GenPFrame * * generate a P-frame from previous frame, adding the result to the * given bit bucket * * RETURNS: frame appended to bb * *===========================================================================*/voidGenPFrame(BitBucket * const bb, MpegFrame * const current, MpegFrame * const prev) { extern int **pmvHistogram; FlatBlock fba[6], fb[6]; Block dec[6]; int32 y_dc_pred, cr_dc_pred, cb_dc_pred; int x, y; int motionX, motionY; int oldMotionX = 0, oldMotionY = 0; int offsetX, offsetY; int tempX, tempY; int motionXrem, motionXquot; int motionYrem, motionYquot; int pattern; int mbAddrInc = 1; int numIBlocks = 0; int numPBlocks = 0; int numSkipped = 0; int numIBits = 0; int numPBits = 0; int totalBits; int totalFrameBits; int32 startTime, endTime; int lastBlockX, lastBlockY; int lastX, lastY; int mbAddress; int slicePos; register int index; float snr[3], psnr[3]; int QScale; BlockMV *info; int bitstreamMode, newQScale; int rc_blockStart = 0; boolean overflowChange = FALSE; int overflowValue = 0; if (collect_quant) {fprintf(collect_quant_fp, "# P\n");} if (dct==NULL) AllocDctBlocks(); numFrames++; totalFrameBits = bb->cumulativeBits; startTime = time_elapsed(); DBG_PRINT(("Generating pframe\n")); QScale = GetPQScale(); /* bit allocation for rate control purposes */ bitstreamMode = getRateMode(); if (bitstreamMode == FIXED_RATE) { targetRateControl(current); } Mhead_GenPictureHeader(bb, P_FRAME, current->id, fCodeP); /* Check for Qscale change */ if (specificsOn) { /* Set a Qscale for this frame? */ newQScale = SpecLookup(current->id, 0, 0 /* junk */, &info /*junk*/, QScale); if (newQScale != -1) { QScale = newQScale; } /* Set for slice? */ newQScale = SpecLookup(current->id, 1, 1, &info /*junk*/, QScale); if (newQScale != -1) { QScale = newQScale; } } DBG_PRINT(("Slice Header\n")); Mhead_GenSliceHeader(bb, 1, QScale, NULL, 0); if ( referenceFrame == DECODED_FRAME ) { Frame_AllocDecoded(current, TRUE); } else if ( printSNR ) { Frame_AllocDecoded(current, FALSE); } /* don't do dct on blocks yet */ Frame_AllocBlocks(current); BlockifyFrame(current); /* for I-blocks */ y_dc_pred = cr_dc_pred = cb_dc_pred = 128; totalBits = bb->cumulativeBits; if ( (! pixelFullSearch) && (! prev->halfComputed) ) { ComputeHalfPixelData(prev); } lastBlockX = Fsize_x>>3; lastBlockY = Fsize_y>>3; lastX = lastBlockX-2; lastY = lastBlockY-2; computeMotionAndDct(lastBlockY, lastBlockX, specificsOn, IntraPBAllowed, current, prev, &info, QScale, searchRangeP, dct, &numPBlocks, &numIBlocks, pmvHistogram); mbAddress = 0; for (y = 0; y < lastBlockY; y += 2) { for (x = 0; x < lastBlockX; x += 2) { slicePos = (mbAddress % blocksPerSlice); if ( (slicePos == 0) && (mbAddress != 0) ) { if (specificsOn) { /* Make sure no slice Qscale change */ newQScale = SpecLookup(current->id, 1, mbAddress/blocksPerSlice, &info /*junk*/, QScale); if (newQScale != -1) QScale = newQScale; } Mhead_GenSliceEnder(bb); Mhead_GenSliceHeader(bb, 1+(y>>1), QScale, NULL, 0); /* reset everything */ oldMotionX = 0; oldMotionY = 0; y_dc_pred = cr_dc_pred = cb_dc_pred = 128; mbAddrInc = 1+(x>>1); } /* Determine if new Qscale needed for Rate Control purposes */ if (bitstreamMode == FIXED_RATE) { rc_blockStart = bb->cumulativeBits; newQScale = needQScaleChange(qscaleP, current->y_blocks[y][x], current->y_blocks[y][x+1], current->y_blocks[y+1][x], current->y_blocks[y+1][x+1]); if (newQScale > 0) { QScale = newQScale; } } /* Check for Qscale change */ if (specificsOn) { newQScale = SpecLookup(current->id, 2, mbAddress, &info, QScale); if (newQScale != -1) { QScale = newQScale; } } if (! dct_data[y][x].useMotion) { GEN_I_BLOCK(P_FRAME, current, bb, mbAddrInc, QScale); mbAddrInc = 1; numIBits += (bb->cumulativeBits-totalBits); totalBits = bb->cumulativeBits; /* reset because intra-coded */ oldMotionX = 0; oldMotionY = 0; if ( decodeRefFrames ) { /* need to decode block we just encoded */ Mpost_UnQuantZigBlock(fb[0], dec[0], QScale, TRUE); Mpost_UnQuantZigBlock(fb[1], dec[1], QScale, TRUE); Mpost_UnQuantZigBlock(fb[2], dec[2], QScale, TRUE); Mpost_UnQuantZigBlock(fb[3], dec[3], QScale, TRUE); Mpost_UnQuantZigBlock(fb[4], dec[4], QScale, TRUE); Mpost_UnQuantZigBlock(fb[5], dec[5], QScale, TRUE); /* now, reverse the DCT transform */ for ( index = 0; index < 6; index++ ) { mpeg_jrevdct((int16 *)dec[index]); } /* now, unblockify */ BlockToData(current->decoded_y, dec[0], y, x); BlockToData(current->decoded_y, dec[1], y, x+1); BlockToData(current->decoded_y, dec[2], y+1, x); BlockToData(current->decoded_y, dec[3], y+1, x+1); BlockToData(current->decoded_cb, dec[4], y>>1, x>>1); BlockToData(current->decoded_cr, dec[5], y>>1, x>>1); } } else { int fCode = fCodeP; /* reset because non-intra-coded */ y_dc_pred = cr_dc_pred = cb_dc_pred = 128; pattern = dct_data[y][x].pattern; motionX = dct_data[y][x].fmotionX; motionY = dct_data[y][x].fmotionY;#ifdef BLEAH ComputeAndPrintPframeMAD(currentBlock, prev, y, x, motionY, motionX, mbAddress);#endif if ( pixelFullSearch ) { /* should be even */ motionY /= 2; motionX /= 2; } /* transform the motion vector into the appropriate values */ offsetX = motionX - oldMotionX; offsetY = motionY - oldMotionY; /* if ((offsetX+(8*x)) >= (Fsize_x-8)) log(10.0); */ ENCODE_MOTION_VECTOR(offsetX, offsetY, motionXquot, motionYquot, motionXrem, motionYrem, FORW_F);#ifdef BLEAH if ( (motionX != 0) || (motionY != 0) ) { fprintf(stdout, "FRAME (y, x) %d, %d (block %d)\n", y, x, mbAddress); fprintf(stdout, "motionX = %d, motionY = %d\n", motionX, motionY); fprintf(stdout, " mxq, mxr = %d, %d myq, myr = %d, %d\n", motionXquot, motionXrem, motionYquot, motionYrem); }#endif oldMotionX = motionX; oldMotionY = motionY; if ( pixelFullSearch ) { /* reset for use with PMotionSearch */ motionY *= 2; motionX *= 2; } calc_blocks: /* create flat blocks and update pattern if necessary */ /* Note DoQuant references QScale, overflowChange, overflowValue, pattern, and the calc_blocks label */ DoQuant(0x20, dct[y][x], fba[0]); DoQuant(0x10, dct[y][x+1], fba[1]); DoQuant(0x08, dct[y+1][x], fba[2]); DoQuant(0x04, dct[y+1][x+1], fba[3]); DoQuant(0x02, dctb[y>>1][x>>1], fba[4]); DoQuant(0x01, dctr[y>>1][x>>1], fba[5]); if ( decodeRefFrames) { for ( index = 0; index < 6; index++ ) { if ( pattern & (1 << (5-index))) { Mpost_UnQuantZigBlock(fba[index], dec[index], QScale, FALSE); mpeg_jrevdct((int16 *)dec[index]); } else { memset((char *)dec[index], 0, sizeof(Block)); } } /* now add the motion block */ AddMotionBlock(dec[0], prev->decoded_y, y, x, motionY, motionX); AddMotionBlock(dec[1], prev->decoded_y, y, x+1, motionY, motionX); AddMotionBlock(dec[2], prev->decoded_y, y+1, x, motionY, motionX); AddMotionBlock(dec[3], prev->decoded_y, y+1, x+1, motionY, motionX); AddMotionBlock(dec[4], prev->decoded_cb, y>>1, x>>1, motionY/2, motionX/2); AddMotionBlock(dec[5], prev->decoded_cr, y>>1, x>>1, motionY/2, motionX/2); /* now, unblockify */ BlockToData(current->decoded_y, dec[0], y, x); BlockToData(current->decoded_y, dec[1], y, x+1); BlockToData(current->decoded_y, dec[2], y+1, x); BlockToData(current->decoded_y, dec[3], y+1, x+1); BlockToData(current->decoded_cb, dec[4], y>>1, x>>1); BlockToData(current->decoded_cr, dec[5], y>>1, x>>1); } if ( (motionX == 0) && (motionY == 0) ) { if ( pattern == 0 ) { /* can only skip if: * 1) not the last block in frame * 2) not the last block in slice * 3) not the first block in slice */ if ( ((y < lastY) || (x < lastX)) && (slicePos+1 != blocksPerSlice) && (slicePos != 0) ) { mbAddrInc++; /* skipped macroblock */ numSkipped++; numPBlocks--; } else { /* first/last macroblock */ Mhead_GenMBHeader(bb, 2 /* pict_code_type */, mbAddrInc /* addr_incr */, QScale /* q_scale */, fCode /* forw_f_code */, 1 /* back_f_code */, motionXrem /* horiz_forw_r */, motionYrem /* vert_forw_r */, 0 /* horiz_back_r */, 0 /* vert_back_r */, 1 /* motion_forw */, motionXquot /* m_horiz_forw */, motionYquot /* m_vert_forw */, 0 /* motion_back */, 0 /* m_horiz_back */, 0 /* m_vert_back */, 0 /* mb_pattern */, 0 /* mb_intra */); mbAddrInc = 1; } } else { DBG_PRINT(("MB Header(%d,%d)\n", x, y)); Mhead_GenMBHeader(bb, 2 /* pict_code_type */, mbAddrInc /* addr_incr */, QScale /* q_scale */, fCode /* forw_f_code */, 1 /* back_f_code */, 0 /* horiz_forw_r */, 0 /* vert_forw_r */, 0 /* horiz_back_r */, 0 /* vert_back_r */, 0 /* motion_forw */, 0 /* m_horiz_forw */, 0 /* m_vert_forw */, 0 /* motion_back */, 0 /* m_horiz_back */, 0 /* m_vert_back */, pattern /* mb_pattern */, 0 /* mb_intra */); mbAddrInc = 1; } } else { /* DBG_PRINT(("MB Header(%d,%d)\n", x, y)); */ Mhead_GenMBHeader(bb, 2 /* pict_code_type */, mbAddrInc /* addr_incr */, QScale /* q_scale */, fCode /* forw_f_code */, 1 /* back_f_code */, motionXrem /* horiz_forw_r */, motionYrem /* vert_forw_r */, 0 /* horiz_back_r */, 0 /* vert_back_r */, 1 /* motion_forw */, motionXquot /* m_horiz_forw */, motionYquot /* m_vert_forw */, 0 /* motion_back */, 0 /* m_horiz_back */, 0 /* m_vert_back */, pattern /* mb_pattern */, 0 /* mb_intra */);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -