1 |
#include <stdlib.h> |
2 |
#include <stdio.h> |
3 |
#include <math.h> |
4 |
|
5 |
#include "encoder.h" |
6 |
#include "prediction/mbprediction.h" |
7 |
#include "global.h" |
8 |
#include "utils/timer.h" |
9 |
#include "image/image.h" |
10 |
#include "bitstream/cbp.h" |
11 |
#include "utils/mbfunctions.h" |
12 |
#include "bitstream/bitstream.h" |
13 |
#include "bitstream/mbcoding.h" |
14 |
#include "utils/ratecontrol.h" |
15 |
#include "utils/emms.h" |
16 |
#include "bitstream/mbcoding.h" |
17 |
#include "quant/adapt_quant.h" |
18 |
#include "quant/quant_matrix.h" |
19 |
#include "utils/mem_align.h" |
20 |
|
21 |
#define ENC_CHECK(X) if(!(X)) return XVID_ERR_FORMAT |
22 |
|
23 |
|
24 |
static int FrameCodeI(Encoder * pEnc, Bitstream * bs, uint32_t *pBits); |
25 |
static int FrameCodeP(Encoder * pEnc, Bitstream * bs, uint32_t *pBits, bool force_inter, bool vol_header); |
26 |
|
27 |
static int DQtab[4] = |
28 |
{ |
29 |
-1, -2, 1, 2 |
30 |
}; |
31 |
|
32 |
static int iDQtab[5] = |
33 |
{ |
34 |
1, 0, NO_CHANGE, 2, 3 |
35 |
}; |
36 |
|
37 |
|
38 |
int encoder_create(XVID_ENC_PARAM * pParam) |
39 |
{ |
40 |
Encoder *pEnc; |
41 |
uint32_t i; |
42 |
|
43 |
pParam->handle = NULL; |
44 |
|
45 |
ENC_CHECK(pParam); |
46 |
|
47 |
ENC_CHECK(pParam->width > 0 && pParam->width <= 1920); |
48 |
ENC_CHECK(pParam->height > 0 && pParam->height <= 1280); |
49 |
ENC_CHECK(!(pParam->width % 2)); |
50 |
ENC_CHECK(!(pParam->height % 2)); |
51 |
|
52 |
if (pParam->fincr <= 0 || pParam->fbase <= 0) |
53 |
{ |
54 |
pParam->fincr = 1; |
55 |
pParam->fbase = 25; |
56 |
} |
57 |
|
58 |
// simplify the "fincr/fbase" fraction |
59 |
// (neccessary, since windows supplies us with huge numbers) |
60 |
|
61 |
i = pParam->fincr; |
62 |
while (i > 1) |
63 |
{ |
64 |
if (pParam->fincr % i == 0 && pParam->fbase % i == 0) |
65 |
{ |
66 |
pParam->fincr /= i; |
67 |
pParam->fbase /= i; |
68 |
i = pParam->fincr; |
69 |
continue; |
70 |
} |
71 |
i--; |
72 |
} |
73 |
|
74 |
if (pParam->fbase > 65535) |
75 |
{ |
76 |
float div = (float)pParam->fbase / 65535; |
77 |
pParam->fbase = (int)(pParam->fbase / div); |
78 |
pParam->fincr = (int)(pParam->fincr / div); |
79 |
} |
80 |
|
81 |
if (pParam->bitrate <= 0) |
82 |
pParam->bitrate = 900000; |
83 |
|
84 |
if (pParam->rc_buffersize <= 0) |
85 |
pParam->rc_buffersize = pParam->bitrate * pParam->fbase; |
86 |
|
87 |
if ((pParam->min_quantizer <= 0) || (pParam->min_quantizer > 31)) |
88 |
pParam->min_quantizer = 1; |
89 |
|
90 |
if ((pParam->max_quantizer <= 0) || (pParam->max_quantizer > 31)) |
91 |
pParam->max_quantizer = 31; |
92 |
|
93 |
if (pParam->max_key_interval == 0) /* 1 keyframe each 10 seconds */ |
94 |
pParam->max_key_interval = 10 * pParam->fincr / pParam->fbase; |
95 |
|
96 |
if (pParam->max_quantizer < pParam->min_quantizer) |
97 |
pParam->max_quantizer = pParam->min_quantizer; |
98 |
|
99 |
if ((pEnc = (Encoder *) xvid_malloc(sizeof(Encoder), 16)) == NULL) |
100 |
return XVID_ERR_MEMORY; |
101 |
|
102 |
/* Fill members of Encoder structure */ |
103 |
|
104 |
pEnc->mbParam.width = pParam->width; |
105 |
pEnc->mbParam.height = pParam->height; |
106 |
|
107 |
pEnc->mbParam.mb_width = (pEnc->mbParam.width + 15) / 16; |
108 |
pEnc->mbParam.mb_height = (pEnc->mbParam.height + 15) / 16; |
109 |
|
110 |
pEnc->mbParam.edged_width = 16 * pEnc->mbParam.mb_width + 2 * EDGE_SIZE; |
111 |
pEnc->mbParam.edged_height = 16 * pEnc->mbParam.mb_height + 2 * EDGE_SIZE; |
112 |
|
113 |
pEnc->sStat.fMvPrevSigma = -1; |
114 |
|
115 |
/* Fill rate control parameters */ |
116 |
|
117 |
pEnc->mbParam.quant = 4; |
118 |
|
119 |
pEnc->bitrate = pParam->bitrate; |
120 |
|
121 |
pEnc->iFrameNum = 0; |
122 |
pEnc->iMaxKeyInterval = pParam->max_key_interval; |
123 |
|
124 |
if (image_create(&pEnc->sCurrent, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0) |
125 |
{ |
126 |
xvid_free(pEnc); |
127 |
return XVID_ERR_MEMORY; |
128 |
} |
129 |
|
130 |
if (image_create(&pEnc->sReference, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0) |
131 |
{ |
132 |
image_destroy(&pEnc->sCurrent, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height); |
133 |
xvid_free(pEnc); |
134 |
return XVID_ERR_MEMORY; |
135 |
} |
136 |
|
137 |
if (image_create(&pEnc->vInterH, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0) |
138 |
{ |
139 |
image_destroy(&pEnc->sCurrent, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height); |
140 |
image_destroy(&pEnc->sReference, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height); |
141 |
xvid_free(pEnc); |
142 |
return XVID_ERR_MEMORY; |
143 |
} |
144 |
|
145 |
if (image_create(&pEnc->vInterV, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0) |
146 |
{ |
147 |
image_destroy(&pEnc->sCurrent, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height); |
148 |
image_destroy(&pEnc->sReference, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height); |
149 |
image_destroy(&pEnc->vInterH, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height); |
150 |
xvid_free(pEnc); |
151 |
return XVID_ERR_MEMORY; |
152 |
} |
153 |
|
154 |
if (image_create(&pEnc->vInterHV, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height) < 0) |
155 |
{ |
156 |
image_destroy(&pEnc->sCurrent, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height); |
157 |
image_destroy(&pEnc->sReference, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height); |
158 |
image_destroy(&pEnc->vInterH, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height); |
159 |
image_destroy(&pEnc->vInterV, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height); |
160 |
xvid_free(pEnc); |
161 |
return XVID_ERR_MEMORY; |
162 |
} |
163 |
|
164 |
pEnc->pMBs = xvid_malloc(sizeof(MACROBLOCK) * pEnc->mbParam.mb_width * pEnc->mbParam.mb_height, 16); |
165 |
if (pEnc->pMBs == NULL) |
166 |
{ |
167 |
image_destroy(&pEnc->sCurrent, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height); |
168 |
image_destroy(&pEnc->sReference, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height); |
169 |
image_destroy(&pEnc->vInterH, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height); |
170 |
image_destroy(&pEnc->vInterV, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height); |
171 |
image_destroy(&pEnc->vInterHV, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height); |
172 |
xvid_free(pEnc); |
173 |
return XVID_ERR_MEMORY; |
174 |
} |
175 |
|
176 |
// init macroblock array |
177 |
for (i = 0; i < pEnc->mbParam.mb_width * pEnc->mbParam.mb_height; i++) |
178 |
{ |
179 |
pEnc->pMBs[i].dquant = NO_CHANGE; |
180 |
} |
181 |
|
182 |
pParam->handle = (void *)pEnc; |
183 |
|
184 |
if (pParam->bitrate) |
185 |
{ |
186 |
RateControlInit(pParam->bitrate, pParam->rc_buffersize, pParam->fbase, pParam->width, |
187 |
pParam->height, pParam->max_quantizer, pParam->min_quantizer); |
188 |
} |
189 |
|
190 |
create_vlc_tables(); |
191 |
init_timer(); |
192 |
|
193 |
return XVID_ERR_OK; |
194 |
} |
195 |
|
196 |
|
197 |
int encoder_destroy(Encoder * pEnc) |
198 |
{ |
199 |
ENC_CHECK(pEnc); |
200 |
ENC_CHECK(pEnc->sCurrent.y); |
201 |
ENC_CHECK(pEnc->sReference.y); |
202 |
|
203 |
xvid_free(pEnc->pMBs); |
204 |
image_destroy(&pEnc->sCurrent, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height); |
205 |
image_destroy(&pEnc->sReference, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height); |
206 |
image_destroy(&pEnc->vInterH, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height); |
207 |
image_destroy(&pEnc->vInterV, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height); |
208 |
image_destroy(&pEnc->vInterHV, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height); |
209 |
xvid_free(pEnc); |
210 |
|
211 |
destroy_vlc_tables(); |
212 |
|
213 |
return XVID_ERR_OK; |
214 |
} |
215 |
|
216 |
int encoder_encode(Encoder * pEnc, XVID_ENC_FRAME * pFrame, XVID_ENC_STATS * pResult) |
217 |
{ |
218 |
uint16_t x, y; |
219 |
Bitstream bs; |
220 |
uint32_t bits; |
221 |
uint16_t write_vol_header = 0; |
222 |
|
223 |
start_global_timer(); |
224 |
|
225 |
ENC_CHECK(pEnc); |
226 |
ENC_CHECK(pFrame); |
227 |
ENC_CHECK(pFrame->bitstream); |
228 |
ENC_CHECK(pFrame->image); |
229 |
|
230 |
pEnc->mbParam.global_flags = pFrame->general; |
231 |
pEnc->mbParam.motion_flags = pFrame->motion; |
232 |
|
233 |
start_timer(); |
234 |
if (image_input(&pEnc->sCurrent, pEnc->mbParam.width, pEnc->mbParam.height, pEnc->mbParam.edged_width, |
235 |
pFrame->image, pFrame->colorspace)) |
236 |
{ |
237 |
return XVID_ERR_FORMAT; |
238 |
} |
239 |
stop_conv_timer(); |
240 |
|
241 |
EMMS(); |
242 |
|
243 |
BitstreamInit(&bs, pFrame->bitstream, 0); |
244 |
|
245 |
if (pFrame->quant == 0) |
246 |
{ |
247 |
pEnc->mbParam.quant = RateControlGetQ(0); |
248 |
} |
249 |
else |
250 |
{ |
251 |
pEnc->mbParam.quant = pFrame->quant; |
252 |
} |
253 |
|
254 |
if ((pEnc->mbParam.global_flags & XVID_LUMIMASKING) > 0) |
255 |
{ |
256 |
int * temp_dquants = (int *) xvid_malloc(pEnc->mbParam.mb_width * pEnc->mbParam.mb_height * sizeof(int), 16); |
257 |
|
258 |
pEnc->mbParam.quant = adaptive_quantization(pEnc->sCurrent.y, pEnc->mbParam.width, |
259 |
temp_dquants, pFrame->quant, pFrame->quant, |
260 |
2*pFrame->quant, pEnc->mbParam.mb_width, pEnc->mbParam.mb_height); |
261 |
|
262 |
for (y = 0; y < pEnc->mbParam.mb_height; y++) |
263 |
for (x = 0; x < pEnc->mbParam.mb_width; x++) |
264 |
{ |
265 |
MACROBLOCK *pMB = &pEnc->pMBs[x + y * pEnc->mbParam.mb_width]; |
266 |
pMB->dquant = iDQtab[(temp_dquants[y * pEnc->mbParam.mb_width + x] + 2)]; |
267 |
} |
268 |
xvid_free(temp_dquants); |
269 |
} |
270 |
|
271 |
if(pEnc->mbParam.global_flags & XVID_H263QUANT) { |
272 |
if(pEnc->mbParam.quant_type != H263_QUANT) |
273 |
write_vol_header = 1; |
274 |
pEnc->mbParam.quant_type = H263_QUANT; |
275 |
} |
276 |
else if(pEnc->mbParam.global_flags & XVID_MPEGQUANT) { |
277 |
int ret1, ret2; |
278 |
|
279 |
if(pEnc->mbParam.quant_type != MPEG4_QUANT) |
280 |
write_vol_header = 1; |
281 |
|
282 |
pEnc->mbParam.quant_type = MPEG4_QUANT; |
283 |
|
284 |
if ((pEnc->mbParam.global_flags & XVID_CUSTOM_QMATRIX) > 0) { |
285 |
if(pFrame->quant_intra_matrix != NULL) |
286 |
ret1 = set_intra_matrix(pFrame->quant_intra_matrix); |
287 |
if(pFrame->quant_inter_matrix != NULL) |
288 |
ret2 = set_inter_matrix(pFrame->quant_inter_matrix); |
289 |
} |
290 |
else { |
291 |
ret1 = set_intra_matrix(get_default_intra_matrix()); |
292 |
ret2 = set_inter_matrix(get_default_inter_matrix()); |
293 |
} |
294 |
if(write_vol_header == 0) |
295 |
write_vol_header = ret1 | ret2; |
296 |
} |
297 |
|
298 |
if (pFrame->intra < 0) |
299 |
{ |
300 |
if ((pEnc->iFrameNum == 0) || ((pEnc->iMaxKeyInterval > 0) |
301 |
&& (pEnc->iFrameNum >= pEnc->iMaxKeyInterval))) |
302 |
|
303 |
pFrame->intra = FrameCodeI(pEnc, &bs, &bits); |
304 |
else |
305 |
pFrame->intra = FrameCodeP(pEnc, &bs, &bits, 0, write_vol_header); |
306 |
} |
307 |
else |
308 |
{ |
309 |
if (pFrame->intra == 1) |
310 |
pFrame->intra = FrameCodeI(pEnc, &bs, &bits); |
311 |
else |
312 |
pFrame->intra = FrameCodeP(pEnc, &bs, &bits, 1, write_vol_header); |
313 |
} |
314 |
|
315 |
BitstreamPutBits(&bs, 0xFFFF, 16); |
316 |
BitstreamPutBits(&bs, 0xFFFF, 16); |
317 |
BitstreamPad(&bs); |
318 |
pFrame->length = BitstreamLength(&bs); |
319 |
|
320 |
if (pResult) |
321 |
{ |
322 |
pResult->quant = pEnc->mbParam.quant; |
323 |
pResult->hlength = pFrame->length - (pEnc->sStat.iTextBits / 8); |
324 |
pResult->kblks = pEnc->sStat.kblks; |
325 |
pResult->mblks = pEnc->sStat.mblks; |
326 |
pResult->ublks = pEnc->sStat.ublks; |
327 |
} |
328 |
|
329 |
EMMS(); |
330 |
|
331 |
if (pFrame->quant == 0) |
332 |
{ |
333 |
RateControlUpdate(pEnc->mbParam.quant, pFrame->length, pFrame->intra); |
334 |
} |
335 |
|
336 |
pEnc->iFrameNum++; |
337 |
image_swap(&pEnc->sCurrent, &pEnc->sReference); |
338 |
|
339 |
stop_global_timer(); |
340 |
write_timer(); |
341 |
|
342 |
return XVID_ERR_OK; |
343 |
} |
344 |
|
345 |
|
346 |
static __inline void CodeIntraMB(Encoder *pEnc, MACROBLOCK *pMB) { |
347 |
|
348 |
pMB->mode = MODE_INTRA; |
349 |
|
350 |
if ((pEnc->mbParam.global_flags & XVID_LUMIMASKING) > 0) { |
351 |
if(pMB->dquant != NO_CHANGE) |
352 |
{ |
353 |
pMB->mode = MODE_INTRA_Q; |
354 |
pEnc->mbParam.quant += DQtab[pMB->dquant]; |
355 |
|
356 |
if (pEnc->mbParam.quant > 31) pEnc->mbParam.quant = 31; |
357 |
if (pEnc->mbParam.quant < 1) pEnc->mbParam.quant = 1; |
358 |
} |
359 |
} |
360 |
|
361 |
pMB->quant = pEnc->mbParam.quant; |
362 |
} |
363 |
|
364 |
|
365 |
static int FrameCodeI(Encoder * pEnc, Bitstream * bs, uint32_t *pBits) |
366 |
{ |
367 |
int16_t dct_codes[6][64]; |
368 |
int16_t qcoeff[6][64]; |
369 |
uint16_t x, y; |
370 |
|
371 |
pEnc->iFrameNum = 0; |
372 |
pEnc->mbParam.rounding_type = 1; |
373 |
pEnc->mbParam.coding_type = I_VOP; |
374 |
|
375 |
BitstreamWriteVolHeader(bs, pEnc->mbParam.width, pEnc->mbParam.height, pEnc->mbParam.quant_type); |
376 |
BitstreamWriteVopHeader(bs, I_VOP, pEnc->mbParam.rounding_type, |
377 |
pEnc->mbParam.quant, |
378 |
pEnc->mbParam.fixed_code); |
379 |
|
380 |
*pBits = BitstreamPos(bs); |
381 |
|
382 |
pEnc->sStat.iTextBits = 0; |
383 |
pEnc->sStat.kblks = pEnc->mbParam.mb_width * pEnc->mbParam.mb_height; |
384 |
pEnc->sStat.mblks = pEnc->sStat.ublks = 0; |
385 |
|
386 |
for (y = 0; y < pEnc->mbParam.mb_height; y++) |
387 |
for (x = 0; x < pEnc->mbParam.mb_width; x++) |
388 |
{ |
389 |
MACROBLOCK *pMB = &pEnc->pMBs[x + y * pEnc->mbParam.mb_width]; |
390 |
|
391 |
CodeIntraMB(pEnc, pMB); |
392 |
|
393 |
MBTransQuantIntra(&pEnc->mbParam, x, y, dct_codes, qcoeff, &pEnc->sCurrent); |
394 |
|
395 |
start_timer(); |
396 |
MBPrediction(&pEnc->mbParam, x, y, pEnc->mbParam.mb_width, qcoeff, pEnc->pMBs); |
397 |
stop_prediction_timer(); |
398 |
|
399 |
start_timer(); |
400 |
MBCoding(&pEnc->mbParam, pMB, qcoeff, bs, &pEnc->sStat); |
401 |
stop_coding_timer(); |
402 |
} |
403 |
|
404 |
emms(); |
405 |
|
406 |
*pBits = BitstreamPos(bs) - *pBits; |
407 |
pEnc->sStat.fMvPrevSigma = -1; |
408 |
pEnc->sStat.iMvSum = 0; |
409 |
pEnc->sStat.iMvCount = 0; |
410 |
pEnc->mbParam.fixed_code = 2; |
411 |
|
412 |
return 1; // intra |
413 |
} |
414 |
|
415 |
|
416 |
#define INTRA_THRESHOLD 0.5 |
417 |
|
418 |
static int FrameCodeP(Encoder * pEnc, Bitstream * bs, uint32_t *pBits, bool force_inter, bool vol_header) |
419 |
{ |
420 |
float fSigma; |
421 |
int16_t dct_codes[6][64]; |
422 |
int16_t qcoeff[6][64]; |
423 |
int iLimit; |
424 |
uint32_t x, y; |
425 |
int iSearchRange; |
426 |
bool bIntra; |
427 |
|
428 |
IMAGE *pCurrent = &pEnc->sCurrent; |
429 |
IMAGE *pRef = &pEnc->sReference; |
430 |
|
431 |
image_setedges(pRef,pEnc->mbParam.edged_width, pEnc->mbParam.edged_height, pEnc->mbParam.width, pEnc->mbParam.height); |
432 |
|
433 |
pEnc->mbParam.rounding_type = 1 - pEnc->mbParam.rounding_type; |
434 |
|
435 |
if (!force_inter) |
436 |
iLimit = (int)(pEnc->mbParam.mb_width * pEnc->mbParam.mb_height * INTRA_THRESHOLD); |
437 |
else |
438 |
iLimit = pEnc->mbParam.mb_width * pEnc->mbParam.mb_height + 1; |
439 |
|
440 |
if ((pEnc->mbParam.global_flags & XVID_HALFPEL) > 0) { |
441 |
start_timer(); |
442 |
image_interpolate(pRef, &pEnc->vInterH, &pEnc->vInterV, &pEnc->vInterHV, |
443 |
pEnc->mbParam.edged_width, pEnc->mbParam.edged_height, |
444 |
pEnc->mbParam.rounding_type); |
445 |
stop_inter_timer(); |
446 |
} |
447 |
|
448 |
start_timer(); |
449 |
bIntra = MotionEstimation(pEnc->pMBs, &pEnc->mbParam, &pEnc->sReference, |
450 |
&pEnc->vInterH, &pEnc->vInterV, |
451 |
&pEnc->vInterHV, &pEnc->sCurrent, iLimit); |
452 |
stop_motion_timer(); |
453 |
|
454 |
if (bIntra == 1) |
455 |
return FrameCodeI(pEnc, bs, pBits); |
456 |
|
457 |
pEnc->mbParam.coding_type = P_VOP; |
458 |
|
459 |
if(vol_header) |
460 |
BitstreamWriteVolHeader(bs, pEnc->mbParam.width, pEnc->mbParam.height, pEnc->mbParam.quant_type); |
461 |
|
462 |
BitstreamWriteVopHeader(bs, P_VOP, pEnc->mbParam.rounding_type, |
463 |
pEnc->mbParam.quant, |
464 |
pEnc->mbParam.fixed_code); |
465 |
|
466 |
*pBits = BitstreamPos(bs); |
467 |
|
468 |
pEnc->sStat.iTextBits = 0; |
469 |
pEnc->sStat.iMvSum = 0; |
470 |
pEnc->sStat.iMvCount = 0; |
471 |
pEnc->sStat.kblks = pEnc->sStat.mblks = pEnc->sStat.ublks = 0; |
472 |
|
473 |
for(y = 0; y < pEnc->mbParam.mb_height; y++) |
474 |
{ |
475 |
for(x = 0; x < pEnc->mbParam.mb_width; x++) |
476 |
{ |
477 |
MACROBLOCK * pMB = &pEnc->pMBs[x + y * pEnc->mbParam.mb_width]; |
478 |
|
479 |
bIntra = (pMB->mode == MODE_INTRA) || (pMB->mode == MODE_INTRA_Q); |
480 |
|
481 |
if (!bIntra) |
482 |
{ |
483 |
start_timer(); |
484 |
MBMotionCompensation(pMB, x, y, &pEnc->sReference, |
485 |
&pEnc->vInterH, &pEnc->vInterV, |
486 |
&pEnc->vInterHV, &pEnc->sCurrent, dct_codes, |
487 |
pEnc->mbParam.width, |
488 |
pEnc->mbParam.height, |
489 |
pEnc->mbParam.edged_width, |
490 |
pEnc->mbParam.rounding_type); |
491 |
stop_comp_timer(); |
492 |
|
493 |
if ((pEnc->mbParam.global_flags & XVID_LUMIMASKING) > 0) { |
494 |
if(pMB->dquant != NO_CHANGE) { |
495 |
pMB->mode = MODE_INTER_Q; |
496 |
pEnc->mbParam.quant += DQtab[pMB->dquant]; |
497 |
if (pEnc->mbParam.quant > 31) pEnc->mbParam.quant = 31; |
498 |
else if(pEnc->mbParam.quant < 1) pEnc->mbParam.quant = 1; |
499 |
} |
500 |
} |
501 |
pMB->quant = pEnc->mbParam.quant; |
502 |
|
503 |
pMB->cbp = MBTransQuantInter(&pEnc->mbParam, x, y, dct_codes, qcoeff, pCurrent); |
504 |
} |
505 |
else |
506 |
{ |
507 |
CodeIntraMB(pEnc, pMB); |
508 |
MBTransQuantIntra(&pEnc->mbParam, x, y, dct_codes, qcoeff, pCurrent); |
509 |
} |
510 |
|
511 |
start_timer(); |
512 |
MBPrediction(&pEnc->mbParam, x, y, pEnc->mbParam.mb_width, qcoeff, pEnc->pMBs); |
513 |
stop_prediction_timer(); |
514 |
|
515 |
if (pMB->mode == MODE_INTRA || pMB->mode == MODE_INTRA_Q) |
516 |
{ |
517 |
pEnc->sStat.kblks++; |
518 |
} |
519 |
else if (pMB->cbp || |
520 |
pMB->mvs[0].x || pMB->mvs[0].y || |
521 |
pMB->mvs[1].x || pMB->mvs[1].y || |
522 |
pMB->mvs[2].x || pMB->mvs[2].y || |
523 |
pMB->mvs[3].x || pMB->mvs[3].y) |
524 |
{ |
525 |
pEnc->sStat.mblks++; |
526 |
} |
527 |
else |
528 |
{ |
529 |
pEnc->sStat.ublks++; |
530 |
} |
531 |
|
532 |
start_timer(); |
533 |
MBCoding(&pEnc->mbParam, pMB, qcoeff, bs, &pEnc->sStat); |
534 |
stop_coding_timer(); |
535 |
} |
536 |
} |
537 |
|
538 |
emms(); |
539 |
|
540 |
if (pEnc->sStat.iMvCount == 0) |
541 |
pEnc->sStat.iMvCount = 1; |
542 |
|
543 |
fSigma = (float)sqrt((float) pEnc->sStat.iMvSum / pEnc->sStat.iMvCount); |
544 |
|
545 |
iSearchRange = 1 << (3 + pEnc->mbParam.fixed_code); |
546 |
|
547 |
if ((fSigma > iSearchRange / 3) |
548 |
&& (pEnc->mbParam.fixed_code <= 3)) // maximum search range 128 |
549 |
{ |
550 |
pEnc->mbParam.fixed_code++; |
551 |
iSearchRange *= 2; |
552 |
} |
553 |
else if ((fSigma < iSearchRange / 6) |
554 |
&& (pEnc->sStat.fMvPrevSigma >= 0) |
555 |
&& (pEnc->sStat.fMvPrevSigma < iSearchRange / 6) |
556 |
&& (pEnc->mbParam.fixed_code >= 2)) // minimum search range 16 |
557 |
{ |
558 |
pEnc->mbParam.fixed_code--; |
559 |
iSearchRange /= 2; |
560 |
} |
561 |
|
562 |
pEnc->sStat.fMvPrevSigma = fSigma; |
563 |
|
564 |
*pBits = BitstreamPos(bs) - *pBits; |
565 |
|
566 |
return 0; // inter |
567 |
} |