54 |
#include "2pass.h" |
#include "2pass.h" |
55 |
|
|
56 |
int pmvfast_presets[7] = { |
int pmvfast_presets[7] = { |
57 |
0, PMV_QUICKSTOP16, 0, 0, |
0, PMV_QUICKSTOP16, PMV_EARLYSTOP16, PMV_EARLYSTOP16 | PMV_EARLYSTOP8, |
58 |
0 | PMV_HALFPELREFINE16 | PMV_HALFPELDIAMOND8, |
PMV_EARLYSTOP16 | PMV_HALFPELREFINE16 | PMV_EARLYSTOP8 | PMV_HALFPELDIAMOND8, |
59 |
0 | PMV_HALFPELREFINE16 | PMV_HALFPELDIAMOND8 | |
PMV_EARLYSTOP16 | PMV_HALFPELREFINE16 | PMV_EARLYSTOP8 | PMV_HALFPELDIAMOND8 | |
60 |
PMV_ADVANCEDDIAMOND16, PMV_HALFPELREFINE16 | PMV_EXTSEARCH16 | |
PMV_ADVANCEDDIAMOND16, PMV_EARLYSTOP16 | PMV_HALFPELREFINE16 | PMV_EXTSEARCH16 | |
61 |
PMV_HALFPELREFINE8 | PMV_HALFPELDIAMOND8 | PMV_USESQUARES16 |
PMV_EARLYSTOP8 | PMV_HALFPELREFINE8 | PMV_HALFPELDIAMOND8 | PMV_USESQUARES16 |
62 |
}; |
}; |
63 |
|
|
64 |
/* return xvid compatbile colorspace, |
/* return xvid compatbile colorspace, |
67 |
|
|
68 |
int get_colorspace(BITMAPINFOHEADER * hdr) |
int get_colorspace(BITMAPINFOHEADER * hdr) |
69 |
{ |
{ |
70 |
/* rgb only: negative height specifies top down image */ |
if (hdr->biHeight < 0) |
71 |
int rgb_flip = (hdr->biHeight < 0 ? 0 : XVID_CSP_VFLIP); |
{ |
72 |
|
DEBUGERR("colorspace: inverted input format not supported"); |
73 |
|
return XVID_CSP_NULL; |
74 |
|
} |
75 |
|
|
76 |
switch(hdr->biCompression) |
switch(hdr->biCompression) |
77 |
{ |
{ |
79 |
if (hdr->biBitCount == 16) |
if (hdr->biBitCount == 16) |
80 |
{ |
{ |
81 |
DEBUG("RGB16 (RGB555)"); |
DEBUG("RGB16 (RGB555)"); |
82 |
return rgb_flip | XVID_CSP_RGB555; |
return XVID_CSP_VFLIP | XVID_CSP_RGB555; |
83 |
} |
} |
84 |
if (hdr->biBitCount == 24) |
if (hdr->biBitCount == 24) |
85 |
{ |
{ |
86 |
DEBUG("RGB24"); |
DEBUG("RGB24"); |
87 |
return rgb_flip | XVID_CSP_RGB24; |
return XVID_CSP_VFLIP | XVID_CSP_RGB24; |
88 |
} |
} |
89 |
if (hdr->biBitCount == 32) |
if (hdr->biBitCount == 32) |
90 |
{ |
{ |
91 |
DEBUG("RGB32"); |
DEBUG("RGB32"); |
92 |
return rgb_flip | XVID_CSP_RGB32; |
return XVID_CSP_VFLIP | XVID_CSP_RGB32; |
93 |
} |
} |
94 |
|
|
95 |
DEBUG1("unsupported BI_RGB biBitCount", hdr->biBitCount); |
DEBUG1("BI_RGB unsupported", hdr->biBitCount); |
96 |
return XVID_CSP_NULL; |
return XVID_CSP_NULL; |
97 |
|
|
98 |
case BI_BITFIELDS : |
// how do these work in BITMAPINFOHEADER ??? |
99 |
if (hdr->biSize >= sizeof(BITMAPV4HEADER)) |
/* case BI_BITFIELDS : |
100 |
{ |
if (hdr->biBitCount == 16 |
101 |
BITMAPV4HEADER * hdr4 = (BITMAPV4HEADER *)hdr; |
if(hdr->biBitCount == 16 && |
102 |
|
hdr->bV4RedMask == 0x7c00 && |
103 |
if (hdr4->bV4BitCount == 16 && |
hdr->bV4GreenMask == 0x3e0 && |
104 |
hdr4->bV4RedMask == 0x7c00 && |
hdr->bV4BlueMask == 0x1f) |
|
hdr4->bV4GreenMask == 0x3e0 && |
|
|
hdr4->bV4BlueMask == 0x1f) |
|
105 |
{ |
{ |
106 |
DEBUG("RGB555"); |
DEBUG("RGB555"); |
107 |
return rgb_flip | XVID_CSP_RGB555; |
return XVID_CSP_VFLIP | XVID_CSP_RGB555; |
108 |
} |
} |
109 |
|
if(hdr->bV4BitCount == 16 && |
110 |
if(hdr4->bV4BitCount == 16 && |
hdr->bV4RedMask == 0xf800 && |
111 |
hdr4->bV4RedMask == 0xf800 && |
hdr->bV4GreenMask == 0x7e0 && |
112 |
hdr4->bV4GreenMask == 0x7e0 && |
hdr->bV4BlueMask == 0x1f) |
|
hdr4->bV4BlueMask == 0x1f) |
|
113 |
{ |
{ |
114 |
DEBUG("RGB565"); |
DEBUG("RGB565"); |
115 |
return rgb_flip | XVID_CSP_RGB565; |
return XVID_CSP_VFLIP | XVID_CSP_RGB565; |
116 |
} |
} |
117 |
|
|
118 |
DEBUG("unsupported BI_BITFIELDS mode"); |
DEBUG1("BI_FIELDS unsupported", hdr->bV4BitCount); |
119 |
return XVID_CSP_NULL; |
return XVID_CSP_NULL; |
120 |
} |
*/ |
|
|
|
|
DEBUG("unsupported BI_BITFIELDS/BITMAPHEADER combination"); |
|
|
return XVID_CSP_NULL; |
|
|
|
|
121 |
case FOURCC_I420 : |
case FOURCC_I420 : |
122 |
case FOURCC_IYUV : |
case FOURCC_IYUV : |
123 |
DEBUG("IYUY"); |
DEBUG("IYUY"); |
129 |
|
|
130 |
case FOURCC_YUYV : |
case FOURCC_YUYV : |
131 |
case FOURCC_YUY2 : |
case FOURCC_YUY2 : |
132 |
|
case FOURCC_V422 : |
133 |
DEBUG("YUY2"); |
DEBUG("YUY2"); |
134 |
return XVID_CSP_YUY2; |
return XVID_CSP_YUY2; |
135 |
|
|
141 |
DEBUG("UYVY"); |
DEBUG("UYVY"); |
142 |
return XVID_CSP_UYVY; |
return XVID_CSP_UYVY; |
143 |
|
|
|
default : |
|
|
DEBUGFOURCC("unsupported colorspace", hdr->biCompression); |
|
|
return XVID_CSP_NULL; |
|
144 |
} |
} |
145 |
|
DEBUGFOURCC("colorspace: unknown", hdr->biCompression); |
146 |
|
return XVID_CSP_NULL; |
147 |
} |
} |
148 |
|
|
149 |
|
|
168 |
} |
} |
169 |
|
|
170 |
if (inhdr->biWidth != outhdr->biWidth || inhdr->biHeight != outhdr->biHeight || |
if (inhdr->biWidth != outhdr->biWidth || inhdr->biHeight != outhdr->biHeight || |
171 |
(outhdr->biCompression != FOURCC_XVID && outhdr->biCompression != FOURCC_DIVX && outhdr->biCompression != FOURCC_DX50)) |
(outhdr->biCompression != FOURCC_XVID && outhdr->biCompression != FOURCC_DIVX)) |
172 |
{ |
{ |
173 |
return ICERR_BADFORMAT; |
return ICERR_BADFORMAT; |
174 |
} |
} |
194 |
|
|
195 |
memcpy(outhdr, inhdr, sizeof(BITMAPINFOHEADER)); |
memcpy(outhdr, inhdr, sizeof(BITMAPINFOHEADER)); |
196 |
outhdr->biSize = sizeof(BITMAPINFOHEADER); |
outhdr->biSize = sizeof(BITMAPINFOHEADER); |
197 |
|
outhdr->biBitCount = 24; // or 16 |
198 |
outhdr->biSizeImage = compress_get_size(codec, lpbiInput, lpbiOutput); |
outhdr->biSizeImage = compress_get_size(codec, lpbiInput, lpbiOutput); |
199 |
outhdr->biXPelsPerMeter = 0; |
outhdr->biXPelsPerMeter = 0; |
200 |
outhdr->biYPelsPerMeter = 0; |
outhdr->biYPelsPerMeter = 0; |
220 |
|
|
221 |
LRESULT compress_get_size(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput) |
LRESULT compress_get_size(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput) |
222 |
{ |
{ |
223 |
return 2 * lpbiOutput->bmiHeader.biWidth * lpbiOutput->bmiHeader.biHeight * 3; |
return |
224 |
|
#ifdef BFRAMES |
225 |
|
2 * |
226 |
|
#endif |
227 |
|
lpbiOutput->bmiHeader.biWidth * lpbiOutput->bmiHeader.biHeight * 3; |
228 |
} |
} |
229 |
|
|
230 |
|
|
299 |
param.num_threads = codec->config.num_threads; |
param.num_threads = codec->config.num_threads; |
300 |
#endif |
#endif |
301 |
|
|
302 |
|
#ifdef BFRAMES |
303 |
param.global = 0; |
param.global = 0; |
304 |
if (codec->config.packed) param.global |= XVID_GLOBAL_PACKED; |
if (codec->config.packed) param.global |= XVID_GLOBAL_PACKED; |
305 |
if (codec->config.dx50bvop) param.global |= XVID_GLOBAL_DX50BVOP; |
if (codec->config.dx50bvop) param.global |= XVID_GLOBAL_DX50BVOP; |
306 |
if (codec->config.debug) param.global |= XVID_GLOBAL_DEBUG; |
if (codec->config.debug) param.global |= XVID_GLOBAL_DEBUG; |
|
if (codec->config.reduced_resolution) param.global |= XVID_GLOBAL_REDUCED; |
|
307 |
param.max_bframes = codec->config.max_bframes; |
param.max_bframes = codec->config.max_bframes; |
308 |
param.bquant_ratio = codec->config.bquant_ratio; |
param.bquant_ratio = codec->config.bquant_ratio; |
|
param.bquant_offset = codec->config.bquant_offset; |
|
309 |
param.frame_drop_ratio = codec->config.frame_drop_ratio; |
param.frame_drop_ratio = codec->config.frame_drop_ratio; |
310 |
|
#endif |
311 |
|
|
312 |
switch(xvid_encore(0, XVID_ENC_CREATE, ¶m, NULL)) |
switch(xvid_encore(0, XVID_ENC_CREATE, ¶m, NULL)) |
313 |
{ |
{ |
397 |
if (codec->config.interlacing) |
if (codec->config.interlacing) |
398 |
frame.general |= XVID_INTERLACING; |
frame.general |= XVID_INTERLACING; |
399 |
|
|
|
if (codec->config.qpel) { |
|
|
frame.general |= XVID_QUARTERPEL; |
|
|
frame.motion |= PMV_QUARTERPELREFINE16 | PMV_QUARTERPELREFINE8; |
|
|
} |
|
|
|
|
|
if (codec->config.gmc) |
|
|
frame.general |= XVID_GMC; |
|
|
|
|
|
if (codec->config.chromame) |
|
|
frame.general |= XVID_ME_COLOUR; |
|
400 |
|
|
|
if (codec->config.reduced_resolution) |
|
|
frame.general |= XVID_REDUCED; |
|
401 |
|
|
402 |
// added by koepi for credits greyscale |
// added by koepi for credits greyscale |
403 |
|
|
445 |
} |
} |
446 |
} |
} |
447 |
|
|
448 |
frame.motion |= pmvfast_presets[codec->config.motion_search]; |
frame.motion = pmvfast_presets[codec->config.motion_search]; |
449 |
|
|
450 |
frame.image = icc->lpInput; |
frame.image = icc->lpInput; |
|
frame.stride = (((icc->lpbiInput->biWidth * icc->lpbiInput->biBitCount) + 31) & ~31) >> 3; |
|
451 |
|
|
452 |
if ((frame.colorspace = get_colorspace(inhdr)) == XVID_CSP_NULL) |
if ((frame.colorspace = get_colorspace(inhdr)) == XVID_CSP_NULL) |
453 |
return ICERR_BADFORMAT; |
return ICERR_BADFORMAT; |
454 |
|
|
|
if (frame.colorspace == XVID_CSP_I420 || frame.colorspace == XVID_CSP_YV12) |
|
|
frame.stride = (frame.stride*2)/3; |
|
|
|
|
455 |
frame.bitstream = icc->lpOutput; |
frame.bitstream = icc->lpOutput; |
456 |
frame.length = icc->lpbiOutput->biSizeImage; |
frame.length = icc->lpbiOutput->biSizeImage; |
457 |
|
|
528 |
frame.intra = 0; |
frame.intra = 0; |
529 |
} |
} |
530 |
|
|
531 |
|
#ifdef BFRAMES |
532 |
frame.bquant = 0; |
frame.bquant = 0; |
533 |
|
#endif |
534 |
|
|
535 |
// OutputDebugString(" "); |
// OutputDebugString(" "); |
536 |
switch (xvid_encore(codec->ehandle, XVID_ENC_ENCODE, &frame, &stats)) |
switch (xvid_encore(codec->ehandle, XVID_ENC_ENCODE, &frame, &stats)) |
545 |
return ICERR_BADFORMAT; |
return ICERR_BADFORMAT; |
546 |
} |
} |
547 |
|
|
548 |
if (frame.intra==1) |
if (frame.intra) |
549 |
{ |
{ |
550 |
codec->keyspacing = 0; |
codec->keyspacing = 0; |
551 |
*icc->lpdwFlags = AVIIF_KEYFRAME; |
*icc->lpdwFlags = AVIIF_KEYFRAME; |
584 |
} |
} |
585 |
} |
} |
586 |
|
|
|
//quick fix for delayed frames |
|
|
// if (frame.intra != 5) |
|
587 |
codec_2pass_update(codec, &frame, &stats); |
codec_2pass_update(codec, &frame, &stats); |
588 |
|
|
589 |
++codec->framenum; |
++codec->framenum; |
606 |
return ICERR_ERROR; |
return ICERR_ERROR; |
607 |
} |
} |
608 |
|
|
609 |
if (inhdr->biCompression != FOURCC_XVID && inhdr->biCompression != FOURCC_DIVX && inhdr->biCompression != FOURCC_DX50 && get_colorspace(inhdr) == XVID_CSP_NULL) |
if (inhdr->biCompression != FOURCC_XVID && inhdr->biCompression != FOURCC_DIVX) |
610 |
{ |
{ |
611 |
return ICERR_BADFORMAT; |
return ICERR_BADFORMAT; |
612 |
} |
} |
638 |
return sizeof(BITMAPINFOHEADER); |
return sizeof(BITMAPINFOHEADER); |
639 |
} |
} |
640 |
|
|
|
/* --- yv12 --- */ |
|
|
|
|
|
if (get_colorspace(inhdr) != XVID_CSP_NULL) { |
|
|
memcpy(outhdr, inhdr, sizeof(BITMAPINFOHEADER)); |
|
|
// XXX: should we set outhdr->biSize ?? |
|
|
return ICERR_OK; |
|
|
} |
|
|
/* --- yv12 --- */ |
|
|
|
|
641 |
result = decompress_query(codec, lpbiInput, lpbiOutput); |
result = decompress_query(codec, lpbiInput, lpbiOutput); |
642 |
if (result != ICERR_OK) |
if (result != ICERR_OK) |
643 |
{ |
{ |
707 |
|
|
708 |
frame.bitstream = icd->lpInput; |
frame.bitstream = icd->lpInput; |
709 |
frame.length = icd->lpbiInput->biSizeImage; |
frame.length = icd->lpbiInput->biSizeImage; |
|
frame.general = XVID_DEC_LOWDELAY; /* force low_delay_default mode */ |
|
|
if (codec->config.deblock_y) |
|
|
frame.general |= XVID_DEC_DEBLOCKY; |
|
|
if (codec->config.deblock_uv) |
|
|
frame.general |= XVID_DEC_DEBLOCKUV; |
|
710 |
|
|
711 |
frame.image = icd->lpOutput; |
frame.image = icd->lpOutput; |
712 |
frame.stride = (((icd->lpbiOutput->biWidth * icd->lpbiOutput->biBitCount) + 31) & ~31) >> 3; |
frame.stride = icd->lpbiOutput->biWidth; |
|
|
|
|
/* --- yv12 --- */ |
|
|
if (icd->lpbiInput->biCompression != FOURCC_XVID && |
|
|
icd->lpbiInput->biCompression != FOURCC_DIVX && |
|
|
icd->lpbiInput->biCompression != FOURCC_DX50) |
|
|
{ |
|
|
XVID_INIT_CONVERTINFO convert; |
|
|
DEBUGFOURCC("input", icd->lpbiInput->biCompression); |
|
|
DEBUGFOURCC("output", icd->lpbiOutput->biCompression); |
|
|
convert.input.colorspace = get_colorspace(icd->lpbiInput); |
|
|
convert.input.y = icd->lpInput; |
|
|
convert.input.y_stride = (((icd->lpbiInput->biWidth *icd->lpbiInput->biBitCount) + 31) & ~31) >> 3; |
|
|
if (convert.input.colorspace == XVID_CSP_I420 || convert.input.colorspace == XVID_CSP_YV12) |
|
|
convert.input.y_stride = (convert.input.y_stride*2)/3; |
|
|
|
|
|
convert.output.colorspace = get_colorspace(icd->lpbiOutput); |
|
|
convert.output.y = icd->lpOutput; |
|
|
convert.output.y_stride = (((icd->lpbiOutput->biWidth *icd->lpbiOutput->biBitCount) + 31) & ~31) >> 3; |
|
|
if (convert.output.colorspace == XVID_CSP_I420 || convert.output.colorspace == XVID_CSP_YV12) |
|
|
convert.output.y_stride = (convert.output.y_stride*2)/3; |
|
|
|
|
|
convert.width = icd->lpbiInput->biWidth; |
|
|
convert.height = icd->lpbiInput->biHeight; |
|
|
convert.interlacing = 0; |
|
|
if (convert.input.colorspace == XVID_CSP_NULL || |
|
|
convert.output.colorspace == XVID_CSP_NULL || |
|
|
xvid_init(NULL, XVID_INIT_CONVERT, &convert, NULL) != XVID_ERR_OK) |
|
|
{ |
|
|
return ICERR_BADFORMAT; |
|
|
} |
|
|
return ICERR_OK; |
|
|
} |
|
|
/* --- yv12 --- */ |
|
|
|
|
713 |
|
|
714 |
if (~((icd->dwFlags & ICDECOMPRESS_HURRYUP) | (icd->dwFlags & ICDECOMPRESS_UPDATE) | (icd->dwFlags & ICDECOMPRESS_PREROLL))) |
if (~((icd->dwFlags & ICDECOMPRESS_HURRYUP) | (icd->dwFlags & ICDECOMPRESS_UPDATE) | (icd->dwFlags & ICDECOMPRESS_PREROLL))) |
715 |
{ |
{ |
723 |
frame.colorspace = XVID_CSP_NULL; |
frame.colorspace = XVID_CSP_NULL; |
724 |
} |
} |
725 |
|
|
|
if (frame.colorspace == XVID_CSP_I420 || frame.colorspace == XVID_CSP_YV12) |
|
|
frame.stride = (frame.stride*2)/3; |
|
|
|
|
726 |
switch (xvid_decore(codec->dhandle, XVID_DEC_DECODE, &frame, NULL)) |
switch (xvid_decore(codec->dhandle, XVID_DEC_DECODE, &frame, NULL)) |
727 |
{ |
{ |
728 |
case XVID_ERR_FAIL : |
case XVID_ERR_FAIL : |