<div dir="ltr"><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Nov 10, 2017 at 1:04 PM, Divya Manivannan <span dir="ltr"><<a href="mailto:divya@multicorewareinc.com" target="_blank">divya@multicorewareinc.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class=""># HG changeset patch<br>
# User Divya Manivannan <<a href="mailto:divya@multicorewareinc.com">divya@multicorewareinc.com</a>><br>
# Date 1510141098 -19800<br>
#      Wed Nov 08 17:08:18 2017 +0530<br>
</span># Node ID 563cbe1f4a21dcfe2117ccaa874b71<wbr>3d94434f92<br>
<span class=""># Parent  bd438ce108435deb4f0063fca9a9e1<wbr>4a75e8de38<br>
api: move csv and dither functions into api structure<br>
<br>
</span>csv is now moved into libx265. So, we can remove x265-extras.h<br></blockquote><div><br></div><div>Pushed to default branch. Thanks!</div><div> <br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
diff -r bd438ce10843 -r 563cbe1f4a21 source/CMakeLists.txt<br>
<span class="">--- a/source/CMakeLists.txt     Wed Nov 08 16:18:29 2017 +0530<br>
+++ b/source/CMakeLists.txt     Wed Nov 08 17:08:18 2017 +0530<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 142)<br>
+set(X265_BUILD 143)<br>
 configure_file("${PROJECT_<wbr>SOURCE_DIR}/<a href="http://x265.def.in" rel="noreferrer" target="_blank">x265.def.in</a>"<br>
                "${PROJECT_BINARY_DIR}/x265.<wbr>def")<br>
 configure_file("${PROJECT_<wbr>SOURCE_DIR}/<a href="http://x265_config.h.in" rel="noreferrer" target="_blank">x265_config.h.in</a>"<br>
</span>diff -r bd438ce10843 -r 563cbe1f4a21 source/encoder/CMakeLists.txt<br>
<span class="">--- a/source/encoder/CMakeLists.<wbr>txt     Wed Nov 08 16:18:29 2017 +0530<br>
+++ b/source/encoder/CMakeLists.<wbr>txt     Wed Nov 08 17:08:18 2017 +0530<br>
@@ -43,5 +43,4 @@<br>
     reference.cpp reference.h<br>
     encoder.cpp encoder.h<br>
     api.cpp<br>
-    weightPrediction.cpp<br>
-    ../x265-extras.cpp ../x265-extras.h)<br>
+    weightPrediction.cpp)<br>
</span>diff -r bd438ce10843 -r 563cbe1f4a21 source/encoder/api.cpp<br>
<div><div class="h5">--- a/source/encoder/api.cpp    Wed Nov 08 16:18:29 2017 +0530<br>
+++ b/source/encoder/api.cpp    Wed Nov 08 17:08:18 2017 +0530<br>
@@ -30,7 +30,6 @@<br>
 #include "level.h"<br>
 #include "nal.h"<br>
 #include "bitcost.h"<br>
-#include "x265-extras.h"<br>
<br>
 /* multilib namespace reflectors */<br>
 #if LINKED_8BIT<br>
@@ -63,6 +62,14 @@<br>
 namespace X265_NS {<br>
 #endif<br>
<br>
+static const char* summaryCSVHeader =<br>
+    "Command, Date/Time, Elapsed Time, FPS, Bitrate, "<br>
+    "Y PSNR, U PSNR, V PSNR, Global PSNR, SSIM, SSIM (dB), "<br>
+    "I count, I ave-QP, I kbps, I-PSNR Y, I-PSNR U, I-PSNR V, I-SSIM (dB), "<br>
+    "P count, P ave-QP, P kbps, P-PSNR Y, P-PSNR U, P-PSNR V, P-SSIM (dB), "<br>
+    "B count, B ave-QP, B kbps, B-PSNR Y, B-PSNR U, B-PSNR V, B-SSIM (dB), "<br>
+    "MaxCLL, MaxFALL, Version\n";<br>
+<br>
 x265_encoder *x265_encoder_open(x265_param *p)<br>
 {<br>
     if (!p)<br>
@@ -120,7 +127,7 @@<br>
     /* Try to open CSV file handle */<br>
     if (encoder->m_param->csvfn)<br>
     {<br>
-        encoder->m_param->csvfpt = x265_csvlog_open(*encoder->m_<wbr>param, encoder->m_param->csvfn, encoder->m_param->csvLogLevel)<wbr>;<br>
+        encoder->m_param->csvfpt = x265_csvlog_open(*encoder->m_<wbr>param);<br>
         if (!encoder->m_param->csvfpt)<br>
         {<br>
             x265_log(encoder->m_param, X265_LOG_ERROR, "Unable to open CSV log file <%s>, aborting\n", encoder->m_param->csvfn);<br>
@@ -280,7 +287,7 @@<br>
         *pi_nal = 0;<br>
<br>
     if (numEncoded && encoder->m_param->csvLogLevel)<br>
-        x265_csvlog_frame(encoder->m_<wbr>param->csvfpt, *encoder->m_param, *pic_out, encoder->m_param->csvLogLevel)<wbr>;<br>
+        x265_csvlog_frame(*encoder->m_<wbr>param, *pic_out);<br>
<br>
     if (numEncoded < 0)<br>
         encoder->m_aborted = true;<br>
@@ -303,11 +310,8 @@<br>
     {<br>
         Encoder *encoder = static_cast<Encoder*>(enc);<br>
         x265_stats stats;<br>
-        int padx = encoder->m_sps.<wbr>conformanceWindow.rightOffset;<br>
-        int pady = encoder->m_sps.<wbr>conformanceWindow.<wbr>bottomOffset;<br>
         encoder->fetchStats(&stats, sizeof(stats));<br>
-        const x265_api * api = x265_api_get(0);<br>
-        x265_csvlog_encode(encoder->m_<wbr>param->csvfpt, api->version_str, *encoder->m_param, padx, pady, stats, encoder->m_param->csvLogLevel, argc, argv);<br>
+        x265_csvlog_encode(enc, stats, argc, argv);<br>
     }<br>
 }<br>
<br>
@@ -436,6 +440,10 @@<br>
     &x265_encoder_ctu_info,<br>
     &x265_get_slicetype_poc_and_<wbr>scenecut,<br>
     &x265_get_ref_frame_list,<br>
+    &x265_csvlog_open,<br>
+    &x265_csvlog_frame,<br>
+    &x265_csvlog_encode,<br>
+    &x265_dither_image,<br>
 };<br>
<br>
 typedef const x265_api* (*api_get_func)(int bitDepth);<br>
@@ -630,4 +638,422 @@<br>
     return &libapi;<br>
 }<br>
<br>
+FILE* x265_csvlog_open(const x265_param& param)<br>
+{<br>
+    FILE *csvfp = x265_fopen(param.csvfn, "r");<br>
+    if (csvfp)<br>
+    {<br>
+        /* file already exists, re-open for append */<br>
+        fclose(csvfp);<br>
+        return x265_fopen(param.csvfn, "ab");<br>
+    }<br>
+    else<br>
+    {<br>
+        /* new CSV file, write header */<br>
+        csvfp = x265_fopen(param.csvfn, "wb");<br>
+        if (csvfp)<br>
+        {<br>
+            if (param.csvLogLevel)<br>
+            {<br>
+                fprintf(csvfp, "Encode Order, Type, POC, QP, Bits, Scenecut, ");<br>
+                if (param.csvLogLevel >= 2)<br>
+                    fprintf(csvfp, "I/P cost ratio, ");<br>
+                if (param.rc.rateControlMode == X265_RC_CRF)<br>
+                    fprintf(csvfp, "RateFactor, ");<br>
+                if (param.rc.vbvBufferSize)<br>
+                    fprintf(csvfp, "BufferFill, ");<br>
+                if (param.bEnablePsnr)<br>
+                    fprintf(csvfp, "Y PSNR, U PSNR, V PSNR, YUV PSNR, ");<br>
+                if (param.bEnableSsim)<br>
+                    fprintf(csvfp, "SSIM, SSIM(dB), ");<br>
+                fprintf(csvfp, "Latency, ");<br>
+                fprintf(csvfp, "List 0, List 1");<br>
+                uint32_t size = param.maxCUSize;<br>
+                for (uint32_t depth = 0; depth <= param.maxCUDepth; depth++)<br>
+                {<br>
+                    fprintf(csvfp, ", Intra %dx%d DC, Intra %dx%d Planar, Intra %dx%d Ang", size, size, size, size, size, size);<br>
+                    size /= 2;<br>
+                }<br>
+                fprintf(csvfp, ", 4x4");<br>
+                size = param.maxCUSize;<br>
+                if (param.bEnableRectInter)<br>
+                {<br>
+                    for (uint32_t depth = 0; depth <= param.maxCUDepth; depth++)<br>
+                    {<br>
+                        fprintf(csvfp, ", Inter %dx%d, Inter %dx%d (Rect)", size, size, size, size);<br>
+                        if (param.bEnableAMP)<br>
+                            fprintf(csvfp, ", Inter %dx%d (Amp)", size, size);<br>
+                        size /= 2;<br>
+                    }<br>
+                }<br>
+                else<br>
+                {<br>
+                    for (uint32_t depth = 0; depth <= param.maxCUDepth; depth++)<br>
+                    {<br>
+                        fprintf(csvfp, ", Inter %dx%d", size, size);<br>
+                        size /= 2;<br>
+                    }<br>
+                }<br>
+                size = param.maxCUSize;<br>
+                for (uint32_t depth = 0; depth <= param.maxCUDepth; depth++)<br>
+                {<br>
+                    fprintf(csvfp, ", Skip %dx%d", size, size);<br>
+                    size /= 2;<br>
+                }<br>
+                size = param.maxCUSize;<br>
+                for (uint32_t depth = 0; depth <= param.maxCUDepth; depth++)<br>
+                {<br>
+                    fprintf(csvfp, ", Merge %dx%d", size, size);<br>
+                    size /= 2;<br>
+                }<br>
+<br>
+                if (param.csvLogLevel >= 2)<br>
+                {<br>
+                    fprintf(csvfp, ", Avg Luma Distortion, Avg Chroma Distortion, Avg psyEnergy, Avg Residual Energy,"<br>
+                        " Min Luma Level, Max Luma Level, Avg Luma Level");<br>
+<br>
+                    if (param.internalCsp != X265_CSP_I400)<br>
+                        fprintf(csvfp, ", Min Cb Level, Max Cb Level, Avg Cb Level, Min Cr Level, Max Cr Level, Avg Cr Level");<br>
+<br>
+                    /* PU statistics */<br>
+                    size = param.maxCUSize;<br>
+                    for (uint32_t i = 0; i< param.maxLog2CUSize - (uint32_t)g_log2Size[param.<wbr>minCUSize] + 1; i++)<br>
+                    {<br>
+                        fprintf(csvfp, ", Intra %dx%d", size, size);<br>
+                        fprintf(csvfp, ", Skip %dx%d", size, size);<br>
+                        fprintf(csvfp, ", AMP %d", size);<br>
+                        fprintf(csvfp, ", Inter %dx%d", size, size);<br>
+                        fprintf(csvfp, ", Merge %dx%d", size, size);<br>
+                        fprintf(csvfp, ", Inter %dx%d", size, size / 2);<br>
+                        fprintf(csvfp, ", Merge %dx%d", size, size / 2);<br>
+                        fprintf(csvfp, ", Inter %dx%d", size / 2, size);<br>
+                        fprintf(csvfp, ", Merge %dx%d", size / 2, size);<br>
+                        size /= 2;<br>
+                    }<br>
+<br>
+                    if ((uint32_t)g_log2Size[param.<wbr>minCUSize] == 3)<br>
+                        fprintf(csvfp, ", 4x4");<br>
+<br>
+                    /* detailed performance statistics */<br>
+                    fprintf(csvfp, ", DecideWait (ms), Row0Wait (ms), Wall time (ms), Ref Wait Wall (ms), Total CTU time (ms),"<br>
+                        "Stall Time (ms), Total frame time (ms), Avg WPP, Row Blocks");<br>
+                }<br>
+                fprintf(csvfp, "\n");<br>
+            }<br>
+            else<br>
+                fputs(summaryCSVHeader, csvfp);<br>
+        }<br>
+        return csvfp;<br>
+    }<br>
+}<br>
+<br>
+// per frame CSV logging<br>
+void x265_csvlog_frame(const x265_param& param, const x265_picture& pic)<br>
+{<br>
+    if (!param.csvfpt)<br>
+        return;<br>
+<br>
+    const x265_frame_stats* frameStats = &pic.frameData;<br>
+    fprintf(param.csvfpt, "%d, %c-SLICE, %4d, %2.2lf, %10d, %d,", frameStats->encoderOrder, frameStats->sliceType, frameStats->poc,<br>
+                                                                  frameStats->qp, (int)frameStats->bits, frameStats->bScenecut);<br>
+    if (param.csvLogLevel >= 2)<br>
+        fprintf(param.csvfpt, "%.2f,", frameStats->ipCostRatio);<br>
+    if (param.rc.rateControlMode == X265_RC_CRF)<br>
+        fprintf(param.csvfpt, "%.3lf,", frameStats->rateFactor);<br>
+    if (param.rc.vbvBufferSize)<br>
+        fprintf(param.csvfpt, "%.3lf,", frameStats->bufferFill);<br>
+    if (param.bEnablePsnr)<br>
+        fprintf(param.csvfpt, "%.3lf, %.3lf, %.3lf, %.3lf,", frameStats->psnrY, frameStats->psnrU, frameStats->psnrV, frameStats->psnr);<br>
+    if (param.bEnableSsim)<br>
+        fprintf(param.csvfpt, " %.6f, %6.3f,", frameStats->ssim, x265_ssim2dB(frameStats->ssim)<wbr>);<br>
+    fprintf(param.csvfpt, "%d, ", frameStats->frameLatency);<br>
+    if (frameStats->sliceType == 'I' || frameStats->sliceType == 'i')<br>
+        fputs(" -, -,", param.csvfpt);<br>
+    else<br>
+    {<br>
+        int i = 0;<br>
+        while (frameStats->list0POC[i] != -1)<br>
+            fprintf(param.csvfpt, "%d ", frameStats->list0POC[i++]);<br>
+        fprintf(param.csvfpt, ",");<br>
+        if (frameStats->sliceType != 'P')<br>
+        {<br>
+            i = 0;<br>
+            while (frameStats->list1POC[i] != -1)<br>
+                fprintf(param.csvfpt, "%d ", frameStats->list1POC[i++]);<br>
+            fprintf(param.csvfpt, ",");<br>
+        }<br>
+        else<br>
+            fputs(" -,", param.csvfpt);<br>
+    }<br>
+<br>
+    if (param.csvLogLevel)<br>
+    {<br>
+        for (uint32_t depth = 0; depth <= param.maxCUDepth; depth++)<br>
+            fprintf(param.csvfpt, "%5.2lf%%, %5.2lf%%, %5.2lf%%,", frameStats->cuStats.<wbr>percentIntraDistribution[<wbr>depth][0],<br>
+                                                                   frameStats->cuStats.<wbr>percentIntraDistribution[<wbr>depth][1],<br>
+                                                                   frameStats->cuStats.<wbr>percentIntraDistribution[<wbr>depth][2]);<br>
+        fprintf(param.csvfpt, "%5.2lf%%", frameStats->cuStats.<wbr>percentIntraNxN);<br>
+        if (param.bEnableRectInter)<br>
+        {<br>
+            for (uint32_t depth = 0; depth <= param.maxCUDepth; depth++)<br>
+            {<br>
+                fprintf(param.csvfpt, ", %5.2lf%%, %5.2lf%%", frameStats->cuStats.<wbr>percentInterDistribution[<wbr>depth][0],<br>
+                                                              frameStats->cuStats.<wbr>percentInterDistribution[<wbr>depth][1]);<br>
+                if (param.bEnableAMP)<br>
+                    fprintf(param.csvfpt, ", %5.2lf%%", frameStats->cuStats.<wbr>percentInterDistribution[<wbr>depth][2]);<br>
+            }<br>
+        }<br>
+        else<br>
+        {<br>
+            for (uint32_t depth = 0; depth <= param.maxCUDepth; depth++)<br>
+                fprintf(param.csvfpt, ", %5.2lf%%", frameStats->cuStats.<wbr>percentInterDistribution[<wbr>depth][0]);<br>
+        }<br>
+        for (uint32_t depth = 0; depth <= param.maxCUDepth; depth++)<br>
+            fprintf(param.csvfpt, ", %5.2lf%%", frameStats->cuStats.<wbr>percentSkipCu[depth]);<br>
+        for (uint32_t depth = 0; depth <= param.maxCUDepth; depth++)<br>
+            fprintf(param.csvfpt, ", %5.2lf%%", frameStats->cuStats.<wbr>percentMergeCu[depth]);<br>
+    }<br>
+<br>
+    if (param.csvLogLevel >= 2)<br>
+    {<br>
+        fprintf(param.csvfpt, ", %.2lf, %.2lf, %.2lf, %.2lf ", frameStats->avgLumaDistortion,<br>
+                                                               frameStats-><wbr>avgChromaDistortion,<br>
+                                                               frameStats->avgPsyEnergy,<br>
+                                                               frameStats->avgResEnergy);<br>
+<br>
+        fprintf(param.csvfpt, ", %d, %d, %.2lf", frameStats->minLumaLevel, frameStats->maxLumaLevel, frameStats->avgLumaLevel);<br>
+<br>
+        if (param.internalCsp != X265_CSP_I400)<br>
+        {<br>
+            fprintf(param.csvfpt, ", %d, %d, %.2lf", frameStats->minChromaULevel, frameStats->maxChromaULevel, frameStats->avgChromaULevel);<br>
+            fprintf(param.csvfpt, ", %d, %d, %.2lf", frameStats->minChromaVLevel, frameStats->maxChromaVLevel, frameStats->avgChromaVLevel);<br>
+        }<br>
+<br>
+        for (uint32_t i = 0; i < param.maxLog2CUSize - (uint32_t)g_log2Size[param.<wbr>minCUSize] + 1; i++)<br>
+        {<br>
+            fprintf(param.csvfpt, ", %.2lf%%", frameStats->puStats.<wbr>percentIntraPu[i]);<br>
+            fprintf(param.csvfpt, ", %.2lf%%", frameStats->puStats.<wbr>percentSkipPu[i]);<br>
+            fprintf(param.csvfpt, ",%.2lf%%", frameStats->puStats.<wbr>percentAmpPu[i]);<br>
+            for (uint32_t j = 0; j < 3; j++)<br>
+            {<br>
+                fprintf(param.csvfpt, ", %.2lf%%", frameStats->puStats.<wbr>percentInterPu[i][j]);<br>
+                fprintf(param.csvfpt, ", %.2lf%%", frameStats->puStats.<wbr>percentMergePu[i][j]);<br>
+            }<br>
+        }<br>
+        if ((uint32_t)g_log2Size[param.<wbr>minCUSize] == 3)<br>
+            fprintf(param.csvfpt, ",%.2lf%%", frameStats->puStats.<wbr>percentNxN);<br>
+<br>
+        fprintf(param.csvfpt, ", %.1lf, %.1lf, %.1lf, %.1lf, %.1lf, %.1lf, %.1lf,", frameStats->decideWaitTime, frameStats->row0WaitTime,<br>
+                                                                                    frameStats->wallTime, frameStats->refWaitWallTime,<br>
+                                                                                    frameStats->totalCTUTime, frameStats->stallTime,<br>
+                                                                                    frameStats->totalFrameTime);<br>
+<br>
+        fprintf(param.csvfpt, " %.3lf, %d", frameStats->avgWPP, frameStats->countRowBlocks);<br>
+    }<br>
+    fprintf(param.csvfpt, "\n");<br>
+    fflush(stderr);<br>
+}<br>
+<br>
+void x265_csvlog_encode(x265_<wbr>encoder *enc, const x265_stats& stats, int argc, char** argv)<br>
+{<br>
+    if (enc)<br>
+    {<br>
+        Encoder *encoder = static_cast<Encoder*>(enc);<br>
+        int padx = encoder->m_sps.<wbr>conformanceWindow.rightOffset;<br>
+        int pady = encoder->m_sps.<wbr>conformanceWindow.<wbr>bottomOffset;<br>
+        const x265_api * api = x265_api_get(0);<br>
+<br>
+        if (!encoder->m_param->csvfpt)<br>
+            return;<br>
+<br>
+        if (encoder->m_param-><wbr>csvLogLevel)<br>
+        {<br>
+            // adding summary to a per-frame csv log file, so it needs a summary header<br>
+            fprintf(encoder->m_param-><wbr>csvfpt, "\nSummary\n");<br>
+            fputs(summaryCSVHeader, encoder->m_param->csvfpt);<br>
+        }<br>
+<br>
+        // CLI arguments or other<br>
+        if (argc)<br>
+        {<br>
+            fputc('"', encoder->m_param->csvfpt);<br>
+            for (int i = 1; i < argc; i++)<br>
+            {<br>
+                fputc(' ', encoder->m_param->csvfpt);<br>
+                fputs(argv[i], encoder->m_param->csvfpt);<br>
+            }<br>
+            fputc('"', encoder->m_param->csvfpt);<br>
+        }<br>
+        else<br>
+        {<br>
+            const x265_param* paramTemp = encoder->m_param;<br>
+            char *opts = x265_param2string((x265_param*<wbr>)paramTemp, padx, pady);<br>
+            if (opts)<br>
+            {<br>
+                fputc('"', encoder->m_param->csvfpt);<br>
+                fputs(opts, encoder->m_param->csvfpt);<br>
+                fputc('"', encoder->m_param->csvfpt);<br>
+            }<br>
+        }<br>
+<br>
+        // current date and time<br>
+        time_t now;<br>
+        struct tm* timeinfo;<br>
+        time(&now);<br>
+        timeinfo = localtime(&now);<br>
+        char buffer[200];<br>
+        strftime(buffer, 128, "%c", timeinfo);<br>
+        fprintf(encoder->m_param-><wbr>csvfpt, ", %s, ", buffer);<br>
+<br>
+        // elapsed time, fps, bitrate<br>
+        fprintf(encoder->m_param-><wbr>csvfpt, "%.2f, %.2f, %.2f,",<br>
+            stats.elapsedEncodeTime, stats.encodedPictureCount / stats.elapsedEncodeTime, stats.bitrate);<br>
+<br>
+        if (encoder->m_param-><wbr>bEnablePsnr)<br>
+            fprintf(encoder->m_param-><wbr>csvfpt, " %.3lf, %.3lf, %.3lf, %.3lf,",<br>
+            stats.globalPsnrY / stats.encodedPictureCount, stats.globalPsnrU / stats.encodedPictureCount,<br>
+            stats.globalPsnrV / stats.encodedPictureCount, stats.globalPsnr);<br>
+        else<br>
+            fprintf(encoder->m_param-><wbr>csvfpt, " -, -, -, -,");<br>
+        if (encoder->m_param-><wbr>bEnableSsim)<br>
+            fprintf(encoder->m_param-><wbr>csvfpt, " %.6f, %6.3f,", stats.globalSsim, x265_ssim2dB(stats.globalSsim)<wbr>);<br>
+        else<br>
+            fprintf(encoder->m_param-><wbr>csvfpt, " -, -,");<br>
+<br>
+        if (stats.statsI.numPics)<br>
+        {<br>
+            fprintf(encoder->m_param-><wbr>csvfpt, " %-6u, %2.2lf, %-8.2lf,", stats.statsI.numPics, stats.statsI.avgQp, stats.statsI.bitrate);<br>
+            if (encoder->m_param-><wbr>bEnablePsnr)<br>
+                fprintf(encoder->m_param-><wbr>csvfpt, " %.3lf, %.3lf, %.3lf,", stats.statsI.psnrY, stats.statsI.psnrU, stats.statsI.psnrV);<br>
+            else<br>
+                fprintf(encoder->m_param-><wbr>csvfpt, " -, -, -,");<br>
+            if (encoder->m_param-><wbr>bEnableSsim)<br>
+                fprintf(encoder->m_param-><wbr>csvfpt, " %.3lf,", stats.statsI.ssim);<br>
+            else<br>
+                fprintf(encoder->m_param-><wbr>csvfpt, " -,");<br>
+        }<br>
+        else<br>
+            fprintf(encoder->m_param-><wbr>csvfpt, " -, -, -, -, -, -, -,");<br>
+<br>
+        if (stats.statsP.numPics)<br>
+        {<br>
+            fprintf(encoder->m_param-><wbr>csvfpt, " %-6u, %2.2lf, %-8.2lf,", stats.statsP.numPics, stats.statsP.avgQp, stats.statsP.bitrate);<br>
+            if (encoder->m_param-><wbr>bEnablePsnr)<br>
+                fprintf(encoder->m_param-><wbr>csvfpt, " %.3lf, %.3lf, %.3lf,", stats.statsP.psnrY, stats.statsP.psnrU, stats.statsP.psnrV);<br>
+            else<br>
+                fprintf(encoder->m_param-><wbr>csvfpt, " -, -, -,");<br>
+            if (encoder->m_param-><wbr>bEnableSsim)<br>
+                fprintf(encoder->m_param-><wbr>csvfpt, " %.3lf,", stats.statsP.ssim);<br>
+            else<br>
+                fprintf(encoder->m_param-><wbr>csvfpt, " -,");<br>
+        }<br>
+        else<br>
+            fprintf(encoder->m_param-><wbr>csvfpt, " -, -, -, -, -, -, -,");<br>
+<br>
+        if (stats.statsB.numPics)<br>
+        {<br>
+            fprintf(encoder->m_param-><wbr>csvfpt, " %-6u, %2.2lf, %-8.2lf,", stats.statsB.numPics, stats.statsB.avgQp, stats.statsB.bitrate);<br>
+            if (encoder->m_param-><wbr>bEnablePsnr)<br>
+                fprintf(encoder->m_param-><wbr>csvfpt, " %.3lf, %.3lf, %.3lf,", stats.statsB.psnrY, stats.statsB.psnrU, stats.statsB.psnrV);<br>
+            else<br>
+                fprintf(encoder->m_param-><wbr>csvfpt, " -, -, -,");<br>
+            if (encoder->m_param-><wbr>bEnableSsim)<br>
+                fprintf(encoder->m_param-><wbr>csvfpt, " %.3lf,", stats.statsB.ssim);<br>
+            else<br>
+                fprintf(encoder->m_param-><wbr>csvfpt, " -,");<br>
+        }<br>
+        else<br>
+            fprintf(encoder->m_param-><wbr>csvfpt, " -, -, -, -, -, -, -,");<br>
+<br>
+        fprintf(encoder->m_param-><wbr>csvfpt, " %-6u, %-6u, %s\n", stats.maxCLL, stats.maxFALL, api->version_str);<br>
+    }<br>
+}<br>
+<br>
+/* The dithering algorithm is based on Sierra-2-4A error diffusion.<br>
+ * We convert planes in place (without allocating a new buffer). */<br>
+static void ditherPlane(uint16_t *src, int srcStride, int width, int height, int16_t *errors, int bitDepth)<br>
+{<br>
+    const int lShift = 16 - bitDepth;<br>
+    const int rShift = 16 - bitDepth + 2;<br>
+    const int half = (1 << (16 - bitDepth + 1));<br>
+    const int pixelMax = (1 << bitDepth) - 1;<br>
+<br>
+    memset(errors, 0, (width + 1) * sizeof(int16_t));<br>
+<br>
+    if (bitDepth == 8)<br>
+    {<br>
+        for (int y = 0; y < height; y++, src += srcStride)<br>
+        {<br>
+            uint8_t* dst = (uint8_t *)src;<br>
+            int16_t err = 0;<br>
+            for (int x = 0; x < width; x++)<br>
+            {<br>
+                err = err * 2 + errors[x] + errors[x + 1];<br>
+                int tmpDst = x265_clip3(0, pixelMax, ((src[x] << 2) + err + half) >> rShift);<br>
+                errors[x] = err = (int16_t)(src[x] - (tmpDst << lShift));<br>
+                dst[x] = (uint8_t)tmpDst;<br>
+            }<br>
+        }<br>
+    }<br>
+    else<br>
+    {<br>
+        for (int y = 0; y < height; y++, src += srcStride)<br>
+        {<br>
+            int16_t err = 0;<br>
+            for (int x = 0; x < width; x++)<br>
+            {<br>
+                err = err * 2 + errors[x] + errors[x + 1];<br>
+                int tmpDst = x265_clip3(0, pixelMax, ((src[x] << 2) + err + half) >> rShift);<br>
+                errors[x] = err = (int16_t)(src[x] - (tmpDst << lShift));<br>
+                src[x] = (uint16_t)tmpDst;<br>
+            }<br>
+        }<br>
+    }<br>
+}<br>
+<br>
+void x265_dither_image(x265_<wbr>picture& picIn, int picWidth, int picHeight, int16_t *errorBuf, int bitDepth)<br>
+{<br>
+    const x265_api* api = x265_api_get(0);<br>
+<br>
+    if (sizeof(x265_picture) != api->sizeof_picture)<br>
+    {<br>
+        fprintf(stderr, "extras [error]: structure size skew, unable to dither\n");<br>
+        return;<br>
+    }<br>
+<br>
+    if (picIn.bitDepth <= 8)<br>
+    {<br>
+        fprintf(stderr, "extras [error]: dither support enabled only for input bitdepth > 8\n");<br>
+        return;<br>
+    }<br>
+<br>
+    if (picIn.bitDepth == bitDepth)<br>
+    {<br>
+        fprintf(stderr, "extras[error]: dither support enabled only if encoder depth is different from picture depth\n");<br>
+        return;<br>
+    }<br>
+<br>
+    /* This portion of code is from readFrame in x264. */<br>
+    for (int i = 0; i < x265_cli_csps[picIn.<wbr>colorSpace].planes; i++)<br>
+    {<br>
+        if (picIn.bitDepth < 16)<br>
+        {<br>
+            /* upconvert non 16bit high depth planes to 16bit */<br>
+            uint16_t *plane = (uint16_t*)picIn.planes[i];<br>
+            uint32_t pixelCount = x265_picturePlaneSize(picIn.<wbr>colorSpace, picWidth, picHeight, i);<br>
+            int lShift = 16 - picIn.bitDepth;<br>
+<br>
+            /* This loop assumes width is equal to stride which<br>
+             * happens to be true for file reader outputs */<br>
+            for (uint32_t j = 0; j < pixelCount; j++)<br>
+                plane[j] = plane[j] << lShift;<br>
+        }<br>
+<br>
+        int height = (int)(picHeight >> x265_cli_csps[picIn.<wbr>colorSpace].height[i]);<br>
+        int width = (int)(picWidth >> x265_cli_csps[picIn.<wbr>colorSpace].width[i]);<br>
+<br>
+        ditherPlane(((uint16_t*)picIn.<wbr>planes[i]), picIn.stride[i] / 2, width, height, errorBuf, bitDepth);<br>
+    }<br>
+}<br>
+<br>
 } /* end namespace or extern "C" */<br>
</div></div>diff -r bd438ce10843 -r 563cbe1f4a21 source/x265-extras.cpp<br>
<div><div class="h5">--- a/source/x265-extras.cpp    Wed Nov 08 16:18:29 2017 +0530<br>
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000<br>
@@ -1,447 +0,0 @@<br>
-/****************************<wbr>******************************<wbr>*******************<br>
- * Copyright (C) 2013-2017 MulticoreWare, Inc<br>
- *<br>
- * Authors: Steve Borho <<a href="mailto:steve@borho.org">steve@borho.org</a>><br>
- *          Selvakumar Nithiyaruban <<a href="mailto:selvakumar@multicorewareinc.com">selvakumar@multicorewareinc.<wbr>com</a>><br>
- *          Divya Manivannan <<a href="mailto:divya@multicorewareinc.com">divya@multicorewareinc.com</a>><br>
- *<br>
- * This program is free software; you can redistribute it and/or modify<br>
- * it under the terms of the GNU General Public License as published by<br>
- * the Free Software Foundation; either version 2 of the License, or<br>
- * (at your option) any later version.<br>
- *<br>
- * This program is distributed in the hope that it will be useful,<br>
- * but WITHOUT ANY WARRANTY; without even the implied warranty of<br>
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the<br>
- * GNU General Public License for more details.<br>
- *<br>
- * You should have received a copy of the GNU General Public License<br>
- * along with this program; if not, write to the Free Software<br>
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.<br>
- *<br>
- * This program is also available under a commercial proprietary license.<br>
- * For more information, contact us at license @ <a href="http://x265.com" rel="noreferrer" target="_blank">x265.com</a>.<br>
- ******************************<wbr>******************************<wbr>*****************/<br>
-<br>
-#include "x265.h"<br>
-#include "x265-extras.h"<br>
-#include "param.h"<br>
-#include "common.h"<br>
-<br>
-using namespace X265_NS;<br>
-<br>
-static const char* summaryCSVHeader =<br>
-    "Command, Date/Time, Elapsed Time, FPS, Bitrate, "<br>
-    "Y PSNR, U PSNR, V PSNR, Global PSNR, SSIM, SSIM (dB), "<br>
-    "I count, I ave-QP, I kbps, I-PSNR Y, I-PSNR U, I-PSNR V, I-SSIM (dB), "<br>
-    "P count, P ave-QP, P kbps, P-PSNR Y, P-PSNR U, P-PSNR V, P-SSIM (dB), "<br>
-    "B count, B ave-QP, B kbps, B-PSNR Y, B-PSNR U, B-PSNR V, B-SSIM (dB), "<br>
-    "MaxCLL, MaxFALL, Version\n";<br>
-<br>
-FILE* x265_csvlog_open(const x265_param& param, const char* fname, int level)<br>
-{<br>
-    FILE *csvfp = x265_fopen(fname, "r");<br>
-    if (csvfp)<br>
-    {<br>
-        /* file already exists, re-open for append */<br>
-        fclose(csvfp);<br>
-        return x265_fopen(fname, "ab");<br>
-    }<br>
-    else<br>
-    {<br>
-        /* new CSV file, write header */<br>
-        csvfp = x265_fopen(fname, "wb");<br>
-        if (csvfp)<br>
-        {<br>
-            if (level)<br>
-            {<br>
-                fprintf(csvfp, "Encode Order, Type, POC, QP, Bits, Scenecut, ");<br>
-                if (level >= 2)<br>
-                    fprintf(csvfp, "I/P cost ratio, ");<br>
-                if (param.rc.rateControlMode == X265_RC_CRF)<br>
-                    fprintf(csvfp, "RateFactor, ");<br>
-                if (param.rc.vbvBufferSize)<br>
-                    fprintf(csvfp, "BufferFill, ");<br>
-                if (param.bEnablePsnr)<br>
-                    fprintf(csvfp, "Y PSNR, U PSNR, V PSNR, YUV PSNR, ");<br>
-                if (param.bEnableSsim)<br>
-                    fprintf(csvfp, "SSIM, SSIM(dB), ");<br>
-                fprintf(csvfp, "Latency, ");<br>
-                fprintf(csvfp, "List 0, List 1");<br>
-                uint32_t size = param.maxCUSize;<br>
-                for (uint32_t depth = 0; depth <= param.maxCUDepth; depth++)<br>
-                {<br>
-                    fprintf(csvfp, ", Intra %dx%d DC, Intra %dx%d Planar, Intra %dx%d Ang", size, size, size, size, size, size);<br>
-                    size /= 2;<br>
-                }<br>
-                fprintf(csvfp, ", 4x4");<br>
-                size = param.maxCUSize;<br>
-                if (param.bEnableRectInter)<br>
-                {<br>
-                    for (uint32_t depth = 0; depth <= param.maxCUDepth; depth++)<br>
-                    {<br>
-                        fprintf(csvfp, ", Inter %dx%d, Inter %dx%d (Rect)", size, size, size, size);<br>
-                        if (param.bEnableAMP)<br>
-                            fprintf(csvfp, ", Inter %dx%d (Amp)", size, size);<br>
-                        size /= 2;<br>
-                    }<br>
-                }<br>
-                else<br>
-                {<br>
-                    for (uint32_t depth = 0; depth <= param.maxCUDepth; depth++)<br>
-                    {<br>
-                        fprintf(csvfp, ", Inter %dx%d", size, size);<br>
-                        size /= 2;<br>
-                    }<br>
-                }<br>
-                size = param.maxCUSize;<br>
-                for (uint32_t depth = 0; depth <= param.maxCUDepth; depth++)<br>
-                {<br>
-                    fprintf(csvfp, ", Skip %dx%d", size, size);<br>
-                    size /= 2;<br>
-                }<br>
-                size = param.maxCUSize;<br>
-                for (uint32_t depth = 0; depth <= param.maxCUDepth; depth++)<br>
-                {<br>
-                    fprintf(csvfp, ", Merge %dx%d", size, size);<br>
-                    size /= 2;<br>
-                }<br>
-<br>
-                if (level >= 2)<br>
-                {<br>
-                    fprintf(csvfp, ", Avg Luma Distortion, Avg Chroma Distortion, Avg psyEnergy, Avg Residual Energy,"<br>
-                        " Min Luma Level, Max Luma Level, Avg Luma Level");<br>
-<br>
-                    if (param.internalCsp != X265_CSP_I400)<br>
-                        fprintf(csvfp, ", Min Cb Level, Max Cb Level, Avg Cb Level, Min Cr Level, Max Cr Level, Avg Cr Level");<br>
-<br>
-                    /* PU statistics */<br>
-                    size = param.maxCUSize;<br>
-                    for (uint32_t i = 0; i< param.maxLog2CUSize - (uint32_t)g_log2Size[param.<wbr>minCUSize] + 1; i++)<br>
-                    {<br>
-                        fprintf(csvfp, ", Intra %dx%d", size, size);<br>
-                        fprintf(csvfp, ", Skip %dx%d", size, size);<br>
-                        fprintf(csvfp, ", AMP %d", size);<br>
-                        fprintf(csvfp, ", Inter %dx%d", size, size);<br>
-                        fprintf(csvfp, ", Merge %dx%d", size, size);<br>
-                        fprintf(csvfp, ", Inter %dx%d", size, size / 2);<br>
-                        fprintf(csvfp, ", Merge %dx%d", size, size / 2);<br>
-                        fprintf(csvfp, ", Inter %dx%d", size / 2, size);<br>
-                        fprintf(csvfp, ", Merge %dx%d", size / 2, size);<br>
-                        size /= 2;<br>
-                    }<br>
-<br>
-                    if ((uint32_t)g_log2Size[param.<wbr>minCUSize] == 3)<br>
-                        fprintf(csvfp, ", 4x4");<br>
-<br>
-                    /* detailed performance statistics */<br>
-                    fprintf(csvfp, ", DecideWait (ms), Row0Wait (ms), Wall time (ms), Ref Wait Wall (ms), Total CTU time (ms),"<br>
-                    "Stall Time (ms), Total frame time (ms), Avg WPP, Row Blocks");<br>
-                }<br>
-                fprintf(csvfp, "\n");<br>
-            }<br>
-            else<br>
-                fputs(summaryCSVHeader, csvfp);<br>
-        }<br>
-        return csvfp;<br>
-    }<br>
-}<br>
-<br>
-// per frame CSV logging<br>
-void x265_csvlog_frame(FILE* csvfp, const x265_param& param, const x265_picture& pic, int level)<br>
-{<br>
-    if (!csvfp)<br>
-        return;<br>
-<br>
-    const x265_frame_stats* frameStats = &pic.frameData;<br>
-    fprintf(csvfp, "%d, %c-SLICE, %4d, %2.2lf, %10d, %d,", frameStats->encoderOrder, frameStats->sliceType, frameStats->poc,<br>
-                                                           frameStats->qp, (int)frameStats->bits, frameStats->bScenecut);<br>
-    if (level >= 2)<br>
-        fprintf(csvfp, "%.2f,", frameStats->ipCostRatio);<br>
-    if (param.rc.rateControlMode == X265_RC_CRF)<br>
-        fprintf(csvfp, "%.3lf,", frameStats->rateFactor);<br>
-    if (param.rc.vbvBufferSize)<br>
-        fprintf(csvfp, "%.3lf,", frameStats->bufferFill);<br>
-    if (param.bEnablePsnr)<br>
-        fprintf(csvfp, "%.3lf, %.3lf, %.3lf, %.3lf,", frameStats->psnrY, frameStats->psnrU, frameStats->psnrV, frameStats->psnr);<br>
-    if (param.bEnableSsim)<br>
-        fprintf(csvfp, " %.6f, %6.3f,", frameStats->ssim, x265_ssim2dB(frameStats->ssim)<wbr>);<br>
-    fprintf(csvfp, "%d, ", frameStats->frameLatency);<br>
-    if (frameStats->sliceType == 'I' || frameStats->sliceType == 'i')<br>
-        fputs(" -, -,", csvfp);<br>
-    else<br>
-    {<br>
-        int i = 0;<br>
-        while (frameStats->list0POC[i] != -1)<br>
-            fprintf(csvfp, "%d ", frameStats->list0POC[i++]);<br>
-        fprintf(csvfp, ",");<br>
-        if (frameStats->sliceType != 'P')<br>
-        {<br>
-            i = 0;<br>
-            while (frameStats->list1POC[i] != -1)<br>
-                fprintf(csvfp, "%d ", frameStats->list1POC[i++]);<br>
-            fprintf(csvfp, ",");<br>
-        }<br>
-        else<br>
-            fputs(" -,", csvfp);<br>
-    }<br>
-<br>
-    if (level)<br>
-    {<br>
-        for (uint32_t depth = 0; depth <= param.maxCUDepth; depth++)<br>
-            fprintf(csvfp, "%5.2lf%%, %5.2lf%%, %5.2lf%%,", frameStats->cuStats.<wbr>percentIntraDistribution[<wbr>depth][0],<br>
-            frameStats->cuStats.<wbr>percentIntraDistribution[<wbr>depth][1],<br>
-            frameStats->cuStats.<wbr>percentIntraDistribution[<wbr>depth][2]);<br>
-        fprintf(csvfp, "%5.2lf%%", frameStats->cuStats.<wbr>percentIntraNxN);<br>
-        if (param.bEnableRectInter)<br>
-        {<br>
-            for (uint32_t depth = 0; depth <= param.maxCUDepth; depth++)<br>
-            {<br>
-                fprintf(csvfp, ", %5.2lf%%, %5.2lf%%", frameStats->cuStats.<wbr>percentInterDistribution[<wbr>depth][0],<br>
-                    frameStats->cuStats.<wbr>percentInterDistribution[<wbr>depth][1]);<br>
-                if (param.bEnableAMP)<br>
-                    fprintf(csvfp, ", %5.2lf%%", frameStats->cuStats.<wbr>percentInterDistribution[<wbr>depth][2]);<br>
-            }<br>
-        }<br>
-        else<br>
-        {<br>
-            for (uint32_t depth = 0; depth <= param.maxCUDepth; depth++)<br>
-                fprintf(csvfp, ", %5.2lf%%", frameStats->cuStats.<wbr>percentInterDistribution[<wbr>depth][0]);<br>
-        }<br>
-        for (uint32_t depth = 0; depth <= param.maxCUDepth; depth++)<br>
-            fprintf(csvfp, ", %5.2lf%%", frameStats->cuStats.<wbr>percentSkipCu[depth]);<br>
-        for (uint32_t depth = 0; depth <= param.maxCUDepth; depth++)<br>
-            fprintf(csvfp, ", %5.2lf%%", frameStats->cuStats.<wbr>percentMergeCu[depth]);<br>
-    }<br>
-<br>
-    if (level >= 2)<br>
-    {<br>
-        fprintf(csvfp, ", %.2lf, %.2lf, %.2lf, %.2lf ", frameStats->avgLumaDistortion,<br>
-            frameStats-><wbr>avgChromaDistortion,<br>
-            frameStats->avgPsyEnergy,<br>
-            frameStats->avgResEnergy);<br>
-<br>
-        fprintf(csvfp, ", %d, %d, %.2lf", frameStats->minLumaLevel, frameStats->maxLumaLevel, frameStats->avgLumaLevel);<br>
-<br>
-        if (param.internalCsp != X265_CSP_I400)<br>
-        {<br>
-            fprintf(csvfp, ", %d, %d, %.2lf", frameStats->minChromaULevel, frameStats->maxChromaULevel, frameStats->avgChromaULevel);<br>
-            fprintf(csvfp, ", %d, %d, %.2lf", frameStats->minChromaVLevel, frameStats->maxChromaVLevel, frameStats->avgChromaVLevel);<br>
-        }<br>
-<br>
-        for (uint32_t i = 0; i < param.maxLog2CUSize - (uint32_t)g_log2Size[param.<wbr>minCUSize] + 1; i++)<br>
-        {<br>
-            fprintf(csvfp, ", %.2lf%%", frameStats->puStats.<wbr>percentIntraPu[i]);<br>
-            fprintf(csvfp, ", %.2lf%%", frameStats->puStats.<wbr>percentSkipPu[i]);<br>
-            fprintf(csvfp, ",%.2lf%%", frameStats->puStats.<wbr>percentAmpPu[i]);<br>
-            for (uint32_t j = 0; j < 3; j++)<br>
-            {<br>
-                fprintf(csvfp, ", %.2lf%%", frameStats->puStats.<wbr>percentInterPu[i][j]);<br>
-                fprintf(csvfp, ", %.2lf%%", frameStats->puStats.<wbr>percentMergePu[i][j]);<br>
-            }<br>
-        }<br>
-        if ((uint32_t)g_log2Size[param.<wbr>minCUSize] == 3)<br>
-            fprintf(csvfp, ",%.2lf%%", frameStats->puStats.<wbr>percentNxN);<br>
-<br>
-        fprintf(csvfp, ", %.1lf, %.1lf, %.1lf, %.1lf, %.1lf, %.1lf, %.1lf,", frameStats->decideWaitTime, frameStats->row0WaitTime,<br>
-                                                                             frameStats->wallTime, frameStats->refWaitWallTime,<br>
-                                                                             frameStats->totalCTUTime, frameStats->stallTime,<br>
-                                                                             frameStats->totalFrameTime);<br>
-<br>
-        fprintf(csvfp, " %.3lf, %d", frameStats->avgWPP, frameStats->countRowBlocks);<br>
-    }<br>
-    fprintf(csvfp, "\n");<br>
-    fflush(stderr);<br>
-}<br>
-<br>
-void x265_csvlog_encode(FILE* csvfp, const char* version, const x265_param& param, int padx, int pady, const x265_stats& stats, int level, int argc, char** argv)<br>
-{<br>
-    if (!csvfp)<br>
-        return;<br>
-<br>
-    if (level)<br>
-    {<br>
-        // adding summary to a per-frame csv log file, so it needs a summary header<br>
-        fprintf(csvfp, "\nSummary\n");<br>
-        fputs(summaryCSVHeader, csvfp);<br>
-    }<br>
-<br>
-    // CLI arguments or other<br>
-    if (argc)<br>
-    {<br>
-        fputc('"', csvfp);<br>
-        for (int i = 1; i < argc; i++)<br>
-        {<br>
-            fputc(' ', csvfp);<br>
-            fputs(argv[i], csvfp);<br>
-        }<br>
-        fputc('"', csvfp);<br>
-    }<br>
-    else<br>
-    {<br>
-        const x265_param* paramTemp = &param;<br>
-        char *opts = x265_param2string((x265_param*<wbr>)paramTemp, padx, pady);<br>
-        if (opts)<br>
-        {<br>
-            fputc('"', csvfp);<br>
-            fputs(opts, csvfp);<br>
-            fputc('"', csvfp);<br>
-        }<br>
-    }<br>
-<br>
-    // current date and time<br>
-    time_t now;<br>
-    struct tm* timeinfo;<br>
-    time(&now);<br>
-    timeinfo = localtime(&now);<br>
-    char buffer[200];<br>
-    strftime(buffer, 128, "%c", timeinfo);<br>
-    fprintf(csvfp, ", %s, ", buffer);<br>
-<br>
-    // elapsed time, fps, bitrate<br>
-    fprintf(csvfp, "%.2f, %.2f, %.2f,",<br>
-        stats.elapsedEncodeTime, stats.encodedPictureCount / stats.elapsedEncodeTime, stats.bitrate);<br>
-<br>
-    if (param.bEnablePsnr)<br>
-        fprintf(csvfp, " %.3lf, %.3lf, %.3lf, %.3lf,",<br>
-        stats.globalPsnrY / stats.encodedPictureCount, stats.globalPsnrU / stats.encodedPictureCount,<br>
-        stats.globalPsnrV / stats.encodedPictureCount, stats.globalPsnr);<br>
-    else<br>
-        fprintf(csvfp, " -, -, -, -,");<br>
-    if (param.bEnableSsim)<br>
-        fprintf(csvfp, " %.6f, %6.3f,", stats.globalSsim, x265_ssim2dB(stats.globalSsim)<wbr>);<br>
-    else<br>
-        fprintf(csvfp, " -, -,");<br>
-<br>
-    if (stats.statsI.numPics)<br>
-    {<br>
-        fprintf(csvfp, " %-6u, %2.2lf, %-8.2lf,", stats.statsI.numPics, stats.statsI.avgQp, stats.statsI.bitrate);<br>
-        if (param.bEnablePsnr)<br>
-            fprintf(csvfp, " %.3lf, %.3lf, %.3lf,", stats.statsI.psnrY, stats.statsI.psnrU, stats.statsI.psnrV);<br>
-        else<br>
-            fprintf(csvfp, " -, -, -,");<br>
-        if (param.bEnableSsim)<br>
-            fprintf(csvfp, " %.3lf,", stats.statsI.ssim);<br>
-        else<br>
-            fprintf(csvfp, " -,");<br>
-    }<br>
-    else<br>
-        fprintf(csvfp, " -, -, -, -, -, -, -,");<br>
-<br>
-    if (stats.statsP.numPics)<br>
-    {<br>
-        fprintf(csvfp, " %-6u, %2.2lf, %-8.2lf,", stats.statsP.numPics, stats.statsP.avgQp, stats.statsP.bitrate);<br>
-        if (param.bEnablePsnr)<br>
-            fprintf(csvfp, " %.3lf, %.3lf, %.3lf,", stats.statsP.psnrY, stats.statsP.psnrU, stats.statsP.psnrV);<br>
-        else<br>
-            fprintf(csvfp, " -, -, -,");<br>
-        if (param.bEnableSsim)<br>
-            fprintf(csvfp, " %.3lf,", stats.statsP.ssim);<br>
-        else<br>
-            fprintf(csvfp, " -,");<br>
-    }<br>
-    else<br>
-        fprintf(csvfp, " -, -, -, -, -, -, -,");<br>
-<br>
-    if (stats.statsB.numPics)<br>
-    {<br>
-        fprintf(csvfp, " %-6u, %2.2lf, %-8.2lf,", stats.statsB.numPics, stats.statsB.avgQp, stats.statsB.bitrate);<br>
-        if (param.bEnablePsnr)<br>
-            fprintf(csvfp, " %.3lf, %.3lf, %.3lf,", stats.statsB.psnrY, stats.statsB.psnrU, stats.statsB.psnrV);<br>
-        else<br>
-            fprintf(csvfp, " -, -, -,");<br>
-        if (param.bEnableSsim)<br>
-            fprintf(csvfp, " %.3lf,", stats.statsB.ssim);<br>
-        else<br>
-            fprintf(csvfp, " -,");<br>
-    }<br>
-    else<br>
-        fprintf(csvfp, " -, -, -, -, -, -, -,");<br>
-<br>
-    fprintf(csvfp, " %-6u, %-6u, %s\n", stats.maxCLL, stats.maxFALL, version);<br>
-}<br>
-<br>
-/* The dithering algorithm is based on Sierra-2-4A error diffusion.<br>
- * We convert planes in place (without allocating a new buffer). */<br>
-static void ditherPlane(uint16_t *src, int srcStride, int width, int height, int16_t *errors, int bitDepth)<br>
-{<br>
-    const int lShift = 16 - bitDepth;<br>
-    const int rShift = 16 - bitDepth + 2;<br>
-    const int half = (1 << (16 - bitDepth + 1));<br>
-    const int pixelMax = (1 << bitDepth) - 1;<br>
-<br>
-    memset(errors, 0, (width + 1) * sizeof(int16_t));<br>
-<br>
-    if (bitDepth == 8)<br>
-    {<br>
-        for (int y = 0; y < height; y++, src += srcStride)<br>
-        {<br>
-            uint8_t* dst = (uint8_t *)src;<br>
-            int16_t err = 0;<br>
-            for (int x = 0; x < width; x++)<br>
-            {<br>
-                err = err * 2 + errors[x] + errors[x + 1];<br>
-                int tmpDst = x265_clip3(0, pixelMax, ((src[x] << 2) + err + half) >> rShift);<br>
-                errors[x] = err = (int16_t)(src[x] - (tmpDst << lShift));<br>
-                dst[x] = (uint8_t)tmpDst;<br>
-            }<br>
-        }<br>
-    }<br>
-    else<br>
-    {<br>
-        for (int y = 0; y < height; y++, src += srcStride)<br>
-        {<br>
-            int16_t err = 0;<br>
-            for (int x = 0; x < width; x++)<br>
-            {<br>
-                err = err * 2 + errors[x] + errors[x + 1];<br>
-                int tmpDst = x265_clip3(0, pixelMax, ((src[x] << 2) + err + half) >> rShift);<br>
-                errors[x] = err = (int16_t)(src[x] - (tmpDst << lShift));<br>
-                src[x] = (uint16_t)tmpDst;<br>
-            }<br>
-        }<br>
-    }<br>
-}<br>
-<br>
-void x265_dither_image(const x265_api& api, x265_picture& picIn, int picWidth, int picHeight, int16_t *errorBuf, int bitDepth)<br>
-{<br>
-    if (sizeof(x265_picture) != api.sizeof_picture)<br>
-    {<br>
-        fprintf(stderr, "extras [error]: structure size skew, unable to dither\n");<br>
-        return;<br>
-    }<br>
-<br>
-    if (picIn.bitDepth <= 8)<br>
-    {<br>
-        fprintf(stderr, "extras [error]: dither support enabled only for input bitdepth > 8\n");<br>
-        return;<br>
-    }<br>
-<br>
-    if (picIn.bitDepth == bitDepth)<br>
-    {<br>
-        fprintf(stderr, "extras[error]: dither support enabled only if encoder depth is different from picture depth\n");<br>
-        return;<br>
-    }<br>
-<br>
-    /* This portion of code is from readFrame in x264. */<br>
-    for (int i = 0; i < x265_cli_csps[picIn.<wbr>colorSpace].planes; i++)<br>
-    {<br>
-        if (picIn.bitDepth < 16)<br>
-        {<br>
-            /* upconvert non 16bit high depth planes to 16bit */<br>
-            uint16_t *plane = (uint16_t*)picIn.planes[i];<br>
-            uint32_t pixelCount = x265_picturePlaneSize(picIn.<wbr>colorSpace, picWidth, picHeight, i);<br>
-            int lShift = 16 - picIn.bitDepth;<br>
-<br>
-            /* This loop assumes width is equal to stride which<br>
-             * happens to be true for file reader outputs */<br>
-            for (uint32_t j = 0; j < pixelCount; j++)<br>
-                plane[j] = plane[j] << lShift;<br>
-        }<br>
-<br>
-        int height = (int)(picHeight >> x265_cli_csps[picIn.<wbr>colorSpace].height[i]);<br>
-        int width = (int)(picWidth >> x265_cli_csps[picIn.<wbr>colorSpace].width[i]);<br>
-<br>
-        ditherPlane(((uint16_t*)picIn.<wbr>planes[i]), picIn.stride[i] / 2, width, height, errorBuf, bitDepth);<br>
-    }<br>
-}<br>
</div></div>diff -r bd438ce10843 -r 563cbe1f4a21 source/x265-extras.h<br>
<div><div class="h5">--- a/source/x265-extras.h      Wed Nov 08 16:18:29 2017 +0530<br>
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000<br>
@@ -1,66 +0,0 @@<br>
-/****************************<wbr>******************************<wbr>*******************<br>
- * Copyright (C) 2013-2017 MulticoreWare, Inc<br>
- *<br>
- * Authors: Steve Borho <<a href="mailto:steve@borho.org">steve@borho.org</a>><br>
- *<br>
- * This program is free software; you can redistribute it and/or modify<br>
- * it under the terms of the GNU General Public License as published by<br>
- * the Free Software Foundation; either version 2 of the License, or<br>
- * (at your option) any later version.<br>
- *<br>
- * This program is distributed in the hope that it will be useful,<br>
- * but WITHOUT ANY WARRANTY; without even the implied warranty of<br>
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the<br>
- * GNU General Public License for more details.<br>
- *<br>
- * You should have received a copy of the GNU General Public License<br>
- * along with this program; if not, write to the Free Software<br>
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.<br>
- *<br>
- * This program is also available under a commercial proprietary license.<br>
- * For more information, contact us at license @ <a href="http://x265.com" rel="noreferrer" target="_blank">x265.com</a>.<br>
- ******************************<wbr>******************************<wbr>*****************/<br>
-<br>
-#ifndef X265_EXTRAS_H<br>
-#define X265_EXTRAS_H 1<br>
-<br>
-#include "x265.h"<br>
-<br>
-#include <stdio.h><br>
-#include <stdint.h><br>
-<br>
-#ifdef __cplusplus<br>
-extern "C" {<br>
-#endif<br>
-<br>
-#if _WIN32<br>
-#define LIBAPI __declspec(dllexport)<br>
-#else<br>
-#define LIBAPI<br>
-#endif<br>
-<br>
-/* Open a CSV log file. On success it returns a file handle which must be passed<br>
- * to x265_csvlog_frame() and/or x265_csvlog_encode(). The file handle must be<br>
- * closed by the caller using fclose(). If level is 0, then no frame logging<br>
- * header is written to the file. This function will return NULL if it is unable<br>
- * to open the file for write or if it detects a structure size skew */<br>
-LIBAPI FILE* x265_csvlog_open(const x265_param& param, const char* fname, int level);<br>
-<br>
-/* Log frame statistics to the CSV file handle. level should have been non-zero<br>
- * in the call to x265_csvlog_open() if this function is called. */<br>
-LIBAPI void x265_csvlog_frame(FILE* csvfp, const x265_param& param, const x265_picture& pic, int level);<br>
-<br>
-/* Log final encode statistics to the CSV file handle. 'argc' and 'argv' are<br>
- * intended to be command line arguments passed to the encoder. Encode<br>
- * statistics should be queried from the encoder just prior to closing it. */<br>
-LIBAPI void x265_csvlog_encode(FILE* csvfp, const char* version, const x265_param& param, int padx, int pady, const x265_stats& stats, int level, int argc, char** argv);<br>
-<br>
-/* In-place downshift from a bit-depth greater than 8 to a bit-depth of 8, using<br>
- * the residual bits to dither each row. */<br>
-LIBAPI void x265_dither_image(const x265_api& api, x265_picture&, int picWidth, int picHeight, int16_t *errorBuf, int bitDepth);<br>
-<br>
-#ifdef __cplusplus<br>
-}<br>
-#endif<br>
-<br>
-#endif<br>
</div></div>diff -r bd438ce10843 -r 563cbe1f4a21 source/x265.cpp<br>
<span class="">--- a/source/x265.cpp   Wed Nov 08 16:18:29 2017 +0530<br>
+++ b/source/x265.cpp   Wed Nov 08 17:08:18 2017 +0530<br>
@@ -26,7 +26,6 @@<br>
 #endif<br>
<br>
 #include "x265.h"<br>
-#include "x265-extras.h"<br>
 #include "x265cli.h"<br>
<br>
 #include "input/input.h"<br>
@@ -639,7 +638,7 @@<br>
         {<br>
             if (pic_in->bitDepth > param->internalBitDepth && cliopt.bDither)<br>
             {<br>
-                x265_dither_image(*api, *pic_in, cliopt.input->getWidth(), cliopt.input->getHeight(), errorBuf, param->internalBitDepth);<br>
+                x265_dither_image(*pic_in, cliopt.input->getWidth(), cliopt.input->getHeight(), errorBuf, param->internalBitDepth);<br>
                 pic_in->bitDepth = param->internalBitDepth;<br>
             }<br>
             /* Overwrite PTS */<br>
</span>diff -r bd438ce10843 -r 563cbe1f4a21 source/<a href="http://x265.def.in" rel="noreferrer" target="_blank">x265.def.in</a><br>
<span class="">--- a/source/<a href="http://x265.def.in" rel="noreferrer" target="_blank">x265.def.in</a>        Wed Nov 08 16:18:29 2017 +0530<br>
+++ b/source/<a href="http://x265.def.in" rel="noreferrer" target="_blank">x265.def.in</a>        Wed Nov 08 17:08:18 2017 +0530<br>
@@ -26,3 +26,7 @@<br>
 x265_encoder_ctu_info<br>
 x265_get_slicetype_poc_and_<wbr>scenecut<br>
 x265_get_ref_frame_list<br>
+x265_csvlog_open<br>
+x265_csvlog_frame<br>
+x265_csvlog_encode<br>
+x265_dither_image<br>
</span>diff -r bd438ce10843 -r 563cbe1f4a21 source/x265.h<br>
<div class="HOEnZb"><div class="h5">--- a/source/x265.h     Wed Nov 08 16:18:29 2017 +0530<br>
+++ b/source/x265.h     Wed Nov 08 17:08:18 2017 +0530<br>
@@ -1745,6 +1745,26 @@<br>
<br>
 void x265_cleanup(void);<br>
<br>
+/* Open a CSV log file. On success it returns a file handle which must be passed<br>
+ * to x265_csvlog_frame() and/or x265_csvlog_encode(). The file handle must be<br>
+ * closed by the caller using fclose(). If csv-loglevel is 0, then no frame logging<br>
+ * header is written to the file. This function will return NULL if it is unable<br>
+ * to open the file for write or if it detects a structure size skew */<br>
+FILE* x265_csvlog_open(const x265_param& param);<br>
+<br>
+/* Log frame statistics to the CSV file handle. csv-loglevel should have been non-zero<br>
+ * in the call to x265_csvlog_open() if this function is called. */<br>
+void x265_csvlog_frame(const x265_param& param, const x265_picture& pic);<br>
+<br>
+/* Log final encode statistics to the CSV file handle. 'argc' and 'argv' are<br>
+ * intended to be command line arguments passed to the encoder. Encode<br>
+ * statistics should be queried from the encoder just prior to closing it. */<br>
+void x265_csvlog_encode(x265_<wbr>encoder *encoder, const x265_stats& stats, int argc, char** argv);<br>
+<br>
+/* In-place downshift from a bit-depth greater than 8 to a bit-depth of 8, using<br>
+ * the residual bits to dither each row. */<br>
+void x265_dither_image(x265_<wbr>picture& pic, int picWidth, int picHeight, int16_t *errorBuf, int bitDepth);<br>
+<br>
 #define X265_MAJOR_VERSION 1<br>
<br>
 /* === Multi-lib API ===<br>
@@ -1792,6 +1812,10 @@<br>
     int           (*encoder_ctu_info)(x265_<wbr>encoder*, int, x265_ctu_info_t**);<br>
     int           (*get_slicetype_poc_and_<wbr>scenecut)(x265_encoder*, int*, int*, int*);<br>
     int           (*get_ref_frame_list)(x265_<wbr>encoder*, x265_picyuv**, x265_picyuv**, int, int);<br>
+    FILE*         (*csvlog_open)(const x265_param&);<br>
+    void          (*csvlog_frame)(const x265_param&, const x265_picture&);<br>
+    void          (*csvlog_encode)(x265_encoder*<wbr>, const x265_stats&, int, char**);<br>
+    void          (*dither_image)(x265_picture&, int, int, int16_t*, int);<br>
     /* add new pointers to the end, or increment X265_MAJOR_VERSION */<br>
 } x265_api;<br>
<br>
</div></div><br>______________________________<wbr>_________________<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/<wbr>listinfo/x265-devel</a><br>
<br></blockquote></div><br></div></div>