📄 bframe.c
字号:
numBFOBlocks, (numBFOBlocks==0)?0:numBFOBits/numBFOBlocks, numBBABlocks, (numBBABlocks==0)?0:numBBABits/numBBABlocks, numBINBlocks, (numBINBlocks==0)?0:numBINBits/numBINBlocks); } else { fprintf(fpointer, " B Blocks: %5d\n", 0); } fprintf(fpointer, " Skipped: %5d\n", numBSkipped); fprintf(fpointer, " Frames: %5d (%6d bits) (%5d bpf) (%2.1f%% of total)\n", numFrames, numFrameBits, numFrameBits/numFrames, 100.0*(float)numFrameBits/(float)totalBits); fprintf(fpointer, " Compression: %3d:1 (%9.4f bpp)\n", numFrames*inputFrameBits/numFrameBits, 24.0*(float)numFrameBits/(float)(numFrames*inputFrameBits)); if ( printSNR ) fprintf(fpointer, " Avg Y SNR/PSNR: %.1f %.1f\n", totalSNR/(float)numFrames, totalPSNR/(float)numFrames); if ( totalTime == 0 ) { fprintf(fpointer, " Seconds: NONE\n"); } else { fprintf(fpointer, " Seconds: %9ld (%9.4f fps) (%9ld pps) (%9ld mps)\n", (long)(totalTime/TIME_RATE), (float)((float)(TIME_RATE*numFrames)/(float)totalTime), (long)((float)TIME_RATE*(float)numFrames*(float)inputFrameBits/(24.0*(float)totalTime)), (long)((float)TIME_RATE*(float)numFrames*(float)inputFrameBits/(256.0*24.0*(float)totalTime))); } }}/*===========================================================================* * * ComputeBMotionLumBlock * * compute the luminance block resulting from motion compensation * * RETURNS: motionBlock modified * * SIDE EFFECTS: none * * PRECONDITION: the motion vectors must be valid! * *===========================================================================*/voidComputeBMotionLumBlock(prev, next, by, bx, mode, fmy, fmx, bmy, bmx, motionBlock) MpegFrame *prev; MpegFrame *next; int by; int bx; int mode; int fmy; int fmx; int bmy; int bmx; LumBlock motionBlock;{ LumBlock prevBlock, nextBlock; register int y, x; switch(mode) { case MOTION_FORWARD: ComputeMotionLumBlock(prev, by, bx, fmy, fmx, motionBlock); break; case MOTION_BACKWARD: ComputeMotionLumBlock(next, by, bx, bmy, bmx, motionBlock); break; case MOTION_INTERPOLATE: ComputeMotionLumBlock(prev, by, bx, fmy, fmx, prevBlock); ComputeMotionLumBlock(next, by, bx, bmy, bmx, nextBlock); for ( y = 0; y < 16; y++ ) { for ( x = 0; x < 16; x++ ) { motionBlock[y][x] = (prevBlock[y][x]+nextBlock[y][x]+1)/2; } } break; default: fprintf(stderr, "Bad mode!\nProgrammer error!\n"); break; }}/*===========================================================================* * * EstimateSecondsPerBFrame * * estimate the seconds to compute a B-frame * * RETURNS: the time, in seconds * * SIDE EFFECTS: none * *===========================================================================*/floatEstimateSecondsPerBFrame(){ if ( numFrames == 0 ) { return 20.0; } else { return (float)totalTime/((float)TIME_RATE*(float)numFrames); }}/*=====================* * INTERNAL PROCEDURES * *=====================*//*===========================================================================* * * ComputeBMotionBlock * * compute the block resulting from motion compensation * * RETURNS: motionBlock is modified * * SIDE EFFECTS: none * * PRECONDITION: the motion vectors must be valid! * *===========================================================================*/static voidComputeBMotionBlock(prev, next, by, bx, mode, fmy, fmx, bmy, bmx, motionBlock, type) MpegFrame *prev; MpegFrame *next; int by; int bx; int mode; int fmy; int fmx; int bmy; int bmx; Block motionBlock; int type;{ Block prevBlock, nextBlock; register int y, x; switch(mode) { case MOTION_FORWARD: if ( type == LUM_BLOCK ) { ComputeMotionBlock(prev->ref_y, by, bx, fmy, fmx, motionBlock); } else if ( type == CB_BLOCK ) { ComputeMotionBlock(prev->ref_cb, by, bx, fmy, fmx, motionBlock); } else if ( type == CR_BLOCK ) { ComputeMotionBlock(prev->ref_cr, by, bx, fmy, fmx, motionBlock); } break; case MOTION_BACKWARD: if ( type == LUM_BLOCK ) { ComputeMotionBlock(next->ref_y, by, bx, bmy, bmx, motionBlock); } else if ( type == CB_BLOCK ) { ComputeMotionBlock(next->ref_cb, by, bx, bmy, bmx, motionBlock); } else if ( type == CR_BLOCK ) { ComputeMotionBlock(next->ref_cr, by, bx, bmy, bmx, motionBlock); } break; case MOTION_INTERPOLATE: if ( type == LUM_BLOCK ) { ComputeMotionBlock(prev->ref_y, by, bx, fmy, fmx, prevBlock); ComputeMotionBlock(next->ref_y, by, bx, bmy, bmx, nextBlock); } else if ( type == CB_BLOCK ) { ComputeMotionBlock(prev->ref_cb, by, bx, fmy, fmx, prevBlock); ComputeMotionBlock(next->ref_cb, by, bx, bmy, bmx, nextBlock); } else if ( type == CR_BLOCK ) { ComputeMotionBlock(prev->ref_cr, by, bx, fmy, fmx, prevBlock); ComputeMotionBlock(next->ref_cr, by, bx, bmy, bmx, nextBlock); } for ( y = 0; y < 8; y++ ) { for ( x = 0; x < 8; x++ ) { motionBlock[y][x] = (prevBlock[y][x]+nextBlock[y][x]+1)/2; } } break; }}/*===========================================================================* * * ComputeBDiffDCTs * * compute the DCT of the error term * * RETURNS: appropriate blocks of current will contain the DCTs * * SIDE EFFECTS: none * * PRECONDITION: the motion vectors must be valid! * *===========================================================================*/static voidComputeBDiffDCTs(current, prev, next, by, bx, mode, fmy, fmx, bmy, bmx, pattern) MpegFrame *current; MpegFrame *prev; MpegFrame *next; int by; int bx; int mode; int fmy; int fmx; int bmy; int bmx; int *pattern;{ Block motionBlock; if ( *pattern & 0x20 ) { ComputeBMotionBlock(prev, next, by, bx, mode, fmy, fmx, bmy, bmx, motionBlock, LUM_BLOCK); if (! ComputeDiffDCTBlock(current->y_blocks[by][bx], dct[by][bx], motionBlock)) { *pattern ^= 0x20; } } if ( *pattern & 0x10 ) { ComputeBMotionBlock(prev, next, by, bx+1, mode, fmy, fmx, bmy, bmx, motionBlock, LUM_BLOCK); if (! ComputeDiffDCTBlock(current->y_blocks[by][bx+1], dct[by][bx+1], motionBlock)) { *pattern ^= 0x10; } } if ( *pattern & 0x8 ) { ComputeBMotionBlock(prev, next, by+1, bx, mode, fmy, fmx, bmy, bmx, motionBlock, LUM_BLOCK); if (! ComputeDiffDCTBlock(current->y_blocks[by+1][bx], dct[by+1][bx], motionBlock)) { *pattern ^= 0x8; } } if ( *pattern & 0x4 ) { ComputeBMotionBlock(prev, next, by+1, bx+1, mode, fmy, fmx, bmy, bmx, motionBlock, LUM_BLOCK); if (! ComputeDiffDCTBlock(current->y_blocks[by+1][bx+1], dct[by+1][bx+1], motionBlock)) { *pattern ^= 0x4; } } if ( *pattern & 0x2 ) { ComputeBMotionBlock(prev, next, by>>1, bx>>1, mode, fmy/2, fmx/2, bmy/2, bmx/2, motionBlock, CB_BLOCK); if (! ComputeDiffDCTBlock(current->cb_blocks[by >> 1][bx >> 1], dctb[by >> 1][bx >> 1], motionBlock)) { *pattern ^= 0x2; } } if ( *pattern & 0x1 ) { ComputeBMotionBlock(prev, next, by>>1, bx>>1, mode, fmy/2, fmx/2, bmy/2, bmx/2, motionBlock, CR_BLOCK); if (! ComputeDiffDCTBlock(current->cr_blocks[by >> 1][bx >> 1], dctr[by >> 1][bx >> 1], motionBlock)) { *pattern ^= 0x1; } }}/*===========================================================================* * * USER-MODIFIABLE * * DoBIntraCode * * decides if this block should be coded as intra-block * * RETURNS: TRUE if intra-coding should be used; FALSE otherwise * * SIDE EFFECTS: none * * PRECONDITION: the motion vectors must be valid! * *===========================================================================*/static booleanDoBIntraCode(current, prev, next, by, bx, mode, fmy, fmx, bmy, bmx) MpegFrame *current; MpegFrame *prev; MpegFrame *next; int by; int bx; int mode; int fmy; int fmx; int bmy; int bmx;{ int x, y; int32 sum = 0, vard = 0, varc = 0, dif; int32 currPixel, prevPixel; LumBlock motionBlock; int fy, fx; ComputeBMotionLumBlock(prev, next, by, bx, mode, fmy, fmx, bmy, bmx, motionBlock); MOTION_TO_FRAME_COORD(by, bx, 0, 0, fy, fx); for ( y = 0; y < 16; y++ ) { for ( x = 0; x < 16; x++ ) { currPixel = current->orig_y[fy+y][fx+x]; prevPixel = motionBlock[y][x]; sum += currPixel; varc += currPixel*currPixel; dif = currPixel - prevPixel; vard += dif*dif; } } vard >>= 8; /* divide by 256; assumes mean is close to zero */ varc = (varc>>8) - (sum>>8)*(sum>>8); if ( vard <= 64 ) { return FALSE; } else if ( vard < varc ) { return FALSE; } else { return TRUE; }}static intComputeBlockColorDiff(current, motionBlock) Block current, motionBlock;{ register int x, y, diff_total = 0, diff_tmp; for ( y = 0; y < 8; y++ ) { for ( x = 0; x < 8; x++ ) { diff_tmp = current[y][x] - motionBlock[y][x]; diff_total += ABS(diff_tmp); } } return diff_total;}/*===========================================================================* * * USER-MODIFIABLE * * MotionSufficient * * decides if this motion vector is sufficient without DCT coding * * RETURNS: TRUE if no DCT is needed; FALSE otherwise * * SIDE EFFECTS: none * * PRECONDITION: the motion vectors must be valid! * *===========================================================================*/static booleanMotionSufficient(curr, currBlock, prev, next, by, bx, mode, fmy, fmx, bmy, bmx) MpegFrame *curr; LumBlock currBlock; MpegFrame *prev; MpegFrame *next; int by, bx; int mode; int fmy, fmx; int bmy, bmx;{ LumBlock mLumBlock; Block mColorBlock; int lumErr, colorErr; /* check bounds */ if ( mode != MOTION_BACKWARD ) { if ( (by*DCTSIZE+(fmy-1)/2 < 0) || ((by+2)*DCTSIZE+(fmy+1)/2-1 >= Fsize_y) ) { return FALSE; } if ( (bx*DCTSIZE+(fmx-1)/2 < 0) || ((bx+2)*DCTSIZE+(fmx+1)/2-1 >= Fsize_x) ) { return FALSE; } } if ( mode != MOTION_FORWARD ) { if ( (by*DCTSIZE+(bmy-1)/2 < 0) || ((by+2)*DCTSIZE+(bmy+1)/2-1 >= Fsize_y) ) { return FALSE; } if ( (bx*DCTSIZE+(bmx-1)/2 < 0) || ((bx+2)*DCTSIZE+(bmx+1)/2-1 >= Fsize_x) ) { return FALSE; } } /* check Lum */ ComputeBMotionLumBlock(prev, next, by, bx, mode, fmy, fmx, bmy, bmx, mLumBlock); lumErr = LumBlockMAD(currBlock, mLumBlock, 0x7fffffff); if (lumErr > 512) { return FALSE; } /* check color */ ComputeBMotionBlock(prev, next, by>>1, bx>>1, mode, fmy/2, fmx/2, bmy/2, bmx/2, mColorBlock, CR_BLOCK); colorErr = ComputeBlockColorDiff(curr->cr_blocks[by >> 1][bx >> 1], mColorBlock); ComputeBMotionBlock(prev, next, by>>1, bx>>1, mode, fmy/2, fmx/2, bmy/2, bmx/2, mColorBlock, CB_BLOCK); colorErr += ComputeBlockColorDiff(curr->cr_blocks[by >> 1][bx >> 1], mColorBlock); return (colorErr < 256); /* lumErr checked above */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -