[x265] [PATCH] cli: move raw bitstream output to separate file
Xinyue Lu
maillist at 7086.in
Tue Mar 31 07:44:09 CEST 2015
# HG changeset patch
# User Xinyue Lu <i at 7086.in>
# Date 1427779747 25200
# Mon Mar 30 22:29:07 2015 -0700
# Branch Yuuki
# Node ID 7e8766ca607ac29b7eace99556d8dfba70f400e3
# Parent 123d028332d6fe5d3b08e35a8a9be98314e69031
cli: move raw bitstream output to separate file
diff -r 123d028332d6 -r 7e8766ca607a source/output/output.cpp
--- a/source/output/output.cpp Mon Mar 30 21:27:28 2015 -0700
+++ b/source/output/output.cpp Mon Mar 30 22:29:07 2015 -0700
@@ -1,7 +1,8 @@
/*****************************************************************************
- * Copyright (C) 2013 x265 project
+ * Copyright (C) 2013-2015 x265 project
*
* Authors: Steve Borho <steve at borho.org>
+ * Xinyue Lu <i at 7086.in>
*
* 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
@@ -25,6 +26,8 @@
#include "yuv.h"
#include "y4m.h"
+#include "raw.h"
+
using namespace x265;
ReconFile* ReconFile::open(const char *fname, int width, int height, uint32_t bitdepth, uint32_t fpsNum, uint32_t fpsDenom, int csp)
@@ -36,3 +39,8 @@
else
return new YUVOutput(fname, width, height, bitdepth, csp);
}
+
+OutputFile* OutputFile::open(const char *fname)
+{
+ return new RAWOutput(fname);
+}
diff -r 123d028332d6 -r 7e8766ca607a source/output/output.h
--- a/source/output/output.h Mon Mar 30 21:27:28 2015 -0700
+++ b/source/output/output.h Mon Mar 30 22:29:07 2015 -0700
@@ -1,7 +1,8 @@
/*****************************************************************************
- * Copyright (C) 2013 x265 project
+ * Copyright (C) 2013-2015 x265 project
*
* Authors: Steve Borho <steve at borho.org>
+ * Xinyue Lu <i at 7086.in>
*
* 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
@@ -50,6 +51,33 @@
virtual const char *getName() const = 0;
};
+
+class OutputFile
+{
+protected:
+
+ virtual ~OutputFile() {}
+
+public:
+
+ OutputFile() {}
+
+ static OutputFile* open(const char *fname);
+
+ virtual bool isFail() const = 0;
+
+ virtual void release() = 0;
+
+ virtual const char *getName() const = 0;
+
+ virtual void setParam(x265_param *param, x265_encoder *encoder) = 0;
+
+ virtual int writeHeaders(const x265_nal* nal, uint32_t nalcount) = 0;
+
+ virtual int writeFrame(const x265_nal* nal, uint32_t nalcount, x265_picture& pic) = 0;
+
+ virtual void closeFile(int64_t largest_pts, int64_t second_largest_pts) = 0;
+};
}
#endif // ifndef X265_OUTPUT_H
diff -r 123d028332d6 -r 7e8766ca607a source/output/raw.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/source/output/raw.cpp Mon Mar 30 22:29:07 2015 -0700
@@ -0,0 +1,73 @@
+/*****************************************************************************
+ * Copyright (C) 2013-2015 x265 project
+ *
+ * Authors: Steve Borho <steve at borho.org>
+ * Xinyue Lu <i at 7086.in>
+ *
+ * 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 "raw.h"
+
+using namespace x265;
+using namespace std;
+
+RAWOutput::RAWOutput(const char *fname)
+{
+ b_fail = false;
+ if (!strcmp(fname, "-"))
+ {
+ ofs = &cout;
+ return;
+ }
+ ofs = new ofstream(fname, ios::binary | ios::out);
+ if(ofs->fail())
+ b_fail = true;
+}
+
+void RAWOutput::setParam(x265_param *, x265_encoder *) { }
+
+int RAWOutput::writeHeaders(const x265_nal* nal, uint32_t nalcount)
+{
+ uint32_t bytes = 0;
+ for (uint32_t i = 0; i < nalcount; i++)
+ {
+ ofs->write((const char*)nal->payload, nal->sizeBytes);
+ bytes += nal->sizeBytes;
+ nal++;
+ }
+ return bytes;
+}
+
+int RAWOutput::writeFrame(const x265_nal* nal, uint32_t nalcount, x265_picture&)
+{
+ uint32_t bytes = 0;
+ for (uint32_t i = 0; i < nalcount; i++)
+ {
+ ofs->write((const char*)nal->payload, nal->sizeBytes);
+ bytes += nal->sizeBytes;
+ nal++;
+ }
+ return bytes;
+}
+
+void RAWOutput::closeFile(int64_t, int64_t)
+{
+ if(ofs != &cout)
+ delete ofs;
+}
diff -r 123d028332d6 -r 7e8766ca607a source/output/raw.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/source/output/raw.h Mon Mar 30 22:29:07 2015 -0700
@@ -0,0 +1,63 @@
+/*****************************************************************************
+ * Copyright (C) 2013-2015 x265 project
+ *
+ * Authors: Steve Borho <steve at borho.org>
+ * Xinyue Lu <i at 7086.in>
+ *
+ * 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_HEVC_RAW_H
+#define X265_HEVC_RAW_H
+
+#include "output.h"
+#include "common.h"
+#include <fstream>
+#include <iostream>
+
+namespace x265 {
+
+class RAWOutput : public OutputFile
+{
+protected:
+
+ std::ostream *ofs;
+
+ bool b_fail;
+
+public:
+
+ RAWOutput(const char *fname);
+
+ bool isFail() const { return b_fail; }
+
+ void release() { delete this; }
+
+ const char *getName() const { return "RAW Bitstream"; };
+
+ void setParam(x265_param *param, x265_encoder *);
+
+ int writeHeaders(const x265_nal* nal, uint32_t nalcount);
+
+ int writeFrame(const x265_nal* nal, uint32_t nalcount, x265_picture&);
+
+ void closeFile(int64_t largest_pts, int64_t second_largest_pts);
+};
+}
+
+#endif
diff -r 123d028332d6 -r 7e8766ca607a source/x265.cpp
--- a/source/x265.cpp Mon Mar 30 21:27:28 2015 -0700
+++ b/source/x265.cpp Mon Mar 30 22:29:07 2015 -0700
@@ -46,6 +46,7 @@
#include <string>
#include <ostream>
#include <fstream>
+#include <queue>
#define CONSOLE_TITLE_SIZE 200
#ifdef _WIN32
@@ -70,7 +71,7 @@
{
InputFile* input;
ReconFile* recon;
- std::fstream bitstreamFile;
+ OutputFile* output;
bool bProgress;
bool bForceY4m;
bool bDither;
@@ -109,7 +110,6 @@
}
void destroy();
- void writeNALs(const x265_nal* nal, uint32_t nalcount);
void printStatus(uint32_t frameNum, x265_param *param);
bool parse(int argc, char **argv, x265_param* param);
bool parseQPFile(x265_picture &pic_org);
@@ -130,17 +130,9 @@
if (analysisFile)
fclose(analysisFile);
analysisFile = NULL;
-}
-
-void CLIOptions::writeNALs(const x265_nal* nal, uint32_t nalcount)
-{
- ProfileScopeEvent(bitstreamWrite);
- for (uint32_t i = 0; i < nalcount; i++)
- {
- bitstreamFile.write((const char*)nal->payload, nal->sizeBytes);
- totalbytes += nal->sizeBytes;
- nal++;
- }
+ if (output)
+ output->release();
+ output = NULL;
}
void CLIOptions::printStatus(uint32_t frameNum, x265_param *param)
@@ -178,7 +170,7 @@
int reconFileBitDepth = 0;
const char *inputfn = NULL;
const char *reconfn = NULL;
- const char *bitstreamfn = NULL;
+ const char *outputfn = NULL;
const char *preset = NULL;
const char *tune = NULL;
const char *profile = NULL;
@@ -264,7 +256,7 @@
OPT2("frame-skip", "seek") this->seek = (uint32_t)x265_atoi(optarg, bError);
OPT("frames") this->framesToBeEncoded = (uint32_t)x265_atoi(optarg, bError);
OPT("no-progress") this->bProgress = false;
- OPT("output") bitstreamfn = optarg;
+ OPT("output") outputfn = optarg;
OPT("input") inputfn = optarg;
OPT("recon") reconfn = optarg;
OPT("input-depth") inputBitDepth = (uint32_t)x265_atoi(optarg, bError);
@@ -298,8 +290,8 @@
if (optind < argc && !inputfn)
inputfn = argv[optind++];
- if (optind < argc && !bitstreamfn)
- bitstreamfn = argv[optind++];
+ if (optind < argc && !outputfn)
+ outputfn = argv[optind++];
if (optind < argc)
{
x265_log(param, X265_LOG_WARNING, "extra unused command arguments given <%s>\n", argv[optind]);
@@ -309,7 +301,7 @@
if (argc <= 1 || help)
showHelp(param);
- if (inputfn == NULL || bitstreamfn == NULL)
+ if (inputfn == NULL || outputfn == NULL)
{
x265_log(param, X265_LOG_ERROR, "input or output file not specified, try -V for help\n");
return true;
@@ -422,12 +414,13 @@
x265_source_csp_names[param->internalCsp]);
}
- this->bitstreamFile.open(bitstreamfn, std::fstream::binary | std::fstream::out);
- if (!this->bitstreamFile)
+ this->output = OutputFile::open(outputfn);
+ if (this->output->isFail())
{
- x265_log(NULL, X265_LOG_ERROR, "failed to open bitstream file <%s> for writing\n", bitstreamfn);
+ x265_log(NULL, X265_LOG_ERROR, "failed to open output file <%s> for writing\n", outputfn);
return true;
}
+ general_log(param, "out", X265_LOG_INFO, "Using %s\n", this->output->getName());
return false;
}
@@ -523,6 +516,7 @@
uint32_t nal;
int16_t *errorBuf = NULL;
int ret = 0;
+ std::priority_queue<int64_t> pts_queue;
if (!param->bRepeatHeaders)
{
@@ -532,8 +526,10 @@
ret = 3;
goto fail;
}
- else
- cliopt.writeNALs(p_nal, nal);
+ else {
+ cliopt.output->setParam(param, encoder);
+ cliopt.totalbytes += cliopt.output->writeHeaders(p_nal, nal);
+ }
}
x265_picture_init(param, pic_in);
@@ -593,8 +589,12 @@
if (numEncoded && pic_recon && cliopt.recon)
cliopt.recon->writePicture(pic_out);
- if (nal)
- cliopt.writeNALs(p_nal, nal);
+ if (nal) {
+ cliopt.totalbytes += cliopt.output->writeFrame(p_nal, nal, pic_out);
+ pts_queue.push(-pic_out.pts);
+ if (pts_queue.size() > 2)
+ pts_queue.pop();
+ }
cliopt.printStatus(outFrameCount, param);
}
@@ -611,8 +611,12 @@
outFrameCount += numEncoded;
if (numEncoded && pic_recon && cliopt.recon)
cliopt.recon->writePicture(pic_out);
- if (nal)
- cliopt.writeNALs(p_nal, nal);
+ if (nal) {
+ cliopt.totalbytes += cliopt.output->writeFrame(p_nal, nal, pic_out);
+ pts_queue.push(-pic_out.pts);
+ if (pts_queue.size() > 2)
+ pts_queue.pop();
+ }
cliopt.printStatus(outFrameCount, param);
@@ -629,7 +633,16 @@
if (param->csvfn && !b_ctrl_c)
x265_encoder_log(encoder, argc, argv);
x265_encoder_close(encoder);
- cliopt.bitstreamFile.close();
+
+ int64_t second_largest_pts = 0;
+ int64_t largest_pts = 0;
+ if (pts_queue.size() >= 2) {
+ second_largest_pts = -pts_queue.top();
+ pts_queue.pop();
+ largest_pts = -pts_queue.top();
+ pts_queue.pop();
+ }
+ cliopt.output->closeFile(largest_pts, second_largest_pts);
if (b_ctrl_c)
general_log(param, NULL, X265_LOG_INFO, "aborted at input frame %d, output frame %d\n",
More information about the x265-devel
mailing list