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 }
5
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
6
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
7
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 }