--- plugin_2pass1.c 2003/03/23 04:03:01 1.1 +++ plugin_2pass1.c 2003/11/19 15:42:38 1.1.2.9 @@ -0,0 +1,165 @@ +/****************************************************************************** + * + * XviD Bit Rate Controller Library + * - VBR 2 pass bitrate controler implementation - + * + * Copyright (C) 2002-2003 Edouard Gomez + * + * The curve treatment algorithm is the one implemented by Foxer and + * Dirk Knop for the XviD vfw dynamic library. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * $Id: plugin_2pass1.c,v 1.1.2.9 2003/11/19 15:42:38 syskin Exp $ + * + *****************************************************************************/ + +#include + +#include "../xvid.h" +#include "../image/image.h" + + +/* context struct */ +typedef struct +{ + FILE * stat_file; + + double fq_error; +} rc_2pass1_t; + + + +static int rc_2pass1_create(xvid_plg_create_t * create, rc_2pass1_t ** handle) +{ + xvid_plugin_2pass1_t * param = (xvid_plugin_2pass1_t *)create->param; + rc_2pass1_t * rc; + + /* check filename */ + if ((param->filename == NULL) || + (param->filename != NULL && param->filename[0] == '\0')) + return XVID_ERR_FAIL; + + /* allocate context struct */ + if((rc = malloc(sizeof(rc_2pass1_t))) == NULL) + return(XVID_ERR_MEMORY); + + /* Initialize safe defaults for 2pass 1 */ + rc->stat_file = NULL; + + /* Open the 1st pass file */ + if((rc->stat_file = fopen(param->filename, "w+b")) == NULL) + return(XVID_ERR_FAIL); + + /* + * The File Header + */ + fprintf(rc->stat_file, "# XviD 2pass stat file (core version %d.%d.%d)\n", + XVID_VERSION_MAJOR(XVID_VERSION), + XVID_VERSION_MINOR(XVID_VERSION), + XVID_VERSION_PATCH(XVID_VERSION)); + fprintf(rc->stat_file, "# Please do not modify this file\n\n"); + + rc->fq_error = 0; + + *handle = rc; + return(0); +} + + +static int rc_2pass1_destroy(rc_2pass1_t * rc, xvid_plg_destroy_t * destroy) +{ + fclose(rc->stat_file); + free(rc); + return(0); +} + + +static int rc_2pass1_before(rc_2pass1_t * rc, xvid_plg_data_t * data) +{ + if (data->quant <= 0) { + if (data->zone && data->zone->mode == XVID_ZONE_QUANT) { + rc->fq_error += (double)data->zone->increment / (double)data->zone->base; + data->quant = (int)rc->fq_error; + rc->fq_error -= data->quant; + + }else { + data->quant = 2; + } + } + return 0; +} + + +static int rc_2pass1_after(rc_2pass1_t * rc, xvid_plg_data_t * data) +{ + char type; + + /* Frame type in ascii I/P/B */ + switch(data->type) { + case XVID_TYPE_IVOP: + type = 'i'; + break; + case XVID_TYPE_PVOP: + type = 'p'; + break; + case XVID_TYPE_BVOP: + type = 'b'; + break; + case XVID_TYPE_SVOP: + type = 's'; + break; + default: /* Should not go here */ + return(XVID_ERR_FAIL); + } + + /* write the resulting statistics */ + + fprintf(rc->stat_file, "%c %d %d %d %d %d\n", + type, + data->quant, + data->kblks, + data->mblks, + data->ublks, + data->length); + + return(0); +} + + + +int xvid_plugin_2pass1(void * handle, int opt, void * param1, void * param2) +{ + switch(opt) + { + case XVID_PLG_INFO : + case XVID_PLG_FRAME : + return 0; + + case XVID_PLG_CREATE : + return rc_2pass1_create((xvid_plg_create_t*)param1, param2); + + case XVID_PLG_DESTROY : + return rc_2pass1_destroy((rc_2pass1_t*)handle, (xvid_plg_destroy_t*)param1); + + case XVID_PLG_BEFORE : + return rc_2pass1_before((rc_2pass1_t*)handle, (xvid_plg_data_t*)param1); + + case XVID_PLG_AFTER : + return rc_2pass1_after((rc_2pass1_t*)handle, (xvid_plg_data_t*)param1); + } + + return XVID_ERR_FAIL; +}