00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152 #ifdef CLOCKS_PER_SEC
00153 #include <times.h>
00154 #else
00155 #include <sys/times.h>
00156 #endif
00157
00158 #include <sys/param.h>
00159 #include "all.h"
00160 #include "mtypes.h"
00161 #include "frames.h"
00162 #include "prototypes.h"
00163 #include "mpeg.h"
00164 #include "param.h"
00165 #include "mheaders.h"
00166 #include "fsize.h"
00167 #include "parallel.h"
00168 #include "postdct.h"
00169 #include "rate.h"
00170 #include "opts.h"
00171
00172
00173
00174
00175
00176 static int lastNumBits = 0;
00177 static int lastIFrame = 0;
00178 static int numBlocks = 0;
00179 static int numBits;
00180 static int numFrames = 0;
00181 static int numFrameBits = 0;
00182 static int32 totalTime = 0;
00183 static float totalSNR = 0.0;
00184 static float totalPSNR = 0.0;
00185
00186 static int lengths[256] = {
00187 0, 1, 2, 2, 3, 3, 3, 3,
00188 4, 4, 4, 4, 4, 4, 4, 4,
00189 5, 5, 5, 5, 5, 5, 5, 5,
00190 5, 5, 5, 5, 5, 5, 5, 5,
00191 6, 6, 6, 6, 6, 6, 6, 6,
00192 6, 6, 6, 6, 6, 6, 6, 6,
00193 6, 6, 6, 6, 6, 6, 6, 6,
00194 6, 6, 6, 6, 6, 6, 6, 6,
00195 7, 7, 7, 7, 7, 7, 7, 7,
00196 7, 7, 7, 7, 7, 7, 7, 7,
00197 7, 7, 7, 7, 7, 7, 7, 7,
00198 7, 7, 7, 7, 7, 7, 7, 7,
00199 7, 7, 7, 7, 7, 7, 7, 7,
00200 7, 7, 7, 7, 7, 7, 7, 7,
00201 7, 7, 7, 7, 7, 7, 7, 7,
00202 7, 7, 7, 7, 7, 7, 7, 7,
00203 8, 8, 8, 8, 8, 8, 8, 8,
00204 8, 8, 8, 8, 8, 8, 8, 8,
00205 8, 8, 8, 8, 8, 8, 8, 8,
00206 8, 8, 8, 8, 8, 8, 8, 8,
00207 8, 8, 8, 8, 8, 8, 8, 8,
00208 8, 8, 8, 8, 8, 8, 8, 8,
00209 8, 8, 8, 8, 8, 8, 8, 8,
00210 8, 8, 8, 8, 8, 8, 8, 8,
00211 8, 8, 8, 8, 8, 8, 8, 8,
00212 8, 8, 8, 8, 8, 8, 8, 8,
00213 8, 8, 8, 8, 8, 8, 8, 8,
00214 8, 8, 8, 8, 8, 8, 8, 8,
00215 8, 8, 8, 8, 8, 8, 8, 8,
00216 8, 8, 8, 8, 8, 8, 8, 8,
00217 8, 8, 8, 8, 8, 8, 8, 8,
00218 8, 8, 8, 8, 8, 8, 8, 8
00219 };
00220
00221
00222
00223
00224
00225
00226 int qscaleI;
00227 int slicesPerFrame;
00228 int blocksPerSlice;
00229 int fCodeI, fCodeP, fCodeB;
00230 boolean printSNR = FALSE;
00231 boolean printMSE = FALSE;
00232 boolean decodeRefFrames = FALSE;
00233 Block **dct=NULL, **dctr=NULL, **dctb=NULL;
00234 dct_data_type **dct_data;
00235 int TIME_RATE;
00236
00237
00238
00239
00240
00241 extern void PrintItoIBitRate _ANSI_ARGS_((int numBits, int frameNum));
00242
00243
00244
00245
00246 void AllocDctBlocks _ANSI_ARGS_((void ));
00247 int SetFCodeHelper _ANSI_ARGS_((int sr));
00248 void CalcDistortion _ANSI_ARGS_((MpegFrame *current, int y, int x));
00249
00250 int
00251 SetFCodeHelper(SR)
00252 int SR;
00253 {
00254 int range,fCode;
00255
00256 if ( pixelFullSearch ) {
00257 range = SR;
00258 } else {
00259 range = SR*2;
00260 }
00261
00262 if ( range < 256 ) {
00263 if ( range < 64 ) {
00264 if ( range < 32 ) {
00265 fCode = 1;
00266 } else {
00267 fCode = 2;
00268 }
00269 } else {
00270 if ( range < 128 ) {
00271 fCode = 3;
00272 } else {
00273 fCode = 4;
00274 }
00275 }
00276 } else {
00277 if ( range < 1024 ) {
00278 if ( range < 512 ) {
00279 fCode = 5;
00280 } else {
00281 fCode = 6;
00282 }
00283 } else {
00284 if ( range < 2048 ) {
00285 fCode = 7;
00286 } else {
00287 fprintf(stderr, "ERROR: INVALID SEARCH RANGE!!!\n");
00288 exit(1);
00289 }
00290 }
00291 }
00292 return fCode;
00293 }
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309 void
00310 SetFCode()
00311 {
00312 fCodeI = SetFCodeHelper(1);
00313 fCodeP = SetFCodeHelper(searchRangeP);
00314 fCodeB = SetFCodeHelper(searchRangeB);
00315 }
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328 void
00329 SetSlicesPerFrame(number)
00330 int number;
00331 {
00332 slicesPerFrame = number;
00333 }
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347 void
00348 SetBlocksPerSlice()
00349 {
00350 int totalBlocks;
00351
00352 totalBlocks = (Fsize_y>>4)*(Fsize_x>>4);
00353
00354 if ( slicesPerFrame > totalBlocks ) {
00355 blocksPerSlice = 1;
00356 } else {
00357 blocksPerSlice = totalBlocks/slicesPerFrame;
00358 }
00359 }
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373 void
00374 SetIQScale(qI)
00375 int qI;
00376 {
00377 qscaleI = qI;
00378 }
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391 int
00392 GetIQScale()
00393 {
00394 return qscaleI;
00395 }
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408 void
00409 GenIFrame(bb, current)
00410 BitBucket *bb;
00411 MpegFrame *current;
00412 {
00413 register int x, y;
00414 register int index;
00415 FlatBlock fb[6];
00416 Block dec[6];
00417 int32 y_dc_pred, cr_dc_pred, cb_dc_pred;
00418 int totalBits;
00419 int totalFrameBits;
00420 int32 startTime, endTime;
00421 float snr[3], psnr[3];
00422 int mbAddress;
00423 int QScale;
00424 BlockMV *info;
00425 int bitstreamMode, newQScale;
00426 int rc_blockStart=0;
00427
00428 if (dct==NULL) AllocDctBlocks();
00429 if (collect_quant) {fprintf(collect_quant_fp, "# I\n");}
00430
00431
00432 numFrames++;
00433 totalFrameBits = bb->cumulativeBits;
00434 if ( ( ! childProcess) && showBitRatePerFrame ) {
00435 if ( lastNumBits == 0 ) {
00436 lastNumBits = bb->cumulativeBits;
00437 lastIFrame = current->id;
00438 } else {
00439
00440
00441 if (! realQuiet) {
00442 fprintf(stdout, "I-to-I (frames %5d to %5d) bitrate: %8d\n",
00443 lastIFrame, current->id-1,
00444 ((bb->cumulativeBits-lastNumBits)*30)/
00445 (current->id-lastIFrame));
00446 }
00447
00448 fprintf(bitRateFile, "I-to-I (frames %5d to %5d) bitrate: %8d\n",
00449 lastIFrame, current->id-1,
00450 ((bb->cumulativeBits-lastNumBits)*30)/
00451 (current->id-lastIFrame));
00452 lastNumBits = bb->cumulativeBits;
00453 lastIFrame = current->id;
00454 }
00455 }
00456
00457 startTime = time_elapsed();
00458
00459 Frame_AllocBlocks(current);
00460 BlockifyFrame(current);
00461
00462 DBG_PRINT(("Generating iframe\n"));
00463 QScale = GetIQScale();
00464
00465 bitstreamMode = getRateMode();
00466 if (bitstreamMode == FIXED_RATE) {
00467 targetRateControl(current);
00468 }
00469
00470 Mhead_GenPictureHeader(bb, I_FRAME, current->id, fCodeI);
00471
00472 if (specificsOn) {
00473 newQScale = SpecLookup(current->id, 0, 0 , &info, QScale);
00474 if (newQScale != -1) {
00475 QScale = newQScale;
00476 }
00477
00478 newQScale = SpecLookup(current->id, 1, 1, &info, QScale);
00479 if (newQScale != -1) {
00480 QScale = newQScale;
00481 }
00482 }
00483 Mhead_GenSliceHeader(bb, 1, QScale, NULL, 0);
00484
00485 if ( referenceFrame == DECODED_FRAME ) {
00486 Frame_AllocDecoded(current, TRUE);
00487 } else if ( printSNR ) {
00488 Frame_AllocDecoded(current, FALSE);
00489 }
00490
00491 y_dc_pred = cr_dc_pred = cb_dc_pred = 128;
00492 totalBits = bb->cumulativeBits;
00493 mbAddress = 0;
00494
00495
00496 for (y = 0; y < (Fsize_y >> 3); y += 2) {
00497 for (x = 0; x < (Fsize_x >> 3); x += 2) {
00498 if (collect_quant && (collect_quant_detailed & 1)) fprintf(collect_quant_fp, "l\n");
00499 if (DoLaplace) {LaplaceCnum = 0;}
00500 mp_fwd_dct_block2(current->y_blocks[y][x], dct[y][x]);
00501 mp_fwd_dct_block2(current->y_blocks[y][x+1], dct[y][x+1]);
00502 mp_fwd_dct_block2(current->y_blocks[y+1][x], dct[y+1][x]);
00503 mp_fwd_dct_block2(current->y_blocks[y+1][x+1], dct[y+1][x+1]);
00504 if (collect_quant && (collect_quant_detailed & 1)) fprintf(collect_quant_fp, "c\n");
00505 if (DoLaplace) {LaplaceCnum = 1;}
00506 mp_fwd_dct_block2(current->cb_blocks[y>>1][x>>1], dctb[y>>1][x>>1]);
00507 if (DoLaplace) {LaplaceCnum = 2;}
00508 mp_fwd_dct_block2(current->cr_blocks[y>>1][x>>1], dctr[y>>1][x>>1]);
00509 }}
00510
00511 if (DoLaplace) {
00512 extern void CalcLambdas();
00513 CalcLambdas();
00514 }
00515
00516 for (y = 0; y < (Fsize_y >> 3); y += 2) {
00517 for (x = 0; x < (Fsize_x >> 3); x += 2) {
00518
00519 if (specificsOn) {
00520 newQScale = SpecLookup(current->id, 2, mbAddress, &info, QScale);
00521 if (newQScale != -1) {
00522 QScale = newQScale;
00523 }
00524 }
00525
00526
00527 if (bitstreamMode == FIXED_RATE) {
00528 rc_blockStart = bb->cumulativeBits;
00529 newQScale = needQScaleChange(qscaleI,
00530 current->y_blocks[y][x],
00531 current->y_blocks[y][x+1],
00532 current->y_blocks[y+1][x],
00533 current->y_blocks[y+1][x+1]);
00534 if (newQScale > 0) {
00535 QScale = newQScale;
00536 }
00537 }
00538
00539 if ( (mbAddress % blocksPerSlice == 0) && (mbAddress != 0) ) {
00540
00541 if (specificsOn) {
00542
00543 newQScale = SpecLookup(current->id,1,mbAddress/blocksPerSlice, &info, QScale);
00544 if (newQScale != -1) QScale = newQScale;
00545 }
00546 Mhead_GenSliceEnder(bb);
00547 Mhead_GenSliceHeader(bb, 1+(y>>1), QScale, NULL, 0);
00548 y_dc_pred = cr_dc_pred = cb_dc_pred = 128;
00549
00550 GEN_I_BLOCK(I_FRAME, current, bb, 1+(x>>1), QScale);
00551 } else {
00552 GEN_I_BLOCK(I_FRAME, current, bb, 1, QScale);
00553 }
00554
00555 if (WriteDistortionNumbers) {
00556 CalcDistortion(current, y, x);
00557 }
00558
00559 if ( decodeRefFrames ) {
00560
00561 LaplaceCnum = 0;
00562 for ( index = 0; index < 6; index++ ) {
00563 if (!DoLaplace) {
00564 Mpost_UnQuantZigBlock(fb[index], dec[index], QScale, TRUE);
00565 } else {
00566 if (index == 4) {LaplaceCnum = 1;}
00567 if (index == 5) {LaplaceCnum = 2;}
00568 Mpost_UnQuantZigBlockLaplace(fb[index], dec[index], QScale, TRUE);
00569 }
00570 mpeg_jrevdct((int16 *)dec[index]);
00571 }
00572
00573
00574 BlockToData(current->decoded_y, dec[0], y, x);
00575 BlockToData(current->decoded_y, dec[1], y, x+1);
00576 BlockToData(current->decoded_y, dec[2], y+1, x);
00577 BlockToData(current->decoded_y, dec[3], y+1, x+1);
00578 BlockToData(current->decoded_cb, dec[4], y>>1, x>>1);
00579 BlockToData(current->decoded_cr, dec[5], y>>1, x>>1);
00580 }
00581
00582 numBlocks++;
00583 mbAddress++;
00584
00585 if (bitstreamMode == FIXED_RATE) {
00586 incMacroBlockBits(bb->cumulativeBits - rc_blockStart);
00587 rc_blockStart = bb->cumulativeBits;
00588 MB_RateOut(TYPE_IFRAME);
00589 }
00590 }
00591 }
00592
00593 if ( printSNR ) {
00594 BlockComputeSNR(current,snr,psnr);
00595 totalSNR += snr[0];
00596 totalPSNR += psnr[0];
00597 }
00598
00599 if ( (referenceFrame == DECODED_FRAME) && NonLocalRefFrame(current->id) ) {
00600 if ( remoteIO ) {
00601 SendDecodedFrame(current);
00602 } else {
00603 WriteDecodedFrame(current);
00604 }
00605
00606
00607 NotifyDecodeServerReady(current->id);
00608 }
00609
00610 numBits += (bb->cumulativeBits-totalBits);
00611
00612 DBG_PRINT(("End of frame\n"));
00613
00614 Mhead_GenSliceEnder(bb);
00615
00616 if (bitstreamMode == FIXED_RATE) {
00617 updateRateControl(TYPE_IFRAME);
00618 }
00619
00620 endTime = time_elapsed();
00621 totalTime += (endTime-startTime);
00622
00623 numFrameBits += (bb->cumulativeBits-totalFrameBits);
00624
00625 if ( ( ! childProcess) && showBitRatePerFrame ) {
00626
00627 fprintf(bitRateFile, "%5d\t%8d\n", current->id,
00628 30*(bb->cumulativeBits-totalFrameBits));
00629 }
00630
00631 if ( (! childProcess) && frameSummary && (! realQuiet) ) {
00632
00633
00634 fprintf(stdout, "FRAME %d (I): %ld seconds (%d bits/s output)\n",
00635 current->id, (long)((endTime-startTime)/TIME_RATE),
00636 30*(bb->cumulativeBits-totalFrameBits));
00637 if ( printSNR ) {
00638 fprintf(stdout, "FRAME %d: SNR: %.1f\t%.1f\t%.1f\tPSNR: %.1f\t%.1f\t%.1f\n",
00639 current->id, snr[0], snr[1], snr[2],
00640 psnr[0], psnr[1], psnr[2]);
00641 }
00642 }
00643 }
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657 void
00658 ResetIFrameStats()
00659 {
00660 numBlocks = 0;
00661 numBits = 0;
00662 numFrames = 0;
00663 numFrameBits = 0;
00664 totalTime = 0;
00665 }
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679 float
00680 ShowIFrameSummary(inputFrameBits, totalBits, fpointer)
00681 int inputFrameBits;
00682 int32 totalBits;
00683 FILE *fpointer;
00684 {
00685 if ( numFrames == 0 ) {
00686 return 0.0;
00687 }
00688
00689 fprintf(fpointer, "-------------------------\n");
00690 fprintf(fpointer, "*****I FRAME SUMMARY*****\n");
00691 fprintf(fpointer, "-------------------------\n");
00692
00693 fprintf(fpointer, " Blocks: %5d (%6d bits) (%5d bpb)\n",
00694 numBlocks, numBits, numBits/numBlocks);
00695 fprintf(fpointer, " Frames: %5d (%6d bits) (%5d bpf) (%2.1f%% of total)\n",
00696 numFrames, numFrameBits, numFrameBits/numFrames,
00697 100.0*(float)numFrameBits/(float)totalBits);
00698 fprintf(fpointer, " Compression: %3d:1 (%9.4f bpp)\n",
00699 numFrames*inputFrameBits/numFrameBits,
00700 24.0*(float)numFrameBits/(float)(numFrames*inputFrameBits));
00701 if ( printSNR )
00702 fprintf(fpointer, " Avg Y SNR/PSNR: %.1f %.1f\n",
00703 totalSNR/(float)numFrames, totalPSNR/(float)numFrames);
00704 if ( totalTime == 0 ) {
00705 fprintf(fpointer, " Seconds: NONE\n");
00706 } else {
00707 fprintf(fpointer, " Seconds: %9ld (%9.4f fps) (%9ld pps) (%9ld mps)\n",
00708 (long)(totalTime/TIME_RATE),
00709 (float)((float)(TIME_RATE*numFrames)/(float)totalTime),
00710 (long)((float)TIME_RATE*(float)numFrames*(float)inputFrameBits/(24.0*(float)totalTime)),
00711 (long)((float)TIME_RATE*(float)numFrames*(float)inputFrameBits/(256.0*24.0*(float)totalTime)));
00712 }
00713
00714 return (float)totalTime/(float)TIME_RATE;
00715 }
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729 float
00730 EstimateSecondsPerIFrame()
00731 {
00732 return (float)totalTime/((float)TIME_RATE*(float)numFrames);
00733 }
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747 void
00748 EncodeYDC(dc_term, pred_term, bb)
00749 int32 dc_term;
00750 int32 *pred_term;
00751 BitBucket *bb;
00752 {
00753
00754 static int codes[9] = {
00755 0x4, 0x0, 0x1, 0x5, 0x6, 0xe, 0x1e, 0x3e, 0x7e
00756 };
00757 static int codeLengths[9] = {
00758 3, 2, 2, 3, 3, 4, 5, 6, 7
00759 };
00760 int ydiff, ydiff_abs;
00761 int length;
00762
00763 ydiff = (dc_term - (*pred_term));
00764 if (ydiff > 255) {
00765 #ifdef BLEAH
00766 fprintf(stdout, "TRUNCATED\n");
00767 #endif
00768 ydiff = 255;
00769 } else if (ydiff < -255) {
00770 #ifdef BLEAH
00771 fprintf(stdout, "TRUNCATED\n");
00772 #endif
00773 ydiff = -255;
00774 }
00775
00776 ydiff_abs = ABS(ydiff);
00777 length = lengths[ydiff_abs];
00778 Bitio_Write(bb, codes[length], codeLengths[length]);
00779 if ( length != 0 ) {
00780 if ( ydiff > 0 ) {
00781 Bitio_Write(bb, ydiff_abs, length);
00782 } else {
00783 Bitio_Write(bb, ~ydiff_abs, length);
00784 }
00785 }
00786
00787 (*pred_term) += ydiff;
00788 }
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802 void
00803 EncodeCDC(dc_term, pred_term, bb)
00804 int32 dc_term;
00805 int32 *pred_term;
00806 BitBucket *bb;
00807 {
00808
00809 static int codes[9] = {
00810 0x0, 0x1, 0x2, 0x6, 0xe, 0x1e, 0x3e, 0x7e, 0xfe
00811 };
00812 static int codeLengths[9] = {
00813 2, 2, 2, 3, 4, 5, 6, 7, 8
00814 };
00815 int cdiff, cdiff_abs;
00816 int length;
00817
00818 cdiff = (dc_term - (*pred_term));
00819 if (cdiff > 255) {
00820 #ifdef BLEAH
00821 fprintf(stdout, "TRUNCATED\n");
00822 #endif
00823 cdiff = 255;
00824 } else if (cdiff < -255) {
00825 #ifdef BLEAH
00826 fprintf(stdout, "TRUNCATED\n");
00827 #endif
00828 cdiff = -255;
00829 }
00830
00831 cdiff_abs = ABS(cdiff);
00832 length = lengths[cdiff_abs];
00833 Bitio_Write(bb, codes[length], codeLengths[length]);
00834 if ( length != 0 ) {
00835 if ( cdiff > 0 ) {
00836 Bitio_Write(bb, cdiff_abs, length);
00837 } else {
00838 Bitio_Write(bb, ~cdiff_abs, length);
00839 }
00840 }
00841
00842 (*pred_term) += cdiff;
00843 }
00844
00845
00846 void
00847 BlockComputeSNR(current, snr, psnr)
00848 MpegFrame *current;
00849 float snr[];
00850 float psnr[];
00851 {
00852 register int32 tempInt;
00853 register int y, x;
00854 int32 varDiff[3];
00855 double ratio[3];
00856 double total[3];
00857 register uint8 **origY=current->orig_y, **origCr=current->orig_cr,
00858 **origCb=current->orig_cb;
00859 register uint8 **newY=current->decoded_y, **newCr=current->decoded_cr,
00860 **newCb=current->decoded_cb;
00861 static int32 **SignalY, **NoiseY;
00862 static int32 **SignalCb, **NoiseCb;
00863 static int32 **SignalCr, **NoiseCr;
00864 static short ySize[3], xSize[3];
00865 static boolean needs_init=TRUE;
00866
00867
00868 if (needs_init) {
00869 int ysz = (Fsize_y>>3) * sizeof(int32 *);
00870 int xsz = (Fsize_x>>3);
00871
00872 needs_init = FALSE;
00873 for (y=0; y<3; y++) {
00874 varDiff[y] = ratio[y] = total[y] = 0.0;
00875 }
00876 ySize[0]=Fsize_y; xSize[0]=Fsize_x;
00877 ySize[1]=Fsize_y>>1; xSize[1]=Fsize_x>>1;
00878 ySize[2]=Fsize_y>>1; xSize[2]=Fsize_x>>1;
00879 SignalY = (int32 **) malloc(ysz);
00880 NoiseY = (int32 **) malloc(ysz);
00881 SignalCb = (int32 **) malloc(ysz);
00882 NoiseCb = (int32 **) malloc(ysz);
00883 SignalCr = (int32 **) malloc(ysz);
00884 NoiseCr = (int32 **) malloc(ysz);
00885 if (SignalY == NULL || NoiseY == NULL || SignalCr == NULL ||
00886 NoiseCb == NULL || SignalCb == NULL || NoiseCr == NULL) {
00887 fprintf(stderr, "Out of memory in BlockComputeSNR\n");
00888 exit(-1);
00889 }
00890 for (y = 0; y < ySize[0]>>3; y++) {
00891 SignalY[y] = (int32 *) calloc(xsz,4);
00892 SignalCr[y] = (int32 *) calloc(xsz,4);
00893 SignalCb[y] = (int32 *) calloc(xsz,4);
00894 NoiseY[y] = (int32 *) calloc(xsz,4);
00895 NoiseCr[y] = (int32 *) calloc(xsz,4);
00896 NoiseCb[y] = (int32 *) calloc(xsz,4);
00897 }
00898 } else {
00899 for (y = 0; y < ySize[0]>>3; y++) {
00900 memset((char *) &NoiseY[y][0], 0, (xSize[0]>>3) * 4);
00901 memset((char *) &SignalY[y][0], 0, (xSize[0]>>3) * 4);
00902 memset((char *) &NoiseCb[y][0], 0, (xSize[0]>>3) * 4);
00903 memset((char *) &NoiseCr[y][0], 0, (xSize[0]>>3) * 4);
00904 memset((char *) &SignalCb[y][0], 0, (xSize[0]>>3) * 4);
00905 memset((char *) &SignalCr[y][0], 0, (xSize[0]>>3) * 4);
00906 }
00907 }
00908
00909
00910 for (y = 0; y < ySize[0]; y++) {
00911 for (x = 0; x < xSize[0]; x++) {
00912 tempInt = (origY[y][x] - newY[y][x]);
00913 NoiseY[y>>4][x>>4] += tempInt*tempInt;
00914 total[0] += (double)abs(tempInt);
00915 tempInt = origY[y][x];
00916 SignalY[y>>4][x>>4] += tempInt*tempInt;
00917 }}
00918 for (y = 0; y < ySize[1]; y++) {
00919 for (x = 0; x < xSize[1]; x ++) {
00920 tempInt = (origCb[y][x] - newCb[y][x]);
00921 NoiseCb[y>>3][x>>3] += tempInt*tempInt;
00922 total[1] += (double)abs(tempInt);
00923 tempInt = origCb[y][x];
00924 SignalCb[y>>3][x>>3] += tempInt*tempInt;
00925 tempInt = (origCr[y][x]-newCr[y][x]);
00926 NoiseCr[y>>3][x>>3] += tempInt*tempInt;
00927 total[2] += (double)abs(tempInt);
00928 tempInt = origCr[y][x];
00929 SignalCr[y>>3][x>>3] += tempInt*tempInt;
00930 }}
00931
00932
00933 for(y=0; y<Fsize_y>>4; y++){
00934 for(x=0; x<Fsize_x>>4; x++){
00935 varDiff[0] += NoiseY[y][x];
00936 varDiff[1] += NoiseCb[y][x];
00937 varDiff[2] += NoiseCr[y][x];
00938 if (printMSE) printf("%4d ",(int)(NoiseY[y][x]/256.0));
00939 }
00940 if (printMSE) puts("");
00941 }
00942
00943
00944 for(y=0; y<Fsize_y>>4; y++){
00945 for(x=0; x<Fsize_x>>4; x++){
00946 ratio[0] += (double)SignalY[y][x]/(double)varDiff[0];
00947 ratio[1] += (double)SignalCb[y][x]/(double)varDiff[1];
00948 ratio[2] += (double)SignalCr[y][x]/(double)varDiff[2];
00949 }}
00950
00951 for (x=0; x<3; x++) {
00952 snr[x] = 10.0*log10(ratio[x]);
00953 psnr[x] = 20.0*log10(255.0/sqrt((double)varDiff[x]/(double)(ySize[x]*xSize[x])));
00954
00955 if (! realQuiet) {
00956 fprintf(stdout, "Mean error[%1d]: %f\n", x, total[x]/(double)(xSize[x]*ySize[x]));
00957 }
00958
00959 }
00960 }
00961
00962 void
00963 WriteDecodedFrame(frame)
00964 MpegFrame *frame;
00965 {
00966 FILE *fpointer;
00967 char fileName[256];
00968 int width, height;
00969 register int y;
00970
00971
00972
00973
00974 width = Fsize_x;
00975 height = Fsize_y;
00976
00977 sprintf(fileName, "%s.decoded.%d", outputFileName, frame->id);
00978
00979 if (!realQuiet) {
00980 fprintf(stdout, "Outputting to %s\n", fileName);
00981 fflush(stdout);
00982 }
00983
00984 fpointer = fopen(fileName, "wb");
00985
00986 for ( y = 0; y < height; y++ ) {
00987 fwrite(frame->decoded_y[y], 1, width, fpointer);
00988 }
00989
00990 for (y = 0; y < (height >> 1); y++) {
00991 fwrite(frame->decoded_cb[y], 1, width >> 1, fpointer);
00992 }
00993
00994 for (y = 0; y < (height >> 1); y++) {
00995 fwrite(frame->decoded_cr[y], 1, width >> 1, fpointer);
00996 }
00997 fflush(fpointer);
00998 fclose(fpointer);
00999 }
01000
01001
01002 void
01003 PrintItoIBitRate(numBits, frameNum)
01004 int numBits;
01005 int frameNum;
01006 {
01007 if ( ( ! childProcess) && showBitRatePerFrame ) {
01008
01009
01010 if (! realQuiet) {
01011 fprintf(stdout, "I-to-I (frames %5d to %5d) bitrate: %8d\n",
01012 lastIFrame, frameNum-1,
01013 ((numBits-lastNumBits)*30)/
01014 (frameNum-lastIFrame));
01015 }
01016
01017 fprintf(bitRateFile, "I-to-I (frames %5d to %5d) bitrate: %8d\n",
01018 lastIFrame, frameNum-1,
01019 ((numBits-lastNumBits)*30)/
01020 (frameNum-lastIFrame));
01021 }
01022 }
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036 void
01037 AllocDctBlocks()
01038 {
01039 int dctx, dcty;
01040 int i;
01041
01042 dctx = Fsize_x / DCTSIZE;
01043 dcty = Fsize_y / DCTSIZE;
01044
01045 dct = (Block **) malloc(sizeof(Block *) * dcty);
01046 ERRCHK(dct, "malloc");
01047 for (i = 0; i < dcty; i++) {
01048 dct[i] = (Block *) malloc(sizeof(Block) * dctx);
01049 ERRCHK(dct[i], "malloc");
01050 }
01051
01052 dct_data = (dct_data_type **) malloc(sizeof(dct_data_type *) * dcty);
01053 ERRCHK(dct_data, "malloc");
01054 for (i = 0; i < dcty; i++) {
01055 dct_data[i] = (dct_data_type *) malloc(sizeof(dct_data_type) * dctx);
01056 ERRCHK(dct[i], "malloc");
01057 }
01058
01059 dctr = (Block **) malloc(sizeof(Block *) * (dcty >> 1));
01060 dctb = (Block **) malloc(sizeof(Block *) * (dcty >> 1));
01061 ERRCHK(dctr, "malloc");
01062 ERRCHK(dctb, "malloc");
01063 for (i = 0; i < (dcty >> 1); i++) {
01064 dctr[i] = (Block *) malloc(sizeof(Block) * (dctx >> 1));
01065 dctb[i] = (Block *) malloc(sizeof(Block) * (dctx >> 1));
01066 ERRCHK(dctr[i], "malloc");
01067 ERRCHK(dctb[i], "malloc");
01068 }
01069 }
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081 int32 time_elapsed()
01082 {
01083 #ifdef CLOCKS_PER_SEC
01084
01085 TIME_RATE = CLOCKS_PER_SEC;
01086 return (int32) clock();
01087 #else
01088 struct tms timeBuffer;
01089 TIME_RATE = 60;
01090 times(&timeBuffer);
01091 return timeBuffer.tms_utime + timeBuffer.tms_stime;
01092 #endif
01093 }
01094
01095
01096 void
01097 CalcDistortion(current, y, x)
01098 MpegFrame *current;
01099 int y,x;
01100 {
01101
01102 int qscale, distort=0;
01103 Block decblk;
01104 FlatBlock fblk;
01105 int datarate = 0;
01106
01107 for (qscale = 1; qscale < 32; qscale ++) {
01108 distort = 0;
01109 datarate = 0;
01110 Mpost_QuantZigBlock(dct[y][x], fblk, qscale, TRUE);
01111 Mpost_UnQuantZigBlock(fblk, decblk, qscale, TRUE);
01112 if (collect_distortion_detailed) datarate += CalcRLEHuffLength(fblk);
01113 mpeg_jrevdct((int16 *)decblk);
01114 distort += mse(current->y_blocks[y][x], decblk);
01115
01116 Mpost_QuantZigBlock(dct[y][x+1], fblk, qscale, TRUE);
01117 Mpost_UnQuantZigBlock(fblk, decblk, qscale, TRUE);
01118 if (collect_distortion_detailed) datarate += CalcRLEHuffLength(fblk);
01119 mpeg_jrevdct((int16 *)decblk);
01120 distort += mse(current->y_blocks[y][x+1], decblk);
01121
01122 Mpost_QuantZigBlock(dct[y+1][x], fblk, qscale, TRUE);
01123 Mpost_UnQuantZigBlock(fblk, decblk, qscale, TRUE);
01124 if (collect_distortion_detailed) datarate += CalcRLEHuffLength(fblk);
01125 mpeg_jrevdct((int16 *)decblk);
01126 distort += mse(current->y_blocks[y+1][x], decblk);
01127
01128 Mpost_QuantZigBlock(dct[y+1][x+1], fblk, qscale, TRUE);
01129 Mpost_UnQuantZigBlock(fblk, decblk, qscale, TRUE);
01130 if (collect_distortion_detailed) datarate += CalcRLEHuffLength(fblk);
01131 mpeg_jrevdct((int16 *)decblk);
01132 distort += mse(current->y_blocks[y+1][x+1], decblk);
01133
01134 Mpost_QuantZigBlock(dctb[y >> 1][x >> 1], fblk, qscale, TRUE);
01135 Mpost_UnQuantZigBlock(fblk, decblk, qscale, TRUE);
01136 if (collect_distortion_detailed) datarate += CalcRLEHuffLength(fblk);
01137 mpeg_jrevdct((int16 *)decblk);
01138 distort += mse(current->cb_blocks[y>>1][x>>1], decblk);
01139
01140 Mpost_QuantZigBlock(dctr[y >> 1][x >> 1], fblk, qscale, TRUE);
01141 Mpost_UnQuantZigBlock(fblk, decblk, qscale, TRUE);
01142 if (collect_distortion_detailed) datarate += CalcRLEHuffLength(fblk);
01143 mpeg_jrevdct((int16 *)decblk);
01144 distort += mse(current->cr_blocks[y >> 1][x >> 1], decblk);
01145
01146 if (!collect_distortion_detailed) {
01147 fprintf(distortion_fp, "\t%d\n", distort);
01148 } else if (collect_distortion_detailed == 1) {
01149 fprintf(distortion_fp, "\t%d\t%d\n", distort, datarate);
01150 } else {
01151 fprintf(fp_table_rate[qscale-1], "%d\n", datarate);
01152 fprintf(fp_table_dist[qscale-1], "%d\n", distort);
01153 }
01154 }
01155 }
01156
01157
01158
01159