[x265] [PATCH RFC] api: add support for float or rational FPS [API CHANGE]
Steve Borho
steve at borho.org
Tue Feb 18 08:44:13 CET 2014
# HG changeset patch
# User Steve Borho <steve at borho.org>
# Date 1392704518 21600
# Tue Feb 18 00:21:58 2014 -0600
# Node ID 3512dec4936ea2d6346587ede59b61e3c5c1b3c9
# Parent 8571d160aedb00e07a3f47016f04d8d9aeaa5856
api: add support for float or rational FPS [API CHANGE]
Since x265_param was changing anyway, I went ahead and changed inputBitDepth
to internalBitDepth, which has always been its real function.
X265_BUILD is bumped to 6
diff -r 8571d160aedb -r 3512dec4936e source/CMakeLists.txt
--- a/source/CMakeLists.txt Tue Feb 18 01:43:42 2014 -0600
+++ b/source/CMakeLists.txt Tue Feb 18 00:21:58 2014 -0600
@@ -17,7 +17,7 @@
include(CheckCXXCompilerFlag)
# X265_BUILD must be incremented each time the public API is changed
-set(X265_BUILD 5)
+set(X265_BUILD 6)
configure_file("${PROJECT_SOURCE_DIR}/x265.def.in"
"${PROJECT_BINARY_DIR}/x265.def")
configure_file("${PROJECT_SOURCE_DIR}/x265_config.h.in"
diff -r 8571d160aedb -r 3512dec4936e source/Lib/TLibCommon/TComSlice.cpp
--- a/source/Lib/TLibCommon/TComSlice.cpp Tue Feb 18 01:43:42 2014 -0600
+++ b/source/Lib/TLibCommon/TComSlice.cpp Tue Feb 18 00:21:58 2014 -0600
@@ -598,7 +598,7 @@
m_RPSList.create(numRPS);
}
-void TComSPS::setHrdParameters(uint32_t frameRate, uint32_t numDU, uint32_t bitRate, bool randomAccess)
+void TComSPS::setHrdParameters(uint32_t fpsNum, uint32_t fpsDenom, uint32_t numDU, uint32_t bitRate, bool randomAccess)
{
if (!getVuiParametersPresentFlag())
{
@@ -610,33 +610,8 @@
TimingInfo *timingInfo = vui->getTimingInfo();
timingInfo->setTimingInfoPresentFlag(true);
- switch (frameRate)
- {
- case 24:
- timingInfo->setNumUnitsInTick(1125000);
- timingInfo->setTimeScale(27000000);
- break;
- case 25:
- timingInfo->setNumUnitsInTick(1080000);
- timingInfo->setTimeScale(27000000);
- break;
- case 30:
- timingInfo->setNumUnitsInTick(900900);
- timingInfo->setTimeScale(27000000);
- break;
- case 50:
- timingInfo->setNumUnitsInTick(540000);
- timingInfo->setTimeScale(27000000);
- break;
- case 60:
- timingInfo->setNumUnitsInTick(450450);
- timingInfo->setTimeScale(27000000);
- break;
- default:
- timingInfo->setNumUnitsInTick(1001);
- timingInfo->setTimeScale(60000);
- break;
- }
+ timingInfo->setNumUnitsInTick(fpsDenom);
+ timingInfo->setTimeScale(fpsNum);
bool rateCnt = (bitRate > 0);
hrd->setNalHrdParametersPresentFlag(rateCnt);
diff -r 8571d160aedb -r 3512dec4936e source/Lib/TLibCommon/TComSlice.h
--- a/source/Lib/TLibCommon/TComSlice.h Tue Feb 18 01:43:42 2014 -0600
+++ b/source/Lib/TLibCommon/TComSlice.h Tue Feb 18 00:21:58 2014 -0600
@@ -1053,7 +1053,7 @@
TComVUI* getVuiParameters() { return &m_vuiParameters; }
- void setHrdParameters(uint32_t frameRate, uint32_t numDU, uint32_t bitRate, bool randomAccess);
+ void setHrdParameters(uint32_t fpsNum, uint32_t fpsDenom, uint32_t numDU, uint32_t bitRate, bool randomAccess);
TComPTL* getPTL() { return &m_ptl; }
};
diff -r 8571d160aedb -r 3512dec4936e source/common/common.cpp
--- a/source/common/common.cpp Tue Feb 18 01:43:42 2014 -0600
+++ b/source/common/common.cpp Tue Feb 18 00:21:58 2014 -0600
@@ -149,7 +149,7 @@
param->csvfn = NULL;
/* Source specifications */
- param->inputBitDepth = x265_max_bit_depth;
+ param->internalBitDepth = x265_max_bit_depth;
param->internalCsp = X265_CSP_I420;
/* CU definitions */
@@ -228,7 +228,7 @@
{
memset(pic, 0, sizeof(x265_picture));
- pic->bitDepth = param->inputBitDepth;
+ pic->bitDepth = param->internalBitDepth;
pic->colorSpace = param->internalCsp;
}
@@ -242,7 +242,7 @@
else if (!strcmp(profile, "main10"))
{
#if HIGH_BIT_DEPTH
- param->inputBitDepth = 10;
+ param->internalBitDepth = 10;
#else
x265_log(param, X265_LOG_WARNING, "Main10 not supported, not compiled for 16bpp.\n");
return -1;
@@ -440,16 +440,16 @@
/* These checks might be temporary */
#if HIGH_BIT_DEPTH
- CHECK(param->inputBitDepth != 10,
+ CHECK(param->internalBitDepth != 10,
"x265 was compiled for 10bit encodes, only 10bit inputs supported");
#endif
- CHECK(param->inputBitDepth > x265_max_bit_depth,
- "inputBitDepth must be <= x265_max_bit_depth");
- CHECK(param->rc.qp < -6 * (param->inputBitDepth - 8) || param->rc.qp > 51,
+ CHECK(param->internalBitDepth > x265_max_bit_depth,
+ "internalBitDepth must be <= x265_max_bit_depth");
+ CHECK(param->rc.qp < -6 * (param->internalBitDepth - 8) || param->rc.qp > 51,
"QP exceeds supported range (-QpBDOffsety to 51)");
- CHECK(param->frameRate <= 0,
- "Frame rate must be more than 1");
+ CHECK(param->fpsNum == 0 || param->fpsDenom == 0,
+ "Frame rate numerator and denominator must be specified");
CHECK(param->searchMethod<0 || param->searchMethod> X265_FULL_SEARCH,
"Search method is not supported value (0:DIA 1:HEX 2:UMH 3:HM 5:FULL)");
CHECK(param->searchRange < 0,
@@ -537,9 +537,9 @@
x265_log(param, X265_LOG_ERROR, "maxCUSize must be the same for all encoders in a single process");
return -1;
}
- if (param->inputBitDepth != g_bitDepth)
+ if (param->internalBitDepth != g_bitDepth)
{
- x265_log(param, X265_LOG_ERROR, "inputBitDepth must be the same for all encoders in a single process");
+ x265_log(param, X265_LOG_ERROR, "internalBitDepth must be the same for all encoders in a single process");
return -1;
}
}
@@ -548,7 +548,7 @@
// set max CU width & height
g_maxCUWidth = param->maxCUSize;
g_maxCUHeight = param->maxCUSize;
- g_bitDepth = param->inputBitDepth;
+ g_bitDepth = param->internalBitDepth;
// compute actual CU depth with respect to config depth and max transform size
g_addCUDepth = 0;
@@ -577,7 +577,7 @@
if (param->logLevel < X265_LOG_INFO)
return;
#if HIGH_BIT_DEPTH
- x265_log(param, X265_LOG_INFO, "Internal bit depth : %d\n", param->inputBitDepth);
+ x265_log(param, X265_LOG_INFO, "Internal bit depth : %d\n", param->internalBitDepth);
#endif
x265_log(param, X265_LOG_INFO, "CU size : %d\n", param->maxCUSize);
x265_log(param, X265_LOG_INFO, "Max RQT depth inter / intra : %d / %d\n", param->tuQTMaxInterDepth, param->tuQTMaxIntraDepth);
@@ -678,7 +678,25 @@
#endif
#define OPT(STR) else if (!strcmp(name, STR))
if (0) ;
- OPT("fps") p->frameRate = atoi(value);
+ OPT("fps")
+ {
+ if (sscanf(value, "%u/%u", &p->fpsNum, &p->fpsDenom) == 2)
+ ;
+ else
+ {
+ float fps = atof(value);
+ if (fps > 0 && fps <= INT_MAX/1000)
+ {
+ p->fpsNum = (int)(fps * 1000 + .5);
+ p->fpsDenom = 1000;
+ }
+ else
+ {
+ p->fpsNum = atoi(value);
+ p->fpsDenom = 1;
+ }
+ }
+ }
OPT("csv") p->csvfn = value;
OPT("threads") p->poolNumThreads = atoi(value);
OPT("frame-threads") p->frameNumThreads = atoi(value);
@@ -767,7 +785,7 @@
s += sprintf(s, " %s", (param) ? cliopt : "no-"cliopt);
BOOL(p->bEnableWavefront, "wpp");
- s += sprintf(s, " fps=%d", p->frameRate);
+ s += sprintf(s, " fps=%d/%d", p->fpsNum, p->fpsDenom);
s += sprintf(s, " ctu=%d", p->maxCUSize);
s += sprintf(s, " tu-intra-depth=%d", p->tuQTMaxIntraDepth);
s += sprintf(s, " tu-inter-depth=%d", p->tuQTMaxInterDepth);
diff -r 8571d160aedb -r 3512dec4936e source/encoder/encoder.cpp
--- a/source/encoder/encoder.cpp Tue Feb 18 01:43:42 2014 -0600
+++ b/source/encoder/encoder.cpp Tue Feb 18 00:21:58 2014 -0600
@@ -426,7 +426,7 @@
char* Encoder::statsString(EncStats& stat, char* buffer)
{
- double fps = (double)param.frameRate;
+ double fps = (double)param.fpsNum / param.fpsDenom;
double scale = fps / 1000 / (double)stat.m_numPics;
int len = sprintf(buffer, "%-6d ", stat.m_numPics);
@@ -632,7 +632,7 @@
{
stats->globalSsim = m_analyzeAll.m_globalSsim / stats->encodedPictureCount;
stats->globalPsnr = (stats->globalPsnrY * 6 + stats->globalPsnrU + stats->globalPsnrV) / (8 * stats->encodedPictureCount);
- stats->elapsedVideoTime = (double)stats->encodedPictureCount / param.frameRate;
+ stats->elapsedVideoTime = (double)stats->encodedPictureCount * param.fpsDenom / param.fpsNum;
stats->bitrate = (0.001f * stats->accBits) / stats->elapsedVideoTime;
}
else
@@ -1142,7 +1142,7 @@
// TODO: there are minimum CTU sizes for higher levels, needs to be enforced
uint32_t lumaSamples = _param->sourceWidth * _param->sourceHeight;
- uint32_t samplesPerSec = lumaSamples * _param->frameRate;
+ uint32_t samplesPerSec = lumaSamples * ((double)_param->fpsNum / _param->fpsDenom);
uint32_t bitrate = _param->rc.bitrate;
m_level = Level::LEVEL1;
@@ -1242,7 +1242,7 @@
break;
}
- if (_param->inputBitDepth > 8)
+ if (_param->internalBitDepth > 8)
m_profile = Profile::MAIN10;
else if (_param->keyframeMax == 1)
m_profile = Profile::MAINSTILLPICTURE;
@@ -1312,7 +1312,8 @@
}
if (!_param->keyframeMin)
{
- _param->keyframeMin = X265_MIN(_param->frameRate, _param->keyframeMax / 10);
+ double fps = (double)_param->fpsNum / _param->fpsDenom;
+ _param->keyframeMin = X265_MIN((int)fps, _param->keyframeMax / 10);
}
_param->keyframeMin = X265_MAX(1, X265_MIN(_param->keyframeMin, _param->keyframeMax / 2 + 1));
if (!_param->bEnableRectInter)
diff -r 8571d160aedb -r 3512dec4936e source/encoder/frameencoder.cpp
--- a/source/encoder/frameencoder.cpp Tue Feb 18 01:43:42 2014 -0600
+++ b/source/encoder/frameencoder.cpp Tue Feb 18 00:21:58 2014 -0600
@@ -138,7 +138,7 @@
m_sps.setNumLongTermRefPicSPS(0);
if (m_cfg->getPictureTimingSEIEnabled() || m_cfg->getDecodingUnitInfoSEIEnabled())
{
- m_sps.setHrdParameters(m_cfg->param.frameRate, 0, m_cfg->param.rc.bitrate, m_cfg->param.bframes > 0);
+ m_sps.setHrdParameters(m_cfg->param.fpsNum, m_cfg->param.fpsDenom, 0, m_cfg->param.rc.bitrate, m_cfg->param.bframes > 0);
}
if (m_cfg->getBufferingPeriodSEIEnabled() || m_cfg->getPictureTimingSEIEnabled() || m_cfg->getDecodingUnitInfoSEIEnabled())
{
diff -r 8571d160aedb -r 3512dec4936e source/encoder/ratecontrol.cpp
--- a/source/encoder/ratecontrol.cpp Tue Feb 18 01:43:42 2014 -0600
+++ b/source/encoder/ratecontrol.cpp Tue Feb 18 00:21:58 2014 -0600
@@ -229,7 +229,7 @@
isAbr = cfg->param.rc.rateControlMode != X265_RC_CQP; // later add 2pass option
bitrate = cfg->param.rc.bitrate * 1000;
- frameDuration = 1.0 / cfg->param.frameRate;
+ frameDuration = (double)cfg->param.fpsDenom / cfg->param.fpsNum;
qp = cfg->param.rc.qp;
lastRceq = 1; /* handles the cmplxrsum when the previous frame cost is zero */
totalBits = 0;
@@ -279,7 +279,7 @@
}
isVbv = cfg->param.rc.vbvMaxBitrate > 0 && cfg->param.rc.vbvBufferSize > 0;
- fps = cfg->param.frameRate;
+ double fps = (double)cfg->param.fpsNum / cfg->param.fpsDenom;
if (isVbv)
{
/* We don't support changing the ABR bitrate right now,
@@ -505,7 +505,7 @@
if (!vbvMinRate && lastSatd)
{
/* use framesDone instead of POC as poc count is not serial with bframes enabled */
- double timeDone = (double)(framesDone - cfg->param.frameNumThreads + 1) / cfg->param.frameRate;
+ double timeDone = (double)(framesDone - cfg->param.frameNumThreads + 1) * frameDuration;
wantedBits = timeDone * bitrate;
if (wantedBits > 0 && totalBits > 0)
{
@@ -741,9 +741,7 @@
if (cfg->param.rc.cuTree)
{
// Scale and units are obtained from rateNum and rateDenom for videos with fixed frame rates.
- double scale = cfg->param.frameRate * 2;
- double numTicks = 1;
- double timescale = numTicks / scale;
+ double timescale = cfg->param.fpsDenom / (2 * cfg->param.fpsNum);
q = pow(BASE_FRAME_DURATION / CLIP_DURATION(2 * timescale), 1 - cfg->param.rc.qCompress);
}
else
diff -r 8571d160aedb -r 3512dec4936e source/encoder/ratecontrol.h
--- a/source/encoder/ratecontrol.h Tue Feb 18 01:43:42 2014 -0600
+++ b/source/encoder/ratecontrol.h Tue Feb 18 00:21:58 2014 -0600
@@ -92,7 +92,6 @@
double vbvMinRate; /* in kbps */
bool singleFrameVbv;
bool isVbv;
- double fps;
Predictor pred[5];
Predictor predBfromP;
int bframes;
diff -r 8571d160aedb -r 3512dec4936e source/encoder/slicetype.cpp
--- a/source/encoder/slicetype.cpp Tue Feb 18 01:43:42 2014 -0600
+++ b/source/encoder/slicetype.cpp Tue Feb 18 00:21:58 2014 -0600
@@ -780,7 +780,7 @@
double totalDuration = 0.0;
for (int j = 0; j <= numframes; j++)
{
- totalDuration += 1.0 / cfg->param.frameRate;
+ totalDuration += (double)cfg->param.fpsDenom / cfg->param.fpsNum;
}
double averageDuration = totalDuration / (numframes + 1);
@@ -890,7 +890,7 @@
uint16_t *propagateCost = frames[b]->propagateCost;
x265_emms();
- double fpsFactor = CLIP_DURATION(1.0 / cfg->param.frameRate) / CLIP_DURATION(averageDuration);
+ double fpsFactor = CLIP_DURATION((double)cfg->param.fpsDenom / cfg->param.fpsNum) / CLIP_DURATION(averageDuration);
/* For non-refferd frames the source costs are always zero, so just memset one row and re-use it. */
if (!referenced)
@@ -980,7 +980,7 @@
void Lookahead::cuTreeFinish(Lowres *frame, double averageDuration, int ref0Distance)
{
- int fpsFactor = (int)(CLIP_DURATION(averageDuration) / CLIP_DURATION(1.0 / cfg->param.frameRate) * 256);
+ int fpsFactor = (int)(CLIP_DURATION(averageDuration) / CLIP_DURATION((double)cfg->param.fpsDenom / cfg->param.fpsNum) * 256);
double weightdelta = 0.0;
if (ref0Distance && frame->weightedCostDelta[ref0Distance - 1] > 0)
diff -r 8571d160aedb -r 3512dec4936e source/input/input.h
--- a/source/input/input.h Tue Feb 18 01:43:42 2014 -0600
+++ b/source/input/input.h Tue Feb 18 00:21:58 2014 -0600
@@ -54,7 +54,7 @@
virtual void setColorSpace(int csp) = 0;
- virtual float getRate() const = 0;
+ virtual void getRate(uint32_t& num, uint32_t& denom) const = 0;
virtual int getWidth() const = 0;
diff -r 8571d160aedb -r 3512dec4936e source/input/y4m.h
--- a/source/input/y4m.h Tue Feb 18 01:43:42 2014 -0600
+++ b/source/input/y4m.h Tue Feb 18 00:21:58 2014 -0600
@@ -81,7 +81,7 @@
void setColorSpace(int) { /* ignore, warn */ }
- float getRate() const { return ((float)rateNum) / rateDenom; }
+ void getRate(uint32_t& num, uint32_t& denom) const { num = rateNum; denom = rateDenom; }
int getWidth() const { return width; }
diff -r 8571d160aedb -r 3512dec4936e source/input/yuv.h
--- a/source/input/yuv.h Tue Feb 18 01:43:42 2014 -0600
+++ b/source/input/yuv.h Tue Feb 18 00:21:58 2014 -0600
@@ -81,7 +81,7 @@
void setBitDepth(uint32_t bitDepth) { depth = bitDepth; }
- float getRate() const { return 0.0f; }
+ void getRate(uint32_t&, uint32_t&) const { }
int getWidth() const { return width; }
diff -r 8571d160aedb -r 3512dec4936e source/output/output.cpp
--- a/source/output/output.cpp Tue Feb 18 01:43:42 2014 -0600
+++ b/source/output/output.cpp Tue Feb 18 00:21:58 2014 -0600
@@ -28,12 +28,12 @@
using namespace x265;
-Output* Output::open(const char *fname, int width, int height, uint32_t bitdepth, int rate, int csp)
+Output* Output::open(const char *fname, int width, int height, uint32_t bitdepth, uint32_t fpsNum, uint32_t fpsDenom, int csp)
{
const char * s = strrchr(fname, '.');
if (s && !strcmp(s, ".y4m"))
- return new Y4MOutput(fname, width, height, rate, bitdepth, csp);
+ return new Y4MOutput(fname, width, height, fpsNum, fpsDenom, csp);
else
return new YUVOutput(fname, width, height, bitdepth, csp);
}
diff -r 8571d160aedb -r 3512dec4936e source/output/output.h
--- a/source/output/output.h Tue Feb 18 01:43:42 2014 -0600
+++ b/source/output/output.h Tue Feb 18 00:21:58 2014 -0600
@@ -39,7 +39,8 @@
Output() {}
- static Output* open(const char *fname, int width, int height, uint32_t bitdepth, int rate, int csp);
+ static Output* open(const char *fname, int width, int height, uint32_t bitdepth,
+ uint32_t fpsNum, uint32_t fpsDenom, int csp);
virtual bool isFail() const = 0;
diff -r 8571d160aedb -r 3512dec4936e source/output/y4m.cpp
--- a/source/output/y4m.cpp Tue Feb 18 01:43:42 2014 -0600
+++ b/source/output/y4m.cpp Tue Feb 18 00:21:58 2014 -0600
@@ -30,7 +30,7 @@
using namespace x265;
using namespace std;
-Y4MOutput::Y4MOutput(const char *filename, int w, int h, int rate, uint32_t depth, int csp)
+Y4MOutput::Y4MOutput(const char *filename, int w, int h, uint32_t fpsNum, uint32_t fpsDenom, int csp)
: width(w)
, height(h)
, colorSpace(csp)
@@ -41,21 +41,9 @@
const char *cf = (csp >= X265_CSP_I444) ? "444" : (csp >= X265_CSP_I422) ? "422" : "420";
-#if HIGH_BIT_DEPTH
- if (depth > 8)
- {
- x265_log(NULL, X265_LOG_WARNING, "y4m: down-shifting reconstructed pixels to 8 bits\n");
- }
-#else
- if (depth > 8)
- {
- x265_log(NULL, X265_LOG_WARNING, "y4m: forcing reconstructed pixels to 8 bits\n");
- }
-#endif
-
if (ofs)
{
- ofs << "YUV4MPEG2 W" << width << " H" << height << " F" << rate << ":1 Ip" << " C" << cf << "\n";
+ ofs << "YUV4MPEG2 W" << width << " H" << height << " F" << fpsNum << ":" << fpsDenom << " Ip" << " C" << cf << "\n";
header = ofs.tellp();
}
@@ -80,6 +68,18 @@
ofs << "FRAME\n";
#if HIGH_BIT_DEPTH
+ if (pic.bitDepth > 8 && pic.poc == 0)
+ {
+ x265_log(NULL, X265_LOG_WARNING, "y4m: down-shifting reconstructed pixels to 8 bits\n");
+ }
+#else
+ if (pic.bitDepth > 8 && pic.poc == 0)
+ {
+ x265_log(NULL, X265_LOG_WARNING, "y4m: forcing reconstructed pixels to 8 bits\n");
+ }
+#endif
+
+#if HIGH_BIT_DEPTH
// encoder gave us short pixels, downshift, then write
int shift = pic.bitDepth - 8;
for (int i = 0; i < x265_cli_csps[colorSpace].planes; i++)
diff -r 8571d160aedb -r 3512dec4936e source/output/y4m.h
--- a/source/output/y4m.h Tue Feb 18 01:43:42 2014 -0600
+++ b/source/output/y4m.h Tue Feb 18 00:21:58 2014 -0600
@@ -52,7 +52,7 @@
public:
- Y4MOutput(const char *filename, int width, int height, int rate, uint32_t depth, int csp);
+ Y4MOutput(const char *filename, int width, int height, uint32_t fpsNum, uint32_t fpsDenom, int csp);
virtual ~Y4MOutput();
diff -r 8571d160aedb -r 3512dec4936e source/x265.cpp
--- a/source/x265.cpp Tue Feb 18 01:43:42 2014 -0600
+++ b/source/x265.cpp Tue Feb 18 00:21:58 2014 -0600
@@ -177,6 +177,7 @@
int64_t startTime;
int64_t prevUpdateTime;
+ float frameRate;
/* in microseconds */
static const int UPDATE_INTERVAL = 250000;
@@ -225,29 +226,29 @@
void CLIOptions::printStatus(uint32_t frameNum, x265_param *param)
{
char buf[200];
- int64_t i_time = x265_mdate();
+ int64_t time = x265_mdate();
- if (!bProgress || !frameNum || (prevUpdateTime && i_time - prevUpdateTime < UPDATE_INTERVAL))
+ if (!bProgress || !frameNum || (prevUpdateTime && time - prevUpdateTime < UPDATE_INTERVAL))
return;
- int64_t i_elapsed = i_time - startTime;
- double fps = i_elapsed > 0 ? frameNum * 1000000. / i_elapsed : 0;
+ int64_t elapsed = time - startTime;
+ double fps = elapsed > 0 ? frameNum * 1000000. / elapsed : 0;
if (framesToBeEncoded)
{
- float bitrate = 0.008f * totalbytes / ((float)frameNum / param->frameRate);
- int eta = (int)(i_elapsed * (framesToBeEncoded - frameNum) / ((int64_t)frameNum * 1000000));
+ float bitrate = 0.008f * totalbytes / ((float)frameNum / ((float)param->fpsNum / param->fpsDenom));
+ int eta = (int)(elapsed * (framesToBeEncoded - frameNum) / ((int64_t)frameNum * 1000000));
sprintf(buf, "x265 [%.1f%%] %d/%d frames, %.2f fps, %.2f kb/s, eta %d:%02d:%02d",
100. * frameNum / framesToBeEncoded, frameNum, framesToBeEncoded, fps, bitrate,
eta / 3600, (eta / 60) % 60, eta % 60);
}
else
{
- double bitrate = (double)totalbytes * 8 / ((double)1000 * param->frameRate);
+ float bitrate = (float)totalbytes * 8 / ((float)1000 * param->fpsNum / param->fpsDenom);
sprintf(buf, "x265 %d frames: %.2f fps, %.2f kb/s", frameNum, fps, bitrate);
}
fprintf(stderr, "%s \r", buf + 5);
SetConsoleTitle(buf);
fflush(stderr); // needed in windows
- prevUpdateTime = i_time;
+ prevUpdateTime = time;
}
void CLIOptions::printVersion(x265_param *param)
@@ -285,7 +286,7 @@
H0(" --input-depth Bit-depth of input file. Default 8\n");
H0(" --input-res Source picture size [w x h], auto-detected if Y4M\n");
H0(" --input-csp Source color space parameter, auto-detected if Y4M. 1:i420 3:i444. Default: 1\n");
- H0(" --fps Source frame rate, auto-detected if Y4M\n");
+ H0(" --fps Source frame rate (float or num/denom), auto-detected if Y4M\n");
H0(" --frame-skip Number of frames to skip at start of input file\n");
H0("-f/--frames Number of frames to be encoded. Default all\n");
H0("\nQuad-Tree analysis:\n");
@@ -364,7 +365,6 @@
const char *inputfn = NULL;
const char *reconfn = NULL;
const char *bitstreamfn = NULL;
- const char *inputRes = NULL;
const char *preset = "medium";
const char *tune = "ssim";
@@ -443,9 +443,9 @@
OPT("output") bitstreamfn = optarg;
OPT("input") inputfn = optarg;
OPT("recon") reconfn = optarg;
+ OPT("input-res") berror |= sscanf(optarg, "%dx%d", ¶m->sourceWidth, ¶m->sourceHeight) != 2;
OPT("input-depth") inputBitDepth = (uint32_t)atoi(optarg);
OPT("recon-depth") reconFileBitDepth = (uint32_t)atoi(optarg);
- OPT("input-res") inputRes = optarg;
OPT("no-scenecut") param->scenecutThreshold = 0; // special handling
OPT("y4m") bForceY4m = true;
OPT("preset") ;
@@ -493,13 +493,11 @@
param->internalCsp = this->input->getColorSpace();
param->sourceWidth = this->input->getWidth();
param->sourceHeight = this->input->getHeight();
- param->frameRate = (int)this->input->getRate();
+ this->input->getRate(param->fpsNum, param->fpsDenom);
}
else
{
- if (inputRes)
- sscanf(inputRes, "%dx%d", ¶m->sourceWidth, ¶m->sourceHeight);
- if (param->sourceHeight <= 0 || param->sourceWidth <= 0 || param->frameRate <= 0)
+ if (param->sourceHeight <= 0 || param->sourceWidth <= 0 || param->fpsNum == 0 || param->fpsDenom == 0)
{
x265_log(param, X265_LOG_ERROR, "YUV input requires --input-res WxH and --fps N to be specified\n");
return true;
@@ -534,12 +532,12 @@
if (param->logLevel >= X265_LOG_INFO)
{
if (this->framesToBeEncoded == 0)
- fprintf(stderr, "%s [info]: %dx%d %dHz %s, unknown frame count\n", input->getName(),
- param->sourceWidth, param->sourceHeight, param->frameRate,
+ fprintf(stderr, "%s [info]: %dx%d %d/%d fps %s, unknown frame count\n", input->getName(),
+ param->sourceWidth, param->sourceHeight, param->fpsNum, param->fpsDenom,
x265_source_csp_names[param->internalCsp]);
else
- fprintf(stderr, "%s [info]: %dx%d %dHz %s, frames %u - %d of %d\n", input->getName(),
- param->sourceWidth, param->sourceHeight, param->frameRate,
+ fprintf(stderr, "%s [info]: %dx%d %d/%d fps %s, frames %u - %d of %d\n", input->getName(),
+ param->sourceWidth, param->sourceHeight, param->fpsNum, param->fpsDenom,
x265_source_csp_names[param->internalCsp],
this->frameSkip, this->frameSkip + this->framesToBeEncoded - 1, fileFrameCount);
}
@@ -549,8 +547,9 @@
if (reconfn)
{
if (reconFileBitDepth == 0)
- reconFileBitDepth = param->inputBitDepth;
- this->recon = Output::open(reconfn, param->sourceWidth, param->sourceHeight, reconFileBitDepth, param->frameRate, param->internalCsp);
+ reconFileBitDepth = param->internalBitDepth;
+ this->recon = Output::open(reconfn, param->sourceWidth, param->sourceHeight, reconFileBitDepth,
+ param->fpsNum, param->fpsDenom, param->internalCsp);
if (this->recon->isFail())
{
x265_log(param, X265_LOG_WARNING, "unable to write reconstruction file\n");
@@ -560,13 +559,13 @@
}
#if HIGH_BIT_DEPTH
- if (param->inputBitDepth != 10)
+ if (param->internalBitDepth != 10)
{
x265_log(param, X265_LOG_ERROR, "Only bit depths of 10 are supported in this build\n");
return true;
}
#else
- if (param->inputBitDepth != 8)
+ if (param->internalBitDepth != 8)
{
x265_log(param, X265_LOG_ERROR, "Only bit depths of 8 are supported in this build\n");
return true;
diff -r 8571d160aedb -r 3512dec4936e source/x265.h
--- a/source/x265.h Tue Feb 18 01:43:42 2014 -0600
+++ b/source/x265.h Tue Feb 18 00:21:58 2014 -0600
@@ -337,7 +337,7 @@
/* Internal encoder bit depth. If x265 was compiled to use 8bit pixels
* (HIGH_BIT_DEPTH=0), this field must be 8, else this field must be 10.
* Future builds may support 12bit pixels. */
- int inputBitDepth;
+ int internalBitDepth;
/* Color space of internal pictures. Only X265_CSP_I420 and X265_CSP_I444
* are supported. Eventually, i422 will also be supported as an internal
@@ -345,8 +345,9 @@
* x265_picture.colorSpace */
int internalCsp;
- /* Frame rate of source pictures */
- int frameRate;
+ /* Numerator and denominator of frame rate */
+ uint32_t fpsNum;
+ uint32_t fpsDenom;
/* Width (in pixels) of the source pictures. If this width is not an even
* multiple of 4, the encoder will pad the pictures internally to meet this
More information about the x265-devel
mailing list