1 |
/*============================================================================* |
2 |
* rate.c * |
3 |
* * |
4 |
* Procedures concerned with rate control * |
5 |
* * |
6 |
* EXPORTED PROCEDURES: * |
7 |
* initRatecontrol() * |
8 |
* targetRateControl() * |
9 |
* updateRateControl() * |
10 |
* MB_RateOut() * |
11 |
* needQScaleChange() * |
12 |
* incNumBlocks() * |
13 |
* incQuant() * |
14 |
* incMacroBlockBits() * |
15 |
* setPictureRate() * |
16 |
* setBitRate() * |
17 |
* getBitRate() * |
18 |
* setBufferSize() * |
19 |
* getBufferSize() * |
20 |
* * |
21 |
* NOTES: * |
22 |
* Naming conventions follow those of MPEG-2 draft algorithm (chap. 10) * |
23 |
*============================================================================*/ |
24 |
|
25 |
|
26 |
/* |
27 |
* Copyright (c) 1995 The Regents of the University of California. |
28 |
* All rights reserved. |
29 |
* |
30 |
* Permission to use, copy, modify, and distribute this software and its |
31 |
* documentation for any purpose, without fee, and without written agreement is |
32 |
* hereby granted, provided that the above copyright notice and the following |
33 |
* two paragraphs appear in all copies of this software. |
34 |
* |
35 |
* IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR |
36 |
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT |
37 |
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF |
38 |
* CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
39 |
* |
40 |
* THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, |
41 |
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY |
42 |
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS |
43 |
* ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO |
44 |
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. |
45 |
*/ |
46 |
|
47 |
/*==============* |
48 |
* HEADER FILES * |
49 |
*==============*/ |
50 |
#ifndef WIN32 |
51 |
#include <sys/times.h> |
52 |
#endif |
53 |
|
54 |
#include "all.h" |
55 |
#include "mtypes.h" |
56 |
#include "bitio.h" |
57 |
#include "frames.h" |
58 |
#include "prototypes.h" |
59 |
#include "param.h" |
60 |
#include "mheaders.h" |
61 |
#include "fsize.h" |
62 |
#include "postdct.h" |
63 |
#include "mpeg.h" |
64 |
#include "parallel.h" |
65 |
#include "dct.h" |
66 |
#include "rate.h" |
67 |
|
68 |
|
69 |
/*==================* |
70 |
* GLOBAL VARIABLES * |
71 |
*==================*/ |
72 |
|
73 |
#define MAX_BIT_RATE 104857600 /* 18 digit number in units of 400 */ |
74 |
#define MAX_BUFFER_SIZE 16760832 /* 10 digit number in units of 16k */ |
75 |
#define DEFAULT_BUFFER_SIZE 327680 /* maximun for "constrained" bitstream */ |
76 |
#define DEFAULT_VBV_FULLNESS 3 /* wait till 1/3 full */ |
77 |
#define DEFAULT_PICT_RATE_CODE 5 /* code for 30 Frames/sec */ |
78 |
#define DEFAULT_PICT_RATE 30 /* 30 frames per second */ |
79 |
#define MAX_VBV_DELAY 32768 /* 16 digits */ |
80 |
|
81 |
|
82 |
/* Variables from Parameter File */ |
83 |
|
84 |
static int RateControlMode = VARIABLE_RATE; |
85 |
static int32 buffer_size = DEFAULT_BUFFER_SIZE; |
86 |
static int32 bit_rate = -1; |
87 |
|
88 |
|
89 |
/* Variables for the VBV buffer defined in MPEG specs */ |
90 |
static int32 VBV_delay =0; /* delay in units of 1/90000 seconds */ |
91 |
static int32 VBV_buffer = 0; /* fullness of the theoretical VBV buffer */ |
92 |
static int32 bufferFillRate = 0; /* constant rate at which buffer filled */ |
93 |
static int32 frameDelayIncrement = 0; /* number of "delay" units/Frame */ |
94 |
|
95 |
/* Global complexity measure variables */ |
96 |
static int Xi, Xp, Xb; /* Global complexity measure */ |
97 |
|
98 |
static int Si, Sp, Sb; /* Total # bits for last pict of type (Overhead?) */ |
99 |
|
100 |
static float Qi, Qp, Qb; /* avg quantizaton for last picture of type */ |
101 |
|
102 |
/* Target bit allocations for each type of picture*/ |
103 |
int Ti, Tp, Tb; |
104 |
|
105 |
int current_Tx; /* allocation for current frame */ |
106 |
|
107 |
/* Count of number of pictures of each type remaining */ |
108 |
int GOP_X = 0; |
109 |
int GOP_I = 0; |
110 |
int GOP_P = 0; |
111 |
int GOP_B = 0; |
112 |
|
113 |
int Nx = 0; |
114 |
int Ni = 0; |
115 |
int Np = 0; |
116 |
int Nb = 0; |
117 |
|
118 |
/* Counters used while encoding frames */ |
119 |
|
120 |
int rc_numBlocks = 0; |
121 |
int rc_totalQuant = 0; |
122 |
int rc_bitsThisMB; |
123 |
int rc_totalMBBits; |
124 |
int rc_totalFrameBits; |
125 |
int rc_totalOverheadBits = 0; |
126 |
|
127 |
|
128 |
/* Want to print out Macroblock info every Nth MB */ |
129 |
int RC_MB_SAMPLE_RATE = 0; |
130 |
|
131 |
static float Ki = .7; |
132 |
static float Kp = 1; |
133 |
static float Kb = 1.4; |
134 |
static int rc_R; |
135 |
static int rc_G; |
136 |
|
137 |
/* Rate Control variables */ |
138 |
|
139 |
/* Virtual buffers for each frame type */ |
140 |
static int d0_i; /* Initial fullnesses */ |
141 |
static int d0_p; |
142 |
static int d0_b; |
143 |
|
144 |
static int lastFrameVirtBuf; /* fullness after last frame of this type */ |
145 |
static int currentVirtBuf; /* fullness during current encoding*/ |
146 |
|
147 |
static int MB_cnt = -1; /* Number of MB's in picture */ |
148 |
|
149 |
static int rc_Q; /* reference quantization parameter */ |
150 |
|
151 |
static int reactionParameter; /* Reaction parameter */ |
152 |
|
153 |
/* Adaptive Quantization variables */ |
154 |
static int act_j; /* spatial activity measure */ |
155 |
static float N_act; /* Normalised spacial activity */ |
156 |
static int avg_act; /* average activity value in last picture encoded */ |
157 |
static int total_act_j; /* Sum of activity values in current frame */ |
158 |
|
159 |
static int var_sblk; /* sub-block activity */ |
160 |
static int P_mean; /* Mean value of pixels in 8x8 sub-block */ |
161 |
|
162 |
static int mquant; /* Raw Quantization value */ |
163 |
static int Qscale; /* Clipped, truncated quantization value */ |
164 |
|
165 |
|
166 |
|
167 |
/* Output-related variables */ |
168 |
#ifdef RC_STATS_FILE |
169 |
static FILE *RC_FILE; |
170 |
#endif |
171 |
|
172 |
static char *Frame_header1 = " Fm # Bit GOP V "; |
173 |
static char *Frame_header2 = " # type MBs Alloc left Ni Np Nb N_act buff Q_rc Qscale"; |
174 |
static char *Frame_header3 = "---- - ---- ------ ------- -- -- -- ----- ------ ---- ----"; |
175 |
static char *Frame_trailer1 = " avg virt % GOP % VBV"; |
176 |
static char *Frame_trailer2 = " Sx Qx Xx act N_act buffer alloc left left buf delay"; |
177 |
static char *Frame_trailer3 = "------ --.-- ------- --- --.-- ------- --- ------- --- ------- ------"; |
178 |
|
179 |
static char *MB_header1 = "MB# #bits Q mqt Dj Q_j actj N_act totbits b/MB %alloc %done"; |
180 |
static char *MB_header2 = "--- ----- -- --- ------ --- ----- --.-- ------ ---- --- ---"; |
181 |
|
182 |
static char rc_buffer[101]; |
183 |
|
184 |
/* EXTERNAL Variables */ |
185 |
extern char *framePattern; |
186 |
extern int framePatternLen; |
187 |
|
188 |
|
189 |
/*===============================* |
190 |
* INTERNAL PROCEDURE prototypes * |
191 |
*===============================*/ |
192 |
|
193 |
int initGOPRateControl _ANSI_ARGS_((void)); |
194 |
int determineMBCount _ANSI_ARGS_((void)); |
195 |
void checkBufferFullness _ANSI_ARGS_((int count)); |
196 |
void checkSpatialActivity _ANSI_ARGS_((Block blk0, Block blk1, Block blk2, Block blk3)); |
197 |
void incNumBlocks _ANSI_ARGS_((int num)); |
198 |
void calculateVBVDelay _ANSI_ARGS_((int num)); |
199 |
void updateVBVBuffer _ANSI_ARGS_((int frameBits)); |
200 |
int BlockExperiments _ANSI_ARGS_((int16 *OrigBlock, int16 *NewBlock, int control)); |
201 |
|
202 |
|
203 |
/*=====================* |
204 |
* EXPORTED PROCEDURES * |
205 |
*=====================*/ |
206 |
|
207 |
/*===========================================================================* |
208 |
* |
209 |
* initRateControl |
210 |
* |
211 |
* initialize the allocation parameters. |
212 |
* |
213 |
* RETURNS: nothing |
214 |
* |
215 |
* SIDE EFFECTS: many global variables |
216 |
* |
217 |
* NOTES: Get rid of the redundant pattern stuff!! |
218 |
*===========================================================================*/ |
219 |
int |
220 |
initRateControl() |
221 |
{ |
222 |
int index; |
223 |
int result; |
224 |
|
225 |
DBG_PRINT(("\tInitializing Allocation Data\n")); |
226 |
|
227 |
#ifdef RC_STATS_FILE |
228 |
RC_FILE = fopen("RC_STATS_FILE", "w"); |
229 |
if ( RC_FILE == NULL) { |
230 |
DBG_PRINT(("\tOpen of RC file failed, using stderr\n")); |
231 |
RC_FILE = stderr; |
232 |
fprintf(RC_FILE, "\tOpen of RC file failed, using stderr\n"); |
233 |
fflush(RC_FILE); |
234 |
} |
235 |
#endif |
236 |
|
237 |
/* Initialize Pattern info */ |
238 |
GOP_X = framePatternLen; |
239 |
for ( index = 0; index < framePatternLen; index++ ) { |
240 |
switch( framePattern[index] ) { |
241 |
case 'i': |
242 |
GOP_I++; |
243 |
break; |
244 |
case 'p': |
245 |
GOP_P++; |
246 |
break; |
247 |
case 'b': |
248 |
GOP_B++; |
249 |
break; |
250 |
default: |
251 |
printf("\n\tERROR rate.c - BAD PATTERN!\n"); |
252 |
RateControlMode = VARIABLE_RATE; |
253 |
return (0); |
254 |
} |
255 |
} |
256 |
if (GOP_X != (GOP_I + GOP_P + GOP_B )) { |
257 |
printf("\n\tERROR rate.c - Pattern Length Mismatch\n"); |
258 |
RateControlMode = VARIABLE_RATE; |
259 |
return (-1); |
260 |
} |
261 |
|
262 |
/* Initializing GOP bit allocation */ |
263 |
rc_R = 0; |
264 |
rc_G = (bit_rate * GOP_X/frameRateRounded); |
265 |
|
266 |
/* Initialize the "global complexity measures" */ |
267 |
Xi = (160 * bit_rate/115); |
268 |
Xp = (60 * bit_rate/115); |
269 |
Xb = (42 * bit_rate/115); |
270 |
|
271 |
/* Initialize MB counters */ |
272 |
rc_totalMBBits= rc_bitsThisMB= rc_totalFrameBits=rc_totalOverheadBits = 0; |
273 |
rc_numBlocks = rc_totalQuant = 0; |
274 |
|
275 |
/* init virtual buffers */ |
276 |
reactionParameter = (2 * bit_rate / frameRateRounded); |
277 |
d0_i = (10 * reactionParameter / 31); |
278 |
d0_p = (Kp * d0_i); |
279 |
d0_b = (Kb * d0_i); |
280 |
|
281 |
lastFrameVirtBuf = d0_i; /* start with I Frame */ |
282 |
rc_Q = lastFrameVirtBuf * 31 / reactionParameter; |
283 |
|
284 |
/* init spatial activity measures */ |
285 |
avg_act = 400; /* Suggested initial value */ |
286 |
N_act = 1; |
287 |
|
288 |
mquant = rc_Q * N_act; |
289 |
|
290 |
frameDelayIncrement = (90000 / frameRateRounded); /* num of "delay" units per frame */ |
291 |
bufferFillRate = bit_rate / frameRateRounded; /* VBV buf fills at constant rate */ |
292 |
VBV_buffer = buffer_size; |
293 |
DBG_PRINT(("\tVBV- delay: %d, fill rate: %d, delay/Frame: %d units, buffer size: %d\n", |
294 |
VBV_delay, bufferFillRate, frameDelayIncrement, buffer_size)); |
295 |
|
296 |
result = initGOPRateControl(); |
297 |
|
298 |
return result; |
299 |
} |
300 |
|
301 |
/*===========================================================================* |
302 |
* |
303 |
* initGOPRateControl |
304 |
* |
305 |
* (re)-initialize the RC for the a new Group of Pictures. |
306 |
* New bit allocation, but carry over complexity measures. |
307 |
* |
308 |
* RETURNS: nothing |
309 |
* |
310 |
* SIDE EFFECTS: many global variables |
311 |
* |
312 |
*===========================================================================*/ |
313 |
int |
314 |
initGOPRateControl() |
315 |
{ |
316 |
DBG_PRINT(("\tInitializing new GOP\n")); |
317 |
|
318 |
Nx = GOP_X; |
319 |
Ni = GOP_I; |
320 |
Np = GOP_P; |
321 |
Nb = GOP_B; |
322 |
|
323 |
rc_R += rc_G; |
324 |
|
325 |
DBG_PRINT(("\tbufsize: %d, bitrate: %d, pictrate: %d, GOP bits: %d\n", |
326 |
buffer_size, bit_rate, frameRateRounded, rc_R)); |
327 |
DBG_PRINT(("\tXi: %d, Xp: %d, Xb: %d Nx: %d, Ni: %d, Np: %d, Nb: %d\n", |
328 |
Xi, Xp, Xb, Nx,Ni,Np,Nb)); |
329 |
DBG_PRINT(("\td0_i: %d, d0_p: %d, d0_b: %d, avg_act: %d, rc_Q: %d, mquant: %d\n", |
330 |
d0_i, d0_p, d0_b, avg_act, rc_Q, mquant)); |
331 |
return 1; |
332 |
} |
333 |
|
334 |
|
335 |
/*===========================================================================* |
336 |
* |
337 |
* targetRateControl |
338 |
* |
339 |
* Determine the target allocation for given picture type, initiates |
340 |
* variables for rate control process. |
341 |
* |
342 |
* RETURNS: nothing. |
343 |
* |
344 |
* SIDE EFFECTS: many global variables |
345 |
* |
346 |
*===========================================================================*/ |
347 |
void |
348 |
targetRateControl(frame) |
349 |
MpegFrame *frame; |
350 |
{ |
351 |
float temp1, minimumBits; |
352 |
float tempX, tempY, tempZ; |
353 |
int result; |
354 |
int frameType; |
355 |
char *strPtr; |
356 |
|
357 |
minimumBits = (bit_rate / (8 * frameRateRounded)); |
358 |
|
359 |
/* Check if new GOP */ |
360 |
if (Nx == 0) { |
361 |
initGOPRateControl(); |
362 |
} |
363 |
|
364 |
if (MB_cnt < 0) {MB_cnt = determineMBCount();} |
365 |
|
366 |
switch (frame->type) { |
367 |
case TYPE_IFRAME: |
368 |
frameType = 'I'; |
369 |
|
370 |
/* temp1 = ( rc_R / ( 1+ ((Np * Xp) / (Xi * Kp)) + ((Nb*Xb) / (Xi*Kb))))); */ |
371 |
|
372 |
tempX = ( (Np * Ki * Xp) / (Xi * Kp) ); |
373 |
tempY = ( (Nb * Ki * Xb) / (Xi*Kb) ); |
374 |
tempZ = Ni + tempX + tempY; |
375 |
temp1 = (rc_R / tempZ); |
376 |
result = (int) (temp1 > minimumBits ? temp1 : minimumBits); |
377 |
current_Tx = Ti = result; |
378 |
lastFrameVirtBuf = d0_i; |
379 |
break; |
380 |
|
381 |
case TYPE_PFRAME: |
382 |
frameType = 'P'; |
383 |
tempX = ( (Ni * Kp * Xi) / (Ki * Xp) ); |
384 |
tempY = ( (Nb * Kp * Xb) / (Kb * Xp) ); |
385 |
tempZ = Np + tempX + tempY; |
386 |
temp1 = (rc_R/ tempZ); |
387 |
result = (int) (temp1 > minimumBits ? temp1 : minimumBits); |
388 |
current_Tx = Tp = result; |
389 |
lastFrameVirtBuf = d0_p; |
390 |
break; |
391 |
|
392 |
case TYPE_BFRAME: |
393 |
frameType = 'B'; |
394 |
tempX = ( (Ni * Kb * Xi) / (Ki * Xb) ); |
395 |
tempY = ( (Np * Kb * Xp) / (Kp * Xb) ); |
396 |
tempZ = Nb + tempX + tempY; |
397 |
temp1 = (rc_R/ tempZ); |
398 |
result = (int) (temp1 > minimumBits ? temp1 : minimumBits); |
399 |
current_Tx = Tb = result; |
400 |
lastFrameVirtBuf = d0_b; |
401 |
break; |
402 |
|
403 |
default: |
404 |
frameType = 'X'; |
405 |
} |
406 |
|
407 |
N_act = 1; |
408 |
rc_Q = lastFrameVirtBuf * 31 / reactionParameter; |
409 |
mquant = rc_Q * N_act; |
410 |
Qscale = (mquant > 31 ? 31 : mquant); |
411 |
Qscale = (Qscale < 1 ? 1 : Qscale); |
412 |
|
413 |
/* Print headers for Frame info */ |
414 |
strPtr = Frame_header1; |
415 |
DBG_PRINT(("%s\n",strPtr)); |
416 |
strPtr = Frame_header2; |
417 |
DBG_PRINT(("%s\n",strPtr)); |
418 |
strPtr = Frame_header3; |
419 |
DBG_PRINT(("%s\n",strPtr)); |
420 |
|
421 |
/* Print Frame info */ |
422 |
sprintf(rc_buffer, "%4d %1c %4d %6d %7d %2d %2d %2d %2.2f %6d %4d %3d", |
423 |
frame->id,frameType,MB_cnt,current_Tx,rc_R,Ni,Np,Nb, N_act, lastFrameVirtBuf, rc_Q, Qscale); |
424 |
|
425 |
#ifdef RC_STATS_FILE |
426 |
fprintf(RC_FILE,"%s\n", rc_buffer); |
427 |
fflush(RC_FILE); |
428 |
#endif |
429 |
DBG_PRINT(("%s\n",rc_buffer)); |
430 |
|
431 |
/* Print headers for Macroblock info */ |
432 |
if (RC_MB_SAMPLE_RATE) { |
433 |
strPtr = MB_header1; |
434 |
DBG_PRINT(("%s\n",strPtr)); |
435 |
strPtr = MB_header2; |
436 |
DBG_PRINT(("%s\n",strPtr)); |
437 |
} else { |
438 |
return; |
439 |
} |
440 |
|
441 |
return; |
442 |
} |
443 |
|
444 |
|
445 |
|
446 |
/*===========================================================================* |
447 |
* |
448 |
* updateRateControl |
449 |
* |
450 |
* Update the statistics kept, after end of frame. Resets |
451 |
* various global variables |
452 |
* |
453 |
* RETURNS: nothing |
454 |
* |
455 |
* SIDE EFFECTS: many global variables |
456 |
* |
457 |
*===========================================================================*/ |
458 |
void |
459 |
updateRateControl(type) |
460 |
int type; |
461 |
{ |
462 |
int totalBits, frameComplexity, pctAllocUsed, pctGOPUsed; |
463 |
float avgQuant; |
464 |
char *strPtr; |
465 |
|
466 |
totalBits = rc_totalFrameBits; |
467 |
avgQuant = ((float) rc_totalQuant / (float) rc_numBlocks); |
468 |
frameComplexity = totalBits * avgQuant; |
469 |
pctAllocUsed = (totalBits *100 / current_Tx); |
470 |
rc_R -= totalBits; |
471 |
pctGOPUsed = (rc_R *100/ rc_G); |
472 |
|
473 |
avg_act = (total_act_j / MB_cnt); |
474 |
|
475 |
updateVBVBuffer(totalBits); |
476 |
|
477 |
switch (type) { |
478 |
case TYPE_IFRAME: |
479 |
Ti = current_Tx; |
480 |
d0_i = currentVirtBuf; |
481 |
Ni--; |
482 |
Si = totalBits; |
483 |
Qi = avgQuant; |
484 |
Xi = frameComplexity; |
485 |
break; |
486 |
case TYPE_PFRAME: |
487 |
Tp = current_Tx; |
488 |
d0_p = currentVirtBuf; |
489 |
Np--; |
490 |
Sp = totalBits; |
491 |
Qp = avgQuant; |
492 |
Xp = frameComplexity; |
493 |
break; |
494 |
case TYPE_BFRAME: |
495 |
Tb = current_Tx; |
496 |
d0_b = currentVirtBuf; |
497 |
Nb--; |
498 |
Sb = totalBits; |
499 |
Qb = avgQuant; |
500 |
Xb = frameComplexity; |
501 |
break; |
502 |
} |
503 |
|
504 |
|
505 |
/* Print Frame info */ |
506 |
strPtr = Frame_trailer1; |
507 |
DBG_PRINT(("%s\n",strPtr)); |
508 |
strPtr = Frame_trailer2; |
509 |
DBG_PRINT(("%s\n",strPtr)); |
510 |
strPtr = Frame_trailer3; |
511 |
DBG_PRINT(("%s\n",strPtr)); |
512 |
|
513 |
sprintf(rc_buffer, "%6d %2.2f %6d %3d %2.2f %7d %3d %7d %3d %6d %6d", |
514 |
totalBits, avgQuant, frameComplexity, avg_act, N_act, currentVirtBuf, pctAllocUsed, rc_R, pctGOPUsed, VBV_buffer, VBV_delay); |
515 |
#ifdef RC_STATS_FILE |
516 |
fprintf(RC_FILE,"%s\n", rc_buffer); |
517 |
fflush(RC_FILE); |
518 |
#endif |
519 |
DBG_PRINT(("%s\n",rc_buffer)); |
520 |
|
521 |
Nx--; |
522 |
rc_totalMBBits= rc_bitsThisMB= rc_totalFrameBits=rc_totalOverheadBits = 0; |
523 |
rc_numBlocks = rc_totalQuant = total_act_j = currentVirtBuf = 0; |
524 |
|
525 |
DBG_PRINT(("GOP now has %d bits remaining (%3d%%) for %d frames .. , Ni= %d, Np= %d, Nb= %d\n", rc_R, (rc_R*100/rc_G), (Ni+Np+Nb), Ni, Np, Nb)); |
526 |
|
527 |
} |
528 |
|
529 |
|
530 |
/*===========================================================================* |
531 |
* |
532 |
* MB_RateOut |
533 |
* |
534 |
* Prints out sampling of MB rate control data. Every "nth" block |
535 |
* stats are printed, with "n" controled by global RC_MB_SAMPLE_RATE |
536 |
* (NB. "skipped" blocks do not go through this function and thus do not |
537 |
* show up in the sample ) |
538 |
* |
539 |
* RETURNS: nothing |
540 |
* |
541 |
* SIDE EFFECTS: none |
542 |
* |
543 |
* NOTES: |
544 |
* |
545 |
*===========================================================================*/ |
546 |
void |
547 |
MB_RateOut(type) |
548 |
int type; |
549 |
{ |
550 |
int totalBits; |
551 |
int pctUsed, pctDone; |
552 |
int bitsThisMB; |
553 |
int bitsPerMB; |
554 |
|
555 |
bitsThisMB = rc_bitsThisMB; |
556 |
totalBits = rc_totalFrameBits; |
557 |
bitsPerMB = (totalBits / rc_numBlocks); |
558 |
pctDone = (rc_numBlocks * 100/ MB_cnt); |
559 |
pctUsed = (totalBits *100/current_Tx); |
560 |
|
561 |
sprintf(rc_buffer, "%3d %5d %2d %3d %6d %3d %6d %2.2f %6d %4d %3d %3d\n", |
562 |
(rc_numBlocks - 1), bitsThisMB, Qscale, mquant, currentVirtBuf, |
563 |
rc_Q, act_j, N_act, totalBits, bitsPerMB, pctUsed, pctDone); |
564 |
#ifdef RC_STATS_FILE |
565 |
fprintf(RC_FILE, "%s", rc_buffer); |
566 |
fflush(RC_FILE); |
567 |
#endif |
568 |
|
569 |
if ( (RC_MB_SAMPLE_RATE) && ((rc_numBlocks -1) % RC_MB_SAMPLE_RATE)) { |
570 |
DBG_PRINT(("%s\n", rc_buffer)); |
571 |
} else { |
572 |
return; |
573 |
} |
574 |
} |
575 |
|
576 |
|
577 |
|
578 |
/*===========================================================================* |
579 |
* |
580 |
* incNumBlocks() |
581 |
* |
582 |
* |
583 |
* RETURNS: nothing |
584 |
* |
585 |
* SIDE EFFECTS: rc_numBlocks |
586 |
* |
587 |
* NOTES: |
588 |
* |
589 |
*===========================================================================*/ |
590 |
void incNumBlocks(num) |
591 |
int num; |
592 |
{ |
593 |
rc_numBlocks += num; |
594 |
} |
595 |
|
596 |
|
597 |
/*===========================================================================* |
598 |
* |
599 |
* incMacroBlockBits() |
600 |
* |
601 |
* Increments the number of Macro Block bits and the total of Frame |
602 |
* bits by the number passed. |
603 |
* |
604 |
* RETURNS: nothing |
605 |
* |
606 |
* SIDE EFFECTS: rc_totalMBBits |
607 |
* |
608 |
* NOTES: |
609 |
* |
610 |
*===========================================================================*/ |
611 |
void incMacroBlockBits(num) |
612 |
int num; |
613 |
{ |
614 |
rc_bitsThisMB = num; |
615 |
rc_totalMBBits += num; |
616 |
rc_totalFrameBits += num; |
617 |
} |
618 |
|
619 |
|
620 |
/*===========================================================================* |
621 |
* |
622 |
* needQScaleChange(current Q scale, 4 luminance blocks) |
623 |
* |
624 |
* |
625 |
* RETURNS: new Qscale |
626 |
* |
627 |
* SIDE EFFECTS: |
628 |
* |
629 |
*===========================================================================*/ |
630 |
int needQScaleChange(oldQScale, blk0, blk1, blk2, blk3) |
631 |
int oldQScale; |
632 |
Block blk0; |
633 |
Block blk1; |
634 |
Block blk2; |
635 |
Block blk3; |
636 |
{ |
637 |
|
638 |
/* One more MacroBlock seen */ |
639 |
rc_numBlocks++; /* this notes each block num in MB */ |
640 |
|
641 |
checkBufferFullness(oldQScale); |
642 |
|
643 |
checkSpatialActivity(blk0, blk1, blk2, blk3); |
644 |
|
645 |
mquant = rc_Q * N_act; |
646 |
Qscale = (mquant > 31 ? 31 : mquant); |
647 |
Qscale = (Qscale < 1 ? 1 : Qscale); |
648 |
rc_totalQuant += Qscale; |
649 |
|
650 |
if (oldQScale == Qscale) |
651 |
return -1; |
652 |
else |
653 |
return Qscale; |
654 |
} |
655 |
|
656 |
|
657 |
/*===========================================================================* |
658 |
* |
659 |
* determineMBCount() |
660 |
* |
661 |
* Determines number of Macro Blocks in frame from the frame sizes |
662 |
* passed. |
663 |
* |
664 |
* RETURNS: nothing |
665 |
* |
666 |
* SIDE EFFECTS: sets the count passed |
667 |
* |
668 |
*===========================================================================*/ |
669 |
int |
670 |
determineMBCount () |
671 |
{ |
672 |
int y,x; |
673 |
|
674 |
x = (Fsize_x +15)/16; |
675 |
y = (Fsize_y +15)/16; |
676 |
return (x * y); |
677 |
} |
678 |
|
679 |
|
680 |
|
681 |
/*===========================================================================* |
682 |
* |
683 |
* void checkBufferFullness () |
684 |
* |
685 |
* Calculates the fullness of the virtual buffer for each |
686 |
* frame type. Called before encoding each macro block. Along |
687 |
* with the normalisec spatial activity measure (N_act), it |
688 |
* determine the quantization factor for the next macroblock. |
689 |
* |
690 |
* RETURNS: nothing |
691 |
* |
692 |
* SIDE EFFECTS: the "currentVirtBuf" variable |
693 |
* |
694 |
* NOTES: |
695 |
* |
696 |
*===========================================================================*/ |
697 |
void checkBufferFullness (oldQScale) |
698 |
int oldQScale; |
699 |
{ |
700 |
int temp; |
701 |
|
702 |
temp = lastFrameVirtBuf + rc_totalFrameBits; |
703 |
temp -= (current_Tx * rc_numBlocks / MB_cnt); |
704 |
currentVirtBuf = temp; |
705 |
|
706 |
rc_Q = (currentVirtBuf * 31 / reactionParameter); |
707 |
return; |
708 |
} |
709 |
|
710 |
|
711 |
/*===========================================================================* |
712 |
* |
713 |
* void checkSpatialActivity() |
714 |
* |
715 |
* Calcualtes the spatial activity for the four luminance blocks of the |
716 |
* macroblock. Along with the normalised reference quantization parameter |
717 |
* (rc_Q) , it determines the quantization factor for the next macroblock. |
718 |
* |
719 |
* RETURNS: nothing |
720 |
* |
721 |
* SIDE EFFECTS: the Adaptive quantization variables- act_j, N_act. |
722 |
* |
723 |
* NOTES: |
724 |
* |
725 |
*===========================================================================*/ |
726 |
void checkSpatialActivity(blk0, blk1, blk2, blk3) |
727 |
Block blk0; |
728 |
Block blk1; |
729 |
Block blk2; |
730 |
Block blk3; |
731 |
{ |
732 |
int temp; |
733 |
int16 *blkArray[4]; |
734 |
int16 *curBlock; |
735 |
int16 *blk_ptr; |
736 |
int var[4]; |
737 |
int i, j; |
738 |
|
739 |
|
740 |
blkArray[0] = (int16 *) blk0; |
741 |
blkArray[1] = (int16 *) blk1; |
742 |
blkArray[2] = (int16 *) blk2; |
743 |
blkArray[3] = (int16 *) blk3; |
744 |
|
745 |
|
746 |
for (i =0; i < 4; i++) { /* Compute the activity in each block */ |
747 |
curBlock = blkArray[i]; |
748 |
blk_ptr = curBlock; |
749 |
P_mean = 0; |
750 |
/* Find the mean pixel value */ |
751 |
for (j=0; j < DCTSIZE_SQ; j ++) { |
752 |
P_mean += *(blk_ptr++); |
753 |
/* P_mean += curBlock[j]; |
754 |
if (curBlock[j] != *(blk_ptr++)) { |
755 |
printf("\n\tARRAY ERROR: block %d\n", j); |
756 |
} |
757 |
*/ |
758 |
} |
759 |
P_mean /= DCTSIZE_SQ; |
760 |
|
761 |
/* Now find the variance */ |
762 |
curBlock = blkArray[i]; |
763 |
blk_ptr = curBlock; |
764 |
var[i] = 0; |
765 |
for (j=0; j < DCTSIZE_SQ; j++) { |
766 |
#ifdef notdef |
767 |
if (curBlock[j] != *(blk_ptr++)) { |
768 |
printf("\n\tARRAY ERROR: block %d\n", j); |
769 |
} |
770 |
temp = curBlock[j] - P_mean; |
771 |
#endif |
772 |
temp = *(blk_ptr++) - P_mean; |
773 |
var[i] += (temp * temp); |
774 |
} |
775 |
var[i] /= DCTSIZE_SQ; |
776 |
} |
777 |
|
778 |
/* Choose the minimum variance from the 4 blocks and use as the activity */ |
779 |
var_sblk = var[0]; |
780 |
for (i=1; i < 4; i++) { |
781 |
var_sblk = (var_sblk < var[i] ? var_sblk : var[i]); |
782 |
} |
783 |
|
784 |
|
785 |
act_j = 1 + var_sblk; |
786 |
total_act_j += act_j; |
787 |
temp = (2 * act_j + avg_act); |
788 |
N_act = ( (float) temp / (float) (act_j + 2*avg_act) ); |
789 |
|
790 |
return; |
791 |
} |
792 |
|
793 |
|
794 |
|
795 |
|
796 |
/*============================================================================* |
797 |
* |
798 |
* getRateMode () |
799 |
* |
800 |
* Returns the rate mode- interpreted as either Fixed or Variable |
801 |
* |
802 |
* RETURNS: integer |
803 |
* |
804 |
* SIDE EFFECTS: none |
805 |
* |
806 |
* |
807 |
*==========================================================================*/ |
808 |
int getRateMode() |
809 |
{ |
810 |
return RateControlMode; |
811 |
} |
812 |
|
813 |
|
814 |
/*===========================================================================* |
815 |
* |
816 |
* setBitRate () |
817 |
* |
818 |
* Checks the string parsed from the parameter file. Verifies |
819 |
* number and sets global values. MPEG standard specifies that bit rate |
820 |
* be rounded up to nearest 400 bits/sec. |
821 |
* |
822 |
* RETURNS: nothing |
823 |
* |
824 |
* SIDE EFFECTS: global variables |
825 |
* |
826 |
* NOTES: Should this be in the 400-bit units used in sequence header? |
827 |
* |
828 |
*===========================================================================*/ |
829 |
void setBitRate (charPtr) |
830 |
char * charPtr; |
831 |
{ |
832 |
int rate, rnd; |
833 |
|
834 |
rate = atoi(charPtr); |
835 |
if (rate > 0) { |
836 |
RateControlMode = FIXED_RATE; |
837 |
} else { |
838 |
printf("Parameter File Error: invalid BIT_RATE: \"%s\", defaults to Variable ratemode\n", |
839 |
charPtr); |
840 |
RateControlMode = VARIABLE_RATE; |
841 |
bit_rate = -1; |
842 |
} |
843 |
rnd = (rate % 400); |
844 |
rate += (rnd ? 400 -rnd : 0); /* round UP to nearest 400 bps */ |
845 |
rate = (rate > MAX_BIT_RATE ? MAX_BIT_RATE : rate); |
846 |
bit_rate = rate; |
847 |
DBG_PRINT(("Bit rate is: %d\n", bit_rate)); |
848 |
} |
849 |
|
850 |
|
851 |
|
852 |
/*===========================================================================* |
853 |
* |
854 |
* getBitRate () |
855 |
* |
856 |
* Returns the bit rate read from the parameter file. This is the |
857 |
* real rate in bits per second, not in 400 bit units as is written to |
858 |
* the sequence header. |
859 |
* |
860 |
* RETURNS: int (-1 if Variable mode operation) |
861 |
* |
862 |
* SIDE EFFECTS: none |
863 |
* |
864 |
*===========================================================================*/ |
865 |
int getBitRate () |
866 |
{ |
867 |
return bit_rate; |
868 |
} |
869 |
|
870 |
|
871 |
|
872 |
|
873 |
/*===========================================================================* |
874 |
* |
875 |
* setBufferSize () |
876 |
* |
877 |
* Checks the string parsed from the parameter file. Verifies |
878 |
* number and sets global values. |
879 |
* |
880 |
* RETURNS: nothing |
881 |
* |
882 |
* SIDE EFFECTS: buffer_size global variable. |
883 |
* |
884 |
* NOTES: The global is in bits, NOT the 16kb units used in sequence header |
885 |
* |
886 |
*===========================================================================*/ |
887 |
void setBufferSize (charPtr) |
888 |
char * charPtr; |
889 |
{ |
890 |
int size; |
891 |
|
892 |
size = atoi(charPtr); |
893 |
size = (size > MAX_BUFFER_SIZE ? MAX_BUFFER_SIZE : size); |
894 |
if (size > 0) { |
895 |
size = (16*1024) * ((size + (16*1024 - 1)) / (16*1024)); |
896 |
buffer_size = size; |
897 |
} else { |
898 |
buffer_size = DEFAULT_BUFFER_SIZE; |
899 |
printf("Parameter File Error: invalid BUFFER_SIZE: \"%s\", defaults to : %d\n", |
900 |
charPtr, buffer_size); |
901 |
} |
902 |
DBG_PRINT(("Buffer size is: %d\n", buffer_size)); |
903 |
} |
904 |
|
905 |
|
906 |
/*===========================================================================* |
907 |
* |
908 |
* getBufferSize () |
909 |
* |
910 |
* returns the buffer size read from the parameter file. Size is |
911 |
* in bits- not in units of 16k as written to the sequence header. |
912 |
* |
913 |
* RETURNS: int (or -1 if invalid) |
914 |
* |
915 |
* SIDE EFFECTS: none |
916 |
* |
917 |
*===========================================================================*/ |
918 |
int getBufferSize () |
919 |
{ |
920 |
return buffer_size; |
921 |
} |
922 |
|
923 |
|
924 |
/*===========================================================================* |
925 |
* |
926 |
* updateVBVBuffer () |
927 |
* |
928 |
* Update the VBV buffer after each frame. This theoretical |
929 |
* buffer is being filled at constant rate, given by the bit rate. |
930 |
* It is emptied as each frame is grabbed by the decoder. Exception |
931 |
* is that the deocder will wait until the "delay" is over. |
932 |
* |
933 |
* RETURNS: nothing |
934 |
* |
935 |
* SIDE EFFECTS: VBV_buffer |
936 |
* |
937 |
* NOTES: |
938 |
* |
939 |
*===========================================================================*/ |
940 |
void updateVBVBuffer (frameBits) |
941 |
int frameBits; |
942 |
{ |
943 |
if (VBV_delay) { |
944 |
VBV_delay -= frameDelayIncrement; |
945 |
if (VBV_delay < 0) { |
946 |
VBV_delay = 0; |
947 |
} |
948 |
|
949 |
} else { |
950 |
VBV_buffer -= frameBits; |
951 |
} |
952 |
VBV_buffer += bufferFillRate; |
953 |
if (VBV_buffer < 0) { |
954 |
fprintf(stderr, "\tWARNING - VBV buffer underflow (%d)\n", VBV_buffer); |
955 |
} |
956 |
if (VBV_buffer > buffer_size) { |
957 |
fprintf(stderr, "WARNING - VBV buffer overflow (%d > %d)\n", |
958 |
VBV_buffer, buffer_size); |
959 |
} |
960 |
} |