<html>
<head>
<meta content="text/html; charset=ISO-8859-1"
http-equiv="Content-Type">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<div class="moz-cite-prefix">On 02/24/2014 09:03 PM, Steve Borho
wrote:<br>
</div>
<blockquote
cite="mid:dfc6889247da48d658df.1393304634@batman.gateway.pace.com"
type="cite">
<pre wrap=""># HG changeset patch
# User Steve Borho <a class="moz-txt-link-rfc2396E" href="mailto:steve@borho.org"><steve@borho.org></a>
# Date 1393303499 21600
# Mon Feb 24 22:44:59 2014 -0600
# Node ID dfc6889247da48d658dfe124d5dcda817b3447b3
# Parent 6214d2609ea806408ed18d92f5f95acad8c8c5d1
cli: refactor handling of input file parameters
* allow y4m header to provide aspect ratio
* allow user to override Y4M aspect ratio or frame rate
* allow user to provide data possibly missing from Y4M header
* do not clamp framesToBeEncoded to predicted file size (stop at EOF)
diff -r 6214d2609ea8 -r dfc6889247da source/common/param.cpp
--- a/source/common/param.cpp Mon Feb 24 22:45:15 2014 -0600
+++ b/source/common/param.cpp Mon Feb 24 22:44:59 2014 -0600
@@ -556,10 +556,10 @@
}
OPT("extended-sar")
{
- p->bEnableVuiParametersPresentFlag = 1;
- p->bEnableAspectRatioIdc = 1;
- p->aspectRatioIdc = X265_EXTENDED_SAR;
- bError |= sscanf(value, "%dx%d", &p->sarWidth, &p->sarHeight) != 2;
+ int width, height;
+ bError |= sscanf(value, "%dx%d", &width, &height) != 2;
+ if (!bError)
+ setParamAspectRatio(p, width, height);
}
OPT("overscan")
{
@@ -751,6 +751,44 @@
namespace x265 {
// internal encoder functions
+void setParamAspectRatio(x265_param *p, int width, int height)
+{
+ const int fixedRatios[][2] =
+ {
+ { 1, 1 },
+ { 12, 11 },
+ { 10, 11 },
+ { 16, 11 },
+ { 40, 33 },
+ { 24, 11 },
+ { 20, 11 },
+ { 32, 11 },
+ { 80, 33 },
+ { 18, 11 },
+ { 15, 11 },
+ { 64, 33 },
+ { 160, 99 },
+ { 4, 3 },
+ { 3, 2 },
+ { 2, 1 },
+
+ { 0, 0 }
+ };
+ p->bEnableVuiParametersPresentFlag = 1;
+ p->bEnableAspectRatioIdc = 1;
+ p->aspectRatioIdc = X265_EXTENDED_SAR;
+ p->sarWidth = width;
+ p->sarHeight = height;
+ for (int i = 0; fixedRatios[i][0]; i++)
+ {
+ if (width == fixedRatios[i][0] && height == fixedRatios[i][1])
+ {
+ p->aspectRatioIdc = i + 1;
+ return;
+ }
+ }
+}
+
</pre>
</blockquote>
What's wrong with using parseName for aspectRatio?<br>
<br>
<blockquote
cite="mid:dfc6889247da48d658df.1393304634@batman.gateway.pace.com"
type="cite">
<pre wrap=""> static inline int _confirm(x265_param *param, bool bflag, const char* message)
{
if (!bflag)
diff -r 6214d2609ea8 -r dfc6889247da source/common/param.h
--- a/source/common/param.h Mon Feb 24 22:45:15 2014 -0600
+++ b/source/common/param.h Mon Feb 24 22:44:59 2014 -0600
@@ -30,6 +30,7 @@
int x265_set_globals(x265_param *param);
void x265_print_params(x265_param *param);
char* x265_param2string(x265_param *param);
+void setParamAspectRatio(x265_param *p, int width, int height);
}
diff -r 6214d2609ea8 -r dfc6889247da source/input/input.cpp
--- a/source/input/input.cpp Mon Feb 24 22:45:15 2014 -0600
+++ b/source/input/input.cpp Mon Feb 24 22:44:59 2014 -0600
@@ -28,12 +28,12 @@
using namespace x265;
-Input* Input::open(const char *filename, uint32_t inputBitDepth, bool bForceY4m)
+Input* Input::open(InputFileInfo& info, bool bForceY4m)
{
- const char * s = strrchr(filename, '.');
+ const char * s = strrchr(info.filename, '.');
if (bForceY4m || (s && !strcmp(s, ".y4m")))
- return new Y4MInput(filename, inputBitDepth);
+ return new Y4MInput(info);
else
- return new YUVInput(filename, inputBitDepth);
+ return new YUVInput(info);
}
diff -r 6214d2609ea8 -r dfc6889247da source/input/input.h
--- a/source/input/input.h Mon Feb 24 22:45:15 2014 -0600
+++ b/source/input/input.h Mon Feb 24 22:44:59 2014 -0600
@@ -36,6 +36,24 @@
namespace x265 {
// private x265 namespace
+struct InputFileInfo
+{
+ /* possibly user-supplied, possibly read from file header */
+ int width;
+ int height;
+ int csp;
+ int depth;
+ int fpsNum;
+ int fpsDenom;
+ int sarWidth;
+ int sarHeight;
+ int frameCount;
+
+ /* user supplied */
+ int skipFrames;
+ const char *filename;
+};
+
class Input
{
protected:
@@ -46,36 +64,18 @@
Input() {}
- static Input* open(const char *filename, uint32_t inputBitDepth, bool bForceY4m);
-
- virtual void setDimensions(int width, int height) = 0;
-
- virtual void setBitDepth(uint32_t bitDepth) = 0;
-
- virtual void setColorSpace(int csp) = 0;
-
- virtual void getRate(uint32_t& num, uint32_t& denom) const = 0;
-
- virtual int getWidth() const = 0;
-
- virtual int getHeight() const = 0;
-
- virtual int getColorSpace() const = 0;
+ static Input* open(InputFileInfo& info, bool bForceY4m);
virtual void startReader() = 0;
virtual void release() = 0;
- virtual void skipFrames(uint32_t numFrames) = 0;
-
virtual bool readPicture(x265_picture& pic) = 0;
virtual bool isEof() const = 0;
virtual bool isFail() = 0;
- virtual int guessFrameCount() = 0;
-
virtual const char *getName() const = 0;
};
}
diff -r 6214d2609ea8 -r dfc6889247da source/input/y4m.cpp
--- a/source/input/y4m.cpp Mon Feb 24 22:45:15 2014 -0600
+++ b/source/input/y4m.cpp Mon Feb 24 22:44:59 2014 -0600
@@ -41,7 +41,9 @@
using namespace x265;
using namespace std;
-Y4MInput::Y4MInput(const char *filename, uint32_t /*inputBitDepth*/)
+static const char header[] = "FRAME";
+
+Y4MInput::Y4MInput(InputFileInfo& info)
{
for (uint32_t i = 0; i < QUEUE_SIZE; i++)
{
@@ -49,10 +51,17 @@
}
head = tail = 0;
- colorSpace = X265_CSP_I420;
+
+ colorSpace = info.csp;
+ sarWidth = info.sarWidth;
+ sarHeight = info.sarHeight;
+ width = info.width;
+ height = info.height;
+ rateNum = info.fpsNum;
+ rateDenom = info.fpsDenom;
ifs = NULL;
- if (!strcmp(filename, "-"))
+ if (!strcmp(info.filename, "-"))
{
ifs = &cin;
#if _WIN32
@@ -60,24 +69,47 @@
#endif
}
else
- ifs = new ifstream(filename, ios::binary | ios::in);
+ ifs = new ifstream(info.filename, ios::binary | ios::in);
threadActive = false;
- if (ifs && ifs->good())
+ if (ifs && ifs->good() && parseHeader())
{
- if (parseHeader())
+ threadActive = true;
+ for (uint32_t i = 0; i < QUEUE_SIZE; i++)
{
- threadActive = true;
- for (uint32_t i = 0; i < QUEUE_SIZE; i++)
- {
- pictureAlloc(i);
- }
+ pictureAlloc(i);
}
}
- if (!threadActive && ifs && ifs != &cin)
+ if (!threadActive)
{
- delete ifs;
+ if (ifs && ifs != &cin)
+ delete ifs;
ifs = NULL;
+ return;
+ }
+
+ info.width = width;
+ info.height = height;
+ info.sarHeight = sarHeight;
+ info.sarWidth = sarWidth;
+ info.fpsNum = rateNum;
+ info.fpsDenom = rateDenom;
+ info.csp = colorSpace;
+ info.depth = 8;
+ info.frameCount = guessFrameCount();
+
+ if (info.skipFrames)
+ {
+ size_t frameSize = strlen(header) + 1;
+ for (int i = 0; i < x265_cli_csps[colorSpace].planes; i++)
+ {
+ frameSize += (size_t)((width >> x265_cli_csps[colorSpace].width[i]) * (height >> x265_cli_csps[colorSpace].height[i]));
+ }
+
+ for (int i = 0; i < info.skipFrames; i++)
+ {
+ ifs->ignore(frameSize);
+ }
}
}
@@ -117,11 +149,6 @@
if (!ifs)
return false;
- width = 0;
- height = 0;
- rateNum = 0;
- rateDenom = 0;
- colorSpace = X265_CSP_I420;
int csp = 0;
while (!ifs->eof())
@@ -221,7 +248,37 @@
break;
+ case 'A':
+ sarWidth = 0;
+ sarHeight = 0;
+ while (!ifs->eof())
+ {
+ c = ifs->get();
+ if (c == ':')
+ {
+ while (!ifs->eof())
+ {
+ c = ifs->get();
+ if (c == ' ' || c == '\n')
+ {
+ break;
+ }
+ else
+ sarHeight = sarHeight * 10 + (c - '0');
+ }
+
+ break;
+ }
+ else
+ {
+ sarWidth = sarWidth * 10 + (c - '0');
+ }
+ }
+
+ break;
+
case 'C':
+ csp = 0;
while (!ifs->eof())
{
c = ifs->get();
@@ -267,8 +324,6 @@
return true;
}
-static const char header[] = "FRAME";
-
int Y4MInput::guessFrameCount()
{
if (!ifs || ifs == &cin)
@@ -292,23 +347,6 @@
return (int)((size - cur) / frameSize);
}
-void Y4MInput::skipFrames(uint32_t numFrames)
-{
- if (ifs && numFrames)
- {
- size_t frameSize = strlen(header) + 1;
- for (int i = 0; i < x265_cli_csps[colorSpace].planes; i++)
- {
- frameSize += (size_t)((width >> x265_cli_csps[colorSpace].width[i]) * (height >> x265_cli_csps[colorSpace].height[i]));
- }
-
- for (uint32_t i = 0; i < numFrames; i++)
- {
- ifs->ignore(frameSize);
- }
- }
-}
-
void Y4MInput::startReader()
{
#if ENABLE_THREADING
diff -r 6214d2609ea8 -r dfc6889247da source/input/y4m.h
--- a/source/input/y4m.h Mon Feb 24 22:45:15 2014 -0600
+++ b/source/input/y4m.h Mon Feb 24 22:44:59 2014 -0600
@@ -41,11 +41,15 @@
uint32_t rateDenom;
+ uint32_t sarWidth;
+
+ uint32_t sarHeight;
+
int width;
int height;
- int colorSpace; ///< source Color Space Parameter
+ int colorSpace;
uint32_t plane_size[3];
@@ -69,25 +73,21 @@
bool parseHeader();
+ void pictureAlloc(int index);
+
+ int guessFrameCount();
+
+ void threadMain();
+
+ bool populateFrameQueue();
+
public:
- Y4MInput(const char *filename, uint32_t inputBitDepth);
+ Y4MInput(InputFileInfo& info);
virtual ~Y4MInput();
- void setDimensions(int, int) { /* ignore, warn */ }
-
- void setBitDepth(uint32_t) { /* ignore, warn */ }
-
- void setColorSpace(int) { /* ignore, warn */ }
-
- void getRate(uint32_t& num, uint32_t& denom) const { num = rateNum; denom = rateDenom; }
-
- int getWidth() const { return width; }
-
- int getHeight() const { return height; }
-
- int getColorSpace() const { return colorSpace; }
+ void release();
bool isEof() const { return ifs && ifs->eof(); }
@@ -95,20 +95,8 @@
void startReader();
- void release();
-
- int guessFrameCount();
-
- void skipFrames(uint32_t numFrames);
-
bool readPicture(x265_picture&);
- void pictureAlloc(int index);
-
- void threadMain();
-
- bool populateFrameQueue();
-
const char *getName() const { return "y4m"; }
};
}
diff -r 6214d2609ea8 -r dfc6889247da source/input/yuv.cpp
--- a/source/input/yuv.cpp Mon Feb 24 22:45:15 2014 -0600
+++ b/source/input/yuv.cpp Mon Feb 24 22:44:59 2014 -0600
@@ -42,7 +42,7 @@
using namespace x265;
using namespace std;
-YUVInput::YUVInput(const char *filename, uint32_t inputBitDepth)
+YUVInput::YUVInput(InputFileInfo& info)
{
for (int i = 0; i < QUEUE_SIZE; i++)
{
@@ -51,11 +51,21 @@
head = 0;
tail = 0;
- depth = inputBitDepth;
- pixelbytes = inputBitDepth > 8 ? 2 : 1;
- width = height = framesize = 0;
+ framesize = 0;
+ depth = info.depth;
+ width = info.width;
+ height = info.height;
+ colorSpace = info.csp;
threadActive = false;
- if (!strcmp(filename, "-"))
+ ifs = NULL;
+
+ if (width == 0 || height == 0 || info.fpsNum == 0 || info.fpsDenom == 0)
+ {
+ x265_log(NULL, X265_LOG_ERROR, "yuv: width, height, and FPS must be specified\n");
+ return;
+ }
+
+ if (!strcmp(info.filename, "-"))
{
ifs = &cin;
#if _WIN32
@@ -63,14 +73,43 @@
#endif
}
else
- ifs = new ifstream(filename, ios::binary | ios::in);
+ ifs = new ifstream(info.filename, ios::binary | ios::in);
if (ifs && ifs->good())
threadActive = true;
- else if (ifs && ifs != &cin)
+ else
{
- delete ifs;
+ if (ifs && ifs != &cin)
+ delete ifs;
ifs = NULL;
+ return;
+ }
+
+ pixelbytes = depth > 8 ? 2 : 1;
+ for (int i = 0; i < x265_cli_csps[colorSpace].planes; i++)
+ {
+ uint32_t w = width >> x265_cli_csps[colorSpace].width[i];
+ uint32_t h = height >> x265_cli_csps[colorSpace].height[i];
+ framesize += w * h * pixelbytes;
+ }
+
+ for (uint32_t i = 0; i < QUEUE_SIZE; i++)
+ {
+ buf[i] = new char[framesize];
+ if (buf[i] == NULL)
+ {
+ x265_log(NULL, X265_LOG_ERROR, "yuv: buffer allocation failure, aborting\n");
+ threadActive = false;
+ return;
+ }
+ }
+ info.frameCount = guessFrameCount();
+ if (info.skipFrames)
+ {
+ for (int i = 0; i < info.skipFrames; i++)
+ {
+ ifs->ignore(framesize);
+ }
}
}
@@ -92,32 +131,8 @@
delete this;
}
-void YUVInput::init()
-{
- if (!framesize)
- {
- for (int i = 0; i < x265_cli_csps[colorSpace].planes; i++)
- {
- uint32_t w = width >> x265_cli_csps[colorSpace].width[i];
- uint32_t h = height >> x265_cli_csps[colorSpace].height[i];
- framesize += w * h * pixelbytes;
- }
-
- for (uint32_t i = 0; i < QUEUE_SIZE; i++)
- {
- buf[i] = new char[framesize];
- if (buf[i] == NULL)
- {
- x265_log(NULL, X265_LOG_ERROR, "yuv: buffer allocation failure, aborting\n");
- threadActive = false;
- }
- }
- }
-}
-
int YUVInput::guessFrameCount()
{
- init();
if (!ifs || ifs == &cin) return -1;
ifstream::pos_type cur = ifs->tellg();
@@ -134,21 +149,8 @@
return (int)((size - cur) / framesize);
}
-void YUVInput::skipFrames(uint32_t numFrames)
-{
- init();
- if (ifs)
- {
- for (uint32_t i = 0; i < numFrames; i++)
- {
- ifs->ignore(framesize);
- }
- }
-}
-
void YUVInput::startReader()
{
- init();
#if ENABLE_THREADING
if (ifs && threadActive)
start();
diff -r 6214d2609ea8 -r dfc6889247da source/input/yuv.h
--- a/source/input/yuv.h Mon Feb 24 22:45:15 2014 -0600
+++ b/source/input/yuv.h Mon Feb 24 22:44:59 2014 -0600
@@ -65,27 +65,19 @@
std::istream *ifs;
- void init();
+ int guessFrameCount();
+
+ void threadMain();
+
+ bool populateFrameQueue();
public:
- YUVInput(const char *filename, uint32_t inputBitDepth);
+ YUVInput(InputFileInfo& info);
virtual ~YUVInput();
- void setDimensions(int w, int h) { width = w; height = h; }
-
- void setColorSpace(int csp) { colorSpace = csp; }
-
- int getColorSpace() const { return colorSpace; }
-
- void setBitDepth(uint32_t bitDepth) { depth = bitDepth; }
-
- void getRate(uint32_t&, uint32_t&) const { }
-
- int getWidth() const { return width; }
-
- int getHeight() const { return height; }
+ void release();
bool isEof() const { return ifs && ifs->eof(); }
@@ -93,18 +85,8 @@
void startReader();
- void release();
-
- int guessFrameCount();
-
- void skipFrames(uint32_t numFrames);
-
bool readPicture(x265_picture&);
- void threadMain();
-
- bool populateFrameQueue();
-
const char *getName() const { return "yuv"; }
};
}
diff -r 6214d2609ea8 -r dfc6889247da source/x265.cpp
--- a/source/x265.cpp Mon Feb 24 22:45:15 2014 -0600
+++ b/source/x265.cpp Mon Feb 24 22:44:59 2014 -0600
@@ -527,57 +527,70 @@
x265_log(param, X265_LOG_ERROR, "input or output file not specified, try -V for help\n");
return true;
}
- this->input = Input::open(inputfn, inputBitDepth, bForceY4m);
+
+#if HIGH_BIT_DEPTH
+ 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->internalBitDepth != 8)
+ {
+ x265_log(param, X265_LOG_ERROR, "Only bit depths of 8 are supported in this build\n");
+ return true;
+ }
+#endif // if HIGH_BIT_DEPTH
+
+ InputFileInfo info;
+ info.filename = inputfn;
+ info.depth = inputBitDepth;
+ info.csp = param->internalCsp;
+ info.width = param->sourceWidth;
+ info.height = param->sourceHeight;
+ info.fpsNum = param->fpsNum;
+ info.fpsDenom = param->fpsDenom;
+ info.sarWidth = param->sarWidth;
+ info.sarHeight = param->sarHeight;
+ info.skipFrames = seek;
+ info.frameCount = 0;
+
+ this->input = Input::open(info, bForceY4m);
if (!this->input || this->input->isFail())
{
x265_log(param, X265_LOG_ERROR, "unable to open input file <%s>\n", inputfn);
return true;
}
- if (this->input->getWidth())
- {
- /* the file knows its own dimensions, must be Y4M */
- param->internalCsp = this->input->getColorSpace();
- param->sourceWidth = this->input->getWidth();
- param->sourceHeight = this->input->getHeight();
- this->input->getRate(param->fpsNum, param->fpsDenom);
- }
- else
- {
- 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;
- }
- this->input->setDimensions(param->sourceWidth, param->sourceHeight);
- this->input->setColorSpace(param->internalCsp);
- this->input->setBitDepth(inputBitDepth);
- }
- if (param->internalCsp != X265_CSP_I420 && param->internalCsp != X265_CSP_I444)
+ if (info.csp != X265_CSP_I420 && info.csp != X265_CSP_I444)
{
x265_log(param, X265_LOG_ERROR, "Only i420 and i444 color spaces are supported in this build\n");
return true;
}
- if (inputBitDepth < 8 || inputBitDepth > 16)
+ if (info.depth < 8 || info.depth > 16)
{
x265_log(param, X265_LOG_ERROR, "Input bit depth (%d) must be between 8 and 16\n", inputBitDepth);
return true;
}
- int guess = this->input->guessFrameCount();
- if (this->seek)
+ /* Unconditionally accept height/width/csp from file info */
+ param->sourceWidth = info.width;
+ param->sourceHeight = info.height;
+ param->internalCsp = info.csp;
+
+ /* Accept fps and sar from file info if not specified by user */
+ if (param->fpsDenom == 0 || param->fpsNum == 0)
{
- this->input->skipFrames(this->seek);
+ param->fpsDenom = info.fpsDenom;
+ param->fpsNum = info.fpsNum;
}
+ if (!param->bEnableAspectRatioIdc && info.sarWidth && info.sarHeight)
+ setParamAspectRatio(param, info.sarWidth, info.sarHeight);
- uint32_t fileFrameCount = guess < 0 ? 0 : (uint32_t)guess;
- if (this->framesToBeEncoded && fileFrameCount)
- this->framesToBeEncoded = X265_MIN(this->framesToBeEncoded, fileFrameCount - this->seek);
- else if (fileFrameCount)
- this->framesToBeEncoded = fileFrameCount - this->seek;
-
+ if (this->framesToBeEncoded == 0 && info.frameCount > seek)
+ this->framesToBeEncoded = info.frameCount - seek;
if (param->logLevel >= X265_LOG_INFO)
{
- if (this->framesToBeEncoded == 0)
+ if (framesToBeEncoded == 0)
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]);
@@ -585,7 +598,7 @@
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->seek, this->seek + this->framesToBeEncoded - 1, fileFrameCount);
+ this->seek, this->seek + this->framesToBeEncoded - 1, info.frameCount);
}
this->input->startReader();
@@ -608,20 +621,6 @@
x265_source_csp_names[param->internalCsp]);
}
-#if HIGH_BIT_DEPTH
- 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->internalBitDepth != 8)
- {
- x265_log(param, X265_LOG_ERROR, "Only bit depths of 8 are supported in this build\n");
- return true;
- }
-#endif // if HIGH_BIT_DEPTH
-
this->bitstreamFile.open(bitstreamfn, std::fstream::binary | std::fstream::out);
if (!this->bitstreamFile)
{
</pre>
<br>
<fieldset class="mimeAttachmentHeader"></fieldset>
<br>
<pre wrap="">_______________________________________________
x265-devel mailing list
<a class="moz-txt-link-abbreviated" href="mailto:x265-devel@videolan.org">x265-devel@videolan.org</a>
<a class="moz-txt-link-freetext" href="https://mailman.videolan.org/listinfo/x265-devel">https://mailman.videolan.org/listinfo/x265-devel</a>
</pre>
</blockquote>
<br>
</body>
</html>