注:问号以及未注释部分 会在x265-1.8版本内更新
/*****************************************************************************
* Copyright (C) 2013 x265 project
*
* Authors: Steve Borho <steve@borho.org>
*
* 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_ENCODER_H
#define X265_ENCODER_H
#include "common.h"
#include "slice.h"
#include "scalinglist.h"
#include "x265.h"
#include "nal.h"
struct x265_encoder {};
namespace x265 {
// private namespace
extern const char g_sliceTypeToChar[3];
class Entropy;
struct EncStats
{
double m_psnrSumY;
double m_psnrSumU;
double m_psnrSumV;
double m_globalSsim;
double m_totalQp;
uint64_t m_accBits;
uint32_t m_numPics;
EncStats()
{
m_psnrSumY = m_psnrSumU = m_psnrSumV = m_globalSsim = 0;
m_accBits = 0;
m_numPics = 0;
m_totalQp = 0;
}
void addQP(double aveQp);
void addPsnr(double psnrY, double psnrU, double psnrV);
void addBits(uint64_t bits);
void addSsim(double ssim);
};
class FrameEncoder;
class DPB;
class Lookahead;
class RateControl;
class ThreadPool;
class Encoder : public x265_encoder
{
public:
int m_pocLast; // 当前已经读入的视频帧数(从0开始计数,初始化为-1)time index (POC)
int m_encodedFrameNum; // 计数当前编码的帧数 (从1开始计数)
int m_outputCount;
int m_bframeDelay;//延迟帧数:p->bframes ? (p->bBPyramid ? 2 : 1) : 0; 一般等于2
int64_t m_firstPts; //第一帧,其值等于最先进入的pts号(一般等于0)
int64_t m_bframeDelayTime;//延迟的pts号个数 一般等于2
int64_t m_prevReorderedPts[2];//存储前两帧的PTS,用于计算DTS
ThreadPool* m_threadPool;
FrameEncoder* m_frameEncoder[X265_MAX_FRAME_THREADS];//存储frame并行的个数,用于帧级编码的多线程
DPB* m_dpb;
Frame* m_exportedPic;
int m_numPools;
int m_curEncoder;//记录当前是哪个FrmaeEncoder,每完成一个m_curEncoder = (m_curEncoder + 1) % m_param->frameNumThreads;
/* cached PicYuv offset arrays, shared by all instances of
* PicYuv created by this encoder */
//当前只为指针,其存储空间在某一个frame的m_fencPic中,整个空间在编码器中只申请一次
/*如:一幅图像416x240 总过有7x4个LCU
m_cuOffsetY[0] = 0 m_cuOffsetY[1] = 64 m_cuOffsetY[2]= 128 m_cuOffsetY[7] = 40960 = 640*64 (640是步长含有扩边值)
m_cuOffsetC[0] = 0 m_cuOffsetC[1] = 32 m_cuOffsetC[2]= 64 m_cuOffsetC[7] = 13312 = 416*64 (416是步长含有扩边值)
m_buOffsetY[0] = 0 m_buOffsetY[1] = 4 m_buOffsetY[2]= 2560 (按照4x4块计算 zigzag排序 2560 = 640*4)
m_buOffsetC[0] = 0 m_buOffsetC[1] = 2 m_buOffsetY[2]= 832 (按照2x2块计算 zigzag排序 832 = 416*2)
**/
intptr_t* m_cuOffsetY; //申请空间为一帧LCU个数,按照行列对应亮度LCU的pixel地址
intptr_t* m_cuOffsetC; //申请空间为一帧LCU个数,按照行列对应色度LCU的pixel地址
intptr_t* m_buOffsetY; //申请空间为一个LCU的part个数(默认256个4x4),为当前亮度位置与LCU首地址的偏移地址 (按照zigzag4x4排序)
intptr_t* m_buOffsetC; //申请空间为一个LCU的part个数(默认256个4x4),为当前色度位置与LCU首地址的偏移地址 (按照zigzag2x2排序)
/* Collect statistics globally */
EncStats m_analyzeAll;
EncStats m_analyzeI;
EncStats m_analyzeP;
EncStats m_analyzeB;
FILE* m_csvfpt;
int64_t m_encodeStartTime;
// weighted prediction
int m_numLumaWPFrames; // number of P frames with weighted luma reference
int m_numChromaWPFrames; // number of P frames with weighted chroma reference
int m_numLumaWPBiFrames; // number of B frames with weighted luma reference
int m_numChromaWPBiFrames; // number of B frames with weighted chroma reference
FILE* m_analysisFile;
int m_conformanceMode;
VPS m_vps;
SPS m_sps;
PPS m_pps;
NALList m_nalList;
ScalingList m_scalingList; // quantization matrix information
int m_lastBPSEI;
uint32_t m_numDelayedPic;//当前列表中有多少帧未编码 每当读入一帧++,每当编码完毕一帧减--
x265_param* m_param;
x265_param* m_latestParam;
RateControl* m_rateControl;
Lookahead* m_lookahead; //用于帧类型决策以及framecost计算
Window m_conformanceWindow;
bool m_bZeroLatency; // x265_encoder_encode() returns NALs for the input picture, zero lag
bool m_aborted; // 用于检错处理,出错(如内存申请失败等)置为true 初始化为false fatal error detected
bool m_reconfigured; // reconfigure of encoder detected
Encoder();
~Encoder() {}
void create();
void stopJobs();
void destroy();
int encode(const x265_picture* pic, x265_picture *pic_out);
int reconfigureParam(x265_param* encParam, x265_param* param);
void getStreamHeaders(NALList& list, Entropy& sbacCoder, Bitstream& bs);
void fetchStats(x265_stats* stats, size_t statsSizeBytes);
void writeLog(int argc, char **argv);
void printSummary();
char* statsString(EncStats&, char*);
char* statsCSVString(EncStats& stat, char* buffer);
void configure(x265_param *param);
void updateVbvPlan(RateControl* rc);
void allocAnalysis(x265_analysis_data* analysis);
void freeAnalysis(x265_analysis_data* analysis);
void readAnalysisFile(x265_analysis_data* analysis, int poc);
void writeAnalysisFile(x265_analysis_data* pic);
void finishFrameStats(Frame* pic, FrameEncoder *curEncoder, uint64_t bits);
protected:
void initVPS(VPS *vps);
void initSPS(SPS *sps);
void initPPS(PPS *pps);
};
}
#endif // ifndef X265_ENCODER_H