[x265] [PATCH] build: export x265-extras in the DLL
Deepthi Nandakumar
deepthi at multicorewareinc.com
Wed Aug 19 10:00:12 CEST 2015
right - this patch should be ignored
On Wed, Aug 19, 2015 at 1:26 PM, Steve Borho <steve at borho.org> wrote:
> On 08/17, deepthi at multicorewareinc.com wrote:
> > # HG changeset patch
> > # User Deepthi Nandakumar <deepthi at multicorewareinc.com>
> > # 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 <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 "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 <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
> > +
> > +/* 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 <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 "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 <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_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
> > x265-devel at videolan.org
> > https://mailman.videolan.org/listinfo/x265-devel
> >
>
> --
> Steve Borho
>
> _______________________________________________
> x265-devel mailing list
> x265-devel at videolan.org
> https://mailman.videolan.org/listinfo/x265-devel
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/x265-devel/attachments/20150819/86e51061/attachment-0001.html>
More information about the x265-devel
mailing list