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

1 : edgomez 194 /*****************************************************************************
2 : edgomez 145 *
3 :     * XVID MPEG-4 VIDEO CODEC
4 :     * - Encoder main module -
5 :     *
6 : edgomez 402 * Copyright(C) 2002 Michael Militzer
7 :     *
8 : edgomez 145 * This program is an implementation of a part of one or more MPEG-4
9 :     * Video tools as specified in ISO/IEC 14496-2 standard. Those intending
10 :     * to use this software module in hardware or software products are
11 :     * advised that its use may infringe existing patents or copyrights, and
12 :     * any such use would be at such party's own risk. The original
13 :     * developer of this software module and his/her company, and subsequent
14 :     * editors and their companies, will have no liability for use of this
15 :     * software or modifications or derivatives thereof.
16 :     *
17 :     * This program is free software; you can redistribute it and/or modify
18 :     * it under the terms of the GNU General Public License as published by
19 :     * the Free Software Foundation; either version 2 of the License, or
20 :     * (at your option) any later version.
21 :     *
22 :     * This program is distributed in the hope that it will be useful,
23 :     * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 :     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 :     * GNU General Public License for more details.
26 :     *
27 :     * You should have received a copy of the GNU General Public License
28 :     * along with this program; if not, write to the Free Software
29 :     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30 :     *
31 : edgomez 194 ****************************************************************************/
32 : suxen_drol 118
33 : Isibaar 3 #include <stdlib.h>
34 :     #include <stdio.h>
35 :     #include <math.h>
36 : edgomez 198 #include <string.h>
37 : Isibaar 3
38 :     #include "encoder.h"
39 :     #include "prediction/mbprediction.h"
40 :     #include "global.h"
41 :     #include "utils/timer.h"
42 :     #include "image/image.h"
43 : suxen_drol 152 #include "motion/motion.h"
44 : Isibaar 3 #include "bitstream/cbp.h"
45 :     #include "utils/mbfunctions.h"
46 :     #include "bitstream/bitstream.h"
47 :     #include "bitstream/mbcoding.h"
48 :     #include "utils/ratecontrol.h"
49 :     #include "utils/emms.h"
50 :     #include "bitstream/mbcoding.h"
51 :     #include "quant/adapt_quant.h"
52 : Isibaar 4 #include "quant/quant_matrix.h"
53 : Isibaar 41 #include "utils/mem_align.h"
54 : Isibaar 3
55 : chl 259 #ifdef _SMP
56 :     #include "motion/smp_motion_est.h"
57 :     #endif
58 : edgomez 194 /*****************************************************************************
59 :     * Local macros
60 :     ****************************************************************************/
61 :    
62 : Isibaar 3 #define ENC_CHECK(X) if(!(X)) return XVID_ERR_FORMAT
63 : suxen_drol 136 #define SWAP(A,B) { void * tmp = A; A = B; B = tmp; }
64 : Isibaar 3
65 : edgomez 194 /*****************************************************************************
66 :     * Local function prototypes
67 :     ****************************************************************************/
68 :    
69 : edgomez 192 static int FrameCodeI(Encoder * pEnc,
70 : edgomez 195 Bitstream * bs,
71 :     uint32_t * pBits);
72 : Isibaar 3
73 : edgomez 192 static int FrameCodeP(Encoder * pEnc,
74 : edgomez 195 Bitstream * bs,
75 :     uint32_t * pBits,
76 :     bool force_inter,
77 :     bool vol_header);
78 : Isibaar 3
79 : edgomez 194 /*****************************************************************************
80 :     * Local data
81 :     ****************************************************************************/
82 :    
83 : edgomez 195 static int DQtab[4] = {
84 : Isibaar 3 -1, -2, 1, 2
85 :     };
86 :    
87 : edgomez 195 static int iDQtab[5] = {
88 : Isibaar 3 1, 0, NO_CHANGE, 2, 3
89 :     };
90 :    
91 :    
92 : edgomez 195 static void __inline
93 :     image_null(IMAGE * image)
94 : suxen_drol 136 {
95 :     image->y = image->u = image->v = NULL;
96 :     }
97 :    
98 :    
99 : edgomez 194 /*****************************************************************************
100 :     * Encoder creation
101 :     *
102 :     * This function creates an Encoder instance, it allocates all necessary
103 :     * image buffers (reference, current and bframes) and initialize the internal
104 :     * xvid encoder paremeters according to the XVID_ENC_PARAM input parameter.
105 :     *
106 :     * The code seems to be very long but is very basic, mainly memory allocation
107 :     * and cleaning code.
108 :     *
109 :     * Returned values :
110 :     * - XVID_ERR_OK - no errors
111 :     * - XVID_ERR_MEMORY - the libc could not allocate memory, the function
112 :     * cleans the structure before exiting.
113 :     * pParam->handle is also set to NULL.
114 :     *
115 :     ****************************************************************************/
116 :    
117 :     int
118 :     encoder_create(XVID_ENC_PARAM * pParam)
119 : Isibaar 3 {
120 : edgomez 13 Encoder *pEnc;
121 : suxen_drol 229 int i;
122 : Isibaar 3
123 : edgomez 13 pParam->handle = NULL;
124 : Isibaar 3
125 : edgomez 13 ENC_CHECK(pParam);
126 : Isibaar 3
127 : edgomez 13 ENC_CHECK(pParam->width > 0 && pParam->width <= 1920);
128 :     ENC_CHECK(pParam->height > 0 && pParam->height <= 1280);
129 :     ENC_CHECK(!(pParam->width % 2));
130 :     ENC_CHECK(!(pParam->height % 2));
131 : Isibaar 3
132 : edgomez 192 /* Fps */
133 :    
134 : edgomez 195 if (pParam->fincr <= 0 || pParam->fbase <= 0) {
135 : Isibaar 3 pParam->fincr = 1;
136 :     pParam->fbase = 25;
137 :     }
138 :    
139 : edgomez 192 /*
140 :     * Simplify the "fincr/fbase" fraction
141 :     * (neccessary, since windows supplies us with huge numbers)
142 :     */
143 : Isibaar 3
144 :     i = pParam->fincr;
145 : edgomez 195 while (i > 1) {
146 :     if (pParam->fincr % i == 0 && pParam->fbase % i == 0) {
147 : Isibaar 3 pParam->fincr /= i;
148 :     pParam->fbase /= i;
149 :     i = pParam->fincr;
150 :     continue;
151 :     }
152 :     i--;
153 :     }
154 :    
155 : edgomez 195 if (pParam->fbase > 65535) {
156 :     float div = (float) pParam->fbase / 65535;
157 :    
158 :     pParam->fbase = (int) (pParam->fbase / div);
159 :     pParam->fincr = (int) (pParam->fincr / div);
160 : Isibaar 3 }
161 :    
162 : edgomez 192 /* Bitrate allocator defaults */
163 :    
164 : h 121 if (pParam->rc_bitrate <= 0)
165 :     pParam->rc_bitrate = 900000;
166 : Isibaar 3
167 : h 121 if (pParam->rc_reaction_delay_factor <= 0)
168 :     pParam->rc_reaction_delay_factor = 16;
169 : Isibaar 3
170 : h 121 if (pParam->rc_averaging_period <= 0)
171 :     pParam->rc_averaging_period = 100;
172 :    
173 :     if (pParam->rc_buffer <= 0)
174 :     pParam->rc_buffer = 100;
175 :    
176 : edgomez 192 /* Max and min quantizers */
177 :    
178 : edgomez 13 if ((pParam->min_quantizer <= 0) || (pParam->min_quantizer > 31))
179 : Isibaar 3 pParam->min_quantizer = 1;
180 :    
181 : edgomez 13 if ((pParam->max_quantizer <= 0) || (pParam->max_quantizer > 31))
182 : Isibaar 3 pParam->max_quantizer = 31;
183 :    
184 : edgomez 13 if (pParam->max_quantizer < pParam->min_quantizer)
185 : Isibaar 3 pParam->max_quantizer = pParam->min_quantizer;
186 :    
187 : edgomez 195 /* 1 keyframe each 10 seconds */
188 : edgomez 192
189 : edgomez 325 if (pParam->max_key_interval <= 0)
190 : edgomez 192 pParam->max_key_interval = 10 * pParam->fincr / pParam->fbase;
191 :    
192 :     pEnc = (Encoder *) xvid_malloc(sizeof(Encoder), CACHE_LINE);
193 :     if (pEnc == NULL)
194 : Isibaar 3 return XVID_ERR_MEMORY;
195 :    
196 : edgomez 198 /* Zero the Encoder Structure */
197 :    
198 :     memset(pEnc, 0, sizeof(Encoder));
199 :    
200 : Isibaar 3 /* Fill members of Encoder structure */
201 :    
202 : edgomez 13 pEnc->mbParam.width = pParam->width;
203 :     pEnc->mbParam.height = pParam->height;
204 : Isibaar 3
205 :     pEnc->mbParam.mb_width = (pEnc->mbParam.width + 15) / 16;
206 :     pEnc->mbParam.mb_height = (pEnc->mbParam.height + 15) / 16;
207 :    
208 : edgomez 195 pEnc->mbParam.edged_width = 16 * pEnc->mbParam.mb_width + 2 * EDGE_SIZE;
209 :     pEnc->mbParam.edged_height = 16 * pEnc->mbParam.mb_height + 2 * EDGE_SIZE;
210 : Isibaar 3
211 : suxen_drol 152 pEnc->mbParam.fbase = pParam->fbase;
212 :     pEnc->mbParam.fincr = pParam->fincr;
213 :    
214 : Isibaar 208 pEnc->mbParam.m_quant_type = H263_QUANT;
215 :    
216 : suxen_drol 295 #ifdef _SMP
217 :     pEnc->mbParam.num_threads = MIN(pParam->num_threads, MAXNUMTHREADS);
218 :     #endif
219 :    
220 : edgomez 13 pEnc->sStat.fMvPrevSigma = -1;
221 : Isibaar 3
222 :     /* Fill rate control parameters */
223 :    
224 : h 121 pEnc->bitrate = pParam->rc_bitrate;
225 : Isibaar 3
226 : edgomez 13 pEnc->iFrameNum = 0;
227 :     pEnc->iMaxKeyInterval = pParam->max_key_interval;
228 : Isibaar 3
229 : suxen_drol 136 /* try to allocate frame memory */
230 : Isibaar 3
231 : edgomez 192 pEnc->current = xvid_malloc(sizeof(FRAMEINFO), CACHE_LINE);
232 :     pEnc->reference = xvid_malloc(sizeof(FRAMEINFO), CACHE_LINE);
233 : Isibaar 3
234 : edgomez 195 if (pEnc->current == NULL || pEnc->reference == NULL)
235 : edgomez 192 goto xvid_err_memory1;
236 :    
237 : suxen_drol 136 /* try to allocate mb memory */
238 : Isibaar 3
239 : edgomez 195 pEnc->current->mbs =
240 :     xvid_malloc(sizeof(MACROBLOCK) * pEnc->mbParam.mb_width *
241 :     pEnc->mbParam.mb_height, CACHE_LINE);
242 :     pEnc->reference->mbs =
243 :     xvid_malloc(sizeof(MACROBLOCK) * pEnc->mbParam.mb_width *
244 :     pEnc->mbParam.mb_height, CACHE_LINE);
245 : suxen_drol 136
246 : edgomez 192 if (pEnc->current->mbs == NULL || pEnc->reference->mbs == NULL)
247 :     goto xvid_err_memory2;
248 : suxen_drol 136
249 :     /* try to allocate image memory */
250 :    
251 : suxen_drol 229 #ifdef _DEBUG_PSNR
252 : suxen_drol 136 image_null(&pEnc->sOriginal);
253 :     #endif
254 :     image_null(&pEnc->current->image);
255 :     image_null(&pEnc->reference->image);
256 :     image_null(&pEnc->vInterH);
257 :     image_null(&pEnc->vInterV);
258 :     image_null(&pEnc->vInterVf);
259 :     image_null(&pEnc->vInterHV);
260 :     image_null(&pEnc->vInterHVf);
261 : edgomez 192
262 : suxen_drol 229 #ifdef _DEBUG_PSNR
263 : edgomez 195 if (image_create
264 :     (&pEnc->sOriginal, pEnc->mbParam.edged_width,
265 :     pEnc->mbParam.edged_height) < 0)
266 : edgomez 192 goto xvid_err_memory3;
267 : suxen_drol 136 #endif
268 : edgomez 195 if (image_create
269 :     (&pEnc->current->image, pEnc->mbParam.edged_width,
270 :     pEnc->mbParam.edged_height) < 0)
271 : edgomez 192 goto xvid_err_memory3;
272 : edgomez 195 if (image_create
273 :     (&pEnc->reference->image, pEnc->mbParam.edged_width,
274 :     pEnc->mbParam.edged_height) < 0)
275 : edgomez 192 goto xvid_err_memory3;
276 : edgomez 195 if (image_create
277 :     (&pEnc->vInterH, pEnc->mbParam.edged_width,
278 :     pEnc->mbParam.edged_height) < 0)
279 : edgomez 192 goto xvid_err_memory3;
280 : edgomez 195 if (image_create
281 :     (&pEnc->vInterV, pEnc->mbParam.edged_width,
282 :     pEnc->mbParam.edged_height) < 0)
283 : edgomez 192 goto xvid_err_memory3;
284 : edgomez 195 if (image_create
285 :     (&pEnc->vInterVf, pEnc->mbParam.edged_width,
286 :     pEnc->mbParam.edged_height) < 0)
287 : edgomez 192 goto xvid_err_memory3;
288 : edgomez 195 if (image_create
289 :     (&pEnc->vInterHV, pEnc->mbParam.edged_width,
290 :     pEnc->mbParam.edged_height) < 0)
291 : edgomez 192 goto xvid_err_memory3;
292 : edgomez 195 if (image_create
293 :     (&pEnc->vInterHVf, pEnc->mbParam.edged_width,
294 :     pEnc->mbParam.edged_height) < 0)
295 : edgomez 192 goto xvid_err_memory3;
296 : suxen_drol 136
297 : edgomez 195 pParam->handle = (void *) pEnc;
298 : Isibaar 3
299 : edgomez 195 if (pParam->rc_bitrate) {
300 :     RateControlInit(&pEnc->rate_control, pParam->rc_bitrate,
301 :     pParam->rc_reaction_delay_factor,
302 :     pParam->rc_averaging_period, pParam->rc_buffer,
303 :     pParam->fbase * 1000 / pParam->fincr,
304 :     pParam->max_quantizer, pParam->min_quantizer);
305 : Isibaar 3 }
306 :    
307 : Isibaar 36 init_timer();
308 : Isibaar 3
309 :     return XVID_ERR_OK;
310 : edgomez 192
311 :     /*
312 :     * We handle all XVID_ERR_MEMORY here, this makes the code lighter
313 :     */
314 : suxen_drol 229
315 : edgomez 195 xvid_err_memory3:
316 : suxen_drol 229 #ifdef _DEBUG_PSNR
317 : edgomez 195 image_destroy(&pEnc->sOriginal, pEnc->mbParam.edged_width,
318 :     pEnc->mbParam.edged_height);
319 : edgomez 192 #endif
320 :    
321 : edgomez 195 image_destroy(&pEnc->current->image, pEnc->mbParam.edged_width,
322 :     pEnc->mbParam.edged_height);
323 :     image_destroy(&pEnc->reference->image, pEnc->mbParam.edged_width,
324 :     pEnc->mbParam.edged_height);
325 :     image_destroy(&pEnc->vInterH, pEnc->mbParam.edged_width,
326 :     pEnc->mbParam.edged_height);
327 :     image_destroy(&pEnc->vInterV, pEnc->mbParam.edged_width,
328 :     pEnc->mbParam.edged_height);
329 :     image_destroy(&pEnc->vInterVf, pEnc->mbParam.edged_width,
330 :     pEnc->mbParam.edged_height);
331 :     image_destroy(&pEnc->vInterHV, pEnc->mbParam.edged_width,
332 :     pEnc->mbParam.edged_height);
333 :     image_destroy(&pEnc->vInterHVf, pEnc->mbParam.edged_width,
334 :     pEnc->mbParam.edged_height);
335 : edgomez 192
336 : edgomez 195 xvid_err_memory2:
337 : edgomez 192 xvid_free(pEnc->current->mbs);
338 :     xvid_free(pEnc->reference->mbs);
339 :    
340 : edgomez 195 xvid_err_memory1:
341 : edgomez 192 xvid_free(pEnc->current);
342 :     xvid_free(pEnc->reference);
343 :     xvid_free(pEnc);
344 :    
345 : edgomez 194 pParam->handle = NULL;
346 :    
347 : edgomez 192 return XVID_ERR_MEMORY;
348 : Isibaar 3 }
349 :    
350 : edgomez 194 /*****************************************************************************
351 :     * Encoder destruction
352 :     *
353 :     * This function destroy the entire encoder structure created by a previous
354 :     * successful encoder_create call.
355 :     *
356 :     * Returned values (for now only one returned value) :
357 :     * - XVID_ERR_OK - no errors
358 :     *
359 :     ****************************************************************************/
360 :    
361 :     int
362 :     encoder_destroy(Encoder * pEnc)
363 : Isibaar 3 {
364 : suxen_drol 229
365 : edgomez 13 ENC_CHECK(pEnc);
366 : Isibaar 3
367 : edgomez 192 /* All images, reference, current etc ... */
368 : edgomez 195 image_destroy(&pEnc->current->image, pEnc->mbParam.edged_width,
369 :     pEnc->mbParam.edged_height);
370 :     image_destroy(&pEnc->reference->image, pEnc->mbParam.edged_width,
371 :     pEnc->mbParam.edged_height);
372 :     image_destroy(&pEnc->vInterH, pEnc->mbParam.edged_width,
373 :     pEnc->mbParam.edged_height);
374 :     image_destroy(&pEnc->vInterV, pEnc->mbParam.edged_width,
375 :     pEnc->mbParam.edged_height);
376 :     image_destroy(&pEnc->vInterVf, pEnc->mbParam.edged_width,
377 :     pEnc->mbParam.edged_height);
378 :     image_destroy(&pEnc->vInterHV, pEnc->mbParam.edged_width,
379 :     pEnc->mbParam.edged_height);
380 :     image_destroy(&pEnc->vInterHVf, pEnc->mbParam.edged_width,
381 :     pEnc->mbParam.edged_height);
382 : edgomez 403
383 : suxen_drol 229 #ifdef _DEBUG_PSNR
384 : edgomez 195 image_destroy(&pEnc->sOriginal, pEnc->mbParam.edged_width,
385 :     pEnc->mbParam.edged_height);
386 : Isibaar 113 #endif
387 : edgomez 192
388 :     /* Encoder structure */
389 : suxen_drol 136 xvid_free(pEnc->current->mbs);
390 :     xvid_free(pEnc->current);
391 :    
392 :     xvid_free(pEnc->reference->mbs);
393 :     xvid_free(pEnc->reference);
394 :    
395 : Isibaar 41 xvid_free(pEnc);
396 : edgomez 192
397 : edgomez 13 return XVID_ERR_OK;
398 : Isibaar 3 }
399 :    
400 : suxen_drol 229
401 :     void inc_frame_num(Encoder * pEnc)
402 :     {
403 :     pEnc->mbParam.m_ticks += pEnc->mbParam.fincr;
404 : chl 387 pEnc->mbParam.m_seconds = pEnc->mbParam.m_ticks / pEnc->mbParam.fbase;
405 :     pEnc->mbParam.m_ticks = pEnc->mbParam.m_ticks % pEnc->mbParam.fbase;
406 :     }
407 : suxen_drol 229
408 : edgomez 194 /*****************************************************************************
409 : suxen_drol 229 * "original" IP frame encoder entry point
410 :     *
411 :     * Returned values :
412 :     * - XVID_ERR_OK - no errors
413 :     * - XVID_ERR_FORMAT - the image subsystem reported the image had a wrong
414 :     * format
415 : edgomez 194 ****************************************************************************/
416 : suxen_drol 229
417 : edgomez 194 int
418 :     encoder_encode(Encoder * pEnc,
419 : edgomez 195 XVID_ENC_FRAME * pFrame,
420 :     XVID_ENC_STATS * pResult)
421 : suxen_drol 152 {
422 :     uint16_t x, y;
423 :     Bitstream bs;
424 :     uint32_t bits;
425 : Isibaar 4 uint16_t write_vol_header = 0;
426 : edgomez 195
427 : suxen_drol 229 #ifdef _DEBUG_PSNR
428 : Isibaar 113 float psnr;
429 : edgomez 194 uint8_t temp[128];
430 : Isibaar 113 #endif
431 : Isibaar 3
432 :     start_global_timer();
433 :    
434 : edgomez 13 ENC_CHECK(pEnc);
435 :     ENC_CHECK(pFrame);
436 :     ENC_CHECK(pFrame->bitstream);
437 :     ENC_CHECK(pFrame->image);
438 : Isibaar 3
439 : suxen_drol 136 SWAP(pEnc->current, pEnc->reference);
440 :    
441 :     pEnc->current->global_flags = pFrame->general;
442 :     pEnc->current->motion_flags = pFrame->motion;
443 : suxen_drol 229 pEnc->current->seconds = pEnc->mbParam.m_seconds;
444 :     pEnc->current->ticks = pEnc->mbParam.m_ticks;
445 : h 101 pEnc->mbParam.hint = &pFrame->hint;
446 : Isibaar 3
447 :     start_timer();
448 : edgomez 195 if (image_input
449 :     (&pEnc->current->image, pEnc->mbParam.width, pEnc->mbParam.height,
450 :     pEnc->mbParam.edged_width, pFrame->image, pFrame->colorspace) < 0)
451 : Isibaar 3 return XVID_ERR_FORMAT;
452 :     stop_conv_timer();
453 :    
454 : suxen_drol 229 #ifdef _DEBUG_PSNR
455 : edgomez 195 image_copy(&pEnc->sOriginal, &pEnc->current->image,
456 :     pEnc->mbParam.edged_width, pEnc->mbParam.height);
457 : Isibaar 113 #endif
458 :    
459 : edgomez 198 emms();
460 : suxen_drol 136
461 : edgomez 13 BitstreamInit(&bs, pFrame->bitstream, 0);
462 : Isibaar 3
463 : edgomez 195 if (pFrame->quant == 0) {
464 :     pEnc->current->quant = RateControlGetQ(&pEnc->rate_control, 0);
465 :     } else {
466 : suxen_drol 136 pEnc->current->quant = pFrame->quant;
467 : Isibaar 3 }
468 :    
469 : edgomez 195 if ((pEnc->current->global_flags & XVID_LUMIMASKING)) {
470 :     int *temp_dquants =
471 :     (int *) xvid_malloc(pEnc->mbParam.mb_width *
472 :     pEnc->mbParam.mb_height * sizeof(int),
473 :     CACHE_LINE);
474 :    
475 : edgomez 194 pEnc->current->quant =
476 :     adaptive_quantization(pEnc->current->image.y,
477 : edgomez 195 pEnc->mbParam.edged_width, temp_dquants,
478 :     pEnc->current->quant, pEnc->current->quant,
479 :     2 * pEnc->current->quant,
480 :     pEnc->mbParam.mb_width,
481 :     pEnc->mbParam.mb_height);
482 : edgomez 194
483 : edgomez 195 for (y = 0; y < pEnc->mbParam.mb_height; y++) {
484 : edgomez 194
485 : edgomez 195 #define OFFSET(x,y) ((x) + (y)*pEnc->mbParam.mb_width)
486 : edgomez 194
487 : edgomez 195 for (x = 0; x < pEnc->mbParam.mb_width; x++) {
488 : edgomez 194
489 : edgomez 195
490 :     MACROBLOCK *pMB = &pEnc->current->mbs[OFFSET(x, y)];
491 :    
492 :     pMB->dquant = iDQtab[temp_dquants[OFFSET(x, y)] + 2];
493 : Isibaar 3 }
494 : edgomez 194
495 : edgomez 195 #undef OFFSET
496 : edgomez 194 }
497 :    
498 : Isibaar 41 xvid_free(temp_dquants);
499 : Isibaar 3 }
500 :    
501 : edgomez 195 if (pEnc->current->global_flags & XVID_H263QUANT) {
502 :     if (pEnc->mbParam.m_quant_type != H263_QUANT)
503 : Isibaar 20 write_vol_header = 1;
504 : suxen_drol 136 pEnc->mbParam.m_quant_type = H263_QUANT;
505 : edgomez 195 } else if (pEnc->current->global_flags & XVID_MPEGQUANT) {
506 : edgomez 194 int matrix1_changed, matrix2_changed;
507 : Isibaar 3
508 : edgomez 194 matrix1_changed = matrix2_changed = 0;
509 : edgomez 78
510 : edgomez 195 if (pEnc->mbParam.m_quant_type != MPEG4_QUANT)
511 : Isibaar 20 write_vol_header = 1;
512 : edgomez 195
513 : suxen_drol 136 pEnc->mbParam.m_quant_type = MPEG4_QUANT;
514 : edgomez 195
515 : suxen_drol 136 if ((pEnc->current->global_flags & XVID_CUSTOM_QMATRIX) > 0) {
516 : edgomez 195 if (pFrame->quant_intra_matrix != NULL)
517 :     matrix1_changed = set_intra_matrix(pFrame->quant_intra_matrix);
518 :     if (pFrame->quant_inter_matrix != NULL)
519 :     matrix2_changed = set_inter_matrix(pFrame->quant_inter_matrix);
520 :     } else {
521 : edgomez 194 matrix1_changed = set_intra_matrix(get_default_intra_matrix());
522 :     matrix2_changed = set_inter_matrix(get_default_inter_matrix());
523 : Isibaar 20 }
524 : edgomez 195 if (write_vol_header == 0)
525 : edgomez 194 write_vol_header = matrix1_changed | matrix2_changed;
526 : Isibaar 4 }
527 : Isibaar 3
528 : edgomez 195 if (pFrame->intra < 0) {
529 :     if ((pEnc->iFrameNum == 0)
530 :     || ((pEnc->iMaxKeyInterval > 0)
531 :     && (pEnc->iFrameNum >= pEnc->iMaxKeyInterval))) {
532 :     pFrame->intra = FrameCodeI(pEnc, &bs, &bits);
533 :     } else {
534 :     pFrame->intra = FrameCodeP(pEnc, &bs, &bits, 0, write_vol_header);
535 : edgomez 194 }
536 : edgomez 195 } else {
537 :     if (pFrame->intra == 1) {
538 :     pFrame->intra = FrameCodeI(pEnc, &bs, &bits);
539 :     } else {
540 :     pFrame->intra = FrameCodeP(pEnc, &bs, &bits, 1, write_vol_header);
541 : edgomez 194 }
542 :    
543 : edgomez 13 }
544 : Isibaar 3
545 :     BitstreamPutBits(&bs, 0xFFFF, 16);
546 : edgomez 13 BitstreamPutBits(&bs, 0xFFFF, 16);
547 :     BitstreamPad(&bs);
548 :     pFrame->length = BitstreamLength(&bs);
549 : h 29
550 : edgomez 195 if (pResult) {
551 : suxen_drol 136 pResult->quant = pEnc->current->quant;
552 : Isibaar 3 pResult->hlength = pFrame->length - (pEnc->sStat.iTextBits / 8);
553 :     pResult->kblks = pEnc->sStat.kblks;
554 :     pResult->mblks = pEnc->sStat.mblks;
555 :     pResult->ublks = pEnc->sStat.ublks;
556 : edgomez 13 }
557 : edgomez 195
558 : edgomez 198 emms();
559 : Isibaar 41
560 : edgomez 195 if (pFrame->quant == 0) {
561 :     RateControlUpdate(&pEnc->rate_control, pEnc->current->quant,
562 :     pFrame->length, pFrame->intra);
563 : Isibaar 3 }
564 : suxen_drol 229 #ifdef _DEBUG_PSNR
565 : edgomez 195 psnr =
566 :     image_psnr(&pEnc->sOriginal, &pEnc->current->image,
567 :     pEnc->mbParam.edged_width, pEnc->mbParam.width,
568 :     pEnc->mbParam.height);
569 : Isibaar 113
570 : edgomez 194 snprintf(temp, 127, "PSNR: %f\n", psnr);
571 : Isibaar 113 DEBUG(temp);
572 :     #endif
573 :    
574 : suxen_drol 229 inc_frame_num(pEnc);
575 : Isibaar 3 pEnc->iFrameNum++;
576 : edgomez 195
577 : Isibaar 3 stop_global_timer();
578 :     write_timer();
579 :    
580 :     return XVID_ERR_OK;
581 :     }
582 :    
583 :    
584 : edgomez 195 static __inline void
585 :     CodeIntraMB(Encoder * pEnc,
586 :     MACROBLOCK * pMB)
587 :     {
588 : Isibaar 3
589 :     pMB->mode = MODE_INTRA;
590 :    
591 : suxen_drol 136 /* zero mv statistics */
592 :     pMB->mvs[0].x = pMB->mvs[1].x = pMB->mvs[2].x = pMB->mvs[3].x = 0;
593 :     pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = 0;
594 :     pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = 0;
595 :     pMB->sad16 = 0;
596 :    
597 :     if ((pEnc->current->global_flags & XVID_LUMIMASKING)) {
598 : edgomez 195 if (pMB->dquant != NO_CHANGE) {
599 : Isibaar 3 pMB->mode = MODE_INTRA_Q;
600 : suxen_drol 136 pEnc->current->quant += DQtab[pMB->dquant];
601 : edgomez 195
602 :     if (pEnc->current->quant > 31)
603 :     pEnc->current->quant = 31;
604 :     if (pEnc->current->quant < 1)
605 :     pEnc->current->quant = 1;
606 : Isibaar 3 }
607 :     }
608 :    
609 : suxen_drol 136 pMB->quant = pEnc->current->quant;
610 : Isibaar 3 }
611 :    
612 :    
613 : h 101 #define FCODEBITS 3
614 :     #define MODEBITS 5
615 :    
616 : edgomez 195 void
617 :     HintedMESet(Encoder * pEnc,
618 :     int *intra)
619 : h 101 {
620 : edgomez 195 HINTINFO *hint;
621 : h 101 Bitstream bs;
622 :     int length, high;
623 :     uint32_t x, y;
624 :    
625 :     hint = pEnc->mbParam.hint;
626 :    
627 : edgomez 195 if (hint->rawhints) {
628 : h 101 *intra = hint->mvhint.intra;
629 : edgomez 195 } else {
630 : h 101 BitstreamInit(&bs, hint->hintstream, hint->hintlength);
631 :     *intra = BitstreamGetBit(&bs);
632 :     }
633 :    
634 : edgomez 195 if (*intra) {
635 : h 101 return;
636 :     }
637 :    
638 : edgomez 195 pEnc->current->fcode =
639 :     (hint->rawhints) ? hint->mvhint.fcode : BitstreamGetBits(&bs,
640 :     FCODEBITS);
641 : h 101
642 : edgomez 195 length = pEnc->current->fcode + 5;
643 :     high = 1 << (length - 1);
644 : h 101
645 : edgomez 195 for (y = 0; y < pEnc->mbParam.mb_height; ++y) {
646 :     for (x = 0; x < pEnc->mbParam.mb_width; ++x) {
647 :     MACROBLOCK *pMB =
648 :     &pEnc->current->mbs[x + y * pEnc->mbParam.mb_width];
649 :     MVBLOCKHINT *bhint =
650 :     &hint->mvhint.block[x + y * pEnc->mbParam.mb_width];
651 : chl 284 VECTOR pred;
652 : h 101 VECTOR tmp;
653 :     int vec;
654 :    
655 : edgomez 195 pMB->mode =
656 :     (hint->rawhints) ? bhint->mode : BitstreamGetBits(&bs,
657 :     MODEBITS);
658 : h 101
659 : h 128 pMB->mode = (pMB->mode == MODE_INTER_Q) ? MODE_INTER : pMB->mode;
660 :     pMB->mode = (pMB->mode == MODE_INTRA_Q) ? MODE_INTRA : pMB->mode;
661 :    
662 : edgomez 195 if (pMB->mode == MODE_INTER) {
663 :     tmp.x =
664 :     (hint->rawhints) ? bhint->mvs[0].x : BitstreamGetBits(&bs,
665 :     length);
666 :     tmp.y =
667 :     (hint->rawhints) ? bhint->mvs[0].y : BitstreamGetBits(&bs,
668 :     length);
669 :     tmp.x -= (tmp.x >= high) ? high * 2 : 0;
670 :     tmp.y -= (tmp.y >= high) ? high * 2 : 0;
671 : h 101
672 : chl 284 pred = get_pmv2(pEnc->current->mbs,pEnc->mbParam.mb_width,0,x,y,0);
673 : h 101
674 : edgomez 195 for (vec = 0; vec < 4; ++vec) {
675 :     pMB->mvs[vec].x = tmp.x;
676 :     pMB->mvs[vec].y = tmp.y;
677 : chl 284 pMB->pmvs[vec].x = pMB->mvs[0].x - pred.x;
678 :     pMB->pmvs[vec].y = pMB->mvs[0].y - pred.y;
679 : h 101 }
680 : edgomez 195 } else if (pMB->mode == MODE_INTER4V) {
681 :     for (vec = 0; vec < 4; ++vec) {
682 :     tmp.x =
683 :     (hint->rawhints) ? bhint->mvs[vec].
684 :     x : BitstreamGetBits(&bs, length);
685 :     tmp.y =
686 :     (hint->rawhints) ? bhint->mvs[vec].
687 :     y : BitstreamGetBits(&bs, length);
688 :     tmp.x -= (tmp.x >= high) ? high * 2 : 0;
689 :     tmp.y -= (tmp.y >= high) ? high * 2 : 0;
690 : h 101
691 : chl 284 pred = get_pmv2(pEnc->current->mbs,pEnc->mbParam.mb_width,0,x,y,vec);
692 : h 101
693 : edgomez 195 pMB->mvs[vec].x = tmp.x;
694 :     pMB->mvs[vec].y = tmp.y;
695 : chl 284 pMB->pmvs[vec].x = pMB->mvs[vec].x - pred.x;
696 :     pMB->pmvs[vec].y = pMB->mvs[vec].y - pred.y;
697 : h 101 }
698 : edgomez 195 } else // intra / stuffing / not_coded
699 : h 101 {
700 : edgomez 195 for (vec = 0; vec < 4; ++vec) {
701 :     pMB->mvs[vec].x = pMB->mvs[vec].y = 0;
702 : h 101 }
703 :     }
704 : h 128
705 : suxen_drol 136 if (pMB->mode == MODE_INTER4V &&
706 : edgomez 195 (pEnc->current->global_flags & XVID_LUMIMASKING)
707 :     && pMB->dquant != NO_CHANGE) {
708 : h 128 pMB->mode = MODE_INTRA;
709 :    
710 : edgomez 195 for (vec = 0; vec < 4; ++vec) {
711 : h 128 pMB->mvs[vec].x = pMB->mvs[vec].y = 0;
712 :     }
713 :     }
714 : h 101 }
715 :     }
716 :     }
717 :    
718 :    
719 : edgomez 195 void
720 :     HintedMEGet(Encoder * pEnc,
721 :     int intra)
722 : h 101 {
723 : edgomez 195 HINTINFO *hint;
724 : h 101 Bitstream bs;
725 :     uint32_t x, y;
726 :     int length, high;
727 :    
728 :     hint = pEnc->mbParam.hint;
729 :    
730 : edgomez 195 if (hint->rawhints) {
731 : h 101 hint->mvhint.intra = intra;
732 : edgomez 195 } else {
733 : h 101 BitstreamInit(&bs, hint->hintstream, 0);
734 :     BitstreamPutBit(&bs, intra);
735 :     }
736 :    
737 : edgomez 195 if (intra) {
738 :     if (!hint->rawhints) {
739 : h 101 BitstreamPad(&bs);
740 :     hint->hintlength = BitstreamLength(&bs);
741 :     }
742 :     return;
743 :     }
744 :    
745 : edgomez 195 length = pEnc->current->fcode + 5;
746 :     high = 1 << (length - 1);
747 : h 101
748 : edgomez 195 if (hint->rawhints) {
749 : suxen_drol 136 hint->mvhint.fcode = pEnc->current->fcode;
750 : edgomez 195 } else {
751 : suxen_drol 136 BitstreamPutBits(&bs, pEnc->current->fcode, FCODEBITS);
752 : h 101 }
753 :    
754 : edgomez 195 for (y = 0; y < pEnc->mbParam.mb_height; ++y) {
755 :     for (x = 0; x < pEnc->mbParam.mb_width; ++x) {
756 :     MACROBLOCK *pMB =
757 :     &pEnc->current->mbs[x + y * pEnc->mbParam.mb_width];
758 :     MVBLOCKHINT *bhint =
759 :     &hint->mvhint.block[x + y * pEnc->mbParam.mb_width];
760 : h 101 VECTOR tmp;
761 :    
762 : edgomez 195 if (hint->rawhints) {
763 : h 101 bhint->mode = pMB->mode;
764 : edgomez 195 } else {
765 : h 101 BitstreamPutBits(&bs, pMB->mode, MODEBITS);
766 :     }
767 :    
768 : edgomez 195 if (pMB->mode == MODE_INTER || pMB->mode == MODE_INTER_Q) {
769 :     tmp.x = pMB->mvs[0].x;
770 :     tmp.y = pMB->mvs[0].y;
771 :     tmp.x += (tmp.x < 0) ? high * 2 : 0;
772 :     tmp.y += (tmp.y < 0) ? high * 2 : 0;
773 : h 101
774 : edgomez 195 if (hint->rawhints) {
775 : h 101 bhint->mvs[0].x = tmp.x;
776 :     bhint->mvs[0].y = tmp.y;
777 : edgomez 195 } else {
778 : h 101 BitstreamPutBits(&bs, tmp.x, length);
779 :     BitstreamPutBits(&bs, tmp.y, length);
780 :     }
781 : edgomez 195 } else if (pMB->mode == MODE_INTER4V) {
782 : h 101 int vec;
783 :    
784 : edgomez 195 for (vec = 0; vec < 4; ++vec) {
785 :     tmp.x = pMB->mvs[vec].x;
786 :     tmp.y = pMB->mvs[vec].y;
787 :     tmp.x += (tmp.x < 0) ? high * 2 : 0;
788 :     tmp.y += (tmp.y < 0) ? high * 2 : 0;
789 : h 101
790 : edgomez 195 if (hint->rawhints) {
791 : h 101 bhint->mvs[vec].x = tmp.x;
792 :     bhint->mvs[vec].y = tmp.y;
793 : edgomez 195 } else {
794 : h 101 BitstreamPutBits(&bs, tmp.x, length);
795 :     BitstreamPutBits(&bs, tmp.y, length);
796 :     }
797 :     }
798 :     }
799 :     }
800 :     }
801 :    
802 : edgomez 195 if (!hint->rawhints) {
803 : h 101 BitstreamPad(&bs);
804 :     hint->hintlength = BitstreamLength(&bs);
805 :     }
806 :     }
807 :    
808 :    
809 : edgomez 195 static int
810 :     FrameCodeI(Encoder * pEnc,
811 :     Bitstream * bs,
812 :     uint32_t * pBits)
813 : h 104 {
814 :    
815 :     DECLARE_ALIGNED_MATRIX(dct_codes, 6, 64, int16_t, CACHE_LINE);
816 : edgomez 195 DECLARE_ALIGNED_MATRIX(qcoeff, 6, 64, int16_t, CACHE_LINE);
817 : h 104
818 :     uint16_t x, y;
819 :    
820 :     pEnc->iFrameNum = 0;
821 : suxen_drol 136 pEnc->mbParam.m_rounding_type = 1;
822 :     pEnc->current->rounding_type = pEnc->mbParam.m_rounding_type;
823 :     pEnc->current->coding_type = I_VOP;
824 : h 104
825 : suxen_drol 136 BitstreamWriteVolHeader(bs, &pEnc->mbParam, pEnc->current);
826 : edgomez 403
827 : suxen_drol 229 BitstreamWriteVopHeader(bs, &pEnc->mbParam, pEnc->current, 1);
828 : h 104
829 :     *pBits = BitstreamPos(bs);
830 :    
831 :     pEnc->sStat.iTextBits = 0;
832 :     pEnc->sStat.kblks = pEnc->mbParam.mb_width * pEnc->mbParam.mb_height;
833 :     pEnc->sStat.mblks = pEnc->sStat.ublks = 0;
834 :    
835 :     for (y = 0; y < pEnc->mbParam.mb_height; y++)
836 : edgomez 195 for (x = 0; x < pEnc->mbParam.mb_width; x++) {
837 :     MACROBLOCK *pMB =
838 :     &pEnc->current->mbs[x + y * pEnc->mbParam.mb_width];
839 : h 104
840 :     CodeIntraMB(pEnc, pMB);
841 :    
842 : edgomez 195 MBTransQuantIntra(&pEnc->mbParam, pEnc->current, pMB, x, y,
843 :     dct_codes, qcoeff);
844 : h 104
845 :     start_timer();
846 : suxen_drol 136 MBPrediction(pEnc->current, x, y, pEnc->mbParam.mb_width, qcoeff);
847 : h 104 stop_prediction_timer();
848 :    
849 :     start_timer();
850 : chl 353 if (pEnc->current->global_flags & XVID_GREYSCALE)
851 :     { pMB->cbp &= 0x3C; /* keep only bits 5-2 */
852 :     qcoeff[4*64+0]=0; /* zero, because for INTRA MBs DC value is saved */
853 :     qcoeff[5*64+0]=0;
854 :     }
855 : suxen_drol 136 MBCoding(pEnc->current, pMB, qcoeff, bs, &pEnc->sStat);
856 : h 104 stop_coding_timer();
857 :     }
858 :    
859 :     emms();
860 :    
861 :     *pBits = BitstreamPos(bs) - *pBits;
862 :     pEnc->sStat.fMvPrevSigma = -1;
863 :     pEnc->sStat.iMvSum = 0;
864 :     pEnc->sStat.iMvCount = 0;
865 : suxen_drol 136 pEnc->mbParam.m_fcode = 2;
866 : h 104
867 : edgomez 195 if (pEnc->current->global_flags & XVID_HINTEDME_GET) {
868 : h 104 HintedMEGet(pEnc, 1);
869 :     }
870 :    
871 : edgomez 195 return 1; // intra
872 : h 104 }
873 :    
874 :    
875 : Isibaar 3 #define INTRA_THRESHOLD 0.5
876 :    
877 : edgomez 195 static int
878 :     FrameCodeP(Encoder * pEnc,
879 :     Bitstream * bs,
880 :     uint32_t * pBits,
881 :     bool force_inter,
882 :     bool vol_header)
883 : Isibaar 3 {
884 : edgomez 13 float fSigma;
885 : Isibaar 42
886 : edgomez 78 DECLARE_ALIGNED_MATRIX(dct_codes, 6, 64, int16_t, CACHE_LINE);
887 : edgomez 195 DECLARE_ALIGNED_MATRIX(qcoeff, 6, 64, int16_t, CACHE_LINE);
888 : edgomez 78
889 : Isibaar 3 int iLimit;
890 : chl 354 int x, y, k;
891 : edgomez 13 int iSearchRange;
892 : edgomez 145 int bIntra;
893 : suxen_drol 240
894 : edgomez 145 /* IMAGE *pCurrent = &pEnc->current->image; */
895 : suxen_drol 136 IMAGE *pRef = &pEnc->reference->image;
896 : Isibaar 3
897 : h 69 start_timer();
898 : edgomez 195 image_setedges(pRef, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height,
899 :     pEnc->mbParam.width, pEnc->mbParam.height,
900 :     pEnc->current->global_flags & XVID_INTERLACING);
901 : h 69 stop_edges_timer();
902 : Isibaar 3
903 : suxen_drol 136 pEnc->mbParam.m_rounding_type = 1 - pEnc->mbParam.m_rounding_type;
904 :     pEnc->current->rounding_type = pEnc->mbParam.m_rounding_type;
905 :     pEnc->current->fcode = pEnc->mbParam.m_fcode;
906 : Isibaar 3
907 :     if (!force_inter)
908 : edgomez 195 iLimit =
909 :     (int) (pEnc->mbParam.mb_width * pEnc->mbParam.mb_height *
910 :     INTRA_THRESHOLD);
911 : edgomez 13 else
912 : Isibaar 3 iLimit = pEnc->mbParam.mb_width * pEnc->mbParam.mb_height + 1;
913 :    
914 : suxen_drol 136 if ((pEnc->current->global_flags & XVID_HALFPEL)) {
915 : Isibaar 3 start_timer();
916 : edgomez 195 image_interpolate(pRef, &pEnc->vInterH, &pEnc->vInterV,
917 :     &pEnc->vInterHV, pEnc->mbParam.edged_width,
918 :     pEnc->mbParam.edged_height,
919 :     pEnc->current->rounding_type);
920 : Isibaar 3 stop_inter_timer();
921 :     }
922 :    
923 :     start_timer();
924 : edgomez 195 if (pEnc->current->global_flags & XVID_HINTEDME_SET) {
925 : h 101 HintedMESet(pEnc, &bIntra);
926 : edgomez 195 } else {
927 : chl 259
928 :     #ifdef _SMP
929 : suxen_drol 295 if (pEnc->mbParam.num_threads > 1)
930 :     bIntra =
931 :     SMP_MotionEstimation(&pEnc->mbParam, pEnc->current, pEnc->reference,
932 :     &pEnc->vInterH, &pEnc->vInterV, &pEnc->vInterHV,
933 :     iLimit);
934 :     else
935 : chl 259 #endif
936 : suxen_drol 295 bIntra =
937 :     MotionEstimation(&pEnc->mbParam, pEnc->current, pEnc->reference,
938 :     &pEnc->vInterH, &pEnc->vInterV, &pEnc->vInterHV,
939 :     iLimit);
940 :    
941 : h 101 }
942 : Isibaar 3 stop_motion_timer();
943 :    
944 : edgomez 195 if (bIntra == 1) {
945 : Isibaar 3 return FrameCodeI(pEnc, bs, pBits);
946 : h 101 }
947 : Isibaar 3
948 : suxen_drol 136 pEnc->current->coding_type = P_VOP;
949 : Isibaar 3
950 : edgomez 195 if (vol_header)
951 : suxen_drol 136 BitstreamWriteVolHeader(bs, &pEnc->mbParam, pEnc->current);
952 : Isibaar 3
953 : suxen_drol 229 BitstreamWriteVopHeader(bs, &pEnc->mbParam, pEnc->current, 1);
954 : Isibaar 3
955 : edgomez 13 *pBits = BitstreamPos(bs);
956 : Isibaar 3
957 : edgomez 13 pEnc->sStat.iTextBits = 0;
958 :     pEnc->sStat.iMvSum = 0;
959 :     pEnc->sStat.iMvCount = 0;
960 : Isibaar 3 pEnc->sStat.kblks = pEnc->sStat.mblks = pEnc->sStat.ublks = 0;
961 :    
962 : edgomez 195 for (y = 0; y < pEnc->mbParam.mb_height; y++) {
963 :     for (x = 0; x < pEnc->mbParam.mb_width; x++) {
964 :     MACROBLOCK *pMB =
965 :     &pEnc->current->mbs[x + y * pEnc->mbParam.mb_width];
966 : Isibaar 3
967 : edgomez 13 bIntra = (pMB->mode == MODE_INTRA) || (pMB->mode == MODE_INTRA_Q);
968 : Isibaar 3
969 : edgomez 195 if (!bIntra) {
970 : Isibaar 3 start_timer();
971 : edgomez 195 MBMotionCompensation(pMB, x, y, &pEnc->reference->image,
972 :     &pEnc->vInterH, &pEnc->vInterV,
973 :     &pEnc->vInterHV, &pEnc->current->image,
974 :     dct_codes, pEnc->mbParam.width,
975 :     pEnc->mbParam.height,
976 :     pEnc->mbParam.edged_width,
977 :     pEnc->current->rounding_type);
978 : Isibaar 3 stop_comp_timer();
979 :    
980 : suxen_drol 136 if ((pEnc->current->global_flags & XVID_LUMIMASKING)) {
981 : edgomez 195 if (pMB->dquant != NO_CHANGE) {
982 : Isibaar 3 pMB->mode = MODE_INTER_Q;
983 : suxen_drol 136 pEnc->current->quant += DQtab[pMB->dquant];
984 : edgomez 195 if (pEnc->current->quant > 31)
985 :     pEnc->current->quant = 31;
986 :     else if (pEnc->current->quant < 1)
987 :     pEnc->current->quant = 1;
988 : Isibaar 3 }
989 :     }
990 : suxen_drol 136 pMB->quant = pEnc->current->quant;
991 : Isibaar 3
992 : h 69 pMB->field_pred = 0;
993 :    
994 : edgomez 195 pMB->cbp =
995 :     MBTransQuantInter(&pEnc->mbParam, pEnc->current, pMB, x, y,
996 :     dct_codes, qcoeff);
997 :     } else {
998 : Isibaar 3 CodeIntraMB(pEnc, pMB);
999 : edgomez 195 MBTransQuantIntra(&pEnc->mbParam, pEnc->current, pMB, x, y,
1000 :     dct_codes, qcoeff);
1001 : Isibaar 3 }
1002 :    
1003 : edgomez 13 start_timer();
1004 : edgomez 195 MBPrediction(pEnc->current, x, y, pEnc->mbParam.mb_width, qcoeff);
1005 : Isibaar 3 stop_prediction_timer();
1006 :    
1007 : edgomez 195 if (pMB->mode == MODE_INTRA || pMB->mode == MODE_INTRA_Q) {
1008 : Isibaar 3 pEnc->sStat.kblks++;
1009 : edgomez 195 } else if (pMB->cbp || pMB->mvs[0].x || pMB->mvs[0].y ||
1010 :     pMB->mvs[1].x || pMB->mvs[1].y || pMB->mvs[2].x ||
1011 :     pMB->mvs[2].y || pMB->mvs[3].x || pMB->mvs[3].y) {
1012 : Isibaar 3 pEnc->sStat.mblks++;
1013 : chl 340 } else {
1014 : Isibaar 3 pEnc->sStat.ublks++;
1015 : chl 340 }
1016 : Isibaar 3
1017 :     start_timer();
1018 : chl 347
1019 :     /* Finished processing the MB, now check if to CODE or SKIP */
1020 :    
1021 :     if (pMB->cbp == 0 && pMB->mode == MODE_INTER && pMB->mvs[0].x == 0 &&
1022 :     pMB->mvs[0].y == 0) {
1023 :    
1024 :     MBSkip(bs); /* without B-frames, no precautions are needed */
1025 :    
1026 : edgomez 403 }
1027 :     else {
1028 :     if (pEnc->current->global_flags & XVID_GREYSCALE) {
1029 :     pMB->cbp &= 0x3C; /* keep only bits 5-2 */
1030 : chl 353 qcoeff[4*64+0]=0; /* zero, because DC for INTRA MBs DC value is saved */
1031 :     qcoeff[5*64+0]=0;
1032 :     }
1033 : chl 347 MBCoding(pEnc->current, pMB, qcoeff, bs, &pEnc->sStat);
1034 :     }
1035 :    
1036 : Isibaar 3 stop_coding_timer();
1037 :     }
1038 :     }
1039 :    
1040 :     emms();
1041 :    
1042 : edgomez 195 if (pEnc->current->global_flags & XVID_HINTEDME_GET) {
1043 : h 101 HintedMEGet(pEnc, 0);
1044 :     }
1045 :    
1046 : Isibaar 3 if (pEnc->sStat.iMvCount == 0)
1047 :     pEnc->sStat.iMvCount = 1;
1048 :    
1049 : edgomez 195 fSigma = (float) sqrt((float) pEnc->sStat.iMvSum / pEnc->sStat.iMvCount);
1050 : Isibaar 3
1051 : suxen_drol 136 iSearchRange = 1 << (3 + pEnc->mbParam.m_fcode);
1052 : Isibaar 3
1053 : edgomez 195 if ((fSigma > iSearchRange / 3)
1054 :     && (pEnc->mbParam.m_fcode <= 3)) // maximum search range 128
1055 : edgomez 13 {
1056 : suxen_drol 136 pEnc->mbParam.m_fcode++;
1057 : Isibaar 3 iSearchRange *= 2;
1058 : edgomez 195 } else if ((fSigma < iSearchRange / 6)
1059 :     && (pEnc->sStat.fMvPrevSigma >= 0)
1060 :     && (pEnc->sStat.fMvPrevSigma < iSearchRange / 6)
1061 :     && (pEnc->mbParam.m_fcode >= 2)) // minimum search range 16
1062 : edgomez 13 {
1063 : suxen_drol 136 pEnc->mbParam.m_fcode--;
1064 : Isibaar 3 iSearchRange /= 2;
1065 : edgomez 13 }
1066 : Isibaar 3
1067 : edgomez 13 pEnc->sStat.fMvPrevSigma = fSigma;
1068 : edgomez 195
1069 : Isibaar 3 *pBits = BitstreamPos(bs) - *pBits;
1070 :    
1071 : edgomez 195 return 0; // inter
1072 : suxen_drol 118
1073 :     }

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