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

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