[svn] / branches / dev-api-4 / xvidcore / vfw / src / codec.c Repository:
ViewVC logotype

Annotation of /branches/dev-api-4/xvidcore/vfw/src/codec.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 983 - (view) (download)

1 : suxen_drol 889 /**************************************************************************
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 :     * 12.07.2002 num_threads
27 :     * 23.06.2002 XVID_CPU_CHKONLY; loading speed up
28 :     * 25.04.2002 ICDECOMPRESS_PREROLL
29 :     * 17.04.2002 re-enabled lumi masking for 1st pass
30 :     * 15.04.2002 updated cbr support
31 :     * 04.04.2002 separated 2-pass code to 2pass.c
32 :     * interlacing support
33 :     * hinted ME support
34 :     * 23.03.2002 daniel smith <danielsmith@astroboymail.com>
35 :     * changed inter4v to only be in modes 5 or 6
36 :     * fixed null mode crash ?
37 :     * merged foxer's alternative 2-pass code
38 :     * added DEBUGERR output on errors instead of returning
39 :     * 16.03.2002 daniel smith <danielsmith@astroboymail.com>
40 :     * changed BITMAPV4HEADER to BITMAPINFOHEADER
41 :     * - prevents memcpy crash in compress_get_format()
42 :     * credits are processed in external 2pass mode
43 :     * motion search precision = 0 now effective in 2-pass
44 :     * modulated quantization
45 :     * added DX50 fourcc
46 :     * 01.12.2001 inital version; (c)2001 peter ross <pross@xvid.org>
47 :     *
48 :     *************************************************************************/
49 :    
50 :     #include <windows.h>
51 :     #include <vfw.h>
52 :    
53 : suxen_drol 983 #include <xvid.h>
54 :     #include "debug.h"
55 : suxen_drol 889 #include "codec.h"
56 :    
57 : suxen_drol 983
58 :     static const int pmvfast_presets[7] = {
59 : suxen_drol 889 0, 0, 0, 0,
60 : edgomez 949 0 | XVID_ME_HALFPELREFINE16 | 0,
61 :     0 | XVID_ME_HALFPELREFINE16 | 0 |
62 :     XVID_ME_ADVANCEDDIAMOND16, XVID_ME_HALFPELREFINE16 | XVID_ME_EXTSEARCH16 |
63 :     XVID_ME_HALFPELREFINE8 | 0 | XVID_ME_USESQUARES16
64 : suxen_drol 889 };
65 :    
66 : suxen_drol 983
67 :    
68 : suxen_drol 889 /* return xvid compatbile colorspace,
69 :     or XVID_CSP_NULL if failure
70 :     */
71 :    
72 :     int get_colorspace(BITMAPINFOHEADER * hdr)
73 :     {
74 :     /* rgb only: negative height specifies top down image */
75 :     int rgb_flip = (hdr->biHeight < 0 ? 0 : XVID_CSP_VFLIP);
76 :    
77 :     switch(hdr->biCompression)
78 :     {
79 :     case BI_RGB :
80 :     if (hdr->biBitCount == 16)
81 :     {
82 : suxen_drol 983 DPRINTF("RGB16 (RGB555)");
83 : suxen_drol 889 return rgb_flip | XVID_CSP_RGB555;
84 :     }
85 :     if (hdr->biBitCount == 24)
86 :     {
87 : suxen_drol 983 DPRINTF("RGB24");
88 : suxen_drol 889 return rgb_flip | XVID_CSP_BGR;
89 :     }
90 :     if (hdr->biBitCount == 32)
91 :     {
92 : suxen_drol 983 DPRINTF("RGB32");
93 : suxen_drol 889 return rgb_flip | XVID_CSP_BGRA;
94 :     }
95 :    
96 : suxen_drol 983 DPRINTF("unsupported BI_RGB biBitCount=%i", hdr->biBitCount);
97 : suxen_drol 889 return XVID_CSP_NULL;
98 :    
99 :     case BI_BITFIELDS :
100 :     if (hdr->biSize >= sizeof(BITMAPV4HEADER))
101 :     {
102 :     BITMAPV4HEADER * hdr4 = (BITMAPV4HEADER *)hdr;
103 :    
104 :     if (hdr4->bV4BitCount == 16 &&
105 :     hdr4->bV4RedMask == 0x7c00 &&
106 :     hdr4->bV4GreenMask == 0x3e0 &&
107 :     hdr4->bV4BlueMask == 0x1f)
108 :     {
109 : suxen_drol 983 DPRINTF("RGB555");
110 : suxen_drol 889 return rgb_flip | XVID_CSP_RGB555;
111 :     }
112 :    
113 :     if(hdr4->bV4BitCount == 16 &&
114 :     hdr4->bV4RedMask == 0xf800 &&
115 :     hdr4->bV4GreenMask == 0x7e0 &&
116 :     hdr4->bV4BlueMask == 0x1f)
117 :     {
118 : suxen_drol 983 DPRINTF("RGB565");
119 : suxen_drol 889 return rgb_flip | XVID_CSP_RGB565;
120 :     }
121 :    
122 : suxen_drol 983 DPRINTF("unsupported BI_BITFIELDS mode");
123 : suxen_drol 889 return XVID_CSP_NULL;
124 :     }
125 :    
126 : suxen_drol 983 DPRINTF("unsupported BI_BITFIELDS/BITMAPHEADER combination");
127 : suxen_drol 889 return XVID_CSP_NULL;
128 :    
129 :     case FOURCC_I420 :
130 :     case FOURCC_IYUV :
131 : suxen_drol 983 DPRINTF("IYUY");
132 : suxen_drol 889 return XVID_CSP_I420;
133 :    
134 :     case FOURCC_YV12 :
135 : suxen_drol 983 DPRINTF("YV12");
136 : suxen_drol 889 return XVID_CSP_YV12;
137 :    
138 :     case FOURCC_YUYV :
139 :     case FOURCC_YUY2 :
140 : suxen_drol 983 DPRINTF("YUY2");
141 : suxen_drol 889 return XVID_CSP_YUY2;
142 :    
143 :     case FOURCC_YVYU :
144 : suxen_drol 983 DPRINTF("YVYU");
145 : suxen_drol 889 return XVID_CSP_YVYU;
146 :    
147 :     case FOURCC_UYVY :
148 : suxen_drol 983 DPRINTF("UYVY");
149 : suxen_drol 889 return XVID_CSP_UYVY;
150 :    
151 :     default :
152 : suxen_drol 983 DPRINTF("unsupported colorspace %c%c%c%c",
153 :     hdr->biCompression&0xff,
154 :     (hdr->biCompression>>8)&0xff,
155 :     (hdr->biCompression>>16)&0xff,
156 :     (hdr->biCompression>>24)&0xff);
157 : suxen_drol 889 return XVID_CSP_NULL;
158 :     }
159 :     }
160 :    
161 :    
162 :     /* compressor */
163 :    
164 :    
165 :     /* test the output format */
166 :    
167 :     LRESULT compress_query(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput)
168 :     {
169 :     BITMAPINFOHEADER * inhdr = &lpbiInput->bmiHeader;
170 :     BITMAPINFOHEADER * outhdr = &lpbiOutput->bmiHeader;
171 :    
172 :     if (get_colorspace(inhdr) == XVID_CSP_NULL)
173 :     {
174 :     return ICERR_BADFORMAT;
175 :     }
176 :    
177 :     if (lpbiOutput == NULL)
178 :     {
179 :     return ICERR_OK;
180 :     }
181 :    
182 :     if (inhdr->biWidth != outhdr->biWidth || inhdr->biHeight != outhdr->biHeight ||
183 :     (outhdr->biCompression != FOURCC_XVID && outhdr->biCompression != FOURCC_DIVX && outhdr->biCompression != FOURCC_DX50))
184 :     {
185 :     return ICERR_BADFORMAT;
186 :     }
187 :    
188 :     return ICERR_OK;
189 :     }
190 :    
191 :    
192 :     LRESULT compress_get_format(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput)
193 :     {
194 :     BITMAPINFOHEADER * inhdr = &lpbiInput->bmiHeader;
195 :     BITMAPINFOHEADER * outhdr = &lpbiOutput->bmiHeader;
196 :    
197 :     if (get_colorspace(inhdr) == XVID_CSP_NULL)
198 :     {
199 :     return ICERR_BADFORMAT;
200 :     }
201 :    
202 :     if (lpbiOutput == NULL)
203 :     {
204 :     return sizeof(BITMAPV4HEADER);
205 :     }
206 :    
207 :     memcpy(outhdr, inhdr, sizeof(BITMAPINFOHEADER));
208 :     outhdr->biSize = sizeof(BITMAPINFOHEADER);
209 :     outhdr->biSizeImage = compress_get_size(codec, lpbiInput, lpbiOutput);
210 :     outhdr->biXPelsPerMeter = 0;
211 :     outhdr->biYPelsPerMeter = 0;
212 :     outhdr->biClrUsed = 0;
213 :     outhdr->biClrImportant = 0;
214 :    
215 :     if (codec->config.fourcc_used == 0)
216 :     {
217 :     outhdr->biCompression = FOURCC_XVID;
218 :     }
219 :     else if (codec->config.fourcc_used == 1)
220 :     {
221 :     outhdr->biCompression = FOURCC_DIVX;
222 :     }
223 :     else
224 :     {
225 :     outhdr->biCompression = FOURCC_DX50;
226 :     }
227 :    
228 :     return ICERR_OK;
229 :     }
230 :    
231 :    
232 :     LRESULT compress_get_size(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput)
233 :     {
234 :     return 2 * lpbiOutput->bmiHeader.biWidth * lpbiOutput->bmiHeader.biHeight * 3;
235 :     }
236 :    
237 :    
238 :     LRESULT compress_frames_info(CODEC * codec, ICCOMPRESSFRAMES * icf)
239 :     {
240 :     codec->fincr = icf->dwScale;
241 :     codec->fbase = icf->dwRate;
242 :     return ICERR_OK;
243 :     }
244 :    
245 :    
246 : suxen_drol 983 const char type2char(int type)
247 :     {
248 :     if (type==XVID_TYPE_IVOP)
249 :     return 'I';
250 :     if (type==XVID_TYPE_PVOP)
251 :     return 'P';
252 :     if (type==XVID_TYPE_BVOP)
253 :     return 'B';
254 :     return 'S';
255 :     }
256 :    
257 :     int vfw_debug(void *handle,
258 :     int opt,
259 :     void *param1,
260 :     void *param2)
261 :     {
262 :     switch (opt) {
263 :     case XVID_PLG_INFO:
264 :     case XVID_PLG_CREATE:
265 :     case XVID_PLG_DESTROY:
266 :     case XVID_PLG_BEFORE:
267 :     return 0;
268 :    
269 :     case XVID_PLG_AFTER:
270 :     {
271 :     xvid_plg_data_t *data = (xvid_plg_data_t *) param1;
272 :    
273 :     DPRINTF("[%5i] type=%c Q:%2i length:%6i",
274 :     data->frame_num,
275 :     type2char(data->type),
276 :     data->quant,
277 :     data->length);
278 :     return 0;
279 :     }
280 :     }
281 :    
282 :     return XVID_ERR_FAIL;
283 :     }
284 :    
285 :    
286 :    
287 : suxen_drol 889 LRESULT compress_begin(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput)
288 :     {
289 :     xvid_gbl_init_t init;
290 :     xvid_enc_create_t create;
291 : suxen_drol 983 xvid_enc_plugin_t plugins[3];
292 : suxen_drol 889
293 : suxen_drol 983 xvid_plugin_fixed_t fixed;
294 :     xvid_plugin_cbr_t cbr;
295 :     xvid_plugin_2pass1_t pass1;
296 :     xvid_plugin_2pass2_t pass2;
297 : suxen_drol 889
298 : suxen_drol 983 /* destroy previously created codec */
299 :     if(codec->ehandle) {
300 :     xvid_encore(codec->ehandle, XVID_ENC_DESTROY, NULL, NULL);
301 :     codec->ehandle = NULL;
302 :     }
303 :    
304 :     memset(&init, 0, sizeof(init));
305 :     init.version = XVID_VERSION;
306 :     init.cpu_flags = codec->config.cpu;
307 :     xvid_global(0, XVID_GBL_INIT, &init, NULL);
308 :    
309 :     memset(&create, 0, sizeof(create));
310 :     create.version = XVID_VERSION;
311 :     create.plugins = plugins;
312 :    
313 : suxen_drol 889 switch (codec->config.mode)
314 :     {
315 : suxen_drol 983 case RC_MODE_CBR :
316 :     memset(&cbr, 0, sizeof(cbr));
317 :     cbr.version = XVID_VERSION;
318 :     cbr.bitrate = codec->config.rc_bitrate;
319 :     cbr.reaction_delay_factor = codec->config.rc_reaction_delay_factor;
320 :     cbr.averaging_period = codec->config.rc_averaging_period;
321 :     cbr.buffer = codec->config.rc_buffer;
322 :     plugins[create.num_plugins].func = xvid_plugin_cbr;
323 :     plugins[create.num_plugins].param = &cbr;
324 :     create.num_plugins++;
325 : suxen_drol 889
326 : suxen_drol 983 case RC_MODE_FIXED :
327 :     memset(&fixed, 0, sizeof(fixed));
328 :     fixed.version = XVID_VERSION;
329 :     fixed.quant_increment = codec->config.quant;
330 :     fixed.quant_base = 1;
331 :     plugins[create.num_plugins].func = xvid_plugin_fixed;
332 :     plugins[create.num_plugins].param = &fixed;
333 :     create.num_plugins++;
334 : suxen_drol 889 break;
335 :    
336 : suxen_drol 983 case RC_MODE_2PASS1 :
337 :     memset(&pass1, 0, sizeof(pass1));
338 :     pass1.version = XVID_VERSION;
339 :    
340 :     plugins[create.num_plugins].func = xvid_plugin_2pass1;
341 :     plugins[create.num_plugins].param = &pass1;
342 :     create.num_plugins++;
343 : suxen_drol 889 break;
344 :    
345 : suxen_drol 983
346 :     case RC_MODE_2PASS2_INT :
347 :     case RC_MODE_2PASS2_EXT :
348 :     memset(&pass2, 0, sizeof(pass2));
349 :     pass2.version = XVID_VERSION;
350 :     pass2.min_quant[0] = codec->config.min_iquant;
351 :     pass2.max_quant[0] = codec->config.max_iquant;
352 :     pass2.min_quant[1] = codec->config.min_pquant;
353 :     pass2.max_quant[1] = codec->config.max_pquant;
354 :     //pass2.min_quant[2] = codec->config.min_bquant;
355 :     //pass2.max_quant[2] = codec->config.max_bquant;
356 :     pass2.filename = codec->config.stats;
357 :     if (codec->config.mode == RC_MODE_2PASS2_INT) {
358 :     pass2.bitrate = 10000; /* xxx */
359 :     }
360 :     plugins[create.num_plugins].func = xvid_plugin_2pass2;
361 :     plugins[create.num_plugins].param = &pass2;
362 :     create.num_plugins++;
363 : suxen_drol 889 break;
364 :    
365 : suxen_drol 983 case RC_MODE_NULL :
366 : suxen_drol 889 return ICERR_OK;
367 :    
368 :     default :
369 :     break;
370 :     }
371 :    
372 : suxen_drol 983 if (codec->config.lum_masking) {
373 :     plugins[create.num_plugins].func = xvid_plugin_lumimasking;
374 :     plugins[create.num_plugins].param = NULL;
375 :     create.num_plugins++;
376 : suxen_drol 889 }
377 :    
378 : suxen_drol 983 plugins[create.num_plugins].func = vfw_debug;
379 :     plugins[create.num_plugins].param = NULL;
380 :     create.num_plugins++;
381 : suxen_drol 889
382 :     create.width = lpbiInput->bmiHeader.biWidth;
383 :     create.height = lpbiInput->bmiHeader.biHeight;
384 :     create.fincr = codec->fincr;
385 :     create.fbase = codec->fbase;
386 :    
387 :     if (codec->config.packed)
388 : edgomez 949 create.global |= XVID_GLOBAL_PACKED;
389 : suxen_drol 983 if (codec->config.closed_gov)
390 : edgomez 949 create.global |= XVID_GLOBAL_CLOSED_GOP;
391 : suxen_drol 889
392 :     create.max_key_interval = codec->config.max_key_interval;
393 :     /* XXX: param.min_quantizer = codec->config.min_pquant;
394 :     param.max_quantizer = codec->config.max_pquant; */
395 :    
396 : suxen_drol 983 if (codec->config.use_bvop)
397 :     create.max_bframes = codec->config.max_bframes;
398 : suxen_drol 889 create.frame_drop_ratio = codec->config.frame_drop_ratio;
399 :    
400 :     create.bquant_ratio = codec->config.bquant_ratio;
401 :     create.bquant_offset = codec->config.bquant_offset;
402 :    
403 :     create.num_threads = codec->config.num_threads;
404 :    
405 : suxen_drol 983 switch(xvid_encore(0, XVID_ENC_CREATE, &create, NULL))
406 : suxen_drol 889 {
407 :     case XVID_ERR_FAIL :
408 :     return ICERR_ERROR;
409 :    
410 :     case XVID_ERR_MEMORY :
411 :     return ICERR_MEMORY;
412 :    
413 :     case XVID_ERR_FORMAT :
414 :     return ICERR_BADFORMAT;
415 :    
416 :     case XVID_ERR_VERSION :
417 :     return ICERR_UNSUPPORTED;
418 :     }
419 :    
420 :     codec->ehandle = create.handle;
421 :     codec->framenum = 0;
422 :     codec->keyspacing = 0;
423 :    
424 :     return ICERR_OK;
425 :     }
426 :    
427 :    
428 :     LRESULT compress_end(CODEC * codec)
429 :     {
430 :     if (codec->ehandle != NULL)
431 :     {
432 :     xvid_encore(codec->ehandle, XVID_ENC_DESTROY, NULL, NULL);
433 :     codec->ehandle = NULL;
434 :     }
435 :    
436 :     return ICERR_OK;
437 :     }
438 :    
439 :     LRESULT compress(CODEC * codec, ICCOMPRESS * icc)
440 :     {
441 :     BITMAPINFOHEADER * inhdr = icc->lpbiInput;
442 :     BITMAPINFOHEADER * outhdr = icc->lpbiOutput;
443 :     xvid_enc_frame_t frame;
444 :     xvid_enc_stats_t stats;
445 :     int length;
446 :    
447 :     // mpeg2avi yuv bug workaround (2 instances of CODEC)
448 :    
449 :     memset(&frame, 0, sizeof(frame));
450 :     frame.version = XVID_VERSION;
451 :    
452 :     frame.type = XVID_TYPE_AUTO;
453 :    
454 :     /* vol stuff */
455 :    
456 :     if (codec->config.quant_type != QUANT_MODE_H263)
457 :     {
458 : edgomez 949 frame.vol_flags |= XVID_VOL_MPEGQUANT;
459 : suxen_drol 889
460 :     // we actually need "default/custom" selectbox for both inter/intra
461 :     // this will do for now
462 :     if (codec->config.quant_type == QUANT_MODE_CUSTOM)
463 :     {
464 :     frame.quant_intra_matrix = codec->config.qmatrix_intra;
465 :     frame.quant_inter_matrix = codec->config.qmatrix_inter;
466 :     }
467 :     else
468 :     {
469 :     frame.quant_intra_matrix = NULL;
470 :     frame.quant_inter_matrix = NULL;
471 :     }
472 :     }
473 :    
474 :     if (codec->config.reduced_resolution) {
475 : edgomez 949 frame.vol_flags |= XVID_VOL_REDUCED_ENABLE;
476 :     frame.vop_flags |= XVID_VOP_REDUCED; /* XXX: need auto decion mode */
477 : suxen_drol 889 }
478 :    
479 :     if (codec->config.qpel) {
480 : edgomez 949 frame.vol_flags |= XVID_VOL_QUARTERPEL;
481 :     frame.motion |= XVID_ME_QUARTERPELREFINE16 | XVID_ME_QUARTERPELREFINE8;
482 : suxen_drol 889 }
483 :    
484 :     if (codec->config.gmc)
485 : edgomez 949 frame.vol_flags |= XVID_VOL_GMC;
486 : suxen_drol 889
487 :     if (codec->config.interlacing)
488 : edgomez 949 frame.vol_flags |= XVID_VOL_INTERLACING;
489 : suxen_drol 889
490 :     /* vop stuff */
491 :    
492 : edgomez 949 frame.vop_flags |= XVID_VOP_HALFPEL;
493 :     frame.vop_flags |= XVID_VOP_HQACPRED;
494 : suxen_drol 889
495 :     if (codec->config.debug)
496 : edgomez 949 frame.vop_flags |= XVID_VOP_DEBUG;
497 : suxen_drol 889
498 :     if (codec->config.motion_search > 4)
499 : edgomez 949 frame.vop_flags |= XVID_VOP_INTER4V;
500 : suxen_drol 889
501 :     if (codec->config.chromame)
502 : edgomez 949 frame.vop_flags |= XVID_ME_CHROMA16 + XVID_ME_CHROMA8;
503 : suxen_drol 889
504 :     if (codec->config.chroma_opt)
505 : edgomez 949 frame.vop_flags |= XVID_VOP_CHROMAOPT;
506 : suxen_drol 889
507 :     frame.motion |= pmvfast_presets[codec->config.motion_search];
508 :    
509 :     switch (codec->config.vhq_mode)
510 :     {
511 :     case VHQ_MODE_DECISION :
512 : edgomez 949 frame.vop_flags |= XVID_VOP_MODEDECISION_BITS;
513 : suxen_drol 889 break;
514 :    
515 :     case VHQ_LIMITED_SEARCH :
516 : edgomez 949 frame.vop_flags |= XVID_VOP_MODEDECISION_BITS;
517 :     frame.motion |= XVID_ME_HALFPELREFINE16_BITS;
518 :     frame.motion |= XVID_ME_QUARTERPELREFINE16_BITS;
519 : suxen_drol 889 break;
520 :    
521 :     case VHQ_MEDIUM_SEARCH :
522 : edgomez 949 frame.vop_flags |= XVID_VOP_MODEDECISION_BITS;
523 :     frame.motion |= XVID_ME_HALFPELREFINE16_BITS;
524 :     frame.motion |= XVID_ME_HALFPELREFINE8_BITS;
525 :     frame.motion |= XVID_ME_QUARTERPELREFINE16_BITS;
526 :     frame.motion |= XVID_ME_QUARTERPELREFINE8_BITS;
527 :     frame.motion |= XVID_ME_CHECKPREDICTION_BITS;
528 : suxen_drol 889 break;
529 :    
530 :     case VHQ_WIDE_SEARCH :
531 : edgomez 949 frame.vop_flags |= XVID_VOP_MODEDECISION_BITS;
532 :     frame.motion |= XVID_ME_HALFPELREFINE16_BITS;
533 :     frame.motion |= XVID_ME_HALFPELREFINE8_BITS;
534 :     frame.motion |= XVID_ME_QUARTERPELREFINE16_BITS;
535 :     frame.motion |= XVID_ME_QUARTERPELREFINE8_BITS;
536 :     frame.motion |= XVID_ME_CHECKPREDICTION_BITS;
537 :     frame.motion |= XVID_ME_EXTSEARCH_BITS;
538 : suxen_drol 889 break;
539 :    
540 :     default :
541 :     break;
542 :     }
543 :    
544 : suxen_drol 983 frame.bframe_threshold = codec->config.bvop_threshold;
545 :    
546 : suxen_drol 889 frame.input.plane[0] = icc->lpInput;
547 :     frame.input.stride[0] = (((icc->lpbiInput->biWidth * icc->lpbiInput->biBitCount) + 31) & ~31) >> 3;
548 :    
549 :     if ((frame.input.csp = get_colorspace(inhdr)) == XVID_CSP_NULL)
550 :     return ICERR_BADFORMAT;
551 :    
552 :     if (frame.input.csp == XVID_CSP_I420 || frame.input.csp == XVID_CSP_YV12)
553 :     frame.input.stride[0] = (frame.input.stride[0]*2)/3;
554 :    
555 :     frame.bitstream = icc->lpOutput;
556 :     frame.length = icc->lpbiOutput->biSizeImage;
557 :    
558 :     switch (codec->config.mode)
559 :     {
560 : suxen_drol 983 case RC_MODE_CBR :
561 : suxen_drol 889 frame.quant = 0; /* use xvidcore cbr rate control */
562 :     break;
563 :    
564 : suxen_drol 983 //case RC_MODE_VBR_QUAL :
565 :     case RC_MODE_FIXED :
566 :     case RC_MODE_2PASS1 :
567 :     /*if (codec_get_quant(codec, &frame) == ICERR_ERROR)
568 : suxen_drol 889 {
569 :     return ICERR_ERROR;
570 : suxen_drol 983 }*/
571 : suxen_drol 889 break;
572 :    
573 : suxen_drol 983 case RC_MODE_2PASS2_EXT :
574 :     case RC_MODE_2PASS2_INT :
575 :     /*if (codec_2pass_get_quant(codec, &frame) == ICERR_ERROR)
576 : suxen_drol 889 {
577 :     return ICERR_ERROR;
578 : suxen_drol 983 }*/
579 : suxen_drol 889 break;
580 :    
581 : suxen_drol 983 case RC_MODE_NULL :
582 : suxen_drol 889 outhdr->biSizeImage = 0;
583 :     *icc->lpdwFlags = AVIIF_KEYFRAME;
584 :     return ICERR_OK;
585 :    
586 :     default :
587 : suxen_drol 983 DPRINTF("Invalid encoding mode");
588 : suxen_drol 889 return ICERR_ERROR;
589 :     }
590 :    
591 :    
592 :     // force keyframe spacing in 2-pass 1st pass
593 :     if (codec->config.motion_search == 0)
594 :     {
595 :     frame.type = XVID_TYPE_IVOP;
596 :     }
597 :     else if (codec->keyspacing < codec->config.min_key_interval && codec->framenum)
598 :     {
599 : suxen_drol 983 DPRINTF("current frame forced to p-frame");
600 : suxen_drol 889 frame.type = XVID_TYPE_PVOP;
601 :     }
602 :    
603 :     memset(&stats, 0, sizeof(stats));
604 :     stats.version = XVID_VERSION;
605 :    
606 :     length = xvid_encore(codec->ehandle, XVID_ENC_ENCODE, &frame, &stats);
607 :     switch (length)
608 :     {
609 :     case XVID_ERR_FAIL :
610 :     return ICERR_ERROR;
611 :    
612 :     case XVID_ERR_MEMORY :
613 :     return ICERR_MEMORY;
614 :    
615 :     case XVID_ERR_FORMAT :
616 :     return ICERR_BADFORMAT;
617 :    
618 :     case XVID_ERR_VERSION :
619 :     return ICERR_UNSUPPORTED;
620 :     }
621 :    
622 : suxen_drol 983 DPRINTF("{type=%i len=%i} length=%i", stats.type, stats.length, length);
623 : suxen_drol 889
624 :     if (length == 0) /* no encoder output */
625 :     {
626 :     *icc->lpdwFlags = 0;
627 :     ((char*)icc->lpOutput)[0] = 0x7f; /* virtual dub skip frame */
628 :     outhdr->biSizeImage = 1;
629 :    
630 :     }else{
631 :     if (frame.out_flags & XVID_KEYFRAME)
632 :     {
633 :     codec->keyspacing = 0;
634 :     *icc->lpdwFlags = AVIIF_KEYFRAME;
635 :     }
636 :     else
637 :     {
638 :     *icc->lpdwFlags = 0;
639 :     }
640 :    
641 :     outhdr->biSizeImage = length;
642 :    
643 : suxen_drol 983 if (codec->config.mode == RC_MODE_2PASS1 && codec->config.discard1pass)
644 : suxen_drol 889 {
645 :     outhdr->biSizeImage = 0;
646 :     }
647 :     }
648 :    
649 :     ++codec->framenum;
650 :     ++codec->keyspacing;
651 :    
652 :     return ICERR_OK;
653 :     }
654 :    
655 :    
656 :     /* decompressor */
657 :    
658 :    
659 :     LRESULT decompress_query(CODEC * codec, BITMAPINFO *lpbiInput, BITMAPINFO *lpbiOutput)
660 :     {
661 :     BITMAPINFOHEADER * inhdr = &lpbiInput->bmiHeader;
662 :     BITMAPINFOHEADER * outhdr = &lpbiOutput->bmiHeader;
663 :    
664 :     if (lpbiInput == NULL)
665 :     {
666 :     return ICERR_ERROR;
667 :     }
668 :    
669 :     if (inhdr->biCompression != FOURCC_XVID && inhdr->biCompression != FOURCC_DIVX && inhdr->biCompression != FOURCC_DX50 && get_colorspace(inhdr) == XVID_CSP_NULL)
670 :     {
671 :     return ICERR_BADFORMAT;
672 :     }
673 :    
674 :     if (lpbiOutput == NULL)
675 :     {
676 :     return ICERR_OK;
677 :     }
678 :    
679 :     if (inhdr->biWidth != outhdr->biWidth ||
680 :     inhdr->biHeight != outhdr->biHeight ||
681 :     get_colorspace(outhdr) == XVID_CSP_NULL)
682 :     {
683 :     return ICERR_BADFORMAT;
684 :     }
685 :    
686 :     return ICERR_OK;
687 :     }
688 :    
689 :    
690 :     LRESULT decompress_get_format(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput)
691 :     {
692 :     BITMAPINFOHEADER * inhdr = &lpbiInput->bmiHeader;
693 :     BITMAPINFOHEADER * outhdr = &lpbiOutput->bmiHeader;
694 :     LRESULT result;
695 :    
696 :     if (lpbiOutput == NULL)
697 :     {
698 :     return sizeof(BITMAPINFOHEADER);
699 :     }
700 :    
701 :     /* --- yv12 --- */
702 :    
703 :     if (get_colorspace(inhdr) != XVID_CSP_NULL) {
704 :     memcpy(outhdr, inhdr, sizeof(BITMAPINFOHEADER));
705 :     // XXX: should we set outhdr->biSize ??
706 :     return ICERR_OK;
707 :     }
708 :     /* --- yv12 --- */
709 :    
710 :     result = decompress_query(codec, lpbiInput, lpbiOutput);
711 :     if (result != ICERR_OK)
712 :     {
713 :     return result;
714 :     }
715 :    
716 :     outhdr->biSize = sizeof(BITMAPINFOHEADER);
717 :     outhdr->biWidth = inhdr->biWidth;
718 :     outhdr->biHeight = inhdr->biHeight;
719 :     outhdr->biPlanes = 1;
720 :     outhdr->biBitCount = 24;
721 :     outhdr->biCompression = BI_RGB; /* sonic foundry vegas video v3 only supports BI_RGB */
722 :     outhdr->biSizeImage = outhdr->biWidth * outhdr->biHeight * outhdr->biBitCount;
723 :     outhdr->biXPelsPerMeter = 0;
724 :     outhdr->biYPelsPerMeter = 0;
725 :     outhdr->biClrUsed = 0;
726 :     outhdr->biClrImportant = 0;
727 :    
728 :     return ICERR_OK;
729 :     }
730 :    
731 :    
732 :     LRESULT decompress_begin(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput)
733 :     {
734 :     xvid_gbl_init_t init;
735 :     xvid_dec_create_t create;
736 :    
737 :     memset(&init, 0, sizeof(init));
738 :     init.version = XVID_VERSION;
739 :     init.cpu_flags = codec->config.cpu;
740 :     xvid_global(0, XVID_GBL_INIT, &init, NULL);
741 :    
742 :     memset(&create, 0, sizeof(create));
743 :     create.version = XVID_VERSION;
744 :     create.width = lpbiInput->bmiHeader.biWidth;
745 :     create.height = lpbiInput->bmiHeader.biHeight;
746 :    
747 :     switch(xvid_decore(0, XVID_DEC_CREATE, &create, NULL))
748 :     {
749 :     case XVID_ERR_FAIL :
750 :     return ICERR_ERROR;
751 :    
752 :     case XVID_ERR_MEMORY :
753 :     return ICERR_MEMORY;
754 :    
755 :     case XVID_ERR_FORMAT :
756 :     return ICERR_BADFORMAT;
757 :    
758 :     case XVID_ERR_VERSION :
759 :     return ICERR_UNSUPPORTED;
760 :     }
761 :    
762 :     codec->dhandle = create.handle;
763 :    
764 :     return ICERR_OK;
765 :     }
766 :    
767 :    
768 :     LRESULT decompress_end(CODEC * codec)
769 :     {
770 :     if (codec->dhandle != NULL)
771 :     {
772 :     xvid_decore(codec->dhandle, XVID_DEC_DESTROY, NULL, NULL);
773 :     codec->dhandle = NULL;
774 :     }
775 :     return ICERR_OK;
776 :     }
777 :    
778 :    
779 :     LRESULT decompress(CODEC * codec, ICDECOMPRESS * icd)
780 :     {
781 :     xvid_dec_frame_t frame;
782 :    
783 :     /* --- yv12 --- */
784 :     if (icd->lpbiInput->biCompression != FOURCC_XVID &&
785 :     icd->lpbiInput->biCompression != FOURCC_DIVX &&
786 :     icd->lpbiInput->biCompression != FOURCC_DX50)
787 :     {
788 :     xvid_gbl_convert_t convert;
789 :    
790 : suxen_drol 983 DPRINTF("input=%c%c%c%c output=%c%c%c%c",
791 :     icd->lpbiInput->biCompression&0xff,
792 :     (icd->lpbiInput->biCompression>>8)&0xff,
793 :     (icd->lpbiInput->biCompression>>16)&0xff,
794 :     (icd->lpbiInput->biCompression>>24)&0xff,
795 :     icd->lpbiOutput->biCompression&0xff,
796 :     (icd->lpbiOutput->biCompression>>8)&0xff,
797 :     (icd->lpbiOutput->biCompression>>16)&0xff,
798 :     (icd->lpbiOutput->biCompression>>24)&0xff);
799 : suxen_drol 889
800 :     memset(&convert, 0, sizeof(convert));
801 :     convert.version = XVID_VERSION;
802 :    
803 :     convert.input.csp = get_colorspace(icd->lpbiInput);
804 :     convert.input.plane[0] = icd->lpInput;
805 :     convert.input.stride[0] = (((icd->lpbiInput->biWidth *icd->lpbiInput->biBitCount) + 31) & ~31) >> 3;
806 :     if (convert.input.csp == XVID_CSP_I420 || convert.input.csp == XVID_CSP_YV12)
807 :     convert.input.stride[0] = (convert.input.stride[0]*2)/3;
808 :    
809 :     convert.output.csp = get_colorspace(icd->lpbiOutput);
810 :     convert.output.plane[0] = icd->lpOutput;
811 :     convert.output.stride[0] = (((icd->lpbiOutput->biWidth *icd->lpbiOutput->biBitCount) + 31) & ~31) >> 3;
812 :     if (convert.output.csp == XVID_CSP_I420 || convert.output.csp == XVID_CSP_YV12)
813 :     convert.output.stride[0] = (convert.output.stride[0]*2)/3;
814 :    
815 :     convert.width = icd->lpbiInput->biWidth;
816 :     convert.height = icd->lpbiInput->biHeight;
817 :     convert.interlacing = 0;
818 :     if (convert.input.csp == XVID_CSP_NULL ||
819 :     convert.output.csp == XVID_CSP_NULL ||
820 :     xvid_global(0, XVID_GBL_CONVERT, &convert, NULL) < 0)
821 :     {
822 :     return ICERR_BADFORMAT;
823 :     }
824 :     return ICERR_OK;
825 :     }
826 :     /* --- yv12 --- */
827 :    
828 :     memset(&frame, 0, sizeof(frame));
829 :     frame.version = XVID_VERSION;
830 :     frame.general = XVID_LOWDELAY; /* force low_delay_default mode */
831 :     frame.bitstream = icd->lpInput;
832 :     frame.length = icd->lpbiInput->biSizeImage;
833 :    
834 :     if (~((icd->dwFlags & ICDECOMPRESS_HURRYUP) | (icd->dwFlags & ICDECOMPRESS_UPDATE) | (icd->dwFlags & ICDECOMPRESS_PREROLL)))
835 :     {
836 :     if ((frame.output.csp = get_colorspace(icd->lpbiOutput)) == XVID_CSP_NULL)
837 :     {
838 :     return ICERR_BADFORMAT;
839 :     }
840 :     frame.output.plane[0] = icd->lpOutput;
841 :     frame.output.stride[0] = (((icd->lpbiOutput->biWidth * icd->lpbiOutput->biBitCount) + 31) & ~31) >> 3;
842 :     if (frame.output.csp == XVID_CSP_I420 || frame.output.csp == XVID_CSP_YV12)
843 :     frame.output.stride[0] = (frame.output.stride[0]*2)/3;
844 :     }
845 :     else
846 :     {
847 :     frame.output.csp = XVID_CSP_NULL;
848 :     }
849 :    
850 :     switch (xvid_decore(codec->dhandle, XVID_DEC_DECODE, &frame, NULL))
851 :     {
852 :     case XVID_ERR_FAIL :
853 :     return ICERR_ERROR;
854 :    
855 :     case XVID_ERR_MEMORY :
856 :     return ICERR_MEMORY;
857 :    
858 :     case XVID_ERR_FORMAT :
859 :     return ICERR_BADFORMAT;
860 :    
861 :     case XVID_ERR_VERSION :
862 :     return ICERR_UNSUPPORTED;
863 :     }
864 :    
865 :     return ICERR_OK;
866 :     }
867 :    

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