博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
x265-1.7版本-common/slice.cpp注释
阅读量:2190 次
发布时间:2019-05-02

本文共 7562 字,大约阅读时间需要 25 分钟。

注:问号以及未注释部分 会在x265-1.8版本内更新

/***************************************************************************** * Copyright (C) 2015 x265 project * * Authors: Steve Borho 
* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA. * * This program is also available under a commercial proprietary license. * For more information, contact us at license @ x265.com. *****************************************************************************/#include "common.h"#include "frame.h"#include "piclist.h"#include "picyuv.h"#include "slice.h"using namespace x265;/** 函数功能 : 获取参考帧List 以及 POC/* 调用范围 : 只在DPB::prepareEncode函数中被调用* \参数 picList : DPB m_picList* 返回值 : null**/void Slice::setRefPicList(PicList& picList){ if (m_sliceType == I_SLICE) { memset(m_refPicList, 0, sizeof(m_refPicList)); //I帧 无参考帧,全部置为0 m_numRefIdx[1] = m_numRefIdx[0] = 0; return; } Frame* refPic = NULL;//临时变量 用于获取参考帧 Frame* refPicSetStCurr0[MAX_NUM_REF];//存储前向帧 指针 Frame* refPicSetStCurr1[MAX_NUM_REF];//存储后向帧 指针 Frame* refPicSetLtCurr[MAX_NUM_REF];//存储长期参考帧 (x265没有应用) int numPocStCurr0 = 0;//计数前向帧个数 int numPocStCurr1 = 0;//计数后向帧个数 int numPocLtCurr = 0;//计数long-term 参考帧 (x265没有应用) int i;//临时变量 用于计数 for (i = 0; i < m_rps.numberOfNegativePictures; i++)//获取前向参考帧 { if (m_rps.bUsed[i]) { refPic = picList.getPOC(m_poc + m_rps.deltaPOC[i]); refPicSetStCurr0[numPocStCurr0] = refPic; numPocStCurr0++; } } for (; i < m_rps.numberOfNegativePictures + m_rps.numberOfPositivePictures; i++)//获取后向参考帧 { if (m_rps.bUsed[i]) { refPic = picList.getPOC(m_poc + m_rps.deltaPOC[i]); refPicSetStCurr1[numPocStCurr1] = refPic; numPocStCurr1++; } } X265_CHECK(m_rps.numberOfPictures == m_rps.numberOfNegativePictures + m_rps.numberOfPositivePictures, "unexpected picture in RPS\n"); // ref_pic_list_init Frame* rpsCurrList0[MAX_NUM_REF + 1];//存储List0 Frame* rpsCurrList1[MAX_NUM_REF + 1];//存储List1 int numPocTotalCurr = numPocStCurr0 + numPocStCurr1 + numPocLtCurr;//参考着个数 int cIdx = 0; //将前向帧和后向帧已经长期参考帧全部存入List0 for (i = 0; i < numPocStCurr0; i++, cIdx++) rpsCurrList0[cIdx] = refPicSetStCurr0[i]; for (i = 0; i < numPocStCurr1; i++, cIdx++) rpsCurrList0[cIdx] = refPicSetStCurr1[i]; for (i = 0; i < numPocLtCurr; i++, cIdx++) rpsCurrList0[cIdx] = refPicSetLtCurr[i]; X265_CHECK(cIdx == numPocTotalCurr, "RPS index check fail\n"); if (m_sliceType == B_SLICE) { cIdx = 0; //将后向帧和前向帧已经长期参考帧全部存入List0 for (i = 0; i < numPocStCurr1; i++, cIdx++) rpsCurrList1[cIdx] = refPicSetStCurr1[i]; for (i = 0; i < numPocStCurr0; i++, cIdx++) rpsCurrList1[cIdx] = refPicSetStCurr0[i]; for (i = 0; i < numPocLtCurr; i++, cIdx++) rpsCurrList1[cIdx] = refPicSetLtCurr[i]; X265_CHECK(cIdx == numPocTotalCurr, "RPS index check fail\n"); } //存储实际List0列表值 for (int rIdx = 0; rIdx < m_numRefIdx[0]; rIdx++) { cIdx = rIdx % numPocTotalCurr; X265_CHECK(cIdx >= 0 && cIdx < numPocTotalCurr, "RPS index check fail\n"); m_refPicList[0][rIdx] = rpsCurrList0[cIdx]; } if (m_sliceType != B_SLICE) { m_numRefIdx[1] = 0; memset(m_refPicList[1], 0, sizeof(m_refPicList[1]));//不是B帧 ,将后向List置为0 } else { for (int rIdx = 0; rIdx < m_numRefIdx[1]; rIdx++) { //存储实际List1列表值 cIdx = rIdx % numPocTotalCurr; X265_CHECK(cIdx >= 0 && cIdx < numPocTotalCurr, "RPS index check fail\n"); m_refPicList[1][rIdx] = rpsCurrList1[cIdx]; } } //获取参考帧POC for (int dir = 0; dir < 2; dir++) for (int numRefIdx = 0; numRefIdx < m_numRefIdx[dir]; numRefIdx++) m_refPOCList[dir][numRefIdx] = m_refPicList[dir][numRefIdx]->m_poc;}/** 函数功能 : 关闭当前帧的加权预测/* 调用范围 : 只在Slice()、FrameEncoder::compressFrame()、weightAnalyse函数中被调用* 返回值 : null**/void Slice::disableWeights(){ for (int l = 0; l < 2; l++) for (int i = 0; i < MAX_NUM_REF; i++) for (int yuv = 0; yuv < 3; yuv++) { WeightParam& wp = m_weightPredTable[l][i][yuv]; wp.bPresentFlag = false; wp.log2WeightDenom = 0; wp.inputWeight = 1; wp.inputOffset = 0; }}/* Sorts the deltaPOC and Used by current values in the RPS based on the * deltaPOC values. deltaPOC values are sorted with -ve values before the +ve * values. -ve values are in decreasing order. +ve values are in increasing * order *//** 函数功能 : 将RPS列表中的deltaPOC和bused 按照 远 近 (当前帧) 近 远的次序排序/* 调用范围 : 只在DPB::computeRPS函数中被调用* 返回值 : null**/void RPS::sortDeltaPOC(){ // sort in increasing order (smallest first) for (int j = 1; j < numberOfPictures; j++) //将deltaPoc按照从小到大排序(即,按照poc的顺序从小到大排序) { int dPOC = deltaPOC[j]; bool used = bUsed[j]; for (int k = j - 1; k >= 0; k--) { int temp = deltaPOC[k]; if (dPOC < temp) { deltaPOC[k + 1] = temp; bUsed[k + 1] = bUsed[k]; deltaPOC[k] = dPOC; bUsed[k] = used; } } } // flip the negative values to largest first int numNegPics = numberOfNegativePictures;//获取前向帧个数 for (int j = 0, k = numNegPics - 1; j < numNegPics >> 1; j++, k--)//将前向帧按照由远即近排序 { int dPOC = deltaPOC[j]; bool used = bUsed[j]; deltaPOC[j] = deltaPOC[k]; bUsed[j] = bUsed[k]; deltaPOC[k] = dPOC; bUsed[k] = used; }}/** 函数功能 : 返回一帧中最后实际像素在帧中的4x4块标号+1/* 调用范围 : 只在Encoder::encode函数中被调用* \参数 endCUAddr : (一帧CTU个数)*(在CTU中4x4的个数)* 返回值 : 返回一帧中最后实际像素在帧中的4x4块标号+1**/uint32_t Slice::realEndAddress(uint32_t endCUAddr) const{ // Calculate end address uint32_t internalAddress = (endCUAddr - 1) % NUM_4x4_PARTITIONS;//最后一个CTU的最后一个4x4块在内部的标号 uint32_t externalAddress = (endCUAddr - 1) / NUM_4x4_PARTITIONS;//最后一个CTU在帧中的标号 uint32_t xmax = m_sps->picWidthInLumaSamples - (externalAddress % m_sps->numCuInWidth) * g_maxCUSize;//最后一个CTU的实际像素宽度上有多少像素(不含扩边) uint32_t ymax = m_sps->picHeightInLumaSamples - (externalAddress / m_sps->numCuInWidth) * g_maxCUSize;//最后一个CTU的实际像素高度上有多少像素(不含扩边) while (g_zscanToPelX[internalAddress] >= xmax || g_zscanToPelY[internalAddress] >= ymax)//找到实际像素右下角的4x4的zigzag标号 internalAddress--; internalAddress++;//因为是从0开始计数,这样加一看看是否充满整个CTU的4x4个数 (这里可以理解为最后一个CTU含有多少实际的4x4块个数) if (internalAddress == NUM_4x4_PARTITIONS)//如果最后一个CTU是一个完成的CTU { internalAddress = 0;//内部编号为0 externalAddress++; //因为是从0开始计数,这里表示一帧含有多少个(充满状态)CTU } return externalAddress * NUM_4x4_PARTITIONS + internalAddress;//返回一帧中最后实际像素在帧中的4x4块标号+1}

 

转载地址:http://youub.baihongyu.com/

你可能感兴趣的文章
Leetcode C++《热题 Hot 100-28》19.删除链表的倒数第N个节点
查看>>
Leetcode C++《热题 Hot 100-29》22.括号生成
查看>>
Leetcode C++《热题 Hot 100-44》102.二叉树的层次遍历
查看>>
Leetcode C++《热题 Hot 100-47》236.二叉树的最近公共祖先
查看>>
Leetcode C++《热题 Hot 100-48》406.根据身高重建队列
查看>>
《kubernetes权威指南·第四版》第二章:kubernetes安装配置指南
查看>>
Leetcode C++《热题 Hot 100-49》399.除法求值
查看>>
Leetcode C++《热题 Hot 100-51》152. 乘积最大子序列
查看>>
Leetcode C++ 《第181场周赛-1》 5364. 按既定顺序创建目标数组
查看>>
Leetcode C++ 《第181场周赛-2》 1390. 四因数
查看>>
阿里云《云原生》公开课笔记 第一章 云原生启蒙
查看>>
阿里云《云原生》公开课笔记 第二章 容器基本概念
查看>>
阿里云《云原生》公开课笔记 第三章 kubernetes核心概念
查看>>
阿里云《云原生》公开课笔记 第四章 理解Pod和容器设计模式
查看>>
阿里云《云原生》公开课笔记 第五章 应用编排与管理
查看>>
阿里云《云原生》公开课笔记 第六章 应用编排与管理:Deployment
查看>>
阿里云《云原生》公开课笔记 第七章 应用编排与管理:Job和DaemonSet
查看>>
阿里云《云原生》公开课笔记 第八章 应用配置管理
查看>>
阿里云《云原生》公开课笔记 第九章 应用存储和持久化数据卷:核心知识
查看>>
linux系统 阿里云源
查看>>