精华内容
下载资源
问答
  • H264帧内编码与帧间编码

    千次阅读 2017-02-13 19:14:50
    晚上没事干,无聊,所以想写点什么。 为了达到节约空间的目的,视频图像都是经过编码,然后用于各种不同的场合,特别是...P帧,要前向参考,而B帧,则要进行双向参考,这两种,都属于帧间编码。 先说说帧内编码...

    晚上没事干,无聊,所以想写点什么。

    为了达到节约空间的目的,视频图像都是经过编码,然后用于各种不同的场合,特别是网络传输,因为带宽的限制,为了更好的传输数据,必须对视频进行压缩处理。而目前最流行的当属H264了。

    经过H264压缩的视频,可分为I、B、P三种不同的帧。其中I帧因为不参考其他帧,所以是帧内编码。P帧,要前向参考,而B帧,则要进行双向参考,这两种,都属于帧间编码。

    先说说帧内编码:

    帧内,顾名思义,就是不求外,只求内。不管外部数据如何,仅仅通过自身已有的数据进行编码。一幅图像里面的物体往往具有空间上的相关性,比如,以下图片:

    除了中间的几个字,其他区域都是蓝色的,并且是一模一样的,所以,在空间上,数据就有相当大的冗余。而帧内编码,就是要去除这部分冗余数据。在帧内编码情况下,编码图像仅仅进过DCT(离散余弦变换)、量化器呗编码器就可生成编码比特流。DCT直接用于原始数据。

    下面来说说帧间编码:

    视频,其实就是一张一张图片而已,而这些图片其实都是相似的,仅仅只有很小的区别,这样就可以达到欺骗我们肉眼的效果,给我们一种动画的感觉。而这,就是所谓的时间相关性。比如上图,如果我们把它想象成一个视频,Media这个单词在里面运动,不管Media运动到哪里,他始终都是Media这个单词,样子都没有任何变化,仅仅是位置变了。而变化量、方向,我们可以用一个矢量表示,这就是所谓的运动矢量。帧间编码与帧内编码的不同之处在于他经过预测环节的处理。步骤如下:

    1、计算参考帧与原始帧之间的运动矢量

    2、通过参考帧与运动矢量生成原始帧的预测图像

    3、讲原始图像与预测像素差值生成差分图像数据

    4、对差分图像数据进行DCT变换

    5、经过量化器量化

    6、编码器生成压缩数据

    以上就是笔者对编码的意见简单的理解,后面再有无聊的时候,会对这几个步骤做一些详细的分析

    展开全文
  • 视频编码中快速帧间编码算法的研究,王洪彬,杨志钢,本文提出一种自适应方向性搜索与快速模式选择相结合的快速帧间编码方案,以降低H.264视频编码中帧间编码的计算复杂度。运动估计过�
  • 曾经有在读研究生问我有关帧间编码快速判定算法,因为他(她)目前的任务主要是为帧间编码或者帧内编码提出一种实用实时的快速算法。对于实时编码软件(或者硬件)而言包括X264,T264在内为了达快速的效果,以达到...

     

    曾经有在读研究生问我有关帧间编码快速判定算法,因为他(她)目前的任务主要是为帧间编码或者帧内编码提出一种实用实时的快速算法。对于实时编码软件(或者硬件)而言包括X264,T264在内为了达快速的效果,以达到实时传送图像信息的效果,都会采用快速判定帧间或者帧内预测,有的会去掉一些复杂的算法。主要的想法就是,既然要得到最优的编码模式,要用很高的复杂计算和大量的计算时间,倒不如不再要求得到最优的编码模式,只要能得到80%的次优的编码模式,甚至得到一部分中优的编码模式,只要编码后再解码的图像质量下降不多,能适用,码率增加不多,编码时间能大幅下降,那这样的目的也就达到了。所以目前就有很多人提出了很多帧间或帧内快速判定法,先去除一些认为出现概率不大的预测模式,比如或先删P16的P16x16模式,或先删P16的P16x8,P8x16模式,或先删P8的P8x8模式,或先删P8的P8x4,P4x8模式,或先删P8的P4x4模式,如此林林种种,各种算法五花八门。
    对于帧间预测模式而言,大体上分了如下几类。
    第一种分法:
    P16全模式:包括P16x16, P16x8, P8x16
    P16大模式:p16x16
    P16小模式:包括P16x8, P8x16
    P8全模式:包括P8 x8, P8x4, P4x8, P4x4
    P8大模式:p8x8
    P8小模式:包括P8x4, P4x8, P4x4
    第二种分法:
    A类模式:包括P16x16,PSKIP/BSKIP_DIRECT
    B类模式:包括P16x8, P8x16
    C类模式:包括P8 x8
    D类模式:包括P8x4, P4x8
    E类模式:包括P4x4。

    帧间快速判定模式,很多是或者根据边缘强度,或者根据纹理特征,或者根据原图像点和参考图像点的SAD值,去除掉其中一类或者多类帧间预测模式,用少量的帧间预测模式进行预测,进行代价(开销)比较,取最小的代价(开销或者成本)为最佳模式进行编码。这样得到的基本是:大部分次优(次佳)模式+少量的最优模式+少量的中优模式。
    这样图像质量有所下降,码率有所增加,但大幅度降低了编码时间,更适用了实时的编码场合。

    这儿提的“概分法快速判定帧间预测模式”指的是:用概率分布的方法来判定某一块最有可能的帧间预测模式。
    具体方法是:把待编码图像按4x4分为若干不重叠的块即我们通常所说的4x4块,将该块与一帧参考帧或者多帧参考相对应的位置(相同的位置)进行4x4块内SAD累加和计算。然后用该块的SAD累加和与五个动态的SAD阀值比较,根据比较结果将该块按本文所说的第二种帧间模式分类的类别,根本进行该模式类别相应帧间预测进行帧间预测计算。

    本文对该算法进行过测试。图像质量下降不明显,码率有所提高,编码时间有大幅下降为原编码时间的40%~60%不等。
    该法虽然去掉了不少的帧间预测计算的时间,但SAD累加和的计算和五个动态的SAD阀值计算仍占了不少的时间。
    展开全文
  • 3D-HEVC帧间编码的低复杂度算法
  • 基于分布式压缩感知的H.264帧间编码
  • 帧间编码和帧内编码Coding Interviews require time and practice to ace. You need to be thorough with all the concepts and also be confident about the projects and internships you have mentioned on your ...

    帧间编码和帧内编码

    Coding Interviews require time and practice to ace. You need to be thorough with all the concepts and also be confident about the projects and internships you have mentioned on your resume. This article will give you a complete roadmap for your preparation and how I prepared for my interviews in around 3 months. This article is intended for a fresher who is about to enter the placement season and not for people having a few years of experience. I started my preparation in the month of March 2020, just after the commencement of the worldwide global pandemic.

    çoding采访需要时间和实践来王牌。 您需要全面了解所有概念,并对简历中提到的项目和实习充满信心。 本文将为您提供准备工作的完整路线图,以及我如何在大约3个月的时间里为面试做准备。 本文适用于即将进入分班季节的新人,而不适合有几年经验的人。 在全球大流行开始后的2020年3月,我开始准备工作。

    Before you go any further in the article, I would like to give a brief about my background. I am currently a final year B. Tech student from Vellore Institute of Technology, Vellore with a full time SWE offer from Société Générale. Throughout my degree, I have worked on projects in various domains like AI, Android and Web. So, what do I mean when I say preparing for the interviews when I have had some coding experience in college? Two things basically :

    在继续本文之前,我想简要介绍一下我的背景。 我目前是Vellore理工学院的B. Tech大学最后一年的学生,并拥有SociétéGénérale的全职SWE职位。 在整个学位课程中,我从事过AI,Android和Web等各个领域的项目。 那么,当我在大学里有一些编码经验时,说准备面试是什么意思? 基本上有两件事:

    1. Undergraduates are judged only on their coding, problem solving and computer fundamentals knowledge and not on the tech stack they have worked upon. This is the reason, an AI guy might turn out to be a Full Stack Web Developer or an Android Developer may turn out to be a great Data Scientist. The technologies you work upon when you join a company may not be the technologies you work upon as a college student.

      仅根据他们的编码,问题解决和计算机基础知识对大学生进行评判,而不根据他们所从事的技术知识来对他们进行评判。 这就是原因,一个AI专家可能证明是Full Stack Web开发人员,或者Android开发人员可能证明是一位出色的数据科学家。 加入公司时所使用的技术可能不是大学生所使用的技术。
    2. The hobby projects which freshers mention in their resume rarely are up to the standards of the enterprise projects. Enterprise level software should be scalable.

      应届毕业生在简历中提到的业余项目很少达到企业项目的标准。 企业级软件应具有可伸缩性。
    Image for post
    Data Structures and Algorithms for the base of any coding interview
    编码面试的基础数据结构和算法

    Now, coming to the placement strategy, I will basically divide it into 4 parts:

    现在,在介绍布局策略时,我将其大致分为4部分:

    1. Choosing a language — This is the first step for any student aiming to join a product-based company. Choose any language which you prefer and stick to it. Do not change it after a month. Go for any Object Oriented Language from Java, C++ or Python. I prepared in Java. The reason I have excluded languages like JS, C# from the list is because lot of companies do not give you the option of choosing a language other than the 3. Therefore, playing it safe, select any one of the three I have mentioned. Learn the Object Oriented Programming concepts and try to implement all of them in the language you have selected. Luckily for me, I had the Java Programming course in the sixth semester of my college, i.e, just before I started with my preparation. Thus, I could basically skip this step as I had covered these concepts pretty recently and the information was fresh in my mind.

      选择语言 -这是任何旨在加入基于产品的公司的学生的第一步。 选择您喜欢的任何语言并坚持使用。 一个月后请勿更改。 寻找Java,C ++或Python的任何面向对象的语言。 我用Java编写。 我之所以从列表中排除诸如JS,C#之类的语言,是因为许多公司没有给您选择3种语言之外的其他语言的选择。因此,为了安全起见,请选择我提到的三种语言中的任何一种。 学习面向对象编程的概念,并尝试以所选的语言实现所有这些。 对我来说幸运的是,我在大学第六学期(即,在我开始准备之前)上了Java编程课程。 因此,我基本上可以跳过此步骤,因为我最近刚刚介绍了这些概念,因此我脑海中有了新鲜的信息。

    2. Data Structures and Algorithms — This is the most important step of your process. DSA accounts for up to 80% of the questions you get in a coding interview. This step involves learning the basics of DSA and not competitive programming. Select any resource you are comfortable with and stick to it. You can choose either a book or a website. However, choose a single resource and stick to it. I studied from the book called Data Structures and Algorithms made easy in Java by Narsimha Karumanchi. It is one the most complete book out there and is extremely beginner friendly. The book contains multiple questions which are solved using multiple different approaches. The topics to be studied are — Arrays, Strings, Linked Lists, Stacks, Queues, Trees, Graphs, Greedy Programming, Recursion, Backtracking, Dynamic Programming, Bit Manipulation, Binary Search and Sorting Algorithms. In the next couple of months, I will be writing separate articles on some of the important and difficult topics among them and try to give a walk through of how I studied all of them.

      数据结构和算法 -这是过程中最重要的步骤。 DSA最多占您在编码采访中遇到的问题的80%。 此步骤涉及学习DSA的基础知识,而不是竞争性编程。 选择您喜欢的任何资源并坚持使用。 您可以选择书籍或网站。 但是,请选择一个资源并坚持使用。 我从Narsimha Karumanchi的《 Java中的数据结构和算法 》一书中学习。 这是一本最完整的书,对初学者非常友好。 本书包含多个问题,可以使用多种不同的方法来解决。 要研究的主题是-数组,字符串,链表,堆栈,队列,树,图,贪婪编程,递归,回溯,动态编程,位操作,二进制搜索和排序算法。 在接下来的几个月中,我将针对其中的一些重要和困难主题撰写单独的文章,并尝试逐步介绍我如何研究所有这些主题。

    3. Competitive Programming and SQL — The third step is to get your hands dirty in the world of competitive programming. The types of questions you get in Competitive Programming(CP) are a bit different from the types of questions you get in the interviews. CP is a bit mathematical whereas interviews are a bit focused towards DSA. This is the step where you apply the concepts learnt in the previous phase and build your actual thinking ability. I highly recommend solving questions from any one of the proper competitive programming websites like Codeforces, Codechef or Hackerrank as the type of questions you get in these platforms are generally questions you have not seen before. This trains your mind in thinking about the most optimized solution on the spot and will build your thought process. Apart from this, solve questions from any one of Leetcode or Geeksforgeeks depending upon your personal preference. Apart from this, I highly recommend you to brush up your RDBMS concepts. At the same time also practice SQL questions from any website of your choice.

      竞争性编程和SQL —第三步是让您在竞争性编程的世界中变脏。 在竞争性编程(CP)中遇到的问题类型与在面试中遇到的问题类型有些不同。 CP有点数学,而访谈则有点针对DSA。 这是您应用上一阶段学到的概念并增强实际思维能力的步骤。 我强烈建议您从Codeforces,Codechef或Hackerrank等任何适当的竞争性编程网站中解决问题,因为在这些平台中遇到的问题通常是您以前从未见过的问题。 这样可以训练您的思维,让您思考当场最优化的解决方案,并建立您的思考过程。 除此之外,根据您的个人喜好,从Leetcode或Geeksforgeeks中解决任何一个问题。 除此之外,我强烈建议您复习RDBMS概念。 同时,还可以从您选择的任何网站练习SQL问题。

    4. Revision and Mock Interviews — This is the final phase of the preparation process. Revise the concepts of Operating Systems and Computer Networks as companies tend to ask question from these topics in the online test as well as in the interviews. The final step which you need to follow and which I would say becomes the difference in you acing your first interview or not is practicing mock interviews. This step is a must as it gets you into the feel of how you need to approach the interview. This also removes the fear which you posses for the interviews making you completely comfortable with the process. During interviews, explaining your thought process to the interviewer is more important that solving the question. Thus, do at least 5–10 mock interviews before the placement season begins on Pramp. Also, go through the book called Cracking the Coding Interview by Gayle Laakmann McDowell a week or two before your interviews for a final revision.

      修订和模拟访谈 —这是准备过程的最后阶段。 修订操作系统和计算机网络的概念,因为公司倾向于在在线测试以及面试中从这些主题中提出问题。 您需要遵循的最后一步,我想说的是,您在进行初次面试与不进行面试时的区别在于练习模拟面试。 这一步是必须的,因为它可以使您了解如何进行面试。 这也消除了您为面试带来的恐惧感,使您完全满意此过程。 在面试中,向面试官解释您的思维过程比解决问题更为重要。 因此,在就职季节开始于Pramp之前,至少要进行5-10次模拟面试。 另外, 在面试前一到两周,请阅读盖尔·拉克曼·麦克道威尔(Gayle Laakmann McDowell)撰写的《 破解编码面试 》一书,以进行最终修订。

    TIPS:

    提示:

    1. Solve the questions the correct way. Always get out of your comfort zone and allow your mind to think. Otherwise, even solving a thousand questions won’t get you through.

      以正确的方式解决问题。 始终走出您的舒适区,让您的思想进行思考。 否则,即使解决一千个问题也无法解决问题。
    2. Having a breadth first knowledge of all the topics is recommended rather than having a depth first one. This will allow you to think in all possible directions for a given problem.

      建议您具有所有主题的广度优先知识,而不是深度知识。 这将使您能够针对所有给定问题进行思考。
    3. Never ever mug up a particular approach. This will easily set you a couple of months back in your preparation. Although, it may seem as a shortcut but will definitely harm you in the long run as you are confining your mind in one direction.

      永远不要搞砸特定的方法。 这很容易使您重新准备几个月。 虽然,这似乎是一种捷径,但从长远来看,肯定会损害您的利益,因为您将注意力集中在一个方向上。
    4. Whenever you learn a new algorithm, always try to implement it by yourself before looking how it is implemented in a language. This will increase your grip in the programming language of your choice.

      每当您学习新算法时,在查看如何以某种语言实现该算法之前,请始终尝试自行实现该算法。 这将增加您对所选编程语言的了解。
    5. Along with programming skills and computer fundamentals, having good projects in your resume is equally important. It will allow you with some breathing space and will also give the interviewer a good impression about your problem solving skills with respect to a real time scenario.

      除了编程技巧和计算机基础知识外,简历中的优秀项目也同样重要。 这将为您提供一些喘息的空间,也将使访问员对您在实时场景中解决问题的技能有良好的印象。

    RECOMMENDED RESOURCES:

    推荐资源:

    1. Data Structures and Algorithms made Easy by Narsimha Karumanchi

      Narsimha Karumanchi简化了数据结构和算法
    2. Cracking the Coding Interview by Gayle Laakmann McDowell

      盖伊·拉克曼·麦克道威尔(Gayle Laakmann McDowell)
    3. Leetcode/Geeksforgeeks for DSAquestions.

      Leetcode / Geeksforgeeks用于DSAquestions。
    4. Codeforces/Codechef/Hackerrank for Competitive Programming.

      竞争性编程的Codeforces / Codechef / Hackerrank。
    5. Knowledge Gate youtube channel for DBMS and OS.

      用于DBMS和OS的Knowledge Gate youtube频道。
    6. Hackerrank for SQL Questions.

      有关SQL问题的Hackerrank。
    7. Gate Smashers for Computer Networks.

      计算机网络的门粉碎机。

    This is basically the strategy which I followed during my preparation and the strategy I would recommend to any junior for their preparation. There are still lots of things which I have covered only up to a superficial level in this article which I would be covering in the future. Till then, Happy Coding :)

    这基本上是我在准备过程中遵循的策略,也是我会推荐给任何大三学生准备的策略。 在本文中,我仍然会涉及很多东西,直到我只涉及一个肤浅的层面,以后我会再讨论它们。 直到那时,快乐编码:)

    翻译自: https://medium.com/swlh/how-i-prepared-for-coding-interviews-in-3-months-8d54ba3bf50

    帧间编码和帧内编码

    展开全文
  • HEVC中帧间编码的复杂度可扩展模式决策算法
  • H264/avc帧间编码算法研究与改进,刘奎,李旭杰,为了减少视频编码的运算量,通过对H.264标准原有帧间编码算法的分析,提出一种改进的帧间编码算法。该算法利用宏块的运动特性和相�
  • H.264/AVC视频编解码技术详解 GitHub代码地 一、基本概念 nalu按照解码顺序frame_num送入解码器解码 ...在解码图像缓存中,用于P帧或B帧帧间编码的参考帧图像保存为一个或两个参考帧列表,列表中参考帧的顺序可

    H.264/AVC视频编解码技术详解
    GitHub代码地

    一、基本概念

    nalu按照解码顺序frame_num送入解码器解码
    解码后的图像按照播放顺序POC(picture_order_count)进行存储和播放
    (由于B帧的存在,解码顺序和显示顺序会有差异)

    在这里插入图片描述
    frame_num和POC通过slice_header传输:
    在这里插入图片描述

    某一帧图像在解码完成后,可能会被保存于解码图像缓存中,用于后续图像帧间预测的参考帧。在解码图像缓存中,用于P帧或B帧帧间编码的参考帧图像保存为一个或两个参考帧列表,列表中参考帧的顺序可以通过某个专门的过程进行重排列。

    二、解码顺序计数值frame_num(当前slice在GOP中的解码顺序)

    在一个GOP中,第一个slice即作为随机接入点的IDR slice,其frame_num值为0,表示当前slice是一个GOP的起点。
    GOP中的其他slice按照相应距离IDR的顺序按1递增。
    当另一个语法元素gaps_in_frame_num_value_allowed存在时,slice可以以大于1的值递增,此时缺失的frame_num值需要解码器用空slice数据进行填充。

    三、显示顺序标志值POC(picture_order_count)

    视频中IDR的第一个field作为POC的开始,其值为0。在H.264的标准中,POC的计算方法在标准文档中的8.2.1节中定义。

    对于H.264的码流,有三种结构会被赋予POC的值:coded frame(编码帧), coded field(编码场)和complementary field pair(互补参考场对),每种类型的POC都由TopFieldOrderCnt和BottomFieldOrderCnt这两个值的一个或两个组成:
     1、对于每一个编码帧,poc包含两个值TopFieldOrderCnt和BottomFieldOrderCnt;
     2、对于每一个编码场,poc包含一个值,如果该field为顶场则为TopFieldOrderCnt,如果是底场为BottomFieldOrderCnt;
     3、对于每一个互补参考场对,POC包含两个值,对顶场为TopFieldOrderCnt,对底场为BottomFieldOrderCnt;
    在H.264中,TopFieldOrderCnt和BottomFieldOrderCnt共定义了3种解析方法,由sps中的值pic_order_cnt_type决定。

    3.1 直传模式:pic_order_cnt_type=0

    POC的值通过slice_header中的数据计算得到

    1、获得中间变量prevPicOrderCntMsb和prevPicOrderCntLsb
    2、计算当前帧的PicOrderCntMsb
    3、计算TopFieldOrderCnt和BottomFieldOrderCnt
    在这里插入图片描述

    3.2 预测与差分方式(pic_order_cnt_type=1)

    sps中:
    在这里插入图片描述

    1、获得中间变量prevFrameNum、FrameNumOffset、prevFrameNumOffset
    2、计算中间变量absFrameNum、picOrderCntCycleCnt、frameNumInPicOrderCntCycle和expectedPicOrderCnt

    if (sps中)num_ref_frames_in_pic_order_cnt_cycle != 0
    	absFrameNum = FrameNumOffset + frame_num
    else
    	absFrameNum = 0
    end
    
    

    另外,若nal_ref_idc值为0且absFrameNum非0,absFrameNum需再减去1:

    absFrameNum = absFrameNum − 1
    

    当absFrameNum大于0时,picOrderCntCycleCnt和frameNumInPicOrderCntCycle分别为absFrameNum - 1除以num_ref_frames_in_pic_order_cnt_cycle的商和余数:

    picOrderCntCycleCnt = ( absFrameNum − 1 ) / num_ref_frames_in_pic_order_cnt_cycle
    frameNumInPicOrderCntCycle = ( absFrameNum − 1 ) % num_ref_frames_in_pic_order_cnt_cycle
    

    下一步根据absFrameNum的计算expectedPicOrderCnt的值。若absFrameNum的值为0,则expectedPicOrderCnt的值亦为0;否则该值由picOrderCntCycleCnt、ExpectedDeltaPerPicOrderCntCycle和offset_for_ref_frame共同计算得到:

    if( absFrameNum > 0 ){
    	expectedPicOrderCnt = picOrderCntCycleCnt * ExpectedDeltaPerPicOrderCntCycle;
    	for( i = 0; i <= frameNumInPicOrderCntCycle; i++ )
    		expectedPicOrderCnt = expectedPicOrderCnt + offset_for_ref_frame[ i ];
    } else
    	expectedPicOrderCnt = 0
    

    如果nal_ref_idc的值为0,expectedPicOrderCnt再增加offset_for_non_ref_pic:

    expectedPicOrderCnt = expectedPicOrderCnt + offset_for_non_ref_pic;
    

    3.2.3 计算TopFieldOrderCnt和BottomFieldOrderCnt

    对于帧编码的slice,TopFieldOrderCnt和BottomFieldOrderCnt通过上面计算得到的expectedPicOrderCnt,以及sps中读取的语法元素delta_pic_order_cnt和offset_for_top_to_bottom_field计算得到:

    TopFieldOrderCnt = expectedPicOrderCnt + delta_pic_order_cnt[0];
    BottomFieldOrderCnt = TopFieldOrderCnt +offset_for_top_to_bottom_field + delta_pic_order_cnt[1];
    

    3.3 显示顺序与解码顺序一致(pic_order_cnt_type=2)

    FrameNumOffset和prevFrameNumOffset同模式2中的计算方法类似,FrameNumOffset计算方法根据当前帧是否是IDR,以及prevFrameNum与frame_num的比较关系计算得到:

    1、若当前帧为IDR,则FrameNumOffset为0;
    2、若当前帧非IDR,且prevFrameNum大于frame_num,则计算方式为:

    FrameNumOffset = prevFrameNumOffset + MaxFrameNum
    

    3、若当前帧非IDR,且prevFrameNum小于frame_num,则FrameNumOffset的值即为prevFrameNumOffset;

    计算tempPicOrderCnt:
    1、若当前帧为IDR,则tempPicOrderCnt值为0;
    2、若当前帧为非IDR,且nal_ref_idc为0,则tempPicOrderCnt的计算方法为

    tempPicOrderCnt = 2 * ( FrameNumOffset + frame_num )1
    

    3、否则,tempPicOrderCnt的计算方法为:

    tempPicOrderCnt = 2 * ( FrameNumOffset + frame_num )
    

    最后,在帧编码的条件下,TopFieldOrderCnt和BottomFieldOrderCnt的值都与tempPicOrderCnt相等:

    TopFieldOrderCnt = tempPicOrderCnt
    BottomFieldOrderCnt = tempPicOrderCnt
    

    四、图像管理

    当H.264作为参考帧的某一帧解码完成后,该帧的数据将会保存在解码图像缓存区中,并且按照相应的规则标记为短期或长期参考帧。其中,短期参考帧由上文中提到的frame_num标记,长期参考帧由另一个值LongTermPicNum标记。

    每一个P帧的解码对应一个参考帧列表RefPicList0,每一个B帧对应两个独立的参考帧列表RefPicList0和RefPicList1。

    4.1 计算图像序号

    参考帧的索引值用于从参考帧列表中获取数据。在参考帧列表的初始化、更新,参考帧的标记,以及处理非连续的frame_num时,需要计算参考帧的图像序号,其中主要有FrameNum, FrameNumWrap, PicNum, LongTermFrameIdx 和 LongTermPicNum等。

    对于一个短期参考帧,计算FrameNum和FrameNumWrap。当前帧的FrameNum和FrameNumWrap计算方法为:

    首先设FrameNum的值为对应的短期参考帧的frame_num的值;
    如果FrameNum的值大于当前帧slice_header中解析出的frame_num值,则FrameNumWrap的计算方式为:

    FrameNumWrap = FrameNum - MaxFrameNum
    

    否则,FrameNumWrap的计算方式为:

    FrameNumWrap = FrameNum
    

    对于一个长期参考帧,计算其LongTermFrameIdx的值。该过程在下节中详细讨论。

    最后,对于每一个短期参考帧图像,计算PicNum值,对于一个长期参考帧图像,计算LongTermPicNum。如果当前帧为帧编码,即field_pic_flag为0,则二者的值分别与FrameNumWrap和LongTermPicNum相等:

    PicNum = FrameNumWrap
    LongTermPicNum = LongTermFrameIdx
    

    在JM8.6代码中的体现如下:

    if (currPicStructure == FRAME)  
      {
        for (i=0; i<dpb.ref_frames_in_buffer; i++)
        {
          if (dpb.fs_ref[i]->is_used==3)
          {
            if ((dpb.fs_ref[i]->frame->used_for_reference)&&(!dpb.fs_ref[i]->frame->is_long_term))
            {
              if( dpb.fs_ref[i]->frame_num > img->frame_num )
              {
                dpb.fs_ref[i]->frame_num_wrap = dpb.fs_ref[i]->frame_num - MaxFrameNum;
              }
              else
              {
                dpb.fs_ref[i]->frame_num_wrap = dpb.fs_ref[i]->frame_num;
              }
              dpb.fs_ref[i]->frame->pic_num = dpb.fs_ref[i]->frame_num_wrap;
              dpb.fs_ref[i]->frame->order_num=list0idx;
            }
          }
        }
      }
    

    4.2 解码参考帧的标记

    当NALU中的nal_ref_idc值非0,即当前NALU所代表的图像会被作为参考帧的时候,会执行参考帧的标记过程。执行该过程的主要原因可以理解为,由于当前帧会作为参考帧数据放入DPB中,当前DPB中已有的参考帧的性质可能会发生变化,即短期参考帧可能会变为长期参考帧,或者某个参考帧可能会被标记为不再用做参考,因此需要对DPB中的参考帧数据进行重新标记。

    如同其命名所表示的含义一样,一个被标记为“用于短期参考”或“用于长期参考”的视频帧在解码过程中可以作为后续帧的参考数据,直到该参考帧被标记为“不再用作参考”为止。将一个参考帧标记为“不再用作参考”的方法通常有两种:

    • 滑动窗口法:通过一种“先进先出”机制进行的方法;
    • 自适应内存控制法;

    在标准文档8.2.5.1节中,解码参考帧的标记过程按如下步骤执行:

    1. 首先,确保当前帧的所有slice解码完成;
    2. 随后,判断当前帧的帧类型。如果当前帧为一个IDR帧,则进行以下操作:
      • 将所有的参考帧标记为“不作为参考”;
      • 如果long_term_reference_flag为0,则该IDR帧被标记为“作为短期参考”,且MaxLongTermFrameIdx设为“无长期参考帧索引”;
      • 如果long_term_reference_flag为1,则该IDR帧被标记为“作为长期参考”,其LongTermFrameIdx设为0,并且MaxLongTermFrameIdx设为0;
    3. 如果当前帧为非IDR帧,则执行以下操作:
      • 如果adaptive_ref_pic_marking_mode_flag为1,则进行自适应内存控制法标记参考帧;
      • 如果adaptive_ref_pic_marking_mode_flag为0,则进行滑动窗口法标记参考帧;
    4. 如果当前帧为非IDR帧,且没有因为memory_management_control_operation的值等于6而被标记为“用于长期参考”,则该帧被标记为“用于短期参考”。

    4.2.1 滑动窗口法

    下面首先介绍滑动窗口法:

    1. 如果当前图像是一个 complementary reference field pair 中按照解码顺序的第二个场,且第一场被标记为“用作短期参考”,那么当前图像和该complementary reference field pair都被标记为“作为短期参考”。
    2. 否则的话,根据如下步骤执行:
      1. 设numShortTerm为作为短期参考的编码帧、编码场或互补场对的总数,numLongTerm为长期参考帧/场/场对的总数;
      2. 当numShortTerm与numLongTerm之和达到Max(max_num_ref_frames, 1)时,在满足numShortTerm大于0的前提下,FrameNumWrap值最小的那个作为短期参考的编码帧、编码场或互补场对将被标记为“不作为参考”。

    4.2.2 自适应内存控制法

    从上一小节中可以看出,滑动窗口法的效果主要在于将过期的短期参考帧从DPB中移除出去,并不涉及到对长期参考帧的操作(除非遇到IDR时将DPB全部清空)。而自适应内存控制法的操作流程比滑动窗口法要复杂得多。

    执行自适应内存控制法标记参考帧的条件是adaptive_ref_pic_marking_mode_flag为1,此时slice_header中会包含一些附加的语法元素信息,如下表所示:

    从上图的dec_ref_pic_marking结构中可以看出,如果adaptive_ref_pic_marking_mode_flag的值为1,那么其中将会多出若干个值:

    • memory_management_control_operation;
    • difference_of_pic_nums_minus1;
    • long_term_pic_num;
    • long_term_frame_idx;
    • max_long_term_frame_idx_plus1

    其中,memory_management_control_operation可以取的范围为1~6,分别代表了不同的操作。

    4.2.2.1 将短期参考帧标记为“不作为参考”

    当memory_management_control_operation为1时,自适应内存控制过程会将某一个短期参考帧标记为“不作为参考”。具体的执行过程为:

      1、首先计算picNumX。计算方法为:
    picNumX = CurrPicNum − ( difference_of_pic_nums_minus1 + 1 )
    

    其中,CurrPicNum为当前帧的frame_number,difference_of_pic_nums_minus1从dec_ref_pic_marking中解析得到。
    2、对于帧编码的图像,PicNum等于picNumX的短期参考帧会被标记为“不作为参考”;

    4.2.2.2 将长期参考帧标记为“不作为参考”

    当memory_management_control_operation为2时,自适应内存控制过程会将某一个长期参考帧标记为“不作为参考”。具体的执行过程很简单,索引为LongTermPicNum等同于long_term_pic_num的长期参考帧将被标记为不作为参考。

    4.2.2.3 将短期参考帧标记为“长期参考帧”

    当memory_management_control_operation为3时,自适应内存控制过程会将某一个短期参考帧标记为“作为长期参考帧”。在这种情况下,码流中会同时包含difference_of_pic_nums_minus1以及long_term_frame_idx这两个值。执行过程如下:

    1. 按照4.2.2.1中的方法计算picNumX;
    2. 如果long_term_frame_idx对应的长期参考帧存在,则该长期参考帧标记为“不作为参考”;
    3. 对于帧编码图像,由picNumX所代表的短期参考帧,将被标记为长期参考帧,并将对应的LongTermFrameIdx设为long_term_frame_idx。

    4.2.2.4 计算MaxLongTermFrameIdx

    当memory_management_control_operation为4时,执行计算MaxLongTermFrameIdx的操作。计算过程如下:

    • 如果码流中解析出的max_long_term_frame_idx_plus1的值为0,则MaxLongTermFrameIdx被设置为“无长期参考帧索引”;
    • 否则,MaxLongTermFrameIdx的值设置为max_long_term_frame_idx_plus1-1。

    所有被标记为“用作长期参考”且LongTermFrameIdx大于了MaxLongTermFrameIdx的图像都会被标记为“不作为参考”。

    4.2.2.5 清空参考帧列表

    当memory_management_control_operation为5时,执行清空参考帧列表操作。该过程会将所有参考帧标记为“不作为参考”并将MaxLongTermFrameIdx设置为“无长期参考帧索引”。

    4.2.2.6 将当前帧标记为长期参考帧

    当memory_management_control_operation为6时,将当前帧标记为长期参考帧。在这种情况下,需从码流中解析出long_term_frame_idx。执行过程如下:

    • 如果long_term_frame_idx对应的长期参考帧存在,则该长期参考帧标记为“不作为参考”;
    • 将当前帧标记为“作为长期参考”,并将其LongTermFrameIdx设置为long_term_frame_idx;

    在当前帧标记完成后,所有被标记为“作为参考帧”的帧、场和互补场对的数量综合不能超过Max( max_num_ref_frames, 1 )规定的值。

    展开全文
  • 我们知道,对于帧间编码的宏块,其划分方式可以分为两步,其一为宏块级划分,其二为子宏块级划分。下面分别讨论这两个步骤。 1.1 帧间预测宏块划分 我们知道,对于P宏块,其宏块级划分有4种方式:16×16、16×8、8×...
  • 这篇文档主要是介绍mpeg的数据结构,同时介绍了帧间编码的相关技术。主要是I帧B帧以及P帧的相关概念、技术、编解码
  • 中南大学电子信息工程,13级视频信号论文快速帧间编码翻译 题目:An Effective CU Size Decision Method for HEVC Encoders
  • 曾经有在读研究生问我有关帧间编码快速判定算法,因为他(她)目前的任务主要是为帧间编码或者帧内编码提出一种实用实时的快速算法。对于实时编码软件(或者硬件)而言包括X264,T264在内为了达快速的效果,以达到...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,085
精华内容 434
关键字:

帧间编码