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

Annotation of /xvidcore/src/encoder.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.87 - (view) (download)

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

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