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

Diff of /xvidcore/src/encoder.c

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

revision 1.95.2.32, Wed Jul 2 13:15:01 2003 UTC revision 1.95.2.46, Mon Oct 27 00:50:05 2003 UTC
# Line 117  Line 117 
117          Encoder *pEnc;          Encoder *pEnc;
118      int n;      int n;
119    
120          if (XVID_MAJOR(create->version) != 1)   /* v1.x.x */          if (XVID_VERSION_MAJOR(create->version) != 1) /* v1.x.x */
121                  return XVID_ERR_VERSION;                  return XVID_ERR_VERSION;
122    
123          if (create->width%2 || create->height%2)          if (create->width%2 || create->height%2)
# Line 226  Line 226 
226          pEnc->mbParam.frame_drop_ratio = MAX(create->frame_drop_ratio, 0);          pEnc->mbParam.frame_drop_ratio = MAX(create->frame_drop_ratio, 0);
227    
228      /* max keyframe interval */      /* max keyframe interval */
229      pEnc->mbParam.iMaxKeyInterval = create->max_key_interval <= 0 ?      pEnc->mbParam.iMaxKeyInterval = create->max_key_interval <= 0 ? (10 * (int)pEnc->mbParam.fbase) / (int)pEnc->mbParam.fincr : create->max_key_interval;
                 (10 * pEnc->mbParam.fbase) / pEnc->mbParam.fincr : create->max_key_interval;  
230    
231      /* allocate working frame-image memory */      /* allocate working frame-image memory */
232    
# Line 390  Line 389 
389                  image_null(&pEnc->queue[n].image);                  image_null(&pEnc->queue[n].image);
390    
391    
392          for (n = 0; n < pEnc->mbParam.max_bframes+1; n++)          for (n = 0; n < pEnc->mbParam.max_bframes+1; n++) {
         {  
393                  if (image_create                  if (image_create
394                          (&pEnc->queue[n].image, pEnc->mbParam.edged_width,                          (&pEnc->queue[n].image, pEnc->mbParam.edged_width,
395                           pEnc->mbParam.edged_height) < 0)                           pEnc->mbParam.edged_height) < 0)
396                          goto xvid_err_memory5;                          goto xvid_err_memory5;
   
397          }          }
398    
   
399          /* timestamp stuff */          /* timestamp stuff */
400    
401          pEnc->mbParam.m_stamp = 0;          pEnc->mbParam.m_stamp = 0;
# Line 424  Line 420 
420    
421    xvid_err_memory5:    xvid_err_memory5:
422    
423          if (pEnc->mbParam.max_bframes > 0) {          for (n = 0; n < pEnc->mbParam.max_bframes+1; n++) {
424          int i;                          image_destroy(&pEnc->queue[n].image, pEnc->mbParam.edged_width,
   
                 for (i = 0; i < pEnc->mbParam.max_bframes+1; i++) {  
                         image_destroy(&pEnc->queue[i].image, pEnc->mbParam.edged_width,  
425                                                    pEnc->mbParam.edged_height);                                                    pEnc->mbParam.edged_height);
426                  }                  }
427    
428                  xvid_free(pEnc->queue);                  xvid_free(pEnc->queue);
         }  
429    
430    xvid_err_memory4:    xvid_err_memory4:
431    
# Line 446  Line 439 
439    
440                          image_destroy(&pEnc->bframes[i]->image, pEnc->mbParam.edged_width,                          image_destroy(&pEnc->bframes[i]->image, pEnc->mbParam.edged_width,
441                                                    pEnc->mbParam.edged_height);                                                    pEnc->mbParam.edged_height);
   
442                          xvid_free(pEnc->bframes[i]->mbs);                          xvid_free(pEnc->bframes[i]->mbs);
   
443                          xvid_free(pEnc->bframes[i]);                          xvid_free(pEnc->bframes[i]);
   
444                  }                  }
445    
446                  xvid_free(pEnc->bframes);                  xvid_free(pEnc->bframes);
# Line 539  Line 529 
529          int i;          int i;
530    
531          /* B Frames specific */          /* B Frames specific */
         if (pEnc->mbParam.max_bframes > 0) {  
   
532                  for (i = 0; i < pEnc->mbParam.max_bframes+1; i++) {                  for (i = 0; i < pEnc->mbParam.max_bframes+1; i++) {
   
533                          image_destroy(&pEnc->queue[i].image, pEnc->mbParam.edged_width,                          image_destroy(&pEnc->queue[i].image, pEnc->mbParam.edged_width,
534                                            pEnc->mbParam.edged_height);                                            pEnc->mbParam.edged_height);
535                  }                  }
                 xvid_free(pEnc->queue);  
         }  
536    
537            xvid_free(pEnc->queue);
538    
539          if (pEnc->mbParam.max_bframes > 0) {          if (pEnc->mbParam.max_bframes > 0) {
540    
# Line 559  Line 545 
545    
546                          image_destroy(&pEnc->bframes[i]->image, pEnc->mbParam.edged_width,                          image_destroy(&pEnc->bframes[i]->image, pEnc->mbParam.edged_width,
547                                            pEnc->mbParam.edged_height);                                            pEnc->mbParam.edged_height);
   
548                          xvid_free(pEnc->bframes[i]->mbs);                          xvid_free(pEnc->bframes[i]->mbs);
   
549                          xvid_free(pEnc->bframes[i]);                          xvid_free(pEnc->bframes[i]);
550                  }                  }
551    
# Line 741  Line 725 
725    
726              for (j=0; j<pEnc->mbParam.mb_height; j++)              for (j=0; j<pEnc->mbParam.mb_height; j++)
727              for (i=0; i<pEnc->mbParam.mb_width; i++) {              for (i=0; i<pEnc->mbParam.mb_width; i++) {
728                  data.dquant[j*data.dquant_stride + i] = frame->mbs[j*pEnc->mbParam.mb_width + i].dquant;;                  data.dquant[j*data.dquant_stride + i] = frame->mbs[j*pEnc->mbParam.mb_width + i].dquant;
729              }              }
730          }          }
731    
# Line 771  Line 755 
755      }      }
756    
757      /* call plugins */      /* call plugins */
758      for (i=0; i<pEnc->num_plugins;i++) {      for (i=0; i<(unsigned int)pEnc->num_plugins;i++) {
759          emms();          emms();
760          if (pEnc->plugins[i].func) {          if (pEnc->plugins[i].func) {
761              if (pEnc->plugins[i].func(pEnc->plugins[i].param, opt, &data, 0) < 0) {              if (pEnc->plugins[i].func(pEnc->plugins[i].param, opt, &data, 0) < 0) {
# Line 867  Line 851 
851          int type;          int type;
852          Bitstream bs;          Bitstream bs;
853    
854          if (XVID_MAJOR(xFrame->version) != 1 || (stats && XVID_MAJOR(stats->version) != 1))     /* v1.x.x */          if (XVID_VERSION_MAJOR(xFrame->version) != 1 || (stats && XVID_VERSION_MAJOR(stats->version) != 1))     /* v1.x.x */
855                  return XVID_ERR_VERSION;                  return XVID_ERR_VERSION;
856    
857          xFrame->out_flags = 0;          xFrame->out_flags = 0;
# Line 904  Line 888 
888    
889                  if (xFrame->quant_intra_matrix)                  if (xFrame->quant_intra_matrix)
890                  {                  {
891                          memcpy(q->quant_intra_matrix, xFrame->quant_intra_matrix, sizeof(xFrame->quant_intra_matrix));                          memcpy(q->quant_intra_matrix, xFrame->quant_intra_matrix, 64*sizeof(unsigned char));
892                          q->frame.quant_intra_matrix = q->quant_intra_matrix;                          q->frame.quant_intra_matrix = q->quant_intra_matrix;
893                  }                  }
894    
895                  if (xFrame->quant_inter_matrix)                  if (xFrame->quant_inter_matrix)
896                  {                  {
897                          memcpy(q->quant_inter_matrix, xFrame->quant_inter_matrix, sizeof(xFrame->quant_inter_matrix));                          memcpy(q->quant_inter_matrix, xFrame->quant_inter_matrix, 64*sizeof(unsigned char));
898                          q->frame.quant_inter_matrix = q->quant_inter_matrix;                          q->frame.quant_inter_matrix = q->quant_inter_matrix;
899                  }                  }
900    
# Line 1010  Line 994 
994                                  SWAP(FRAMEINFO*, pEnc->current, pEnc->bframes[pEnc->bframenum_tail]);                                  SWAP(FRAMEINFO*, pEnc->current, pEnc->bframes[pEnc->bframenum_tail]);
995    
996                                  /* convert B-VOP to P-VOP */                                  /* convert B-VOP to P-VOP */
997                  pEnc->current->quant = ((pEnc->current->quant*100) - pEnc->mbParam.bquant_offset) / pEnc->mbParam.bquant_ratio;                  pEnc->current->quant  = 100*pEnc->current->quant - pEnc->mbParam.bquant_offset;
998                                    pEnc->current->quant += pEnc->mbParam.bquant_ratio - 1; /* to avoid rouding issues */
999                                    pEnc->current->quant /= pEnc->mbParam.bquant_ratio;
1000    
1001                  if ((pEnc->mbParam.plugin_flags & XVID_REQORIGINAL)) {                  if ((pEnc->mbParam.plugin_flags & XVID_REQORIGINAL)) {
1002                              image_copy(&pEnc->sOriginal, &pEnc->current->image,                              image_copy(&pEnc->sOriginal, &pEnc->current->image,
# Line 1098  Line 1084 
1084    
1085          if ((pEnc->current->vop_flags & XVID_VOP_DEBUG)) {          if ((pEnc->current->vop_flags & XVID_VOP_DEBUG)) {
1086                  image_printf(&pEnc->current->image, pEnc->mbParam.edged_width, pEnc->mbParam.height, 5, 5,                  image_printf(&pEnc->current->image, pEnc->mbParam.edged_width, pEnc->mbParam.height, 5, 5,
1087                          "%i  st:%i  if:%i", pEnc->current->frame_num, pEnc->current->stamp, pEnc->iFrameNum);                          "%d  st:%lld  if:%d", pEnc->current->frame_num, pEnc->current->stamp, pEnc->iFrameNum);
1088          }          }
1089    
1090          /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%          /* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
# Line 1177  Line 1163 
1163                  }                  }
1164    
1165                  /* convert B-VOP quant to P-VOP */                  /* convert B-VOP quant to P-VOP */
1166                  pEnc->current->quant = ((pEnc->current->quant*100) - pEnc->mbParam.bquant_offset) / pEnc->mbParam.bquant_ratio;                  pEnc->current->quant  = 100*pEnc->current->quant - pEnc->mbParam.bquant_offset;
1167                    pEnc->current->quant += pEnc->mbParam.bquant_ratio - 1; /* to avoid rouding issues */
1168                    pEnc->current->quant /= pEnc->mbParam.bquant_ratio;
1169          type = P_VOP;          type = P_VOP;
1170      }      }
1171    
# Line 1200  Line 1188 
1188    
1189                  /* ---- update vol flags at IVOP ----------- */                  /* ---- update vol flags at IVOP ----------- */
1190                  pEnc->current->vol_flags = pEnc->mbParam.vol_flags = frame->vol_flags;                  pEnc->current->vol_flags = pEnc->mbParam.vol_flags = frame->vol_flags;
1191                    switch(frame->par) {
1192                    case XVID_PAR_11_VGA:
1193                    case XVID_PAR_43_PAL:
1194                    case XVID_PAR_43_NTSC:
1195                    case XVID_PAR_169_PAL:
1196                    case XVID_PAR_169_NTSC:
1197                    case XVID_PAR_EXT:
1198                            pEnc->mbParam.par = frame->par;
1199                            break;
1200                    default:
1201                            pEnc->mbParam.par = XVID_PAR_EXT;
1202                            break;
1203                    }
1204                    pEnc->mbParam.par_width = (frame->par_width)?frame->par_width:1;
1205                    pEnc->mbParam.par_height = (frame->par_height)?frame->par_height:1;
1206    
1207          if ((pEnc->mbParam.vol_flags & XVID_VOL_MPEGQUANT)) {          if ((pEnc->mbParam.vol_flags & XVID_VOL_MPEGQUANT)) {
1208                          if (frame->quant_intra_matrix != NULL)                          if (frame->quant_intra_matrix != NULL)
# Line 1253  Line 1256 
1256           * on next enc_encode call we must flush bframes           * on next enc_encode call we must flush bframes
1257           * %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */           * %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% */
1258    
1259  done_flush:  /*done_flush:*/
1260    
1261      pEnc->flush_bframes = 1;      pEnc->flush_bframes = 1;
1262    
# Line 1285  Line 1288 
1288  {  {
1289      unsigned int i,j;      unsigned int i,j;
1290      int quant = frame->quant;      int quant = frame->quant;
1291        if (quant > 31)
1292                    frame->quant = quant = 31;
1293            else if (quant < 1)
1294                    frame->quant = quant = 1;
1295    
1296      for (j=0; j<pParam->mb_height; j++)      for (j=0; j<pParam->mb_height; j++)
1297      for (i=0; i<pParam->mb_width; i++) {      for (i=0; i<pParam->mb_width; i++) {
# Line 1292  Line 1299 
1299          quant += pMB->dquant;          quant += pMB->dquant;
1300          if (quant > 31)          if (quant > 31)
1301                          quant = 31;                          quant = 31;
1302                  if (quant < 1)                  else if (quant < 1)
1303                          quant = 1;                          quant = 1;
1304          pMB->quant = quant;          pMB->quant = quant;
1305      }      }
# Line 1356  Line 1363 
1363    
1364          set_timecodes(pEnc->current,pEnc->reference,pEnc->mbParam.fbase);          set_timecodes(pEnc->current,pEnc->reference,pEnc->mbParam.fbase);
1365    
1366          BitstreamPadAlways(bs);          BitstreamPad(bs);
1367    
1368          BitstreamWriteVopHeader(bs, &pEnc->mbParam, pEnc->current, 1);          BitstreamWriteVopHeader(bs, &pEnc->mbParam, pEnc->current, 1);
1369    
1370          pEnc->current->sStat.iTextBits = 0;          pEnc->current->sStat.iTextBits = 0;
# Line 1395  Line 1403 
1403          }          }
1404          emms();          emms();
1405    
1406  /* XXX: Remove the two #if 0 blocks when we are sure we must always pad the stream */          BitstreamPadAlways(bs); /* next_start_code() at the end of VideoObjectPlane() */
1407  #if 0  
         /* for divx5 compatibility, we must always pad between the packed p and b frames */  
         if ((pEnc->mbParam.global_flags & XVID_GLOBAL_PACKED) && pEnc->bframenum_tail > 0)  
 #endif  
                 BitstreamPadAlways(bs);  
 #if 0  
         else  
                 BitstreamPad(bs);  
 #endif  
1408      pEnc->current->length = (BitstreamPos(bs) - bits) / 8;      pEnc->current->length = (BitstreamPos(bs) - bits) / 8;
1409    
1410          pEnc->fMvPrevSigma = -1;          pEnc->fMvPrevSigma = -1;
# Line 1487  Line 1487 
1487                  current->warp = GlobalMotionEst( current->mbs, pParam, current, reference,                  current->warp = GlobalMotionEst( current->mbs, pParam, current, reference,
1488                                                                   &pEnc->vInterH, &pEnc->vInterV, &pEnc->vInterHV);                                                                   &pEnc->vInterH, &pEnc->vInterV, &pEnc->vInterHV);
1489    
1490                  if (current->motion_flags & XVID_GME_REFINE) {                  if (current->motion_flags & XVID_ME_GME_REFINE) {
1491                          gmcval = GlobalMotionEstRefine(&current->warp,                          gmcval = GlobalMotionEstRefine(&current->warp,
1492                                                                  current->mbs, pParam,                                                                  current->mbs, pParam,
1493                                                                  current, reference,                                                                  current, reference,
# Line 1545  Line 1545 
1545          set_timecodes(current,reference,pParam->fbase);          set_timecodes(current,reference,pParam->fbase);
1546          if (vol_header)          if (vol_header)
1547          {       BitstreamWriteVolHeader(bs, &pEnc->mbParam);          {       BitstreamWriteVolHeader(bs, &pEnc->mbParam);
1548                  BitstreamPadAlways(bs);                  BitstreamPad(bs);
1549          }          }
1550    
1551          BitstreamWriteVopHeader(bs, &pEnc->mbParam, current, 1);          BitstreamWriteVopHeader(bs, &pEnc->mbParam, current, 1);
# Line 1559  Line 1559 
1559                          MACROBLOCK *pMB =                          MACROBLOCK *pMB =
1560                                  &current->mbs[x + y * pParam->mb_width];                                  &current->mbs[x + y * pParam->mb_width];
1561    
 /* Mode decision: Check, if the block should be INTRA / INTER or GMC-coded */  
 /* For a start, leave INTRA decision as is, only choose only between INTER/GMC  - gruel, 9.1.2002 */  
   
1562                          bIntra = (pMB->mode == MODE_INTRA) || (pMB->mode == MODE_INTRA_Q);                          bIntra = (pMB->mode == MODE_INTRA) || (pMB->mode == MODE_INTRA_Q);
1563    
1564                          if (bIntra) {                          if (bIntra) {
# Line 1575  Line 1572 
1572    
1573                                  current->sStat.kblks++;                                  current->sStat.kblks++;
1574    
1575                                    if (pEnc->current->vop_flags & XVID_VOP_GREYSCALE)
1576                                    {       pMB->cbp &= 0x3C;               /* keep only bits 5-2 */
1577                                            qcoeff[4*64+0]=0;               /* zero, because for INTRA MBs DC value is saved */
1578                                            qcoeff[5*64+0]=0;
1579                                    }
1580                                  MBCoding(current, pMB, qcoeff, bs, &current->sStat);                                  MBCoding(current, pMB, qcoeff, bs, &current->sStat);
1581                                  stop_coding_timer();                                  stop_coding_timer();
1582                                  continue;                                  continue;
1583                          }                          }
1584    
                         if (current->coding_type == S_VOP) {  
   
                                 int32_t iSAD = sad16(current->image.y + 16*y*pParam->edged_width + 16*x,  
                                         pEnc->vGMC.y + 16*y*pParam->edged_width + 16*x,  
                                         pParam->edged_width, 65536);  
   
                                 if (current->motion_flags & XVID_ME_CHROMA16) {  
                                         iSAD += sad8(current->image.u + 8*y*(pParam->edged_width/2) + 8*x,  
                                         pEnc->vGMC.u + 8*y*(pParam->edged_width/2) + 8*x, pParam->edged_width/2);  
   
                                         iSAD += sad8(current->image.v + 8*y*(pParam->edged_width/2) + 8*x,  
                                         pEnc->vGMC.v + 8*y*(pParam->edged_width/2) + 8*x, pParam->edged_width/2);  
                                 }  
   
                                 if (iSAD <= pMB->sad16) {               /* mode decision GMC */  
   
                                         if ((pParam->vol_flags & XVID_VOL_QUARTERPEL))  
                                                 pMB->qmvs[0] = pMB->qmvs[1] = pMB->qmvs[2] = pMB->qmvs[3] = pMB->amv;  
                                         else  
                                                 pMB->mvs[0] = pMB->mvs[1] = pMB->mvs[2] = pMB->mvs[3] = pMB->amv;  
   
                                         pMB->mode = MODE_INTER;  
                                         pMB->mcsel = 1;  
                                         pMB->sad16 = iSAD;  
                                 } else {  
                                         pMB->mcsel = 0;  
                                 }  
                         } else {  
                                 pMB->mcsel = 0; /* just a precaution */  
                         }  
   
1585                          start_timer();                          start_timer();
1586                          MBMotionCompensation(pMB, x, y, &reference->image,                          MBMotionCompensation(pMB, x, y, &reference->image,
1587                                                                   &pEnc->vInterH, &pEnc->vInterV,                                                                   &pEnc->vInterH, &pEnc->vInterV,
# Line 1825  Line 1796 
1796          }          }
1797          */          */
1798    
1799  /* XXX: Remove the two #if 0 blocks when we are sure we must always pad the stream */          BitstreamPadAlways(bs); /* next_start_code() at the end of VideoObjectPlane() */
 #if 0  
         /* for divx5 compatibility, we must always pad between the packed p and b frames */  
         if ((pParam->global_flags & XVID_GLOBAL_PACKED) && pEnc->bframenum_tail > 0)  
 #endif  
                 BitstreamPadAlways(bs);  
 #if 0  
         else  
                 BitstreamPad(bs);  
 #endif  
1800    
1801      current->length = (BitstreamPos(bs) - bits) / 8;      current->length = (BitstreamPos(bs) - bits) / 8;
1802    
# Line 1914  Line 1876 
1876          for (y = 0; y < pEnc->mbParam.mb_height; y++) {          for (y = 0; y < pEnc->mbParam.mb_height; y++) {
1877                  for (x = 0; x < pEnc->mbParam.mb_width; x++) {                  for (x = 0; x < pEnc->mbParam.mb_width; x++) {
1878                          MACROBLOCK * const mb = &frame->mbs[x + y * pEnc->mbParam.mb_width];                          MACROBLOCK * const mb = &frame->mbs[x + y * pEnc->mbParam.mb_width];
                         int direction = frame->vop_flags & XVID_VOP_ALTERNATESCAN ? 2 : 0;  
1879    
1880                          /* decoder ignores mb when refence block is INTER(0,0), CBP=0 */                          /* decoder ignores mb when refence block is INTER(0,0), CBP=0 */
1881                          if (mb->mode == MODE_NOT_CODED) {                          if (mb->mode == MODE_NOT_CODED) {
# Line 1941  Line 1902 
1902                                  }                                  }
1903                          }                          }
1904    
1905  #ifdef BFRAMES_DEC_DEBUG                          /* keep only bits 5-2 -- Chroma blocks will just be skipped by the
1906          BFRAME_DEBUG                           * coding function for BFrames, that's why we don't zero teh DC
1907  #endif                           * coeffs */
1908                            if ((frame->vop_flags & XVID_VOP_GREYSCALE))
1909                                    mb->cbp &= 0x3C;
1910    
1911                          start_timer();                          start_timer();
1912                          MBCodingBVOP(mb, qcoeff, frame->fcode, frame->bcode, bs,                          MBCodingBVOP(frame, mb, qcoeff, frame->fcode, frame->bcode, bs,
1913                                                   &frame->sStat, direction);                                                   &frame->sStat);
1914                          stop_coding_timer();                          stop_coding_timer();
1915                  }                  }
1916          }          }
# Line 1955  Line 1919 
1919    
1920          /* TODO: dynamic fcode/bcode ??? */          /* TODO: dynamic fcode/bcode ??? */
1921    
1922      BitstreamPadAlways(bs);      BitstreamPadAlways(bs); /* next_start_code() at the end of VideoObjectPlane() */
1923          frame->length = (BitstreamPos(bs) - bits) / 8;          frame->length = (BitstreamPos(bs) - bits) / 8;
1924    
1925  #ifdef BFRAMES_DEC_DEBUG  #ifdef BFRAMES_DEC_DEBUG

Legend:
Removed from v.1.95.2.32  
changed lines
  Added in v.1.95.2.46

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