您的当前位置:首页>新品 > 正文

FFmpeg XAVC实现/x264实现 应用设置接口参数

来源:CSDN 时间:2022-12-27 10:29:27


(相关资料图)

思路

上一篇文章提到了XAVC的一些背景,以及非每帧固定码率的实现方法。然而如果要实现XAVC中的CBG模式(Constrained Bytes per GOP)就必须修改x264源码固定每帧码率。

x264中对松下 AVC Intra Class 有支持,AVC Intra Class 100/200是定义在HD下的与XAVC类似的标准。因此可以通过扩展这部分的代码功能来实现4K XAVC Intra Class 300/480。

应用设置接口参数 avcintra-class=300 avcintra-flavor=sony进行编码标准的设置。

代码

diff --git a/encoder/encoder.c b/encoder/encoder.cindex 074c4a5c..5fb84fcd 100644--- a/encoder/encoder.c+++ b/encoder/encoder.c@@ -678,9 +678,13 @@ static int validate_parameters( x264_t *h, int b_open )             return -1;         } -        int type = h->param.i_avcintra_class == 200 ? 2 :+        int type = h->param.i_avcintra_class == 480 ? 4 :+                   h->param.i_avcintra_class == 300 ? 3 :+                   h->param.i_avcintra_class == 200 ? 2 :                    h->param.i_avcintra_class == 100 ? 1 :                    h->param.i_avcintra_class == 50 ? 0 : -1;+        int xavc =  (h->param.i_avcintra_flavor == X264_AVCINTRA_FLAVOR_SONY);+         if( type < 0 )         {             x264_log( h, X264_LOG_ERROR, "Invalid AVC-Intra class\n" );@@ -733,21 +737,101 @@ static int validate_parameters( x264_t *h, int b_open )               { 24000, 1001, 0, 7444, x264_cqm_avci100_1080_4ic, x264_cqm_avci100_1080p_8iy }}}         }; -        int res = -1;-        if( i_csp >= X264_CSP_I420 && i_csp < X264_CSP_I422 && !type )+        /* [50/100/200/300/480][720p/1440x1080/1080p/2048x1080/4K][fps] */+        static const struct         {-            if(      h->param.i_width == 1440 && h->param.i_height == 1080 ) res =  1;-            else if( h->param.i_width ==  960 && h->param.i_height ==  720 ) res =  0;-        }-        else if( i_csp >= X264_CSP_I422 && i_csp < X264_CSP_I444 && type )+            uint16_t fps_num;+            uint16_t fps_den;+            uint8_t interlaced;+            uint16_t frame_size;+            const uint8_t *cqm_4ic;+            const uint8_t *cqm_8iy;+        } xavcintra_lut[5][5][7] =          {-            if(      h->param.i_width == 1920 && h->param.i_height == 1080 ) res =  1;-            else if( h->param.i_width == 1280 && h->param.i_height ==  720 ) res =  0;-        }-        else+            {{{}},+              {{   50,    1, 1, 2120, x264_cqm_avci50_4ic, x264_cqm_avci50_p_8iy },+              { 60000, 1001, 1, 1744, x264_cqm_avci50_4ic, x264_cqm_avci50_p_8iy },+              { 24000, 1001, 0, 1744, x264_cqm_avci50_4ic, x264_cqm_avci50_p_8iy },+              {    25,    1, 0, 2120, x264_cqm_avci50_4ic, x264_cqm_avci50_p_8iy },+              { 30000, 1001, 0, 1744, x264_cqm_avci50_4ic, x264_cqm_avci50_p_8iy }}},+            {{{ 60000, 1001, 0, 1804, x264_cqm_avci100_720p_4ic, x264_cqm_avci100_720p_8iy },+              {    50,    1, 0, 2180, x264_cqm_avci100_720p_4ic, x264_cqm_avci100_720p_8iy }},+             {{}},+             {{    50,    1, 1, 4368, x264_cqm_avci100_1080_4ic, x264_cqm_avci100_1080i_8iy },+              { 60000, 1001, 1, 3616, x264_cqm_avci100_1080_4ic, x264_cqm_avci100_1080i_8iy },+              { 24000, 1001, 0, 3616, x264_cqm_avci100_1080_4ic, x264_cqm_avci100_1080p_8iy },+              {    25,    1, 0, 4368, x264_cqm_avci100_1080_4ic, x264_cqm_avci100_1080p_8iy },+              { 30000, 1001, 0, 3616, x264_cqm_avci100_1080_4ic, x264_cqm_avci100_1080p_8iy },+              {    50,    1, 0, 4368, x264_cqm_avci100_1080_4ic, x264_cqm_avci100_1080p_8iy },+              { 60000, 1001, 0, 3616, x264_cqm_avci100_1080_4ic, x264_cqm_avci100_1080p_8iy }},+             {{ 24000, 1001, 0, 3616, x264_cqm_avci100_1080_4ic, x264_cqm_avci100_1080p_8iy },+              {    24,    1, 0, 3616, x264_cqm_avci100_1080_4ic, x264_cqm_avci100_1080p_8iy },+              {    25,    1, 0, 3616, x264_cqm_avci100_1080_4ic, x264_cqm_avci100_1080p_8iy },+              { 30000, 1001, 0, 3616, x264_cqm_avci100_1080_4ic, x264_cqm_avci100_1080p_8iy },+              {    50,    1, 0, 3616, x264_cqm_avci100_1080_4ic, x264_cqm_avci100_1080p_8iy },+              { 60000, 1001, 0, 3616, x264_cqm_avci100_1080_4ic, x264_cqm_avci100_1080p_8iy }}},+            {{{}},+             {{}},+             {{    50,    1, 1, 8864, x264_cqm_avci100_1080_4ic, x264_cqm_avci100_1080i_8iy },+              { 60000, 1001, 1, 7368, x264_cqm_avci100_1080_4ic, x264_cqm_avci100_1080i_8iy },+              { 24000, 1001, 0, 7368, x264_cqm_avci100_1080_4ic, x264_cqm_avci100_1080p_8iy },+              {    25,    1, 0, 8864, x264_cqm_avci100_1080_4ic, x264_cqm_avci100_1080p_8iy },+              { 30000, 1001, 0, 7368, x264_cqm_avci100_1080_4ic, x264_cqm_avci100_1080p_8iy },+              {    50,    1, 0, 8864, x264_cqm_avci100_1080_4ic, x264_cqm_avci100_1080p_8iy },+              { 60000, 1001, 0, 7368, x264_cqm_avci100_1080_4ic, x264_cqm_avci100_1080p_8iy }}},+            {{{}},+             {{}},+             {{}},+             {{}},+             {{ 24000, 1001, 0, 9768, x264_cqm_avci100_1080_4ic, x264_cqm_avci100_1080p_8iy },+              {    25,    1, 0, 9768, x264_cqm_avci100_1080_4ic, x264_cqm_avci100_1080p_8iy },+              { 30000, 1001, 0, 9768, x264_cqm_avci100_1080_4ic, x264_cqm_avci100_1080p_8iy },+              {    50,    1, 0, 9768, x264_cqm_avci100_1080_4ic, x264_cqm_avci100_1080p_8iy },+              { 60000, 1001, 0, 9768, x264_cqm_avci100_1080_4ic, x264_cqm_avci100_1080p_8iy }}},+            {{{}},+             {{}},+             {{}},+             {{}},+             {{ 24000, 1001, 0,15624, x264_cqm_avci100_1080_4ic, x264_cqm_avci100_1080p_8iy },+              {    25,    1, 0,15624, x264_cqm_avci100_1080_4ic, x264_cqm_avci100_1080p_8iy },+              { 30000, 1001, 0,15624, x264_cqm_avci100_1080_4ic, x264_cqm_avci100_1080p_8iy },+              {    50,    1, 0,15624, x264_cqm_avci100_1080_4ic, x264_cqm_avci100_1080p_8iy },+              { 60000, 1001, 0,15624, x264_cqm_avci100_1080_4ic, x264_cqm_avci100_1080p_8iy }}},+        };++        int res = -1;+        if(xavc)         {-            x264_log( h, X264_LOG_ERROR, "Invalid colorspace for AVC-Intra %d\n", h->param.i_avcintra_class );-            return -1;+            if( i_csp >= X264_CSP_I422 && i_csp < X264_CSP_I444 && type )+            {+                if( h->param.i_width == 1280 && h->param.i_height ==  720 ) res =  0;+                else if(h->param.i_width == 1440 && h->param.i_height == 1080 ) res =  1;+                else if(h->param.i_width == 1920 && h->param.i_height == 1080 ) res =  2;+                else if(h->param.i_width == 2048 && h->param.i_height == 1080 ) res =  3;+                else if(h->param.i_width == 3840 && h->param.i_height == 2160 ) res =  4;+                else if(h->param.i_width == 4096 && h->param.i_height == 2160 ) res =  4;+            }+            else+            {+                x264_log( h, X264_LOG_ERROR, "Invalid colorspace for XAVC-Intra %d\n", h->param.i_avcintra_class );+                return -1;+            }+        } else {+            if( i_csp >= X264_CSP_I420 && i_csp < X264_CSP_I422 && !type )+            {+                if(      h->param.i_width == 1440 && h->param.i_height == 1080 ) res =  1;+                else if( h->param.i_width ==  960 && h->param.i_height ==  720 ) res =  0;+            }+            else if( i_csp >= X264_CSP_I422 && i_csp < X264_CSP_I444 && type )+            {+                if(      h->param.i_width == 1920 && h->param.i_height == 1080 ) res =  1;+                else if( h->param.i_width == 1280 && h->param.i_height ==  720 ) res =  0;+            }+            else+            {+                x264_log( h, X264_LOG_ERROR, "Invalid colorspace for AVC-Intra %d\n", h->param.i_avcintra_class );+                return -1;+            }         }          if( res < 0 )@@ -774,11 +858,20 @@ static int validate_parameters( x264_t *h, int b_open )         x264_reduce_fraction( &fps_num, &fps_den );         for( i = 0; i < 7; i++ )         {-            if( avcintra_lut[type][res][i].fps_num == fps_num &&-                avcintra_lut[type][res][i].fps_den == fps_den &&-                avcintra_lut[type][res][i].interlaced == PARAM_INTERLACED )-            {-                break;+            if (xavc) {+                if( xavcintra_lut[type][res][i].fps_num == fps_num &&+                    xavcintra_lut[type][res][i].fps_den == fps_den &&+                    xavcintra_lut[type][res][i].interlaced == PARAM_INTERLACED )+                {+                    break;+                }+            } else {+                if( avcintra_lut[type][res][i].fps_num == fps_num &&+                    avcintra_lut[type][res][i].fps_den == fps_den &&+                    avcintra_lut[type][res][i].interlaced == PARAM_INTERLACED )+                {+                    break;+                }             }         }         if( i == 7 )@@ -806,7 +899,7 @@ static int validate_parameters( x264_t *h, int b_open )         h->param.analyse.intra = X264_ANALYSE_I8x8;         h->param.analyse.i_chroma_qp_offset = res && type ? 3 : 4;         h->param.b_cabac = !type;-        h->param.rc.i_vbv_buffer_size = avcintra_lut[type][res][i].frame_size;+        h->param.rc.i_vbv_buffer_size = xavc ? xavcintra_lut[type][res][i].frame_size : avcintra_lut[type][res][i].frame_size;         h->param.rc.i_vbv_max_bitrate =         h->param.rc.i_bitrate = h->param.rc.i_vbv_buffer_size * fps_num / fps_den;         h->param.rc.i_rc_method = X264_RC_ABR;@@ -814,8 +907,13 @@ static int validate_parameters( x264_t *h, int b_open )         h->param.rc.b_filler = 1;         h->param.i_cqm_preset = X264_CQM_CUSTOM;         memcpy( h->param.cqm_4iy, x264_cqm_jvt4i, sizeof(h->param.cqm_4iy) );-        memcpy( h->param.cqm_4ic, avcintra_lut[type][res][i].cqm_4ic, sizeof(h->param.cqm_4ic) );-        memcpy( h->param.cqm_8iy, avcintra_lut[type][res][i].cqm_8iy, sizeof(h->param.cqm_8iy) );+        if (xavc) {+            memcpy( h->param.cqm_4ic, xavcintra_lut[type][res][i].cqm_4ic, sizeof(h->param.cqm_4ic) );+            memcpy( h->param.cqm_8iy, xavcintra_lut[type][res][i].cqm_8iy, sizeof(h->param.cqm_8iy) );+        } else {+            memcpy( h->param.cqm_4ic, avcintra_lut[type][res][i].cqm_4ic, sizeof(h->param.cqm_4ic) );+            memcpy( h->param.cqm_8iy, avcintra_lut[type][res][i].cqm_8iy, sizeof(h->param.cqm_8iy) );+        }          /* Sony XAVC flavor much more simple */         if( h->param.i_avcintra_flavor == X264_AVCINTRA_FLAVOR_SONY )

运行

./ffmpeg  -i "/home/lyh/4K/Customer/Sobey/2018080927test_video/10M_SR012CA3.mp4" -r 50 -pix_fmt yuv422p10le -c:v libx264 -avcintra-class 300 -x264opts avcintra-class=300 -x264opts avcintra-flavor=sony 1.mxf

标签:

最新新闻:

新闻放送
Top