[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.28, Sat Jan 3 12:06:11 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    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    const 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    int vfw_debug(void *handle,
269                             int opt,
270                             void *param1,
271                             void *param2)
272    {
273            switch (opt) {
274            case XVID_PLG_INFO:
275            case XVID_PLG_CREATE:
276            case XVID_PLG_DESTROY:
277            case XVID_PLG_BEFORE:
278                    return 0;
279    
280            case XVID_PLG_AFTER:
281                    {
282                            xvid_plg_data_t *data = (xvid_plg_data_t *) param1;
283    
284                            /* We don't use DPRINTF here because it's active only for _DEBUG
285                             * builds and that activates lot of other debug printfs. We only
286                             * want these all the time */
287                            char buf[1024];
288                            sprintf(buf, "[%6i]   type=%c   Q:%2i   length:%6i",
289                                            data->frame_num,
290                                            type2char(data->type),
291                                            data->quant,
292                                            data->length);
293                            OutputDebugString(buf);
294    
295                            return 0;
296                    }
297            }
298    
299            return XVID_ERR_FAIL;
300    }
301    
302    #define XVID_DLL_NAME "xvidcore.dll"
303    
304    static int init_dll()
305    {
306            if (m_hdll != NULL) return 0;
307    
308            DPRINTF("init_dll");
309            m_hdll = LoadLibrary(XVID_DLL_NAME);
310            if (m_hdll == NULL) {
311                    DPRINTF("dll load failed");
312                    MessageBox(0, XVID_DLL_NAME " not found","Error", 0);
313                    return XVID_ERR_FAIL;
314            }
315    
316            xvid_global_func = (int (__cdecl *)(void *, int, void *, void *))GetProcAddress(m_hdll, "xvid_global");
317            if (xvid_global_func == NULL) {
318                    MessageBox(0, "xvid_global() not found", "Error", 0);
319                    return XVID_ERR_FAIL;
320            }
321    
322            xvid_encore_func = (int (__cdecl *)(void *, int, void *, void *))GetProcAddress(m_hdll, "xvid_encore");
323            if (xvid_encore_func == NULL) {
324                    MessageBox(0, "xvid_encore() not found", "Error", 0);
325                    return XVID_ERR_FAIL;
326            }
327    
328            xvid_decore_func = (int (__cdecl *)(void *, int, void *, void *))GetProcAddress(m_hdll, "xvid_decore");
329            if (xvid_decore_func == NULL) {
330                    MessageBox(0, "xvid_decore() not found", "Error", 0);
331                    return XVID_ERR_FAIL;
332            }
333    
334            xvid_plugin_single_func =
335                    (int (__cdecl *)(void *, int, void *, void *))(GetProcAddress(m_hdll, "xvid_plugin_single"));
336            xvid_plugin_2pass1_func =
337                    (int (__cdecl *)(void *, int, void *, void *))(GetProcAddress(m_hdll, "xvid_plugin_2pass1"));
338            xvid_plugin_2pass2_func =
339                    (int (__cdecl *)(void *, int, void *, void *))(GetProcAddress(m_hdll, "xvid_plugin_2pass2"));
340            xvid_plugin_lumimasking_func =
341                    (int (__cdecl *)(void *, int, void *, void *))(GetProcAddress(m_hdll, "xvid_plugin_lumimasking"));
342            xvid_plugin_psnr_func =
343                    (int (__cdecl *)(void *, int, void *, void *))(GetProcAddress(m_hdll, "xvid_plugin_psnr"));
344    
345            return 0;
346    }
347    
348    
349    LRESULT compress_begin(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput)
350    {
351            xvid_gbl_init_t init;
352            xvid_enc_create_t create;
353        xvid_enc_plugin_t plugins[3];
354            xvid_plugin_single_t single;
355            xvid_plugin_2pass1_t pass1;
356            xvid_plugin_2pass2_t pass2;
357        int i;
358    
359            if (init_dll() != 0) return ICERR_ERROR;
360        /* destroy previously created codec */
361            if(codec->ehandle) {
362                    xvid_encore_func(codec->ehandle, XVID_ENC_DESTROY, NULL, NULL);
363                    codec->ehandle = NULL;
364            }
365    
366        memset(&init, 0, sizeof(init));
367            init.version = XVID_VERSION;
368            init.cpu_flags = codec->config.cpu;
369        init.debug = codec->config.debug;
370            xvid_global_func(0, XVID_GBL_INIT, &init, NULL);
371    
372            memset(&create, 0, sizeof(create));
373            create.version = XVID_VERSION;
374    
375        /* zones */
376        create.zones = malloc(sizeof(xvid_enc_zone_t) * codec->config.num_zones);
377        create.num_zones = codec->config.num_zones;
378        for (i=0; i < create.num_zones; i++) {
379            create.zones[i].frame = codec->config.zones[i].frame;
380            if (codec->config.zones[i].mode == RC_ZONE_QUANT) {
381                create.zones[i].mode = XVID_ZONE_QUANT;
382                create.zones[i].increment = codec->config.zones[i].quant;
383            }else{
384                create.zones[i].mode = XVID_ZONE_WEIGHT;
385                create.zones[i].increment = codec->config.zones[i].weight;
386            }
387            create.zones[i].base = 100;
388        }
389    
390        /* plugins */
391            create.plugins = plugins;
392            switch (codec->config.mode)
393            {
394            case RC_MODE_1PASS :
395            memset(&single, 0, sizeof(single));
396                single.version = XVID_VERSION;
397            single.bitrate = codec->config.bitrate * CONFIG_KBPS;
398            single.reaction_delay_factor = codec->config.rc_reaction_delay_factor;
399                    single.averaging_period = codec->config.rc_averaging_period;
400                    single.buffer = codec->config.rc_buffer;
401            plugins[create.num_plugins].func = xvid_plugin_single_func;
402            plugins[create.num_plugins].param = &single;
403            create.num_plugins++;
404            break;
405    
406            case RC_MODE_2PASS1 :
407            memset(&pass1, 0, sizeof(pass1));
408                pass1.version = XVID_VERSION;
409            pass1.filename = codec->config.stats;
410    
411            plugins[create.num_plugins].func = xvid_plugin_2pass1_func;
412            plugins[create.num_plugins].param = &pass1;
413            create.num_plugins++;
414                    break;
415    
416            case RC_MODE_2PASS2 :
417            memset(&pass2, 0, sizeof(pass2));
418                pass2.version = XVID_VERSION;
419            if (codec->config.use_2pass_bitrate) {
420                pass2.bitrate = codec->config.bitrate * CONFIG_KBPS;
421            }else{
422                pass2.bitrate = -codec->config.desired_size;    /* kilobytes */
423            }
424                    pass2.filename = codec->config.stats;
425    
426            pass2.keyframe_boost = codec->config.keyframe_boost;   /* keyframe boost percentage: [0..100...]; */
427            pass2.curve_compression_high = codec->config.curve_compression_high;
428            pass2.curve_compression_low = codec->config.curve_compression_low;
429                    pass2.overflow_control_strength = codec->config.overflow_control_strength;
430            pass2.max_overflow_improvement = codec->config.twopass_max_overflow_improvement;
431            pass2.max_overflow_degradation = codec->config.twopass_max_overflow_degradation;
432                pass2.kfreduction = codec->config.kfreduction;
433            pass2.kfthreshold = codec->config.kfthreshold;
434            pass2.container_frame_overhead = 24;    /* AVI */
435    
436            plugins[create.num_plugins].func = xvid_plugin_2pass2_func;
437            plugins[create.num_plugins].param = &pass2;
438            create.num_plugins++;
439                    break;
440    
441            case RC_MODE_NULL :
442                    return ICERR_OK;
443    
444            default :
445                    break;
446            }
447    
448            if ((profiles[codec->config.profile].flags & PROFILE_ADAPTQUANT) && codec->config.lum_masking) {
449            plugins[create.num_plugins].func = xvid_plugin_lumimasking_func;
450            plugins[create.num_plugins].param = NULL;
451            create.num_plugins++;
452            }
453    
454        plugins[create.num_plugins].func = vfw_debug;
455        plugins[create.num_plugins].param = NULL;
456        create.num_plugins++;
457    
458        create.profile = profiles[codec->config.profile].id;
459    
460            create.width = lpbiInput->bmiHeader.biWidth;
461            create.height = lpbiInput->bmiHeader.biHeight;
462            create.fincr = codec->fincr;
463            create.fbase = codec->fbase;
464    
465        create.max_key_interval = codec->config.max_key_interval;
466    
467        create.min_quant[0] = codec->config.min_iquant;
468        create.max_quant[0] = codec->config.max_iquant;
469        create.min_quant[1] = codec->config.min_pquant;
470        create.max_quant[1] = codec->config.max_pquant;
471        create.min_quant[2] = codec->config.min_bquant;
472        create.max_quant[2] = codec->config.max_bquant;
473    
474        if ((profiles[codec->config.profile].flags & PROFILE_BVOP) && codec->config.use_bvop) {
475            create.max_bframes = codec->config.max_bframes;
476                create.bquant_ratio = codec->config.bquant_ratio;
477                create.bquant_offset = codec->config.bquant_offset;
478    
479            if (codec->config.packed)
480                create.global |= XVID_GLOBAL_PACKED;
481    
482                if (codec->config.closed_gov)
483                        create.global |= XVID_GLOBAL_CLOSED_GOP;
484    
485        }
486    
487            create.frame_drop_ratio = codec->config.frame_drop_ratio;
488    
489        create.num_threads = codec->config.num_threads;
490    
491            switch(xvid_encore_func(0, XVID_ENC_CREATE, &create, NULL))
492            {
493            case XVID_ERR_FAIL :
494                    return ICERR_ERROR;
495    
496            case XVID_ERR_MEMORY :
497                    return ICERR_MEMORY;
498    
499            case XVID_ERR_FORMAT :
500                    return ICERR_BADFORMAT;
501    
502            case XVID_ERR_VERSION :
503                    return ICERR_UNSUPPORTED;
504            }
505    
506            codec->ehandle = create.handle;
507            codec->framenum = 0;
508            codec->keyspacing = 0;
509    
510        if (codec->config.display_status) {
511            status_destroy_always(&codec->status);
512            status_create(&codec->status, codec->fincr, codec->fbase);
513        }
514    
515            return ICERR_OK;
516    }
517    
518    
519    LRESULT compress_end(CODEC * codec)
520    {
521        if (m_hdll != NULL) {
522                    if (codec->ehandle != NULL) {
523                            xvid_encore_func(codec->ehandle, XVID_ENC_DESTROY, NULL, NULL);
524                            codec->ehandle = NULL;
525                    }
526                    FreeLibrary(m_hdll);
527                    m_hdll = NULL;
528            }
529    
530        if (codec->config.display_status)
531            status_destroy(&codec->status);
532    
533            return ICERR_OK;
534    }
535    
536    
537    static void apply_zone_modifiers(xvid_enc_frame_t * frame, CONFIG * config, int framenum)
538    {
539        int i;
540    
541        for (i=0; i<config->num_zones && config->zones[i].frame <= framenum; i++) ;
542    
543        if (--i < 0) return; /* there are no zones, or we're before the first zone */
544    
545        if (framenum == config->zones[i].frame)
546                    frame->type = config->zones[i].type;
547    
548        if (config->zones[i].greyscale) {
549            frame->vop_flags |= XVID_VOP_GREYSCALE;
550        }
551    
552        if (config->zones[i].chroma_opt) {
553            frame->vop_flags |= XVID_VOP_CHROMAOPT;
554        }
555    
556        if ((profiles[config->profile].flags & PROFILE_BVOP) && config->use_bvop) {
557            frame->bframe_threshold = config->zones[i].bvop_threshold;
558        }
559    }
560    
561    
562    LRESULT compress(CODEC * codec, ICCOMPRESS * icc)
563    {
564            BITMAPINFOHEADER * inhdr = icc->lpbiInput;
565            BITMAPINFOHEADER * outhdr = icc->lpbiOutput;
566            xvid_enc_frame_t frame;
567            xvid_enc_stats_t stats;
568            int length;
569    
570            memset(&frame, 0, sizeof(frame));
571            frame.version = XVID_VERSION;
572    
573        frame.type = XVID_TYPE_AUTO;
574    
575            /* vol stuff */
576    
577        if ((profiles[codec->config.profile].flags & PROFILE_MPEGQUANT) &&
578            codec->config.quant_type != QUANT_MODE_H263)
579            {
580                    frame.vol_flags |= XVID_VOL_MPEGQUANT;
581    
582                    if (codec->config.quant_type == QUANT_MODE_CUSTOM) {
583                            frame.quant_intra_matrix = codec->config.qmatrix_intra;
584                            frame.quant_inter_matrix = codec->config.qmatrix_inter;
585                    }else{
586                            frame.quant_intra_matrix = NULL;
587                            frame.quant_inter_matrix = NULL;
588                    }
589            }
590    
591        if ((profiles[codec->config.profile].flags & PROFILE_REDUCED) &&
592                codec->config.reduced_resolution) {
593                    frame.vol_flags |= XVID_VOL_REDUCED_ENABLE;
594                    frame.vop_flags |= XVID_VOP_REDUCED;    /* XXX: need auto decion mode */
595            }
596    
597            if ((profiles[codec->config.profile].flags & PROFILE_QPEL) && codec->config.qpel) {
598                    frame.vol_flags |= XVID_VOL_QUARTERPEL;
599                    frame.motion |= XVID_ME_QUARTERPELREFINE16 | XVID_ME_QUARTERPELREFINE8;
600            }
601    
602            if ((profiles[codec->config.profile].flags & PROFILE_GMC) && codec->config.gmc) {
603                    frame.vol_flags |= XVID_VOL_GMC;
604                    frame.motion |= XVID_ME_GME_REFINE;
605            }
606    
607            if ((profiles[codec->config.profile].flags & PROFILE_INTERLACE) && codec->config.interlacing)
608                    frame.vol_flags |= XVID_VOL_INTERLACING;
609    
610            if (codec->config.ar_mode == 0) { /* PAR */
611                    if (codec->config.display_aspect_ratio != 5) {
612                            frame.par = codec->config.display_aspect_ratio + 1;
613                    } else {
614                            frame.par = XVID_PAR_EXT;
615                            frame.par_width = codec->config.par_x;
616                            frame.par_height= codec->config.par_y;
617                    }
618            } else { /* AR */
619                    /* custom pixel aspect ratio -> calculated from DAR */
620                    frame.par = XVID_PAR_EXT;
621                    frame.par_width = (100 * inhdr->biHeight) / codec->config.ar_y;
622                    frame.par_height= (100 * inhdr->biWidth) / codec->config.ar_x;
623            }
624    
625        /* vop stuff */
626    
627            frame.vop_flags |= XVID_VOP_HALFPEL;
628            frame.vop_flags |= XVID_VOP_HQACPRED;
629    
630            if (codec->config.vop_debug)
631                    frame.vop_flags |= XVID_VOP_DEBUG;
632    
633        if (codec->config.trellis_quant) {
634            frame.vop_flags |= XVID_VOP_TRELLISQUANT;
635        }
636    
637        if (codec->config.motion_search > 4)
638                    frame.vop_flags |= XVID_VOP_INTER4V;
639    
640            if (codec->config.chromame)
641                    frame.motion |= XVID_ME_CHROMA_PVOP + XVID_ME_CHROMA_BVOP;
642    
643            if (codec->config.cartoon_mode) {
644                    frame.vop_flags |= XVID_VOP_CARTOON;
645                    frame.motion |= XVID_ME_DETECT_STATIC_MOTION;
646            }
647    
648            if (codec->config.turbo)
649                    frame.motion |= XVID_ME_FASTREFINE16 | XVID_ME_FASTREFINE8 |
650                                                    XVID_ME_SKIP_DELTASEARCH | XVID_ME_FAST_MODEINTERPOLATE |
651                                                    XVID_ME_BFRAME_EARLYSTOP;
652    
653            frame.motion |= pmvfast_presets[codec->config.motion_search];
654    
655            switch (codec->config.vhq_mode)
656            {
657            case VHQ_MODE_DECISION :
658                    frame.vop_flags |= XVID_VOP_MODEDECISION_RD;
659                    break;
660    
661            case VHQ_LIMITED_SEARCH :
662                    frame.vop_flags |= XVID_VOP_MODEDECISION_RD;
663                    frame.motion |= XVID_ME_HALFPELREFINE16_RD;
664                    frame.motion |= XVID_ME_QUARTERPELREFINE16_RD;
665                    break;
666    
667            case VHQ_MEDIUM_SEARCH :
668                    frame.vop_flags |= XVID_VOP_MODEDECISION_RD;
669                    frame.motion |= XVID_ME_HALFPELREFINE16_RD;
670                    frame.motion |= XVID_ME_HALFPELREFINE8_RD;
671                    frame.motion |= XVID_ME_QUARTERPELREFINE16_RD;
672                    frame.motion |= XVID_ME_QUARTERPELREFINE8_RD;
673                    frame.motion |= XVID_ME_CHECKPREDICTION_RD;
674                    break;
675    
676            case VHQ_WIDE_SEARCH :
677                    frame.vop_flags |= XVID_VOP_MODEDECISION_RD;
678                    frame.motion |= XVID_ME_HALFPELREFINE16_RD;
679                    frame.motion |= XVID_ME_HALFPELREFINE8_RD;
680                    frame.motion |= XVID_ME_QUARTERPELREFINE16_RD;
681                    frame.motion |= XVID_ME_QUARTERPELREFINE8_RD;
682                    frame.motion |= XVID_ME_CHECKPREDICTION_RD;
683                    frame.motion |= XVID_ME_EXTSEARCH_RD;
684                    break;
685    
686            default :
687                    break;
688            }
689    
690            frame.input.plane[0] = icc->lpInput;
691            frame.input.stride[0] = (((icc->lpbiInput->biWidth * icc->lpbiInput->biBitCount) + 31) & ~31) >> 3;
692    
693            if ((frame.input.csp = get_colorspace(inhdr)) == XVID_CSP_NULL)
694                    return ICERR_BADFORMAT;
695    
696            if (frame.input.csp == XVID_CSP_I420 || frame.input.csp == XVID_CSP_YV12)
697                    frame.input.stride[0] = (frame.input.stride[0]*2)/3;
698    
699            frame.bitstream = icc->lpOutput;
700            frame.length = icc->lpbiOutput->biSizeImage;
701    
702        frame.quant = 0;
703    
704        if (codec->config.mode == RC_MODE_NULL) {
705                    outhdr->biSizeImage = 0;
706                    *icc->lpdwFlags = AVIIF_KEYFRAME;
707                    return ICERR_OK;
708        }
709    
710            // force keyframe spacing in 2-pass 1st pass
711            if (codec->config.motion_search == 0)
712                    frame.type = XVID_TYPE_IVOP;
713    
714        /* frame-based stuff */
715        apply_zone_modifiers(&frame, &codec->config, codec->framenum);
716    
717        /* call encore */
718    
719            memset(&stats, 0, sizeof(stats));
720            stats.version = XVID_VERSION;
721    
722        length = xvid_encore_func(codec->ehandle, XVID_ENC_ENCODE, &frame, &stats);
723            switch (length)
724            {
725            case XVID_ERR_FAIL :
726                    return ICERR_ERROR;
727    
728            case XVID_ERR_MEMORY :
729                    return ICERR_MEMORY;
730    
731            case XVID_ERR_FORMAT :
732                    return ICERR_BADFORMAT;
733    
734            case XVID_ERR_VERSION :
735                    return ICERR_UNSUPPORTED;
736            }
737    
738        if (codec->config.display_status && stats.type>0) {
739            status_update(&codec->status, stats.type, stats.length, stats.quant);
740        }
741    
742            DPRINTF("{type=%i len=%i} length=%i", stats.type, stats.length, length);
743    
744        if (length == 0)    /* no encoder output */
745            {
746                    *icc->lpdwFlags = 0;
747                    ((char*)icc->lpOutput)[0] = 0x7f;       /* virtual dub skip frame */
748                    outhdr->biSizeImage = 1;
749    
750            }else{
751                    if (frame.out_flags & XVID_KEYFRAME)
752                {
753                        codec->keyspacing = 0;
754                        *icc->lpdwFlags = AVIIF_KEYFRAME;
755                }
756                else
757                {
758                         *icc->lpdwFlags = 0;
759                }
760    
761            outhdr->biSizeImage = length;
762    
763            if (codec->config.mode == RC_MODE_2PASS1 && codec->config.discard1pass)
764                {
765                        outhdr->biSizeImage = 0;
766                }
767        }
768    
769            codec->framenum++;
770            codec->keyspacing++;
771    
772            return ICERR_OK;
773    }
774    
775    
776    /* decompressor */
777    
778    
779    LRESULT decompress_query(CODEC * codec, BITMAPINFO *lpbiInput, BITMAPINFO *lpbiOutput)
780    {
781            BITMAPINFOHEADER * inhdr = &lpbiInput->bmiHeader;
782            BITMAPINFOHEADER * outhdr = &lpbiOutput->bmiHeader;
783    
784            if (lpbiInput == NULL)
785            {
786                    return ICERR_ERROR;
787            }
788    
789            if (inhdr->biCompression != FOURCC_XVID && inhdr->biCompression != FOURCC_DIVX && inhdr->biCompression != FOURCC_DX50 && get_colorspace(inhdr) == XVID_CSP_NULL)
790            {
791                    return ICERR_BADFORMAT;
792            }
793    
794            if (lpbiOutput == NULL)
795            {
796                    return ICERR_OK;
797            }
798    
799            if (inhdr->biWidth != outhdr->biWidth ||
800                    inhdr->biHeight != outhdr->biHeight ||
801                    get_colorspace(outhdr) == XVID_CSP_NULL)
802            {
803                    return ICERR_BADFORMAT;
804            }
805    
806            return ICERR_OK;
807    }
808    
809    
810    LRESULT decompress_get_format(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput)
811    {
812            BITMAPINFOHEADER * inhdr = &lpbiInput->bmiHeader;
813            BITMAPINFOHEADER * outhdr = &lpbiOutput->bmiHeader;
814            LRESULT result;
815    
816            if (lpbiOutput == NULL)
817            {
818                    return sizeof(BITMAPINFOHEADER);
819            }
820    
821            /* --- yv12 --- */
822    
823            if (get_colorspace(inhdr) != XVID_CSP_NULL) {
824                    memcpy(outhdr, inhdr, sizeof(BITMAPINFOHEADER));
825                    /* XXX: should we set outhdr->biSize ?? */
826                    return ICERR_OK;
827            }
828            /* --- yv12 --- */
829    
830            result = decompress_query(codec, lpbiInput, lpbiOutput);
831            if (result != ICERR_OK)
832            {
833                    return result;
834            }
835    
836            outhdr->biSize = sizeof(BITMAPINFOHEADER);
837            outhdr->biWidth = inhdr->biWidth;
838            outhdr->biHeight = inhdr->biHeight;
839            outhdr->biPlanes = 1;
840            outhdr->biBitCount = 24;
841            outhdr->biCompression = BI_RGB; /* sonic foundry vegas video v3 only supports BI_RGB */
842            outhdr->biSizeImage = outhdr->biWidth * outhdr->biHeight * outhdr->biBitCount;
843            outhdr->biXPelsPerMeter = 0;
844            outhdr->biYPelsPerMeter = 0;
845            outhdr->biClrUsed = 0;
846            outhdr->biClrImportant = 0;
847    
848            return ICERR_OK;
849    }
850    
851    
852    LRESULT decompress_begin(CODEC * codec, BITMAPINFO * lpbiInput, BITMAPINFO * lpbiOutput)
853    {
854            xvid_gbl_init_t init;
855            xvid_dec_create_t create;
856    
857            if (init_dll() != 0) return ICERR_ERROR;
858    
859            memset(&init, 0, sizeof(init));
860            init.version = XVID_VERSION;
861            init.cpu_flags = codec->config.cpu;
862            xvid_global_func(0, XVID_GBL_INIT, &init, NULL);
863    
864            memset(&create, 0, sizeof(create));
865            create.version = XVID_VERSION;
866            create.width = lpbiInput->bmiHeader.biWidth;
867            create.height = lpbiInput->bmiHeader.biHeight;
868    
869            switch(xvid_decore_func(0, XVID_DEC_CREATE, &create, NULL))
870            {
871            case XVID_ERR_FAIL :
872                    return ICERR_ERROR;
873    
874            case XVID_ERR_MEMORY :
875                    return ICERR_MEMORY;
876    
877            case XVID_ERR_FORMAT :
878                    return ICERR_BADFORMAT;
879    
880            case XVID_ERR_VERSION :
881                    return ICERR_UNSUPPORTED;
882            }
883    
884            codec->dhandle = create.handle;
885    
886            return ICERR_OK;
887    }
888    
889    
890    LRESULT decompress_end(CODEC * codec)
891    {
892            if (m_hdll != NULL) {
893                    if (codec->dhandle != NULL) {
894                            xvid_decore_func(codec->dhandle, XVID_DEC_DESTROY, NULL, NULL);
895                            codec->dhandle = NULL;
896                    }
897                    FreeLibrary(m_hdll);
898                    m_hdll = NULL;
899            }
900    
901            return ICERR_OK;
902    }
903    
904    
905    LRESULT decompress(CODEC * codec, ICDECOMPRESS * icd)
906    {
907            xvid_dec_frame_t frame;
908    
909            /* --- yv12 --- */
910            if (icd->lpbiInput->biCompression != FOURCC_XVID &&
911                     icd->lpbiInput->biCompression != FOURCC_DIVX &&
912                     icd->lpbiInput->biCompression != FOURCC_DX50)
913            {
914                    xvid_gbl_convert_t convert;
915    
916                    DPRINTF("input=%c%c%c%c output=%c%c%c%c",
917                icd->lpbiInput->biCompression&0xff,
918                (icd->lpbiInput->biCompression>>8)&0xff,
919                (icd->lpbiInput->biCompression>>16)&0xff,
920                (icd->lpbiInput->biCompression>>24)&0xff,
921                icd->lpbiOutput->biCompression&0xff,
922                (icd->lpbiOutput->biCompression>>8)&0xff,
923                (icd->lpbiOutput->biCompression>>16)&0xff,
924                (icd->lpbiOutput->biCompression>>24)&0xff);
925    
926                    memset(&convert, 0, sizeof(convert));
927                    convert.version = XVID_VERSION;
928    
929                    convert.input.csp = get_colorspace(icd->lpbiInput);
930                    convert.input.plane[0] = icd->lpInput;
931                    convert.input.stride[0] = (((icd->lpbiInput->biWidth *icd->lpbiInput->biBitCount) + 31) & ~31) >> 3;
932                    if (convert.input.csp == XVID_CSP_I420 || convert.input.csp == XVID_CSP_YV12)
933                            convert.input.stride[0] = (convert.input.stride[0]*2)/3;
934    
935                    convert.output.csp = get_colorspace(icd->lpbiOutput);
936                    convert.output.plane[0] = icd->lpOutput;
937                    convert.output.stride[0] = (((icd->lpbiOutput->biWidth *icd->lpbiOutput->biBitCount) + 31) & ~31) >> 3;
938                    if (convert.output.csp == XVID_CSP_I420 || convert.output.csp == XVID_CSP_YV12)
939                            convert.output.stride[0] = (convert.output.stride[0]*2)/3;
940    
941                    convert.width = icd->lpbiInput->biWidth;
942                    convert.height = icd->lpbiInput->biHeight;
943                    convert.interlacing = 0;
944                    if (convert.input.csp == XVID_CSP_NULL ||
945                            convert.output.csp == XVID_CSP_NULL ||
946                            xvid_global_func(0, XVID_GBL_CONVERT, &convert, NULL) < 0)
947                    {
948                             return ICERR_BADFORMAT;
949                    }
950                    return ICERR_OK;
951            }
952            /* --- yv12 --- */
953    
954        memset(&frame, 0, sizeof(frame));
955        frame.version = XVID_VERSION;
956        frame.general = XVID_LOWDELAY;      /* force low_delay_default mode */
957            frame.bitstream = icd->lpInput;
958            frame.length = icd->lpbiInput->biSizeImage;
959    
960            if (~((icd->dwFlags & ICDECOMPRESS_HURRYUP) | (icd->dwFlags & ICDECOMPRESS_UPDATE) | (icd->dwFlags & ICDECOMPRESS_PREROLL)))
961            {
962                    if ((frame.output.csp = get_colorspace(icd->lpbiOutput)) == XVID_CSP_NULL)
963                    {
964                            return ICERR_BADFORMAT;
965                    }
966                    frame.output.plane[0] = icd->lpOutput;
967                    frame.output.stride[0] = (((icd->lpbiOutput->biWidth * icd->lpbiOutput->biBitCount) + 31) & ~31) >> 3;
968                    if (frame.output.csp == XVID_CSP_I420 || frame.output.csp == XVID_CSP_YV12)
969                            frame.output.stride[0] = (frame.output.stride[0]*2)/3;
970            }
971            else
972            {
973                    frame.output.csp = XVID_CSP_NULL;
974            }
975    
976            switch (xvid_decore_func(codec->dhandle, XVID_DEC_DECODE, &frame, NULL))
977            {
978            case XVID_ERR_FAIL :
979                    return ICERR_ERROR;
980    
981            case XVID_ERR_MEMORY :
982                    return ICERR_MEMORY;
983    
984            case XVID_ERR_FORMAT :
985                    return ICERR_BADFORMAT;
986    
987            case XVID_ERR_VERSION :
988                    return ICERR_UNSUPPORTED;
989            }
990    
991            return ICERR_OK;
992    }
993    

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

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