HEVC/H265 HM10.0 分析(三)TAppDecTop.cpp

在TAppDecTop.cpp  ,最重要的是decode 函数,下面将对其进行分析,是解码上层的一个重要函数。

代码如下,代码后将进行分析。

Void TAppDecTop::decode()
{Int                 poc;TComList<TComPic*>* pcListPic = NULL;ifstream bitstreamFile(m_pchBitstreamFile, ifstream::in | ifstream::binary);if (!bitstreamFile){fprintf(stderr, "\nfailed to open bitstream file `%s' for reading\n", m_pchBitstreamFile);exit(EXIT_FAILURE);}InputByteStream bytestream(bitstreamFile);// create & initialize internal classesxCreateDecLib();xInitDecLib  ();m_iPOCLastDisplay += m_iSkipFrame;      // set the last displayed POC correctly for skip forward.// main decoder loopBool recon_opened = false; // reconstruction file not yet opened. (must be performed after SPS is seen)while (!!bitstreamFile){/* location serves to work around a design fault in the decoder, whereby* the process of reading a new slice that is the first slice of a new frame* requires the TDecTop::decode() method to be called again with the same* nal unit. */streampos location = bitstreamFile.tellg();AnnexBStats stats = AnnexBStats();Bool bPreviousPictureDecoded = false;vector<uint8_t> nalUnit;InputNALUnit nalu;byteStreamNALUnit(bytestream, nalUnit, stats);// call actual decoding functionBool bNewPicture = false;if (nalUnit.empty()){/* this can happen if the following occur:*  - empty input file*  - two back-to-back start_code_prefixes*  - start_code_prefix immediately followed by EOF*/fprintf(stderr, "Warning: Attempt to decode an empty NAL unit\n");}else{read(nalu, nalUnit);if( (m_iMaxTemporalLayer >= 0 && nalu.m_temporalId > m_iMaxTemporalLayer) || !isNaluWithinTargetDecLayerIdSet(&nalu)  ){if(bPreviousPictureDecoded){bNewPicture = true;bPreviousPictureDecoded = false;}else{bNewPicture = false;}}else{bNewPicture = m_cTDecTop.decode(nalu, m_iSkipFrame, m_iPOCLastDisplay);if (bNewPicture){bitstreamFile.clear();/* location points to the current nalunit payload[1] due to the* need for the annexB parser to read three extra bytes.* [1] except for the first NAL unit in the file*     (but bNewPicture doesn't happen then) */bitstreamFile.seekg(location-streamoff(3));bytestream.reset();}bPreviousPictureDecoded = true; }}if (bNewPicture || !bitstreamFile){m_cTDecTop.executeLoopFilters(poc, pcListPic);printf("\npoc =%d\n",poc);}if( pcListPic ){printf("\nnaluType =%d\n",nalu.m_nalUnitType);if ( m_pchReconFile && !recon_opened ){if (!m_outputBitDepthY) { m_outputBitDepthY = g_bitDepthY; }if (!m_outputBitDepthC) { m_outputBitDepthC = g_bitDepthC; }m_cTVideoIOYuvReconFile.open( m_pchReconFile, true, m_outputBitDepthY, m_outputBitDepthC, g_bitDepthY, g_bitDepthC ); // write moderecon_opened = true;}if ( bNewPicture && (   nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR|| nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_IDR_N_LP|| nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_BLA_N_LP|| nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_BLANT|| nalu.m_nalUnitType == NAL_UNIT_CODED_SLICE_BLA ) ){xFlushOutput( pcListPic );}// write reconstruction to fileif(bNewPicture){xWriteOutput( pcListPic, nalu.m_temporalId );}}}xFlushOutput( pcListPic );// delete buffersm_cTDecTop.deletePicBuffer();// destroy internal classesxDestroyDecLib();
}



代码xCreateDecLib 和 xInitDecLib 重要是初始化四叉树和解码需要的全局变量和申请内存。

当提供一个码流文件的文件名后,进行ifstream bitstreamFile(m_pchBitstreamFile, ifstream::in | ifstream::binary); 以二进制方式打开文件名,码流以字节方式InputByteStream bytestream(bitstreamFile);进行读操作。


我们都知道,HEVC/H265 是以NAL方式组织数据的,解析VPS,SPS,PPS,SEI,SEI_SUFFIX 后,其他的是一个个slice的NAL数据,而Deblocking & SAO Filters 等滤波是对整个picuture进行滤波操作,出现从第二帧开始,每帧的第一个slice两次进行解析,这是参考软件的一个bug或不好的地方,其实完全可以知道是否是最后一个slice,不必进行两次打开。

所以出现:

bitstreamFile.clear();

bitstreamFile.seekg(location-streamoff(3));
bytestream.reset();


大家有兴趣,可以先增加一个变量,判断是否是最后一个slice,就不需要执行上面代码了。


如下代码是从来不会执行,因为HEVC/H265没有cavlc,也就不会有slice part A ,slice part B,slice part C ,是现实的编解码告诉了设计者,slice part A ,slice part B,slice part C 没有人使用,就被抛弃了,实际的编解码从来没有实现slice part A ,slice part B,slice part C 等编解码的。

 if( (m_iMaxTemporalLayer >= 0 && nalu.m_temporalId > m_iMaxTemporalLayer) || !isNaluWithinTargetDecLayerIdSet(&nalu)  )
      {
        if(bPreviousPictureDecoded)
        {
          bNewPicture = true;
          bPreviousPictureDecoded = false;
        }
        else
        {
          bNewPicture = false;
        }
      }


解码和滤波后当然就是输出重构数据,xWriteOutput( pcListPic, nalu.m_temporalId ), 如果slice是NAL_UNIT_CODED_SLICE_IDR,NAL_UNIT_CODED_SLICE_IDR_N_LP,NAL_UNIT_CODED_SLICE_BLA_N_LP,NAL_UNIT_CODED_SLICE_BLANT,NAL_UNIT_CODED_SLICE_BLA中的一种,将解码产生的picture全部清空,没有任何参考帧,相当于一个新的sequence进行解码了。


其他的代码很简单,请自己分析。





本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/449531.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

windows下xmllib2使用简介 64位

1&#xff1a;环境配置 包含目录下 包含include libxml2_64\include     包含xmllib库路径  libxml2_64 注意 libxml分为32位程序和64位程序&#xff0c;这两种的环境需要的lib不一样&#xff0c;需要分别下载 需要使用库 libxml2.lib 注意&#xff1a…

backtrader2

backtrader的基本策略构成&#xff1a; #构成 #Backtrader 回测代码编写流程如下&#xff1a; import backtrader as bt # 导入 Backtrader import backtrader.indicators as btind # 导入策略分析模块 import backtrader.feeds as btfeeds # 导入数据模块# 创建策略 class T…

解决浏览器 Provisional headers are shown 无法向后台发送请求问题

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 我的情况和下面情况一样&#xff0c;有一个断点。 今天调试项目BUG&#xff0c;页面的一个按钮点击后页面无反应&#xff0c;去后台找对…

台湾邮政历史常设展重新开幕

1月29日&#xff0c;重新开幕的台湾邮政历史常设展增加了与观众的对话和互动&#xff0c;希望吸引不同年龄层观众。中新社记者 孔任远 摄 1月29日&#xff0c;重新开幕的台湾邮政历史常设展增加了与观众的对话和互动&#xff0c;希望吸引不同年龄层观众。中新社记者 孔任远 摄 …

如何用vc6编译ffmpeg, 并单步调试。

如何用vc6编译ffmpeg, 并单步调试。目前官方ffmpeg的最新版本为0.9, 我们就以此为例&#xff1a; 1. 下载最新git版本的源代码(http://ffmpeg.zeranoe.com/builds/, 本例下载的是2011-12-12版本) 2. 放到MSYS环境里配置&#xff0c;生成config.h文件。mingw gcc是能顺利编译…

backtrader指标

添加分析指标 # 添加分析指标 # 返回年初至年末的年度收益率 cerebro.addanalyzer(bt.analyzers.AnnualReturn, _name_AnnualReturn) # 计算最大回撤相关指标 cerebro.addanalyzer(bt.analyzers.DrawDown, _name_DrawDown) # 计算年化收益&#xff1a;日度收益 cerebro.addana…

Javascript DOM对属性的操作

获得属性值 itnode . 属性名称          //只能操作w3c规定内容 itnode . getAttribute(属性名称)    //规定的 和 自定义的都可以获取 设置属性值 itnode . 属性名称 值        //只能操作w3c规定的属性 itnode . setAttribute(名称&#xff0c;值) …

172开头的IP不一定是局域网的地址

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 A类 10.0.0.0-10.255.255.255 网络数&#xff1a;1B类 172.16.0.0-172.31.255.255 网络数&#xff1a;16C类 192.168.0.0-192.168.255.…

微信屏蔽百度红包活动页面,谁在焦虑?

1月29日消息&#xff0c;百度与中央电视台合作的百度红包链接分享页面被微信屏蔽&#xff0c;打开相关页面显示&#xff1a;网页包含诱导分享、关注等诱导行为内容&#xff0c;被多人投诉&#xff0c;为维护绿色上网环境&#xff0c;已经停止访问该网页。 雷锋网了解到&#x…

Visual C++利用Intel C++ 编译器提升多核性能与多媒体指令支持获取更高的程序效率与缩小程序体积

Intel c编译器有下列优点&#xff0c;建议VC项目开发采用intel c编译器取代VS自带c编译器&#xff1a; 与 Microsoft Visual C 相兼容&#xff0c;可以嵌入 Microsoft Visual Studio 开发环境。 支持最新的多核处理器&#xff0c;并提供安全功能&#xff0c;可以通过执行堆栈…

Backtrader交易基础

查看账户情况&#xff1a; class TestStrategy(bt.Strategy):def next(self):print(当前可用资金, self.broker.getcash())print(当前总资产, self.broker.getvalue())print(当前持仓量, self.broker.getposition(self.data).size)print(当前持仓成本, self.broker.getpositio…

IP地址分类/IP地址10开头和172开头和192开头的区别

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 IP地址分类/IP地址10开头和172开头和192开头的区别/判断是否同一网段 简单来说在公司或企业内部看到的就基本都是内网IP&#xff0c;AB…

Redis数据结构之简单动态字符串SDS

Redis的底层数据结构非常多&#xff0c;其中包括SDS、ZipList、SkipList、LinkedList、HashTable、Intset等。如果你对Redis的理解还只停留在get、set的水平的话&#xff0c;是远远不足以应对面试提问的。本文简单介绍了Redis底层最重要的数据结构 - 简单动态字符串&#xff08…

Centos7 安装OpenTSDB

Centos7 安装OpenTSDB https://www.imzcy.cn/1697.html转载于:https://www.cnblogs.com/RHadoop-Hive/p/10563385.html

职场潜规则冷思考:别让老板“杀”了你

一位3年前共事过的同事走了&#xff0c;就在他以200多万的房贷代价拿到大门钥匙的时候&#xff0c;猝然倒在新房的楼梯上。另一个曾经在同一战壕里冲锋陷阵的同事被老板辞掉了&#xff0c;兢兢业业&#xff0c;起早贪黑&#xff0c;竟然没有熬过35岁下岗这一关&#xff0c;这时…

Backtrader交易基础2

成交价格确定&#xff1a; Order.Market 市价单&#xff0c;以当时市场价格成交的订单&#xff0c;不需要自己设定价格。市价单能被快速达成交易&#xff0c;防止踏空&#xff0c;尽快止损/止盈&#xff1b; 按下一个 Bar &#xff08;即生成订单的那个交易日的下一个交易日&…

windows 小技巧

2019独角兽企业重金招聘Python工程师标准>>> 桌面图标显示不全、图标呈现白色方块 ie4uinit -show 关闭占用指定端口的进程 获取进程: netstat -ano | findstr 端口号关闭进程&#xff1a;taskkill -f -pid 进程号文件被占用 打开任务管理器&#xff0c;切换到 性能…

进一步了解 apt-get 的几个命令

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 用 apt-get 也很久了&#xff0c;没多想它的实现&#xff0c;最近遇到 gstreamer 装不上的问题&#xff0c;才多看看了它 apt-get 就是…

java学习笔记20(Arraylist复习,Collection接口方法,迭代器,增强型for循环)

集合&#xff1a;集合是Java提供的一种容器&#xff0c;可以用来存储多个数据&#xff1b; 集合与数组的区别&#xff1a;集合的长度是可变的&#xff0c;数组的长度是固定的 集合中存储的数据必须是引用类型数据&#xff1b; ArrayList回顾&#xff1a; public class Person {…

backtrader数据基础

cerebro bt.Cerebro() cerebro.addstrategy(TestStrategy2) codes[600862.SH,300326.SZ,300394.SZ] #加载最近两日交易数据 for code in codes:feed Addmoredata(dataname get_data(code,20200506),namecode)cerebro.adddata(feed) cerebro.run() 数据查看&#xff1a; cl…