r955: Fix the Diffkey icon.
[cinelerra_cv.git] / quicktime / encore50 / text_code.c
blobc6db0901670cd4bce7359befcc3c3ec7471bae56
2 /**************************************************************************
3 * *
4 * This code is developed by Adam Li. This software is an *
5 * implementation of a part of one or more MPEG-4 Video tools as *
6 * specified in ISO/IEC 14496-2 standard. Those intending to use this *
7 * software module in hardware or software products are advised that its *
8 * use may infringe existing patents or copyrights, and any such use *
9 * would be at such party's own risk. The original developer of this *
10 * software module and his/her company, and subsequent editors and their *
11 * companies (including Project Mayo), will have no liability for use of *
12 * this software or modifications or derivatives thereof. *
13 * *
14 * Project Mayo gives users of the Codec a license to this software *
15 * module or modifications thereof for use in hardware or software *
16 * products claiming conformance to the MPEG-4 Video Standard as *
17 * described in the Open DivX license. *
18 * *
19 * The complete Open DivX license can be found at *
20 * http://www.projectmayo.com/opendivx/license.php . *
21 * *
22 **************************************************************************/
24 /**************************************************************************
26 * text_code.c
28 * Copyright (C) 2001 Project Mayo
30 * Adam Li
32 * DivX Advance Research Center <darc@projectmayo.com>
34 **************************************************************************/
36 /* This file contains some functions for text coding of image. */
37 /* Some codes of this project come from MoMuSys MPEG-4 implementation. */
38 /* Please see seperate acknowledgement file for a list of contributors. */
40 #include "text_defs.h"
41 #include "mot_code.h"
42 #include "bitstream.h"
43 #include "putvlc.h"
44 #include "mot_util.h"
45 #include "text_code_mb.h"
46 #include "text_code.h"
48 #define SKIPP 6
50 extern FILE *ftrace;
52 Void Bits_CountMB_combined ( Int DQUANT,
53 Int Mode,
54 Int COD,
55 Int ACpred_flag,
56 Int CBP,
57 Int vop_type,
58 Bits *bits,
59 Image *mottext_bitstream,
60 Int *MB_transp_pattern
62 Int doDCACpred ( Int *qcoeff,
63 Int *CBP,
64 Int ncoeffs,
65 Int x_pos,
66 Int y_pos,
67 Int ***DC_store,
68 Int QP,
69 Int MB_width,
70 Int direction[],
71 Int mid_grey
73 Void nullfill(Int pred[], Int mid_grey);
74 Int Idir_c(Int val, Int QP);
75 Int IntraDCSwitch_Decision _P_(( Int Mode,
76 Int intra_dc_vlc_thr,
77 Int Qp
78 ));
79 Int FindCBP _P_(( Int *qcoeff,
80 Int Mode,
81 Int ncoeffs
82 ));
85 /***********************************************************CommentBegin******
87 * -- VopCodeShapeTextIntraCom --Intra texture encoding of one vop,
88 * Combined shape/(motion)/texture mode
90 * Purpose :
91 * Intra texture encoding of one vop (combined shape/(mot)/text mode)
93 * Arguments in :
94 * Vop curr : the current vop to be coded
95 * Int intra_dcpred_disable : disable intradc prediction
96 * Image* AB_SizeConversionDecisions:
97 * Image* AB_first_MMR_values
98 * VolConfig *vol_config : configuration information
99 * Int rc_type : rate control type:
101 * Arguments out :
102 * Vop *rec_curr : the reconstructed current vop
103 * Image *texture_bitstream : the output bitstream
104 * Bits : statistics information
106 * Description :
107 * This function performs Intra texture encoding of one vop.
109 ***********************************************************CommentEnd********/
111 Void VopCodeShapeTextIntraCom(Vop *curr,
112 Vop *rec_curr, Image *mottext_bitstream)
114 Int QP = GetVopIntraQuantizer(curr);
115 Int Mode = MODE_INTRA;
116 Int* qcoeff;
117 Int i, j;
118 Int CBP, COD;
119 Int CBPY, CBPC;
120 Int num_pixels = GetImageSizeX(GetVopY(curr));
121 Int num_lines = GetImageSizeY(GetVopY(curr));
122 Int vop_type;
123 Int ***DC_store;
124 Int MB_width = num_pixels / MB_SIZE;
125 Int MB_height = num_lines / MB_SIZE;
126 Int m;
127 Int ACpred_flag=-1;
128 Int direction[6];
129 Int switched=0;
130 Int DQUANT =0;
132 Bits nbits, *bits;
133 bits = &nbits;
135 qcoeff = (Int *) malloc (sizeof (Int) * 384);
137 #ifdef _RC_DEBUG_
138 fprintf(ftrace, "RC - VopCodeShapeTextIntraCom(): ---> CODING WITH: %d \n",QP);
139 #endif
141 for (i = 0; i < 6; i++)
142 direction[i] = 0;
144 /* allocate space for 3D matrix to keep track of prediction values
145 for DC/AC prediction */
147 DC_store = (Int ***)calloc(MB_width*MB_height, sizeof(Int **));
148 for (i = 0; i < MB_width*MB_height; i++)
150 DC_store[i] = (Int **)calloc(6, sizeof(Int *));
151 for (j = 0; j < 6; j++)
152 DC_store[i][j] = (Int *)calloc(15, sizeof(Int));
155 Bits_Reset (bits);
156 vop_type = PCT_INTRA;
158 for (j = 0; j < num_lines/MB_SIZE; j++) /* Macro Block loop */
160 for (i = 0; i < num_pixels/MB_SIZE; i++)
162 DQUANT = 0;
164 COD = 0;
165 bits->no_intra++;
167 CodeMB (curr, rec_curr, NULL, i*MB_SIZE, j*MB_SIZE,
168 num_pixels, QP+DQUANT, MODE_INTRA, qcoeff);
170 m =0;
172 DC_store[j*MB_width+i][0][m] = qcoeff[m]*cal_dc_scaler(QP+DQUANT,1);
173 DC_store[j*MB_width+i][1][m] = qcoeff[m+64]*cal_dc_scaler(QP+DQUANT,1);
174 DC_store[j*MB_width+i][2][m] = qcoeff[m+128]*cal_dc_scaler(QP+DQUANT,1);
175 DC_store[j*MB_width+i][3][m] = qcoeff[m+192]*cal_dc_scaler(QP+DQUANT,1);
176 DC_store[j*MB_width+i][4][m] = qcoeff[m+256]*cal_dc_scaler(QP+DQUANT,2);
177 DC_store[j*MB_width+i][5][m] = qcoeff[m+320]*cal_dc_scaler(QP+DQUANT,2);
179 for (m = 1; m < 8; m++)
181 DC_store[j*MB_width+i][0][m] = qcoeff[m];
182 DC_store[j*MB_width+i][1][m] = qcoeff[m+64];
183 DC_store[j*MB_width+i][2][m] = qcoeff[m+128];
184 DC_store[j*MB_width+i][3][m] = qcoeff[m+192];
185 DC_store[j*MB_width+i][4][m] = qcoeff[m+256];
186 DC_store[j*MB_width+i][5][m] = qcoeff[m+320];
188 for (m = 0; m < 7; m++)
190 DC_store[j*MB_width+i][0][m+8] = qcoeff[(m+1)*8];
191 DC_store[j*MB_width+i][1][m+8] = qcoeff[(m+1)*8+64];
192 DC_store[j*MB_width+i][2][m+8] = qcoeff[(m+1)*8+128];
193 DC_store[j*MB_width+i][3][m+8] = qcoeff[(m+1)*8+192];
194 DC_store[j*MB_width+i][4][m+8] = qcoeff[(m+1)*8+256];
195 DC_store[j*MB_width+i][5][m+8] = qcoeff[(m+1)*8+320];
198 CBP = FindCBP(qcoeff,Mode,64);
200 /* Do the DC/AC prediction, changing the qcoeff values as
201 appropriate */
202 if (GetVopIntraACDCPredDisable(curr) == 0)
204 ACpred_flag = doDCACpred(qcoeff, &CBP, 64, i, j, DC_store,
205 QP+DQUANT, MB_width,
206 direction,GetVopMidGrey(curr));
208 else
209 ACpred_flag = -1;
211 switched = IntraDCSwitch_Decision(Mode,
212 GetVopIntraDCVlcThr(curr),
213 QP);
214 if (switched)
215 CBP = FindCBP(qcoeff,MODE_INTER,64);
216 if (DQUANT) Mode=MODE_INTRA_Q;else Mode=MODE_INTRA;
218 QP+=DQUANT;
220 CBPY = CBP >> 2;
221 CBPY = CBPY & 15; /* last 4 bits */
222 CBPC = CBP & 3; /* last 2 bits */
224 Bits_CountMB_combined (DQUANT, Mode, COD, ACpred_flag, CBP,
225 vop_type,
226 bits, mottext_bitstream,/*MB_transp_pattern*/NULL);
228 /* added the variable intra_dcpred_diable */
229 MB_CodeCoeff(bits, qcoeff, Mode, CBP, 64,
230 GetVopIntraACDCPredDisable(curr),
231 NULL, mottext_bitstream,
232 /*MB_transp_pattern*/NULL, direction,
233 1 /*GetVopErrorResDisable(curr)*/,
234 0 /*GetVopReverseVlc(curr)*/,
235 switched,
236 0 /*curr->alternate_scan*/);
240 /* Free allocated memory for 3D matrix */
241 for (i = 0; i < MB_width*MB_height; i++)
243 for (j = 0; j < 6; j++)
244 free(DC_store[i][j]);
245 free(DC_store[i]);
247 free(DC_store);
249 free ((Char*)qcoeff);
252 /***********************************************************CommentBegin******
254 * -- VopShapeMotText -- Combined Inter encoding of shape motion and texture
256 * Purpose :
257 * Combined Inter encoding of texture and motion.
258 * Used by VopCodeMotTextInter
260 * Arguments in :
261 * Vop *curr : the current vop to be encoded
262 * Vop *rec_prev: the previous reconstructed vop
263 * Image *mot_x : the x-coordinates of the motion vectors
264 * Image *mot_y : the y-coordinates of the motion vectors
265 * Image *MB_decisions: Contains for each macroblock the encoding mode
266 * Int f_code_for: MV search range 1/2 pel: 1=32,2=64,...,7=2048
267 * Image* AB_SizeConversionDecisions:
268 * Image* AB_first_MMR_values :
269 * Int intra_dcpred_disable : disable the intra dc prediction
270 * VolConfig *vol_config : configuration information
271 * Int rc_type : rate control type
273 * Arguments out :
274 * Vop *rec_curr : the reconstructed current vop
275 * Image *mottext_bitstream : the output texture/motion bitstream
276 * Bits *bits : Coding statistics
278 ***********************************************************CommentEnd********/
280 Void VopShapeMotText (Vop *curr, Vop *comp,
281 Image *MB_decisions, Image *mot_x, Image *mot_y,
282 Int f_code_for,
283 Int intra_acdc_pred_disable,
284 Vop *rec_curr,
285 Image *mottext_bitstream
288 Int Mode=0;
289 Int QP = GetVopQuantizer(curr);
290 Int* qcoeff=NULL;
291 Int i, j;
292 Int CBP;
293 Int COD;
294 Int CBPY, CBPC;
295 Int MB_in_width, MB_in_height, B_in_width, mbnum, boff;
296 SInt p;
297 SInt *ptr=NULL;
298 Float *motx_ptr=NULL, *moty_ptr=NULL;
299 Int num_pixels;
300 Int num_lines;
301 Int vop_type=PCT_INTER;
302 Int ***DC_store=NULL;
303 Int m, n;
304 Int ACpred_flag=-1;
305 Int direction[6];
306 Int switched=0;
307 Int DQUANT=0;
309 Bits nbits, *bits;
310 bits = &nbits;
312 qcoeff = (Int *) malloc (sizeof (Int) * 384);
314 num_pixels = GetImageSizeX(GetVopY(curr));
315 num_lines = GetImageSizeY(GetVopY(curr));
316 MB_in_width = num_pixels / MB_SIZE;
317 MB_in_height = num_lines / MB_SIZE;
318 B_in_width = 2 * MB_in_width;
320 for (i = 0; i < 6; i++) direction[i] = 0;
322 #ifdef _RC_DEBUG_
323 printf("RC - VopShapeMotText(): ---> CODING WITH: %d \n",QP);
324 #endif
326 /* allocate space for 3D matrix to keep track of prediction values
327 for DC/AC prediction */
328 DC_store = (Int ***)calloc(MB_in_width*MB_in_height,
329 sizeof(Int **));
330 for (i = 0; i < MB_in_width*MB_in_height; i++)
332 DC_store[i] = (Int **)calloc(6, sizeof(Int *));
333 for (j = 0; j < 6; j++)
334 DC_store[i][j] = (Int *)calloc(15, sizeof(Int));
337 Bits_Reset (bits);
339 vop_type = PCT_INTER;
341 ptr = (SInt *) GetImageData(MB_decisions);
342 motx_ptr = (Float *) GetImageData(mot_x);
343 moty_ptr = (Float *) GetImageData(mot_y);
345 for (j = 0; j < num_lines/MB_SIZE; j++)
347 for (i = 0; i < MB_in_width; i++)
349 switched=0;
350 p = *ptr;
351 DQUANT = 0;
353 /* Fill DC_store with default coeff values */
354 for (m = 0; m < 6; m++)
356 DC_store[j*MB_in_width+i][m][0] = GetVopMidGrey(curr)*8;
357 for (n = 1; n < 15; n++)
358 DC_store[j*MB_in_width+i][m][n] = 0;
361 switch (p)
364 case MBM_INTRA:
365 Mode = (DQUANT == 0) ? MODE_INTRA : MODE_INTRA_Q;
366 bits->no_intra++;
367 break;
369 case MBM_INTER16:
370 Mode = (DQUANT == 0) ? MODE_INTER : MODE_INTER_Q;
371 bits->no_inter++;
372 break;
374 case MBM_INTER8:
375 Mode = MODE_INTER4V;
376 bits->no_inter4v++;
377 DQUANT = 0; /* Can't change QP for 8x8 mode */
378 break;
380 default:
381 printf("invalid MB_decision value :%d\n", p);
382 exit(0);
385 CodeMB (curr, rec_curr, comp, i*MB_SIZE, j*MB_SIZE,
386 num_pixels, QP + DQUANT, Mode, qcoeff);
388 mbnum = j*MB_in_width + i;
389 boff = (2 * (mbnum / MB_in_width) * B_in_width
390 + 2 * (mbnum % MB_in_width));
392 CBP = FindCBP(qcoeff,Mode,64);
394 if ((CBP == 0) && (p == 1) && (*(motx_ptr +boff) == 0.0)
395 && (*(moty_ptr +boff) == 0.0))
397 COD = 1; /* skipped macroblock */
398 BitstreamPutBits(mottext_bitstream, (long) (COD), 1L);
399 bits->COD ++;
401 *ptr = SKIPP;
402 Mode = MODE_INTER;
404 else
406 COD = 0; /* coded macroblock */
408 if ((Mode == MODE_INTRA) || (Mode == MODE_INTRA_Q))
411 /* Store the qcoeff-values needed later for prediction */
412 m =0;
414 DC_store[j*MB_in_width+i][0][m] = qcoeff[m]*cal_dc_scaler(QP+DQUANT,1);
415 DC_store[j*MB_in_width+i][1][m] = qcoeff[m+64]*cal_dc_scaler(QP+DQUANT,1);
416 DC_store[j*MB_in_width+i][2][m] = qcoeff[m+128]*cal_dc_scaler(QP+DQUANT,1);
417 DC_store[j*MB_in_width+i][3][m] = qcoeff[m+192]*cal_dc_scaler(QP+DQUANT,1);
418 DC_store[j*MB_in_width+i][4][m] = qcoeff[m+256]*cal_dc_scaler(QP+DQUANT,2);
419 DC_store[j*MB_in_width+i][5][m] = qcoeff[m+320]*cal_dc_scaler(QP+DQUANT,2);
421 for (m = 1; m < 8; m++)
423 DC_store[j*MB_in_width+i][0][m] = qcoeff[m];
424 DC_store[j*MB_in_width+i][1][m] = qcoeff[m+64];
425 DC_store[j*MB_in_width+i][2][m] = qcoeff[m+128];
426 DC_store[j*MB_in_width+i][3][m] = qcoeff[m+192];
427 DC_store[j*MB_in_width+i][4][m] = qcoeff[m+256];
428 DC_store[j*MB_in_width+i][5][m] = qcoeff[m+320];
430 for (m = 0; m < 7; m++)
432 DC_store[j*MB_in_width+i][0][m+8] = qcoeff[(m+1)*8];
433 DC_store[j*MB_in_width+i][1][m+8] = qcoeff[(m+1)*8+64];
434 DC_store[j*MB_in_width+i][2][m+8] = qcoeff[(m+1)*8+128];
435 DC_store[j*MB_in_width+i][3][m+8] = qcoeff[(m+1)*8+192];
436 DC_store[j*MB_in_width+i][4][m+8] = qcoeff[(m+1)*8+256];
437 DC_store[j*MB_in_width+i][5][m+8] = qcoeff[(m+1)*8+320];
440 if (intra_acdc_pred_disable == 0)
441 ACpred_flag = doDCACpred(qcoeff, &CBP, 64, i, j,
442 DC_store,
443 QP+DQUANT, MB_in_width,
444 direction,GetVopMidGrey(curr));
445 else
446 ACpred_flag = -1; /* Not to go into bitstream */
449 switched = IntraDCSwitch_Decision(Mode,
450 GetVopIntraDCVlcThr(curr),
451 QP);
452 if (switched)
453 CBP = FindCBP(qcoeff,MODE_INTER,64);
455 CBPY = CBP >> 2;
456 CBPY = CBPY & 15; /* last 4 bits */
457 CBPC = CBP & 3; /* last 2 bits */
459 Bits_CountMB_combined (DQUANT, Mode, COD, ACpred_flag, CBP,
460 vop_type, bits,
461 mottext_bitstream,/*MB_transp_pattern*/NULL);
463 Bits_CountMB_Motion( mot_x, mot_y, NULL,
464 MB_decisions, i, j, f_code_for, 0 /*quarter_pel*/,
465 mottext_bitstream,
466 1 /*GetVopErrorResDisable(curr)*/, 0,
467 (Int **)NULL, 0 /*GetVopShape(curr)*/);
469 MB_CodeCoeff(bits, qcoeff, Mode, CBP, 64,
470 intra_acdc_pred_disable,
471 NULL, mottext_bitstream,
472 /*MB_transp_pattern*/NULL, direction,
473 1/*GetVopErrorResDisable(curr)*/,
474 0/*GetVopReverseVlc(curr)*/,
475 switched,
476 0 /*curr->alternate_scan*/);
479 ptr++;
481 } /* for i loop */
482 } /* for j loop */
484 /* Free allocated memory for 3D matrix */
485 for (i = 0; i < MB_in_width*MB_in_height; i++)
488 for (j = 0; j < 6; j++)
489 free(DC_store[i][j]);
490 free(DC_store[i]);
492 free(DC_store);
494 free ((Char*)qcoeff);
498 /***********************************************************CommentBegin******
500 * -- Bits_CountMB_combined -- texture encoding for combined texture/motion
502 * Purpose :
503 * Used for texture encoding in case of combined texture/motion
504 * encoding. This function encodes the :
505 * - COD flag
506 * - MCBPC flag
507 * - CBPY flag
508 * - CBPC flag
509 * - DQUANT information
511 * Arguments in :
512 * SInt Mode : The macroblock encoding mode
513 * Int CBP : Coded block pattern information
514 * Int COD : Indicates whether this macroblock is coded or not
515 * Int ACpred_flag
516 * Int vop_type : indicates the picture coding type
517 * (Intra,Inter)
519 * Arguments out :
520 * Bits* bits : a structure counting the number of bits
521 * Image *bitstream : output texture bit stream *
523 ***********************************************************CommentEnd********/
525 Void Bits_CountMB_combined(Int DQUANT, Int Mode, Int COD, Int ACpred_flag,
526 Int CBP, Int vop_type,
527 Bits* bits, Image *mottext_bitstream,Int *MB_transp_pattern)
529 Int cbpy ,cbpc, length;
530 Int MBtype=-1;
532 if ( Mode == MODE_INTRA ) MBtype = 3;
533 if ( Mode == MODE_INTER ) MBtype = 0;
534 if ( Mode == MODE_INTRA_Q) MBtype = 4;
535 if ( Mode == MODE_INTER_Q) MBtype = 1;
536 if ( Mode == MODE_INTER4V) MBtype = 2;
538 /* modified by NTT for GMC coding : start
539 if ( Mode == MODE_DYN_SP) MBtype = 0;
540 if ( Mode == MODE_DYN_SP_Q) MBtype = 1;
542 if ( Mode == MODE_GMC) MBtype = 0;
543 if ( Mode == MODE_GMC_Q) MBtype = 1;
544 /* modified by NTT for GMC coding : end */
546 #ifdef D_TRACE
547 fprintf(ftrace, "DQUANT : %d\tMODE : %d\tVop Type : %d\n", DQUANT, Mode, vop_type);
548 fprintf(ftrace, "COD : %d\tCBP : %d\tAC Pred Flag : %d\n\n", COD, CBP, ACpred_flag);
549 #endif
551 cbpc = CBP & 3;
552 cbpy = CBP>>2;
554 /* COD */
556 if (vop_type != PCT_INTRA )
558 if (COD)
560 printf("COD = 1 in Bits_CountMB_combined \n");
561 printf("This function should not be used if COD is '1' \n");
562 exit(1);
565 /* write COD */
566 BitstreamPutBits(mottext_bitstream, (long)(COD), 1L);
567 bits->COD++;
570 /* MCBPC */
572 if (vop_type == PCT_INTRA)
573 length = PutMCBPC_Intra (cbpc, MBtype, mottext_bitstream);
574 else
575 length = PutMCBPC_Inter (cbpc, MBtype, mottext_bitstream);
577 bits->MCBPC += length;
579 /* MCSEL syntax */
580 /* modified by NTT for GMC coding : start
581 if (((Mode == MODE_INTER) || (Mode == MODE_INTER_Q) || (Mode == MODE_DYN_SP) || (Mode == MODE_DYN_SP_Q)) && (vop_type == PCT_SPRITE))
583 if (((Mode == MODE_INTER) || (Mode == MODE_INTER_Q) || (Mode == MODE_GMC) || (Mode == MODE_GMC_Q)) && (vop_type == PCT_SPRITE))
584 /* modified by NTT for GMC coding : end */
586 if ((Mode == MODE_INTER) || (Mode == MODE_INTER_Q))
587 BitstreamPutBits(mottext_bitstream, (long) 0, 1L);
588 /* modified by NTT for GMC coding : start
589 if ((Mode == MODE_DYN_SP) || (Mode == MODE_DYN_SP_Q))
591 if ((Mode == MODE_GMC) || (Mode == MODE_GMC_Q))
592 /* modified by NTT for GMC coding : end */
593 BitstreamPutBits(mottext_bitstream, (long) 1, 1L);
595 bits->MCBPC += 1;
598 /* ACpred_flag */
599 /* 17-Jan-97 JDL : correction no ACpred_flag in combined mode when intra_acdc_pred_disable is true */
600 if ((Mode == MODE_INTRA || Mode==MODE_INTRA_Q) && ACpred_flag != -1)
602 BitstreamPutBits(mottext_bitstream, (long)ACpred_flag, 1L);
603 bits->ACpred_flag += 1;
606 /* CBPY */
608 length = PutCBPY (cbpy, (Char)(Mode==MODE_INTRA||Mode==MODE_INTRA_Q),/*MB_transp_pattern*/NULL,mottext_bitstream);
610 bits->CBPY += length;
612 /* DQUANT */
614 /* modified by NTT for GMC coding : start
615 if ((Mode == MODE_INTER_Q) || (Mode == MODE_INTRA_Q)|| (Mode == MODE_DYN_SP_Q))
617 if ((Mode == MODE_INTER_Q) || (Mode == MODE_INTRA_Q)|| (Mode == MODE_GMC_Q))
618 /* modified by NTT for GMC coding : end */
620 switch (DQUANT)
622 case -1:
623 BitstreamPutBits(mottext_bitstream, 0L, 2L);
624 break;
625 case -2:
626 BitstreamPutBits(mottext_bitstream, 1L, 2L);
627 break;
628 case 1:
629 BitstreamPutBits(mottext_bitstream, 2L, 2L);
630 break;
631 case 2:
632 BitstreamPutBits(mottext_bitstream, 3L, 2L);
633 break;
634 default:
635 fprintf(stderr,"Invalid DQUANT\n");
636 exit(1);
638 bits->DQUANT += 2;
643 /***********************************************************CommentBegin******
645 * -- doDCACpred -- Does DC/AC prediction. Changes qcoeff values as
646 * appropriate.
648 * Purpose :
649 * Does DC/AC prediction. Changes qcoeff values as appropriate.
651 * Arguments in :
652 * Int CBP
653 * Int ncoeffs
654 * Int x_pos
655 * Int y_pos
656 * Int DC_store[][6][15] Stores coefficient values per MB for
657 * prediction (for one Vop)
658 * Int QP QP value for this MB
659 * Int MB_width
661 * Arguments in/out :
662 * Int *qcoeff
664 * Return values :
665 * Int The ACpred_flag, which is to be put into the bitstream
667 * Side effects :
668 * Modifies qcoeff if needed for the prediction.
670 ***********************************************************CommentEnd********/
672 Int doDCACpred(Int *qcoeff, Int *CBP, Int ncoeffs, Int x_pos, Int y_pos,
673 Int ***DC_store, Int QP, Int MB_width,
674 Int direction[], Int mid_grey )
676 Int i, m;
677 Int block_A, block_B, block_C;
678 Int Xpos[6] = {-1, 0, -1, 0, -1, -1};
679 Int Ypos[6] = {-1, -1, 0, 0, -1, -1};
680 Int Xtab[6] = {1, 0, 3, 2, 4, 5};
681 Int Ytab[6] = {2, 3, 0, 1, 4, 5};
682 Int Ztab[6] = {3, 2, 1, 0, 4, 5};
683 Int grad_hor, grad_ver, DC_pred;
684 Int pred_A[15], pred_C[15];
685 Int S = 0, S1, S2;
686 Int diff;
687 Int pcoeff[384];
688 Int ACpred_flag=-1;
690 /* Copy qcoeff to the prediction array pcoeff */
691 for (i = 0; i < (6*ncoeffs); i++)
693 pcoeff[i] = qcoeff[i];
696 for (i = 0; i < 6; i++)
698 if ((x_pos == 0) && y_pos == 0) /* top left corner */
700 block_A = (i == 1 || i == 3) ? DC_store[y_pos*MB_width+(x_pos+Xpos[i])][Xtab[i]][0] : mid_grey*8;
701 block_B = (i == 3) ? DC_store[(y_pos+Ypos[i])*MB_width+(x_pos+Xpos[i])][Ztab[i]][0] : mid_grey*8;
702 block_C = (i == 2 || i == 3) ? DC_store[(y_pos+Ypos[i])*MB_width+x_pos][Ytab[i]][0] : mid_grey*8;
704 else if (x_pos == 0) /* left edge */
706 block_A = (i == 1 || i == 3) ? DC_store[y_pos*MB_width+(x_pos+Xpos[i])][Xtab[i]][0] : mid_grey*8;
707 block_B = (i == 1 || i == 3) ? DC_store[(y_pos+Ypos[i])*MB_width+(x_pos+Xpos[i])][Ztab[i]][0] : mid_grey*8;
708 block_C = DC_store[(y_pos+Ypos[i])*MB_width+x_pos][Ytab[i]][0];
710 else if (y_pos == 0) /* top row */
712 block_A = DC_store[y_pos*MB_width+(x_pos+Xpos[i])][Xtab[i]][0];
713 block_B = (i == 2 || i == 3) ? DC_store[(y_pos+Ypos[i])*MB_width+(x_pos+Xpos[i])][Ztab[i]][0] : mid_grey*8;
714 block_C = (i == 2 || i == 3) ? DC_store[(y_pos+Ypos[i])*MB_width+x_pos][Ytab[i]][0] : mid_grey*8;
716 else
718 block_A = DC_store[y_pos*MB_width+(x_pos+Xpos[i])][Xtab[i]][0];
719 block_B = (DC_store[(y_pos+Ypos[i])*MB_width+(x_pos+Xpos[i])]
720 [Ztab[i]][0]);
721 block_C = DC_store[(y_pos+Ypos[i])*MB_width+x_pos][Ytab[i]][0];
723 grad_hor = block_B - block_C;
724 grad_ver = block_A - block_B;
726 if ((ABS(grad_ver)) < (ABS(grad_hor)))
728 DC_pred = block_C;
729 direction[i] = 2;
731 else
733 DC_pred = block_A;
734 direction[i] = 1;
737 pcoeff[i*ncoeffs] = qcoeff[i*ncoeffs] - (DC_pred+cal_dc_scaler(QP,(i<4)?1:2)/2)/cal_dc_scaler(QP,(i<4)?1:2);
739 /* Find AC predictions */
740 if ((x_pos == 0) && y_pos == 0) /* top left corner */
742 if (i == 1 || i == 3)
743 for (m = 0; m < 15; m++)
744 pred_A[m] = Idir_c(((DC_store[y_pos*MB_width+(x_pos+Xpos[i])][Xtab[i]][m]) * QP*2) , 2*QP);
745 else
746 nullfill(pred_A,mid_grey);
747 if (i == 2 || i == 3)
748 for (m = 0; m < 15; m++)
749 pred_C[m] = Idir_c(((DC_store[(y_pos+Ypos[i])*MB_width+x_pos][Ytab[i]][m]) * QP*2) , 2*QP);
750 else
751 nullfill(pred_C,mid_grey);
753 else if (x_pos == 0) /* left edge */
755 if (i == 1 || i == 3)
756 for (m = 0; m < 15; m++)
757 pred_A[m] = Idir_c(((DC_store[y_pos*MB_width+(x_pos+Xpos[i])][Xtab[i]][m]) * QP*2) , 2*QP);
758 else
759 nullfill(pred_A,mid_grey);
760 for (m = 0; m < 15; m++)
761 pred_C[m] = Idir_c(((DC_store[(y_pos+Ypos[i])*MB_width+x_pos][Ytab[i]][m]) * QP*2) , 2*QP);
763 else if (y_pos == 0) /* top row */
765 for (m = 0; m < 15; m++)
766 pred_A[m] = Idir_c(((DC_store[y_pos*MB_width+(x_pos+Xpos[i])][Xtab[i]][m]) * QP*2) , 2*QP);
767 if (i == 2 || i == 3)
768 for (m = 0; m < 15; m++)
769 pred_C[m] = Idir_c(((DC_store[(y_pos+Ypos[i])*MB_width+x_pos][Ytab[i]][m]) * QP*2) , 2*QP);
770 else
771 nullfill(pred_C,mid_grey);
773 else
775 for (m = 0; m < 15; m++)
777 pred_A[m] = Idir_c(((DC_store[y_pos*MB_width+(x_pos+Xpos[i])][Xtab[i]][m]) * QP*2) , 2*QP);
778 pred_C[m] = Idir_c(((DC_store[(y_pos+Ypos[i])*MB_width+x_pos][Ytab[i]][m]) * QP*2) , 2*QP);
782 #if 1 /* I think it should be like this, 14-NOV-1996 MW */
783 S1 = 0;
784 S2 = 0;
785 /* Now decide on AC prediction */
786 if (direction[i] == 1) /* Horizontal, left COLUMN of block A */
788 for (m = 0; m < 7; m++)
790 S1 += ABS(qcoeff[i*ncoeffs+(m+1)*8]);
791 diff = pcoeff[i*ncoeffs+(m+1)*8]
792 = qcoeff[i*ncoeffs+(m+1)*8] - pred_A[m+8];
793 S2 += ABS(diff);
796 else /* Vertical, top ROW of block C */
798 for (m = 1; m < 8; m++)
800 S1 += ABS(qcoeff[i*ncoeffs+m]);
801 diff = pcoeff[i*ncoeffs+m]
802 = qcoeff[i*ncoeffs+m] - pred_C[m];
803 S2 += ABS(diff);
806 S += (S1 - S2);
807 #endif
809 /* Now change qcoeff for DC pred or DC/AC pred */
810 if (S >=0)
812 for (i=0;i<ncoeffs*6; i++)
813 /* Modified due to N2171 Cl. 2.2.14 MW 25-MAR-1998 */
814 /* if ((i%64)&&(abs(pcoeff[i])>127)) { */
815 if ((i%64)&&(abs(pcoeff[i])>2047))
817 printf("predicted AC out of range");
818 S=-1;break;
821 if (S >= 0) /* Both DC and AC prediction */
823 ACpred_flag = 1;
824 for (i = 0; i < ncoeffs*6; i++)
826 qcoeff[i] = pcoeff[i];
828 /* Update CBP for predicted coeffs. */
829 *CBP = FindCBP(qcoeff, MODE_INTRA, 64);
831 else /* Only DC prediction */
833 ACpred_flag = 0;
834 for (i = 0; i < 6; i++)
836 qcoeff[i*ncoeffs] = pcoeff[i*ncoeffs];
837 direction[i] = 0;
840 return ACpred_flag; /* To be put into bitstream */
844 * Small routine to fill default prediction values into a DC_store entry
847 Void nullfill(Int pred[], Int mid_grey)
849 Int i;
851 pred[0] = mid_grey*8;
852 for (i = 1; i < 15; i++)
854 pred[i] = 0;
858 Int Idir_c(Int val, Int QP)
860 if (val<0) return (val-QP/2)/QP;
861 else return (val+QP/2)/QP;
865 /***********************************************************CommentBegin******
867 * -- IntraDCSwitch_decisions --
869 * Purpose :
870 * decide whether to use inter AC table to encode DC
872 * Arguments in :
873 * Int Mode
874 * Int intra_dc_vlc_thr
875 * Int Qp
877 ***********************************************************CommentEnd********/
879 Int IntraDCSwitch_Decision(Int Mode,Int intra_dc_vlc_thr,Int Qp)
881 Int switched =0;
882 if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q)
884 if (intra_dc_vlc_thr==0)
885 switched=0;
886 else if (intra_dc_vlc_thr==7)
887 switched=1;
888 else if (Qp>=intra_dc_vlc_thr*2+11)
889 switched=1;
892 return switched;
896 /***********************************************************CommentBegin******
898 * -- cal_dc_scaler -- calculation of DC quantization scale according
899 * to the incoming Q and type;
901 * Arguments in :
902 * Int Qp
904 ***********************************************************CommentEnd********/
906 Int cal_dc_scaler (Int QP, Int type)
909 Int dc_scaler;
910 if (type == 1)
912 if (QP > 0 && QP < 5) dc_scaler = 8;
913 else if (QP > 4 && QP < 9) dc_scaler = 2 * QP;
914 else if (QP > 8 && QP < 25) dc_scaler = QP + 8;
915 else dc_scaler = 2 * QP - 16;
917 else
919 if (QP > 0 && QP < 5) dc_scaler = 8;
920 else if (QP > 4 && QP < 25) dc_scaler = (QP + 13) / 2;
921 else dc_scaler = QP - 6;
923 return dc_scaler;
928 /***********************************************************CommentBegin******
930 * -- FindCBP -- Find the CBP for a macroblock
932 * Purpose :
933 * Find the CBP for a macroblock
935 * Arguments in :
936 * Int *qcoeff : pointer to quantized coefficients
937 * Int Mode : macroblock encoding mode information
938 * Int ncoeffs : the number of coefficients
940 * Return values :
941 * Int CBP : The coded block pattern for a macroblock
943 ***********************************************************CommentEnd********/
946 FindCBP (Int* qcoeff, Int Mode, Int ncoeffs)
948 Int i,j;
949 Int CBP = 0;
950 Int intra = (Mode == MODE_INTRA || Mode == MODE_INTRA_Q);
952 /* Set CBP for this Macroblock */
954 for (i = 0; i < 6; i++)
956 for (j = i*ncoeffs + intra; j < (i+1)*ncoeffs; j++)
959 if (qcoeff[j])
961 if (i == 0) {CBP |= 32;}
962 else if (i == 1) {CBP |= 16;}
963 else if (i == 2) {CBP |= 8;}
964 else if (i == 3) {CBP |= 4;}
965 else if (i == 4) {CBP |= 2;}
966 else if (i == 5) {CBP |= 1;}
967 else
969 fprintf (stderr, "Error in CBP assignment\n");
970 exit(-1);
973 break;
978 return CBP;