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

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

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