diff x265/source/encoder/frameencoder.h @ 0:772086c29cc7

Initial import.
author Matti Hamalainen <ccr@tnsp.org>
date Wed, 16 Nov 2016 11:16:33 +0200
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/x265/source/encoder/frameencoder.h	Wed Nov 16 11:16:33 2016 +0200
@@ -0,0 +1,234 @@
+/*****************************************************************************
+ * Copyright (C) 2013 x265 project
+ *
+ * Authors: Shin Yee <shinyee@multicorewareinc.com>
+ *          Min Chen <chenm003@163.com>
+ *
+ * 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_FRAMEENCODER_H
+#define X265_FRAMEENCODER_H
+
+#include "common.h"
+#include "wavefront.h"
+#include "bitstream.h"
+#include "frame.h"
+#include "picyuv.h"
+#include "md5.h"
+
+#include "analysis.h"
+#include "sao.h"
+
+#include "entropy.h"
+#include "framefilter.h"
+#include "ratecontrol.h"
+#include "reference.h"
+#include "nal.h"
+
+namespace X265_NS {
+// private x265 namespace
+
+class ThreadPool;
+class Encoder;
+
+#define ANGULAR_MODE_ID 2
+#define AMP_ID 3
+
+struct StatisticLog
+{
+    uint64_t cntInter[4];
+    uint64_t cntIntra[4];
+    uint64_t cuInterDistribution[4][INTER_MODES];
+    uint64_t cuIntraDistribution[4][INTRA_MODES];
+    uint64_t cntIntraNxN;
+    uint64_t cntSkipCu[4];
+    uint64_t cntTotalCu[4];
+    uint64_t totalCu;
+
+    StatisticLog()
+    {
+        memset(this, 0, sizeof(StatisticLog));
+    }
+};
+
+/* manages the state of encoding one row of CTU blocks.  When
+ * WPP is active, several rows will be simultaneously encoded. */
+struct CTURow
+{
+    Entropy           bufferedEntropy;  /* store CTU2 context for next row CTU0 */
+    Entropy           rowGoOnCoder;     /* store context between CTUs, code bitstream if !SAO */
+
+    FrameStats        rowStats;
+
+    /* Threading variables */
+
+    /* This lock must be acquired when reading or writing m_active or m_busy */
+    Lock              lock;
+
+    /* row is ready to run, has no neighbor dependencies. The row may have
+     * external dependencies (reference frame pixels) that prevent it from being
+     * processed, so it may stay with m_active=true for some time before it is
+     * encoded by a worker thread. */
+    volatile bool     active;
+
+    /* row is being processed by a worker thread.  This flag is only true when a
+     * worker thread is within the context of FrameEncoder::processRow(). This
+     * flag is used to detect multiple possible wavefront problems. */
+    volatile bool     busy;
+
+    /* count of completed CUs in this row */
+    volatile uint32_t completed;
+
+    /* called at the start of each frame to initialize state */
+    void init(Entropy& initContext)
+    {
+        active = false;
+        busy = false;
+        completed = 0;
+        memset(&rowStats, 0, sizeof(rowStats));
+        rowGoOnCoder.load(initContext);
+    }
+};
+
+// Manages the wave-front processing of a single encoding frame
+class FrameEncoder : public WaveFront, public Thread
+{
+public:
+
+    FrameEncoder();
+
+    virtual ~FrameEncoder() {}
+
+    virtual bool init(Encoder *top, int numRows, int numCols);
+
+    void destroy();
+
+    /* triggers encode of a new frame by the worker thread */
+    bool startCompressFrame(Frame* curFrame);
+
+    /* blocks until worker thread is done, returns access unit */
+    Frame *getEncodedPicture(NALList& list);
+
+    Event                    m_enable;
+    Event                    m_done;
+    Event                    m_completionEvent;
+    int                      m_localTldIdx;
+
+    volatile bool            m_threadActive;
+    volatile bool            m_bAllRowsStop;
+    volatile int             m_completionCount;
+    volatile int             m_vbvResetTriggerRow;
+
+    uint32_t                 m_numRows;
+    uint32_t                 m_numCols;
+    uint32_t                 m_filterRowDelay;
+    uint32_t                 m_filterRowDelayCus;
+    uint32_t                 m_refLagRows;
+
+    CTURow*                  m_rows;
+    RateControlEntry         m_rce;
+    SEIDecodedPictureHash    m_seiReconPictureDigest;
+
+    uint64_t                 m_SSDY;
+    uint64_t                 m_SSDU;
+    uint64_t                 m_SSDV;
+    double                   m_ssim;
+    uint64_t                 m_accessUnitBits;
+    uint32_t                 m_ssimCnt;
+    MD5Context               m_state[3];
+    uint32_t                 m_crc[3];
+    uint32_t                 m_checksum[3];
+
+    volatile int             m_activeWorkerCount;        // count of workers currently encoding or filtering CTUs
+    volatile int             m_totalActiveWorkerCount;   // sum of m_activeWorkerCount sampled at end of each CTU
+    volatile int             m_activeWorkerCountSamples; // count of times m_activeWorkerCount was sampled (think vbv restarts)
+    volatile int             m_countRowBlocks;           // count of workers forced to abandon a row because of top dependency
+    int64_t                  m_startCompressTime;        // timestamp when frame encoder is given a frame
+    int64_t                  m_row0WaitTime;             // timestamp when row 0 is allowed to start
+    int64_t                  m_allRowsAvailableTime;     // timestamp when all reference dependencies are resolved
+    int64_t                  m_endCompressTime;          // timestamp after all CTUs are compressed
+    int64_t                  m_endFrameTime;             // timestamp after RCEnd, NR updates, etc
+    int64_t                  m_stallStartTime;           // timestamp when worker count becomes 0
+    int64_t                  m_prevOutputTime;           // timestamp when prev frame was retrieved by API thread
+    int64_t                  m_slicetypeWaitTime;        // total elapsed time waiting for decided frame
+    int64_t                  m_totalWorkerElapsedTime;   // total elapsed time spent by worker threads processing CTUs
+    int64_t                  m_totalNoWorkerTime;        // total elapsed time without any active worker threads
+#if DETAILED_CU_STATS
+    CUStats                  m_cuStats;
+#endif
+
+    Encoder*                 m_top;
+    x265_param*              m_param;
+    Frame*                   m_frame;
+    NoiseReduction*          m_nr;
+    ThreadLocalData*         m_tld; /* for --no-wpp */
+    Bitstream*               m_outStreams;
+    uint32_t*                m_substreamSizes;
+
+    CUGeom*                  m_cuGeoms;
+    uint32_t*                m_ctuGeomMap;
+
+    Bitstream                m_bs;
+    MotionReference          m_mref[2][MAX_NUM_REF + 1];
+    Entropy                  m_entropyCoder;
+    Entropy                  m_initSliceContext;
+    FrameFilter              m_frameFilter;
+    NALList                  m_nalList;
+
+    class WeightAnalysis : public BondedTaskGroup
+    {
+    public:
+
+        FrameEncoder& master;
+
+        WeightAnalysis(FrameEncoder& fe) : master(fe) {}
+
+        void processTasks(int workerThreadId);
+
+    protected:
+
+        WeightAnalysis operator=(const WeightAnalysis&);
+    };
+
+protected:
+
+    bool initializeGeoms();
+
+    /* analyze / compress frame, can be run in parallel within reference constraints */
+    void compressFrame();
+
+    /* called by compressFrame to generate final per-row bitstreams */
+    void encodeSlice();
+
+    void threadMain();
+    int  collectCTUStatistics(const CUData& ctu, FrameStats* frameLog);
+    void noiseReductionUpdate();
+
+    /* Called by WaveFront::findJob() */
+    virtual void processRow(int row, int threadId);
+    virtual void processRowEncoder(int row, ThreadLocalData& tld);
+
+    void enqueueRowEncoder(int row) { WaveFront::enqueueRow(row * 2 + 0); }
+    void enqueueRowFilter(int row)  { WaveFront::enqueueRow(row * 2 + 1); }
+    void enableRowEncoder(int row)  { WaveFront::enableRow(row * 2 + 0); }
+    void enableRowFilter(int row)   { WaveFront::enableRow(row * 2 + 1); }
+};
+}
+
+#endif // ifndef X265_FRAMEENCODER_H