1 /* putmpg.c, block and motion vector encoding routines */
3 /* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */
6 * Disclaimer of Warranty
8 * These software programs are available to the user without any license fee or
9 * royalty on an "as is" basis. The MPEG Software Simulation Group disclaims
10 * any and all warranties, whether express, implied, or statuary, including any
11 * implied warranties or merchantability or of fitness for a particular
12 * purpose. In no event shall the copyright-holder be liable for any
13 * incidental, punitive, or consequential damages of any kind whatsoever
14 * arising from the use of these programs.
16 * This disclaimer of warranty extends to the user of these programs and user's
17 * customers, employees, agents, transferees, successors, and assigns.
19 * The MPEG Software Simulation Group does not represent or warrant that the
20 * programs furnished hereunder are free of infringement of any third-party
23 * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware,
24 * are subject to royalty fees to patent holders. Many of these patents are
25 * general enough such that they are unavoidable regardless of implementation
34 /* generate variable length codes for an intra-coded block (6.2.6, 6.3.17) */
35 void putintrablk(slice_engine_t
*engine
,
40 int n
, dct_diff
, run
, signed_level
;
42 /* DC coefficient (7.2.1) */
43 dct_diff
= blk
[0] - engine
->dc_dct_pred
[cc
]; /* difference to previous block */
44 engine
->dc_dct_pred
[cc
] = blk
[0];
47 putDClum(engine
, dct_diff
);
49 putDCchrom(engine
, dct_diff
);
51 /* AC coefficients (7.2.2) */
53 for(n
= 1; n
< 64; n
++)
55 /* use appropriate entropy scanning pattern */
56 signed_level
= blk
[(picture
->altscan
? alternate_scan
: mpeg2_zig_zag_scan
)[n
]];
59 //printf("putintrablk 1 %d\n", picture->altscan);slice_testbits(engine);
60 putAC(engine
, run
, signed_level
, picture
->intravlc
);
61 //printf("putintrablk 2\n");slice_testbits(engine);
65 run
++; /* count zero coefficients */
68 /* End of Block -- normative block punctuation */
69 if (picture
->intravlc
)
70 slice_putbits(engine
, 6, 4); /* 0110 (Table B-15) */
72 slice_putbits(engine
, 2, 2); /* 10 (Table B-14) */
75 /* generate variable length codes for a non-intra-coded block (6.2.6, 6.3.17) */
76 void putnonintrablk(slice_engine_t
*engine
,
80 int n
, run
, signed_level
, first
;
85 for(n
= 0; n
< 64; n
++)
87 /* use appropriate entropy scanning pattern */
88 signed_level
= blk
[(picture
->altscan
? alternate_scan
: mpeg2_zig_zag_scan
)[n
]];
94 /* first coefficient in non-intra block */
95 putACfirst(engine
, run
, signed_level
);
99 putAC(engine
, run
, signed_level
, 0);
104 run
++; /* count zero coefficients */
107 /* End of Block -- normative block punctuation */
108 slice_putbits(engine
, 2, 2);
111 /* generate variable length code for a motion vector component (7.6.3.1) */
112 void putmv(slice_engine_t
*engine
, int dmv
, int f_code
)
114 int r_size
, f
, vmin
, vmax
, dv
, temp
, motion_code
, motion_residual
;
116 r_size
= f_code
- 1; /* number of fixed length code ('residual') bits */
118 vmin
= -16 * f
; /* lower range limit */
119 vmax
= 16 * f
- 1; /* upper range limit */
122 /* fold vector difference into [vmin...vmax] */
130 if(dmv
< vmin
|| dmv
> vmax
)
132 fprintf(stderr
,"invalid motion vector\n");
134 /* split dmv into motion_code and motion_residual */
135 temp
= ((dmv
< 0) ? -dmv
: dmv
) + f
- 1;
136 motion_code
= temp
>> r_size
;
138 motion_code
= -motion_code
;
139 motion_residual
= temp
& (f
- 1);
141 putmotioncode(engine
, motion_code
); /* variable length code */
143 if (r_size
!= 0 && motion_code
!= 0)
144 slice_putbits(engine
, motion_residual
, r_size
); /* fixed length code */