--- encoder.c 2003/11/20 12:07:19 1.95.2.55 +++ encoder.c 2003/12/19 10:55:58 1.95.2.60 @@ -21,7 +21,7 @@ * along with this program ; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * $Id: encoder.c,v 1.95.2.55 2003/11/20 12:07:19 syskin Exp $ + * $Id: encoder.c,v 1.95.2.60 2003/12/19 10:55:58 syskin Exp $ * ****************************************************************************/ @@ -250,6 +250,14 @@ if (pEnc->current->mbs == NULL || pEnc->reference->mbs == NULL) goto xvid_err_memory2; + /* allocate quant matrix memory */ + + pEnc->mbParam.mpeg_quant_matrices = + xvid_malloc(sizeof(uint16_t) * 64 * 8, CACHE_LINE); + + if (pEnc->mbParam.mpeg_quant_matrices == NULL) + goto xvid_err_memory2a; + /* allocate interpolation image memory */ if ((pEnc->mbParam.plugin_flags & XVID_REQORIGINAL)) { @@ -403,6 +411,7 @@ create->handle = (void *) pEnc; init_timer(); + init_mpeg_matrix(pEnc->mbParam.mpeg_quant_matrices); return 0; /* ok */ @@ -469,6 +478,8 @@ image_destroy(&pEnc->vGMC, pEnc->mbParam.edged_width, pEnc->mbParam.edged_height); + xvid_err_memory2a: + xvid_free(pEnc->mbParam.mpeg_quant_matrices); xvid_err_memory2: xvid_free(pEnc->current->mbs); @@ -597,6 +608,8 @@ xvid_free(pEnc->plugins); } + xvid_free(pEnc->mbParam.mpeg_quant_matrices); + if (pEnc->num_plugins>0) xvid_free(pEnc->zones); @@ -727,20 +740,22 @@ data.mblks = frame->sStat.mblks; data.ublks = frame->sStat.ublks; - if (stats) { - stats->type = coding2type(frame->coding_type); - stats->quant = frame->quant; - stats->vol_flags = frame->vol_flags; - stats->vop_flags = frame->vop_flags; - stats->length = frame->length; - stats->hlength = frame->length - (frame->sStat.iTextBits / 8); - stats->kblks = frame->sStat.kblks; - stats->mblks = frame->sStat.mblks; - stats->ublks = frame->sStat.ublks; - stats->sse_y = data.sse_y; - stats->sse_u = data.sse_u; - stats->sse_v = data.sse_v; - } + /* New code */ + data.stats.type = coding2type(frame->coding_type); + data.stats.quant = frame->quant; + data.stats.vol_flags = frame->vol_flags; + data.stats.vop_flags = frame->vop_flags; + data.stats.length = frame->length; + data.stats.hlength = frame->length - (frame->sStat.iTextBits / 8); + data.stats.kblks = frame->sStat.kblks; + data.stats.mblks = frame->sStat.mblks; + data.stats.ublks = frame->sStat.ublks; + data.stats.sse_y = data.sse_y; + data.stats.sse_u = data.sse_u; + data.stats.sse_v = data.sse_v; + + if (stats) + *stats = data.stats; } /* call plugins */ @@ -833,20 +848,65 @@ { pCur->ticks = (int32_t)pCur->stamp % time_base; - pCur->seconds = ((int32_t)pCur->stamp / time_base) - ((int32_t)pRef->stamp / time_base) ; + pCur->seconds = ((int32_t)pCur->stamp / time_base) - ((int32_t)pRef->stamp / time_base) ; - /* HEAVY DEBUG OUTPUT remove when timecodes prove to be stable */ - -/* fprintf(stderr,"WriteVop: %d - %d \n", +#if 0 /* HEAVY DEBUG OUTPUT */ + fprintf(stderr,"WriteVop: %d - %d \n", ((int32_t)pCur->stamp / time_base), ((int32_t)pRef->stamp / time_base)); - fprintf(stderr,"set_timecodes: VOP %1d stamp=%lld ref_stamp=%lld base=%d\n", + fprintf(stderr,"set_timecodes: VOP %1d stamp=%lld ref_stamp=%lld base=%d\n", pCur->coding_type, pCur->stamp, pRef->stamp, time_base); - fprintf(stderr,"set_timecodes: VOP %1d seconds=%d ticks=%d (ref-sec=%d ref-tick=%d)\n", + fprintf(stderr,"set_timecodes: VOP %1d seconds=%d ticks=%d (ref-sec=%d ref-tick=%d)\n", pCur->coding_type, pCur->seconds, pCur->ticks, pRef->seconds, pRef->ticks); +#endif +} -*/ +static int +gcd(int a, int b) +{ + int r ; + + if (b > a) { + r = a; + a = b; + b = r; + } + + while ((r = a % b)) { + a = b; + b = r; + } + return b; } +static void +simplify_par(int *par_width, int *par_height) +{ + + int _par_width = (!*par_width) ? 1 : (*par_width<0) ? -*par_width: *par_width; + int _par_height = (!*par_height) ? 1 : (*par_height<0) ? -*par_height: *par_height; + int divisor = gcd(_par_width, _par_height); + + _par_width /= divisor; + _par_height /= divisor; + + /* 2^8 precision maximum */ + if (_par_width>255 || _par_height>255) { + float div; + emms(); + if (_par_width>_par_height) + div = (float)_par_width/255; + else + div = (float)_par_height/255; + + _par_width = (int)((float)_par_width/div); + _par_height = (int)((float)_par_height/div); + } + + *par_width = _par_width; + *par_height = _par_height; + + return; +} /***************************************************************************** @@ -1208,7 +1268,9 @@ pEnc->iFrameNum = 1; /* ---- update vol flags at IVOP ----------- */ - pEnc->current->vol_flags = pEnc->mbParam.vol_flags = frame->vol_flags; + pEnc->mbParam.vol_flags = pEnc->current->vol_flags; + + /* Aspect ratio */ switch(frame->par) { case XVID_PAR_11_VGA: case XVID_PAR_43_PAL: @@ -1219,17 +1281,22 @@ pEnc->mbParam.par = frame->par; break; default: - pEnc->mbParam.par = XVID_PAR_EXT; + pEnc->mbParam.par = XVID_PAR_11_VGA; break; } - pEnc->mbParam.par_width = (frame->par_width)?frame->par_width:1; - pEnc->mbParam.par_height = (frame->par_height)?frame->par_height:1; + + /* For extended PAR only, we try to sanityse/simplify par values */ + if (pEnc->mbParam.par == XVID_PAR_EXT) { + pEnc->mbParam.par_width = frame->par_width; + pEnc->mbParam.par_height = frame->par_height; + simplify_par(&pEnc->mbParam.par_width, &pEnc->mbParam.par_height); + } if ((pEnc->mbParam.vol_flags & XVID_VOL_MPEGQUANT)) { if (frame->quant_intra_matrix != NULL) - set_intra_matrix(frame->quant_intra_matrix); + set_intra_matrix(pEnc->mbParam.mpeg_quant_matrices, frame->quant_intra_matrix); if (frame->quant_inter_matrix != NULL) - set_inter_matrix(frame->quant_inter_matrix); + set_inter_matrix(pEnc->mbParam.mpeg_quant_matrices, frame->quant_inter_matrix); } /* prevent vol/vop misuse */