--- branches/dev-api-4/xvidcore/vfw/src/codec.c 2003/04/12 06:58:50 983 +++ branches/dev-api-4/xvidcore/vfw/src/codec.c 2003/05/14 11:44:29 1017 @@ -49,6 +49,7 @@ #include #include +#include "vfwext.h" #include #include "debug.h" @@ -169,6 +170,11 @@ BITMAPINFOHEADER * inhdr = &lpbiInput->bmiHeader; BITMAPINFOHEADER * outhdr = &lpbiOutput->bmiHeader; + /* VFWEXT detection */ + if (inhdr->biCompression == VFWEXT_FOURCC) { + return (ICM_USER+0x0fff); + } + if (get_colorspace(inhdr) == XVID_CSP_NULL) { return ICERR_BADFORMAT; @@ -237,6 +243,7 @@ LRESULT compress_frames_info(CODEC * codec, ICCOMPRESSFRAMES * icf) { + //DPRINTF("%i %i", icf->lStartFrame, icf->lFrameCount); codec->fincr = icf->dwScale; codec->fbase = icf->dwRate; return ICERR_OK; @@ -289,11 +296,10 @@ xvid_gbl_init_t init; xvid_enc_create_t create; xvid_enc_plugin_t plugins[3]; - - xvid_plugin_fixed_t fixed; - xvid_plugin_cbr_t cbr; + xvid_plugin_single_t single; xvid_plugin_2pass1_t pass1; xvid_plugin_2pass2_t pass2; + int i; /* destroy previously created codec */ if(codec->ehandle) { @@ -308,30 +314,36 @@ memset(&create, 0, sizeof(create)); create.version = XVID_VERSION; - create.plugins = plugins; + // zones + create.zones = malloc(sizeof(xvid_enc_zone_t) * codec->config.num_zones); + create.num_zones = codec->config.num_zones; + for (i=0; i < create.num_zones; i++) { + create.zones[i].frame = codec->config.zones[i].frame; + if (create.zones[i].mode = RC_ZONE_QUANT) { + create.zones[i].mode = XVID_ZONE_QUANT; + create.zones[i].increment = codec->config.zones[i].quant; + }else{ + create.zones[i].mode = XVID_ZONE_WEIGHT; + create.zones[i].increment = codec->config.zones[i].weight; + } + create.zones[i].base = 100; + } + + // plugins + create.plugins = plugins; switch (codec->config.mode) { - case RC_MODE_CBR : - memset(&cbr, 0, sizeof(cbr)); - cbr.version = XVID_VERSION; - cbr.bitrate = codec->config.rc_bitrate; - cbr.reaction_delay_factor = codec->config.rc_reaction_delay_factor; - cbr.averaging_period = codec->config.rc_averaging_period; - cbr.buffer = codec->config.rc_buffer; - plugins[create.num_plugins].func = xvid_plugin_cbr; - plugins[create.num_plugins].param = &cbr; - create.num_plugins++; - - case RC_MODE_FIXED : - memset(&fixed, 0, sizeof(fixed)); - fixed.version = XVID_VERSION; - fixed.quant_increment = codec->config.quant; - fixed.quant_base = 1; - plugins[create.num_plugins].func = xvid_plugin_fixed; - plugins[create.num_plugins].param = &fixed; + case RC_MODE_1PASS : + memset(&single, 0, sizeof(single)); + single.version = XVID_VERSION; + single.bitrate = codec->config.bitrate; + single.reaction_delay_factor = codec->config.rc_reaction_delay_factor; + single.averaging_period = codec->config.rc_averaging_period; + single.buffer = codec->config.rc_buffer; + plugins[create.num_plugins].func = xvid_plugin_single; + plugins[create.num_plugins].param = &single; create.num_plugins++; - break; case RC_MODE_2PASS1 : memset(&pass1, 0, sizeof(pass1)); @@ -342,21 +354,12 @@ create.num_plugins++; break; - - case RC_MODE_2PASS2_INT : - case RC_MODE_2PASS2_EXT : + case RC_MODE_2PASS2 : memset(&pass2, 0, sizeof(pass2)); pass2.version = XVID_VERSION; - pass2.min_quant[0] = codec->config.min_iquant; - pass2.max_quant[0] = codec->config.max_iquant; - pass2.min_quant[1] = codec->config.min_pquant; - pass2.max_quant[1] = codec->config.max_pquant; - //pass2.min_quant[2] = codec->config.min_bquant; - //pass2.max_quant[2] = codec->config.max_bquant; + pass2.bitrate = codec->config.bitrate; pass2.filename = codec->config.stats; - if (codec->config.mode == RC_MODE_2PASS2_INT) { - pass2.bitrate = 10000; /* xxx */ - } + plugins[create.num_plugins].func = xvid_plugin_2pass2; plugins[create.num_plugins].param = &pass2; create.num_plugins++; @@ -369,7 +372,7 @@ break; } - if (codec->config.lum_masking) { + if ((profiles[codec->config.profile].flags & PROFILE_ADAPTQUANT) && codec->config.lum_masking) { plugins[create.num_plugins].func = xvid_plugin_lumimasking; plugins[create.num_plugins].param = NULL; create.num_plugins++; @@ -379,28 +382,38 @@ plugins[create.num_plugins].param = NULL; create.num_plugins++; + create.profile = profiles[codec->config.profile].id; + create.width = lpbiInput->bmiHeader.biWidth; create.height = lpbiInput->bmiHeader.biHeight; create.fincr = codec->fincr; create.fbase = codec->fbase; - if (codec->config.packed) - create.global |= XVID_GLOBAL_PACKED; - if (codec->config.closed_gov) - create.global |= XVID_GLOBAL_CLOSED_GOP; - create.max_key_interval = codec->config.max_key_interval; - /* XXX: param.min_quantizer = codec->config.min_pquant; - param.max_quantizer = codec->config.max_pquant; */ - if (codec->config.use_bvop) + create.min_quant[0] = codec->config.min_iquant; + create.max_quant[0] = codec->config.max_iquant; + create.min_quant[1] = codec->config.min_pquant; + create.max_quant[1] = codec->config.max_pquant; + create.min_quant[2] = codec->config.min_bquant; + create.max_quant[2] = codec->config.max_bquant; + + if ((profiles[codec->config.profile].flags & PROFILE_BVOP) && codec->config.use_bvop) { create.max_bframes = codec->config.max_bframes; - create.frame_drop_ratio = codec->config.frame_drop_ratio; + create.bquant_ratio = codec->config.bquant_ratio; + create.bquant_offset = codec->config.bquant_offset; + + if (codec->config.packed) + create.global |= XVID_GLOBAL_PACKED; + + if (codec->config.closed_gov) + create.global |= XVID_GLOBAL_CLOSED_GOP; + + } - create.bquant_ratio = codec->config.bquant_ratio; - create.bquant_offset = codec->config.bquant_offset; + create.frame_drop_ratio = codec->config.frame_drop_ratio; - create.num_threads = codec->config.num_threads; + create.num_threads = codec->config.num_threads; switch(xvid_encore(0, XVID_ENC_CREATE, &create, NULL)) { @@ -436,6 +449,28 @@ return ICERR_OK; } + +static void apply_zone_modifiers(xvid_enc_frame_t * frame, CONFIG * config, int framenum) +{ + int i; + + for (i=0; inum_zones && config->zones[i].frame <= framenum; i++) ; + i--; + + if (config->zones[i].greyscale) { + frame->vop_flags |= XVID_VOP_GREYSCALE; + } + + if (config->zones[i].chroma_opt) { + frame->vop_flags |= XVID_VOP_CHROMAOPT; + } + + if ((profiles[config->profile].flags & PROFILE_BVOP) && config->use_bvop) { + frame->bframe_threshold = config->zones[i].bvop_threshold; + } +} + + LRESULT compress(CODEC * codec, ICCOMPRESS * icc) { BITMAPINFOHEADER * inhdr = icc->lpbiInput; @@ -444,8 +479,6 @@ xvid_enc_stats_t stats; int length; - // mpeg2avi yuv bug workaround (2 instances of CODEC) - memset(&frame, 0, sizeof(frame)); frame.version = XVID_VERSION; @@ -453,38 +486,35 @@ /* vol stuff */ - if (codec->config.quant_type != QUANT_MODE_H263) + if ((profiles[codec->config.profile].flags & PROFILE_MPEGQUANT) && + codec->config.quant_type != QUANT_MODE_H263) { frame.vol_flags |= XVID_VOL_MPEGQUANT; - // we actually need "default/custom" selectbox for both inter/intra - // this will do for now - if (codec->config.quant_type == QUANT_MODE_CUSTOM) - { + if (codec->config.quant_type == QUANT_MODE_CUSTOM) { frame.quant_intra_matrix = codec->config.qmatrix_intra; frame.quant_inter_matrix = codec->config.qmatrix_inter; - } - else - { + }else{ frame.quant_intra_matrix = NULL; frame.quant_inter_matrix = NULL; } } - if (codec->config.reduced_resolution) { + if ((profiles[codec->config.profile].flags & PROFILE_REDUCED) && + codec->config.reduced_resolution) { frame.vol_flags |= XVID_VOL_REDUCED_ENABLE; frame.vop_flags |= XVID_VOP_REDUCED; /* XXX: need auto decion mode */ } - if (codec->config.qpel) { + if ((profiles[codec->config.profile].flags & PROFILE_QPEL) && codec->config.qpel) { frame.vol_flags |= XVID_VOL_QUARTERPEL; frame.motion |= XVID_ME_QUARTERPELREFINE16 | XVID_ME_QUARTERPELREFINE8; } - if (codec->config.gmc) + if ((profiles[codec->config.profile].flags & PROFILE_GMC) && codec->config.gmc) frame.vol_flags |= XVID_VOL_GMC; - if (codec->config.interlacing) + if ((profiles[codec->config.profile].flags & PROFILE_INTERLACE) && codec->config.interlacing) frame.vol_flags |= XVID_VOL_INTERLACING; /* vop stuff */ @@ -495,15 +525,16 @@ if (codec->config.debug) frame.vop_flags |= XVID_VOP_DEBUG; - if (codec->config.motion_search > 4) + if (codec->config.trellis_quant) { + frame.vop_flags |= XVID_VOP_TRELLISQUANT; + } + + if (codec->config.motion_search > 4) frame.vop_flags |= XVID_VOP_INTER4V; if (codec->config.chromame) frame.vop_flags |= XVID_ME_CHROMA16 + XVID_ME_CHROMA8; - if (codec->config.chroma_opt) - frame.vop_flags |= XVID_VOP_CHROMAOPT; - frame.motion |= pmvfast_presets[codec->config.motion_search]; switch (codec->config.vhq_mode) @@ -541,8 +572,6 @@ break; } - frame.bframe_threshold = codec->config.bvop_threshold; - frame.input.plane[0] = icc->lpInput; frame.input.stride[0] = (((icc->lpbiInput->biWidth * icc->lpbiInput->biBitCount) + 31) & ~31) >> 3; @@ -555,39 +584,13 @@ frame.bitstream = icc->lpOutput; frame.length = icc->lpbiOutput->biSizeImage; - switch (codec->config.mode) - { - case RC_MODE_CBR : - frame.quant = 0; /* use xvidcore cbr rate control */ - break; - - //case RC_MODE_VBR_QUAL : - case RC_MODE_FIXED : - case RC_MODE_2PASS1 : - /*if (codec_get_quant(codec, &frame) == ICERR_ERROR) - { - return ICERR_ERROR; - }*/ - break; - - case RC_MODE_2PASS2_EXT : - case RC_MODE_2PASS2_INT : - /*if (codec_2pass_get_quant(codec, &frame) == ICERR_ERROR) - { - return ICERR_ERROR; - }*/ - break; + frame.quant = 0; - case RC_MODE_NULL : + if (codec->config.mode == RC_MODE_NULL) { outhdr->biSizeImage = 0; *icc->lpdwFlags = AVIIF_KEYFRAME; return ICERR_OK; - - default : - DPRINTF("Invalid encoding mode"); - return ICERR_ERROR; - } - + } // force keyframe spacing in 2-pass 1st pass if (codec->config.motion_search == 0) @@ -600,6 +603,11 @@ frame.type = XVID_TYPE_PVOP; } + /* frame-based stuff */ + apply_zone_modifiers(&frame, &codec->config, codec->framenum); + + /* call encore */ + memset(&stats, 0, sizeof(stats)); stats.version = XVID_VERSION; @@ -646,8 +654,8 @@ } } - ++codec->framenum; - ++codec->keyspacing; + codec->framenum++; + codec->keyspacing++; return ICERR_OK; }