[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 194 - (view) (download)

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

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