/* * H.265 video codec. * Copyright (c) 2013-2014 struktur AG, Dirk Farin * * This file is part of libde265. * * libde265 is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of * the License, or (at your option) any later version. * * libde265 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libde265. If not, see . */ #include "slice.h" #include #include #include bool D = false; context_model_table::context_model_table() : model(NULL), refcnt(NULL) { } context_model_table::context_model_table(const context_model_table& src) { if (D) printf("%p c'tor = %p\n",this,&src); if (src.refcnt) { (*(src.refcnt))++; } refcnt = src.refcnt; model = src.model; } context_model_table::~context_model_table() { if (D) printf("%p destructor\n",this); if (refcnt) { (*refcnt)--; if (*refcnt==0) { if (D) printf("mfree %p\n",model); delete[] model; delete refcnt; } } } void context_model_table::init(int initType, int QPY) { if (D) printf("%p init\n",this); decouple_or_alloc_with_empty_data(); initialize_CABAC_models(model, initType, QPY); } void context_model_table::release() { if (D) printf("%p release %p\n",this,refcnt); if (!refcnt) { return; } // if (*refcnt == 1) { return; } <- keep memory for later, but does not work when we believe that we freed the memory and nulled all references (*refcnt)--; if (*refcnt==0) { delete[] model; delete refcnt; } model = nullptr; refcnt= nullptr; } void context_model_table::decouple() { if (D) printf("%p decouple (%p)\n",this,refcnt); assert(refcnt); // not necessarily so, but we never use it on an unitialized object if (*refcnt > 1) { (*refcnt)--; context_model* oldModel = model; model = new context_model[CONTEXT_MODEL_TABLE_LENGTH]; refcnt= new int; *refcnt=1; memcpy(model,oldModel,sizeof(context_model)*CONTEXT_MODEL_TABLE_LENGTH); } } context_model_table context_model_table::transfer() { context_model_table newtable; newtable.model = model; newtable.refcnt= refcnt; model =nullptr; refcnt=nullptr; return newtable; } context_model_table& context_model_table::operator=(const context_model_table& src) { if (D) printf("%p assign = %p\n",this,&src); // assert(src.refcnt); // not necessarily so, but we never use it on an unitialized object if (!src.refcnt) { release(); return *this; } (*(src.refcnt))++; release(); model = src.model; refcnt= src.refcnt; return *this; } bool context_model_table::operator==(const context_model_table& b) const { if (b.model == model) return true; if (b.model == nullptr || model == nullptr) return false; for (int i=0;i1); (*refcnt)--; } if (D) printf("%p (alloc)\n",this); model = new context_model[CONTEXT_MODEL_TABLE_LENGTH]; refcnt= new int; *refcnt=1; } static void set_initValue(int SliceQPY, context_model* model, int initValue, int nContexts) { int slopeIdx = initValue >> 4; int intersecIdx = initValue & 0xF; int m = slopeIdx*5 - 45; int n = (intersecIdx<<3) - 16; int preCtxState = Clip3(1,126, ((m*Clip3(0,51, SliceQPY))>>4)+n); // logtrace(LogSlice,"QP=%d slopeIdx=%d intersecIdx=%d m=%d n=%d\n",SliceQPY,slopeIdx,intersecIdx,m,n); for (int i=0;i 0) { init_context(QPY, cm+CONTEXT_MODEL_CU_SKIP_FLAG, initValue_cu_skip_flag[initType-1], 3); init_context(QPY, cm+CONTEXT_MODEL_PRED_MODE_FLAG, &initValue_pred_mode_flag[initType-1], 1); init_context(QPY, cm+CONTEXT_MODEL_MERGE_FLAG, &initValue_merge_flag[initType-1],1); init_context(QPY, cm+CONTEXT_MODEL_MERGE_IDX, &initValue_merge_idx[initType-1], 1); init_context(QPY, cm+CONTEXT_MODEL_INTER_PRED_IDC, initValue_inter_pred_idc, 5); init_context(QPY, cm+CONTEXT_MODEL_REF_IDX_LX, initValue_ref_idx_lX, 2); init_context(QPY, cm+CONTEXT_MODEL_ABS_MVD_GREATER01_FLAG, &initValue_abs_mvd_greater01_flag[initType == 1 ? 0 : 2], 2); init_context(QPY, cm+CONTEXT_MODEL_MVP_LX_FLAG, initValue_mvp_lx_flag, 1); init_context(QPY, cm+CONTEXT_MODEL_RQT_ROOT_CBF, initValue_rqt_root_cbf, 1); init_context_const(QPY, cm+CONTEXT_MODEL_RDPCM_FLAG, 139, 2); init_context_const(QPY, cm+CONTEXT_MODEL_RDPCM_DIR, 139, 2); } init_context(QPY, cm+CONTEXT_MODEL_SPLIT_CU_FLAG, initValue_split_cu_flag[initType], 3); init_context(QPY, cm+CONTEXT_MODEL_PART_MODE, &initValue_part_mode[(initType!=2 ? initType : 5)], 4); init_context(QPY, cm+CONTEXT_MODEL_PREV_INTRA_LUMA_PRED_FLAG, &initValue_prev_intra_luma_pred_flag[initType], 1); init_context(QPY, cm+CONTEXT_MODEL_INTRA_CHROMA_PRED_MODE, &initValue_intra_chroma_pred_mode[initType], 1); init_context(QPY, cm+CONTEXT_MODEL_CBF_LUMA, &initValue_cbf_luma[initType == 0 ? 0 : 2], 2); init_context(QPY, cm+CONTEXT_MODEL_CBF_CHROMA, &initValue_cbf_chroma[initType * 4], 4); init_context(QPY, cm+CONTEXT_MODEL_SPLIT_TRANSFORM_FLAG, &initValue_split_transform_flag[initType * 3], 3); init_context(QPY, cm+CONTEXT_MODEL_LAST_SIGNIFICANT_COEFFICIENT_X_PREFIX, &initValue_last_significant_coefficient_prefix[initType * 18], 18); init_context(QPY, cm+CONTEXT_MODEL_LAST_SIGNIFICANT_COEFFICIENT_Y_PREFIX, &initValue_last_significant_coefficient_prefix[initType * 18], 18); init_context(QPY, cm+CONTEXT_MODEL_CODED_SUB_BLOCK_FLAG, &initValue_coded_sub_block_flag[initType * 4], 4); init_context(QPY, cm+CONTEXT_MODEL_SIGNIFICANT_COEFF_FLAG, initValue_significant_coeff_flag[initType], 42); init_context(QPY, cm+CONTEXT_MODEL_SIGNIFICANT_COEFF_FLAG+42, initValue_significant_coeff_flag_skipmode[initType], 2); init_context(QPY, cm+CONTEXT_MODEL_COEFF_ABS_LEVEL_GREATER1_FLAG, &initValue_coeff_abs_level_greater1_flag[initType * 24], 24); init_context(QPY, cm+CONTEXT_MODEL_COEFF_ABS_LEVEL_GREATER2_FLAG, &initValue_coeff_abs_level_greater2_flag[initType * 6], 6); init_context(QPY, cm+CONTEXT_MODEL_SAO_MERGE_FLAG, &initValue_sao_merge_leftUp_flag[initType], 1); init_context(QPY, cm+CONTEXT_MODEL_SAO_TYPE_IDX, &initValue_sao_type_idx_lumaChroma_flag[initType], 1); init_context(QPY, cm+CONTEXT_MODEL_CU_QP_DELTA_ABS, initValue_cu_qp_delta_abs, 2); init_context(QPY, cm+CONTEXT_MODEL_TRANSFORM_SKIP_FLAG, initValue_transform_skip_flag, 2); init_context(QPY, cm+CONTEXT_MODEL_CU_TRANSQUANT_BYPASS_FLAG, &initValue_cu_transquant_bypass_flag[initType], 1); init_context_const(QPY, cm+CONTEXT_MODEL_LOG2_RES_SCALE_ABS_PLUS1, 154, 8); init_context_const(QPY, cm+CONTEXT_MODEL_RES_SCALE_SIGN_FLAG, 154, 2); init_context_const(QPY, cm+CONTEXT_MODEL_CU_CHROMA_QP_OFFSET_FLAG, 154, 1); init_context_const(QPY, cm+CONTEXT_MODEL_CU_CHROMA_QP_OFFSET_IDX, 154, 1); }