right - this patch should be ignored On Wed, Aug 19, 2015 at 1:26 PM, Steve Borho <[email protected]> wrote:
> On 08/17, [email protected] wrote: > > # HG changeset patch > > # User Deepthi Nandakumar <[email protected]> > > # Date 1439811205 -19800 > > # Mon Aug 17 17:03:25 2015 +0530 > > # Node ID 9834fc054362a039580b205323d47fe1561c1ac9 > > # Parent 996ebce8c874fc511d495cee227d24413e99d0c1 > > build: export x265-extras in the DLL > > this defeats the purpose of them being in 'extras' to begin with. If the > features are linked into the shared library they might as well be > configured via x265_param and managed by the encoder itself (and turned > into encoder/csv.cpp and common/dither.cpp) > > > diff -r 996ebce8c874 -r 9834fc054362 source/CMakeLists.txt > > --- a/source/CMakeLists.txt Mon Aug 17 10:52:15 2015 +0530 > > +++ b/source/CMakeLists.txt Mon Aug 17 17:03:25 2015 +0530 > > @@ -535,11 +535,11 @@ > > if(XCODE) > > # Xcode seems unable to link the CLI with libs, so link as one > targget > > add_executable(cli ../COPYING ${InputFiles} ${OutputFiles} > ${GETOPT} > > - x265.cpp x265.h x265cli.h x265-extras.h > x265-extras.cpp > > + x265.cpp x265.h x265cli.h > > $<TARGET_OBJECTS:encoder> > $<TARGET_OBJECTS:common> ${YASM_OBJS} ${YASM_SRCS}) > > else() > > add_executable(cli ../COPYING ${InputFiles} ${OutputFiles} > ${GETOPT} ${X265_RC_FILE} > > - ${ExportDefs} x265.cpp x265.h x265cli.h > x265-extras.h x265-extras.cpp) > > + ${ExportDefs} x265.cpp x265.h x265cli.h) > > if(WIN32 OR NOT ENABLE_SHARED OR INTEL_CXX) > > # The CLI cannot link to the shared library on Windows, it > > # requires internal APIs not exported from the DLL > > diff -r 996ebce8c874 -r 9834fc054362 source/common/CMakeLists.txt > > --- a/source/common/CMakeLists.txt Mon Aug 17 10:52:15 2015 +0530 > > +++ b/source/common/CMakeLists.txt Mon Aug 17 17:03:25 2015 +0530 > > @@ -110,4 +110,5 @@ > > predict.cpp predict.h > > scalinglist.cpp scalinglist.h > > quant.cpp quant.h contexts.h > > - deblock.cpp deblock.h) > > + deblock.cpp deblock.h > > + x265-extras.cpp x265-extras.h) > > diff -r 996ebce8c874 -r 9834fc054362 source/common/x265-extras.cpp > > --- /dev/null Thu Jan 01 00:00:00 1970 +0000 > > +++ b/source/common/x265-extras.cpp Mon Aug 17 17:03:25 2015 +0530 > > @@ -0,0 +1,341 @@ > > > +/***************************************************************************** > > + * Copyright (C) 2015 x265 project > > + * > > + * Authors: Steve Borho <[email protected]> > > + * Selvakumar Nithiyaruban <[email protected]> > > + * Divya Manivannan <[email protected]> > > + * > > + * 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 "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_api& api, const x265_param& param, > const char* fname, int level) > > +{ > > + if (sizeof(x265_stats) != api.sizeof_stats || sizeof(x265_picture) > != api.sizeof_picture) > > + { > > + fprintf(stderr, "extras [error]: structure size skew, unable to > create CSV logfile\n"); > > + return NULL; > > + } > > + > > + FILE *csvfp = fopen(fname, "r"); > > + if (csvfp) > > + { > > + /* file already exists, re-open for append */ > > + fclose(csvfp); > > + return fopen(fname, "ab"); > > + } > > + else > > + { > > + /* new CSV file, write header */ > > + csvfp = fopen(fname, "wb"); > > + if (csvfp) > > + { > > + if (level) > > + { > > + fprintf(csvfp, "Encode Order, Type, POC, QP, Bits, "); > > + if (param.rc.rateControlMode == X265_RC_CRF) > > + fprintf(csvfp, "RateFactor, "); > > + fprintf(csvfp, "Y PSNR, U PSNR, V PSNR, YUV PSNR, SSIM, > SSIM (dB), List 0, List 1"); > > + /* detailed performance statistics */ > > + fprintf(csvfp, ", DecideWait (ms), Row0Wait (ms), Wall > time (ms), Ref Wait Wall (ms), Total CTU time (ms), Stall Time (ms), Avg > WPP, Row Blocks"); > > + if (level >= 2) > > + { > > + uint32_t size = param.maxCUSize; > > + for (uint32_t depth = 0; depth <= g_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 <= g_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 <= g_maxCUDepth; > depth++) > > + { > > + fprintf(csvfp, ", Inter %dx%d", size, size); > > + size /= 2; > > + } > > + } > > + size = param.maxCUSize; > > + for (uint32_t depth = 0; depth <= g_maxCUDepth; > depth++) > > + { > > + fprintf(csvfp, ", Skip %dx%d", size, size); > > + size /= 2; > > + } > > + size = param.maxCUSize; > > + for (uint32_t depth = 0; depth <= g_maxCUDepth; > depth++) > > + { > > + fprintf(csvfp, ", Merge %dx%d", size, size); > > + size /= 2; > > + } > > + fprintf(csvfp, ", Avg Luma Distortion, Avg Chroma > Distortion, Avg psyEnergy, Avg Luma Level, Max Luma Level"); > > + } > > + 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,", > frameStats->encoderOrder, frameStats->sliceType, frameStats->poc, > frameStats->qp, (int)frameStats->bits); > > + if (param.rc.rateControlMode == X265_RC_CRF) > > + fprintf(csvfp, "%.3lf,", frameStats->rateFactor); > > + if (param.bEnablePsnr) > > + fprintf(csvfp, "%.3lf, %.3lf, %.3lf, %.3lf,", > frameStats->psnrY, frameStats->psnrU, frameStats->psnrV, frameStats->psnr); > > + else > > + fputs(" -, -, -, -,", csvfp); > > + if (param.bEnableSsim) > > + fprintf(csvfp, " %.6f, %6.3f,", frameStats->ssim, > x265_ssim2dB(frameStats->ssim)); > > + else > > + fputs(" -, -,", csvfp); > > + if (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); > > + } > > + fprintf(csvfp, " %.1lf, %.1lf, %.1lf, %.1lf, %.1lf, %.1lf,", > frameStats->decideWaitTime, frameStats->row0WaitTime, frameStats->wallTime, > frameStats->refWaitWallTime, frameStats->totalCTUTime, > frameStats->stallTime); > > + fprintf(csvfp, " %.3lf, %d", frameStats->avgWPP, > frameStats->countRowBlocks); > > + if (level >= 2) > > + { > > + for (uint32_t depth = 0; depth <= g_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 <= g_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 <= g_maxCUDepth; depth++) > > + fprintf(csvfp, ", %5.2lf%%", > frameStats->cuStats.percentInterDistribution[depth][0]); > > + } > > + for (uint32_t depth = 0; depth <= g_maxCUDepth; depth++) > > + fprintf(csvfp, ", %5.2lf%%", > frameStats->cuStats.percentSkipCu[depth]); > > + for (uint32_t depth = 0; depth <= g_maxCUDepth; depth++) > > + fprintf(csvfp, ", %5.2lf%%", > frameStats->cuStats.percentMergeCu[depth]); > > + fprintf(csvfp, ", %.2lf, %.2lf, %.2lf, %.2lf, %d", > frameStats->avgLumaDistortion, frameStats->avgChromaDistortion, > frameStats->avgPsyEnergy, frameStats->avgLumaLevel, > frameStats->maxLumaLevel); > > + } > > + fprintf(csvfp, "\n"); > > + fflush(stderr); > > +} > > + > > +void x265_csvlog_encode(FILE* csvfp, const x265_api& api, const > x265_param& param, 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 > > + for (int i = 1; i < argc; i++) > > + { > > + if (i) fputc(' ', csvfp); > > + fputs(argv[i], 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, > api.version_str); > > +} > > + > > +/* The dithering algorithm is based on Sierra-2-4A error diffusion. */ > > +static void ditherPlane(pixel *dst, int dstStride, 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)); > > + int pitch = 1; > > + for (int y = 0; y < height; y++, src += srcStride, dst += dstStride) > > + { > > + int16_t err = 0; > > + for (int x = 0; x < width; x++) > > + { > > + err = err * 2 + errors[x] + errors[x + 1]; > > + dst[x * pitch] = (pixel)x265_clip3(0, pixelMax, ((src[x * > 1] << 2) + err + half) >> rShift); > > + errors[x] = err = src[x * pitch] - (dst[x * pitch] << > lShift); > > + } > > + } > > +} > > + > > +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; > > + } > > + > > + /* This portion of code is from readFrame in x264. */ > > + for (int i = 0; i < x265_cli_csps[picIn.colorSpace].planes; i++) > > + { > > + if ((picIn.bitDepth & 7) && (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; > > + } > > + } > > + > > + for (int i = 0; i < x265_cli_csps[picIn.colorSpace].planes; i++) > > + { > > + int height = (int)(picHeight >> > x265_cli_csps[picIn.colorSpace].height[i]); > > + int width = (int)(picWidth >> > x265_cli_csps[picIn.colorSpace].width[i]); > > + > > + ditherPlane(((pixel*)picIn.planes[i]), picIn.stride[i] / > sizeof(pixel), ((uint16_t*)picIn.planes[i]), > > + picIn.stride[i] / 2, width, height, errorBuf, > bitDepth); > > + } > > +} > > diff -r 996ebce8c874 -r 9834fc054362 source/common/x265-extras.h > > --- /dev/null Thu Jan 01 00:00:00 1970 +0000 > > +++ b/source/common/x265-extras.h Mon Aug 17 17:03:25 2015 +0530 > > @@ -0,0 +1,60 @@ > > > +/***************************************************************************** > > + * Copyright (C) 2015 x265 project > > + * > > + * Authors: Steve Borho <[email protected]> > > + * > > + * 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 > > + > > +/* 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 */ > > +FILE* x265_csvlog_open(const x265_api& api, 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. */ > > +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. */ > > +void x265_csvlog_encode(FILE* csvfp, const x265_api& api, const > x265_param& param, 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. */ > > +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 996ebce8c874 -r 9834fc054362 source/x265-extras.cpp > > --- a/source/x265-extras.cpp Mon Aug 17 10:52:15 2015 +0530 > > +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 > > @@ -1,341 +0,0 @@ > > > -/***************************************************************************** > > - * Copyright (C) 2015 x265 project > > - * > > - * Authors: Steve Borho <[email protected]> > > - * Selvakumar Nithiyaruban <[email protected]> > > - * Divya Manivannan <[email protected]> > > - * > > - * 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 "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_api& api, const x265_param& param, > const char* fname, int level) > > -{ > > - if (sizeof(x265_stats) != api.sizeof_stats || sizeof(x265_picture) > != api.sizeof_picture) > > - { > > - fprintf(stderr, "extras [error]: structure size skew, unable to > create CSV logfile\n"); > > - return NULL; > > - } > > - > > - FILE *csvfp = fopen(fname, "r"); > > - if (csvfp) > > - { > > - /* file already exists, re-open for append */ > > - fclose(csvfp); > > - return fopen(fname, "ab"); > > - } > > - else > > - { > > - /* new CSV file, write header */ > > - csvfp = fopen(fname, "wb"); > > - if (csvfp) > > - { > > - if (level) > > - { > > - fprintf(csvfp, "Encode Order, Type, POC, QP, Bits, "); > > - if (param.rc.rateControlMode == X265_RC_CRF) > > - fprintf(csvfp, "RateFactor, "); > > - fprintf(csvfp, "Y PSNR, U PSNR, V PSNR, YUV PSNR, SSIM, > SSIM (dB), List 0, List 1"); > > - /* detailed performance statistics */ > > - fprintf(csvfp, ", DecideWait (ms), Row0Wait (ms), Wall > time (ms), Ref Wait Wall (ms), Total CTU time (ms), Stall Time (ms), Avg > WPP, Row Blocks"); > > - if (level >= 2) > > - { > > - uint32_t size = param.maxCUSize; > > - for (uint32_t depth = 0; depth <= g_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 <= g_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 <= g_maxCUDepth; > depth++) > > - { > > - fprintf(csvfp, ", Inter %dx%d", size, size); > > - size /= 2; > > - } > > - } > > - size = param.maxCUSize; > > - for (uint32_t depth = 0; depth <= g_maxCUDepth; > depth++) > > - { > > - fprintf(csvfp, ", Skip %dx%d", size, size); > > - size /= 2; > > - } > > - size = param.maxCUSize; > > - for (uint32_t depth = 0; depth <= g_maxCUDepth; > depth++) > > - { > > - fprintf(csvfp, ", Merge %dx%d", size, size); > > - size /= 2; > > - } > > - fprintf(csvfp, ", Avg Luma Distortion, Avg Chroma > Distortion, Avg psyEnergy, Avg Luma Level, Max Luma Level"); > > - } > > - 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,", > frameStats->encoderOrder, frameStats->sliceType, frameStats->poc, > frameStats->qp, (int)frameStats->bits); > > - if (param.rc.rateControlMode == X265_RC_CRF) > > - fprintf(csvfp, "%.3lf,", frameStats->rateFactor); > > - if (param.bEnablePsnr) > > - fprintf(csvfp, "%.3lf, %.3lf, %.3lf, %.3lf,", > frameStats->psnrY, frameStats->psnrU, frameStats->psnrV, frameStats->psnr); > > - else > > - fputs(" -, -, -, -,", csvfp); > > - if (param.bEnableSsim) > > - fprintf(csvfp, " %.6f, %6.3f,", frameStats->ssim, > x265_ssim2dB(frameStats->ssim)); > > - else > > - fputs(" -, -,", csvfp); > > - if (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); > > - } > > - fprintf(csvfp, " %.1lf, %.1lf, %.1lf, %.1lf, %.1lf, %.1lf,", > frameStats->decideWaitTime, frameStats->row0WaitTime, frameStats->wallTime, > frameStats->refWaitWallTime, frameStats->totalCTUTime, > frameStats->stallTime); > > - fprintf(csvfp, " %.3lf, %d", frameStats->avgWPP, > frameStats->countRowBlocks); > > - if (level >= 2) > > - { > > - for (uint32_t depth = 0; depth <= g_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 <= g_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 <= g_maxCUDepth; depth++) > > - fprintf(csvfp, ", %5.2lf%%", > frameStats->cuStats.percentInterDistribution[depth][0]); > > - } > > - for (uint32_t depth = 0; depth <= g_maxCUDepth; depth++) > > - fprintf(csvfp, ", %5.2lf%%", > frameStats->cuStats.percentSkipCu[depth]); > > - for (uint32_t depth = 0; depth <= g_maxCUDepth; depth++) > > - fprintf(csvfp, ", %5.2lf%%", > frameStats->cuStats.percentMergeCu[depth]); > > - fprintf(csvfp, ", %.2lf, %.2lf, %.2lf, %.2lf, %d", > frameStats->avgLumaDistortion, frameStats->avgChromaDistortion, > frameStats->avgPsyEnergy, frameStats->avgLumaLevel, > frameStats->maxLumaLevel); > > - } > > - fprintf(csvfp, "\n"); > > - fflush(stderr); > > -} > > - > > -void x265_csvlog_encode(FILE* csvfp, const x265_api& api, const > x265_param& param, 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 > > - for (int i = 1; i < argc; i++) > > - { > > - if (i) fputc(' ', csvfp); > > - fputs(argv[i], 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, > api.version_str); > > -} > > - > > -/* The dithering algorithm is based on Sierra-2-4A error diffusion. */ > > -static void ditherPlane(pixel *dst, int dstStride, 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)); > > - int pitch = 1; > > - for (int y = 0; y < height; y++, src += srcStride, dst += dstStride) > > - { > > - int16_t err = 0; > > - for (int x = 0; x < width; x++) > > - { > > - err = err * 2 + errors[x] + errors[x + 1]; > > - dst[x * pitch] = (pixel)x265_clip3(0, pixelMax, ((src[x * > 1] << 2) + err + half) >> rShift); > > - errors[x] = err = src[x * pitch] - (dst[x * pitch] << > lShift); > > - } > > - } > > -} > > - > > -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; > > - } > > - > > - /* This portion of code is from readFrame in x264. */ > > - for (int i = 0; i < x265_cli_csps[picIn.colorSpace].planes; i++) > > - { > > - if ((picIn.bitDepth & 7) && (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; > > - } > > - } > > - > > - for (int i = 0; i < x265_cli_csps[picIn.colorSpace].planes; i++) > > - { > > - int height = (int)(picHeight >> > x265_cli_csps[picIn.colorSpace].height[i]); > > - int width = (int)(picWidth >> > x265_cli_csps[picIn.colorSpace].width[i]); > > - > > - ditherPlane(((pixel*)picIn.planes[i]), picIn.stride[i] / > sizeof(pixel), ((uint16_t*)picIn.planes[i]), > > - picIn.stride[i] / 2, width, height, errorBuf, > bitDepth); > > - } > > -} > > diff -r 996ebce8c874 -r 9834fc054362 source/x265-extras.h > > --- a/source/x265-extras.h Mon Aug 17 10:52:15 2015 +0530 > > +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 > > @@ -1,66 +0,0 @@ > > > -/***************************************************************************** > > - * Copyright (C) 2015 x265 project > > - * > > - * Authors: Steve Borho <[email protected]> > > - * > > - * 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_api& api, 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 x265_api& api, const > x265_param& param, 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 996ebce8c874 -r 9834fc054362 source/x265.def.in > > --- a/source/x265.def.in Mon Aug 17 10:52:15 2015 +0530 > > +++ b/source/x265.def.in Mon Aug 17 17:03:25 2015 +0530 > > @@ -22,3 +22,7 @@ > > x265_cleanup > > x265_api_get_${X265_BUILD} > > x265_api_query > > +x265_csvlog_open > > +x265_csvlog_frame > > +x265_csvlog_encode > > +x265_dither_image > > _______________________________________________ > > x265-devel mailing list > > [email protected] > > https://mailman.videolan.org/listinfo/x265-devel > > > > -- > Steve Borho > > _______________________________________________ > x265-devel mailing list > [email protected] > https://mailman.videolan.org/listinfo/x265-devel > >
_______________________________________________ x265-devel mailing list [email protected] https://mailman.videolan.org/listinfo/x265-devel
