1/* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13 * express or implied.
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
17 */
18/******************************************************************************
19*
20* This software module was originally developed by
21*
22* Robert Danielsen (Telenor / ACTS-MoMuSys).
23*
24* and edited by
25*
26* Luis Ducla-Soares (IST / ACTS-MoMuSys).
27* Cor Quist (KPN / ACTS-MoMuSys).
28*
29* in the course of development of the MPEG-4 Video (ISO/IEC 14496-2) standard.
30* This software module is an implementation of a part of one or more MPEG-4
31* Video (ISO/IEC 14496-2) tools as specified by the MPEG-4 Video (ISO/IEC
32* 14496-2) standard.
33*
34* ISO/IEC gives users of the MPEG-4 Video (ISO/IEC 14496-2) standard free
35* license to this software module or modifications thereof for use in hardware
36* or software products claiming conformance to the MPEG-4 Video (ISO/IEC
37* 14496-2) standard.
38*
39* Those intending to use this software module in hardware or software products
40* are advised that its use may infringe existing patents. The original
41* developer of this software module and his/her company, the subsequent
42* editors and their companies, and ISO/IEC have no liability for use of this
43* software module or modifications thereof in an implementation. Copyright is
44* not released for non MPEG-4 Video (ISO/IEC 14496-2) standard conforming
45* products.
46*
47* ACTS-MoMuSys partners retain full right to use the code for his/her own
48* purpose, assign or donate the code to a third party and to inhibit third
49* parties from using the code for non MPEG-4 Video (ISO/IEC 14496-2) standard
50* conforming products. This copyright notice must be included in all copies or
51* derivative works.
52*
53* Copyright (c) 1997
54*
55*****************************************************************************/
56
57/***********************************************************HeaderBegin*******
58*
59* File: putvlc.c
60*
61* Author:   Robert Danielsen, Telenor R&D
62* Created:  07.07.96
63*
64* Description: Functions for writing to bitstream
65*
66* Notes:    Same kind of tables as in the MPEG-2 software simulation
67*       group software.
68*
69* Modified:
70*   28.10.96 Robert Danielsen: Added PutCoeff_Intra(), renamed
71*           PutCoeff() to PutCoeff_Inter().
72*   06.11.96 Robert Danielsen: Added PutMCBPC_sep()
73*      01.05.97 Luis Ducla-Soares: added PutCoeff_Intra_RVLC() and
74*                                  PutCoeff_Inter_RVLC().
75*
76***********************************************************HeaderEnd*********/
77
78/************************    INCLUDE FILES    ********************************/
79
80
81#include "mp4lib_int.h"
82#include "mp4enc_lib.h"
83#include "vlc_enc_tab.h"
84#include "bitstream_io.h"
85#include "m4venc_oscl.h"
86#include "vlc_encode_inline.h"
87
88typedef void (*BlockCodeCoeffPtr)(RunLevelBlock*, BitstreamEncVideo*, Int, Int, UChar) ;
89
90const static Int mode_MBtype[] =
91{
92    3,
93    0,
94    4,
95    1,
96    2,
97};
98
99const static Int zigzag_inv[NCOEFF_BLOCK] =
100{
101    0,  1,  8, 16,  9,  2,  3, 10,
102    17, 24, 32, 25, 18, 11,  4,  5,
103    12, 19, 26, 33, 40, 48, 41, 34,
104    27, 20, 13,  6,  7, 14, 21, 28,
105    35, 42, 49, 56, 57, 50, 43, 36,
106    29, 22, 15, 23, 30, 37, 44, 51,
107    58, 59, 52, 45, 38, 31, 39, 46,
108    53, 60, 61, 54, 47, 55, 62, 63
109};
110
111/* Horizontal zigzag inverse */
112const static Int zigzag_h_inv[NCOEFF_BLOCK] =
113{
114    0, 1, 2, 3, 8, 9, 16, 17,
115    10, 11, 4, 5, 6, 7, 15, 14,
116    13, 12, 19, 18, 24, 25, 32, 33,
117    26, 27, 20, 21, 22, 23, 28, 29,
118    30, 31, 34, 35, 40, 41, 48, 49,
119    42, 43, 36, 37, 38, 39, 44, 45,
120    46, 47, 50, 51, 56, 57, 58, 59,
121    52, 53, 54, 55, 60, 61, 62, 63
122};
123
124/* Vertical zigzag inverse */
125const static Int zigzag_v_inv[NCOEFF_BLOCK] =
126{
127    0, 8, 16, 24, 1, 9, 2, 10,
128    17, 25, 32, 40, 48, 56, 57, 49,
129    41, 33, 26, 18, 3, 11, 4, 12,
130    19, 27, 34, 42, 50, 58, 35, 43,
131    51, 59, 20, 28, 5, 13, 6, 14,
132    21, 29, 36, 44, 52, 60, 37, 45,
133    53, 61, 22, 30, 7, 15, 23, 31,
134    38, 46, 54, 62, 39, 47, 55, 63
135};
136
137#ifdef __cplusplus
138extern "C"
139{
140#endif
141
142    Int PutCoeff_Inter(Int run, Int level, BitstreamEncVideo *bitstream);
143    Int PutCoeff_Inter_Last(Int run, Int level, BitstreamEncVideo *bitstream);
144    Int PutCoeff_Intra(Int run, Int level, BitstreamEncVideo *bitstream);
145    Int PutCoeff_Intra_Last(Int run, Int level, BitstreamEncVideo *bitstream);
146    Int PutCBPY(Int cbpy, Char intra, BitstreamEncVideo *bitstream);
147    Int PutMCBPC_Inter(Int cbpc, Int mode, BitstreamEncVideo *bitstream);
148    Int PutMCBPC_Intra(Int cbpc, Int mode, BitstreamEncVideo *bitstream);
149    Int PutMV(Int mvint, BitstreamEncVideo *bitstream);
150    Int PutDCsize_chrom(Int size, BitstreamEncVideo *bitstream);
151    Int PutDCsize_lum(Int size, BitstreamEncVideo *bitstream);
152    Int PutDCsize_lum(Int size, BitstreamEncVideo *bitstream);
153#ifndef NO_RVLC
154    Int PutCoeff_Inter_RVLC(Int run, Int level, BitstreamEncVideo *bitstream);
155    Int PutCoeff_Inter_RVLC_Last(Int run, Int level, BitstreamEncVideo *bitstream);
156    Int PutCoeff_Intra_RVLC(Int run, Int level, BitstreamEncVideo *bitstream);
157    Int PutCoeff_Intra_RVLC_Last(Int run, Int level, BitstreamEncVideo *bitstream);
158#endif
159    Int PutRunCoeff_Inter(Int run, Int level, BitstreamEncVideo *bitstream);
160    Int PutRunCoeff_Inter_Last(Int run, Int level, BitstreamEncVideo *bitstream);
161    Int PutRunCoeff_Intra(Int run, Int level, BitstreamEncVideo *bitstream);
162    Int PutRunCoeff_Intra_Last(Int run, Int level, BitstreamEncVideo *bitstream);
163    Int PutLevelCoeff_Inter(Int run, Int level, BitstreamEncVideo *bitstream);
164    Int PutLevelCoeff_Inter_Last(Int run, Int level, BitstreamEncVideo *bitstream);
165    Int PutLevelCoeff_Intra(Int run, Int level, BitstreamEncVideo *bitstream);
166    Int PutLevelCoeff_Intra_Last(Int run, Int level, BitstreamEncVideo *bitstream);
167
168    void RunLevel(VideoEncData *video, Int intra, Int intraDC_decision, Int ncoefblck[]);
169    Int IntraDC_dpcm(Int val, Int lum, BitstreamEncVideo *bitstream);
170    Void DCACPred(VideoEncData *video, UChar Mode, Int *intraDC_decision, Int intraDCVlcQP);
171    Void find_pmvs(VideoEncData *video, Int block, Int *mvx, Int *mvy);
172    Void  WriteMVcomponent(Int f_code, Int dmv, BitstreamEncVideo *bs);
173    static Bool IntraDCSwitch_Decision(Int Mode, Int intra_dc_vlc_threshold, Int intraDCVlcQP);
174
175    Void ScaleMVD(Int  f_code, Int  diff_vector, Int  *residual, Int  *vlc_code_mag);
176
177#ifdef __cplusplus
178}
179#endif
180
181Int
182PutDCsize_lum(Int size, BitstreamEncVideo *bitstream)
183{
184    Int length;
185
186    if (!(size >= 0 && size < 13))
187        return -1;
188
189    length = DCtab_lum[size].len;
190    if (length)
191        BitstreamPutBits(bitstream, length, DCtab_lum[size].code);
192
193    return length;
194}
195
196Int
197PutDCsize_chrom(Int size, BitstreamEncVideo *bitstream)
198{
199    Int length;
200
201    if (!(size >= 0 && size < 13))
202        return -1;
203    length = DCtab_chrom[size].len;
204    if (length)
205        BitstreamPutBits(bitstream, length, DCtab_chrom[size].code);
206
207    return length;
208}
209
210Int
211PutMV(Int mvint, BitstreamEncVideo *bitstream)
212{
213    Int sign = 0;
214    Int absmv;
215    Int length;
216
217    if (mvint > 32)
218    {
219        absmv = -mvint + 65;
220        sign = 1;
221    }
222    else
223        absmv = mvint;
224
225    length = mvtab[absmv].len;
226    if (length)
227        BitstreamPutBits(bitstream, length, mvtab[absmv].code);
228
229    if (mvint != 0)
230    {
231        BitstreamPut1Bits(bitstream, sign);
232        return (length + 1);
233    }
234    else
235        return length;
236}
237
238Int
239PutMCBPC_Intra(Int cbp, Int mode, BitstreamEncVideo *bitstream)
240{
241    Int ind;
242    Int length;
243
244    ind = ((mode_MBtype[mode] >> 1) & 3) | ((cbp & 3) << 2);
245
246    length = mcbpc_intra_tab[ind].len;
247    if (length)
248        BitstreamPutBits(bitstream, length, mcbpc_intra_tab[ind].code);
249
250    return length;
251}
252
253Int
254PutMCBPC_Inter(Int cbp, Int mode, BitstreamEncVideo *bitstream)
255{
256    Int ind;
257    Int length;
258
259    ind = (mode_MBtype[mode] & 7) | ((cbp & 3) << 3);
260
261    length = mcbpc_inter_tab[ind].len;
262    if (length)
263        BitstreamPutBits(bitstream, length, mcbpc_inter_tab[ind].code);
264
265    return length;
266}
267
268Int
269PutCBPY(Int cbpy, Char intra, BitstreamEncVideo *bitstream)
270{
271    Int ind;
272    Int length;
273
274    if ((intra == 0))
275        cbpy = 15 - cbpy;
276
277    ind = cbpy;
278
279    length = cbpy_tab[ind].len;
280    if (length)
281        BitstreamPutBits(bitstream, length, (UInt)cbpy_tab[ind].code);
282
283    return length;
284}
285
286/* 5/16/01, break up function for last and not-last coefficient */
287/* Note:::: I checked the ARM assembly for if( run > x && run < y) type
288    of code, they do a really good job compiling it to if( (UInt)(run-x) < y-x).
289    No need to hand-code it!!!!!, 6/1/2001 */
290
291Int PutCoeff_Inter(Int run, Int level, BitstreamEncVideo *bitstream)
292{
293    Int length = 0;
294
295    if (run < 2 && level < 13)
296    {
297        length = coeff_tab0[run][level-1].len;
298        if (length)
299            BitstreamPutBits(bitstream, length, (UInt)coeff_tab0[run][level-1].code);
300    }
301    else if (run > 1 && run < 27 && level < 5)
302    {
303        length = coeff_tab1[run-2][level-1].len;
304        if (length)
305            BitstreamPutBits(bitstream, length, (UInt)coeff_tab1[run-2][level-1].code);
306    }
307
308    return length;
309}
310
311Int PutCoeff_Inter_Last(Int run, Int level, BitstreamEncVideo *bitstream)
312{
313    Int length = 0;
314
315    if (run < 2 && level < 4)
316    {
317        length = coeff_tab2[run][level-1].len;
318        if (length)
319            BitstreamPutBits(bitstream, length, (UInt)coeff_tab2[run][level-1].code);
320    }
321    else if (run > 1 && run < 42 && level == 1)
322    {
323        length = coeff_tab3[run-2].len;
324        if (length)
325            BitstreamPutBits(bitstream, length, (UInt)coeff_tab3[run-2].code);
326    }
327
328    return length;
329}
330
331/* 5/16/01, break up function for last and not-last coefficient */
332
333Int PutCoeff_Intra(Int run, Int level, BitstreamEncVideo *bitstream)
334{
335    Int length = 0;
336
337    if (run == 0 && level < 28)
338    {
339        length = coeff_tab4[level-1].len;
340        if (length)
341            BitstreamPutBits(bitstream, length, (UInt)coeff_tab4[level-1].code);
342    }
343    else if (run == 1 && level < 11)
344    {
345        length = coeff_tab5[level-1].len;
346        if (length)
347            BitstreamPutBits(bitstream, length, (UInt)coeff_tab5[level-1].code);
348    }
349    else if (run > 1 && run < 10 && level < 6)
350    {
351        length = coeff_tab6[run-2][level-1].len;
352        if (length)
353            BitstreamPutBits(bitstream, length, (UInt)coeff_tab6[run-2][level-1].code);
354    }
355    else if (run > 9 && run < 15 && level == 1)
356    {
357        length = coeff_tab7[run-10].len;
358        if (length)
359            BitstreamPutBits(bitstream, length, (UInt)coeff_tab7[run-10].code);
360    }
361
362    return length;
363}
364
365Int PutCoeff_Intra_Last(Int run, Int level, BitstreamEncVideo *bitstream)
366{
367    Int length = 0;
368
369    if (run == 0 && level < 9)
370    {
371        length = coeff_tab8[level-1].len;
372        if (length)
373            BitstreamPutBits(bitstream, length, (UInt)coeff_tab8[level-1].code);
374    }
375    else if (run > 0 && run < 7 && level < 4)
376    {
377        length = coeff_tab9[run-1][level-1].len;
378        if (length)
379            BitstreamPutBits(bitstream, length, (UInt)coeff_tab9[run-1][level-1].code);
380    }
381    else if (run > 6 && run < 21 && level == 1)
382    {
383        length = coeff_tab10[run-7].len;
384        if (length)
385            BitstreamPutBits(bitstream, length, (UInt)coeff_tab10[run-7].code);
386    }
387
388    return length;
389}
390
391/* 5/16/01, break up function for last and not-last coefficient */
392#ifndef NO_RVLC
393Int PutCoeff_Inter_RVLC(Int run, Int level, BitstreamEncVideo *bitstream)
394{
395    Int length = 0;
396
397    if (run == 0 && level < 20)
398    {
399        length =  coeff_RVLCtab14[level-1].len;
400        if (length)
401            BitstreamPutBits(bitstream, length, (UInt)coeff_RVLCtab14[level-1].code);
402    }
403    else if (run == 1 && level < 11)
404    {
405        length = coeff_RVLCtab15[level-1].len;
406        if (length)
407            BitstreamPutBits(bitstream, length, (UInt)coeff_RVLCtab15[level-1].code);
408    }
409    else if (run > 1 && run < 4 && level < 8)
410    {
411        length = coeff_RVLCtab16[run-2][level-1].len;
412        if (length)
413            BitstreamPutBits(bitstream, length, (UInt)coeff_RVLCtab16[run-2][level-1].code);
414    }
415    else if (run == 4 && level < 6)
416    {
417        length = coeff_RVLCtab17[level-1].len;
418        if (length)
419            BitstreamPutBits(bitstream, length, (UInt)coeff_RVLCtab17[level-1].code);
420    }
421    else if (run > 4 && run < 8 && level < 5)
422    {
423        length = coeff_RVLCtab18[run-5][level-1].len;
424        if (length)
425            BitstreamPutBits(bitstream, length, (UInt)coeff_RVLCtab18[run-5][level-1].code);
426    }
427    else if (run > 7 && run < 10 && level < 4)
428    {
429        length = coeff_RVLCtab19[run-8][level-1].len;
430        if (length)
431            BitstreamPutBits(bitstream, length, (UInt)coeff_RVLCtab19[run-8][level-1].code);
432    }
433    else if (run > 9 && run < 18 && level < 3)
434    {
435        length = coeff_RVLCtab20[run-10][level-1].len;
436        if (length)
437            BitstreamPutBits(bitstream, length, (UInt)coeff_RVLCtab20[run-10][level-1].code);
438    }
439    else if (run > 17 && run < 39 && level == 1)
440    {
441        length = coeff_RVLCtab21[run-18].len;
442        if (length)
443            BitstreamPutBits(bitstream, length, (UInt)coeff_RVLCtab21[run-18].code);
444    }
445
446    return length;
447}
448
449Int PutCoeff_Inter_RVLC_Last(Int run, Int level, BitstreamEncVideo *bitstream)
450{
451    Int length = 0;
452
453    if (run >= 0 && run < 2 && level < 6)
454    {
455        length = coeff_RVLCtab22[run][level-1].len;
456        if (length)
457            BitstreamPutBits(bitstream, length, (UInt)coeff_RVLCtab22[run][level-1].code);
458    }
459    else if (run == 2 && level < 4)
460    {
461        length = coeff_RVLCtab23[level-1].len;
462        if (length)
463            BitstreamPutBits(bitstream, length, (UInt)coeff_RVLCtab23[level-1].code);
464    }
465    else if (run > 2 && run < 14 && level < 3)
466    {
467        length = coeff_RVLCtab24[run-3][level-1].len;
468        if (length)
469            BitstreamPutBits(bitstream, length, (UInt)coeff_RVLCtab24[run-3][level-1].code);
470    }
471    else if (run > 13 && run < 45 && level == 1)
472    {
473        length = coeff_RVLCtab25[run-14].len;
474        if (length)
475            BitstreamPutBits(bitstream, length, (UInt)coeff_RVLCtab25[run-14].code);
476    }
477
478    return length;
479}
480
481/* 5/16/01, break up function for last and not-last coefficient */
482
483Int PutCoeff_Intra_RVLC(Int run, Int level, BitstreamEncVideo *bitstream)
484{
485    Int length = 0;
486
487    if (run == 0 && level < 28)
488    {
489        length = coeff_RVLCtab1[level-1].len;
490        if (length)
491            BitstreamPutBits(bitstream, length, (UInt)coeff_RVLCtab1[level-1].code);
492    }
493    else if (run == 1 && level < 14)
494    {
495        length = coeff_RVLCtab2[level-1].len;
496        if (length)
497            BitstreamPutBits(bitstream, length, (UInt)coeff_RVLCtab2[level-1].code);
498    }
499    else if (run == 2 && level < 12)
500    {
501        length = coeff_RVLCtab3[level-1].len;
502        if (length)
503            BitstreamPutBits(bitstream, length, (UInt)coeff_RVLCtab3[level-1].code);
504    }
505    else if (run == 3 && level < 10)
506    {
507        length = coeff_RVLCtab4[level-1].len;
508        if (length)
509            BitstreamPutBits(bitstream, length, (UInt)coeff_RVLCtab4[level-1].code);
510    }
511    else if (run > 3 && run < 6 && level < 7)
512    {
513        length = coeff_RVLCtab5[run-4][level-1].len;
514        if (length)
515            BitstreamPutBits(bitstream, length, (UInt)coeff_RVLCtab5[run-4][level-1].code);
516    }
517    else if (run > 5 && run < 8 && level < 6)
518    {
519        length = coeff_RVLCtab6[run-6][level-1].len;
520        if (length)
521            BitstreamPutBits(bitstream, length, (UInt)coeff_RVLCtab6[run-6][level-1].code);
522    }
523    else if (run > 7 && run < 10 && level < 5)
524    {
525        length = coeff_RVLCtab7[run-8][level-1].len;
526        if (length)
527            BitstreamPutBits(bitstream, length, (UInt)coeff_RVLCtab7[run-8][level-1].code);
528
529    }
530    else if (run > 9 && run < 13 && level < 3)
531    {
532        length = coeff_RVLCtab8[run-10][level-1].len;
533        if (length)
534            BitstreamPutBits(bitstream, length, (UInt)coeff_RVLCtab8[run-10][level-1].code);
535    }
536    else if (run > 12 && run < 20 && level == 1)
537    {
538        length = coeff_RVLCtab9[run-13].len;
539        if (length)
540            BitstreamPutBits(bitstream, length, (UInt)coeff_RVLCtab9[run-13].code);
541    }
542    return length;
543}
544
545Int PutCoeff_Intra_RVLC_Last(Int run, Int level, BitstreamEncVideo *bitstream)
546{
547    Int length = 0;
548
549    if (run >= 0 && run < 2 && level < 6)
550    {
551        length = coeff_RVLCtab10[run][level-1].len;
552        if (length)
553            BitstreamPutBits(bitstream, length, (UInt)coeff_RVLCtab10[run][level-1].code);
554    }
555    else if (run == 2 && level < 4)
556    {
557        length = coeff_RVLCtab11[level-1].len;
558        if (length)
559            BitstreamPutBits(bitstream, length, (UInt)coeff_RVLCtab11[level-1].code);
560    }
561    else if (run > 2 && run < 14 && level < 3)
562    {
563        length = coeff_RVLCtab12[run-3][level-1].len;
564        if (length)
565            BitstreamPutBits(bitstream, length, (UInt)coeff_RVLCtab12[run-3][level-1].code);
566    }
567    else if (run > 13 && run < 45 && level == 1)
568    {
569        length = coeff_RVLCtab13[run-14].len;
570        if (length)
571            BitstreamPutBits(bitstream, length, (UInt)coeff_RVLCtab13[run-14].code);
572    }
573    return length;
574}
575#endif
576
577/* The following is for 3-mode VLC */
578
579Int
580PutRunCoeff_Inter(Int run, Int level, BitstreamEncVideo *bitstream)
581{
582    Int length = 0;
583
584    if (run < 2 && level < 13)
585    {
586        length = coeff_tab0[run][level-1].len;
587        if (length)
588        {
589            BitstreamPutGT8Bits(bitstream, 7 + 2, 14/*3*/);
590            //BitstreamPutBits(bitstream, 2, 2);
591            BitstreamPutBits(bitstream, length, (UInt)coeff_tab0[run][level-1].code);
592            length += 9;
593        }
594    }
595    else if (run > 1 && run < 27 && level < 5)
596    {
597        length = coeff_tab1[run-2][level-1].len;
598        if (length)
599        {
600            BitstreamPutGT8Bits(bitstream, 7 + 2, 14/*3*/);
601            //BitstreamPutBits(bitstream, 2, 2);
602            BitstreamPutBits(bitstream, length, (UInt)coeff_tab1[run-2][level-1].code);
603            length += 9;
604        }
605    }
606    return length;
607}
608
609Int PutRunCoeff_Inter_Last(Int run, Int level, BitstreamEncVideo *bitstream)
610{
611    Int length = 0;
612
613    if (run < 2 && level < 4)
614    {
615        length = coeff_tab2[run][level-1].len;
616        if (length)
617        {
618            BitstreamPutGT8Bits(bitstream, 7 + 2, 14/*3*/);
619            //BitstreamPutBits(bitstream, 2, 2);
620            BitstreamPutBits(bitstream, length, (UInt)coeff_tab2[run][level-1].code);
621            length += 9;
622        }
623    }
624    else if (run > 1 && run < 42 && level == 1)
625    {
626        length = coeff_tab3[run-2].len;
627        if (length)
628        {
629            BitstreamPutGT8Bits(bitstream, 7 + 2, 14/*3*/);
630            //BitstreamPutBits(bitstream, 2, 2);
631            BitstreamPutBits(bitstream, length, (UInt)coeff_tab3[run-2].code);
632            length += 9;
633        }
634    }
635    return length;
636}
637
638Int PutRunCoeff_Intra(Int run, Int level, BitstreamEncVideo *bitstream)
639{
640    Int length = 0;
641
642    if (run == 0 && level < 28)
643    {
644        length = coeff_tab4[level-1].len;
645        if (length)
646        {
647            BitstreamPutGT8Bits(bitstream, 7 + 2, 14/*3*/);
648            //BitstreamPutBits(bitstream, 2, 2);
649            BitstreamPutBits(bitstream, length, (UInt)coeff_tab4[level-1].code);
650            length += 9;
651        }
652    }
653    else if (run == 1 && level < 11)
654    {
655        length = coeff_tab5[level-1].len;
656        if (length)
657        {
658            BitstreamPutGT8Bits(bitstream, 7 + 2, 14/*3*/);
659            //BitstreamPutBits(bitstream, 2, 2);
660            BitstreamPutBits(bitstream, length, (UInt)coeff_tab5[level-1].code);
661            length += 9;
662        }
663    }
664    else if (run > 1 && run < 10 && level < 6)
665    {
666        length = coeff_tab6[run-2][level-1].len;
667        if (length)
668        {
669            BitstreamPutGT8Bits(bitstream, 7 + 2, 14/*3*/);
670            //BitstreamPutBits(bitstream, 2, 2);
671            BitstreamPutBits(bitstream, length, (UInt)coeff_tab6[run-2][level-1].code);
672            length += 9;
673        }
674    }
675    else if (run > 9 && run < 15 && level == 1)
676    {
677        length = coeff_tab7[run-10].len;
678        if (length)
679        {
680            BitstreamPutGT8Bits(bitstream, 7 + 2, 14/*3*/);
681            //BitstreamPutBits(bitstream, 2, 2);
682            BitstreamPutBits(bitstream, length, (UInt)coeff_tab7[run-10].code);
683            length += 9;
684        }
685    }
686    return length;
687}
688Int PutRunCoeff_Intra_Last(Int run, Int level, BitstreamEncVideo *bitstream)
689{
690    Int length = 0;
691
692    if (run == 0 && level < 9)
693    {
694        length = coeff_tab8[level-1].len;
695        if (length)
696        {
697            BitstreamPutGT8Bits(bitstream, 7 + 2, 14/*3*/);
698            //BitstreamPutBits(bitstream, 2, 2);
699            BitstreamPutBits(bitstream, length, (UInt)coeff_tab8[level-1].code);
700            length += 9;
701        }
702    }
703    else if (run > 0 && run < 7 && level < 4)
704    {
705        length = coeff_tab9[run-1][level-1].len;
706        if (length)
707        {
708            BitstreamPutGT8Bits(bitstream, 7 + 2, 14/*3*/);
709            //BitstreamPutBits(bitstream, 2, 2);
710            BitstreamPutBits(bitstream, length, (UInt)coeff_tab9[run-1][level-1].code);
711            length += 9;
712        }
713    }
714    else if (run > 6 && run < 21 && level == 1)
715    {
716        length = coeff_tab10[run-7].len;
717        if (length)
718        {
719            BitstreamPutGT8Bits(bitstream, 7 + 2, 14/*3*/);
720            //BitstreamPutBits(bitstream, 2, 2);
721            BitstreamPutBits(bitstream, length, (UInt)coeff_tab10[run-7].code);
722            length += 9;
723        }
724    }
725    return length;
726}
727
728Int
729PutLevelCoeff_Inter(Int run, Int level, BitstreamEncVideo *bitstream)
730{
731    Int length = 0;
732
733    if (run < 2 && level < 13)
734    {
735        length = coeff_tab0[run][level-1].len;
736        if (length)
737        {
738            BitstreamPutBits(bitstream, 7 + 1, 6/*3*/);
739            BitstreamPutBits(bitstream, length, (UInt)coeff_tab0[run][level-1].code);
740            length += 8;
741        }
742    }
743    else if (run > 1 && run < 27 && level < 5)
744    {
745        length = coeff_tab1[run-2][level-1].len;
746        if (length)
747        {
748            BitstreamPutBits(bitstream, 7 + 1, 6/*3*/);
749            BitstreamPutBits(bitstream, length, (UInt)coeff_tab1[run-2][level-1].code);
750            length += 8;
751        }
752    }
753    return length;
754}
755
756Int PutLevelCoeff_Inter_Last(Int run, Int level, BitstreamEncVideo *bitstream)
757{
758    Int length = 0;
759
760    if (run < 2 && level < 4)
761    {
762        length = coeff_tab2[run][level-1].len;
763        if (length)
764        {
765            BitstreamPutBits(bitstream, 7 + 1, 6/*3*/);
766            BitstreamPutBits(bitstream, length, (UInt)coeff_tab2[run][level-1].code);
767            length += 8;
768        }
769    }
770    else if (run > 1 && run < 42 && level == 1)
771    {
772        length = coeff_tab3[run-2].len;
773        if (length)
774        {
775            BitstreamPutBits(bitstream, 7 + 1, 6/*3*/);
776            BitstreamPutBits(bitstream, length, (UInt)coeff_tab3[run-2].code);
777            length += 8;
778        }
779    }
780    return length;
781}
782
783Int PutLevelCoeff_Intra(Int run, Int level, BitstreamEncVideo *bitstream)
784{
785    Int length = 0;
786
787    if (run == 0 && level < 28)
788    {
789        length = coeff_tab4[level-1].len;
790        if (length)
791        {
792            BitstreamPutBits(bitstream, 7 + 1, 6/*3*/);
793            BitstreamPutBits(bitstream, length, (UInt)coeff_tab4[level-1].code);
794            length += 8;
795        }
796    }
797    else if (run == 1 && level < 11)
798    {
799        length = coeff_tab5[level-1].len;
800        if (length)
801        {
802            BitstreamPutBits(bitstream, 7 + 1, 6/*3*/);
803            BitstreamPutBits(bitstream, length, (UInt)coeff_tab5[level-1].code);
804            length += 8;
805        }
806    }
807    else if (run > 1 && run < 10 && level < 6)
808    {
809        length = coeff_tab6[run-2][level-1].len;
810        if (length)
811        {
812            BitstreamPutBits(bitstream, 7 + 1, 6/*3*/);
813            BitstreamPutBits(bitstream, length, (UInt)coeff_tab6[run-2][level-1].code);
814            length += 8;
815        }
816    }
817    else if (run > 9 && run < 15 && level == 1)
818    {
819        length = coeff_tab7[run-10].len;
820        if (length)
821        {
822            BitstreamPutBits(bitstream, 7 + 1, 6/*3*/);
823            BitstreamPutBits(bitstream, length, (UInt)coeff_tab7[run-10].code);
824            length += 8;
825        }
826    }
827    return length;
828}
829Int PutLevelCoeff_Intra_Last(Int run, Int level, BitstreamEncVideo *bitstream)
830{
831    Int length = 0;
832
833    if (run == 0 && level < 9)
834    {
835        length = coeff_tab8[level-1].len;
836        if (length)
837        {
838            BitstreamPutBits(bitstream, 7 + 1, 6/*3*/);
839            BitstreamPutBits(bitstream, length, (UInt)coeff_tab8[level-1].code);
840            length += 8;
841        }
842    }
843    else if (run > 0 && run < 7 && level < 4)
844    {
845        length = coeff_tab9[run-1][level-1].len;
846        if (length)
847        {
848            BitstreamPutBits(bitstream, 7 + 1, 6/*3*/);
849            BitstreamPutBits(bitstream, length, (UInt)coeff_tab9[run-1][level-1].code);
850            length += 8;
851        }
852    }
853    else if (run > 6 && run < 21 && level == 1)
854    {
855        length = coeff_tab10[run-7].len;
856        if (length)
857        {
858            BitstreamPutBits(bitstream, 7 + 1, 6/*3*/);
859            BitstreamPutBits(bitstream, length, (UInt)coeff_tab10[run-7].code);
860            length += 8;
861        }
862    }
863    return length;
864}
865
866
867
868/* ======================================================================== */
869/*  Function : MBVlcEncode()                                                */
870/*  Date     : 09/10/2000                                                   */
871/*  Purpose  : Encode GOV Header                                            */
872/*  In/out   :                                                              */
873/*  Return   :                                                              */
874/*  Modified : 5/21/01, break up into smaller functions                     */
875/* ======================================================================== */
876#ifndef H263_ONLY
877/**************************************/
878/* Data Partitioning I-VOP Encoding   */
879/**************************************/
880
881void MBVlcEncodeDataPar_I_VOP(
882    VideoEncData *video,
883    Int ncoefblck[],
884    void *blkCodePtr)
885{
886
887    BitstreamEncVideo *bs1 = video->bitstream1;
888    BitstreamEncVideo *bs2 = video->bitstream2;
889    BitstreamEncVideo *bs3 = video->bitstream3;
890    int i;
891    UChar Mode = video->headerInfo.Mode[video->mbnum];
892    UChar CBP;
893//  MacroBlock *MB=video->outputMB;
894    Int mbnum = video->mbnum;
895    Int intraDC_decision, DC;
896//  int temp;
897    Int dquant; /* 3/15/01 */
898    RunLevelBlock *RLB = video->RLB;
899    BlockCodeCoeffPtr BlockCodeCoeff = (BlockCodeCoeffPtr) blkCodePtr;
900
901    /* DC and AC Prediction, 5/28/01, compute CBP, intraDC_decision*/
902    DCACPred(video, Mode, &intraDC_decision, video->QP_prev);
903
904    /* CBP, Run, Level, and Sign */
905    RunLevel(video, 1, intraDC_decision, ncoefblck);
906    CBP = video->headerInfo.CBP[mbnum];
907
908    /* Compute DQuant */
909    dquant = video->QPMB[mbnum] - video->QP_prev; /* 3/15/01, QP_prev may not equal QPMB[mbnum-1] if mbnum-1 is skipped*/
910
911    video->QP_prev = video->QPMB[mbnum];
912
913    if (dquant && Mode == MODE_INTRA)
914    {
915        Mode = MODE_INTRA_Q;
916    }
917
918    if (dquant >= 0)
919        dquant = (PV_ABS(dquant) + 1);
920    else
921        dquant = (PV_ABS(dquant) - 1);
922
923    /* FIRST PART: ALL TO BS1 */
924
925    PutMCBPC_Intra(CBP, Mode, bs1); /* MCBPC */
926
927    if (Mode == MODE_INTRA_Q)
928        /*  MAY NEED TO CHANGE DQUANT HERE  */
929        BitstreamPutBits(bs1, 2, dquant);  /* dquant*/
930
931
932    if (intraDC_decision == 0)
933    {
934        for (i = 0; i < 6; i++)
935        {
936            DC = video->RLB[i].level[0];
937            if (video->RLB[i].s[0])
938                DC = -DC;
939            if (i < 4)
940                /*temp =*/ IntraDC_dpcm(DC, 1, bs1);        /* dct_dc_size_luminance, */
941            else                                    /* dct_dc_differential, and */
942                /*temp =*/ IntraDC_dpcm(DC, 0, bs1);        /* marker bit */
943        }
944    }
945
946    /* SECOND PART: ALL TO BS2*/
947
948    BitstreamPut1Bits(bs2, video->acPredFlag[video->mbnum]);    /* ac_pred_flag */
949
950    /*temp=*/
951    PutCBPY(CBP >> 2, (Char)(1), bs2); /* cbpy */
952
953
954    /* THIRD PART:  ALL TO BS3*/
955    /* MB_CodeCoeff(video,bs3); */ /* 5/22/01, replaced with below */
956    for (i = 0; i < 6; i++)
957    {
958        if (CBP&(1 << (5 - i)))
959            (*BlockCodeCoeff)(&(RLB[i]), bs3, 1 - intraDC_decision, ncoefblck[i], Mode);/* Code Intra AC*/
960    }
961
962    return ;
963}
964
965/************************************/
966/* Data Partitioning P-VOP Encoding */
967/************************************/
968
969void MBVlcEncodeDataPar_P_VOP(
970    VideoEncData *video,
971    Int ncoefblck[],
972    void *blkCodePtr)
973{
974
975    BitstreamEncVideo *bs1 = video->bitstream1;
976    BitstreamEncVideo *bs2 = video->bitstream2;
977    BitstreamEncVideo *bs3 = video->bitstream3;
978    int i;
979    Int mbnum = video->mbnum;
980    UChar Mode = video->headerInfo.Mode[mbnum];
981    Int QP_tmp = video->QPMB[mbnum];
982    UChar CBP;
983//  MacroBlock *MB=video->outputMB;
984    Int intra, intraDC_decision, DC;
985    Int pmvx, pmvy;
986//  int temp;
987    Int dquant; /* 3/15/01 */
988    RunLevelBlock *RLB = video->RLB;
989    BlockCodeCoeffPtr BlockCodeCoeff = (BlockCodeCoeffPtr) blkCodePtr;
990
991    intra = (Mode == MODE_INTRA || Mode == MODE_INTRA_Q);
992
993    /* DC and AC Prediction, 5/28/01, compute CBP, intraDC_decision*/
994
995    if (intra)
996    {
997        if (video->usePrevQP)
998        {
999            QP_tmp = video->QPMB[mbnum-1];
1000        }
1001
1002        DCACPred(video, Mode, &intraDC_decision, QP_tmp);
1003    }
1004    else
1005        intraDC_decision = 0; /* used in RunLevel */
1006
1007    /* CBP, Run, Level, and Sign */
1008    RunLevel(video, intra, intraDC_decision, ncoefblck);
1009    CBP = video->headerInfo.CBP[mbnum];
1010
1011    /* Compute DQuant */
1012    dquant = video->QPMB[mbnum] - video->QP_prev; /* 3/15/01, QP_prev may not equal QPMB[mbnum-1] if mbnum-1 is skipped*/
1013
1014    if (dquant && (Mode == MODE_INTRA || Mode == MODE_INTER))
1015    {
1016        Mode += 2;  /* make it MODE_INTRA_Q and MODE_INTER_Q */
1017    }
1018
1019    if (dquant >= 0)
1020        dquant = (PV_ABS(dquant) + 1);
1021    else
1022        dquant = (PV_ABS(dquant) - 1);
1023
1024    /* FIRST PART: ALL TO BS1 */
1025
1026    if (CBP == 0 && intra == 0)  /* Determine if Skipped MB */
1027    {
1028        if ((Mode == MODE_INTER) && (video->mot[mbnum][0].x == 0) && (video->mot[mbnum][0].y == 0))
1029            Mode = video->headerInfo.Mode[video->mbnum] = MODE_SKIPPED;
1030        else if ((Mode == MODE_INTER4V) && (video->mot[mbnum][1].x == 0) && (video->mot[mbnum][1].y == 0)
1031                 && (video->mot[mbnum][2].x == 0) && (video->mot[mbnum][2].y == 0)
1032                 && (video->mot[mbnum][3].x == 0) && (video->mot[mbnum][3].y == 0)
1033                 && (video->mot[mbnum][4].x == 0) && (video->mot[mbnum][4].y == 0))
1034            Mode = video->headerInfo.Mode[video->mbnum] = MODE_SKIPPED;
1035    }
1036
1037
1038    if (Mode == MODE_SKIPPED)
1039    {
1040        BitstreamPut1Bits(bs1, 1); /* not_coded = 1 */
1041        return;
1042    }
1043    else
1044        BitstreamPut1Bits(bs1, 0); /* not_coded =0 */
1045
1046    video->QP_prev = video->QPMB[mbnum];
1047    video->usePrevQP = 1;
1048
1049    PutMCBPC_Inter(CBP, Mode, bs1); /* MCBPC */
1050
1051    video->header_bits -= BitstreamGetPos(bs1); /* Header Bits */
1052
1053    if (Mode == MODE_INTER || Mode == MODE_INTER_Q)
1054    {
1055        find_pmvs(video, 0, &pmvx, &pmvy); /* Get predicted motion vectors */
1056        WriteMVcomponent(video->currVop->fcodeForward, video->mot[mbnum][0].x - pmvx, bs1); /* Write x to bitstream */
1057        WriteMVcomponent(video->currVop->fcodeForward, video->mot[mbnum][0].y - pmvy, bs1);     /* Write y to bitstream */
1058    }
1059    else if (Mode == MODE_INTER4V)
1060    {
1061        for (i = 1; i < 5; i++)
1062        {
1063            find_pmvs(video, i, &pmvx, &pmvy);
1064            WriteMVcomponent(video->currVop->fcodeForward, video->mot[mbnum][i].x - pmvx, bs1);
1065            WriteMVcomponent(video->currVop->fcodeForward, video->mot[mbnum][i].y - pmvy, bs1);
1066        }
1067    }
1068    video->header_bits += BitstreamGetPos(bs1); /* Header Bits */
1069
1070    /* SECOND PART: ALL TO BS2 */
1071
1072
1073    if (intra)
1074    {
1075        BitstreamPut1Bits(bs2, video->acPredFlag[video->mbnum]);    /* ac_pred_flag */
1076        /*temp=*/
1077        PutCBPY(CBP >> 2, (Char)(Mode == MODE_INTRA || Mode == MODE_INTRA_Q), bs2); /* cbpy */
1078
1079        if (Mode == MODE_INTRA_Q)
1080            BitstreamPutBits(bs2, 2, dquant);  /* dquant, 3/15/01*/
1081
1082        if (intraDC_decision == 0)
1083        {
1084            for (i = 0; i < 6; i++)
1085            {
1086                DC = video->RLB[i].level[0];
1087                if (video->RLB[i].s[0])
1088                    DC = -DC;
1089                if (i < 4)
1090                    /*temp =*/ IntraDC_dpcm(DC, 1, bs2);        /* dct_dc_size_luminance, */
1091                else                                    /* dct_dc_differential, and */
1092                    /*temp =*/ IntraDC_dpcm(DC, 0, bs2);        /* marker bit */
1093            }
1094        }
1095
1096        /****************************/  /* THIRD PART: ALL TO BS3 */
1097        for (i = 0; i < 6; i++)
1098        {
1099            if (CBP&(1 << (5 - i)))
1100                (*BlockCodeCoeff)(&(RLB[i]), bs3, 1 - intraDC_decision, ncoefblck[i], Mode);/* Code Intra AC*/
1101        }
1102    }
1103    else
1104    {
1105        /*temp=*/
1106        PutCBPY(CBP >> 2, (Char)(Mode == MODE_INTRA || Mode == MODE_INTRA_Q), bs2); /* cbpy */
1107        if (Mode == MODE_INTER_Q)
1108            /*  MAY NEED TO CHANGE DQUANT HERE  */
1109            BitstreamPutBits(bs2, 2, dquant);  /* dquant, 3/15/01*/
1110
1111        /****************************/  /* THIRD PART: ALL TO BS3 */
1112        for (i = 0; i < 6; i++)
1113        {
1114            if (CBP&(1 << (5 - i)))
1115                (*BlockCodeCoeff)(&(RLB[i]), bs3, 0, ncoefblck[i], Mode);/* Code Intra AC*/
1116        }
1117    }
1118
1119    return ;
1120}
1121#endif /* H263_ONLY */
1122/****************************************************************************************/
1123/* Short Header/Combined Mode with or without Error Resilience I-VOP and P-VOP Encoding */
1124/* 5/21/01, B-VOP is not implemented yet!!!!                                            */
1125/****************************************************************************************/
1126
1127void MBVlcEncodeCombined_I_VOP(
1128    VideoEncData *video,
1129    Int ncoefblck[],
1130    void *blkCodePtr)
1131{
1132
1133    BitstreamEncVideo *bs1 = video->bitstream1;
1134//  BitstreamEncVideo *bs2 = video->bitstream2;
1135//  BitstreamEncVideo *bs3 = video->bitstream3;
1136    int i;
1137    UChar Mode = video->headerInfo.Mode[video->mbnum];
1138    UChar CBP = video->headerInfo.CBP[video->mbnum];
1139//  MacroBlock *MB=video->outputMB;
1140    Int mbnum = video->mbnum;
1141    Int intraDC_decision;
1142//  int temp;
1143    Int dquant; /* 3/15/01 */
1144    RunLevelBlock *RLB = video->RLB;
1145    Int DC;
1146    Int shortVideoHeader = video->vol[video->currLayer]->shortVideoHeader;
1147    BlockCodeCoeffPtr BlockCodeCoeff = (BlockCodeCoeffPtr) blkCodePtr;
1148
1149    /* DC and AC Prediction, 5/28/01, compute CBP, intraDC_decision*/
1150
1151#ifndef H263_ONLY
1152    if (!shortVideoHeader)
1153        DCACPred(video, Mode, &intraDC_decision, video->QP_prev);
1154    else
1155#endif
1156    {
1157        intraDC_decision = 0;
1158    }
1159
1160    /* CBP, Run, Level, and Sign */
1161
1162    RunLevel(video, 1, intraDC_decision, ncoefblck);
1163    CBP = video->headerInfo.CBP[mbnum];
1164
1165    /* Compute DQuant */
1166    dquant = video->QPMB[mbnum] - video->QP_prev; /* 3/15/01, QP_prev may not equal QPMB[mbnum-1] if mbnum-1 is skipped*/
1167
1168    video->QP_prev = video->QPMB[mbnum];
1169
1170    if (dquant && Mode == MODE_INTRA)
1171    {
1172        Mode = MODE_INTRA_Q;
1173    }
1174
1175    if (dquant >= 0)
1176        dquant = (PV_ABS(dquant) + 1);
1177    else
1178        dquant = (PV_ABS(dquant) - 1);
1179
1180    PutMCBPC_Intra(CBP, Mode, bs1); /* mcbpc I_VOP */
1181
1182    if (!video->vol[video->currLayer]->shortVideoHeader)
1183    {
1184        BitstreamPut1Bits(bs1, video->acPredFlag[video->mbnum]);    /* ac_pred_flag */
1185    }
1186
1187    /*temp=*/
1188    PutCBPY(CBP >> 2, (Char)(1), bs1); /* cbpy */
1189
1190    if (Mode == MODE_INTRA_Q)
1191        /*  MAY NEED TO CHANGE DQUANT HERE */
1192        BitstreamPutBits(bs1, 2, dquant);  /* dquant, 3/15/01*/
1193
1194    /*MB_CodeCoeff(video,bs1); 5/21/01, replaced by below */
1195    /*******************/
1196#ifndef H263_ONLY
1197    if (shortVideoHeader) /* Short Header DC coefficients */
1198    {
1199#endif
1200        for (i = 0; i < 6; i++)
1201        {
1202            DC = RLB[i].level[0];
1203            if (RLB[i].s[0])
1204                DC = -DC;
1205            if (DC != 128)
1206                BitstreamPutBits(bs1, 8, DC);   /* intra_dc_size_luminance */
1207            else
1208                BitstreamPutBits(bs1, 8, 255);          /* intra_dc_size_luminance */
1209            if (CBP&(1 << (5 - i)))
1210                (*BlockCodeCoeff)(&(RLB[i]), bs1, 1, ncoefblck[i], Mode); /* Code short header Intra AC*/
1211        }
1212#ifndef H263_ONLY
1213    }
1214    else if (intraDC_decision == 0)   /* Combined Intra Mode DC and AC coefficients */
1215    {
1216        for (i = 0; i < 6; i++)
1217        {
1218            DC = RLB[i].level[0];
1219            if (RLB[i].s[0])
1220                DC = -DC;
1221
1222            if (i < 4)
1223                /*temp =*/ IntraDC_dpcm(DC, 1, bs1);        /* dct_dc_size_luminance, */
1224            else                                                /* dct_dc_differential, and */
1225                /*temp =*/ IntraDC_dpcm(DC, 0, bs1);        /* marker bit */
1226            if (CBP&(1 << (5 - i)))
1227                (*BlockCodeCoeff)(&(RLB[i]), bs1, 1, ncoefblck[i], Mode);/* Code Intra AC */
1228        }
1229    }
1230    else   /* Combined Mode Intra DC/AC coefficients */
1231    {
1232        for (i = 0; i < 6; i++)
1233        {
1234            if (CBP&(1 << (5 - i)))
1235                (*BlockCodeCoeff)(&(RLB[i]), bs1, 0, ncoefblck[i], Mode);/* Code Intra AC */
1236        }
1237    }
1238#endif
1239    /*******************/
1240    return ;
1241}
1242
1243void MBVlcEncodeCombined_P_VOP(
1244    VideoEncData *video,
1245    Int ncoefblck[],
1246    void *blkCodePtr)
1247{
1248
1249    BitstreamEncVideo *bs1 = video->bitstream1;
1250//  BitstreamEncVideo *bs2 = video->bitstream2;
1251//  BitstreamEncVideo *bs3 = video->bitstream3;
1252    int i;
1253    Int mbnum = video->mbnum;
1254    UChar Mode = video->headerInfo.Mode[mbnum];
1255    Int QP_tmp = video->QPMB[mbnum];
1256    UChar CBP ;
1257//  MacroBlock *MB=video->outputMB;
1258    Int intra, intraDC_decision;
1259    Int pmvx, pmvy;
1260//  int temp;
1261    Int dquant; /* 3/15/01 */
1262    RunLevelBlock *RLB = video->RLB;
1263    Int DC;
1264    Int shortVideoHeader = video->vol[video->currLayer]->shortVideoHeader;
1265    BlockCodeCoeffPtr BlockCodeCoeff = (BlockCodeCoeffPtr) blkCodePtr;
1266
1267    intra = (Mode == MODE_INTRA || Mode == MODE_INTRA_Q);
1268
1269    /* DC and AC Prediction, 5/28/01, compute intraDC_decision*/
1270#ifndef H263_ONLY
1271    if (!shortVideoHeader && intra)
1272    {
1273        if (video->usePrevQP)
1274        {
1275            QP_tmp = video->QPMB[mbnum-1];
1276        }
1277        DCACPred(video, Mode, &intraDC_decision, QP_tmp);
1278    }
1279    else
1280#endif
1281        intraDC_decision = 0;
1282
1283    /* CBP, Run, Level, and Sign */
1284
1285    RunLevel(video, intra, intraDC_decision, ncoefblck);
1286    CBP = video->headerInfo.CBP[mbnum];
1287
1288    /* Compute DQuant */
1289    dquant = video->QPMB[mbnum] - video->QP_prev; /* 3/15/01, QP_prev may not equal QPMB[mbnum-1] if mbnum-1 is skipped*/
1290    if (dquant && (Mode == MODE_INTRA || Mode == MODE_INTER))
1291    {
1292        Mode += 2;  /* make it MODE_INTRA_Q and MODE_INTER_Q */
1293    }
1294
1295    if (dquant >= 0)
1296        dquant = (PV_ABS(dquant) + 1);
1297    else
1298        dquant = (PV_ABS(dquant) - 1);
1299
1300    if (CBP == 0 && intra == 0)  /* Determine if Skipped MB */
1301    {
1302        if ((Mode == MODE_INTER) && (video->mot[mbnum][0].x == 0) && (video->mot[mbnum][0].y == 0))
1303            Mode = video->headerInfo.Mode[video->mbnum] = MODE_SKIPPED;
1304        else if ((Mode == MODE_INTER4V) && (video->mot[mbnum][1].x == 0) && (video->mot[mbnum][1].y == 0)
1305                 && (video->mot[mbnum][2].x == 0) && (video->mot[mbnum][2].y == 0)
1306                 && (video->mot[mbnum][3].x == 0) && (video->mot[mbnum][3].y == 0)
1307                 && (video->mot[mbnum][4].x == 0) && (video->mot[mbnum][4].y == 0))
1308            Mode = video->headerInfo.Mode[video->mbnum] = MODE_SKIPPED;
1309    }
1310
1311    if (Mode == MODE_SKIPPED)
1312    {
1313        BitstreamPut1Bits(bs1, 1); /* not_coded = 1 */
1314        return;
1315    }
1316    else
1317        BitstreamPut1Bits(bs1, 0); /* not_coded =0 */
1318
1319    video->QP_prev = video->QPMB[mbnum];
1320    video->usePrevQP = 1;
1321
1322    PutMCBPC_Inter(CBP, Mode, bs1); /* mcbpc P_VOP */
1323
1324    if (!video->vol[video->currLayer]->shortVideoHeader && intra)
1325    {
1326        BitstreamPut1Bits(bs1, video->acPredFlag[video->mbnum]);    /* ac_pred_flag */
1327    }
1328
1329    /*temp=*/
1330    PutCBPY(CBP >> 2, (Char)(intra), bs1); /* cbpy */
1331
1332    if (Mode == MODE_INTRA_Q || Mode == MODE_INTER_Q)
1333        /*  MAY NEED TO CHANGE DQUANT HERE  */
1334        BitstreamPutBits(bs1, 2, dquant);  /* dquant, 3/15/01*/
1335
1336    video->header_bits -= BitstreamGetPos(bs1); /* Header Bits */
1337
1338    if (!((video->vol[video->currLayer]->scalability) && (video->currVop->refSelectCode == 3)))
1339    {
1340        if (Mode == MODE_INTER || Mode == MODE_INTER_Q)
1341        {
1342            find_pmvs(video, 0, &pmvx, &pmvy); /* Get predicted motion vectors */
1343            WriteMVcomponent(video->currVop->fcodeForward, video->mot[mbnum][0].x - pmvx, bs1); /* Write x to bitstream */
1344            WriteMVcomponent(video->currVop->fcodeForward, video->mot[mbnum][0].y - pmvy, bs1);     /* Write y to bitstream */
1345        }
1346        else if (Mode == MODE_INTER4V)
1347        {
1348            for (i = 1; i < 5; i++)
1349            {
1350                find_pmvs(video, i, &pmvx, &pmvy);
1351                WriteMVcomponent(video->currVop->fcodeForward, video->mot[mbnum][i].x - pmvx, bs1);
1352                WriteMVcomponent(video->currVop->fcodeForward, video->mot[mbnum][i].y - pmvy, bs1);
1353            }
1354        }
1355    }
1356    video->header_bits += BitstreamGetPos(bs1); /* Header Bits */
1357
1358    /* MB_CodeCoeff(video,bs1); */ /* 5/22/01, replaced with below */
1359    /****************************/
1360    if (intra)
1361    {
1362#ifndef H263_ONLY
1363        if (shortVideoHeader) /* Short Header DC coefficients */
1364        {
1365#endif
1366            for (i = 0; i < 6; i++)
1367            {
1368                DC = RLB[i].level[0];
1369                if (RLB[i].s[0])
1370                    DC = -DC;
1371                if (DC != 128)
1372                    BitstreamPutBits(bs1, 8, DC);   /* intra_dc_size_luminance */
1373                else
1374                    BitstreamPutBits(bs1, 8, 255);          /* intra_dc_size_luminance */
1375                if (CBP&(1 << (5 - i)))
1376                    (*BlockCodeCoeff)(&(RLB[i]), bs1, 1, ncoefblck[i], Mode); /* Code short header Intra AC*/
1377            }
1378#ifndef H263_ONLY
1379        }
1380        else if (intraDC_decision == 0)   /* Combined Intra Mode DC and AC coefficients */
1381        {
1382            for (i = 0; i < 6; i++)
1383            {
1384                DC = RLB[i].level[0];
1385                if (RLB[i].s[0])
1386                    DC = -DC;
1387
1388                if (i < 4)
1389                    /*temp =*/ IntraDC_dpcm(DC, 1, bs1);        /* dct_dc_size_luminance, */
1390                else                                                /* dct_dc_differential, and */
1391                    /*temp =*/ IntraDC_dpcm(DC, 0, bs1);        /* marker bit */
1392                if (CBP&(1 << (5 - i)))
1393                    (*BlockCodeCoeff)(&(RLB[i]), bs1, 1, ncoefblck[i], Mode);/* Code Intra AC */
1394            }
1395        }
1396        else   /* Combined Mode Intra DC/AC coefficients */
1397        {
1398            for (i = 0; i < 6; i++)
1399            {
1400                if (CBP&(1 << (5 - i)))
1401                    (*BlockCodeCoeff)(&(RLB[i]), bs1, 0, ncoefblck[i], Mode);/* Code Intra AC */
1402            }
1403        }
1404#endif
1405    }
1406    else   /* Shortheader or Combined INTER Mode AC coefficients */
1407    {
1408        for (i = 0; i < 6; i++)
1409        {
1410            if (CBP&(1 << (5 - i)))
1411                (*BlockCodeCoeff)(&(RLB[i]), bs1, 0, ncoefblck[i], Mode);/* Code Inter AC*/
1412        }
1413    }
1414    /****************************/
1415
1416    return ;
1417}
1418
1419/* ======================================================================== */
1420/*  Function : BlockCodeCoeff()                                         */
1421/*  Date     : 09/18/2000                                                   */
1422/*  Purpose  : VLC Encode  AC/DC coeffs                                     */
1423/*  In/out   :                                                              */
1424/*  Return   :                                                              */
1425/*  Modified :  5/16/01  grouping BitstreamPutBits calls                    */
1426/*              5/22/01  break up function                              */
1427/* ======================================================================== */
1428#ifndef NO_RVLC
1429/*****************/
1430/* RVLC ENCODING */
1431/*****************/
1432Void BlockCodeCoeff_RVLC(RunLevelBlock *RLB, BitstreamEncVideo *bs, Int j_start, Int j_stop, UChar Mode)
1433{
1434    int length = 0;
1435    int i;
1436    Int level;
1437    Int run;
1438    Int intra = (Mode == MODE_INTRA || Mode == MODE_INTRA_Q);
1439
1440    /* Not Last Coefficient */
1441    for (i = j_start; i < j_stop - 1; i++)
1442    {
1443        run = RLB->run[i];
1444        level = RLB->level[i];
1445        //if(i==63||RLB->run[i+1] == -1)    /* Don't Code Last Coefficient Here */
1446        //  break;
1447        /*ENCODE RUN LENGTH */
1448        if (level < 28 && run < 39)
1449        {
1450            if (intra)
1451                length = PutCoeff_Intra_RVLC(run, level, bs);
1452            else
1453                length = PutCoeff_Inter_RVLC(run, level, bs);
1454        }
1455        else
1456            length = 0;
1457        /* ESCAPE CODING */
1458        if (length == 0)
1459        {
1460            BitstreamPutBits(bs, 5 + 1, 2); /* ESCAPE + Not Last Coefficient */
1461            //BitstreamPutBits(bs,1,0); /* Not Last Coefficient */
1462            BitstreamPutBits(bs, 6 + 1, (run << 1) | 1); /* RUN + MARKER BIT*/
1463            //BitstreamPutBits(bs,1,1);  /* MARKER BIT */
1464            BitstreamPutGT8Bits(bs, 11, level); /* LEVEL */
1465            BitstreamPutBits(bs, 1 + 4, 16); /* MARKER BIT */
1466            //BitstreamPutBits(bs,4,0);  /* RVLC TRAILING ESCAPE */
1467        }
1468        BitstreamPutBits(bs, 1, RLB->s[i]); /* SIGN BIT */
1469    }
1470    /* Last Coefficient!!! */
1471    run = RLB->run[i];
1472    level = RLB->level[i];
1473
1474    /*ENCODE RUN LENGTH */
1475    if (level < 6 && run < 45)
1476    {
1477        if (intra)
1478            length = PutCoeff_Intra_RVLC_Last(run, level, bs);
1479        else
1480            length = PutCoeff_Inter_RVLC_Last(run, level, bs);
1481    }
1482    else
1483        length = 0;
1484    /* ESCAPE CODING */
1485    if (length == 0)
1486    {
1487        BitstreamPutBits(bs, 5 + 1, 3); /* ESCAPE CODE + Last Coefficient*/
1488        //BitstreamPutBits(bs,1,1); /* Last Coefficient !*/
1489        BitstreamPutBits(bs, 6 + 1, (run << 1) | 1); /* RUN + MARKER BIT*/
1490        //BitstreamPutBits(bs,1,1);  /* MARKER BIT */
1491        BitstreamPutGT8Bits(bs, 11, level); /* LEVEL */
1492        BitstreamPutBits(bs, 1 + 4, 16); /* MARKER BIT + RVLC TRAILING ESCAPE */
1493        //BitstreamPutBits(bs,4,0);  /* */
1494    }
1495    BitstreamPut1Bits(bs, RLB->s[i]); /* SIGN BIT */
1496
1497    return ;
1498}
1499#endif
1500/*******************************/
1501/* SHORT VIDEO HEADER ENCODING */
1502/*******************************/
1503
1504Void BlockCodeCoeff_ShortHeader(RunLevelBlock *RLB, BitstreamEncVideo *bs, Int j_start, Int j_stop, UChar Mode)
1505{
1506    int length = 0;
1507    int i;
1508//  int temp;
1509    Int level;
1510    Int run;
1511
1512    OSCL_UNUSED_ARG(Mode);
1513
1514    /* Not Last Coefficient */
1515    for (i = j_start; i < j_stop - 1; i++)
1516    {
1517        run = RLB->run[i];
1518        level = RLB->level[i];
1519//      if(i==63 ||RLB->run[i+1] == -1) /* Don't Code Last Coefficient Here */
1520//          break;
1521        /*ENCODE RUN LENGTH */
1522        if (level < 13)
1523        {
1524            length = PutCoeff_Inter(run, level, bs);
1525            if (length != 0)
1526                /*temp =*/ BitstreamPut1Bits(bs, RLB->s[i]); /* Sign Bit */
1527        }
1528        else
1529            length = 0;
1530        /* ESCAPE CODING */
1531        if (length == 0)
1532        {
1533            if (RLB->s[i])
1534                level = -level;
1535            BitstreamPutBits(bs, 7 + 1, 6); /* ESCAPE CODE + Not Last Coefficient */
1536            //BitstreamPutBits(bs,1,0); /* Not Last Coefficient */
1537            BitstreamPutBits(bs, 6, run); /* RUN */
1538            BitstreamPutBits(bs, 8, level&0xFF); /* LEVEL, mask to make sure length 8 */
1539        }
1540    }
1541    /* Last Coefficient!!! */
1542    run = RLB->run[i];
1543    level = RLB->level[i];
1544
1545    /*ENCODE RUN LENGTH */
1546    if (level < 13)
1547    {
1548        length = PutCoeff_Inter_Last(run, level, bs);
1549        if (length != 0)
1550            /*temp =*/ BitstreamPut1Bits(bs, RLB->s[i]); /* Sign Bit */
1551    }
1552    else
1553        length = 0;
1554    /* ESCAPE CODING */
1555    if (length == 0)
1556    {
1557        if (RLB->s[i])
1558            level = -level;
1559        BitstreamPutBits(bs, 7 + 1, 7); /* ESCAPE CODE + Last Coefficient */
1560        //BitstreamPutBits(bs,1,1); /* Last Coefficient !!!*/
1561        BitstreamPutBits(bs, 6, run); /* RUN */
1562        BitstreamPutBits(bs, 8, level&0xFF); /* LEVEL, mask to make sure length 8  */
1563    }
1564
1565    return ;
1566
1567}
1568
1569#ifndef H263_ONLY
1570/****************/
1571/* VLC ENCODING */
1572/****************/
1573Void BlockCodeCoeff_Normal(RunLevelBlock *RLB, BitstreamEncVideo *bs, Int j_start, Int j_stop, UChar Mode)
1574{
1575    int length = 0;
1576    int i;
1577    //int temp;
1578    Int level;
1579    Int run;
1580    Int intra = (Mode == MODE_INTRA || Mode == MODE_INTRA_Q);
1581    Int level_minus_max;
1582    Int run_minus_max;
1583    Int(*PutCoeff)(Int, Int, BitstreamEncVideo *); /* pointer to functions, 5/28/01 */
1584
1585    /* Not Last Coefficient!!! */
1586
1587    if (intra)
1588        PutCoeff = &PutCoeff_Intra;
1589    else
1590        PutCoeff = &PutCoeff_Inter;
1591
1592    for (i = j_start; i < j_stop - 1; i++)
1593    {
1594        run = RLB->run[i];
1595        level = RLB->level[i];
1596
1597        /* Encode Run Length */
1598        if (level < 28)
1599        {
1600            length = (*PutCoeff)(run, level, bs); /* 5/28/01 replaces above */
1601        }
1602        else
1603        {
1604            length = 0;
1605        }
1606
1607        /* First escape mode: LEVEL OFFSET */
1608        if (length == 0)
1609        {
1610            if (intra)
1611            {
1612                level_minus_max = level - intra_max_level[0][run];
1613                if (level_minus_max < 28)
1614                    length = PutLevelCoeff_Intra(run, level_minus_max, bs);
1615                else
1616                    length = 0;
1617            }
1618            else
1619            {
1620                level_minus_max = level - inter_max_level[0][run];
1621                if (level_minus_max < 13)
1622                    length = PutLevelCoeff_Inter(run, level_minus_max, bs);
1623                else
1624                    length = 0;
1625            }
1626
1627            /* Second escape mode: RUN OFFSET */
1628            if (length == 0)
1629            {
1630                if (level < 28)
1631                {
1632                    if (intra)
1633                    {
1634                        run_minus_max = run - (intra_max_run0[level] + 1);
1635                        length = PutRunCoeff_Intra(run_minus_max, level, bs);
1636                    }
1637                    else if (level < 13)
1638                    {
1639                        run_minus_max = run - (inter_max_run0[level] + 1);
1640                        length = PutRunCoeff_Inter(run_minus_max, level, bs);
1641                    }
1642                    else
1643                    {
1644                        length = 0;
1645                    }
1646                }
1647                else
1648                {
1649                    length = 0;
1650                }
1651
1652                /* Third escape mode: FIXED LENGTH CODE */
1653                if (length == 0)
1654                {
1655                    if (RLB->s[i])
1656                        level = -level;
1657                    /*temp =*/
1658                    BitstreamPutBits(bs, 7 + 2 + 1, 30); /* ESCAPE CODE + Followed by 11 + Not Last Coefficient*/
1659                    //temp = BitstreamPutBits(bs,2,3); /* Followed by 11 */
1660                    //temp = BitstreamPutBits(bs, 1, 0); /* Not Last Coefficient*/
1661                    /*temp =*/
1662                    BitstreamPutBits(bs, 6 + 1, (run << 1) | 1); /* Encode Run + Marker Bit */
1663                    //temp = BitstreamPutBits(bs,1,1); /* Marker Bit */
1664                    /*temp =*/
1665                    BitstreamPutGT8Bits(bs, 12 + 1, ((level << 1) | 1)&0x1FFF); /* Encode Level, mask to make sure length 12  */
1666                    //temp = BitstreamPutBits(bs,1,1); /* Marker Bit */
1667                }
1668            }
1669        }
1670
1671        /* Encode Sign Bit */
1672        if (length != 0)
1673            /*temp =*/ BitstreamPut1Bits(bs, RLB->s[i]); /* Sign Bit */
1674
1675    }
1676    /* Last Coefficient */
1677    run = RLB->run[i];
1678    level = RLB->level[i];
1679
1680    /* Encode Run Length */
1681    if (level < 9)
1682    {
1683        if (intra)
1684        {
1685            length = PutCoeff_Intra_Last(run, level, bs);
1686        }
1687        else if (level < 4)
1688        {
1689            length = PutCoeff_Inter_Last(run, level, bs);
1690        }
1691        else
1692        {
1693            length = 0;
1694        }
1695    }
1696    else
1697    {
1698        length = 0;
1699    }
1700
1701    /* First escape mode: LEVEL OFFSET */
1702    if (length == 0)
1703    {
1704        if (intra)
1705        {
1706            level_minus_max = level - intra_max_level[1][run];
1707            if (level_minus_max < 9)
1708                length = PutLevelCoeff_Intra_Last(run, level_minus_max, bs);
1709            else
1710                length = 0;
1711        }
1712        else
1713        {
1714            level_minus_max = level - inter_max_level[1][run];
1715            if (level_minus_max < 4)
1716                length = PutLevelCoeff_Inter_Last(run, level_minus_max, bs);
1717            else
1718                length = 0;
1719        }
1720        /* Second escape mode: RUN OFFSET */
1721        if (length == 0)
1722        {
1723            if (level < 9)
1724            {
1725                if (intra)
1726                {
1727                    run_minus_max = run - (intra_max_run1[level] + 1);
1728                    length = PutRunCoeff_Intra_Last(run_minus_max, level, bs);
1729                }
1730                else if (level < 4)
1731                {
1732                    run_minus_max = run - (inter_max_run1[level] + 1);
1733                    length = PutRunCoeff_Inter_Last(run_minus_max, level, bs);
1734                }
1735                else
1736                {
1737                    length = 0;
1738                }
1739            }
1740            else
1741            {
1742                length = 0;
1743            }
1744            /* Third escape mode: FIXED LENGTH CODE */
1745            if (length == 0)
1746            {
1747                if (RLB->s[i])
1748                    level = -level;
1749                /*temp =*/
1750                BitstreamPutGT8Bits(bs, 7 + 2 + 1, 31); /* ESCAPE CODE + Followed by 11 + Last Coefficient*/
1751                //temp = BitstreamPutBits(bs,2,3); /* Followed by 11 */
1752                //temp = BitstreamPutBits(bs, 1, 1); /* Last Coefficient!!!*/
1753                /*temp =*/
1754                BitstreamPutBits(bs, 6 + 1, (run << 1) | 1); /* Encode Run + Marker Bit */
1755                //temp = BitstreamPutBits(bs,1,1); /* Marker Bit */
1756                /*temp =*/
1757                BitstreamPutGT8Bits(bs, 12 + 1, ((level << 1) | 1)&0x1FFF); /* Encode Level, mask to make sure length 8 */
1758                //temp = BitstreamPutBits(bs,1,1); /* Marker Bit */
1759            }
1760        }
1761    }
1762
1763    /* Encode Sign Bit */
1764    if (length != 0)
1765        /*temp =*/ BitstreamPut1Bits(bs, RLB->s[i]);
1766
1767
1768    return ;
1769}
1770
1771#endif /* H263_ONLY */
1772/* ======================================================================== */
1773/*  Function : RUNLevel                                                     */
1774/*  Date     : 09/20/2000                                                   */
1775/*  Purpose  : Get the Coded Block Pattern for each block                   */
1776/*  In/out   :                                                              */
1777/*      Int* qcoeff     Quantized DCT coefficients
1778        Int Mode        Coding Mode
1779        Int ncoeffs     Number of coefficients                              */
1780/*  Return   :                                                              */
1781/*      Int CBP         Coded Block Pattern                                 */
1782/*  Modified :                                                              */
1783/* ======================================================================== */
1784
1785void RunLevel(VideoEncData *video, Int intra, Int intraDC_decision, Int ncoefblck[])
1786{
1787    Int i, j;
1788    Int CBP = video->headerInfo.CBP[video->mbnum];
1789    Int ShortNacNintra = (!(video->vol[video->currLayer]->shortVideoHeader) && video->acPredFlag[video->mbnum] && intra);
1790    MacroBlock *MB = video->outputMB;
1791    Short *dataBlock;
1792    Int level;
1793    RunLevelBlock *RLB;
1794    Int run, idx;
1795    Int *zz, nc, zzorder;
1796    UChar imask[6] = {0x1F, 0x2F, 0x37, 0x3B, 0x3D, 0x3E};
1797    UInt *bitmapzz;
1798
1799    /* Set Run, Level and CBP for this Macroblock */
1800    /* ZZ scan is done here.  */
1801
1802    if (intra)
1803    {
1804
1805        if (intraDC_decision != 0)
1806            intra = 0;              /* DC/AC in Run/Level */
1807
1808        for (i = 0; i < 6 ; i++)
1809        {
1810
1811            zz = (Int *) zigzag_inv;
1812
1813            RLB = video->RLB + i;
1814
1815            dataBlock = MB->block[i];
1816
1817            if (intra)
1818            {
1819                RLB->run[0] = 0;
1820                level = dataBlock[0];
1821                dataBlock[0] = 0; /* reset to zero */
1822                if (level < 0)
1823                {
1824                    RLB->level[0] = -level;
1825                    RLB->s[0] = 1;
1826                }
1827                else
1828                {
1829                    RLB->level[0] = level;
1830                    RLB->s[0] = 0;
1831                }
1832            }
1833
1834            idx = intra;
1835
1836            if ((CBP >> (5 - i)) & 1)
1837            {
1838                if (ShortNacNintra)
1839                {
1840                    switch ((video->zz_direction >> (5 - i))&1)
1841                    {
1842                        case 0:
1843                            zz = (Int *)zigzag_v_inv;
1844                            break;
1845                        case 1:
1846                            zz = (Int *)zigzag_h_inv;
1847                            break;
1848                    }
1849                }
1850                run = 0;
1851                nc = ncoefblck[i];
1852                for (j = intra, zz += intra; j < nc; j++, zz++)
1853                {
1854                    zzorder = *zz;
1855                    level = dataBlock[zzorder];
1856                    if (level == 0)
1857                        run++;
1858                    else
1859                    {
1860                        dataBlock[zzorder] = 0; /* reset output */
1861                        if (level < 0)
1862                        {
1863                            RLB->level[idx] = -level;
1864                            RLB->s[idx] = 1;
1865                            RLB->run[idx] = run;
1866                            run = 0;
1867                            idx++;
1868                        }
1869                        else
1870                        {
1871                            RLB->level[idx] = level;
1872                            RLB->s[idx] = 0;
1873                            RLB->run[idx] = run;
1874                            run = 0;
1875                            idx++;
1876                        }
1877                    }
1878                }
1879            }
1880
1881            ncoefblck[i] = idx; /* 5/22/01, reuse ncoefblck */
1882
1883            if (idx == intra) /* reset CBP, nothing to be coded */
1884                CBP &= imask[i];
1885        }
1886
1887        video->headerInfo.CBP[video->mbnum] = CBP;
1888
1889        return ;
1890    }
1891    else
1892    {
1893//      zz = (Int *) zigzag_inv;  no need to use it, default
1894
1895        if (CBP)
1896        {
1897            for (i = 0; i < 6 ; i++)
1898            {
1899                RLB = video->RLB + i;
1900                idx = 0;
1901
1902                if ((CBP >> (5 - i)) & 1)
1903                {   /* 7/30/01 */
1904                    /* Use bitmapzz to find the Run,Level,Sign symbols */
1905                    bitmapzz = video->bitmapzz[i];
1906                    dataBlock = MB->block[i];
1907                    nc  = ncoefblck[i];
1908
1909                    idx = zero_run_search(bitmapzz, dataBlock, RLB, nc);
1910                }
1911                ncoefblck[i] = idx; /* 5/22/01, reuse ncoefblck */
1912                if (idx == 0) /* reset CBP, nothing to be coded */
1913                    CBP &= imask[i];
1914            }
1915            video->headerInfo.CBP[video->mbnum] = CBP;
1916        }
1917        return ;
1918    }
1919}
1920
1921#ifndef H263_ONLY
1922#ifdef __cplusplus
1923extern "C"
1924{
1925#endif
1926    static Bool IntraDCSwitch_Decision(Int Mode, Int intra_dc_vlc_thr, Int intraDCVlcQP)
1927    {
1928        Bool switched = FALSE;
1929
1930        if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q)
1931        {
1932            if (intra_dc_vlc_thr != 0)
1933            {
1934                switched = (intra_dc_vlc_thr == 7 || intraDCVlcQP >= intra_dc_vlc_thr * 2 + 11);
1935            }
1936        }
1937
1938        return switched;
1939    }
1940#ifdef __cplusplus
1941}
1942#endif
1943
1944Int IntraDC_dpcm(Int val, Int lum, BitstreamEncVideo *bitstream)
1945{
1946    Int n_bits;
1947    Int absval, size = 0;
1948
1949    absval = (val < 0) ? -val : val;    /* abs(val) */
1950
1951
1952    /* compute dct_dc_size */
1953
1954    size = 0;
1955    while (absval)
1956    {
1957        absval >>= 1;
1958        size++;
1959    }
1960
1961    if (lum)
1962    {   /* luminance */
1963        n_bits = PutDCsize_lum(size, bitstream);
1964    }
1965    else
1966    {   /* chrominance */
1967        n_bits = PutDCsize_chrom(size, bitstream);
1968    }
1969
1970    if (size != 0)
1971    {
1972        if (val >= 0)
1973        {
1974            ;
1975        }
1976        else
1977        {
1978            absval = -val; /* set to "-val" MW 14-NOV-1996 */
1979            val = absval ^((1 << size) - 1);
1980        }
1981        BitstreamPutBits(bitstream, (size), (UInt)(val));
1982        n_bits += size;
1983
1984        if (size > 8)
1985            BitstreamPut1Bits(bitstream, 1);
1986    }
1987
1988    return n_bits;  /* # bits for intra_dc dpcm */
1989
1990}
1991
1992/* ======================================================================== */
1993/*  Function : DC_AC_PRED                                                   */
1994/*  Date     : 09/24/2000                                                   */
1995/*  Purpose  : DC and AC encoding of Intra Blocks                           */
1996/*  In/out   :                                                              */
1997/*      VideoEncData    *video
1998        UChar           Mode                                                */
1999/*  Return   :                                                              */
2000/*                                                                          */
2001/* ======================================================================== */
2002Int cal_dc_scalerENC(Int QP, Int type) ;
2003
2004
2005#define PREDICT_AC  for (m = 0; m < 7; m++){ \
2006                        tmp = DCAC[0]*QPtmp;\
2007                        if(tmp<0)   tmp = (tmp-(QP/2))/QP;\
2008                        else        tmp = (tmp+(QP/2))/QP;\
2009                        pred[m] = tmp;\
2010                        DCAC++;\
2011                    }
2012
2013
2014Void DCACPred(VideoEncData *video, UChar Mode, Int *intraDC_decision, Int intraDCVlcQP)
2015{
2016    MacroBlock *MB = video->outputMB;
2017    Int mbnum = video->mbnum;
2018    typeDCStore *DC_store = video->predDC + mbnum;
2019    typeDCACStore *DCAC_row = video->predDCAC_row;
2020    typeDCACStore *DCAC_col = video->predDCAC_col;
2021    Short   *DCAC;
2022    UChar Mode_top, Mode_left;
2023
2024    Vol *currVol = video->vol[video->currLayer];
2025    Int nMBPerRow = currVol->nMBPerRow;
2026    Int x_pos = video->outputMB->mb_x; /* 5/28/01 */
2027    Int y_pos = video->outputMB->mb_y;
2028    UChar QP = video->QPMB[mbnum];
2029    UChar *QPMB = video->QPMB;
2030    UChar *slice_nb = video->sliceNo;
2031    Bool bACPredEnable = video->encParams->ACDCPrediction;
2032    Int *ACpred_flag = video->acPredFlag;
2033    Int mid_grey = 128 << 3;
2034    Int m;
2035    Int comp;
2036    Int dc_scale = 8, tmp;
2037
2038    static const Int Xpos[6] = { -1, 0, -1, 0, -1, -1};
2039    static const Int Ypos[6] = { -1, -1, 0, 0, -1, -1};
2040    static const Int Xtab[6] = {1, 0, 3, 2, 4, 5};
2041    static const Int Ytab[6] = {2, 3, 0, 1, 4, 5};
2042    static const Int Ztab[6] = {3, 2, 1, 0, 4, 5};
2043
2044    /* I added these to speed up comparisons */
2045    static const Int Pos0[6] = { 1, 1, 0, 0, 1, 1};
2046    static const Int Pos1[6] = { 1, 0, 1, 0, 1, 1};
2047    static const Int B_Xtab[6] = {0, 1, 0, 1, 2, 3};
2048    static const Int B_Ytab[6] = {0, 0, 1, 1, 2, 3};
2049
2050    Int direction[6];       /* 0: HORIZONTAL, 1: VERTICAL */
2051    Int block_A, block_B, block_C;
2052    Int grad_hor, grad_ver, DC_pred;
2053    Short pred[7], *predptr;
2054    Short pcoeff[42];
2055    Short *qcoeff;
2056    Int S = 0, S1, S2;
2057    Int diff, QPtmp;
2058    Int newCBP[6];
2059    UChar mask1[6] = {0x20, 0x10, 0x8, 0x4, 0x2, 0x1};
2060//  UChar mask2[6] = {0x1f,0x2f,0x37,0x3b,0x3d,0x3e};
2061
2062    Int y_offset, x_offset, x_tab, y_tab, z_tab;    /* speedup coefficients */
2063    Int b_xtab, b_ytab;
2064
2065    video->zz_direction = 0;
2066
2067    /* Standard MPEG-4 Headers do DC/AC prediction*/
2068    /* check whether neighbors are INTER */
2069    if (y_pos > 0)
2070    {
2071        Mode_top = video->headerInfo.Mode[mbnum-nMBPerRow];
2072        if (!(Mode_top == MODE_INTRA || Mode_top == MODE_INTRA_Q))
2073        {
2074            DCAC = DC_store[-nMBPerRow];
2075            *DCAC++ = mid_grey;
2076            *DCAC++ = mid_grey;
2077            *DCAC++ = mid_grey;
2078            *DCAC++ = mid_grey;
2079            *DCAC++ = mid_grey;
2080            *DCAC++ = mid_grey;
2081            /* set to 0 DCAC_row[x_pos][0..3] */
2082            if (bACPredEnable == TRUE)
2083            {
2084                M4VENC_MEMSET(DCAC_row[x_pos][0], 0, sizeof(Short) << 5);
2085            }
2086        }
2087    }
2088    if (x_pos > 0)
2089    {
2090        Mode_left = video->headerInfo.Mode[mbnum-1];
2091        if (!(Mode_left == MODE_INTRA || Mode_left == MODE_INTRA_Q))
2092        {
2093            DCAC = DC_store[-1];
2094            *DCAC++ = mid_grey;
2095            *DCAC++ = mid_grey;
2096            *DCAC++ = mid_grey;
2097            *DCAC++ = mid_grey;
2098            *DCAC++ = mid_grey;
2099            *DCAC++ = mid_grey;
2100            /* set to 0 DCAC_col[x_pos][0..3] */
2101            if (bACPredEnable == TRUE)
2102            {
2103                M4VENC_MEMSET(DCAC_col[0][0], 0, sizeof(Short) << 5);
2104            }
2105        }
2106    }
2107
2108    S1 = 0;
2109    S2 = 0;
2110
2111    for (comp = 0; comp < 6; comp++)
2112    {
2113
2114        if (Ypos[comp] != 0)        y_offset = -nMBPerRow;
2115        else                    y_offset = 0;
2116        x_offset = Xpos[comp];
2117        x_tab = Xtab[comp];
2118        y_tab = Ytab[comp];
2119        z_tab = Ztab[comp];
2120
2121        b_xtab = B_Xtab[comp];
2122        b_ytab = B_Ytab[comp];
2123
2124        qcoeff = MB->block[comp];
2125
2126        /****************************/
2127        /*  Store DC coefficients */
2128        /****************************/
2129        /* Store coeff values for Intra MB */
2130        if (comp == 0) dc_scale = cal_dc_scalerENC(QP, 1) ;
2131        if (comp == 4) dc_scale = cal_dc_scalerENC(QP, 2) ;
2132
2133        QPtmp = qcoeff[0] * dc_scale; /* DC value */
2134
2135        if (QPtmp > 2047)   /* 10/10/01, add clipping (bug fixed) */
2136            DC_store[0][comp] = 2047;
2137        else if (QPtmp < -2048)
2138            DC_store[0][comp] = -2048;
2139        else
2140            DC_store[0][comp] = QPtmp;
2141
2142        /**************************************************************/
2143        /* Find the direction of the prediction and the DC prediction */
2144        /**************************************************************/
2145
2146        if ((x_pos == 0) && y_pos == 0)
2147        {   /* top left corner */
2148            block_A = (comp == 1 || comp == 3) ? DC_store[0][x_tab] : mid_grey;
2149            block_B = (comp == 3) ? DC_store[x_offset][z_tab] : mid_grey;
2150            block_C = (comp == 2 || comp == 3) ? DC_store[0][y_tab] : mid_grey;
2151        }
2152        else if (x_pos == 0)
2153        {   /* left edge */
2154            block_A = (comp == 1 || comp == 3) ? DC_store[0][x_tab] : mid_grey;
2155            block_B = ((comp == 1 && (slice_nb[mbnum] == slice_nb[mbnum-nMBPerRow])) || comp == 3) ?
2156                      DC_store[y_offset+x_offset][z_tab] : mid_grey;
2157            block_C = (comp == 2 || comp == 3 ||
2158                       (Pos0[comp] && (slice_nb[mbnum] == slice_nb[mbnum-nMBPerRow]))) ?
2159                      DC_store[y_offset][y_tab] : mid_grey;
2160        }
2161        else if (y_pos == 0)
2162        { /* top row */
2163            block_A = (comp == 1 || comp == 3 || (Pos1[comp] && (slice_nb[mbnum] == slice_nb[mbnum-1]))) ?
2164                      DC_store[x_offset][x_tab] : mid_grey;
2165            block_B = ((comp == 2 && (slice_nb[mbnum] == slice_nb[mbnum-1])) || comp == 3) ?
2166                      DC_store[y_offset + x_offset][z_tab] : mid_grey;
2167            block_C = (comp == 2 || comp == 3) ?
2168                      DC_store[y_offset][y_tab] : mid_grey;
2169        }
2170        else
2171        {
2172            block_A = (comp == 1 || comp == 3 || (Pos1[comp] && (slice_nb[mbnum] == slice_nb[mbnum-1]))) ?
2173                      DC_store[x_offset][x_tab] : mid_grey;
2174            block_B = (((comp == 0 || comp == 4 || comp == 5) &&
2175                        (slice_nb[mbnum] == slice_nb[mbnum-1-nMBPerRow])) ||
2176                       (comp == 1 && (slice_nb[mbnum] == slice_nb[mbnum-nMBPerRow])) ||
2177                       (comp == 2 && (slice_nb[mbnum] == slice_nb[mbnum-1])) || (comp == 3)) ?
2178                      (DC_store[y_offset + x_offset][z_tab]) : mid_grey;
2179            block_C = (comp == 2 || comp == 3 || (Pos0[comp] && (slice_nb[mbnum] == slice_nb[mbnum-nMBPerRow]))) ?
2180                      DC_store[y_offset][y_tab] : mid_grey;
2181        }
2182        grad_hor = block_B - block_C;
2183        grad_ver = block_A - block_B;
2184
2185        if ((PV_ABS(grad_ver)) < (PV_ABS(grad_hor)))
2186        {
2187            DC_pred = block_C;
2188            direction[comp] = 1;
2189            video->zz_direction = (video->zz_direction) | mask1[comp];
2190
2191        }
2192        else
2193        {
2194            DC_pred = block_A;
2195            direction[comp] = 0;
2196            //video->zz_direction=video->zz_direction<<1;
2197        }
2198
2199        /* DC prediction */
2200        QPtmp = dc_scale; /* 5/28/01 */
2201        qcoeff[0] -= (DC_pred + QPtmp / 2) / QPtmp;
2202
2203
2204        if (bACPredEnable)
2205        {
2206            /***********************/
2207            /* Find AC prediction  */
2208            /***********************/
2209
2210            if ((x_pos == 0) && y_pos == 0)     /* top left corner */
2211            {
2212                if (direction[comp] == 0)
2213                {
2214                    if (comp == 1 || comp == 3)
2215                    {
2216                        QPtmp = QPMB[mbnum+x_offset];
2217                        DCAC = DCAC_col[0][b_ytab];
2218                        if (QPtmp != QP)
2219                        {
2220                            predptr = pred;
2221                            PREDICT_AC
2222                        }
2223                        else
2224                        {
2225                            predptr = DCAC;
2226                        }
2227                    }
2228                    else
2229                    {
2230                        predptr = pred;
2231                        pred[0] = pred[1] = pred[2] = pred[3] = pred[4] = pred[5] = pred[6] = 0;
2232                    }
2233                }
2234                else
2235                {
2236                    if (comp == 2 || comp == 3)
2237                    {
2238                        QPtmp = QPMB[mbnum+ y_offset];
2239                        DCAC = DCAC_row[x_pos][b_xtab];
2240                        if (QPtmp != QP)
2241                        {
2242                            predptr = pred;
2243                            PREDICT_AC
2244                        }
2245                        else
2246                        {
2247                            predptr = DCAC;
2248                        }
2249                    }
2250                    else
2251                    {
2252                        predptr = pred;
2253                        pred[0] = pred[1] = pred[2] = pred[3] = pred[4] = pred[5] = pred[6] = 0;
2254                    }
2255                }
2256            }
2257            else if (x_pos == 0)    /* left edge */
2258            {
2259                if (direction[comp] == 0)
2260                {
2261                    if (comp == 1 || comp == 3)
2262                    {
2263                        QPtmp = QPMB[mbnum+x_offset];
2264                        DCAC = DCAC_col[0][b_ytab];
2265                        if (QPtmp != QP)
2266                        {
2267                            predptr = pred;
2268                            PREDICT_AC
2269                        }
2270                        else
2271                        {
2272                            predptr = DCAC;
2273                        }
2274                    }
2275                    else
2276                    {
2277                        predptr = pred;
2278                        pred[0] = pred[1] = pred[2] = pred[3] = pred[4] = pred[5] = pred[6] = 0;
2279                    }
2280                }
2281                else
2282                {
2283
2284                    if ((Pos0[comp] && (slice_nb[mbnum] == slice_nb[mbnum-nMBPerRow]))
2285                            || comp == 2 || comp == 3)
2286                    {
2287                        QPtmp = QPMB[mbnum+y_offset];
2288                        DCAC = DCAC_row[x_pos][b_xtab];
2289                        if (QPtmp != QP)
2290                        {
2291                            predptr = pred;
2292                            PREDICT_AC
2293                        }
2294                        else
2295                        {
2296                            predptr = DCAC;
2297                        }
2298                    }
2299                    else
2300                    {
2301                        predptr = pred;
2302                        pred[0] = pred[1] = pred[2] = pred[3] = pred[4] = pred[5] = pred[6] = 0;
2303                    }
2304                }
2305            }
2306            else if (y_pos == 0)  /* top row */
2307            {
2308                if (direction[comp] == 0)
2309                {
2310                    if ((Pos1[comp] && (slice_nb[mbnum] == slice_nb[mbnum-1]))
2311                            || comp == 1 || comp == 3)
2312                    {
2313                        QPtmp = QPMB[mbnum+x_offset];
2314                        DCAC = DCAC_col[0][b_ytab];
2315                        if (QPtmp != QP)
2316                        {
2317                            predptr = pred;
2318                            PREDICT_AC
2319                        }
2320                        else
2321                        {
2322                            predptr = DCAC;
2323                        }
2324                    }
2325                    else
2326                    {
2327                        predptr = pred;
2328                        pred[0] = pred[1] = pred[2] = pred[3] = pred[4] = pred[5] = pred[6] = 0;
2329                    }
2330                }
2331                else
2332                {
2333                    if (comp == 2 || comp == 3)
2334                    {
2335                        QPtmp = QPMB[mbnum+y_offset];
2336                        DCAC = DCAC_row[x_pos][b_xtab];
2337                        if (QPtmp != QP)
2338                        {
2339                            predptr = pred;
2340                            PREDICT_AC
2341                        }
2342                        else
2343                        {
2344                            predptr = DCAC;
2345                        }
2346                    }
2347                    else
2348                    {
2349                        predptr = pred;
2350                        pred[0] = pred[1] = pred[2] = pred[3] = pred[4] = pred[5] = pred[6] = 0;
2351                    }
2352                }
2353            }
2354            else
2355            {
2356                if (direction[comp] == 0)
2357                {
2358                    if ((Pos1[comp] && (slice_nb[mbnum] == slice_nb[mbnum-1]))
2359                            || comp == 1 || comp == 3)
2360                    {
2361                        QPtmp = QPMB[mbnum+x_offset];
2362                        DCAC = DCAC_col[0][b_ytab];
2363                        if (QPtmp != QP)
2364                        {
2365                            predptr = pred;
2366                            PREDICT_AC
2367                        }
2368                        else
2369                        {
2370                            predptr = DCAC;
2371                        }
2372                    }
2373                    else
2374                    {
2375                        predptr = pred;
2376                        pred[0] = pred[1] = pred[2] = pred[3] = pred[4] = pred[5] = pred[6] = 0;
2377                    }
2378                }
2379                else
2380                {
2381                    if ((Pos0[comp] && (slice_nb[mbnum] == slice_nb[mbnum-nMBPerRow]))
2382                            || comp  == 2 || comp == 3)
2383                    {
2384                        QPtmp = QPMB[mbnum+y_offset];
2385                        DCAC = DCAC_row[x_pos][b_xtab];
2386                        if (QPtmp != QP)
2387                        {
2388                            predptr = pred;
2389                            PREDICT_AC
2390                        }
2391                        else
2392                        {
2393                            predptr = DCAC;
2394                        }
2395                    }
2396                    else
2397                    {
2398                        predptr = pred;
2399                        pred[0] = pred[1] = pred[2] = pred[3] = pred[4] = pred[5] = pred[6] = 0;
2400                    }
2401                }
2402            }
2403
2404            /************************************/
2405            /* Decide and Perform AC prediction */
2406            /************************************/
2407            newCBP[comp] = 0;
2408
2409            if (direction[comp] == 0)   /* Horizontal, left COLUMN of block A */
2410            {
2411                DCAC = pcoeff + comp * 7; /* re-use DCAC as local var */
2412                qcoeff += 8;
2413                for (m = 0; m < 7; m++)
2414                {
2415                    QPtmp = qcoeff[m<<3];
2416                    if (QPtmp > 0)  S1 += QPtmp;
2417                    else        S1 -= QPtmp;
2418                    QPtmp -= predptr[m];
2419                    DCAC[m] = QPtmp; /* save prediction residue to pcoeff*/
2420                    if (QPtmp)  newCBP[comp] = 1;
2421                    diff = PV_ABS(QPtmp);
2422                    S2 += diff;
2423                }
2424            }
2425            else            /* Vertical, top ROW of block C */
2426            {
2427                qcoeff++;
2428                DCAC = pcoeff + comp * 7; /* re-use DCAC as local var */
2429                for (m = 0; m < 7; m++)
2430                {
2431                    QPtmp = qcoeff[m];
2432                    if (QPtmp > 0)  S1 += QPtmp;
2433                    else        S1 -= QPtmp;
2434                    QPtmp -= predptr[m];
2435                    DCAC[m] = QPtmp; /* save prediction residue to pcoeff*/
2436                    if (QPtmp)  newCBP[comp] = 1;
2437                    diff = PV_ABS(QPtmp);
2438                    S2 += diff;
2439                }
2440            }
2441
2442            /****************************/
2443            /*  Store DCAC coefficients */
2444            /****************************/
2445            /* Store coeff values for Intra MB */
2446            qcoeff = MB->block[comp];
2447            DCAC = DCAC_row[x_pos][b_xtab];
2448            DCAC[0] = qcoeff[1];
2449            DCAC[1] = qcoeff[2];
2450            DCAC[2] = qcoeff[3];
2451            DCAC[3] = qcoeff[4];
2452            DCAC[4] = qcoeff[5];
2453            DCAC[5] = qcoeff[6];
2454            DCAC[6] = qcoeff[7];
2455
2456            DCAC = DCAC_col[0][b_ytab];
2457            DCAC[0] = qcoeff[8];
2458            DCAC[1] = qcoeff[16];
2459            DCAC[2] = qcoeff[24];
2460            DCAC[3] = qcoeff[32];
2461            DCAC[4] = qcoeff[40];
2462            DCAC[5] = qcoeff[48];
2463            DCAC[6] = qcoeff[56];
2464
2465
2466        } /* bACPredEnable */
2467
2468    } /* END COMP FOR LOOP */
2469
2470    //if (diff > 2047)
2471    //    break;
2472    S += (S1 - S2);
2473
2474
2475    if (S >= 0 && bACPredEnable == TRUE)
2476    {
2477        ACpred_flag[mbnum] = 1;
2478        DCAC = pcoeff; /* prediction residue */
2479        qcoeff = MB->block[0];
2480
2481        for (comp = 0; comp < 6; comp++)
2482        {
2483            if (direction[comp] == 0)
2484            {
2485                qcoeff[8] = DCAC[0];
2486                qcoeff[16] = DCAC[1];
2487                qcoeff[24] = DCAC[2];
2488                qcoeff[32] = DCAC[3];
2489                qcoeff[40] = DCAC[4];
2490                qcoeff[48] = DCAC[5];
2491                qcoeff[56] = DCAC[6];
2492
2493            }
2494            else
2495            {
2496                qcoeff[1] = DCAC[0];
2497                qcoeff[2] = DCAC[1];
2498                qcoeff[3] = DCAC[2];
2499                qcoeff[4] = DCAC[3];
2500                qcoeff[5] = DCAC[4];
2501                qcoeff[6] = DCAC[5];
2502                qcoeff[7] = DCAC[6];
2503            }
2504            if (newCBP[comp]) /* 5/28/01, update CBP */
2505                video->headerInfo.CBP[mbnum] |= mask1[comp];
2506            DCAC += 7;
2507            qcoeff += 64;
2508        }
2509    }
2510    else  /* Only DC Prediction */
2511    {
2512        ACpred_flag[mbnum] = 0;
2513    }
2514
2515    *intraDC_decision = IntraDCSwitch_Decision(Mode, video->currVop->intraDCVlcThr, intraDCVlcQP);
2516    if (*intraDC_decision) /* code DC with AC , 5/28/01*/
2517    {
2518        qcoeff = MB->block[0];
2519        for (comp = 0; comp < 6; comp++)
2520        {
2521            if (*qcoeff)
2522                video->headerInfo.CBP[mbnum] |= mask1[comp];
2523            qcoeff += 64;
2524        }
2525    }
2526    return;
2527}
2528#endif /* H263_ONLY */
2529
2530
2531
2532Void find_pmvs(VideoEncData *video, Int block, Int *mvx, Int *mvy)
2533{
2534    Vol *currVol = video->vol[video->currLayer];
2535//  UChar *Mode = video->headerInfo.Mode; /* modes for MBs */
2536    UChar *slice_nb = video->sliceNo;
2537    Int nMBPerRow = currVol->nMBPerRow;
2538    Int mbnum = video->mbnum;
2539
2540    Int   p1x, p2x, p3x;
2541    Int   p1y, p2y, p3y;
2542    Int   xin1, xin2, xin3;
2543    Int   yin1, yin2, yin3;
2544    Int   vec1, vec2, vec3;
2545    Int   rule1, rule2, rule3;
2546    MOT   **motdata = video->mot;
2547    Int   x = mbnum % nMBPerRow;
2548    Int   y = mbnum / nMBPerRow;
2549
2550    /*
2551        In a previous version, a MB vector (block = 0) was predicted the same way
2552        as block 1, which is the most likely interpretation of the VM.
2553
2554        Therefore, if we have advanced pred. mode, and if all MBs around have
2555        only one 16x16 vector each, we chose the appropiate block as if these
2556        MBs have 4 vectors.
2557
2558        This different prediction affects only 16x16 vectors of MBs with
2559        transparent blocks.
2560
2561        In the current version, we choose for the 16x16 mode the first
2562        non-transparent block in the surrounding MBs
2563    */
2564
2565    switch (block)
2566    {
2567        case 0:
2568            vec1 = 2 ;
2569            yin1 = y  ;
2570            xin1 = x - 1;
2571            vec2 = 3 ;
2572            yin2 = y - 1;
2573            xin2 = x;
2574            vec3 = 3 ;
2575            yin3 = y - 1;
2576            xin3 = x + 1;
2577            break;
2578
2579        case 1:
2580            vec1 = 2 ;
2581            yin1 = y  ;
2582            xin1 = x - 1;
2583            vec2 = 3 ;
2584            yin2 = y - 1;
2585            xin2 = x;
2586            vec3 = 3 ;
2587            yin3 = y - 1;
2588            xin3 = x + 1;
2589            break;
2590
2591        case 2:
2592            vec1 = 1 ;
2593            yin1 = y  ;
2594            xin1 = x;
2595            vec2 = 4 ;
2596            yin2 = y - 1;
2597            xin2 = x;
2598            vec3 = 3 ;
2599            yin3 = y - 1;
2600            xin3 = x + 1;
2601            break;
2602
2603        case 3:
2604            vec1 = 4 ;
2605            yin1 = y  ;
2606            xin1 = x - 1;
2607            vec2 = 1 ;
2608            yin2 = y  ;
2609            xin2 = x;
2610            vec3 = 2 ;
2611            yin3 = y  ;
2612            xin3 = x;
2613            break;
2614
2615        default: /* case 4 */
2616            vec1 = 3 ;
2617            yin1 = y  ;
2618            xin1 = x;
2619            vec2 = 1 ;
2620            yin2 = y  ;
2621            xin2 = x;
2622            vec3 = 2 ;
2623            yin3 = y  ;
2624            xin3 = x;
2625            break;
2626    }
2627
2628    if (block == 0)
2629    {
2630        /* according to the motion encoding, we must choose a first non-transparent
2631        block in the surrounding MBs (16-mode)
2632            */
2633
2634        if (x > 0 && slice_nb[mbnum] == slice_nb[mbnum-1])
2635            rule1 = 0;
2636        else
2637            rule1 = 1;
2638
2639        if (y > 0 && slice_nb[mbnum] == slice_nb[mbnum-nMBPerRow])
2640            rule2 = 0;
2641        else
2642            rule2 = 1;
2643
2644        if ((x != nMBPerRow - 1) && (y > 0) && slice_nb[mbnum] == slice_nb[mbnum+1-nMBPerRow])
2645            rule3 = 0;
2646        else
2647            rule3 = 1;
2648    }
2649    else
2650    {
2651        /* check borders for single blocks (advanced mode) */
2652        /* rule 1 */
2653        if (((block == 1 || block == 3) &&
2654                (x == 0 || slice_nb[mbnum] != slice_nb[mbnum-1])))
2655            rule1 = 1;
2656        else
2657            rule1 = 0;
2658
2659        /* rule 2 */
2660        if (((block == 1 || block == 2) &&
2661                (y == 0 || slice_nb[mbnum] != slice_nb[mbnum-nMBPerRow])))
2662            rule2 = 1;
2663        else
2664            rule2 = 0;
2665
2666        /* rule 3 */
2667        if (((block == 1 || block == 2) &&
2668                (x == nMBPerRow - 1 || y == 0 || slice_nb[mbnum] != slice_nb[mbnum+1-nMBPerRow])))
2669            rule3 = 1;
2670        else
2671            rule3 = 0;
2672    }
2673
2674    if (rule1)
2675    {
2676        p1x = p1y = 0;
2677    }
2678    else
2679    {
2680
2681        p1x = motdata[yin1*nMBPerRow+xin1][vec1].x;
2682        p1y = motdata[yin1*nMBPerRow+xin1][vec1].y;
2683        //p1x = motxdata[xin1*2+(vec1&0x1) + (yin1*2+(vec1>>1))*xB];
2684        //p1y = motydata[xin1*2+(vec1&0x1) + (yin1*2+(vec1>>1))*xB];
2685    }
2686
2687    if (rule2)
2688    {
2689        p2x = p2y = 0;
2690    }
2691    else
2692    {
2693        p2x = motdata[yin2*nMBPerRow+xin2][vec2].x;
2694        p2y = motdata[yin2*nMBPerRow+xin2][vec2].y;
2695        //p2x = motxdata[xin2*2+(vec2&0x1) + (yin2*2+(vec2>>1))*xB];
2696        //p2y = motydata[xin2*2+(vec2&0x1) + (yin2*2+(vec2>>1))*xB];
2697    }
2698
2699    if (rule3)
2700    {
2701        p3x = p3y = 0;
2702    }
2703    else
2704    {
2705        p3x = motdata[yin3*nMBPerRow+xin3][vec3].x;
2706        p3y = motdata[yin3*nMBPerRow+xin3][vec3].y;
2707        //p3x = motxdata[xin3*2+ (vec3&0x1) + (yin3*2+(vec3>>1))*xB];
2708        //p3y = motydata[xin3*2+ (vec3&0x1) + (yin3*2+(vec3>>1))*xB];
2709    }
2710
2711    if (rule1 && rule2 && rule3)
2712    {
2713        /* all MBs are outside the VOP */
2714        *mvx = *mvy = 0;
2715    }
2716    else if (rule1 + rule2 + rule3 == 2)
2717    {
2718        /* two of three are zero */
2719        *mvx = (p1x + p2x + p3x);
2720        *mvy = (p1y + p2y + p3y);
2721    }
2722    else
2723    {
2724        *mvx = ((p1x + p2x + p3x - PV_MAX(p1x, PV_MAX(p2x, p3x)) - PV_MIN(p1x, PV_MIN(p2x, p3x))));
2725        *mvy = ((p1y + p2y + p3y - PV_MAX(p1y, PV_MAX(p2y, p3y)) - PV_MIN(p1y, PV_MIN(p2y, p3y))));
2726    }
2727
2728    return;
2729}
2730
2731
2732Void WriteMVcomponent(Int f_code, Int dmv, BitstreamEncVideo *bs)
2733{
2734    Int residual, vlc_code_mag, bits, entry;
2735
2736    ScaleMVD(f_code, dmv, &residual, &vlc_code_mag);
2737
2738    if (vlc_code_mag < 0)
2739        entry = vlc_code_mag + 65;
2740    else
2741        entry = vlc_code_mag;
2742
2743    bits = PutMV(entry, bs);
2744
2745    if ((f_code != 1) && (vlc_code_mag != 0))
2746    {
2747        BitstreamPutBits(bs, f_code - 1, residual);
2748        bits += f_code - 1;
2749    }
2750    return;
2751}
2752
2753
2754Void
2755ScaleMVD(
2756    Int  f_code,       /* <-- MV range in 1/2 units: 1=32,2=64,...,7=2048     */
2757    Int  diff_vector,  /* <-- MV Difference commponent in 1/2 units           */
2758    Int  *residual,    /* --> value to be FLC coded                           */
2759    Int  *vlc_code_mag /* --> value to be VLC coded                           */
2760)
2761{
2762    Int   range;
2763    Int   scale_factor;
2764    Int   r_size;
2765    Int   low;
2766    Int   high;
2767    Int   aux;
2768
2769    r_size = f_code - 1;
2770    scale_factor = 1 << r_size;
2771    range = 32 * scale_factor;
2772    low   = -range;
2773    high  =  range - 1;
2774
2775    if (diff_vector < low)
2776        diff_vector += 2 * range;
2777    else if (diff_vector > high)
2778        diff_vector -= 2 * range;
2779
2780    if (diff_vector == 0)
2781    {
2782        *vlc_code_mag = 0;
2783        *residual = 0;
2784    }
2785    else if (scale_factor == 1)
2786    {
2787        *vlc_code_mag = diff_vector;
2788        *residual = 0;
2789    }
2790    else
2791    {
2792        aux = PV_ABS(diff_vector) + scale_factor - 1;
2793        *vlc_code_mag = aux >> r_size;
2794
2795        if (diff_vector < 0)
2796            *vlc_code_mag = -*vlc_code_mag;
2797        *residual = aux & (scale_factor - 1);
2798    }
2799}
2800