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

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

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