在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进行解码了。

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

HEVC/H265 HM10.0 分析(三)TAppDecTop.cpp相关推荐

  1. HEVC/H265 HM10.0 分析(一)NALread.cpp

    下面分析 NALread.cpp 函数和代码. void read(InputNALUnit& nalu, vector<uint8_t>& nalUnitBuf) {/* ...

  2. HEVC/H265 HM10.0 分析(二)TComDataCU.cpp

    以下分析TComDataCU.cpp.这个cpp是很重要的,要分几次分析完,这是分析TComDataCU.cpp(一). Void TComDataCU::getPartPosition( UInt ...

  3. HEVC/H265 性能分析

    HEVC/H265 标准中的目标是:H264的码率一般,质量一样,是否达到,数据说话.  下面是视频编解码大师测试数据: HEVC: is it really twice as good as H.2 ...

  4. Android 系统(42)---Android7.0 PowerManagerService亮灭屏分析(三)

    Android7.0 PowerManagerService亮灭屏分析(三) 在前面两部分已经对绘制windows与设置设备状态进行了详细讲解. 之后接着就该对亮度值进行设置, 实现亮屏动作了. 在D ...

  5. 【投屏】Scrcpy源码分析三(Client篇-投屏阶段)

    Scrcpy源码分析系列 [投屏]Scrcpy源码分析一(编译篇) [投屏]Scrcpy源码分析二(Client篇-连接阶段) [投屏]Scrcpy源码分析三(Client篇-投屏阶段) [投屏]Sc ...

  6. FFmpeg的HEVC解码器源代码简单分析:环路滤波(Loop Filter)

    ===================================================== HEVC源代码分析文章列表: [解码 -libavcodec HEVC 解码器] FFmpe ...

  7. Spectacle源码及分析3 —— Main.cpp解析2

    接前一篇文章<Spectacle源码及分析2 -- Main.cpp解析1>: Spectacle源码及分析2 -- Main.cpp解析1_蓝天居士的博客-CSDN博客 继续深入分析Ma ...

  8. <2021SC@SDUSC>开源游戏引擎Overload代码分析三(OvWindowing结束):OvWindowing——Dialogs

    2021SC@SDUSC Overload代码分析三:OvWindowing--Dialogs 前言 Dialogs 一.FileDialog FileDialog.h FileDialog.cpp ...

  9. HEVC/H265 namespace 介绍

    在 HEVC/H265 代码中,有三个使用的namespace: 1. df 2. df::program_options_lite 3. RasterAddress 对于第一个 df 的namesp ...

最新文章

  1. .Net上下文Context  学习记录
  2. 如何提高数据安全性与可用性——行云管家堡垒机
  3. C语言写一个简单的数学程序,用C语言计算简单的数学式子
  4. 阿里云量产50家独角兽前夜
  5. 获取sqlserver数据库中所有库、表、字段名的方法
  6. stringbuilder寻找字符串位置可能存在多个 java_Java 语言基础amp;String
  7. 宋体配置JAVA j2ee (一) 轻松入门
  8. 疫情后全国热门博物馆榜单出炉 第一名竟不是故宫
  9. java中使用事务案例_Java事务之四——成功的案例
  10. QT开发(四十)——GraphicsView编程
  11. 【实用】神级工具类Hutool,你值得拥有!
  12. usb启动计算机boss设置方法,技嘉主板bios设置usb启动(图文教程)
  13. 开机后主板测试卡直接显示“FF或00”的故障原因及排除方法:
  14. 苹果手机备份数据到电脑什么位置 iPhone备份到电脑上的东西在哪里
  15. 【Bug解决】 -1073740791 (0xC0000409)
  16. 熟悉RT-Thread的软硬件环境【RT-Thread学习笔记 1】
  17. 设计师思维模式你get到多少个?
  18. python列表查找整数_Python:找出整数列表是否为coheren
  19. 情商比智商更能决定人的一生
  20. 02-leveldb入门

热门文章

  1. 【转】人工智能-1.2.2 神经网络是如何进行预测的
  2. 【转】WPF入门教程系列六——布局介绍与Canvas(一)
  3. 【转】01Teams的前世今生
  4. 第一节:框架前期准备篇之Log4Net日志详解
  5. python nodemcu_python开发nodemcu(一)
  6. python @修饰符_python函数修饰符@的使用方法解析
  7. android 传感器ceshi,Android代码-传感器-测试手机支持那几种传感
  8. php 和jsp,jsp和php哪个好?jsp和php的简单比较
  9. CCIE理论-第六篇-SD-WAN网络(一)
  10. 【HDU - 6118】度度熊的交易计划(最小费用可行流,网络流费用流变形 )