<div dir="ltr"><span style="color:rgb(80,0,80)"># HG changeset patch</span><br style="color:rgb(80,0,80)"><span style="color:rgb(80,0,80)"># User Shushuang <</span><a href="mailto:shushang@multicorewareinc.com" target="_blank">shushang@multicorewareinc.com</a><span style="color:rgb(80,0,80)">></span><br style="color:rgb(80,0,80)"><span style="color:rgb(80,0,80)"># Date 1558582124 -28800</span><br style="color:rgb(80,0,80)"><span style="color:rgb(80,0,80)">#      Thu May 23 11:28:44 2019 +0800</span><br style="color:rgb(80,0,80)"><span style="color:rgb(80,0,80)"># Node ID 220cdb4328a1e2c7419546b50c4d07</span><span style="color:rgb(80,0,80)">e652ae1537</span><br style="color:rgb(80,0,80)"><span style="color:rgb(80,0,80)"># Parent  3f4fb9a2ac6817c9be4acab5c87746</span><span style="color:rgb(80,0,80)">d405fcffd4</span><br style="color:rgb(80,0,80)"><span style="color:rgb(80,0,80)">Add codes to support field feature</span> <div><br></div><div>Pushed patch to x265 default public repo.</div><div><br></div><div>Thanks & Regards,</div><div>Dinesh <br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, May 23, 2019 at 12:00 PM <<a href="mailto:santhoshini@multicorewareinc.com">santhoshini@multicorewareinc.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"># HG changeset patch<br>
# User Shushuang <<a href="mailto:shushang@multicorewareinc.com" target="_blank">shushang@multicorewareinc.com</a>><br>
# Date 1558582124 -28800<br>
#      Thu May 23 11:28:44 2019 +0800<br>
# Node ID 220cdb4328a1e2c7419546b50c4d07e652ae1537<br>
# Parent  3f4fb9a2ac6817c9be4acab5c87746d405fcffd4<br>
Add codes to support field feature<br>
<br>
diff --git a/doc/reST/cli.rst b/doc/reST/cli.rst<br>
--- a/doc/reST/cli.rst<br>
+++ b/doc/reST/cli.rst<br>
@@ -551,6 +551,10 @@<br>
        This feature can be enabled only in closed GOP structures.<br>
        Default 0 (disabled).<br>
<br>
+.. option:: --field, --no-field<br>
+<br>
+       Enable or disable field coding. Default disabled.<br>
+       <br>
 Profile, Level, Tier<br>
 ====================<br>
<br>
diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt<br>
--- a/source/CMakeLists.txt<br>
+++ b/source/CMakeLists.txt<br>
@@ -29,7 +29,7 @@<br>
 option(STATIC_LINK_CRT "Statically link C runtime for release builds" OFF)<br>
 mark_as_advanced(FPROFILE_USE FPROFILE_GENERATE NATIVE_BUILD)<br>
 # X265_BUILD must be incremented each time the public API is changed<br>
-set(X265_BUILD 174)<br>
+set(X265_BUILD 175)<br>
 configure_file("${PROJECT_SOURCE_DIR}/<a href="http://x265.def.in" rel="noreferrer" target="_blank">x265.def.in</a>"<br>
                "${PROJECT_BINARY_DIR}/x265.def")<br>
 configure_file("${PROJECT_SOURCE_DIR}/<a href="http://x265_config.h.in" rel="noreferrer" target="_blank">x265_config.h.in</a>"<br>
diff --git a/source/common/frame.cpp b/source/common/frame.cpp<br>
--- a/source/common/frame.cpp<br>
+++ b/source/common/frame.cpp<br>
@@ -56,6 +56,7 @@<br>
     m_addOnCtuInfo = NULL;<br>
     m_addOnPrevChange = NULL;<br>
     m_classifyFrame = false;<br>
+    m_fieldNum = 0;<br>
 }<br>
<br>
 bool Frame::create(x265_param *param, float* quantOffsets)<br>
diff --git a/source/common/frame.h b/source/common/frame.h<br>
--- a/source/common/frame.h<br>
+++ b/source/common/frame.h<br>
@@ -129,6 +129,7 @@<br>
     uint32_t*              m_classifyCount;<br>
<br>
     bool                   m_classifyFrame;<br>
+    int                    m_fieldNum;<br>
<br>
     Frame();<br>
<br>
diff --git a/source/common/param.cpp b/source/common/param.cpp<br>
--- a/source/common/param.cpp<br>
+++ b/source/common/param.cpp<br>
@@ -140,6 +140,7 @@<br>
     param->uhdBluray = 0;<br>
     param->bHighTier = 1; //Allow high tier by default<br>
     param->interlaceMode = 0;<br>
+    param->bField = 0;<br>
     param->bAnnexB = 1;<br>
     param->bRepeatHeaders = 0;<br>
     param->bEnableAccessUnitDelimiters = 0;<br>
@@ -1267,6 +1268,7 @@<br>
         OPT("svt-fps-in-vps") x265_log(p, X265_LOG_WARNING, "Option %s is SVT-HEVC Encoder specific; Disabling it here \n", name);<br>
 #endif<br>
         OPT("fades") p->bEnableFades = atobool(value);<br>
+        OPT("field") p->bField = atobool( value );<br>
         else<br>
             return X265_PARAM_BAD_NAME;<br>
     }<br>
@@ -1639,6 +1641,12 @@<br>
         if (param->dolbyProfile == 81)<br>
             CHECK(!(param->masteringDisplayColorVolume), "Dolby Vision profile - 8.1 requires Mastering display color volume information\n");<br>
     }<br>
+<br>
+    if (param->bField && param->interlaceMode)<br>
+    {<br>
+        CHECK( (param->bFrameAdaptive==0), "Adaptive B-frame decision method should be closed for field feature.\n" );<br>
+        // to do<br>
+    }<br>
 #if !X86_64<br>
     CHECK(param->searchMethod == X265_SEA && (param->sourceWidth > 840 || param->sourceHeight > 480),<br>
         "SEA motion search does not support resolutions greater than 480p in 32 bit build");<br>
@@ -2045,6 +2053,7 @@<br>
     BOOL(p->bSingleSeiNal, "single-sei");<br>
     BOOL(p->rc.hevcAq, "hevc-aq");<br>
     BOOL(p->bEnableSvtHevc, "svt");<br>
+    BOOL(p->bField, "field");<br>
     s += sprintf(s, " qp-adaptation-range=%.2f", p->rc.qpAdaptationRange);<br>
 #undef BOOL<br>
     return buf;<br>
@@ -2370,6 +2379,7 @@<br>
     dst->dolbyProfile = src->dolbyProfile;<br>
     dst->bEnableSvtHevc = src->bEnableSvtHevc;<br>
     dst->bEnableFades = src->bEnableFades;<br>
+    dst->bField = src->bField;<br>
<br>
 #ifdef SVT_HEVC<br>
     memcpy(dst->svtHevcParam, src->svtHevcParam, sizeof(EB_H265_ENC_CONFIGURATION));<br>
diff --git a/source/common/slice.h b/source/common/slice.h<br>
--- a/source/common/slice.h<br>
+++ b/source/common/slice.h<br>
@@ -361,6 +361,7 @@<br>
     int         numRefIdxDefault[2];<br>
     int         m_iNumRPSInSPS;<br>
     const x265_param *m_param;<br>
+    int         m_fieldNum;<br>
<br>
     Slice()<br>
     {<br>
@@ -376,6 +377,7 @@<br>
         numRefIdxDefault[1] = 1;<br>
         m_rpsIdx = -1;<br>
         m_chromaQpOffset[0] = m_chromaQpOffset[1] = 0;<br>
+        m_fieldNum = 0;<br>
     }<br>
<br>
     void disableWeights();<br>
diff --git a/source/encoder/dpb.cpp b/source/encoder/dpb.cpp<br>
--- a/source/encoder/dpb.cpp<br>
+++ b/source/encoder/dpb.cpp<br>
@@ -127,6 +127,7 @@<br>
 {<br>
     Slice* slice = newFrame->m_encData->m_slice;<br>
     slice->m_poc = newFrame->m_poc;<br>
+    slice->m_fieldNum = newFrame->m_fieldNum;<br>
<br>
     int pocCurr = slice->m_poc;<br>
     int type = newFrame->m_lowres.sliceType;<br>
diff --git a/source/encoder/encoder.cpp b/source/encoder/encoder.cpp<br>
--- a/source/encoder/encoder.cpp<br>
+++ b/source/encoder/encoder.cpp<br>
@@ -1107,6 +1107,8 @@<br>
         inFrame->m_pts       = pic_in->pts;<br>
         inFrame->m_forceqp   = pic_in->forceqp;<br>
         inFrame->m_param     = (m_reconfigure || m_reconfigureRc) ? m_latestParam : m_param;<br>
+        if (m_param->bField && m_param->interlaceMode)<br>
+            inFrame->m_fieldNum = pic_in->fieldNum;<br>
<br>
         copyUserSEIMessages(inFrame, pic_in);<br>
<br>
diff --git a/source/encoder/frameencoder.cpp b/source/encoder/frameencoder.cpp<br>
--- a/source/encoder/frameencoder.cpp<br>
+++ b/source/encoder/frameencoder.cpp<br>
@@ -686,10 +686,25 @@<br>
<br>
         if (vui->frameFieldInfoPresentFlag)<br>
         {<br>
-            if (m_param->interlaceMode == 2)<br>
-                sei->m_picStruct = (poc & 1) ? 1 /* top */ : 2 /* bottom */;<br>
-            else if (m_param->interlaceMode == 1)<br>
-                sei->m_picStruct = (poc & 1) ? 2 /* bottom */ : 1 /* top */;<br>
+            if (m_param->interlaceMode > 0)<br>
+            {<br>
+                if( m_param->interlaceMode == 2 )<br>
+                {   <br>
+                    // m_picStruct should be set to 3 or 4 when field feature is enabled<br>
+                    if (m_param->bField)<br>
+                        // 3: Top field, bottom field, in that order; 4: Bottom field, top field, in that order<br>
+                        sei->m_picStruct = (slice->m_fieldNum == 1) ? 4 : 3;<br>
+                    else<br>
+                        sei->m_picStruct = (poc & 1) ? 1 /* top */ : 2 /* bottom */;<br>
+                }     <br>
+                else if (m_param->interlaceMode == 1)<br>
+                {<br>
+                    if (m_param->bField)<br>
+                        sei->m_picStruct = (slice->m_fieldNum == 1) ? 3: 4;<br>
+                    else<br>
+                        sei->m_picStruct = (poc & 1) ? 2 /* bottom */ : 1 /* top */;<br>
+                }<br>
+            }<br>
             else<br>
                 sei->m_picStruct = m_param->pictureStructure;<br>
<br>
diff --git a/source/x265.cpp b/source/x265.cpp<br>
--- a/source/x265.cpp<br>
+++ b/source/x265.cpp<br>
@@ -575,6 +575,15 @@<br>
     info.timebaseNum = param->fpsDenom;<br>
     info.timebaseDenom = param->fpsNum;<br>
<br>
+    if (param->bField && param->interlaceMode)<br>
+    {   // Field FPS<br>
+        param->fpsNum *= 2;<br>
+        // Field height<br>
+        param->sourceHeight = param->sourceHeight >> 1;<br>
+        // Number of fields to encode<br>
+        param->totalFrames *= 2;<br>
+    }<br>
+<br>
     if (api->param_apply_profile(param, profile))<br>
         return true;<br>
<br>
@@ -916,7 +925,8 @@<br>
     bool bDolbyVisionRPU = false;<br>
     uint8_t *rpuPayload = NULL;<br>
     int ret = 0;<br>
-<br>
+    int inputPicNum = 1;<br>
+    x265_picture picField1, picField2;<br>
<br>
     if (!param->bRepeatHeaders && !param->bEnableSvtHevc)<br>
     {<br>
@@ -930,7 +940,16 @@<br>
             cliopt.totalbytes += cliopt.output->writeHeaders(p_nal, nal);<br>
     }<br>
<br>
-    api->picture_init(param, pic_in);<br>
+    if (param->bField && param->interlaceMode)<br>
+    {<br>
+        api->picture_init(param, &picField1);<br>
+        api->picture_init(param, &picField2);<br>
+        // return back the original height of input<br>
+        param->sourceHeight *= 2;<br>
+        api->picture_init(param, pic_in);<br>
+    }<br>
+    else<br>
+        api->picture_init(param, pic_in);<br>
<br>
     if (param->dolbyProfile && cliopt.dolbyVisionRpu)<br>
     {<br>
@@ -952,7 +971,7 @@<br>
     // main encoder loop<br>
     while (pic_in && !b_ctrl_c)<br>
     {<br>
-        pic_orig.poc = inFrameCount;<br>
+        pic_orig.poc = (param->bField && param->interlaceMode) ? inFrameCount * 2 : inFrameCount;<br>
         if (cliopt.qpfile)<br>
         {<br>
             if (!cliopt.parseQPFile(pic_orig))<br>
@@ -980,39 +999,128 @@<br>
             /* Overwrite PTS */<br>
             pic_in->pts = pic_in->poc;<br>
<br>
+            // convert to field<br>
+            if (param->bField && param->interlaceMode)<br>
+            {<br>
+                int height = pic_in->height >> 1;<br>
+                <br>
+                int static bCreated = 0;<br>
+                if (bCreated == 0)<br>
+                {<br>
+                    bCreated = 1;<br>
+                    inputPicNum = 2;<br>
+                    picField1.fieldNum = 1;<br>
+                    picField2.fieldNum = 2;<br>
+<br>
+                    picField1.bitDepth = picField2.bitDepth = pic_in->bitDepth;<br>
+                    picField1.colorSpace = picField2.colorSpace = pic_in->colorSpace;<br>
+                    picField1.height = picField2.height = pic_in->height >> 1;<br>
+                    picField1.framesize = picField2.framesize = pic_in->framesize >> 1;<br>
+<br>
+                    char* field1Buf = X265_MALLOC( char, pic_in->framesize >> 1 );<br>
+                    char* field2Buf = X265_MALLOC( char, pic_in->framesize >> 1 );<br>
+  <br>
+                    int stride = picField1.stride[0] = picField2.stride[0] = pic_in->stride[0];<br>
+                    int framesize = stride * (height >> x265_cli_csps[pic_in->colorSpace].height[0]);<br>
+                    picField1.planes[0] = field1Buf;<br>
+                    picField2.planes[0] = field2Buf;<br>
+                    for (int i = 1; i < x265_cli_csps[pic_in->colorSpace].planes; i++)<br>
+                    {<br>
+                        picField1.planes[i] = field1Buf + framesize;<br>
+                        picField2.planes[i] = field2Buf + framesize;<br>
+<br>
+                        stride = picField1.stride[i] = picField2.stride[i] = pic_in->stride[i];<br>
+                        framesize += (stride * (height >> x265_cli_csps[pic_in->colorSpace].height[i]));<br>
+                    }<br>
+                    assert(framesize  == picField1.framesize);<br>
+                }<br>
+<br>
+                picField1.pts = picField1.poc = pic_in->poc;<br>
+                picField2.pts = picField2.poc = pic_in->poc + 1;<br>
+<br>
+                picField1.userSEI = picField2.userSEI = pic_in->userSEI;<br>
+<br>
+                //if (pic_in->userData)<br>
+                //{<br>
+                //    // Have to handle userData here<br>
+                //}<br>
+<br>
+                if (pic_in->framesize)<br>
+                {<br>
+                    for (int i = 0; i < x265_cli_csps[pic_in->colorSpace].planes; i++)<br>
+                    {<br>
+                        char* srcP1 = (char*)pic_in->planes[i];<br>
+                        char* srcP2 = (char*)pic_in->planes[i] + pic_in->stride[i];<br>
+                        char* p1 = (char*)picField1.planes[i];<br>
+                        char* p2 = (char*)picField2.planes[i];<br>
+<br>
+                        int stride = picField1.stride[i];<br>
+<br>
+                        for (int y = 0; y < (height >> x265_cli_csps[pic_in->colorSpace].height[i]); y++)<br>
+                        {<br>
+                            memcpy(p1, srcP1, stride);<br>
+                            memcpy(p2, srcP2, stride);<br>
+                            srcP1 += 2*stride;<br>
+                            srcP2 += 2*stride;<br>
+                            p1 += stride;<br>
+                            p2 += stride;<br>
+                        }<br>
+                    }<br>
+                }<br>
+            }<br>
+<br>
             if (bDolbyVisionRPU)<br>
             {<br>
-                if (rpuParser(pic_in, cliopt.dolbyVisionRpu) > 0)<br>
-                    goto fail;<br>
+                if (param->bField && param->interlaceMode)<br>
+                {<br>
+                    if (rpuParser(&picField1, cliopt.dolbyVisionRpu) > 0)<br>
+                        goto fail;<br>
+                    if (rpuParser(&picField2, cliopt.dolbyVisionRpu) > 0)<br>
+                        goto fail;<br>
+                }<br>
+                else<br>
+                {<br>
+                    if (rpuParser(pic_in, cliopt.dolbyVisionRpu) > 0)<br>
+                        goto fail;<br>
+                }<br>
             }<br>
         }<br>
-        int numEncoded = api->encoder_encode(encoder, &p_nal, &nal, pic_in, pic_recon);<br>
-        if (numEncoded < 0)<br>
-        {<br>
-            b_ctrl_c = 1;<br>
-            ret = 4;<br>
-            break;<br>
+                <br>
+        for (int inputNum = 0; inputNum < inputPicNum; inputNum++)<br>
+        {  <br>
+            x265_picture *picInput = NULL;<br>
+            if (inputPicNum == 2)<br>
+                picInput = pic_in ? (inputNum ? &picField2 : &picField1) : NULL;<br>
+            else<br>
+                picInput = pic_in;<br>
+<br>
+            int numEncoded = api->encoder_encode( encoder, &p_nal, &nal, picInput, pic_recon );<br>
+            if( numEncoded < 0 )<br>
+            {<br>
+                b_ctrl_c = 1;<br>
+                ret = 4;<br>
+                break;<br>
+            }<br>
+<br>
+            if (reconPlay && numEncoded)<br>
+                reconPlay->writePicture(*pic_recon);<br>
+<br>
+            outFrameCount += numEncoded;<br>
+<br>
+            if (numEncoded && pic_recon && cliopt.recon)<br>
+                cliopt.recon->writePicture(pic_out);<br>
+            if (nal)<br>
+            {<br>
+                cliopt.totalbytes += cliopt.output->writeFrame(p_nal, nal, pic_out);<br>
+                if (pts_queue)<br>
+                {<br>
+                    pts_queue->push(-pic_out.pts);<br>
+                    if (pts_queue->size() > 2)<br>
+                        pts_queue->pop();<br>
+                }<br>
+            }<br>
+            cliopt.printStatus( outFrameCount );<br>
         }<br>
-<br>
-        if (reconPlay && numEncoded)<br>
-            reconPlay->writePicture(*pic_recon);<br>
-<br>
-        outFrameCount += numEncoded;<br>
-<br>
-        if (numEncoded && pic_recon && cliopt.recon)<br>
-            cliopt.recon->writePicture(pic_out);<br>
-        if (nal)<br>
-        {<br>
-            cliopt.totalbytes += cliopt.output->writeFrame(p_nal, nal, pic_out);<br>
-            if (pts_queue)<br>
-            {<br>
-                pts_queue->push(-pic_out.pts);<br>
-                if (pts_queue->size() > 2)<br>
-                    pts_queue->pop();<br>
-            }<br>
-        }<br>
-<br>
-        cliopt.printStatus(outFrameCount);<br>
     }<br>
<br>
     /* Flush the encoder */<br>
diff --git a/source/x265.h b/source/x265.h<br>
--- a/source/x265.h<br>
+++ b/source/x265.h<br>
@@ -464,6 +464,8 @@<br>
<br>
     //Dolby Vision RPU metadata<br>
     x265_dolby_vision_rpu rpu;<br>
+ <br>
+    int fieldNum;<br>
 } x265_picture;<br>
<br>
 typedef enum<br>
@@ -1775,6 +1777,9 @@<br>
     /* Detect fade-in regions. Enforces I-slice for the brightest point.<br>
        Re-init RC history at that point in ABR mode. Default is disabled. */<br>
     int       bEnableFades;<br>
+<br>
+    /* Enable field coding */<br>
+    int bField;<br>
 } x265_param;<br>
 /* x265_param_alloc:<br>
  *  Allocates an x265_param instance. The returned param structure is not<br>
diff --git a/source/x265cli.h b/source/x265cli.h<br>
--- a/source/x265cli.h<br>
+++ b/source/x265cli.h<br>
@@ -73,6 +73,8 @@<br>
     { "input-csp",      required_argument, NULL, 0 },<br>
     { "interlace",      required_argument, NULL, 0 },<br>
     { "no-interlace",         no_argument, NULL, 0 },<br>
+    { "field",                no_argument, NULL, 0 },<br>
+    { "no-field",             no_argument, NULL, 0 },<br>
     { "fps",            required_argument, NULL, 0 },<br>
     { "seek",           required_argument, NULL, 0 },<br>
     { "frame-skip",     required_argument, NULL, 0 },<br>
@@ -391,6 +393,7 @@<br>
     H0("-f/--frames <integer>            Maximum number of frames to encode. Default all\n");<br>
     H0("   --seek <integer>              First frame to encode\n");<br>
     H1("   --[no-]interlace <bff|tff>    Indicate input pictures are interlace fields in temporal order. Default progressive\n");<br>
+    H0("   --[no-]field                  Enable or disable field coding. Default %s\n", OPT( param->bField));<br>
     H1("   --dither                      Enable dither if downscaling to 8 bit pixels. Default disabled\n");<br>
     H0("   --[no-]copy-pic               Copy buffers of input picture in frame. Default %s\n", OPT(param->bCopyPicToFrame));<br>
     H0("\nQuality reporting metrics:\n");<br>
_______________________________________________<br>
x265-devel mailing list<br>
<a href="mailto:x265-devel@videolan.org" target="_blank">x265-devel@videolan.org</a><br>
<a href="https://mailman.videolan.org/listinfo/x265-devel" rel="noreferrer" target="_blank">https://mailman.videolan.org/listinfo/x265-devel</a><br>
</blockquote></div>