[svn] / trunk / vfw / src / codec.c Repository:
ViewVC logotype

Annotation of /trunk/vfw/src/codec.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 278 - (view) (download)

1 : Isibaar 3 /**************************************************************************
2 :     *
3 :     * XVID VFW FRONTEND
4 :     * codec
5 :     *
6 :     * This program is free software; you can redistribute it and/or modify
7 :     * it under the terms of the GNU General Public License as published by
8 :     * the Free Software Foundation; either version 2 of the License, or
9 :     * (at your option) any later version.
10 :     *
11 :     * This program is distributed in the hope that it will be useful,
12 :     * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 :     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 :     * GNU General Public License for more details.
15 :     *
16 :     * You should have received a copy of the GNU General Public License
17 :     * along with this program; if not, write to the Free Software
18 :     * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 :     *
20 :     *************************************************************************/
21 :    
22 :     /**************************************************************************
23 :     *
24 :     * History:
25 :     *
26 : suxen_drol 235 * 23.06.2002 XVID_CPU_CHKONLY; loading speed up
27 : suxen_drol 137 * 25.04.2002 ICDECOMPRESS_PREROLL
28 : h 127 * 17.04.2002 re-enabled lumi masking for 1st pass
29 : h 121 * 15.04.2002 updated cbr support
30 : h 102 * 04.04.2002 separated 2-pass code to 2pass.c
31 :     * interlacing support
32 :     * hinted ME support
33 : h 61 * 23.03.2002 daniel smith <danielsmith@astroboymail.com>
34 :     * changed inter4v to only be in modes 5 or 6
35 :     * fixed null mode crash ?
36 :     * merged foxer's alternative 2-pass code
37 :     * added DEBUGERR output on errors instead of returning
38 : h 30 * 16.03.2002 daniel smith <danielsmith@astroboymail.com>
39 :     * changed BITMAPV4HEADER to BITMAPINFOHEADER
40 :     * - prevents memcpy crash in compress_get_format()
41 :     * credits are processed in external 2pass mode
42 :     * motion search precision = 0 now effective in 2-pass
43 :     * modulated quantization
44 :     * added DX50 fourcc
45 : Isibaar 3 * 01.12.2001 inital version; (c)2001 peter ross <suxen_drol@hotmail.com>
46 :     *
47 :     *************************************************************************/
48 :    
49 :     #include <windows.h>
50 :     #include <vfw.h>
51 :    
52 :     #include "codec.h"
53 : h 102 #include "2pass.h"
54 : Isibaar 3
55 :     int pmvfast_presets[7] = {
56 :     0, PMV_QUICKSTOP16, PMV_EARLYSTOP16, PMV_EARLYSTOP16 | PMV_EARLYSTOP8,
57 :     PMV_EARLYSTOP16 | PMV_HALFPELREFINE16 | PMV_EARLYSTOP8 | PMV_HALFPELDIAMOND8,
58 :     PMV_EARLYSTOP16 | PMV_HALFPELREFINE16 | PMV_EARLYSTOP8 | PMV_HALFPELDIAMOND8,
59 :     PMV_EARLYSTOP16 | PMV_HALFPELREFINE16 | PMV_EXTSEARCH16 |
60 :     PMV_EARLYSTOP8 | PMV_HALFPELREFINE8 | PMV_HALFPELDIAMOND8
61 :     };
62 :    
63 :     /* return xvid compatbile colorspace,
64 :     or XVID_CSP_NULL if failure
65 :     */
66 :    
67 : h 30 int get_colorspace(BITMAPINFOHEADER * hdr)
68 : Isibaar 3 {
69 : h 30 if (hdr->biHeight < 0)
70 : Isibaar 3 {
71 : h 61 DEBUGERR("colorspace: inverted input format not supported");
72 : Isibaar 3 return XVID_CSP_NULL;
73 :     }
74 :    
75 : h 30 switch(hdr->biCompression)
76 : Isibaar 3 {
77 :     case BI_RGB :
78 : h 30 if (hdr->biBitCount == 16)
79 : Isibaar 3 {
80 :     DEBUG("RGB16 (RGB555)");
81 :     return XVID_CSP_VFLIP | XVID_CSP_RGB555;
82 :     }
83 : h 30 if (hdr->biBitCount == 24)
84 : Isibaar 3 {
85 :     DEBUG("RGB24");
86 :     return XVID_CSP_VFLIP | XVID_CSP_RGB24;
87 :     }
88 : h 30 if (hdr->biBitCount == 32)
89 : Isibaar 3 {
90 :     DEBUG("RGB32");
91 :     return XVID_CSP_VFLIP | XVID_CSP_RGB32;
92 :     }
93 :    
94 : h 30 DEBUG1("BI_RGB unsupported", hdr->biBitCount);
95 : Isibaar 3 return XVID_CSP_NULL;
96 :    
97 : h 30 // how do these work in BITMAPINFOHEADER ???
98 :     /* case BI_BITFIELDS :
99 :     if (hdr->biBitCount == 16
100 :     if(hdr->biBitCount == 16 &&
101 : Isibaar 3 hdr->bV4RedMask == 0x7c00 &&
102 :     hdr->bV4GreenMask == 0x3e0 &&
103 :     hdr->bV4BlueMask == 0x1f)
104 :     {
105 :     DEBUG("RGB555");
106 :     return XVID_CSP_VFLIP | XVID_CSP_RGB555;
107 :     }
108 :     if(hdr->bV4BitCount == 16 &&
109 :     hdr->bV4RedMask == 0xf800 &&
110 :     hdr->bV4GreenMask == 0x7e0 &&
111 :     hdr->bV4BlueMask == 0x1f)
112 :     {
113 :     DEBUG("RGB565");
114 :     return XVID_CSP_VFLIP | XVID_CSP_RGB565;
115 :     }
116 :    
117 :     DEBUG1("BI_FIELDS unsupported", hdr->bV4BitCount);
118 :     return XVID_CSP_NULL;
119 : h 30 */
120 : Isibaar 3 case FOURCC_I420:
121 :     case FOURCC_IYUV:
122 :     DEBUG("IYUY");
123 :     return XVID_CSP_I420;
124 :    
125 :     case FOURCC_YV12 :
126 :     DEBUG("YV12");
127 :     return XVID_CSP_YV12;
128 :    
129 :     case FOURCC_YUYV :
130 :     case FOURCC_YUY2 :
131 :     case FOURCC_V422 :
132 :     DEBUG("YUY2");
133 :     return XVID_CSP_YUY2;
134 :    
135 :     case FOURCC_YVYU:
136 :     DEBUG("YVYU");
137 :     return XVID_CSP_YVYU;
138 :    
139 :     case FOURCC_UYVY:
140 :     DEBUG("UYVY");
141 :     return XVID_CSP_UYVY;
142 :    
143 :     }
144 : h 30 DEBUGFOURCC("colorspace: unknown", hdr->biCompression);
145 : Isibaar 3 return XVID_CSP_NULL;
146 :     }
147 :    
148 :    
149 :     /* compressor */
150 :    
151 :    
152 :     /* test the output format */
153 :    
154 :     LRESULT compress_query(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput)
155 :     {
156 : h 30 BITMAPINFOHEADER * inhdr = &lpbiInput->bmiHeader;
157 :     BITMAPINFOHEADER * outhdr = &lpbiOutput->bmiHeader;
158 : Isibaar 3
159 :     if (get_colorspace(inhdr) == XVID_CSP_NULL)
160 :     {
161 :     return ICERR_BADFORMAT;
162 :     }
163 :    
164 :     if (lpbiOutput == NULL)
165 :     {
166 :     return ICERR_OK;
167 :     }
168 : h 30
169 :     if (inhdr->biWidth != outhdr->biWidth || inhdr->biHeight != outhdr->biHeight ||
170 :     (outhdr->biCompression != FOURCC_XVID && outhdr->biCompression != FOURCC_DIVX))
171 : Isibaar 3 {
172 :     return ICERR_BADFORMAT;
173 :     }
174 :    
175 :     return ICERR_OK;
176 :     }
177 :    
178 :    
179 :     LRESULT compress_get_format(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput)
180 :     {
181 : h 30 BITMAPINFOHEADER * inhdr = &lpbiInput->bmiHeader;
182 :     BITMAPINFOHEADER * outhdr = &lpbiOutput->bmiHeader;
183 : Isibaar 3
184 : h 30 if (get_colorspace(inhdr) == XVID_CSP_NULL)
185 : Isibaar 3 {
186 : h 30 return ICERR_BADFORMAT;
187 : Isibaar 3 }
188 :    
189 :     if (lpbiOutput == NULL)
190 :     {
191 :     return sizeof(BITMAPV4HEADER);
192 :     }
193 :    
194 : h 30 memcpy(outhdr, inhdr, sizeof(BITMAPINFOHEADER));
195 :     outhdr->biSize = sizeof(BITMAPINFOHEADER);
196 :     outhdr->biBitCount = 24; // or 16
197 :     outhdr->biSizeImage = compress_get_size(codec, lpbiInput, lpbiOutput);
198 :     outhdr->biXPelsPerMeter = 0;
199 :     outhdr->biYPelsPerMeter = 0;
200 :     outhdr->biClrUsed = 0;
201 :     outhdr->biClrImportant = 0;
202 : Isibaar 3
203 :     if (codec->config.fourcc_used == 0)
204 :     {
205 : h 30 outhdr->biCompression = FOURCC_XVID;
206 : Isibaar 3 }
207 : h 30 else if (codec->config.fourcc_used == 1)
208 :     {
209 :     outhdr->biCompression = FOURCC_DIVX;
210 :     }
211 : Isibaar 3 else
212 :     {
213 : h 30 outhdr->biCompression = FOURCC_DX50;
214 : Isibaar 3 }
215 :    
216 :     return ICERR_OK;
217 :     }
218 :    
219 :    
220 :     LRESULT compress_get_size(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput)
221 :     {
222 : suxen_drol 228 return
223 :     #ifdef BFRAMES
224 :     2 *
225 :     #endif
226 :     lpbiOutput->bmiHeader.biWidth * lpbiOutput->bmiHeader.biHeight * 3;
227 : Isibaar 3 }
228 :    
229 :    
230 :     LRESULT compress_frames_info(CODEC * codec, ICCOMPRESSFRAMES * icf)
231 :     {
232 :     // DEBUG2("frate fscale", codec->frate, codec->fscale);
233 :     codec->fincr = icf->dwScale;
234 :     codec->fbase = icf->dwRate;
235 :     return ICERR_OK;
236 :     }
237 :    
238 :    
239 :     LRESULT compress_begin(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput)
240 :     {
241 :     XVID_ENC_PARAM param;
242 :     XVID_INIT_PARAM init_param;
243 :    
244 :     switch (codec->config.mode)
245 :     {
246 :     case DLG_MODE_CBR :
247 : h 121 param.rc_bitrate = codec->config.rc_bitrate;
248 :     param.rc_reaction_delay_factor = codec->config.rc_reaction_delay_factor;
249 :     param.rc_averaging_period = codec->config.rc_averaging_period;
250 :     param.rc_buffer = codec->config.rc_buffer;
251 : Isibaar 3 break;
252 :    
253 :     case DLG_MODE_VBR_QUAL :
254 :     codec->config.fquant = 0;
255 : h 121 param.rc_bitrate = 0;
256 : Isibaar 3 break;
257 :    
258 :     case DLG_MODE_VBR_QUANT :
259 :     codec->config.fquant = (float) codec->config.quant;
260 : h 121 param.rc_bitrate = 0;
261 : Isibaar 3 break;
262 :    
263 : h 61 case DLG_MODE_2PASS_1 :
264 :     case DLG_MODE_2PASS_2_INT :
265 :     case DLG_MODE_2PASS_2_EXT :
266 : h 121 param.rc_bitrate = 0;
267 : h 109 codec->twopass.max_framesize = (int)((double)codec->config.twopass_max_bitrate / 8.0 / ((double)codec->fbase / (double)codec->fincr));
268 : Isibaar 3 break;
269 :    
270 : h 61 case DLG_MODE_NULL :
271 :     return ICERR_OK;
272 :    
273 : Isibaar 3 default :
274 :     break;
275 :     }
276 :    
277 :     if(codec->ehandle)
278 :     {
279 :     xvid_encore(codec->ehandle, XVID_ENC_DESTROY, NULL, NULL);
280 :     codec->ehandle = NULL;
281 :     }
282 :    
283 :     init_param.cpu_flags = codec->config.cpu;
284 :     xvid_init(0, 0, &init_param, NULL);
285 :     if((codec->config.cpu & XVID_CPU_FORCE) <= 0)
286 :     codec->config.cpu = init_param.cpu_flags;
287 :    
288 : h 30 param.width = lpbiInput->bmiHeader.biWidth;
289 :     param.height = lpbiInput->bmiHeader.biHeight;
290 : Isibaar 3 param.fincr = codec->fincr;
291 :     param.fbase = codec->fbase;
292 :    
293 : h 30 param.min_quantizer = codec->config.min_pquant;
294 :     param.max_quantizer = codec->config.max_pquant;
295 : Isibaar 3 param.max_key_interval = codec->config.max_key_interval;
296 :    
297 : suxen_drol 228 #ifdef BFRAMES
298 : suxen_drol 235 param.global = 0;
299 :     if (codec->config.packed) param.global |= XVID_GLOBAL_PACKED;
300 :     if (codec->config.dx50bvop) param.global |= XVID_GLOBAL_DX50BVOP;
301 :     if (codec->config.debug) param.global |= XVID_GLOBAL_DEBUG;
302 : suxen_drol 228 param.max_bframes = codec->config.max_bframes;
303 :     param.bquant_ratio = codec->config.bquant_ratio;
304 :     #endif
305 :    
306 : Isibaar 3 switch(xvid_encore(0, XVID_ENC_CREATE, &param, NULL))
307 :     {
308 :     case XVID_ERR_FAIL :
309 :     return ICERR_ERROR;
310 :    
311 :     case XVID_ERR_MEMORY :
312 :     return ICERR_MEMORY;
313 :    
314 :     case XVID_ERR_FORMAT :
315 :     return ICERR_BADFORMAT;
316 :     }
317 :    
318 :     codec->ehandle = param.handle;
319 :     codec->framenum = 0;
320 :     codec->keyspacing = 0;
321 :    
322 : h 102 codec->twopass.hints = codec->twopass.stats1 = codec->twopass.stats2 = INVALID_HANDLE_VALUE;
323 :     codec->twopass.hintstream = NULL;
324 : Isibaar 3
325 :     return ICERR_OK;
326 :     }
327 :    
328 :    
329 :     LRESULT compress_end(CODEC * codec)
330 :     {
331 :     if (codec->ehandle != NULL)
332 :     {
333 :     xvid_encore(codec->ehandle, XVID_ENC_DESTROY, NULL, NULL);
334 : h 102
335 :     if (codec->twopass.hints != INVALID_HANDLE_VALUE)
336 :     {
337 :     CloseHandle(codec->twopass.hints);
338 :     }
339 : Isibaar 3 if (codec->twopass.stats1 != INVALID_HANDLE_VALUE)
340 :     {
341 :     CloseHandle(codec->twopass.stats1);
342 :     }
343 :     if (codec->twopass.stats2 != INVALID_HANDLE_VALUE)
344 :     {
345 :     CloseHandle(codec->twopass.stats2);
346 :     }
347 : h 102 if (codec->twopass.hintstream != NULL)
348 :     {
349 :     free(codec->twopass.hintstream);
350 :     }
351 :    
352 : Isibaar 3 codec->ehandle = NULL;
353 : h 105
354 :     codec_2pass_finish(codec);
355 : Isibaar 3 }
356 :    
357 :     return ICERR_OK;
358 :     }
359 :    
360 :    
361 :     LRESULT compress(CODEC * codec, ICCOMPRESS * icc)
362 :     {
363 : h 30 BITMAPINFOHEADER * inhdr = icc->lpbiInput;
364 :     BITMAPINFOHEADER * outhdr = icc->lpbiOutput;
365 : Isibaar 3 XVID_ENC_FRAME frame;
366 :     XVID_ENC_STATS stats;
367 :    
368 :     // mpeg2avi yuv bug workaround (2 instances of CODEC)
369 :     if (codec->twopass.stats1 == INVALID_HANDLE_VALUE)
370 :     {
371 :     if (codec_2pass_init(codec) == ICERR_ERROR)
372 :     {
373 :     return ICERR_ERROR;
374 :     }
375 :     }
376 :    
377 :     frame.general = 0;
378 :     frame.motion = 0;
379 : h 30 frame.intra = -1;
380 : Isibaar 3
381 :     frame.general |= XVID_HALFPEL;
382 :    
383 : h 127 if (codec->config.motion_search > 4)
384 : Isibaar 3 frame.general |= XVID_INTER4V;
385 :    
386 : h 127 if (codec->config.lum_masking)
387 : Isibaar 3 frame.general |= XVID_LUMIMASKING;
388 :    
389 : h 102 if (codec->config.interlacing)
390 :     frame.general |= XVID_INTERLACING;
391 : Isibaar 176 // fix 1pass modes/hinted MV by koepi
392 :     if (codec->config.hinted_me && (codec->config.mode == DLG_MODE_CBR || codec->config.mode == DLG_MODE_VBR_QUAL || codec->config.mode == DLG_MODE_VBR_QUANT))
393 :     {
394 :     codec->config.hinted_me = 0;
395 :     }
396 :     // end of ugly hack
397 : h 102
398 :     if (codec->config.hinted_me && codec->config.mode == DLG_MODE_2PASS_1)
399 :     {
400 :     frame.hint.hintstream = codec->twopass.hintstream;
401 :     frame.hint.rawhints = 0;
402 :     frame.general |= XVID_HINTEDME_GET;
403 :     }
404 : h 103 else if (codec->config.hinted_me && (codec->config.mode == DLG_MODE_2PASS_2_EXT || codec->config.mode == DLG_MODE_2PASS_2_INT))
405 : h 102 {
406 :     DWORD read;
407 :     DWORD blocksize;
408 :    
409 :     frame.hint.hintstream = codec->twopass.hintstream;
410 :     frame.hint.rawhints = 0;
411 :     frame.general |= XVID_HINTEDME_SET;
412 :    
413 :     if (codec->twopass.hints == INVALID_HANDLE_VALUE)
414 :     {
415 :     codec->twopass.hints = CreateFile(codec->config.hintfile, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0);
416 :     if (codec->twopass.hints == INVALID_HANDLE_VALUE)
417 :     {
418 :     DEBUGERR("couldn't open hints file");
419 :     return ICERR_ERROR;
420 :     }
421 :     }
422 :     if (!ReadFile(codec->twopass.hints, &blocksize, sizeof(DWORD), &read, 0) || read != sizeof(DWORD) ||
423 :     !ReadFile(codec->twopass.hints, frame.hint.hintstream, blocksize, &read, 0) || read != blocksize)
424 :     {
425 :     DEBUGERR("couldn't read from hints file");
426 :     return ICERR_ERROR;
427 :     }
428 :     }
429 :    
430 : Isibaar 3 frame.motion = pmvfast_presets[codec->config.motion_search];
431 : h 30
432 : Isibaar 3 frame.image = icc->lpInput;
433 :    
434 : h 30 if ((frame.colorspace = get_colorspace(inhdr)) == XVID_CSP_NULL)
435 : Isibaar 3 return ICERR_BADFORMAT;
436 :    
437 :     frame.bitstream = icc->lpOutput;
438 :     frame.length = icc->lpbiOutput->biSizeImage;
439 :    
440 :     switch (codec->config.mode)
441 :     {
442 :     case DLG_MODE_CBR :
443 :     frame.quant = 0;
444 :     break;
445 :    
446 :     case DLG_MODE_VBR_QUAL :
447 :     case DLG_MODE_VBR_QUANT :
448 :     case DLG_MODE_2PASS_1 :
449 :     if (codec_get_quant(codec, &frame) == ICERR_ERROR)
450 :     {
451 :     return ICERR_ERROR;
452 :     }
453 :     break;
454 :    
455 :     case DLG_MODE_2PASS_2_EXT :
456 :     case DLG_MODE_2PASS_2_INT :
457 :     if (codec_2pass_get_quant(codec, &frame) == ICERR_ERROR)
458 :     {
459 :     return ICERR_ERROR;
460 :     }
461 :     if (codec->config.dummy2pass)
462 :     {
463 : h 30 outhdr->biSizeImage = codec->twopass.bytes2;
464 : Isibaar 3 *icc->lpdwFlags = (codec->twopass.nns1.quant & NNSTATS_KEYFRAME) ? AVIIF_KEYFRAME : 0;
465 :     return ICERR_OK;
466 :     }
467 :     break;
468 :    
469 :     case DLG_MODE_NULL :
470 : h 30 outhdr->biSizeImage = 0;
471 : Isibaar 3 *icc->lpdwFlags = AVIIF_KEYFRAME;
472 :     return ICERR_OK;
473 :    
474 :     default :
475 : h 61 DEBUGERR("Invalid encoding mode");
476 : Isibaar 3 return ICERR_ERROR;
477 :     }
478 :    
479 : h 30 if (codec->config.quant_type == QUANT_MODE_H263)
480 : Isibaar 3 {
481 : h 30 frame.general |= XVID_H263QUANT;
482 :     }
483 :     else
484 :     {
485 :     frame.general |= XVID_MPEGQUANT;
486 :    
487 :     // we actually need "default/custom" selectbox for both inter/intra
488 :     // this will do for now
489 :     if (codec->config.quant_type == QUANT_MODE_CUSTOM)
490 :     {
491 :     frame.general |= XVID_CUSTOM_QMATRIX;
492 :     frame.quant_intra_matrix = codec->config.qmatrix_intra;
493 :     frame.quant_inter_matrix = codec->config.qmatrix_inter;
494 :     }
495 :     else
496 :     {
497 :     frame.quant_intra_matrix = NULL;
498 :     frame.quant_inter_matrix = NULL;
499 :     }
500 :     }
501 :    
502 :     // force keyframe spacing in 2-pass 1st pass
503 :     if (codec->config.motion_search == 0)
504 :     {
505 :     frame.intra = 1;
506 :     }
507 : h 109 else if (codec->keyspacing < codec->config.min_key_interval && codec->framenum)
508 : h 30 {
509 : Isibaar 3 DEBUG("current frame forced to p-frame");
510 :     frame.intra = 0;
511 :     }
512 :    
513 : suxen_drol 278 #ifdef BFRAMES
514 :     frame.bquant = 0;
515 :     #endif
516 :    
517 : suxen_drol 228 OutputDebugString(" ");
518 : Isibaar 3 switch (xvid_encore(codec->ehandle, XVID_ENC_ENCODE, &frame, &stats))
519 :     {
520 :     case XVID_ERR_FAIL :
521 :     return ICERR_ERROR;
522 :    
523 :     case XVID_ERR_MEMORY :
524 :     return ICERR_MEMORY;
525 :    
526 :     case XVID_ERR_FORMAT :
527 :     return ICERR_BADFORMAT;
528 :     }
529 :    
530 :     if (frame.intra)
531 :     {
532 :     codec->keyspacing = 0;
533 :     *icc->lpdwFlags = AVIIF_KEYFRAME;
534 :     }
535 :     else
536 :     {
537 :     *icc->lpdwFlags = 0;
538 :     }
539 :    
540 : h 30 outhdr->biSizeImage = frame.length;
541 : Isibaar 3
542 : h 30 if (codec->config.mode == DLG_MODE_2PASS_1 && codec->config.discard1pass)
543 : Isibaar 3 {
544 : h 30 outhdr->biSizeImage = 0;
545 : Isibaar 3 }
546 :    
547 : h 102 if (frame.general & XVID_HINTEDME_GET)
548 :     {
549 :     DWORD wrote;
550 :     DWORD blocksize = frame.hint.hintlength;
551 :    
552 :     if (codec->twopass.hints == INVALID_HANDLE_VALUE)
553 :     {
554 :     codec->twopass.hints = CreateFile(codec->config.hintfile, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0);
555 : suxen_drol 228 if (codec->twopass.hints == INVALID_HANDLE_VALUE)
556 : h 102 {
557 :     DEBUGERR("couldn't create hints file");
558 :     return ICERR_ERROR;
559 :     }
560 :     }
561 :     if (!WriteFile(codec->twopass.hints, &frame.hint.hintlength, sizeof(int), &wrote, 0) || wrote != sizeof(int) ||
562 :     !WriteFile(codec->twopass.hints, frame.hint.hintstream, blocksize, &wrote, 0) || wrote != blocksize)
563 :     {
564 :     DEBUGERR("couldn't write to hints file");
565 :     return ICERR_ERROR;
566 :     }
567 :     }
568 :    
569 : Isibaar 3 codec_2pass_update(codec, &frame, &stats);
570 :    
571 :     ++codec->framenum;
572 :     ++codec->keyspacing;
573 :    
574 :     return ICERR_OK;
575 :     }
576 :    
577 :    
578 :     /* decompressor */
579 :    
580 :    
581 :     LRESULT decompress_query(CODEC * codec, BITMAPINFO *lpbiInput, BITMAPINFO *lpbiOutput)
582 :     {
583 : h 30 BITMAPINFOHEADER * inhdr = &lpbiInput->bmiHeader;
584 :     BITMAPINFOHEADER * outhdr = &lpbiOutput->bmiHeader;
585 : Isibaar 3
586 :     if (lpbiInput == NULL)
587 :     {
588 :     return ICERR_ERROR;
589 :     }
590 :    
591 : h 30 if (inhdr->biCompression != FOURCC_XVID && inhdr->biCompression != FOURCC_DIVX)
592 : Isibaar 3 {
593 :     return ICERR_BADFORMAT;
594 :     }
595 :    
596 :     if (lpbiOutput == NULL)
597 :     {
598 :     return ICERR_OK;
599 :     }
600 :    
601 : h 30 if (inhdr->biWidth != outhdr->biWidth ||
602 :     inhdr->biHeight != outhdr->biHeight ||
603 : Isibaar 3 get_colorspace(outhdr) == XVID_CSP_NULL)
604 :     {
605 :     return ICERR_BADFORMAT;
606 :     }
607 :    
608 :     return ICERR_OK;
609 :     }
610 :    
611 :    
612 :     LRESULT decompress_get_format(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput)
613 :     {
614 : h 30 BITMAPINFOHEADER * inhdr = &lpbiInput->bmiHeader;
615 :     BITMAPINFOHEADER * outhdr = &lpbiOutput->bmiHeader;
616 : Isibaar 3 LRESULT result;
617 :    
618 :     if (lpbiOutput == NULL)
619 :     {
620 : h 30 return sizeof(BITMAPINFOHEADER);
621 : Isibaar 3 }
622 :    
623 :     result = decompress_query(codec, lpbiInput, lpbiOutput);
624 :     if (result != ICERR_OK)
625 :     {
626 :     return result;
627 :     }
628 :    
629 : h 30 memcpy(outhdr, inhdr, sizeof(BITMAPINFOHEADER));
630 :     outhdr->biSize = sizeof(BITMAPINFOHEADER);
631 :     outhdr->biCompression = FOURCC_YUY2;
632 :     outhdr->biSizeImage = outhdr->biWidth * outhdr->biHeight * outhdr->biBitCount;
633 :     outhdr->biXPelsPerMeter = 0;
634 :     outhdr->biYPelsPerMeter = 0;
635 :     outhdr->biClrUsed = 0;
636 :     outhdr->biClrImportant = 0;
637 : Isibaar 3
638 :     return ICERR_OK;
639 :     }
640 :    
641 :    
642 :     LRESULT decompress_begin(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput)
643 :     {
644 :     XVID_DEC_PARAM param;
645 :     XVID_INIT_PARAM init_param;
646 :    
647 :     init_param.cpu_flags = codec->config.cpu;
648 :     xvid_init(0, 0, &init_param, NULL);
649 :     if((codec->config.cpu & XVID_CPU_FORCE) <= 0)
650 :     {
651 :     codec->config.cpu = init_param.cpu_flags;
652 :     }
653 :    
654 : h 30 param.width = lpbiInput->bmiHeader.biWidth;
655 :     param.height = lpbiInput->bmiHeader.biHeight;
656 : Isibaar 3
657 :     switch(xvid_decore(0, XVID_DEC_CREATE, &param, NULL))
658 :     {
659 :     case XVID_ERR_FAIL :
660 :     return ICERR_ERROR;
661 :    
662 :     case XVID_ERR_MEMORY :
663 :     return ICERR_MEMORY;
664 :    
665 :     case XVID_ERR_FORMAT :
666 :     return ICERR_BADFORMAT;
667 :     }
668 :    
669 :     codec->dhandle = param.handle;
670 :    
671 :     return ICERR_OK;
672 :     }
673 :    
674 :    
675 :     LRESULT decompress_end(CODEC * codec)
676 :     {
677 :     if (codec->dhandle != NULL)
678 :     {
679 :     xvid_decore(codec->dhandle, XVID_DEC_DESTROY, NULL, NULL);
680 :     codec->dhandle = NULL;
681 :     }
682 :     return ICERR_OK;
683 :     }
684 :    
685 :    
686 :     LRESULT decompress(CODEC * codec, ICDECOMPRESS * icd)
687 :     {
688 :     XVID_DEC_FRAME frame;
689 :    
690 :     frame.bitstream = icd->lpInput;
691 :     frame.length = icd->lpbiInput->biSizeImage;
692 :    
693 :     frame.image = icd->lpOutput;
694 :     frame.stride = icd->lpbiOutput->biWidth;
695 :    
696 : suxen_drol 137 if (~((icd->dwFlags & ICDECOMPRESS_HURRYUP) | (icd->dwFlags & ICDECOMPRESS_UPDATE) | (icd->dwFlags & ICDECOMPRESS_PREROLL)))
697 : Isibaar 3 {
698 : h 30 if ((frame.colorspace = get_colorspace(icd->lpbiOutput)) == XVID_CSP_NULL)
699 : Isibaar 3 {
700 :     return ICERR_BADFORMAT;
701 :     }
702 :     }
703 :     else
704 :     {
705 :     frame.colorspace = XVID_CSP_NULL;
706 :     }
707 :    
708 :     switch (xvid_decore(codec->dhandle, XVID_DEC_DECODE, &frame, NULL))
709 :     {
710 :     case XVID_ERR_FAIL :
711 :     return ICERR_ERROR;
712 :    
713 :     case XVID_ERR_MEMORY :
714 :     return ICERR_MEMORY;
715 :    
716 :     case XVID_ERR_FORMAT :
717 :     return ICERR_BADFORMAT;
718 :     }
719 :    
720 :     return ICERR_OK;
721 :     }
722 :    
723 :     int codec_get_quant(CODEC* codec, XVID_ENC_FRAME* frame)
724 :     {
725 :     switch (codec->config.mode)
726 :     {
727 :     case DLG_MODE_VBR_QUAL :
728 :     if (codec_is_in_credits(&codec->config, codec->framenum))
729 :     {
730 :     switch (codec->config.credits_mode)
731 :     {
732 :     case CREDITS_MODE_RATE :
733 :     frame->quant = codec_get_vbr_quant(&codec->config, codec->config.quality * codec->config.credits_rate / 100);
734 :     break;
735 :    
736 :     case CREDITS_MODE_QUANT :
737 :     frame->quant = codec->config.credits_quant_p;
738 :     break;
739 :    
740 :     default :
741 : h 61 DEBUGERR("Can't use credits size mode in quality mode");
742 : Isibaar 3 return ICERR_ERROR;
743 :     }
744 :     }
745 :     else
746 :     {
747 :     frame->quant = codec_get_vbr_quant(&codec->config, codec->config.quality);
748 :     }
749 :     return ICERR_OK;
750 :    
751 :     case DLG_MODE_VBR_QUANT :
752 :     if (codec_is_in_credits(&codec->config, codec->framenum))
753 :     {
754 :     switch (codec->config.credits_mode)
755 :     {
756 :     case CREDITS_MODE_RATE :
757 :     frame->quant =
758 : h 30 codec->config.max_pquant -
759 :     ((codec->config.max_pquant - codec->config.quant) * codec->config.credits_rate / 100);
760 : Isibaar 3 break;
761 :    
762 :     case CREDITS_MODE_QUANT :
763 :     frame->quant = codec->config.credits_quant_p;
764 :     break;
765 :    
766 :     default :
767 : h 61 DEBUGERR("Can't use credits size mode in quantizer mode");
768 : Isibaar 3 return ICERR_ERROR;
769 :     }
770 :     }
771 :     else
772 :     {
773 :     frame->quant = codec->config.quant;
774 :     }
775 :     return ICERR_OK;
776 :    
777 :     case DLG_MODE_2PASS_1 :
778 :     if (codec->config.credits_mode == CREDITS_MODE_QUANT)
779 :     {
780 :     if (codec_is_in_credits(&codec->config, codec->framenum))
781 :     {
782 :     frame->quant = codec->config.credits_quant_p;
783 :     }
784 :     else
785 :     {
786 :     frame->quant = 2;
787 :     }
788 :     }
789 :     else
790 :     {
791 :     frame->quant = 2;
792 :     }
793 :     return ICERR_OK;
794 :    
795 :     default:
796 : h 61 DEBUGERR("get quant: invalid mode");
797 : Isibaar 3 return ICERR_ERROR;
798 :     }
799 :     }
800 :    
801 :    
802 :     int codec_is_in_credits(CONFIG* config, int framenum)
803 :     {
804 :     if (config->credits_start)
805 :     {
806 :     if (framenum >= config->credits_start_begin &&
807 :     framenum <= config->credits_start_end)
808 :     {
809 :     return CREDITS_START;
810 :     }
811 :     }
812 :    
813 :     if (config->credits_end)
814 :     {
815 :     if (framenum >= config->credits_end_begin &&
816 :     framenum <= config->credits_end_end)
817 :     {
818 :     return CREDITS_END;
819 :     }
820 :     }
821 :    
822 :     return 0;
823 :     }
824 :    
825 :    
826 :     int codec_get_vbr_quant(CONFIG* config, int quality)
827 :     {
828 :     static float fquant_running = 0;
829 :     static int my_quality = -1;
830 :     int quant;
831 :    
832 :     // if quality changes, recalculate fquant (credits)
833 :     if (quality != my_quality)
834 :     {
835 :     config->fquant = 0;
836 :     }
837 :    
838 :     my_quality = quality;
839 :    
840 :     // desired quantiser = (maxQ-minQ)/100 * (100-qual) + minQ
841 :     if (!config->fquant)
842 :     {
843 :     config->fquant =
844 : h 30 ((float) (config->max_pquant - config->min_pquant) / 100) *
845 : Isibaar 3 (100 - quality) +
846 : h 30 (float) config->min_pquant;
847 : Isibaar 3
848 :     fquant_running = config->fquant;
849 :     }
850 :    
851 : h 30 if (fquant_running < config->min_pquant)
852 : Isibaar 3 {
853 : h 30 fquant_running = (float) config->min_pquant;
854 : Isibaar 3 }
855 : h 30 else if(fquant_running > config->max_pquant)
856 : Isibaar 3 {
857 : h 30 fquant_running = (float) config->max_pquant;
858 : Isibaar 3 }
859 :    
860 :     quant = (int) fquant_running;
861 :    
862 :     // add error between fquant and quant to fquant_running
863 :     fquant_running += config->fquant - quant;
864 :    
865 :     return quant;
866 :     }
867 :    

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