[svn] / branches / dev-api-3 / xvidcore / src / encoder.c Repository:
ViewVC logotype

Annotation of /branches/dev-api-3/xvidcore/src/encoder.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 164 - (view) (download)
Original Path: trunk/xvidcore/src/encoder.c

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 164 * $Id: encoder.c,v 1.35 2002-05-06 10:07:18 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 : suxen_drol 164 pEnc->mbParam.max_bframes = pParam->max_bframes;
268 : suxen_drol 152 pEnc->bquant_ratio = pParam->bquant_ratio;
269 : suxen_drol 164 if (pEnc->mbParam.max_bframes > 0)
270 : suxen_drol 152 {
271 :     int n;
272 :    
273 : suxen_drol 164 pEnc->bframes = malloc(pEnc->mbParam.max_bframes * sizeof(FRAMEINFO *));
274 : suxen_drol 152
275 : suxen_drol 164 for (n = 0; n < pEnc->mbParam.max_bframes; n++)
276 : suxen_drol 152 {
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 : suxen_drol 164 if (pEnc->mbParam.max_bframes > 0)
320 : suxen_drol 152 {
321 :     int n;
322 : suxen_drol 164 for (n = 0; n < pEnc->mbParam.max_bframes; n++)
323 : suxen_drol 152 {
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 : edgomez 158 #endif
331 : suxen_drol 152 //====================================================================
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 : Isibaar 157
437 :     if(pEnc->current->quant < 1)
438 :     pEnc->current->quant = 1;
439 :    
440 :     if(pEnc->current->quant > 31)
441 :     pEnc->current->quant = 31;
442 :    
443 : suxen_drol 152 pEnc->current->global_flags = pFrame->general;
444 :     pEnc->current->motion_flags = pFrame->motion;
445 :     pEnc->current->seconds = pEnc->mbParam.m_seconds;
446 :     pEnc->current->ticks = pEnc->mbParam.m_ticks;
447 :     //@@@ TODO: dyanmic fcode (in both directions)
448 :     pEnc->current->fcode = pEnc->mbParam.m_fcode;
449 :     pEnc->current->bcode = pEnc->mbParam.m_fcode;
450 :    
451 :     start_timer();
452 :     if (image_input(&pEnc->current->image, pEnc->mbParam.width, pEnc->mbParam.height, pEnc->mbParam.edged_width,
453 :     pFrame->image, pFrame->colorspace))
454 :     {
455 :     return XVID_ERR_FORMAT;
456 :     }
457 :     stop_conv_timer();
458 :    
459 :     #ifdef _DEBUG
460 :     image_copy(&pEnc->sOriginal, &pEnc->sCurrent, pEnc->mbParam.edged_width, pEnc->mbParam.height);
461 :     #endif
462 :    
463 :    
464 :     // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
465 :     // lumi masking
466 :     // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
467 :    
468 :     if ((pEnc->current->global_flags & XVID_LUMIMASKING))
469 :     {
470 :     int * temp_dquants = (int *) xvid_malloc(pEnc->mbParam.mb_width * pEnc->mbParam.mb_height * sizeof(int), CACHE_LINE);
471 :    
472 :     pEnc->current->quant = adaptive_quantization(pEnc->current->image.y,
473 :     pEnc->mbParam.edged_width, // stride
474 :     temp_dquants,
475 :     pEnc->current->quant,
476 :     pEnc->current->quant, // min_quant
477 :     2*pEnc->current->quant, // max_quant
478 :     pEnc->mbParam.mb_width,
479 :     pEnc->mbParam.mb_height);
480 :    
481 :     for (y = 0; y < pEnc->mbParam.mb_height; y++)
482 :     for (x = 0; x < pEnc->mbParam.mb_width; x++)
483 :     {
484 :     MACROBLOCK *pMB = &pEnc->current->mbs[x + y * pEnc->mbParam.mb_width];
485 :     pMB->dquant = iDQtab[(temp_dquants[y * pEnc->mbParam.mb_width + x] + 2)];
486 :     }
487 :     xvid_free(temp_dquants);
488 :     }
489 :    
490 :    
491 :     // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
492 :     // ivop/pvop/bvop selection
493 :     // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
494 :    
495 :     if (pEnc->iFrameNum == 0 ||
496 :     pFrame->intra == 1 ||
497 :     (pFrame->intra < 0 && (pEnc->iMaxKeyInterval > 0 && pEnc->iFrameNum >= pEnc->iMaxKeyInterval)) ||
498 :     image_mad(&pEnc->reference->image, &pEnc->current->image, pEnc->mbParam.edged_width, pEnc->mbParam.width, pEnc->mbParam.height) > 30)
499 :     {
500 :     dprintf("--- IFRAME ---");
501 :    
502 :     FrameCodeI(pEnc, &bs, &bits);
503 :    
504 :     pFrame->intra = 1;
505 :     pEnc->flush_bframes = 1;
506 :    
507 :     /* note: sequences like "IIBB" decode fine with msfdam but,
508 :     go screwy with divx5.00 */
509 :     }
510 : suxen_drol 164 else if (pEnc->bframenum_tail >= pEnc->mbParam.max_bframes)
511 : suxen_drol 152 {
512 :     dprintf("--- PFRAME ---");
513 :    
514 :     FrameCodeP(pEnc, &bs, &bits, 1, 0);
515 :     pFrame->intra = 0;
516 :     pEnc->flush_bframes = 1;
517 :     }
518 :     else
519 :     {
520 :     dprintf("--- BFRAME (store) --- head=%i tail=%i", pEnc->bframenum_head, pEnc->bframenum_tail);
521 :    
522 :     if (pFrame->bquant < 1)
523 :     {
524 :     pEnc->current->quant = ((pEnc->reference->quant + pEnc->current->quant) * pEnc->bquant_ratio) / 200;
525 :     }
526 :     else
527 :     {
528 :     pEnc->current->quant = pFrame->bquant;
529 :     }
530 :    
531 :     // store frame into bframe buffer & swap ref back to current
532 :     SWAP(pEnc->current, pEnc->bframes[pEnc->bframenum_tail]);
533 :     SWAP(pEnc->current, pEnc->reference);
534 :    
535 :     pEnc->bframenum_tail++;
536 :    
537 :     pFrame->intra = 0;
538 :     pFrame->length = 0;
539 :     pFrame->input_consumed = 1;
540 :    
541 :     pEnc->mbParam.m_ticks += pEnc->mbParam.fincr;
542 :     if (pEnc->mbParam.m_ticks > pEnc->mbParam.fbase)
543 :     {
544 :     pEnc->mbParam.m_seconds++;
545 :     pEnc->mbParam.m_ticks = 0;
546 :     }
547 :     return XVID_ERR_OK;
548 :     }
549 :    
550 :     BitstreamPad(&bs);
551 :     pFrame->length = BitstreamLength(&bs);
552 :    
553 :     if (pResult)
554 :     {
555 :     pResult->quant = pEnc->current->quant;
556 :     pResult->hlength = pFrame->length - (pEnc->sStat.iTextBits / 8);
557 :     pResult->kblks = pEnc->sStat.kblks;
558 :     pResult->mblks = pEnc->sStat.mblks;
559 :     pResult->ublks = pEnc->sStat.ublks;
560 :     }
561 :    
562 :     #ifdef _DEBUG
563 :     psnr = image_psnr(&pEnc->sOriginal, &pEnc->current->image, pEnc->mbParam.edged_width,
564 :     pEnc->mbParam.width, pEnc->mbParam.height);
565 :    
566 :     sprintf(temp, "PSNR: %f\n", psnr);
567 :     DEBUG(temp);
568 :     #endif
569 :    
570 :     if (pFrame->quant == 0)
571 :     {
572 :     RateControlUpdate(pEnc->current->quant, pFrame->length, pFrame->intra);
573 :     }
574 :    
575 :     pEnc->iFrameNum++;
576 :     pEnc->mbParam.m_ticks += pEnc->mbParam.fincr;
577 :     if (pEnc->mbParam.m_ticks > pEnc->mbParam.fbase)
578 :     {
579 :     pEnc->mbParam.m_seconds++;
580 :     pEnc->mbParam.m_ticks = 0;
581 :     }
582 :     pFrame->input_consumed = 1;
583 :    
584 :     stop_global_timer();
585 :     write_timer();
586 :    
587 :     return XVID_ERR_OK;
588 :     }
589 :     // ==================================================================
590 :     #else
591 :     int encoder_encode(Encoder * pEnc, XVID_ENC_FRAME * pFrame, XVID_ENC_STATS * pResult)
592 :     {
593 :     uint16_t x, y;
594 :     Bitstream bs;
595 :     uint32_t bits;
596 : Isibaar 4 uint16_t write_vol_header = 0;
597 : Isibaar 113 #ifdef _DEBUG
598 :     float psnr;
599 :     uint8_t temp[100];
600 :     #endif
601 : Isibaar 3
602 :     start_global_timer();
603 :    
604 : edgomez 13 ENC_CHECK(pEnc);
605 :     ENC_CHECK(pFrame);
606 :     ENC_CHECK(pFrame->bitstream);
607 :     ENC_CHECK(pFrame->image);
608 : Isibaar 3
609 : suxen_drol 136 SWAP(pEnc->current, pEnc->reference);
610 :    
611 :     pEnc->current->global_flags = pFrame->general;
612 :     pEnc->current->motion_flags = pFrame->motion;
613 : h 101 pEnc->mbParam.hint = &pFrame->hint;
614 : Isibaar 3
615 :     start_timer();
616 : suxen_drol 136 if (image_input(&pEnc->current->image, pEnc->mbParam.width, pEnc->mbParam.height, pEnc->mbParam.edged_width,
617 : edgomez 13 pFrame->image, pFrame->colorspace))
618 : Isibaar 3 {
619 :     return XVID_ERR_FORMAT;
620 :     }
621 :     stop_conv_timer();
622 :    
623 : Isibaar 113 #ifdef _DEBUG
624 : chenm001 150 image_copy(&pEnc->sOriginal, &pEnc->current->image, pEnc->mbParam.edged_width, pEnc->mbParam.height);
625 : Isibaar 113 #endif
626 :    
627 : suxen_drol 136 EMMS();
628 :    
629 : edgomez 13 BitstreamInit(&bs, pFrame->bitstream, 0);
630 : Isibaar 3
631 :     if (pFrame->quant == 0)
632 :     {
633 : suxen_drol 136 pEnc->current->quant = RateControlGetQ(0);
634 : Isibaar 3 }
635 :     else
636 :     {
637 : suxen_drol 136 pEnc->current->quant = pFrame->quant;
638 : Isibaar 3 }
639 :    
640 : suxen_drol 136 if ((pEnc->current->global_flags & XVID_LUMIMASKING))
641 : Isibaar 3 {
642 : canard 66 int * temp_dquants = (int *) xvid_malloc(pEnc->mbParam.mb_width * pEnc->mbParam.mb_height * sizeof(int), CACHE_LINE);
643 : Isibaar 3
644 : suxen_drol 136 pEnc->current->quant = adaptive_quantization(pEnc->current->image.y,
645 :     pEnc->mbParam.edged_width, // stride
646 : edgomez 78 temp_dquants,
647 : suxen_drol 136 pEnc->current->quant,
648 :     pEnc->current->quant, // min_quant
649 :     2*pEnc->current->quant, // max_quant
650 : edgomez 78 pEnc->mbParam.mb_width,
651 :     pEnc->mbParam.mb_height);
652 : Isibaar 3
653 :     for (y = 0; y < pEnc->mbParam.mb_height; y++)
654 :     for (x = 0; x < pEnc->mbParam.mb_width; x++)
655 :     {
656 : suxen_drol 136 MACROBLOCK *pMB = &pEnc->current->mbs[x + y * pEnc->mbParam.mb_width];
657 : Isibaar 3 pMB->dquant = iDQtab[(temp_dquants[y * pEnc->mbParam.mb_width + x] + 2)];
658 :     }
659 : Isibaar 41 xvid_free(temp_dquants);
660 : Isibaar 3 }
661 :    
662 : suxen_drol 136 if (pEnc->current->global_flags & XVID_H263QUANT) {
663 :     if(pEnc->mbParam.m_quant_type != H263_QUANT)
664 : Isibaar 20 write_vol_header = 1;
665 : suxen_drol 136 pEnc->mbParam.m_quant_type = H263_QUANT;
666 : Isibaar 3 }
667 : suxen_drol 136 else if(pEnc->current->global_flags & XVID_MPEGQUANT) {
668 : Isibaar 20 int ret1, ret2;
669 : Isibaar 3
670 : edgomez 78 ret1 = ret2 = 0;
671 :    
672 : suxen_drol 136 if(pEnc->mbParam.m_quant_type != MPEG4_QUANT)
673 : Isibaar 20 write_vol_header = 1;
674 :    
675 : suxen_drol 136 pEnc->mbParam.m_quant_type = MPEG4_QUANT;
676 : Isibaar 20
677 : suxen_drol 136 if ((pEnc->current->global_flags & XVID_CUSTOM_QMATRIX) > 0) {
678 : Isibaar 20 if(pFrame->quant_intra_matrix != NULL)
679 :     ret1 = set_intra_matrix(pFrame->quant_intra_matrix);
680 :     if(pFrame->quant_inter_matrix != NULL)
681 :     ret2 = set_inter_matrix(pFrame->quant_inter_matrix);
682 :     }
683 :     else {
684 :     ret1 = set_intra_matrix(get_default_intra_matrix());
685 :     ret2 = set_inter_matrix(get_default_inter_matrix());
686 :     }
687 : Isibaar 4 if(write_vol_header == 0)
688 :     write_vol_header = ret1 | ret2;
689 :     }
690 : Isibaar 3
691 :     if (pFrame->intra < 0)
692 : edgomez 13 {
693 : Isibaar 3 if ((pEnc->iFrameNum == 0) || ((pEnc->iMaxKeyInterval > 0)
694 : edgomez 13 && (pEnc->iFrameNum >= pEnc->iMaxKeyInterval)))
695 : Isibaar 3
696 :     pFrame->intra = FrameCodeI(pEnc, &bs, &bits);
697 :     else
698 : Isibaar 4 pFrame->intra = FrameCodeP(pEnc, &bs, &bits, 0, write_vol_header);
699 : edgomez 13 }
700 :     else
701 :     {
702 : Isibaar 3 if (pFrame->intra == 1)
703 : edgomez 13 pFrame->intra = FrameCodeI(pEnc, &bs, &bits);
704 : Isibaar 3 else
705 : Isibaar 4 pFrame->intra = FrameCodeP(pEnc, &bs, &bits, 1, write_vol_header);
706 : edgomez 13 }
707 : Isibaar 3
708 :     BitstreamPutBits(&bs, 0xFFFF, 16);
709 : edgomez 13 BitstreamPutBits(&bs, 0xFFFF, 16);
710 :     BitstreamPad(&bs);
711 :     pFrame->length = BitstreamLength(&bs);
712 : h 29
713 : Isibaar 3 if (pResult)
714 : edgomez 13 {
715 : suxen_drol 136 pResult->quant = pEnc->current->quant;
716 : Isibaar 3 pResult->hlength = pFrame->length - (pEnc->sStat.iTextBits / 8);
717 :     pResult->kblks = pEnc->sStat.kblks;
718 :     pResult->mblks = pEnc->sStat.mblks;
719 :     pResult->ublks = pEnc->sStat.ublks;
720 : edgomez 13 }
721 : Isibaar 3
722 : Isibaar 41 EMMS();
723 :    
724 : h 29 if (pFrame->quant == 0)
725 : Isibaar 3 {
726 : suxen_drol 136 RateControlUpdate(pEnc->current->quant, pFrame->length, pFrame->intra);
727 : Isibaar 3 }
728 :    
729 : Isibaar 113 #ifdef _DEBUG
730 : suxen_drol 136 psnr = image_psnr(&pEnc->sOriginal, &pEnc->current->image, pEnc->mbParam.edged_width,
731 : Isibaar 113 pEnc->mbParam.width, pEnc->mbParam.height);
732 :    
733 :     sprintf(temp, "PSNR: %f\n", psnr);
734 :     DEBUG(temp);
735 :     #endif
736 :    
737 : Isibaar 3 pEnc->iFrameNum++;
738 :    
739 :     stop_global_timer();
740 :     write_timer();
741 :    
742 :     return XVID_ERR_OK;
743 :     }
744 : suxen_drol 152 #endif
745 : Isibaar 3
746 :    
747 :     static __inline void CodeIntraMB(Encoder *pEnc, MACROBLOCK *pMB) {
748 :    
749 :     pMB->mode = MODE_INTRA;
750 :    
751 : suxen_drol 136 /* zero mv statistics */
752 :     pMB->mvs[0].x = pMB->mvs[1].x = pMB->mvs[2].x = pMB->mvs[3].x = 0;
753 :     pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = 0;
754 :     pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = 0;
755 :     pMB->sad16 = 0;
756 :    
757 :     if ((pEnc->current->global_flags & XVID_LUMIMASKING)) {
758 : Isibaar 3 if(pMB->dquant != NO_CHANGE)
759 :     {
760 :     pMB->mode = MODE_INTRA_Q;
761 : suxen_drol 136 pEnc->current->quant += DQtab[pMB->dquant];
762 : Isibaar 3
763 : suxen_drol 136 if (pEnc->current->quant > 31) pEnc->current->quant = 31;
764 :     if (pEnc->current->quant < 1) pEnc->current->quant = 1;
765 : Isibaar 3 }
766 :     }
767 :    
768 : suxen_drol 136 pMB->quant = pEnc->current->quant;
769 : Isibaar 3 }
770 :    
771 :    
772 : h 101 #define FCODEBITS 3
773 :     #define MODEBITS 5
774 :    
775 :     void HintedMESet(Encoder * pEnc, int * intra)
776 :     {
777 :     HINTINFO * hint;
778 :     Bitstream bs;
779 :     int length, high;
780 :     uint32_t x, y;
781 :    
782 :     hint = pEnc->mbParam.hint;
783 :    
784 :     if (hint->rawhints)
785 :     {
786 :     *intra = hint->mvhint.intra;
787 :     }
788 :     else
789 :     {
790 :     BitstreamInit(&bs, hint->hintstream, hint->hintlength);
791 :     *intra = BitstreamGetBit(&bs);
792 :     }
793 :    
794 :     if (*intra)
795 :     {
796 :     return;
797 :     }
798 :    
799 : suxen_drol 136 pEnc->current->fcode = (hint->rawhints) ? hint->mvhint.fcode : BitstreamGetBits(&bs, FCODEBITS);
800 : h 101
801 : suxen_drol 136 length = pEnc->current->fcode + 5;
802 : h 101 high = 1 << (length - 1);
803 :    
804 :     for (y=0 ; y<pEnc->mbParam.mb_height ; ++y)
805 :     {
806 :     for (x=0 ; x<pEnc->mbParam.mb_width ; ++x)
807 :     {
808 : suxen_drol 136 MACROBLOCK * pMB = &pEnc->current->mbs[x + y * pEnc->mbParam.mb_width];
809 : h 101 MVBLOCKHINT * bhint = &hint->mvhint.block[x + y * pEnc->mbParam.mb_width];
810 :     VECTOR pred[4];
811 :     VECTOR tmp;
812 : edgomez 147 int32_t dummy[4];
813 : h 101 int vec;
814 :    
815 :     pMB->mode = (hint->rawhints) ? bhint->mode : BitstreamGetBits(&bs, MODEBITS);
816 :    
817 : h 128 pMB->mode = (pMB->mode == MODE_INTER_Q) ? MODE_INTER : pMB->mode;
818 :     pMB->mode = (pMB->mode == MODE_INTRA_Q) ? MODE_INTRA : pMB->mode;
819 :    
820 :     if (pMB->mode == MODE_INTER)
821 : h 101 {
822 :     tmp.x = (hint->rawhints) ? bhint->mvs[0].x : BitstreamGetBits(&bs, length);
823 :     tmp.y = (hint->rawhints) ? bhint->mvs[0].y : BitstreamGetBits(&bs, length);
824 :     tmp.x -= (tmp.x >= high) ? high*2 : 0;
825 :     tmp.y -= (tmp.y >= high) ? high*2 : 0;
826 :    
827 : suxen_drol 136 get_pmvdata(pEnc->current->mbs, x, y, pEnc->mbParam.mb_width, 0, pred, dummy);
828 : h 101
829 :     for (vec=0 ; vec<4 ; ++vec)
830 :     {
831 :     pMB->mvs[vec].x = tmp.x;
832 :     pMB->mvs[vec].y = tmp.y;
833 :     pMB->pmvs[vec].x = pMB->mvs[0].x - pred[0].x;
834 :     pMB->pmvs[vec].y = pMB->mvs[0].y - pred[0].y;
835 :     }
836 :     }
837 :     else if (pMB->mode == MODE_INTER4V)
838 :     {
839 :     for (vec=0 ; vec<4 ; ++vec)
840 :     {
841 :     tmp.x = (hint->rawhints) ? bhint->mvs[vec].x : BitstreamGetBits(&bs, length);
842 :     tmp.y = (hint->rawhints) ? bhint->mvs[vec].y : BitstreamGetBits(&bs, length);
843 :     tmp.x -= (tmp.x >= high) ? high*2 : 0;
844 :     tmp.y -= (tmp.y >= high) ? high*2 : 0;
845 :    
846 : suxen_drol 136 get_pmvdata(pEnc->current->mbs, x, y, pEnc->mbParam.mb_width, vec, pred, dummy);
847 : h 101
848 :     pMB->mvs[vec].x = tmp.x;
849 :     pMB->mvs[vec].y = tmp.y;
850 :     pMB->pmvs[vec].x = pMB->mvs[vec].x - pred[0].x;
851 :     pMB->pmvs[vec].y = pMB->mvs[vec].y - pred[0].y;
852 :     }
853 :     }
854 : h 128 else // intra / stuffing / not_coded
855 : h 101 {
856 :     for (vec=0 ; vec<4 ; ++vec)
857 :     {
858 :     pMB->mvs[vec].x = pMB->mvs[vec].y = 0;
859 :     }
860 :     }
861 : h 128
862 : suxen_drol 136 if (pMB->mode == MODE_INTER4V &&
863 :     (pEnc->current->global_flags & XVID_LUMIMASKING) && pMB->dquant != NO_CHANGE)
864 : h 128 {
865 :     pMB->mode = MODE_INTRA;
866 :    
867 :     for (vec=0 ; vec<4 ; ++vec)
868 :     {
869 :     pMB->mvs[vec].x = pMB->mvs[vec].y = 0;
870 :     }
871 :     }
872 : h 101 }
873 :     }
874 :     }
875 :    
876 :    
877 :     void HintedMEGet(Encoder * pEnc, int intra)
878 :     {
879 :     HINTINFO * hint;
880 :     Bitstream bs;
881 :     uint32_t x, y;
882 :     int length, high;
883 :    
884 :     hint = pEnc->mbParam.hint;
885 :    
886 :     if (hint->rawhints)
887 :     {
888 :     hint->mvhint.intra = intra;
889 :     }
890 :     else
891 :     {
892 :     BitstreamInit(&bs, hint->hintstream, 0);
893 :     BitstreamPutBit(&bs, intra);
894 :     }
895 :    
896 :     if (intra)
897 :     {
898 :     if (!hint->rawhints)
899 :     {
900 :     BitstreamPad(&bs);
901 :     hint->hintlength = BitstreamLength(&bs);
902 :     }
903 :     return;
904 :     }
905 :    
906 : suxen_drol 136 length = pEnc->current->fcode + 5;
907 : h 101 high = 1 << (length - 1);
908 :    
909 :     if (hint->rawhints)
910 :     {
911 : suxen_drol 136 hint->mvhint.fcode = pEnc->current->fcode;
912 : h 101 }
913 :     else
914 :     {
915 : suxen_drol 136 BitstreamPutBits(&bs, pEnc->current->fcode, FCODEBITS);
916 : h 101 }
917 :    
918 :     for (y=0 ; y<pEnc->mbParam.mb_height ; ++y)
919 :     {
920 :     for (x=0 ; x<pEnc->mbParam.mb_width ; ++x)
921 :     {
922 : suxen_drol 136 MACROBLOCK * pMB = &pEnc->current->mbs[x + y * pEnc->mbParam.mb_width];
923 : h 101 MVBLOCKHINT * bhint = &hint->mvhint.block[x + y * pEnc->mbParam.mb_width];
924 :     VECTOR tmp;
925 :    
926 :     if (hint->rawhints)
927 :     {
928 :     bhint->mode = pMB->mode;
929 :     }
930 :     else
931 :     {
932 :     BitstreamPutBits(&bs, pMB->mode, MODEBITS);
933 :     }
934 :    
935 :     if (pMB->mode == MODE_INTER || pMB->mode == MODE_INTER_Q)
936 :     {
937 :     tmp.x = pMB->mvs[0].x;
938 :     tmp.y = pMB->mvs[0].y;
939 :     tmp.x += (tmp.x < 0) ? high*2 : 0;
940 :     tmp.y += (tmp.y < 0) ? high*2 : 0;
941 :    
942 :     if (hint->rawhints)
943 :     {
944 :     bhint->mvs[0].x = tmp.x;
945 :     bhint->mvs[0].y = tmp.y;
946 :     }
947 :     else
948 :     {
949 :     BitstreamPutBits(&bs, tmp.x, length);
950 :     BitstreamPutBits(&bs, tmp.y, length);
951 :     }
952 :     }
953 :     else if (pMB->mode == MODE_INTER4V)
954 :     {
955 :     int vec;
956 :    
957 :     for (vec=0 ; vec<4 ; ++vec)
958 :     {
959 :     tmp.x = pMB->mvs[vec].x;
960 :     tmp.y = pMB->mvs[vec].y;
961 :     tmp.x += (tmp.x < 0) ? high*2 : 0;
962 :     tmp.y += (tmp.y < 0) ? high*2 : 0;
963 :    
964 :     if (hint->rawhints)
965 :     {
966 :     bhint->mvs[vec].x = tmp.x;
967 :     bhint->mvs[vec].y = tmp.y;
968 :     }
969 :     else
970 :     {
971 :     BitstreamPutBits(&bs, tmp.x, length);
972 :     BitstreamPutBits(&bs, tmp.y, length);
973 :     }
974 :     }
975 :     }
976 :     }
977 :     }
978 :    
979 :     if (!hint->rawhints)
980 :     {
981 :     BitstreamPad(&bs);
982 :     hint->hintlength = BitstreamLength(&bs);
983 :     }
984 :     }
985 :    
986 :    
987 : h 104 static int FrameCodeI(Encoder * pEnc, Bitstream * bs, uint32_t *pBits)
988 :     {
989 :    
990 :     DECLARE_ALIGNED_MATRIX(dct_codes, 6, 64, int16_t, CACHE_LINE);
991 :     DECLARE_ALIGNED_MATRIX(qcoeff, 6, 64, int16_t, CACHE_LINE);
992 :    
993 :     uint16_t x, y;
994 :    
995 :     pEnc->iFrameNum = 0;
996 : suxen_drol 136 pEnc->mbParam.m_rounding_type = 1;
997 :     pEnc->current->rounding_type = pEnc->mbParam.m_rounding_type;
998 :     pEnc->current->coding_type = I_VOP;
999 : h 104
1000 : suxen_drol 136 BitstreamWriteVolHeader(bs, &pEnc->mbParam, pEnc->current);
1001 :     BitstreamWriteVopHeader(bs, &pEnc->mbParam, pEnc->current);
1002 : h 104
1003 :     *pBits = BitstreamPos(bs);
1004 :    
1005 :     pEnc->sStat.iTextBits = 0;
1006 :     pEnc->sStat.kblks = pEnc->mbParam.mb_width * pEnc->mbParam.mb_height;
1007 :     pEnc->sStat.mblks = pEnc->sStat.ublks = 0;
1008 :    
1009 :     for (y = 0; y < pEnc->mbParam.mb_height; y++)
1010 :     for (x = 0; x < pEnc->mbParam.mb_width; x++)
1011 :     {
1012 : suxen_drol 136 MACROBLOCK *pMB = &pEnc->current->mbs[x + y * pEnc->mbParam.mb_width];
1013 : h 104
1014 :     CodeIntraMB(pEnc, pMB);
1015 :    
1016 : suxen_drol 136 MBTransQuantIntra(&pEnc->mbParam, pEnc->current, pMB, x, y, dct_codes, qcoeff);
1017 : h 104
1018 :     start_timer();
1019 : suxen_drol 136 MBPrediction(pEnc->current, x, y, pEnc->mbParam.mb_width, qcoeff);
1020 : h 104 stop_prediction_timer();
1021 :    
1022 :     start_timer();
1023 : suxen_drol 136 MBCoding(pEnc->current, pMB, qcoeff, bs, &pEnc->sStat);
1024 : h 104 stop_coding_timer();
1025 :     }
1026 :    
1027 :     emms();
1028 :    
1029 :     *pBits = BitstreamPos(bs) - *pBits;
1030 :     pEnc->sStat.fMvPrevSigma = -1;
1031 :     pEnc->sStat.iMvSum = 0;
1032 :     pEnc->sStat.iMvCount = 0;
1033 : suxen_drol 136 pEnc->mbParam.m_fcode = 2;
1034 : h 104
1035 : suxen_drol 136 if (pEnc->current->global_flags & XVID_HINTEDME_GET)
1036 : h 104 {
1037 :     HintedMEGet(pEnc, 1);
1038 :     }
1039 :    
1040 :     return 1; // intra
1041 :     }
1042 :    
1043 :    
1044 : Isibaar 3 #define INTRA_THRESHOLD 0.5
1045 :    
1046 :     static int FrameCodeP(Encoder * pEnc, Bitstream * bs, uint32_t *pBits, bool force_inter, bool vol_header)
1047 :     {
1048 : edgomez 13 float fSigma;
1049 : Isibaar 42
1050 : edgomez 78 DECLARE_ALIGNED_MATRIX(dct_codes, 6, 64, int16_t, CACHE_LINE);
1051 :     DECLARE_ALIGNED_MATRIX(qcoeff, 6, 64, int16_t, CACHE_LINE);
1052 :    
1053 : Isibaar 3 int iLimit;
1054 : edgomez 13 uint32_t x, y;
1055 :     int iSearchRange;
1056 : edgomez 145 int bIntra;
1057 : Isibaar 3
1058 : edgomez 145 /* IMAGE *pCurrent = &pEnc->current->image; */
1059 : suxen_drol 136 IMAGE *pRef = &pEnc->reference->image;
1060 : Isibaar 3
1061 : h 69 start_timer();
1062 : edgomez 78 image_setedges(pRef,
1063 : h 85 pEnc->mbParam.edged_width,
1064 :     pEnc->mbParam.edged_height,
1065 :     pEnc->mbParam.width,
1066 :     pEnc->mbParam.height,
1067 : suxen_drol 136 pEnc->current->global_flags & XVID_INTERLACING);
1068 : h 69 stop_edges_timer();
1069 : Isibaar 3
1070 : suxen_drol 136 pEnc->mbParam.m_rounding_type = 1 - pEnc->mbParam.m_rounding_type;
1071 :     pEnc->current->rounding_type = pEnc->mbParam.m_rounding_type;
1072 :     pEnc->current->fcode = pEnc->mbParam.m_fcode;
1073 : Isibaar 3
1074 :     if (!force_inter)
1075 :     iLimit = (int)(pEnc->mbParam.mb_width * pEnc->mbParam.mb_height * INTRA_THRESHOLD);
1076 : edgomez 13 else
1077 : Isibaar 3 iLimit = pEnc->mbParam.mb_width * pEnc->mbParam.mb_height + 1;
1078 :    
1079 : suxen_drol 136 if ((pEnc->current->global_flags & XVID_HALFPEL)) {
1080 : Isibaar 3 start_timer();
1081 : h 85 image_interpolate(pRef, &pEnc->vInterH, &pEnc->vInterV, &pEnc->vInterHV,
1082 :     pEnc->mbParam.edged_width, pEnc->mbParam.edged_height,
1083 : suxen_drol 136 pEnc->current->rounding_type);
1084 : Isibaar 3 stop_inter_timer();
1085 :     }
1086 :    
1087 :     start_timer();
1088 : suxen_drol 136 if (pEnc->current->global_flags & XVID_HINTEDME_SET)
1089 : h 101 {
1090 :     HintedMESet(pEnc, &bIntra);
1091 :     }
1092 :     else
1093 :     {
1094 : suxen_drol 136 bIntra = MotionEstimation(
1095 :     &pEnc->mbParam,
1096 :     pEnc->current,
1097 :     pEnc->reference,
1098 :     &pEnc->vInterH,
1099 :     &pEnc->vInterV,
1100 :     &pEnc->vInterHV,
1101 :     iLimit);
1102 : h 101 }
1103 : Isibaar 3 stop_motion_timer();
1104 :    
1105 :     if (bIntra == 1)
1106 : h 101 {
1107 : Isibaar 3 return FrameCodeI(pEnc, bs, pBits);
1108 : h 101 }
1109 : Isibaar 3
1110 : suxen_drol 136 pEnc->current->coding_type = P_VOP;
1111 : Isibaar 3
1112 :     if(vol_header)
1113 : suxen_drol 136 BitstreamWriteVolHeader(bs, &pEnc->mbParam, pEnc->current);
1114 : Isibaar 3
1115 : suxen_drol 136 BitstreamWriteVopHeader(bs, &pEnc->mbParam, pEnc->current);
1116 : Isibaar 3
1117 : edgomez 13 *pBits = BitstreamPos(bs);
1118 : Isibaar 3
1119 : edgomez 13 pEnc->sStat.iTextBits = 0;
1120 :     pEnc->sStat.iMvSum = 0;
1121 :     pEnc->sStat.iMvCount = 0;
1122 : Isibaar 3 pEnc->sStat.kblks = pEnc->sStat.mblks = pEnc->sStat.ublks = 0;
1123 :    
1124 : edgomez 13 for(y = 0; y < pEnc->mbParam.mb_height; y++)
1125 : Isibaar 3 {
1126 :     for(x = 0; x < pEnc->mbParam.mb_width; x++)
1127 :     {
1128 : suxen_drol 136 MACROBLOCK * pMB = &pEnc->current->mbs[x + y * pEnc->mbParam.mb_width];
1129 : Isibaar 3
1130 : edgomez 13 bIntra = (pMB->mode == MODE_INTRA) || (pMB->mode == MODE_INTRA_Q);
1131 : Isibaar 3
1132 :     if (!bIntra)
1133 : edgomez 13 {
1134 : Isibaar 3 start_timer();
1135 : edgomez 78 MBMotionCompensation(pMB,
1136 :     x, y,
1137 : suxen_drol 136 &pEnc->reference->image,
1138 : edgomez 78 &pEnc->vInterH,
1139 : h 85 &pEnc->vInterV,
1140 :     &pEnc->vInterHV,
1141 : suxen_drol 136 &pEnc->current->image,
1142 : edgomez 78 dct_codes,
1143 : edgomez 13 pEnc->mbParam.width,
1144 :     pEnc->mbParam.height,
1145 :     pEnc->mbParam.edged_width,
1146 : suxen_drol 136 pEnc->current->rounding_type);
1147 : Isibaar 3 stop_comp_timer();
1148 :    
1149 : suxen_drol 136 if ((pEnc->current->global_flags & XVID_LUMIMASKING)) {
1150 : Isibaar 3 if(pMB->dquant != NO_CHANGE) {
1151 :     pMB->mode = MODE_INTER_Q;
1152 : suxen_drol 136 pEnc->current->quant += DQtab[pMB->dquant];
1153 :     if (pEnc->current->quant > 31) pEnc->current->quant = 31;
1154 :     else if(pEnc->current->quant < 1) pEnc->current->quant = 1;
1155 : Isibaar 3 }
1156 :     }
1157 : suxen_drol 136 pMB->quant = pEnc->current->quant;
1158 : Isibaar 3
1159 : h 69 pMB->field_pred = 0;
1160 :    
1161 : suxen_drol 136 pMB->cbp = MBTransQuantInter(&pEnc->mbParam, pEnc->current, pMB, x, y, dct_codes, qcoeff);
1162 : edgomez 13 }
1163 : Isibaar 3 else
1164 :     {
1165 :     CodeIntraMB(pEnc, pMB);
1166 : suxen_drol 136 MBTransQuantIntra(&pEnc->mbParam, pEnc->current, pMB, x, y, dct_codes, qcoeff);
1167 : Isibaar 3 }
1168 :    
1169 : edgomez 13 start_timer();
1170 : suxen_drol 136 MBPrediction(pEnc->current, x, y, pEnc->mbParam.mb_width, qcoeff);
1171 : Isibaar 3 stop_prediction_timer();
1172 :    
1173 :     if (pMB->mode == MODE_INTRA || pMB->mode == MODE_INTRA_Q)
1174 :     {
1175 :     pEnc->sStat.kblks++;
1176 :     }
1177 :     else if (pMB->cbp ||
1178 : edgomez 13 pMB->mvs[0].x || pMB->mvs[0].y ||
1179 :     pMB->mvs[1].x || pMB->mvs[1].y ||
1180 :     pMB->mvs[2].x || pMB->mvs[2].y ||
1181 :     pMB->mvs[3].x || pMB->mvs[3].y)
1182 : Isibaar 3 {
1183 :     pEnc->sStat.mblks++;
1184 :     }
1185 :     else
1186 :     {
1187 :     pEnc->sStat.ublks++;
1188 :     }
1189 :    
1190 :     start_timer();
1191 : suxen_drol 136 MBCoding(pEnc->current, pMB, qcoeff, bs, &pEnc->sStat);
1192 : Isibaar 3 stop_coding_timer();
1193 :     }
1194 :     }
1195 :    
1196 :     emms();
1197 :    
1198 : suxen_drol 136 if (pEnc->current->global_flags & XVID_HINTEDME_GET)
1199 : h 101 {
1200 :     HintedMEGet(pEnc, 0);
1201 :     }
1202 :    
1203 : Isibaar 3 if (pEnc->sStat.iMvCount == 0)
1204 :     pEnc->sStat.iMvCount = 1;
1205 :    
1206 : edgomez 13 fSigma = (float)sqrt((float) pEnc->sStat.iMvSum / pEnc->sStat.iMvCount);
1207 : Isibaar 3
1208 : suxen_drol 136 iSearchRange = 1 << (3 + pEnc->mbParam.m_fcode);
1209 : Isibaar 3
1210 : edgomez 13 if ((fSigma > iSearchRange / 3)
1211 : suxen_drol 136 && (pEnc->mbParam.m_fcode <= 3)) // maximum search range 128
1212 : edgomez 13 {
1213 : suxen_drol 136 pEnc->mbParam.m_fcode++;
1214 : Isibaar 3 iSearchRange *= 2;
1215 : edgomez 13 }
1216 :     else if ((fSigma < iSearchRange / 6)
1217 :     && (pEnc->sStat.fMvPrevSigma >= 0)
1218 :     && (pEnc->sStat.fMvPrevSigma < iSearchRange / 6)
1219 : suxen_drol 136 && (pEnc->mbParam.m_fcode >= 2)) // minimum search range 16
1220 : edgomez 13 {
1221 : suxen_drol 136 pEnc->mbParam.m_fcode--;
1222 : Isibaar 3 iSearchRange /= 2;
1223 : edgomez 13 }
1224 : Isibaar 3
1225 : edgomez 13 pEnc->sStat.fMvPrevSigma = fSigma;
1226 : Isibaar 3
1227 :     *pBits = BitstreamPos(bs) - *pBits;
1228 :    
1229 : edgomez 13 return 0; // inter
1230 : Isibaar 3 }
1231 : suxen_drol 118
1232 :    
1233 : suxen_drol 152 #ifdef BFRAMES
1234 : suxen_drol 118 static void FrameCodeB(Encoder * pEnc, FRAMEINFO * frame, Bitstream * bs, uint32_t *pBits)
1235 :     {
1236 : suxen_drol 152 int16_t dct_codes[6*64];
1237 :     int16_t qcoeff[6*64];
1238 :     uint32_t x, y;
1239 : suxen_drol 118 VECTOR forward;
1240 :     VECTOR backward;
1241 :    
1242 : suxen_drol 152 IMAGE *f_ref = &pEnc->reference->image;
1243 : suxen_drol 118 IMAGE *b_ref = &pEnc->current->image;
1244 :    
1245 : suxen_drol 152 // forward
1246 :     image_setedges(f_ref, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height, pEnc->mbParam.width, pEnc->mbParam.height, frame->global_flags & XVID_INTERLACING);
1247 : suxen_drol 118 start_timer();
1248 :     image_interpolate(f_ref, &pEnc->f_refh, &pEnc->f_refv, &pEnc->f_refhv,
1249 : suxen_drol 152 pEnc->mbParam.edged_width, pEnc->mbParam.edged_height, 0);
1250 : suxen_drol 118 stop_inter_timer();
1251 :    
1252 : suxen_drol 152 // backward
1253 :     image_setedges(b_ref, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height, pEnc->mbParam.width, pEnc->mbParam.height, frame->global_flags & XVID_INTERLACING);
1254 :     start_timer();
1255 : suxen_drol 118 image_interpolate(b_ref, &pEnc->vInterH, &pEnc->vInterV, &pEnc->vInterHV,
1256 : suxen_drol 152 pEnc->mbParam.edged_width, pEnc->mbParam.edged_height, 0);
1257 : suxen_drol 118 stop_inter_timer();
1258 :    
1259 :     start_timer();
1260 :     MotionEstimationBVOP(&pEnc->mbParam, frame,
1261 : suxen_drol 152 pEnc->reference->mbs, f_ref, &pEnc->f_refh, &pEnc->f_refv, &pEnc->f_refhv,
1262 :     pEnc->current->mbs, b_ref, &pEnc->vInterH, &pEnc->vInterV, &pEnc->vInterHV);
1263 :    
1264 : suxen_drol 118
1265 :     stop_motion_timer();
1266 :    
1267 : suxen_drol 152 /*if (test_quant_type(&pEnc->mbParam, pEnc->current))
1268 : suxen_drol 118 {
1269 :     BitstreamWriteVolHeader(bs, pEnc->mbParam.width, pEnc->mbParam.height, pEnc->mbParam.quant_type);
1270 : suxen_drol 152 }*/
1271 : suxen_drol 118
1272 : suxen_drol 152 frame->coding_type = B_VOP;
1273 :     BitstreamWriteVopHeader(bs, &pEnc->mbParam, frame);
1274 : suxen_drol 118
1275 : suxen_drol 152 *pBits = BitstreamPos(bs);
1276 : suxen_drol 118
1277 : suxen_drol 152 pEnc->sStat.iTextBits = 0;
1278 :     pEnc->sStat.iMvSum = 0;
1279 :     pEnc->sStat.iMvCount = 0;
1280 : suxen_drol 118 pEnc->sStat.kblks = pEnc->sStat.mblks = pEnc->sStat.ublks = 0;
1281 :    
1282 :    
1283 : suxen_drol 152 for (y = 0; y < pEnc->mbParam.mb_height; y++)
1284 : suxen_drol 118 {
1285 :     // reset prediction
1286 :    
1287 :     forward.x = 0;
1288 :     forward.y = 0;
1289 :     backward.x = 0;
1290 :     backward.y = 0;
1291 :    
1292 :     for (x = 0; x < pEnc->mbParam.mb_width; x++)
1293 :     {
1294 :     MACROBLOCK * f_mb = &pEnc->reference->mbs[x + y * pEnc->mbParam.mb_width];
1295 :     MACROBLOCK * b_mb = &pEnc->current->mbs[x + y * pEnc->mbParam.mb_width];
1296 :     MACROBLOCK * mb = &frame->mbs[x + y * pEnc->mbParam.mb_width];
1297 :    
1298 :     // decoder ignores mb when refence block is INTER(0,0), CBP=0
1299 :     if (mb->mode == MODE_NOT_CODED)
1300 :     {
1301 :     mb->mvs[0].x = 0;
1302 :     mb->mvs[0].y = 0;
1303 :     continue;
1304 :     }
1305 :    
1306 :     MBMotionCompensationBVOP(&pEnc->mbParam, mb, x, y, &frame->image,
1307 : suxen_drol 152 f_ref, &pEnc->f_refh, &pEnc->f_refv, &pEnc->f_refhv,
1308 :     b_ref, &pEnc->vInterH, &pEnc->vInterV, &pEnc->vInterHV,
1309 :     dct_codes);
1310 : suxen_drol 118
1311 :     mb->quant = frame->quant;
1312 : suxen_drol 152 mb->cbp = MBTransQuantInter(&pEnc->mbParam, frame, mb, x, y, dct_codes, qcoeff);
1313 : suxen_drol 118 //mb->cbp = MBTransQuantBVOP(&pEnc->mbParam, x, y, dct_codes, qcoeff, &frame->image, frame->quant);
1314 :    
1315 :    
1316 :     if ((mb->mode == MODE_INTERPOLATE || mb->mode == MODE_DIRECT) &&
1317 : suxen_drol 152 mb->cbp == 0 &&
1318 :     mb->mvs[0].x == 0 &&
1319 :     mb->mvs[0].y == 0)
1320 : suxen_drol 118 {
1321 :     mb->mode = 5; // skipped
1322 :     }
1323 :    
1324 :     if (mb->mode == MODE_INTERPOLATE || mb->mode == MODE_FORWARD)
1325 :     {
1326 :     mb->pmvs[0].x = mb->mvs[0].x - forward.x;
1327 :     mb->pmvs[0].y = mb->mvs[0].y - forward.y;
1328 :     forward.x = mb->mvs[0].x;
1329 :     forward.y = mb->mvs[0].y;
1330 :     }
1331 :    
1332 :     if (mb->mode == MODE_INTERPOLATE || mb->mode == MODE_BACKWARD)
1333 :     {
1334 :     mb->b_pmvs[0].x = mb->b_mvs[0].x - backward.x;
1335 :     mb->b_pmvs[0].y = mb->b_mvs[0].y - backward.y;
1336 :     backward.x = mb->b_mvs[0].x;
1337 :     backward.y = mb->b_mvs[0].y;
1338 :     }
1339 :    
1340 : 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);
1341 : suxen_drol 118
1342 :     start_timer();
1343 : suxen_drol 152 MBCodingBVOP(mb, qcoeff, frame->fcode, frame->bcode, bs, &pEnc->sStat);
1344 : suxen_drol 118 stop_coding_timer();
1345 :     }
1346 :     }
1347 :    
1348 :     emms();
1349 :    
1350 :     // TODO: dynamic fcode/bcode ???
1351 :    
1352 :     *pBits = BitstreamPos(bs) - *pBits;
1353 :     }
1354 : suxen_drol 152 #endif

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