<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Feb 18, 2014 at 1:14 PM, Steve Borho <span dir="ltr"><<a href="mailto:steve@borho.org" target="_blank">steve@borho.org</a>></span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"># HG changeset patch<br>
# User Steve Borho <<a href="mailto:steve@borho.org" target="_blank">steve@borho.org</a>><br>
# Date 1392704518 21600<br>
#      Tue Feb 18 00:21:58 2014 -0600<br>
# Node ID 3512dec4936ea2d6346587ede59b61e3c5c1b3c9<br>
# Parent  8571d160aedb00e07a3f47016f04d8d9aeaa5856<br>
api: add support for float or rational FPS [API CHANGE]<br>
<br>
Since x265_param was changing anyway, I went ahead and changed inputBitDepth<br>
to internalBitDepth, which has always been its real function.<br>
<br>
X265_BUILD is bumped to 6<br>
<br>
diff -r 8571d160aedb -r 3512dec4936e source/CMakeLists.txt<br>
--- a/source/CMakeLists.txt     Tue Feb 18 01:43:42 2014 -0600<br>
+++ b/source/CMakeLists.txt     Tue Feb 18 00:21:58 2014 -0600<br>
@@ -17,7 +17,7 @@<br>
 include(CheckCXXCompilerFlag)<br>
<br>
 # X265_BUILD must be incremented each time the public API is changed<br>
-set(X265_BUILD 5)<br>
+set(X265_BUILD 6)<br>
 configure_file("${PROJECT_SOURCE_DIR}/<a href="http://x265.def.in" target="_blank">x265.def.in</a>"<br>
                "${PROJECT_BINARY_DIR}/x265.def")<br>
 configure_file("${PROJECT_SOURCE_DIR}/<a href="http://x265_config.h.in" target="_blank">x265_config.h.in</a>"<br>
diff -r 8571d160aedb -r 3512dec4936e source/Lib/TLibCommon/TComSlice.cpp<br>
--- a/source/Lib/TLibCommon/TComSlice.cpp       Tue Feb 18 01:43:42 2014 -0600<br>
+++ b/source/Lib/TLibCommon/TComSlice.cpp       Tue Feb 18 00:21:58 2014 -0600<br>
@@ -598,7 +598,7 @@<br>
     m_RPSList.create(numRPS);<br>
 }<br>
<br>
-void TComSPS::setHrdParameters(uint32_t frameRate, uint32_t numDU, uint32_t bitRate, bool randomAccess)<br>
+void TComSPS::setHrdParameters(uint32_t fpsNum, uint32_t fpsDenom, uint32_t numDU, uint32_t bitRate, bool randomAccess)<br>
 {<br>
     if (!getVuiParametersPresentFlag())<br>
     {<br>
@@ -610,33 +610,8 @@<br>
<br></blockquote><div>The encoder doesnt reach this point. VUI, pictureTimingSEI, DecodingUnitSEI are all disabled. In short, fps and other info are not encoded in the bitstream (hrdparameters is not present). <br><br>if (m_cfg->getPictureTimingSEIEnabled() || m_cfg->getDecodingUnitInfoSEIEnabled())<br>
<br></div><div>Since this is disabled?    <br></div><div> </div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
     TimingInfo *timingInfo = vui->getTimingInfo();<br>
     timingInfo->setTimingInfoPresentFlag(true);<br>
-    switch (frameRate)<br>
-    {<br>
-    case 24:<br>
-        timingInfo->setNumUnitsInTick(1125000);<br>
-        timingInfo->setTimeScale(27000000);<br>
-        break;<br>
-    case 25:<br>
-        timingInfo->setNumUnitsInTick(1080000);<br>
-        timingInfo->setTimeScale(27000000);<br>
-        break;<br>
-    case 30:<br>
-        timingInfo->setNumUnitsInTick(900900);<br>
-        timingInfo->setTimeScale(27000000);<br>
-        break;<br>
-    case 50:<br>
-        timingInfo->setNumUnitsInTick(540000);<br>
-        timingInfo->setTimeScale(27000000);<br>
-        break;<br>
-    case 60:<br>
-        timingInfo->setNumUnitsInTick(450450);<br>
-        timingInfo->setTimeScale(27000000);<br>
-        break;<br>
-    default:<br>
-        timingInfo->setNumUnitsInTick(1001);<br>
-        timingInfo->setTimeScale(60000);<br>
-        break;<br>
-    }<br>
+    timingInfo->setNumUnitsInTick(fpsDenom);<br>
+    timingInfo->setTimeScale(fpsNum);<br>
<br>
     bool rateCnt = (bitRate > 0);<br>
     hrd->setNalHrdParametersPresentFlag(rateCnt);<br>
diff -r 8571d160aedb -r 3512dec4936e source/Lib/TLibCommon/TComSlice.h<br>
--- a/source/Lib/TLibCommon/TComSlice.h Tue Feb 18 01:43:42 2014 -0600<br>
+++ b/source/Lib/TLibCommon/TComSlice.h Tue Feb 18 00:21:58 2014 -0600<br>
@@ -1053,7 +1053,7 @@<br>
<br>
     TComVUI* getVuiParameters() { return &m_vuiParameters; }<br>
<br>
-    void setHrdParameters(uint32_t frameRate, uint32_t numDU, uint32_t bitRate, bool randomAccess);<br>
+    void setHrdParameters(uint32_t fpsNum, uint32_t fpsDenom, uint32_t numDU, uint32_t bitRate, bool randomAccess);<br>
<br>
     TComPTL* getPTL() { return &m_ptl; }<br>
 };<br>
diff -r 8571d160aedb -r 3512dec4936e source/common/common.cpp<br>
--- a/source/common/common.cpp  Tue Feb 18 01:43:42 2014 -0600<br>
+++ b/source/common/common.cpp  Tue Feb 18 00:21:58 2014 -0600<br>
@@ -149,7 +149,7 @@<br>
     param->csvfn = NULL;<br>
<br>
     /* Source specifications */<br>
-    param->inputBitDepth = x265_max_bit_depth;<br>
+    param->internalBitDepth = x265_max_bit_depth;<br>
     param->internalCsp = X265_CSP_I420;<br>
<br>
     /* CU definitions */<br>
@@ -228,7 +228,7 @@<br>
 {<br>
     memset(pic, 0, sizeof(x265_picture));<br>
<br>
-    pic->bitDepth = param->inputBitDepth;<br>
+    pic->bitDepth = param->internalBitDepth;<br>
     pic->colorSpace = param->internalCsp;<br>
 }<br>
<br>
@@ -242,7 +242,7 @@<br>
     else if (!strcmp(profile, "main10"))<br>
     {<br>
 #if HIGH_BIT_DEPTH<br>
-        param->inputBitDepth = 10;<br>
+        param->internalBitDepth = 10;<br>
 #else<br>
         x265_log(param, X265_LOG_WARNING, "Main10 not supported, not compiled for 16bpp.\n");<br>
         return -1;<br>
@@ -440,16 +440,16 @@<br>
<br>
     /* These checks might be temporary */<br>
 #if HIGH_BIT_DEPTH<br>
-    CHECK(param->inputBitDepth != 10,<br>
+    CHECK(param->internalBitDepth != 10,<br>
           "x265 was compiled for 10bit encodes, only 10bit inputs supported");<br>
 #endif<br>
<br>
-    CHECK(param->inputBitDepth > x265_max_bit_depth,<br>
-          "inputBitDepth must be <= x265_max_bit_depth");<br>
-    CHECK(param->rc.qp < -6 * (param->inputBitDepth - 8) || param->rc.qp > 51,<br>
+    CHECK(param->internalBitDepth > x265_max_bit_depth,<br>
+          "internalBitDepth must be <= x265_max_bit_depth");<br>
+    CHECK(param->rc.qp < -6 * (param->internalBitDepth - 8) || param->rc.qp > 51,<br>
           "QP exceeds supported range (-QpBDOffsety to 51)");<br>
-    CHECK(param->frameRate <= 0,<br>
-          "Frame rate must be more than 1");<br>
+    CHECK(param->fpsNum == 0 || param->fpsDenom == 0,<br>
+          "Frame rate numerator and denominator must be specified");<br>
     CHECK(param->searchMethod<0 || param->searchMethod> X265_FULL_SEARCH,<br>
           "Search method is not supported value (0:DIA 1:HEX 2:UMH 3:HM 5:FULL)");<br>
     CHECK(param->searchRange < 0,<br>
@@ -537,9 +537,9 @@<br>
             x265_log(param, X265_LOG_ERROR, "maxCUSize must be the same for all encoders in a single process");<br>
             return -1;<br>
         }<br>
-        if (param->inputBitDepth != g_bitDepth)<br>
+        if (param->internalBitDepth != g_bitDepth)<br>
         {<br>
-            x265_log(param, X265_LOG_ERROR, "inputBitDepth must be the same for all encoders in a single process");<br>
+            x265_log(param, X265_LOG_ERROR, "internalBitDepth must be the same for all encoders in a single process");<br>
             return -1;<br>
         }<br>
     }<br>
@@ -548,7 +548,7 @@<br>
         // set max CU width & height<br>
         g_maxCUWidth  = param->maxCUSize;<br>
         g_maxCUHeight = param->maxCUSize;<br>
-        g_bitDepth = param->inputBitDepth;<br>
+        g_bitDepth = param->internalBitDepth;<br>
<br>
         // compute actual CU depth with respect to config depth and max transform size<br>
         g_addCUDepth = 0;<br>
@@ -577,7 +577,7 @@<br>
     if (param->logLevel < X265_LOG_INFO)<br>
         return;<br>
 #if HIGH_BIT_DEPTH<br>
-    x265_log(param, X265_LOG_INFO, "Internal bit depth                  : %d\n", param->inputBitDepth);<br>
+    x265_log(param, X265_LOG_INFO, "Internal bit depth                  : %d\n", param->internalBitDepth);<br>
 #endif<br>
     x265_log(param, X265_LOG_INFO, "CU size                             : %d\n", param->maxCUSize);<br>
     x265_log(param, X265_LOG_INFO, "Max RQT depth inter / intra         : %d / %d\n", param->tuQTMaxInterDepth, param->tuQTMaxIntraDepth);<br>
@@ -678,7 +678,25 @@<br>
 #endif<br>
 #define OPT(STR) else if (!strcmp(name, STR))<br>
     if (0) ;<br>
-    OPT("fps") p->frameRate = atoi(value);<br>
+    OPT("fps")<br>
+    {<br>
+        if (sscanf(value, "%u/%u", &p->fpsNum, &p->fpsDenom) == 2)<br>
+            ;<br>
+        else<br>
+        {<br>
+            float fps = atof(value);<br>
+            if (fps > 0 && fps <= INT_MAX/1000)<br>
+            {<br>
+                p->fpsNum = (int)(fps * 1000 + .5);<br>
+                p->fpsDenom = 1000;<br>
+            }<br>
+            else<br>
+            {<br>
+                p->fpsNum = atoi(value);<br>
+                p->fpsDenom = 1;<br>
+            }<br>
+        }<br>
+    }<br>
     OPT("csv") p->csvfn = value;<br>
     OPT("threads") p->poolNumThreads = atoi(value);<br>
     OPT("frame-threads") p->frameNumThreads = atoi(value);<br>
@@ -767,7 +785,7 @@<br>
     s += sprintf(s, " %s", (param) ? cliopt : "no-"cliopt);<br>
<br>
     BOOL(p->bEnableWavefront, "wpp");<br>
-    s += sprintf(s, " fps=%d", p->frameRate);<br>
+    s += sprintf(s, " fps=%d/%d", p->fpsNum, p->fpsDenom);<br>
     s += sprintf(s, " ctu=%d", p->maxCUSize);<br>
     s += sprintf(s, " tu-intra-depth=%d", p->tuQTMaxIntraDepth);<br>
     s += sprintf(s, " tu-inter-depth=%d", p->tuQTMaxInterDepth);<br>
diff -r 8571d160aedb -r 3512dec4936e source/encoder/encoder.cpp<br>
--- a/source/encoder/encoder.cpp        Tue Feb 18 01:43:42 2014 -0600<br>
+++ b/source/encoder/encoder.cpp        Tue Feb 18 00:21:58 2014 -0600<br>
@@ -426,7 +426,7 @@<br>
<br>
 char* Encoder::statsString(EncStats& stat, char* buffer)<br>
 {<br>
-    double fps = (double)param.frameRate;<br>
+    double fps = (double)param.fpsNum / param.fpsDenom;<br>
     double scale = fps / 1000 / (double)stat.m_numPics;<br>
<br>
     int len = sprintf(buffer, "%-6d ", stat.m_numPics);<br>
@@ -632,7 +632,7 @@<br>
         {<br>
             stats->globalSsim = m_analyzeAll.m_globalSsim / stats->encodedPictureCount;<br>
             stats->globalPsnr = (stats->globalPsnrY * 6 + stats->globalPsnrU + stats->globalPsnrV) / (8 * stats->encodedPictureCount);<br>
-            stats->elapsedVideoTime = (double)stats->encodedPictureCount / param.frameRate;<br>
+            stats->elapsedVideoTime = (double)stats->encodedPictureCount * param.fpsDenom / param.fpsNum;<br>
             stats->bitrate = (0.001f * stats->accBits) / stats->elapsedVideoTime;<br>
         }<br>
         else<br>
@@ -1142,7 +1142,7 @@<br>
     // TODO: there are minimum CTU sizes for higher levels, needs to be enforced<br>
<br>
     uint32_t lumaSamples = _param->sourceWidth * _param->sourceHeight;<br>
-    uint32_t samplesPerSec = lumaSamples * _param->frameRate;<br>
+    uint32_t samplesPerSec = lumaSamples * ((double)_param->fpsNum / _param->fpsDenom);<br>
     uint32_t bitrate = _param->rc.bitrate;<br>
<br>
     m_level = Level::LEVEL1;<br>
@@ -1242,7 +1242,7 @@<br>
         break;<br>
     }<br>
<br>
-    if (_param->inputBitDepth > 8)<br>
+    if (_param->internalBitDepth > 8)<br>
         m_profile = Profile::MAIN10;<br>
     else if (_param->keyframeMax == 1)<br>
         m_profile = Profile::MAINSTILLPICTURE;<br>
@@ -1312,7 +1312,8 @@<br>
     }<br>
     if (!_param->keyframeMin)<br>
     {<br>
-        _param->keyframeMin = X265_MIN(_param->frameRate, _param->keyframeMax / 10);<br>
+        double fps = (double)_param->fpsNum / _param->fpsDenom;<br>
+        _param->keyframeMin = X265_MIN((int)fps, _param->keyframeMax / 10);<br>
     }<br>
     _param->keyframeMin = X265_MAX(1, X265_MIN(_param->keyframeMin, _param->keyframeMax / 2 + 1));<br>
     if (!_param->bEnableRectInter)<br>
diff -r 8571d160aedb -r 3512dec4936e source/encoder/frameencoder.cpp<br>
--- a/source/encoder/frameencoder.cpp   Tue Feb 18 01:43:42 2014 -0600<br>
+++ b/source/encoder/frameencoder.cpp   Tue Feb 18 00:21:58 2014 -0600<br>
@@ -138,7 +138,7 @@<br>
     m_sps.setNumLongTermRefPicSPS(0);<br>
     if (m_cfg->getPictureTimingSEIEnabled() || m_cfg->getDecodingUnitInfoSEIEnabled())<br>
     {<br>
-        m_sps.setHrdParameters(m_cfg->param.frameRate, 0, m_cfg->param.rc.bitrate, m_cfg->param.bframes > 0);<br>
+        m_sps.setHrdParameters(m_cfg->param.fpsNum, m_cfg->param.fpsDenom, 0, m_cfg->param.rc.bitrate, m_cfg->param.bframes > 0);<br>
     }<br>
     if (m_cfg->getBufferingPeriodSEIEnabled() || m_cfg->getPictureTimingSEIEnabled() || m_cfg->getDecodingUnitInfoSEIEnabled())<br>
     {<br>
diff -r 8571d160aedb -r 3512dec4936e source/encoder/ratecontrol.cpp<br>
--- a/source/encoder/ratecontrol.cpp    Tue Feb 18 01:43:42 2014 -0600<br>
+++ b/source/encoder/ratecontrol.cpp    Tue Feb 18 00:21:58 2014 -0600<br>
@@ -229,7 +229,7 @@<br>
     isAbr = cfg->param.rc.rateControlMode != X265_RC_CQP; // later add 2pass option<br>
<br>
     bitrate = cfg->param.rc.bitrate * 1000;<br>
-    frameDuration = 1.0 / cfg->param.frameRate;<br>
+    frameDuration = (double)cfg->param.fpsDenom / cfg->param.fpsNum;<br>
     qp = cfg->param.rc.qp;<br>
     lastRceq = 1; /* handles the cmplxrsum when the previous frame cost is zero */<br>
     totalBits = 0;<br>
@@ -279,7 +279,7 @@<br>
     }<br>
<br>
     isVbv = cfg->param.rc.vbvMaxBitrate > 0 && cfg->param.rc.vbvBufferSize > 0;<br>
-    fps = cfg->param.frameRate;<br>
+    double fps = (double)cfg->param.fpsNum / cfg->param.fpsDenom;<br>
     if (isVbv)<br>
     {<br>
         /* We don't support changing the ABR bitrate right now,<br>
@@ -505,7 +505,7 @@<br>
             if (!vbvMinRate && lastSatd)<br>
             {<br>
                 /* use framesDone instead of POC as poc count is not serial with bframes enabled */<br>
-                double timeDone = (double)(framesDone - cfg->param.frameNumThreads + 1) / cfg->param.frameRate;<br>
+                double timeDone = (double)(framesDone - cfg->param.frameNumThreads + 1) * frameDuration;<br>
                 wantedBits = timeDone * bitrate;<br>
                 if (wantedBits > 0 && totalBits > 0)<br>
                 {<br>
@@ -741,9 +741,7 @@<br>
     if (cfg->param.rc.cuTree)<br>
     {<br>
         // Scale and units are obtained from rateNum and rateDenom for videos with fixed frame rates.<br>
-        double scale = cfg->param.frameRate * 2;<br>
-        double numTicks = 1;<br>
-        double timescale = numTicks / scale;<br>
+        double timescale = cfg->param.fpsDenom / (2 * cfg->param.fpsNum);<br>
         q = pow(BASE_FRAME_DURATION / CLIP_DURATION(2 * timescale), 1 - cfg->param.rc.qCompress);<br>
     }<br>
     else<br>
diff -r 8571d160aedb -r 3512dec4936e source/encoder/ratecontrol.h<br>
--- a/source/encoder/ratecontrol.h      Tue Feb 18 01:43:42 2014 -0600<br>
+++ b/source/encoder/ratecontrol.h      Tue Feb 18 00:21:58 2014 -0600<br>
@@ -92,7 +92,6 @@<br>
     double vbvMinRate;       /* in kbps */<br>
     bool singleFrameVbv;<br>
     bool isVbv;<br>
-    double fps;<br>
     Predictor pred[5];<br>
     Predictor predBfromP;<br>
     int bframes;<br>
diff -r 8571d160aedb -r 3512dec4936e source/encoder/slicetype.cpp<br>
--- a/source/encoder/slicetype.cpp      Tue Feb 18 01:43:42 2014 -0600<br>
+++ b/source/encoder/slicetype.cpp      Tue Feb 18 00:21:58 2014 -0600<br>
@@ -780,7 +780,7 @@<br>
     double totalDuration = 0.0;<br>
     for (int j = 0; j <= numframes; j++)<br>
     {<br>
-        totalDuration += 1.0 / cfg->param.frameRate;<br>
+        totalDuration += (double)cfg->param.fpsDenom / cfg->param.fpsNum;<br>
     }<br>
<br>
     double averageDuration = totalDuration / (numframes + 1);<br>
@@ -890,7 +890,7 @@<br>
     uint16_t *propagateCost = frames[b]->propagateCost;<br>
<br>
     x265_emms();<br>
-    double fpsFactor = CLIP_DURATION(1.0 / cfg->param.frameRate) / CLIP_DURATION(averageDuration);<br>
+    double fpsFactor = CLIP_DURATION((double)cfg->param.fpsDenom / cfg->param.fpsNum) / CLIP_DURATION(averageDuration);<br>
<br>
     /* For non-refferd frames the source costs are always zero, so just memset one row and re-use it. */<br>
     if (!referenced)<br>
@@ -980,7 +980,7 @@<br>
<br>
 void Lookahead::cuTreeFinish(Lowres *frame, double averageDuration, int ref0Distance)<br>
 {<br>
-    int fpsFactor = (int)(CLIP_DURATION(averageDuration) / CLIP_DURATION(1.0 / cfg->param.frameRate) * 256);<br>
+    int fpsFactor = (int)(CLIP_DURATION(averageDuration) / CLIP_DURATION((double)cfg->param.fpsDenom / cfg->param.fpsNum) * 256);<br>
     double weightdelta = 0.0;<br>
<br>
     if (ref0Distance && frame->weightedCostDelta[ref0Distance - 1] > 0)<br>
diff -r 8571d160aedb -r 3512dec4936e source/input/input.h<br>
--- a/source/input/input.h      Tue Feb 18 01:43:42 2014 -0600<br>
+++ b/source/input/input.h      Tue Feb 18 00:21:58 2014 -0600<br>
@@ -54,7 +54,7 @@<br>
<br>
     virtual void setColorSpace(int csp) = 0;<br>
<br>
-    virtual float getRate() const = 0;<br>
+    virtual void getRate(uint32_t& num, uint32_t& denom) const = 0;<br>
<br>
     virtual int getWidth() const = 0;<br>
<br>
diff -r 8571d160aedb -r 3512dec4936e source/input/y4m.h<br>
--- a/source/input/y4m.h        Tue Feb 18 01:43:42 2014 -0600<br>
+++ b/source/input/y4m.h        Tue Feb 18 00:21:58 2014 -0600<br>
@@ -81,7 +81,7 @@<br>
<br>
     void setColorSpace(int)       { /* ignore, warn */ }<br>
<br>
-    float getRate() const         { return ((float)rateNum) / rateDenom; }<br>
+    void getRate(uint32_t& num, uint32_t& denom) const { num = rateNum; denom = rateDenom; }<br>
<br>
     int getWidth() const          { return width; }<br>
<br>
diff -r 8571d160aedb -r 3512dec4936e source/input/yuv.h<br>
--- a/source/input/yuv.h        Tue Feb 18 01:43:42 2014 -0600<br>
+++ b/source/input/yuv.h        Tue Feb 18 00:21:58 2014 -0600<br>
@@ -81,7 +81,7 @@<br>
<br>
     void setBitDepth(uint32_t bitDepth)           { depth = bitDepth; }<br>
<br>
-    float getRate() const                         { return 0.0f; }<br>
+    void getRate(uint32_t&, uint32_t&) const      { }<br>
<br>
     int getWidth() const                          { return width; }<br>
<br>
diff -r 8571d160aedb -r 3512dec4936e source/output/output.cpp<br>
--- a/source/output/output.cpp  Tue Feb 18 01:43:42 2014 -0600<br>
+++ b/source/output/output.cpp  Tue Feb 18 00:21:58 2014 -0600<br>
@@ -28,12 +28,12 @@<br>
<br>
 using namespace x265;<br>
<br>
-Output* Output::open(const char *fname, int width, int height, uint32_t bitdepth, int rate, int csp)<br>
+Output* Output::open(const char *fname, int width, int height, uint32_t bitdepth, uint32_t fpsNum, uint32_t fpsDenom, int csp)<br>
 {<br>
     const char * s = strrchr(fname, '.');<br>
<br>
     if (s && !strcmp(s, ".y4m"))<br>
-        return new Y4MOutput(fname, width, height, rate, bitdepth, csp);<br>
+        return new Y4MOutput(fname, width, height, fpsNum, fpsDenom, csp);<br>
     else<br>
         return new YUVOutput(fname, width, height, bitdepth, csp);<br>
 }<br>
diff -r 8571d160aedb -r 3512dec4936e source/output/output.h<br>
--- a/source/output/output.h    Tue Feb 18 01:43:42 2014 -0600<br>
+++ b/source/output/output.h    Tue Feb 18 00:21:58 2014 -0600<br>
@@ -39,7 +39,8 @@<br>
<br>
     Output()           {}<br>
<br>
-    static Output* open(const char *fname, int width, int height, uint32_t bitdepth, int rate, int csp);<br>
+    static Output* open(const char *fname, int width, int height, uint32_t bitdepth,<br>
+                        uint32_t fpsNum, uint32_t fpsDenom, int csp);<br>
<br>
     virtual bool isFail() const = 0;<br>
<br>
diff -r 8571d160aedb -r 3512dec4936e source/output/y4m.cpp<br>
--- a/source/output/y4m.cpp     Tue Feb 18 01:43:42 2014 -0600<br>
+++ b/source/output/y4m.cpp     Tue Feb 18 00:21:58 2014 -0600<br>
@@ -30,7 +30,7 @@<br>
 using namespace x265;<br>
 using namespace std;<br>
<br>
-Y4MOutput::Y4MOutput(const char *filename, int w, int h, int rate, uint32_t depth, int csp)<br>
+Y4MOutput::Y4MOutput(const char *filename, int w, int h, uint32_t fpsNum, uint32_t fpsDenom, int csp)<br>
     : width(w)<br>
     , height(h)<br>
     , colorSpace(csp)<br>
@@ -41,21 +41,9 @@<br>
<br>
     const char *cf = (csp >= X265_CSP_I444) ? "444" : (csp >= X265_CSP_I422) ? "422" : "420";<br>
<br>
-#if HIGH_BIT_DEPTH<br>
-    if (depth > 8)<br>
-    {<br>
-        x265_log(NULL, X265_LOG_WARNING, "y4m: down-shifting reconstructed pixels to 8 bits\n");<br>
-    }<br>
-#else<br>
-    if (depth > 8)<br>
-    {<br>
-        x265_log(NULL, X265_LOG_WARNING, "y4m: forcing reconstructed pixels to 8 bits\n");<br>
-    }<br>
-#endif<br>
-<br>
     if (ofs)<br>
     {<br>
-        ofs << "YUV4MPEG2 W" << width << " H" << height << " F" << rate << ":1 Ip" << " C" << cf << "\n";<br>


+        ofs << "YUV4MPEG2 W" << width << " H" << height << " F" << fpsNum << ":" << fpsDenom << " Ip" << " C" << cf << "\n";<br>


         header = ofs.tellp();<br>
     }<br>
<br>
@@ -80,6 +68,18 @@<br>
     ofs << "FRAME\n";<br>
<br>
 #if HIGH_BIT_DEPTH<br>
+    if (pic.bitDepth > 8 && pic.poc == 0)<br>
+    {<br>
+        x265_log(NULL, X265_LOG_WARNING, "y4m: down-shifting reconstructed pixels to 8 bits\n");<br>
+    }<br>
+#else<br>
+    if (pic.bitDepth > 8 && pic.poc == 0)<br>
+    {<br>
+        x265_log(NULL, X265_LOG_WARNING, "y4m: forcing reconstructed pixels to 8 bits\n");<br>
+    }<br>
+#endif<br>
+<br>
+#if HIGH_BIT_DEPTH<br>
     // encoder gave us short pixels, downshift, then write<br>
     int shift = pic.bitDepth - 8;<br>
     for (int i = 0; i < x265_cli_csps[colorSpace].planes; i++)<br>
diff -r 8571d160aedb -r 3512dec4936e source/output/y4m.h<br>
--- a/source/output/y4m.h       Tue Feb 18 01:43:42 2014 -0600<br>
+++ b/source/output/y4m.h       Tue Feb 18 00:21:58 2014 -0600<br>
@@ -52,7 +52,7 @@<br>
<br>
 public:<br>
<br>
-    Y4MOutput(const char *filename, int width, int height, int rate, uint32_t depth, int csp);<br>
+    Y4MOutput(const char *filename, int width, int height, uint32_t fpsNum, uint32_t fpsDenom, int csp);<br>
<br>
     virtual ~Y4MOutput();<br>
<br>
diff -r 8571d160aedb -r 3512dec4936e source/x265.cpp<br>
--- a/source/x265.cpp   Tue Feb 18 01:43:42 2014 -0600<br>
+++ b/source/x265.cpp   Tue Feb 18 00:21:58 2014 -0600<br>
@@ -177,6 +177,7 @@<br>
<br>
     int64_t startTime;<br>
     int64_t prevUpdateTime;<br>
+    float   frameRate;<br>
<br>
     /* in microseconds */<br>
     static const int UPDATE_INTERVAL = 250000;<br>
@@ -225,29 +226,29 @@<br>
 void CLIOptions::printStatus(uint32_t frameNum, x265_param *param)<br>
 {<br>
     char buf[200];<br>
-    int64_t i_time = x265_mdate();<br>
+    int64_t time = x265_mdate();<br>
<br>
-    if (!bProgress || !frameNum || (prevUpdateTime && i_time - prevUpdateTime < UPDATE_INTERVAL))<br>
+    if (!bProgress || !frameNum || (prevUpdateTime && time - prevUpdateTime < UPDATE_INTERVAL))<br>
         return;<br>
-    int64_t i_elapsed = i_time - startTime;<br>
-    double fps = i_elapsed > 0 ? frameNum * 1000000. / i_elapsed : 0;<br>
+    int64_t elapsed = time - startTime;<br>
+    double fps = elapsed > 0 ? frameNum * 1000000. / elapsed : 0;<br>
     if (framesToBeEncoded)<br>
     {<br>
-        float bitrate = 0.008f * totalbytes / ((float)frameNum / param->frameRate);<br>
-        int eta = (int)(i_elapsed * (framesToBeEncoded - frameNum) / ((int64_t)frameNum * 1000000));<br>
+        float bitrate = 0.008f * totalbytes / ((float)frameNum / ((float)param->fpsNum / param->fpsDenom));<br>
+        int eta = (int)(elapsed * (framesToBeEncoded - frameNum) / ((int64_t)frameNum * 1000000));<br>
         sprintf(buf, "x265 [%.1f%%] %d/%d frames, %.2f fps, %.2f kb/s, eta %d:%02d:%02d",<br>
                 100. * frameNum / framesToBeEncoded, frameNum, framesToBeEncoded, fps, bitrate,<br>
                 eta / 3600, (eta / 60) % 60, eta % 60);<br>
     }<br>
     else<br>
     {<br>
-        double bitrate = (double)totalbytes * 8 / ((double)1000 * param->frameRate);<br>
+        float bitrate = (float)totalbytes * 8 / ((float)1000 * param->fpsNum / param->fpsDenom);<br>
         sprintf(buf, "x265 %d frames: %.2f fps, %.2f kb/s", frameNum, fps, bitrate);<br>
     }<br>
     fprintf(stderr, "%s  \r", buf + 5);<br>
     SetConsoleTitle(buf);<br>
     fflush(stderr); // needed in windows<br>
-    prevUpdateTime = i_time;<br>
+    prevUpdateTime = time;<br>
 }<br>
<br>
 void CLIOptions::printVersion(x265_param *param)<br>
@@ -285,7 +286,7 @@<br>
     H0("   --input-depth                 Bit-depth of input file. Default 8\n");<br>
     H0("   --input-res                   Source picture size [w x h], auto-detected if Y4M\n");<br>
     H0("   --input-csp                   Source color space parameter, auto-detected if Y4M. 1:i420 3:i444. Default: 1\n");<br>
-    H0("   --fps                         Source frame rate, auto-detected if Y4M\n");<br>
+    H0("   --fps                         Source frame rate (float or num/denom), auto-detected if Y4M\n");<br>
     H0("   --frame-skip                  Number of frames to skip at start of input file\n");<br>
     H0("-f/--frames                      Number of frames to be encoded. Default all\n");<br>
     H0("\nQuad-Tree analysis:\n");<br>
@@ -364,7 +365,6 @@<br>
     const char *inputfn = NULL;<br>
     const char *reconfn = NULL;<br>
     const char *bitstreamfn = NULL;<br>
-    const char *inputRes = NULL;<br>
     const char *preset = "medium";<br>
     const char *tune = "ssim";<br>
<br>
@@ -443,9 +443,9 @@<br>
             OPT("output") bitstreamfn = optarg;<br>
             OPT("input") inputfn = optarg;<br>
             OPT("recon") reconfn = optarg;<br>
+            OPT("input-res") berror |= sscanf(optarg, "%dx%d", &param->sourceWidth, &param->sourceHeight) != 2;<br>
             OPT("input-depth") inputBitDepth = (uint32_t)atoi(optarg);<br>
             OPT("recon-depth") reconFileBitDepth = (uint32_t)atoi(optarg);<br>
-            OPT("input-res") inputRes = optarg;<br>
             OPT("no-scenecut") param->scenecutThreshold = 0; // special handling<br>
             OPT("y4m") bForceY4m = true;<br>
             OPT("preset") ;<br>
@@ -493,13 +493,11 @@<br>
         param->internalCsp = this->input->getColorSpace();<br>
         param->sourceWidth = this->input->getWidth();<br>
         param->sourceHeight = this->input->getHeight();<br>
-        param->frameRate = (int)this->input->getRate();<br>
+        this->input->getRate(param->fpsNum, param->fpsDenom);<br>
     }<br>
     else<br>
     {<br>
-        if (inputRes)<br>
-            sscanf(inputRes, "%dx%d", &param->sourceWidth, &param->sourceHeight);<br>
-        if (param->sourceHeight <= 0 || param->sourceWidth <= 0 || param->frameRate <= 0)<br>
+        if (param->sourceHeight <= 0 || param->sourceWidth <= 0 || param->fpsNum == 0 || param->fpsDenom == 0)<br>
         {<br>
             x265_log(param, X265_LOG_ERROR, "YUV input requires --input-res WxH and --fps N to be specified\n");<br>
             return true;<br>
@@ -534,12 +532,12 @@<br>
     if (param->logLevel >= X265_LOG_INFO)<br>
     {<br>
         if (this->framesToBeEncoded == 0)<br>
-            fprintf(stderr, "%s  [info]: %dx%d %dHz %s, unknown frame count\n", input->getName(),<br>
-                    param->sourceWidth, param->sourceHeight, param->frameRate,<br>
+            fprintf(stderr, "%s  [info]: %dx%d %d/%d fps %s, unknown frame count\n", input->getName(),<br>
+                    param->sourceWidth, param->sourceHeight, param->fpsNum, param->fpsDenom,<br>
                     x265_source_csp_names[param->internalCsp]);<br>
         else<br>
-            fprintf(stderr, "%s  [info]: %dx%d %dHz %s, frames %u - %d of %d\n", input->getName(),<br>
-                    param->sourceWidth, param->sourceHeight, param->frameRate,<br>
+            fprintf(stderr, "%s  [info]: %dx%d %d/%d fps %s, frames %u - %d of %d\n", input->getName(),<br>
+                    param->sourceWidth, param->sourceHeight, param->fpsNum, param->fpsDenom,<br>
                     x265_source_csp_names[param->internalCsp],<br>
                     this->frameSkip, this->frameSkip + this->framesToBeEncoded - 1, fileFrameCount);<br>
     }<br>
@@ -549,8 +547,9 @@<br>
     if (reconfn)<br>
     {<br>
         if (reconFileBitDepth == 0)<br>
-            reconFileBitDepth = param->inputBitDepth;<br>
-        this->recon = Output::open(reconfn, param->sourceWidth, param->sourceHeight, reconFileBitDepth, param->frameRate, param->internalCsp);<br>
+            reconFileBitDepth = param->internalBitDepth;<br>
+        this->recon = Output::open(reconfn, param->sourceWidth, param->sourceHeight, reconFileBitDepth,<br>
+                                   param->fpsNum, param->fpsDenom, param->internalCsp);<br>
         if (this->recon->isFail())<br>
         {<br>
             x265_log(param, X265_LOG_WARNING, "unable to write reconstruction file\n");<br>
@@ -560,13 +559,13 @@<br>
     }<br>
<br>
 #if HIGH_BIT_DEPTH<br>
-    if (param->inputBitDepth != 10)<br>
+    if (param->internalBitDepth != 10)<br>
     {<br>
         x265_log(param, X265_LOG_ERROR, "Only bit depths of 10 are supported in this build\n");<br>
         return true;<br>
     }<br>
 #else<br>
-    if (param->inputBitDepth != 8)<br>
+    if (param->internalBitDepth != 8)<br>
     {<br>
         x265_log(param, X265_LOG_ERROR, "Only bit depths of 8 are supported in this build\n");<br>
         return true;<br>
diff -r 8571d160aedb -r 3512dec4936e source/x265.h<br>
--- a/source/x265.h     Tue Feb 18 01:43:42 2014 -0600<br>
+++ b/source/x265.h     Tue Feb 18 00:21:58 2014 -0600<br>
@@ -337,7 +337,7 @@<br>
     /* Internal encoder bit depth. If x265 was compiled to use 8bit pixels<br>
      * (HIGH_BIT_DEPTH=0), this field must be 8, else this field must be 10.<br>
      * Future builds may support 12bit pixels. */<br>
-    int       inputBitDepth;<br>
+    int       internalBitDepth;<br>
<br>
     /* Color space of internal pictures. Only X265_CSP_I420 and X265_CSP_I444<br>
      * are supported.  Eventually, i422 will also be supported as an internal<br>
@@ -345,8 +345,9 @@<br>
      * x265_picture.colorSpace */<br>
     int       internalCsp;<br>
<br>
-    /* Frame rate of source pictures */<br>
-    int       frameRate;<br>
+    /* Numerator and denominator of frame rate */<br>
+    uint32_t  fpsNum;<br>
+    uint32_t  fpsDenom;<br>
<br>
     /* Width (in pixels) of the source pictures. If this width is not an even<br>
      * multiple of 4, the encoder will pad the pictures internally to meet this<br>
_______________________________________________<br>
x265-devel mailing list<br>
<a href="mailto:x265-devel@videolan.org" target="_blank">x265-devel@videolan.org</a><br>
<a href="https://mailman.videolan.org/listinfo/x265-devel" target="_blank">https://mailman.videolan.org/listinfo/x265-devel</a><br>
</blockquote></div><br></div></div>