[x265] [PATCH for review] cli: annex_b format switch

Xinyue Lu maillist at 7086.in
Fri Apr 10 04:04:22 CEST 2015


# HG changeset patch
# User Xinyue Lu <i at 7086.in>
# Date 1428628004 25200
#      Thu Apr 09 18:06:44 2015 -0700
# Branch Yuuki
# Node ID b671599a35f478033747c02585ade86f8a2abb2f
# Parent  984e254f93f7cedc5a9b00851d2e14b49dc94e91
cli: annex_b format switch

When bAnnexB set to true, the NAL serializer will place start codes (0x00 00 00 01) before NAL.
When false, it will place 4 bytes length before NAL.
Container formats may prefer the latter.

Also move output->setParam up so that it can select format before we initialize the encoder.

diff -r 984e254f93f7 -r b671599a35f4 doc/reST/cli.rst
--- a/doc/reST/cli.rst	Thu Apr 09 11:48:08 2015 -0500
+++ b/doc/reST/cli.rst	Thu Apr 09 18:06:44 2015 -0700
@@ -1481,6 +1481,15 @@
 Bitstream options
 =================

+.. option:: --annexb, --no-annexb
+
+	If enabled, x265 will produce Annex B bitstream format, which places
+	start codes before NAL. If disabled, x265 will produce file format,
+	which places length before NAL. x265 CLI will choose the right option
+	based on output format. Default enabled
+
+	**API ONLY**
+
 .. option:: --repeat-headers, --no-repeat-headers

 	If enabled, x265 will emit VPS, SPS, and PPS headers with every
diff -r 984e254f93f7 -r b671599a35f4 source/CMakeLists.txt
--- a/source/CMakeLists.txt	Thu Apr 09 11:48:08 2015 -0500
+++ b/source/CMakeLists.txt	Thu Apr 09 18:06:44 2015 -0700
@@ -30,7 +30,7 @@
 mark_as_advanced(FPROFILE_USE FPROFILE_GENERATE NATIVE_BUILD)

 # X265_BUILD must be incremented each time the public API is changed
-set(X265_BUILD 54)
+set(X265_BUILD 55)
 configure_file("${PROJECT_SOURCE_DIR}/x265.def.in"
                "${PROJECT_BINARY_DIR}/x265.def")
 configure_file("${PROJECT_SOURCE_DIR}/x265_config.h.in"
diff -r 984e254f93f7 -r b671599a35f4 source/common/param.cpp
--- a/source/common/param.cpp	Thu Apr 09 11:48:08 2015 -0500
+++ b/source/common/param.cpp	Thu Apr 09 18:06:44 2015 -0700
@@ -117,6 +117,7 @@
     param->levelIdc = 0;
     param->bHighTier = 0;
     param->interlaceMode = 0;
+    param->bAnnexB = 1;
     param->bRepeatHeaders = 0;
     param->bEnableAccessUnitDelimiters = 0;
     param->bEmitHRDSEI = 0;
@@ -580,6 +581,7 @@
         }
     }
     OPT("cu-stats") p->bLogCuStats = atobool(value);
+    OPT("annexb") p->bAnnexB = atobool(value);
     OPT("repeat-headers") p->bRepeatHeaders = atobool(value);
     OPT("wpp") p->bEnableWavefront = atobool(value);
     OPT("ctu") p->maxCUSize = (uint32_t)atoi(value);
diff -r 984e254f93f7 -r b671599a35f4 source/encoder/encoder.cpp
--- a/source/encoder/encoder.cpp	Thu Apr 09 11:48:08 2015 -0500
+++ b/source/encoder/encoder.cpp	Thu Apr 09 18:06:44 2015 -0700
@@ -161,7 +161,10 @@
     x265_log(p, X265_LOG_INFO, "frame threads / pool features       : %d / %s\n", p->frameNumThreads, buf);

     for (int i = 0; i < m_param->frameNumThreads; i++)
+    {
         m_frameEncoder[i] = new FrameEncoder;
+        m_frameEncoder[i]->m_nalList.m_annexB = m_param->bAnnexB;
+    }

     if (m_numPools)
     {
@@ -289,6 +292,8 @@
     m_aborted |= parseLambdaFile(m_param);

     m_encodeStartTime = x265_mdate();
+
+    m_nalList.m_annexB = m_param->bAnnexB;
 }

 void Encoder::stop()
diff -r 984e254f93f7 -r b671599a35f4 source/encoder/nal.cpp
--- a/source/encoder/nal.cpp	Thu Apr 09 11:48:08 2015 -0500
+++ b/source/encoder/nal.cpp	Thu Apr 09 18:06:44 2015 -0700
@@ -35,6 +35,7 @@
     , m_extraBuffer(NULL)
     , m_extraOccupancy(0)
     , m_extraAllocSize(0)
+    , m_annexB(true)
 {}

 void NALList::takeContents(NALList& other)
@@ -90,7 +91,12 @@
     uint8_t *out = m_buffer + m_occupancy;
     uint32_t bytes = 0;

-    if (!m_numNal || nalUnitType == NAL_UNIT_VPS || nalUnitType == NAL_UNIT_SPS || nalUnitType == NAL_UNIT_PPS)
+    if (!m_annexB)
+    {
+        /* Will write size later */
+        bytes += 4;
+    }
+    else if (!m_numNal || nalUnitType == NAL_UNIT_VPS || nalUnitType == NAL_UNIT_SPS || nalUnitType == NAL_UNIT_PPS)
     {
         memcpy(out, startCodePrefix, 4);
         bytes += 4;
@@ -144,6 +150,16 @@
      * to 0x03 is appended to the end of the data.  */
     if (!out[bytes - 1])
         out[bytes++] = 0x03;
+
+    if (!m_annexB)
+    {
+        uint32_t dataSize = bytes - 4;
+        out[0] = dataSize >> 24;
+        out[1] = dataSize >> 16;
+        out[2] = dataSize >>  8;
+        out[3] = dataSize;
+    }
+
     m_occupancy += bytes;

     X265_CHECK(m_numNal < (uint32_t)MAX_NAL_UNITS, "NAL count overflow\n");
diff -r 984e254f93f7 -r b671599a35f4 source/encoder/nal.h
--- a/source/encoder/nal.h	Thu Apr 09 11:48:08 2015 -0500
+++ b/source/encoder/nal.h	Thu Apr 09 18:06:44 2015 -0700
@@ -48,6 +48,7 @@
     uint8_t*    m_extraBuffer;
     uint32_t    m_extraOccupancy;
     uint32_t    m_extraAllocSize;
+    bool        m_annexB;

     NALList();
     ~NALList() { X265_FREE(m_buffer); X265_FREE(m_extraBuffer); }
diff -r 984e254f93f7 -r b671599a35f4 source/output/output.h
--- a/source/output/output.h	Thu Apr 09 11:48:08 2015 -0500
+++ b/source/output/output.h	Thu Apr 09 18:06:44 2015 -0700
@@ -63,7 +63,7 @@

     OutputFile() {}

-    static OutputFile* open(const char *fname, InputFileInfo& inputInfo);
+    static OutputFile* open(const char* fname, InputFileInfo& inputInfo);

     virtual bool isFail() const = 0;

@@ -71,9 +71,9 @@

     virtual void release() = 0;

-    virtual const char *getName() const = 0;
+    virtual const char* getName() const = 0;

-    virtual void setParam(x265_param *param, x265_encoder *encoder) = 0;
+    virtual void setParam(x265_param* param) = 0;

     virtual int writeHeaders(const x265_nal* nal, uint32_t nalcount) = 0;

diff -r 984e254f93f7 -r b671599a35f4 source/output/raw.cpp
--- a/source/output/raw.cpp	Thu Apr 09 11:48:08 2015 -0500
+++ b/source/output/raw.cpp	Thu Apr 09 18:06:44 2015 -0700
@@ -27,7 +27,7 @@
 using namespace x265;
 using namespace std;

-RAWOutput::RAWOutput(const char *fname, InputFileInfo&)
+RAWOutput::RAWOutput(const char* fname, InputFileInfo&)
 {
     b_fail = false;
     if (!strcmp(fname, "-"))
@@ -40,7 +40,10 @@
         b_fail = true;
 }

-void RAWOutput::setParam(x265_param *, x265_encoder *) { }
+void RAWOutput::setParam(x265_param* param)
+{
+    param->bAnnexB = true;
+}

 int RAWOutput::writeHeaders(const x265_nal* nal, uint32_t nalcount)
 {
diff -r 984e254f93f7 -r b671599a35f4 source/output/raw.h
--- a/source/output/raw.h	Thu Apr 09 11:48:08 2015 -0500
+++ b/source/output/raw.h	Thu Apr 09 18:06:44 2015 -0700
@@ -35,13 +35,13 @@
 {
 protected:

-    std::ostream *ofs;
+    std::ostream* ofs;

     bool b_fail;

 public:

-    RAWOutput(const char *fname, InputFileInfo&);
+    RAWOutput(const char* fname, InputFileInfo&);

     bool isFail() const { return b_fail; }

@@ -49,9 +49,9 @@

     void release() { delete this; }

-    const char *getName() const { return "raw"; }
+    const char* getName() const { return "raw"; }

-    void setParam(x265_param *param, x265_encoder *);
+    void setParam(x265_param* param);

     int writeHeaders(const x265_nal* nal, uint32_t nalcount);

diff -r 984e254f93f7 -r b671599a35f4 source/x265.cpp
--- a/source/x265.cpp	Thu Apr 09 11:48:08 2015 -0500
+++ b/source/x265.cpp	Thu Apr 09 18:06:44 2015 -0700
@@ -483,6 +483,9 @@
         exit(1);
     }

+    /* This allow muxers to modify bitstream format */
+    cliopt.output->setParam(param);
+
     /* note: we could try to acquire a different libx265 API here based on
      * the profile found during option parsing, but it must be done before
      * opening an encoder */
@@ -526,10 +529,7 @@
             goto fail;
         }
         else
-        {
-            cliopt.output->setParam(param, encoder);
             cliopt.totalbytes += cliopt.output->writeHeaders(p_nal, nal);
-        }
     }

     api->picture_init(param, pic_in);
diff -r 984e254f93f7 -r b671599a35f4 source/x265.h
--- a/source/x265.h	Thu Apr 09 11:48:08 2015 -0500
+++ b/source/x265.h	Thu Apr 09 18:06:44 2015 -0700
@@ -532,6 +532,11 @@
      * each keyframe. Default false */
     int       bRepeatHeaders;

+    /* Flag indicating whether the encoder should generate start codes (Annex B
+     * format) or length (file format) before NAL units. Default true, Annex B.
+     * Muxers should set this to the correct value */
+    int       bAnnexB;
+
     /* Flag indicating whether the encoder should emit an Access Unit Delimiter
      * NAL at the start of every access unit. Default false */
     int       bEnableAccessUnitDelimiters;


在 2015/4/9 7:54, Steve Borho 写道:
> On 04/09, Xinyue Lu wrote:
>> Please do NOT push this patch.
>>
>> I've noticed that only headers are correctly serialized, but not frames.
>>
>> I'll fix the problem and resend one.
> 
> ok, this one is un-queued
> 


More information about the x265-devel mailing list