[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 136 - (view) (download)
Original Path: trunk/xvidcore/src/encoder.c

1 : suxen_drol 118 // 14.04.2002 added FrameCodeB()
2 :    
3 : Isibaar 3 #include <stdlib.h>
4 :     #include <stdio.h>
5 :     #include <math.h>
6 :    
7 :     #include "encoder.h"
8 :     #include "prediction/mbprediction.h"
9 :     #include "global.h"
10 :     #include "utils/timer.h"
11 :     #include "image/image.h"
12 :     #include "bitstream/cbp.h"
13 :     #include "utils/mbfunctions.h"
14 :     #include "bitstream/bitstream.h"
15 :     #include "bitstream/mbcoding.h"
16 :     #include "utils/ratecontrol.h"
17 :     #include "utils/emms.h"
18 :     #include "bitstream/mbcoding.h"
19 :     #include "quant/adapt_quant.h"
20 : Isibaar 4 #include "quant/quant_matrix.h"
21 : Isibaar 41 #include "utils/mem_align.h"
22 : Isibaar 3
23 :     #define ENC_CHECK(X) if(!(X)) return XVID_ERR_FORMAT
24 : suxen_drol 136 #define SWAP(A,B) { void * tmp = A; A = B; B = tmp; }
25 : Isibaar 3
26 :    
27 :     static int FrameCodeI(Encoder * pEnc, Bitstream * bs, uint32_t *pBits);
28 :     static int FrameCodeP(Encoder * pEnc, Bitstream * bs, uint32_t *pBits, bool force_inter, bool vol_header);
29 :    
30 :     static int DQtab[4] =
31 :     {
32 :     -1, -2, 1, 2
33 :     };
34 :    
35 :     static int iDQtab[5] =
36 :     {
37 :     1, 0, NO_CHANGE, 2, 3
38 :     };
39 :    
40 :    
41 : suxen_drol 136 void static image_null(IMAGE * image)
42 :     {
43 :     image->y = image->u = image->v = NULL;
44 :     }
45 :    
46 :    
47 : Isibaar 3 int encoder_create(XVID_ENC_PARAM * pParam)
48 :     {
49 : edgomez 13 Encoder *pEnc;
50 : Isibaar 3 uint32_t i;
51 :    
52 : edgomez 13 pParam->handle = NULL;
53 : Isibaar 3
54 : edgomez 13 ENC_CHECK(pParam);
55 : Isibaar 3
56 : edgomez 13 ENC_CHECK(pParam->width > 0 && pParam->width <= 1920);
57 :     ENC_CHECK(pParam->height > 0 && pParam->height <= 1280);
58 :     ENC_CHECK(!(pParam->width % 2));
59 :     ENC_CHECK(!(pParam->height % 2));
60 : Isibaar 3
61 :     if (pParam->fincr <= 0 || pParam->fbase <= 0)
62 :     {
63 :     pParam->fincr = 1;
64 :     pParam->fbase = 25;
65 :     }
66 :    
67 :     // simplify the "fincr/fbase" fraction
68 :     // (neccessary, since windows supplies us with huge numbers)
69 :    
70 :     i = pParam->fincr;
71 :     while (i > 1)
72 :     {
73 :     if (pParam->fincr % i == 0 && pParam->fbase % i == 0)
74 :     {
75 :     pParam->fincr /= i;
76 :     pParam->fbase /= i;
77 :     i = pParam->fincr;
78 :     continue;
79 :     }
80 :     i--;
81 :     }
82 :    
83 :     if (pParam->fbase > 65535)
84 :     {
85 :     float div = (float)pParam->fbase / 65535;
86 :     pParam->fbase = (int)(pParam->fbase / div);
87 :     pParam->fincr = (int)(pParam->fincr / div);
88 :     }
89 :    
90 : h 121 if (pParam->rc_bitrate <= 0)
91 :     pParam->rc_bitrate = 900000;
92 : Isibaar 3
93 : h 121 if (pParam->rc_reaction_delay_factor <= 0)
94 :     pParam->rc_reaction_delay_factor = 16;
95 : Isibaar 3
96 : h 121 if (pParam->rc_averaging_period <= 0)
97 :     pParam->rc_averaging_period = 100;
98 :    
99 :     if (pParam->rc_buffer <= 0)
100 :     pParam->rc_buffer = 100;
101 :    
102 : edgomez 13 if ((pParam->min_quantizer <= 0) || (pParam->min_quantizer > 31))
103 : Isibaar 3 pParam->min_quantizer = 1;
104 :    
105 : edgomez 13 if ((pParam->max_quantizer <= 0) || (pParam->max_quantizer > 31))
106 : Isibaar 3 pParam->max_quantizer = 31;
107 :    
108 : edgomez 13 if (pParam->max_key_interval == 0) /* 1 keyframe each 10 seconds */
109 : Isibaar 3 pParam->max_key_interval = 10 * pParam->fincr / pParam->fbase;
110 :    
111 : edgomez 13 if (pParam->max_quantizer < pParam->min_quantizer)
112 : Isibaar 3 pParam->max_quantizer = pParam->min_quantizer;
113 :    
114 : canard 66 if ((pEnc = (Encoder *) xvid_malloc(sizeof(Encoder), CACHE_LINE)) == NULL)
115 : Isibaar 3 return XVID_ERR_MEMORY;
116 :    
117 :     /* Fill members of Encoder structure */
118 :    
119 : edgomez 13 pEnc->mbParam.width = pParam->width;
120 :     pEnc->mbParam.height = pParam->height;
121 : Isibaar 3
122 :     pEnc->mbParam.mb_width = (pEnc->mbParam.width + 15) / 16;
123 :     pEnc->mbParam.mb_height = (pEnc->mbParam.height + 15) / 16;
124 :    
125 :     pEnc->mbParam.edged_width = 16 * pEnc->mbParam.mb_width + 2 * EDGE_SIZE;
126 :     pEnc->mbParam.edged_height = 16 * pEnc->mbParam.mb_height + 2 * EDGE_SIZE;
127 :    
128 : edgomez 13 pEnc->sStat.fMvPrevSigma = -1;
129 : Isibaar 3
130 :     /* Fill rate control parameters */
131 :    
132 : h 121 pEnc->bitrate = pParam->rc_bitrate;
133 : Isibaar 3
134 : edgomez 13 pEnc->iFrameNum = 0;
135 :     pEnc->iMaxKeyInterval = pParam->max_key_interval;
136 : Isibaar 3
137 : suxen_drol 136 /* try to allocate frame memory */
138 : Isibaar 3
139 : suxen_drol 136 pEnc->current = NULL;
140 :     pEnc->reference = NULL;
141 :     if ( (pEnc->current = xvid_malloc(sizeof(FRAMEINFO), CACHE_LINE)) == NULL ||
142 :     (pEnc->reference = xvid_malloc(sizeof(FRAMEINFO), CACHE_LINE)) == NULL)
143 :     {
144 :     if (pEnc->current) xvid_free(pEnc->current);
145 :     xvid_free(pEnc);
146 :     return XVID_ERR_MEMORY;
147 :     }
148 : Isibaar 3
149 : suxen_drol 136 /* try to allocate mb memory */
150 : Isibaar 3
151 : suxen_drol 136 pEnc->current->mbs = NULL;
152 :     pEnc->reference->mbs = NULL;
153 :    
154 :     OutputDebugString("malloc mbs");
155 :     if ((pEnc->current->mbs = xvid_malloc(sizeof(MACROBLOCK) * pEnc->mbParam.mb_width * pEnc->mbParam.mb_height, CACHE_LINE)) == NULL ||
156 :     (pEnc->reference->mbs = xvid_malloc(sizeof(MACROBLOCK) * pEnc->mbParam.mb_width * pEnc->mbParam.mb_height, CACHE_LINE)) == NULL)
157 :     {
158 :     if (pEnc->current->mbs) xvid_free(pEnc->current->mbs);
159 :     xvid_free(pEnc->current);
160 :     xvid_free(pEnc->reference);
161 :     xvid_free(pEnc);
162 :     }
163 :    
164 :     /* try to allocate image memory */
165 :    
166 :     #ifdef _DEBUG
167 :     image_null(&pEnc->sOriginal);
168 :     #endif
169 :     image_null(&pEnc->current->image);
170 :     image_null(&pEnc->reference->image);
171 :     image_null(&pEnc->vInterH);
172 :     image_null(&pEnc->vInterV);
173 :     image_null(&pEnc->vInterVf);
174 :     image_null(&pEnc->vInterHV);
175 :     image_null(&pEnc->vInterHVf);
176 :    
177 :    
178 :     OutputDebugString("malloc images");
179 :     if (
180 :     #ifdef _DEBUG
181 :     image_create(&pEnc->sOriginal, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0 ||
182 :     #endif
183 :     image_create(&pEnc->current->image, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0 ||
184 :     image_create(&pEnc->reference->image, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0 ||
185 : h 86 image_create(&pEnc->vInterH, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0 ||
186 :     image_create(&pEnc->vInterV, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0 ||
187 :     image_create(&pEnc->vInterVf, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0 ||
188 :     image_create(&pEnc->vInterHV, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0 ||
189 : suxen_drol 136 image_create(&pEnc->vInterHVf, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0)
190 :     {
191 : Isibaar 113 #ifdef _DEBUG
192 : suxen_drol 136 image_destroy(&pEnc->sOriginal, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);
193 : Isibaar 113 #endif
194 : suxen_drol 136 image_destroy(&pEnc->current->image, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);
195 :     image_destroy(&pEnc->reference->image, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);
196 : Isibaar 3 image_destroy(&pEnc->vInterH, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);
197 :     image_destroy(&pEnc->vInterV, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);
198 : h 86 image_destroy(&pEnc->vInterVf, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);
199 : Isibaar 3 image_destroy(&pEnc->vInterHV, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);
200 : h 86 image_destroy(&pEnc->vInterHVf, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);
201 : suxen_drol 136
202 :     xvid_free(pEnc->current);
203 :     xvid_free(pEnc->reference);
204 :     xvid_free(pEnc);
205 : Isibaar 3 return XVID_ERR_MEMORY;
206 :     }
207 :    
208 : edgomez 13 pParam->handle = (void *)pEnc;
209 : Isibaar 3
210 : h 121 if (pParam->rc_bitrate)
211 : Isibaar 3 {
212 : h 121 RateControlInit(pParam->rc_bitrate, pParam->rc_reaction_delay_factor,
213 :     pParam->rc_averaging_period, pParam->rc_buffer, pParam->fbase * 1000 / pParam->fincr,
214 :     pParam->max_quantizer, pParam->min_quantizer);
215 : Isibaar 3 }
216 :    
217 : Isibaar 36 init_timer();
218 : Isibaar 3
219 :     return XVID_ERR_OK;
220 :     }
221 :    
222 :    
223 :     int encoder_destroy(Encoder * pEnc)
224 :     {
225 : edgomez 13 ENC_CHECK(pEnc);
226 : Isibaar 3
227 : suxen_drol 136 image_destroy(&pEnc->current->image, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);
228 :     image_destroy(&pEnc->reference->image, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);
229 : edgomez 13 image_destroy(&pEnc->vInterH, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);
230 :     image_destroy(&pEnc->vInterV, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);
231 : h 87 image_destroy(&pEnc->vInterVf, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);
232 : edgomez 13 image_destroy(&pEnc->vInterHV, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);
233 : h 87 image_destroy(&pEnc->vInterHVf, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);
234 : Isibaar 113 #ifdef _DEBUG
235 :     image_destroy(&pEnc->sOriginal, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height);
236 :     #endif
237 : suxen_drol 136 xvid_free(pEnc->current->mbs);
238 :     xvid_free(pEnc->current);
239 :    
240 :     xvid_free(pEnc->reference->mbs);
241 :     xvid_free(pEnc->reference);
242 :    
243 : Isibaar 41 xvid_free(pEnc);
244 : edgomez 13 return XVID_ERR_OK;
245 : Isibaar 3 }
246 :    
247 :     int encoder_encode(Encoder * pEnc, XVID_ENC_FRAME * pFrame, XVID_ENC_STATS * pResult)
248 :     {
249 : edgomez 13 uint16_t x, y;
250 :     Bitstream bs;
251 :     uint32_t bits;
252 : Isibaar 4 uint16_t write_vol_header = 0;
253 : Isibaar 113 #ifdef _DEBUG
254 :     float psnr;
255 :     uint8_t temp[100];
256 :     #endif
257 : Isibaar 3
258 :     start_global_timer();
259 :    
260 : edgomez 13 ENC_CHECK(pEnc);
261 :     ENC_CHECK(pFrame);
262 :     ENC_CHECK(pFrame->bitstream);
263 :     ENC_CHECK(pFrame->image);
264 : Isibaar 3
265 : suxen_drol 136 SWAP(pEnc->current, pEnc->reference);
266 :    
267 :     pEnc->current->global_flags = pFrame->general;
268 :     pEnc->current->motion_flags = pFrame->motion;
269 : h 101 pEnc->mbParam.hint = &pFrame->hint;
270 : Isibaar 3
271 :     start_timer();
272 : suxen_drol 136 if (image_input(&pEnc->current->image, pEnc->mbParam.width, pEnc->mbParam.height, pEnc->mbParam.edged_width,
273 : edgomez 13 pFrame->image, pFrame->colorspace))
274 : Isibaar 3 {
275 :     return XVID_ERR_FORMAT;
276 :     }
277 :     stop_conv_timer();
278 :    
279 : Isibaar 113 #ifdef _DEBUG
280 :     image_copy(&pEnc->sOriginal, &pEnc->sCurrent, pEnc->mbParam.edged_width, pEnc->mbParam.height);
281 :     #endif
282 :    
283 : suxen_drol 136 EMMS();
284 :    
285 : edgomez 13 BitstreamInit(&bs, pFrame->bitstream, 0);
286 : Isibaar 3
287 :     if (pFrame->quant == 0)
288 :     {
289 : suxen_drol 136 pEnc->current->quant = RateControlGetQ(0);
290 : Isibaar 3 }
291 :     else
292 :     {
293 : suxen_drol 136 pEnc->current->quant = pFrame->quant;
294 : Isibaar 3 }
295 :    
296 : suxen_drol 136 if ((pEnc->current->global_flags & XVID_LUMIMASKING))
297 : Isibaar 3 {
298 : canard 66 int * temp_dquants = (int *) xvid_malloc(pEnc->mbParam.mb_width * pEnc->mbParam.mb_height * sizeof(int), CACHE_LINE);
299 : Isibaar 3
300 : suxen_drol 136 pEnc->current->quant = adaptive_quantization(pEnc->current->image.y,
301 :     pEnc->mbParam.edged_width, // stride
302 : edgomez 78 temp_dquants,
303 : suxen_drol 136 pEnc->current->quant,
304 :     pEnc->current->quant, // min_quant
305 :     2*pEnc->current->quant, // max_quant
306 : edgomez 78 pEnc->mbParam.mb_width,
307 :     pEnc->mbParam.mb_height);
308 : Isibaar 3
309 :     for (y = 0; y < pEnc->mbParam.mb_height; y++)
310 :     for (x = 0; x < pEnc->mbParam.mb_width; x++)
311 :     {
312 : suxen_drol 136 MACROBLOCK *pMB = &pEnc->current->mbs[x + y * pEnc->mbParam.mb_width];
313 : Isibaar 3 pMB->dquant = iDQtab[(temp_dquants[y * pEnc->mbParam.mb_width + x] + 2)];
314 :     }
315 : Isibaar 41 xvid_free(temp_dquants);
316 : Isibaar 3 }
317 :    
318 : suxen_drol 136 if (pEnc->current->global_flags & XVID_H263QUANT) {
319 :     if(pEnc->mbParam.m_quant_type != H263_QUANT)
320 : Isibaar 20 write_vol_header = 1;
321 : suxen_drol 136 pEnc->mbParam.m_quant_type = H263_QUANT;
322 : Isibaar 3 }
323 : suxen_drol 136 else if(pEnc->current->global_flags & XVID_MPEGQUANT) {
324 : Isibaar 20 int ret1, ret2;
325 : Isibaar 3
326 : edgomez 78 ret1 = ret2 = 0;
327 :    
328 : suxen_drol 136 if(pEnc->mbParam.m_quant_type != MPEG4_QUANT)
329 : Isibaar 20 write_vol_header = 1;
330 :    
331 : suxen_drol 136 pEnc->mbParam.m_quant_type = MPEG4_QUANT;
332 : Isibaar 20
333 : suxen_drol 136 if ((pEnc->current->global_flags & XVID_CUSTOM_QMATRIX) > 0) {
334 : Isibaar 20 if(pFrame->quant_intra_matrix != NULL)
335 :     ret1 = set_intra_matrix(pFrame->quant_intra_matrix);
336 :     if(pFrame->quant_inter_matrix != NULL)
337 :     ret2 = set_inter_matrix(pFrame->quant_inter_matrix);
338 :     }
339 :     else {
340 :     ret1 = set_intra_matrix(get_default_intra_matrix());
341 :     ret2 = set_inter_matrix(get_default_inter_matrix());
342 :     }
343 : Isibaar 4 if(write_vol_header == 0)
344 :     write_vol_header = ret1 | ret2;
345 :     }
346 : Isibaar 3
347 :     if (pFrame->intra < 0)
348 : edgomez 13 {
349 : Isibaar 3 if ((pEnc->iFrameNum == 0) || ((pEnc->iMaxKeyInterval > 0)
350 : edgomez 13 && (pEnc->iFrameNum >= pEnc->iMaxKeyInterval)))
351 : Isibaar 3
352 :     pFrame->intra = FrameCodeI(pEnc, &bs, &bits);
353 :     else
354 : Isibaar 4 pFrame->intra = FrameCodeP(pEnc, &bs, &bits, 0, write_vol_header);
355 : edgomez 13 }
356 :     else
357 :     {
358 : Isibaar 3 if (pFrame->intra == 1)
359 : edgomez 13 pFrame->intra = FrameCodeI(pEnc, &bs, &bits);
360 : Isibaar 3 else
361 : Isibaar 4 pFrame->intra = FrameCodeP(pEnc, &bs, &bits, 1, write_vol_header);
362 : edgomez 13 }
363 : Isibaar 3
364 :     BitstreamPutBits(&bs, 0xFFFF, 16);
365 : edgomez 13 BitstreamPutBits(&bs, 0xFFFF, 16);
366 :     BitstreamPad(&bs);
367 :     pFrame->length = BitstreamLength(&bs);
368 : h 29
369 : Isibaar 3 if (pResult)
370 : edgomez 13 {
371 : suxen_drol 136 pResult->quant = pEnc->current->quant;
372 : Isibaar 3 pResult->hlength = pFrame->length - (pEnc->sStat.iTextBits / 8);
373 :     pResult->kblks = pEnc->sStat.kblks;
374 :     pResult->mblks = pEnc->sStat.mblks;
375 :     pResult->ublks = pEnc->sStat.ublks;
376 : edgomez 13 }
377 : Isibaar 3
378 : Isibaar 41 EMMS();
379 :    
380 : h 29 if (pFrame->quant == 0)
381 : Isibaar 3 {
382 : suxen_drol 136 RateControlUpdate(pEnc->current->quant, pFrame->length, pFrame->intra);
383 : Isibaar 3 }
384 :    
385 : Isibaar 113 #ifdef _DEBUG
386 : suxen_drol 136 psnr = image_psnr(&pEnc->sOriginal, &pEnc->current->image, pEnc->mbParam.edged_width,
387 : Isibaar 113 pEnc->mbParam.width, pEnc->mbParam.height);
388 :    
389 :     sprintf(temp, "PSNR: %f\n", psnr);
390 :     DEBUG(temp);
391 :     #endif
392 :    
393 : Isibaar 3 pEnc->iFrameNum++;
394 :    
395 :     stop_global_timer();
396 :     write_timer();
397 :    
398 :     return XVID_ERR_OK;
399 :     }
400 :    
401 :    
402 :     static __inline void CodeIntraMB(Encoder *pEnc, MACROBLOCK *pMB) {
403 :    
404 :     pMB->mode = MODE_INTRA;
405 :    
406 : suxen_drol 136 /* zero mv statistics */
407 :     pMB->mvs[0].x = pMB->mvs[1].x = pMB->mvs[2].x = pMB->mvs[3].x = 0;
408 :     pMB->mvs[0].y = pMB->mvs[1].y = pMB->mvs[2].y = pMB->mvs[3].y = 0;
409 :     pMB->sad8[0] = pMB->sad8[1] = pMB->sad8[2] = pMB->sad8[3] = 0;
410 :     pMB->sad16 = 0;
411 :    
412 :     if ((pEnc->current->global_flags & XVID_LUMIMASKING)) {
413 : Isibaar 3 if(pMB->dquant != NO_CHANGE)
414 :     {
415 :     pMB->mode = MODE_INTRA_Q;
416 : suxen_drol 136 pEnc->current->quant += DQtab[pMB->dquant];
417 : Isibaar 3
418 : suxen_drol 136 if (pEnc->current->quant > 31) pEnc->current->quant = 31;
419 :     if (pEnc->current->quant < 1) pEnc->current->quant = 1;
420 : Isibaar 3 }
421 :     }
422 :    
423 : suxen_drol 136 pMB->quant = pEnc->current->quant;
424 : Isibaar 3 }
425 :    
426 :    
427 : h 101 #define FCODEBITS 3
428 :     #define MODEBITS 5
429 :    
430 :     void HintedMESet(Encoder * pEnc, int * intra)
431 :     {
432 :     HINTINFO * hint;
433 :     Bitstream bs;
434 :     int length, high;
435 :     uint32_t x, y;
436 :    
437 :     hint = pEnc->mbParam.hint;
438 :    
439 :     if (hint->rawhints)
440 :     {
441 :     *intra = hint->mvhint.intra;
442 :     }
443 :     else
444 :     {
445 :     BitstreamInit(&bs, hint->hintstream, hint->hintlength);
446 :     *intra = BitstreamGetBit(&bs);
447 :     }
448 :    
449 :     if (*intra)
450 :     {
451 :     return;
452 :     }
453 :    
454 : suxen_drol 136 pEnc->current->fcode = (hint->rawhints) ? hint->mvhint.fcode : BitstreamGetBits(&bs, FCODEBITS);
455 : h 101
456 : suxen_drol 136 length = pEnc->current->fcode + 5;
457 : h 101 high = 1 << (length - 1);
458 :    
459 :     for (y=0 ; y<pEnc->mbParam.mb_height ; ++y)
460 :     {
461 :     for (x=0 ; x<pEnc->mbParam.mb_width ; ++x)
462 :     {
463 : suxen_drol 136 MACROBLOCK * pMB = &pEnc->current->mbs[x + y * pEnc->mbParam.mb_width];
464 : h 101 MVBLOCKHINT * bhint = &hint->mvhint.block[x + y * pEnc->mbParam.mb_width];
465 :     VECTOR pred[4];
466 :     VECTOR tmp;
467 :     int dummy[4];
468 :     int vec;
469 :    
470 :     pMB->mode = (hint->rawhints) ? bhint->mode : BitstreamGetBits(&bs, MODEBITS);
471 :    
472 : h 128 pMB->mode = (pMB->mode == MODE_INTER_Q) ? MODE_INTER : pMB->mode;
473 :     pMB->mode = (pMB->mode == MODE_INTRA_Q) ? MODE_INTRA : pMB->mode;
474 :    
475 :     if (pMB->mode == MODE_INTER)
476 : h 101 {
477 :     tmp.x = (hint->rawhints) ? bhint->mvs[0].x : BitstreamGetBits(&bs, length);
478 :     tmp.y = (hint->rawhints) ? bhint->mvs[0].y : BitstreamGetBits(&bs, length);
479 :     tmp.x -= (tmp.x >= high) ? high*2 : 0;
480 :     tmp.y -= (tmp.y >= high) ? high*2 : 0;
481 :    
482 : suxen_drol 136 get_pmvdata(pEnc->current->mbs, x, y, pEnc->mbParam.mb_width, 0, pred, dummy);
483 : h 101
484 :     for (vec=0 ; vec<4 ; ++vec)
485 :     {
486 :     pMB->mvs[vec].x = tmp.x;
487 :     pMB->mvs[vec].y = tmp.y;
488 :     pMB->pmvs[vec].x = pMB->mvs[0].x - pred[0].x;
489 :     pMB->pmvs[vec].y = pMB->mvs[0].y - pred[0].y;
490 :     }
491 :     }
492 :     else if (pMB->mode == MODE_INTER4V)
493 :     {
494 :     for (vec=0 ; vec<4 ; ++vec)
495 :     {
496 :     tmp.x = (hint->rawhints) ? bhint->mvs[vec].x : BitstreamGetBits(&bs, length);
497 :     tmp.y = (hint->rawhints) ? bhint->mvs[vec].y : BitstreamGetBits(&bs, length);
498 :     tmp.x -= (tmp.x >= high) ? high*2 : 0;
499 :     tmp.y -= (tmp.y >= high) ? high*2 : 0;
500 :    
501 : suxen_drol 136 get_pmvdata(pEnc->current->mbs, x, y, pEnc->mbParam.mb_width, vec, pred, dummy);
502 : h 101
503 :     pMB->mvs[vec].x = tmp.x;
504 :     pMB->mvs[vec].y = tmp.y;
505 :     pMB->pmvs[vec].x = pMB->mvs[vec].x - pred[0].x;
506 :     pMB->pmvs[vec].y = pMB->mvs[vec].y - pred[0].y;
507 :     }
508 :     }
509 : h 128 else // intra / stuffing / not_coded
510 : h 101 {
511 :     for (vec=0 ; vec<4 ; ++vec)
512 :     {
513 :     pMB->mvs[vec].x = pMB->mvs[vec].y = 0;
514 :     }
515 :     }
516 : h 128
517 : suxen_drol 136 if (pMB->mode == MODE_INTER4V &&
518 :     (pEnc->current->global_flags & XVID_LUMIMASKING) && pMB->dquant != NO_CHANGE)
519 : h 128 {
520 :     pMB->mode = MODE_INTRA;
521 :    
522 :     for (vec=0 ; vec<4 ; ++vec)
523 :     {
524 :     pMB->mvs[vec].x = pMB->mvs[vec].y = 0;
525 :     }
526 :     }
527 : h 101 }
528 :     }
529 :     }
530 :    
531 :    
532 :     void HintedMEGet(Encoder * pEnc, int intra)
533 :     {
534 :     HINTINFO * hint;
535 :     Bitstream bs;
536 :     uint32_t x, y;
537 :     int length, high;
538 :    
539 :     hint = pEnc->mbParam.hint;
540 :    
541 :     if (hint->rawhints)
542 :     {
543 :     hint->mvhint.intra = intra;
544 :     }
545 :     else
546 :     {
547 :     BitstreamInit(&bs, hint->hintstream, 0);
548 :     BitstreamPutBit(&bs, intra);
549 :     }
550 :    
551 :     if (intra)
552 :     {
553 :     if (!hint->rawhints)
554 :     {
555 :     BitstreamPad(&bs);
556 :     hint->hintlength = BitstreamLength(&bs);
557 :     }
558 :     return;
559 :     }
560 :    
561 : suxen_drol 136 length = pEnc->current->fcode + 5;
562 : h 101 high = 1 << (length - 1);
563 :    
564 :     if (hint->rawhints)
565 :     {
566 : suxen_drol 136 hint->mvhint.fcode = pEnc->current->fcode;
567 : h 101 }
568 :     else
569 :     {
570 : suxen_drol 136 BitstreamPutBits(&bs, pEnc->current->fcode, FCODEBITS);
571 : h 101 }
572 :    
573 :     for (y=0 ; y<pEnc->mbParam.mb_height ; ++y)
574 :     {
575 :     for (x=0 ; x<pEnc->mbParam.mb_width ; ++x)
576 :     {
577 : suxen_drol 136 MACROBLOCK * pMB = &pEnc->current->mbs[x + y * pEnc->mbParam.mb_width];
578 : h 101 MVBLOCKHINT * bhint = &hint->mvhint.block[x + y * pEnc->mbParam.mb_width];
579 :     VECTOR tmp;
580 :    
581 :     if (hint->rawhints)
582 :     {
583 :     bhint->mode = pMB->mode;
584 :     }
585 :     else
586 :     {
587 :     BitstreamPutBits(&bs, pMB->mode, MODEBITS);
588 :     }
589 :    
590 :     if (pMB->mode == MODE_INTER || pMB->mode == MODE_INTER_Q)
591 :     {
592 :     tmp.x = pMB->mvs[0].x;
593 :     tmp.y = pMB->mvs[0].y;
594 :     tmp.x += (tmp.x < 0) ? high*2 : 0;
595 :     tmp.y += (tmp.y < 0) ? high*2 : 0;
596 :    
597 :     if (hint->rawhints)
598 :     {
599 :     bhint->mvs[0].x = tmp.x;
600 :     bhint->mvs[0].y = tmp.y;
601 :     }
602 :     else
603 :     {
604 :     BitstreamPutBits(&bs, tmp.x, length);
605 :     BitstreamPutBits(&bs, tmp.y, length);
606 :     }
607 :     }
608 :     else if (pMB->mode == MODE_INTER4V)
609 :     {
610 :     int vec;
611 :    
612 :     for (vec=0 ; vec<4 ; ++vec)
613 :     {
614 :     tmp.x = pMB->mvs[vec].x;
615 :     tmp.y = pMB->mvs[vec].y;
616 :     tmp.x += (tmp.x < 0) ? high*2 : 0;
617 :     tmp.y += (tmp.y < 0) ? high*2 : 0;
618 :    
619 :     if (hint->rawhints)
620 :     {
621 :     bhint->mvs[vec].x = tmp.x;
622 :     bhint->mvs[vec].y = tmp.y;
623 :     }
624 :     else
625 :     {
626 :     BitstreamPutBits(&bs, tmp.x, length);
627 :     BitstreamPutBits(&bs, tmp.y, length);
628 :     }
629 :     }
630 :     }
631 :     }
632 :     }
633 :    
634 :     if (!hint->rawhints)
635 :     {
636 :     BitstreamPad(&bs);
637 :     hint->hintlength = BitstreamLength(&bs);
638 :     }
639 :     }
640 :    
641 :    
642 : h 104 static int FrameCodeI(Encoder * pEnc, Bitstream * bs, uint32_t *pBits)
643 :     {
644 :    
645 :     DECLARE_ALIGNED_MATRIX(dct_codes, 6, 64, int16_t, CACHE_LINE);
646 :     DECLARE_ALIGNED_MATRIX(qcoeff, 6, 64, int16_t, CACHE_LINE);
647 :    
648 :     uint16_t x, y;
649 :    
650 :     pEnc->iFrameNum = 0;
651 : suxen_drol 136 pEnc->mbParam.m_rounding_type = 1;
652 :     pEnc->current->rounding_type = pEnc->mbParam.m_rounding_type;
653 :     pEnc->current->coding_type = I_VOP;
654 : h 104
655 : suxen_drol 136 BitstreamWriteVolHeader(bs, &pEnc->mbParam, pEnc->current);
656 :     BitstreamWriteVopHeader(bs, &pEnc->mbParam, pEnc->current);
657 : h 104
658 :     *pBits = BitstreamPos(bs);
659 :    
660 :     pEnc->sStat.iTextBits = 0;
661 :     pEnc->sStat.kblks = pEnc->mbParam.mb_width * pEnc->mbParam.mb_height;
662 :     pEnc->sStat.mblks = pEnc->sStat.ublks = 0;
663 :    
664 :     for (y = 0; y < pEnc->mbParam.mb_height; y++)
665 :     for (x = 0; x < pEnc->mbParam.mb_width; x++)
666 :     {
667 : suxen_drol 136 MACROBLOCK *pMB = &pEnc->current->mbs[x + y * pEnc->mbParam.mb_width];
668 : h 104
669 :     CodeIntraMB(pEnc, pMB);
670 :    
671 : suxen_drol 136 MBTransQuantIntra(&pEnc->mbParam, pEnc->current, pMB, x, y, dct_codes, qcoeff);
672 : h 104
673 :     start_timer();
674 : suxen_drol 136 MBPrediction(pEnc->current, x, y, pEnc->mbParam.mb_width, qcoeff);
675 : h 104 stop_prediction_timer();
676 :    
677 :     start_timer();
678 : suxen_drol 136 MBCoding(pEnc->current, pMB, qcoeff, bs, &pEnc->sStat);
679 : h 104 stop_coding_timer();
680 :     }
681 :    
682 :     emms();
683 :    
684 :     *pBits = BitstreamPos(bs) - *pBits;
685 :     pEnc->sStat.fMvPrevSigma = -1;
686 :     pEnc->sStat.iMvSum = 0;
687 :     pEnc->sStat.iMvCount = 0;
688 : suxen_drol 136 pEnc->mbParam.m_fcode = 2;
689 : h 104
690 : suxen_drol 136 if (pEnc->current->global_flags & XVID_HINTEDME_GET)
691 : h 104 {
692 :     HintedMEGet(pEnc, 1);
693 :     }
694 :    
695 :     return 1; // intra
696 :     }
697 :    
698 :    
699 : Isibaar 3 #define INTRA_THRESHOLD 0.5
700 :    
701 :     static int FrameCodeP(Encoder * pEnc, Bitstream * bs, uint32_t *pBits, bool force_inter, bool vol_header)
702 :     {
703 : edgomez 13 float fSigma;
704 : Isibaar 42
705 : edgomez 78 DECLARE_ALIGNED_MATRIX(dct_codes, 6, 64, int16_t, CACHE_LINE);
706 :     DECLARE_ALIGNED_MATRIX(qcoeff, 6, 64, int16_t, CACHE_LINE);
707 :    
708 : Isibaar 3 int iLimit;
709 : edgomez 13 uint32_t x, y;
710 :     int iSearchRange;
711 : Isibaar 3 bool bIntra;
712 :    
713 : suxen_drol 136 IMAGE *pCurrent = &pEnc->current->image;
714 :     IMAGE *pRef = &pEnc->reference->image;
715 : Isibaar 3
716 : h 69 start_timer();
717 : edgomez 78 image_setedges(pRef,
718 : h 85 pEnc->mbParam.edged_width,
719 :     pEnc->mbParam.edged_height,
720 :     pEnc->mbParam.width,
721 :     pEnc->mbParam.height,
722 : suxen_drol 136 pEnc->current->global_flags & XVID_INTERLACING);
723 : h 69 stop_edges_timer();
724 : Isibaar 3
725 : suxen_drol 136 pEnc->mbParam.m_rounding_type = 1 - pEnc->mbParam.m_rounding_type;
726 :     pEnc->current->rounding_type = pEnc->mbParam.m_rounding_type;
727 :     pEnc->current->fcode = pEnc->mbParam.m_fcode;
728 : Isibaar 3
729 :     if (!force_inter)
730 :     iLimit = (int)(pEnc->mbParam.mb_width * pEnc->mbParam.mb_height * INTRA_THRESHOLD);
731 : edgomez 13 else
732 : Isibaar 3 iLimit = pEnc->mbParam.mb_width * pEnc->mbParam.mb_height + 1;
733 :    
734 : suxen_drol 136 if ((pEnc->current->global_flags & XVID_HALFPEL)) {
735 : Isibaar 3 start_timer();
736 : h 85 image_interpolate(pRef, &pEnc->vInterH, &pEnc->vInterV, &pEnc->vInterHV,
737 :     pEnc->mbParam.edged_width, pEnc->mbParam.edged_height,
738 : suxen_drol 136 pEnc->current->rounding_type);
739 : Isibaar 3 stop_inter_timer();
740 :     }
741 :    
742 :     start_timer();
743 : suxen_drol 136 if (pEnc->current->global_flags & XVID_HINTEDME_SET)
744 : h 101 {
745 :     HintedMESet(pEnc, &bIntra);
746 :     }
747 :     else
748 :     {
749 : suxen_drol 136 bIntra = MotionEstimation(
750 :     &pEnc->mbParam,
751 :     pEnc->current,
752 :     pEnc->reference,
753 :     &pEnc->vInterH,
754 :     &pEnc->vInterV,
755 :     &pEnc->vInterHV,
756 :     iLimit);
757 : h 101 }
758 : Isibaar 3 stop_motion_timer();
759 :    
760 :     if (bIntra == 1)
761 : h 101 {
762 : Isibaar 3 return FrameCodeI(pEnc, bs, pBits);
763 : h 101 }
764 : Isibaar 3
765 : suxen_drol 136 pEnc->current->coding_type = P_VOP;
766 : Isibaar 3
767 :     if(vol_header)
768 : suxen_drol 136 BitstreamWriteVolHeader(bs, &pEnc->mbParam, pEnc->current);
769 : Isibaar 3
770 : suxen_drol 136 BitstreamWriteVopHeader(bs, &pEnc->mbParam, pEnc->current);
771 : Isibaar 3
772 : edgomez 13 *pBits = BitstreamPos(bs);
773 : Isibaar 3
774 : edgomez 13 pEnc->sStat.iTextBits = 0;
775 :     pEnc->sStat.iMvSum = 0;
776 :     pEnc->sStat.iMvCount = 0;
777 : Isibaar 3 pEnc->sStat.kblks = pEnc->sStat.mblks = pEnc->sStat.ublks = 0;
778 :    
779 : edgomez 13 for(y = 0; y < pEnc->mbParam.mb_height; y++)
780 : Isibaar 3 {
781 :     for(x = 0; x < pEnc->mbParam.mb_width; x++)
782 :     {
783 : suxen_drol 136 MACROBLOCK * pMB = &pEnc->current->mbs[x + y * pEnc->mbParam.mb_width];
784 : Isibaar 3
785 : edgomez 13 bIntra = (pMB->mode == MODE_INTRA) || (pMB->mode == MODE_INTRA_Q);
786 : Isibaar 3
787 :     if (!bIntra)
788 : edgomez 13 {
789 : Isibaar 3 start_timer();
790 : edgomez 78 MBMotionCompensation(pMB,
791 :     x, y,
792 : suxen_drol 136 &pEnc->reference->image,
793 : edgomez 78 &pEnc->vInterH,
794 : h 85 &pEnc->vInterV,
795 :     &pEnc->vInterHV,
796 : suxen_drol 136 &pEnc->current->image,
797 : edgomez 78 dct_codes,
798 : edgomez 13 pEnc->mbParam.width,
799 :     pEnc->mbParam.height,
800 :     pEnc->mbParam.edged_width,
801 : suxen_drol 136 pEnc->current->rounding_type);
802 : Isibaar 3 stop_comp_timer();
803 :    
804 : suxen_drol 136 if ((pEnc->current->global_flags & XVID_LUMIMASKING)) {
805 : Isibaar 3 if(pMB->dquant != NO_CHANGE) {
806 :     pMB->mode = MODE_INTER_Q;
807 : suxen_drol 136 pEnc->current->quant += DQtab[pMB->dquant];
808 :     if (pEnc->current->quant > 31) pEnc->current->quant = 31;
809 :     else if(pEnc->current->quant < 1) pEnc->current->quant = 1;
810 : Isibaar 3 }
811 :     }
812 : suxen_drol 136 pMB->quant = pEnc->current->quant;
813 : Isibaar 3
814 : h 69 pMB->field_pred = 0;
815 :    
816 : suxen_drol 136 pMB->cbp = MBTransQuantInter(&pEnc->mbParam, pEnc->current, pMB, x, y, dct_codes, qcoeff);
817 : edgomez 13 }
818 : Isibaar 3 else
819 :     {
820 :     CodeIntraMB(pEnc, pMB);
821 : suxen_drol 136 MBTransQuantIntra(&pEnc->mbParam, pEnc->current, pMB, x, y, dct_codes, qcoeff);
822 : Isibaar 3 }
823 :    
824 : edgomez 13 start_timer();
825 : suxen_drol 136 MBPrediction(pEnc->current, x, y, pEnc->mbParam.mb_width, qcoeff);
826 : Isibaar 3 stop_prediction_timer();
827 :    
828 :     if (pMB->mode == MODE_INTRA || pMB->mode == MODE_INTRA_Q)
829 :     {
830 :     pEnc->sStat.kblks++;
831 :     }
832 :     else if (pMB->cbp ||
833 : edgomez 13 pMB->mvs[0].x || pMB->mvs[0].y ||
834 :     pMB->mvs[1].x || pMB->mvs[1].y ||
835 :     pMB->mvs[2].x || pMB->mvs[2].y ||
836 :     pMB->mvs[3].x || pMB->mvs[3].y)
837 : Isibaar 3 {
838 :     pEnc->sStat.mblks++;
839 :     }
840 :     else
841 :     {
842 :     pEnc->sStat.ublks++;
843 :     }
844 :    
845 :     start_timer();
846 : suxen_drol 136 MBCoding(pEnc->current, pMB, qcoeff, bs, &pEnc->sStat);
847 : Isibaar 3 stop_coding_timer();
848 :     }
849 :     }
850 :    
851 :     emms();
852 :    
853 : suxen_drol 136 if (pEnc->current->global_flags & XVID_HINTEDME_GET)
854 : h 101 {
855 :     HintedMEGet(pEnc, 0);
856 :     }
857 :    
858 : Isibaar 3 if (pEnc->sStat.iMvCount == 0)
859 :     pEnc->sStat.iMvCount = 1;
860 :    
861 : edgomez 13 fSigma = (float)sqrt((float) pEnc->sStat.iMvSum / pEnc->sStat.iMvCount);
862 : Isibaar 3
863 : suxen_drol 136 iSearchRange = 1 << (3 + pEnc->mbParam.m_fcode);
864 : Isibaar 3
865 : edgomez 13 if ((fSigma > iSearchRange / 3)
866 : suxen_drol 136 && (pEnc->mbParam.m_fcode <= 3)) // maximum search range 128
867 : edgomez 13 {
868 : suxen_drol 136 pEnc->mbParam.m_fcode++;
869 : Isibaar 3 iSearchRange *= 2;
870 : edgomez 13 }
871 :     else if ((fSigma < iSearchRange / 6)
872 :     && (pEnc->sStat.fMvPrevSigma >= 0)
873 :     && (pEnc->sStat.fMvPrevSigma < iSearchRange / 6)
874 : suxen_drol 136 && (pEnc->mbParam.m_fcode >= 2)) // minimum search range 16
875 : edgomez 13 {
876 : suxen_drol 136 pEnc->mbParam.m_fcode--;
877 : Isibaar 3 iSearchRange /= 2;
878 : edgomez 13 }
879 : Isibaar 3
880 : edgomez 13 pEnc->sStat.fMvPrevSigma = fSigma;
881 : Isibaar 3
882 :     *pBits = BitstreamPos(bs) - *pBits;
883 :    
884 : edgomez 13 return 0; // inter
885 : Isibaar 3 }
886 : suxen_drol 118
887 :    
888 :    
889 :     /*
890 :     static void FrameCodeB(Encoder * pEnc, FRAMEINFO * frame, Bitstream * bs, uint32_t *pBits)
891 :     {
892 :     int16_t dct_codes[6][64];
893 :     int16_t qcoeff[6][64];
894 :     uint32_t x, y;
895 :     VECTOR forward;
896 :     VECTOR backward;
897 :    
898 :     IMAGE *f_ref = &pEnc->reference->image;
899 :     IMAGE *b_ref = &pEnc->current->image;
900 :    
901 :     // forward
902 :     image_setedges(f_ref, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height, pEnc->mbParam.width, pEnc->mbParam.height);
903 :     start_timer();
904 :     image_interpolate(f_ref, &pEnc->f_refh, &pEnc->f_refv, &pEnc->f_refhv,
905 :     pEnc->mbParam.edged_width, pEnc->mbParam.edged_height, 0);
906 :     stop_inter_timer();
907 :    
908 :     // backward
909 :     image_setedges(b_ref, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height, pEnc->mbParam.width, pEnc->mbParam.height);
910 :     start_timer();
911 :     image_interpolate(b_ref, &pEnc->vInterH, &pEnc->vInterV, &pEnc->vInterHV,
912 :     pEnc->mbParam.edged_width, pEnc->mbParam.edged_height, 0);
913 :     stop_inter_timer();
914 :    
915 :     start_timer();
916 :     MotionEstimationBVOP(&pEnc->mbParam, frame,
917 :     pEnc->reference->mbs, f_ref, &pEnc->f_refh, &pEnc->f_refv, &pEnc->f_refhv,
918 :     pEnc->current->mbs, b_ref, &pEnc->vInterH, &pEnc->vInterV, &pEnc->vInterHV);
919 :    
920 :     stop_motion_timer();
921 :    
922 :     if (test_quant_type(&pEnc->mbParam, pEnc->current))
923 :     {
924 :     BitstreamWriteVolHeader(bs, pEnc->mbParam.width, pEnc->mbParam.height, pEnc->mbParam.quant_type);
925 :     }
926 :    
927 :     frame->coding_type = B_VOP;
928 :     BitstreamWriteVopHeader(bs, B_VOP, frame->tick, 0,
929 :     frame->quant, frame->fcode, frame->bcode);
930 :    
931 :     *pBits = BitstreamPos(bs);
932 :    
933 :     pEnc->sStat.iTextBits = 0;
934 :     pEnc->sStat.iMvSum = 0;
935 :     pEnc->sStat.iMvCount = 0;
936 :     pEnc->sStat.kblks = pEnc->sStat.mblks = pEnc->sStat.ublks = 0;
937 :    
938 :    
939 :     for (y = 0; y < pEnc->mbParam.mb_height; y++)
940 :     {
941 :     // reset prediction
942 :    
943 :     forward.x = 0;
944 :     forward.y = 0;
945 :     backward.x = 0;
946 :     backward.y = 0;
947 :    
948 :     for (x = 0; x < pEnc->mbParam.mb_width; x++)
949 :     {
950 :     MACROBLOCK * f_mb = &pEnc->reference->mbs[x + y * pEnc->mbParam.mb_width];
951 :     MACROBLOCK * b_mb = &pEnc->current->mbs[x + y * pEnc->mbParam.mb_width];
952 :     MACROBLOCK * mb = &frame->mbs[x + y * pEnc->mbParam.mb_width];
953 :    
954 :     // decoder ignores mb when refence block is INTER(0,0), CBP=0
955 :     if (mb->mode == MODE_NOT_CODED)
956 :     {
957 :     mb->mvs[0].x = 0;
958 :     mb->mvs[0].y = 0;
959 :     continue;
960 :     }
961 :    
962 :     MBMotionCompensationBVOP(&pEnc->mbParam, mb, x, y, &frame->image,
963 :     f_ref, &pEnc->f_refh, &pEnc->f_refv, &pEnc->f_refhv,
964 :     b_ref, &pEnc->vInterH, &pEnc->vInterV, &pEnc->vInterHV,
965 :     dct_codes);
966 :    
967 :     mb->quant = frame->quant;
968 :     mb->cbp = MBTransQuantInter(&pEnc->mbParam, frame, x, y, dct_codes, qcoeff);
969 :     //mb->cbp = MBTransQuantBVOP(&pEnc->mbParam, x, y, dct_codes, qcoeff, &frame->image, frame->quant);
970 :    
971 :    
972 :     if ((mb->mode == MODE_INTERPOLATE || mb->mode == MODE_DIRECT) &&
973 :     mb->cbp == 0 &&
974 :     mb->mvs[0].x == 0 &&
975 :     mb->mvs[0].y == 0)
976 :     {
977 :     mb->mode = 5; // skipped
978 :     }
979 :    
980 :     if (mb->mode == MODE_INTERPOLATE || mb->mode == MODE_FORWARD)
981 :     {
982 :     mb->pmvs[0].x = mb->mvs[0].x - forward.x;
983 :     mb->pmvs[0].y = mb->mvs[0].y - forward.y;
984 :     forward.x = mb->mvs[0].x;
985 :     forward.y = mb->mvs[0].y;
986 :     }
987 :    
988 :     if (mb->mode == MODE_INTERPOLATE || mb->mode == MODE_BACKWARD)
989 :     {
990 :     mb->b_pmvs[0].x = mb->b_mvs[0].x - backward.x;
991 :     mb->b_pmvs[0].y = mb->b_mvs[0].y - backward.y;
992 :     backward.x = mb->b_mvs[0].x;
993 :     backward.y = mb->b_mvs[0].y;
994 :     }
995 :    
996 :     // 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);
997 :    
998 :     start_timer();
999 :     MBCodingBVOP(frame, mb, qcoeff, bs, &pEnc->sStat);
1000 :     stop_coding_timer();
1001 :     }
1002 :     }
1003 :    
1004 :     emms();
1005 :    
1006 :     // TODO: dynamic fcode/bcode ???
1007 :    
1008 :     *pBits = BitstreamPos(bs) - *pBits;
1009 :    
1010 :     }
1011 :    
1012 :     */

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