/* [<][>][^][v][top][bottom][index][help] */
/*
* H.265 video codec.
* Copyright (c) 2013-2014 struktur AG, Dirk Farin <farin@struktur.de>
*
* Authors: struktur AG, Dirk Farin <farin@struktur.de>
* Min Chen <chenm003@163.com>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef DE265_SLICE_H
#define DE265_SLICE_H
#include "libde265/cabac.h"
#include "libde265/de265.h"
#include "libde265/util.h"
#include "libde265/refpic.h"
#include "libde265/threads.h"
#include <vector>
#define MAX_NUM_REF_PICS 16
#define SLICE_TYPE_B 0
#define SLICE_TYPE_P 1
#define SLICE_TYPE_I 2
/*
2Nx2N 2NxN Nx2N NxN
+-------+ +-------+ +---+---+ +---+---+
| | | | | | | | | |
| | |_______| | | | |___|___|
| | | | | | | | | |
| | | | | | | | | |
+-------+ +-------+ +---+---+ +---+---+
2NxnU 2NxnD nLx2N nRx2N
+-------+ +-------+ +-+-----+ +-----+-+
|_______| | | | | | | | |
| | | | | | | | | |
| | |_______| | | | | | |
| | | | | | | | | |
+-------+ +-------+ +-+-----+ +-----+-+
- AMP only if CU size > min CU size -> minimum PU size = CUsize/2
- NxN only if size >= 16x16 (-> minimum block size = 8x8)
- minimum block size for Bi-Pred is 8x8 (wikipedia: Coding_tree_unit)
*/
enum PartMode
{
PART_2Nx2N = 0,
PART_2NxN = 1,
PART_Nx2N = 2,
PART_NxN = 3,
PART_2NxnU = 4,
PART_2NxnD = 5,
PART_nLx2N = 6,
PART_nRx2N = 7
};
enum PredMode
{
MODE_INTRA, MODE_INTER, MODE_SKIP
};
enum IntraPredMode
{
INTRA_PLANAR = 0,
INTRA_DC = 1,
INTRA_ANGULAR_2 = 2, INTRA_ANGULAR_3 = 3, INTRA_ANGULAR_4 = 4, INTRA_ANGULAR_5 = 5,
INTRA_ANGULAR_6 = 6, INTRA_ANGULAR_7 = 7, INTRA_ANGULAR_8 = 8, INTRA_ANGULAR_9 = 9,
INTRA_ANGULAR_10 = 10, INTRA_ANGULAR_11 = 11, INTRA_ANGULAR_12 = 12, INTRA_ANGULAR_13 = 13,
INTRA_ANGULAR_14 = 14, INTRA_ANGULAR_15 = 15, INTRA_ANGULAR_16 = 16, INTRA_ANGULAR_17 = 17,
INTRA_ANGULAR_18 = 18, INTRA_ANGULAR_19 = 19, INTRA_ANGULAR_20 = 20, INTRA_ANGULAR_21 = 21,
INTRA_ANGULAR_22 = 22, INTRA_ANGULAR_23 = 23, INTRA_ANGULAR_24 = 24, INTRA_ANGULAR_25 = 25,
INTRA_ANGULAR_26 = 26, INTRA_ANGULAR_27 = 27, INTRA_ANGULAR_28 = 28, INTRA_ANGULAR_29 = 29,
INTRA_ANGULAR_30 = 30, INTRA_ANGULAR_31 = 31, INTRA_ANGULAR_32 = 32, INTRA_ANGULAR_33 = 33,
INTRA_ANGULAR_34 = 34,
INTRA_CHROMA_EQ_LUMA = 100 // chroma := luma
};
enum InterPredIdc
{
PRED_L0=0,
PRED_L1=1,
PRED_BI=2
};
enum context_model_indices {
CONTEXT_MODEL_SAO_MERGE_FLAG = 0,
CONTEXT_MODEL_SAO_TYPE_IDX = CONTEXT_MODEL_SAO_MERGE_FLAG +1,
CONTEXT_MODEL_SPLIT_CU_FLAG = CONTEXT_MODEL_SAO_TYPE_IDX + 1,
CONTEXT_MODEL_CU_SKIP_FLAG = CONTEXT_MODEL_SPLIT_CU_FLAG + 3,
CONTEXT_MODEL_PART_MODE = CONTEXT_MODEL_CU_SKIP_FLAG + 3,
CONTEXT_MODEL_PREV_INTRA_LUMA_PRED_FLAG = CONTEXT_MODEL_PART_MODE + 4,
CONTEXT_MODEL_INTRA_CHROMA_PRED_MODE = CONTEXT_MODEL_PREV_INTRA_LUMA_PRED_FLAG + 1,
CONTEXT_MODEL_CBF_LUMA = CONTEXT_MODEL_INTRA_CHROMA_PRED_MODE + 1,
CONTEXT_MODEL_CBF_CHROMA = CONTEXT_MODEL_CBF_LUMA + 2,
CONTEXT_MODEL_SPLIT_TRANSFORM_FLAG = CONTEXT_MODEL_CBF_CHROMA + 4,
CONTEXT_MODEL_LAST_SIGNIFICANT_COEFFICIENT_X_PREFIX = CONTEXT_MODEL_SPLIT_TRANSFORM_FLAG + 3,
CONTEXT_MODEL_LAST_SIGNIFICANT_COEFFICIENT_Y_PREFIX = CONTEXT_MODEL_LAST_SIGNIFICANT_COEFFICIENT_X_PREFIX + 18,
CONTEXT_MODEL_CODED_SUB_BLOCK_FLAG = CONTEXT_MODEL_LAST_SIGNIFICANT_COEFFICIENT_Y_PREFIX + 18,
CONTEXT_MODEL_SIGNIFICANT_COEFF_FLAG = CONTEXT_MODEL_CODED_SUB_BLOCK_FLAG + 4,
CONTEXT_MODEL_COEFF_ABS_LEVEL_GREATER1_FLAG = CONTEXT_MODEL_SIGNIFICANT_COEFF_FLAG + 42,
CONTEXT_MODEL_COEFF_ABS_LEVEL_GREATER2_FLAG = CONTEXT_MODEL_COEFF_ABS_LEVEL_GREATER1_FLAG + 24,
CONTEXT_MODEL_CU_QP_DELTA_ABS = CONTEXT_MODEL_COEFF_ABS_LEVEL_GREATER2_FLAG + 6,
CONTEXT_MODEL_TRANSFORM_SKIP_FLAG = CONTEXT_MODEL_CU_QP_DELTA_ABS + 2,
CONTEXT_MODEL_MERGE_FLAG = CONTEXT_MODEL_TRANSFORM_SKIP_FLAG + 2,
CONTEXT_MODEL_MERGE_IDX = CONTEXT_MODEL_MERGE_FLAG + 1,
CONTEXT_MODEL_PRED_MODE_FLAG = CONTEXT_MODEL_MERGE_IDX + 1,
CONTEXT_MODEL_ABS_MVD_GREATER01_FLAG = CONTEXT_MODEL_PRED_MODE_FLAG + 1,
CONTEXT_MODEL_MVP_LX_FLAG = CONTEXT_MODEL_ABS_MVD_GREATER01_FLAG + 2,
CONTEXT_MODEL_RQT_ROOT_CBF = CONTEXT_MODEL_MVP_LX_FLAG + 1,
CONTEXT_MODEL_REF_IDX_LX = CONTEXT_MODEL_RQT_ROOT_CBF + 1,
CONTEXT_MODEL_INTER_PRED_IDC = CONTEXT_MODEL_REF_IDX_LX + 2,
CONTEXT_MODEL_CU_TRANSQUANT_BYPASS_FLAG = CONTEXT_MODEL_INTER_PRED_IDC + 5,
CONTEXT_MODEL_TABLE_LENGTH = CONTEXT_MODEL_CU_TRANSQUANT_BYPASS_FLAG + 1
};
typedef struct slice_segment_header {
slice_segment_header() { }
de265_error read(bitreader* br, struct decoder_context*, bool* continueDecoding);
void dump_slice_segment_header(const decoder_context*, int fd) const;
int slice_index; // index through all slices in a picture
char first_slice_segment_in_pic_flag;
char no_output_of_prior_pics_flag;
int slice_pic_parameter_set_id;
char dependent_slice_segment_flag;
int slice_segment_address;
int slice_type;
char pic_output_flag;
char colour_plane_id;
int slice_pic_order_cnt_lsb;
char short_term_ref_pic_set_sps_flag;
ref_pic_set slice_ref_pic_set;
int short_term_ref_pic_set_idx;
int num_long_term_sps;
int num_long_term_pics;
uint8_t lt_idx_sps[MAX_NUM_REF_PICS];
int poc_lsb_lt[MAX_NUM_REF_PICS];
char used_by_curr_pic_lt_flag[MAX_NUM_REF_PICS];
char delta_poc_msb_present_flag[MAX_NUM_REF_PICS];
int delta_poc_msb_cycle_lt[MAX_NUM_REF_PICS];
char slice_temporal_mvp_enabled_flag;
char slice_sao_luma_flag;
char slice_sao_chroma_flag;
char num_ref_idx_active_override_flag;
int num_ref_idx_l0_active; // [1;16]
int num_ref_idx_l1_active; // [1;16]
char ref_pic_list_modification_flag_l0;
char ref_pic_list_modification_flag_l1;
uint8_t list_entry_l0[16];
uint8_t list_entry_l1[16];
char mvd_l1_zero_flag;
char cabac_init_flag;
char collocated_from_l0_flag;
int collocated_ref_idx;
// --- pred_weight_table ---
uint8_t luma_log2_weight_denom; // [0;7]
uint8_t ChromaLog2WeightDenom; // [0;7]
// first index is L0/L1
uint8_t luma_weight_flag[2][16]; // bool
uint8_t chroma_weight_flag[2][16]; // bool
int16_t LumaWeight[2][16];
int8_t luma_offset[2][16];
int16_t ChromaWeight[2][16][2];
int8_t ChromaOffset[2][16][2];
int five_minus_max_num_merge_cand;
int slice_qp_delta;
int slice_cb_qp_offset;
int slice_cr_qp_offset;
char deblocking_filter_override_flag;
char slice_deblocking_filter_disabled_flag;
int slice_beta_offset; // = pps->beta_offset if undefined
int slice_tc_offset; // = pps->tc_offset if undefined
char slice_loop_filter_across_slices_enabled_flag;
int num_entry_point_offsets;
int offset_len;
std::vector<int> entry_point_offset;
int slice_segment_header_extension_length;
// --- derived data ---
int SliceAddrRS; // start of last independent slice
int SliceQPY;
int initType;
int MaxNumMergeCand;
int CurrRpsIdx;
ref_pic_set CurrRps; // the active reference-picture set
int NumPocTotalCurr;
int RefPicList[2][MAX_NUM_REF_PICS]; // contains indices into DPB
int RefPicList_POC[2][MAX_NUM_REF_PICS];
int RefPicList_PicState[2][MAX_NUM_REF_PICS]; /* We have to save the PicState because the decoding
of an image may be delayed and the PicState can
change in the mean-time (e.g. from ShortTerm to
LongTerm). PicState is used in motion.cc */
char LongTermRefPic[2][MAX_NUM_REF_PICS]; /* Flag whether the picture at this ref-pic-list
is a long-term picture. */
// context storage for dependent slices (stores CABAC model at end of slice segment)
context_model ctx_model_storage[CONTEXT_MODEL_TABLE_LENGTH];
std::vector<int> RemoveReferencesList; // images that can be removed from the DPB before decoding this slice
} slice_segment_header;
typedef struct {
// TODO: we could combine SaoTypeIdx and SaoEoClass into one byte to make the struct 16 bytes only
unsigned char SaoTypeIdx; // use with (SaoTypeIdx>>(2*cIdx)) & 0x3
unsigned char SaoEoClass; // use with (SaoTypeIdx>>(2*cIdx)) & 0x3
uint8_t sao_band_position[3];
int8_t saoOffsetVal[3][4]; // index with [][idx-1] as saoOffsetVal[][0]==0 always
} sao_info;
de265_error read_slice_segment_data(struct thread_context* tctx);
bool alloc_and_init_significant_coeff_ctxIdx_lookupTable();
void free_significant_coeff_ctxIdx_lookupTable();
class thread_task_ctb_row : public thread_task
{
public:
bool firstSliceSubstream;
struct thread_context* tctx;
virtual void work();
};
class thread_task_slice_segment : public thread_task
{
public:
bool firstSliceSubstream;
struct thread_context* tctx;
virtual void work();
};
#endif