[x265] [PATCH] cli: move raw bitstream output to separate file

Steve Borho steve at borho.org
Tue Mar 31 17:02:57 CEST 2015


On 03/31, Xinyue Lu wrote:
> # Uninitialized variable `cliopt.output` issue, resubmit patch
> # =====
> 
> # 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 0a6fa7943f7b43b10503c1ebb61a96c4a26a00db
> # Parent  123d028332d6fe5d3b08e35a8a9be98314e69031
> cli: move raw bitstream output to separate file
> 
> diff -r 123d028332d6 -r 0a6fa7943f7b 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 0a6fa7943f7b 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;
> +};
>  }

ok

>  #endif // ifndef X265_OUTPUT_H
> diff -r 123d028332d6 -r 0a6fa7943f7b 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())

watch the space between if and ()

For new files, you can run them through uncrustify using the config file
in our doc/ folder. This will enforce the coding style mechanically.

> +        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)

here too

> +        delete ofs;
> +}
> diff -r 123d028332d6 -r 0a6fa7943f7b 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;  }

nit remove extra space

> +    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 0a6fa7943f7b 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;
> @@ -95,6 +96,7 @@
>          frameRate = 0.f;
>          input = NULL;
>          recon = NULL;
> +        output = NULL;
>          framesToBeEncoded = seek = 0;
>          totalbytes = 0;
>          bProgress = true;
> @@ -109,7 +111,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 +131,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 +171,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 +257,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 +291,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 +302,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 +415,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 +517,7 @@
>      uint32_t nal;
>      int16_t *errorBuf = NULL;
>      int ret = 0;
> +    std::priority_queue<int64_t> pts_queue;
> 
>      if (!param->bRepeatHeaders)
>      {
> @@ -532,8 +527,10 @@
>              ret = 3;
>              goto fail;
>          }
> -        else
> -            cliopt.writeNALs(p_nal, nal);
> +        else {

watch the brace style, open brace on new-line

> +            cliopt.output->setParam(param, encoder);
> +            cliopt.totalbytes += cliopt.output->writeHeaders(p_nal, nal);
> +        }
>      }
> 
>      x265_picture_init(param, pic_in);
> @@ -593,8 +590,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 +612,12 @@
>          outFrameCount += numEncoded;
>          if (numEncoded && pic_recon && cliopt.recon)
>              cliopt.recon->writePicture(pic_out);
> -        if (nal)
> -            cliopt.writeNALs(p_nal, nal);

does pts queueing need to be done in the CLI, or can it be done in the
output file class (if it needs it)?

> +        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 +634,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",
> _______________________________________________
> x265-devel mailing list
> x265-devel at videolan.org
> https://mailman.videolan.org/listinfo/x265-devel

-- 
Steve Borho


More information about the x265-devel mailing list