Example #1
0
void WritePictureHeader()
{
    BEGIN("WritePictureHeader");

    mputv(PSC_LENGTH,PSC);
    mputv(5,TemporalReference);
#ifdef VERSION_1_0
    mputv(13,PType);
    if (ParityEnable)
    {
        mputb(1);
        mputv(8,ParityFS(CFS));
    }
    else
        mputb(0);  /* No Parity */
    if (PSpareEnable)
    {
        mputb(1);
        mputv(16,PSpare);
    }
    else
        mputb(0);  /* No Spare */
#else
    mputv(6,PType);
    if (PSpareEnable)
    {
        mputb(1);
        mputv(8,PSpare);
    }
    mputb(0);  /* No Spare */
#endif
}
Example #2
0
int CountBitsSlice(int slice, int quant)
{
  int bits = 0;


  /* Picture Start Code */
  if (Global::trace)
    fprintf(Global::tf,"GOB sync (GBSC): ");
  mputv(PSC_LENGTH,PSC); /* PSC */
  bits += PSC_LENGTH;

  /* Group Number */
  if (Global::trace)
    fprintf(Global::tf,"GN: ");
  mputv(5,slice);
  bits += 5;

  /* GOB Sub Bitstream Indicator */
  /* if CPM == 1: read 2 bits GSBI */
  /* not supported in this version */

  /* GOB Frame ID */
  if (Global::trace)
    fprintf(Global::tf,"GFID: ");
  mputv(2, 0);  
  /* NB: in error-prone environments this value should change if 
     PTYPE in picture header changes. In this version of the encoder
     PTYPE only changes when PB-frames are used in the following cases:
     (i) after the first intra frame
     (ii) if the distance between two P-frames is very large 
     Therefore I haven't implemented this GFID change */
  /* GFID is not allowed to change unless PTYPE changes */
  bits += 2;

  /* Gquant */
  if (Global::trace)
    fprintf(Global::tf,"GQUANT: ");
  mputv(5,quant);
  bits += 5;

  return bits;
}
Example #3
0
void WriteGOBHeader()
{
    BEGIN("WriteGOBHeader");

    mputv(GBSC_LENGTH,GBSC);
    mputv(4,GRead+1);
#ifdef VERSION_1_0
    mputv(6,Type2);
#endif
    mputv(5,GQuant);
#ifdef VERSION_1_0
    if (GSpareEnable)
    {
        mputb(1);
        mputv(16,GSpare);
    }
    else
        mputb(0);
#else
    if (GSpareEnable)
    {
        mputb(1);
        mputv(8,GSpare);
    }
    mputb(0);
#endif
}
Example #4
0
void CountBitsMB(int Mode, int COD, int CBP, int CBPB, Pict *pic, Bits *bits)
{
  extern EHUFF *vlc_cbpy, *vlc_cbpcm, *vlc_cbpcm_intra;
  int cbpy, cbpcm, length;

  /* COD */
  if (Global::trace) {
    fprintf(Global::tf,"MB-nr: %d",pic->MB);
    if (pic->picture_coding_type == PCT_INTER)
      fprintf(Global::tf,"  COD: %d\n",COD);
  }
  if (pic->picture_coding_type == PCT_INTER) {
    mputv(1,COD);
    bits->COD++;
  }

  if (COD) 
    return;    /* not coded */

  /* CBPCM */
  cbpcm = Mode | ((CBP&3)<<4);


  if (Global::trace) {
    fprintf(Global::tf,"CBPCM (CBP=%d) (cbpcm=%d): ",CBP,cbpcm);
  }
  if (pic->picture_coding_type == PCT_INTRA) {
    length = Encode(cbpcm,vlc_cbpcm_intra);
  } else {
    length = Encode(cbpcm,vlc_cbpcm);
  }
  bits->CBPCM += length;

    
  /* CBPY */
  cbpy = CBP>>2;
  if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q) /* Intra */
    cbpy = cbpy^15;
  if (Global::trace) {
    fprintf(Global::tf,"CBPY (CBP=%d) (cbpy=%d): ",CBP,cbpy);
  }
  length = Encode(cbpy, vlc_cbpy);
  bits->CBPY += length;
  

  return;
}
Example #5
0
void WriteMBHeader()
{
    BEGIN("WriteMBHeader");
    int TempH,TempV,Start;

    Start=swtell();
    if (!Encode(MBA,MBAEHuff))
    {
        WHEREAMI();
        printf("Attempting to write an empty Huffman code.\n");
        exit(ERROR_HUFFMAN_ENCODE);
    }
    if (!Encode(MType,T3EHuff))
    {
        WHEREAMI();
        printf("Attempting to write an empty Huffman code.\n");
        exit(ERROR_HUFFMAN_ENCODE);
    }
    if (QuantMType[MType])
        mputv(5,MQuant);

    NumberBitsCoded=0;
    if (MFMType[MType])
    {
        if ((!MFMType[LastMType])||(MBA!=1)||
                (LastMBA==-1)||(LastMBA==10)||(LastMBA==21))
        {
            if (!Encode(MVDH&0x1f,MVDEHuff)||
                    !Encode(MVDV&0x1f,MVDEHuff))
            {
                WHEREAMI();
                printf("Cannot encode motion vectors.\n");
            }
        }
        else
        {
            TempH = MVDH - LastMVDH;
            if (TempH < -16) TempH += 32;
            if (TempH > 15) TempH -= 32;
            TempV = MVDV - LastMVDV;
            if (TempV < -16) TempV += 32;
            if (TempV > 15) TempV -= 32;
            if (!Encode(TempH&0x1f,MVDEHuff)||!Encode(TempV&0x1f,MVDEHuff))
            {
                WHEREAMI();
                printf("Cannot encode motion vectors.\n");
            }
        }
        LastMVDV = MVDV;
        LastMVDH = MVDH;
    }
    else
    {
        LastMVDV=LastMVDH=MVDV=MVDH=0; /* Redundant in most cases */
    }

    MotionVectorBits+=NumberBitsCoded;
    if (CBPMType[MType])
    {
        if (!Encode(CBP,CBPEHuff))
        {
            WHEREAMI();
            printf("CBP write error\n");
            exit(-1);
        }
    }
    MacroAttributeBits+=(swtell()-Start);
}
Example #6
0
int CountBitsPicture(Pict *pic)
{
  int bits = 0;

 
  /* Picture start code */
  if (Global::trace) {
    fprintf(Global::tf,"picture_start_code: ");
  }
  mputv(PSC_LENGTH,PSC);
  bits += PSC_LENGTH;

  /* Group number */
  if (Global::trace) {
    fprintf(Global::tf,"Group number in picture header: ");
  }
  mputv(5,0); 
  bits += 5;
  
  /* Time reference */
  if (Global::trace) {
    fprintf(Global::tf,"Time reference: ");
  }
  mputv(8,pic->TR);
  bits += 8;

 /* bit 1 */
  if (Global::trace) {
    fprintf(Global::tf,"spare: ");
  }
  pic->spare = 1; /* always 1 to avoid start code emulation */
  mputv(1,pic->spare);
  bits += 1;

  /* bit 2 */
  if (Global::trace) {
    fprintf(Global::tf,"always zero for distinction with H.261\n");
  }
  mputv(1,0);
  bits += 1;
  
  /* bit 3 */
  if (Global::trace) {
    fprintf(Global::tf,"split_screen_indicator: ");
  }
  mputv(1,0);     /* no support for split-screen in this software */
  bits += 1;

  /* bit 4 */
  if (Global::trace) {
    fprintf(Global::tf,"document_camera_indicator: ");
  }
  mputv(1,0);
  bits += 1;

  /* bit 5 */
  if (Global::trace) {
    fprintf(Global::tf,"freeze_picture_release: ");
  }
  mputv(1,0);
  bits += 1;

  /* bit 6-8 */
  if (Global::trace) {
    fprintf(Global::tf,"source_format: ");
  }
  mputv(3,pic->source_format);
  bits += 3;

  /* bit 9 */
  if (Global::trace) {
    fprintf(Global::tf,"picture_coding_type: ");
  }
  mputv(1,pic->picture_coding_type);
  bits += 1;

  /* bit 10 */
  if (Global::trace) {
    fprintf(Global::tf,"Global::mv_outside_frame: ");
  }
  mputv(1,pic->unrestricted_mv_mode);  /* Unrestricted Motion Vector mode */
  bits += 1;

  /* bit 11 */
  if (Global::trace) {
    fprintf(Global::tf,"sac_coding: ");
  }
  mputv(1,0); /* Syntax-based Arithmetic Coding mode not used*/
  bits += 1;

  /* bit 12 */
  if (Global::trace) {
    fprintf(Global::tf,"adv_pred_mode: ");
  }
  mputv(1,Global::advanced); /* Advanced Prediction mode */
  bits += 1;

  /* bit 13 */
  if (Global::trace) {
    fprintf(Global::tf,"PB-coded: "); /* PB-frames mode */
  }
  mputv(1,pic->PB);
  bits += 1;


  /* QUANT */
  if (Global::trace) {
    fprintf(Global::tf,"QUANT: ");
  }
  mputv(5,pic->QUANT);
  bits += 5;

  /* Continuous Presence Multipoint (CPM) */
  mputv(1,0); /* CPM is not supported in this software */
  bits += 1;

  /* Picture Sub Bitstream Indicator (PSBI) */
  /* if CPM == 1: 2 bits PSBI */
  /* not supported */


  /* PEI (extra information) */
  if (Global::trace) {
    fprintf(Global::tf,"PEI: ");
  }
  /* "Encoders shall not insert PSPARE until specified by the ITU" */
  mputv(1,0); 
  bits += 1;

  /* PSPARE */
  /* if PEI == 1: 8 bits PSPARE + another PEI bit */
  /* not supported */

  return bits;
}
Example #7
0
int CodeCoeff(int Mode, int *qcoeff, int block, int ncoeffs)
{
  int j, bits;
  int prev_run, run, prev_level, level, first;
  int prev_ind, ind, prev_s, s, length;

  extern EHUFF *vlc_3d;

  run = bits = 0;
  first = 1;
  prev_run = prev_level = prev_ind = level = s = prev_s = ind = 0;
  
  for (j = block*ncoeffs; j< (block + 1)*ncoeffs; j++) {
    /* Do this block's DC-coefficient first */
    if (!(j%ncoeffs) && (Mode == MODE_INTRA)) {
      /* DC coeff */
      if (Global::trace) {
	fprintf(Global::tf,"DC: ");
      }
      if (qcoeff[block*ncoeffs] != 128)
	mputv(8,qcoeff[block*ncoeffs]);
      else
	mputv(8,255);
      bits += 8;
    }
    else {
      /* AC coeff */
      s = 0;
      /* Increment run if coeff is zero */
      if ((level = qcoeff[j]) == 0) {
	run++;
      }
      else {
	/* code run & level and count bits */
	if (level < 0) {
	  s = 1;
	  level = -level;
	}
	ind = level | run<<4;
	ind = ind | 0<<12; /* Not last coeff */

	if (!first) {
	  /* Encode the previous ind */
	  if (prev_level  < 13 && prev_run < 64) {
	    length = Encode(prev_ind,vlc_3d);

	  } else
	    length = 0;
	  if (length == 0) {  /* Escape coding */
	    if (Global::trace) {
	      fprintf(Global::tf,"Escape coding:\n");
	    }
	    if (prev_s == 1) {prev_level = (prev_level^0xff)+1;}
	    Encode(ESCAPE,vlc_3d);
	    mputv(1,0);
	    mputv(6,prev_run);
	    mputv(8,prev_level);
	    bits += 22;
	  }
	  else {
	    mputv(1,prev_s);
	    bits += length + 1;
	  }
	}
	prev_run = run; prev_s = s;
	prev_level = level; prev_ind = ind;

	run = first = 0;
      }
    }
  }
  /* Encode the last coeff */
  if (!first) {
    if (Global::trace) {
      fprintf(Global::tf,"Last coeff: ");
    }
    prev_ind = prev_ind | 1<<12;   /* last coeff */
    if (prev_level  < 13 && prev_run < 64) { 
      length = Encode(prev_ind,vlc_3d);
    } else
      length = 0;
    if (length == 0) {  /* Escape coding */
      if (Global::trace) {
	fprintf(Global::tf,"Escape coding:\n");
      }
      if (prev_s == 1) {prev_level = (prev_level^0xff)+1;}
      Encode(ESCAPE,vlc_3d);
      mputv(1,1);
      mputv(6,prev_run);
      mputv(8,prev_level);
      bits += 22;
    }
    else {
      mputv(1,prev_s);
      bits += length + 1;
    }
  }
  return bits;
}