23 |
* |
* |
24 |
* History: |
* History: |
25 |
* |
* |
26 |
* ... ??? |
* 16.03.2002 daniel smith <danielsmith@astroboymail.com> |
27 |
|
* changed BITMAPV4HEADER to BITMAPINFOHEADER |
28 |
|
* - prevents memcpy crash in compress_get_format() |
29 |
|
* credits are processed in external 2pass mode |
30 |
|
* motion search precision = 0 now effective in 2-pass |
31 |
|
* modulated quantization |
32 |
|
* added DX50 fourcc |
33 |
* 01.12.2001 inital version; (c)2001 peter ross <suxen_drol@hotmail.com> |
* 01.12.2001 inital version; (c)2001 peter ross <suxen_drol@hotmail.com> |
34 |
* |
* |
35 |
*************************************************************************/ |
*************************************************************************/ |
52 |
or XVID_CSP_NULL if failure |
or XVID_CSP_NULL if failure |
53 |
*/ |
*/ |
54 |
|
|
55 |
int get_colorspace(BITMAPV4HEADER * hdr) |
int get_colorspace(BITMAPINFOHEADER * hdr) |
56 |
{ |
{ |
57 |
if (hdr->bV4Height < 0) |
if (hdr->biHeight < 0) |
58 |
{ |
{ |
59 |
DEBUG("colorspace: inverted input format not supported"); |
DEBUG("colorspace: inverted input format not supported"); |
60 |
return XVID_CSP_NULL; |
return XVID_CSP_NULL; |
61 |
} |
} |
62 |
|
|
63 |
switch(hdr->bV4V4Compression) |
switch(hdr->biCompression) |
64 |
{ |
{ |
65 |
case BI_RGB : |
case BI_RGB : |
66 |
if (hdr->bV4BitCount == 16) |
if (hdr->biBitCount == 16) |
67 |
{ |
{ |
68 |
DEBUG("RGB16 (RGB555)"); |
DEBUG("RGB16 (RGB555)"); |
69 |
return XVID_CSP_VFLIP | XVID_CSP_RGB555; |
return XVID_CSP_VFLIP | XVID_CSP_RGB555; |
70 |
} |
} |
71 |
if (hdr->bV4BitCount == 24) |
if (hdr->biBitCount == 24) |
72 |
{ |
{ |
73 |
DEBUG("RGB24"); |
DEBUG("RGB24"); |
74 |
return XVID_CSP_VFLIP | XVID_CSP_RGB24; |
return XVID_CSP_VFLIP | XVID_CSP_RGB24; |
75 |
} |
} |
76 |
if (hdr->bV4BitCount == 32) |
if (hdr->biBitCount == 32) |
77 |
{ |
{ |
78 |
DEBUG("RGB32"); |
DEBUG("RGB32"); |
79 |
return XVID_CSP_VFLIP | XVID_CSP_RGB32; |
return XVID_CSP_VFLIP | XVID_CSP_RGB32; |
80 |
} |
} |
81 |
|
|
82 |
DEBUG1("BI_RGB unsupported", hdr->bV4BitCount); |
DEBUG1("BI_RGB unsupported", hdr->biBitCount); |
83 |
return XVID_CSP_NULL; |
return XVID_CSP_NULL; |
84 |
|
|
85 |
case BI_BITFIELDS : |
// how do these work in BITMAPINFOHEADER ??? |
86 |
if(hdr->bV4BitCount == 16 && |
/* case BI_BITFIELDS : |
87 |
|
if (hdr->biBitCount == 16 |
88 |
|
if(hdr->biBitCount == 16 && |
89 |
hdr->bV4RedMask == 0x7c00 && |
hdr->bV4RedMask == 0x7c00 && |
90 |
hdr->bV4GreenMask == 0x3e0 && |
hdr->bV4GreenMask == 0x3e0 && |
91 |
hdr->bV4BlueMask == 0x1f) |
hdr->bV4BlueMask == 0x1f) |
104 |
|
|
105 |
DEBUG1("BI_FIELDS unsupported", hdr->bV4BitCount); |
DEBUG1("BI_FIELDS unsupported", hdr->bV4BitCount); |
106 |
return XVID_CSP_NULL; |
return XVID_CSP_NULL; |
107 |
|
*/ |
108 |
case FOURCC_I420: |
case FOURCC_I420: |
109 |
case FOURCC_IYUV: |
case FOURCC_IYUV: |
110 |
DEBUG("IYUY"); |
DEBUG("IYUY"); |
129 |
return XVID_CSP_UYVY; |
return XVID_CSP_UYVY; |
130 |
|
|
131 |
} |
} |
132 |
DEBUGFOURCC("colorspace: unknown", hdr->bV4V4Compression); |
DEBUGFOURCC("colorspace: unknown", hdr->biCompression); |
133 |
return XVID_CSP_NULL; |
return XVID_CSP_NULL; |
134 |
} |
} |
135 |
|
|
141 |
|
|
142 |
LRESULT compress_query(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput) |
LRESULT compress_query(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput) |
143 |
{ |
{ |
144 |
BITMAPV4HEADER * inhdr = (BITMAPV4HEADER *)&lpbiInput->bmiHeader; |
BITMAPINFOHEADER * inhdr = &lpbiInput->bmiHeader; |
145 |
BITMAPV4HEADER * outhdr = (BITMAPV4HEADER *)&lpbiOutput->bmiHeader; |
BITMAPINFOHEADER * outhdr = &lpbiOutput->bmiHeader; |
146 |
|
|
147 |
if (get_colorspace(inhdr) == XVID_CSP_NULL) |
if (get_colorspace(inhdr) == XVID_CSP_NULL) |
148 |
{ |
{ |
154 |
return ICERR_OK; |
return ICERR_OK; |
155 |
} |
} |
156 |
|
|
157 |
if (inhdr->bV4Width != outhdr->bV4Width || inhdr->bV4Height != outhdr->bV4Height || |
if (inhdr->biWidth != outhdr->biWidth || inhdr->biHeight != outhdr->biHeight || |
158 |
(outhdr->bV4V4Compression != FOURCC_XVID && outhdr->bV4V4Compression != FOURCC_DIVX)) |
(outhdr->biCompression != FOURCC_XVID && outhdr->biCompression != FOURCC_DIVX)) |
159 |
{ |
{ |
160 |
return ICERR_BADFORMAT; |
return ICERR_BADFORMAT; |
161 |
} |
} |
166 |
|
|
167 |
LRESULT compress_get_format(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput) |
LRESULT compress_get_format(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput) |
168 |
{ |
{ |
169 |
BITMAPV4HEADER * inhdr = (BITMAPV4HEADER *)&lpbiInput->bmiHeader; |
BITMAPINFOHEADER * inhdr = &lpbiInput->bmiHeader; |
170 |
BITMAPV4HEADER * outhdr = (BITMAPV4HEADER *)&lpbiOutput->bmiHeader; |
BITMAPINFOHEADER * outhdr = &lpbiOutput->bmiHeader; |
171 |
|
|
172 |
if (get_colorspace(inhdr) == XVID_CSP_NULL) |
if (get_colorspace(inhdr) == XVID_CSP_NULL) |
173 |
{ |
{ |
179 |
return sizeof(BITMAPV4HEADER); |
return sizeof(BITMAPV4HEADER); |
180 |
} |
} |
181 |
|
|
182 |
memcpy(outhdr, inhdr, sizeof(BITMAPV4HEADER)); |
memcpy(outhdr, inhdr, sizeof(BITMAPINFOHEADER)); |
183 |
outhdr->bV4Size = sizeof(BITMAPV4HEADER); |
outhdr->biSize = sizeof(BITMAPINFOHEADER); |
184 |
outhdr->bV4BitCount = 24; // or 16 |
outhdr->biBitCount = 24; // or 16 |
185 |
outhdr->bV4SizeImage = compress_get_size(codec, lpbiInput, lpbiOutput); |
outhdr->biSizeImage = compress_get_size(codec, lpbiInput, lpbiOutput); |
186 |
outhdr->bV4XPelsPerMeter = 0; |
outhdr->biXPelsPerMeter = 0; |
187 |
outhdr->bV4YPelsPerMeter = 0; |
outhdr->biYPelsPerMeter = 0; |
188 |
outhdr->bV4ClrUsed = 0; |
outhdr->biClrUsed = 0; |
189 |
outhdr->bV4ClrImportant = 0; |
outhdr->biClrImportant = 0; |
190 |
|
|
191 |
if (codec->config.fourcc_used == 0) |
if (codec->config.fourcc_used == 0) |
192 |
{ |
{ |
193 |
outhdr->bV4V4Compression = FOURCC_XVID; |
outhdr->biCompression = FOURCC_XVID; |
194 |
|
} |
195 |
|
else if (codec->config.fourcc_used == 1) |
196 |
|
{ |
197 |
|
outhdr->biCompression = FOURCC_DIVX; |
198 |
} |
} |
199 |
else |
else |
200 |
{ |
{ |
201 |
outhdr->bV4V4Compression = FOURCC_DIVX; |
outhdr->biCompression = FOURCC_DX50; |
202 |
} |
} |
203 |
|
|
204 |
return ICERR_OK; |
return ICERR_OK; |
207 |
|
|
208 |
LRESULT compress_get_size(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput) |
LRESULT compress_get_size(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput) |
209 |
{ |
{ |
210 |
BITMAPV4HEADER * outhdr = (BITMAPV4HEADER *)&lpbiOutput->bmiHeader; |
return lpbiOutput->bmiHeader.biWidth * lpbiOutput->bmiHeader.biHeight * 3; |
|
return outhdr->bV4Width * outhdr->bV4Height * 3; |
|
211 |
} |
} |
212 |
|
|
213 |
|
|
222 |
|
|
223 |
LRESULT compress_begin(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput) |
LRESULT compress_begin(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput) |
224 |
{ |
{ |
|
BITMAPV4HEADER * inhdr = (BITMAPV4HEADER *)&lpbiInput->bmiHeader; |
|
225 |
XVID_ENC_PARAM param; |
XVID_ENC_PARAM param; |
226 |
XVID_INIT_PARAM init_param; |
XVID_INIT_PARAM init_param; |
227 |
|
|
228 |
switch (codec->config.mode) |
switch (codec->config.mode) |
229 |
{ |
{ |
230 |
case DLG_MODE_CBR : |
case DLG_MODE_CBR : |
231 |
|
DEBUG1("bitrate: ", codec->config.bitrate); |
232 |
param.bitrate = codec->config.bitrate; |
param.bitrate = codec->config.bitrate; |
233 |
param.rc_buffersize = codec->config.rc_buffersize; |
param.rc_buffersize = codec->config.rc_buffersize; |
234 |
break; |
break; |
264 |
if((codec->config.cpu & XVID_CPU_FORCE) <= 0) |
if((codec->config.cpu & XVID_CPU_FORCE) <= 0) |
265 |
codec->config.cpu = init_param.cpu_flags; |
codec->config.cpu = init_param.cpu_flags; |
266 |
|
|
267 |
param.width = inhdr->bV4Width; |
param.width = lpbiInput->bmiHeader.biWidth; |
268 |
param.height = inhdr->bV4Height; |
param.height = lpbiInput->bmiHeader.biHeight; |
269 |
param.fincr = codec->fincr; |
param.fincr = codec->fincr; |
270 |
param.fbase = codec->fbase; |
param.fbase = codec->fbase; |
271 |
|
|
272 |
param.rc_buffersize = codec->config.rc_buffersize; |
param.rc_buffersize = codec->config.rc_buffersize; |
273 |
|
|
274 |
param.min_quantizer = codec->config.min_quant; |
param.min_quantizer = codec->config.min_pquant; |
275 |
param.max_quantizer = codec->config.max_quant; |
param.max_quantizer = codec->config.max_pquant; |
276 |
param.max_key_interval = codec->config.max_key_interval; |
param.max_key_interval = codec->config.max_key_interval; |
277 |
|
|
278 |
switch(xvid_encore(0, XVID_ENC_CREATE, ¶m, NULL)) |
switch(xvid_encore(0, XVID_ENC_CREATE, ¶m, NULL)) |
319 |
|
|
320 |
LRESULT compress(CODEC * codec, ICCOMPRESS * icc) |
LRESULT compress(CODEC * codec, ICCOMPRESS * icc) |
321 |
{ |
{ |
322 |
BITMAPV4HEADER * inhdr = (BITMAPV4HEADER *)icc->lpbiInput; |
BITMAPINFOHEADER * inhdr = icc->lpbiInput; |
323 |
BITMAPV4HEADER * outhdr = (BITMAPV4HEADER *)icc->lpbiOutput; |
BITMAPINFOHEADER * outhdr = icc->lpbiOutput; |
324 |
XVID_ENC_FRAME frame; |
XVID_ENC_FRAME frame; |
325 |
XVID_ENC_STATS stats; |
XVID_ENC_STATS stats; |
326 |
|
|
335 |
|
|
336 |
frame.general = 0; |
frame.general = 0; |
337 |
frame.motion = 0; |
frame.motion = 0; |
338 |
|
frame.intra = -1; |
|
if(codec->config.motion_search == 0) |
|
|
frame.intra = 1; |
|
339 |
|
|
340 |
frame.general |= XVID_HALFPEL; |
frame.general |= XVID_HALFPEL; |
341 |
|
|
342 |
if(codec->config.motion_search > 3) |
if(codec->config.motion_search > 3) |
343 |
frame.general |= XVID_INTER4V; |
frame.general |= XVID_INTER4V; |
344 |
|
|
|
// we actually need "default/custom" selectbox for both inter/intra |
|
|
// this will do for now |
|
|
|
|
|
if (codec->config.quant_type == QUANT_MODE_CUSTOM) |
|
|
{ |
|
|
frame.general |= XVID_CUSTOM_QMATRIX; |
|
|
frame.quant_intra_matrix = codec->config.qmatrix_intra; |
|
|
frame.quant_inter_matrix = codec->config.qmatrix_inter; |
|
|
} |
|
|
else |
|
|
{ |
|
|
frame.quant_intra_matrix = NULL; |
|
|
frame.quant_inter_matrix = NULL; |
|
|
} |
|
|
|
|
|
if(codec->config.quant_type == 0) |
|
|
frame.general |= XVID_H263QUANT; |
|
|
else |
|
|
frame.general |= XVID_MPEGQUANT; |
|
|
|
|
345 |
if(((codec->config.mode == DLG_MODE_2PASS_1) ? 0 : codec->config.lum_masking) == 1) |
if(((codec->config.mode == DLG_MODE_2PASS_1) ? 0 : codec->config.lum_masking) == 1) |
346 |
frame.general |= XVID_LUMIMASKING; |
frame.general |= XVID_LUMIMASKING; |
347 |
|
|
349 |
|
|
350 |
frame.image = icc->lpInput; |
frame.image = icc->lpInput; |
351 |
|
|
352 |
if ((frame.colorspace = get_colorspace(inhdr)) == XVID_CSP_NULL) { |
if ((frame.colorspace = get_colorspace(inhdr)) == XVID_CSP_NULL) |
353 |
return ICERR_BADFORMAT; |
return ICERR_BADFORMAT; |
|
} |
|
354 |
|
|
355 |
frame.bitstream = icc->lpOutput; |
frame.bitstream = icc->lpOutput; |
356 |
frame.length = icc->lpbiOutput->biSizeImage; |
frame.length = icc->lpbiOutput->biSizeImage; |
|
frame.intra = -1; |
|
357 |
|
|
358 |
switch (codec->config.mode) |
switch (codec->config.mode) |
359 |
{ |
{ |
378 |
} |
} |
379 |
if (codec->config.dummy2pass) |
if (codec->config.dummy2pass) |
380 |
{ |
{ |
381 |
outhdr->bV4SizeImage = codec->twopass.bytes2; |
outhdr->biSizeImage = codec->twopass.bytes2; |
382 |
*icc->lpdwFlags = (codec->twopass.nns1.quant & NNSTATS_KEYFRAME) ? AVIIF_KEYFRAME : 0; |
*icc->lpdwFlags = (codec->twopass.nns1.quant & NNSTATS_KEYFRAME) ? AVIIF_KEYFRAME : 0; |
383 |
return ICERR_OK; |
return ICERR_OK; |
384 |
} |
} |
385 |
break; |
break; |
386 |
|
|
387 |
case DLG_MODE_NULL : |
case DLG_MODE_NULL : |
388 |
outhdr->bV4SizeImage = 0; |
outhdr->biSizeImage = 0; |
389 |
*icc->lpdwFlags = AVIIF_KEYFRAME; |
*icc->lpdwFlags = AVIIF_KEYFRAME; |
390 |
return ICERR_OK; |
return ICERR_OK; |
391 |
|
|
394 |
return ICERR_ERROR; |
return ICERR_ERROR; |
395 |
} |
} |
396 |
|
|
397 |
// force keyframe spacing in 2-pass modes |
if (codec->config.quant_type == QUANT_MODE_H263) |
398 |
if ((codec->keyspacing < codec->config.min_key_interval && codec->framenum) && |
{ |
399 |
(codec->config.mode == DLG_MODE_2PASS_1 || codec->config.mode == DLG_MODE_2PASS_2_INT || |
frame.general |= XVID_H263QUANT; |
400 |
codec->config.mode == DLG_MODE_2PASS_2_EXT)) |
} |
401 |
|
else |
402 |
|
{ |
403 |
|
frame.general |= XVID_MPEGQUANT; |
404 |
|
|
405 |
|
// we actually need "default/custom" selectbox for both inter/intra |
406 |
|
// this will do for now |
407 |
|
if (codec->config.quant_type == QUANT_MODE_CUSTOM) |
408 |
|
{ |
409 |
|
frame.general |= XVID_CUSTOM_QMATRIX; |
410 |
|
frame.quant_intra_matrix = codec->config.qmatrix_intra; |
411 |
|
frame.quant_inter_matrix = codec->config.qmatrix_inter; |
412 |
|
} |
413 |
|
else |
414 |
|
{ |
415 |
|
frame.quant_intra_matrix = NULL; |
416 |
|
frame.quant_inter_matrix = NULL; |
417 |
|
} |
418 |
|
} |
419 |
|
|
420 |
|
// force keyframe spacing in 2-pass 1st pass |
421 |
|
if (codec->config.motion_search == 0) |
422 |
|
{ |
423 |
|
frame.intra = 1; |
424 |
|
} |
425 |
|
else if ((codec->keyspacing < codec->config.min_key_interval && codec->framenum) && |
426 |
|
(codec->config.mode == DLG_MODE_2PASS_1)) |
427 |
{ |
{ |
428 |
DEBUG("current frame forced to p-frame"); |
DEBUG("current frame forced to p-frame"); |
429 |
frame.intra = 0; |
frame.intra = 0; |
451 |
*icc->lpdwFlags = 0; |
*icc->lpdwFlags = 0; |
452 |
} |
} |
453 |
|
|
454 |
outhdr->bV4SizeImage = frame.length; |
outhdr->biSizeImage = frame.length; |
455 |
|
|
456 |
if (codec->config.mode == DLG_MODE_2PASS_1) |
if (codec->config.mode == DLG_MODE_2PASS_1 && codec->config.discard1pass) |
457 |
{ |
{ |
458 |
if (codec->config.discard1pass) |
outhdr->biSizeImage = 0; |
|
{ |
|
|
outhdr->bV4SizeImage = 0; |
|
|
} |
|
459 |
} |
} |
460 |
|
|
461 |
codec_2pass_update(codec, &frame, &stats); |
codec_2pass_update(codec, &frame, &stats); |
472 |
|
|
473 |
LRESULT decompress_query(CODEC * codec, BITMAPINFO *lpbiInput, BITMAPINFO *lpbiOutput) |
LRESULT decompress_query(CODEC * codec, BITMAPINFO *lpbiInput, BITMAPINFO *lpbiOutput) |
474 |
{ |
{ |
475 |
BITMAPV4HEADER * inhdr = (BITMAPV4HEADER *)&lpbiInput->bmiHeader; |
BITMAPINFOHEADER * inhdr = &lpbiInput->bmiHeader; |
476 |
BITMAPV4HEADER * outhdr = (BITMAPV4HEADER *)&lpbiOutput->bmiHeader; |
BITMAPINFOHEADER * outhdr = &lpbiOutput->bmiHeader; |
477 |
|
|
478 |
if (lpbiInput == NULL) |
if (lpbiInput == NULL) |
479 |
{ |
{ |
480 |
return ICERR_ERROR; |
return ICERR_ERROR; |
481 |
} |
} |
482 |
|
|
483 |
if (inhdr->bV4V4Compression != FOURCC_XVID && inhdr->bV4V4Compression != FOURCC_DIVX) |
if (inhdr->biCompression != FOURCC_XVID && inhdr->biCompression != FOURCC_DIVX) |
484 |
{ |
{ |
485 |
return ICERR_BADFORMAT; |
return ICERR_BADFORMAT; |
486 |
} |
} |
490 |
return ICERR_OK; |
return ICERR_OK; |
491 |
} |
} |
492 |
|
|
493 |
if (inhdr->bV4Width != outhdr->bV4Width || |
if (inhdr->biWidth != outhdr->biWidth || |
494 |
inhdr->bV4Height != outhdr->bV4Height || |
inhdr->biHeight != outhdr->biHeight || |
495 |
get_colorspace(outhdr) == XVID_CSP_NULL) |
get_colorspace(outhdr) == XVID_CSP_NULL) |
496 |
{ |
{ |
497 |
return ICERR_BADFORMAT; |
return ICERR_BADFORMAT; |
503 |
|
|
504 |
LRESULT decompress_get_format(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput) |
LRESULT decompress_get_format(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput) |
505 |
{ |
{ |
506 |
BITMAPV4HEADER * inhdr = (BITMAPV4HEADER *)&lpbiInput->bmiHeader; |
BITMAPINFOHEADER * inhdr = &lpbiInput->bmiHeader; |
507 |
BITMAPV4HEADER * outhdr = (BITMAPV4HEADER *)&lpbiOutput->bmiHeader; |
BITMAPINFOHEADER * outhdr = &lpbiOutput->bmiHeader; |
508 |
LRESULT result; |
LRESULT result; |
509 |
|
|
510 |
if (lpbiOutput == NULL) |
if (lpbiOutput == NULL) |
511 |
{ |
{ |
512 |
return sizeof(BITMAPV4HEADER); |
return sizeof(BITMAPINFOHEADER); |
513 |
} |
} |
514 |
|
|
515 |
result = decompress_query(codec, lpbiInput, lpbiOutput); |
result = decompress_query(codec, lpbiInput, lpbiOutput); |
518 |
return result; |
return result; |
519 |
} |
} |
520 |
|
|
521 |
memcpy(outhdr, inhdr, sizeof(BITMAPV4HEADER)); |
memcpy(outhdr, inhdr, sizeof(BITMAPINFOHEADER)); |
522 |
outhdr->bV4Size = sizeof(BITMAPV4HEADER); |
outhdr->biSize = sizeof(BITMAPINFOHEADER); |
523 |
outhdr->bV4V4Compression = FOURCC_YUY2; |
outhdr->biCompression = FOURCC_YUY2; |
524 |
outhdr->bV4SizeImage = outhdr->bV4Width * outhdr->bV4Height * outhdr->bV4BitCount; |
outhdr->biSizeImage = outhdr->biWidth * outhdr->biHeight * outhdr->biBitCount; |
525 |
outhdr->bV4XPelsPerMeter = 0; |
outhdr->biXPelsPerMeter = 0; |
526 |
outhdr->bV4YPelsPerMeter = 0; |
outhdr->biYPelsPerMeter = 0; |
527 |
outhdr->bV4ClrUsed = 0; |
outhdr->biClrUsed = 0; |
528 |
outhdr->bV4ClrImportant = 0; |
outhdr->biClrImportant = 0; |
529 |
|
|
530 |
return ICERR_OK; |
return ICERR_OK; |
531 |
} |
} |
533 |
|
|
534 |
LRESULT decompress_begin(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput) |
LRESULT decompress_begin(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput) |
535 |
{ |
{ |
|
BITMAPV4HEADER * inhdr = (BITMAPV4HEADER *)&lpbiInput->bmiHeader; |
|
|
BITMAPV4HEADER * outhdr = (BITMAPV4HEADER *)&lpbiOutput->bmiHeader; |
|
536 |
XVID_DEC_PARAM param; |
XVID_DEC_PARAM param; |
537 |
XVID_INIT_PARAM init_param; |
XVID_INIT_PARAM init_param; |
538 |
|
|
543 |
codec->config.cpu = init_param.cpu_flags; |
codec->config.cpu = init_param.cpu_flags; |
544 |
} |
} |
545 |
|
|
546 |
param.width = inhdr->bV4Width; |
param.width = lpbiInput->bmiHeader.biWidth; |
547 |
param.height = inhdr->bV4Height; |
param.height = lpbiInput->bmiHeader.biHeight; |
548 |
|
|
549 |
switch(xvid_decore(0, XVID_DEC_CREATE, ¶m, NULL)) |
switch(xvid_decore(0, XVID_DEC_CREATE, ¶m, NULL)) |
550 |
{ |
{ |
577 |
|
|
578 |
LRESULT decompress(CODEC * codec, ICDECOMPRESS * icd) |
LRESULT decompress(CODEC * codec, ICDECOMPRESS * icd) |
579 |
{ |
{ |
|
BITMAPV4HEADER * inhdr = (BITMAPV4HEADER *)icd->lpbiInput; |
|
|
BITMAPV4HEADER * outhdr = (BITMAPV4HEADER *)icd->lpbiOutput; |
|
580 |
XVID_DEC_FRAME frame; |
XVID_DEC_FRAME frame; |
581 |
|
|
582 |
frame.bitstream = icd->lpInput; |
frame.bitstream = icd->lpInput; |
587 |
|
|
588 |
if (~((icd->dwFlags & ICDECOMPRESS_HURRYUP) | (icd->dwFlags & ICDECOMPRESS_UPDATE))) |
if (~((icd->dwFlags & ICDECOMPRESS_HURRYUP) | (icd->dwFlags & ICDECOMPRESS_UPDATE))) |
589 |
{ |
{ |
590 |
if ((frame.colorspace = get_colorspace(outhdr)) == XVID_CSP_NULL) |
if ((frame.colorspace = get_colorspace(icd->lpbiOutput)) == XVID_CSP_NULL) |
591 |
{ |
{ |
592 |
return ICERR_BADFORMAT; |
return ICERR_BADFORMAT; |
593 |
} |
} |
1012 |
{ |
{ |
1013 |
case CREDITS_MODE_RATE : |
case CREDITS_MODE_RATE : |
1014 |
frame->quant = |
frame->quant = |
1015 |
codec->config.max_quant - |
codec->config.max_pquant - |
1016 |
((codec->config.max_quant - codec->config.quant) * codec->config.credits_rate / 100); |
((codec->config.max_pquant - codec->config.quant) * codec->config.credits_rate / 100); |
1017 |
break; |
break; |
1018 |
|
|
1019 |
case CREDITS_MODE_QUANT : |
case CREDITS_MODE_QUANT : |
1304 |
} |
} |
1305 |
else |
else |
1306 |
{ |
{ |
1307 |
if (frame->quant > codec->config.max_quant) |
if (frame->quant > codec->config.max_pquant) |
1308 |
{ |
{ |
1309 |
frame->quant = codec->config.max_quant; |
frame->quant = codec->config.max_pquant; |
1310 |
} |
} |
1311 |
if (frame->quant < codec->config.min_quant) |
if (frame->quant < codec->config.min_pquant) |
1312 |
{ |
{ |
1313 |
frame->quant = codec->config.min_quant; |
frame->quant = codec->config.min_pquant; |
1314 |
} |
} |
1315 |
|
|
1316 |
// subsequent frame quants can only be +- 2 |
// subsequent frame quants can only be +- 2 |
1331 |
|
|
1332 |
last_quant = frame->quant; |
last_quant = frame->quant; |
1333 |
|
|
1334 |
|
if (codec->config.quant_type == QUANT_MODE_MOD) |
1335 |
|
{ |
1336 |
|
frame->general |= (frame->quant < 4) ? XVID_MPEGQUANT : XVID_H263QUANT; |
1337 |
|
frame->general &= (frame->quant < 4) ? ~XVID_H263QUANT : ~XVID_MPEGQUANT; |
1338 |
|
} |
1339 |
|
|
1340 |
return ICERR_OK; |
return ICERR_OK; |
1341 |
} |
} |
1342 |
|
|
1347 |
|
|
1348 |
NNSTATS nns1; |
NNSTATS nns1; |
1349 |
DWORD wrote; |
DWORD wrote; |
1350 |
|
char* quant_type; |
1351 |
|
|
1352 |
if (codec->framenum == 0) |
if (codec->framenum == 0) |
1353 |
{ |
{ |
1354 |
total_size = 0; |
total_size = 0; |
1355 |
} |
} |
1356 |
|
|
1357 |
|
quant_type = (frame->general & XVID_H263QUANT) ? "H.263" : |
1358 |
|
(frame->general & XVID_MPEGQUANT) ? "MPEG" : "Cust"; |
1359 |
|
|
1360 |
switch (codec->config.mode) |
switch (codec->config.mode) |
1361 |
{ |
{ |
1362 |
case DLG_MODE_2PASS_1 : |
case DLG_MODE_2PASS_1 : |
1379 |
nns1.lum_noise[0] = nns1.lum_noise[1] = 1; |
nns1.lum_noise[0] = nns1.lum_noise[1] = 1; |
1380 |
|
|
1381 |
total_size += frame->length; |
total_size += frame->length; |
1382 |
DEBUG1ST(frame->length, (int)total_size/1024, frame->intra, frame->quant, stats->kblks, stats->mblks) |
|
1383 |
|
DEBUG1ST(frame->length, (int)total_size/1024, frame->intra, frame->quant, quant_type, stats->kblks, stats->mblks) |
1384 |
|
|
1385 |
if (WriteFile(codec->twopass.stats1, &nns1, sizeof(NNSTATS), &wrote, 0) == 0 || wrote != sizeof(NNSTATS)) |
if (WriteFile(codec->twopass.stats1, &nns1, sizeof(NNSTATS), &wrote, 0) == 0 || wrote != sizeof(NNSTATS)) |
1386 |
{ |
{ |
1392 |
case DLG_MODE_2PASS_2_INT : |
case DLG_MODE_2PASS_2_INT : |
1393 |
case DLG_MODE_2PASS_2_EXT : |
case DLG_MODE_2PASS_2_EXT : |
1394 |
codec->twopass.overflow += codec->twopass.desired_bytes2 - frame->length; |
codec->twopass.overflow += codec->twopass.desired_bytes2 - frame->length; |
1395 |
DEBUG2ND(frame->quant, frame->intra, codec->twopass.bytes1, codec->twopass.desired_bytes2, frame->length, codec->twopass.overflow, codec_is_in_credits(&codec->config, codec->framenum)) |
DEBUG2ND(frame->quant, quant_type, frame->intra, codec->twopass.bytes1, codec->twopass.desired_bytes2, frame->length, codec->twopass.overflow, codec_is_in_credits(&codec->config, codec->framenum)) |
1396 |
break; |
break; |
1397 |
|
|
1398 |
default: |
default: |
1405 |
|
|
1406 |
int codec_is_in_credits(CONFIG* config, int framenum) |
int codec_is_in_credits(CONFIG* config, int framenum) |
1407 |
{ |
{ |
|
if (config->mode == DLG_MODE_2PASS_2_EXT) |
|
|
{ |
|
|
return 0; |
|
|
} |
|
|
|
|
1408 |
if (config->credits_start) |
if (config->credits_start) |
1409 |
{ |
{ |
1410 |
if (framenum >= config->credits_start_begin && |
if (framenum >= config->credits_start_begin && |
1445 |
if (!config->fquant) |
if (!config->fquant) |
1446 |
{ |
{ |
1447 |
config->fquant = |
config->fquant = |
1448 |
((float) (config->max_quant - config->min_quant) / 100) * |
((float) (config->max_pquant - config->min_pquant) / 100) * |
1449 |
(100 - quality) + |
(100 - quality) + |
1450 |
(float) config->min_quant; |
(float) config->min_pquant; |
1451 |
|
|
1452 |
fquant_running = config->fquant; |
fquant_running = config->fquant; |
1453 |
} |
} |
1454 |
|
|
1455 |
if (fquant_running < config->min_quant) |
if (fquant_running < config->min_pquant) |
1456 |
{ |
{ |
1457 |
fquant_running = (float) config->min_quant; |
fquant_running = (float) config->min_pquant; |
1458 |
} |
} |
1459 |
else if(fquant_running > config->max_quant) |
else if(fquant_running > config->max_pquant) |
1460 |
{ |
{ |
1461 |
fquant_running = (float) config->max_quant; |
fquant_running = (float) config->max_pquant; |
1462 |
} |
} |
1463 |
|
|
1464 |
quant = (int) fquant_running; |
quant = (int) fquant_running; |