x265,帧内预测代码分析

  1 void Analysis::compressIntraCU(const CUData& parentCTU, const CUGeom& cuGeom, uint32_t& zOrder)
  2 {
  3     uint32_t depth = cuGeom.depth;//geometric  CU几何结构
  4     ModeDepth& md = m_modeDepth[depth];
  5     md.bestMode = NULL;
  6 
  7     bool mightSplit = !(cuGeom.flags & CUGeom::LEAF);//为ture非叶子节点,还需继续分裂
  8     bool mightNotSplit = !(cuGeom.flags & CUGeom::SPLIT_MANDATORY);//
  9 
 10     if (m_param->analysisMode == X265_ANALYSIS_LOAD)
 11     {
 12         uint8_t* reuseDepth  = &m_reuseIntraDataCTU->depth[parentCTU.m_cuAddr * parentCTU.m_numPartitions];
 13         uint8_t* reuseModes  = &m_reuseIntraDataCTU->modes[parentCTU.m_cuAddr * parentCTU.m_numPartitions];
 14         char* reusePartSizes = &m_reuseIntraDataCTU->partSizes[parentCTU.m_cuAddr * parentCTU.m_numPartitions];
 15 
 16         if (mightNotSplit && depth == reuseDepth[zOrder] && zOrder == cuGeom.encodeIdx)
 17         {
 18             m_quant.setQPforQuant(parentCTU);
 19 
 20             PartSize size = (PartSize)reusePartSizes[zOrder];
 21             Mode& mode = size == SIZE_2Nx2N ? md.pred[PRED_INTRA] : md.pred[PRED_INTRA_NxN];
 22             mode.cu.initSubCU(parentCTU, cuGeom);
 23             checkIntra(mode, cuGeom, size, &reuseModes[zOrder]);
 24             checkBestMode(mode, depth);
 25 
 26             if (m_bTryLossless)
 27                 tryLossless(cuGeom);
 28 
 29             if (mightSplit)
 30                 addSplitFlagCost(*md.bestMode, cuGeom.depth);
 31 
 32             // increment zOrder offset to point to next best depth in sharedDepth buffer
 33             zOrder += g_depthInc[g_maxCUDepth - 1][reuseDepth[zOrder]];
 34             mightSplit = false;
 35         }
 36     }
 37     else if (mightNotSplit)
 38     {
 39         m_quant.setQPforQuant(parentCTU);
 40 
 41         md.pred[PRED_INTRA].cu.initSubCU(parentCTU, cuGeom);
 42         checkIntra(md.pred[PRED_INTRA], cuGeom, SIZE_2Nx2N, NULL);//intra2Nx2N  模式
 43         checkBestMode(md.pred[PRED_INTRA], depth);
 44 
 45         if (depth == g_maxCUDepth)
 46         {
 47             md.pred[PRED_INTRA_NxN].cu.initSubCU(parentCTU, cuGeom);
 48             checkIntra(md.pred[PRED_INTRA_NxN], cuGeom, SIZE_NxN, NULL);//INTRA_NxN  模式
 49             checkBestMode(md.pred[PRED_INTRA_NxN], depth);
 50         }
 51 
 52         if (m_bTryLossless)
 53             tryLossless(cuGeom);
 54 
 55         if (mightSplit)
 56             addSplitFlagCost(*md.bestMode, cuGeom.depth);
 57     }
 58 
 59     if (mightSplit)
 60     {
 61         Mode* splitPred = &md.pred[PRED_SPLIT];
 62         splitPred->initCosts();
 63         CUData* splitCU = &splitPred->cu;
 64         splitCU->initSubCU(parentCTU, cuGeom);//分裂成4四subCU
 65 
 66         uint32_t nextDepth = depth + 1;
 67         ModeDepth& nd = m_modeDepth[nextDepth];
 68         invalidateContexts(nextDepth);
 69         Entropy* nextContext = &m_rqt[depth].cur;
 70 
 71         for (uint32_t subPartIdx = 0; subPartIdx < 4; subPartIdx++)
 72         {
 73             const CUGeom& childGeom = *(&cuGeom + cuGeom.childOffset + subPartIdx);
 74             if (childGeom.flags & CUGeom::PRESENT)
 75             {
 76                 m_modeDepth[0].fencYuv.copyPartToYuv(nd.fencYuv, childGeom.encodeIdx);
 77                 m_rqt[nextDepth].cur.load(*nextContext);
 78                 compressIntraCU(parentCTU, childGeom, zOrder);//递归
 79 
 80                 // Save best CU and pred data for this sub CU
 81                 splitCU->copyPartFrom(nd.bestMode->cu, childGeom, subPartIdx);
 82                 splitPred->addSubCosts(*nd.bestMode);
 83                 nd.bestMode->reconYuv.copyToPartYuv(splitPred->reconYuv, childGeom.numPartitions * subPartIdx);
 84                 nextContext = &nd.bestMode->contexts;
 85             }
 86             else
 87             {
 88                 /* record the depth of this non-present sub-CU */
 89                 splitCU->setEmptyPart(childGeom, subPartIdx);
 90                 zOrder += g_depthInc[g_maxCUDepth - 1][nextDepth];
 91             }
 92         }
 93         nextContext->store(splitPred->contexts);
 94         if (mightNotSplit)
 95             addSplitFlagCost(*splitPred, cuGeom.depth);
 96         else
 97             updateModeCost(*splitPred);
 98         checkBestMode(*splitPred, depth);
 99     }
100 
101     checkDQP(md.bestMode->cu, cuGeom);
102 
103     /* Copy best data to encData CTU and recon */
104     md.bestMode->cu.copyToPic(depth);
105     if (md.bestMode != &md.pred[PRED_SPLIT])
106         md.bestMode->reconYuv.copyToPicYuv(*m_frame->m_reconPic, parentCTU.m_cuAddr, cuGeom.encodeIdx);
107 }

 

转载于:https://www.cnblogs.com/mlj318/p/4234213.html

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
H.264是一种视频编码标准,其中的预测是其中一种压缩技术。在MATLAB中实现H.264编码可以使用一些开源库和工具,例如JM、x264等。以下是一个示例代码,实现了H.264预测编码: ```matlab % Read input video vidObj = VideoReader('input_video.mp4'); % Create output video object outputVideo = VideoWriter('output_video.mp4','MPEG-4'); outputVideo.FrameRate = vidObj.FrameRate; open(outputVideo); % Set H.264 encoder parameters params = struct('Profile','High','Level','4.0','BitRate',5000000,'FrameRate',vidObj.FrameRate); % Loop through each video frame while hasFrame(vidObj) % Read current frame frame = readFrame(vidObj); % Convert to YCbCr color space YCbCr = rgb2ycbcr(frame); % Split YCbCr into separate components Y = YCbCr(:,:,1); Cb = YCbCr(:,:,2); Cr = YCbCr(:,:,3); % Perform frame intra prediction on Y component Y_pred = intra_prediction(Y); % Combine YCbCr components YCbCr_pred = cat(3,Y_pred,Cb,Cr); % Convert back to RGB color space frame_pred = ycbcr2rgb(YCbCr_pred); % Write encoded frame to output video writeVideo(outputVideo,frame_pred); end % Close output video object close(outputVideo); function Y_pred = intra_prediction(Y) % Block size (8x8) block_size = 8; % Pad input image [rows,cols] = size(Y); Y_pad = padarray(Y,[block_size-1 block_size-1],'replicate','post'); % Perform intra prediction on each block for r = 1:block_size:rows for c = 1:block_size:cols % Get current block block = Y_pad(r:r+block_size-1,c:c+block_size-1); % Calculate prediction mode mode = calculate_mode(block); % Perform prediction switch mode case 0 % DC mode pred = mean(block(:)); case 1 % Horizontal mode pred = repmat(block(1,:),[block_size 1]); case 2 % Vertical mode pred = repmat(block(:,1),[1 block_size]); case 3 % Diagonal mode pred = diag(block); pred = repmat(pred(:),[1 block_size]) + repmat(pred(:)',[block_size 1]); pred = pred/(block_size+1); otherwise error('Invalid prediction mode'); end % Subtract prediction from current block Y_pred(r:r+block_size-1,c:c+block_size-1) = block - pred; end end end function mode = calculate_mode(block) % Calculate sum of absolute differences (SAD) for each mode SAD = zeros(4,1); SAD(1) = sum(abs(block(:)-mean(block(:)))); SAD(2) = sum(abs(block(1,:)-mean(block(:)))); SAD(3) = sum(abs(block(:,1)-mean(block(:)))); SAD(4) = sum(abs(diag(block)-mean(block(:)))); % Find mode with minimum SAD [~,mode] = min(SAD); mode = mode-1; end ``` 这段代码实现了一个简单的预测编码器,基于直接模式选择方法(mode selection),并且使用直流、水平、垂直和对角线预测模式进行预测。在实际应用中,需要使用更复杂的编码器和预测算法,以达到更好的压缩效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值