[cvs] / xvidcore / vfw / src / codec.c Repository:
ViewVC logotype

Diff of /xvidcore/vfw/src/codec.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.1, Sat Feb 22 08:24:01 2003 UTC revision 1.1.2.33, Mon Jan 26 03:16:53 2004 UTC
# Line 0  Line 1 
1    /**************************************************************************
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    #include <stdio.h>
53    #include "vfwext.h"
54    
55    #include <xvid.h>
56    #include "debug.h"
57    #include "codec.h"
58    #include "status.h"
59    
60    
61    static const int pmvfast_presets[7] = {
62            0, 0, 0, 0,
63            0 | XVID_ME_HALFPELREFINE16 | 0,
64            0 | XVID_ME_HALFPELREFINE16 | 0 |
65            XVID_ME_ADVANCEDDIAMOND16, XVID_ME_HALFPELREFINE16 | XVID_ME_EXTSEARCH16 |
66            XVID_ME_HALFPELREFINE8 | 0 | XVID_ME_USESQUARES16
67    };
68    
69    
70    
71    /*      return xvid compatbile colorspace,
72            or XVID_CSP_NULL if failure
73    */
74    
75    static int get_colorspace(BITMAPINFOHEADER * hdr)
76    {
77            /* rgb only: negative height specifies top down image */
78            int rgb_flip = (hdr->biHeight < 0 ? 0 : XVID_CSP_VFLIP);
79    
80            switch(hdr->biCompression)
81            {
82            case BI_RGB :
83                    if (hdr->biBitCount == 16)
84                    {
85                            DPRINTF("RGB16 (RGB555)");
86                            return rgb_flip | XVID_CSP_RGB555;
87                    }
88                    if (hdr->biBitCount == 24)
89                    {
90                            DPRINTF("RGB24");
91                            return rgb_flip | XVID_CSP_BGR;
92                    }
93                    if (hdr->biBitCount == 32)
94                    {
95                            DPRINTF("RGB32");
96                            return rgb_flip | XVID_CSP_BGRA;
97                    }
98    
99                    DPRINTF("unsupported BI_RGB biBitCount=%i", hdr->biBitCount);
100                    return XVID_CSP_NULL;
101    
102            case BI_BITFIELDS :
103                    if (hdr->biSize >= sizeof(BITMAPV4HEADER))
104                    {
105                            BITMAPV4HEADER * hdr4 = (BITMAPV4HEADER *)hdr;
106    
107                            if (hdr4->bV4BitCount == 16 &&
108                                    hdr4->bV4RedMask == 0x7c00 &&
109                                    hdr4->bV4GreenMask == 0x3e0 &&
110                                    hdr4->bV4BlueMask == 0x1f)
111                            {
112                                    DPRINTF("RGB555");
113                                    return rgb_flip | XVID_CSP_RGB555;
114                            }
115    
116                            if(hdr4->bV4BitCount == 16 &&
117                                    hdr4->bV4RedMask == 0xf800 &&
118                                    hdr4->bV4GreenMask == 0x7e0 &&
119                                    hdr4->bV4BlueMask == 0x1f)
120                            {
121                                    DPRINTF("RGB565");
122                                    return rgb_flip | XVID_CSP_RGB565;
123                            }
124    
125                            DPRINTF("unsupported BI_BITFIELDS mode");
126                            return XVID_CSP_NULL;
127                    }
128    
129                    DPRINTF("unsupported BI_BITFIELDS/BITMAPHEADER combination");
130                    return XVID_CSP_NULL;
131    
132            case FOURCC_I420 :
133            case FOURCC_IYUV :
134                    DPRINTF("IYUY");
135                    return XVID_CSP_I420;
136    
137            case FOURCC_YV12 :
138                    DPRINTF("YV12");
139                    return XVID_CSP_YV12;
140    
141            case FOURCC_YUYV :
142            case FOURCC_YUY2 :
143                    DPRINTF("YUY2");
144                    return XVID_CSP_YUY2;
145    
146            case FOURCC_YVYU :
147                    DPRINTF("YVYU");
148                    return XVID_CSP_YVYU;
149    
150            case FOURCC_UYVY :
151                    DPRINTF("UYVY");
152                    return XVID_CSP_UYVY;
153    
154            default :
155                    DPRINTF("unsupported colorspace %c%c%c%c",
156                            hdr->biCompression&0xff,
157                            (hdr->biCompression>>8)&0xff,
158                            (hdr->biCompression>>16)&0xff,
159                            (hdr->biCompression>>24)&0xff);
160                    return XVID_CSP_NULL;
161            }
162    }
163    
164    
165    /* compressor */
166    
167    
168    /* test the output format */
169    
170    LRESULT compress_query(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput)
171    {
172            BITMAPINFOHEADER * inhdr = &lpbiInput->bmiHeader;
173            BITMAPINFOHEADER * outhdr = &lpbiOutput->bmiHeader;
174    
175            /* VFWEXT detection */
176            if (inhdr->biCompression == VFWEXT_FOURCC) {
177                    return (ICM_USER+0x0fff);
178            }
179    
180            if (get_colorspace(inhdr) == XVID_CSP_NULL)
181            {
182                    return ICERR_BADFORMAT;
183            }
184    
185            if (lpbiOutput == NULL)
186            {
187                    return ICERR_OK;
188            }
189    
190            if (inhdr->biWidth != outhdr->biWidth || inhdr->biHeight != outhdr->biHeight ||
191                    (outhdr->biCompression != FOURCC_XVID && outhdr->biCompression != FOURCC_DIVX && outhdr->biCompression != FOURCC_DX50))
192            {
193                    return ICERR_BADFORMAT;
194            }
195    
196            return ICERR_OK;
197    }
198    
199    
200    LRESULT compress_get_format(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput)
201    {
202            BITMAPINFOHEADER * inhdr = &lpbiInput->bmiHeader;
203            BITMAPINFOHEADER * outhdr = &lpbiOutput->bmiHeader;
204    
205            if (get_colorspace(inhdr) == XVID_CSP_NULL)
206            {
207                    return ICERR_BADFORMAT;
208            }
209    
210            if (lpbiOutput == NULL)
211            {
212                    return sizeof(BITMAPINFOHEADER);
213            }
214    
215            memcpy(outhdr, inhdr, sizeof(BITMAPINFOHEADER));
216            outhdr->biSize = sizeof(BITMAPINFOHEADER);
217            outhdr->biSizeImage = compress_get_size(codec, lpbiInput, lpbiOutput);
218            outhdr->biXPelsPerMeter = 0;
219            outhdr->biYPelsPerMeter = 0;
220            outhdr->biClrUsed = 0;
221            outhdr->biClrImportant = 0;
222    
223            if (codec->config.fourcc_used == 0)
224            {
225                    outhdr->biCompression = FOURCC_XVID;
226            }
227            else if (codec->config.fourcc_used == 1)
228            {
229                    outhdr->biCompression = FOURCC_DIVX;
230            }
231            else
232            {
233                    outhdr->biCompression = FOURCC_DX50;
234            }
235    
236            return ICERR_OK;
237    }
238    
239    
240    LRESULT compress_get_size(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput)
241    {
242            return 2 * lpbiOutput->bmiHeader.biWidth * lpbiOutput->bmiHeader.biHeight * 3;
243    }
244    
245    
246    LRESULT compress_frames_info(CODEC * codec, ICCOMPRESSFRAMES * icf)
247    {
248    #if 0
249            DPRINTF("%i %i", icf->lStartFrame, icf->lFrameCount);
250    #endif
251            codec->fincr = icf->dwScale;
252            codec->fbase = icf->dwRate;
253            return ICERR_OK;
254    }
255    
256    
257    static char type2char(int type)
258    {
259            if (type==XVID_TYPE_IVOP)
260                    return 'I';
261            if (type==XVID_TYPE_PVOP)
262                    return 'P';
263            if (type==XVID_TYPE_BVOP)
264                    return 'B';
265            return 'S';
266    }
267    
268    static int vfw_debug(void *handle,
269                             int opt,
270                             void *param1,
271                             void *param2)
272    {
273            switch (opt) {
274            case XVID_PLG_CREATE:
275                    *((void**)param2) = NULL;
276            case XVID_PLG_INFO:
277            case XVID_PLG_DESTROY:
278            case XVID_PLG_BEFORE:
279                    return 0;
280    
281            case XVID_PLG_AFTER:
282                    {
283                            xvid_plg_data_t *data = (xvid_plg_data_t *) param1;
284    
285                            /* We don't use DPRINTF here because it's active only for _DEBUG
286                             * builds and that activates lot of other debug printfs. We only
287                             * want these all the time */
288                            char buf[1024];
289                            sprintf(buf, "[%6i]   type=%c   Q:%2i   length:%6i",
290                                            data->frame_num,
291                                            type2char(data->type),
292                                            data->quant,
293                                            data->length);
294                            OutputDebugString(buf);
295    
296                            return 0;
297                    }
298            }
299    
300            return XVID_ERR_FAIL;
301    }
302    
303    #define XVID_DLL_NAME "xvidcore.dll"
304    
305    static int init_dll()
306    {
307            if (m_hdll != NULL) return 0;
308    
309            DPRINTF("init_dll");
310            m_hdll = LoadLibrary(XVID_DLL_NAME);
311            if (m_hdll == NULL) {
312                    DPRINTF("dll load failed");
313                    MessageBox(0, XVID_DLL_NAME " not found!","Error!", MB_ICONEXCLAMATION|MB_OK);
314                    return XVID_ERR_FAIL;
315            }
316    
317            xvid_global_func = (int (__cdecl *)(void *, int, void *, void *))GetProcAddress(m_hdll, "xvid_global");
318            if (xvid_global_func == NULL) {
319                    MessageBox(0, "xvid_global() not found", "Error", 0);
320                    return XVID_ERR_FAIL;
321            }
322    
323            xvid_encore_func = (int (__cdecl *)(void *, int, void *, void *))GetProcAddress(m_hdll, "xvid_encore");
324            if (xvid_encore_func == NULL) {
325                    MessageBox(0, "xvid_encore() not found", "Error", 0);
326                    return XVID_ERR_FAIL;
327            }
328    
329            xvid_decore_func = (int (__cdecl *)(void *, int, void *, void *))GetProcAddress(m_hdll, "xvid_decore");
330            if (xvid_decore_func == NULL) {
331                    MessageBox(0, "xvid_decore() not found", "Error", 0);
332                    return XVID_ERR_FAIL;
333            }
334    
335            xvid_plugin_single_func =
336                    (int (__cdecl *)(void *, int, void *, void *))(GetProcAddress(m_hdll, "xvid_plugin_single"));
337            xvid_plugin_2pass1_func =
338                    (int (__cdecl *)(void *, int, void *, void *))(GetProcAddress(m_hdll, "xvid_plugin_2pass1"));
339            xvid_plugin_2pass2_func =
340                    (int (__cdecl *)(void *, int, void *, void *))(GetProcAddress(m_hdll, "xvid_plugin_2pass2"));
341            xvid_plugin_lumimasking_func =
342                    (int (__cdecl *)(void *, int, void *, void *))(GetProcAddress(m_hdll, "xvid_plugin_lumimasking"));
343            xvid_plugin_psnr_func =
344                    (int (__cdecl *)(void *, int, void *, void *))(GetProcAddress(m_hdll, "xvid_plugin_psnr"));
345    
346            return 0;
347    }
348    
349    
350    static void
351    prepare_cquant_zones(CONFIG * config) {
352    
353            int i = 0;
354            if (config->num_zones == 0 || config->zones[0].frame != 0) {
355                    /* first zone does not start at frame 0 or doesn't exist */
356    
357                    if (config->num_zones >= MAX_ZONES) config->num_zones--; /* we scrifice last zone */
358    
359                    config->zones[config->num_zones].frame = 0;
360                    config->zones[config->num_zones].mode = RC_ZONE_QUANT;
361                    config->zones[config->num_zones].weight = 100;
362                    config->zones[config->num_zones].quant = config->desired_quant;
363                    config->zones[config->num_zones].type = XVID_TYPE_AUTO;
364                    config->zones[config->num_zones].greyscale = 0;
365                    config->zones[config->num_zones].chroma_opt = 0;
366                    config->zones[config->num_zones].bvop_threshold = 0;
367                    config->num_zones++;
368    
369                    sort_zones(config->zones, config->num_zones, &i);
370            }
371    
372            /* step 2: let's change all weight zones into quant zones */
373    
374            for(i = 0; i < config->num_zones; i++)
375                    if (config->zones[i].mode == RC_ZONE_WEIGHT) {
376                            config->zones[i].mode = RC_ZONE_QUANT;
377                            config->zones[i].quant = (100*config->desired_quant) / config->zones[i].weight;
378                    }
379    }
380    
381    
382    LRESULT compress_begin(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput)
383    {
384            xvid_gbl_init_t init;
385            xvid_enc_create_t create;
386            xvid_enc_plugin_t plugins[3];
387            xvid_plugin_single_t single;
388            xvid_plugin_2pass1_t pass1;
389            xvid_plugin_2pass2_t pass2;
390            int i;
391            HANDLE hFile;
392    
393            CONFIG tmpCfg; /* if we want to alter config to suit our needs, it shouldn't be visible to user later */
394            memcpy(&tmpCfg, &codec->config, sizeof(CONFIG));
395    
396            if (init_dll() != 0) return ICERR_ERROR;
397            /* destroy previously created codec */
398            if(codec->ehandle) {
399                    xvid_encore_func(codec->ehandle, XVID_ENC_DESTROY, NULL, NULL);
400                    codec->ehandle = NULL;
401            }
402    
403            memset(&init, 0, sizeof(init));
404            init.version = XVID_VERSION;
405            init.cpu_flags = codec->config.cpu;
406            init.debug = codec->config.debug;
407            xvid_global_func(0, XVID_GBL_INIT, &init, NULL);
408    
409            memset(&create, 0, sizeof(create));
410            create.version = XVID_VERSION;
411    
412            /* plugins */
413            create.plugins = plugins;
414            switch (codec->config.mode)
415            {
416            case RC_MODE_1PASS :
417                    memset(&single, 0, sizeof(single));
418                    single.version = XVID_VERSION;
419                    single.bitrate = codec->config.bitrate * CONFIG_KBPS;
420                    single.reaction_delay_factor = codec->config.rc_reaction_delay_factor;
421                    single.averaging_period = codec->config.rc_averaging_period;
422                    single.buffer = codec->config.rc_buffer;
423                    plugins[create.num_plugins].func = xvid_plugin_single_func;
424                    plugins[create.num_plugins].param = &single;
425                    create.num_plugins++;
426                    if (!codec->config.use_2pass_bitrate) /* constant-quant mode */
427                            prepare_cquant_zones(&tmpCfg);
428                    break;
429    
430            case RC_MODE_2PASS1 :
431                    memset(&pass1, 0, sizeof(pass1));
432                    pass1.version = XVID_VERSION;
433                    pass1.filename = codec->config.stats;
434    
435                    plugins[create.num_plugins].func = xvid_plugin_2pass1_func;
436                    plugins[create.num_plugins].param = &pass1;
437                    create.num_plugins++;
438                    break;
439    
440            case RC_MODE_2PASS2 :
441                    memset(&pass2, 0, sizeof(pass2));
442                    pass2.version = XVID_VERSION;
443                    if (codec->config.use_2pass_bitrate) {
444                            pass2.bitrate = codec->config.bitrate * CONFIG_KBPS;
445                    } else {
446                            pass2.bitrate = -codec->config.desired_size;    /* kilobytes */
447                    }
448                    pass2.filename = codec->config.stats;
449    
450                    hFile = CreateFile(pass2.filename, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
451                    if (hFile == INVALID_HANDLE_VALUE)
452                    {
453                            MessageBox(0, "Statsfile not found!","Error!", MB_ICONEXCLAMATION|MB_OK);
454                            return XVID_ERR_FAIL;
455                    } else
456                    {
457                            CloseHandle(hFile);
458                    }
459    
460                    pass2.keyframe_boost = codec->config.keyframe_boost;   /* keyframe boost percentage: [0..100...]; */
461                    pass2.curve_compression_high = codec->config.curve_compression_high;
462                    pass2.curve_compression_low = codec->config.curve_compression_low;
463                    pass2.overflow_control_strength = codec->config.overflow_control_strength;
464                    pass2.max_overflow_improvement = codec->config.twopass_max_overflow_improvement;
465                    pass2.max_overflow_degradation = codec->config.twopass_max_overflow_degradation;
466                    pass2.kfreduction = codec->config.kfreduction;
467                    pass2.kfthreshold = codec->config.kfthreshold;
468                    pass2.container_frame_overhead = 24;    /* AVI */
469    
470                    plugins[create.num_plugins].func = xvid_plugin_2pass2_func;
471                    plugins[create.num_plugins].param = &pass2;
472                    create.num_plugins++;
473                    break;
474    
475            case RC_MODE_NULL :
476                    return ICERR_OK;
477    
478            default :
479                    break;
480            }
481    
482            /* zones  - copy from tmpCfg in case we automatically altered them above */
483            create.zones = malloc(sizeof(xvid_enc_zone_t) * tmpCfg.num_zones);
484            create.num_zones = tmpCfg.num_zones;
485            for (i=0; i < create.num_zones; i++) {
486                    create.zones[i].frame = tmpCfg.zones[i].frame;
487                    if (tmpCfg.zones[i].mode == RC_ZONE_QUANT) {
488                            create.zones[i].mode = XVID_ZONE_QUANT;
489                            create.zones[i].increment = tmpCfg.zones[i].quant;
490                    }else{
491                            create.zones[i].mode = XVID_ZONE_WEIGHT;
492                            create.zones[i].increment = tmpCfg.zones[i].weight;
493                    }
494                    create.zones[i].base = 100;
495            }
496    
497            /* lumimasking plugin */
498            if ((profiles[codec->config.profile].flags & PROFILE_ADAPTQUANT) && codec->config.lum_masking) {
499                    plugins[create.num_plugins].func = xvid_plugin_lumimasking_func;
500                    plugins[create.num_plugins].param = NULL;
501                    create.num_plugins++;
502            }
503    
504            plugins[create.num_plugins].func = vfw_debug;
505            plugins[create.num_plugins].param = NULL;
506            create.num_plugins++;
507    
508            create.profile = profiles[codec->config.profile].id;
509    
510            create.width = lpbiInput->bmiHeader.biWidth;
511            create.height = lpbiInput->bmiHeader.biHeight;
512            create.fincr = codec->fincr;
513            create.fbase = codec->fbase;
514    
515            create.max_key_interval = codec->config.max_key_interval;
516    
517            create.min_quant[0] = codec->config.min_iquant;
518            create.max_quant[0] = codec->config.max_iquant;
519            create.min_quant[1] = codec->config.min_pquant;
520            create.max_quant[1] = codec->config.max_pquant;
521            create.min_quant[2] = codec->config.min_bquant;
522            create.max_quant[2] = codec->config.max_bquant;
523    
524            if ((profiles[codec->config.profile].flags & PROFILE_BVOP) && codec->config.use_bvop) {
525                    create.max_bframes = codec->config.max_bframes;
526                    create.bquant_ratio = codec->config.bquant_ratio;
527                    create.bquant_offset = codec->config.bquant_offset;
528    
529                    if (codec->config.packed)
530                            create.global |= XVID_GLOBAL_PACKED;
531    
532                    if (codec->config.closed_gov)
533                            create.global |= XVID_GLOBAL_CLOSED_GOP;
534    
535            }
536    
537            create.frame_drop_ratio = codec->config.frame_drop_ratio;
538    
539            create.num_threads = codec->config.num_threads;
540    
541            switch(xvid_encore_func(0, XVID_ENC_CREATE, &create, NULL))
542            {
543            case XVID_ERR_FAIL :
544                    return ICERR_ERROR;
545    
546            case XVID_ERR_MEMORY :
547                    return ICERR_MEMORY;
548    
549            case XVID_ERR_FORMAT :
550                    return ICERR_BADFORMAT;
551    
552            case XVID_ERR_VERSION :
553                    return ICERR_UNSUPPORTED;
554            }
555    
556            codec->ehandle = create.handle;
557            codec->framenum = 0;
558            codec->keyspacing = 0;
559    
560            if (codec->config.display_status) {
561                    status_destroy_always(&codec->status);
562                    status_create(&codec->status, codec->fincr, codec->fbase);
563            }
564    
565            return ICERR_OK;
566    }
567    
568    
569    LRESULT compress_end(CODEC * codec)
570    {
571            if (m_hdll != NULL) {
572                    if (codec->ehandle != NULL) {
573                            xvid_encore_func(codec->ehandle, XVID_ENC_DESTROY, NULL, NULL);
574                            codec->ehandle = NULL;
575                    }
576                    FreeLibrary(m_hdll);
577                    m_hdll = NULL;
578            }
579    
580            if (codec->config.display_status)
581                    status_destroy(&codec->status);
582    
583            return ICERR_OK;
584    }
585    
586    
587    static void apply_zone_modifiers(xvid_enc_frame_t * frame, CONFIG * config, int framenum)
588    {
589            int i;
590    
591            for (i=0; i<config->num_zones && config->zones[i].frame <= framenum; i++) ;
592    
593            if (--i < 0) return; /* there are no zones, or we're before the first zone */
594    
595            if (framenum == config->zones[i].frame)
596                    frame->type = config->zones[i].type;
597    
598            if (config->zones[i].greyscale) {
599                    frame->vop_flags |= XVID_VOP_GREYSCALE;
600            }
601    
602            if (config->zones[i].chroma_opt) {
603                    frame->vop_flags |= XVID_VOP_CHROMAOPT;
604            }
605    
606            if ((profiles[config->profile].flags & PROFILE_BVOP) && config->use_bvop) {
607                    frame->bframe_threshold = config->zones[i].bvop_threshold;
608            }
609    }
610    
611    
612    LRESULT compress(CODEC * codec, ICCOMPRESS * icc)
613    {
614            BITMAPINFOHEADER * inhdr = icc->lpbiInput;
615            BITMAPINFOHEADER * outhdr = icc->lpbiOutput;
616            xvid_enc_frame_t frame;
617            xvid_enc_stats_t stats;
618            int length;
619    
620            memset(&frame, 0, sizeof(frame));
621            frame.version = XVID_VERSION;
622    
623            frame.type = XVID_TYPE_AUTO;
624    
625            /* vol stuff */
626    
627            if ((profiles[codec->config.profile].flags & PROFILE_MPEGQUANT) &&
628                    codec->config.quant_type != QUANT_MODE_H263)
629            {
630                    frame.vol_flags |= XVID_VOL_MPEGQUANT;
631    
632                    if (codec->config.quant_type == QUANT_MODE_CUSTOM) {
633                            frame.quant_intra_matrix = codec->config.qmatrix_intra;
634                            frame.quant_inter_matrix = codec->config.qmatrix_inter;
635                    }else{
636                            frame.quant_intra_matrix = NULL;
637                            frame.quant_inter_matrix = NULL;
638                    }
639            }
640    
641            if ((profiles[codec->config.profile].flags & PROFILE_REDUCED) &&
642                    codec->config.reduced_resolution) {
643                    frame.vol_flags |= XVID_VOL_REDUCED_ENABLE;
644                    frame.vop_flags |= XVID_VOP_REDUCED;    /* XXX: need auto decion mode */
645            }
646    
647            if ((profiles[codec->config.profile].flags & PROFILE_QPEL) && codec->config.qpel) {
648                    frame.vol_flags |= XVID_VOL_QUARTERPEL;
649                    frame.motion |= XVID_ME_QUARTERPELREFINE16 | XVID_ME_QUARTERPELREFINE8;
650            }
651    
652            if ((profiles[codec->config.profile].flags & PROFILE_GMC) && codec->config.gmc) {
653                    frame.vol_flags |= XVID_VOL_GMC;
654                    frame.motion |= XVID_ME_GME_REFINE;
655            }
656    
657            if ((profiles[codec->config.profile].flags & PROFILE_INTERLACE) && codec->config.interlacing)
658                    frame.vol_flags |= XVID_VOL_INTERLACING;
659    
660            if (codec->config.ar_mode == 0) { /* PAR */
661                    if (codec->config.display_aspect_ratio != 5) {
662                            frame.par = codec->config.display_aspect_ratio + 1;
663                    } else {
664                            frame.par = XVID_PAR_EXT;
665                            frame.par_width = codec->config.par_x;
666                            frame.par_height= codec->config.par_y;
667                    }
668            } else { /* AR */
669                    /* custom pixel aspect ratio -> calculated from DAR */
670                    frame.par = XVID_PAR_EXT;
671                    frame.par_width = (100 * inhdr->biHeight) / codec->config.ar_y;
672                    frame.par_height= (100 * inhdr->biWidth) / codec->config.ar_x;
673            }
674    
675            /* vop stuff */
676    
677            frame.vop_flags |= XVID_VOP_HALFPEL;
678            frame.vop_flags |= XVID_VOP_HQACPRED;
679    
680            if (codec->config.vop_debug)
681                    frame.vop_flags |= XVID_VOP_DEBUG;
682    
683            if (codec->config.trellis_quant) {
684                    frame.vop_flags |= XVID_VOP_TRELLISQUANT;
685            }
686    
687            if (codec->config.motion_search > 4)
688                    frame.vop_flags |= XVID_VOP_INTER4V;
689    
690            if (codec->config.chromame)
691                    frame.motion |= XVID_ME_CHROMA_PVOP + XVID_ME_CHROMA_BVOP;
692    
693            if (codec->config.cartoon_mode) {
694                    frame.vop_flags |= XVID_VOP_CARTOON;
695                    frame.motion |= XVID_ME_DETECT_STATIC_MOTION;
696            }
697    
698            if (codec->config.turbo)
699                    frame.motion |= XVID_ME_FASTREFINE16 | XVID_ME_FASTREFINE8 |
700                                                    XVID_ME_SKIP_DELTASEARCH | XVID_ME_FAST_MODEINTERPOLATE |
701                                                    XVID_ME_BFRAME_EARLYSTOP;
702    
703            frame.motion |= pmvfast_presets[codec->config.motion_search];
704    
705            switch (codec->config.vhq_mode)
706            {
707            case VHQ_MODE_DECISION :
708                    frame.vop_flags |= XVID_VOP_MODEDECISION_RD;
709                    break;
710    
711            case VHQ_LIMITED_SEARCH :
712                    frame.vop_flags |= XVID_VOP_MODEDECISION_RD;
713                    frame.motion |= XVID_ME_HALFPELREFINE16_RD;
714                    frame.motion |= XVID_ME_QUARTERPELREFINE16_RD;
715                    break;
716    
717            case VHQ_MEDIUM_SEARCH :
718                    frame.vop_flags |= XVID_VOP_MODEDECISION_RD;
719                    frame.motion |= XVID_ME_HALFPELREFINE16_RD;
720                    frame.motion |= XVID_ME_HALFPELREFINE8_RD;
721                    frame.motion |= XVID_ME_QUARTERPELREFINE16_RD;
722                    frame.motion |= XVID_ME_QUARTERPELREFINE8_RD;
723                    frame.motion |= XVID_ME_CHECKPREDICTION_RD;
724                    break;
725    
726            case VHQ_WIDE_SEARCH :
727                    frame.vop_flags |= XVID_VOP_MODEDECISION_RD;
728                    frame.motion |= XVID_ME_HALFPELREFINE16_RD;
729                    frame.motion |= XVID_ME_HALFPELREFINE8_RD;
730                    frame.motion |= XVID_ME_QUARTERPELREFINE16_RD;
731                    frame.motion |= XVID_ME_QUARTERPELREFINE8_RD;
732                    frame.motion |= XVID_ME_CHECKPREDICTION_RD;
733                    frame.motion |= XVID_ME_EXTSEARCH_RD;
734                    break;
735    
736            default :
737                    break;
738            }
739    
740            frame.input.plane[0] = icc->lpInput;
741            frame.input.stride[0] = (((icc->lpbiInput->biWidth * icc->lpbiInput->biBitCount) + 31) & ~31) >> 3;
742    
743            if ((frame.input.csp = get_colorspace(inhdr)) == XVID_CSP_NULL)
744                    return ICERR_BADFORMAT;
745    
746            if (frame.input.csp == XVID_CSP_I420 || frame.input.csp == XVID_CSP_YV12)
747                    frame.input.stride[0] = (frame.input.stride[0]*2)/3;
748    
749            frame.bitstream = icc->lpOutput;
750            frame.length = icc->lpbiOutput->biSizeImage;
751    
752            frame.quant = 0;
753    
754            if (codec->config.mode == RC_MODE_NULL) {
755                    outhdr->biSizeImage = 0;
756                    *icc->lpdwFlags = AVIIF_KEYFRAME;
757                    return ICERR_OK;
758            }
759    
760            // force keyframe spacing in 2-pass 1st pass
761            if (codec->config.motion_search == 0)
762                    frame.type = XVID_TYPE_IVOP;
763    
764            /* frame-based stuff */
765            apply_zone_modifiers(&frame, &codec->config, codec->framenum);
766    
767            /* call encore */
768    
769            memset(&stats, 0, sizeof(stats));
770            stats.version = XVID_VERSION;
771    
772            length = xvid_encore_func(codec->ehandle, XVID_ENC_ENCODE, &frame, &stats);
773            switch (length)
774            {
775            case XVID_ERR_FAIL :
776                    return ICERR_ERROR;
777    
778            case XVID_ERR_MEMORY :
779                    return ICERR_MEMORY;
780    
781            case XVID_ERR_FORMAT :
782                    return ICERR_BADFORMAT;
783    
784            case XVID_ERR_VERSION :
785                    return ICERR_UNSUPPORTED;
786            }
787    
788            if (codec->config.display_status && stats.type>0) {
789                    status_update(&codec->status, stats.type, stats.length, stats.quant);
790            }
791    
792            DPRINTF("{type=%i len=%i} length=%i", stats.type, stats.length, length);
793    
794            if (length == 0)        /* no encoder output */
795            {
796                    *icc->lpdwFlags = 0;
797                    ((char*)icc->lpOutput)[0] = 0x7f;       /* virtual dub skip frame */
798                    outhdr->biSizeImage = 1;
799    
800            }else{
801                    if (frame.out_flags & XVID_KEYFRAME)
802                    {
803                            codec->keyspacing = 0;
804                            *icc->lpdwFlags = AVIIF_KEYFRAME;
805                    }
806                    else
807                    {
808                             *icc->lpdwFlags = 0;
809                    }
810    
811                    outhdr->biSizeImage = length;
812    
813                    if (codec->config.mode == RC_MODE_2PASS1 && codec->config.discard1pass)
814                    {
815                            outhdr->biSizeImage = 0;
816                    }
817            }
818    
819            codec->framenum++;
820            codec->keyspacing++;
821    
822            return ICERR_OK;
823    }
824    
825    
826    /* decompressor */
827    
828    
829    LRESULT decompress_query(CODEC * codec, BITMAPINFO *lpbiInput, BITMAPINFO *lpbiOutput)
830    {
831            BITMAPINFOHEADER * inhdr = &lpbiInput->bmiHeader;
832            BITMAPINFOHEADER * outhdr = &lpbiOutput->bmiHeader;
833    
834            if (lpbiInput == NULL)
835            {
836                    return ICERR_ERROR;
837            }
838    
839            if (inhdr->biCompression != FOURCC_XVID && inhdr->biCompression != FOURCC_DIVX && inhdr->biCompression != FOURCC_DX50 && get_colorspace(inhdr) == XVID_CSP_NULL)
840            {
841                    return ICERR_BADFORMAT;
842            }
843    
844            if (lpbiOutput == NULL)
845            {
846                    return ICERR_OK;
847            }
848    
849            if (inhdr->biWidth != outhdr->biWidth ||
850                    inhdr->biHeight != outhdr->biHeight ||
851                    get_colorspace(outhdr) == XVID_CSP_NULL)
852            {
853                    return ICERR_BADFORMAT;
854            }
855    
856            return ICERR_OK;
857    }
858    
859    
860    LRESULT decompress_get_format(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput)
861    {
862            BITMAPINFOHEADER * inhdr = &lpbiInput->bmiHeader;
863            BITMAPINFOHEADER * outhdr = &lpbiOutput->bmiHeader;
864            LRESULT result;
865    
866            if (lpbiOutput == NULL)
867            {
868                    return sizeof(BITMAPINFOHEADER);
869            }
870    
871            /* --- yv12 --- */
872    
873            if (get_colorspace(inhdr) != XVID_CSP_NULL) {
874                    memcpy(outhdr, inhdr, sizeof(BITMAPINFOHEADER));
875                    /* XXX: should we set outhdr->biSize ?? */
876                    return ICERR_OK;
877            }
878            /* --- yv12 --- */
879    
880            result = decompress_query(codec, lpbiInput, lpbiOutput);
881            if (result != ICERR_OK)
882            {
883                    return result;
884            }
885    
886            outhdr->biSize = sizeof(BITMAPINFOHEADER);
887            outhdr->biWidth = inhdr->biWidth;
888            outhdr->biHeight = inhdr->biHeight;
889            outhdr->biPlanes = 1;
890            outhdr->biBitCount = 24;
891            outhdr->biCompression = BI_RGB; /* sonic foundry vegas video v3 only supports BI_RGB */
892            outhdr->biSizeImage = outhdr->biWidth * outhdr->biHeight * outhdr->biBitCount;
893            outhdr->biXPelsPerMeter = 0;
894            outhdr->biYPelsPerMeter = 0;
895            outhdr->biClrUsed = 0;
896            outhdr->biClrImportant = 0;
897    
898            return ICERR_OK;
899    }
900    
901    #define REG_GET_N(X, Y, Z) \
902    { \
903            DWORD size = sizeof(int); \
904            if (RegQueryValueEx(hKey, X, 0, 0, (LPBYTE)&Y, &size) != ERROR_SUCCESS) { \
905                    Y=Z; \
906            } \
907    }while(0)
908    
909    LRESULT decompress_begin(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput)
910    {
911            xvid_gbl_init_t init;
912            xvid_dec_create_t create;
913            HKEY hKey;
914    
915            if (init_dll() != 0) return ICERR_ERROR;
916    
917            memset(&init, 0, sizeof(init));
918            init.version = XVID_VERSION;
919            init.cpu_flags = codec->config.cpu;
920            xvid_global_func(0, XVID_GBL_INIT, &init, NULL);
921    
922            memset(&create, 0, sizeof(create));
923            create.version = XVID_VERSION;
924            create.width = lpbiInput->bmiHeader.biWidth;
925            create.height = lpbiInput->bmiHeader.biHeight;
926    
927            switch(xvid_decore_func(0, XVID_DEC_CREATE, &create, NULL))
928            {
929            case XVID_ERR_FAIL :
930                    return ICERR_ERROR;
931    
932            case XVID_ERR_MEMORY :
933                    return ICERR_MEMORY;
934    
935            case XVID_ERR_FORMAT :
936                    return ICERR_BADFORMAT;
937    
938            case XVID_ERR_VERSION :
939                    return ICERR_UNSUPPORTED;
940            }
941    
942            codec->dhandle = create.handle;
943    
944            RegOpenKeyEx(XVID_REG_KEY, XVID_REG_PARENT "\\" XVID_REG_CHILD, 0, KEY_READ, &hKey);
945    
946            REG_GET_N("Deblock_Y",  pp_dy, 0)
947            REG_GET_N("Deblock_UV", pp_duv, 0)
948            REG_GET_N("Dering",  pp_dr, 0)
949            REG_GET_N("FilmEffect", pp_fe, 0)
950    
951            RegCloseKey(hKey);
952    
953            return ICERR_OK;
954    }
955    
956    
957    LRESULT decompress_end(CODEC * codec)
958    {
959            if (m_hdll != NULL) {
960                    if (codec->dhandle != NULL) {
961                            xvid_decore_func(codec->dhandle, XVID_DEC_DESTROY, NULL, NULL);
962                            codec->dhandle = NULL;
963                    }
964                    FreeLibrary(m_hdll);
965                    m_hdll = NULL;
966            }
967    
968            return ICERR_OK;
969    }
970    
971    
972    LRESULT decompress(CODEC * codec, ICDECOMPRESS * icd)
973    {
974            xvid_dec_frame_t frame;
975    
976            /* --- yv12 --- */
977            if (icd->lpbiInput->biCompression != FOURCC_XVID &&
978                     icd->lpbiInput->biCompression != FOURCC_DIVX &&
979                     icd->lpbiInput->biCompression != FOURCC_DX50)
980            {
981                    xvid_gbl_convert_t convert;
982    
983                    DPRINTF("input=%c%c%c%c output=%c%c%c%c",
984                            icd->lpbiInput->biCompression&0xff,
985                            (icd->lpbiInput->biCompression>>8)&0xff,
986                            (icd->lpbiInput->biCompression>>16)&0xff,
987                            (icd->lpbiInput->biCompression>>24)&0xff,
988                            icd->lpbiOutput->biCompression&0xff,
989                            (icd->lpbiOutput->biCompression>>8)&0xff,
990                            (icd->lpbiOutput->biCompression>>16)&0xff,
991                            (icd->lpbiOutput->biCompression>>24)&0xff);
992    
993                    memset(&convert, 0, sizeof(convert));
994                    convert.version = XVID_VERSION;
995    
996                    convert.input.csp = get_colorspace(icd->lpbiInput);
997                    convert.input.plane[0] = icd->lpInput;
998                    convert.input.stride[0] = (((icd->lpbiInput->biWidth *icd->lpbiInput->biBitCount) + 31) & ~31) >> 3;
999                    if (convert.input.csp == XVID_CSP_I420 || convert.input.csp == XVID_CSP_YV12)
1000                            convert.input.stride[0] = (convert.input.stride[0]*2)/3;
1001    
1002                    convert.output.csp = get_colorspace(icd->lpbiOutput);
1003                    convert.output.plane[0] = icd->lpOutput;
1004                    convert.output.stride[0] = (((icd->lpbiOutput->biWidth *icd->lpbiOutput->biBitCount) + 31) & ~31) >> 3;
1005                    if (convert.output.csp == XVID_CSP_I420 || convert.output.csp == XVID_CSP_YV12)
1006                            convert.output.stride[0] = (convert.output.stride[0]*2)/3;
1007    
1008                    convert.width = icd->lpbiInput->biWidth;
1009                    convert.height = icd->lpbiInput->biHeight;
1010                    convert.interlacing = 0;
1011                    if (convert.input.csp == XVID_CSP_NULL ||
1012                            convert.output.csp == XVID_CSP_NULL ||
1013                            xvid_global_func(0, XVID_GBL_CONVERT, &convert, NULL) < 0)
1014                    {
1015                             return ICERR_BADFORMAT;
1016                    }
1017                    return ICERR_OK;
1018            }
1019            /* --- yv12 --- */
1020    
1021            memset(&frame, 0, sizeof(frame));
1022            frame.version = XVID_VERSION;
1023            frame.general = XVID_LOWDELAY;  /* force low_delay_default mode */
1024            frame.bitstream = icd->lpInput;
1025            frame.length = icd->lpbiInput->biSizeImage;
1026    
1027            if (~((icd->dwFlags & ICDECOMPRESS_HURRYUP) | (icd->dwFlags & ICDECOMPRESS_UPDATE) | (icd->dwFlags & ICDECOMPRESS_PREROLL)))
1028            {
1029                    if ((frame.output.csp = get_colorspace(icd->lpbiOutput)) == XVID_CSP_NULL)
1030                    {
1031                            return ICERR_BADFORMAT;
1032                    }
1033                    frame.output.plane[0] = icd->lpOutput;
1034                    frame.output.stride[0] = (((icd->lpbiOutput->biWidth * icd->lpbiOutput->biBitCount) + 31) & ~31) >> 3;
1035                    if (frame.output.csp == XVID_CSP_I420 || frame.output.csp == XVID_CSP_YV12)
1036                            frame.output.stride[0] = (frame.output.stride[0]*2)/3;
1037            }
1038            else
1039            {
1040                    frame.output.csp = XVID_CSP_NULL;
1041            }
1042    
1043            if (pp_dy)frame.general |= XVID_DEBLOCKY;
1044            if (pp_duv) frame.general |= XVID_DEBLOCKUV;
1045    /*      if (pp_dr) frame.general |= XVID_DERING; */
1046            if (pp_fe) frame.general |= XVID_FILMEFFECT;
1047    
1048            switch (xvid_decore_func(codec->dhandle, XVID_DEC_DECODE, &frame, NULL))
1049            {
1050            case XVID_ERR_FAIL :
1051                    return ICERR_ERROR;
1052    
1053            case XVID_ERR_MEMORY :
1054                    return ICERR_MEMORY;
1055    
1056            case XVID_ERR_FORMAT :
1057                    return ICERR_BADFORMAT;
1058    
1059            case XVID_ERR_VERSION :
1060                    return ICERR_UNSUPPORTED;
1061            }
1062    
1063            return ICERR_OK;
1064    }
1065    

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.1.2.33

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