[cvs] / xvidcore / src / plugins / plugin_2pass1.c Repository:
ViewVC logotype

Diff of /xvidcore/src/plugins/plugin_2pass1.c

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

revision 1.1, Sun Mar 23 04:03:01 2003 UTC revision 1.1.2.13, Sat Dec 20 15:38:13 2003 UTC
# Line 0  Line 1 
1    /******************************************************************************
2     *
3     *  XviD Bit Rate Controller Library
4     *  - VBR 2 pass bitrate controler implementation -
5     *
6     *  Copyright (C) 2002-2003 Edouard Gomez <ed.gomez@free.fr>
7     *
8     *  The curve treatment algorithm is the one implemented by Foxer <email?> and
9     *  Dirk Knop <dknop@gwdg.de> for the XviD vfw dynamic library.
10     *
11     *  This program is free software; you can redistribute it and/or modify
12     *  it under the terms of the GNU General Public License as published by
13     *  the Free Software Foundation; either version 2 of the License, or
14     *  (at your option) any later version.
15     *
16     *  This program is distributed in the hope that it will be useful,
17     *  but WITHOUT ANY WARRANTY; without even the implied warranty of
18     *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19     *  GNU General Public License for more details.
20     *
21     *  You should have received a copy of the GNU General Public License
22     *  along with this program; if not, write to the Free Software
23     *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24     *
25     * $Id$
26     *
27     *****************************************************************************/
28    
29    #include <stdio.h>
30    #include <errno.h> /* errno var (or function with recent libc) */
31    #include <string.h> /* strerror() */
32    
33    #include "../xvid.h"
34    #include "../image/image.h"
35    
36    
37    #define FAST1PASS
38    
39    
40    /* context struct */
41    typedef struct
42    {
43            FILE * stat_file;
44    
45        double fq_error;
46    } rc_2pass1_t;
47    
48    
49    
50    static int rc_2pass1_create(xvid_plg_create_t * create, rc_2pass1_t ** handle)
51    {
52        xvid_plugin_2pass1_t * param = (xvid_plugin_2pass1_t *)create->param;
53            rc_2pass1_t * rc;
54    
55        /* check filename */
56        if ((param->filename == NULL) ||
57                    (param->filename != NULL && param->filename[0] == '\0'))
58            return XVID_ERR_FAIL;
59    
60        /* allocate context struct */
61            if((rc = malloc(sizeof(rc_2pass1_t))) == NULL)
62                    return(XVID_ERR_MEMORY);
63    
64        /* Initialize safe defaults for 2pass 1 */
65        rc->stat_file = NULL;
66    
67            /* Open the 1st pass file */
68            if((rc->stat_file = fopen(param->filename, "w+b")) == NULL)
69                    return(XVID_ERR_FAIL);
70    
71            /* I swear xvidcore isn't buggy, but when using mencoder+xvid4 i observe
72             * this weird bug.
73             *
74             * Symptoms: The stats file grows until it's fclosed, but at this moment
75             *           a large part of the file is filled by 0x00 bytes w/o any
76             *           reasonable cause. The stats file is then completly unusable
77             *
78             * So far, i think i found "the why":
79             *  - take a MPEG stream containing 2 sequences (concatenate 2 MPEG files
80             *    together)
81             *  - Encode this MPEG file
82             *
83             * It should trigger the bug
84             *
85             * I think this is caused by some kind of race condition on mencoder module
86             * start/stop.
87             *  - mencoder encodes the first sequence
88             *    + xvid4 module opens xvid-twopass.stats and writes stats in it.
89             *  - mencoder detects the second sequence and initialize a second
90             *    module and stops the old encoder
91             *    + new xvid4 module opens a new xvid-twopass.stats, old xvid4
92             *      module closes it
93             *
94             * This is IT, got a racing condition.
95             * Unbuffered IO, may help ... */
96            setbuf(rc->stat_file, NULL);
97    
98            /*
99             * The File Header
100             */
101            fprintf(rc->stat_file, "# XviD 2pass stat file (core version %d.%d.%d)\n",
102                            XVID_VERSION_MAJOR(XVID_VERSION),
103                            XVID_VERSION_MINOR(XVID_VERSION),
104                            XVID_VERSION_PATCH(XVID_VERSION));
105            fprintf(rc->stat_file, "# Please do not modify this file\n\n");
106    
107        rc->fq_error = 0;
108    
109        *handle = rc;
110            return(0);
111    }
112    
113    
114    static int rc_2pass1_destroy(rc_2pass1_t * rc, xvid_plg_destroy_t * destroy)
115    {
116            if (rc->stat_file) {
117                    if (fclose(rc->stat_file) == EOF) {
118                            DPRINTF(XVID_DEBUG_RC, "Error closing stats file (%s)", strerror(errno));
119                    }
120            }
121            rc->stat_file = NULL; /* Just a paranoid reset */
122            free(rc); /* as the container structure is freed anyway */
123            return(0);
124    }
125    
126    
127    static int rc_2pass1_before(rc_2pass1_t * rc, xvid_plg_data_t * data)
128    {
129             if (data->quant <= 0) {
130                    if (data->zone && data->zone->mode == XVID_ZONE_QUANT) {
131                            rc->fq_error += (double)data->zone->increment / (double)data->zone->base;
132                            data->quant = (int)rc->fq_error;
133                            rc->fq_error -= data->quant;
134                    } else {
135                            data->quant = 2;
136    
137    #ifdef FAST1PASS
138    
139                            data->motion_flags &= ~(XVID_ME_CHROMA_PVOP + XVID_ME_CHROMA_BVOP + XVID_ME_USESQUARES16
140                                                                            + XVID_ME_ADVANCEDDIAMOND16 + XVID_ME_EXTSEARCH16);
141    
142                            data->motion_flags |= XVID_ME_FAST_MODEINTERPOLATE + XVID_ME_SKIP_DELTASEARCH
143                                                                            + XVID_ME_FASTREFINE16 + XVID_ME_BFRAME_EARLYSTOP;
144    
145                            data->vop_flags &= ~(XVID_VOP_MODEDECISION_RD + XVID_VOP_FAST_MODEDECISION_RD
146                                                                    + XVID_VOP_TRELLISQUANT + XVID_VOP_INTER4V + XVID_VOP_HQACPRED);
147    
148                            data->vol_flags &= ~XVID_VOL_GMC;
149    #endif
150                    }
151            }
152             return(0);
153    }
154    
155    
156    static int rc_2pass1_after(rc_2pass1_t * rc, xvid_plg_data_t * data)
157    {
158            char type;
159            xvid_enc_stats_t *stats = &data->stats;
160    
161            /* Frame type in ascii I/P/B */
162            switch(stats->type) {
163            case XVID_TYPE_IVOP:
164                    type = 'i';
165                    break;
166            case XVID_TYPE_PVOP:
167                    type = 'p';
168                    break;
169            case XVID_TYPE_BVOP:
170                    type = 'b';
171                    break;
172            case XVID_TYPE_SVOP:
173                    type = 's';
174                    break;
175            default: /* Should not go here */
176                    return(XVID_ERR_FAIL);
177            }
178    
179            /* write the resulting statistics */
180    
181            fprintf(rc->stat_file, "%c %d %d %d %d %d %d\n",
182                            type,
183                            stats->quant,
184                            stats->kblks,
185                            stats->mblks,
186                            stats->ublks,
187                            stats->length,
188                            stats->hlength);
189    
190            return(0);
191    }
192    
193    
194    
195    int xvid_plugin_2pass1(void * handle, int opt, void * param1, void * param2)
196    {
197        switch(opt)
198        {
199        case XVID_PLG_INFO :
200            case XVID_PLG_FRAME :
201            return 0;
202    
203        case XVID_PLG_CREATE :
204            return rc_2pass1_create((xvid_plg_create_t*)param1, param2);
205    
206        case XVID_PLG_DESTROY :
207            return rc_2pass1_destroy((rc_2pass1_t*)handle, (xvid_plg_destroy_t*)param1);
208    
209        case XVID_PLG_BEFORE :
210            return rc_2pass1_before((rc_2pass1_t*)handle, (xvid_plg_data_t*)param1);
211    
212        case XVID_PLG_AFTER :
213            return rc_2pass1_after((rc_2pass1_t*)handle, (xvid_plg_data_t*)param1);
214        }
215    
216        return XVID_ERR_FAIL;
217    }

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

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