[svn] / trunk / xvidcore / src / encoder.c Repository:
ViewVC logotype

Annotation of /trunk/xvidcore/src/encoder.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 192 - (view) (download)

1 : edgomez 145 /**************************************************************************
2 :     *
3 :     * XVID MPEG-4 VIDEO CODEC
4 :     * - Encoder main module -
5 :     *
6 :     * This program is an implementation of a part of one or more MPEG-4
7 :     * Video tools as specified in ISO/IEC 14496-2 standard. Those intending
8 :     * to use this software module in hardware or software products are
9 :     * advised that its use may infringe existing patents or copyrights, and
10 :     * any such use would be at such party's own risk. The original
11 :     * developer of this software module and his/her company, and subsequent
12 :     * editors and their companies, will have no liability for use of this
13 :     * software or modifications or derivatives thereof.
14 :     *
15 :     * This program is free software; you can redistribute it and/or modify
16 :     * it under the terms of the GNU General Public License as published by
17 :     * the Free Software Foundation; either version 2 of the License, or
18 :     * (at your option) any later version.
19 :     *
20 :     * This program is distributed in the hope that it will be useful,
21 :     * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 :     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 :     * GNU General Public License for more details.
24 :     *
25 :     * You should have received a copy of the GNU General Public License
26 :     * along with this program; if not, write to the Free Software
27 :     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 :     *
29 :     ***************************************************************************/
30 : suxen_drol 118
31 : edgomez 145 /****************************************************************************
32 :     *
33 :     * History
34 :     *
35 : chenm001 168 * 08.05.2002 fix some problem in DEBUG mode;
36 :     * MinChen <chenm001@163.com>
37 : edgomez 145 * 14.04.2002 added FrameCodeB()
38 :     *
39 : edgomez 192 * $Id: encoder.c,v 1.39 2002-06-09 13:16:26 edgomez Exp $
40 : edgomez 145 *
41 :     ***************************************************************************/
42 :    
43 : Isibaar 3 #include <stdlib.h>
44 :     #include <stdio.h>
45 :     #include <math.h>
46 :    
47 :     #include "encoder.h"
48 :     #include "prediction/mbprediction.h"
49 :     #include "global.h"
50 :     #include "utils/timer.h"
51 :     #include "image/image.h"
52 : suxen_drol 152 #include "motion/motion.h"
53 : Isibaar 3 #include "bitstream/cbp.h"
54 :     #include "utils/mbfunctions.h"
55 :     #include "bitstream/bitstream.h"
56 :     #include "bitstream/mbcoding.h"
57 :     #include "utils/ratecontrol.h"
58 :     #include "utils/emms.h"
59 :     #include "bitstream/mbcoding.h"
60 :     #include "quant/adapt_quant.h"
61 : Isibaar 4 #include "quant/quant_matrix.h"
62 : Isibaar 41 #include "utils/mem_align.h"
63 : Isibaar 3
64 :     #define ENC_CHECK(X) if(!(X)) return XVID_ERR_FORMAT
65 : suxen_drol 136 #define SWAP(A,B) { void * tmp = A; A = B; B = tmp; }
66 : Isibaar 3
67 : edgomez 192 static int FrameCodeI(Encoder * pEnc,
68 :     Bitstream * bs,
69 :     uint32_t *pBits);
70 : Isibaar 3
71 : edgomez 192 static int FrameCodeP(Encoder * pEnc,
72 :     Bitstream * bs,
73 :     uint32_t *pBits,
74 :     bool force_inter,
75 :     bool vol_header);
76 : Isibaar 3
77 : edgomez 192 #ifdef BFRAMES
78 :     static void FrameCodeB(Encoder * pEnc,
79 :     FRAMEINFO * frame,
80 :     Bitstream * bs,
81 :     uint32_t *pBits);
82 :     #endif
83 :    
84 : Isibaar 3 static int DQtab[4] =
85 :     {
86 :     -1, -2, 1, 2
87 :     };
88 :    
89 :     static int iDQtab[5] =
90 :     {
91 :     1, 0, NO_CHANGE, 2, 3
92 :     };
93 :    
94 :    
95 : suxen_drol 136 void static image_null(IMAGE * image)
96 :     {
97 :     image->y = image->u = image->v = NULL;
98 :     }
99 :    
100 :    
101 : Isibaar 3 int encoder_create(XVID_ENC_PARAM * pParam)
102 :     {
103 : edgomez 13 Encoder *pEnc;
104 : Isibaar 3 uint32_t i;
105 :    
106 : edgomez 13 pParam->handle = NULL;
107 : Isibaar 3
108 : edgomez 13 ENC_CHECK(pParam);
109 : Isibaar 3
110 : edgomez 13 ENC_CHECK(pParam->width > 0 && pParam->width <= 1920);
111 :     ENC_CHECK(pParam->height > 0 && pParam->height <= 1280);
112 :     ENC_CHECK(!(pParam->width % 2));
113 :     ENC_CHECK(!(pParam->height % 2));
114 : Isibaar 3
115 : edgomez 192 /* Fps */
116 :    
117 : Isibaar 3 if (pParam->fincr <= 0 || pParam->fbase <= 0)
118 :     {
119 :     pParam->fincr = 1;
120 :     pParam->fbase = 25;
121 :     }
122 :    
123 : edgomez 192 /*
124 :     * Simplify the "fincr/fbase" fraction
125 :     * (neccessary, since windows supplies us with huge numbers)
126 :     */
127 : Isibaar 3
128 :     i = pParam->fincr;
129 :     while (i > 1)
130 :     {
131 :     if (pParam->fincr % i == 0 && pParam->fbase % i == 0)
132 :     {
133 :     pParam->fincr /= i;
134 :     pParam->fbase /= i;
135 :     i = pParam->fincr;
136 :     continue;
137 :     }
138 :     i--;
139 :     }
140 :    
141 :     if (pParam->fbase > 65535)
142 :     {
143 :     float div = (float)pParam->fbase / 65535;
144 :     pParam->fbase = (int)(pParam->fbase / div);
145 :     pParam->fincr = (int)(pParam->fincr / div);
146 :     }
147 :    
148 : edgomez 192 /* Bitrate allocator defaults */
149 :    
150 : h 121 if (pParam->rc_bitrate <= 0)
151 :     pParam->rc_bitrate = 900000;
152 : Isibaar 3
153 : h 121 if (pParam->rc_reaction_delay_factor <= 0)
154 :     pParam->rc_reaction_delay_factor = 16;
155 : Isibaar 3
156 : h 121 if (pParam->rc_averaging_period <= 0)
157 :     pParam->rc_averaging_period = 100;
158 :    
159 :     if (pParam->rc_buffer <= 0)
160 :     pParam->rc_buffer = 100;
161 :    
162 : edgomez 192 /* Max and min quantizers */
163 :    
164 : edgomez 13 if ((pParam->min_quantizer <= 0) || (pParam->min_quantizer > 31))
165 : Isibaar 3 pParam->min_quantizer = 1;
166 :    
167 : edgomez 13 if ((pParam->max_quantizer <= 0) || (pParam->max_quantizer > 31))
168 : Isibaar 3 pParam->max_quantizer = 31;
169 :    
170 : edgomez 13 if (pParam->max_quantizer < pParam->min_quantizer)
171 : Isibaar 3 pParam->max_quantizer = pParam->min_quantizer;
172 :    
173 : edgomez 192 /* 1 keyframe each 10 seconds */
174 :    
175 :     if (pParam->max_key_interval == 0)
176 :     pParam->max_key_interval = 10 * pParam->fincr / pParam->fbase;
177 :    
178 :    
179 :     pEnc = (Encoder *) xvid_malloc(sizeof(Encoder), CACHE_LINE);
180 :     if (pEnc == NULL)
181 : Isibaar 3 return XVID_ERR_MEMORY;
182 :    
183 :     /* Fill members of Encoder structure */
184 :    
185 : edgomez 13 pEnc->mbParam.width = pParam->width;
186 :     pEnc->mbParam.height = pParam->height;
187 : Isibaar 3
188 :     pEnc->mbParam.mb_width = (pEnc->mbParam.width + 15) / 16;
189 :     pEnc->mbParam.mb_height = (pEnc->mbParam.height + 15) / 16;
190 :    
191 : edgomez 192 pEnc->mbParam.edged_width = 16*pEnc->mbParam.mb_width + 2*EDGE_SIZE;
192 :     pEnc->mbParam.edged_height = 16*pEnc->mbParam.mb_height + 2*EDGE_SIZE;
193 : Isibaar 3
194 : suxen_drol 152 pEnc->mbParam.fbase = pParam->fbase;
195 :     pEnc->mbParam.fincr = pParam->fincr;
196 :    
197 : edgomez 13 pEnc->sStat.fMvPrevSigma = -1;
198 : Isibaar 3
199 :     /* Fill rate control parameters */
200 :    
201 : h 121 pEnc->bitrate = pParam->rc_bitrate;
202 : Isibaar 3
203 : edgomez 13 pEnc->iFrameNum = 0;
204 :     pEnc->iMaxKeyInterval = pParam->max_key_interval;
205 : Isibaar 3
206 : suxen_drol 136 /* try to allocate frame memory */
207 : Isibaar 3
208 : edgomez 192 pEnc->current = xvid_malloc(sizeof(FRAMEINFO), CACHE_LINE);
209 :     pEnc->reference = xvid_malloc(sizeof(FRAMEINFO), CACHE_LINE);
210 : Isibaar 3
211 : edgomez 192 if ( pEnc->current == NULL || pEnc->reference == NULL)
212 :     goto xvid_err_memory1;
213 :    
214 : suxen_drol 136 /* try to allocate mb memory */
215 : Isibaar 3
216 : edgomez 192 pEnc->current->mbs = xvid_malloc(sizeof(MACROBLOCK) * \
217 :     pEnc->mbParam.mb_width * \
218 :     pEnc->mbParam.mb_height,
219 :     CACHE_LINE);
220 :     pEnc->reference->mbs = xvid_malloc(sizeof(MACROBLOCK) * \
221 :     pEnc->mbParam.mb_width * \
222 :     pEnc->mbParam.mb_height,
223 :     CACHE_LINE);
224 : suxen_drol 136
225 : edgomez 192 if (pEnc->current->mbs == NULL || pEnc->reference->mbs == NULL)
226 :     goto xvid_err_memory2;
227 : suxen_drol 136
228 :     /* try to allocate image memory */
229 :    
230 :     #ifdef _DEBUG
231 :     image_null(&pEnc->sOriginal);
232 :     #endif
233 : suxen_drol 152 #ifdef BFRAMES
234 :     image_null(&pEnc->f_refh);
235 :     image_null(&pEnc->f_refv);
236 :     image_null(&pEnc->f_refhv);
237 :     #endif
238 : suxen_drol 136 image_null(&pEnc->current->image);
239 :     image_null(&pEnc->reference->image);
240 :     image_null(&pEnc->vInterH);
241 :     image_null(&pEnc->vInterV);
242 :     image_null(&pEnc->vInterVf);
243 :     image_null(&pEnc->vInterHV);
244 :     image_null(&pEnc->vInterHVf);
245 : edgomez 192
246 : suxen_drol 136 #ifdef _DEBUG
247 : edgomez 192 if (image_create(&pEnc->sOriginal,
248 :     pEnc->mbParam.edged_width,
249 :     pEnc->mbParam.edged_height) < 0)
250 :     goto xvid_err_memory3;
251 : suxen_drol 136 #endif
252 : suxen_drol 152 #ifdef BFRAMES
253 : edgomez 192 if (image_create(&pEnc->f_refh,
254 :     pEnc->mbParam.edged_width,
255 :     pEnc->mbParam.edged_height) < 0)
256 :     goto xvid_err_memory3;
257 :     if (image_create(&pEnc->f_refv,
258 :     pEnc->mbParam.edged_width,
259 :     pEnc->mbParam.edged_height) < 0)
260 :     goto xvid_err_memory3;
261 :     if (image_create(&pEnc->f_refhv,
262 :     pEnc->mbParam.edged_width,
263 :     pEnc->mbParam.edged_height) < 0)
264 :     goto xvid_err_memory3;
265 : suxen_drol 152 #endif
266 : edgomez 192 if (image_create(&pEnc->current->image,
267 :     pEnc->mbParam.edged_width,
268 :     pEnc->mbParam.edged_height) < 0)
269 :     goto xvid_err_memory3;
270 :     if (image_create(&pEnc->reference->image,
271 :     pEnc->mbParam.edged_width,
272 :     pEnc->mbParam.edged_height) < 0)
273 :     goto xvid_err_memory3;
274 :     if (image_create(&pEnc->vInterH,
275 :     pEnc->mbParam.edged_width,
276 :     pEnc->mbParam.edged_height) < 0)
277 :     goto xvid_err_memory3;
278 :     if (image_create(&pEnc->vInterV,
279 :     pEnc->mbParam.edged_width,
280 :     pEnc->mbParam.edged_height) < 0)
281 :     goto xvid_err_memory3;
282 :     if (image_create(&pEnc->vInterVf,
283 :     pEnc->mbParam.edged_width,
284 :     pEnc->mbParam.edged_height) < 0)
285 :     goto xvid_err_memory3;
286 :     if (image_create(&pEnc->vInterHV,
287 :     pEnc->mbParam.edged_width,
288 :     pEnc->mbParam.edged_height) < 0)
289 :     goto xvid_err_memory3;
290 :     if (image_create(&pEnc->vInterHVf,
291 :     pEnc->mbParam.edged_width,
292 :     pEnc->mbParam.edged_height) < 0)
293 :     goto xvid_err_memory3;
294 : suxen_drol 136
295 : Isibaar 3
296 : edgomez 192
297 :     /* B Frames specific init */
298 : suxen_drol 152 #ifdef BFRAMES
299 :    
300 : suxen_drol 164 pEnc->mbParam.max_bframes = pParam->max_bframes;
301 : suxen_drol 152 pEnc->bquant_ratio = pParam->bquant_ratio;
302 : edgomez 192 pEnc->bframes = NULL;
303 :    
304 : suxen_drol 164 if (pEnc->mbParam.max_bframes > 0)
305 : suxen_drol 152 {
306 :     int n;
307 :    
308 : edgomez 192 pEnc->bframes = xvid_malloc(pEnc->mbParam.max_bframes * \
309 :     sizeof(FRAMEINFO *),
310 :     CACHE_LINE);
311 : suxen_drol 152
312 : edgomez 192 if (pEnc->bframes == NULL)
313 :     goto xvid_err_memory3;
314 :    
315 :     for (n=0; n<pEnc->mbParam.max_bframes; n++)
316 :     pEnc->bframes[n] = NULL;
317 :    
318 :    
319 : suxen_drol 164 for (n = 0; n < pEnc->mbParam.max_bframes; n++)
320 : suxen_drol 152 {
321 : edgomez 192 pEnc->bframes[n] = xvid_malloc(sizeof(FRAMEINFO),
322 :     CACHE_LINE);
323 : suxen_drol 152
324 : edgomez 192 if (pEnc->bframes[n] == NULL)
325 :     goto xvid_err_memory4;
326 :    
327 :     pEnc->bframes[n]->mbs = xvid_malloc(sizeof(MACROBLOCK) * \
328 :     pEnc->mbParam.mb_width * \
329 :     pEnc->mbParam.mb_height,
330 :     CACHE_LINE);
331 :    
332 :     if (pEnc->bframes[n]->mbs == NULL)
333 :     goto xvid_err_memory4;
334 :    
335 :     image_null(&pEnc->bframes[n]->image);
336 :    
337 :     if (image_create(&pEnc->bframes[n]->image,
338 :     pEnc->mbParam.edged_width,
339 :     pEnc->mbParam.edged_height) < 0)
340 :     goto xvid_err_memory4;
341 :    
342 : suxen_drol 152 }
343 :     }
344 : edgomez 192
345 : suxen_drol 152 pEnc->bframenum_head = 0;
346 :     pEnc->bframenum_tail = 0;
347 :     pEnc->flush_bframes = 0;
348 :    
349 :     pEnc->mbParam.m_seconds = 0;
350 :     pEnc->mbParam.m_ticks = 0;
351 :     #endif
352 :    
353 : edgomez 13 pParam->handle = (void *)pEnc;
354 : Isibaar 3
355 : h 121 if (pParam->rc_bitrate)
356 : Isibaar 3 {
357 : edgomez 188 RateControlInit(&pEnc->rate_control,
358 :     pParam->rc_bitrate,
359 :     pParam->rc_reaction_delay_factor,
360 :     pParam->rc_averaging_period,
361 :     pParam->rc_buffer,
362 :     pParam->fbase * 1000 / pParam->fincr,
363 :     pParam->max_quantizer,
364 :     pParam->min_quantizer);
365 : Isibaar 3 }
366 :    
367 : Isibaar 36 init_timer();
368 : Isibaar 3
369 :     return XVID_ERR_OK;
370 : edgomez 192
371 :     /*
372 :     * We handle all XVID_ERR_MEMORY here, this makes the code lighter
373 :     *
374 :     * ToDo?: We could avoid that piece of code if encoder_destroy could
375 :     * handle different destroy levels
376 :     */
377 :     #ifdef BFRAMES
378 :     xvid_err_memory4:
379 :     for (i=0; i<pEnc->mbParam.max_bframes; i++)
380 :     {
381 :    
382 :     if (pEnc->bframes[i] == NULL) continue;
383 :    
384 :     image_destroy(&pEnc->bframes[i]->image,
385 :     pEnc->mbParam.edged_width,
386 :     pEnc->mbParam.edged_height);
387 :    
388 :     xvid_free(pEnc->bframes[i]->mbs);
389 :    
390 :     xvid_free(pEnc->bframes[i]);
391 :    
392 :     }
393 :    
394 :     xvid_free(pEnc->bframes);
395 :    
396 :     #endif
397 :    
398 :     xvid_err_memory3:
399 :     #ifdef _DEBUG
400 :     image_destroy(&pEnc->sOriginal,
401 :     pEnc->mbParam.edged_width,
402 :     pEnc->mbParam.edged_height);
403 :     #endif
404 :    
405 :     #ifdef BFRAMES
406 :     image_destroy(&pEnc->f_refh,
407 :     pEnc->mbParam.edged_width,
408 :     pEnc->mbParam.edged_height);
409 :     image_destroy(&pEnc->f_refv,
410 :     pEnc->mbParam.edged_width,
411 :     pEnc->mbParam.edged_height);
412 :     image_destroy(&pEnc->f_refhv,
413 :     pEnc->mbParam.edged_width,
414 :     pEnc->mbParam.edged_height);
415 :     #endif
416 :    
417 :     image_destroy(&pEnc->current->image,
418 :     pEnc->mbParam.edged_width,
419 :     pEnc->mbParam.edged_height);
420 :     image_destroy(&pEnc->reference->image,
421 :     pEnc->mbParam.edged_width,
422 :     pEnc->mbParam.edged_height);
423 :     image_destroy(&pEnc->vInterH,
424 :     pEnc->mbParam.edged_width,
425 :     pEnc->mbParam.edged_height);
426 :     image_destroy(&pEnc->vInterV,
427 :     pEnc->mbParam.edged_width,
428 :     pEnc->mbParam.edged_height);
429 :     image_destroy(&pEnc->vInterVf,
430 :     pEnc->mbParam.edged_width,
431 :     pEnc->mbParam.edged_height);
432 :     image_destroy(&pEnc->vInterHV,
433 :     pEnc->mbParam.edged_width,
434 :     pEnc->mbParam.edged_height);
435 :     image_destroy(&pEnc->vInterHVf,
436 :     pEnc->mbParam.edged_width,
437 :     pEnc->mbParam.edged_height);
438 :    
439 :     xvid_err_memory2:
440 :     xvid_free(pEnc->current->mbs);
441 :     xvid_free(pEnc->reference->mbs);
442 :    
443 :     xvid_err_memory1:
444 :     xvid_free(pEnc->current);
445 :     xvid_free(pEnc->reference);
446 :     xvid_free(pEnc);
447 :    
448 :     return XVID_ERR_MEMORY;
449 : Isibaar 3 }
450 :    
451 :     int encoder_destroy(Encoder * pEnc)
452 :     {
453 : edgomez 13 ENC_CHECK(pEnc);
454 : Isibaar 3
455 : edgomez 192 /* B Frames specific */
456 : suxen_drol 152 #ifdef BFRAMES
457 : edgomez 192 int i;
458 :    
459 :     for (i=0; i<pEnc->mbParam.max_bframes; i++)
460 : suxen_drol 152 {
461 : edgomez 192
462 :     if (pEnc->bframes[i] == NULL) continue;
463 :    
464 :     image_destroy(&pEnc->bframes[i]->image,
465 :     pEnc->mbParam.edged_width,
466 :     pEnc->mbParam.edged_height);
467 :    
468 :     xvid_free(pEnc->bframes[i]->mbs);
469 :    
470 :     xvid_free(pEnc->bframes[i]);
471 :    
472 : suxen_drol 152 }
473 : edgomez 192
474 :     xvid_free(pEnc->bframes);
475 :    
476 : edgomez 158 #endif
477 : suxen_drol 152
478 : edgomez 192 /* All images, reference, current etc ... */
479 :    
480 :     image_destroy(&pEnc->current->image,
481 :     pEnc->mbParam.edged_width,
482 :     pEnc->mbParam.edged_height);
483 :     image_destroy(&pEnc->reference->image,
484 :     pEnc->mbParam.edged_width,
485 :     pEnc->mbParam.edged_height);
486 :     image_destroy(&pEnc->vInterH,
487 :     pEnc->mbParam.edged_width,
488 :     pEnc->mbParam.edged_height);
489 :     image_destroy(&pEnc->vInterV,
490 :     pEnc->mbParam.edged_width,
491 :     pEnc->mbParam.edged_height);
492 :     image_destroy(&pEnc->vInterVf,
493 :     pEnc->mbParam.edged_width,
494 :     pEnc->mbParam.edged_height);
495 :     image_destroy(&pEnc->vInterHV,
496 :     pEnc->mbParam.edged_width,
497 :     pEnc->mbParam.edged_height);
498 :     image_destroy(&pEnc->vInterHVf,
499 :     pEnc->mbParam.edged_width,
500 :     pEnc->mbParam.edged_height);
501 : suxen_drol 152 #ifdef BFRAMES
502 : edgomez 192 image_destroy(&pEnc->f_refh,
503 :     pEnc->mbParam.edged_width,
504 :     pEnc->mbParam.edged_height);
505 :     image_destroy(&pEnc->f_refv,
506 :     pEnc->mbParam.edged_width,
507 :     pEnc->mbParam.edged_height);
508 :     image_destroy(&pEnc->f_refhv,
509 :     pEnc->mbParam.edged_width,
510 :     pEnc->mbParam.edged_height);
511 : suxen_drol 152 #endif
512 : Isibaar 113 #ifdef _DEBUG
513 : edgomez 192 image_destroy(&pEnc->sOriginal,
514 :     pEnc->mbParam.edged_width,
515 :     pEnc->mbParam.edged_height);
516 : Isibaar 113 #endif
517 : edgomez 192
518 :     /* Encoder structure */
519 :    
520 : suxen_drol 136 xvid_free(pEnc->current->mbs);
521 :     xvid_free(pEnc->current);
522 :    
523 :     xvid_free(pEnc->reference->mbs);
524 :     xvid_free(pEnc->reference);
525 :    
526 : Isibaar 41 xvid_free(pEnc);
527 : edgomez 192
528 : edgomez 13 return XVID_ERR_OK;
529 : Isibaar 3 }
530 :    
531 : suxen_drol 152
532 :    
533 :     // ==================================================================
534 :     #ifdef BFRAMES
535 : Isibaar 3 int encoder_encode(Encoder * pEnc, XVID_ENC_FRAME * pFrame, XVID_ENC_STATS * pResult)
536 :     {
537 : edgomez 13 uint16_t x, y;
538 :     Bitstream bs;
539 :     uint32_t bits;
540 : suxen_drol 152
541 : chenm001 168 #ifdef _DEBUG
542 :     float psnr;
543 :     char temp[128];
544 :     #endif
545 :    
546 : suxen_drol 152 ENC_CHECK(pEnc);
547 :     ENC_CHECK(pFrame);
548 :    
549 :     start_global_timer();
550 :    
551 :     BitstreamInit(&bs, pFrame->bitstream, 0);
552 :    
553 :     // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
554 :     // bframe "flush" code
555 :     // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
556 :    
557 :     if ((pFrame->image == NULL || pEnc->flush_bframes) &&
558 :     pEnc->bframenum_head < pEnc->bframenum_tail)
559 :     {
560 :    
561 :     if (pEnc->flush_bframes == 0)
562 :     {
563 :     // we have reached end of stream without getting a future reference
564 :     // .. so encode last final frame a pframe
565 : edgomez 192 //dprintf("--- PFRAME (final frame correction) --- ");
566 : suxen_drol 152 pEnc->bframenum_tail--;
567 :     SWAP(pEnc->current, pEnc->reference);
568 :    
569 :     SWAP(pEnc->current, pEnc->bframes[pEnc->bframenum_tail]);
570 :    
571 :     FrameCodeP(pEnc, &bs, &bits, 1, 0);
572 :    
573 :     BitstreamPad(&bs);
574 :     pFrame->length = BitstreamLength(&bs);
575 :     pFrame->input_consumed = 0;
576 :     pFrame->intra = 0;
577 :     return XVID_ERR_OK;
578 :     }
579 :    
580 : edgomez 192 //dprintf("--- BFRAME (flush) --- ");
581 : suxen_drol 152 FrameCodeB(pEnc,
582 :     pEnc->bframes[pEnc->bframenum_head],
583 :     &bs, &bits);
584 :     pEnc->bframenum_head++;
585 :    
586 :    
587 :     BitstreamPad(&bs);
588 :     pFrame->length = BitstreamLength(&bs);
589 :     pFrame->input_consumed = 0;
590 :     pFrame->intra = 0;
591 :     return XVID_ERR_OK;
592 :     }
593 :    
594 :     if (pFrame->image == NULL)
595 :     {
596 :     pFrame->length = 0;
597 :     pFrame->input_consumed = 1;
598 :     pFrame->intra = 0;
599 :     return XVID_ERR_OK;
600 :     }
601 :    
602 :     if (pEnc->bframenum_head > 0)
603 :     {
604 :     pEnc->bframenum_head = pEnc->bframenum_tail = 0;
605 :     }
606 :    
607 :     pEnc->flush_bframes = 0;
608 :    
609 :     // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
610 :    
611 :     SWAP(pEnc->current, pEnc->reference);
612 :    
613 : edgomez 189 pEnc->current->quant = (pFrame->quant == 0) ? RateControlGetQ(&pEnc->rate_control, 0) : pFrame->quant;
614 : Isibaar 157
615 :     if(pEnc->current->quant < 1)
616 :     pEnc->current->quant = 1;
617 :    
618 :     if(pEnc->current->quant > 31)
619 :     pEnc->current->quant = 31;
620 :    
621 : suxen_drol 152 pEnc->current->global_flags = pFrame->general;
622 :     pEnc->current->motion_flags = pFrame->motion;
623 :     pEnc->current->seconds = pEnc->mbParam.m_seconds;
624 :     pEnc->current->ticks = pEnc->mbParam.m_ticks;
625 :     //@@@ TODO: dyanmic fcode (in both directions)
626 :     pEnc->current->fcode = pEnc->mbParam.m_fcode;
627 :     pEnc->current->bcode = pEnc->mbParam.m_fcode;
628 :    
629 :     start_timer();
630 :     if (image_input(&pEnc->current->image, pEnc->mbParam.width, pEnc->mbParam.height, pEnc->mbParam.edged_width,
631 :     pFrame->image, pFrame->colorspace))
632 :     {
633 :     return XVID_ERR_FORMAT;
634 :     }
635 :     stop_conv_timer();
636 :    
637 :     #ifdef _DEBUG
638 : chenm001 168 image_copy(&pEnc->sOriginal, &pEnc->current->image, pEnc->mbParam.edged_width, pEnc->mbParam.height);
639 : suxen_drol 152 #endif
640 :    
641 :    
642 :     // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
643 :     // lumi masking
644 :     // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
645 :    
646 :     if ((pEnc->current->global_flags & XVID_LUMIMASKING))
647 :     {
648 :     int * temp_dquants = (int *) xvid_malloc(pEnc->mbParam.mb_width * pEnc->mbParam.mb_height * sizeof(int), CACHE_LINE);
649 :    
650 :     pEnc->current->quant = adaptive_quantization(pEnc->current->image.y,
651 :     pEnc->mbParam.edged_width, // stride
652 :     temp_dquants,
653 :     pEnc->current->quant,
654 :     pEnc->current->quant, // min_quant
655 :     2*pEnc->current->quant, // max_quant
656 :     pEnc->mbParam.mb_width,
657 :     pEnc->mbParam.mb_height);
658 :    
659 :     for (y = 0; y < pEnc->mbParam.mb_height; y++)
660 :     for (x = 0; x < pEnc->mbParam.mb_width; x++)
661 :     {
662 :     MACROBLOCK *pMB = &pEnc->current->mbs[x + y * pEnc->mbParam.mb_width];
663 :     pMB->dquant = iDQtab[(temp_dquants[y * pEnc->mbParam.mb_width + x] + 2)];
664 :     }
665 :     xvid_free(temp_dquants);
666 :     }
667 :    
668 :    
669 :     // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
670 :     // ivop/pvop/bvop selection
671 :     // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
672 :    
673 :     if (pEnc->iFrameNum == 0 ||
674 :     pFrame->intra == 1 ||
675 :     (pFrame->intra < 0 && (pEnc->iMaxKeyInterval > 0 && pEnc->iFrameNum >= pEnc->iMaxKeyInterval)) ||
676 :     image_mad(&pEnc->reference->image, &pEnc->current->image, pEnc->mbParam.edged_width, pEnc->mbParam.width, pEnc->mbParam.height) > 30)
677 :     {
678 : edgomez 192 //dprintf("--- IFRAME ---");
679 : suxen_drol 152
680 :     FrameCodeI(pEnc, &bs, &bits);
681 :    
682 :     pFrame->intra = 1;
683 :     pEnc->flush_bframes = 1;
684 :    
685 :     /* note: sequences like "IIBB" decode fine with msfdam but,
686 :     go screwy with divx5.00 */
687 :     }
688 : suxen_drol 164 else if (pEnc->bframenum_tail >= pEnc->mbParam.max_bframes)
689 : suxen_drol 152 {
690 : edgomez 192 //dprintf("--- PFRAME ---");
691 : suxen_drol 152
692 :     FrameCodeP(pEnc, &bs, &bits, 1, 0);
693 :     pFrame->intra = 0;
694 :     pEnc->flush_bframes = 1;
695 :     }
696 :     else
697 :     {
698 : edgomez 192 //dprintf("--- BFRAME (store) --- head=%i tail=%i", pEnc->bframenum_head, pEnc->bframenum_tail);
699 : suxen_drol 152
700 :     if (pFrame->bquant < 1)
701 :     {
702 :     pEnc->current->quant = ((pEnc->reference->quant + pEnc->current->quant) * pEnc->bquant_ratio) / 200;
703 :     }
704 :     else
705 :     {
706 :     pEnc->current->quant = pFrame->bquant;
707 :     }
708 :    
709 :     // store frame into bframe buffer & swap ref back to current
710 :     SWAP(pEnc->current, pEnc->bframes[pEnc->bframenum_tail]);
711 :     SWAP(pEnc->current, pEnc->reference);
712 :    
713 :     pEnc->bframenum_tail++;
714 :    
715 :     pFrame->intra = 0;
716 :     pFrame->length = 0;
717 :     pFrame->input_consumed = 1;
718 :    
719 :     pEnc->mbParam.m_ticks += pEnc->mbParam.fincr;
720 :     if (pEnc->mbParam.m_ticks > pEnc->mbParam.fbase)
721 :     {
722 :     pEnc->mbParam.m_seconds++;
723 :     pEnc->mbParam.m_ticks = 0;
724 :     }
725 :     return XVID_ERR_OK;
726 :     }
727 :    
728 :     BitstreamPad(&bs);
729 :     pFrame->length = BitstreamLength(&bs);
730 :    
731 :     if (pResult)
732 :     {
733 :     pResult->quant = pEnc->current->quant;
734 :     pResult->hlength = pFrame->length - (pEnc->sStat.iTextBits / 8);
735 :     pResult->kblks = pEnc->sStat.kblks;
736 :     pResult->mblks = pEnc->sStat.mblks;
737 :     pResult->ublks = pEnc->sStat.ublks;
738 :     }
739 :    
740 :     #ifdef _DEBUG
741 :     psnr = image_psnr(&pEnc->sOriginal, &pEnc->current->image, pEnc->mbParam.edged_width,
742 :     pEnc->mbParam.width, pEnc->mbParam.height);
743 :    
744 :     sprintf(temp, "PSNR: %f\n", psnr);
745 :     DEBUG(temp);
746 :     #endif
747 :    
748 :     if (pFrame->quant == 0)
749 :     {
750 : edgomez 189 RateControlUpdate(&pEnc->rate_control,
751 :     pEnc->current->quant,
752 :     pFrame->length,
753 :     pFrame->intra);
754 : suxen_drol 152 }
755 :    
756 :     pEnc->iFrameNum++;
757 :     pEnc->mbParam.m_ticks += pEnc->mbParam.fincr;
758 :     if (pEnc->mbParam.m_ticks > pEnc->mbParam.fbase)
759 :     {
760 :     pEnc->mbParam.m_seconds++;
761 :     pEnc->mbParam.m_ticks = 0;
762 :     }
763 :     pFrame->input_consumed = 1;
764 :    
765 :     stop_global_timer();
766 :     write_timer();
767 :    
768 :     return XVID_ERR_OK;
769 :     }
770 :     // ==================================================================
771 :     #else
772 :     int encoder_encode(Encoder * pEnc, XVID_ENC_FRAME * pFrame, XVID_ENC_STATS * pResult)
773 :     {
774 :     uint16_t x, y;
775 :     Bitstream bs;
776 :     uint32_t bits;
777 : Isibaar 4 uint16_t write_vol_header = 0;
778 : Isibaar 113 #ifdef _DEBUG
779 :     float psnr;
780 :     uint8_t temp[100];
781 :     #endif
782 : Isibaar 3
783 :     start_global_timer();
784 :    
785 : edgomez 13 ENC_CHECK(pEnc);
786 :     ENC_CHECK(pFrame);
787 :     ENC_CHECK(pFrame->bitstream);
788 :     ENC_CHECK(pFrame->image);
789 : Isibaar 3
790 : suxen_drol 136 SWAP(pEnc->current, pEnc->reference);
791 :    
792 :     pEnc->current->global_flags = pFrame->general;
793 :     pEnc->current->motion_flags = pFrame->motion;
794 : h 101 pEnc->mbParam.hint = &pFrame->hint;
795 : Isibaar 3
796 :     start_timer();
797 : suxen_drol 136 if (image_input(&pEnc->current->image, pEnc->mbParam.width, pEnc->mbParam.height, pEnc->mbParam.edged_width,
798 : edgomez 13 pFrame->image, pFrame->colorspace))
799 : Isibaar 3 {
800 :     return XVID_ERR_FORMAT;
801 :     }
802 :     stop_conv_timer();
803 :    
804 : Isibaar 113 #ifdef _DEBUG
805 : chenm001 150 image_copy(&pEnc->sOriginal, &pEnc->current->image, pEnc->mbParam.edged_width, pEnc->mbParam.height);
806 : Isibaar 113 #endif
807 :    
808 : suxen_drol 136 EMMS();
809 :    
810 : edgomez 13 BitstreamInit(&bs, pFrame->bitstream, 0);
811 : Isibaar 3
812 :     if (pFrame->quant == 0)
813 :     {
814 : edgomez 188 pEnc->current->quant = RateControlGetQ(&pEnc->rate_control,0);
815 : Isibaar 3 }
816 :     else
817 :     {
818 : suxen_drol 136 pEnc->current->quant = pFrame->quant;
819 : Isibaar 3 }
820 :    
821 : suxen_drol 136 if ((pEnc->current->global_flags & XVID_LUMIMASKING))
822 : Isibaar 3 {
823 : canard 66 int * temp_dquants = (int *) xvid_malloc(pEnc->mbParam.mb_width * pEnc->mbParam.mb_height * sizeof(int), CACHE_LINE);
824 : Isibaar 3
825 : suxen_drol 136 pEnc->current->quant = adaptive_quantization(pEnc->current->image.y,
826 :     pEnc->mbParam.edged_width, // stride
827 : edgomez 78 temp_dquants,
828 : suxen_drol 136 pEnc->current->quant,
829 :     pEnc->current->quant, // min_quant
830 :     2*pEnc->current->quant, // max_quant
831 : edgomez 78 pEnc->mbParam.mb_width,
832 :     pEnc->mbParam.mb_height);
833 : Isibaar 3
834 :     for (y = 0; y < pEnc->mbParam.mb_height; y++)
835 :     for (x = 0; x < pEnc->mbParam.mb_width; x++)
836 :     {
837 : suxen_drol 136 MACROBLOCK *pMB = &pEnc->current->mbs[x + y * pEnc->mbParam.mb_width];
838 : Isibaar 3 pMB->dquant = iDQtab[(temp_dquants[y * pEnc->mbParam.mb_width + x] + 2)];
839 :     }
840 : Isibaar 41 xvid_free(temp_dquants);
841 : Isibaar 3 }
842 :    
843 : suxen_drol 136 if (pEnc->current->global_flags & XVID_H263QUANT) {
844 :     if(pEnc->mbParam.m_quant_type != H263_QUANT)
845 : Isibaar 20 write_vol_header = 1;
846 : suxen_drol 136 pEnc->mbParam.m_quant_type = H263_QUANT;
847 : Isibaar 3 }
848 : suxen_drol 136 else if(pEnc->current->global_flags & XVID_MPEGQUANT) {
849 : Isibaar 20 int ret1, ret2;
850 : Isibaar 3
851 : edgomez 78 ret1 = ret2 = 0;
852 :    
853 : suxen_drol 136 if(pEnc->mbParam.m_quant_type != MPEG4_QUANT)
854 : Isibaar 20 write_vol_header = 1;
855 :    
856 : suxen_drol 136 pEnc->mbParam.m_quant_type = MPEG4_QUANT;
857 : Isibaar 20
858 : suxen_drol 136 if ((pEnc->current->global_flags & XVID_CUSTOM_QMATRIX) > 0) {
859 : Isibaar 20 if(pFrame->quant_intra_matrix != NULL)
860 :     ret1 = set_intra_matrix(pFrame->quant_intra_matrix);
861 :     if(pFrame->quant_inter_matrix != NULL)
862 :     ret2 = set_inter_matrix(pFrame->quant_inter_matrix);
863 :     }
864 :     else {
865 :     ret1 = set_intra_matrix(get_default_intra_matrix());
866 :     ret2 = set_inter_matrix(get_default_inter_matrix());
867 :     }
868 : Isibaar 4 if(write_vol_header == 0)
869 :     write_vol_header = ret1 | ret2;
870 :     }
871 : Isibaar 3
872 :     if (pFrame->intra < 0)
873 : edgomez 13 {
874 : Isibaar 3 if ((pEnc->iFrameNum == 0) || ((pEnc->iMaxKeyInterval > 0)
875 : edgomez 13 && (pEnc->iFrameNum >= pEnc->iMaxKeyInterval)))
876 : Isibaar 3
877 :     pFrame->intra = FrameCodeI(pEnc, &bs, &bits);
878 :     else
879 : Isibaar 4 pFrame->intra = FrameCodeP(pEnc, &bs, &bits, 0, write_vol_header);
880 : edgomez 13 }
881 :     else
882 :     {
883 : Isibaar 3 if (pFrame->intra == 1)
884 : edgomez 13 pFrame->intra = FrameCodeI(pEnc, &bs, &bits);
885 : Isibaar 3 else
886 : Isibaar 4 pFrame->intra = FrameCodeP(pEnc, &bs, &bits, 1, write_vol_header);
887 : edgomez 13 }
888 : Isibaar 3
889 :     BitstreamPutBits(&bs, 0xFFFF, 16);
890 : edgomez 13 BitstreamPutBits(&bs, 0xFFFF, 16);
891 :     BitstreamPad(&bs);
892 :     pFrame->length = BitstreamLength(&bs);
893 : h 29
894 : Isibaar 3 if (pResult)
895 : edgomez 13 {
896 : suxen_drol 136 pResult->quant = pEnc->current->quant;
897 : Isibaar 3 pResult->hlength = pFrame->length - (pEnc->sStat.iTextBits / 8);
898 :     pResult->kblks = pEnc->sStat.kblks;
899 :     pResult->mblks = pEnc->sStat.mblks;
900 :     pResult->ublks = pEnc->sStat.ublks;
901 : edgomez 13 }
902 : Isibaar 3
903 : Isibaar 41 EMMS();
904 :    
905 : h 29 if (pFrame->quant == 0)
906 : Isibaar 3 {
907 : edgomez 188 RateControlUpdate(&pEnc->rate_control,
908 :     pEnc->current->quant,
909 :     pFrame->length,
910 :     pFrame->intra);
911 : Isibaar 3 }
912 :    
913 : Isibaar 113 #ifdef _DEBUG
914 : suxen_drol 136 psnr = image_psnr(&pEnc->sOriginal, &pEnc->current->image, pEnc->mbParam.edged_width,
915 : Isibaar 113 pEnc->mbParam.width, pEnc->mbParam.height);
916 :    
917 :     sprintf(temp, "PSNR: %f\n", psnr);
918 :     DEBUG(temp);
919 :     #endif
920 :    
921 : Isibaar 3 pEnc->iFrameNum++;
922 :    
923 :     stop_global_timer();
924 :     write_timer();
925 :    
926 :     return XVID_ERR_OK;
927 :     }
928 : suxen_drol 152 #endif
929 : Isibaar 3
930 :    
931 :     static __inline void CodeIntraMB(Encoder *pEnc, MACROBLOCK *pMB) {
932 :    
933 :     pMB->mode = MODE_INTRA;
934 :    
935 : suxen_drol 136 /* zero mv statistics */
936 :     pMB->mvs[0].x = pMB->mvs[1].x = pMB->mvs[2].x = pMB->mvs[3].x = 0;
937 :     pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = 0;
938 :     pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = 0;
939 :     pMB->sad16 = 0;
940 :    
941 :     if ((pEnc->current->global_flags & XVID_LUMIMASKING)) {
942 : Isibaar 3 if(pMB->dquant != NO_CHANGE)
943 :     {
944 :     pMB->mode = MODE_INTRA_Q;
945 : suxen_drol 136 pEnc->current->quant += DQtab[pMB->dquant];
946 : Isibaar 3
947 : suxen_drol 136 if (pEnc->current->quant > 31) pEnc->current->quant = 31;
948 :     if (pEnc->current->quant < 1) pEnc->current->quant = 1;
949 : Isibaar 3 }
950 :     }
951 :    
952 : suxen_drol 136 pMB->quant = pEnc->current->quant;
953 : Isibaar 3 }
954 :    
955 :    
956 : h 101 #define FCODEBITS 3
957 :     #define MODEBITS 5
958 :    
959 :     void HintedMESet(Encoder * pEnc, int * intra)
960 :     {
961 :     HINTINFO * hint;
962 :     Bitstream bs;
963 :     int length, high;
964 :     uint32_t x, y;
965 :    
966 :     hint = pEnc->mbParam.hint;
967 :    
968 :     if (hint->rawhints)
969 :     {
970 :     *intra = hint->mvhint.intra;
971 :     }
972 :     else
973 :     {
974 :     BitstreamInit(&bs, hint->hintstream, hint->hintlength);
975 :     *intra = BitstreamGetBit(&bs);
976 :     }
977 :    
978 :     if (*intra)
979 :     {
980 :     return;
981 :     }
982 :    
983 : suxen_drol 136 pEnc->current->fcode = (hint->rawhints) ? hint->mvhint.fcode : BitstreamGetBits(&bs, FCODEBITS);
984 : h 101
985 : suxen_drol 136 length = pEnc->current->fcode + 5;
986 : h 101 high = 1 << (length - 1);
987 :    
988 :     for (y=0 ; y<pEnc->mbParam.mb_height ; ++y)
989 :     {
990 :     for (x=0 ; x<pEnc->mbParam.mb_width ; ++x)
991 :     {
992 : suxen_drol 136 MACROBLOCK * pMB = &pEnc->current->mbs[x + y * pEnc->mbParam.mb_width];
993 : h 101 MVBLOCKHINT * bhint = &hint->mvhint.block[x + y * pEnc->mbParam.mb_width];
994 :     VECTOR pred[4];
995 :     VECTOR tmp;
996 : edgomez 147 int32_t dummy[4];
997 : h 101 int vec;
998 :    
999 :     pMB->mode = (hint->rawhints) ? bhint->mode : BitstreamGetBits(&bs, MODEBITS);
1000 :    
1001 : h 128 pMB->mode = (pMB->mode == MODE_INTER_Q) ? MODE_INTER : pMB->mode;
1002 :     pMB->mode = (pMB->mode == MODE_INTRA_Q) ? MODE_INTRA : pMB->mode;
1003 :    
1004 :     if (pMB->mode == MODE_INTER)
1005 : h 101 {
1006 :     tmp.x = (hint->rawhints) ? bhint->mvs[0].x : BitstreamGetBits(&bs, length);
1007 :     tmp.y = (hint->rawhints) ? bhint->mvs[0].y : BitstreamGetBits(&bs, length);
1008 :     tmp.x -= (tmp.x >= high) ? high*2 : 0;
1009 :     tmp.y -= (tmp.y >= high) ? high*2 : 0;
1010 :    
1011 : suxen_drol 136 get_pmvdata(pEnc->current->mbs, x, y, pEnc->mbParam.mb_width, 0, pred, dummy);
1012 : h 101
1013 :     for (vec=0 ; vec<4 ; ++vec)
1014 :     {
1015 :     pMB->mvs[vec].x = tmp.x;
1016 :     pMB->mvs[vec].y = tmp.y;
1017 :     pMB->pmvs[vec].x = pMB->mvs[0].x - pred[0].x;
1018 :     pMB->pmvs[vec].y = pMB->mvs[0].y - pred[0].y;
1019 :     }
1020 :     }
1021 :     else if (pMB->mode == MODE_INTER4V)
1022 :     {
1023 :     for (vec=0 ; vec<4 ; ++vec)
1024 :     {
1025 :     tmp.x = (hint->rawhints) ? bhint->mvs[vec].x : BitstreamGetBits(&bs, length);
1026 :     tmp.y = (hint->rawhints) ? bhint->mvs[vec].y : BitstreamGetBits(&bs, length);
1027 :     tmp.x -= (tmp.x >= high) ? high*2 : 0;
1028 :     tmp.y -= (tmp.y >= high) ? high*2 : 0;
1029 :    
1030 : suxen_drol 136 get_pmvdata(pEnc->current->mbs, x, y, pEnc->mbParam.mb_width, vec, pred, dummy);
1031 : h 101
1032 :     pMB->mvs[vec].x = tmp.x;
1033 :     pMB->mvs[vec].y = tmp.y;
1034 :     pMB->pmvs[vec].x = pMB->mvs[vec].x - pred[0].x;
1035 :     pMB->pmvs[vec].y = pMB->mvs[vec].y - pred[0].y;
1036 :     }
1037 :     }
1038 : h 128 else // intra / stuffing / not_coded
1039 : h 101 {
1040 :     for (vec=0 ; vec<4 ; ++vec)
1041 :     {
1042 :     pMB->mvs[vec].x = pMB->mvs[vec].y = 0;
1043 :     }
1044 :     }
1045 : h 128
1046 : suxen_drol 136 if (pMB->mode == MODE_INTER4V &&
1047 :     (pEnc->current->global_flags & XVID_LUMIMASKING) && pMB->dquant != NO_CHANGE)
1048 : h 128 {
1049 :     pMB->mode = MODE_INTRA;
1050 :    
1051 :     for (vec=0 ; vec<4 ; ++vec)
1052 :     {
1053 :     pMB->mvs[vec].x = pMB->mvs[vec].y = 0;
1054 :     }
1055 :     }
1056 : h 101 }
1057 :     }
1058 :     }
1059 :    
1060 :    
1061 :     void HintedMEGet(Encoder * pEnc, int intra)
1062 :     {
1063 :     HINTINFO * hint;
1064 :     Bitstream bs;
1065 :     uint32_t x, y;
1066 :     int length, high;
1067 :    
1068 :     hint = pEnc->mbParam.hint;
1069 :    
1070 :     if (hint->rawhints)
1071 :     {
1072 :     hint->mvhint.intra = intra;
1073 :     }
1074 :     else
1075 :     {
1076 :     BitstreamInit(&bs, hint->hintstream, 0);
1077 :     BitstreamPutBit(&bs, intra);
1078 :     }
1079 :    
1080 :     if (intra)
1081 :     {
1082 :     if (!hint->rawhints)
1083 :     {
1084 :     BitstreamPad(&bs);
1085 :     hint->hintlength = BitstreamLength(&bs);
1086 :     }
1087 :     return;
1088 :     }
1089 :    
1090 : suxen_drol 136 length = pEnc->current->fcode + 5;
1091 : h 101 high = 1 << (length - 1);
1092 :    
1093 :     if (hint->rawhints)
1094 :     {
1095 : suxen_drol 136 hint->mvhint.fcode = pEnc->current->fcode;
1096 : h 101 }
1097 :     else
1098 :     {
1099 : suxen_drol 136 BitstreamPutBits(&bs, pEnc->current->fcode, FCODEBITS);
1100 : h 101 }
1101 :    
1102 :     for (y=0 ; y<pEnc->mbParam.mb_height ; ++y)
1103 :     {
1104 :     for (x=0 ; x<pEnc->mbParam.mb_width ; ++x)
1105 :     {
1106 : suxen_drol 136 MACROBLOCK * pMB = &pEnc->current->mbs[x + y * pEnc->mbParam.mb_width];
1107 : h 101 MVBLOCKHINT * bhint = &hint->mvhint.block[x + y * pEnc->mbParam.mb_width];
1108 :     VECTOR tmp;
1109 :    
1110 :     if (hint->rawhints)
1111 :     {
1112 :     bhint->mode = pMB->mode;
1113 :     }
1114 :     else
1115 :     {
1116 :     BitstreamPutBits(&bs, pMB->mode, MODEBITS);
1117 :     }
1118 :    
1119 :     if (pMB->mode == MODE_INTER || pMB->mode == MODE_INTER_Q)
1120 :     {
1121 :     tmp.x = pMB->mvs[0].x;
1122 :     tmp.y = pMB->mvs[0].y;
1123 :     tmp.x += (tmp.x < 0) ? high*2 : 0;
1124 :     tmp.y += (tmp.y < 0) ? high*2 : 0;
1125 :    
1126 :     if (hint->rawhints)
1127 :     {
1128 :     bhint->mvs[0].x = tmp.x;
1129 :     bhint->mvs[0].y = tmp.y;
1130 :     }
1131 :     else
1132 :     {
1133 :     BitstreamPutBits(&bs, tmp.x, length);
1134 :     BitstreamPutBits(&bs, tmp.y, length);
1135 :     }
1136 :     }
1137 :     else if (pMB->mode == MODE_INTER4V)
1138 :     {
1139 :     int vec;
1140 :    
1141 :     for (vec=0 ; vec<4 ; ++vec)
1142 :     {
1143 :     tmp.x = pMB->mvs[vec].x;
1144 :     tmp.y = pMB->mvs[vec].y;
1145 :     tmp.x += (tmp.x < 0) ? high*2 : 0;
1146 :     tmp.y += (tmp.y < 0) ? high*2 : 0;
1147 :    
1148 :     if (hint->rawhints)
1149 :     {
1150 :     bhint->mvs[vec].x = tmp.x;
1151 :     bhint->mvs[vec].y = tmp.y;
1152 :     }
1153 :     else
1154 :     {
1155 :     BitstreamPutBits(&bs, tmp.x, length);
1156 :     BitstreamPutBits(&bs, tmp.y, length);
1157 :     }
1158 :     }
1159 :     }
1160 :     }
1161 :     }
1162 :    
1163 :     if (!hint->rawhints)
1164 :     {
1165 :     BitstreamPad(&bs);
1166 :     hint->hintlength = BitstreamLength(&bs);
1167 :     }
1168 :     }
1169 :    
1170 :    
1171 : h 104 static int FrameCodeI(Encoder * pEnc, Bitstream * bs, uint32_t *pBits)
1172 :     {
1173 :    
1174 :     DECLARE_ALIGNED_MATRIX(dct_codes, 6, 64, int16_t, CACHE_LINE);
1175 :     DECLARE_ALIGNED_MATRIX(qcoeff, 6, 64, int16_t, CACHE_LINE);
1176 :    
1177 :     uint16_t x, y;
1178 :    
1179 :     pEnc->iFrameNum = 0;
1180 : suxen_drol 136 pEnc->mbParam.m_rounding_type = 1;
1181 :     pEnc->current->rounding_type = pEnc->mbParam.m_rounding_type;
1182 :     pEnc->current->coding_type = I_VOP;
1183 : h 104
1184 : suxen_drol 136 BitstreamWriteVolHeader(bs, &pEnc->mbParam, pEnc->current);
1185 :     BitstreamWriteVopHeader(bs, &pEnc->mbParam, pEnc->current);
1186 : h 104
1187 :     *pBits = BitstreamPos(bs);
1188 :    
1189 :     pEnc->sStat.iTextBits = 0;
1190 :     pEnc->sStat.kblks = pEnc->mbParam.mb_width * pEnc->mbParam.mb_height;
1191 :     pEnc->sStat.mblks = pEnc->sStat.ublks = 0;
1192 :    
1193 :     for (y = 0; y < pEnc->mbParam.mb_height; y++)
1194 :     for (x = 0; x < pEnc->mbParam.mb_width; x++)
1195 :     {
1196 : suxen_drol 136 MACROBLOCK *pMB = &pEnc->current->mbs[x + y * pEnc->mbParam.mb_width];
1197 : h 104
1198 :     CodeIntraMB(pEnc, pMB);
1199 :    
1200 : suxen_drol 136 MBTransQuantIntra(&pEnc->mbParam, pEnc->current, pMB, x, y, dct_codes, qcoeff);
1201 : h 104
1202 :     start_timer();
1203 : suxen_drol 136 MBPrediction(pEnc->current, x, y, pEnc->mbParam.mb_width, qcoeff);
1204 : h 104 stop_prediction_timer();
1205 :    
1206 :     start_timer();
1207 : suxen_drol 136 MBCoding(pEnc->current, pMB, qcoeff, bs, &pEnc->sStat);
1208 : h 104 stop_coding_timer();
1209 :     }
1210 :    
1211 :     emms();
1212 :    
1213 :     *pBits = BitstreamPos(bs) - *pBits;
1214 :     pEnc->sStat.fMvPrevSigma = -1;
1215 :     pEnc->sStat.iMvSum = 0;
1216 :     pEnc->sStat.iMvCount = 0;
1217 : suxen_drol 136 pEnc->mbParam.m_fcode = 2;
1218 : h 104
1219 : suxen_drol 136 if (pEnc->current->global_flags & XVID_HINTEDME_GET)
1220 : h 104 {
1221 :     HintedMEGet(pEnc, 1);
1222 :     }
1223 :    
1224 :     return 1; // intra
1225 :     }
1226 :    
1227 :    
1228 : Isibaar 3 #define INTRA_THRESHOLD 0.5
1229 :    
1230 :     static int FrameCodeP(Encoder * pEnc, Bitstream * bs, uint32_t *pBits, bool force_inter, bool vol_header)
1231 :     {
1232 : edgomez 13 float fSigma;
1233 : Isibaar 42
1234 : edgomez 78 DECLARE_ALIGNED_MATRIX(dct_codes, 6, 64, int16_t, CACHE_LINE);
1235 :     DECLARE_ALIGNED_MATRIX(qcoeff, 6, 64, int16_t, CACHE_LINE);
1236 :    
1237 : Isibaar 3 int iLimit;
1238 : edgomez 13 uint32_t x, y;
1239 :     int iSearchRange;
1240 : edgomez 145 int bIntra;
1241 : Isibaar 3
1242 : edgomez 145 /* IMAGE *pCurrent = &pEnc->current->image; */
1243 : suxen_drol 136 IMAGE *pRef = &pEnc->reference->image;
1244 : Isibaar 3
1245 : h 69 start_timer();
1246 : edgomez 78 image_setedges(pRef,
1247 : h 85 pEnc->mbParam.edged_width,
1248 :     pEnc->mbParam.edged_height,
1249 :     pEnc->mbParam.width,
1250 :     pEnc->mbParam.height,
1251 : suxen_drol 136 pEnc->current->global_flags & XVID_INTERLACING);
1252 : h 69 stop_edges_timer();
1253 : Isibaar 3
1254 : suxen_drol 136 pEnc->mbParam.m_rounding_type = 1 - pEnc->mbParam.m_rounding_type;
1255 :     pEnc->current->rounding_type = pEnc->mbParam.m_rounding_type;
1256 :     pEnc->current->fcode = pEnc->mbParam.m_fcode;
1257 : Isibaar 3
1258 :     if (!force_inter)
1259 :     iLimit = (int)(pEnc->mbParam.mb_width * pEnc->mbParam.mb_height * INTRA_THRESHOLD);
1260 : edgomez 13 else
1261 : Isibaar 3 iLimit = pEnc->mbParam.mb_width * pEnc->mbParam.mb_height + 1;
1262 :    
1263 : suxen_drol 136 if ((pEnc->current->global_flags & XVID_HALFPEL)) {
1264 : Isibaar 3 start_timer();
1265 : h 85 image_interpolate(pRef, &pEnc->vInterH, &pEnc->vInterV, &pEnc->vInterHV,
1266 :     pEnc->mbParam.edged_width, pEnc->mbParam.edged_height,
1267 : suxen_drol 136 pEnc->current->rounding_type);
1268 : Isibaar 3 stop_inter_timer();
1269 :     }
1270 :    
1271 :     start_timer();
1272 : suxen_drol 136 if (pEnc->current->global_flags & XVID_HINTEDME_SET)
1273 : h 101 {
1274 :     HintedMESet(pEnc, &bIntra);
1275 :     }
1276 :     else
1277 :     {
1278 : suxen_drol 136 bIntra = MotionEstimation(
1279 :     &pEnc->mbParam,
1280 :     pEnc->current,
1281 :     pEnc->reference,
1282 :     &pEnc->vInterH,
1283 :     &pEnc->vInterV,
1284 :     &pEnc->vInterHV,
1285 :     iLimit);
1286 : h 101 }
1287 : Isibaar 3 stop_motion_timer();
1288 :    
1289 :     if (bIntra == 1)
1290 : h 101 {
1291 : Isibaar 3 return FrameCodeI(pEnc, bs, pBits);
1292 : h 101 }
1293 : Isibaar 3
1294 : suxen_drol 136 pEnc->current->coding_type = P_VOP;
1295 : Isibaar 3
1296 :     if(vol_header)
1297 : suxen_drol 136 BitstreamWriteVolHeader(bs, &pEnc->mbParam, pEnc->current);
1298 : Isibaar 3
1299 : suxen_drol 136 BitstreamWriteVopHeader(bs, &pEnc->mbParam, pEnc->current);
1300 : Isibaar 3
1301 : edgomez 13 *pBits = BitstreamPos(bs);
1302 : Isibaar 3
1303 : edgomez 13 pEnc->sStat.iTextBits = 0;
1304 :     pEnc->sStat.iMvSum = 0;
1305 :     pEnc->sStat.iMvCount = 0;
1306 : Isibaar 3 pEnc->sStat.kblks = pEnc->sStat.mblks = pEnc->sStat.ublks = 0;
1307 :    
1308 : edgomez 13 for(y = 0; y < pEnc->mbParam.mb_height; y++)
1309 : Isibaar 3 {
1310 :     for(x = 0; x < pEnc->mbParam.mb_width; x++)
1311 :     {
1312 : suxen_drol 136 MACROBLOCK * pMB = &pEnc->current->mbs[x + y * pEnc->mbParam.mb_width];
1313 : Isibaar 3
1314 : edgomez 13 bIntra = (pMB->mode == MODE_INTRA) || (pMB->mode == MODE_INTRA_Q);
1315 : Isibaar 3
1316 :     if (!bIntra)
1317 : edgomez 13 {
1318 : Isibaar 3 start_timer();
1319 : edgomez 78 MBMotionCompensation(pMB,
1320 :     x, y,
1321 : suxen_drol 136 &pEnc->reference->image,
1322 : edgomez 78 &pEnc->vInterH,
1323 : h 85 &pEnc->vInterV,
1324 :     &pEnc->vInterHV,
1325 : suxen_drol 136 &pEnc->current->image,
1326 : edgomez 78 dct_codes,
1327 : edgomez 13 pEnc->mbParam.width,
1328 :     pEnc->mbParam.height,
1329 :     pEnc->mbParam.edged_width,
1330 : suxen_drol 136 pEnc->current->rounding_type);
1331 : Isibaar 3 stop_comp_timer();
1332 :    
1333 : suxen_drol 136 if ((pEnc->current->global_flags & XVID_LUMIMASKING)) {
1334 : Isibaar 3 if(pMB->dquant != NO_CHANGE) {
1335 :     pMB->mode = MODE_INTER_Q;
1336 : suxen_drol 136 pEnc->current->quant += DQtab[pMB->dquant];
1337 :     if (pEnc->current->quant > 31) pEnc->current->quant = 31;
1338 :     else if(pEnc->current->quant < 1) pEnc->current->quant = 1;
1339 : Isibaar 3 }
1340 :     }
1341 : suxen_drol 136 pMB->quant = pEnc->current->quant;
1342 : Isibaar 3
1343 : h 69 pMB->field_pred = 0;
1344 :    
1345 : suxen_drol 136 pMB->cbp = MBTransQuantInter(&pEnc->mbParam, pEnc->current, pMB, x, y, dct_codes, qcoeff);
1346 : edgomez 13 }
1347 : Isibaar 3 else
1348 :     {
1349 :     CodeIntraMB(pEnc, pMB);
1350 : suxen_drol 136 MBTransQuantIntra(&pEnc->mbParam, pEnc->current, pMB, x, y, dct_codes, qcoeff);
1351 : Isibaar 3 }
1352 :    
1353 : edgomez 13 start_timer();
1354 : suxen_drol 136 MBPrediction(pEnc->current, x, y, pEnc->mbParam.mb_width, qcoeff);
1355 : Isibaar 3 stop_prediction_timer();
1356 :    
1357 :     if (pMB->mode == MODE_INTRA || pMB->mode == MODE_INTRA_Q)
1358 :     {
1359 :     pEnc->sStat.kblks++;
1360 :     }
1361 :     else if (pMB->cbp ||
1362 : edgomez 13 pMB->mvs[0].x || pMB->mvs[0].y ||
1363 :     pMB->mvs[1].x || pMB->mvs[1].y ||
1364 :     pMB->mvs[2].x || pMB->mvs[2].y ||
1365 :     pMB->mvs[3].x || pMB->mvs[3].y)
1366 : Isibaar 3 {
1367 :     pEnc->sStat.mblks++;
1368 :     }
1369 :     else
1370 :     {
1371 :     pEnc->sStat.ublks++;
1372 :     }
1373 :    
1374 :     start_timer();
1375 : suxen_drol 136 MBCoding(pEnc->current, pMB, qcoeff, bs, &pEnc->sStat);
1376 : Isibaar 3 stop_coding_timer();
1377 :     }
1378 :     }
1379 :    
1380 :     emms();
1381 :    
1382 : suxen_drol 136 if (pEnc->current->global_flags & XVID_HINTEDME_GET)
1383 : h 101 {
1384 :     HintedMEGet(pEnc, 0);
1385 :     }
1386 :    
1387 : Isibaar 3 if (pEnc->sStat.iMvCount == 0)
1388 :     pEnc->sStat.iMvCount = 1;
1389 :    
1390 : edgomez 13 fSigma = (float)sqrt((float) pEnc->sStat.iMvSum / pEnc->sStat.iMvCount);
1391 : Isibaar 3
1392 : suxen_drol 136 iSearchRange = 1 << (3 + pEnc->mbParam.m_fcode);
1393 : Isibaar 3
1394 : edgomez 13 if ((fSigma > iSearchRange / 3)
1395 : suxen_drol 136 && (pEnc->mbParam.m_fcode <= 3)) // maximum search range 128
1396 : edgomez 13 {
1397 : suxen_drol 136 pEnc->mbParam.m_fcode++;
1398 : Isibaar 3 iSearchRange *= 2;
1399 : edgomez 13 }
1400 :     else if ((fSigma < iSearchRange / 6)
1401 :     && (pEnc->sStat.fMvPrevSigma >= 0)
1402 :     && (pEnc->sStat.fMvPrevSigma < iSearchRange / 6)
1403 : suxen_drol 136 && (pEnc->mbParam.m_fcode >= 2)) // minimum search range 16
1404 : edgomez 13 {
1405 : suxen_drol 136 pEnc->mbParam.m_fcode--;
1406 : Isibaar 3 iSearchRange /= 2;
1407 : edgomez 13 }
1408 : Isibaar 3
1409 : edgomez 13 pEnc->sStat.fMvPrevSigma = fSigma;
1410 : Isibaar 3
1411 :     *pBits = BitstreamPos(bs) - *pBits;
1412 :    
1413 : edgomez 13 return 0; // inter
1414 : Isibaar 3 }
1415 : suxen_drol 118
1416 :    
1417 : suxen_drol 152 #ifdef BFRAMES
1418 : suxen_drol 118 static void FrameCodeB(Encoder * pEnc, FRAMEINFO * frame, Bitstream * bs, uint32_t *pBits)
1419 :     {
1420 : suxen_drol 152 int16_t dct_codes[6*64];
1421 :     int16_t qcoeff[6*64];
1422 :     uint32_t x, y;
1423 : suxen_drol 118 VECTOR forward;
1424 :     VECTOR backward;
1425 :    
1426 : suxen_drol 152 IMAGE *f_ref = &pEnc->reference->image;
1427 : suxen_drol 118 IMAGE *b_ref = &pEnc->current->image;
1428 :    
1429 : suxen_drol 152 // forward
1430 :     image_setedges(f_ref, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height, pEnc->mbParam.width, pEnc->mbParam.height, frame->global_flags & XVID_INTERLACING);
1431 : suxen_drol 118 start_timer();
1432 :     image_interpolate(f_ref, &pEnc->f_refh, &pEnc->f_refv, &pEnc->f_refhv,
1433 : suxen_drol 152 pEnc->mbParam.edged_width, pEnc->mbParam.edged_height, 0);
1434 : suxen_drol 118 stop_inter_timer();
1435 :    
1436 : suxen_drol 152 // backward
1437 :     image_setedges(b_ref, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height, pEnc->mbParam.width, pEnc->mbParam.height, frame->global_flags & XVID_INTERLACING);
1438 :     start_timer();
1439 : suxen_drol 118 image_interpolate(b_ref, &pEnc->vInterH, &pEnc->vInterV, &pEnc->vInterHV,
1440 : suxen_drol 152 pEnc->mbParam.edged_width, pEnc->mbParam.edged_height, 0);
1441 : suxen_drol 118 stop_inter_timer();
1442 :    
1443 :     start_timer();
1444 :     MotionEstimationBVOP(&pEnc->mbParam, frame,
1445 : suxen_drol 152 pEnc->reference->mbs, f_ref, &pEnc->f_refh, &pEnc->f_refv, &pEnc->f_refhv,
1446 :     pEnc->current->mbs, b_ref, &pEnc->vInterH, &pEnc->vInterV, &pEnc->vInterHV);
1447 :    
1448 : suxen_drol 118
1449 :     stop_motion_timer();
1450 :    
1451 : suxen_drol 152 /*if (test_quant_type(&pEnc->mbParam, pEnc->current))
1452 : suxen_drol 118 {
1453 :     BitstreamWriteVolHeader(bs, pEnc->mbParam.width, pEnc->mbParam.height, pEnc->mbParam.quant_type);
1454 : suxen_drol 152 }*/
1455 : suxen_drol 118
1456 : suxen_drol 152 frame->coding_type = B_VOP;
1457 :     BitstreamWriteVopHeader(bs, &pEnc->mbParam, frame);
1458 : suxen_drol 118
1459 : suxen_drol 152 *pBits = BitstreamPos(bs);
1460 : suxen_drol 118
1461 : suxen_drol 152 pEnc->sStat.iTextBits = 0;
1462 :     pEnc->sStat.iMvSum = 0;
1463 :     pEnc->sStat.iMvCount = 0;
1464 : suxen_drol 118 pEnc->sStat.kblks = pEnc->sStat.mblks = pEnc->sStat.ublks = 0;
1465 :    
1466 :    
1467 : suxen_drol 152 for (y = 0; y < pEnc->mbParam.mb_height; y++)
1468 : suxen_drol 118 {
1469 :     // reset prediction
1470 :    
1471 :     forward.x = 0;
1472 :     forward.y = 0;
1473 :     backward.x = 0;
1474 :     backward.y = 0;
1475 :    
1476 :     for (x = 0; x < pEnc->mbParam.mb_width; x++)
1477 :     {
1478 :     MACROBLOCK * f_mb = &pEnc->reference->mbs[x + y * pEnc->mbParam.mb_width];
1479 :     MACROBLOCK * b_mb = &pEnc->current->mbs[x + y * pEnc->mbParam.mb_width];
1480 :     MACROBLOCK * mb = &frame->mbs[x + y * pEnc->mbParam.mb_width];
1481 :    
1482 :     // decoder ignores mb when refence block is INTER(0,0), CBP=0
1483 :     if (mb->mode == MODE_NOT_CODED)
1484 :     {
1485 :     mb->mvs[0].x = 0;
1486 :     mb->mvs[0].y = 0;
1487 :     continue;
1488 :     }
1489 :    
1490 :     MBMotionCompensationBVOP(&pEnc->mbParam, mb, x, y, &frame->image,
1491 : suxen_drol 152 f_ref, &pEnc->f_refh, &pEnc->f_refv, &pEnc->f_refhv,
1492 :     b_ref, &pEnc->vInterH, &pEnc->vInterV, &pEnc->vInterHV,
1493 :     dct_codes);
1494 : suxen_drol 118
1495 :     mb->quant = frame->quant;
1496 : suxen_drol 152 mb->cbp = MBTransQuantInter(&pEnc->mbParam, frame, mb, x, y, dct_codes, qcoeff);
1497 : suxen_drol 118 //mb->cbp = MBTransQuantBVOP(&pEnc->mbParam, x, y, dct_codes, qcoeff, &frame->image, frame->quant);
1498 :    
1499 :    
1500 :     if ((mb->mode == MODE_INTERPOLATE || mb->mode == MODE_DIRECT) &&
1501 : suxen_drol 152 mb->cbp == 0 &&
1502 :     mb->mvs[0].x == 0 &&
1503 :     mb->mvs[0].y == 0)
1504 : suxen_drol 118 {
1505 :     mb->mode = 5; // skipped
1506 :     }
1507 :    
1508 :     if (mb->mode == MODE_INTERPOLATE || mb->mode == MODE_FORWARD)
1509 :     {
1510 :     mb->pmvs[0].x = mb->mvs[0].x - forward.x;
1511 :     mb->pmvs[0].y = mb->mvs[0].y - forward.y;
1512 :     forward.x = mb->mvs[0].x;
1513 :     forward.y = mb->mvs[0].y;
1514 :     }
1515 :    
1516 :     if (mb->mode == MODE_INTERPOLATE || mb->mode == MODE_BACKWARD)
1517 :     {
1518 :     mb->b_pmvs[0].x = mb->b_mvs[0].x - backward.x;
1519 :     mb->b_pmvs[0].y = mb->b_mvs[0].y - backward.y;
1520 :     backward.x = mb->b_mvs[0].x;
1521 :     backward.y = mb->b_mvs[0].y;
1522 :     }
1523 :    
1524 : suxen_drol 152 // printf("[%i %i] M=%i CBP=%i MVX=%i MVY=%i %i,%i %i,%i\n", x, y, pMB->mode, pMB->cbp, pMB->mvs[0].x, bmb->pmvs[0].x, bmb->pmvs[0].y, forward.x, forward.y);
1525 : suxen_drol 118
1526 :     start_timer();
1527 : suxen_drol 152 MBCodingBVOP(mb, qcoeff, frame->fcode, frame->bcode, bs, &pEnc->sStat);
1528 : suxen_drol 118 stop_coding_timer();
1529 :     }
1530 :     }
1531 :    
1532 :     emms();
1533 :    
1534 :     // TODO: dynamic fcode/bcode ???
1535 :    
1536 :     *pBits = BitstreamPos(bs) - *pBits;
1537 :     }
1538 : edgomez 188 #endif

No admin address has been configured
ViewVC Help
Powered by ViewVC 1.0.4