2 /**************************************************************************
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. *
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. *
19 * The complete Open DivX license can be found at *
20 * http://www.projectmayo.com/opendivx/license.php . *
22 **************************************************************************/
24 /**************************************************************************
28 * Copyright (C) 2001 Project Mayo
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"
42 #include "bitstream.h"
45 #include "text_code_mb.h"
46 #include "text_code.h"
52 Void
Bits_CountMB_combined ( Int DQUANT
,
59 Image
*mottext_bitstream
,
60 Int
*MB_transp_pattern
62 Int
doDCACpred ( Int
*qcoeff
,
73 Void
nullfill(Int pred
[], Int mid_grey
);
74 Int
Idir_c(Int val
, Int QP
);
75 Int IntraDCSwitch_Decision
_P_(( Int Mode
,
79 Int FindCBP
_P_(( Int
*qcoeff
,
85 /***********************************************************CommentBegin******
87 * -- VopCodeShapeTextIntraCom --Intra texture encoding of one vop,
88 * Combined shape/(motion)/texture mode
91 * Intra texture encoding of one vop (combined shape/(mot)/text mode)
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:
102 * Vop *rec_curr : the reconstructed current vop
103 * Image *texture_bitstream : the output bitstream
104 * Bits : statistics information
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
;
120 Int num_pixels
= GetImageSizeX(GetVopY(curr
));
121 Int num_lines
= GetImageSizeY(GetVopY(curr
));
124 Int MB_width
= num_pixels
/ MB_SIZE
;
125 Int MB_height
= num_lines
/ MB_SIZE
;
135 qcoeff
= (Int
*) malloc (sizeof (Int
) * 384);
138 fprintf(ftrace
, "RC - VopCodeShapeTextIntraCom(): ---> CODING WITH: %d \n",QP
);
141 for (i
= 0; i
< 6; i
++)
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
));
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
++)
167 CodeMB (curr
, rec_curr
, NULL
, i
*MB_SIZE
, j
*MB_SIZE
,
168 num_pixels
, QP
+DQUANT
, MODE_INTRA
, qcoeff
);
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
202 if (GetVopIntraACDCPredDisable(curr
) == 0)
204 ACpred_flag
= doDCACpred(qcoeff
, &CBP
, 64, i
, j
, DC_store
,
206 direction
,GetVopMidGrey(curr
));
211 switched
= IntraDCSwitch_Decision(Mode
,
212 GetVopIntraDCVlcThr(curr
),
215 CBP
= FindCBP(qcoeff
,MODE_INTER
,64);
216 if (DQUANT
) Mode
=MODE_INTRA_Q
;else Mode
=MODE_INTRA
;
221 CBPY
= CBPY
& 15; /* last 4 bits */
222 CBPC
= CBP
& 3; /* last 2 bits */
224 Bits_CountMB_combined (DQUANT
, Mode
, COD
, ACpred_flag
, CBP
,
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)*/,
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
]);
249 free ((Char
*)qcoeff
);
252 /***********************************************************CommentBegin******
254 * -- VopShapeMotText -- Combined Inter encoding of shape motion and texture
257 * Combined Inter encoding of texture and motion.
258 * Used by VopCodeMotTextInter
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
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
,
283 Int intra_acdc_pred_disable
,
285 Image
*mottext_bitstream
289 Int QP
= GetVopQuantizer(curr
);
295 Int MB_in_width
, MB_in_height
, B_in_width
, mbnum
, boff
;
298 Float
*motx_ptr
=NULL
, *moty_ptr
=NULL
;
301 Int vop_type
=PCT_INTER
;
302 Int
***DC_store
=NULL
;
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;
323 printf("RC - VopShapeMotText(): ---> CODING WITH: %d \n",QP
);
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
,
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
));
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
++)
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;
365 Mode
= (DQUANT
== 0) ? MODE_INTRA
: MODE_INTRA_Q
;
370 Mode
= (DQUANT
== 0) ? MODE_INTER
: MODE_INTER_Q
;
377 DQUANT
= 0; /* Can't change QP for 8x8 mode */
381 printf("invalid MB_decision value :%d\n", p
);
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);
406 COD
= 0; /* coded macroblock */
408 if ((Mode
== MODE_INTRA
) || (Mode
== MODE_INTRA_Q
))
411 /* Store the qcoeff-values needed later for prediction */
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
,
443 QP
+DQUANT
, MB_in_width
,
444 direction
,GetVopMidGrey(curr
));
446 ACpred_flag
= -1; /* Not to go into bitstream */
449 switched
= IntraDCSwitch_Decision(Mode
,
450 GetVopIntraDCVlcThr(curr
),
453 CBP
= FindCBP(qcoeff
,MODE_INTER
,64);
456 CBPY
= CBPY
& 15; /* last 4 bits */
457 CBPC
= CBP
& 3; /* last 2 bits */
459 Bits_CountMB_combined (DQUANT
, Mode
, COD
, ACpred_flag
, CBP
,
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*/,
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)*/,
476 0 /*curr->alternate_scan*/);
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
]);
494 free ((Char
*)qcoeff
);
498 /***********************************************************CommentBegin******
500 * -- Bits_CountMB_combined -- texture encoding for combined texture/motion
503 * Used for texture encoding in case of combined texture/motion
504 * encoding. This function encodes the :
509 * - DQUANT information
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
516 * Int vop_type : indicates the picture coding type
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
;
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 */
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
);
556 if (vop_type
!= PCT_INTRA
)
560 printf("COD = 1 in Bits_CountMB_combined \n");
561 printf("This function should not be used if COD is '1' \n");
566 BitstreamPutBits(mottext_bitstream
, (long)(COD
), 1L);
572 if (vop_type
== PCT_INTRA
)
573 length
= PutMCBPC_Intra (cbpc
, MBtype
, mottext_bitstream
);
575 length
= PutMCBPC_Inter (cbpc
, MBtype
, mottext_bitstream
);
577 bits
->MCBPC
+= length
;
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);
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;
608 length
= PutCBPY (cbpy
, (Char
)(Mode
==MODE_INTRA
||Mode
==MODE_INTRA_Q
),/*MB_transp_pattern*/NULL
,mottext_bitstream
);
610 bits
->CBPY
+= length
;
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 */
623 BitstreamPutBits(mottext_bitstream
, 0L, 2L);
626 BitstreamPutBits(mottext_bitstream
, 1L, 2L);
629 BitstreamPutBits(mottext_bitstream
, 2L, 2L);
632 BitstreamPutBits(mottext_bitstream
, 3L, 2L);
635 fprintf(stderr
,"Invalid DQUANT\n");
643 /***********************************************************CommentBegin******
645 * -- doDCACpred -- Does DC/AC prediction. Changes qcoeff values as
649 * Does DC/AC prediction. Changes qcoeff values as appropriate.
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
665 * Int The ACpred_flag, which is to be put into the bitstream
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
)
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];
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;
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
])]
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
)))
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
);
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
);
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
);
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
);
771 nullfill(pred_C
,mid_grey
);
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 */
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];
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
];
809 /* Now change qcoeff for DC pred or DC/AC pred */
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");
821 if (S
>= 0) /* Both DC and AC prediction */
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 */
834 for (i
= 0; i
< 6; i
++)
836 qcoeff
[i
*ncoeffs
] = pcoeff
[i
*ncoeffs
];
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
)
851 pred
[0] = mid_grey
*8;
852 for (i
= 1; i
< 15; i
++)
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 --
870 * decide whether to use inter AC table to encode DC
874 * Int intra_dc_vlc_thr
877 ***********************************************************CommentEnd********/
879 Int
IntraDCSwitch_Decision(Int Mode
,Int intra_dc_vlc_thr
,Int Qp
)
882 if (Mode
== MODE_INTRA
|| Mode
== MODE_INTRA_Q
)
884 if (intra_dc_vlc_thr
==0)
886 else if (intra_dc_vlc_thr
==7)
888 else if (Qp
>=intra_dc_vlc_thr
*2+11)
896 /***********************************************************CommentBegin******
898 * -- cal_dc_scaler -- calculation of DC quantization scale according
899 * to the incoming Q and type;
904 ***********************************************************CommentEnd********/
906 Int
cal_dc_scaler (Int QP
, Int type
)
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;
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;
928 /***********************************************************CommentBegin******
930 * -- FindCBP -- Find the CBP for a macroblock
933 * Find the CBP for a macroblock
936 * Int *qcoeff : pointer to quantized coefficients
937 * Int Mode : macroblock encoding mode information
938 * Int ncoeffs : the number of coefficients
941 * Int CBP : The coded block pattern for a macroblock
943 ***********************************************************CommentEnd********/
946 FindCBP (Int
* qcoeff
, Int Mode
, Int ncoeffs
)
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
++)
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;}
969 fprintf (stderr
, "Error in CBP assignment\n");