📄 bframe.c
字号:
if (specificsOn) { /* Make sure no slice Qscale change */ newQScale = SpecLookup(curr->id,1,mbAddress/blocksPerSlice, &info, QScale); if (newQScale != -1) QScale = newQScale; } Mhead_GenSliceEnder(bb); Mhead_GenSliceHeader(bb, 1+(y>>1), QScale, NULL, 0); /* reset everything */ oldFMotionX = 0; oldFMotionY = 0; oldBMotionX = 0; oldBMotionY = 0; oldMode = MOTION_FORWARD; lastIntra = TRUE; 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(QScale, curr->y_blocks[y][x], curr->y_blocks[y][x+1], curr->y_blocks[y+1][x], curr->y_blocks[y+1][x+1]); if (newQScale > 0) { QScale = newQScale; } } if (specificsOn) { newQScale = SpecLookup(curr->id, 2, mbAddress, &info, QScale); if (newQScale != -1) { QScale = newQScale; }} if (dct_data[y][x].useMotion == NO_MOTION) { GEN_I_BLOCK(B_FRAME, curr, bb, mbAddrInc, QScale); mbAddrInc = 1; numIBits += (bb->cumulativeBits-totalBits); totalBits = bb->cumulativeBits; /* reset because intra-coded */ oldFMotionX = 0; oldFMotionY = 0; oldBMotionX = 0; oldBMotionY = 0; oldMode = MOTION_FORWARD; lastIntra = TRUE; if ( printSNR ) { /* need to decode block we just encoded */ /* and reverse the DCT transform */ for ( idx = 0; idx < 6; idx++ ) { Mpost_UnQuantZigBlock(fb[idx], dec[idx], QScale, TRUE); mpeg_jrevdct((int16 *)dec[idx]); } /* now, unblockify */ BlockToData(curr->decoded_y, dec[0], y, x); BlockToData(curr->decoded_y, dec[1], y, x+1); BlockToData(curr->decoded_y, dec[2], y+1, x); BlockToData(curr->decoded_y, dec[3], y+1, x+1); BlockToData(curr->decoded_cb, dec[4], y>>1, x>>1); BlockToData(curr->decoded_cr, dec[5], y>>1, x>>1); } } else if (dct_data[y][x].useMotion == SKIP) { numSkipped++; mbAddrInc++; /* decode skipped block */ if ( printSNR ) { int fmy, fmx, bmy, bmx; for ( idx = 0; idx < 6; idx++ ) { memset((char *)dec[idx], 0, sizeof(Block)); } if ( pixelFullSearch ) { fmy = 2*oldFMotionY; fmx = 2*oldFMotionX; bmy = 2*oldBMotionY; bmx = 2*oldBMotionX; } else { fmy = oldFMotionY; fmx = oldFMotionX; bmy = oldBMotionY; bmx = oldBMotionX; } /* now add the motion block */ AddBMotionBlock(dec[0], prev->decoded_y, next->decoded_y, y, x, mode, fmy, fmx, bmy, bmx); AddBMotionBlock(dec[1], prev->decoded_y, next->decoded_y, y, x+1, mode, fmy, fmx, bmy, bmx); AddBMotionBlock(dec[2], prev->decoded_y, next->decoded_y, y+1, x, mode, fmy, fmx, bmy, bmx); AddBMotionBlock(dec[3], prev->decoded_y, next->decoded_y, y+1, x+1, mode, fmy, fmx, bmy, bmx); AddBMotionBlock(dec[4], prev->decoded_cb, next->decoded_cb, y>>1, x>>1, mode, fmy/2, fmx/2, bmy/2, bmx/2); AddBMotionBlock(dec[5], prev->decoded_cr, next->decoded_cr, y>>1, x>>1, mode, fmy/2, fmx/2, bmy/2, bmx/2); /* now, unblockify */ BlockToData(curr->decoded_y, dec[0], y, x); BlockToData(curr->decoded_y, dec[1], y, x+1); BlockToData(curr->decoded_y, dec[2], y+1, x); BlockToData(curr->decoded_y, dec[3], y+1, x+1); BlockToData(curr->decoded_cb, dec[4], y>>1, x>>1); BlockToData(curr->decoded_cr, dec[5], y>>1, x>>1); } } else /* B block */ { int fCode = fCodeB; pattern = dct_data[y][x].pattern; fMotionX = dct_data[y][x].fmotionX; fMotionY = dct_data[y][x].fmotionY; bMotionX = dct_data[y][x].bmotionX; bMotionY = dct_data[y][x].bmotionY; if ( pixelFullSearch ) { fMotionX /= 2; fMotionY /= 2; bMotionX /= 2; bMotionY /= 2; } /* create flat blocks and update pattern if necessary */ calc_blocks: /* 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]); motionForward = (dct_data[y][x].mode != MOTION_BACKWARD); motionBackward = (dct_data[y][x].mode != MOTION_FORWARD); /* Encode Vectors */ if ( motionForward ) { /* transform the fMotion vector into the appropriate values */ offsetX = fMotionX - oldFMotionX; offsetY = fMotionY - oldFMotionY; ENCODE_MOTION_VECTOR(offsetX, offsetY, fMotionXquot, fMotionYquot, fMotionXrem, fMotionYrem, FORW_F); oldFMotionX = fMotionX; oldFMotionY = fMotionY; } if ( motionBackward ) { /* transform the bMotion vector into the appropriate values */ offsetX = bMotionX - oldBMotionX; offsetY = bMotionY - oldBMotionY; ENCODE_MOTION_VECTOR(offsetX, offsetY, bMotionXquot, bMotionYquot, bMotionXrem, bMotionYrem, BACK_F); oldBMotionX = bMotionX; oldBMotionY = bMotionY; } oldMode = dct_data[y][x].mode; if ( printSNR ) { /* Need to decode */ if ( pixelFullSearch ) { fMotionX *= 2; fMotionY *= 2; bMotionX *= 2; bMotionY *= 2; } for ( idx = 0; idx < 6; idx++ ) { if ( pattern & (1 << (5-idx)) ) { Mpost_UnQuantZigBlock(fba[idx], dec[idx], QScale, FALSE); mpeg_jrevdct((int16 *)dec[idx]); } else { memset((char *)dec[idx], 0, sizeof(Block)); } } /* now add the motion block */ AddBMotionBlock(dec[0], prev->decoded_y, next->decoded_y, y, x, mode, fMotionY, fMotionX, bMotionY, bMotionX); AddBMotionBlock(dec[1], prev->decoded_y, next->decoded_y, y, x+1, mode, fMotionY, fMotionX, bMotionY, bMotionX); AddBMotionBlock(dec[2], prev->decoded_y, next->decoded_y, y+1, x, mode, fMotionY, fMotionX, bMotionY, bMotionX); AddBMotionBlock(dec[3], prev->decoded_y, next->decoded_y, y+1, x+1, mode, fMotionY, fMotionX, bMotionY, bMotionX); AddBMotionBlock(dec[4], prev->decoded_cb, next->decoded_cb, y>>1, x>>1, mode, fMotionY/2, fMotionX/2, bMotionY/2, bMotionX/2); AddBMotionBlock(dec[5], prev->decoded_cr, next->decoded_cr, y>>1, x>>1, mode, fMotionY/2, fMotionX/2, bMotionY/2, bMotionX/2); /* now, unblockify */ BlockToData(curr->decoded_y, dec[0], y, x); BlockToData(curr->decoded_y, dec[1], y, x+1); BlockToData(curr->decoded_y, dec[2], y+1, x); BlockToData(curr->decoded_y, dec[3], y+1, x+1); BlockToData(curr->decoded_cb, dec[4], y>>1, x>>1); BlockToData(curr->decoded_cr, dec[5], y>>1, x>>1); } /* reset because non-intra-coded */ y_dc_pred = cr_dc_pred = cb_dc_pred = 128; lastIntra = FALSE; mode = dct_data[y][x].mode; /* DBG_PRINT(("MB Header(%d,%d)\n", x, y)); */ Mhead_GenMBHeader(bb, 3 /* pict_code_type */, mbAddrInc /* addr_incr */, QScale /* q_scale */, fCodeB /* forw_f_code */, fCodeB /* back_f_code */, fMotionXrem /* horiz_forw_r */, fMotionYrem /* vert_forw_r */, bMotionXrem /* horiz_back_r */, bMotionYrem /* vert_back_r */, motionForward /* motion_forw */, fMotionXquot /* m_horiz_forw */, fMotionYquot /* m_vert_forw */, motionBackward /* motion_back */, bMotionXquot /* m_horiz_back */, bMotionYquot /* m_vert_back */, pattern /* mb_pattern */, FALSE /* mb_intra */); mbAddrInc = 1; /* now output the difference */ for ( tempX = 0; tempX < 6; tempX++ ) { if ( GET_ITH_BIT(pattern, 5-tempX) ) { Mpost_RLEHuffPBlock(fba[tempX], bb); } } switch (mode) { case MOTION_FORWARD: numBFOBits += (bb->cumulativeBits-totalBits); break; case MOTION_BACKWARD: numBBABits += (bb->cumulativeBits-totalBits); break; case MOTION_INTERPOLATE: numBINBits += (bb->cumulativeBits-totalBits); break; default: fprintf(stderr, "PROGRAMMER ERROR: Illegal mode: %d\n", mode); exit(1); } numBBits += (bb->cumulativeBits-totalBits); totalBits = bb->cumulativeBits; if (overflowChange) { /* undo an overflow-caused Qscale change */ overflowChange = FALSE; QScale -= overflowValue; overflowValue = 0; } } /* if I-block, skip, or B */ mbAddress++; /* Rate Control */ if (bitstreamMode == FIXED_RATE) { incMacroBlockBits( bb->cumulativeBits - rc_blockStart); rc_blockStart = bb->cumulativeBits; MB_RateOut(TYPE_BFRAME); } } } if ( printSNR ) { BlockComputeSNR(curr,snr,psnr); totalSNR += snr[0]; totalPSNR += psnr[0]; } Mhead_GenSliceEnder(bb); /* Rate Control */ if (bitstreamMode == FIXED_RATE) { updateRateControl(TYPE_BFRAME); } endTime = time_elapsed(); totalTime += (endTime-startTime); if ( showBitRatePerFrame ) { /* ASSUMES 30 FRAMES PER SECOND */ fprintf(bitRateFile, "%5d\t%8d\n", curr->id, 30*(bb->cumulativeBits-totalFrameBits)); } if ( frameSummary && !realQuiet) { fprintf(stdout, "FRAME %d (B): I BLOCKS: %5d; B BLOCKS: %5d SKIPPED: %5d (%ld seconds)\n", curr->id, numIBlocks, numBBlocks, numSkipped, (long)((endTime-startTime)/TIME_RATE)); if ( printSNR ) fprintf(stdout, "FRAME %d: SNR: %.1f\t%.1f\t%.1f\tPSNR: %.1f\t%.1f\t%.1f\n", curr->id, snr[0], snr[1], snr[2], psnr[0], psnr[1], psnr[2]); } numFrameBits += (bb->cumulativeBits-totalFrameBits); numBIBlocks += numIBlocks; numBBBlocks += numBBlocks; numBSkipped += numSkipped; numBIBits += numIBits; numBBBits += numBBits; }/*===========================================================================* * * SetBQScale * * set the B-frame Q-scale * * RETURNS: nothing * * SIDE EFFECTS: qscaleB * *===========================================================================*/voidSetBQScale(qB) int qB;{ qscaleB = qB;}/*===========================================================================* * * GetBQScale * * get the B-frame Q-scale * * RETURNS: the Q-scale * * SIDE EFFECTS: none * *===========================================================================*/intGetBQScale(){ return qscaleB;}/*===========================================================================* * * ResetBFrameStats * * reset the B-frame stats * * RETURNS: nothing * * SIDE EFFECTS: none * *===========================================================================*/voidResetBFrameStats(){ numBIBlocks = 0; numBBBlocks = 0; numBSkipped = 0; numBIBits = 0; numBBBits = 0; numFrames = 0; numFrameBits = 0; totalTime = 0;}floatBFrameTotalTime(void) { return (float)totalTime/(float)TIME_RATE;}voidShowBFrameSummary(unsigned int const inputFrameBits, unsigned int const totalBits, FILE * const fpointer) { if (numFrames > 0) { fprintf(fpointer, "-------------------------\n"); fprintf(fpointer, "*****B FRAME SUMMARY*****\n"); fprintf(fpointer, "-------------------------\n"); if ( numBIBlocks != 0 ) { fprintf(fpointer, " I Blocks: %5d (%6d bits) (%5d bpb)\n", numBIBlocks, numBIBits, numBIBits/numBIBlocks); } else { fprintf(fpointer, " I Blocks: %5d\n", 0); } if ( numBBBlocks != 0 ) { fprintf(fpointer, " B Blocks: %5d (%6d bits) (%5d bpb)\n", numBBBlocks, numBBBits, numBBBits/numBBBlocks); fprintf(fpointer, " B types: %5d (%4d bpb) forw %5d (%4d bpb) back %5d (%4d bpb) bi\n",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -