ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/trunk/xvidcore/src/encoder.c
Revision: 41
Committed: Wed Mar 20 00:28:02 2002 UTC (22 years, 6 months ago) by Isibaar
Content type: text/plain
File size: 15565 byte(s)
Log Message:
xvid_malloc/xvid_free

File Contents

# Content
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 }