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 }
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; }
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 }
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; }
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); }
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; }
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; }