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

Annotation of /xvidcore/src/encoder.c

Parent Directory Parent Directory | Revision Log Revision Log


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

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