文档章节

x264 x264_slicetype_analyse 函数分析

貌似高手
 貌似高手
发布于 2017/05/01 11:52
字数 2005
阅读 40
收藏 0

 x264_slicetype_annlyse 方法是确定待编码slice在率失真限制下slicetype 的选择:

       1,已经确定slicetype 的最近的一个非Bslice为参照帧和待编码的slices组成一个slices 数

作为分析slicestype 的基础数据结构.

       2,针对qp初始化对应的各种cost table https://my.oschina.net/u/269082/blog/886661

       3,check 是否是一个gop 的开始(需要插入IDR) 或者是否视频内容有场景切换没有向前参考的价值(需要插入Islice),此时只检查一个none_B 之后的第一个未确定类型的帧.注意GOP的最后一个帧一定要是P帧(B帧的话需要下一个GOP的帧做p1参考帧,场景都切换了做参考帧没有意义)

                         4,如果不是Islice 则具体计算分别是P,B片时的cost.

                            以X264_B_ADAPT_FAST为例计算第i帧是P帧即P_OR_I(last_none_B_slice)P(i)P(i+1)的代价,以及第i帧是B帧即P_OR_I(last_none_B_slice)B(i)P(i+1)的代价 来确定当前slice 的类型是选择P还是选择B具体参见后续x264_slicetype_frame_cost函数:

   int cost2p1 = x264_slicetype_frame_cost( h, &a, frames, last_nonb+0, j+1, j+1, 1 ); //last_nonb+0 为p0参考帧,j+1 为P 帧的代价

        int cost1b1 = x264_slicetype_frame_cost( h, &a, frames, last_nonb+0, j+1, j+0, 0 );// last_nonb+0为p0参考帧,j为B帧j+1为P帧作为p1参考的代价

        int cost1p0 = x264_slicetype_frame_cost( h, &a, frames, last_nonb+0, j+0, j+0, 0 ); //ast_nonb+0为p0参考,j为P帧的代价

        int cost2p0 = x264_slicetype_frame_cost( h, &a, frames, last_nonb+1, j+1, j+1, 0 );//ast_nonb+1为p0参考,j+1为P帧的代价

      选定第j帧为P 还是为 B的标准如下last_nonb+0,j,j+1 三帧确定第j帧的类型:cost(P,P,P) < cost(P,B,P)?P:B

1639                      if( cost1p0 + cost2p0 < cost1b1 + cost2p1 )
1640                      {// cost(P,P,P) < cost(p,b,p)?P:B 
1641                          frames[j]->i_type = X264_TYPE_P;
1642                          continue;
1643                      }
1644                      frames[j]->i_type = X264_TYPE_B;
1645                      continue;

       5, check 是否超过最大的连续Bslice 限制,如果超过最大连续Bslices 限制则下一片的类型为改为P帧(避免量化误差在时间上的蔓延)

    6,猜测:检查minigop 已经确定的连续B帧中是不是有场景切换,如果有则把B帧换成P帧编码//TODO fixed me.

    7,如果有具体RC算法,需要遵循具体的RC 算法限制,微调类型选择,详见VBV 算法分析.

1770      if( vbv_lookahead )
1771          x264_vbv_lookahead( h, &a, frames, num_frames, keyframe );

 

整个方法的源代码如下/x264/encoder/slicetype.c

void x264_slicetype_analyse( x264_t *h, int intra_minigop )
1478  {
1479      x264_mb_analysis_t a;
1480      x264_frame_t *frames[X264_LOOKAHEAD_MAX+3] = { NULL, };
1481      int num_frames, orig_num_frames, keyint_limit, framecnt;
1482      int i_mb_count = NUM_MBS;
1483      int i_max_search = X264_MIN( h->lookahead->next.i_size, X264_LOOKAHEAD_MAX );
1484      int vbv_lookahead = h->param.rc.i_vbv_buffer_size && h->param.rc.i_lookahead;
1485      /* For determinism we should limit the search to the number of frames lookahead has for sure
1486       * in h->lookahead->next.list buffer, except at the end of stream.
1487       * For normal calls with (intra_minigop == 0) that is h->lookahead->i_slicetype_length + 1 frames.
1488       * And for I-frame calls (intra_minigop != 0) we already removed intra_minigop frames from there. */
1489      if( h->param.b_deterministic )
1490          i_max_search = X264_MIN( i_max_search, h->lookahead->i_slicetype_length + 1 - intra_minigop );
1491      int keyframe = !!intra_minigop;
1492  
1493      assert( h->frames.b_have_lowres );
1494  
1495      if( !h->lookahead->last_nonb )
1496          return;

1

1497      frames[0] = h->lookahead->last_nonb;
1498      for( framecnt = 0; framecnt < i_max_search; framecnt++ )
1499          frames[framecnt+1] = h->lookahead->next.list[framecnt];
1500  

2

1501      x264_lowres_context_init( h, &a );
1502  
1503      if( !framecnt )
1504      {
1505          if( h->param.rc.b_mb_tree )
1506              x264_macroblock_tree( h, &a, frames, 0, keyframe );
1507          return;
1508      }
1509  
1510      keyint_limit = h->param.i_keyint_max - frames[0]->i_frame + h->lookahead->i_last_keyframe - 1;
1511      orig_num_frames = num_frames = h->param.b_intra_refresh ? framecnt : X264_MIN( framecnt, keyint_limit );
1512  
1513      /* This is important psy-wise: if we have a non-scenecut keyframe,
1514       * there will be significant visual artifacts if the frames just before
1515       * go down in quality due to being referenced less, despite it being
1516       * more RD-optimal. */
1517      if( (h->param.analyse.b_psy && h->param.rc.b_mb_tree) || vbv_lookahead )
1518          num_frames = framecnt;
1519      else if( h->param.b_open_gop && num_frames < framecnt )
1520          num_frames++;
1521      else if( num_frames == 0 )
1522      {
1523          frames[1]->i_type = X264_TYPE_I;
1524          return;
1525      }
1526  

3

1527      if( IS_X264_TYPE_AUTO_OR_I( frames[1]->i_type ) &&
1528          h->param.i_scenecut_threshold && scenecut( h, &a, frames, 0, 1, 1, orig_num_frames, i_max_search ) )
1529      {
1530          if( frames[1]->i_type == X264_TYPE_AUTO )
1531              frames[1]->i_type = X264_TYPE_I;
1532          return;
1533      }
1534  
1535  #if HAVE_OPENCL
1536      x264_opencl_slicetype_prep( h, frames, num_frames, a.i_lambda );
1537  #endif
1538  
1539      /* Replace forced keyframes with I/IDR-frames */
1540      for( int j = 1; j <= num_frames; j++ )
1541      {
1542          if( frames[j]->i_type == X264_TYPE_KEYFRAME )
1543              frames[j]->i_type = h->param.b_open_gop ? X264_TYPE_I : X264_TYPE_IDR;
1544      }
1545  
1546      /* Close GOP at IDR-frames */
1547      for( int j = 2; j <= num_frames; j++ )
1548      {
1549          if( frames[j]->i_type == X264_TYPE_IDR && IS_X264_TYPE_AUTO_OR_B( frames[j-1]->i_type ) )
1550              frames[j-1]->i_type = X264_TYPE_P;
1551      }
1552  
1553      int num_analysed_frames = num_frames;
1554      int reset_start;
1555  
1556      if( h->param.i_bframe )
1557      {
1558          if( h->param.i_bframe_adaptive == X264_B_ADAPT_TRELLIS )
1559          {
1560              if( num_frames > 1 )
1561              {
1562                  char best_paths[X264_BFRAME_MAX+1][X264_LOOKAHEAD_MAX+1] = {"","P"};
1563                  int best_path_index = num_frames % (X264_BFRAME_MAX+1);
1564  
1565                  /* Perform the frametype analysis. */
1566                  for( int j = 2; j <= num_frames; j++ )
1567                      x264_slicetype_path( h, &a, frames, j, best_paths );
1568  
1569                  /* Load the results of the analysis into the frame types. */
1570                  for( int j = 1; j < num_frames; j++ )
1571                  {
1572                      if( best_paths[best_path_index][j-1] != 'B' )
1573                      {
1574                          if( IS_X264_TYPE_AUTO_OR_B( frames[j]->i_type ) )
1575                              frames[j]->i_type = X264_TYPE_P;
1576                      }
1577                      else
1578                      {
1579                          if( frames[j]->i_type == X264_TYPE_AUTO )
1580                              frames[j]->i_type = X264_TYPE_B;
1581                      }
1582                  }
1583              }
1584          }

4

1585          else if( h->param.i_bframe_adaptive == X264_B_ADAPT_FAST )
1586          {
1587              int last_nonb = 0;
1588              int num_bframes = h->param.i_bframe;
1589              for( int j = 1; j < num_frames; j++ )
1590              {
1591                  if( j-1 > 0 && IS_X264_TYPE_B( frames[j-1]->i_type ) )
1592                      num_bframes--;
1593                  else
1594                  {
1595                      last_nonb = j-1;
1596                      num_bframes = h->param.i_bframe;
1597                  }
1598                  if( !num_bframes )
1599                  {
1600                      if( IS_X264_TYPE_AUTO_OR_B( frames[j]->i_type ) )
1601                          frames[j]->i_type = X264_TYPE_P;
1602                      continue;
1603                  }
1604  
1605                  if( frames[j]->i_type != X264_TYPE_AUTO )
1606                      continue;
1607  
1608                  if( IS_X264_TYPE_B( frames[j+1]->i_type ) )
1609                  {
1610                      frames[j]->i_type = X264_TYPE_P;
1611                      continue;
1612                  }
1613  
1614                  if( j - last_nonb <= 1 )
1615                  {
1616                      int cost2p1 = x264_slicetype_frame_cost( h, &a, frames, last_nonb+0, j+1, j+1, 1 );
1617                      if( frames[j+1]->i_intra_mbs[2] > i_mb_count / 2 )
1618                      {
1619                          frames[j]->i_type = X264_TYPE_P;
1620                          continue;
1621                      }
1622  
1623  #if HAVE_OPENCL
1624                      if( h->param.b_opencl )
1625                      {
1626                          int b_work_done = 0;
1627                          b_work_done |= x264_opencl_precalculate_frame_cost(h, frames, a.i_lambda, last_nonb+0, j+1, j+0 );
1628                          b_work_done |= x264_opencl_precalculate_frame_cost(h, frames, a.i_lambda, last_nonb+0, j+0, j+0 );
1629                          b_work_done |= x264_opencl_precalculate_frame_cost(h, frames, a.i_lambda, last_nonb+1, j+1, j+1 );
1630                          if( b_work_done )
1631                              x264_opencl_flush( h );
1632                      }
1633  #endif
1634  
1635                      int cost1b1 = x264_slicetype_frame_cost( h, &a, frames, last_nonb+0, j+1, j+0, 0 );
1636                      int cost1p0 = x264_slicetype_frame_cost( h, &a, frames, last_nonb+0, j+0, j+0, 0 );
1637                      int cost2p0 = x264_slicetype_frame_cost( h, &a, frames, last_nonb+1, j+1, j+1, 0 );
1638  
1639                      if( cost1p0 + cost2p0 < cost1b1 + cost2p1 )
1640                      {
1641                          frames[j]->i_type = X264_TYPE_P;
1642                          continue;
1643                      }
1644                      frames[j]->i_type = X264_TYPE_B;
1645                      continue;
1646                  }
1647  
1648                  // arbitrary and untuned
1649                  #define INTER_THRESH 300
1650                  #define P_SENS_BIAS (50 - h->param.i_bframe_bias)
1651  
1652                  int pthresh = X264_MAX(INTER_THRESH - P_SENS_BIAS * (j-last_nonb-1), INTER_THRESH/10);
1653                  int pcost = x264_slicetype_frame_cost( h, &a, frames, last_nonb, j+1, j+1, 1 );
1654                  if( pcost > pthresh*i_mb_count || frames[j+1]->i_intra_mbs[j-last_nonb+1] > i_mb_count/3 )
1655                      frames[j]->i_type = X264_TYPE_P;
1656                  else
1657                      frames[j]->i_type = X264_TYPE_B;
1658              }
1659          }
1660          else
1661          {
1662              int num_bframes = h->param.i_bframe;
1663              for( int j = 1; j < num_frames; j++ )
1664              {
1665                  if( !num_bframes )
1666                  {
1667                      if( IS_X264_TYPE_AUTO_OR_B( frames[j]->i_type ) )
1668                          frames[j]->i_type = X264_TYPE_P;
1669                  }
1670                  else if( frames[j]->i_type == X264_TYPE_AUTO )
1671                  {
1672                      if( IS_X264_TYPE_B( frames[j+1]->i_type ) )
1673                          frames[j]->i_type = X264_TYPE_P;
1674                      else
1675                          frames[j]->i_type = X264_TYPE_B;
1676                  }
1677                  if( IS_X264_TYPE_B( frames[j]->i_type ) )
1678                      num_bframes--;
1679                  else
1680                      num_bframes = h->param.i_bframe;
1681              }
1682          }

1683          if( IS_X264_TYPE_AUTO_OR_B( frames[num_frames]->i_type ) )
1684              frames[num_frames]->i_type = X264_TYPE_P;
1685  
1686          int num_bframes = 0;
1687          while( num_bframes < num_frames && IS_X264_TYPE_B( frames[num_bframes+1]->i_type ) )
1688              num_bframes++;
1689 

 
1690          /* Check scenecut on the first minigop. */
1691          for( int j = 1; j < num_bframes+1; j++ )
1692          {
1693              if( frames[j]->i_forced_type == X264_TYPE_AUTO && IS_X264_TYPE_AUTO_OR_I( frames[j+1]->i_forced_type ) &&
1694                  h->param.i_scenecut_threshold && scenecut( h, &a, frames, j, j+1, 0, orig_num_frames, i_max_search ) )
1695              {
1696                  frames[j]->i_type = X264_TYPE_P;
1697                  num_analysed_frames = j;
1698                  break;
1699              }
1700          }
1701  
1702          reset_start = keyframe ? 1 : X264_MIN( num_bframes+2, num_analysed_frames+1 );
1703      }
1704      else
1705      {
1706          for( int j = 1; j <= num_frames; j++ )
1707              if( IS_X264_TYPE_AUTO_OR_B( frames[j]->i_type ) )
1708                  frames[j]->i_type = X264_TYPE_P;
1709          reset_start = !keyframe + 1;
1710      }
1711  
1712      /* Perform the actual macroblock tree analysis.
1713       * Don't go farther than the maximum keyframe interval; this helps in short GOPs. */
1714      if( h->param.rc.b_mb_tree )
1715          x264_macroblock_tree( h, &a, frames, X264_MIN(num_frames, h->param.i_keyint_max), keyframe );
1716  
1717      /* Enforce keyframe limit. */
1718      if( !h->param.b_intra_refresh )
1719      {
1720          int last_keyframe = h->lookahead->i_last_keyframe;
1721          int last_possible = 0;
1722          for( int j = 1; j <= num_frames; j++ )
1723          {
1724              x264_frame_t *frm = frames[j];
1725              int keyframe_dist = frm->i_frame - last_keyframe;
1726  
1727              if( IS_X264_TYPE_AUTO_OR_I( frm->i_forced_type ) )
1728              {
1729                  if( h->param.b_open_gop || !IS_X264_TYPE_B( frames[j-1]->i_forced_type ) )
1730                      last_possible = j;
1731              }
1732              if( keyframe_dist >= h->param.i_keyint_max )
1733              {
1734                  if( last_possible != 0 && last_possible != j )
1735                  {
1736                      j = last_possible;
1737                      frm = frames[j];
1738                      keyframe_dist = frm->i_frame - last_keyframe;
1739                  }
1740                  last_possible = 0;
1741                  if( frm->i_type != X264_TYPE_IDR )
1742                      frm->i_type = h->param.b_open_gop ? X264_TYPE_I : X264_TYPE_IDR;
1743              }
1744              if( frm->i_type == X264_TYPE_I && keyframe_dist >= h->param.i_keyint_min )
1745              {
1746                  if( h->param.b_open_gop )
1747                  {
1748                      last_keyframe = frm->i_frame;
1749                      if( h->param.b_bluray_compat )
1750                      {
1751                          // Use bluray order
1752                          int bframes = 0;
1753                          while( bframes < j-1 && IS_X264_TYPE_B( frames[j-1-bframes]->i_type ) )
1754                              bframes++;
1755                          last_keyframe -= bframes;
1756                      }
1757                  }
1758                  else if( frm->i_forced_type != X264_TYPE_I )
1759                      frm->i_type = X264_TYPE_IDR;
1760              }
1761              if( frm->i_type == X264_TYPE_IDR )
1762              {
1763                  last_keyframe = frm->i_frame;
1764                  if( j > 1 && IS_X264_TYPE_B( frames[j-1]->i_type ) )
1765                      frames[j-1]->i_type = X264_TYPE_P;
1766              }
1767          }
1768      }
1769

  
1770      if( vbv_lookahead )
1771          x264_vbv_lookahead( h, &a, frames, num_frames, keyframe );
1772  
1773      /* Restore frametypes for all frames that haven't actually been decided yet. */
1774      for( int j = reset_start; j <= num_frames; j++ )
1775          frames[j]->i_type = frames[j]->i_forced_type;
1776  
1777  #if HAVE_OPENCL
1778      x264_opencl_slicetype_end( h );
1779  #endif
1780  }

 

 

© 著作权归作者所有

共有 人打赏支持
貌似高手
粉丝 9
博文 75
码字总数 63031
作品 0
海淀
高级程序员
私信 提问
x264源代码简单分析:编码器主干部分-2

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/leixiaohua1020/article/details/45719905 ===================================================== H.264源代......

雷霄骅
2015/05/14
0
0
音视频技术--H.264代码与标准如何对应

总是有人说自己把代码和标准对应不起来。其实是因为你要么不知道标准各个章节讲的什么,要么不知道代码中各个函数的功能,或者两者都不知道。今天再以 X264 的帧内编码为例让大家体会一下读代...

技术小阿哥
2017/11/27
0
0
x264源代码简单分析:宏块分析(Analysis)部分-帧内宏块(Intra)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/leixiaohua1020/article/details/45917757 ===================================================== H.264源代......

雷霄骅
2015/05/22
0
0
x264源代码简单分析:宏块分析(Analysis)部分-帧间宏块(Inter)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/leixiaohua1020/article/details/45936267 ===================================================== H.264源代......

雷霄骅
2015/05/23
0
0
x264源代码简单分析:编码器主干部分-1

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/leixiaohua1020/article/details/45644367 ===================================================== H.264源代......

雷霄骅
2015/05/11
0
0

没有更多内容

加载失败,请刷新页面

加载更多

zookeeper配置与使用

一.登录官网下载 不要带后缀的,那是公侧版本,下稳定版,比如3.4.9 二.安装与使用 解压后bin里是启动程序 配置文件:在conf下 复制zoo_sample.cfg改名为为zoo.cfg,打开zoo修改文件...

小兵胖胖
20分钟前
1
0
spring源码阅读笔记(一)

ClassPathXmlApplicationContext 与 FileSystemXmlApplicationContext 用了这么久的框架,是时候搞一下源码了,一般最初接触spring 从以下步骤开始 创建一个bean类 并创建 ooxx.xml之类的spr...

NotFound403
44分钟前
2
0
MySQL主从配置

12月14日任务 17.1 MySQL主从介绍 17.2 准备工作 17.3 配置主 17.4 配置从 17.5 测试主从同步 MySQL主从介绍 MySQL主从又叫做Replication、AB复制。简单将就是A/B两个服务器做主从后,在A上写...

robertt15
46分钟前
8
0
我的Linux系统九阴真经

在今天,互联网的迅猛发展,科技技术也日新月异,各种编程技术也如雨后春笋一样,冒出尖来了。各种创业公司也百花齐放百家争鸣,特别是针对服务行业,新型互联网服务行业,共享经济等概念的公...

问题终结者
59分钟前
22
0
Java 使用 gson 对 json 根据 key 键进行排序

引入Google的gson jar <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.8.0</version>......

yh32
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部