[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