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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1.2.13 - (view) (download)

1 : suxen_drol 1.1.2.1 /******************************************************************************
2 :     *
3 : edgomez 1.1.2.5 * XviD Bit Rate Controller Library
4 :     * - VBR 2 pass bitrate controler implementation -
5 : suxen_drol 1.1.2.1 *
6 : edgomez 1.1.2.5 * Copyright (C) 2002-2003 Edouard Gomez <ed.gomez@free.fr>
7 : suxen_drol 1.1.2.1 *
8 : edgomez 1.1.2.5 * 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 : suxen_drol 1.1.2.1 *
11 : edgomez 1.1.2.5 * 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 : suxen_drol 1.1.2.1 *
16 : edgomez 1.1.2.5 * 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 : suxen_drol 1.1.2.1 *
21 : edgomez 1.1.2.5 * 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 : suxen_drol 1.1.2.1 *
25 : syskin 1.1.2.13 * $Id: plugin_2pass1.c,v 1.1.2.12 2003/12/20 15:30:03 edgomez Exp $
26 : suxen_drol 1.1.2.1 *
27 :     *****************************************************************************/
28 :    
29 :     #include <stdio.h>
30 : edgomez 1.1.2.12 #include <errno.h> /* errno var (or function with recent libc) */
31 :     #include <string.h> /* strerror() */
32 : suxen_drol 1.1.2.1
33 :     #include "../xvid.h"
34 :     #include "../image/image.h"
35 :    
36 :    
37 : syskin 1.1.2.13 #define FAST1PASS
38 :    
39 :    
40 : suxen_drol 1.1.2.1 /* context struct */
41 :     typedef struct
42 :     {
43 :     FILE * stat_file;
44 : suxen_drol 1.1.2.3
45 :     double fq_error;
46 : suxen_drol 1.1.2.1 } 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 : edgomez 1.1.2.6 if ((param->filename == NULL) ||
57 :     (param->filename != NULL && param->filename[0] == '\0'))
58 : suxen_drol 1.1.2.1 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 : edgomez 1.1.2.7 /* Initialize safe defaults for 2pass 1 */
65 : suxen_drol 1.1.2.1 rc->stat_file = NULL;
66 :    
67 :     /* Open the 1st pass file */
68 : edgomez 1.1.2.8 if((rc->stat_file = fopen(param->filename, "w+b")) == NULL)
69 : suxen_drol 1.1.2.1 return(XVID_ERR_FAIL);
70 : suxen_drol 1.1.2.3
71 : edgomez 1.1.2.12 /* 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 : suxen_drol 1.1.2.1 /*
99 :     * The File Header
100 :     */
101 : edgomez 1.1.2.8 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 : edgomez 1.1.2.7
107 : suxen_drol 1.1.2.3 rc->fq_error = 0;
108 : suxen_drol 1.1.2.1
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 : edgomez 1.1.2.12 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 : suxen_drol 1.1.2.1 return(0);
124 :     }
125 :    
126 :    
127 :     static int rc_2pass1_before(rc_2pass1_t * rc, xvid_plg_data_t * data)
128 :     {
129 : edgomez 1.1.2.10 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 : syskin 1.1.2.13
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 : edgomez 1.1.2.10 }
151 :     }
152 :     return(0);
153 : suxen_drol 1.1.2.1 }
154 :    
155 :    
156 :     static int rc_2pass1_after(rc_2pass1_t * rc, xvid_plg_data_t * data)
157 :     {
158 :     char type;
159 : edgomez 1.1.2.11 xvid_enc_stats_t *stats = &data->stats;
160 : suxen_drol 1.1.2.1
161 :     /* Frame type in ascii I/P/B */
162 : edgomez 1.1.2.11 switch(stats->type) {
163 : suxen_drol 1.1.2.1 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 : edgomez 1.1.2.11 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 : suxen_drol 1.1.2.1
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 : syskin 1.1.2.9 case XVID_PLG_FRAME :
201 : suxen_drol 1.1.2.1 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 :     }

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