This source file includes following definitions.
- childX
- childY
#ifndef ENCODE_H
#define ENCODE_H
#include "libde265/image.h"
#include "libde265/decctx.h"
#include "libde265/image-io.h"
#include "libde265/alloc_pool.h"
#include <memory>
class encoder_context;
class enc_cb;
class small_image_buffer
{
public:
explicit small_image_buffer(int log2Size,int bytes_per_pixel=1);
~small_image_buffer();
uint8_t* get_buffer_u8() const { return mBuf; }
int16_t* get_buffer_s16() const { return (int16_t*)mBuf; }
uint16_t* get_buffer_u16() const { return (uint16_t*)mBuf; }
template <class pixel_t> pixel_t* get_buffer() const { return (pixel_t*)mBuf; }
void copy_to(small_image_buffer& b) const {
assert(b.mHeight==mHeight);
assert(b.mBytesPerRow==mBytesPerRow);
memcpy(b.mBuf, mBuf, mBytesPerRow*mHeight);
}
int getWidth() const { return mWidth; }
int getHeight() const { return mHeight; }
int getStride() const { return mStride; }
private:
uint8_t* mBuf;
uint16_t mStride;
uint16_t mBytesPerRow;
uint8_t mWidth, mHeight;
small_image_buffer(const small_image_buffer&) { assert(false); }
small_image_buffer& operator=(const small_image_buffer&) { assert(false); return *this; }
};
class enc_node
{
public:
enc_node() { }
enc_node(int _x,int _y, int _log2Size) : x(_x), y(_y), log2Size(_log2Size) { }
virtual ~enc_node() { }
uint16_t x,y;
uint8_t log2Size : 3;
static const int DUMPTREE_INTRA_PREDICTION = (1<<0);
static const int DUMPTREE_RESIDUAL = (1<<1);
static const int DUMPTREE_RECONSTRUCTION = (1<<2);
static const int DUMPTREE_ALL = 0xFFFF;
virtual void debug_dumpTree(int flags, int indent=0) const = 0;
};
class PixelAccessor
{
public:
PixelAccessor(small_image_buffer& buf, int x0,int y0) {
mBase = buf.get_buffer_u8();
mStride = buf.getStride();
mXMin = x0;
mYMin = y0;
mWidth = buf.getWidth();
mHeight= buf.getHeight();
mBase -= x0 + y0*mStride;
}
const uint8_t* operator[](int y) const { return mBase+y*mStride; }
int getLeft() const { return mXMin; }
int getWidth() const { return mWidth; }
int getTop() const { return mYMin; }
int getHeight() const { return mHeight; }
void copyToImage(de265_image* img, int cIdx) const;
void copyFromImage(const de265_image* img, int cIdx);
static PixelAccessor invalid() {
return PixelAccessor();
}
private:
uint8_t* mBase;
short mStride;
short mXMin, mYMin;
uint8_t mWidth, mHeight;
PixelAccessor() {
mBase = NULL;
mStride = mXMin = mYMin = mWidth = mHeight = 0;
}
};
class enc_tb : public enc_node
{
public:
enc_tb(int x,int y,int log2TbSize, enc_cb* _cb);
~enc_tb();
enc_tb* parent;
enc_cb* cb;
enc_tb** downPtr;
uint8_t split_transform_flag : 1;
uint8_t TrafoDepth : 2;
uint8_t blkIdx : 2;
enum IntraPredMode intra_mode;
enum IntraPredMode intra_mode_chroma;
uint8_t cbf[3];
std::shared_ptr<small_image_buffer> intra_prediction[3];
std::shared_ptr<small_image_buffer> residual[3];
mutable std::shared_ptr<small_image_buffer> reconstruction[3];
union {
struct {
enc_tb* children[4];
};
struct {
int16_t* coeff[3];
bool skip_transform[3][2];
uint8_t explicit_rdpcm[3][2];
};
};
float distortion;
float rate;
float rate_withoutCbfChroma;
void set_cbf_flags_from_children();
void reconstruct(encoder_context* ectx, de265_image* img) const;
void debug_writeBlack(encoder_context* ectx, de265_image* img) const;
bool isZeroBlock() const { return cbf[0]==false && cbf[1]==false && cbf[2]==false; }
void alloc_coeff_memory(int cIdx, int tbSize);
const enc_tb* getTB(int x,int y) const;
PixelAccessor getPixels(int x,int y, int cIdx, const seq_parameter_set& sps);
void writeReconstructionToImage(de265_image* img,
const seq_parameter_set* sps) const;
virtual void debug_dumpTree(int flags, int indent=0) const;
private:
static alloc_pool mMemPool;
void reconstruct_tb(encoder_context* ectx,
de265_image* img, int x0,int y0, int log2TbSize,
int cIdx) const;
};
struct enc_pb_inter
{
PBMotion motion;
PBMotionCoding spec;
};
class enc_cb : public enc_node
{
public:
enc_cb();
~enc_cb();
enc_cb* parent;
enc_cb** downPtr;
uint8_t split_cu_flag : 1;
uint8_t ctDepth : 2;
union {
struct {
enc_cb* children[4];
};
struct {
uint8_t qp : 6;
uint8_t cu_transquant_bypass_flag : 1;
uint8_t pcm_flag : 1;
enum PredMode PredMode;
enum PartMode PartMode;
union {
struct {
} intra;
struct {
enc_pb_inter pb[4];
uint8_t rqt_root_cbf : 1;
} inter;
};
enc_tb* transform_tree;
};
};
float distortion;
float rate;
void set_rqt_root_bf_from_children_cbf();
void reconstruct(encoder_context* ectx,de265_image* img) const;
const enc_tb* getTB(int x,int y) const;
void writeReconstructionToImage(de265_image* img,
const seq_parameter_set* sps) const;
virtual void debug_dumpTree(int flags, int indent=0) const;
static void* operator new(const size_t size) {
void* p = mMemPool.new_obj(size);
return p;
}
static void operator delete(void* obj) {
mMemPool.delete_obj(obj);
}
private:
static alloc_pool mMemPool;
};
class CTBTreeMatrix
{
public:
CTBTreeMatrix() : mWidthCtbs(0), mHeightCtbs(0), mLog2CtbSize(0) { }
~CTBTreeMatrix() { free(); }
void alloc(int w,int h, int log2CtbSize);
void clear() { free(); }
void setCTB(int xCTB, int yCTB, enc_cb* ctb) {
int idx = xCTB + yCTB*mWidthCtbs;
assert(idx < mCTBs.size());
if (mCTBs[idx]) { delete mCTBs[idx]; }
mCTBs[idx] = ctb;
}
const enc_cb* getCTB(int xCTB, int yCTB) const {
int idx = xCTB + yCTB*mWidthCtbs;
assert(idx < mCTBs.size());
return mCTBs[idx];
}
enc_cb** getCTBRootPointer(int x, int y) {
x >>= mLog2CtbSize;
y >>= mLog2CtbSize;
int idx = x + y*mWidthCtbs;
assert(idx < mCTBs.size());
return &mCTBs[idx];
}
const enc_cb* getCB(int x,int y) const;
const enc_tb* getTB(int x,int y) const;
const enc_pb_inter* getPB(int x,int y) const;
void writeReconstructionToImage(de265_image* img,
const seq_parameter_set*) const;
private:
std::vector<enc_cb*> mCTBs;
int mWidthCtbs;
int mHeightCtbs;
int mLog2CtbSize;
void free() {
for (int i=0 ; i<mWidthCtbs*mHeightCtbs ; i++) {
if (mCTBs[i]) {
delete mCTBs[i];
mCTBs[i]=NULL;
}
}
}
};
inline int childX(int x0, int idx, int log2CbSize)
{
return x0 + ((idx&1) << (log2CbSize-1));
}
inline int childY(int y0, int idx, int log2CbSize)
{
return y0 + ((idx>>1) << (log2CbSize-1));
}
#endif