[x265] [PATCH] api: move csv and dither functions into api structure

Divya Manivannan divya at multicorewareinc.com
Fri Nov 10 08:34:52 CET 2017


# HG changeset patch
# User Divya Manivannan <divya at multicorewareinc.com>
# Date 1510141098 -19800
#      Wed Nov 08 17:08:18 2017 +0530
# Node ID 563cbe1f4a21dcfe2117ccaa874b713d94434f92
# Parent  bd438ce108435deb4f0063fca9a9e14a75e8de38
api: move csv and dither functions into api structure

csv is now moved into libx265. So, we can remove x265-extras.h

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


More information about the x265-devel mailing list