📄 sequence.c
字号:
}/** seqClose:** Parameters:* seq Encoder sequence to be closed** Function:* Deinitializes sequence by closing files and deallocating memory* * Returns:* -*/void avceClose(avceEncoder_t *pSeq){ sequence_s *seq; seq = (sequence_s *) pSeq; vlcuSendEndOfSeq(&seq->bitbuf); frmClose(& seq->recoFrm); frmEncBufClose(& seq->mbData); rc_free_mem(&seq->bRC); dpbRelease(& seq->dpbBuf, seq->encPar.low_complex_prof3); mbkRelease(& seq->slice.mb); bibClose(& seq->bitbuf); /* Accumulate & output statistics of intra and inter frames */#if PRINT_DETAILED_SEQ_STATISTICS printIntraStat(&seq->intraStat, stdout); printf("\n"); printInterStat(&seq->interStat, stdout);#endif psCloseParameterSet(& seq->pps); nccFree(seq->forcedIR); nccFree(seq);}#if PRINT_DETAILED_SEQ_STATISTICS/** printIntraStat** Parameters:* intraStat Intra statistics* fp Destination stream** Function:* Print intra statistics** Returns:* -*/static void printIntraStat(statSlice_s *intraStat, FILE *fp){ int i; deb0f(fp, "INTRA\n-----\n"); deb1f(fp, "Intra 4x4: %i\n", intraStat->intraModeCtr1); for (i = 0; i < 4; i++) deb2f(fp, "Intra 16x16 mode %2i: %i\n", i, intraStat->intraModeCtr2[i]); deb0f(fp, "\n"); deb1f(fp, "Hdr: %i\n", intraStat->bitsHdr); deb1f(fp, "Modeinfo: %i\n", intraStat->bitsPred); deb1f(fp, "CBP: %i\n", intraStat->bitsCBP); deb1f(fp, "Coef Y: %i\n", (intraStat->bitsCoefLumaDC+intraStat->bitsCoefLuma)); deb1f(fp, "Coef C: %i\n", (intraStat->bitsCoefChromaDC+intraStat->bitsCoefChroma)); intraStat = 0; /* Avoid warnings */ fp = 0; /* Avoid warnings */}/** printInterStat** Parameters:* intraStat Inter statistics* fp Destination stream** Function:* Print inter statistics** Returns:* -*/static void printInterStat(statSlice_s *interStat, FILE *fp){ int i; interStat->nFrames = max(1, interStat->nFrames); deb0f(fp, "\nINTER\n-----\n"); for (i = 0; i < 8; i++) deb2f(fp, "Inter mode %i: %i\n", i, interStat->interModeCtr[i]); deb1f(fp, "Intra 4x4: %i\n", interStat->intraModeCtr1); for (i = 0; i < 4; i++) deb2f(fp, "Intra 16x16 mode %2i: %i\n", i, interStat->intraModeCtr2[i]); deb0f(fp, "\n"); deb1f(fp, "Hdr: %i\n", interStat->bitsHdr/interStat->nFrames); deb1f(fp, "CBP: %i\n", interStat->bitsCBP/interStat->nFrames); deb1f(fp, "Coef Y: %i ", (interStat->bitsCoefLumaDC+interStat->bitsCoefLuma+interStat->bitsVec)/interStat->nFrames); deb1f(fp, "(Vecs: %i)\n", interStat->bitsVec/interStat->nFrames); deb1f(fp, "Coef C: %i\n", (interStat->bitsCoefChromaDC+interStat->bitsCoefChroma)/interStat->nFrames); fp = 0; /* Avoid warnings */}#endif /* #if PRINT_DETAILED_SEQ_STATISTICS *//** avceGetIntraStat, avceGetInterStat, avceGetSeqStat** Parameters:* seq Encoder instance** Function:* Get statistics for intra/inter/all frames* * Returns:* Statistics*/void avceGetIntraStat(avceEncoder_t *seq, avceStatistics_s *stat){ getStat(stat, & ((sequence_s *) seq)->intraStat);}void avceGetInterStat(avceEncoder_t *seq, avceStatistics_s *stat){ getStat(stat, & ((sequence_s *) seq)->interStat);}void avceGetSeqStat(avceEncoder_t *seq, avceStatistics_s *stat){ statSlice_s seqStat; staClear(&seqStat); staAccumulate(&seqStat, & ((sequence_s *) seq)->intraStat); staAccumulate(&seqStat, & ((sequence_s *) seq)->interStat); // statistics of encoded frames getStat(stat, &seqStat); // statistics of NAL, Sequence PS, Picture PS, stat->bits += ((sequence_s *) seq)->nonSliceStat.bitsNAL; stat->bits += ((sequence_s *) seq)->nonSliceStat.bitsPPS; stat->bits += ((sequence_s *) seq)->nonSliceStat.bitsSEI; stat->bits += ((sequence_s *) seq)->nonSliceStat.bitsSPS;}void avceGetFrmStat(avceEncoder_t *seq, avceStatistics_s *stat){ stat->bits = staGetTotalBits(& ((sequence_s *) seq)->frmStat); stat->psnrY = ((sequence_s *) seq)->frmStat.psnrY; stat->psnrU = ((sequence_s *) seq)->frmStat.psnrU; stat->psnrV = ((sequence_s *) seq)->frmStat.psnrV; stat->bufFullness = ((sequence_s *) seq)->bRC.CurrentBufferFullness/8; stat->numIntraMbs = ((sequence_s *) seq)->bRC.numIntraMBs; }int avceGetBitsNAL(avceEncoder_t *seq){ return ((sequence_s *) seq)->nonSliceStat.bitsNAL;}int avceGetBitsSPS(avceEncoder_t *seq){ return ((sequence_s *) seq)->nonSliceStat.bitsSPS;}int avceGetBitsPPS(avceEncoder_t *seq){ return ((sequence_s *) seq)->nonSliceStat.bitsPPS;}static void getStat(avceStatistics_s *retStat, statSlice_s *stat){ retStat->psnrY = stat->psnrY; retStat->psnrU = stat->psnrU; retStat->psnrV = stat->psnrV; retStat->bits = staGetTotalBits(stat); retStat->nFrames = stat->nFrames;}/** calcFrmError** Parameters:* orig Original pixels* reco Reconstructed pixels* width Width of the frame* height Height of the frame** Function:* Calculates PSNR error between two framebuffers.** Returns:* -*/static double calcFrmError(u_int8 *orig, u_int8 *reco, int width, int height){ double sqSum; int sqSumLine; int diff; int i, j, j2; for (sqSum = 0.0, j = 0; j < height; j += 8) { for (sqSumLine = 0, j2 = j; j2 < j+8; j2++) { for (i = 0; i < width; i += 4) { diff = (int)orig[j2*width+i+0] - (int)reco[j2*width+i+0]; sqSumLine += diff*diff; diff = (int)orig[j2*width+i+1] - (int)reco[j2*width+i+1]; sqSumLine += diff*diff; diff = (int)orig[j2*width+i+2] - (int)reco[j2*width+i+2]; sqSumLine += diff*diff; diff = (int)orig[j2*width+i+3] - (int)reco[j2*width+i+3]; sqSumLine += diff*diff; } } sqSum += sqSumLine; } if (sqSum == 0) sqSum = 1; return (10.0*log10(width*height*65025.0/sqSum));}/** calcRecoError** Parameters:* f Reconstructed frame buffer* orig Original frame buffer* stat Statistics** Function:* Calculates frame reconstruction error for Y, U and V components.** Returns:* -*/static void calcRecoError(frmBuf_s *reco, frmBuf_s *orig, statSlice_s *stat){ stat->psnrY += calcFrmError(orig->y, reco->y, reco->width, reco->height); stat->psnrU += calcFrmError(orig->u, reco->u, reco->width/2, reco->height/2); stat->psnrV += calcFrmError(orig->v, reco->v, reco->width/2, reco->height/2);}/** seqEncode:** Parameters:* seq Encoder instance* origPic YUV buffers for original frame* recoPic YUV buffers for reconstruction frame* intraFlag 1 -> Intra, 0 -> Inter* qp Quantization parameter* srcPicNum Source picture index* nalBuffer Return pointer for nal bits buffer* nalBufSize Return pointer for nal buffer size** Function:* Encode sequence using parameters in seq structure.* * Returns:* AVCE_ERROR for error* AVCE_OK for ok* AVCE_FRAME_SKIPPED for frame got skipped*/int avceEncodeOneFrame(avceEncoder_t *pSeq, avceYUVbuffer_s *origPic, avceYUVbuffer_s *recoPic, int intraFlag, int idrFlag, int scutFlag, int nalRefIdc, int ltrCandidate, int srcPicNum, int qp, void **nalBuffer, int *nalBufSize){ frmBuf_s origBuf; statSlice_s *seqStat; statSlice_s *frmStat; int numIntraMbs, numMbsPerFrm; slice_s *slice; int i; int textureBits,headerBits;#ifdef ENABLE_REENCODE int maxreencode=5;#endif sequence_s *seq; seq = (sequence_s *) pSeq; frmStat = & seq->frmStat; slice = & seq->slice; origBuf.width = (int16) (seq->encPar.picWidth); origBuf.height = (int16) (seq->encPar.picHeight); origBuf.y = origPic->y; origBuf.u = origPic->u; origBuf.v = origPic->v; numMbsPerFrm = (seq->encPar.picWidth/16) * (seq->encPar.picHeight/16); seq->bRC.scut = scutFlag; if(seq->encPar.brcBitRate!=0) seq->bRC.scut = scutFlag; if (idrFlag) { seq->lastIdrTr = srcPicNum; slice->idrPicId = seq->nextIdrPicId; seq->nextIdrPicId = (int16)((seq->nextIdrPicId + 1) & 0x0F); } /* Select slice type and number of reference frames for inter frames */ if (intraFlag) { slice->sliceType = SLICE_I; seqStat = &seq->intraStat; } else { slice->sliceType = SLICE_P; seqStat = &seq->interStat; } rc_init_pict(& seq->bRC,slice->sliceType,nalRefIdc,srcPicNum); if(seq->bRC.useSEI) seq->nonSliceStat.bitsSEI += sendPictureTimingSEIMessage(&seq->bitbuf,&seq->bRC.picture_timing_SEI,&seq->sps.vui_parameters.vcl_hrd_parameters, &seq->nonSliceStat.bitsNAL); dbpBeforeEncodeFrame(& seq->dpbBuf, nalRefIdc, idrFlag, ltrCandidate); // Set a different sliceGroupCycle, for slice group types 3 to 5 // sliceGroupCycle is an syntax element in slice header // Just an example of changing sliceGroupCycle from one frame to the next if (seq->pps.slice_group_map_type >= 3 && seq->pps.slice_group_map_type <= 5) { int sliceGroupCycleLimit; // calculate maximum sliceGroupCycle allowed, with ceiling operation sliceGroupCycleLimit = (seq->slice.picSizeInMbs + seq->pps.slice_group_change_rate_minus1)/ (seq->pps.slice_group_change_rate_minus1 + 1); // larger than that does not make sense, and may not be represented properly if (seq->sliceGroupCycle >= sliceGroupCycleLimit) seq->sliceGroupCycle = 0; else seq->sliceGroupCycle ++; slice->sliceGroupChangeCycle = seq->sliceGroupCycle; } slice->origBuf = & origBuf; slice->isIDR = (int16) idrFlag; slice->poc = (int16) (srcPicNum - seq->lastIdrTr); slice->qp = (int16) qp; slice->nalRefIdc = (int16) nalRefIdc; slice->frmStat = frmStat; /* Have been cleared */ // : set up low complexity prof 3 slice->meProfile.lc3.low_complex_prof3=seq->encPar.low_complex_prof3; slice->meProfile.lc3.spec_search_pos=seq->encPar.spec_search_pos; //////////////// /* Clear frame statistics */ staClear(frmStat); if (slice->recoBuf->channelDistortion) memset(slice->recoBuf->channelDistortion, 0, sizeof(int)*numMbsPerFrm); if(seq->bRC.bit_rate > 0) { slice->qp = (int16)rc_getFrameQP(& seq->bRC,slice->sliceType); /* Encode frame */ numIntraMbs = frmEncode(slice, & seq->dpbBuf, &seq->encPar, &seq->mbData, &seq->sps, &seq->pps, seq->forcedIRNo, seq->forcedIR, &seq->bRC); textureBits= frmStat->bitsCoefLumaDC + frmStat->bitsCoefLuma + frmStat->bitsCoefChromaDC + frmStat->bitsCoefChroma + frmStat->bitsArithmeticStream; headerBits= frmStat->bitsNAL + frmStat->bitsHdr + frmStat->bitsSkipLen + frmStat->bitsMBtype + frmStat->bitsPred + frmStat->bitsVec + frmStat->bitsCBP; #ifdef ENABLE_REENCODE if(seq->bRC.PictureIndex == 0) { if(seq->bRC.ignoreIDR==0 && 1.5*(seq->bRC.CurrentBufferFullness + textureBits + headerBits - seq->bRC.bitsPerFrame) > seq->bRC.BufferSize) { while( 1.5*(seq->bRC.CurrentBufferFullness + textureBits + headerBits - seq->bRC.bitsPerFrame) > seq->bRC.BufferSize) { //Buffer Overflow and I picture bibInit(&seq->bitbuf); if(seq->bRC.useSEI) sendPictureTimingSEIMessage(&seq->bitbuf,&seq->bRC.picture_timing_SEI,&seq->sps.vui_parameters.vcl_hrd_parameters, &seq->nonSliceStat.bitsNAL); staClear(frmStat); seq->bRC.numIntraMBs = 0; seq->bRC.stat_NumberofReencodes++; printf("REENCODE\n"); slice->qp = seq->bRC.frameComputedQP+2; seq->bRC.frameComputedQP = slice->qp; seq->bRC.frameReturnedQP = slice->qp; numIntraMbs = frmEncode(slice, & seq->dpbBuf, &seq->encPar, &seq->mbData, &seq->sps, &seq->pps, seq->forcedIRNo, seq->forcedIR, &seq->bRC); textureBits= frmStat->bitsCoefLumaDC +
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -