<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Jul 28, 2015 at 1:07 PM,  <span dir="ltr"><<a href="mailto:aarthi@multicorewareinc.com" target="_blank">aarthi@multicorewareinc.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"># HG changeset patch<br>
# User Aarthi Thirumalai<br>
# Date 1437505166 -19800<br>
#      Wed Jul 22 00:29:26 2015 +0530<br>
# Node ID 2a901547b3b8ebed95a4580ff4bcbc2582e55437<br>
# Parent  46152345eb6ff261fd90272f7a0712300d6324c0<br>
slicetype: Modify Scenecut algorithm to detect scene transition points<br>
to improve Rate Control.<br>
<br>
identify scene trasitions, fade-ins, fadeouts, sceneCuts and signal the flag bSceneChange<br>
in Lowres structure. This flag will be used by RateControl to adjust the wps during scene cuts.<br>
No changes in sliceType decisions or I frame placement.<br>
<br>
diff -r 46152345eb6f -r 2a901547b3b8 source/common/lowres.cpp<br>
--- a/source/common/lowres.cpp  Mon Jul 20 17:18:54 2015 -0700<br>
+++ b/source/common/lowres.cpp  Wed Jul 22 00:29:26 2015 +0530<br>
@@ -127,6 +127,7 @@<br>
 {<br>
     bLastMiniGopBFrame = false;<br>
     bScenecut = true;  // could be a scene-cut, until ruled out by flash detection<br>
+    bSceneChange = true;<br>
     bKeyframe = false; // Not a keyframe unless identified by lookahead<br>
     frameNum = poc;<br>
     leadingBframes = 0;<br>
diff -r 46152345eb6f -r 2a901547b3b8 source/common/lowres.h<br>
--- a/source/common/lowres.h    Mon Jul 20 17:18:54 2015 -0700<br>
+++ b/source/common/lowres.h    Wed Jul 22 00:29:26 2015 +0530<br>
@@ -115,6 +115,7 @@<br>
     int    leadingBframes;   // number of leading B frames for P or I<br>
<br>
     bool   bScenecut;        // Set to false if the frame cannot possibly be part of a real scenecut.<br>
+    bool   bSceneChange;<br>
     bool   bKeyframe;<br>
     bool   bLastMiniGopBFrame;<br>
<br>
diff -r 46152345eb6f -r 2a901547b3b8 source/encoder/slicetype.cpp<br>
--- a/source/encoder/slicetype.cpp      Mon Jul 20 17:18:54 2015 -0700<br>
+++ b/source/encoder/slicetype.cpp      Wed Jul 22 00:29:26 2015 +0530<br>
@@ -462,6 +462,7 @@<br>
     m_pool  = pool;<br>
<br>
     m_lastNonB = NULL;<br>
+    m_isSceneTransition = false;<br>
     m_scratch  = NULL;<br>
     m_tld      = NULL;<br>
     m_filled   = false;<br>
@@ -881,6 +882,8 @@<br>
<br>
         if (/* (!param->intraRefresh || frm.frameNum == 0) && */ frm.frameNum - m_lastKeyframe >= m_param->keyframeMax)<br>
         {<br>
+            if (frm.sliceType != X265_TYPE_I)<br>
+                frm.bSceneChange = false;<br></blockquote><div><br></div><div>We're still conflating scene changes and scene transitions with slicetype decisions. <br> <br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
             if (frm.sliceType == X265_TYPE_AUTO || frm.sliceType == X265_TYPE_I)<br>
                 frm.sliceType = m_param->bOpenGOP && m_lastKeyframe >= 0 ? X265_TYPE_I : X265_TYPE_IDR;<br>
             bool warn = frm.sliceType != X265_TYPE_IDR;<br>
@@ -1375,6 +1378,9 @@<br>
 bool Lookahead::scenecut(Lowres **frames, int p0, int p1, bool bRealScenecut, int numFrames, int maxSearch)<br>
 {<br>
     /* Only do analysis during a normal scenecut check. */<br>
+    int64_t avgSatdCost = 0;<br>
+    int cnt = 0;<br>
+<br>
     if (bRealScenecut && m_param->bframes)<br>
     {<br>
         int origmaxp1 = p0 + 1;<br>
@@ -1392,11 +1398,45 @@<br>
         for (int cp1 = p1; cp1 <= maxp1; cp1++)<br>
         {<br>
             if (!scenecutInternal(frames, p0, cp1, false))<br>
+            {<br>
                 /* Any frame in between p0 and cur_p1 cannot be a real scenecut. */<br>
                 for (int i = cp1; i > p0; i--)<br>
+                {<br>
                     frames[i]->bScenecut = false;<br>
+                    frames[i]->bSceneChange = false;<br>
+                }<br>
+            }<br>
+            else if (!scenecutInternal(frames,cp1 - 1, cp1, false))<br>
+            {<br>
+                /* Prevent false flashes. */<br>
+                frames[cp1]->bSceneChange = false;<br>
+            }<br>
+            else<br>
+            {<br>
+                /* compute average satdcost of flashes of scenecuts to confirm<br>
+                 * bwhether a scene transition is possible within the segment. */<br>
+                avgSatdCost += frames[cp1]->costEst[1][0];<br>
+                cnt++;<br>
+            }<br>
         }<br>
-<br>
+        /* Identify possible scene fluctuations by comparing the satd cost of the flashes.<br>
+         * This could denote the beginning or ending of scene transitions.<br>
+         * During a scene transition(fade in/fade outs), if fluctuate remains false,<br>
+         * then the scene had completed its transition or stabilized.<br>
+         */<br>
+        bool fluctuate = false;<br>
+        if (avgSatdCost > 0)<br>
+        {<br>
+            avgSatdCost /= cnt;<br>
+            for (int i= p1 ; i <= maxp1; i++)<br>
+            {<br>
+                if (abs(frames[i]->costEst[1][0] - avgSatdCost)  > 0.1 * avgSatdCost)<br>
+                {<br>
+                    fluctuate = true;<br>
+                    break;<br>
+                }<br>
+            }<br>
+        }<br></blockquote><div>Looks good, the adaptive cost thresholding will hopefully avoid spurious decisions.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
         /* Where A-F are scenes: AAAAABBCCDDEEFFFFFF<br>
          * If each of BB ... EE are shorter than (maxp1-p0), they are<br>
          * detected as flashes and not considered scenecuts.<br>
@@ -1405,8 +1445,25 @@<br>
         for (int cp0 = p0; cp0 <= maxp1; cp0++)<br>
         {<br>
             if (origmaxp1 > maxSearch || (cp0 < maxp1 && scenecutInternal(frames, cp0, maxp1, false)))<br>
+            {<br>
                 /* If cur_p0 is the p0 of a scenecut, it cannot be the p1 of a scenecut. */<br>
                 frames[cp0]->bScenecut = false;<br>
+                /* Check for start of flash sequence for a new scene transition segment. */<br>
+                bool isSceneChangeNext = scenecutInternal(frames, cp0, cp0 + 1, false);<br>
+                if (frames[cp0]->bSceneChange && isSceneChangeNext)<br>
+                {<br>
+                    if (!m_isSceneTransition && fluctuate)<br>
+                        m_isSceneTransition = true;<br>
+                    else<br>
+                        frames[cp0]->bSceneChange = false;<br>
+                }<br>
+             }<br>
+        }<br>
+<br></blockquote><div><br></div><div>To determine m_isSceneTransition for this frame, we need to look at this flag for the previous frames (in addition to checking for end of the scene transition), no? <br> <br></div><div>also, why are sceneChange and sceneTransition in different classes? They should both be in lowres, and will be consumed by ratecontrol only. <br><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+        if (numFrames > origmaxp1 && (avgSatdCost == 0 || !fluctuate))<br>
+        {<br>
+            /* Signal end of scene transitioning */<br>
+            m_isSceneTransition = false;<br>
         }<br>
     }<br>
<br>
diff -r 46152345eb6f -r 2a901547b3b8 source/encoder/slicetype.h<br>
--- a/source/encoder/slicetype.h        Mon Jul 20 17:18:54 2015 -0700<br>
+++ b/source/encoder/slicetype.h        Wed Jul 22 00:29:26 2015 +0530<br>
@@ -127,7 +127,7 @@<br>
     int           m_numCoopSlices;<br>
     int           m_numRowsPerSlice;<br>
     bool          m_filled;<br>
-<br>
+    bool          m_isSceneTransition;<br>
     Lookahead(x265_param *param, ThreadPool *pool);<br>
<br>
 #if DETAILED_CU_STATS<br>
_______________________________________________<br>
x265-devel mailing list<br>
<a href="mailto:x265-devel@videolan.org">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><br></div></div>